Back to index

lightning-sunbird  0.9+nobinonly
nsDOMEvent.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Steve Clark (buster@netscape.com)
00024  *   Ilya Konstantinov (mozilla-code@future.shiny.co.il)
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsCOMPtr.h"
00041 #include "nsDOMEvent.h"
00042 #include "nsEventStateManager.h"
00043 #include "nsIFrame.h"
00044 #include "nsIContent.h"
00045 #include "nsIPresShell.h"
00046 #include "nsIDocument.h"
00047 #include "nsIPrivateCompositionEvent.h"
00048 #include "nsIDOMEventTarget.h"
00049 #include "nsIInterfaceRequestor.h"
00050 #include "nsIInterfaceRequestorUtils.h"
00051 #include "prmem.h"
00052 #include "nsLayoutAtoms.h"
00053 #include "nsMutationEvent.h"
00054 #include "nsContentUtils.h"
00055 #include "nsIURI.h"
00056 #include "nsIScriptSecurityManager.h"
00057 #include "nsIScriptError.h"
00058 
00059 static const char* const sEventNames[] = {
00060   "mousedown", "mouseup", "click", "dblclick", "mouseover",
00061   "mouseout", "mousemove", "contextmenu", "keydown", "keyup", "keypress",
00062   "focus", "blur", "load", "beforeunload", "unload", "abort", "error",
00063   "submit", "reset", "change", "select", "input", "paint" ,"text",
00064   "compositionstart", "compositionend", "popupshowing", "popupshown",
00065   "popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate",
00066   "dragenter", "dragover", "dragexit", "dragdrop", "draggesture", "resize",
00067   "scroll","overflow", "underflow", "overflowchanged",
00068   "DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved", 
00069   "DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
00070   "DOMAttrModified", "DOMCharacterDataModified",
00071   "DOMActivate", "DOMFocusIn", "DOMFocusOut",
00072   "pageshow", "pagehide"
00073 #ifdef MOZ_SVG
00074  ,
00075   "SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
00076   "SVGZoom"
00077 #endif // MOZ_SVG
00078 };
00079 
00080 static char *sPopupAllowedEvents;
00081 
00082 
00083 nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
00084 {
00085   mPresContext = aPresContext;
00086 
00087   if (aEvent) {
00088     mEvent = aEvent;
00089     mEventIsInternal = PR_FALSE;
00090   }
00091   else {
00092     mEventIsInternal = PR_TRUE;
00093     /*
00094       A derived class might want to allocate its own type of aEvent
00095       (derived from nsEvent). To do this, it should take care to pass
00096       a non-NULL aEvent to this ctor, e.g.:
00097       
00098         nsDOMFooEvent::nsDOMFooEvent(..., nsEvent* aEvent)
00099         : nsDOMEvent(..., aEvent ? aEvent : new nsFooEvent())
00100       
00101       Then, to override the mEventIsInternal assignments done by the
00102       base ctor, it should do this in its own ctor:
00103 
00104         nsDOMFooEvent::nsDOMFooEvent(..., nsEvent* aEvent)
00105         ...
00106         {
00107           ...
00108           if (aEvent) {
00109             mEventIsInternal = PR_FALSE;
00110           }
00111           else {
00112             mEventIsInternal = PR_TRUE;
00113           }
00114           ...
00115         }
00116      */
00117     mEvent = new nsEvent(PR_FALSE, 0);
00118     mEvent->time = PR_Now();
00119   }
00120 
00121   // Get the explicit original target (if it's anonymous make it null)
00122   {
00123     mExplicitOriginalTarget = GetTargetFromFrame();
00124     mTmpRealOriginalTarget = mExplicitOriginalTarget;
00125     nsCOMPtr<nsIContent> content = do_QueryInterface(mExplicitOriginalTarget);
00126     if (content) {
00127       if (content->IsNativeAnonymous()) {
00128         mExplicitOriginalTarget = nsnull;
00129       }
00130       if (content->GetBindingParent()) {
00131         mExplicitOriginalTarget = nsnull;
00132       }
00133     }
00134   }
00135 }
00136 
00137 nsDOMEvent::~nsDOMEvent() 
00138 {
00139   NS_ASSERT_OWNINGTHREAD(nsDOMEvent);
00140 
00141   if (mEventIsInternal && mEvent) {
00142     delete mEvent->userType;
00143     delete mEvent;
00144   }
00145 }
00146 
00147 NS_IMPL_ADDREF(nsDOMEvent)
00148 NS_IMPL_RELEASE(nsDOMEvent)
00149 
00150 NS_INTERFACE_MAP_BEGIN(nsDOMEvent)
00151   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEvent)
00152   NS_INTERFACE_MAP_ENTRY(nsIDOMEvent)
00153   NS_INTERFACE_MAP_ENTRY(nsIDOMNSEvent)
00154   NS_INTERFACE_MAP_ENTRY(nsIPrivateDOMEvent)
00155   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(Event)
00156 NS_INTERFACE_MAP_END
00157 
00158 // nsIDOMEventInterface
00159 NS_METHOD nsDOMEvent::GetType(nsAString& aType)
00160 {
00161   const char* name = GetEventName(mEvent->message);
00162 
00163   if (name) {
00164     CopyASCIItoUTF16(name, aType);
00165     return NS_OK;
00166   }
00167   else {
00168     if (mEvent->message == NS_USER_DEFINED_EVENT && mEvent->userType) {
00169       aType.Assign(NS_STATIC_CAST(nsStringKey*, mEvent->userType)->GetString());
00170       return NS_OK;
00171     }
00172   }
00173   
00174   return NS_ERROR_FAILURE;
00175 }
00176 
00177 NS_METHOD nsDOMEvent::GetTarget(nsIDOMEventTarget** aTarget)
00178 {
00179   if (nsnull != mTarget) {
00180     *aTarget = mTarget;
00181     NS_ADDREF(*aTarget);
00182     return NS_OK;
00183   }
00184   
00185   *aTarget = nsnull;
00186 
00187   nsCOMPtr<nsIContent> targetContent;  
00188 
00189   if (mPresContext) {
00190     mPresContext->EventStateManager()->
00191       GetEventTargetContent(mEvent, getter_AddRefs(targetContent));
00192   }
00193   
00194   if (targetContent) {
00195     mTarget = do_QueryInterface(targetContent);
00196     if (mTarget) {
00197       *aTarget = mTarget;
00198       NS_ADDREF(*aTarget);
00199     }
00200   }
00201   else {
00202     //Always want a target.  Use document if nothing else.
00203     nsIPresShell *presShell;
00204     if (mPresContext && (presShell = mPresContext->GetPresShell())) {
00205       nsIDocument *doc = presShell->GetDocument();
00206       if (doc) {
00207         mTarget = do_QueryInterface(doc);
00208         if (mTarget) {
00209           *aTarget = mTarget;
00210           NS_ADDREF(*aTarget);
00211         }      
00212       }
00213     }
00214   }
00215 
00216   return NS_OK;
00217 }
00218 
00219 NS_IMETHODIMP
00220 nsDOMEvent::GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget)
00221 {
00222   *aCurrentTarget = mCurrentTarget;
00223   NS_IF_ADDREF(*aCurrentTarget);
00224   return NS_OK;
00225 }
00226 
00227 //
00228 // Get the actual event target node (may have been retargeted for mouse events)
00229 //
00230 already_AddRefed<nsIDOMEventTarget>
00231 nsDOMEvent::GetTargetFromFrame()
00232 {
00233   if (!mPresContext) { return nsnull; }
00234 
00235   // Get the target frame (have to get the ESM first)
00236   nsIFrame* targetFrame = nsnull;
00237   mPresContext->EventStateManager()->GetEventTarget(&targetFrame);
00238   if (!targetFrame) { return nsnull; }
00239 
00240   // get the real content
00241   nsCOMPtr<nsIContent> realEventContent;
00242   targetFrame->GetContentForEvent(mPresContext, mEvent, getter_AddRefs(realEventContent));
00243   if (!realEventContent) { return nsnull; }
00244 
00245   // Finally, we have the real content.  QI it and return.
00246   nsIDOMEventTarget* target = nsnull;
00247   CallQueryInterface(realEventContent, &target);
00248   return target;
00249 }
00250 
00251 NS_IMETHODIMP
00252 nsDOMEvent::GetExplicitOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
00253 {
00254   if (mExplicitOriginalTarget) {
00255     *aRealEventTarget = mExplicitOriginalTarget;
00256     NS_ADDREF(*aRealEventTarget);
00257     return NS_OK;
00258   }
00259 
00260   return GetTarget(aRealEventTarget);
00261 }
00262 
00263 NS_IMETHODIMP
00264 nsDOMEvent::GetTmpRealOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
00265 {
00266   if (mTmpRealOriginalTarget) {
00267     *aRealEventTarget = mTmpRealOriginalTarget;
00268     NS_ADDREF(*aRealEventTarget);
00269     return NS_OK;
00270   }
00271 
00272   return GetOriginalTarget(aRealEventTarget);
00273 }
00274 
00275 NS_IMETHODIMP
00276 nsDOMEvent::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
00277 {
00278   if (!mOriginalTarget)
00279     return GetTarget(aOriginalTarget);
00280 
00281   *aOriginalTarget = mOriginalTarget;
00282   NS_IF_ADDREF(*aOriginalTarget);
00283   return NS_OK;
00284 }
00285 
00286 NS_IMETHODIMP
00287 nsDOMEvent::HasOriginalTarget(PRBool* aResult)
00288 {
00289   *aResult = (mOriginalTarget != nsnull);
00290   return NS_OK;
00291 }
00292 
00293 NS_IMETHODIMP
00294 nsDOMEvent::SetTrusted(PRBool aTrusted)
00295 {
00296   if (aTrusted) {
00297     mEvent->internalAppFlags |= NS_APP_EVENT_FLAG_TRUSTED;
00298   } else {
00299     mEvent->internalAppFlags &= ~NS_APP_EVENT_FLAG_TRUSTED;
00300   }
00301 
00302   return NS_OK;
00303 }
00304 
00305 NS_IMETHODIMP
00306 nsDOMEvent::GetEventPhase(PRUint16* aEventPhase)
00307 {
00308   if (mEvent->flags & NS_EVENT_FLAG_CAPTURE) {
00309     if (mEvent->flags & NS_EVENT_FLAG_BUBBLE) {
00310       *aEventPhase = nsIDOMEvent::AT_TARGET;
00311     }
00312     else {
00313       *aEventPhase = nsIDOMEvent::CAPTURING_PHASE;
00314     }
00315   }
00316   else if (mEvent->flags & NS_EVENT_FLAG_BUBBLE) {
00317     *aEventPhase = nsIDOMEvent::BUBBLING_PHASE;
00318   }
00319   else {
00320     *aEventPhase = 0;
00321   }
00322 
00323   return NS_OK;
00324 }
00325 
00326 NS_IMETHODIMP
00327 nsDOMEvent::GetBubbles(PRBool* aBubbles)
00328 {
00329   *aBubbles = !(mEvent->flags & NS_EVENT_FLAG_CANT_BUBBLE);
00330   return NS_OK;
00331 }
00332 
00333 NS_IMETHODIMP
00334 nsDOMEvent::GetCancelable(PRBool* aCancelable)
00335 {
00336   *aCancelable = !(mEvent->flags & NS_EVENT_FLAG_CANT_CANCEL);
00337   return NS_OK;
00338 }
00339 
00340 NS_IMETHODIMP
00341 nsDOMEvent::GetTimeStamp(PRUint64* aTimeStamp)
00342 {
00343   LL_UI2L(*aTimeStamp, mEvent->time);
00344   return NS_OK;
00345 }
00346 
00347 NS_IMETHODIMP
00348 nsDOMEvent::StopPropagation()
00349 {
00350   mEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
00351   return NS_OK;
00352 }
00353 
00354 static void
00355 ReportUseOfDeprecatedMethod(nsIDOMEvent* aDOMEvent, const char* aWarning)
00356 {
00357   nsCOMPtr<nsIDocument> doc;
00358   nsCOMPtr<nsIDOMEventTarget> target;
00359   aDOMEvent->GetCurrentTarget(getter_AddRefs(target));
00360   nsCOMPtr<nsIContent> content = do_QueryInterface(target);
00361   if (content) {
00362     doc = content->GetOwnerDoc();
00363   } else {
00364     doc = do_QueryInterface(target);
00365     if (!doc) {
00366       nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(target);
00367       if (window) {
00368         doc = do_QueryInterface(window->GetExtantDocument());
00369       }
00370     }
00371   }
00372 
00373   nsAutoString type;
00374   aDOMEvent->GetType(type);
00375   const PRUnichar *strings[] = { type.get() };
00376   nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
00377                                   aWarning,
00378                                   strings, NS_ARRAY_LENGTH(strings),
00379                                   doc ? doc->GetDocumentURI() : nsnull,
00380                                   EmptyString(), 0, 0,
00381                                   nsIScriptError::warningFlag,
00382                                   "DOM Events");
00383 }
00384 
00385 NS_IMETHODIMP
00386 nsDOMEvent::PreventBubble()
00387 {
00388   ReportUseOfDeprecatedMethod(this, "UseOfPreventBubbleWarning");
00389 
00390   if (mEvent->flags & NS_EVENT_FLAG_BUBBLE || mEvent->flags & NS_EVENT_FLAG_INIT) {
00391     mEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
00392   }
00393   return NS_OK;
00394 }
00395 
00396 NS_IMETHODIMP
00397 nsDOMEvent::PreventCapture()
00398 {
00399   ReportUseOfDeprecatedMethod(this, "UseOfPreventCaptureWarning");
00400 
00401   if (mEvent->flags & NS_EVENT_FLAG_CAPTURE) {
00402     mEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
00403   }
00404   return NS_OK;
00405 }
00406 
00407 NS_IMETHODIMP
00408 nsDOMEvent::GetIsTrusted(PRBool *aIsTrusted)
00409 {
00410   *aIsTrusted = NS_IS_TRUSTED_EVENT(mEvent);
00411 
00412   return NS_OK;
00413 }
00414 
00415 NS_IMETHODIMP
00416 nsDOMEvent::PreventDefault()
00417 {
00418   if (!(mEvent->flags & NS_EVENT_FLAG_CANT_CANCEL)) {
00419     mEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT;
00420   }
00421   return NS_OK;
00422 }
00423 
00424 nsresult
00425 nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
00426 {
00427   nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aEventTypeArg);
00428   mEvent->message = NS_USER_DEFINED_EVENT;
00429 
00430   if (mEvent->eventStructType == NS_MOUSE_EVENT) {
00431     if (atom == nsLayoutAtoms::onmousedown)
00432       mEvent->message = NS_MOUSE_LEFT_BUTTON_DOWN;
00433     else if (atom == nsLayoutAtoms::onmouseup)
00434       mEvent->message = NS_MOUSE_LEFT_BUTTON_UP;
00435     else if (atom == nsLayoutAtoms::onclick)
00436       mEvent->message = NS_MOUSE_LEFT_CLICK;
00437     else if (atom == nsLayoutAtoms::ondblclick)
00438       mEvent->message = NS_MOUSE_LEFT_DOUBLECLICK;
00439     else if (atom == nsLayoutAtoms::onmouseover)
00440       mEvent->message = NS_MOUSE_ENTER_SYNTH;
00441     else if (atom == nsLayoutAtoms::onmouseout)
00442       mEvent->message = NS_MOUSE_EXIT_SYNTH;
00443     else if (atom == nsLayoutAtoms::onmousemove)
00444       mEvent->message = NS_MOUSE_MOVE;
00445     else if (atom == nsLayoutAtoms::oncontextmenu)
00446       mEvent->message = NS_CONTEXTMENU;
00447   } else if (mEvent->eventStructType == NS_KEY_EVENT) {
00448     if (atom == nsLayoutAtoms::onkeydown)
00449       mEvent->message = NS_KEY_DOWN;
00450     else if (atom == nsLayoutAtoms::onkeyup)
00451       mEvent->message = NS_KEY_UP;
00452     else if (atom == nsLayoutAtoms::onkeypress)
00453       mEvent->message = NS_KEY_PRESS;
00454   } else if (mEvent->eventStructType == NS_COMPOSITION_EVENT) {
00455     if (atom == nsLayoutAtoms::oncompositionstart)
00456       mEvent->message = NS_COMPOSITION_START;
00457     else if (atom == nsLayoutAtoms::oncompositionend)
00458       mEvent->message = NS_COMPOSITION_END;
00459   } else if (mEvent->eventStructType == NS_EVENT) {
00460     if (atom == nsLayoutAtoms::onfocus)
00461       mEvent->message = NS_FOCUS_CONTENT;
00462     else if (atom == nsLayoutAtoms::onblur)
00463       mEvent->message = NS_BLUR_CONTENT;
00464     else if (atom == nsLayoutAtoms::onsubmit)
00465       mEvent->message = NS_FORM_SUBMIT;
00466     else if (atom == nsLayoutAtoms::onreset)
00467       mEvent->message = NS_FORM_RESET;
00468     else if (atom == nsLayoutAtoms::onchange)
00469       mEvent->message = NS_FORM_CHANGE;
00470     else if (atom == nsLayoutAtoms::onselect)
00471       mEvent->message = NS_FORM_SELECTED;
00472     else if (atom == nsLayoutAtoms::onload)
00473       mEvent->message = NS_PAGE_LOAD;
00474     else if (atom == nsLayoutAtoms::onunload)
00475       mEvent->message = NS_PAGE_UNLOAD;
00476     else if (atom == nsLayoutAtoms::onabort)
00477       mEvent->message = NS_IMAGE_ABORT;
00478     else if (atom == nsLayoutAtoms::onerror)
00479       mEvent->message = NS_IMAGE_ERROR;
00480   } else if (mEvent->eventStructType == NS_MUTATION_EVENT) {
00481     if (atom == nsLayoutAtoms::onDOMAttrModified)
00482       mEvent->message = NS_MUTATION_ATTRMODIFIED;
00483     else if (atom == nsLayoutAtoms::onDOMCharacterDataModified)
00484       mEvent->message = NS_MUTATION_CHARACTERDATAMODIFIED;
00485     else if (atom == nsLayoutAtoms::onDOMNodeInserted)
00486       mEvent->message = NS_MUTATION_NODEINSERTED;
00487     else if (atom == nsLayoutAtoms::onDOMNodeRemoved)
00488       mEvent->message = NS_MUTATION_NODEREMOVED;
00489     else if (atom == nsLayoutAtoms::onDOMNodeInsertedIntoDocument)
00490       mEvent->message = NS_MUTATION_NODEINSERTEDINTODOCUMENT;
00491     else if (atom == nsLayoutAtoms::onDOMNodeRemovedFromDocument)
00492       mEvent->message = NS_MUTATION_NODEREMOVEDFROMDOCUMENT;
00493     else if (atom == nsLayoutAtoms::onDOMSubtreeModified)
00494       mEvent->message = NS_MUTATION_SUBTREEMODIFIED;
00495   } else if (mEvent->eventStructType == NS_UI_EVENT) {
00496     if (atom == nsLayoutAtoms::onDOMActivate)
00497       mEvent->message = NS_UI_ACTIVATE;
00498     else if (atom == nsLayoutAtoms::onDOMFocusIn)
00499       mEvent->message = NS_UI_FOCUSIN;
00500     else if (atom == nsLayoutAtoms::onDOMFocusOut)
00501       mEvent->message = NS_UI_FOCUSOUT;
00502     else if (atom == nsLayoutAtoms::oninput)
00503       mEvent->message = NS_FORM_INPUT;
00504   } else if (mEvent->eventStructType == NS_PAGETRANSITION_EVENT) {
00505     if (atom == nsLayoutAtoms::onpageshow)
00506       mEvent->message = NS_PAGE_SHOW;
00507     else if (atom == nsLayoutAtoms::onpagehide)
00508       mEvent->message = NS_PAGE_HIDE;
00509   }
00510 #ifdef MOZ_SVG
00511   else if (mEvent->eventStructType == NS_SVG_EVENT) {
00512     if (atom == nsLayoutAtoms::onSVGLoad)
00513       mEvent->message = NS_SVG_LOAD;
00514     else if (atom == nsLayoutAtoms::onSVGUnload)
00515       mEvent->message = NS_SVG_UNLOAD;
00516     else if (atom == nsLayoutAtoms::onSVGAbort)
00517       mEvent->message = NS_SVG_ABORT;
00518     else if (atom == nsLayoutAtoms::onSVGError)
00519       mEvent->message = NS_SVG_ERROR;
00520     else if (atom == nsLayoutAtoms::onSVGResize)
00521       mEvent->message = NS_SVG_RESIZE;
00522     else if (atom == nsLayoutAtoms::onSVGScroll)
00523       mEvent->message = NS_SVG_SCROLL;
00524   } else if (mEvent->eventStructType == NS_SVGZOOM_EVENT) {
00525     if (atom == nsLayoutAtoms::onSVGZoom)
00526       mEvent->message = NS_SVG_ZOOM;
00527   }
00528 #endif // MOZ_SVG
00529 
00530   if (mEvent->message == NS_USER_DEFINED_EVENT)
00531     mEvent->userType = new nsStringKey(aEventTypeArg);
00532 
00533   return NS_OK;
00534 }
00535 
00536 NS_IMETHODIMP
00537 nsDOMEvent::InitEvent(const nsAString& aEventTypeArg, PRBool aCanBubbleArg, PRBool aCancelableArg)
00538 {
00539   // Make sure this event isn't already being dispatched.
00540   NS_ENSURE_TRUE(!NS_IS_EVENT_IN_DISPATCH(mEvent), NS_ERROR_INVALID_ARG);
00541 
00542   if (NS_IS_TRUSTED_EVENT(mEvent)) {
00543     // Ensure the caller is permitted to dispatch trusted DOM events.
00544 
00545     PRBool enabled = PR_FALSE;
00546     nsContentUtils::GetSecurityManager()->
00547       IsCapabilityEnabled("UniversalBrowserWrite", &enabled);
00548 
00549     if (!enabled) {
00550       SetTrusted(PR_FALSE);
00551     }
00552   }
00553 
00554   NS_ENSURE_SUCCESS(SetEventType(aEventTypeArg), NS_ERROR_FAILURE);
00555 
00556   mEvent->flags |=
00557     aCanBubbleArg ? NS_EVENT_FLAG_NONE : NS_EVENT_FLAG_CANT_BUBBLE;
00558   mEvent->flags |=
00559     aCancelableArg ? NS_EVENT_FLAG_NONE : NS_EVENT_FLAG_CANT_CANCEL;
00560 
00561   // Unset the NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY bit (which is
00562   // set at the end of event dispatch) so that this event can be
00563   // dispatched.
00564   mEvent->flags &= ~NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY;
00565 
00566   return NS_OK;
00567 }
00568 
00569 NS_METHOD nsDOMEvent::DuplicatePrivateData()
00570 {
00571   // FIXME! Simplify this method and make it somehow easily extendable,
00572   //        Bug 329127
00573   
00574   NS_ASSERTION(mEvent, "No nsEvent for nsDOMEvent duplication!");
00575   if (mEventIsInternal) {
00576     return NS_OK;
00577   }
00578 
00579   nsEvent* newEvent = nsnull;
00580   PRUint32 msg = mEvent->message;
00581   PRBool isInputEvent = PR_FALSE;
00582 
00583   switch (mEvent->eventStructType) {
00584     case NS_EVENT:
00585     {
00586       newEvent = new nsEvent(PR_FALSE, msg);
00587       break;
00588     }
00589     case NS_GUI_EVENT:
00590     {
00591       // Not copying widget, it is a weak reference.
00592       newEvent = new nsGUIEvent(PR_FALSE, msg, nsnull);
00593       break;
00594     }
00595     case NS_SIZE_EVENT:
00596     {
00597       nsSizeEvent* sizeEvent = new nsSizeEvent(PR_FALSE, msg, nsnull);
00598       NS_ENSURE_TRUE(sizeEvent, NS_ERROR_OUT_OF_MEMORY);
00599       sizeEvent->mWinWidth = NS_STATIC_CAST(nsSizeEvent*, mEvent)->mWinWidth;
00600       sizeEvent->mWinHeight = NS_STATIC_CAST(nsSizeEvent*, mEvent)->mWinHeight;
00601       newEvent = sizeEvent;
00602       break;
00603     }
00604     case NS_SIZEMODE_EVENT:
00605     {
00606       newEvent = new nsSizeModeEvent(PR_FALSE, msg, nsnull);
00607       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00608       NS_STATIC_CAST(nsSizeModeEvent*, newEvent)->mSizeMode =
00609         NS_STATIC_CAST(nsSizeModeEvent*, mEvent)->mSizeMode;
00610       break;
00611     }
00612     case NS_ZLEVEL_EVENT:
00613     {
00614       nsZLevelEvent* zLevelEvent = new nsZLevelEvent(PR_FALSE, msg, nsnull);
00615       NS_ENSURE_TRUE(zLevelEvent, NS_ERROR_OUT_OF_MEMORY);
00616       nsZLevelEvent* oldZLevelEvent = NS_STATIC_CAST(nsZLevelEvent*, mEvent);
00617       zLevelEvent->mPlacement = oldZLevelEvent->mPlacement;
00618       zLevelEvent->mImmediate = oldZLevelEvent->mImmediate;
00619       zLevelEvent->mAdjusted = oldZLevelEvent->mAdjusted;
00620       newEvent = zLevelEvent;
00621       break;
00622     }
00623     case NS_PAINT_EVENT:
00624     {
00625       newEvent = new nsPaintEvent(PR_FALSE, msg, nsnull);
00626       break;
00627     }
00628     case NS_SCROLLBAR_EVENT:
00629     {
00630       newEvent = new nsScrollbarEvent(PR_FALSE, msg, nsnull);
00631       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00632       NS_STATIC_CAST(nsScrollbarEvent*, newEvent)->position =
00633         NS_STATIC_CAST(nsScrollbarEvent*, mEvent)->position;
00634       break;
00635     }
00636     case NS_INPUT_EVENT:
00637     {
00638       newEvent = new nsInputEvent(PR_FALSE, msg, nsnull);
00639       isInputEvent = PR_TRUE;
00640       break;
00641     }
00642     case NS_KEY_EVENT:
00643     {
00644       nsKeyEvent* keyEvent = new nsKeyEvent(PR_FALSE, msg, nsnull);
00645       NS_ENSURE_TRUE(keyEvent, NS_ERROR_OUT_OF_MEMORY);
00646       nsKeyEvent* oldKeyEvent = NS_STATIC_CAST(nsKeyEvent*, mEvent);
00647       isInputEvent = PR_TRUE;
00648       keyEvent->keyCode = oldKeyEvent->keyCode;
00649       keyEvent->charCode = oldKeyEvent->charCode;
00650       keyEvent->isChar = oldKeyEvent->isChar;
00651       newEvent = keyEvent;
00652       break;
00653     }
00654     case NS_MOUSE_EVENT:
00655     {
00656       nsMouseEvent* oldMouseEvent = NS_STATIC_CAST(nsMouseEvent*, mEvent);
00657       nsMouseEvent* mouseEvent =
00658         new nsMouseEvent(PR_FALSE, msg, nsnull, oldMouseEvent->reason);
00659       NS_ENSURE_TRUE(mouseEvent, NS_ERROR_OUT_OF_MEMORY);
00660       isInputEvent = PR_TRUE;
00661       mouseEvent->clickCount = oldMouseEvent->clickCount;
00662       mouseEvent->acceptActivation = oldMouseEvent->acceptActivation;
00663       newEvent = mouseEvent;
00664       break;
00665     }
00666     case NS_MENU_EVENT:
00667     {
00668       newEvent = new nsMenuEvent(PR_FALSE, msg, nsnull);
00669       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00670       NS_STATIC_CAST(nsMenuEvent*, newEvent)->mCommand =
00671         NS_STATIC_CAST(nsMenuEvent*, mEvent)->mCommand;
00672       break;
00673     }
00674     case NS_SCRIPT_ERROR_EVENT:
00675     {
00676       newEvent = new nsScriptErrorEvent(PR_FALSE, msg);
00677       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00678       NS_STATIC_CAST(nsScriptErrorEvent*, newEvent)->lineNr =
00679         NS_STATIC_CAST(nsScriptErrorEvent*, mEvent)->lineNr;
00680       break;
00681     }
00682     case NS_TEXT_EVENT:
00683     {
00684       newEvent = new nsTextEvent(PR_FALSE, msg, nsnull);
00685       isInputEvent = PR_TRUE;
00686       break;
00687     }
00688     case NS_COMPOSITION_EVENT:
00689     {
00690       newEvent = new nsCompositionEvent(PR_FALSE, msg, nsnull);
00691       isInputEvent = PR_TRUE;
00692       break;
00693     }
00694     case NS_RECONVERSION_EVENT:
00695     {
00696       newEvent = new nsReconversionEvent(PR_FALSE, msg, nsnull);
00697       isInputEvent = PR_TRUE;
00698       break;
00699     }
00700     case NS_MOUSE_SCROLL_EVENT:
00701     {
00702       nsMouseScrollEvent* mouseScrollEvent =
00703         new nsMouseScrollEvent(PR_FALSE, msg, nsnull);
00704       NS_ENSURE_TRUE(mouseScrollEvent, NS_ERROR_OUT_OF_MEMORY);
00705       isInputEvent = PR_TRUE;
00706       nsMouseScrollEvent* oldMouseScrollEvent =
00707         NS_STATIC_CAST(nsMouseScrollEvent*, mEvent);
00708       mouseScrollEvent->scrollFlags = oldMouseScrollEvent->scrollFlags;
00709       mouseScrollEvent->delta = oldMouseScrollEvent->delta;
00710       newEvent = mouseScrollEvent;
00711       break;
00712     }
00713     case NS_SCROLLPORT_EVENT:
00714     {
00715       newEvent = new nsScrollPortEvent(PR_FALSE, msg, nsnull);
00716       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00717       NS_STATIC_CAST(nsScrollPortEvent*, newEvent)->orient =
00718         NS_STATIC_CAST(nsScrollPortEvent*, mEvent)->orient;
00719       break;
00720     }
00721     case NS_MUTATION_EVENT:
00722     {
00723       nsMutationEvent* mutationEvent = new nsMutationEvent(PR_FALSE, msg);
00724       NS_ENSURE_TRUE(mutationEvent, NS_ERROR_OUT_OF_MEMORY);
00725       nsMutationEvent* oldMutationEvent =
00726         NS_STATIC_CAST(nsMutationEvent*, mEvent);
00727       mutationEvent->mRelatedNode = oldMutationEvent->mRelatedNode;
00728       mutationEvent->mAttrName = oldMutationEvent->mAttrName;
00729       mutationEvent->mPrevAttrValue = oldMutationEvent->mPrevAttrValue;
00730       mutationEvent->mNewAttrValue = oldMutationEvent->mNewAttrValue;
00731       mutationEvent->mAttrChange = oldMutationEvent->mAttrChange;
00732       newEvent = mutationEvent;
00733       break;
00734     }
00735     case NS_ACCESSIBLE_EVENT:
00736     {
00737       newEvent = new nsAccessibleEvent(PR_FALSE, msg, nsnull);
00738       isInputEvent = PR_TRUE;
00739       break;
00740     }
00741     case NS_FORM_EVENT:
00742     {
00743       newEvent = new nsFormEvent(PR_FALSE, msg);
00744       break;
00745     }
00746     case NS_FOCUS_EVENT:
00747     {
00748       newEvent = new nsFocusEvent(PR_FALSE, msg, nsnull);
00749       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00750       NS_STATIC_CAST(nsFocusEvent*, newEvent)->isMozWindowTakingFocus =
00751         NS_STATIC_CAST(nsFocusEvent*, mEvent)->isMozWindowTakingFocus;
00752       break;
00753     }
00754     case NS_POPUP_EVENT:
00755     {
00756       newEvent = new nsInputEvent(PR_FALSE, msg, nsnull);
00757       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00758       isInputEvent = PR_TRUE;
00759       newEvent->eventStructType = NS_POPUP_EVENT;
00760       break;
00761     }
00762     case NS_APPCOMMAND_EVENT:
00763     {
00764       newEvent = new nsAppCommandEvent(PR_FALSE, msg, nsnull);
00765       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00766       isInputEvent = PR_TRUE;
00767       NS_STATIC_CAST(nsAppCommandEvent*, newEvent)->appCommand =
00768         NS_STATIC_CAST(nsAppCommandEvent*, mEvent)->appCommand;
00769       break;
00770     }
00771     case NS_POPUPBLOCKED_EVENT:
00772     {
00773       NS_WARNING("nsPopupBlockedEvent should never be an external event!");
00774       newEvent = new nsPopupBlockedEvent(PR_FALSE, msg);
00775       break;
00776     }
00777     case NS_BEFORE_PAGE_UNLOAD_EVENT:
00778     {
00779       newEvent = new nsBeforePageUnloadEvent(PR_FALSE, msg);
00780       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00781       NS_STATIC_CAST(nsBeforePageUnloadEvent*, newEvent)->text =
00782         NS_STATIC_CAST(nsBeforePageUnloadEvent*, mEvent)->text;
00783       break;
00784     }
00785     case NS_UI_EVENT:
00786     {
00787       newEvent = new nsUIEvent(PR_FALSE, msg,
00788                                NS_STATIC_CAST(nsUIEvent*, mEvent)->detail);
00789       break;
00790     }
00791     case NS_QUERYCARETRECT_EVENT:
00792     {
00793       newEvent = new nsQueryCaretRectEvent(PR_FALSE, msg, nsnull);
00794       isInputEvent = PR_TRUE;
00795       break;
00796     }
00797     case NS_PAGETRANSITION_EVENT:
00798     {
00799       newEvent =
00800         new nsPageTransitionEvent(PR_FALSE, msg,
00801                                   ((nsPageTransitionEvent*) mEvent)->persisted);
00802       break;
00803     }
00804 #ifdef MOZ_SVG
00805     case NS_SVG_EVENT:
00806     {
00807       newEvent = new nsEvent(PR_FALSE, msg);
00808       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00809       newEvent->eventStructType = NS_SVG_EVENT;
00810       break;
00811     }
00812     case NS_SVGZOOM_EVENT:
00813     {
00814       newEvent = new nsGUIEvent(PR_FALSE, msg, nsnull);
00815       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00816       newEvent->eventStructType = NS_SVGZOOM_EVENT;
00817       break;
00818     }
00819 #endif // MOZ_SVG
00820     case NS_XUL_COMMAND_EVENT:
00821     {
00822       newEvent = new nsXULCommandEvent(PR_FALSE, msg, nsnull);
00823       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00824       isInputEvent = PR_TRUE;
00825       newEvent->eventStructType = NS_XUL_COMMAND_EVENT;
00826       NS_STATIC_CAST(nsXULCommandEvent*, newEvent)->sourceEvent =
00827         NS_STATIC_CAST(nsXULCommandEvent*, mEvent)->sourceEvent;
00828       break;
00829     }
00830     default:
00831     {
00832       NS_WARNING("Unknown event type!!!");
00833       return NS_ERROR_FAILURE;
00834     }
00835   }
00836 
00837   NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
00838 
00839   if (isInputEvent) {
00840     nsInputEvent* oldInputEvent = NS_STATIC_CAST(nsInputEvent*, mEvent);
00841     nsInputEvent* newInputEvent = NS_STATIC_CAST(nsInputEvent*, newEvent);
00842     newInputEvent->isShift = oldInputEvent->isShift;
00843     newInputEvent->isControl = oldInputEvent->isControl;
00844     newInputEvent->isAlt = oldInputEvent->isAlt;
00845     newInputEvent->isMeta = oldInputEvent->isMeta;
00846   }
00847 
00848   if (!mTarget) {
00849     // GetTarget sets mTarget
00850     nsCOMPtr<nsIDOMEventTarget> dummy;
00851     GetTarget(getter_AddRefs(dummy));
00852   }
00853   newEvent->flags                  = mEvent->flags;
00854   newEvent->internalAppFlags       = mEvent->internalAppFlags;
00855   newEvent->time                   = mEvent->time;
00856   newEvent->point                  = mEvent->point;
00857   newEvent->refPoint               = mEvent->refPoint;
00858 
00859   mEvent = newEvent;
00860   mPresContext = nsnull;
00861   mEventIsInternal = PR_TRUE;
00862 
00863   return NS_OK;
00864 }
00865 
00866 NS_METHOD nsDOMEvent::SetTarget(nsIDOMEventTarget* aTarget)
00867 {
00868 #ifdef DEBUG
00869   {
00870     nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aTarget);
00871 
00872     NS_ASSERTION(!win || !win->IsInnerWindow(),
00873                  "Uh, inner window set as event target!");
00874   }
00875 #endif
00876 
00877   mTarget = aTarget;
00878   return NS_OK;
00879 }
00880 
00881 NS_METHOD nsDOMEvent::SetCurrentTarget(nsIDOMEventTarget* aCurrentTarget)
00882 {
00883 #ifdef DEBUG
00884   {
00885     nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aCurrentTarget);
00886 
00887     NS_ASSERTION(!win || !win->IsInnerWindow(),
00888                  "Uh, inner window set as event target!");
00889   }
00890 #endif
00891 
00892   mCurrentTarget = aCurrentTarget;
00893   return NS_OK;
00894 }
00895 
00896 NS_METHOD nsDOMEvent::SetOriginalTarget(nsIDOMEventTarget* aOriginalTarget)
00897 {
00898 #ifdef DEBUG
00899   {
00900     nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aOriginalTarget);
00901 
00902     NS_ASSERTION(!win || !win->IsInnerWindow(),
00903                  "Uh, inner window set as event target!");
00904   }
00905 #endif
00906 
00907   mOriginalTarget = aOriginalTarget;
00908   return NS_OK;
00909 }
00910 
00911 NS_IMETHODIMP
00912 nsDOMEvent::IsDispatchStopped(PRBool* aIsDispatchStopped)
00913 {
00914   if (mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH) {
00915     *aIsDispatchStopped = PR_TRUE;
00916   } else {
00917     *aIsDispatchStopped = PR_FALSE;
00918   }
00919   return NS_OK;
00920 }
00921 
00922 NS_IMETHODIMP
00923 nsDOMEvent::IsHandled(PRBool* aIsHandled)
00924 {
00925   if (mEvent->internalAppFlags | NS_APP_EVENT_FLAG_HANDLED) {
00926     *aIsHandled = PR_TRUE;
00927   } else {
00928     *aIsHandled = PR_FALSE;
00929   }
00930   return NS_OK;
00931 }
00932 
00933 NS_IMETHODIMP
00934 nsDOMEvent::SetHandled(PRBool aHandled)
00935 {
00936   if(aHandled)
00937     mEvent->internalAppFlags |= NS_APP_EVENT_FLAG_HANDLED;
00938   else
00939     mEvent->internalAppFlags &= ~NS_APP_EVENT_FLAG_HANDLED;
00940 
00941   return NS_OK;
00942 }
00943 
00944 NS_IMETHODIMP
00945 nsDOMEvent::GetInternalNSEvent(nsEvent** aNSEvent)
00946 {
00947   NS_ENSURE_ARG_POINTER(aNSEvent);
00948   *aNSEvent = mEvent;
00949   return NS_OK;
00950 }
00951 
00952 // return true if eventName is contained within events, delimited by
00953 // spaces
00954 static PRBool
00955 PopupAllowedForEvent(const char *eventName)
00956 {
00957   if (!sPopupAllowedEvents) {
00958     nsDOMEvent::PopupAllowedEventsChanged();
00959 
00960     if (!sPopupAllowedEvents) {
00961       return PR_FALSE;
00962     }
00963   }
00964 
00965   nsDependentCString events(sPopupAllowedEvents);
00966 
00967   nsAFlatCString::const_iterator start, end;
00968   nsAFlatCString::const_iterator startiter(events.BeginReading(start));
00969   events.EndReading(end);
00970 
00971   while (startiter != end) {
00972     nsAFlatCString::const_iterator enditer(end);
00973 
00974     if (!FindInReadable(nsDependentCString(eventName), startiter, enditer))
00975       return PR_FALSE;
00976 
00977     // the match is surrounded by spaces, or at a string boundary
00978     if ((startiter == start || *--startiter == ' ') &&
00979         (enditer == end || *enditer == ' ')) {
00980       return PR_TRUE;
00981     }
00982 
00983     // Move on and see if there are other matches. (The delimitation
00984     // requirement makes it pointless to begin the next search before
00985     // the end of the invalid match just found.)
00986     startiter = enditer;
00987   }
00988 
00989   return PR_FALSE;
00990 }
00991 
00992 // static
00993 PopupControlState
00994 nsDOMEvent::GetEventPopupControlState(nsEvent *aEvent)
00995 {
00996   // generally if an event handler is running, new windows are disallowed.
00997   // check for exceptions:
00998   PopupControlState abuse = openAbused;
00999 
01000   switch(aEvent->eventStructType) {
01001   case NS_EVENT :
01002     // For these following events only allow popups if they're
01003     // triggered while handling user input. See
01004     // nsPresShell::HandleEventInternal() for details.
01005     if (nsEventStateManager::IsHandlingUserInput()) {
01006       switch(aEvent->message) {
01007       case NS_FORM_SELECTED :
01008         if (::PopupAllowedForEvent("select"))
01009           abuse = openControlled;
01010         break;
01011       case NS_FORM_CHANGE :
01012         if (::PopupAllowedForEvent("change"))
01013           abuse = openControlled;
01014         break;
01015       }
01016     }
01017     break;
01018   case NS_GUI_EVENT :
01019     // For this following event only allow popups if it's triggered
01020     // while handling user input. See
01021     // nsPresShell::HandleEventInternal() for details.
01022     if (nsEventStateManager::IsHandlingUserInput()) {
01023       switch(aEvent->message) {
01024       case NS_FORM_INPUT :
01025         if (::PopupAllowedForEvent("input"))
01026           abuse = openControlled;
01027         break;
01028       }
01029     }
01030     break;
01031   case NS_INPUT_EVENT :
01032     // For this following event only allow popups if it's triggered
01033     // while handling user input. See
01034     // nsPresShell::HandleEventInternal() for details.
01035     if (nsEventStateManager::IsHandlingUserInput()) {
01036       switch(aEvent->message) {
01037       case NS_FORM_CHANGE :
01038         if (::PopupAllowedForEvent("change"))
01039           abuse = openControlled;
01040         break;
01041       }
01042     }
01043     break;
01044   case NS_KEY_EVENT :
01045     if (NS_IS_TRUSTED_EVENT(aEvent)) {
01046       PRUint32 key = NS_STATIC_CAST(nsKeyEvent *, aEvent)->keyCode;
01047       switch(aEvent->message) {
01048       case NS_KEY_PRESS :
01049         // return key on focused button. see note at NS_MOUSE_LEFT_CLICK.
01050         if (key == nsIDOMKeyEvent::DOM_VK_RETURN)
01051           abuse = openAllowed;
01052         else if (::PopupAllowedForEvent("keypress"))
01053           abuse = openControlled;
01054         break;
01055       case NS_KEY_UP :
01056         // space key on focused button. see note at NS_MOUSE_LEFT_CLICK.
01057         if (key == nsIDOMKeyEvent::DOM_VK_SPACE)
01058           abuse = openAllowed;
01059         else if (::PopupAllowedForEvent("keyup"))
01060           abuse = openControlled;
01061         break;
01062       case NS_KEY_DOWN :
01063         if (::PopupAllowedForEvent("keydown"))
01064           abuse = openControlled;
01065         break;
01066       }
01067     }
01068     break;
01069   case NS_MOUSE_EVENT :
01070     if (NS_IS_TRUSTED_EVENT(aEvent)) {
01071       switch(aEvent->message) {
01072       case NS_MOUSE_LEFT_BUTTON_UP :
01073         if (::PopupAllowedForEvent("mouseup"))
01074           abuse = openControlled;
01075         break;
01076       case NS_MOUSE_LEFT_BUTTON_DOWN :
01077         if (::PopupAllowedForEvent("mousedown"))
01078           abuse = openControlled;
01079         break;
01080       case NS_MOUSE_LEFT_CLICK :
01081         /* Click events get special treatment because of their
01082            historical status as a more legitimate event handler. If
01083            click popups are enabled in the prefs, clear the popup
01084            status completely. */
01085         if (::PopupAllowedForEvent("click"))
01086           abuse = openAllowed;
01087         break;
01088       case NS_MOUSE_LEFT_DOUBLECLICK :
01089         if (::PopupAllowedForEvent("dblclick"))
01090           abuse = openControlled;
01091         break;
01092       }
01093     }
01094     break;
01095   case NS_SCRIPT_ERROR_EVENT :
01096     switch(aEvent->message) {
01097     case NS_SCRIPT_ERROR :
01098       // Any error event will allow popups, if enabled in the pref.
01099       if (::PopupAllowedForEvent("error"))
01100         abuse = openControlled;
01101       break;
01102     }
01103     break;
01104   case NS_FORM_EVENT :
01105     // For these following events only allow popups if they're
01106     // triggered while handling user input. See
01107     // nsPresShell::HandleEventInternal() for details.
01108     if (nsEventStateManager::IsHandlingUserInput()) {
01109       switch(aEvent->message) {
01110       case NS_FORM_SUBMIT :
01111         if (::PopupAllowedForEvent("submit"))
01112           abuse = openControlled;
01113         break;
01114       case NS_FORM_RESET :
01115         if (::PopupAllowedForEvent("reset"))
01116           abuse = openControlled;
01117         break;
01118       }
01119     }
01120     break;
01121   }
01122 
01123   return abuse;
01124 }
01125 
01126 // static
01127 void
01128 nsDOMEvent::PopupAllowedEventsChanged()
01129 {
01130   if (sPopupAllowedEvents) {
01131     nsMemory::Free(sPopupAllowedEvents);
01132   }
01133 
01134   nsAdoptingCString str =
01135     nsContentUtils::GetCharPref("dom.popup_allowed_events");
01136 
01137   // We'll want to do this even if str is empty to avoid looking up
01138   // this pref all the time if it's not set.
01139   sPopupAllowedEvents = ToNewCString(str);
01140 }
01141 
01142 // static
01143 void
01144 nsDOMEvent::Shutdown()
01145 {
01146   if (sPopupAllowedEvents) {
01147     nsMemory::Free(sPopupAllowedEvents);
01148   }
01149 }
01150 
01151 // static
01152 const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
01153 {
01154   switch(aEventType) {
01155   case NS_MOUSE_LEFT_BUTTON_DOWN:
01156   case NS_MOUSE_MIDDLE_BUTTON_DOWN:
01157   case NS_MOUSE_RIGHT_BUTTON_DOWN:
01158     return sEventNames[eDOMEvents_mousedown];
01159   case NS_MOUSE_LEFT_BUTTON_UP:
01160   case NS_MOUSE_MIDDLE_BUTTON_UP:
01161   case NS_MOUSE_RIGHT_BUTTON_UP:
01162     return sEventNames[eDOMEvents_mouseup];
01163   case NS_MOUSE_LEFT_CLICK:
01164   case NS_MOUSE_MIDDLE_CLICK:
01165   case NS_MOUSE_RIGHT_CLICK:
01166     return sEventNames[eDOMEvents_click];
01167   case NS_MOUSE_LEFT_DOUBLECLICK:
01168   case NS_MOUSE_MIDDLE_DOUBLECLICK:
01169   case NS_MOUSE_RIGHT_DOUBLECLICK:
01170     return sEventNames[eDOMEvents_dblclick];
01171   case NS_MOUSE_ENTER_SYNTH:
01172     return sEventNames[eDOMEvents_mouseover];
01173   case NS_MOUSE_EXIT_SYNTH:
01174     return sEventNames[eDOMEvents_mouseout];
01175   case NS_MOUSE_MOVE:
01176     return sEventNames[eDOMEvents_mousemove];
01177   case NS_KEY_UP:
01178     return sEventNames[eDOMEvents_keyup];
01179   case NS_KEY_DOWN:
01180     return sEventNames[eDOMEvents_keydown];
01181   case NS_KEY_PRESS:
01182     return sEventNames[eDOMEvents_keypress];
01183   case NS_COMPOSITION_START:
01184     return sEventNames[eDOMEvents_compositionstart];
01185   case NS_COMPOSITION_END:
01186     return sEventNames[eDOMEvents_compositionend];
01187   case NS_FOCUS_CONTENT:
01188     return sEventNames[eDOMEvents_focus];
01189   case NS_BLUR_CONTENT:
01190     return sEventNames[eDOMEvents_blur];
01191   case NS_XUL_CLOSE:
01192     return sEventNames[eDOMEvents_close];
01193   case NS_PAGE_LOAD:
01194   case NS_IMAGE_LOAD:
01195   case NS_SCRIPT_LOAD:
01196     return sEventNames[eDOMEvents_load];
01197   case NS_BEFORE_PAGE_UNLOAD:
01198     return sEventNames[eDOMEvents_beforeunload];
01199   case NS_PAGE_UNLOAD:
01200     return sEventNames[eDOMEvents_unload];
01201   case NS_IMAGE_ABORT:
01202     return sEventNames[eDOMEvents_abort];
01203   case NS_IMAGE_ERROR:
01204   case NS_SCRIPT_ERROR:
01205     return sEventNames[eDOMEvents_error];
01206   case NS_FORM_SUBMIT:
01207     return sEventNames[eDOMEvents_submit];
01208   case NS_FORM_RESET:
01209     return sEventNames[eDOMEvents_reset];
01210   case NS_FORM_CHANGE:
01211     return sEventNames[eDOMEvents_change];
01212   case NS_FORM_SELECTED:
01213     return sEventNames[eDOMEvents_select];
01214   case NS_FORM_INPUT:
01215     return sEventNames[eDOMEvents_input];
01216   case NS_PAINT:
01217     return sEventNames[eDOMEvents_paint];
01218   case NS_RESIZE_EVENT:
01219     return sEventNames[eDOMEvents_resize];
01220   case NS_SCROLL_EVENT:
01221     return sEventNames[eDOMEvents_scroll];
01222   case NS_TEXT_TEXT:
01223     return sEventNames[eDOMEvents_text];
01224   case NS_XUL_POPUP_SHOWING:
01225     return sEventNames[eDOMEvents_popupShowing];
01226   case NS_XUL_POPUP_SHOWN:
01227     return sEventNames[eDOMEvents_popupShown];
01228   case NS_XUL_POPUP_HIDING:
01229     return sEventNames[eDOMEvents_popupHiding];
01230   case NS_XUL_POPUP_HIDDEN:
01231     return sEventNames[eDOMEvents_popupHidden];
01232   case NS_XUL_COMMAND:
01233     return sEventNames[eDOMEvents_command];
01234   case NS_XUL_BROADCAST:
01235     return sEventNames[eDOMEvents_broadcast];
01236   case NS_XUL_COMMAND_UPDATE:
01237     return sEventNames[eDOMEvents_commandupdate];
01238   case NS_DRAGDROP_ENTER:
01239     return sEventNames[eDOMEvents_dragenter];
01240   case NS_DRAGDROP_OVER_SYNTH:
01241     return sEventNames[eDOMEvents_dragover];
01242   case NS_DRAGDROP_EXIT_SYNTH:
01243     return sEventNames[eDOMEvents_dragexit];
01244   case NS_DRAGDROP_DROP:
01245     return sEventNames[eDOMEvents_dragdrop];
01246   case NS_DRAGDROP_GESTURE:
01247     return sEventNames[eDOMEvents_draggesture];
01248   case NS_SCROLLPORT_OVERFLOW:
01249     return sEventNames[eDOMEvents_overflow];
01250   case NS_SCROLLPORT_UNDERFLOW:
01251     return sEventNames[eDOMEvents_underflow];
01252   case NS_SCROLLPORT_OVERFLOWCHANGED:
01253     return sEventNames[eDOMEvents_overflowchanged];
01254   case NS_MUTATION_SUBTREEMODIFIED:
01255     return sEventNames[eDOMEvents_subtreemodified];
01256   case NS_MUTATION_NODEINSERTED:
01257     return sEventNames[eDOMEvents_nodeinserted];
01258   case NS_MUTATION_NODEREMOVED:
01259     return sEventNames[eDOMEvents_noderemoved];
01260   case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
01261     return sEventNames[eDOMEvents_noderemovedfromdocument];
01262   case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
01263     return sEventNames[eDOMEvents_nodeinsertedintodocument];
01264   case NS_MUTATION_ATTRMODIFIED:
01265     return sEventNames[eDOMEvents_attrmodified];
01266   case NS_MUTATION_CHARACTERDATAMODIFIED:
01267     return sEventNames[eDOMEvents_characterdatamodified];
01268   case NS_CONTEXTMENU:
01269   case NS_CONTEXTMENU_KEY:
01270     return sEventNames[eDOMEvents_contextmenu];
01271   case NS_UI_ACTIVATE:
01272     return sEventNames[eDOMEvents_DOMActivate];
01273   case NS_UI_FOCUSIN:
01274     return sEventNames[eDOMEvents_DOMFocusIn];
01275   case NS_UI_FOCUSOUT:
01276     return sEventNames[eDOMEvents_DOMFocusOut];
01277   case NS_PAGE_SHOW:
01278     return sEventNames[eDOMEvents_pageshow];
01279   case NS_PAGE_HIDE:
01280     return sEventNames[eDOMEvents_pagehide];
01281 #ifdef MOZ_SVG
01282   case NS_SVG_LOAD:
01283     return sEventNames[eDOMEvents_SVGLoad];
01284   case NS_SVG_UNLOAD:
01285     return sEventNames[eDOMEvents_SVGUnload];
01286   case NS_SVG_ABORT:
01287     return sEventNames[eDOMEvents_SVGAbort];
01288   case NS_SVG_ERROR:
01289     return sEventNames[eDOMEvents_SVGError];
01290   case NS_SVG_RESIZE:
01291     return sEventNames[eDOMEvents_SVGResize];
01292   case NS_SVG_SCROLL:
01293     return sEventNames[eDOMEvents_SVGScroll];
01294   case NS_SVG_ZOOM:
01295     return sEventNames[eDOMEvents_SVGZoom];
01296 #endif // MOZ_SVG
01297   default:
01298     break;
01299   }
01300   // XXXldb We can hit this case in many ways, partly thanks to
01301   // nsDOMEvent::SetEventType being incomplete, and partly due to some
01302   // event types not having message constants at all (e.g., popup
01303   // blocked events).  Shouldn't we use the event's userType when we
01304   // can?
01305   return nsnull;
01306 }
01307 
01308 nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult,
01309                         nsPresContext* aPresContext,
01310                         nsEvent *aEvent) 
01311 {
01312   nsDOMEvent* it = new nsDOMEvent(aPresContext, aEvent);
01313   if (nsnull == it) {
01314     return NS_ERROR_OUT_OF_MEMORY;
01315   }
01316 
01317   return CallQueryInterface(it, aInstancePtrResult);
01318 }