/* void scrollToElement (in nsIDOMElement child); */ NS_IMETHODIMP nsScrollBoxObject::ScrollToElement(nsIDOMElement *child) { NS_ENSURE_ARG_POINTER(child); nsIScrollableView* scrollableView = GetScrollableView(); if (!scrollableView) return NS_ERROR_FAILURE; nsCOMPtr<nsIPresShell> shell = GetPresShell(PR_FALSE); if (!shell) { return NS_ERROR_UNEXPECTED; } nsIFrame* scrolledBox = GetScrolledBox(this); if (!scrolledBox) return NS_ERROR_FAILURE; nsRect rect, crect; nsCOMPtr<nsIDOMDocument> doc; child->GetOwnerDocument(getter_AddRefs(doc)); nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc)); if(!nsDoc) return NS_ERROR_UNEXPECTED; nsCOMPtr<nsIBoxObject> childBoxObject; nsDoc->GetBoxObjectFor(child, getter_AddRefs(childBoxObject)); if(!childBoxObject) return NS_ERROR_UNEXPECTED; PRInt32 x,y; childBoxObject->GetX(&x); childBoxObject->GetY(&y); // get the twips rectangle from the boxobject (which has pixels) rect.x = nsPresContext::CSSPixelsToAppUnits(x); rect.y = nsPresContext::CSSPixelsToAppUnits(y); // TODO: make sure the child is inside the box // get our current info nsPoint cp; scrollableView->GetScrollPosition(cp.x,cp.y); nsIntRect prect; GetOffsetRect(prect); crect = nsIntRect::ToAppUnits(prect, nsPresContext::AppUnitsPerCSSPixel()); nscoord newx=cp.x, newy=cp.y; // we only scroll in the direction of the scrollbox orientation // always scroll to left or top edge of child element if (scrolledBox->IsHorizontal()) { newx = rect.x - crect.x; } else { newy = rect.y - crect.y; } // scroll away return scrollableView->ScrollTo(newx, newy, 0); }
void nsXULTooltipListener::CheckTreeBodyMove(nsIDOMMouseEvent* aMouseEvent) { nsCOMPtr<nsIContent> sourceNode = do_QueryReferent(mSourceNode); if (!sourceNode) return; // get the boxObject of the documentElement of the document the tree is in nsCOMPtr<nsIBoxObject> bx; nsCOMPtr<nsIDOMDocument> doc(do_QueryInterface(sourceNode->GetDocument())); if (doc) { nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc)); nsCOMPtr<nsIDOMElement> docElement; doc->GetDocumentElement(getter_AddRefs(docElement)); if (nsDoc && docElement) { nsDoc->GetBoxObjectFor(docElement, getter_AddRefs(bx)); } } nsCOMPtr<nsITreeBoxObject> obx; GetSourceTreeBoxObject(getter_AddRefs(obx)); if (bx && obx) { PRInt32 x, y; aMouseEvent->GetScreenX(&x); aMouseEvent->GetScreenY(&y); PRInt32 row; nsCOMPtr<nsITreeColumn> col; nsCAutoString obj; // subtract off the documentElement's boxObject PRInt32 boxX, boxY; bx->GetScreenX(&boxX); bx->GetScreenY(&boxY); x -= boxX; y -= boxY; obx->GetCellAt(x, y, &row, getter_AddRefs(col), obj); // determine if we are going to need a titletip // XXX check the disabletitletips attribute on the tree content mNeedTitletip = PR_FALSE; if (row >= 0 && obj.EqualsLiteral("text")) { obx->IsCellCropped(row, col, &mNeedTitletip); } nsCOMPtr<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip); if (currentTooltip && (row != mLastTreeRow || col != mLastTreeCol)) { HideTooltip(); } mLastTreeRow = row; mLastTreeCol = col; } }
// // LaunchPopup // // Given the element on which the event was triggered and the mouse locations in // Client and widget coordinates, popup a new window showing the appropriate // content. // // aTargetContent is the target of the mouse event aEvent that triggered the // popup. mElement is the element that the popup menu is attached to. // aTargetContent may be equal to mElement or it may be a descendant. // // This looks for an attribute on |mElement| of the appropriate popup type // (popup, context) and uses that attribute's value as an ID for // the popup content in the document. // nsresult nsXULPopupListener::LaunchPopup(nsIDOMEvent* aEvent, nsIContent* aTargetContent) { nsresult rv = NS_OK; nsAutoString type(NS_LITERAL_STRING("popup")); if (mIsContext) type.AssignLiteral("context"); 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> popupElement; if (identifier.EqualsLiteral("_child")) { nsCOMPtr<nsIContent> popup; GetImmediateChild(content, nsGkAtoms::menupopup, getter_AddRefs(popup)); if (popup) popupElement = 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)); if (childContent->NodeInfo()->Equals(nsGkAtoms::menupopup, kNameSpaceID_XUL)) { popupElement = do_QueryInterface(childContent); break; } } } } } else if (NS_FAILED(rv = domDocument->GetElementById(identifier, getter_AddRefs(popupElement)))) { // 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; } // return if no popup was found or the popup is the element itself. if ( !popupElement || popupElement == mElement) return NS_OK; // Submenus can't be used as context menus or popups, bug 288763. // Similar code also in nsXULTooltipListener::GetTooltipFor. nsCOMPtr<nsIContent> popup = do_QueryInterface(popupElement); nsIContent* parent = popup->GetParent(); if (parent) { nsIFrame* frame = parent->GetPrimaryFrame(); if (frame && frame->GetType() == nsGkAtoms::menuFrame) return NS_OK; } nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (!pm) return NS_OK; // For left-clicks, if the popup has an position attribute, or both the // popupanchor and popupalign attributes are used, anchor the popup to the // element, otherwise just open it at the screen position where the mouse // was clicked. Context menus always open at the mouse position. mPopupContent = popup; if (!mIsContext && (mPopupContent->HasAttr(kNameSpaceID_None, nsGkAtoms::position) || (mPopupContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popupanchor) && mPopupContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popupalign)))) { pm->ShowPopup(mPopupContent, content, EmptyString(), 0, 0, PR_FALSE, PR_TRUE, PR_FALSE, aEvent); } else { PRInt32 xPos = 0, yPos = 0; nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent); mouseEvent->GetScreenX(&xPos); mouseEvent->GetScreenY(&yPos); pm->ShowPopupAtScreen(mPopupContent, xPos, yPos, mIsContext, aEvent); } return NS_OK; }
/* void ensureElementIsVisible (in nsIDOMElement child); */ NS_IMETHODIMP nsScrollBoxObject::EnsureElementIsVisible(nsIDOMElement *child) { NS_ENSURE_ARG_POINTER(child); // Start with getting info about the child, since that will flush // layout and possibly destroy scrollable views, presshells, etc. nsCOMPtr<nsIDOMDocument> doc; // XXXbz sXBL/XBL2 issue -- which document? child->GetOwnerDocument(getter_AddRefs(doc)); nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc)); if(!nsDoc) return NS_ERROR_UNEXPECTED; nsCOMPtr<nsIBoxObject> childBoxObject; nsDoc->GetBoxObjectFor(child, getter_AddRefs(childBoxObject)); if(!childBoxObject) return NS_ERROR_UNEXPECTED; PRInt32 x, y, width, height; childBoxObject->GetX(&x); childBoxObject->GetY(&y); childBoxObject->GetWidth(&width); childBoxObject->GetHeight(&height); nsIScrollableView* scrollableView = GetScrollableView(); if (!scrollableView) return NS_ERROR_FAILURE; nsIFrame* scrolledBox = GetScrolledBox(this); if (!scrolledBox) return NS_ERROR_FAILURE; nsRect rect, crect; // get the twips rectangle from the boxobject (which has pixels) rect.x = nsPresContext::CSSPixelsToAppUnits(x); rect.y = nsPresContext::CSSPixelsToAppUnits(y); rect.width = nsPresContext::CSSPixelsToAppUnits(width); rect.height = nsPresContext::CSSPixelsToAppUnits(height); // TODO: make sure the child is inside the box // get our current info nsPoint cp; scrollableView->GetScrollPosition(cp.x,cp.y); nsIntRect prect; GetOffsetRect(prect); crect = nsIntRect::ToAppUnits(prect, nsPresContext::AppUnitsPerCSSPixel()); nscoord newx=cp.x, newy=cp.y; // we only scroll in the direction of the scrollbox orientation if (scrolledBox->IsHorizontal()) { if ((rect.x - crect.x) + rect.width > cp.x + crect.width) { newx = cp.x + (((rect.x - crect.x) + rect.width)-(cp.x + crect.width)); } else if (rect.x - crect.x < cp.x) { newx = rect.x - crect.x; } } else { if ((rect.y - crect.y) + rect.height > cp.y + crect.height) { newy = cp.y + (((rect.y - crect.y) + rect.height)-(cp.y + crect.height)); } else if (rect.y - crect.y < cp.y) { newy = rect.y - crect.y; } } // scroll away return scrollableView->ScrollTo(newx, newy, 0); }