| OLD | NEW | 
 | (Empty) | 
|    1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |  | 
|    2 // Use of this source code is governed by a BSD-style license that can be |  | 
|    3 // found in the LICENSE file. |  | 
|    4  |  | 
|    5 #ifndef V8_PROXY_H__ |  | 
|    6 #define V8_PROXY_H__ |  | 
|    7  |  | 
|    8 #include <v8.h> |  | 
|    9 #include "v8_utility.h" |  | 
|   10 #include "ChromiumBridge.h" |  | 
|   11 #include "Node.h" |  | 
|   12 #include "NodeFilter.h" |  | 
|   13 #include "PlatformString.h"  // for WebCore::String |  | 
|   14 #include "ScriptSourceCode.h"  // for WebCore::ScriptSourceCode |  | 
|   15 #include "SecurityOrigin.h"  // for WebCore::SecurityOrigin |  | 
|   16 #include "V8CustomBinding.h" |  | 
|   17 #include "V8DOMMap.h" |  | 
|   18 #include "V8EventListenerList.h" |  | 
|   19 #include "V8Index.h" |  | 
|   20 #include <wtf/Assertions.h> |  | 
|   21 #include <wtf/PassRefPtr.h> // so generated bindings don't have to |  | 
|   22 #include <wtf/Vector.h> |  | 
|   23  |  | 
|   24 #include <iterator> |  | 
|   25 #include <list> |  | 
|   26  |  | 
|   27 #ifdef ENABLE_DOM_STATS_COUNTERS |  | 
|   28 #define INC_STATS(name) ChromiumBridge::incrementStatsCounter(name) |  | 
|   29 #else |  | 
|   30 #define INC_STATS(name) |  | 
|   31 #endif |  | 
|   32  |  | 
|   33 // FIXME: Remove the following hack when we replace all references to GetDOMObje
     ctMap. |  | 
