[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