2008-04-17 Anders Carlsson <andersca@apple.com>
[WebKit-https.git] / WebCore / bindings / js / JSEventTargetBase.cpp
1 /*
2  * Copyright (C) 2007 Apple Inc. All rights reserved.
3  *           (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "JSEventTargetBase.h"
29
30 #include "JSDOMWindow.h"
31 #include "JSEventTargetNode.h"
32
33 #if ENABLE(SVG)
34 #include "JSSVGElementInstance.h"
35 #endif
36
37 #include "JSEventTargetBase.lut.h"
38
39 using namespace KJS;
40
41 namespace WebCore {
42
43 /* Source for JSEventTargetPropertiesTable
44 @begin JSEventTargetPropertiesTable 50
45 onabort       WebCore::JSEventTargetProperties::OnAbort                DontDelete
46 onblur        WebCore::JSEventTargetProperties::OnBlur                 DontDelete
47 onchange      WebCore::JSEventTargetProperties::OnChange               DontDelete
48 onclick       WebCore::JSEventTargetProperties::OnClick                DontDelete
49 oncontextmenu WebCore::JSEventTargetProperties::OnContextMenu          DontDelete
50 ondblclick    WebCore::JSEventTargetProperties::OnDblClick             DontDelete
51 onbeforecut   WebCore::JSEventTargetProperties::OnBeforeCut            DontDelete
52 oncut         WebCore::JSEventTargetProperties::OnCut                  DontDelete
53 onbeforecopy  WebCore::JSEventTargetProperties::OnBeforeCopy           DontDelete
54 oncopy        WebCore::JSEventTargetProperties::OnCopy                 DontDelete
55 onbeforepaste WebCore::JSEventTargetProperties::OnBeforePaste          DontDelete
56 onpaste       WebCore::JSEventTargetProperties::OnPaste                DontDelete
57 ondrag        WebCore::JSEventTargetProperties::OnDrag                 DontDelete
58 ondragend     WebCore::JSEventTargetProperties::OnDragEnd              DontDelete
59 ondragenter   WebCore::JSEventTargetProperties::OnDragEnter            DontDelete
60 ondragleave   WebCore::JSEventTargetProperties::OnDragLeave            DontDelete
61 ondragover    WebCore::JSEventTargetProperties::OnDragOver             DontDelete
62 ondragstart   WebCore::JSEventTargetProperties::OnDragStart            DontDelete
63 ondrop        WebCore::JSEventTargetProperties::OnDrop                 DontDelete
64 onerror       WebCore::JSEventTargetProperties::OnError                DontDelete
65 onfocus       WebCore::JSEventTargetProperties::OnFocus                DontDelete
66 oninput       WebCore::JSEventTargetProperties::OnInput                DontDelete
67 onkeydown     WebCore::JSEventTargetProperties::OnKeyDown              DontDelete
68 onkeypress    WebCore::JSEventTargetProperties::OnKeyPress             DontDelete
69 onkeyup       WebCore::JSEventTargetProperties::OnKeyUp                DontDelete
70 onload        WebCore::JSEventTargetProperties::OnLoad                 DontDelete
71 onmousedown   WebCore::JSEventTargetProperties::OnMouseDown            DontDelete
72 onmousemove   WebCore::JSEventTargetProperties::OnMouseMove            DontDelete
73 onmouseout    WebCore::JSEventTargetProperties::OnMouseOut             DontDelete
74 onmouseover   WebCore::JSEventTargetProperties::OnMouseOver            DontDelete
75 onmouseup     WebCore::JSEventTargetProperties::OnMouseUp              DontDelete
76 onmousewheel  WebCore::JSEventTargetProperties::OnMouseWheel           DontDelete
77 onreset       WebCore::JSEventTargetProperties::OnReset                DontDelete
78 onresize      WebCore::JSEventTargetProperties::OnResize               DontDelete
79 onscroll      WebCore::JSEventTargetProperties::OnScroll               DontDelete
80 onsearch      WebCore::JSEventTargetProperties::OnSearch               DontDelete
81 onselect      WebCore::JSEventTargetProperties::OnSelect               DontDelete
82 onselectstart WebCore::JSEventTargetProperties::OnSelectStart          DontDelete
83 onsubmit      WebCore::JSEventTargetProperties::OnSubmit               DontDelete
84 onunload      WebCore::JSEventTargetProperties::OnUnload               DontDelete
85 @end
86 */
87
88 /*
89 @begin JSEventTargetPrototypeTable 5
90 addEventListener        WebCore::jsEventTargetAddEventListener    DontDelete|Function 3
91 removeEventListener     WebCore::jsEventTargetRemoveEventListener DontDelete|Function 3
92 dispatchEvent           WebCore::jsEventTargetDispatchEvent       DontDelete|Function 1
93 @end
94 */
95
96 JSValue* jsEventTargetAddEventListener(ExecState* exec, JSObject* thisObj, const List& args)
97 {
98     DOMExceptionTranslator exception(exec);
99
100     Node* eventNode = 0;
101     EventTarget* eventTarget = 0;
102     if (!retrieveEventTargetAndCorrespondingNode(exec, thisObj, eventNode, eventTarget))
103         return throwError(exec, TypeError);
104
105     Frame* frame = eventNode->document()->frame();
106     if (!frame)
107         return jsUndefined();
108
109     if (JSEventListener* listener = toJSDOMWindow(frame)->findOrCreateJSEventListener(args[1]))
110         eventTarget->addEventListener(args[0]->toString(exec), listener, args[2]->toBoolean(exec));
111
112     return jsUndefined();
113 }
114
115 JSValue* jsEventTargetRemoveEventListener(ExecState* exec, JSObject* thisObj, const List& args)
116 {
117     DOMExceptionTranslator exception(exec);
118
119     Node* eventNode = 0;
120     EventTarget* eventTarget = 0;
121     if (!retrieveEventTargetAndCorrespondingNode(exec, thisObj, eventNode, eventTarget))
122         return throwError(exec, TypeError);
123
124     Frame* frame = eventNode->document()->frame();
125     if (!frame)
126         return jsUndefined();
127
128     if (JSEventListener* listener = toJSDOMWindow(frame)->findJSEventListener(args[1]))
129         eventTarget->removeEventListener(args[0]->toString(exec), listener, args[2]->toBoolean(exec));
130
131     return jsUndefined();
132 }
133
134 JSValue* jsEventTargetDispatchEvent(ExecState* exec, JSObject* thisObj, const List& args)
135 {
136     Node* eventNode = 0;
137     EventTarget* eventTarget = 0;
138     if (!retrieveEventTargetAndCorrespondingNode(exec, thisObj, eventNode, eventTarget))
139         return throwError(exec, TypeError);
140
141     DOMExceptionTranslator exception(exec);
142     return jsBoolean(eventTarget->dispatchEvent(toEvent(args[0]), exception));
143 }
144
145 bool retrieveEventTargetAndCorrespondingNode(KJS::ExecState*, KJS::JSObject* thisObj, Node*& eventNode, EventTarget*& eventTarget)
146 {
147     if (!thisObj->inherits(&JSNode::s_info))
148         return false;
149
150     JSEventTargetNode* jsNode = static_cast<JSEventTargetNode*>(thisObj);
151     ASSERT(jsNode);
152
153     EventTargetNode* node = static_cast<EventTargetNode*>(jsNode->impl());
154     ASSERT(node);
155
156     eventNode = node;
157     eventTarget = node;
158     return true;
159 }
160
161 const AtomicString& eventNameForPropertyToken(int token)
162 {    
163     switch (token) {
164     case JSEventTargetProperties::OnAbort:
165         return abortEvent;
166     case JSEventTargetProperties::OnBlur:
167         return blurEvent;
168     case JSEventTargetProperties::OnChange:
169         return changeEvent;
170     case JSEventTargetProperties::OnClick:
171         return clickEvent;
172     case JSEventTargetProperties::OnContextMenu:
173         return contextmenuEvent;
174     case JSEventTargetProperties::OnDblClick:
175         return dblclickEvent;
176     case JSEventTargetProperties::OnError:
177         return errorEvent;
178     case JSEventTargetProperties::OnFocus:
179         return focusEvent;
180     case JSEventTargetProperties::OnInput:
181         return inputEvent;
182     case JSEventTargetProperties::OnKeyDown:
183         return keydownEvent;
184     case JSEventTargetProperties::OnKeyPress:
185         return keypressEvent;
186     case JSEventTargetProperties::OnKeyUp:
187         return keyupEvent;
188     case JSEventTargetProperties::OnLoad:
189         return loadEvent;
190     case JSEventTargetProperties::OnMouseDown:
191         return mousedownEvent;
192     case JSEventTargetProperties::OnMouseMove:
193         return mousemoveEvent;
194     case JSEventTargetProperties::OnMouseOut:
195         return mouseoutEvent;
196     case JSEventTargetProperties::OnMouseOver:
197         return mouseoverEvent;
198     case JSEventTargetProperties::OnMouseUp:
199         return mouseupEvent;      
200     case JSEventTargetProperties::OnMouseWheel:
201         return mousewheelEvent;      
202     case JSEventTargetProperties::OnBeforeCut:
203         return beforecutEvent;
204     case JSEventTargetProperties::OnCut:
205         return cutEvent;
206     case JSEventTargetProperties::OnBeforeCopy:
207         return beforecopyEvent;
208     case JSEventTargetProperties::OnCopy:
209         return copyEvent;
210     case JSEventTargetProperties::OnBeforePaste:
211         return beforepasteEvent;
212     case JSEventTargetProperties::OnPaste:
213         return pasteEvent;
214     case JSEventTargetProperties::OnDragEnter:
215         return dragenterEvent;
216     case JSEventTargetProperties::OnDragOver:
217         return dragoverEvent;
218     case JSEventTargetProperties::OnDragLeave:
219         return dragleaveEvent;
220     case JSEventTargetProperties::OnDrop:
221         return dropEvent;
222     case JSEventTargetProperties::OnDragStart:
223         return dragstartEvent;
224     case JSEventTargetProperties::OnDrag:
225         return dragEvent;
226     case JSEventTargetProperties::OnDragEnd:
227         return dragendEvent;
228     case JSEventTargetProperties::OnReset:
229         return resetEvent;
230     case JSEventTargetProperties::OnResize:
231         return resizeEvent;
232     case JSEventTargetProperties::OnScroll:
233         return scrollEvent;
234     case JSEventTargetProperties::OnSearch:
235         return searchEvent;
236     case JSEventTargetProperties::OnSelect:
237         return selectEvent;
238     case JSEventTargetProperties::OnSelectStart:
239         return selectstartEvent;
240     case JSEventTargetProperties::OnSubmit:
241         return submitEvent;
242     case JSEventTargetProperties::OnUnload:
243         return unloadEvent;
244     }
245
246     return nullAtom;
247 }
248
249 JSValue* toJS(ExecState* exec, EventTarget* target)
250 {
251     if (!target)
252         return jsNull();
253     
254 #if ENABLE(SVG)
255     // SVGElementInstance supports both toSVGElementInstance and toNode since so much mouse handling code depends on toNode returning a valid node.
256     SVGElementInstance* instance = target->toSVGElementInstance();
257     if (instance)
258         return toJS(exec, instance);
259 #endif
260     
261     Node* node = target->toNode();
262     if (node)
263         return toJS(exec, node);
264
265     if (XMLHttpRequest* xhr = target->toXMLHttpRequest())
266         // XMLHttpRequest is always created via JS, so we don't need to use cacheDOMObject() here.
267         return ScriptInterpreter::getDOMObject(xhr);
268
269 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
270     if (DOMApplicationCache* cache = target->toDOMApplicationCache())
271         // DOMApplicationCache is always created via JS, so we don't need to use cacheDOMObject() here.
272         return ScriptInterpreter::getDOMObject(cache);
273 #endif
274     
275     // There are two kinds of EventTargets: EventTargetNode and XMLHttpRequest.
276     // If SVG support is enabled, there is also SVGElementInstance.
277     ASSERT_NOT_REACHED();
278     return jsNull();
279 }
280
281 } // namespace WebCore