|   34 #define GetDOMObjectMap getDOMObjectMap |  | 
|   35  |  | 
|   36 namespace WebCore { |  | 
|   37  |  | 
|   38 class CSSStyleDeclaration; |  | 
|   39 class ClientRectList; |  | 
|   40 class DOMImplementation; |  | 
|   41 class Element; |  | 
|   42 class Event; |  | 
|   43 class EventListener; |  | 
|   44 class Frame; |  | 
|   45 class HTMLCollection; |  | 
|   46 class HTMLOptionsCollection; |  | 
|   47 class HTMLElement; |  | 
|   48 class HTMLDocument; |  | 
|   49 class MediaList; |  | 
|   50 class NamedNodeMap; |  | 
|   51 class Node; |  | 
|   52 class NodeList; |  | 
|   53 class Screen; |  | 
|   54 class String; |  | 
|   55 class StyleSheet; |  | 
|   56 class SVGElement; |  | 
|   57 class DOMWindow; |  | 
|   58 class Document; |  | 
|   59 class EventTarget; |  | 
|   60 class Event; |  | 
|   61 class EventListener; |  | 
|   62 class Navigator; |  | 
|   63 class MimeType; |  | 
|   64 class MimeTypeArray; |  | 
|   65 class Plugin; |  | 
|   66 class PluginArray; |  | 
|   67 class StyleSheetList; |  | 
|   68 class CSSValue; |  | 
|   69 class CSSRule; |  | 
|   70 class CSSRuleList; |  | 
|   71 class CSSValueList; |  | 
|   72 class NodeFilter; |  | 
|   73 class ScriptExecutionContext; |  | 
|   74  |  | 
|   75 #if ENABLE(DOM_STORAGE) |  | 
|   76 class Storage; |  | 
|   77 class StorageEvent; |  | 
|   78 #endif |  | 
|   79  |  | 
|   80 #if ENABLE(SVG) |  | 
|   81 class SVGElementInstance; |  | 
|   82 #endif |  | 
|   83  |  | 
|   84 class V8EventListener; |  | 
|   85 class V8ObjectEventListener; |  | 
|   86  |  | 
|   87  |  | 
|   88 // TODO(fqian): use standard logging facilities in WebCore. |  | 
|   89 void log_info(Frame* frame, const String& msg, const String& url); |  | 
|   90  |  | 
|   91  |  | 
|   92 #ifndef NDEBUG |  | 
|   93  |  | 
|   94 #define GlobalHandleTypeList(V) \ |  | 
|   95   V(PROXY)                      \ |  | 
|   96   V(NPOBJECT)                   \ |  | 
|   97   V(SCHEDULED_ACTION)           \ |  | 
|   98   V(EVENT_LISTENER)             \ |  | 
|   99   V(NODE_FILTER)                \ |  | 
|  100   V(SCRIPTINSTANCE)             \ |  | 
|  101   V(SCRIPTVALUE) |  | 
|  102  |  | 
|  103  |  | 
|  104 // Host information of persistent handles. |  | 
|  105 enum GlobalHandleType { |  | 
|  106 #define ENUM(name) name, |  | 
|  107   GlobalHandleTypeList(ENUM) |  | 
|  108 #undef ENUM |  | 
|  109 }; |  | 
|  110  |  | 
|  111  |  | 
|  112 class GlobalHandleInfo { |  | 
|  113  public: |  | 
|  114   GlobalHandleInfo(void* host, GlobalHandleType type) |  | 
|  115       : host_(host), type_(type) { } |  | 
|  116   void* host_; |  | 
|  117   GlobalHandleType type_; |  | 
|  118 }; |  | 
|  119  |  | 
|  120 #endif  // NDEBUG |  | 
|  121  |  | 
|  122 // The following Batch structs and methods are used for setting multiple |  | 
|  123 // properties on an ObjectTemplate, used from the generated bindings |  | 
|  124 // initialization (ConfigureXXXTemplate).  This greatly reduces the binary |  | 
|  125 // size by moving from code driven setup to data table driven setup. |  | 
|  126  |  | 
|  127 // BatchedAttribute translates into calls to SetAccessor() on either the |  | 
|  128 // instance or the prototype ObjectTemplate, based on |on_proto|. |  | 
|  129 struct BatchedAttribute { |  | 
|  130   const char* const name; |  | 
|  131   v8::AccessorGetter getter; |  | 
|  132   v8::AccessorSetter setter; |  | 
|  133   V8ClassIndex::V8WrapperType data; |  | 
|  134   v8::AccessControl settings; |  | 
|  135   v8::PropertyAttribute attribute; |  | 
|  136   bool on_proto; |  | 
|  137 }; |  | 
|  138  |  | 
|  139 void BatchConfigureAttributes(v8::Handle<v8::ObjectTemplate> inst, |  | 
|  140                               v8::Handle<v8::ObjectTemplate> proto, |  | 
|  141                               const BatchedAttribute* attrs, |  | 
|  142                               size_t num_attrs); |  | 
|  143  |  | 
|  144 // BatchedConstant translates into calls to Set() for setting up an object's |  | 
|  145 // constants.  It sets the constant on both the FunctionTemplate |desc| and the |  | 
|  146 // ObjectTemplate |proto|.  PropertyAttributes is always ReadOnly. |  | 
|  147 struct BatchedConstant { |  | 
|  148   const char* const name; |  | 
|  149   int value; |  | 
|  150 }; |  | 
|  151  |  | 
|  152 void BatchConfigureConstants(v8::Handle<v8::FunctionTemplate> desc, |  | 
|  153                              v8::Handle<v8::ObjectTemplate> proto, |  | 
|  154                              const BatchedConstant* consts, |  | 
|  155                              size_t num_consts); |  | 
|  156  |  | 
|  157 const int kMaxRecursionDepth = 20; |  | 
|  158  |  | 
|  159 // Information about an extension that is registered for use with V8. If scheme |  | 
|  160 // is non-empty, it contains the URL scheme the extension should be used with. |  | 
|  161 // Otherwise, the extension is used with all schemes. |  | 
|  162 struct V8ExtensionInfo { |  | 
|  163   String scheme; |  | 
|  164   v8::Extension* extension; |  | 
|  165 }; |  | 
|  166 typedef std::list<V8ExtensionInfo> V8ExtensionList; |  | 
|  167  |  | 
|  168 class V8Proxy { |  | 
|  169  public: |  | 
|  170   // The types of javascript errors that can be thrown. |  | 
|  171   enum ErrorType { |  | 
|  172     RANGE_ERROR, |  | 
|  173     REFERENCE_ERROR, |  | 
|  174     SYNTAX_ERROR, |  | 
|  175     TYPE_ERROR, |  | 
|  176     GENERAL_ERROR |  | 
|  177   }; |  | 
|  178  |  | 
|  179   explicit V8Proxy(Frame* frame) |  | 
|  180       : m_frame(frame), m_inlineCode(false), |  | 
|  181         m_timerCallback(false), m_recursion(0) { } |  | 
|  182  |  | 
|  183   ~V8Proxy(); |  | 
|  184  |  | 
|  185   Frame* frame() { return m_frame; } |  | 
|  186  |  | 
|  187   // Clear page-specific data, but keep the global object identify. |  | 
|  188   void clearForNavigation(); |  | 
|  189  |  | 
|  190   // Clear page-specific data before shutting down the proxy object. |  | 
|  191   void clearForClose(); |  | 
|  192  |  | 
|  193   // Update document object of the frame. |  | 
|  194   void updateDocument(); |  | 
|  195  |  | 
|  196   // Update the security origin of a document |  | 
|  197   // (e.g., after setting docoument.domain). |  | 
|  198   void updateSecurityOrigin(); |  | 
|  199  |  | 
|  200   // Destroy the global object. |  | 
|  201   void DestroyGlobal(); |  | 
|  202  |  | 
|  203   // TODO(mpcomplete): Need comment.  User Gesture related. |  | 
|  204   bool inlineCode() const { return m_inlineCode; } |  | 
|  205   void setInlineCode(bool value) { m_inlineCode = value; } |  | 
|  206  |  | 
|  207   bool timerCallback() const { return m_timerCallback; } |  | 
|  208   void setTimerCallback(bool value) { m_timerCallback = value; } |  | 
|  209  |  | 
|  210   // Has the context for this proxy been initialized? |  | 
|  211   bool ContextInitialized(); |  | 
|  212  |  | 
|  213   // Disconnects the proxy from its owner frame, |  | 
|  214   // and clears all timeouts on the DOM window. |  | 
|  215   void disconnectFrame(); |  | 
|  216  |  | 
|  217   bool isEnabled(); |  | 
|  218  |  | 
|  219   // Find/Create/Remove event listener wrappers. |  | 
|  220   PassRefPtr<V8EventListener> FindV8EventListener(v8::Local<v8::Value> listener, |  | 
|  221                                        bool html); |  | 
|  222   PassRefPtr<V8EventListener> FindOrCreateV8EventListener(v8::Local<v8::Value> l
     istener, |  | 
|  223                                                bool html); |  | 
|  224  |  | 
|  225   PassRefPtr<V8EventListener> FindObjectEventListener(v8::Local<v8::Value> liste
     ner, |  | 
|  226                                         bool html); |  | 
|  227   PassRefPtr<V8EventListener> FindOrCreateObjectEventListener(v8::Local<v8::Valu
     e> listener, |  | 
|  228                                                 bool html); |  | 
|  229  |  | 
|  230   void RemoveV8EventListener(V8EventListener* listener); |  | 
|  231   void RemoveObjectEventListener(V8ObjectEventListener* listener); |  | 
|  232  |  | 
|  233   // Protect/Unprotect JS wrappers of a DOM object. |  | 
|  234   static void GCProtect(void* dom_object); |  | 
|  235   static void GCUnprotect(void* dom_object); |  | 
|  236  |  | 
|  237 #if ENABLE(SVG) |  | 
|  238   static void SetSVGContext(void* object, SVGElement* context); |  | 
|  239   static SVGElement* GetSVGContext(void* object); |  | 
|  240 #endif |  | 
|  241  |  | 
|  242   void setEventHandlerLineno(int lineno) { m_handlerLineno = lineno; } |  | 
|  243   void finishedWithEvent(Event* event) { } |  | 
|  244  |  | 
|  245   // Evaluate JavaScript in a new isolated world. The script gets its own |  | 
|  246   // global scope, its own prototypes for intrinsic JavaScript objects (String, |  | 
|  247   // Array, and so-on), and its own wrappers for all DOM nodes and DOM |  | 
|  248   // constructors. |  | 
|  249   void evaluateInNewWorld(const Vector<ScriptSourceCode>& sources); |  | 
|  250  |  | 
|  251   // Evaluate JavaScript in a new context. The script gets its own global scope |  | 
|  252   // and its own prototypes for intrinsic JavaScript objects (String, Array, |  | 
|  253   // and so-on). It shares the wrappers for all DOM nodes and DOM constructors. |  | 
|  254   void evaluateInNewContext(const Vector<ScriptSourceCode>& sources); |  | 
|  255  |  | 
|  256   // Evaluate a script file in the current execution environment. |  | 
|  257   // The caller must hold an execution context. |  | 
|  258   // If cannot evalute the script, it returns an error. |  | 
|  259   v8::Local<v8::Value> evaluate(const ScriptSourceCode& source, |  | 
|  260                                 Node* node); |  | 
|  261  |  | 
|  262   // Run an already compiled script. |  | 
|  263   v8::Local<v8::Value> RunScript(v8::Handle<v8::Script> script, |  | 
|  264                                  bool inline_code); |  | 
|  265  |  | 
|  266   // Call the function with the given receiver and arguments. |  | 
|  267   v8::Local<v8::Value> CallFunction(v8::Handle<v8::Function> function, |  | 
|  268                                     v8::Handle<v8::Object> receiver, |  | 
|  269                                     int argc, |  | 
|  270                                     v8::Handle<v8::Value> argv[]); |  | 
|  271  |  | 
|  272   // Call the function as constructor with the given arguments. |  | 
|  273   v8::Local<v8::Value> NewInstance(v8::Handle<v8::Function> constructor, |  | 
|  274                                    int argc, |  | 
|  275                                    v8::Handle<v8::Value> argv[]); |  | 
|  276  |  | 
|  277   // Returns the dom constructor function for the given node type. |  | 
|  278   v8::Local<v8::Function> GetConstructor(V8ClassIndex::V8WrapperType type); |  | 
|  279  |  | 
|  280   // To create JS Wrapper objects, we create a cache of a 'boiler plate' |  | 
|  281   // object, and then simply Clone that object each time we need a new one. |  | 
|  282   // This is faster than going through the full object creation process. |  | 
|  283   v8::Local<v8::Object> CreateWrapperFromCache(V8ClassIndex::V8WrapperType type)
     ; |  | 
|  284  |  | 
|  285   // Returns the window object of the currently executing context. |  | 
|  286   static DOMWindow* retrieveWindow(); |  | 
|  287   // Returns the window object associated with a context. |  | 
|  288   static DOMWindow* retrieveWindow(v8::Handle<v8::Context> context); |  | 
|  289   // Returns V8Proxy object of the currently executing context. |  | 
|  290   static V8Proxy* retrieve(); |  | 
|  291   // Returns V8Proxy object associated with a frame. |  | 
|  292   static V8Proxy* retrieve(Frame* frame); |  | 
|  293   // Returns V8Proxy object associated with a script execution context. |  | 
|  294   static V8Proxy* retrieve(ScriptExecutionContext* context); |  | 
|  295  |  | 
|  296   // Returns the frame object of the window object associated |  | 
|  297   // with the currently executing context. |  | 
|  298   static Frame* retrieveFrame(); |  | 
|  299   // Returns the frame object of the window object associated with |  | 
|  300   // a context. |  | 
|  301   static Frame* retrieveFrame(v8::Handle<v8::Context> context); |  | 
|  302  |  | 
|  303  |  | 
|  304   // The three functions below retrieve WebFrame instances relating the |  | 
|  305   // currently executing JavaScript. Since JavaScript can make function calls |  | 
|  306   // across frames, though, we need to be more precise. |  | 
|  307   // |  | 
|  308   // For example, imagine that a JS function in frame A calls a function in |  | 
|  309   // frame B, which calls native code, which wants to know what the 'active' |  | 
|  310   // frame is. |  | 
|  311   // |  | 
|  312   // The 'entered context' is the context where execution first entered the |  | 
|  313   // script engine; the context that is at the bottom of the JS function stack. |  | 
|  314   // RetrieveFrameForEnteredContext() would return Frame A in our example. |  | 
|  315   // This frame is often referred to as the "dynamic global object." |  | 
|  316   // |  | 
|  317   // The 'current context' is the context the JS engine is currently inside of; |  | 
|  318   // the context that is at the top of the JS function stack. |  | 
|  319   // RetrieveFrameForCurrentContext() would return Frame B in our example. |  | 
|  320   // This frame is often referred to as the "lexical global object." |  | 
|  321   // |  | 
|  322   // Finally, the 'calling context' is the context one below the current |  | 
|  323   // context on the JS function stack.  For example, if function f calls |  | 
|  324   // function g, then the calling context will be the context associated with |  | 
|  325   // f.  This context is commonly used by DOM security checks because they want |  | 
|  326   // to know who called them. |  | 
|  327   // |  | 
|  328   // If you are unsure which of these functions to use, ask abarth. |  | 
|  329   // |  | 
|  330   // NOTE: These cannot be declared as inline function, because VS complains at |  | 
|  331   // linking time. |  | 
|  332   static Frame* retrieveFrameForEnteredContext(); |  | 
|  333   static Frame* retrieveFrameForCurrentContext(); |  | 
|  334   static Frame* retrieveFrameForCallingContext(); |  | 
|  335  |  | 
|  336   // Returns V8 Context of a frame. If none exists, creates |  | 
|  337   // a new context.  It is potentially slow and consumes memory. |  | 
|  338   static v8::Local<v8::Context> GetContext(Frame* frame); |  | 
|  339   static v8::Local<v8::Context> GetCurrentContext(); |  | 
|  340  |  | 
|  341   // If the current context causes out of memory, JavaScript setting |  | 
|  342   // is disabled and it returns true. |  | 
|  343   static bool HandleOutOfMemory(); |  | 
|  344  |  | 
|  345   // Check if the active execution context can access the target frame. |  | 
|  346   static bool CanAccessFrame(Frame* target, bool report_error); |  | 
|  347  |  | 
|  348   // Check if it is safe to access the given node from the |  | 
|  349   // current security context. |  | 
|  350   static bool CheckNodeSecurity(Node* node); |  | 
|  351  |  | 
|  352   static v8::Handle<v8::Value> CheckNewLegal(const v8::Arguments& args); |  | 
|  353  |  | 
|  354   // Create a V8 wrapper for a C pointer |  | 
|  355   static v8::Handle<v8::Value> WrapCPointer(void* cptr) { |  | 
|  356     // Represent void* as int |  | 
|  357     int addr = reinterpret_cast<int>(cptr); |  | 
|  358     ASSERT((addr & 0x01) == 0);  // the address must be aligned. |  | 
|  359     return v8::Integer::New(addr >> 1); |  | 
|  360   } |  | 
|  361  |  | 
|  362   // Take C pointer out of a v8 wrapper |  | 
|  363   template <class C> |  | 
|  364   static C* ExtractCPointer(v8::Handle<v8::Value> obj) { |  | 
|  365     return static_cast<C*>(ExtractCPointerImpl(obj)); |  | 
|  366   } |  | 
|  367  |  | 
|  368   static v8::Handle<v8::Script> CompileScript(v8::Handle<v8::String> code, |  | 
|  369                                               const String& fileName, |  | 
|  370                                               int baseLine); |  | 
|  371  |  | 
|  372 #ifndef NDEBUG |  | 
|  373   // Checks if a v8 value can be a DOM wrapper |  | 
|  374   static bool MaybeDOMWrapper(v8::Handle<v8::Value> value); |  | 
|  375 #endif |  | 
|  376  |  | 
|  377   // Sets contents of a DOM wrapper. |  | 
|  378   static void SetDOMWrapper(v8::Handle<v8::Object> obj, int type, void* ptr); |  | 
|  379  |  | 
|  380   static v8::Handle<v8::Object> LookupDOMWrapper( |  | 
|  381     V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> value); |  | 
|  382  |  | 
|  383   // A helper function extract native object pointer from a DOM wrapper |  | 
|  384   // and cast to the specified type. |  | 
|  385   template <class C> |  | 
|  386   static C* DOMWrapperToNative(v8::Handle<v8::Value> object) { |  | 
|  387     ASSERT(MaybeDOMWrapper(object)); |  | 
|  388     v8::Handle<v8::Value> ptr = |  | 
|  389       v8::Handle<v8::Object>::Cast(object)->GetInternalField( |  | 
|  390           V8Custom::kDOMWrapperObjectIndex); |  | 
|  391     return ExtractCPointer<C>(ptr); |  | 
|  392   } |  | 
|  393  |  | 
|  394   // A help function extract a node type pointer from a DOM wrapper. |  | 
|  395   // Wrapped pointer must be cast to Node* first. |  | 
|  396   static void* DOMWrapperToNodeHelper(v8::Handle<v8::Value> value); |  | 
|  397  |  | 
|  398   template <class C> |  | 
|  399   static C* DOMWrapperToNode(v8::Handle<v8::Value> value) { |  | 
|  400     return static_cast<C*>(DOMWrapperToNodeHelper(value)); |  | 
|  401   } |  | 
|  402  |  | 
|  403   template<typename T> |  | 
|  404   static v8::Handle<v8::Value> ToV8Object(V8ClassIndex::V8WrapperType type, Pass
     RefPtr<T> imp) |  | 
|  405   { |  | 
|  406     return ToV8Object(type, imp.get()); |  | 
|  407   } |  | 
|  408   static v8::Handle<v8::Value> ToV8Object(V8ClassIndex::V8WrapperType type, |  | 
|  409                                           void* imp); |  | 
|  410   // Fast-path for Node objects. |  | 
|  411   static v8::Handle<v8::Value> NodeToV8Object(Node* node); |  | 
|  412  |  | 
|  413   template <class C> |  | 
|  414   static C* ToNativeObject(V8ClassIndex::V8WrapperType type, |  | 
|  415                            v8::Handle<v8::Value> object) { |  | 
|  416     return static_cast<C*>(ToNativeObjectImpl(type, object)); |  | 
|  417   } |  | 
|  418  |  | 
|  419   static V8ClassIndex::V8WrapperType GetDOMWrapperType( |  | 
|  420       v8::Handle<v8::Object> object); |  | 
|  421  |  | 
|  422   // If the exception code is different from zero, a DOM exception is |  | 
|  423   // schedule to be thrown. |  | 
|  424   static void SetDOMException(int exception_code); |  | 
|  425  |  | 
|  426   // Schedule an error object to be thrown. |  | 
|  427   static v8::Handle<v8::Value> ThrowError(ErrorType type, const char* message); |  | 
|  428  |  | 
|  429   // Create an instance of a function descriptor and set to the global object |  | 
|  430   // as a named property. Used by v8_test_shell. |  | 
|  431   static void BindJSObjectToWindow(Frame* frame, |  | 
|  432                                    const char* name, |  | 
|  433                                    int type, |  | 
|  434                                    v8::Handle<v8::FunctionTemplate> desc, |  | 
|  435                                    void* imp); |  | 
|  436  |  | 
|  437   static v8::Handle<v8::Value> EventToV8Object(Event* event); |  | 
|  438   static Event* ToNativeEvent(v8::Handle<v8::Value> jsevent) { |  | 
|  439     if (!IsDOMEventWrapper(jsevent)) return 0; |  | 
|  440     return DOMWrapperToNative<Event>(jsevent); |  | 
|  441   } |  | 
|  442  |  | 
|  443   static v8::Handle<v8::Value> EventTargetToV8Object(EventTarget* target); |  | 
|  444   // Wrap and unwrap JS event listeners |  | 
|  445   static v8::Handle<v8::Value> EventListenerToV8Object(EventListener* target); |  | 
|  446  |  | 
|  447   // DOMImplementation is a singleton and it is handled in a special |  | 
|  448   // way.  A wrapper is generated per document and stored in an |  | 
|  449   // internal field of the document. |  | 
|  450   static v8::Handle<v8::Value> DOMImplementationToV8Object( |  | 
|  451       DOMImplementation* impl); |  | 
|  452  |  | 
|  453   // Wrap JS node filter in C++ |  | 
|  454   static PassRefPtr<NodeFilter> ToNativeNodeFilter(v8::Handle<v8::Value> filter)
     ; |  | 
|  455  |  | 
|  456   static v8::Persistent<v8::FunctionTemplate> GetTemplate( |  | 
|  457       V8ClassIndex::V8WrapperType type); |  | 
|  458  |  | 
|  459   template <int tag, typename T> |  | 
|  460     static v8::Handle<v8::Value> ConstructDOMObject(const v8::Arguments& args); |  | 
|  461  |  | 
|  462   // Checks whether a DOM object has a JS wrapper. |  | 
|  463   static bool DOMObjectHasJSWrapper(void* obj); |  | 
|  464   // Set JS wrapper of a DOM object, the caller in charge of increase ref. |  | 
|  465   static void SetJSWrapperForDOMObject(void* obj, |  | 
|  466                                        v8::Persistent<v8::Object> wrapper); |  | 
|  467   static void SetJSWrapperForActiveDOMObject(void* obj, |  | 
|  468                                              v8::Persistent<v8::Object> wrapper)
     ; |  | 
|  469   static void SetJSWrapperForDOMNode(Node* node, |  | 
|  470                                      v8::Persistent<v8::Object> wrapper); |  | 
|  471  |  | 
|  472   // Process any pending JavaScript console messages. |  | 
|  473   static void ProcessConsoleMessages(); |  | 
|  474  |  | 
|  475 #ifndef NDEBUG |  | 
|  476   // For debugging and leak detection purpose |  | 
|  477   static void RegisterGlobalHandle(GlobalHandleType type, |  | 
|  478                                    void* host, |  | 
|  479                                    v8::Persistent<v8::Value> handle); |  | 
|  480   static void UnregisterGlobalHandle(void* host, |  | 
|  481                                      v8::Persistent<v8::Value> handle); |  | 
|  482 #endif |  | 
|  483  |  | 
|  484   // Check whether a V8 value is a wrapper of type |classType|. |  | 
|  485   static bool IsWrapperOfType(v8::Handle<v8::Value> obj, |  | 
|  486                               V8ClassIndex::V8WrapperType classType); |  | 
|  487  |  | 
|  488   // Function for retrieving the line number and source name for the top |  | 
|  489   // JavaScript stack frame. |  | 
|  490   static int GetSourceLineNumber(); |  | 
|  491   static String GetSourceName(); |  | 
|  492  |  | 
|  493  |  | 
|  494   // Returns a local handle of the context. |  | 
|  495   v8::Local<v8::Context> GetContext() { |  | 
|  496     return v8::Local<v8::Context>::New(m_context); |  | 
|  497   } |  | 
|  498  |  | 
|  499   bool SetContextDebugId(int id); |  | 
|  500   static int GetContextDebugId(v8::Handle<v8::Context> context); |  | 
|  501  |  | 
|  502   // Registers an extension to be available on webpages with a particular scheme |  | 
|  503   // If the scheme argument is empty, the extension is available on all pages. |  | 
|  504   // Will only affect v8 contexts initialized after this call. Takes ownership |  | 
|  505   // of the v8::Extension object passed. |  | 
|  506   static void RegisterExtension(v8::Extension* extension, |  | 
|  507                                 const String& schemeRestriction); |  | 
|  508  |  | 
|  509   static void* ToSVGPODTypeImpl(V8ClassIndex::V8WrapperType type, |  | 
|  510                                 v8::Handle<v8::Value> object); |  | 
|  511  |  | 
|  512   // TODO(abarth): Separate these concerns from V8Proxy? |  | 
|  513   v8::Persistent<v8::Context> createNewContext(v8::Handle<v8::Object> global); |  | 
|  514   bool installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window); |  | 
|  515  |  | 
|  516  private: |  | 
|  517   static const char* kContextDebugDataType; |  | 
|  518   static const char* kContextDebugDataValue; |  | 
|  519  |  | 
|  520   void InitContextIfNeeded(); |  | 
|  521   void DisconnectEventListeners(); |  | 
|  522   void SetSecurityToken(); |  | 
|  523   void ClearDocumentWrapper(); |  | 
|  524   void UpdateDocumentWrapper(v8::Handle<v8::Value> wrapper); |  | 
|  525  |  | 
|  526   // The JavaScript wrapper for the document object is cached on the global |  | 
|  527   // object for fast access.  UpdateDocumentWrapperCache sets the wrapper |  | 
|  528   // for the current document on the global object.  ClearDocumentWrapperCache |  | 
|  529   // deletes the document wrapper from the global object. |  | 
|  530   void UpdateDocumentWrapperCache(); |  | 
|  531   void ClearDocumentWrapperCache(); |  | 
|  532  |  | 
|  533   // Dispose global handles of m_contexts and friends. |  | 
|  534   void DisposeContextHandles(); |  | 
|  535  |  | 
|  536   static bool CanAccessPrivate(DOMWindow* target); |  | 
|  537  |  | 
|  538   // Check whether a V8 value is a DOM Event wrapper |  | 
|  539   static bool IsDOMEventWrapper(v8::Handle<v8::Value> obj); |  | 
|  540  |  | 
|  541   static void* ToNativeObjectImpl(V8ClassIndex::V8WrapperType type, |  | 
|  542                                   v8::Handle<v8::Value> object); |  | 
|  543  |  | 
|  544   // Take C pointer out of a v8 wrapper |  | 
|  545   static void* ExtractCPointerImpl(v8::Handle<v8::Value> obj) { |  | 
|  546     ASSERT(obj->IsNumber()); |  | 
|  547     int addr = obj->Int32Value(); |  | 
|  548     return reinterpret_cast<void*>(addr << 1); |  | 
|  549   } |  | 
|  550  |  | 
|  551  |  | 
|  552   static v8::Handle<v8::Value> StyleSheetToV8Object(StyleSheet* sheet); |  | 
|  553   static v8::Handle<v8::Value> CSSValueToV8Object(CSSValue* value); |  | 
|  554   static v8::Handle<v8::Value> CSSRuleToV8Object(CSSRule* rule); |  | 
|  555   // Returns the JS wrapper of a window object, initializes the environment |  | 
|  556   // of the window frame if needed. |  | 
|  557   static v8::Handle<v8::Value> WindowToV8Object(DOMWindow* window); |  | 
|  558  |  | 
|  559 #if ENABLE(SVG) |  | 
|  560   static v8::Handle<v8::Value> SVGElementInstanceToV8Object( |  | 
|  561       SVGElementInstance* instance); |  | 
|  562   static v8::Handle<v8::Value> SVGObjectWithContextToV8Object( |  | 
|  563       V8ClassIndex::V8WrapperType type, void* object); |  | 
|  564 #endif |  | 
|  565  |  | 
|  566   // Set hidden references in a DOMWindow object of a frame. |  | 
|  567   static void SetHiddenWindowReference(Frame* frame, |  | 
|  568                                        const int internal_index, |  | 
|  569                                        v8::Handle<v8::Object> jsobj); |  | 
|  570  |  | 
|  571   static V8ClassIndex::V8WrapperType GetHTMLElementType(HTMLElement* elm); |  | 
|  572  |  | 
|  573   // The first parameter, desc_type, specifies the function descriptor |  | 
|  574   // used to create JS object. The second parameter, cptr_type, specifies |  | 
|  575   // the type of third parameter, impl, for type casting. |  | 
|  576   // For example, a HTML element has HTMLELEMENT desc_type, but always |  | 
|  577   // use NODE as cptr_type. JS wrapper stores cptr_type and impl as |  | 
|  578   // internal fields. |  | 
|  579   static v8::Local<v8::Object> InstantiateV8Object( |  | 
|  580       V8ClassIndex::V8WrapperType desc_type, |  | 
|  581       V8ClassIndex::V8WrapperType cptr_type, |  | 
|  582       void* impl); |  | 
|  583  |  | 
|  584   static const char* GetRangeExceptionName(int exception_code); |  | 
|  585   static const char* GetEventExceptionName(int exception_code); |  | 
|  586   static const char* GetXMLHttpRequestExceptionName(int exception_code); |  | 
|  587   static const char* GetDOMExceptionName(int exception_code); |  | 
|  588  |  | 
|  589 #if ENABLE(XPATH) |  | 
|  590   static const char* GetXPathExceptionName(int exception_code); |  | 
|  591 #endif |  | 
|  592  |  | 
|  593 #if ENABLE(SVG) |  | 
|  594   static V8ClassIndex::V8WrapperType GetSVGElementType(SVGElement* elm); |  | 
|  595   static const char* GetSVGExceptionName(int exception_code); |  | 
|  596 #endif |  | 
|  597  |  | 
|  598   // Create and populate the utility context. |  | 
|  599   static void CreateUtilityContext(); |  | 
|  600  |  | 
|  601   // Returns a local handle of the utility context. |  | 
|  602   static v8::Local<v8::Context> GetUtilityContext() { |  | 
|  603     if (m_utilityContext.IsEmpty()) { |  | 
|  604       CreateUtilityContext(); |  | 
|  605     } |  | 
|  606     return v8::Local<v8::Context>::New(m_utilityContext); |  | 
|  607   } |  | 
|  608  |  | 
|  609   Frame* m_frame; |  | 
|  610  |  | 
|  611   v8::Persistent<v8::Context> m_context; |  | 
|  612   // For each possible type of wrapper, we keep a boilerplate object. |  | 
|  613   // The boilerplate is used to create additional wrappers of the same type. |  | 
|  614   // We keep a single persistent handle to an array of the activated |  | 
|  615   // boilerplates. |  | 
|  616   v8::Persistent<v8::Array> m_wrapper_boilerplates; |  | 
|  617   v8::Persistent<v8::Value> m_object_prototype; |  | 
|  618  |  | 
|  619   v8::Persistent<v8::Object> m_global; |  | 
|  620   v8::Persistent<v8::Value> m_document; |  | 
|  621  |  | 
|  622   // Utility context holding JavaScript functions used internally. |  | 
|  623   static v8::Persistent<v8::Context> m_utilityContext; |  | 
|  624  |  | 
|  625   int m_handlerLineno; |  | 
|  626  |  | 
|  627   // A list of event listeners created for this frame, |  | 
|  628   // the list gets cleared when removing all timeouts. |  | 
|  629   V8EventListenerList m_event_listeners; |  | 
|  630  |  | 
|  631   // A list of event listeners create for XMLHttpRequest object for this frame, |  | 
|  632   // the list gets cleared when removing all timeouts. |  | 
|  633   V8EventListenerList m_xhr_listeners; |  | 
|  634  |  | 
|  635   // True for <a href="javascript:foo()"> and false for <script>foo()</script>. |  | 
|  636   // Only valid during execution. |  | 
|  637   bool m_inlineCode; |  | 
|  638  |  | 
|  639   // True when executing from within a timer callback.  Only valid during |  | 
|  640   // execution. |  | 
|  641   bool m_timerCallback; |  | 
|  642  |  | 
|  643   // Track the recursion depth to be able to avoid too deep recursion. The V8 |  | 
|  644   // engine allows much more recursion than KJS does so we need to guard against |  | 
|  645   // excessive recursion in the binding layer. |  | 
|  646   int m_recursion; |  | 
|  647  |  | 
|  648   // List of extensions registered with the context. |  | 
|  649   static V8ExtensionList m_extensions; |  | 
|  650 }; |  | 
|  651  |  | 
|  652 template <int tag, typename T> |  | 
|  653 v8::Handle<v8::Value> V8Proxy::ConstructDOMObject(const v8::Arguments& args) { |  | 
|  654   if (!args.IsConstructCall()) { |  | 
|  655     V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, |  | 
|  656         "DOM object constructor cannot be called as a function."); |  | 
|  657     return v8::Undefined(); |  | 
|  658   } |  | 
|  659  |  | 
|  660  |  | 
|  661   // Note: it's OK to let this RefPtr go out of scope because we also call |  | 
|  662   // SetDOMWrapper(), which effectively holds a reference to obj. |  | 
|  663   RefPtr<T> obj = T::create(); |  | 
|  664   V8Proxy::SetDOMWrapper(args.Holder(), tag, obj.get()); |  | 
|  665   obj->ref(); |  | 
|  666   V8Proxy::SetJSWrapperForDOMObject( |  | 
|  667       obj.get(), v8::Persistent<v8::Object>::New(args.Holder())); |  | 
|  668   return args.Holder(); |  | 
|  669 } |  | 
|  670  |  | 
|  671 }  // namespace WebCore |  | 
|  672  |  | 
|  673 #endif  // V8_PROXY_H__ |  | 
| OLD | NEW |