v8::Handle<v8::Value> convertNPVariantToV8Object(const NPVariant* variant, NPObject* owner, v8::Isolate* isolate) { NPVariantType type = variant->type; switch (type) { case NPVariantType_Int32: return v8::Integer::New(NPVARIANT_TO_INT32(*variant), isolate); case NPVariantType_Double: return v8::Number::New(isolate, NPVARIANT_TO_DOUBLE(*variant)); case NPVariantType_Bool: return v8Boolean(NPVARIANT_TO_BOOLEAN(*variant), isolate); case NPVariantType_Null: return v8::Null(isolate); case NPVariantType_Void: return v8::Undefined(isolate); case NPVariantType_String: { NPString src = NPVARIANT_TO_STRING(*variant); return v8::String::NewFromUtf8(isolate, src.UTF8Characters, v8::String::kNormalString, src.UTF8Length); } case NPVariantType_Object: { NPObject* object = NPVARIANT_TO_OBJECT(*variant); if (V8NPObject* v8Object = npObjectToV8NPObject(object)) return v8::Local<v8::Object>::New(isolate, v8Object->v8Object); return createV8ObjectForNPObject(object, owner, isolate); } default: return v8::Undefined(isolate); } }
v8::Handle<v8::Value> convertNPVariantToV8Object(const NPVariant* variant, NPObject* npobject) { NPVariantType type = variant->type; switch (type) { case NPVariantType_Int32: return v8Integer(NPVARIANT_TO_INT32(*variant)); case NPVariantType_Double: return v8::Number::New(NPVARIANT_TO_DOUBLE(*variant)); case NPVariantType_Bool: return v8Boolean(NPVARIANT_TO_BOOLEAN(*variant)); case NPVariantType_Null: return v8::Null(); case NPVariantType_Void: return v8::Undefined(); case NPVariantType_String: { NPString src = NPVARIANT_TO_STRING(*variant); return v8::String::New(src.UTF8Characters, src.UTF8Length); } case NPVariantType_Object: { NPObject* obj = NPVARIANT_TO_OBJECT(*variant); if (obj->_class == npScriptObjectClass) return reinterpret_cast<V8NPObject*>(obj)->v8Object; return createV8ObjectForNPObject(obj, npobject); } default: return v8::Undefined(); } }
PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget) { ASSERT(widget); if (widget->isFrameView()) return 0; #if ENABLE(NETSCAPE_PLUGIN_API) NPObject* npObject = PlatformBridge::pluginScriptableObject(widget); if (!npObject) return 0; // Frame Memory Management for NPObjects // ------------------------------------- // NPObjects are treated differently than other objects wrapped by JS. // NPObjects can be created either by the browser (e.g. the main // window object) or by the plugin (the main plugin object // for a HTMLEmbedElement). Further, unlike most DOM Objects, the frame // is especially careful to ensure NPObjects terminate at frame teardown because // if a plugin leaks a reference, it could leak its objects (or the browser's objects). // // The Frame maintains a list of plugin objects (m_pluginObjects) // which it can use to quickly find the wrapped embed object. // // Inside the NPRuntime, we've added a few methods for registering // wrapped NPObjects. The purpose of the registration is because // javascript garbage collection is non-deterministic, yet we need to // be able to tear down the plugin objects immediately. When an object // is registered, javascript can use it. When the object is destroyed, // or when the object's "owning" object is destroyed, the object will // be un-registered, and the javascript engine must not use it. // // Inside the javascript engine, the engine can keep a reference to the // NPObject as part of its wrapper. However, before accessing the object // it must consult the _NPN_Registry. v8::Local<v8::Object> wrapper = createV8ObjectForNPObject(npObject, 0); #ifdef ANDROID_FIX // TODO: this should be up streamed. // HTMLEmbedElement::getInstance() will call this function with its closest // ancestor who has the objectTag. So this "widget" may be already in the // HashMap. If it does, even m_pluginObjects.set() is a no-op, we do need to // call _NPN_ReleaseObject on the npObject to balance the reference count. PluginObjectMap::iterator it = m_pluginObjects.find(widget); if (it != m_pluginObjects.end()) { ASSERT(it->second == npObject); _NPN_ReleaseObject(it->second); } #endif // Track the plugin object. We've been given a reference to the object. m_pluginObjects.set(widget, npObject); return V8ScriptInstance::create(wrapper); #else return 0; #endif }
// Create a V8 object with an interceptor of NPObjectPropertyGetter. bool ScriptController::bindToWindowObject(LocalFrame* frame, const String& key, NPObject* object) { ScriptState* scriptState = ScriptState::forMainWorld(frame); if (!scriptState->contextIsValid()) return false; ScriptState::Scope scope(scriptState); v8::Local<v8::Object> value = createV8ObjectForNPObject(isolate(), object, 0); // Attach to the global object. return v8CallBoolean(scriptState->context()->Global()->Set(scriptState->context(), v8String(isolate(), key), value)); }
// Create a V8 object with an interceptor of NPObjectPropertyGetter. void ScriptController::bindToWindowObject(LocalFrame* frame, const String& key, NPObject* object) { ScriptState* scriptState = ScriptState::forMainWorld(frame); if (!scriptState->contextIsValid()) return; ScriptState::Scope scope(scriptState); v8::Handle<v8::Object> value = createV8ObjectForNPObject(m_isolate, object, 0); // Attach to the global object. scriptState->context()->Global()->Set(v8String(m_isolate, key), value); }
PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget) { ASSERT(widget); #if PLATFORM(CHROMIUM) if (widget->isFrameView()) return 0; NPObject* npObject = ChromiumBridge::pluginScriptableObject(widget); if (!npObject) return 0; #elif PLATFORM(ANDROID) if (!widget->isPluginView()) return 0; PluginView* pluginView = static_cast<PluginView*>(widget); NPObject* npObject = pluginView->getNPObject(); if (!npObject) return 0; #endif // Frame Memory Management for NPObjects // ------------------------------------- // NPObjects are treated differently than other objects wrapped by JS. // NPObjects can be created either by the browser (e.g. the main // window object) or by the plugin (the main plugin object // for a HTMLEmbedElement). Further, unlike most DOM Objects, the frame // is especially careful to ensure NPObjects terminate at frame teardown because // if a plugin leaks a reference, it could leak its objects (or the browser's objects). // // The Frame maintains a list of plugin objects (m_pluginObjects) // which it can use to quickly find the wrapped embed object. // // Inside the NPRuntime, we've added a few methods for registering // wrapped NPObjects. The purpose of the registration is because // javascript garbage collection is non-deterministic, yet we need to // be able to tear down the plugin objects immediately. When an object // is registered, javascript can use it. When the object is destroyed, // or when the object's "owning" object is destroyed, the object will // be un-registered, and the javascript engine must not use it. // // Inside the javascript engine, the engine can keep a reference to the // NPObject as part of its wrapper. However, before accessing the object // it must consult the _NPN_Registry. v8::Local<v8::Object> wrapper = createV8ObjectForNPObject(npObject, 0); // Track the plugin object. We've been given a reference to the object. m_pluginObjects.set(widget, npObject); return V8ScriptInstance::create(wrapper); }
// Create a V8 object with an interceptor of NPObjectPropertyGetter. void ScriptController::bindToWindowObject(Frame* frame, const String& key, NPObject* object) { v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(frame); if (v8Context.IsEmpty()) return; v8::Context::Scope scope(v8Context); v8::Handle<v8::Object> value = createV8ObjectForNPObject(object, 0); // Attach to the global object. v8::Handle<v8::Object> global = v8Context->Global(); global->Set(v8String(key, v8Context->GetIsolate()), value); }
// Create a V8 object with an interceptor of NPObjectPropertyGetter. void ScriptController::bindToWindowObject(LocalFrame* frame, const String& key, NPObject* object) { v8::HandleScope handleScope(m_isolate); v8::Handle<v8::Context> v8Context = toV8Context(m_isolate, frame, DOMWrapperWorld::mainWorld()); if (v8Context.IsEmpty()) return; v8::Context::Scope scope(v8Context); v8::Handle<v8::Object> value = createV8ObjectForNPObject(object, 0, m_isolate); // Attach to the global object. v8::Handle<v8::Object> global = v8Context->Global(); global->Set(v8String(m_isolate, key), value); }
// Create a V8 object with an interceptor of NPObjectPropertyGetter. void ScriptController::bindToWindowObject(Frame* frame, const String& key, NPObject* object) { v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame); if (v8Context.IsEmpty()) return; v8::Context::Scope scope(v8Context); #if ENABLE(NETSCAPE_PLUGIN_API) v8::Handle<v8::Object> value = createV8ObjectForNPObject(object, 0); // Attach to the global object. v8::Handle<v8::Object> global = v8Context->Global(); global->Set(v8String(key), value); #endif }
PassRefPtr<SharedPersistent<v8::Object> > ScriptController::createPluginWrapper(Widget* widget) { ASSERT(widget); if (!widget->isPluginView()) return nullptr; NPObject* npObject = toPluginView(widget)->scriptableObject(); if (!npObject) return nullptr; // LocalFrame Memory Management for NPObjects // ------------------------------------- // NPObjects are treated differently than other objects wrapped by JS. // NPObjects can be created either by the browser (e.g. the main // window object) or by the plugin (the main plugin object // for a HTMLEmbedElement). Further, unlike most DOM Objects, the frame // is especially careful to ensure NPObjects terminate at frame teardown because // if a plugin leaks a reference, it could leak its objects (or the browser's objects). // // The LocalFrame maintains a list of plugin objects (m_pluginObjects) // which it can use to quickly find the wrapped embed object. // // Inside the NPRuntime, we've added a few methods for registering // wrapped NPObjects. The purpose of the registration is because // javascript garbage collection is non-deterministic, yet we need to // be able to tear down the plugin objects immediately. When an object // is registered, javascript can use it. When the object is destroyed, // or when the object's "owning" object is destroyed, the object will // be un-registered, and the javascript engine must not use it. // // Inside the javascript engine, the engine can keep a reference to the // NPObject as part of its wrapper. However, before accessing the object // it must consult the _NPN_Registry. v8::Local<v8::Object> wrapper = createV8ObjectForNPObject(npObject, 0, m_isolate); // Track the plugin object. We've been given a reference to the object. m_pluginObjects.set(widget, npObject); return SharedPersistent<v8::Object>::create(wrapper, m_isolate); }