1 /* 2 * Copyright (C) 1999-2000 Harri Porten (porten (at) kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 #include "config.h" 21 #include "JSPluginElementFunctions.h" 22 23 #include "Bridge.h" 24 #include "HTMLNames.h" 25 #include "HTMLPlugInElement.h" 26 #include "JSHTMLElement.h" 27 #include "runtime_object.h" 28 29 using namespace JSC; 30 31 namespace WebCore { 32 33 using namespace Bindings; 34 using namespace HTMLNames; 35 36 // Runtime object support code for JSHTMLAppletElement, JSHTMLEmbedElement and JSHTMLObjectElement. 37 38 static Instance* pluginInstance(Node* node) 39 { 40 if (!node) 41 return 0; 42 if (!(node->hasTagName(objectTag) || node->hasTagName(embedTag) || node->hasTagName(appletTag))) 43 return 0; 44 HTMLPlugInElement* plugInElement = static_cast<HTMLPlugInElement*>(node); 45 // The plugin element holds an owning reference, so we don't have to. 46 Instance* instance = plugInElement->getInstance().get(); 47 if (!instance || !instance->rootObject()) 48 return 0; 49 return instance; 50 } 51 52 static RuntimeObjectImp* getRuntimeObject(ExecState* exec, Node* node) 53 { 54 Instance* instance = pluginInstance(node); 55 if (!instance) 56 return 0; 57 return instance->createRuntimeObject(exec); 58 } 59 60 JSValue runtimeObjectGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) 61 { 62 JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase())); 63 HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); 64 RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element); 65 return runtimeObject ? runtimeObject : jsUndefined(); 66 } 67 68 JSValue runtimeObjectPropertyGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) 69 { 70 JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase())); 71 HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); 72 RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element); 73 if (!runtimeObject) 74 return jsUndefined(); 75 return runtimeObject->get(exec, propertyName); 76 } 77 78 bool runtimeObjectCustomGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, JSHTMLElement* element) 79 { 80 RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element->impl()); 81 if (!runtimeObject) 82 return false; 83 if (!runtimeObject->hasProperty(exec, propertyName)) 84 return false; 85 slot.setCustom(element, runtimeObjectPropertyGetter); 86 return true; 87 } 88 89 bool runtimeObjectCustomGetOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, JSHTMLElement* element) 90 { 91 RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element->impl()); 92 if (!runtimeObject) 93 return false; 94 if (!runtimeObject->hasProperty(exec, propertyName)) 95 return false; 96 PropertySlot slot; 97 slot.setCustom(element, runtimeObjectPropertyGetter); 98 // While we don't know what the plugin allows, we do know that we prevent 99 // enumeration or deletion of properties, so we mark plugin properties 100 // as DontEnum | DontDelete 101 descriptor.setDescriptor(slot.getValue(exec, propertyName), DontEnum | DontDelete); 102 return true; 103 } 104 105 bool runtimeObjectCustomPut(ExecState* exec, const Identifier& propertyName, JSValue value, HTMLElement* element, PutPropertySlot& slot) 106 { 107 RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element); 108 if (!runtimeObject) 109 return 0; 110 if (!runtimeObject->hasProperty(exec, propertyName)) 111 return false; 112 runtimeObject->put(exec, propertyName, value, slot); 113 return true; 114 } 115 116 static JSValue JSC_HOST_CALL callPlugin(ExecState* exec, JSObject* function, JSValue, const ArgList& args) 117 { 118 Instance* instance = pluginInstance(static_cast<JSHTMLElement*>(function)->impl()); 119 instance->begin(); 120 JSValue result = instance->invokeDefaultMethod(exec, args); 121 instance->end(); 122 return result; 123 } 124 125 CallType runtimeObjectGetCallData(HTMLElement* element, CallData& callData) 126 { 127 Instance* instance = pluginInstance(element); 128 if (!instance || !instance->supportsInvokeDefaultMethod()) 129 return CallTypeNone; 130 callData.native.function = callPlugin; 131 return CallTypeHost; 132 } 133 134 } // namespace WebCore 135