Home | History | Annotate | Download | only in js
      1 /*
      2  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
      3  * Copyright (C) 2006 Alexey Proskuryakov (ap (at) nypop.com)
      4  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
      5  * Copyright (C) 2008 Eric Seidel <eric (at) webkit.org>
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     24  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #import "config.h"
     30 #import "ScriptController.h"
     31 
     32 #import "BridgeJSC.h"
     33 #import "DOMAbstractViewFrame.h"
     34 #import "DOMWindow.h"
     35 #import "Frame.h"
     36 #import "FrameLoader.h"
     37 #import "FrameLoaderClient.h"
     38 #import "JSDOMWindow.h"
     39 #import "WebScriptObjectPrivate.h"
     40 #import "Widget.h"
     41 #import "objc_instance.h"
     42 #import "runtime_root.h"
     43 #import <JavaScriptCore/APICast.h>
     44 #import <runtime/JSLock.h>
     45 
     46 #if ENABLE(NETSCAPE_PLUGIN_API)
     47 #import "c_instance.h"
     48 #import "NP_jsobject.h"
     49 #import "npruntime_impl.h"
     50 #endif
     51 
     52 #if ENABLE(JAVA_BRIDGE)
     53 #import "JavaInstanceJSC.h"
     54 #endif
     55 
     56 @interface NSObject (WebPlugin)
     57 - (id)objectForWebScript;
     58 - (NPObject *)createPluginScriptableObject;
     59 - (PassRefPtr<JSC::Bindings::Instance>)createPluginBindingsInstance:(PassRefPtr<JSC::Bindings::RootObject>)rootObject;
     60 @end
     61 
     62 using namespace JSC::Bindings;
     63 
     64 namespace WebCore {
     65 
     66 PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget)
     67 {
     68     NSView* widgetView = widget->platformWidget();
     69     if (!widgetView)
     70         return 0;
     71 
     72     RefPtr<RootObject> rootObject = createRootObject(widgetView);
     73 
     74     if ([widgetView respondsToSelector:@selector(createPluginBindingsInstance:)])
     75         return [widgetView createPluginBindingsInstance:rootObject.release()];
     76 
     77     if ([widgetView respondsToSelector:@selector(objectForWebScript)]) {
     78         id objectForWebScript = [widgetView objectForWebScript];
     79         if (!objectForWebScript)
     80             return 0;
     81         return JSC::Bindings::ObjcInstance::create(objectForWebScript, rootObject.release());
     82     }
     83 
     84     if ([widgetView respondsToSelector:@selector(createPluginScriptableObject)]) {
     85 #if !ENABLE(NETSCAPE_PLUGIN_API)
     86         return 0;
     87 #else
     88         NPObject* npObject = [widgetView createPluginScriptableObject];
     89         if (!npObject)
     90             return 0;
     91         RefPtr<Instance> instance = JSC::Bindings::CInstance::create(npObject, rootObject.release());
     92         // -createPluginScriptableObject returns a retained NPObject.  The caller is expected to release it.
     93         _NPN_ReleaseObject(npObject);
     94         return instance.release();
     95 #endif
     96     }
     97 
     98 #if ENABLE(JAVA_BRIDGE)
     99     jobject applet = m_frame->loader()->client()->javaApplet(widgetView);
    100     if (!applet)
    101         return 0;
    102     return JSC::Bindings::JavaInstance::create(applet, rootObject.release());
    103 #else
    104     return 0;
    105 #endif
    106 }
    107 
    108 WebScriptObject* ScriptController::windowScriptObject()
    109 {
    110     if (!canExecuteScripts(NotAboutToExecuteScript))
    111         return 0;
    112 
    113     if (!m_windowScriptObject) {
    114         JSC::JSLock lock(JSC::SilenceAssertionsOnly);
    115         JSC::Bindings::RootObject* root = bindingRootObject();
    116         m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(windowShell(pluginWorld())) originRootObject:root rootObject:root];
    117     }
    118 
    119     ASSERT([m_windowScriptObject.get() isKindOfClass:[DOMAbstractView class]]);
    120     return m_windowScriptObject.get();
    121 }
    122 
    123 void ScriptController::updatePlatformScriptObjects()
    124 {
    125     if (m_windowScriptObject) {
    126         JSC::Bindings::RootObject* root = bindingRootObject();
    127         [m_windowScriptObject.get() _setOriginRootObject:root andRootObject:root];
    128     }
    129 }
    130 
    131 void ScriptController::disconnectPlatformScriptObjects()
    132 {
    133     if (m_windowScriptObject) {
    134         ASSERT([m_windowScriptObject.get() isKindOfClass:[DOMAbstractView class]]);
    135         [(DOMAbstractView *)m_windowScriptObject.get() _disconnectFrame];
    136     }
    137 }
    138 
    139 #if ENABLE(JAVA_BRIDGE)
    140 
    141 static pthread_t mainThread;
    142 
    143 static void updateStyleIfNeededForBindings(JSC::ExecState*, JSC::JSObject* rootObject)
    144 {
    145     if (pthread_self() != mainThread)
    146         return;
    147 
    148     if (!rootObject)
    149         return;
    150 
    151     JSDOMWindow* window = static_cast<JSDOMWindow*>(rootObject);
    152     if (!window)
    153         return;
    154 
    155     Frame* frame = window->impl()->frame();
    156     if (!frame)
    157         return;
    158 
    159     frame->document()->updateStyleIfNeeded();
    160 }
    161 
    162 void ScriptController::initJavaJSBindings()
    163 {
    164     mainThread = pthread_self();
    165     JSC::Bindings::JavaJSObject::initializeJNIThreading();
    166     JSC::Bindings::Instance::setDidExecuteFunction(updateStyleIfNeededForBindings);
    167 }
    168 
    169 #endif
    170 
    171 }
    172