Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / content / events / src / nsDOMEvent.cpp
blob2637cf735f52608888f98c2a9f47e80285cf2a29
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Steve Clark (buster@netscape.com)
24 * Ilya Konstantinov (mozilla-code@future.shiny.co.il)
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #include "nsCOMPtr.h"
41 #include "nsDOMEvent.h"
42 #include "nsEventStateManager.h"
43 #include "nsIFrame.h"
44 #include "nsIContent.h"
45 #include "nsIPresShell.h"
46 #include "nsIDocument.h"
47 #include "nsIPrivateCompositionEvent.h"
48 #include "nsIDOMEventTarget.h"
49 #include "nsIInterfaceRequestor.h"
50 #include "nsIInterfaceRequestorUtils.h"
51 #include "prmem.h"
52 #include "nsGkAtoms.h"
53 #include "nsMutationEvent.h"
54 #include "nsContentUtils.h"
55 #include "nsIURI.h"
56 #include "nsIScriptSecurityManager.h"
57 #include "nsIScriptError.h"
59 static const char* const sEventNames[] = {
60 "mousedown", "mouseup", "click", "dblclick", "mouseover",
61 "mouseout", "mousemove", "contextmenu", "keydown", "keyup", "keypress",
62 "focus", "blur", "load", "beforeunload", "unload", "abort", "error",
63 "submit", "reset", "change", "select", "input", "paint" ,"text",
64 "compositionstart", "compositionend", "popupshowing", "popupshown",
65 "popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate",
66 "dragenter", "dragover", "dragexit", "dragdrop", "draggesture",
67 "drag", "dragend", "dragstart", "dragleave", "drop", "resize",
68 "scroll", "overflow", "underflow", "overflowchanged",
69 "DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
70 "DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
71 "DOMAttrModified", "DOMCharacterDataModified",
72 "DOMActivate", "DOMFocusIn", "DOMFocusOut",
73 "pageshow", "pagehide", "DOMMouseScroll", "MozMousePixelScroll",
74 "offline", "online", "copy", "cut", "paste",
75 #ifdef MOZ_SVG
76 "SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
77 "SVGZoom",
78 #endif // MOZ_SVG
79 #ifdef MOZ_MEDIA
80 "loadstart", "progress", "loadedmetadata", "loadeddata",
81 "emptied", "stalled", "play", "pause",
82 "waiting", "seeking", "seeked", "timeupdate", "ended",
83 "canplay", "canplaythrough", "ratechange", "durationchange", "volumechange",
84 #endif // MOZ_MEDIA
85 "MozAfterPaint",
86 "MozSwipeGesture",
87 "MozMagnifyGestureStart",
88 "MozMagnifyGestureUpdate",
89 "MozMagnifyGesture",
90 "MozRotateGestureStart",
91 "MozRotateGestureUpdate",
92 "MozRotateGesture"
95 static char *sPopupAllowedEvents;
98 nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
100 mPresContext = aPresContext;
101 mPrivateDataDuplicated = PR_FALSE;
103 if (aEvent) {
104 mEvent = aEvent;
105 mEventIsInternal = PR_FALSE;
107 else {
108 mEventIsInternal = PR_TRUE;
110 A derived class might want to allocate its own type of aEvent
111 (derived from nsEvent). To do this, it should take care to pass
112 a non-NULL aEvent to this ctor, e.g.:
114 nsDOMFooEvent::nsDOMFooEvent(..., nsEvent* aEvent)
115 : nsDOMEvent(..., aEvent ? aEvent : new nsFooEvent())
117 Then, to override the mEventIsInternal assignments done by the
118 base ctor, it should do this in its own ctor:
120 nsDOMFooEvent::nsDOMFooEvent(..., nsEvent* aEvent)
124 if (aEvent) {
125 mEventIsInternal = PR_FALSE;
127 else {
128 mEventIsInternal = PR_TRUE;
133 mEvent = new nsEvent(PR_FALSE, 0);
134 mEvent->time = PR_Now();
137 // Get the explicit original target (if it's anonymous make it null)
139 mExplicitOriginalTarget = GetTargetFromFrame();
140 mTmpRealOriginalTarget = mExplicitOriginalTarget;
141 nsCOMPtr<nsIContent> content = do_QueryInterface(mExplicitOriginalTarget);
142 if (content && content->IsInAnonymousSubtree()) {
143 mExplicitOriginalTarget = nsnull;
148 nsDOMEvent::~nsDOMEvent()
150 NS_ASSERT_OWNINGTHREAD(nsDOMEvent);
152 if (mEventIsInternal && mEvent) {
153 delete mEvent;
157 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEvent)
159 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEvent)
160 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEvent)
161 NS_INTERFACE_MAP_ENTRY(nsIDOMEvent)
162 NS_INTERFACE_MAP_ENTRY(nsIDOMNSEvent)
163 NS_INTERFACE_MAP_ENTRY(nsIPrivateDOMEvent)
164 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(Event)
165 NS_INTERFACE_MAP_END
167 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMEvent)
168 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMEvent)
170 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEvent)
171 if (tmp->mEventIsInternal) {
172 tmp->mEvent->target = nsnull;
173 tmp->mEvent->currentTarget = nsnull;
174 tmp->mEvent->originalTarget = nsnull;
175 switch (tmp->mEvent->eventStructType) {
176 case NS_MOUSE_EVENT:
177 case NS_MOUSE_SCROLL_EVENT:
178 static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget = nsnull;
179 break;
180 case NS_DRAG_EVENT:
181 static_cast<nsDragEvent*>(tmp->mEvent)->dataTransfer = nsnull;
182 break;
183 case NS_XUL_COMMAND_EVENT:
184 static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent = nsnull;
185 break;
186 case NS_MUTATION_EVENT:
187 static_cast<nsMutationEvent*>(tmp->mEvent)->mRelatedNode = nsnull;
188 break;
189 default:
190 break;
193 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPresContext);
194 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTmpRealOriginalTarget)
195 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mExplicitOriginalTarget)
196 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
198 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent)
199 if (tmp->mEventIsInternal) {
200 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEvent->target)
201 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEvent->currentTarget)
202 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEvent->originalTarget)
203 switch (tmp->mEvent->eventStructType) {
204 case NS_MOUSE_EVENT:
205 case NS_MOUSE_SCROLL_EVENT:
206 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->relatedTarget");
207 cb.NoteXPCOMChild(
208 static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget);
209 break;
210 case NS_DRAG_EVENT:
211 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->dataTransfer");
212 cb.NoteXPCOMChild(
213 static_cast<nsDragEvent*>(tmp->mEvent)->dataTransfer);
214 break;
215 case NS_XUL_COMMAND_EVENT:
216 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->sourceEvent");
217 cb.NoteXPCOMChild(
218 static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent);
219 break;
220 case NS_MUTATION_EVENT:
221 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mRelatedNode");
222 cb.NoteXPCOMChild(
223 static_cast<nsMutationEvent*>(tmp->mEvent)->mRelatedNode);
224 break;
225 default:
226 break;
229 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPresContext)
230 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTmpRealOriginalTarget)
231 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mExplicitOriginalTarget)
232 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
234 // nsIDOMEventInterface
235 NS_METHOD nsDOMEvent::GetType(nsAString& aType)
237 const char* name = GetEventName(mEvent->message);
239 if (name) {
240 CopyASCIItoUTF16(name, aType);
241 return NS_OK;
242 } else if (mEvent->message == NS_USER_DEFINED_EVENT && mEvent->userType) {
243 nsAutoString name;
244 mEvent->userType->ToString(name);
245 aType = Substring(name, 2, name.Length() - 2); // Remove "on"
246 return NS_OK;
249 return NS_ERROR_FAILURE;
252 static nsresult
253 GetDOMEventTarget(nsISupports* aTarget,
254 nsIDOMEventTarget** aDOMTarget)
256 nsCOMPtr<nsPIDOMEventTarget> piTarget = do_QueryInterface(aTarget);
257 nsISupports* realTarget =
258 piTarget ? piTarget->GetTargetForDOMEvent() : aTarget;
259 if (realTarget) {
260 return CallQueryInterface(realTarget, aDOMTarget);
263 *aDOMTarget = nsnull;
264 return NS_OK;
267 NS_METHOD
268 nsDOMEvent::GetTarget(nsIDOMEventTarget** aTarget)
270 return GetDOMEventTarget(mEvent->target, aTarget);
273 NS_IMETHODIMP
274 nsDOMEvent::GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget)
276 return GetDOMEventTarget(mEvent->currentTarget, aCurrentTarget);
280 // Get the actual event target node (may have been retargeted for mouse events)
282 already_AddRefed<nsIDOMEventTarget>
283 nsDOMEvent::GetTargetFromFrame()
285 if (!mPresContext) { return nsnull; }
287 // Get the target frame (have to get the ESM first)
288 nsIFrame* targetFrame = nsnull;
289 mPresContext->EventStateManager()->GetEventTarget(&targetFrame);
290 if (!targetFrame) { return nsnull; }
292 // get the real content
293 nsCOMPtr<nsIContent> realEventContent;
294 targetFrame->GetContentForEvent(mPresContext, mEvent, getter_AddRefs(realEventContent));
295 if (!realEventContent) { return nsnull; }
297 // Finally, we have the real content. QI it and return.
298 nsIDOMEventTarget* target = nsnull;
299 CallQueryInterface(realEventContent, &target);
300 return target;
303 NS_IMETHODIMP
304 nsDOMEvent::GetExplicitOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
306 if (mExplicitOriginalTarget) {
307 *aRealEventTarget = mExplicitOriginalTarget;
308 NS_ADDREF(*aRealEventTarget);
309 return NS_OK;
312 return GetTarget(aRealEventTarget);
315 NS_IMETHODIMP
316 nsDOMEvent::GetTmpRealOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
318 if (mTmpRealOriginalTarget) {
319 *aRealEventTarget = mTmpRealOriginalTarget;
320 NS_ADDREF(*aRealEventTarget);
321 return NS_OK;
324 return GetOriginalTarget(aRealEventTarget);
327 NS_IMETHODIMP
328 nsDOMEvent::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
330 if (mEvent->originalTarget) {
331 return GetDOMEventTarget(mEvent->originalTarget, aOriginalTarget);
334 return GetTarget(aOriginalTarget);
337 NS_IMETHODIMP_(PRBool)
338 nsDOMEvent::HasOriginalTarget()
340 return !!mEvent->originalTarget;
343 NS_IMETHODIMP
344 nsDOMEvent::SetTrusted(PRBool aTrusted)
346 if (aTrusted) {
347 mEvent->flags |= NS_EVENT_FLAG_TRUSTED;
348 } else {
349 mEvent->flags &= ~NS_EVENT_FLAG_TRUSTED;
352 return NS_OK;
355 NS_IMETHODIMP
356 nsDOMEvent::GetEventPhase(PRUint16* aEventPhase)
358 // Note, remember to check that this works also
359 // if or when Bug 235441 is fixed.
360 if (mEvent->currentTarget == mEvent->target ||
361 ((mEvent->flags & NS_EVENT_FLAG_CAPTURE) &&
362 (mEvent->flags & NS_EVENT_FLAG_BUBBLE))) {
363 *aEventPhase = nsIDOMEvent::AT_TARGET;
364 } else if (mEvent->flags & NS_EVENT_FLAG_CAPTURE) {
365 *aEventPhase = nsIDOMEvent::CAPTURING_PHASE;
366 } else if (mEvent->flags & NS_EVENT_FLAG_BUBBLE) {
367 *aEventPhase = nsIDOMEvent::BUBBLING_PHASE;
368 } else {
369 *aEventPhase = 0;
371 return NS_OK;
374 NS_IMETHODIMP
375 nsDOMEvent::GetBubbles(PRBool* aBubbles)
377 *aBubbles = !(mEvent->flags & NS_EVENT_FLAG_CANT_BUBBLE);
378 return NS_OK;
381 NS_IMETHODIMP
382 nsDOMEvent::GetCancelable(PRBool* aCancelable)
384 *aCancelable = !(mEvent->flags & NS_EVENT_FLAG_CANT_CANCEL);
385 return NS_OK;
388 NS_IMETHODIMP
389 nsDOMEvent::GetTimeStamp(PRUint64* aTimeStamp)
391 LL_UI2L(*aTimeStamp, mEvent->time);
392 return NS_OK;
395 NS_IMETHODIMP
396 nsDOMEvent::StopPropagation()
398 mEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
399 return NS_OK;
402 static nsIDocument* GetDocumentForReport(nsEvent* aEvent)
404 nsCOMPtr<nsINode> node = do_QueryInterface(aEvent->currentTarget);
405 if (node)
406 return node->GetOwnerDoc();
408 nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aEvent->currentTarget);
409 if (!window)
410 return nsnull;
412 nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
413 return doc;
416 static void
417 ReportUseOfDeprecatedMethod(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
418 const char* aWarning)
420 nsCOMPtr<nsIDocument> doc(GetDocumentForReport(aEvent));
422 nsAutoString type;
423 aDOMEvent->GetType(type);
424 const PRUnichar *strings[] = { type.get() };
425 nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
426 aWarning,
427 strings, NS_ARRAY_LENGTH(strings),
428 doc ? doc->GetDocumentURI() : nsnull,
429 EmptyString(), 0, 0,
430 nsIScriptError::warningFlag,
431 "DOM Events");
434 NS_IMETHODIMP
435 nsDOMEvent::PreventBubble()
437 ReportUseOfDeprecatedMethod(mEvent, this, "UseOfPreventBubbleWarning");
438 return NS_OK;
441 NS_IMETHODIMP
442 nsDOMEvent::PreventCapture()
444 ReportUseOfDeprecatedMethod(mEvent, this, "UseOfPreventCaptureWarning");
445 return NS_OK;
448 NS_IMETHODIMP
449 nsDOMEvent::GetIsTrusted(PRBool *aIsTrusted)
451 *aIsTrusted = NS_IS_TRUSTED_EVENT(mEvent);
453 return NS_OK;
456 NS_IMETHODIMP
457 nsDOMEvent::PreventDefault()
459 if (!(mEvent->flags & NS_EVENT_FLAG_CANT_CANCEL)) {
460 mEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT;
462 return NS_OK;
465 nsresult
466 nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
468 nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aEventTypeArg);
469 mEvent->message = NS_USER_DEFINED_EVENT;
471 if (mEvent->eventStructType == NS_MOUSE_EVENT) {
472 if (atom == nsGkAtoms::onmousedown)
473 mEvent->message = NS_MOUSE_BUTTON_DOWN;
474 else if (atom == nsGkAtoms::onmouseup)
475 mEvent->message = NS_MOUSE_BUTTON_UP;
476 else if (atom == nsGkAtoms::onclick)
477 mEvent->message = NS_MOUSE_CLICK;
478 else if (atom == nsGkAtoms::ondblclick)
479 mEvent->message = NS_MOUSE_DOUBLECLICK;
480 else if (atom == nsGkAtoms::onmouseover)
481 mEvent->message = NS_MOUSE_ENTER_SYNTH;
482 else if (atom == nsGkAtoms::onmouseout)
483 mEvent->message = NS_MOUSE_EXIT_SYNTH;
484 else if (atom == nsGkAtoms::onmousemove)
485 mEvent->message = NS_MOUSE_MOVE;
486 else if (atom == nsGkAtoms::oncontextmenu)
487 mEvent->message = NS_CONTEXTMENU;
488 } else if (mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
489 if (atom == nsGkAtoms::onDOMMouseScroll)
490 mEvent->message = NS_MOUSE_SCROLL;
491 else if (atom == nsGkAtoms::onMozMousePixelScroll)
492 mEvent->message = NS_MOUSE_PIXEL_SCROLL;
493 } else if (mEvent->eventStructType == NS_DRAG_EVENT) {
494 if (atom == nsGkAtoms::ondragstart)
495 mEvent->message = NS_DRAGDROP_START;
496 else if (atom == nsGkAtoms::ondraggesture)
497 mEvent->message = NS_DRAGDROP_GESTURE;
498 else if (atom == nsGkAtoms::ondragenter)
499 mEvent->message = NS_DRAGDROP_ENTER;
500 else if (atom == nsGkAtoms::ondragover)
501 mEvent->message = NS_DRAGDROP_OVER_SYNTH;
502 else if (atom == nsGkAtoms::ondragleave)
503 mEvent->message = NS_DRAGDROP_LEAVE_SYNTH;
504 else if (atom == nsGkAtoms::ondragexit)
505 mEvent->message = NS_DRAGDROP_EXIT;
506 else if (atom == nsGkAtoms::ondrag)
507 mEvent->message = NS_DRAGDROP_DRAG;
508 else if (atom == nsGkAtoms::ondrop)
509 mEvent->message = NS_DRAGDROP_DROP;
510 else if (atom == nsGkAtoms::ondragdrop)
511 mEvent->message = NS_DRAGDROP_DRAGDROP;
512 else if (atom == nsGkAtoms::ondragend)
513 mEvent->message = NS_DRAGDROP_END;
514 } else if (mEvent->eventStructType == NS_KEY_EVENT) {
515 if (atom == nsGkAtoms::onkeydown)
516 mEvent->message = NS_KEY_DOWN;
517 else if (atom == nsGkAtoms::onkeyup)
518 mEvent->message = NS_KEY_UP;
519 else if (atom == nsGkAtoms::onkeypress)
520 mEvent->message = NS_KEY_PRESS;
521 } else if (mEvent->eventStructType == NS_COMPOSITION_EVENT) {
522 if (atom == nsGkAtoms::oncompositionstart)
523 mEvent->message = NS_COMPOSITION_START;
524 else if (atom == nsGkAtoms::oncompositionend)
525 mEvent->message = NS_COMPOSITION_END;
526 } else if (mEvent->eventStructType == NS_EVENT) {
527 if (atom == nsGkAtoms::onfocus)
528 mEvent->message = NS_FOCUS_CONTENT;
529 else if (atom == nsGkAtoms::onblur)
530 mEvent->message = NS_BLUR_CONTENT;
531 else if (atom == nsGkAtoms::onsubmit)
532 mEvent->message = NS_FORM_SUBMIT;
533 else if (atom == nsGkAtoms::onreset)
534 mEvent->message = NS_FORM_RESET;
535 else if (atom == nsGkAtoms::onchange)
536 mEvent->message = NS_FORM_CHANGE;
537 else if (atom == nsGkAtoms::onselect)
538 mEvent->message = NS_FORM_SELECTED;
539 else if (atom == nsGkAtoms::onload)
540 mEvent->message = NS_LOAD;
541 else if (atom == nsGkAtoms::onunload)
542 mEvent->message = NS_PAGE_UNLOAD;
543 else if (atom == nsGkAtoms::onabort)
544 mEvent->message = NS_IMAGE_ABORT;
545 else if (atom == nsGkAtoms::onerror)
546 mEvent->message = NS_LOAD_ERROR;
547 else if (atom == nsGkAtoms::onoffline)
548 mEvent->message = NS_OFFLINE;
549 else if (atom == nsGkAtoms::ononline)
550 mEvent->message = NS_ONLINE;
551 else if (atom == nsGkAtoms::oncopy)
552 mEvent->message = NS_COPY;
553 else if (atom == nsGkAtoms::oncut)
554 mEvent->message = NS_CUT;
555 else if (atom == nsGkAtoms::onpaste)
556 mEvent->message = NS_PASTE;
557 } else if (mEvent->eventStructType == NS_MUTATION_EVENT) {
558 if (atom == nsGkAtoms::onDOMAttrModified)
559 mEvent->message = NS_MUTATION_ATTRMODIFIED;
560 else if (atom == nsGkAtoms::onDOMCharacterDataModified)
561 mEvent->message = NS_MUTATION_CHARACTERDATAMODIFIED;
562 else if (atom == nsGkAtoms::onDOMNodeInserted)
563 mEvent->message = NS_MUTATION_NODEINSERTED;
564 else if (atom == nsGkAtoms::onDOMNodeRemoved)
565 mEvent->message = NS_MUTATION_NODEREMOVED;
566 else if (atom == nsGkAtoms::onDOMNodeInsertedIntoDocument)
567 mEvent->message = NS_MUTATION_NODEINSERTEDINTODOCUMENT;
568 else if (atom == nsGkAtoms::onDOMNodeRemovedFromDocument)
569 mEvent->message = NS_MUTATION_NODEREMOVEDFROMDOCUMENT;
570 else if (atom == nsGkAtoms::onDOMSubtreeModified)
571 mEvent->message = NS_MUTATION_SUBTREEMODIFIED;
572 } else if (mEvent->eventStructType == NS_UI_EVENT) {
573 if (atom == nsGkAtoms::onDOMActivate)
574 mEvent->message = NS_UI_ACTIVATE;
575 else if (atom == nsGkAtoms::onDOMFocusIn)
576 mEvent->message = NS_UI_FOCUSIN;
577 else if (atom == nsGkAtoms::onDOMFocusOut)
578 mEvent->message = NS_UI_FOCUSOUT;
579 else if (atom == nsGkAtoms::oninput)
580 mEvent->message = NS_FORM_INPUT;
581 } else if (mEvent->eventStructType == NS_PAGETRANSITION_EVENT) {
582 if (atom == nsGkAtoms::onpageshow)
583 mEvent->message = NS_PAGE_SHOW;
584 else if (atom == nsGkAtoms::onpagehide)
585 mEvent->message = NS_PAGE_HIDE;
586 } else if (mEvent->eventStructType == NS_XUL_COMMAND_EVENT) {
587 if (atom == nsGkAtoms::oncommand)
588 mEvent->message = NS_XUL_COMMAND;
590 #ifdef MOZ_SVG
591 else if (mEvent->eventStructType == NS_SVG_EVENT) {
592 if (atom == nsGkAtoms::onSVGLoad)
593 mEvent->message = NS_SVG_LOAD;
594 else if (atom == nsGkAtoms::onSVGUnload)
595 mEvent->message = NS_SVG_UNLOAD;
596 else if (atom == nsGkAtoms::onSVGAbort)
597 mEvent->message = NS_SVG_ABORT;
598 else if (atom == nsGkAtoms::onSVGError)
599 mEvent->message = NS_SVG_ERROR;
600 else if (atom == nsGkAtoms::onSVGResize)
601 mEvent->message = NS_SVG_RESIZE;
602 else if (atom == nsGkAtoms::onSVGScroll)
603 mEvent->message = NS_SVG_SCROLL;
604 } else if (mEvent->eventStructType == NS_SVGZOOM_EVENT) {
605 if (atom == nsGkAtoms::onSVGZoom)
606 mEvent->message = NS_SVG_ZOOM;
608 #endif // MOZ_SVG
610 #ifdef MOZ_MEDIA
611 else if (mEvent->eventStructType == NS_MEDIA_EVENT) {
612 if (atom == nsGkAtoms::onloadstart)
613 mEvent->message = NS_LOADSTART;
614 else if (atom == nsGkAtoms::onprogress)
615 mEvent->message = NS_PROGRESS;
616 else if (atom == nsGkAtoms::onloadedmetadata)
617 mEvent->message = NS_LOADEDMETADATA;
618 else if (atom == nsGkAtoms::onloadeddata)
619 mEvent->message = NS_LOADEDDATA;
620 else if (atom == nsGkAtoms::onemptied)
621 mEvent->message = NS_EMPTIED;
622 else if (atom == nsGkAtoms::onstalled)
623 mEvent->message = NS_STALLED;
624 else if (atom == nsGkAtoms::onplay)
625 mEvent->message = NS_PLAY;
626 else if (atom == nsGkAtoms::onpause)
627 mEvent->message = NS_PAUSE;
628 else if (atom == nsGkAtoms::onwaiting)
629 mEvent->message = NS_WAITING;
630 else if (atom == nsGkAtoms::onwaiting)
631 mEvent->message = NS_SEEKING;
632 else if (atom == nsGkAtoms::onseeking)
633 mEvent->message = NS_SEEKED;
634 else if (atom == nsGkAtoms::onseeked)
635 mEvent->message = NS_TIMEUPDATE;
636 else if (atom == nsGkAtoms::onended)
637 mEvent->message = NS_ENDED;
638 else if (atom == nsGkAtoms::oncanplay)
639 mEvent->message = NS_CANPLAY;
640 else if (atom == nsGkAtoms::oncanplaythrough)
641 mEvent->message = NS_CANPLAYTHROUGH;
642 else if (atom == nsGkAtoms::onratechange)
643 mEvent->message = NS_RATECHANGE;
644 else if (atom == nsGkAtoms::ondurationchange)
645 mEvent->message = NS_DURATIONCHANGE;
646 else if (atom == nsGkAtoms::onvolumechange)
647 mEvent->message = NS_VOLUMECHANGE;
648 else if (atom == nsGkAtoms::onload)
649 mEvent->message = NS_LOAD;
650 else if (atom == nsGkAtoms::onabort)
651 mEvent->message = NS_MEDIA_ABORT;
652 else if (atom == nsGkAtoms::onerror)
653 mEvent->message = NS_MEDIA_ERROR;
655 #endif // MOZ_MEDIA
656 else if (mEvent->eventStructType == NS_NOTIFYPAINT_EVENT) {
657 if (atom == nsGkAtoms::onMozAfterPaint)
658 mEvent->message = NS_AFTERPAINT;
660 else if (mEvent->eventStructType == NS_SIMPLE_GESTURE_EVENT) {
661 if (atom == nsGkAtoms::onMozSwipeGesture)
662 mEvent->message = NS_SIMPLE_GESTURE_SWIPE;
663 else if (atom == nsGkAtoms::onMozMagnifyGestureStart)
664 mEvent->message = NS_SIMPLE_GESTURE_MAGNIFY_START;
665 else if (atom == nsGkAtoms::onMozMagnifyGestureUpdate)
666 mEvent->message = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
667 else if (atom == nsGkAtoms::onMozMagnifyGesture)
668 mEvent->message = NS_SIMPLE_GESTURE_MAGNIFY;
669 else if (atom == nsGkAtoms::onMozRotateGestureStart)
670 mEvent->message = NS_SIMPLE_GESTURE_ROTATE_START;
671 else if (atom == nsGkAtoms::onMozRotateGestureUpdate)
672 mEvent->message = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
673 else if (atom == nsGkAtoms::onMozRotateGesture)
674 mEvent->message = NS_SIMPLE_GESTURE_ROTATE;
677 if (mEvent->message == NS_USER_DEFINED_EVENT)
678 mEvent->userType = atom;
680 return NS_OK;
683 NS_IMETHODIMP
684 nsDOMEvent::InitEvent(const nsAString& aEventTypeArg, PRBool aCanBubbleArg, PRBool aCancelableArg)
686 // Make sure this event isn't already being dispatched.
687 NS_ENSURE_TRUE(!NS_IS_EVENT_IN_DISPATCH(mEvent), NS_ERROR_INVALID_ARG);
689 if (NS_IS_TRUSTED_EVENT(mEvent)) {
690 // Ensure the caller is permitted to dispatch trusted DOM events.
692 PRBool enabled = PR_FALSE;
693 nsContentUtils::GetSecurityManager()->
694 IsCapabilityEnabled("UniversalBrowserWrite", &enabled);
696 if (!enabled) {
697 SetTrusted(PR_FALSE);
701 NS_ENSURE_SUCCESS(SetEventType(aEventTypeArg), NS_ERROR_FAILURE);
703 if (aCanBubbleArg) {
704 mEvent->flags &= ~NS_EVENT_FLAG_CANT_BUBBLE;
705 } else {
706 mEvent->flags |= NS_EVENT_FLAG_CANT_BUBBLE;
709 if (aCancelableArg) {
710 mEvent->flags &= ~NS_EVENT_FLAG_CANT_CANCEL;
711 } else {
712 mEvent->flags |= NS_EVENT_FLAG_CANT_CANCEL;
715 // Clearing the old targets, so that the event is targeted correctly when
716 // re-dispatching it.
717 mEvent->target = nsnull;
718 mEvent->originalTarget = nsnull;
720 return NS_OK;
723 NS_METHOD nsDOMEvent::DuplicatePrivateData()
725 // FIXME! Simplify this method and make it somehow easily extendable,
726 // Bug 329127
728 NS_ASSERTION(mEvent, "No nsEvent for nsDOMEvent duplication!");
729 if (mEventIsInternal) {
730 return NS_OK;
733 nsEvent* newEvent = nsnull;
734 PRUint32 msg = mEvent->message;
735 PRBool isInputEvent = PR_FALSE;
737 switch (mEvent->eventStructType) {
738 case NS_EVENT:
740 newEvent = new nsEvent(PR_FALSE, msg);
741 break;
743 case NS_GUI_EVENT:
745 // Not copying widget, it is a weak reference.
746 newEvent = new nsGUIEvent(PR_FALSE, msg, nsnull);
747 break;
749 case NS_SIZE_EVENT:
751 nsSizeEvent* sizeEvent = new nsSizeEvent(PR_FALSE, msg, nsnull);
752 NS_ENSURE_TRUE(sizeEvent, NS_ERROR_OUT_OF_MEMORY);
753 sizeEvent->mWinWidth = static_cast<nsSizeEvent*>(mEvent)->mWinWidth;
754 sizeEvent->mWinHeight = static_cast<nsSizeEvent*>(mEvent)->mWinHeight;
755 newEvent = sizeEvent;
756 break;
758 case NS_SIZEMODE_EVENT:
760 newEvent = new nsSizeModeEvent(PR_FALSE, msg, nsnull);
761 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
762 static_cast<nsSizeModeEvent*>(newEvent)->mSizeMode =
763 static_cast<nsSizeModeEvent*>(mEvent)->mSizeMode;
764 break;
766 case NS_ZLEVEL_EVENT:
768 nsZLevelEvent* zLevelEvent = new nsZLevelEvent(PR_FALSE, msg, nsnull);
769 NS_ENSURE_TRUE(zLevelEvent, NS_ERROR_OUT_OF_MEMORY);
770 nsZLevelEvent* oldZLevelEvent = static_cast<nsZLevelEvent*>(mEvent);
771 zLevelEvent->mPlacement = oldZLevelEvent->mPlacement;
772 zLevelEvent->mImmediate = oldZLevelEvent->mImmediate;
773 zLevelEvent->mAdjusted = oldZLevelEvent->mAdjusted;
774 newEvent = zLevelEvent;
775 break;
777 case NS_PAINT_EVENT:
779 newEvent = new nsPaintEvent(PR_FALSE, msg, nsnull);
780 break;
782 case NS_SCROLLBAR_EVENT:
784 newEvent = new nsScrollbarEvent(PR_FALSE, msg, nsnull);
785 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
786 static_cast<nsScrollbarEvent*>(newEvent)->position =
787 static_cast<nsScrollbarEvent*>(mEvent)->position;
788 break;
790 case NS_INPUT_EVENT:
792 newEvent = new nsInputEvent(PR_FALSE, msg, nsnull);
793 isInputEvent = PR_TRUE;
794 break;
796 case NS_KEY_EVENT:
798 nsKeyEvent* keyEvent = new nsKeyEvent(PR_FALSE, msg, nsnull);
799 NS_ENSURE_TRUE(keyEvent, NS_ERROR_OUT_OF_MEMORY);
800 nsKeyEvent* oldKeyEvent = static_cast<nsKeyEvent*>(mEvent);
801 isInputEvent = PR_TRUE;
802 keyEvent->keyCode = oldKeyEvent->keyCode;
803 keyEvent->charCode = oldKeyEvent->charCode;
804 keyEvent->isChar = oldKeyEvent->isChar;
805 newEvent = keyEvent;
806 break;
808 case NS_MOUSE_EVENT:
810 nsMouseEvent* oldMouseEvent = static_cast<nsMouseEvent*>(mEvent);
811 nsMouseEvent* mouseEvent =
812 new nsMouseEvent(PR_FALSE, msg, nsnull, oldMouseEvent->reason);
813 NS_ENSURE_TRUE(mouseEvent, NS_ERROR_OUT_OF_MEMORY);
814 isInputEvent = PR_TRUE;
815 mouseEvent->clickCount = oldMouseEvent->clickCount;
816 mouseEvent->acceptActivation = oldMouseEvent->acceptActivation;
817 mouseEvent->context = oldMouseEvent->context;
818 mouseEvent->relatedTarget = oldMouseEvent->relatedTarget;
819 mouseEvent->button = oldMouseEvent->button;
820 mouseEvent->pressure = oldMouseEvent->pressure;
821 newEvent = mouseEvent;
822 break;
824 case NS_DRAG_EVENT:
826 nsDragEvent* oldDragEvent = static_cast<nsDragEvent*>(mEvent);
827 nsDragEvent* dragEvent =
828 new nsDragEvent(PR_FALSE, msg, nsnull);
829 NS_ENSURE_TRUE(dragEvent, NS_ERROR_OUT_OF_MEMORY);
830 isInputEvent = PR_TRUE;
831 dragEvent->dataTransfer = oldDragEvent->dataTransfer;
832 dragEvent->clickCount = oldDragEvent->clickCount;
833 dragEvent->acceptActivation = oldDragEvent->acceptActivation;
834 dragEvent->relatedTarget = oldDragEvent->relatedTarget;
835 dragEvent->button = oldDragEvent->button;
836 newEvent = dragEvent;
837 break;
839 case NS_MENU_EVENT:
841 newEvent = new nsMenuEvent(PR_FALSE, msg, nsnull);
842 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
843 static_cast<nsMenuEvent*>(newEvent)->mCommand =
844 static_cast<nsMenuEvent*>(mEvent)->mCommand;
845 break;
847 case NS_SCRIPT_ERROR_EVENT:
849 newEvent = new nsScriptErrorEvent(PR_FALSE, msg);
850 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
851 static_cast<nsScriptErrorEvent*>(newEvent)->lineNr =
852 static_cast<nsScriptErrorEvent*>(mEvent)->lineNr;
853 break;
855 case NS_TEXT_EVENT:
857 newEvent = new nsTextEvent(PR_FALSE, msg, nsnull);
858 isInputEvent = PR_TRUE;
859 break;
861 case NS_COMPOSITION_EVENT:
863 newEvent = new nsCompositionEvent(PR_FALSE, msg, nsnull);
864 isInputEvent = PR_TRUE;
865 break;
867 case NS_MOUSE_SCROLL_EVENT:
869 nsMouseScrollEvent* mouseScrollEvent =
870 new nsMouseScrollEvent(PR_FALSE, msg, nsnull);
871 NS_ENSURE_TRUE(mouseScrollEvent, NS_ERROR_OUT_OF_MEMORY);
872 isInputEvent = PR_TRUE;
873 nsMouseScrollEvent* oldMouseScrollEvent =
874 static_cast<nsMouseScrollEvent*>(mEvent);
875 mouseScrollEvent->scrollFlags = oldMouseScrollEvent->scrollFlags;
876 mouseScrollEvent->delta = oldMouseScrollEvent->delta;
877 mouseScrollEvent->relatedTarget = oldMouseScrollEvent->relatedTarget;
878 mouseScrollEvent->button = oldMouseScrollEvent->button;
879 newEvent = mouseScrollEvent;
880 break;
882 case NS_SCROLLPORT_EVENT:
884 newEvent = new nsScrollPortEvent(PR_FALSE, msg, nsnull);
885 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
886 static_cast<nsScrollPortEvent*>(newEvent)->orient =
887 static_cast<nsScrollPortEvent*>(mEvent)->orient;
888 break;
890 case NS_MUTATION_EVENT:
892 nsMutationEvent* mutationEvent = new nsMutationEvent(PR_FALSE, msg);
893 NS_ENSURE_TRUE(mutationEvent, NS_ERROR_OUT_OF_MEMORY);
894 nsMutationEvent* oldMutationEvent =
895 static_cast<nsMutationEvent*>(mEvent);
896 mutationEvent->mRelatedNode = oldMutationEvent->mRelatedNode;
897 mutationEvent->mAttrName = oldMutationEvent->mAttrName;
898 mutationEvent->mPrevAttrValue = oldMutationEvent->mPrevAttrValue;
899 mutationEvent->mNewAttrValue = oldMutationEvent->mNewAttrValue;
900 mutationEvent->mAttrChange = oldMutationEvent->mAttrChange;
901 newEvent = mutationEvent;
902 break;
904 case NS_ACCESSIBLE_EVENT:
906 newEvent = new nsAccessibleEvent(PR_FALSE, msg, nsnull);
907 isInputEvent = PR_TRUE;
908 break;
910 case NS_FORM_EVENT:
912 newEvent = new nsFormEvent(PR_FALSE, msg);
913 break;
915 case NS_FOCUS_EVENT:
917 newEvent = new nsFocusEvent(PR_FALSE, msg, nsnull);
918 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
919 static_cast<nsFocusEvent*>(newEvent)->isMozWindowTakingFocus =
920 static_cast<nsFocusEvent*>(mEvent)->isMozWindowTakingFocus;
921 break;
923 case NS_POPUP_EVENT:
925 newEvent = new nsInputEvent(PR_FALSE, msg, nsnull);
926 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
927 isInputEvent = PR_TRUE;
928 newEvent->eventStructType = NS_POPUP_EVENT;
929 break;
931 case NS_COMMAND_EVENT:
933 newEvent = new nsCommandEvent(PR_FALSE, mEvent->userType,
934 static_cast<nsCommandEvent*>(mEvent)->command, nsnull);
935 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
936 break;
938 case NS_POPUPBLOCKED_EVENT:
940 NS_WARNING("nsPopupBlockedEvent should never be an external event!");
941 newEvent = new nsPopupBlockedEvent(PR_FALSE, msg);
942 break;
944 case NS_BEFORE_PAGE_UNLOAD_EVENT:
946 newEvent = new nsBeforePageUnloadEvent(PR_FALSE, msg);
947 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
948 static_cast<nsBeforePageUnloadEvent*>(newEvent)->text =
949 static_cast<nsBeforePageUnloadEvent*>(mEvent)->text;
950 break;
952 case NS_UI_EVENT:
954 newEvent = new nsUIEvent(PR_FALSE, msg,
955 static_cast<nsUIEvent*>(mEvent)->detail);
956 break;
958 case NS_PAGETRANSITION_EVENT:
960 newEvent =
961 new nsPageTransitionEvent(PR_FALSE, msg,
962 ((nsPageTransitionEvent*) mEvent)->persisted);
963 break;
965 #ifdef MOZ_SVG
966 case NS_SVG_EVENT:
968 newEvent = new nsEvent(PR_FALSE, msg);
969 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
970 newEvent->eventStructType = NS_SVG_EVENT;
971 break;
973 case NS_SVGZOOM_EVENT:
975 newEvent = new nsGUIEvent(PR_FALSE, msg, nsnull);
976 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
977 newEvent->eventStructType = NS_SVGZOOM_EVENT;
978 break;
980 #endif // MOZ_SVG
981 case NS_XUL_COMMAND_EVENT:
983 newEvent = new nsXULCommandEvent(PR_FALSE, msg, nsnull);
984 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
985 isInputEvent = PR_TRUE;
986 newEvent->eventStructType = NS_XUL_COMMAND_EVENT;
987 static_cast<nsXULCommandEvent*>(newEvent)->sourceEvent =
988 static_cast<nsXULCommandEvent*>(mEvent)->sourceEvent;
989 break;
991 case NS_NOTIFYPAINT_EVENT:
993 nsNotifyPaintEvent* event = static_cast<nsNotifyPaintEvent*>(mEvent);
994 newEvent =
995 new nsNotifyPaintEvent(PR_FALSE, msg,
996 event->sameDocRegion, event->crossDocRegion);
997 break;
999 case NS_SIMPLE_GESTURE_EVENT:
1001 nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
1002 nsSimpleGestureEvent* simpleGestureEvent =
1003 new nsSimpleGestureEvent(PR_FALSE, msg, nsnull, 0, 0.0);
1004 NS_ENSURE_TRUE(simpleGestureEvent, NS_ERROR_OUT_OF_MEMORY);
1005 isInputEvent = PR_TRUE;
1006 simpleGestureEvent->direction = oldSimpleGestureEvent->direction;
1007 simpleGestureEvent->delta = oldSimpleGestureEvent->delta;
1008 simpleGestureEvent->isAlt = oldSimpleGestureEvent->isAlt;
1009 simpleGestureEvent->isControl = oldSimpleGestureEvent->isControl;
1010 simpleGestureEvent->isShift = oldSimpleGestureEvent->isShift;
1011 simpleGestureEvent->isMeta = oldSimpleGestureEvent->isMeta;
1012 newEvent = simpleGestureEvent;
1013 break;
1015 default:
1017 NS_WARNING("Unknown event type!!!");
1018 return NS_ERROR_FAILURE;
1022 NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
1024 if (isInputEvent) {
1025 nsInputEvent* oldInputEvent = static_cast<nsInputEvent*>(mEvent);
1026 nsInputEvent* newInputEvent = static_cast<nsInputEvent*>(newEvent);
1027 newInputEvent->isShift = oldInputEvent->isShift;
1028 newInputEvent->isControl = oldInputEvent->isControl;
1029 newInputEvent->isAlt = oldInputEvent->isAlt;
1030 newInputEvent->isMeta = oldInputEvent->isMeta;
1033 newEvent->target = mEvent->target;
1034 newEvent->currentTarget = mEvent->currentTarget;
1035 newEvent->originalTarget = mEvent->originalTarget;
1036 newEvent->flags = mEvent->flags;
1037 newEvent->time = mEvent->time;
1038 newEvent->refPoint = mEvent->refPoint;
1039 newEvent->userType = mEvent->userType;
1041 mEvent = newEvent;
1042 mPresContext = nsnull;
1043 mEventIsInternal = PR_TRUE;
1044 mPrivateDataDuplicated = PR_TRUE;
1046 return NS_OK;
1049 NS_METHOD nsDOMEvent::SetTarget(nsIDOMEventTarget* aTarget)
1051 #ifdef DEBUG
1053 nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aTarget);
1055 NS_ASSERTION(!win || !win->IsInnerWindow(),
1056 "Uh, inner window set as event target!");
1058 #endif
1060 mEvent->target = aTarget;
1061 return NS_OK;
1064 NS_METHOD nsDOMEvent::SetCurrentTarget(nsIDOMEventTarget* aCurrentTarget)
1066 #ifdef DEBUG
1068 nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aCurrentTarget);
1070 NS_ASSERTION(!win || !win->IsInnerWindow(),
1071 "Uh, inner window set as event target!");
1073 #endif
1075 mEvent->currentTarget = aCurrentTarget;
1076 return NS_OK;
1079 NS_METHOD nsDOMEvent::SetOriginalTarget(nsIDOMEventTarget* aOriginalTarget)
1081 #ifdef DEBUG
1083 nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aOriginalTarget);
1085 NS_ASSERTION(!win || !win->IsInnerWindow(),
1086 "Uh, inner window set as event target!");
1088 #endif
1090 mEvent->originalTarget = aOriginalTarget;
1091 return NS_OK;
1094 NS_IMETHODIMP_(PRBool)
1095 nsDOMEvent::IsDispatchStopped()
1097 return !!(mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH);
1100 NS_IMETHODIMP_(nsEvent*)
1101 nsDOMEvent::GetInternalNSEvent()
1103 return mEvent;
1106 // return true if eventName is contained within events, delimited by
1107 // spaces
1108 static PRBool
1109 PopupAllowedForEvent(const char *eventName)
1111 if (!sPopupAllowedEvents) {
1112 nsDOMEvent::PopupAllowedEventsChanged();
1114 if (!sPopupAllowedEvents) {
1115 return PR_FALSE;
1119 nsDependentCString events(sPopupAllowedEvents);
1121 nsAFlatCString::const_iterator start, end;
1122 nsAFlatCString::const_iterator startiter(events.BeginReading(start));
1123 events.EndReading(end);
1125 while (startiter != end) {
1126 nsAFlatCString::const_iterator enditer(end);
1128 if (!FindInReadable(nsDependentCString(eventName), startiter, enditer))
1129 return PR_FALSE;
1131 // the match is surrounded by spaces, or at a string boundary
1132 if ((startiter == start || *--startiter == ' ') &&
1133 (enditer == end || *enditer == ' ')) {
1134 return PR_TRUE;
1137 // Move on and see if there are other matches. (The delimitation
1138 // requirement makes it pointless to begin the next search before
1139 // the end of the invalid match just found.)
1140 startiter = enditer;
1143 return PR_FALSE;
1146 // static
1147 PopupControlState
1148 nsDOMEvent::GetEventPopupControlState(nsEvent *aEvent)
1150 // generally if an event handler is running, new windows are disallowed.
1151 // check for exceptions:
1152 PopupControlState abuse = openAbused;
1154 switch(aEvent->eventStructType) {
1155 case NS_EVENT :
1156 // For these following events only allow popups if they're
1157 // triggered while handling user input. See
1158 // nsPresShell::HandleEventInternal() for details.
1159 if (nsEventStateManager::IsHandlingUserInput()) {
1160 switch(aEvent->message) {
1161 case NS_FORM_SELECTED :
1162 if (::PopupAllowedForEvent("select"))
1163 abuse = openControlled;
1164 break;
1165 case NS_FORM_CHANGE :
1166 if (::PopupAllowedForEvent("change"))
1167 abuse = openControlled;
1168 break;
1171 break;
1172 case NS_GUI_EVENT :
1173 // For this following event only allow popups if it's triggered
1174 // while handling user input. See
1175 // nsPresShell::HandleEventInternal() for details.
1176 if (nsEventStateManager::IsHandlingUserInput()) {
1177 switch(aEvent->message) {
1178 case NS_FORM_INPUT :
1179 if (::PopupAllowedForEvent("input"))
1180 abuse = openControlled;
1181 break;
1184 break;
1185 case NS_INPUT_EVENT :
1186 // For this following event only allow popups if it's triggered
1187 // while handling user input. See
1188 // nsPresShell::HandleEventInternal() for details.
1189 if (nsEventStateManager::IsHandlingUserInput()) {
1190 switch(aEvent->message) {
1191 case NS_FORM_CHANGE :
1192 if (::PopupAllowedForEvent("change"))
1193 abuse = openControlled;
1194 break;
1197 break;
1198 case NS_KEY_EVENT :
1199 if (NS_IS_TRUSTED_EVENT(aEvent)) {
1200 PRUint32 key = static_cast<nsKeyEvent *>(aEvent)->keyCode;
1201 switch(aEvent->message) {
1202 case NS_KEY_PRESS :
1203 // return key on focused button. see note at NS_MOUSE_CLICK.
1204 if (key == nsIDOMKeyEvent::DOM_VK_RETURN)
1205 abuse = openAllowed;
1206 else if (::PopupAllowedForEvent("keypress"))
1207 abuse = openControlled;
1208 break;
1209 case NS_KEY_UP :
1210 // space key on focused button. see note at NS_MOUSE_CLICK.
1211 if (key == nsIDOMKeyEvent::DOM_VK_SPACE)
1212 abuse = openAllowed;
1213 else if (::PopupAllowedForEvent("keyup"))
1214 abuse = openControlled;
1215 break;
1216 case NS_KEY_DOWN :
1217 if (::PopupAllowedForEvent("keydown"))
1218 abuse = openControlled;
1219 break;
1222 break;
1223 case NS_MOUSE_EVENT :
1224 if (NS_IS_TRUSTED_EVENT(aEvent) &&
1225 static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton) {
1226 switch(aEvent->message) {
1227 case NS_MOUSE_BUTTON_UP :
1228 if (::PopupAllowedForEvent("mouseup"))
1229 abuse = openControlled;
1230 break;
1231 case NS_MOUSE_BUTTON_DOWN :
1232 if (::PopupAllowedForEvent("mousedown"))
1233 abuse = openControlled;
1234 break;
1235 case NS_MOUSE_CLICK :
1236 /* Click events get special treatment because of their
1237 historical status as a more legitimate event handler. If
1238 click popups are enabled in the prefs, clear the popup
1239 status completely. */
1240 if (::PopupAllowedForEvent("click"))
1241 abuse = openAllowed;
1242 break;
1243 case NS_MOUSE_DOUBLECLICK :
1244 if (::PopupAllowedForEvent("dblclick"))
1245 abuse = openControlled;
1246 break;
1249 break;
1250 case NS_SCRIPT_ERROR_EVENT :
1251 switch(aEvent->message) {
1252 case NS_LOAD_ERROR :
1253 // Any error event will allow popups, if enabled in the pref.
1254 if (::PopupAllowedForEvent("error"))
1255 abuse = openControlled;
1256 break;
1258 break;
1259 case NS_FORM_EVENT :
1260 // For these following events only allow popups if they're
1261 // triggered while handling user input. See
1262 // nsPresShell::HandleEventInternal() for details.
1263 if (nsEventStateManager::IsHandlingUserInput()) {
1264 switch(aEvent->message) {
1265 case NS_FORM_SUBMIT :
1266 if (::PopupAllowedForEvent("submit"))
1267 abuse = openControlled;
1268 break;
1269 case NS_FORM_RESET :
1270 if (::PopupAllowedForEvent("reset"))
1271 abuse = openControlled;
1272 break;
1275 break;
1276 case NS_XUL_COMMAND_EVENT :
1277 if (nsEventStateManager::IsHandlingUserInput()) {
1278 abuse = openControlled;
1282 return abuse;
1285 // static
1286 void
1287 nsDOMEvent::PopupAllowedEventsChanged()
1289 if (sPopupAllowedEvents) {
1290 nsMemory::Free(sPopupAllowedEvents);
1293 nsAdoptingCString str =
1294 nsContentUtils::GetCharPref("dom.popup_allowed_events");
1296 // We'll want to do this even if str is empty to avoid looking up
1297 // this pref all the time if it's not set.
1298 sPopupAllowedEvents = ToNewCString(str);
1301 // static
1302 void
1303 nsDOMEvent::Shutdown()
1305 if (sPopupAllowedEvents) {
1306 nsMemory::Free(sPopupAllowedEvents);
1310 // To be called ONLY by nsDOMEvent::GetType (which has the additional
1311 // logic for handling user-defined events).
1312 // static
1313 const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
1315 switch(aEventType) {
1316 case NS_MOUSE_BUTTON_DOWN:
1317 return sEventNames[eDOMEvents_mousedown];
1318 case NS_MOUSE_BUTTON_UP:
1319 return sEventNames[eDOMEvents_mouseup];
1320 case NS_MOUSE_CLICK:
1321 return sEventNames[eDOMEvents_click];
1322 case NS_MOUSE_DOUBLECLICK:
1323 return sEventNames[eDOMEvents_dblclick];
1324 case NS_MOUSE_ENTER_SYNTH:
1325 return sEventNames[eDOMEvents_mouseover];
1326 case NS_MOUSE_EXIT_SYNTH:
1327 return sEventNames[eDOMEvents_mouseout];
1328 case NS_MOUSE_MOVE:
1329 return sEventNames[eDOMEvents_mousemove];
1330 case NS_KEY_UP:
1331 return sEventNames[eDOMEvents_keyup];
1332 case NS_KEY_DOWN:
1333 return sEventNames[eDOMEvents_keydown];
1334 case NS_KEY_PRESS:
1335 return sEventNames[eDOMEvents_keypress];
1336 case NS_COMPOSITION_START:
1337 return sEventNames[eDOMEvents_compositionstart];
1338 case NS_COMPOSITION_END:
1339 return sEventNames[eDOMEvents_compositionend];
1340 case NS_FOCUS_CONTENT:
1341 return sEventNames[eDOMEvents_focus];
1342 case NS_BLUR_CONTENT:
1343 return sEventNames[eDOMEvents_blur];
1344 case NS_XUL_CLOSE:
1345 return sEventNames[eDOMEvents_close];
1346 case NS_LOAD:
1347 return sEventNames[eDOMEvents_load];
1348 case NS_BEFORE_PAGE_UNLOAD:
1349 return sEventNames[eDOMEvents_beforeunload];
1350 case NS_PAGE_UNLOAD:
1351 return sEventNames[eDOMEvents_unload];
1352 case NS_IMAGE_ABORT:
1353 return sEventNames[eDOMEvents_abort];
1354 case NS_LOAD_ERROR:
1355 return sEventNames[eDOMEvents_error];
1356 case NS_FORM_SUBMIT:
1357 return sEventNames[eDOMEvents_submit];
1358 case NS_FORM_RESET:
1359 return sEventNames[eDOMEvents_reset];
1360 case NS_FORM_CHANGE:
1361 return sEventNames[eDOMEvents_change];
1362 case NS_FORM_SELECTED:
1363 return sEventNames[eDOMEvents_select];
1364 case NS_FORM_INPUT:
1365 return sEventNames[eDOMEvents_input];
1366 case NS_PAINT:
1367 return sEventNames[eDOMEvents_paint];
1368 case NS_RESIZE_EVENT:
1369 return sEventNames[eDOMEvents_resize];
1370 case NS_SCROLL_EVENT:
1371 return sEventNames[eDOMEvents_scroll];
1372 case NS_TEXT_TEXT:
1373 return sEventNames[eDOMEvents_text];
1374 case NS_XUL_POPUP_SHOWING:
1375 return sEventNames[eDOMEvents_popupShowing];
1376 case NS_XUL_POPUP_SHOWN:
1377 return sEventNames[eDOMEvents_popupShown];
1378 case NS_XUL_POPUP_HIDING:
1379 return sEventNames[eDOMEvents_popupHiding];
1380 case NS_XUL_POPUP_HIDDEN:
1381 return sEventNames[eDOMEvents_popupHidden];
1382 case NS_XUL_COMMAND:
1383 return sEventNames[eDOMEvents_command];
1384 case NS_XUL_BROADCAST:
1385 return sEventNames[eDOMEvents_broadcast];
1386 case NS_XUL_COMMAND_UPDATE:
1387 return sEventNames[eDOMEvents_commandupdate];
1388 case NS_DRAGDROP_ENTER:
1389 return sEventNames[eDOMEvents_dragenter];
1390 case NS_DRAGDROP_OVER_SYNTH:
1391 return sEventNames[eDOMEvents_dragover];
1392 case NS_DRAGDROP_EXIT_SYNTH:
1393 return sEventNames[eDOMEvents_dragexit];
1394 case NS_DRAGDROP_DRAGDROP:
1395 return sEventNames[eDOMEvents_dragdrop];
1396 case NS_DRAGDROP_GESTURE:
1397 return sEventNames[eDOMEvents_draggesture];
1398 case NS_DRAGDROP_DRAG:
1399 return sEventNames[eDOMEvents_drag];
1400 case NS_DRAGDROP_END:
1401 return sEventNames[eDOMEvents_dragend];
1402 case NS_DRAGDROP_START:
1403 return sEventNames[eDOMEvents_dragstart];
1404 case NS_DRAGDROP_LEAVE_SYNTH:
1405 return sEventNames[eDOMEvents_dragleave];
1406 case NS_DRAGDROP_DROP:
1407 return sEventNames[eDOMEvents_drop];
1408 case NS_SCROLLPORT_OVERFLOW:
1409 return sEventNames[eDOMEvents_overflow];
1410 case NS_SCROLLPORT_UNDERFLOW:
1411 return sEventNames[eDOMEvents_underflow];
1412 case NS_SCROLLPORT_OVERFLOWCHANGED:
1413 return sEventNames[eDOMEvents_overflowchanged];
1414 case NS_MUTATION_SUBTREEMODIFIED:
1415 return sEventNames[eDOMEvents_subtreemodified];
1416 case NS_MUTATION_NODEINSERTED:
1417 return sEventNames[eDOMEvents_nodeinserted];
1418 case NS_MUTATION_NODEREMOVED:
1419 return sEventNames[eDOMEvents_noderemoved];
1420 case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
1421 return sEventNames[eDOMEvents_noderemovedfromdocument];
1422 case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
1423 return sEventNames[eDOMEvents_nodeinsertedintodocument];
1424 case NS_MUTATION_ATTRMODIFIED:
1425 return sEventNames[eDOMEvents_attrmodified];
1426 case NS_MUTATION_CHARACTERDATAMODIFIED:
1427 return sEventNames[eDOMEvents_characterdatamodified];
1428 case NS_CONTEXTMENU:
1429 return sEventNames[eDOMEvents_contextmenu];
1430 case NS_UI_ACTIVATE:
1431 return sEventNames[eDOMEvents_DOMActivate];
1432 case NS_UI_FOCUSIN:
1433 return sEventNames[eDOMEvents_DOMFocusIn];
1434 case NS_UI_FOCUSOUT:
1435 return sEventNames[eDOMEvents_DOMFocusOut];
1436 case NS_PAGE_SHOW:
1437 return sEventNames[eDOMEvents_pageshow];
1438 case NS_PAGE_HIDE:
1439 return sEventNames[eDOMEvents_pagehide];
1440 case NS_MOUSE_SCROLL:
1441 return sEventNames[eDOMEvents_DOMMouseScroll];
1442 case NS_MOUSE_PIXEL_SCROLL:
1443 return sEventNames[eDOMEvents_MozMousePixelScroll];
1444 case NS_OFFLINE:
1445 return sEventNames[eDOMEvents_offline];
1446 case NS_ONLINE:
1447 return sEventNames[eDOMEvents_online];
1448 case NS_COPY:
1449 return sEventNames[eDOMEvents_copy];
1450 case NS_CUT:
1451 return sEventNames[eDOMEvents_cut];
1452 case NS_PASTE:
1453 return sEventNames[eDOMEvents_paste];
1454 #ifdef MOZ_SVG
1455 case NS_SVG_LOAD:
1456 return sEventNames[eDOMEvents_SVGLoad];
1457 case NS_SVG_UNLOAD:
1458 return sEventNames[eDOMEvents_SVGUnload];
1459 case NS_SVG_ABORT:
1460 return sEventNames[eDOMEvents_SVGAbort];
1461 case NS_SVG_ERROR:
1462 return sEventNames[eDOMEvents_SVGError];
1463 case NS_SVG_RESIZE:
1464 return sEventNames[eDOMEvents_SVGResize];
1465 case NS_SVG_SCROLL:
1466 return sEventNames[eDOMEvents_SVGScroll];
1467 case NS_SVG_ZOOM:
1468 return sEventNames[eDOMEvents_SVGZoom];
1469 #endif // MOZ_SVG
1470 #ifdef MOZ_MEDIA
1471 case NS_LOADSTART:
1472 return sEventNames[eDOMEvents_loadstart];
1473 case NS_PROGRESS:
1474 return sEventNames[eDOMEvents_progress];
1475 case NS_LOADEDMETADATA:
1476 return sEventNames[eDOMEvents_loadedmetadata];
1477 case NS_LOADEDDATA:
1478 return sEventNames[eDOMEvents_loadeddata];
1479 case NS_EMPTIED:
1480 return sEventNames[eDOMEvents_emptied];
1481 case NS_STALLED:
1482 return sEventNames[eDOMEvents_stalled];
1483 case NS_PLAY:
1484 return sEventNames[eDOMEvents_play];
1485 case NS_PAUSE:
1486 return sEventNames[eDOMEvents_pause];
1487 case NS_WAITING:
1488 return sEventNames[eDOMEvents_waiting];
1489 case NS_SEEKING:
1490 return sEventNames[eDOMEvents_seeking];
1491 case NS_SEEKED:
1492 return sEventNames[eDOMEvents_seeked];
1493 case NS_TIMEUPDATE:
1494 return sEventNames[eDOMEvents_timeupdate];
1495 case NS_ENDED:
1496 return sEventNames[eDOMEvents_ended];
1497 case NS_CANPLAY:
1498 return sEventNames[eDOMEvents_canplay];
1499 case NS_CANPLAYTHROUGH:
1500 return sEventNames[eDOMEvents_canplaythrough];
1501 case NS_RATECHANGE:
1502 return sEventNames[eDOMEvents_ratechange];
1503 case NS_DURATIONCHANGE:
1504 return sEventNames[eDOMEvents_durationchange];
1505 case NS_VOLUMECHANGE:
1506 return sEventNames[eDOMEvents_volumechange];
1507 #endif
1508 case NS_AFTERPAINT:
1509 return sEventNames[eDOMEvents_afterpaint];
1510 case NS_SIMPLE_GESTURE_SWIPE:
1511 return sEventNames[eDOMEvents_MozSwipeGesture];
1512 case NS_SIMPLE_GESTURE_MAGNIFY_START:
1513 return sEventNames[eDOMEvents_MozMagnifyGestureStart];
1514 case NS_SIMPLE_GESTURE_MAGNIFY_UPDATE:
1515 return sEventNames[eDOMEvents_MozMagnifyGestureUpdate];
1516 case NS_SIMPLE_GESTURE_MAGNIFY:
1517 return sEventNames[eDOMEvents_MozMagnifyGesture];
1518 case NS_SIMPLE_GESTURE_ROTATE_START:
1519 return sEventNames[eDOMEvents_MozRotateGestureStart];
1520 case NS_SIMPLE_GESTURE_ROTATE_UPDATE:
1521 return sEventNames[eDOMEvents_MozRotateGestureUpdate];
1522 case NS_SIMPLE_GESTURE_ROTATE:
1523 return sEventNames[eDOMEvents_MozRotateGesture];
1524 default:
1525 break;
1527 // XXXldb We can hit this case for nsEvent objects that we didn't
1528 // create and that are not user defined events since this function and
1529 // SetEventType are incomplete. (But fixing that requires fixing the
1530 // arrays in nsEventListenerManager too, since the events for which
1531 // this is a problem generally *are* created by nsDOMEvent.)
1532 return nsnull;
1535 nsresult
1536 nsDOMEvent::ReportWrongPropertyAccessWarning(const char* aPropertyName)
1538 nsCOMPtr<nsIDocument> doc(GetDocumentForReport(mEvent));
1540 nsAutoString propertyName, type;
1541 GetType(type);
1542 propertyName.AssignASCII(aPropertyName);
1543 const PRUnichar *strings[] = { propertyName.get(), type.get() };
1545 return nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
1546 "WrongEventPropertyAccessWarning",
1547 strings, NS_ARRAY_LENGTH(strings),
1548 doc ? doc->GetDocumentURI() : nsnull,
1549 EmptyString(), 0, 0,
1550 nsIScriptError::warningFlag,
1551 "DOM Events");
1554 nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult,
1555 nsPresContext* aPresContext,
1556 nsEvent *aEvent)
1558 nsDOMEvent* it = new nsDOMEvent(aPresContext, aEvent);
1559 if (nsnull == it) {
1560 return NS_ERROR_OUT_OF_MEMORY;
1563 return CallQueryInterface(it, aInstancePtrResult);