JavaScriptCore:
authorrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 May 2004 01:29:50 +0000 (01:29 +0000)
committerrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 May 2004 01:29:50 +0000 (01:29 +0000)
Implemented new API for WebScriptObject.

Fixed <rdar://problem/3657145>: (objc to javascript method calls do not cause updates.)
Fixed <rdar://problem/3654887>: (Update to JSC to refer to new JSObject LiveConnect object)  (w/ help from Vicki)

        Reviewed by Hyatt.

        * JavaScriptCore.pbproj/project.pbxproj:
        * bindings/c/c_instance.cpp:
        (CInstance::invokeMethod):
        * bindings/jni/jni_instance.cpp:
        (JavaInstance::invokeMethod):
        * bindings/jni/jni_jsobject.cpp:
        (JSObject::convertValueToJObject):
        * bindings/jni/jni_utility.cpp:
        (KJS::Bindings::getJNIField):
        * bindings/objc/WebScriptObject.mm:
        (_didExecute):
        (-[WebScriptObject _initWithObjectImp:KJS::root:Bindings::]):
        (-[WebScriptObject KJS::]):
        (-[WebScriptObject dealloc]):
        (+[WebScriptObject throwException:]):
        (listFromNSArray):
        (-[WebScriptObject callWebScriptMethod:withArguments:]):
        (-[WebScriptObject evaluateWebScript:]):
        (-[WebScriptObject setValue:forKey:]):
        (-[WebScriptObject valueForKey:]):
        (-[WebScriptObject stringRepresentation]):
        (+[WebScriptObject _convertValueToObjcValue:KJS::root:Bindings::]):
        (+[WebUndefined undefined]):
        (-[WebUndefined initWithCoder:]):
        (-[WebUndefined encodeWithCoder:]):
        (-[WebUndefined copyWithZone:]):
        (-[WebUndefined retain]):
        (-[WebUndefined release]):
        (-[WebUndefined retainCount]):
        (-[WebUndefined autorelease]):
        (-[WebUndefined dealloc]):
        (-[WebUndefined copy]):
        (-[WebUndefined replacementObjectForPortCoder:]):
        * bindings/objc/WebScriptObjectPrivate.h: Added.
        * bindings/objc/objc_class.mm:
        (ObjcClass::methodsNamed):
        (ObjcClass::fieldNamed):
        * bindings/objc/objc_instance.mm:
        (ObjcInstance::invokeMethod):
        * bindings/objc/objc_jsobject.h:
        * bindings/objc/objc_jsobject.mm:
        * bindings/objc/objc_runtime.mm:
        (ObjcField::valueFromInstance):
        * bindings/objc/objc_utility.mm:
        (KJS::Bindings::JSMethodNameToObjCMethodName):
        (KJS::Bindings::convertValueToObjcValue):
        (KJS::Bindings::convertObjcValueToValue):
        * bindings/runtime.cpp:
        (Instance::setDidExecuteFunction):
        (Instance::didExecuteFunction):
        (Instance::setValueOfField):
        * bindings/runtime.h:
        * bindings/testbindings.mm:
        (+[MyFirstInterface webScriptNameForSelector:]):
        (-[MyFirstInterface callJSObject::]):

WebCore:
Implemented new API for WebScriptObject.
Fixed <rdar://problem/3657145>: (objc to javascript method calls do not cause updates.)

        Reviewed by Hyatt.

        * kwq/WebCoreBridge.mm:
        (updateRenderingForBindings):
        (-[WebCoreBridge init]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@6620 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
JavaScriptCore/bindings/c/c_instance.cpp
JavaScriptCore/bindings/jni/jni_instance.cpp
JavaScriptCore/bindings/jni/jni_jsobject.cpp
JavaScriptCore/bindings/jni/jni_utility.cpp
JavaScriptCore/bindings/objc/WebScriptObject.mm
JavaScriptCore/bindings/objc/WebScriptObjectPrivate.h [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_class.mm
JavaScriptCore/bindings/objc/objc_instance.mm
JavaScriptCore/bindings/objc/objc_jsobject.h
JavaScriptCore/bindings/objc/objc_jsobject.mm
JavaScriptCore/bindings/objc/objc_runtime.mm
JavaScriptCore/bindings/objc/objc_utility.mm
JavaScriptCore/bindings/runtime.cpp
JavaScriptCore/bindings/runtime.h
JavaScriptCore/bindings/testbindings.mm
WebCore/ChangeLog-2005-08-23
WebCore/kwq/WebCoreBridge.mm

index bd813dc86d1aa7c3d065a4a20875746e4921e7ed..0529e5771c8061c7672618e59e1f02eddfbe9cf2 100644 (file)
@@ -1,3 +1,68 @@
+2004-05-17  Richard Williamson   <rjw@apple.com>
+
+       Implemented new API for WebScriptObject.
+
+       Fixed <rdar://problem/3657145>: (objc to javascript method calls do not cause updates.)
+       Fixed <rdar://problem/3654887>: (Update to JSC to refer to new JSObject LiveConnect object)  (w/ help from Vicki)
+
+        Reviewed by Hyatt.
+
+        * JavaScriptCore.pbproj/project.pbxproj:
+        * bindings/c/c_instance.cpp:
+        (CInstance::invokeMethod):
+        * bindings/jni/jni_instance.cpp:
+        (JavaInstance::invokeMethod):
+        * bindings/jni/jni_jsobject.cpp:
+        (JSObject::convertValueToJObject):
+        * bindings/jni/jni_utility.cpp:
+        (KJS::Bindings::getJNIField):
+        * bindings/objc/WebScriptObject.mm:
+        (_didExecute):
+        (-[WebScriptObject _initWithObjectImp:KJS::root:Bindings::]):
+        (-[WebScriptObject KJS::]):
+        (-[WebScriptObject dealloc]):
+        (+[WebScriptObject throwException:]):
+        (listFromNSArray):
+        (-[WebScriptObject callWebScriptMethod:withArguments:]):
+        (-[WebScriptObject evaluateWebScript:]):
+        (-[WebScriptObject setValue:forKey:]):
+        (-[WebScriptObject valueForKey:]):
+        (-[WebScriptObject stringRepresentation]):
+        (+[WebScriptObject _convertValueToObjcValue:KJS::root:Bindings::]):
+        (+[WebUndefined undefined]):
+        (-[WebUndefined initWithCoder:]):
+        (-[WebUndefined encodeWithCoder:]):
+        (-[WebUndefined copyWithZone:]):
+        (-[WebUndefined retain]):
+        (-[WebUndefined release]):
+        (-[WebUndefined retainCount]):
+        (-[WebUndefined autorelease]):
+        (-[WebUndefined dealloc]):
+        (-[WebUndefined copy]):
+        (-[WebUndefined replacementObjectForPortCoder:]):
+        * bindings/objc/WebScriptObjectPrivate.h: Added.
+        * bindings/objc/objc_class.mm:
+        (ObjcClass::methodsNamed):
+        (ObjcClass::fieldNamed):
+        * bindings/objc/objc_instance.mm:
+        (ObjcInstance::invokeMethod):
+        * bindings/objc/objc_jsobject.h:
+        * bindings/objc/objc_jsobject.mm:
+        * bindings/objc/objc_runtime.mm:
+        (ObjcField::valueFromInstance):
+        * bindings/objc/objc_utility.mm:
+        (KJS::Bindings::JSMethodNameToObjCMethodName):
+        (KJS::Bindings::convertValueToObjcValue):
+        (KJS::Bindings::convertObjcValueToValue):
+        * bindings/runtime.cpp:
+        (Instance::setDidExecuteFunction):
+        (Instance::didExecuteFunction):
+        (Instance::setValueOfField):
+        * bindings/runtime.h:
+        * bindings/testbindings.mm:
+        (+[MyFirstInterface webScriptNameForSelector:]):
+        (-[MyFirstInterface callJSObject::]):
+
 2004-05-14  Vicki Murley  <vicki@apple.com>
 
         Reviewed by mjs.
index 0ea08867305a89ecc6293f61acfb2ae8dc4f2a50..518987346441faa2598bd3a08d8ca1f0b357e0d7 100644 (file)
                                65C02FBC0637462A003E7EE6,
                                650B68DB0639033F009D42DE,
                                51863F70065420E800E9E8DD,
+                               700DA118065984CE00747C0B,
                        );
                        isa = PBXHeadersBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                };
                51856D950562EE9C008B9D83 = {
                        children = (
+                               700DA117065984CE00747C0B,
                                51863F6F065420E800E9E8DD,
                                51863FC406542D3100E9E8DD,
                                5199B265061BB1300070C006,
 //702
 //703
 //704
+               700DA117065984CE00747C0B = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = WebScriptObjectPrivate.h;
+                       path = bindings/objc/WebScriptObjectPrivate.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               700DA118065984CE00747C0B = {
+                       fileRef = 700DA117065984CE00747C0B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
                704FD35305697E6D003DBED9 = {
                        fileEncoding = 30;
                        isa = PBXFileReference;
index ba42bfb4655b6cd833961eff6f64df54a1daef6a..c7ae7508ac26921d94c15e85dac8b3c2e8ae9905 100644 (file)
@@ -98,8 +98,9 @@ Value CInstance::invokeMethod (KJS::ExecState *exec, const MethodList &methodLis
     method = static_cast<CMethod*>(methodList.methodAt(0));
 
     NPIdentifier ident = NPN_GetIdentifier (method->name());
-    if (!_object->_class->hasMethod (_object->_class, ident))
+    if (!_object->_class->hasMethod (_object->_class, ident)) {
         return Undefined();
+    }
 
     unsigned i, count = args.size();
     NPVariant *cArgs;
index 0cce229d7e1634e8c8994269d94943b86e0896cc..a544226893524b4427f3e651ee8b64151e58823f 100644 (file)
@@ -227,7 +227,7 @@ Value JavaInstance::invokeMethod (KJS::ExecState *exec, const MethodList &method
     }
         
     free (jArgs);
-    
+
     return resultValue;
 }
 
index b5a32dedb0327372348e5981f073fefe41162f2d..9590a05c20f10c883d92c2b2a3f3382fb8576d4d 100644 (file)
@@ -369,8 +369,17 @@ jobject JSObject::convertValueToJObject (KJS::Value value) const
             nativeHandle = UndefinedHandle;
         }
         
-        // Now create the Java JSObject.
-        jclass JSObjectClass = env->FindClass ("apple/applet/JSObject");
+        // Now create the Java JSObject.  Look for the JSObject in it's new (Tiger)
+        // location and in the original Java 1.4.2 location.
+        jclass JSObjectClass;
+        
+        JSObjectClass = env->FindClass ("sun/plugin/javascript/webkit/JSObject");
+        if (!JSObjectClass) {
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+            JSObjectClass = env->FindClass ("apple/applet/JSObject");
+        }
+            
         jmethodID constructorID = env->GetMethodID (JSObjectClass, "<init>", "(J)V");
         if (constructorID != NULL) {
             result = env->NewObject (JSObjectClass, constructorID, nativeHandle);
index dc41e6562a1f2987305dc76f81c0b18ecd383861..5b7f0c955fd24d0270dbe4d32014562011be76a8 100644 (file)
@@ -614,7 +614,7 @@ jvalue KJS::Bindings::getJNIField( jobject obj, JNIType type, const char *name,
                 fprintf(stderr, "%s: Could not find field: %s\n", __PRETTY_FUNCTION__, name);
                 env->ExceptionDescribe();
                 env->ExceptionClear();
-                               fprintf (stderr, "\n");
+                fprintf (stderr, "\n");
             }
 
             env->DeleteLocalRef(cls);
index b3ce9a8126ad458ed24479a11c4df986008fc00a..fafe638d5872bcd063842ce46fbd30a89bfb0df2 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
-#import <JavaScriptCore/WebScriptObject.h>
+#import <JavaScriptCore/WebScriptObjectPrivate.h>
+
+#include <JavaScriptCore/internal.h>
+#include <JavaScriptCore/list.h>
+#include <JavaScriptCore/value.h>
+
+#include <objc_jsobject.h>
+#include <objc_instance.h>
+#include <objc_utility.h>
+
+#include <runtime_object.h>
+#include <runtime_root.h>
+
+using namespace KJS;
+using namespace KJS::Bindings;
+
+@interface WebScriptObjectPrivate : NSObject
+{
+    KJS::ObjectImp *imp;
+    const Bindings::RootObject *root;
+}
+@end
+
+@implementation WebScriptObjectPrivate
+@end
 
 @implementation WebScriptObject
 
+static void _didExecute(WebScriptObject *obj)
+{
+    ExecState *exec = obj->_private->root->interpreter()->globalExec();
+    KJSDidExecuteFunctionPtr func = Instance::didExecuteFunction();
+    if (func)
+        func (exec, static_cast<KJS::ObjectImp*>(obj->_private->root->rootObjectImp()));
+}
+
+- _initWithObjectImp:(KJS::ObjectImp *)imp root:(const Bindings::RootObject *)root
+{
+    assert (imp != 0);
+    //assert (root != 0);
+
+    self = [super init];
+
+    _private = [[WebScriptObjectPrivate alloc] init];
+    _private->imp = imp;
+    _private->root = root;    
+
+    addNativeReference (root, imp);
+    
+    return self;
+}
+
+- (KJS::ObjectImp *)_imp
+{
+    return _private->imp;
+}
+
+- (void)dealloc
+{
+    if (_private)
+        removeNativeReference (_private->imp);
+    [_private release];
+    [super dealloc];
+}
+
 + (BOOL)throwException:(NSString *)exceptionMessage
 {
-    NSLog (@"%s:%d  not yet implemented");
+    NSLog (@"%s:%d:  not yet implemented", __PRETTY_FUNCTION__, __LINE__);
     return NO;
 }
 
+static KJS::List listFromNSArray(ExecState *exec, NSArray *array)
+{
+    long i, numObjects = array ? [array count] : 0;
+    KJS::List aList;
+    
+    for (i = 0; i < numObjects; i++) {
+        id anObject = [array objectAtIndex:i];
+        aList.append (convertObjcValueToValue(exec, &anObject, ObjcObjectType));
+    }
+    return aList;
+}
+
 - (id)callWebScriptMethod:(NSString *)name withArguments:(NSArray *)args
 {
-    NSLog (@"%s:%d  not yet implemented");
-    return nil;
+    // Lookup the function object.
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    
+    Value v = convertObjcValueToValue(exec, &name, ObjcObjectType);
+    Identifier identifier(v.toString(exec));
+    Value func = _private->imp->get (exec, identifier);
+    Interpreter::unlock();
+    if (func.isNull() || func.type() == UndefinedType) {
+        // Maybe throw an exception here?
+        return 0;
+    }
+
+    // Call the function object.    
+    ObjectImp *funcImp = static_cast<ObjectImp*>(func.imp());
+    Object thisObj = Object(const_cast<ObjectImp*>(_private->imp));
+    List argList = listFromNSArray(exec, args);
+    Interpreter::lock();
+    Value result = funcImp->call (exec, thisObj, argList);
+    Interpreter::unlock();
+
+    // Convert and return the result of the function call.
+    id resultObj = [WebScriptObject _convertValueToObjcValue:result root:_private->root];
+
+    _didExecute(self);
+        
+    return resultObj;
 }
 
 - (id)evaluateWebScript:(NSString *)script
 {
-    NSLog (@"%s:%d  not yet implemented");
-    return nil;
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Object thisObj = Object(const_cast<ObjectImp*>(_private->imp));
+    Interpreter::lock();
+    Value v = convertObjcValueToValue(exec, &script, ObjcObjectType);
+    KJS::Value result = _private->root->interpreter()->evaluate(v.toString(exec)).value();
+    Interpreter::unlock();
+    
+    id resultObj = [WebScriptObject _convertValueToObjcValue:result root:_private->root];
+
+    _didExecute(self);
+    
+    return resultObj;
+}
+
+- (void)setValue:(id)value forKey:(NSString *)key
+{
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    Value v = convertObjcValueToValue(exec, &key, ObjcObjectType);
+   _private->imp->put (exec, Identifier (v.toString(exec)), (convertObjcValueToValue(exec, &value, ObjcObjectType)));
+    Interpreter::unlock();
+
+    _didExecute(self);
+}
+
+- (id)valueForKey:(NSString *)key
+{
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    Value v = convertObjcValueToValue(exec, &key, ObjcObjectType);
+    Value result = _private->imp->get (exec, Identifier (v.toString(exec)));
+    Interpreter::unlock();
+    
+    id resultObj = [WebScriptObject _convertValueToObjcValue:result root:_private->root];
+
+    _didExecute(self);
+    
+    return resultObj;
 }
 
-- (void)removeWebScriptKey:(NSString *)name;
+- (void)removeWebScriptKey:(NSString *)key;
 {
-    NSLog (@"%s:%d  not yet implemented");
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    Value v = convertObjcValueToValue(exec, &key, ObjcObjectType);
+    _private->imp->deleteProperty (exec, Identifier (v.toString(exec)));
+    Interpreter::unlock();
+
+    _didExecute(self);
 }
 
 - (NSString *)stringRepresentation
 {
-    NSLog (@"%s:%d  not yet implemented");
-    return nil;
+    Interpreter::lock();
+    Object thisObj = Object(const_cast<ObjectImp*>(_private->imp));
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    
+    id result = convertValueToObjcValue(exec, thisObj, ObjcObjectType).objectValue;
+
+    Interpreter::unlock();
+    
+    id resultObj = [result description];
+
+    _didExecute(self);
+
+    return resultObj;
 }
 
 - (id)webScriptValueAtIndex:(unsigned int)index;
 {
-    NSLog (@"%s:%d  not yet implemented");
-    return nil;
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    Value result = _private->imp->get (exec, (unsigned)index);
+    Interpreter::unlock();
+
+    id resultObj = [WebScriptObject _convertValueToObjcValue:result root:_private->root];
+
+    _didExecute(self);
+
+    return resultObj;
 }
 
 - (void)setWebScriptValueAtIndex:(unsigned int)index value:(id)value;
 {
-    NSLog (@"%s:%d  not yet implemented");
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    _private->imp->put (exec, (unsigned)index, (convertObjcValueToValue(exec, &value, ObjcObjectType)));
+    Interpreter::unlock();
+
+    _didExecute(self);
 }
 
 - (void)setException: (NSString *)description;
 {
-    NSLog (@"%s:%d  not yet implemented");
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Object err = Error::create(exec, GeneralError, [description UTF8String]);
+    exec->setException (err);
 }
 
-@end
-
-
-
-@interface WebScriptObjectPrivate : NSObject
++ (id)_convertValueToObjcValue:(KJS::Value)value root:(const Bindings::RootObject *)root
 {
+    id result = 0;
+   
+    // First see if we have a ObjC instance.
+    if (value.type() == KJS::ObjectType){
+        ObjectImp *objectImp = static_cast<ObjectImp*>(value.imp());
+        if (strcmp(objectImp->classInfo()->className, "RuntimeObject") == 0) {
+            RuntimeObjectImp *imp = static_cast<RuntimeObjectImp *>(value.imp());
+            ObjcInstance *instance = static_cast<ObjcInstance*>(imp->getInternalInstance());
+            if (instance)
+                result = instance->getObject();
+        }
+        // Convert to a WebScriptObject
+        else {
+            result = [[[WebScriptObject alloc] _initWithObjectImp:objectImp root:root] autorelease];
+        }
+    }
+    
+    // Convert JavaScript String value to NSString?
+    else if (value.type() == KJS::StringType) {
+        StringImp *s = static_cast<KJS::StringImp*>(value.imp());
+        UString u = s->value();
+        
+        NSString *string = [NSString stringWithCharacters:(const unichar*)u.data() length:u.size()];
+        result = string;
+    }
+    
+    // Convert JavaScript Number value to NSNumber?
+    else if (value.type() == KJS::NumberType) {
+        Number n = Number::dynamicCast(value);
+        result = [NSNumber numberWithDouble:n.value()];
+    }
+    
+    // Boolean?
+    return result;
 }
-@end
 
-@implementation WebScriptObjectPrivate
 @end
 
 
-
 @implementation WebUndefined
+
+static WebUndefined *sharedUndefined = 0;
+
 + (WebUndefined *)undefined
 {
-    NSLog (@"%s:%d  not yet implemented");
-    return nil;
+    if (!sharedUndefined)
+        sharedUndefined = [[WebUndefined alloc] init];
+    return sharedUndefined;
 }
 
 - (id)initWithCoder:(NSCoder *)coder
 {
-    NSLog (@"%s:%d  not yet implemented");
-    return nil;
+    return [WebUndefined undefined];
 }
 
 - (void)encodeWithCoder:(NSCoder *)encoder
 {
-    NSLog (@"%s:%d  not yet implemented");
 }
 
 - (id)copyWithZone:(NSZone *)zone
 {
-    NSLog (@"%s:%d  not yet implemented");
-    return nil;
+    return [WebUndefined undefined];
+}
+
+- (id)retain {
+    return [WebUndefined undefined];
+}
+
+- (void)release {
+}
+
+- (unsigned)retainCount {
+    return 0xFFFFFFFF;
+}
+
+- (id)autorelease {
+    return [WebUndefined undefined];
+}
+
+- (void)dealloc {
+}
+
+- (id)copy {
+    return [WebUndefined undefined];
+}
+
+- (id)replacementObjectForPortCoder:(NSPortCoder *)encoder {
+    return [WebUndefined undefined];
 }
 
 @end
diff --git a/JavaScriptCore/bindings/objc/WebScriptObjectPrivate.h b/JavaScriptCore/bindings/objc/WebScriptObjectPrivate.h
new file mode 100644 (file)
index 0000000..bf062ac
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+    Copyright (C) 2004 Apple Computer, Inc. All rights reserved.    
+*/
+#ifndef _WEB_SCRIPT_OBJECT_PRIVATE_H_
+#define _WEB_SCRIPT_OBJECT_PRIVATE_H_
+
+#import <WebScriptObject.h>
+
+#include <JavaScriptCore/internal.h>
+#include <JavaScriptCore/list.h>
+#include <JavaScriptCore/object.h>
+#include <JavaScriptCore/runtime_root.h>
+#include <JavaScriptCore/value.h>
+
+@interface WebScriptObject (Private)
++ (id)_convertValueToObjcValue:(KJS::Value)value root:(const KJS::Bindings::RootObject *)root;
+- _initWithObjectImp:(KJS::ObjectImp *)imp root:(const KJS::Bindings::RootObject *)root;
+- (KJS::ObjectImp *)_imp;
+@end
+
+#endif
index 89acf68695e56bcf7bfe5d3fd3ba379477da9127..2a18cda18fa529358cf153259c9c881a86ef16ef 100644 (file)
@@ -25,8 +25,8 @@
 #include <Foundation/Foundation.h>
 
 #include <objc_class.h>
-#include <objc_jsobject.h>
 #include <objc_utility.h>
+#include <WebScriptObject.h>
 
 using namespace KJS::Bindings;
 
@@ -113,8 +113,8 @@ MethodList ObjcClass::methodsNamed(const char *_name) const
                 NSString *mappedName = 0;
             
                 // See if the class wants to exclude the selector from visibility in JavaScript.
-                if ([(id)thisClass respondsToSelector:@selector(excludeSelectorFromJavaScript:)]) {
-                    if ([(id)thisClass excludeSelectorFromJavaScript:objcMethod->method_name]) {
+                if ([(id)thisClass respondsToSelector:@selector(isSelectorExcludedFromWebScript:)]) {
+                    if ([(id)thisClass isSelectorExcludedFromWebScript:objcMethod->method_name]) {
                         continue;
                     }
                 }
@@ -122,8 +122,8 @@ MethodList ObjcClass::methodsNamed(const char *_name) const
                 // See if the class want to provide a different name for the selector in JavaScript.
                 // Note that we do not do any checks to guarantee uniqueness. That's the responsiblity
                 // of the class.
-                if ([(id)thisClass respondsToSelector:@selector(JavaScriptNameForSelector:)]){
-                    mappedName = [(id)thisClass JavaScriptNameForSelector: objcMethod->method_name];
+                if ([(id)thisClass respondsToSelector:@selector(webScriptNameForSelector:)]){
+                    mappedName = [(id)thisClass webScriptNameForSelector: objcMethod->method_name];
                 }
 
                 if ((mappedName && [mappedName isEqual:(NSString *)methodName]) ||
@@ -161,7 +161,24 @@ Field *ObjcClass::fieldNamed(const char *name) const
             int i, numFieldsInClass = fieldsInClass->ivar_count;
             for (i = 0; i < numFieldsInClass; i++) {
                 Ivar objcIVar = &fieldsInClass->ivar_list[i];
-                if (strcmp(objcIVar->ivar_name,name) == 0) {
+                NSString *mappedName = 0;
+
+                // See if the class wants to exclude the selector from visibility in JavaScript.
+                if ([(id)thisClass respondsToSelector:@selector(isKeyExcludedFromWebScript:)]) {
+                    if ([(id)thisClass isKeyExcludedFromWebScript:objcIVar->ivar_name]) {
+                        continue;
+                    }
+                }
+                
+                // See if the class want to provide a different name for the selector in JavaScript.
+                // Note that we do not do any checks to guarantee uniqueness. That's the responsiblity
+                // of the class.
+                if ([(id)thisClass respondsToSelector:@selector(webScriptNameForKey:)]){
+                    mappedName = [(id)thisClass webScriptNameForKey:objcIVar->ivar_name];
+                }
+
+                if ((mappedName && [mappedName isEqual:(NSString *)fieldName]) ||
+                    strcmp(objcIVar->ivar_name,name) == 0) {
                     aField = new ObjcField (objcIVar);
                     CFDictionaryAddValue ((CFMutableDictionaryRef)_fields, fieldName, aField);
                     break;
index 2861b94e218bc2968aea805328163c3c19fc6b0a..adac3063ed0f9d68fdb902481cef2ddd5a319b82 100644 (file)
@@ -195,7 +195,7 @@ NS_HANDLER
     resultValue = Undefined();
     
 NS_ENDHANDLER
-    
+
     return resultValue;
 }
 
index 3e96161c0973b04984e1bbef09e6a6f12739c29c..a7cdc29eaa26910f546b31b47e271e4731906847 100644 (file)
 #ifndef _BINDINGS_OBJC_JSOBJECT_H_
 #define _BINDINGS_OBJC_JSOBJECT_H_
 
-#include <Foundation/Foundation.h>
-
-#include <value.h>
-
-#include <runtime_root.h>
-
-/*
-    ObjC      to    JavaScript
-    char            Number
-    short
-    int
-    long
-    float
-    double
-    NSNumber        Number
-    NSString        String
-    NSArray         Array
-    id              Object wrapper
-    other           exception
-    
-    JavaScript to   ObjC
-    Number          coerced char, short, int, long, float, or double
-    String          NSString
-    Object wrapper         id
-    Object          JavaScriptObject
-    [], other       exception
-*/
-
-// This is intended to be a public API.
-@interface NSObject (JavaScriptMethods) 
-
-+ (NSString *)JavaScriptNameForSelector:(SEL)aSelector;
-+ (BOOL)excludeSelectorFromJavaScript:(SEL)aSelector;
-
-@end
-
-@class JavaScriptObjectPrivate;
-
-// This is intended to be a public API.
-@interface JavaScriptObject : NSObject
-{
-    JavaScriptObjectPrivate *_private;
-}
-
-- (id)call:(NSString *)methodName arguments:(NSArray *)args;
-- (id)evaluate:(NSString *)script;
-- (id)getMember:(NSString *)name;
-- (void)setMember:(NSString *)name value:(id)value;
-- (void)removeMember:(NSString *)name;
-- (NSString *)toString;
-- (id)getSlot:(unsigned int)index;
-- (void)setSlot:(unsigned int)index value:(id)value;
-
-@end
-
-@interface JavaScriptObject (Private)
-+ (id)_convertValueToObjcValue:(KJS::Value)value root:(const KJS::Bindings::RootObject *)root;
-- (KJS::ObjectImp *)imp;
-@end
-
 #endif
\ No newline at end of file
index 2be0b4e1eec17764b53407789aded5e7a8c784ae..7b60abc93d7f2c7db560152a330d8b75b41f3c01 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
-#include <JavaScriptCore/internal.h>
-#include <JavaScriptCore/list.h>
-#include <JavaScriptCore/value.h>
-
-#include <objc_jsobject.h>
-#include <objc_instance.h>
-#include <objc_utility.h>
-
-#include <runtime_object.h>
-#include <runtime_root.h>
-
-using namespace KJS;
-using namespace KJS::Bindings;
-
-
-#ifdef JAVASCRIPT_OBJECT_IN_WEBCORE
-static RootObject *rootForView(void *v)
-{
-    NSView *aView = (NSView *)v;
-    WebCoreBridge *aBridge = [[WebCoreViewFactory sharedFactory] bridgeForView:aView];
-    if (aBridge) {
-        KWQKHTMLPart *part = [aBridge part];
-        RootObject *root = new RootObject(v);    // The root gets deleted by JavaScriptCore.
-        
-        root->setRootObjectImp (static_cast<KJS::ObjectImp *>(KJS::Window::retrieveWindow(part)));
-        root->setInterpreter (KJSProxy::proxy(part)->interpreter());
-        part->addPluginRootObject (root);
-            
-        return root;
-    }
-    return 0;
-}
-
-JavaScriptObject *windowJavaScriptObject(RootObject *root)
-{
-    return [[[JavaScriptObject alloc] initWithObjectImp:root->rootObjectImp() root:root] autorelease];
-}
-
-typedef enum {
-    ObjectiveCLanaguage = 1,
-    CLanaguage
-}
-
-void *NPN_GetJavaScriptObjectForWindow (NPNativeLanguage lang)
-void *NPN_GetJavaScriptObjectForSelf (NPNativeLanguage lang)
-
-windowJavaScriptObject(root));
-
-#endif
-
-@interface JavaScriptObjectPrivate : NSObject
-{
-    KJS::ObjectImp *imp;
-    const Bindings::RootObject *root;
-}
-@end
-
-@implementation JavaScriptObjectPrivate
-@end
-
-@interface JavaScriptObject (ReallyPrivate)
-- initWithObjectImp:(KJS::ObjectImp *)imp root:(const Bindings::RootObject *)root;
-@end
-
-@implementation JavaScriptObject
-
-static KJS::List listFromNSArray(ExecState *exec, NSArray *array)
-{
-    long i, numObjects = array ? [array count] : 0;
-    KJS::List aList;
-    
-    for (i = 0; i < numObjects; i++) {
-        id anObject = [array objectAtIndex:i];
-        aList.append (convertObjcValueToValue(exec, &anObject, ObjcObjectType));
-    }
-    return aList;
-}
-
-- initWithObjectImp:(KJS::ObjectImp *)imp root:(const Bindings::RootObject *)root
-{
-    assert (imp != 0);
-    //assert (root != 0);
-
-    self = [super init];
-
-    _private = [[JavaScriptObjectPrivate alloc] init];
-    _private->imp = imp;
-    _private->root = root;    
-
-    addNativeReference (root, imp);
-    
-    return self;
-}
-
-- (void)dealloc
-{
-    removeNativeReference (_private->imp);
-    [_private release];
-    [super dealloc];
-}
-
-- (KJS::ObjectImp *)imp
-{
-    return _private->imp;
-}
-
-+ (id)_convertValueToObjcValue:(KJS::Value)value root:(const Bindings::RootObject *)root
-{
-    id result = 0;
-   
-    // First see if we have a ObjC instance.
-    if (value.type() == KJS::ObjectType){
-        ObjectImp *objectImp = static_cast<ObjectImp*>(value.imp());
-        if (strcmp(objectImp->classInfo()->className, "RuntimeObject") == 0) {
-            RuntimeObjectImp *imp = static_cast<RuntimeObjectImp *>(value.imp());
-            ObjcInstance *instance = static_cast<ObjcInstance*>(imp->getInternalInstance());
-            if (instance)
-                result = instance->getObject();
-        }
-        // Convert to a JavaScriptObject
-        else {
-            result = [[[JavaScriptObject alloc] initWithObjectImp:objectImp root:root] autorelease];
-        }
-    }
-    
-    // Convert JavaScript String value to NSString?
-    else if (value.type() == KJS::StringType) {
-        StringImp *s = static_cast<KJS::StringImp*>(value.imp());
-        UString u = s->value();
-        
-        NSString *string = [NSString stringWithCharacters:(const unichar*)u.data() length:u.size()];
-        result = string;
-    }
-    
-    // Convert JavaScript Number value to NSNumber?
-    else if (value.type() == KJS::NumberType) {
-        Number n = Number::dynamicCast(value);
-        result = [NSNumber numberWithDouble:n.value()];
-    }
-    
-    // Boolean?
-    return result;
-}
-
-- (id)call:(NSString *)methodName arguments:(NSArray *)args
-{
-    // Lookup the function object.
-    ExecState *exec = _private->root->interpreter()->globalExec();
-    Interpreter::lock();
-    
-    Value v = convertObjcValueToValue(exec, &methodName, ObjcObjectType);
-    Identifier identifier(v.toString(exec));
-    Value func = _private->imp->get (exec, identifier);
-    Interpreter::unlock();
-    if (func.isNull() || func.type() == UndefinedType) {
-        // Maybe throw an exception here?
-        return 0;
-    }
-
-    // Call the function object.
-    ObjectImp *funcImp = static_cast<ObjectImp*>(func.imp());
-    Object thisObj = Object(const_cast<ObjectImp*>(_private->imp));
-    List argList = listFromNSArray(exec, args);
-    Interpreter::lock();
-    Value result = funcImp->call (exec, thisObj, argList);
-    Interpreter::unlock();
-
-    // Convert and return the result of the function call.
-    return [JavaScriptObject _convertValueToObjcValue:result root:_private->root];
-}
-
-- (id)evaluate:(NSString *)script
-{
-    ExecState *exec = _private->root->interpreter()->globalExec();
-    Object thisObj = Object(const_cast<ObjectImp*>(_private->imp));
-    Interpreter::lock();
-    Value v = convertObjcValueToValue(exec, &script, ObjcObjectType);
-    KJS::Value result = _private->root->interpreter()->evaluate(v.toString(exec)).value();
-    Interpreter::unlock();
-    return [JavaScriptObject _convertValueToObjcValue:result root:_private->root];
-}
-
-- (id)getMember:(NSString *)name
-{
-    ExecState *exec = _private->root->interpreter()->globalExec();
-    Interpreter::lock();
-    Value v = convertObjcValueToValue(exec, &name, ObjcObjectType);
-    Value result = _private->imp->get (exec, Identifier (v.toString(exec)));
-    Interpreter::unlock();
-    return [JavaScriptObject _convertValueToObjcValue:result root:_private->root];
-}
-
-- (void)setMember:(NSString *)name value:(id)value
-{
-    ExecState *exec = _private->root->interpreter()->globalExec();
-    Interpreter::lock();
-    Value v = convertObjcValueToValue(exec, &name, ObjcObjectType);
-   _private->imp->put (exec, Identifier (v.toString(exec)), (convertObjcValueToValue(exec, &value, ObjcObjectType)));
-    Interpreter::unlock();
-}
-
-- (void)removeMember:(NSString *)name
-{
-    ExecState *exec = _private->root->interpreter()->globalExec();
-    Interpreter::lock();
-    Value v = convertObjcValueToValue(exec, &name, ObjcObjectType);
-    _private->imp->deleteProperty (exec, Identifier (v.toString(exec)));
-    Interpreter::unlock();
-}
-
-- (NSString *)toString
-{
-    Interpreter::lock();
-    Object thisObj = Object(const_cast<ObjectImp*>(_private->imp));
-    ExecState *exec = _private->root->interpreter()->globalExec();
-    
-    id result = convertValueToObjcValue(exec, thisObj, ObjcObjectType).objectValue;
-
-    Interpreter::unlock();
-    
-    return [result description];
-}
-
-- (id)getSlot:(unsigned int)index
-{
-    ExecState *exec = _private->root->interpreter()->globalExec();
-    Interpreter::lock();
-    Value result = _private->imp->get (exec, (unsigned)index);
-    Interpreter::unlock();
-
-    return [JavaScriptObject _convertValueToObjcValue:result root:_private->root];
-}
-
-- (void)setSlot:(unsigned int)index value:(id)value
-{
-    ExecState *exec = _private->root->interpreter()->globalExec();
-    Interpreter::lock();
-    _private->imp->put (exec, (unsigned)index, (convertObjcValueToValue(exec, &value, ObjcObjectType)));
-    Interpreter::unlock();
-}
-
-@end
index ea558adc1a75c4cf134b4658f8cad0d02ab38444..f4ff21d801716a2eaca3963bfc863b64f13c7905 100644 (file)
@@ -28,7 +28,7 @@
 #include <JavaScriptCore/internal.h>
 
 #include <objc_instance.h>
-#include <objc_jsobject.h>
+#include <WebScriptObjectPrivate.h>
 
 #include <runtime_array.h>
 #include <runtime_object.h>
@@ -93,9 +93,9 @@ Value ObjcField::valueFromInstance(KJS::ExecState *exec, const Instance *instanc
         
         case ObjcObjectType: {
             ObjectStructPtr obj = *(ObjectStructPtr *)(ivarValuePtr);
-            if ([obj isKindOfClass:[JavaScriptObject class]]) {
-                JavaScriptObject *jsobject = (JavaScriptObject *)obj;
-                aValue = Object([jsobject imp]);
+            if ([obj isKindOfClass:[WebScriptObject class]]) {
+                WebScriptObject *jsobject = (WebScriptObject *)obj;
+                aValue = Object([jsobject _imp]);
             }
             else {
                 Instance *anInstance = Instance::createBindingForLanguageInstance (Instance::ObjectiveCLanguage, (void *)obj);
index 2d89cede84080fd179b74a561c840ef40b9d2094..f18acb3a0290335baad7f1ad867fd836db30aa05 100644 (file)
 
 #include <JavascriptCore/internal.h>
 
-#include <runtime_array.h>
-#include <runtime_object.h>
 #include <objc_instance.h>
-#include <objc_jsobject.h>
 #include <objc_utility.h>
 
+#include <runtime_array.h>
+#include <runtime_object.h>
+#include <runtime_root.h>
+
+#include <WebScriptObjectPrivate.h>
+
 
 using namespace KJS;
 using namespace KJS::Bindings;
 
 /*
-    Convert ObjectiveC method names to palatable JavaScript names.  ":" in
-    ObjectiveC names are converted to "_".  "_" are escaped.
-    
-    For example:
-    
-    logLevel:message:
-    
-    would turn into
-    
-    logLevel_message_
-    
-    This name mapping can be overriden by the ObjectiveC class by implementing
-
-    + (NSString *)JavaScriptNameForSelector:(SEL)aSelector;
-    
-    See objc_jsobject.h for more details.
+    The default name concatenates the components of the
+    ObjectiveC selector name and replaces ':' with '_'.  '_' characters
+    are escaped with an additional '$', i.e. '_' becomes "$_".  '$' are
+    also escaped, i.e.
+        ObjectiveC name         Default script name
+        moveTo::                move__
+        moveTo_                 moveTo$_
+        moveTo$_                moveTo$$$_
+    @result Returns the name to be used to represent the specificed selector in the
 */
 void KJS::Bindings::JSMethodNameToObjCMethodName(const char *name, char *buffer, unsigned int len)
 {
@@ -65,15 +61,15 @@ void KJS::Bindings::JSMethodNameToObjCMethodName(const char *name, char *buffer,
 
     bp = buffer;
     while (*np) {
+        if (*np == '$') {
+            np++;
+            *bp++ = *np++;
+            continue;
+        }
+        
         if (*np == '_') {
-            if (*(np+1) == '_') {
-                *bp++ = '_';
-                np += 2;
-            }
-            else {
-                *bp++ = ':';
-                np++;
-            }
+            np++;
+            *bp++ = ':';
         }
         else
             *bp++ = *np++;
@@ -87,7 +83,7 @@ void KJS::Bindings::JSMethodNameToObjCMethodName(const char *name, char *buffer,
     Number          coerced to char, short, int, long, float, double, or NSNumber, as appropriate
     String          NSString
     wrapper         id
-    Object          JavaScriptObject
+    Object          WebScriptObject
     [], other       exception
 
 */
@@ -105,7 +101,7 @@ ObjcValue KJS::Bindings::convertValueToObjcValue (KJS::ExecState *exec, const KJ
                 newRoot->setInterpreter (exec->interpreter());
                 root = newRoot;
             }
-            result.objectValue = [JavaScriptObject _convertValueToObjcValue:value root:root];
+            result.objectValue = [WebScriptObject _convertValueToObjcValue:value root:root];
         }
         break;
         
@@ -204,9 +200,9 @@ Value KJS::Bindings::convertObjcValueToValue (KJS::ExecState *exec, void *buffer
                 else if ([*obj isKindOfClass:[NSArray class]]) {
                     aValue = Object(new RuntimeArrayImp(new ObjcArray (*obj)));
                 }
-                else if ([*obj isKindOfClass:[JavaScriptObject class]]) {
-                    JavaScriptObject *jsobject = (JavaScriptObject *)*obj;
-                    aValue = Object([jsobject imp]);
+                else if ([*obj isKindOfClass:[WebScriptObject class]]) {
+                    WebScriptObject *jsobject = (WebScriptObject *)*obj;
+                    aValue = Object([jsobject _imp]);
                 }
                 else {
                     aValue = Object(new RuntimeObjectImp(new ObjcInstance (*obj)));
index 936d84ed9d27ef2617b242d126ff1c0d2cec9530..b703c78bcdecf09e3f96ac05fa8c864c5e83f547 100644 (file)
@@ -84,12 +84,17 @@ MethodList &MethodList::operator=(const MethodList &other)
 }
 
 
+static KJSDidExecuteFunctionPtr _DidExecuteFunction;
+
+void Instance::setDidExecuteFunction (KJSDidExecuteFunctionPtr func) { _DidExecuteFunction = func; }
+KJSDidExecuteFunctionPtr Instance::didExecuteFunction () { return _DidExecuteFunction; }
+
 Value Instance::getValueOfField (KJS::ExecState *exec, const Field *aField) const {  
     return aField->valueFromInstance (exec, this);
 }
 
 void Instance::setValueOfField (KJS::ExecState *exec, const Field *aField, const Value &aValue) const {  
-    return aField->setValueToInstance (exec, this, aValue);
+    aField->setValueToInstance (exec, this, aValue);
 }
 
 Instance *Instance::createBindingForLanguageInstance (BindingLanguage language, void *instance)
index 06a6e5dea18a24a0a6a97f0b2f3383fc09386f23..7e34c6e4b3fb73981de2b312aced7cfb9c9c7f4e 100644 (file)
@@ -120,6 +120,8 @@ public:
     virtual ~Class() {};
 };
 
+typedef void (*KJSDidExecuteFunctionPtr)(KJS::ExecState *exec, KJS::ObjectImp *rootObject);
+
 class Instance
 {
 public:
@@ -129,6 +131,9 @@ public:
         CLanguage
     } BindingLanguage;
 
+    static void setDidExecuteFunction (KJSDidExecuteFunctionPtr func);
+    static KJSDidExecuteFunctionPtr didExecuteFunction ();
+    
     static Instance *createBindingForLanguageInstance (BindingLanguage language, void *instance);
 
     static Object createRuntimeObject (BindingLanguage language, void *myInterface);
index 7a0c145942299dacc7bbe53b49d8775dfc6edcc9..d3b090cf285bc655da43925767d3a45929c05a25 100644 (file)
@@ -21,6 +21,8 @@
  */
 #include <Foundation/Foundation.h>
 
+#import <WebKit/WebScriptObject.h>
+
 #include <stdio.h>
 #include <string.h>
 
 #include "runtime.h"
 #include "runtime_object.h"
 
-@interface JavaScriptObject : NSObject
-
-- (id)call:(NSString *)methodName arguments:(NSArray *)args;
-- (id)evaluate:(NSString *)script;
-- (id)getMember:(NSString *)name;
-- (void)setMember:(NSString *)name value:(id)value;
-- (void)removeMember:(NSString *)name;
-- (NSString *)toString;
-- (id)getSlot:(unsigned int)index;
-- (void)setSlot:(unsigned int)index value:(id)value;
-
-@end
-
 #define LOG(formatAndArgs...) { \
     fprintf (stderr, "%s:  ", __PRETTY_FUNCTION__); \
     fprintf(stderr, formatAndArgs); \
     [super dealloc];
 }
 
-+ (NSString *)JavaScriptNameForSelector:(SEL)aSelector
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
 {
     if (aSelector == @selector(logMessage:))
         return @"logMessage";
 
 - (void)callJSObject:(int)arg1 :(int)arg2
 {
-    id foo = [jsobject call:@"call" arguments:[NSArray arrayWithObjects:jsobject, [NSNumber numberWithInt:arg1], [NSNumber numberWithInt:arg2], nil]];
+    id foo = [jsobject callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:jsobject, [NSNumber numberWithInt:arg1], [NSNumber numberWithInt:arg2], nil]];
     printf ("foo = %s\n", [[foo description] lossyCString] );
 }
 
index 4be732ba3f0da541a184fe4525155ead4a61bc22..60c5dfa7d454779a775e7490a549c76b945a2471 100644 (file)
@@ -1,3 +1,14 @@
+2004-05-17  Richard Williamson   <rjw@apple.com>
+
+       Implemented new API for WebScriptObject.
+       Fixed <rdar://problem/3657145>: (objc to javascript method calls do not cause updates.)
+
+        Reviewed by Hyatt.
+
+        * kwq/WebCoreBridge.mm:
+        (updateRenderingForBindings):
+        (-[WebCoreBridge init]):
+
 2004-05-14  Vicki Murley  <vicki@apple.com>
 
         Reviewed by mjs.
index e8257569d21c3dd019688c0b0a5960da8d2de519..e0745ec58b2b469b1e4affe959e1c8be6e214186 100644 (file)
@@ -149,6 +149,14 @@ static RootObject *rootForView(void *v)
     return 0;
 }
 
+static void updateRenderingForBindings (KJS::ExecState *exec, KJS::ObjectImp *rootObject)
+{
+    KJS::Window *window = static_cast<KJS::Window*>(rootObject);
+    DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(window->part()->document().handle());
+    doc->updateRendering();
+}
+
+
 @implementation WebCoreBridge
 
 static bool initializedObjectCacheSize = FALSE;
@@ -173,6 +181,9 @@ static bool initializedKJS = FALSE;
     
     if (!initializedKJS) {
         KJS::Bindings::RootObject::setFindRootObjectForNativeHandleFunction (rootForView);
+        
+        KJS::Bindings::Instance::setDidExecuteFunction(updateRenderingForBindings);
+        
         initializedKJS = TRUE;
     }