Bug 374570, constrain popups to frame, r+sr=roc

git-svn-id: svn://10.0.0.236/trunk@224799 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
enndeakin%sympatico.ca 2007-04-20 18:20:04 +00:00
parent 3b2a4fb8e4
commit 1f82e44d11
6 changed files with 85 additions and 50 deletions

View File

@ -3027,6 +3027,14 @@ nsGlobalWindow::SetScreenY(PRInt32 aScreenY)
nsresult
nsGlobalWindow::CheckSecurityWidthAndHeight(PRInt32* aWidth, PRInt32* aHeight)
{
if (!nsContentUtils::IsCallerTrustedForWrite()) {
// if attempting to resize the window, hide any open popups
nsCOMPtr<nsIPresShell> presShell;
mDocShell->GetPresShell(getter_AddRefs(presShell));
if (presShell)
presShell->HidePopups();
}
// This one is easy. Just ensure the variable is greater than 100;
if ((aWidth && *aWidth < 100) || (aHeight && *aHeight < 100)) {
// Check security state for use in determing window dimensions
@ -3053,6 +3061,12 @@ nsGlobalWindow::CheckSecurityLeftAndTop(PRInt32* aLeft, PRInt32* aTop)
// Check security state for use in determing window dimensions
if (!nsContentUtils::IsCallerTrustedForWrite()) {
// if attempting to move the window, hide any open popups
nsCOMPtr<nsIPresShell> presShell;
mDocShell->GetPresShell(getter_AddRefs(presShell));
if (presShell)
presShell->HidePopups();
PRInt32 screenLeft, screenTop, screenWidth, screenHeight;
PRInt32 winLeft, winTop, winWidth, winHeight;

View File

@ -365,8 +365,6 @@ private:
nsresult GetPopupLinkNode(nsIDOMNode** aNode);
nsresult GetPopupImageNode(nsIImageLoadingContent** aNode);
void HideViewIfPopup(nsIView* aView);
void DumpContentToPPM(const char* aFileName);
void PrepareToStartLoad(void);
@ -1261,40 +1259,10 @@ DocumentViewerImpl::PageHide(PRBool aIsUnload)
nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull, &status);
}
if (mPresShell) {
// look for open menupopups and close them after the unload event, in case
// the unload event listeners open any new popups
nsIViewManager *vm = mPresShell->GetViewManager();
if (vm) {
nsIView *rootView = nsnull;
vm->GetRootView(rootView);
if (rootView)
HideViewIfPopup(rootView);
}
}
return NS_OK;
}
void
DocumentViewerImpl::HideViewIfPopup(nsIView* aView)
{
nsIFrame* frame = NS_STATIC_CAST(nsIFrame*, aView->GetClientData());
if (frame) {
nsIMenuParent* parent;
CallQueryInterface(frame, &parent);
if (parent) {
parent->HideChain();
// really make sure the view is hidden
mViewManager->SetViewVisibility(aView, nsViewVisibility_kHide);
}
}
nsIView* child = aView->GetFirstChild();
while (child) {
HideViewIfPopup(child);
child = child->GetNextSibling();
}
// look for open menupopups and close them after the unload event, in case
// the unload event listeners open any new popups
if (mPresShell)
mPresShell->HidePopups();
}
static void

View File

@ -100,10 +100,10 @@ class gfxASurface;
typedef short SelectionType;
// A68CFCE1-2A15-47F0-B61B-F2C34079A909
// DC543B71-6F1A-4B9F-B4CF-693AEC4BA24A
#define NS_IPRESSHELL_IID \
{ 0xa78cfce1, 0x2a15, 0x47f0, \
{ 0xb6, 0x1b, 0xf2, 0xc3, 0x40, 0x79, 0xa9, 0x09 } }
{ 0xdc543b71, 0x6f1a, 0x4b9f, \
{ 0xb4, 0xcf, 0x69, 0x3a, 0xec, 0x4b, 0xa2, 0x4a } }
// Constants for ScrollContentIntoView() function
#define NS_PRESSHELL_SCROLL_TOP 0
@ -715,6 +715,8 @@ public:
nsPoint& aPoint,
nsRect* aScreenRect) = 0;
virtual void HidePopups() = 0;
void AddWeakFrame(nsWeakFrame* aWeakFrame);
void RemoveWeakFrame(nsWeakFrame* aWeakFrame);

View File

@ -194,6 +194,7 @@
#include "nsIMenuFrame.h"
#include "nsITreeBoxObject.h"
#endif
#include "nsIMenuParent.h"
#include "nsPlaceholderFrame.h"
// Content viewer interfaces
@ -933,6 +934,8 @@ public:
nsPoint& aPoint,
nsRect* aScreenRect);
virtual void HidePopups();
//nsIViewObserver interface
NS_IMETHOD Paint(nsIView *aView,
@ -1150,6 +1153,9 @@ protected:
void AddAgentSheet(nsISupports* aSheet);
void RemoveSheet(nsStyleSet::sheetType aType, nsISupports* aSheet);
// Hide a view if it is a popup
void HideViewIfPopup(nsIView* aView);
nsICSSStyleSheet* mPrefStyleSheet; // mStyleSet owns it but we maintain a ref, may be null
#ifdef DEBUG
PRUint32 mUpdateCount;
@ -6121,6 +6127,18 @@ PresShell::Thaw()
UnsuppressPainting();
}
void
PresShell::HidePopups()
{
nsIViewManager *vm = GetViewManager();
if (vm) {
nsIView *rootView = nsnull;
vm->GetRootView(rootView);
if (rootView)
HideViewIfPopup(rootView);
}
}
//--------------------------------------------------------
// Start of protected and private methods on the PresShell
//--------------------------------------------------------
@ -6589,6 +6607,27 @@ PresShell::EnumeratePlugins(nsIDOMDocument *aDocument,
}
}
void
PresShell::HideViewIfPopup(nsIView* aView)
{
nsIFrame* frame = NS_STATIC_CAST(nsIFrame*, aView->GetClientData());
if (frame) {
nsIMenuParent* parent;
CallQueryInterface(frame, &parent);
if (parent) {
parent->HideChain();
// really make sure the view is hidden
mViewManager->SetViewVisibility(aView, nsViewVisibility_kHide);
}
}
nsIView* child = aView->GetFirstChild();
while (child) {
HideViewIfPopup(child);
child = child->GetNextSibling();
}
}
//------------------------------------------------------
// End of protected and private methods on the PresShell
//------------------------------------------------------

View File

@ -142,7 +142,8 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContex
mMenuCanOverlapOSBar(PR_FALSE),
mShouldAutoPosition(PR_TRUE),
mShouldRollup(PR_TRUE),
mConsumeRollupEvent(nsIPopupBoxObject::ROLLUP_DEFAULT)
mConsumeRollupEvent(nsIPopupBoxObject::ROLLUP_DEFAULT),
mInContentShell(PR_TRUE)
{
SetIsContextMenu(PR_FALSE); // we're not a context menu by default
} // ctor
@ -191,6 +192,13 @@ nsMenuPopupFrame::Init(nsIContent* aContent,
// about that constraint.
viewManager->SetViewFloating(ourView, PR_TRUE);
nsCOMPtr<nsISupports> cont = PresContext()->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont);
PRInt32 type = -1;
if (dsti && NS_SUCCEEDED(dsti->GetItemType(&type)) &&
type == nsIDocShellTreeItem::typeChrome)
mInContentShell = PR_FALSE;
// XXX make sure we are hidden (shouldn't this be done automatically?)
viewManager->SetViewVisibility(ourView, nsViewVisibility_kHide);
if (!ourView->HasWidget()) {
@ -217,15 +225,7 @@ nsMenuPopupFrame::CreateWidgetForView(nsIView* aView)
nsCSSRendering::FindBackground(PresContext(), this, &bg, &isCanvas);
PRBool viewHasTransparentContent = hasBG &&
(bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) &&
!GetStyleDisplay()->mAppearance;
if (viewHasTransparentContent) {
nsCOMPtr<nsISupports> cont = PresContext()->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont);
PRInt32 type = -1;
if (!dsti || NS_FAILED(dsti->GetItemType(&type)) ||
type != nsIDocShellTreeItem::typeChrome)
viewHasTransparentContent = PR_FALSE;
}
!GetStyleDisplay()->mAppearance && !mInContentShell;
nsIContent* parentContent = GetContent()->GetParent();
nsIAtom *tag = nsnull;
@ -657,7 +657,7 @@ nsMenuPopupFrame::SyncViewWithFrame(nsPresContext* aPresContext,
NS_ENSURE_ARG(aPresContext);
NS_ENSURE_ARG(aFrame);
if (!mShouldAutoPosition)
if (!mShouldAutoPosition && !mInContentShell)
return NS_OK;
// |containingView|
@ -756,6 +756,13 @@ nsMenuPopupFrame::SyncViewWithFrame(nsPresContext* aPresContext,
rect.width -= nsPresContext::CSSPixelsToAppUnits(3);
rect.height -= nsPresContext::CSSPixelsToAppUnits(3);
// for content shells, clip to the client area rather than the screen area
if (mInContentShell) {
nsRect rootScreenRect = presShell->GetRootFrame()->GetScreenRect();
rootScreenRect.ScaleRoundIn(aPresContext->AppUnitsPerDevPixel());
rect.IntersectRect(rect, rootScreenRect);
}
PRInt32 screenLeftTwips = rect.x;
PRInt32 screenTopTwips = rect.y;
PRInt32 screenWidthTwips = rect.width;
@ -2028,6 +2035,10 @@ nsMenuPopupFrame::MoveTo(PRInt32 aLeft, PRInt32 aTop)
void
nsMenuPopupFrame::MoveToInternal(PRInt32 aLeft, PRInt32 aTop)
{
// just don't support moving popups for content shells
if (mInContentShell)
return;
nsIView* view = GetView();
NS_ASSERTION(view->GetParent(), "Must have parent!");

View File

@ -257,6 +257,7 @@ protected:
PRPackedBool mShouldAutoPosition; // Should SyncViewWithFrame be allowed to auto position popup?
PRPackedBool mShouldRollup; // Should this menupopup be allowed to dismiss automatically?
PRPackedBool mConsumeRollupEvent; // Should the rollup event be consumed?
PRPackedBool mInContentShell; // True if the popup is in a content shell
nsString mIncrementalString; // for incremental typing navigation