diff options
author | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-01 22:31:35 +0000 |
---|---|---|
committer | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-01 22:31:35 +0000 |
commit | de56f378336660dcc848763c80267a5e063ae47d (patch) | |
tree | 7f551b88923b35bc4022ce6ab3a3f602fb60d91c /webkit/port/bridge | |
parent | dc4f63c80cb90efe594131030aad6776e5945fcc (diff) | |
download | chromium_src-de56f378336660dcc848763c80267a5e063ae47d.zip chromium_src-de56f378336660dcc848763c80267a5e063ae47d.tar.gz chromium_src-de56f378336660dcc848763c80267a5e063ae47d.tar.bz2 |
Merge the chrome_webkit_merge_branch back on to trunk. This brings us
up to webkit@36102.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2778 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port/bridge')
-rw-r--r-- | webkit/port/bridge/ExceptionContextV8.cpp | 108 | ||||
-rw-r--r-- | webkit/port/bridge/FrameWin.cpp | 112 | ||||
-rw-r--r-- | webkit/port/bridge/HistoryWin.cpp | 49 | ||||
-rw-r--r-- | webkit/port/bridge/JSBridge.h | 271 | ||||
-rw-r--r-- | webkit/port/bridge/KJSBridge.h | 72 | ||||
-rw-r--r-- | webkit/port/bridge/ScriptControllerKJS.cpp (renamed from webkit/port/bridge/KJSBridge.cpp) | 4 | ||||
-rw-r--r-- | webkit/port/bridge/ScriptControllerV8.cpp | 588 | ||||
-rw-r--r-- | webkit/port/bridge/V8Bridge.cpp | 429 | ||||
-rw-r--r-- | webkit/port/bridge/V8Bridge.h | 73 |
9 files changed, 704 insertions, 1002 deletions
diff --git a/webkit/port/bridge/ExceptionContextV8.cpp b/webkit/port/bridge/ExceptionContextV8.cpp new file mode 100644 index 0000000..4d8efdc --- /dev/null +++ b/webkit/port/bridge/ExceptionContextV8.cpp @@ -0,0 +1,108 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 "config.h" +#include "ExceptionContext.h" + +#include "Node.h" + +namespace WebCore { + +ExceptionContext::ExceptionContext() + : m_exceptionCatcher(0) + , m_exception() +{ +} + +ExceptionContext::~ExceptionContext() +{ +} + +void ExceptionContext::setExceptionCatcher(ExceptionCatcher* exceptionCatcher) +{ + if (m_exceptionCatcher && exceptionCatcher) + m_exceptionCatcher->detachContext(); + + m_exceptionCatcher = exceptionCatcher; +} + +bool ExceptionContext::hadException() +{ + if (m_exceptionCatcher) + m_exceptionCatcher->updateContext(); + + return !m_exception.IsEmpty(); +} + +ExceptionContext* ExceptionContext::createFromNode(Node*) +{ + // Unlike JSC, which stores exceptions in ExecState that is accessible from + // ScriptController that is retrievable from Node*, V8 uses static chain of + // handlers (encapsulated as v8::TryCatch and here as ExceptionCatcher) + // to track exceptions, so it has no need for Node*. + return new ExceptionContext(); +} + +JSException ExceptionContext::NoException() +{ + return v8::Local<v8::Value>(); +} + +ExceptionCatcher::ExceptionCatcher(ExceptionContext* exceptionContext) + : m_catcher() + , m_context(exceptionContext) +{ + exceptionContext->setExceptionCatcher(this); +} + +void ExceptionCatcher::detachContext() +{ + m_context = 0; +} + +void ExceptionCatcher::updateContext() +{ + ASSERT(m_context); + + if (m_catcher.HasCaught()) + m_context->setException(m_catcher.Exception()); + else + m_context->setException(ExceptionContext::NoException()); +} + +ExceptionCatcher::~ExceptionCatcher() +{ + if (!m_context) + return; + + updateContext(); + m_context->setExceptionCatcher(0); +} + +} // namespace WebCore diff --git a/webkit/port/bridge/FrameWin.cpp b/webkit/port/bridge/FrameWin.cpp index 60892ec..5c29891 100644 --- a/webkit/port/bridge/FrameWin.cpp +++ b/webkit/port/bridge/FrameWin.cpp @@ -27,124 +27,30 @@ #pragma warning(push, 0) #include "Document.h" -#include "EditorClient.h" -#include "FrameLoader.h" -#include "FrameLoaderClient.h" -#include "FrameLoadRequest.h" #include "FramePrivate.h" #include "FrameView.h" -#include "Frame.h" #include "FrameWin.h" -#include "NotImplemented.h" +#include "RenderFrame.h" #include "RenderView.h" +#include "ScriptController.h" -#if USE(JAVASCRIPTCORE_BINDINGS) -#include "JSLock.h" +#if USE(JSC) #include "kjs_proxy.h" -#include "kjs_window.h" #include "NP_jsobject.h" -#include "NotImplemented.h" #include "bindings/npruntime.h" +#include "runtime_root.h" +#include "runtime.h" #endif -#if USE(V8_BINDING) +#if USE(V8) #include "v8_npobject.h" #include "npruntime_priv.h" #endif -#include "Page.h" -#include "RenderFrame.h" -#include "ResourceHandle.h" -#if USE(JAVASCRIPTCORE_BINDINGS) -#include "runtime_root.h" -#include "runtime.h" -#endif -#include "Settings.h" -#include "TextResourceDecoder.h" #include "webkit/glue/webplugin_impl.h" #pragma warning(pop) -// So we can twiddle event member vars -#define private public -#include "PlatformKeyboardEvent.h" -#undef private - -#include "webkit/glue/cache_manager.h" - namespace WebCore { -void Frame::clearPlatformScriptObjects() -{ -} - -#if USE(JAVASCRIPTCORE_BINDINGS) || USE(V8_BINDING) -JSInstance Frame::createScriptInstanceForWidget(Widget* widget) -{ - ASSERT(widget != 0); - - if (widget->isFrameView()) - return JSInstanceHolder::EmptyInstance(); - - // Note: We have to trust that the widget passed to us here - // is a WebPluginImpl. There isn't a way to dynamically verify - // it, since the derived class (Widget) has no identifier. - WebPluginContainer* container = static_cast<WebPluginContainer*>(widget); - if (!container) - return JSInstanceHolder::EmptyInstance(); - - NPObject *npObject = container->GetPluginScriptableObject(); - if (!npObject) - return JSInstanceHolder::EmptyInstance(); - -#if USE(JAVASCRIPTCORE_BINDINGS) - // Register 'widget' with the frame so that we can teardown - // subobjects when the container goes away. - RefPtr<KJS::Bindings::RootObject> root = - createRootObject(widget, scriptProxy()->globalObject()); - KJS::Bindings::Instance *instance = - KJS::Bindings::Instance::createBindingForLanguageInstance( - KJS::Bindings::Instance::CLanguage, npObject, - root.release()); - // GetPluginScriptableObject returns a retained NPObject. - // The caller is expected to release it. - NPN_ReleaseObject(npObject); - return instance; -#else - // Frame Memory Management for NPObjects - // ------------------------------------- - // NPObjects are treated differently than other objects wrapped by JS. - // NPObjects are not Peerable, and cannot be made peerable, since 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, NULL); - - // Track the plugin object. We've been given a reference to the object. - d->m_pluginObjects.set(widget, npObject); - - JSInstance instance = wrapper; - return instance; -#endif -} -#endif // JAVASCRIPTCORE_BINDINGS - void computePageRectsForFrame(WebCore::Frame* frame, const WebCore::IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& outPageHeight) { ASSERT(frame); @@ -199,14 +105,10 @@ void computePageRectsForFrame(WebCore::Frame* frame, const WebCore::IntRect& pri DragImageRef Frame::dragImageForSelection() { - if (selectionController()->isRange()) + if (selection()->isRange()) return 0; // TODO(pkasting): http://b/119669 Implement me! return 0; } -void Frame::dashboardRegionsChanged() -{ -} - } // namespace WebCore diff --git a/webkit/port/bridge/HistoryWin.cpp b/webkit/port/bridge/HistoryWin.cpp deleted file mode 100644 index 0a835ba..0000000 --- a/webkit/port/bridge/HistoryWin.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (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 "config.h" -#include "History.h" - -#include "CString.h" -#include "DeprecatedString.h" -#include "Document.h" -#include "PlatformString.h" -#include "SecurityOrigin.h" - -#include "webkit/glue/webkit_glue.h" - -namespace WebCore { - -bool historyContains(const UChar* characters, unsigned length, - Document* document) { - // check the document's DNS prefetch settings and pass up to the renderer - CString document_host = document->securityOrigin()->host().utf8(); - return webkit_glue::HistoryContains( - reinterpret_cast<const char16*>(characters), length, - document_host.data(), document_host.length(), - document->isDNSPrefetchEnabled()); -} - -} diff --git a/webkit/port/bridge/JSBridge.h b/webkit/port/bridge/JSBridge.h deleted file mode 100644 index d69521c..0000000 --- a/webkit/port/bridge/JSBridge.h +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// An interface to abstract implementation differences -// for various Javascript engines. - -#ifndef JSBridge_h -#define JSBridge_h - -#include "third_party/npapi/bindings/npruntime.h" -#if USE(JAVASCRIPTCORE_BINDINGS) -#include <kjs/ustring.h> -#endif - -#if USE(V8_BINDING) -#include "v8.h" -//namespace v8 { class Object; } -#endif - -// JavaScript implementations which expose NPObject will need to implement -// these methods. -typedef void (*NPN_ReleaseVariantValueProcPtr) (NPVariant *variant); - -typedef NPIdentifier(*NPN_GetStringIdentifierProcPtr) (const NPUTF8 *name); -typedef void (*NPN_GetStringIdentifiersProcPtr) (const NPUTF8 **names, - int32_t nameCount, - NPIdentifier *identifiers); -typedef NPIdentifier(*NPN_GetIntIdentifierProcPtr) (int32_t intid); -typedef int32_t (*NPN_IntFromIdentifierProcPtr) (NPIdentifier identifier); -typedef bool (*NPN_IdentifierIsStringProcPtr) (NPIdentifier identifier); -typedef NPUTF8 * (*NPN_UTF8FromIdentifierProcPtr) (NPIdentifier identifier); - -typedef NPObject* (*NPN_CreateObjectProcPtr) (NPP, - NPClass *aClass); -typedef NPObject* (*NPN_RetainObjectProcPtr) (NPObject *obj); -typedef void (*NPN_ReleaseObjectProcPtr) (NPObject *obj); -typedef bool (*NPN_InvokeProcPtr) (NPP npp, - NPObject *obj, - NPIdentifier methodName, - const NPVariant *args, - unsigned argCount, - NPVariant *result); -typedef bool (*NPN_InvokeDefaultProcPtr) (NPP npp, - NPObject *obj, - const NPVariant *args, - unsigned argCount, - NPVariant *result); -typedef bool (*NPN_EvaluateProcPtr) (NPP npp, - NPObject *obj, - NPString *script, - NPVariant *result); -typedef bool (*NPN_GetPropertyProcPtr) (NPP npp, - NPObject *obj, - NPIdentifier propertyName, - NPVariant *result); -typedef bool (*NPN_SetPropertyProcPtr) (NPP npp, - NPObject *obj, - NPIdentifier propertyName, - const NPVariant *value); -typedef bool (*NPN_HasPropertyProcPtr) (NPP, - NPObject *npobj, - NPIdentifier propertyName); -typedef bool (*NPN_HasMethodProcPtr) (NPP npp, - NPObject *npobj, - NPIdentifier methodName); -typedef bool (*NPN_RemovePropertyProcPtr) (NPP npp, - NPObject *obj, - NPIdentifier propertyName); -typedef void (*NPN_SetExceptionProcPtr) (NPObject *obj, - const NPUTF8 *message); - -typedef struct _NPRuntimeFunctions { - NPN_GetStringIdentifierProcPtr getStringIdentifier; - NPN_GetStringIdentifiersProcPtr getStringIdentifiers; - NPN_GetIntIdentifierProcPtr getIntIdentifier; - NPN_IdentifierIsStringProcPtr identifierIsString; - NPN_UTF8FromIdentifierProcPtr utf8FromIdentifier; - NPN_IntFromIdentifierProcPtr intFromIdentifier; - NPN_CreateObjectProcPtr createObject; - NPN_RetainObjectProcPtr retainObject; - NPN_ReleaseObjectProcPtr releaseObject; - NPN_InvokeProcPtr invoke; - NPN_InvokeDefaultProcPtr invokeDefault; - NPN_EvaluateProcPtr evaluate; - NPN_GetPropertyProcPtr getProperty; - NPN_SetPropertyProcPtr setProperty; - NPN_RemovePropertyProcPtr removeProperty; - NPN_HasPropertyProcPtr hasProperty; - NPN_HasMethodProcPtr hasMethod; - NPN_ReleaseVariantValueProcPtr releaseVariantValue; - NPN_SetExceptionProcPtr setException; -} NPRuntimeFunctions; - -#if USE(JAVASCRIPTCORE_BINDINGS) -namespace KJS { namespace Bindings { class RootObject; class Instance; } -} -#endif - - -namespace WebCore { -class Document; -class Frame; -class String; -class Node; -class EventListener; -class Event; -class HTMLPlugInElement; -class PausedTimeouts; - -// JSString is the string class used for XMLHttpRequest's -// m_responseText field. -#if USE(JAVASCRIPTCORE_BINDINGS) -typedef KJS::UString JSString; -typedef KJS::Bindings::Instance* JSInstance; -typedef KJS::Bindings::Instance* JSPersistentInstance; -typedef KJS::JSValue* JSException; -typedef KJS::JSValue* JSResult; -#endif - -#if USE(V8_BINDING) -typedef String JSString; -typedef v8::Local<v8::Object> JSInstance; -typedef v8::Persistent<v8::Object> JSPersistentInstance; -typedef v8::Local<v8::Value> JSException; -typedef v8::Persistent<v8::Value> JSResult; -#endif - -class JSBridge { - public: - virtual ~JSBridge() { } - - // Disconnects the proxy from its owner frame. - virtual void disconnectFrame() = 0; - - virtual bool wasRunByUserGesture() = 0; - - - // Evaluate a script file in the environment of this proxy. Used for - // evaluating the code in script tags and for evaluating the code from - // javascript URLs. - // If succeeded, 'succ' is set to true and result is returned - // as a string. - virtual String evaluate(const String& filename, int baseLine, - const String& code, Node*, bool* succ) = 0; - - // Second API function for evaluating a JS code. - // It returns a JSResult which must be disposed by calling - // disposeJSResult. If the result is not disposed, it can cause - // serious memory leak. The caller determines whether the evaluation - // is successful by checking the value of JSResult. - virtual JSResult evaluate(const String& filename, int baseLine, - const String& code, Node*) = 0; - virtual void disposeJSResult(JSResult result) = 0; - - virtual EventListener* createHTMLEventHandler(const String& functionName, - const String& code, Node* node) = 0; - -#if ENABLE(SVG) - virtual EventListener* createSVGEventHandler(const String& functionName, - const String& code, Node* node) = 0; -#endif - - virtual void setEventHandlerLineno(int lineno) = 0; - virtual void finishedWithEvent(Event*) = 0; - - virtual void clear() = 0; - - // Get the Root object - // virtual JSRootObject* getRootObject() = 0; - // Creates a property of the global object of a frame. - virtual void BindToWindowObject(Frame* frame, const String& key, NPObject* object) = 0; - - // Provides access to the NPRuntime functions. - virtual NPRuntimeFunctions *functions() = 0; - - // Create an NPObject for the window object. - virtual NPObject *CreateScriptObject(Frame*) = 0; - - // Create an NPObject for an HTMLPluginElement - virtual NPObject *CreateScriptObject(Frame*, HTMLPlugInElement*) = 0; - - // Create a "NoScript" object (used when JS is unavailable or disabled) - virtual NPObject *CreateNoScriptObject() = 0; - - // Check if the javascript engine has been initialized. - virtual bool haveInterpreter() const = 0; - - virtual bool isEnabled() const = 0; - - virtual void clearDocumentWrapper() = 0; - - virtual void CollectGarbage() = 0; - - // Create a NPObject wrapper for a JSObject - //virtual NPObject *WrapScriptObject(NPP pluginId, JSObject* objectToWrap, - // JSRootObject* originRootObject, - // JSRootObject* rootObject); - - // --- Static methods assume we are running VM in single thread, --- - // --- and there is only one VM instance. --- - - // Returns the frame of the calling code is in. - // Not necessary the frame of this proxy. - // For example, JS code in frame A calls windowB.open(...). - // Window::open method has the frame pointer of B, but - // the execution context is in frame A, so it needs - // frame A's loader to complete URL. - static Frame* retrieveActiveFrame(); - - // Check whether it is safe to access a frame in another domain. - static bool isSafeScript(Frame* target); - - // Tell the proxy that document.domain is set. - static void setDomain(Frame* target, const String& new_domain); - - // Pass flags to the JS engine - static void setFlags(const char* str, int length); - - // Protect and unprotect the JS wrapper from garbage collected. - static void gcProtectJSWrapper(void* dom_object); - static void gcUnprotectJSWrapper(void* dom_Object); - - // Returns a non-exception code object. - static JSException NoException(); - // Returns true if the parameter is a JS exception object. - static bool IsException(JSException exception); - - // Get/Set RecordPlaybackMode flag. - // This is a special mode where JS helps the browser implement - // playback/record mode. Generally, in this mode, some functions - // of client-side randomness are removed. For example, in - // this mode Math.random() and Date.getTime() may not return - // values which vary. - static bool RecordPlaybackMode() { return m_recordPlaybackMode; } - static void setRecordPlaybackMode(bool value) { - m_recordPlaybackMode = value; - } - - // Pause timeouts for a frame. - static PausedTimeouts* pauseTimeouts(Frame* frame); - // Resume timeouts for a frame. - static void resumeTimeouts(Frame* frame, PausedTimeouts* timeouts); - - private: - static bool m_recordPlaybackMode; -}; - -// JSInstance is an abstraction for a wrapped C class. KJS and V8 -// have very different implementations. -class JSInstanceHolder { - public: - JSInstanceHolder(); - JSInstanceHolder(JSInstance instance); - ~JSInstanceHolder(); - // Returns true if the holder is empty. - bool IsEmpty(); - // Get the contained JSInstance. - JSInstance Get(); - // Clear the contained JSInstance. - void Clear(); - JSInstanceHolder& operator=(JSInstance instance); - static JSInstance EmptyInstance(); - private: - JSPersistentInstance m_instance; -}; - -} // namespace WebCore - -#endif // JSBridge_h - diff --git a/webkit/port/bridge/KJSBridge.h b/webkit/port/bridge/KJSBridge.h deleted file mode 100644 index 0704fcd..0000000 --- a/webkit/port/bridge/KJSBridge.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains KJS specific bits required to build WebKit. - -#ifndef KJSBridge_h -#define KJSBridge_h - -#include "JSBridge.h" -#include "kjs_binding.h" -#include "kjs_proxy.h" - -namespace WebCore { -class KJSBridge : public JSBridge { - public: - KJSBridge(Frame* frame) : m_proxy(new KJSProxy(frame)) { } - virtual ~KJSBridge() { delete m_proxy; } - - virtual void disconnectFrame(); - virtual bool wasRunByUserGesture(); - // Evaluate a script file in the environment of this proxy. - virtual String evaluate(const String& filename, int baseLine, - const String& code, Node*, bool* succ); - - virtual JSResult evaluate(const String& filename, int baseLine, - const String& code, Node*); - virtual void disposeJSResult(JSResult) { } - - virtual EventListener* createHTMLEventHandler(const String& functionName, - const String& code, Node* node); -#if ENABLE(SVG) - virtual EventListener* createSVGEventHandler(const String& functionName, - const String& code, Node* node); -#endif - - virtual void setEventHandlerLineno(int lineno); - - virtual void finishedWithEvent(Event* evt); - - virtual void clear(); - - // virtual JSRootObject *getRootObject(); - - // Creates a property of the global object of a frame. - virtual void BindToWindowObject(Frame* frame, const String& key, NPObject* object); - virtual NPRuntimeFunctions *functions(); - virtual NPObject *CreateScriptObject(Frame*); - virtual NPObject *CreateScriptObject(Frame*, HTMLPlugInElement*); - virtual NPObject *CreateNoScriptObject(); - - virtual bool haveInterpreter() const { return m_proxy->haveGlobalObject(); } - virtual bool isEnabled() const { return m_proxy->isEnabled(); } - - virtual void clearDocumentWrapper() { m_proxy->clearDocumentWrapper(); } - - virtual void CollectGarbage() { } - - KJSProxy* proxy() { return m_proxy; } - - private: - // Internal call to create an NPObject for a JSValue - NPObject *CreateScriptObject(Frame*, KJS::JSValue*); - - private: - KJSProxy* m_proxy; -}; - -} // namespace WebCore - -#endif - diff --git a/webkit/port/bridge/KJSBridge.cpp b/webkit/port/bridge/ScriptControllerKJS.cpp index ecbb19c..4786b6c 100644 --- a/webkit/port/bridge/KJSBridge.cpp +++ b/webkit/port/bridge/ScriptControllerKJS.cpp @@ -130,9 +130,7 @@ bool KJSBridge::wasRunByUserGesture() { } -// Evaluate a script file in the environment of this proxy. Used for -// evaluating the code in script tags and for evaluating the code from -// javascript URLs. +// Evaluate a script file in the environment of this proxy. String KJSBridge::evaluate(const String& filename, int baseLine, const String& code, Node* node, bool* succ) { *succ = false; diff --git a/webkit/port/bridge/ScriptControllerV8.cpp b/webkit/port/bridge/ScriptControllerV8.cpp new file mode 100644 index 0000000..ce244a4 --- /dev/null +++ b/webkit/port/bridge/ScriptControllerV8.cpp @@ -0,0 +1,588 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 "config.h" +#include "ScriptController.h" + +#include "CString.h" +#include "Document.h" +#include "DOMWindow.h" +#include "Event.h" +#include "EventNames.h" +#include "Frame.h" +#include "Node.h" +#include "NotImplemented.h" +#include "npruntime_priv.h" +#include "np_v8object.h" +#include "Widget.h" + +#include "v8_proxy.h" +#include "v8_binding.h" +#include "v8_npobject.h" + +//TODO(eseidel): We should remove this glue dependency +#undef LOG // glue defines its own LOG macro +#include "glue/webplugin_impl.h" + +NPRuntimeFunctions npruntime_functions = { + NPN_GetStringIdentifier, + NPN_GetStringIdentifiers, + NPN_GetIntIdentifier, + NPN_IdentifierIsString, + NPN_UTF8FromIdentifier, + NPN_IntFromIdentifier, + NPN_CreateObject, + NPN_RetainObject, + NPN_ReleaseObject, + NPN_Invoke, + NPN_InvokeDefault, + NPN_Evaluate, + NPN_GetProperty, + NPN_SetProperty, + NPN_RemoveProperty, + NPN_HasProperty, + NPN_HasMethod, + NPN_ReleaseVariantValue, + NPN_SetException +}; + + +namespace WebCore { + +bool ScriptController::m_recordPlaybackMode = false; + +void ScriptController::setFlags(const char* str, int length) +{ + v8::V8::SetFlagsFromString(str, length); +} + +void ScriptController::setDomain(Frame* frame, const String&) +{ + V8Proxy::DomainChanged(frame); +} + +Frame* ScriptController::retrieveActiveFrame() +{ + return V8Proxy::retrieveActiveFrame(); +} + +bool ScriptController::isSafeScript(Frame* target) +{ + return V8Proxy::IsFromSameOrigin(target, true); +} + +void ScriptController::gcProtectJSWrapper(void* dom_object) +{ + V8Proxy::GCProtect(static_cast<Peerable*>(dom_object)); +} + +void ScriptController::gcUnprotectJSWrapper(void* dom_object) +{ + V8Proxy::GCUnprotect(static_cast<Peerable*>(dom_object)); +} + +void ScriptController::pauseTimeouts(OwnPtr<PausedTimeouts>& result) +{ + DOMWindow* window = m_frame->domWindow(); + if (!window) { + result.clear(); + return; + } + window->pauseTimeouts(result); +} + +void ScriptController::resumeTimeouts(OwnPtr<PausedTimeouts>& timeouts) +{ + DOMWindow* window = m_frame->domWindow(); + if (!window) { + timeouts.clear(); + return; + } + window->resumeTimeouts(timeouts); +} + +ScriptController::ScriptController(Frame* frame) + : m_frame(frame) + , m_sourceURL(0) + , m_processingTimerCallback(false) + , m_paused(false) + , m_proxy(new V8Proxy(frame)) +#if ENABLE(NETSCAPE_PLUGIN_API) + , m_windowScriptNPObject(0) +#endif +{ +} + +ScriptController::~ScriptController() +{ +} + +void ScriptController::clearScriptObjects() +{ + // TODO(eseidel): JSC handles binding root objects here, why don't we? + +#if ENABLE(NETSCAPE_PLUGIN_API) + if (m_windowScriptNPObject) { + // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window + // script object properly. + // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point. + _NPN_DeallocateObject(m_windowScriptNPObject); + m_windowScriptNPObject = 0; + } +#endif +} + +void ScriptController::clearPluginObjects() +{ + PluginObjectMap::iterator it = m_pluginObjects.begin(); + for (; it != m_pluginObjects.end(); ++it) { + _NPN_UnregisterObject(it->second); + NPN_ReleaseObject(it->second); + } + m_pluginObjects.clear(); +} + +// Disconnect the proxy from its owner frame; +void ScriptController::disconnectFrame() +{ + m_proxy->disconnectFrame(); +} + +bool ScriptController::processingUserGesture() const +{ + Frame* active_frame = V8Proxy::retrieveActiveFrame(); + // No script is running, must be run by users. + if (!active_frame) + return true; + + V8Proxy* active_proxy = active_frame->script()->proxy(); + + v8::HandleScope handle_scope; + v8::Handle<v8::Context> context = V8Proxy::GetContext(active_frame); + // TODO(fqian): find all cases context can be empty: + // 1) JS is disabled; + // 2) page is NULL; + if (context.IsEmpty()) + return true; + + v8::Context::Scope scope(context); + + v8::Handle<v8::Object> global = context->Global(); + v8::Handle<v8::Value> jsevent = global->Get(v8::String::NewSymbol("event")); + Event* event = V8Proxy::ToNativeEvent(jsevent); + + // Based on code from kjs_bindings.cpp. + // Note: This is more liberal than Firefox's implementation. + if (event) { + const AtomicString& type = event->type(); + bool event_ok = + // mouse events + type == EventNames::clickEvent || + type == EventNames::mousedownEvent || + type == EventNames::mouseupEvent || + type == EventNames::dblclickEvent || + // keyboard events + type == EventNames::keydownEvent || + type == EventNames::keypressEvent || + type == EventNames::keyupEvent || + // other accepted events + type == EventNames::selectEvent || + type == EventNames::changeEvent || + type == EventNames::focusEvent || + type == EventNames::blurEvent || + type == EventNames::submitEvent; + + if (event_ok) + return true; + } else if (active_proxy->inlineCode() && !active_proxy->timerCallback()) + // This is the <a href="javascript:window.open('...')> case -> we let it + // through + return true; + + // This is the <script>window.open(...)</script> case or a timer callback -> + // block it + return false; +} + + +// Evaluate a script file in the environment of this proxy. +String ScriptController::evaluate(const String& filename, int baseLine, + const String& code, Node* node, bool* succ) +{ + if (succ) + *succ = false; + String result; + + v8::HandleScope hs; + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame()); + if (context.IsEmpty()) + return result; + + v8::Context::Scope scope(context); + + // HTMLTokenizer used to use base zero line numbers for scripts, now it + // uses base 1. This confuses v8, which uses line offsets from the + // first line. + v8::Local<v8::Value> obj = m_proxy->Evaluate(filename, baseLine - 1, code, + node); + + if (obj.IsEmpty() || obj->IsUndefined()) + return result; + + // If the return value is not a string, return 0 (what KJS does). + if (!obj->IsString()) { + v8::TryCatch exception_block; + obj = obj->ToString(); + if (exception_block.HasCaught()) + obj = v8::String::New(""); + } + + result = ToWebCoreString(obj); + if (succ) + *succ = true; + + return result; +} + +v8::Persistent<v8::Value> ScriptController::evaluate(const String& filename, + int baseLine, + const String& code, + Node* node) +{ + v8::HandleScope hs; + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame()); + if (context.IsEmpty()) + return v8::Persistent<v8::Value>(); + + v8::Context::Scope scope(context); + + v8::Local<v8::Value> obj = m_proxy->Evaluate(filename, baseLine, code, node); + + if (obj.IsEmpty()) + return v8::Persistent<v8::Value>(); + + // TODO(fqian): keep track the global handle created. + return v8::Persistent<v8::Value>::New(obj); +} + +void ScriptController::disposeJSResult(v8::Persistent<v8::Value> result) +{ + result.Dispose(); + result.Clear(); +} + +EventListener* ScriptController::createHTMLEventHandler( + const String& functionName, const String& code, Node* node) +{ + return m_proxy->createHTMLEventHandler(functionName, code, node); +} + +#if ENABLE(SVG) +EventListener* ScriptController::createSVGEventHandler( + const String& functionName, const String& code, Node* node) +{ + return m_proxy->createSVGEventHandler(functionName, code, node); +} +#endif + +void ScriptController::setEventHandlerLineno(int lineno) +{ + m_proxy->setEventHandlerLineno(lineno); +} + +void ScriptController::finishedWithEvent(Event* evt) +{ + m_proxy->finishedWithEvent(evt); +} + +void ScriptController::clearDocumentWrapper() +{ + m_proxy->clearDocumentWrapper(); +} + +// Create a V8 object with an interceptor of NPObjectPropertyGetter +void ScriptController::BindToWindowObject(Frame* frame, const String& key, NPObject* object) +{ + v8::HandleScope handle_scope; + + v8::Handle<v8::Context> context = V8Proxy::GetContext(frame); + if (context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + v8::Handle<v8::Object> value = CreateV8ObjectForNPObject(object, NULL); + + // Attach to the global object + v8::Handle<v8::Object> global = context->Global(); + global->Set(v8String(key), value); +} + +void ScriptController::collectGarbage() +{ + v8::HandleScope hs; + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame()); + if (context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + m_proxy->Evaluate("", 0, "if (window.gc) void(gc());", NULL); +} + +NPRuntimeFunctions* ScriptController::functions() +{ + return &npruntime_functions; +} + + +bool ScriptController::haveInterpreter() const +{ + return m_proxy->ContextInitialized(); +} + +bool ScriptController::isEnabled() const +{ + return m_proxy->isEnabled(); +} + +JSInstance ScriptController::createScriptInstanceForWidget(Widget* widget) +{ + ASSERT(widget != 0); + + if (widget->isFrameView()) + return JSInstanceHolder::EmptyInstance(); + + // Note: We have to trust that the widget passed to us here + // is a WebPluginImpl. There isn't a way to dynamically verify + // it, since the derived class (Widget) has no identifier. + WebPluginContainer* container = static_cast<WebPluginContainer*>(widget); + if (!container) + return JSInstanceHolder::EmptyInstance(); + + NPObject* npObject = container->GetPluginScriptableObject(); + if (!npObject) + return JSInstanceHolder::EmptyInstance(); + +#if USE(JSC) + // Register 'widget' with the frame so that we can teardown + // subobjects when the container goes away. + RefPtr<KJS::Bindings::RootObject> root = script()->createRootObject(widget); + KJS::Bindings::Instance* instance = + KJS::Bindings::Instance::createBindingForLanguageInstance( + KJS::Bindings::Instance::CLanguage, npObject, + root.release()); + // GetPluginScriptableObject returns a retained NPObject. + // The caller is expected to release it. + NPN_ReleaseObject(npObject); + return instance; +#elif USE(V8) + // Frame Memory Management for NPObjects + // ------------------------------------- + // NPObjects are treated differently than other objects wrapped by JS. + // NPObjects are not Peerable, and cannot be made peerable, since 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, NULL); + + // Track the plugin object. We've been given a reference to the object. + m_pluginObjects.set(widget, npObject); + + JSInstance instance = wrapper; + return instance; +#endif +} + +void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle) +{ + PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle); + if (it == m_pluginObjects.end()) + return; + _NPN_UnregisterObject(it->second); + NPN_ReleaseObject(it->second); + m_pluginObjects.remove(it); +} + +static NPObject* createNoScriptObject() +{ + notImplemented(); + return 0; +} + +static NPObject* createScriptObject(Frame* frame) +{ + v8::HandleScope handleScope; + v8::Handle<v8::Context> context = V8Proxy::GetContext(frame); + if (context.IsEmpty()) + return createNoScriptObject(); + + v8::Context::Scope scope(context); + DOMWindow* window = frame->domWindow(); + v8::Handle<v8::Value> global = V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, window); + ASSERT(global->IsObject()); + return NPN_CreateScriptObject(0, v8::Handle<v8::Object>::Cast(global), window); +} + +NPObject* ScriptController::windowScriptNPObject() +{ + if (m_windowScriptNPObject) + return m_windowScriptNPObject; + + if (isEnabled()) { + // JavaScript is enabled, so there is a JavaScript window object. + // Return an NPObject bound to the window object. + m_windowScriptNPObject = createScriptObject(m_frame); + _NPN_RegisterObject(m_windowScriptNPObject, NULL); + } else { + // JavaScript is not enabled, so we cannot bind the NPObject to the + // JavaScript window object. Instead, we create an NPObject of a + // different class, one which is not bound to a JavaScript object. + m_windowScriptNPObject = createNoScriptObject(); + } + return m_windowScriptNPObject; +} + +NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin) +{ + // Can't create NPObjects when JavaScript is disabled + if (!isEnabled()) + return createNoScriptObject(); + + v8::HandleScope handleScope; + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame); + if (context.IsEmpty()) + return createNoScriptObject(); + v8::Context::Scope scope(context); + + DOMWindow* window = m_frame->domWindow(); + v8::Handle<v8::Value> v8plugin = V8Proxy::ToV8Object(V8ClassIndex::HTMLEMBEDELEMENT, plugin); + if (!v8plugin->IsObject()) + return createNoScriptObject(); + + return NPN_CreateScriptObject(0, v8::Handle<v8::Object>::Cast(v8plugin), window); +} + + +void ScriptController::clearWindowShell() +{ + // TODO(eseidel): we don't yet have a split window implementation + // we need to clear the window object here. + m_proxy->clear(); +} + +void ScriptController::attachDebugger(void*) +{ + notImplemented(); +} + +void ScriptController::updateDocument() +{ + // TODO(eseidel): Should update document property on current window object + // and all previous window objects which may still be alive. + notImplemented(); +} + + +JSInstanceHolder::JSInstanceHolder() +{ +} + +JSInstanceHolder::JSInstanceHolder(JSInstance instance) +{ + *this = instance; +} + +JSInstanceHolder::~JSInstanceHolder() +{ + Clear(); +} + +bool JSInstanceHolder::IsEmpty() +{ + return m_instance.IsEmpty(); +} + +JSInstance JSInstanceHolder::Get() +{ + return v8::Local<v8::Object>::New(m_instance); +} + +void JSInstanceHolder::Clear() +{ + if (m_instance.IsEmpty()) + return; + v8::HandleScope scope; + v8::Persistent<v8::Object> handle(m_instance); +#ifndef NDEBUG + V8Proxy::UnregisterGlobalHandle(this, handle); +#endif + handle.Dispose(); + m_instance.Clear(); +} + +JSInstance JSInstanceHolder::EmptyInstance() +{ + return v8::Local<v8::Object>(); +} + +JSInstanceHolder& JSInstanceHolder::operator=(JSInstance instance) +{ + Clear(); + if (instance.IsEmpty()) + return *this; + + v8::Persistent<v8::Object> handle = + v8::Persistent<v8::Object>::New(instance); + m_instance = handle; +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(JSINSTANCE, this, handle); +#endif + return *this; +} + +} // namespace WebCpre diff --git a/webkit/port/bridge/V8Bridge.cpp b/webkit/port/bridge/V8Bridge.cpp deleted file mode 100644 index a3a51ae..0000000 --- a/webkit/port/bridge/V8Bridge.cpp +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#define max max // windef.h overrides this, and it breaks us. -#include "config.h" -#include "V8Bridge.h" -#include "v8_proxy.h" -#include "v8_binding.h" -#include "CString.h" -#include "Event.h" -#include "EventNames.h" -#include "Frame.h" -#include "Node.h" -#include "DOMWindow.h" -#include "Document.h" -#include "np_v8object.h" -#include "v8_npobject.h" - -NPRuntimeFunctions npruntime_functions = { - NPN_GetStringIdentifier, - NPN_GetStringIdentifiers, - NPN_GetIntIdentifier, - NPN_IdentifierIsString, - NPN_UTF8FromIdentifier, - NPN_IntFromIdentifier, - NPN_CreateObject, - NPN_RetainObject, - NPN_ReleaseObject, - NPN_Invoke, - NPN_InvokeDefault, - NPN_Evaluate, - NPN_GetProperty, - NPN_SetProperty, - NPN_RemoveProperty, - NPN_HasProperty, - NPN_HasMethod, - NPN_ReleaseVariantValue, - NPN_SetException -}; - - - -namespace WebCore { - -bool JSBridge::m_recordPlaybackMode = false; - -// Implements static function declared in JSBridge. -void JSBridge::setFlags(const char* str, int length) { - v8::V8::SetFlagsFromString(str, length); -} - -// static -void JSBridge::setDomain(Frame* frame, const String&) { - V8Proxy::DomainChanged(frame); -} - -// static -Frame* JSBridge::retrieveActiveFrame() { - return V8Proxy::retrieveActiveFrame(); -} - -// static -bool JSBridge::isSafeScript(Frame* target) { - return V8Proxy::IsFromSameOrigin(target, true); -} - -// static -void JSBridge::gcProtectJSWrapper(void* dom_object) { - V8Proxy::GCProtect(static_cast<Peerable*>(dom_object)); -} - -// static -void JSBridge::gcUnprotectJSWrapper(void* dom_object) { - V8Proxy::GCUnprotect(static_cast<Peerable*>(dom_object)); -} - -// static -JSException JSBridge::NoException() { - return v8::Local<v8::Value>(); -} - -// static -bool JSBridge::IsException(JSException exception) { - return !exception.IsEmpty(); -} - -// static -PausedTimeouts* JSBridge::pauseTimeouts(Frame* frame) { - if (!frame) return NULL; - DOMWindow* window = frame->domWindow(); - if (!window) return NULL; - return window->pauseTimeouts(); -} - -// static -void JSBridge::resumeTimeouts(Frame* frame, PausedTimeouts* timeouts) { - if (!frame) return; - DOMWindow* window = frame->domWindow(); - if (!window) return; - window->resumeTimeouts(timeouts); -} - - -// --------------------------------------------------------------------------- -// V8 implementation of JSBridge. - -V8Bridge::V8Bridge(Frame* frame) { - m_proxy = new V8Proxy(frame); -} - -V8Bridge::~V8Bridge() { - delete m_proxy; -} - -// Disconnect the proxy from its owner frame; -void V8Bridge::disconnectFrame() { - m_proxy->disconnectFrame(); -} - -bool V8Bridge::wasRunByUserGesture() { - Frame* active_frame = V8Proxy::retrieveActiveFrame(); - // No script is running, must be run by users. - if (!active_frame) - return true; - - V8Proxy* active_proxy = - static_cast<V8Bridge*>(active_frame->scriptBridge())->proxy(); - - v8::HandleScope handle_scope; - v8::Handle<v8::Context> context = V8Proxy::GetContext(active_frame); - // TODO(fqian): find all cases context can be empty: - // 1) JS is disabled; - // 2) page is NULL; - if (context.IsEmpty()) - return true; - - v8::Context::Scope scope(context); - - v8::Handle<v8::Object> global = context->Global(); - v8::Handle<v8::Value> jsevent = global->Get(v8::String::NewSymbol("event")); - Event* event = V8Proxy::ToNativeEvent(jsevent); - - // Based on code from kjs_bindings.cpp. - // Note: This is more liberal than Firefox's implementation. - if (event) { - const AtomicString& type = event->type(); - bool event_ok = - // mouse events - type == EventNames::clickEvent || - type == EventNames::mousedownEvent || - type == EventNames::mouseupEvent || - type == EventNames::dblclickEvent || - // keyboard events - type == EventNames::keydownEvent || - type == EventNames::keypressEvent || - type == EventNames::keyupEvent || - // other accepted events - type == EventNames::selectEvent || - type == EventNames::changeEvent || - type == EventNames::focusEvent || - type == EventNames::blurEvent || - type == EventNames::submitEvent; - - if (event_ok) - return true; - } else { // no event - if (active_proxy->inlineCode() && - !active_proxy->timerCallback()) { - // This is the <a href="javascript:window.open('...')> case -> we let it - // through - return true; - } - // This is the <script>window.open(...)</script> case or a timer callback -> - // block it - } - - return false; -} - - -// Evaluate a script file in the environment of this proxy. Used for -// evaluating the code in script tags and for evaluating the code from -// javascript URLs. -String V8Bridge::evaluate(const String& filename, int baseLine, - const String& code, Node* node, bool* succ) { - *succ = false; - String result; - - v8::HandleScope hs; - v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame()); - if (context.IsEmpty()) - return result; - - v8::Context::Scope scope(context); - - v8::Local<v8::Value> obj; - { - // Isolate exceptions that occur when executing the code. These - // exceptions should not interfere with javascript code we might - // evaluate from C++ when returning from here. - v8::TryCatch exception_block; - exception_block.SetVerbose(true); - obj = m_proxy->Evaluate(filename, baseLine, code, node); - } - - if (obj.IsEmpty() || obj->IsUndefined()) - return result; - - // If the return value is not a string, return 0 (what KJS does). - if (!obj->IsString()) { - v8::TryCatch exception_block; - obj = obj->ToString(); - if (exception_block.HasCaught()) - obj = v8::String::New(""); - } - - result = ToWebCoreString(obj); - *succ = true; - - return result; -} - -v8::Persistent<v8::Value> V8Bridge::evaluate(const String& filename, - int baseLine, - const String& code, - Node* node) { - v8::HandleScope hs; - v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame()); - if (context.IsEmpty()) - return v8::Persistent<v8::Value>(); - - v8::Context::Scope scope(context); - - v8::Local<v8::Value> obj = m_proxy->Evaluate(filename, baseLine, code, node); - - if (obj.IsEmpty()) return v8::Persistent<v8::Value>(); - - // TODO(fqian): keep track the global handle created. - return v8::Persistent<v8::Value>::New(obj); -} - -void V8Bridge::disposeJSResult(v8::Persistent<v8::Value> result) { - result.Dispose(); - result.Clear(); -} - -EventListener* V8Bridge::createHTMLEventHandler( - const String& functionName, const String& code, Node* node) { - return m_proxy->createHTMLEventHandler(functionName, code, node); -} - -#if ENABLE(SVG) -EventListener* V8Bridge::createSVGEventHandler( - const String& functionName, const String& code, Node* node) { - return m_proxy->createSVGEventHandler(functionName, code, node); -} -#endif - -void V8Bridge::setEventHandlerLineno(int lineno) { - m_proxy->setEventHandlerLineno(lineno); -} - -void V8Bridge::finishedWithEvent(Event* evt) { - m_proxy->finishedWithEvent(evt); -} - -void V8Bridge::clear() { - m_proxy->clear(); -} - -void V8Bridge::clearDocumentWrapper() { - m_proxy->clearDocumentWrapper(); -} - -// Create a V8 object with an interceptor of NPObjectPropertyGetter -void V8Bridge::BindToWindowObject(Frame* frame, const String& key, - NPObject* object) { - v8::HandleScope handle_scope; - - v8::Handle<v8::Context> context = V8Proxy::GetContext(frame); - if (context.IsEmpty()) - return; - - v8::Context::Scope scope(context); - - v8::Handle<v8::Object> value = CreateV8ObjectForNPObject(object, NULL); - - // Attach to the global object - v8::Handle<v8::Object> global = context->Global(); - global->Set(v8String(key), value); -} - - -void V8Bridge::CollectGarbage() { - v8::HandleScope hs; - v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame()); - if (context.IsEmpty()) return; - - v8::Context::Scope scope(context); - - m_proxy->Evaluate("", 0, "if (window.gc) void(gc());", NULL); -} - - -NPRuntimeFunctions *V8Bridge::functions() { - return &npruntime_functions; -} - - -NPObject *V8Bridge::CreateScriptObject(Frame* frame) { - v8::HandleScope handle_scope; - v8::Handle<v8::Context> context = V8Proxy::GetContext(frame); - if (context.IsEmpty()) - return 0; - - v8::Context::Scope scope(context); - DOMWindow *window = frame->domWindow(); - v8::Handle<v8::Value> global = - V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, window); - ASSERT(global->IsObject()); - return NPN_CreateScriptObject(0, v8::Handle<v8::Object>::Cast(global), - window); -} - -NPObject *V8Bridge::CreateScriptObject(Frame* frame, - HTMLPlugInElement* element) { - v8::HandleScope handle_scope; - v8::Handle<v8::Context> context = V8Proxy::GetContext(frame); - if (context.IsEmpty()) - return 0; - v8::Context::Scope scope(context); - - DOMWindow *window = frame->domWindow(); - v8::Handle<v8::Value> dom_win = - V8Proxy::ToV8Object(V8ClassIndex::HTMLEMBEDELEMENT, element); - if (dom_win->IsObject()) { - return NPN_CreateScriptObject(0, v8::Handle<v8::Object>::Cast(dom_win), - window); - } else { - return 0; - } -} - -NPObject *V8Bridge::CreateNoScriptObject() { - return 0; // implement me -} - -bool V8Bridge::haveInterpreter() const { - return m_proxy->ContextInitialized(); -} - -bool V8Bridge::isEnabled() const { - return m_proxy->isEnabled(); -} - -JSInstanceHolder::JSInstanceHolder() : m_instance() { } - -JSInstanceHolder::JSInstanceHolder(JSInstance instance) { - *this = instance; -} - -JSInstanceHolder::~JSInstanceHolder() { - Clear(); -} - -bool JSInstanceHolder::IsEmpty() { - return m_instance.IsEmpty(); -} - -JSInstance JSInstanceHolder::Get() { - return v8::Local<v8::Object>::New(m_instance); -} - -void JSInstanceHolder::Clear() { - if (!m_instance.IsEmpty()) { - v8::HandleScope scope; - v8::Persistent<v8::Object> handle(m_instance); -#ifndef NDEBUG - V8Proxy::UnregisterGlobalHandle(this, handle); -#endif - handle.Dispose(); - m_instance.Clear(); - } -} - -JSInstance JSInstanceHolder::EmptyInstance() { - return v8::Local<v8::Object>(); -} - -JSInstanceHolder& JSInstanceHolder::operator=(JSInstance instance) { - Clear(); - if (!instance.IsEmpty()) { - v8::Persistent<v8::Object> handle = - v8::Persistent<v8::Object>::New(instance); - m_instance = handle; -#ifndef NDEBUG - V8Proxy::RegisterGlobalHandle(JSINSTANCE, this, handle); -#endif - } - return *this; -} - -} // namespace WebCpre diff --git a/webkit/port/bridge/V8Bridge.h b/webkit/port/bridge/V8Bridge.h deleted file mode 100644 index 12458f6..0000000 --- a/webkit/port/bridge/V8Bridge.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains V8 specific bits that's necessary to build WebKit. - -#ifndef V8_BRIDGE_H__ -#define V8_BRIDGE_H__ - -#include "v8.h" -#include "JSBridge.h" - -namespace WebCore { -class Frame; -class Node; -class V8Proxy; - -class V8Bridge : public JSBridge { - public: - explicit V8Bridge(Frame* frame); - virtual ~V8Bridge(); - - virtual void disconnectFrame(); - virtual bool wasRunByUserGesture(); - // Evaluate a script file in the environment of this proxy. - // When succeed, sets the 'succ' parameter to true and - // returns the result as a string. - virtual String evaluate(const String& filename, int baseLine, - const String& code, Node* node, bool* succ); - - // Evaluate a script in the environment of this proxy. - // Returns a v8::Persistent handle. If the evaluation fails, - // it returns an empty handle. The caller must check - // whether the return value is empty. - virtual JSResult evaluate(const String& filename, int baseLine, - const String& code, Node* node); - virtual void disposeJSResult(JSResult result); - - virtual EventListener* createHTMLEventHandler(const String& functionName, - const String& code, Node* node); -#if ENABLE(SVG) - virtual EventListener* createSVGEventHandler(const String& functionName, - const String& code, Node* node); -#endif - virtual void setEventHandlerLineno(int lineno); - virtual void finishedWithEvent(Event* evt); - virtual void clear(); - - V8Proxy* proxy() { return m_proxy; } - - // virtual JSRootObject *getRootObject(); - - virtual void BindToWindowObject(Frame* frame, const String& key, - NPObject* object); - virtual NPRuntimeFunctions *functions(); - virtual NPObject *CreateScriptObject(Frame* frame); - virtual NPObject *CreateScriptObject(Frame* frame, HTMLPlugInElement* pe); - virtual NPObject *CreateNoScriptObject(); - - virtual bool haveInterpreter() const; - virtual bool isEnabled() const; - - virtual void clearDocumentWrapper(); - - virtual void CollectGarbage(); - - private: - V8Proxy* m_proxy; -}; - -} // namespace WebCore -#endif // V8_BRIDGE_H__ - |