[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-11 15:16:07
Message-ID: 20100511151607.38E34AC8B2 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1125499 by orlovich:

Looks like we need FunctionRef's after all. Ick. This is trickier than I thought.


 M  +26 -14    scriptableextension.cpp  
 M  +22 -2     scriptableextension.h  
 M  +3 -3      scriptableextension_p.h  


--- trunk/KDE/kdelibs/kparts/scriptableextension.cpp #1125498:1125499
@@ -89,6 +89,17 @@
     return unimplemented();
 }
 
+QVariant ScriptableExtension::callFunctionReference(ScriptableExtension* \
callerPrincipal, +                                                    quint64 objId, \
const QString& f, +                                                    const ArgList& \
args) +{
+    Q_UNUSED(callerPrincipal);
+    Q_UNUSED(objId);
+    Q_UNUSED(args);
+    Q_UNUSED(f);
+    return unimplemented();
+}
+
 QVariant ScriptableExtension::callAsConstructor(ScriptableExtension* \
                callerPrincipal,
                                                 quint64 objId, const ArgList& args)
 {
@@ -191,14 +202,14 @@
 
 // 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)
+QVariant ScriptableLiveConnectExtension::callFunctionReference(ScriptableExtension*,
+                        quint64 o, const QString& f, const \
ScriptableExtension::ArgList& a)  {
     QStringList qargs;
     // Convert args to strings for LC use.
-    for (int i = 0; i < args.size(); ++i) {
+    for (int i = 0; i < a.size(); ++i) {
         bool ok;
-        qargs.append(toLC(args[i], &ok));
+        qargs.append(toLC(a[i], &ok));
         if (!ok)
             return unimplemented();
     }
@@ -206,8 +217,7 @@
     LiveConnectExtension::Type retType;
     unsigned long              retObjId;
     QString                    retVal;    
-    if (wrapee->call((unsigned long)objId, objNames[objId], qargs,
-                     retType, retObjId, retVal)) {
+    if (wrapee->call((unsigned long)o, f, qargs, retType, retObjId, retVal)) {
         return fromLC(QString(), retType, retObjId, retVal);
     } else {
         return unimplemented();
@@ -253,14 +263,16 @@
         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)) {
+    case KParts::LiveConnectExtension::TypeFunction: {
+        if (!refCounts.contains(objId))
             refCounts[objId] = 0;
-            objNames [objId] = name;
+
+        Object o = ScriptableExtension::Object(this, objId);
+        if (type == KParts::LiveConnectExtension::TypeObject)
+            return QVariant::fromValue(o);
+        else
+            return QVariant::fromValue(FunctionRef(o, name));
         }
-        return QVariant::fromValue(ScriptableExtension::Object(this, objId));
     
     case KParts::LiveConnectExtension::TypeNumber:
         return QVariant(value.toDouble());
@@ -280,7 +292,8 @@
 
     // Objects (or exceptions) can't be converted
     if (in.canConvert<ScriptableExtension::Object>() ||
-        in.canConvert<ScriptableExtension::Exception>()) {
+        in.canConvert<ScriptableExtension::Exception>() ||
+        in.canConvert<ScriptableExtension::FunctionRef>()) {
 
         *ok = false;
         return QString();
@@ -317,7 +330,6 @@
     if (!newRC) {
         wrapee->unregister((unsigned long)objId);
         refCounts.remove(objId);
-        objNames.remove(objId);
     }
 }
 
--- trunk/KDE/kdelibs/kparts/scriptableextension.h #1125498:1125499
@@ -55,8 +55,9 @@
      * \li @ref Undefined
      * \li @ref Exception
      * \li @ref Object
+     * \li @ref FunctionRef
      *
-     * All of these other than Object also provide DBus marshallers.
+     * All of these other than Object and FunctionRef also provide DBus marshallers.
      * These are registered when ScriptableExtension::registerDBusTypes()
      * is called, which is in particular done by ScriptableExtension constructor.
      */
@@ -81,7 +82,7 @@
 
     /// Objects are abstracted away as a pair of the ScriptableExtension
     /// the performs operations on it, and an implementation-specific Id,
-    /// which gets passed to the extension's methods. If you store reference
+    /// which gets passed to the extension's methods. If you store a reference to
     /// an object, you should use its owner's @ref acquire and @ref release
     /// methods to update its count of external references (which starts at 0)
     struct Object {
@@ -92,6 +93,18 @@
         Object(ScriptableExtension* o, quint64 id): owner(o), objId(id) {}
     };
 
+    /// Function references are a pair of an object and a field in it.
+    /// Essentially, if you have a base.field(something) call, the
+    /// 'base' needs to be passed as the 'this' to the function, and
+    /// these references can be used to resolve that.
+    struct FunctionRef {
+        Object   base;
+        QString  field;
+
+        FunctionRef() {}
+        FunctionRef(const Object& b, const QString&f): base(b), field(f) {}
+    };
+
     //@}
 
 
@@ -184,6 +197,12 @@
     virtual QVariant callAsFunction(ScriptableExtension* callerPrincipal, quint64 \
objId, const ArgList& args);  
     /**
+     Try to use a function reference to field @p f of object @objId as a function
+     */
+    virtual QVariant callFunctionReference(ScriptableExtension* callerPrincipal, \
quint64 objId, +                                           const QString& f, const \
ArgList& args);  +
+    /**
       Try to use the object @p objId associated with 'this' as a constructor
       (corresponding to ECMAScript's new foo(bar, baz, glarch) expression).
     */
@@ -258,6 +277,7 @@
 Q_DECLARE_METATYPE(KParts::ScriptableExtension::Undefined);
 Q_DECLARE_METATYPE(KParts::ScriptableExtension::Exception);
 Q_DECLARE_METATYPE(KParts::ScriptableExtension::Object);
+Q_DECLARE_METATYPE(KParts::ScriptableExtension::FunctionRef);
 
 const QDBusArgument& KPARTS_EXPORT operator<<(QDBusArgument& argument,
                                               const \
                KParts::ScriptableExtension::Null& n);
--- trunk/KDE/kdelibs/kparts/scriptableextension_p.h #1125498:1125499
@@ -36,8 +36,9 @@
     QVariant rootObject();
     // enclosingObject: not applicable, plugins wouldn't have children
 
-    QVariant callAsFunction(ScriptableExtension* callerPrincipal, quint64 objId,
-                            const ScriptableExtension::ArgList& args);
+    // callAsFunction: we only have function rereferences.
+    QVariant callFunctionReference(ScriptableExtension* callerPrincipal, quint64 \
objId, +                                   const QString& f, const ArgList& args);
 
     // callAsConstructor: unsupported by LC
 
@@ -60,7 +61,6 @@
     // LC uses 0-1 refcounting, we use arbitrary, so we need to call
     // unregister when done.
     QHash<quint64, int>     refCounts;
-    QHash<quint64, QString> objNames;
     LiveConnectExtension* wrapee;
 
     // also registers when needed


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic