Esempio n. 1
0
bool ClassObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecState *exec,
                                      JSC::JSValue value, JSC::JSValue proto)
{
    if (!scriptClass()->supportsExtension(QScriptClass::HasInstance))
        return QScriptObjectDelegate::hasInstance(object, exec, value, proto);
    QScriptValueList args;
    QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(eng_p, exec);
    args << eng_p->scriptValueFromJSCValue(object) << eng_p->scriptValueFromJSCValue(value);
    QVariant result = scriptClass()->extension(QScriptClass::HasInstance, QVariant::fromValue(args));
    return result.toBool();
}
Esempio n. 2
0
QScriptValue QDeclarativeObjectScriptClass::destroy(QScriptContext *context, QScriptEngine *engine)
{
    QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
    QScriptValue that = context->thisObject();

    if (scriptClass(that) != p->objectClass)
        return engine->undefinedValue();

    ObjectData *data = (ObjectData *)p->objectClass->object(that);
    if (!data->object)
        return engine->undefinedValue();

    QDeclarativeData *ddata = QDeclarativeData::get(data->object, false);
    if (!ddata || ddata->indestructible)
        return engine->currentContext()->throwError(QLatin1String("Invalid attempt  to destroy() an indestructible object"));

    QObject *obj = data->object;
    int delay = 0;
    if (context->argumentCount() > 0)
        delay = context->argument(0).toInt32();
    if (delay > 0)
        QTimer::singleShot(delay, obj, SLOT(deleteLater()));
    else
        obj->deleteLater();

    return engine->undefinedValue();
}
QDeclarativeContextData *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v)
{
    if (scriptClass(v) != this)
        return 0;

    ContextData *data = (ContextData *)object(v);
    return data->getContext(engine);
}
Esempio n. 4
0
int QDeclarativeObjectScriptClass::objectType(const QScriptValue &value) const
{
    if (scriptClass(value) != this)
        return QVariant::Invalid;

    Object *o = object(value);
    return ((ObjectData*)(o))->type;
}
QScriptClass::QueryFlags
QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &name,
                                             QScriptClass::QueryFlags flags, QDeclarativeContextData *evalContext,
                                             QueryHints hints)
{
    Q_UNUSED(flags);
    lastData = 0;
    lastTNData = 0;

    if (name == m_destroyId.identifier ||
        name == m_toStringId.identifier)
        return QScriptClass::HandlesReadAccess;

    if (!obj)
        return 0;

    QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine);
    lastData = QDeclarativePropertyCache::property(engine, obj, name, local);
    if ((hints & ImplicitObject) && lastData && lastData->revision != 0) {

        QDeclarativeData *ddata = QDeclarativeData::get(obj);
        if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(lastData)) 
            return 0;
    }

    if (lastData)
        return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess;

    if (!(hints & SkipAttachedProperties)) {
        if (!evalContext && context()) {
            // Global object, QScriptContext activation object, QDeclarativeContext object
            QScriptValue scopeNode = scopeChainValue(context(), -3);
            if (scopeNode.isValid()) {
                Q_ASSERT(scriptClass(scopeNode) == enginePrivate->contextClass);

                evalContext = enginePrivate->contextClass->contextFromValue(scopeNode);
            }
        }

        if (evalContext && evalContext->imports) {
            QDeclarativeTypeNameCache::Data *data = evalContext->imports->data(name);
            if (data) {
                lastTNData = data;
                return QScriptClass::HandlesReadAccess;
            }
        }
    }

    if (!(hints & ImplicitObject)) {
        local.coreIndex = -1;
        lastData = &local;
        return QScriptClass::HandlesWriteAccess;
    }

    return 0;
}
QUrl QDeclarativeContextScriptClass::urlFromValue(const QScriptValue &v)
{
    if (scriptClass(v) != this)
        return QUrl();

    ContextData *data = (ContextData *)object(v);
    if (data->isUrlContext) {
        return QUrl(static_cast<UrlContextData *>(data)->url);
    } else {
        return QUrl();
    }
}
Esempio n. 7
0
QScriptValue QDeclarativeObjectMethodScriptClass::disconnect(QScriptContext *context, QScriptEngine *engine)
{
    QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);

    QScriptValue that = context->thisObject();
    if (&p->objectClass->methods != scriptClass(that))
        return engine->undefinedValue();

    MethodData *data = (MethodData *)object(that);

    if (!data->object || context->argumentCount() == 0)
        return engine->undefinedValue();

    QByteArray signal("2");
    signal.append(data->object->metaObject()->method(data->data.coreIndex).signature());

    if (context->argumentCount() == 1) {
        qScriptDisconnect(data->object, signal.constData(), QScriptValue(), context->argument(0));
    } else {
        qScriptDisconnect(data->object, signal.constData(), context->argument(0), context->argument(1));
    }

    return engine->undefinedValue();
}
Esempio n. 8
0
void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
                                                const Identifier &name,
                                                const QScriptValue &value,
                                                QScriptContext *context,
                                                QDeclarativeContextData *evalContext)
{
    Q_UNUSED(name);

    Q_ASSERT(obj);
    Q_ASSERT(lastData);
    Q_ASSERT(context);

    if (!lastData->isValid()) {
        QString error = QLatin1String("Cannot assign to non-existent property \"") +
                        toString(name) + QLatin1Char('\"');
        context->throwError(error);
        return;
    }

    if (!(lastData->flags & QDeclarativePropertyCache::Data::IsWritable) && 
        !(lastData->flags & QDeclarativePropertyCache::Data::IsQList)) {
        QString error = QLatin1String("Cannot assign to read-only property \"") +
                        toString(name) + QLatin1Char('\"');
        context->throwError(error);
        return;
    }

    QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);

    if (!evalContext) {
        // Global object, QScriptContext activation object, QDeclarativeContext object
        QScriptValue scopeNode = scopeChainValue(context, -3);
        if (scopeNode.isValid()) {
            Q_ASSERT(scriptClass(scopeNode) == enginePriv->contextClass);

            evalContext = enginePriv->contextClass->contextFromValue(scopeNode);
        }
    }

    QDeclarativeAbstractBinding *delBinding =
        QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, 0);
    if (delBinding)
        delBinding->destroy();

    if (value.isNull() && lastData->flags & QDeclarativePropertyCache::Data::IsQObjectDerived) {
        QObject *o = 0;
        int status = -1;
        int flags = 0;
        void *argv[] = { &o, 0, &status, &flags };
        QMetaObject::metacall(obj, QMetaObject::WriteProperty, lastData->coreIndex, argv);
    } else if (value.isUndefined() && lastData->flags & QDeclarativePropertyCache::Data::IsResettable) {
        void *a[] = { 0 };
        QMetaObject::metacall(obj, QMetaObject::ResetProperty, lastData->coreIndex, a);
    } else if (value.isUndefined() && lastData->propType == qMetaTypeId<QVariant>()) {
        QDeclarativePropertyPrivate::write(obj, *lastData, QVariant(), evalContext);
    } else if (value.isUndefined()) {
        QString error = QLatin1String("Cannot assign [undefined] to ") +
                        QLatin1String(QMetaType::typeName(lastData->propType));
        context->throwError(error);
    } else {
        QVariant v;
        if (lastData->flags & QDeclarativePropertyCache::Data::IsQList)
            v = enginePriv->scriptValueToVariant(value, qMetaTypeId<QList<QObject *> >());
        else
            v = enginePriv->scriptValueToVariant(value, lastData->propType);

        if (!QDeclarativePropertyPrivate::write(obj, *lastData, v, evalContext)) {
            const char *valueType = 0;
            if (v.userType() == QVariant::Invalid) valueType = "null";
            else valueType = QMetaType::typeName(v.userType());

            QString error = QLatin1String("Cannot assign ") +
                            QLatin1String(valueType) +
                            QLatin1String(" to ") +
                            QLatin1String(QMetaType::typeName(lastData->propType));
            context->throwError(error);
        }
    }
}
void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
                                                const Identifier &name,
                                                const QScriptValue &value,
                                                QScriptContext *context,
                                                QDeclarativeContextData *evalContext)
{
    Q_UNUSED(name);

    Q_ASSERT(obj);
    Q_ASSERT(lastData);
    Q_ASSERT(context);

    if (!lastData->isValid()) {
        QString error = QLatin1String("Cannot assign to non-existent property \"") +
                        toString(name) + QLatin1Char('\"');
        context->throwError(error);
        return;
    }

    if (!(lastData->flags & QDeclarativePropertyCache::Data::IsWritable) && 
        !(lastData->flags & QDeclarativePropertyCache::Data::IsQList)) {
        QString error = QLatin1String("Cannot assign to read-only property \"") +
                        toString(name) + QLatin1Char('\"');
        context->throwError(error);
        return;
    }

    QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);

    if (!evalContext) {
        // Global object, QScriptContext activation object, QDeclarativeContext object
        QScriptValue scopeNode = scopeChainValue(context, -3);
        if (scopeNode.isValid()) {
            Q_ASSERT(scriptClass(scopeNode) == enginePriv->contextClass);

            evalContext = enginePriv->contextClass->contextFromValue(scopeNode);
        }
    }

    QDeclarativeBinding *newBinding = 0;
    if (value.isFunction() && !value.isRegExp()) {
        QScriptContextInfo ctxtInfo(context);
        QDeclarativePropertyCache::ValueTypeData valueTypeData;

        newBinding = new QDeclarativeBinding(value, obj, evalContext);
        newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber());
        newBinding->setTarget(QDeclarativePropertyPrivate::restore(*lastData, valueTypeData, obj, evalContext));
        if (newBinding->expression().contains(QLatin1String("this")))
            newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
    }

    QDeclarativeAbstractBinding *delBinding =
        QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, newBinding);
    if (delBinding)
        delBinding->destroy();

    if (value.isNull() && lastData->flags & QDeclarativePropertyCache::Data::IsQObjectDerived) {
        QObject *o = 0;
        int status = -1;
        int flags = 0;
        void *argv[] = { &o, 0, &status, &flags };
        QMetaObject::metacall(obj, QMetaObject::WriteProperty, lastData->coreIndex, argv);
    } else if (value.isUndefined() && lastData->flags & QDeclarativePropertyCache::Data::IsResettable) {
        void *a[] = { 0 };
        QMetaObject::metacall(obj, QMetaObject::ResetProperty, lastData->coreIndex, a);
    } else if (value.isUndefined() && lastData->propType == qMetaTypeId<QVariant>()) {
        QDeclarativePropertyPrivate::write(obj, *lastData, QVariant(), evalContext);
    } else if (value.isUndefined()) {
        QString error = QLatin1String("Cannot assign [undefined] to ") +
                        QLatin1String(QMetaType::typeName(lastData->propType));
        context->throwError(error);
    } else if (value.isFunction() && !value.isRegExp()) {
        // this is handled by the binding creation above
    } else {
        //### expand optimization for other known types
        if (lastData->propType == QMetaType::Int && value.isNumber()) {
            int rawValue = qRoundDouble(value.toNumber());
            int status = -1;
            int flags = 0;
            void *a[] = { (void *)&rawValue, 0, &status, &flags };
            QMetaObject::metacall(obj, QMetaObject::WriteProperty,
                                  lastData->coreIndex, a);
            return;
        } else if (lastData->propType == QMetaType::QReal && value.isNumber()) {
            qreal rawValue = qreal(value.toNumber());
            int status = -1;
            int flags = 0;
            void *a[] = { (void *)&rawValue, 0, &status, &flags };
            QMetaObject::metacall(obj, QMetaObject::WriteProperty,
                                  lastData->coreIndex, a);
            return;
        } else if (lastData->propType == QMetaType::QString && value.isString()) {
            const QString &rawValue = value.toString();
            int status = -1;
            int flags = 0;
            void *a[] = { (void *)&rawValue, 0, &status, &flags };
            QMetaObject::metacall(obj, QMetaObject::WriteProperty,
                                  lastData->coreIndex, a);
            return;
        }

        QVariant v;
        if (lastData->flags & QDeclarativePropertyCache::Data::IsQList)
            v = enginePriv->scriptValueToVariant(value, qMetaTypeId<QList<QObject *> >());
        else
            v = enginePriv->scriptValueToVariant(value, lastData->propType);

        if (!QDeclarativePropertyPrivate::write(obj, *lastData, v, evalContext)) {
            const char *valueType = 0;
            if (v.userType() == QVariant::Invalid) valueType = "null";
            else valueType = QMetaType::typeName(v.userType());

            QString error = QLatin1String("Cannot assign ") +
                            QLatin1String(valueType) +
                            QLatin1String(" to ") +
                            QLatin1String(QMetaType::typeName(lastData->propType));
            context->throwError(error);
        }
    }
}
QVariant QDeclarativeValueTypeScriptClass::toVariant(const QScriptValue &value)
{
    Q_ASSERT(scriptClass(value) == this);

    return toVariant(object(value), 0);
}