1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qv8contextwrapper_p.h"
43 #include "qv8engine_p.h"
45 #include <private/qdeclarativeengine_p.h>
46 #include <private/qdeclarativecontext_p.h>
50 class QV8TypeResource : public QV8ObjectResource
52 V8_RESOURCE_TYPE(TypeType);
55 QV8TypeResource(QV8Engine *engine);
56 virtual ~QV8TypeResource();
58 QV8TypeWrapper::TypeNameMode mode;
60 QDeclarativeGuard<QObject> object;
61 QDeclarativeType *type;
62 QDeclarativeTypeNameCache *typeNamespace;
65 QV8TypeResource::QV8TypeResource(QV8Engine *engine)
66 : QV8ObjectResource(engine), mode(QV8TypeWrapper::IncludeEnums), type(0), typeNamespace(0)
70 QV8TypeResource::~QV8TypeResource()
72 if (typeNamespace) typeNamespace->release();
75 QV8TypeWrapper::QV8TypeWrapper()
80 QV8TypeWrapper::~QV8TypeWrapper()
84 void QV8TypeWrapper::destroy()
86 qPersistentDispose(m_constructor);
89 void QV8TypeWrapper::init(QV8Engine *engine)
92 v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
93 ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter);
94 ft->InstanceTemplate()->SetHasExternalResource(true);
95 m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
98 v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QDeclarativeType *t, TypeNameMode mode)
101 // XXX NewInstance() should be optimized
102 v8::Local<v8::Object> rv = m_constructor->NewInstance();
103 QV8TypeResource *r = new QV8TypeResource(m_engine);
104 r->mode = mode; r->object = o; r->type = t;
105 rv->SetExternalResource(r);
109 v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QDeclarativeTypeNameCache *t, TypeNameMode mode)
112 // XXX NewInstance() should be optimized
113 v8::Local<v8::Object> rv = m_constructor->NewInstance();
114 QV8TypeResource *r = new QV8TypeResource(m_engine);
116 r->mode = mode; r->object = o; r->typeNamespace = t;
117 rv->SetExternalResource(r);
121 v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property,
122 const v8::AccessorInfo &info)
124 v8::Object::ExternalResource *r = info.This()->GetExternalResource();
125 QV8TypeResource *resource = v8_resource_cast<QV8TypeResource>(info.This());
128 return v8::Undefined();
130 QV8Engine *v8engine = resource->engine;
131 QObject *object = resource->object;
133 QHashedV8String propertystring(property);
135 if (resource->type) {
136 QDeclarativeType *type = resource->type;
138 if (QV8Engine::startsWithUpper(property)) {
139 if (resource->mode == IncludeEnums) {
140 QString name = v8engine->toString(property);
143 QByteArray enumName = name.toUtf8();
144 const QMetaObject *metaObject = type->baseMetaObject();
145 for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
146 QMetaEnum e = metaObject->enumerator(ii);
147 int value = e.keyToValue(enumName.constData());
149 return v8::Integer::New(value);
153 // Fall through to return empty handle
155 } else if (resource->object) {
156 QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object);
158 return v8engine->qobjectWrapper()->getProperty(ao, propertystring,
159 QV8QObjectWrapper::IgnoreRevision);
161 // Fall through to return empty handle
164 // Fall through to return empty handle
166 } else if (resource->typeNamespace) {
168 QDeclarativeTypeNameCache *typeNamespace = resource->typeNamespace;
169 QDeclarativeTypeNameCache::Data *d = typeNamespace->data(propertystring);
170 Q_ASSERT(!d || !d->typeNamespace); // Nested namespaces not supported
173 return v8engine->typeWrapper()->newObject(object, d->type, resource->mode);
174 } else if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = typeNamespace->moduleApi()) {
176 if (moduleApi->scriptCallback) {
177 moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine());
178 moduleApi->scriptCallback = 0;
179 moduleApi->qobjectCallback = 0;
180 } else if (moduleApi->qobjectCallback) {
181 moduleApi->qobjectApi = moduleApi->qobjectCallback(v8engine->engine(), v8engine->engine());
182 moduleApi->scriptCallback = 0;
183 moduleApi->qobjectCallback = 0;
186 if (moduleApi->qobjectApi) {
187 v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(moduleApi->qobjectApi, propertystring, QV8QObjectWrapper::IgnoreRevision);
190 return v8::Handle<v8::Value>();
194 // Fall through to return empty handle
197 Q_ASSERT(!"Unreachable");
200 return v8::Handle<v8::Value>();
203 v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property,
204 v8::Local<v8::Value> value,
205 const v8::AccessorInfo &info)
207 v8::Object::ExternalResource *r = info.This()->GetExternalResource();
208 QV8TypeResource *resource = v8_resource_cast<QV8TypeResource>(info.This());
213 QV8Engine *v8engine = resource->engine;
215 // XXX TODO: Implement writes to module API objects
217 QHashedV8String propertystring(property);
219 if (resource->type && resource->object) {
220 QDeclarativeType *type = resource->type;
221 QObject *object = resource->object;
222 QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object);
224 v8engine->qobjectWrapper()->setProperty(ao, propertystring, value,
225 QV8QObjectWrapper::IgnoreRevision);
226 } else if (resource->typeNamespace) {
227 if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi()) {
228 if (moduleApi->scriptCallback) {
229 moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine());
230 moduleApi->scriptCallback = 0;
231 moduleApi->qobjectCallback = 0;
232 } else if (moduleApi->qobjectCallback) {
233 moduleApi->qobjectApi = moduleApi->qobjectCallback(v8engine->engine(), v8engine->engine());
234 moduleApi->scriptCallback = 0;
235 moduleApi->qobjectCallback = 0;
238 if (moduleApi->qobjectApi)
239 v8engine->qobjectWrapper()->setProperty(moduleApi->qobjectApi, propertystring, value,
240 QV8QObjectWrapper::IgnoreRevision);