v8::Handle<v8::Value> ConvertNPVariantToV8Object(const NPVariant* variant, NPObject* npobject) { NPVariantType type = variant->type; if (type == NPVariantType_Int32) { return v8::Integer::New(NPVARIANT_TO_INT32(*variant)); } if (type == NPVariantType_Double) { return v8::Number::New(NPVARIANT_TO_DOUBLE(*variant)); } if (type == NPVariantType_Bool) { return NPVARIANT_TO_BOOLEAN(*variant) ? v8::True() : v8::False(); } if (type == NPVariantType_Null) { return v8::Null(); } if (type == NPVariantType_Void) { return v8::Undefined(); } if (type == NPVariantType_String) { NPString src = NPVARIANT_TO_STRING(*variant); return v8::String::New(src.UTF8Characters, src.UTF8Length); } if (type == NPVariantType_Object) { NPObject* obj = NPVARIANT_TO_OBJECT(*variant); if (obj->_class == NPScriptObjectClass) { return reinterpret_cast<V8NPObject*>(obj)->v8_object; } return CreateV8ObjectForNPObject(obj, npobject); } return v8::Undefined(); }
// 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> context = V8Proxy::GetContext(frame); if (context.IsEmpty()) return; v8::Context::Scope scope(context); v8::Handle<v8::Object> value = CreateV8ObjectForNPObject(object, 0); // Attach to the global object. v8::Handle<v8::Object> global = context->Global(); global->Set(v8String(key), value); }
PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget) { ASSERT(widget); if (widget->isFrameView()) return 0; NPObject* npObject = ChromiumBridge::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); // Track the plugin object. We've been given a reference to the object. m_pluginObjects.set(widget, npObject); return V8ScriptInstance::create(wrapper); }