Home | History | Annotate | Download | only in js
      1 /*
      2  *  Copyright (C) 2001 Peter Kelly (pmk (at) post.com)
      3  *  Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
      4  *
      5  *  This library is free software; you can redistribute it and/or
      6  *  modify it under the terms of the GNU Lesser General Public
      7  *  License as published by the Free Software Foundation; either
      8  *  version 2 of the License, or (at your option) any later version.
      9  *
     10  *  This library is distributed in the hope that it will be useful,
     11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  *  Lesser General Public License for more details.
     14  *
     15  *  You should have received a copy of the GNU Lesser General Public
     16  *  License along with this library; if not, write to the Free Software
     17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     18  */
     19 
     20 #ifndef JSEventListener_h
     21 #define JSEventListener_h
     22 
     23 #include "EventListener.h"
     24 #include "JSDOMWindow.h"
     25 #include <runtime/WeakGCPtr.h>
     26 
     27 namespace WebCore {
     28 
     29     class JSDOMGlobalObject;
     30 
     31     class JSEventListener : public EventListener {
     32     public:
     33         static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
     34         {
     35             return adoptRef(new JSEventListener(listener, wrapper, isAttribute, isolatedWorld));
     36         }
     37 
     38         static const JSEventListener* cast(const EventListener* listener)
     39         {
     40             return listener->type() == JSEventListenerType
     41                 ? static_cast<const JSEventListener*>(listener)
     42                 : 0;
     43         }
     44 
     45         virtual ~JSEventListener();
     46 
     47         virtual bool operator==(const EventListener& other);
     48 
     49         // Returns true if this event listener was created for an event handler attribute, like "onload" or "onclick".
     50         bool isAttribute() const { return m_isAttribute; }
     51 
     52         JSC::JSObject* jsFunction(ScriptExecutionContext*) const;
     53         DOMWrapperWorld* isolatedWorld() const { return m_isolatedWorld.get(); }
     54 
     55         JSC::JSObject* wrapper() const { return m_wrapper.get(); }
     56         void setWrapper(JSC::JSObject* wrapper) const { m_wrapper = wrapper; }
     57 
     58     private:
     59         virtual JSC::JSObject* initializeJSFunction(ScriptExecutionContext*) const;
     60         virtual void markJSFunction(JSC::MarkStack&);
     61         virtual void invalidateJSFunction(JSC::JSObject*);
     62         virtual void handleEvent(ScriptExecutionContext*, Event*);
     63         virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber);
     64         virtual bool virtualisAttribute() const;
     65 
     66     protected:
     67         JSEventListener(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld);
     68 
     69     private:
     70         mutable JSC::JSObject* m_jsFunction;
     71         mutable JSC::WeakGCPtr<JSC::JSObject> m_wrapper;
     72 
     73         bool m_isAttribute;
     74         RefPtr<DOMWrapperWorld> m_isolatedWorld;
     75     };
     76 
     77     inline JSC::JSObject* JSEventListener::jsFunction(ScriptExecutionContext* scriptExecutionContext) const
     78     {
     79         if (!m_jsFunction)
     80             m_jsFunction = initializeJSFunction(scriptExecutionContext);
     81 
     82         // Verify that we have a valid wrapper protecting our function from
     83         // garbage collection.
     84         ASSERT(m_wrapper || !m_jsFunction);
     85         if (!m_wrapper)
     86             return 0;
     87 
     88         // Try to verify that m_jsFunction wasn't recycled. (Not exact, since an
     89         // event listener can be almost anything, but this makes test-writing easier).
     90         ASSERT(!m_jsFunction || static_cast<JSC::JSCell*>(m_jsFunction)->isObject());
     91 
     92         return m_jsFunction;
     93     }
     94 
     95     inline void JSEventListener::invalidateJSFunction(JSC::JSObject* wrapper)
     96     {
     97         m_wrapper.clear(wrapper);
     98     }
     99 
    100     // Creates a JS EventListener for an "onXXX" event attribute.
    101     inline PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper)
    102     {
    103         if (!listener.isObject())
    104             return 0;
    105 
    106         return JSEventListener::create(asObject(listener), wrapper, true, currentWorld(exec));
    107     }
    108 
    109 
    110 } // namespace WebCore
    111 
    112 #endif // JSEventListener_h
    113