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:
parent
3b2a4fb8e4
commit
1f82e44d11
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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
|
||||
//------------------------------------------------------
|
||||
|
||||
@ -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!");
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user