[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdelibs/kparts
From: Maks Orlovich <maksim () kde ! org>
Date: 2010-05-10 19:05:51
Message-ID: 20100510190551.B01E2AC8B1 () svn ! kde ! org
[Download RAW message or body]
SVN commit 1125140 by orlovich:
Implement one direction of the adapter. The other direction is less code
but requires more finesse. Might make sense to port KHTMLPart to the new API first.
M +156 -3 scriptableextension.cpp
M +9 -4 scriptableextension.h
AM scriptableextension_p.h [License: LGPL (v2+)]
--- trunk/KDE/kdelibs/kparts/scriptableextension.cpp #1125139:1125140
@@ -1,6 +1,6 @@
/* This file is part of the KDE project
Copyright (C) 2010 Maksim Orlovich <maksim@kde.org>
- Copyright (C) 2002 Koos Vriezen <koos.vriezen@gmail.com>
+ Copyright (C) 2002, 2004 Koos Vriezen <koos.vriezen@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -18,6 +18,7 @@
Boston, MA 02110-1301, USA.
*/
#include "scriptableextension.h"
+#include "scriptableextension_p.h"
#include <kglobal.h>
#include <QDBusMetaType>
@@ -46,7 +47,11 @@
return KGlobal::findDirectChild<KParts::ScriptableExtension*>(obj);
}
-// ### static ScriptableExtension* adapterFromLiveConnect(LiveConnectExtension* \
oldApi); +ScriptableExtension* ScriptableExtension::adapterFromLiveConnect(QObject* \
parentObj, + \
LiveConnectExtension* oldApi) +{
+ return new ScriptableLiveConnectExtension(parentObj, oldApi);
+}
void ScriptableExtension::setHost(ScriptableExtension* host)
{
@@ -169,6 +174,153 @@
Q_UNUSED(objId);
}
+// LiveConnectExtension -> ScriptableExtension adapter. We use
+// lc object IDs as our own object IDs.
+// ----------------------------------------------------------------------------
+QVariant ScriptableLiveConnectExtension::rootObject()
+{
+ // Plugin root is always LC object #0.
+ return QVariant::fromValue(ScriptableExtension::Object(this, 0));
+}
+
+bool ScriptableLiveConnectExtension::hasProperty(ScriptableExtension*, quint64 \
objId, const QString& propName) +{
+ QVariant val = get(0, objId, propName);
+ return !val.canConvert<ScriptableExtension::Exception>();
+}
+
+// Note that since we wrap around a plugin, and do not implement the browser,
+// we do not perform XSS checks ourselves.
+QVariant ScriptableLiveConnectExtension::callAsFunction(ScriptableExtension*,
+ quint64 objId, const ScriptableExtension::ArgList& args)
+{
+ QStringList qargs;
+ // Convert args to strings for LC use.
+ for (int i = 0; i < args.size(); ++i) {
+ bool ok;
+ qargs.append(toLC(args[i], &ok));
+ if (!ok)
+ return unimplemented();
+ }
+
+ LiveConnectExtension::Type retType;
+ unsigned long retObjId;
+ QString retVal;
+ if (wrapee->call((unsigned long)objId, objNames[objId], qargs,
+ retType, retObjId, retVal)) {
+ return fromLC(QString(), retType, retObjId, retVal);
+ } else {
+ return unimplemented();
+ }
+}
+
+QVariant ScriptableLiveConnectExtension::get(ScriptableExtension*,
+ quint64 objId, const QString& propName)
+{
+ LiveConnectExtension::Type retType;
+ unsigned long retObjId;
+ QString retVal;
+ if (wrapee->get((unsigned long)objId, propName, retType, retObjId, retVal)) {
+ return fromLC(propName, retType, retObjId, retVal);
+ } else {
+ // exception signals failure. ### inellegant
+ return unimplemented();
+ }
+}
+
+bool ScriptableLiveConnectExtension::put(ScriptableExtension*, quint64 objId,
+ const QString& propName, const QVariant& \
value) +{
+ bool ok;
+ QString val = toLC(value, &ok);
+ if (!ok)
+ return false;
+
+ return wrapee->put((unsigned long)objId, propName, val);
+}
+
+QVariant ScriptableLiveConnectExtension::fromLC(const QString& name,
+ LiveConnectExtension::Type type,
+ unsigned long objId,
+ const QString& value)
+{
+ switch (type) {
+ case KParts::LiveConnectExtension::TypeBool: {
+ bool ok;
+ int i = value.toInt(&ok);
+ if (ok)
+ return QVariant(bool(i));
+ return QVariant(value.toLower() == QLatin1String("true"));
+ }
+ case KParts::LiveConnectExtension::TypeObject:
+ case KParts::LiveConnectExtension::TypeFunction:
+ // if we got an object, we also have to remeber its name, as we'll need it
+ // for call
+ if (!refCounts.contains(objId)) {
+ refCounts[objId] = 0;
+ objNames [objId] = name;
+ }
+ return QVariant::fromValue(ScriptableExtension::Object(this, objId));
+
+ case KParts::LiveConnectExtension::TypeNumber:
+ return QVariant(value.toDouble());
+
+ case KParts::LiveConnectExtension::TypeString:
+ return QVariant(value);
+
+ case KParts::LiveConnectExtension::TypeVoid:
+ default:
+ return QVariant::fromValue(ScriptableExtension::Undefined());
+ }
+}
+
+QString ScriptableLiveConnectExtension::toLC(const QVariant& in, bool* ok)
+{
+ *ok = true; // most of the time.
+
+ // Objects (or exceptions) can't be converted
+ if (in.canConvert<ScriptableExtension::Object>() ||
+ in.canConvert<ScriptableExtension::Exception>()) {
+
+ *ok = false;
+ return QString();
+ }
+
+ // Convert null and undefined to appropriate strings
+ // ### this matches old KHTML behavior, but is this sensible?
+ if (in.canConvert<ScriptableExtension::Null>())
+ return QString::fromLatin1("null");
+
+ if (in.canConvert<ScriptableExtension::Undefined>())
+ return QString::fromLatin1("undefined");
+
+ if (in.type() == QVariant::Bool)
+ return in.toBool() ? QString::fromLatin1("true") : \
QString::fromLatin1("false"); +
+ // Just stringify everything else, makes sense forn umms as well.
+ if (in.canConvert<QString>())
+ return in.toString();
+
+ // something really icky...
+ *ok = false;
+ return QString();
+}
+
+void ScriptableLiveConnectExtension::acquire(quint64 objId)
+{
+ ++refCounts[objId];
+}
+
+void ScriptableLiveConnectExtension::release(quint64 objId)
+{
+ int newRC = --refCounts[objId];
+ if (!newRC) {
+ wrapee->unregister((unsigned long)objId);
+ refCounts.remove(objId);
+ objNames.remove(objId);
+ }
+}
+
} // namespace KParts
@@ -231,5 +383,6 @@
return arg;
}
+// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
#include "scriptableextension.moc"
-// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
+#include "scriptableextension_p.moc"
--- trunk/KDE/kdelibs/kparts/scriptableextension.h #1125139:1125140
@@ -87,6 +87,9 @@
struct Object {
ScriptableExtension* owner;
quint64 objId;
+
+ Object(): owner(0), objId(0) {}
+ Object(ScriptableExtension* o, quint64 id): owner(o), objId(id) {}
};
//@}
@@ -108,10 +111,10 @@
/**
* This returns a bridge object that permits KParts implementing the older
* LiveConnectExtension to be used via the ScriptableExtension API.
- * Note that this method does not do any memory management on the adapter;
- * the caller is expected to manage its lifetime.
+ * The bridge's parent will be the @p parentObj.
*/
- static ScriptableExtension* adapterFromLiveConnect(LiveConnectExtension* \
oldApi); + static ScriptableExtension* adapterFromLiveConnect(QObject* parentObj,
+ LiveConnectExtension* \
oldApi);
/**
* Registers dbus encodings of Null, Undefined, and Exception.
@@ -168,7 +171,9 @@
/// calling an operation on a KHTMLPart object,
/// then the 'this' parameter would be the object owner, a ScriptableExtension
/// provided by the KHTMLPart, while the callerPrincipal would be the
- /// ScriptableExtension of the \em plugin.
+ /// ScriptableExtension of the \em plugin. The extension is expected
+ /// to do appropriate cross-site scripting checks on this argument
+ /// if it is acting as a host.
//@{
typedef QList<QVariant> ArgList;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic