Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes
XULPopupListenerImpl Class Reference
Inheritance diagram for XULPopupListenerImpl:
Inheritance graph
[legend]
Collaboration diagram for XULPopupListenerImpl:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 XULPopupListenerImpl (void)
virtual ~XULPopupListenerImpl (void)
NS_DECL_ISUPPORTS NS_IMETHOD Init (nsIDOMElement *aElement, const XULPopupType &popupType)
NS_IMETHOD MouseDown (nsIDOMEvent *aMouseEvent)
 Processes a mouse down event.
NS_IMETHOD MouseUp (nsIDOMEvent *aMouseEvent)
 Processes a mouse up event.
NS_IMETHOD MouseClick (nsIDOMEvent *aMouseEvent)
 Processes a mouse click event.
NS_IMETHOD MouseDblClick (nsIDOMEvent *aMouseEvent)
 Processes a mouse click event.
NS_IMETHOD MouseOver (nsIDOMEvent *aMouseEvent)
 Processes a mouse enter event.
NS_IMETHOD MouseOut (nsIDOMEvent *aMouseEvent)
 Processes a mouse leave event.
NS_IMETHOD ContextMenu (nsIDOMEvent *aContextMenuEvent)
 Processes a context menu event.
NS_IMETHOD HandleEvent (nsIDOMEvent *anEvent)
void handleEvent (in nsIDOMEvent event)
 This method is called whenever an event occurs of the type for which the EventListener interface was registered.

Protected Member Functions

virtual nsresult LaunchPopup (nsIDOMEvent *anEvent)
virtual nsresult LaunchPopup (PRInt32 aClientX, PRInt32 aClientY)

Private Member Functions

nsresult PreLaunchPopup (nsIDOMEvent *aMouseEvent)
nsresult FireFocusOnTargetContent (nsIDOMNode *aTargetNode)

Private Attributes

nsIDOMElementmElement
nsCOMPtr< nsIPopupBoxObjectmPopup
XULPopupType popupType

Detailed Description

Definition at line 98 of file nsXULPopupListener.cpp.


Constructor & Destructor Documentation

Definition at line 150 of file nsXULPopupListener.cpp.

  : mElement(nsnull)
{
}

Definition at line 155 of file nsXULPopupListener.cpp.

{
  if (mPopup) {
    mPopup->HidePopup();
  }
  
#ifdef DEBUG_REFS
    --gInstanceCount;
    fprintf(stdout, "%d - RDF: XULPopupListenerImpl\n", gInstanceCount);
#endif
}

Here is the call graph for this function:


Member Function Documentation

nsresult XULPopupListenerImpl::ContextMenu ( nsIDOMEvent aContextMenuEvent) [virtual]

Processes a context menu event.

Parameters:
aContextMenuEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMContextMenuListener.

Definition at line 200 of file nsXULPopupListener.cpp.

{
  if(popupType == eXULPopupType_context)
    return PreLaunchPopup(aMouseEvent);
  else 
    return NS_OK;
}

Here is the call graph for this function:

Definition at line 324 of file nsXULPopupListener.cpp.

{
  nsresult rv;
  nsCOMPtr<nsIDOMDocument> domDoc;
  rv = aTargetNode->GetOwnerDocument(getter_AddRefs(domDoc));
  if(NS_SUCCEEDED(rv) && domDoc)
  {
    nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);

    // Get nsIDOMElement for targetNode
    nsIPresShell *shell = doc->GetShellAt(0);
    if (!shell)
      return NS_ERROR_FAILURE;

    // strong reference to keep this from going away between events
    nsCOMPtr<nsPresContext> context = shell->GetPresContext();
 
    nsCOMPtr<nsIContent> content = do_QueryInterface(aTargetNode);
    nsIFrame* targetFrame;
    shell->GetPrimaryFrameFor(content, &targetFrame);
    if (!targetFrame) return NS_ERROR_FAILURE;
      
    PRBool suppressBlur = PR_FALSE;
    const nsStyleUserInterface* ui = targetFrame->GetStyleUserInterface();
    suppressBlur = (ui->mUserFocus == NS_STYLE_USER_FOCUS_IGNORE);

    nsCOMPtr<nsIDOMElement> element;
    nsCOMPtr<nsIContent> newFocus = do_QueryInterface(content);

    nsIFrame* currFrame = targetFrame;
    // Look for the nearest enclosing focusable frame.
    while (currFrame) {
        if (currFrame->IsFocusable()) {
          newFocus = currFrame->GetContent();
          nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(newFocus));
          if (domElement) {
            element = domElement;
            break;
          }
        }
        currFrame = currFrame->GetParent();
    } 
    nsCOMPtr<nsIContent> focusableContent = do_QueryInterface(element);
    nsIEventStateManager *esm = context->EventStateManager();

    if (focusableContent) {
      // Lock to scroll by SetFocus. See bug 309075.
      nsCOMPtr<nsIFocusController> focusController = nsnull;
      PRBool isAlreadySuppressed = PR_FALSE;
      nsCOMPtr<nsPIDOMWindow> ourWindow =
        do_QueryInterface(doc->GetScriptGlobalObject());
      if (ourWindow) {
        focusController = ourWindow->GetRootFocusController();
        if (focusController) {
          focusController->GetSuppressFocusScroll(&isAlreadySuppressed);
          if (!isAlreadySuppressed)
            focusController->SetSuppressFocusScroll(PR_TRUE);
        }
      }

      focusableContent->SetFocus(context);

      // Unlock scroll if it's needed.
      if (focusController && !isAlreadySuppressed)
        focusController->SetSuppressFocusScroll(PR_FALSE);
    } else if (!suppressBlur)
      esm->SetContentState(nsnull, NS_EVENT_STATE_FOCUS);

    esm->SetContentState(focusableContent, NS_EVENT_STATE_ACTIVE);
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

This method is called whenever an event occurs of the type for which the EventListener interface was registered.

Parameters:
evtThe Event contains contextual information about the event. It also contains the stopPropagation and preventDefault methods which are used in determining the event's flow and default action.

Definition at line 125 of file nsXULPopupListener.cpp.

{ return NS_OK; };

Implements nsIXULPopupListener.

Definition at line 180 of file nsXULPopupListener.cpp.

{
  mElement = aElement; // Weak reference. Don't addref it.
  popupType = popup;
  return NS_OK;
}
nsresult XULPopupListenerImpl::LaunchPopup ( nsIDOMEvent anEvent) [protected, virtual]

Definition at line 401 of file nsXULPopupListener.cpp.

{
  // Retrieve our x and y position.
  nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(anEvent) );
  if (!mouseEvent) {
    //non-ui event passed in.  bad things.
    return NS_OK;
  }

  PRInt32 xPos, yPos;
  mouseEvent->GetClientX(&xPos); 
  mouseEvent->GetClientY(&yPos); 

  return LaunchPopup(xPos, yPos);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult XULPopupListenerImpl::LaunchPopup ( PRInt32  aClientX,
PRInt32  aClientY 
) [protected, virtual]

Definition at line 494 of file nsXULPopupListener.cpp.

{
  nsresult rv = NS_OK;

  nsAutoString type(NS_LITERAL_STRING("popup"));
  if ( popupType == eXULPopupType_context ) {
    type.AssignLiteral("context");
    
    // position the menu two pixels down and to the right from the current
    // mouse position. This makes it easier to dismiss the menu by just
    // clicking.
    aClientX += 2;
    aClientY += 2;
  }

  nsAutoString identifier;
  mElement->GetAttribute(type, identifier);

  if (identifier.IsEmpty()) {
    if (type.EqualsLiteral("popup"))
      mElement->GetAttribute(NS_LITERAL_STRING("menu"), identifier);
    else if (type.EqualsLiteral("context"))
      mElement->GetAttribute(NS_LITERAL_STRING("contextmenu"), identifier);
    if (identifier.IsEmpty())
      return rv;
  }

  // Try to find the popup content and the document.
  nsCOMPtr<nsIContent> content = do_QueryInterface(mElement);
  nsCOMPtr<nsIDocument> document = content->GetDocument();

  // Turn the document into a DOM document so we can use getElementById
  nsCOMPtr<nsIDOMDocument> domDocument = do_QueryInterface(document);
  if (!domDocument) {
    NS_ERROR("Popup attached to an element that isn't in XUL!");
    return NS_ERROR_FAILURE;
  }

  // Handle the _child case for popups and context menus
  nsCOMPtr<nsIDOMElement> popupContent;

  if (identifier.EqualsLiteral("_child")) {
    nsCOMPtr<nsIContent> popup;

    GetImmediateChild(content, nsXULAtoms::menupopup, getter_AddRefs(popup));
    if (popup)
      popupContent = do_QueryInterface(popup);
    else {
      nsCOMPtr<nsIDOMDocumentXBL> nsDoc(do_QueryInterface(domDocument));
      nsCOMPtr<nsIDOMNodeList> list;
      nsDoc->GetAnonymousNodes(mElement, getter_AddRefs(list));
      if (list) {
        PRUint32 ctr,listLength;
        nsCOMPtr<nsIDOMNode> node;
        list->GetLength(&listLength);
        for (ctr = 0; ctr < listLength; ctr++) {
          list->Item(ctr, getter_AddRefs(node));
          nsCOMPtr<nsIContent> childContent(do_QueryInterface(node));

          nsINodeInfo *ni = childContent->GetNodeInfo();

          if (ni && ni->Equals(nsXULAtoms::menupopup, kNameSpaceID_XUL)) {
            popupContent = do_QueryInterface(childContent);
            break;
          }
        }
      }
    }
  }
  else if (NS_FAILED(rv = domDocument->GetElementById(identifier,
                                              getter_AddRefs(popupContent)))) {
    // Use getElementById to obtain the popup content and gracefully fail if 
    // we didn't find any popup content in the document. 
    NS_ERROR("GetElementById had some kind of spasm.");
    return rv;
  }

  if (!popupContent || mElement == popupContent)
    return NS_OK;

  // We have some popup content. Obtain our window.
  nsCOMPtr<nsIDOMWindowInternal> domWindow =
    do_QueryInterface(document->GetScriptGlobalObject());

  if (domWindow) {
    // Find out if we're anchored.
    nsAutoString anchorAlignment;
    popupContent->GetAttribute(NS_LITERAL_STRING("popupanchor"), anchorAlignment);

    nsAutoString popupAlignment;
    popupContent->GetAttribute(NS_LITERAL_STRING("popupalign"), popupAlignment);

    PRInt32 xPos = aClientX, yPos = aClientY;

    ConvertPosition(popupContent, anchorAlignment, popupAlignment, yPos);
    if (!anchorAlignment.IsEmpty() && !popupAlignment.IsEmpty())
      xPos = yPos = -1;

    nsCOMPtr<nsIBoxObject> popupBox;
    nsCOMPtr<nsIDOMXULElement> xulPopupElt(do_QueryInterface(popupContent));
    xulPopupElt->GetBoxObject(getter_AddRefs(popupBox));
    nsCOMPtr<nsIPopupBoxObject> popupBoxObject(do_QueryInterface(popupBox));
    if (popupBoxObject) {
      mPopup = popupBoxObject;
      popupBoxObject->ShowPopup(mElement, popupContent, xPos, yPos, 
                                type.get(), anchorAlignment.get(), 
                                popupAlignment.get());
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHOD XULPopupListenerImpl::MouseClick ( nsIDOMEvent aMouseEvent) [inline, virtual]

Processes a mouse click event.

Parameters:
aMouseEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMMouseListener.

Definition at line 116 of file nsXULPopupListener.cpp.

{ return NS_OK; };
NS_IMETHOD XULPopupListenerImpl::MouseDblClick ( nsIDOMEvent aMouseEvent) [inline, virtual]

Processes a mouse click event.

Parameters:
aMouseEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMMouseListener.

Definition at line 117 of file nsXULPopupListener.cpp.

{ return NS_OK; };

Processes a mouse down event.

Parameters:
aMouseEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMMouseListener.

Definition at line 191 of file nsXULPopupListener.cpp.

{
  if(popupType != eXULPopupType_context)
    return PreLaunchPopup(aMouseEvent);
  else
    return NS_OK;
}

Here is the call graph for this function:

NS_IMETHOD XULPopupListenerImpl::MouseOut ( nsIDOMEvent aMouseEvent) [inline, virtual]

Processes a mouse leave event.

Parameters:
aMouseEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMMouseListener.

Definition at line 119 of file nsXULPopupListener.cpp.

{ return NS_OK; };
NS_IMETHOD XULPopupListenerImpl::MouseOver ( nsIDOMEvent aMouseEvent) [inline, virtual]

Processes a mouse enter event.

Parameters:
aMouseEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMMouseListener.

Definition at line 118 of file nsXULPopupListener.cpp.

{ return NS_OK; };
NS_IMETHOD XULPopupListenerImpl::MouseUp ( nsIDOMEvent aMouseEvent) [inline, virtual]

Processes a mouse up event.

Parameters:
aMouseEvent
See also:
nsIDOMEvent.h
Returns:
whether the event was consumed or ignored.
See also:
nsresult

Implements nsIDOMMouseListener.

Definition at line 115 of file nsXULPopupListener.cpp.

{ return NS_OK; };

Definition at line 209 of file nsXULPopupListener.cpp.

{
  PRUint16 button;

  nsCOMPtr<nsIDOMMouseEvent> mouseEvent;
  mouseEvent = do_QueryInterface(aMouseEvent);
  if (!mouseEvent) {
    //non-ui event passed in.  bad things.
    return NS_OK;
  }

  // check if someone has attempted to prevent this action.
  nsCOMPtr<nsIDOMNSUIEvent> nsUIEvent;
  nsUIEvent = do_QueryInterface(mouseEvent);
  if (!nsUIEvent) {
    return NS_OK;
  }

  // Get the node that was clicked on.
  nsCOMPtr<nsIDOMEventTarget> target;
  mouseEvent->GetTarget(getter_AddRefs(target));
  nsCOMPtr<nsIDOMNode> targetNode = do_QueryInterface(target);

  PRBool preventDefault;
  nsUIEvent->GetPreventDefault(&preventDefault);
  if (preventDefault && targetNode && popupType == eXULPopupType_context) {
    // Someone called preventDefault on a context menu.
    // Let's make sure they are allowed to do so.
    PRBool eventEnabled =
      nsContentUtils::GetBoolPref("dom.event.contextmenu.enabled", PR_TRUE);
    if (!eventEnabled) {
      // The user wants his contextmenus.  Let's make sure that this is a website
      // and not chrome since there could be places in chrome which don't want
      // contextmenus.
      nsCOMPtr<nsIDocument> doc;
      nsCOMPtr<nsIPrincipal> prin;
      nsContentUtils::GetDocumentAndPrincipal(targetNode,
                                              getter_AddRefs(doc),
                                              getter_AddRefs(prin));
      if (prin) {
        nsCOMPtr<nsIPrincipal> system;
        nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(system));
        if (prin != system) {
          // This isn't chrome.  Cancel the preventDefault() and
          // let the event go forth.
          preventDefault = PR_FALSE;
        }
      }
    }
  }

  if (preventDefault) {
    // someone called preventDefault. bail.
    return NS_OK;
  }

  // This is a gross hack to deal with a recursive popup situation happening in AIM code. 
  // See http://bugzilla.mozilla.org/show_bug.cgi?id=96920.
  // If a menu item child was clicked on that leads to a popup needing
  // to show, we know (guaranteed) that we're dealing with a menu or
  // submenu of an already-showing popup.  We don't need to do anything at all.
  if (popupType == eXULPopupType_popup) {
    nsCOMPtr<nsIContent> targetContent = do_QueryInterface(target);

    if (targetContent) {
      nsIAtom *tag = targetContent->Tag();
      if (tag == nsXULAtoms::menu || tag == nsXULAtoms::menuitem)
        return NS_OK;
    }
  }

  // Get the document with the popup.
  nsCOMPtr<nsIContent> content = do_QueryInterface(mElement);

  // Turn the document into a XUL document so we can use SetPopupNode
  nsCOMPtr<nsIDOMXULDocument2> xulDocument = do_QueryInterface(content->GetDocument());
  if (!xulDocument) {
    NS_ERROR("Popup attached to an element that isn't in XUL!");
    return NS_ERROR_FAILURE;
  }

  // Store clicked-on node in xul document for context menus and menu popups.
  // CLEAR THE POPUP EVENT BEFORE THIS FUNCTION EXITS
  xulDocument->SetPopupNode( targetNode );
  xulDocument->SetTrustedPopupEvent( aMouseEvent );

  switch (popupType) {
    case eXULPopupType_popup:
      // Check for left mouse button down
      mouseEvent->GetButton(&button);
      if (button == 0) {
        // Time to launch a popup menu.
        LaunchPopup(aMouseEvent);
        aMouseEvent->StopPropagation();
        aMouseEvent->PreventDefault();
      }
      break;
    case eXULPopupType_context:

    // Time to launch a context menu
#ifndef NS_CONTEXT_MENU_IS_MOUSEUP
    // If the context menu launches on mousedown,
    // we have to fire focus on the content we clicked on
    FireFocusOnTargetContent(targetNode);
#endif
    LaunchPopup(aMouseEvent);
    aMouseEvent->StopPropagation();
    aMouseEvent->PreventDefault();
    break;
  }
  xulDocument->SetTrustedPopupEvent(nsnull);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 138 of file nsXULPopupListener.cpp.

Definition at line 141 of file nsXULPopupListener.cpp.

Definition at line 144 of file nsXULPopupListener.cpp.


The documentation for this class was generated from the following file: