[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdelibs/khtml/ecma
From: Maks Orlovich <maksim () kde ! org>
Date: 2010-05-11 20:09:05
Message-ID: 20100511200905.76433AC8B5 () svn ! kde ! org
[Download RAW message or body]
SVN commit 1125604 by orlovich:
Implement binding for some more operations..
Next few steps will be ultra-tricky, though.
M +152 -38 kjs_scriptable.cpp
M +20 -7 kjs_scriptable.h
--- trunk/KDE/kdelibs/khtml/ecma/kjs_scriptable.cpp #1125603:1125604
@@ -45,7 +45,7 @@
static bool isFuncRef(const QVariant& v)
{
- return v.canConvert<ScriptableExtension::Exception>();
+ return v.canConvert<ScriptableExtension::FunctionRef>();
}
static bool isForeignObject(const QVariant& v)
@@ -177,20 +177,65 @@
JSValue* WrapScriptableObject::callAsFunction(ExecState *exec, JSObject *thisObj, \
const List &args) {
- if (type == Object) {
- // if ()
- // callAsFunction
+ QVariant res;
+
+ if (ScriptableExtension* base = objExtension.data()) {
+ ScriptableExtension::ArgList sargs = exportArgs(args);
+ if (type == Object)
+ res = base->callAsFunction(principal(exec), objId, sargs);
+ else
+ res = base->callFunctionReference(principal(exec), objId, field, sargs);
+ }
+
+ // Problem. Throw an exception.
+ if (!res.isValid() || isException(res))
+ return throwError(exec, GeneralError, "Call to plugin function failed");
+ else
+ return KHTMLScriptable::importValue(exec, res);
+}
+
+JSObject* WrapScriptableObject::construct(ExecState* exec, const List& args)
+{
+ QVariant res;
+
+ bool ok;
+ ScriptableExtension::Object actualObj = resolveAnyReferences(exec, &ok);
+ if (ok) {
+ res = actualObj.owner->callAsConstructor(principal(exec), actualObj.objId,
+ exportArgs(args));
+ }
+
+ if (!res.isValid() || isException(res)) {
+ return throwError(exec, GeneralError, "Call to plugin ctor failed");
} else {
- // callFunctionRefence.
+ JSValue* v = KHTMLScriptable::importValue(exec, res);
+ return v->toObject(exec);
}
}
+void WrapScriptableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& \
a) +{
+ JSObject::getOwnPropertyNames(exec, a);
+
+ bool ok;
+ ScriptableExtension::Object actualObj = resolveAnyReferences(exec, &ok);
+ if (ok) {
+ QStringList out;
+ if (actualObj.owner->enumerateProperties(principal(exec), actualObj.objId, \
&out)) { + foreach (const QString& s, out)
+ a.add(Identifier(s));
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// conversion stuff
+
/**
SECURITY: For the conversion helpers, it is assumed that 'exec' corresponds
to the appropriate principal.
*/
-
JSObject* KHTMLScriptable::importObject(ExecState* exec, const QVariant& v)
{
ScriptableExtension::Object obj = v.value<ScriptableExtension::Object>();
@@ -220,7 +265,7 @@
ScriptableExtension::FunctionRef fr = \
v.value<ScriptableExtension::FunctionRef>();
if (JSObject* base = tryGetNativeObject(fr.base)) {
- return base->get(exec, fr.field);
+ return base->get(exec, Identifier(fr.field));
} else {
if (WrapScriptableObject* old = importedFunctions()->value(fr)) {
return old;
@@ -250,24 +295,52 @@
return jsString(v.toString());
if (v.canConvert<double>())
return jsNumber(v.toDouble());
- kWarning() << "conversion from " << v << "failed";
+ kWarning(6031) << "conversion from " << v << "failed";
return jsNull();
}
-QVariant exportObject(JSObject* o)
+List KHTMLScriptable::importArgs(ExecState* exec, const ArgList& args)
{
+ List out;
+ for (int i = 0; i < args.size(); ++i)
+ out.append(importValue(exec, args[i]));
+ return out;
+}
+
+ScriptableExtension::Object KHTMLScriptable::exportNativeObject(JSObject* o)
+{
+ assert (!o->inherits(&WrapScriptableObject::info));
+ // We're exporting our own. Add to export table if needed.
+ // Use the pointer as an ID.
+ if (!exportedObjects()->contains(o))
+ exportedObjects()->insert(o, 0);
+ return ScriptableExtension::Object(this, reinterpret_cast<quint64>(o);
+}
+
+QVariant KHTMLScriptable::exportObject(JSObject* o)
+{
// XSS checks are done at get time, so if we have a value here, we can
// export it.
-
if (o->inherits(&WrapScriptableObject::info)) {
- // Re-exporting external one
+ // Re-exporting external one. That's easy.
+ WrapScriptableObject* wo = static_cast<WrapScriptableObject*>(o);
+ if (ScriptableExtension* owner = wo->objExtension.data()) {
+ return ScriptableExtension::Object(owner, wo->objId);
} else {
- // Add to export table if needed. Use the pointer
- // as an ID.
- //TODO
+ kWarning(6031) << "export of an object of a destroyed extension. \
Returning null"; + return scriptableNull();
}
+ } else {
+ return exportNativeObject(o);
}
+}
+QVariant KHTMLScriptable::exportFuncRef(JSObject* base, const QString& field)
+{
+ ScriptableExtension::Object base = exportNativeObject(base);
+ return ScriptableExtension::FunctionRef(base, field);
+}
+
QVariant KHTMLScriptable::exportValue(JSValue* v)
{
switch (v->type()) {
@@ -287,25 +360,42 @@
}
}
-#if 0
-exportValue ones.
+//-----------------------------------------------------------------------------
+// letting outsiders use us.
+KHTMLScriptable::KHTMLScriptable(KHTMLPart* part):
+ ScriptableExtension(part), m_part(part)
+{
+}
+KJS::Interpreter* KHTMLScriptable::interpreter()
+{
+{
+ KJSProxy* proxy = m_part->jScript();
+ if (!proxy)
+ return 0;
+ return proxy->interpreter();
+}
+QVariant KHTMLScriptable::rootObject()
+{
+ if (KJS::Interpreter* i = interpreter()) {
+ return exportObject(i->globalObject());
+ }
-get, etc --- check for part for extension, do XSS check on that?
-#endif
+ return scriptableNull();
+}
-KHTMLScriptable::KHTMLScriptable(KHTMLPart* part):
- ScriptableExtension(part), m_part(part)
+QVariant KHTMLScriptable::encloserForKid(KParts::ScriptableExtension* kid)
{
-}
+ ReadOnlyPart* childPart = qobject_cast<ReadOnlyPart*>(kid->parentObject());
+ KJS::Interpreter* i = interpreter();
+ if (!childPart || !i)
+ return scriptableNull();
-QVariant KHTMLScriptable::enclosingObject(KParts::ReadOnlyPart* childPart)
-{
khtml::ChildFrame* f = m_part->frame(childPart);
if (!f) {
@@ -313,16 +403,45 @@
return scriptableNull();
}
- // ### Note: this should never actually get an iframe once iframes are fixed
- // TODO
+ // ### should this deal with fake window objects for iframes?
+ // ### this should never actually get an iframe once iframes are fixed
+ if (!f->m_partContainerElement.isNull()) {
+ return exportObject(getDOMNode(i->globalExec(), f->m_partContainerElement));
}
+ kWarning(6031) << "could not find the part container";
+ return scriptableNull();
+}
+
+QVariant KHTMLScriptable::handleReturn(ExecState* exec, JSValue* v)
+{
+ if (exec->hadException()) {
+ JSValue* e = exec->exception();
+ exec->classException();
+
+ QString msg = QLatin1String("KJS exception");
+
+ if (JSObject* eo = e->getObject()) {
+ JSValue* msgVal = eo->get(exec, exec->propertyNames().message);
+ if (!msgVal->isUndefined())
+ msg = msgVal->toString(exec);
+
+ // in case the get failed too.
+ exec->classException();
+ }
+
+ return ScriptableExtension::Exception(msg);
+ }
+
+ return exportValue(v);
+}
+
QVariant KHTMLScriptable::callAsFunction(ScriptableExtension* caller,
quint64 objId, const ArgList& \
args) {
- KHTMLPart* ctx = partForPrincipal(caller);
- KJSProxy* kjs = ctx ? ctx->jScript() : 0;
- if (!kjs) {
+ ExecState* exec = execStateForPrincipal(caller);
+
+ if (!exec) {
kWarning(6031) << "Trying to script the unscriptable";
return exception("No scripting context or frame");
}
@@ -333,9 +452,13 @@
return exception("Not a function");
}
- //fn->callAsFunction(
+ JSValue* res = fn->callAsFunction(exec, \
exec->dynamicInterpreter()->globalObject(), + \
importArgs(exec, args); +
+ return handleReturn(exec, res);
}
+
KHTMLPart* KHTMLScriptable::partForPrincipal(ScriptableExtension* caller)
{
// We implement our security checks by delegating to the KHTMLPart corresponding
@@ -349,15 +472,6 @@
}
}
-
-List KHTMLScriptable::decodeArgs(const ArgList& args)
-{
- List out;
- for (int i = 0; i < args.size(); ++i)
- out.append(importValue(args[i]));
- return out;
-}
-
// ::get() {
//
// if result is a function... return function reference instead..
--- trunk/KDE/kdelibs/khtml/ecma/kjs_scriptable.h #1125603:1125604
@@ -35,13 +35,14 @@
class KHTMLScriptable: public ScriptableExtension
{
+ Q_OBJECT
public:
KHTMLScriptable(KHTMLPart* part);
// ScriptableExtension API
virtual QVariant rootObject();
- virtual QVariant enclosingObject(KParts::ReadOnlyPart* childPart);
+ virtual QVariant encloserForKid(KParts::ScriptableExtension* kid);
virtual QVariant callAsFunction(ScriptableExtension* callerPrincipal, quint64 \
objId, const ArgList& args);
virtual QVariant callFunctionReference(ScriptableExtension* callerPrincipal, \
quint64 objId,
const QString& f, const ArgList& args);
@@ -66,33 +67,45 @@
static QHash<Object, WrapScriptableObject*>* importedObjects();
static QHash<FunctionRef, WrapScriptableObject*>* importedFunctions();
+ // For exported objects, we keep refcounts, and mark them
+ static QHash<JSObject*, int>* exportedObjects();
+
static JSValue* importValue(ExecState* exec, const QVariant& v);
static JSValue* importFunctionRef(ExecState* exec, const QVariant& v);
static JSObject* importObject(ExecState* exec, const QVariant& v);
+ static List importArgs(ExecState* exec, const ArgList& args);
static QVariant exportValue (JSValue* v);
- static QVariant exportObject(JSValue* v);
+ static QVariant exportObject(JSObject* o);
+ static QVariant exportFuncRef(JSObject* base, const QString& field);
private:
- // May return 0. Used for security checks!
+ // input should not be a WrapScriptableObject.
+ static ScriptableExtension::Object exportNativeObject(JSObject* o);
+
+ // Checks exception state before handling conversion
+ QVariant handleReturn(ExecState* exec, JSValue* v);
+
+ // Both methods ay return 0. Used for security checks!
KHTMLPart* partForPrincipal(ScriptableExtension* callerPrincipal);
+ ExecState* execStateForPrincipal(ScriptableExtension* callerPrincipal);
// May return null.
JSObject* objectForId(quint64 objId);
- List decodeArgs(const ArgList& args);
-
QVariant exception(const char* msg);
QVariant scriptableNull();
+ KJS::Interpreter* interpreter();
+ KHTMLPart* m_part;
+
// If the given object is owned by a KHTMLScriptable, return the
// JS object for it. If not, return 0.
static JSObject* tryGetNativeObject(const Object& sObj);
+ static QHash<JSValue*, int> s_exportedObjects;
static QHash<Object, WrapScriptableObject*>* s_importedObjects;
static QHash<FunctionRef, WrapScriptableObject*>* s_importedFunctions;
- KHTMLPart* m_part;
-
};
// This represents an object we imported from a foreign ScriptableExtension
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic