diff --git a/docshell/base/nsWebShell.cpp b/docshell/base/nsWebShell.cpp index 6820552fbc34..5a7c313eab11 100644 --- a/docshell/base/nsWebShell.cpp +++ b/docshell/base/nsWebShell.cpp @@ -71,6 +71,7 @@ #include "nsIDOMHTMLDocument.h" #include "nsLayoutCID.h" #include "nsIDOMRange.h" +#include "nsIFrameReflow.h" #include "nsMultiMixedConv.h" // for #include "nsIRegistry.h" @@ -186,6 +187,7 @@ public: NS_IMETHOD Destroy(void); NS_IMETHOD GetBounds(PRInt32 &x, PRInt32 &y, PRInt32 &w, PRInt32 &h); NS_IMETHOD SetBounds(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h); + NS_IMETHOD SizeToContent(); NS_IMETHOD MoveTo(PRInt32 aX, PRInt32 aY); NS_IMETHOD Show(); NS_IMETHOD Hide(); @@ -1354,6 +1356,62 @@ nsWebShell::SetBounds(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h) return NS_OK; } +NS_IMETHODIMP +nsWebShell::SizeToContent() +{ + nsresult rv; + + // get the presentation shell + nsCOMPtr cv; + GetContentViewer(getter_AddRefs(cv)); + if (cv) { + nsCOMPtr dv = do_QueryInterface(cv); + if (dv) { + nsCOMPtr pcx; + dv->GetPresContext(*getter_AddRefs(pcx)); + if (pcx) { + nsCOMPtr pshell; + pcx->GetShell(getter_AddRefs(pshell)); + + // whew! so resize the presentation shell + if (pshell) { + nsRect shellArea; + PRInt32 width, height; + float pixelScale; + + rv = pshell->ResizeReflow(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + + // so how big is it? + pcx->GetVisibleArea(shellArea); + pcx->GetTwipsToPixels(&pixelScale); + width = PRInt32((float)shellArea.width*pixelScale); + height = PRInt32((float)shellArea.height*pixelScale); + + // if we're the outermost webshell for this window, size the window + if (mContainer) { + nsCOMPtr browser = do_QueryInterface(mContainer); + if (browser) { + nsCOMPtr browserWebShell; + PRInt32 oldX, oldY, oldWidth, oldHeight, + widthDelta, heightDelta; + nsRect windowBounds; + + GetBounds(oldX, oldY, oldWidth, oldHeight); + widthDelta = width - oldWidth; + heightDelta = height - oldHeight; + browser->GetWindowBounds(windowBounds); + browser->SizeWindowTo(windowBounds.width + widthDelta, + windowBounds.height + heightDelta); + } + } + } + } + } + } + + return rv; +} + NS_IMETHODIMP nsWebShell::MoveTo(PRInt32 aX, PRInt32 aY) { diff --git a/dom/public/base/nsIDOMWindow.h b/dom/public/base/nsIDOMWindow.h index acd02a6a2660..404102b0c46f 100644 --- a/dom/public/base/nsIDOMWindow.h +++ b/dom/public/base/nsIDOMWindow.h @@ -146,6 +146,8 @@ public: NS_IMETHOD ResizeBy(PRInt32 aWidthDif, PRInt32 aHeightDif)=0; + NS_IMETHOD SizeToContent()=0; + NS_IMETHOD ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll)=0; NS_IMETHOD ScrollBy(PRInt32 aXScrollDif, PRInt32 aYScrollDif)=0; @@ -225,6 +227,7 @@ public: NS_IMETHOD MoveBy(PRInt32 aXDif, PRInt32 aYDif); \ NS_IMETHOD ResizeTo(PRInt32 aWidth, PRInt32 aHeight); \ NS_IMETHOD ResizeBy(PRInt32 aWidthDif, PRInt32 aHeightDif); \ + NS_IMETHOD SizeToContent(); \ NS_IMETHOD ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll); \ NS_IMETHOD ScrollBy(PRInt32 aXScrollDif, PRInt32 aYScrollDif); \ NS_IMETHOD ClearTimeout(PRInt32 aTimerID); \ @@ -296,6 +299,7 @@ public: NS_IMETHOD MoveBy(PRInt32 aXDif, PRInt32 aYDif) { return _to MoveBy(aXDif, aYDif); } \ NS_IMETHOD ResizeTo(PRInt32 aWidth, PRInt32 aHeight) { return _to ResizeTo(aWidth, aHeight); } \ NS_IMETHOD ResizeBy(PRInt32 aWidthDif, PRInt32 aHeightDif) { return _to ResizeBy(aWidthDif, aHeightDif); } \ + NS_IMETHOD SizeToContent() { return _to SizeToContent(); } \ NS_IMETHOD ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll) { return _to ScrollTo(aXScroll, aYScroll); } \ NS_IMETHOD ScrollBy(PRInt32 aXScrollDif, PRInt32 aYScrollDif) { return _to ScrollBy(aXScrollDif, aYScrollDif); } \ NS_IMETHOD ClearTimeout(PRInt32 aTimerID) { return _to ClearTimeout(aTimerID); } \ diff --git a/dom/public/idl/base/Window.idl b/dom/public/idl/base/Window.idl index 420f65f9d421..c3332617432e 100644 --- a/dom/public/idl/base/Window.idl +++ b/dom/public/idl/base/Window.idl @@ -48,20 +48,21 @@ void moveTo(in long xPos, in long yPos); void moveBy(in long xDif, in long yDif); void resizeTo(in long width, in long height); - void resizeBy(in long widthDif, in long heightDif); + void resizeBy(in long widthDif, in long heightDif); + void sizeToContent(); void scrollTo(in long xScroll, in long yScroll); - void scrollBy(in long xScrollDif, in long yScrollDif); + void scrollBy(in long xScrollDif, in long yScrollDif); void clearTimeout(in long timerID); void clearInterval(in long timerID); long setTimeout(/* ... */); long setInterval(/* ... */); - Window createPopup(in Element element, in Element popupContent, - in long xPos, in long yPos, - in DOMString popupType, in DOMString anchorAlignment, - in DOMString popupAlignment); - + Window createPopup(in Element element, in Element popupContent, + in long xPos, in long yPos, + in DOMString popupType, in DOMString anchorAlignment, + in DOMString popupAlignment); + Window open(/* ... */); Window openDialog(/* ... */); }; diff --git a/dom/src/base/nsGlobalWindow.cpp b/dom/src/base/nsGlobalWindow.cpp index af3c3023a470..d43774b3e556 100644 --- a/dom/src/base/nsGlobalWindow.cpp +++ b/dom/src/base/nsGlobalWindow.cpp @@ -1476,6 +1476,14 @@ GlobalWindowImpl::ResizeBy(PRInt32 aWidthDif, PRInt32 aHeightDif) return NS_OK; } +NS_IMETHODIMP +GlobalWindowImpl::SizeToContent() +{ + if (mWebShell) + return mWebShell->SizeToContent(); + return NS_ERROR_NOT_INITIALIZED; +} + NS_IMETHODIMP GlobalWindowImpl::ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll) { diff --git a/dom/src/base/nsGlobalWindow.h b/dom/src/base/nsGlobalWindow.h index c9e786b6abc0..2f4d33eac50f 100644 --- a/dom/src/base/nsGlobalWindow.h +++ b/dom/src/base/nsGlobalWindow.h @@ -153,6 +153,7 @@ public: NS_IMETHOD MoveBy(PRInt32 aXDif, PRInt32 aYDif); NS_IMETHOD ResizeTo(PRInt32 aWidth, PRInt32 aHeight); NS_IMETHOD ResizeBy(PRInt32 aWidthDif, PRInt32 aHeightDif); + NS_IMETHOD SizeToContent(); NS_IMETHOD ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll); NS_IMETHOD ScrollBy(PRInt32 aXScrollDif, PRInt32 aYScrollDif); diff --git a/dom/src/base/nsJSWindow.cpp b/dom/src/base/nsJSWindow.cpp index c7eca11e0da3..530652fdb973 100644 --- a/dom/src/base/nsJSWindow.cpp +++ b/dom/src/base/nsJSWindow.cpp @@ -1708,6 +1708,48 @@ WindowResizeBy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rva } +// +// Native method SizeToContent +// +PR_STATIC_CALLBACK(JSBool) +WindowSizeToContent(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + nsIDOMWindow *nativeThis = (nsIDOMWindow*)nsJSUtils::nsGetNativeThis(cx, obj); + + *rval = JSVAL_NULL; + + nsIScriptContext *scriptCX = (nsIScriptContext *)JS_GetContextPrivate(cx); + nsCOMPtr secMan; + if (NS_OK != scriptCX->GetSecurityManager(getter_AddRefs(secMan))) { + return JS_FALSE; + } + { + PRBool ok; + secMan->CheckScriptAccess(scriptCX, obj, "window.sizetocontent",PR_FALSE , &ok); + if (!ok) { + //Need to throw error here + return JS_FALSE; + } + } + + // If there's no private data, this must be the prototype, so ignore + if (nsnull == nativeThis) { + return JS_TRUE; + } + + { + + if (NS_OK != nativeThis->SizeToContent()) { + return JS_FALSE; + } + + *rval = JSVAL_VOID; + } + + return JS_TRUE; +} + + // // Native method ScrollTo // @@ -2498,6 +2540,7 @@ static JSFunctionSpec WindowMethods[] = {"moveBy", WindowMoveBy, 2}, {"resizeTo", WindowResizeTo, 2}, {"resizeBy", WindowResizeBy, 2}, + {"sizeToContent", WindowSizeToContent, 0}, {"scrollTo", WindowScrollTo, 2}, {"scrollBy", WindowScrollBy, 2}, {"clearTimeout", WindowClearTimeout, 1}, diff --git a/layout/generic/nsViewportFrame.cpp b/layout/generic/nsViewportFrame.cpp index 9ac475fd2d5e..a80208b820e6 100644 --- a/layout/generic/nsViewportFrame.cpp +++ b/layout/generic/nsViewportFrame.cpp @@ -533,7 +533,8 @@ ViewportFrame::Reflow(nsIPresContext& aPresContext, // If we were flowed initially at both an unconstrained width and height, // this is a hint that we should return our child's intrinsic size. - if (eReflowReason_Initial == aReflowState.reason && + if ((eReflowReason_Initial == aReflowState.reason || + eReflowReason_Resize == aReflowState.reason) && aReflowState.availableWidth == NS_UNCONSTRAINEDSIZE && aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) { aDesiredSize.width = kidRect.width; diff --git a/layout/html/base/src/nsViewportFrame.cpp b/layout/html/base/src/nsViewportFrame.cpp index 9ac475fd2d5e..a80208b820e6 100644 --- a/layout/html/base/src/nsViewportFrame.cpp +++ b/layout/html/base/src/nsViewportFrame.cpp @@ -533,7 +533,8 @@ ViewportFrame::Reflow(nsIPresContext& aPresContext, // If we were flowed initially at both an unconstrained width and height, // this is a hint that we should return our child's intrinsic size. - if (eReflowReason_Initial == aReflowState.reason && + if ((eReflowReason_Initial == aReflowState.reason || + eReflowReason_Resize == aReflowState.reason) && aReflowState.availableWidth == NS_UNCONSTRAINEDSIZE && aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) { aDesiredSize.width = kidRect.width; diff --git a/webshell/public/nsIWebShell.h b/webshell/public/nsIWebShell.h index e59d81db9f49..44017be6ac5e 100644 --- a/webshell/public/nsIWebShell.h +++ b/webshell/public/nsIWebShell.h @@ -174,6 +174,11 @@ public: */ NS_IMETHOD SetBounds(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h) = 0; + /** + * Shrink-to-fit the WebShell to its contents + */ + NS_IMETHOD SizeToContent() = 0; + NS_IMETHOD MoveTo(PRInt32 aX, PRInt32 aY) = 0; /** diff --git a/webshell/src/nsWebShell.cpp b/webshell/src/nsWebShell.cpp index 6820552fbc34..5a7c313eab11 100644 --- a/webshell/src/nsWebShell.cpp +++ b/webshell/src/nsWebShell.cpp @@ -71,6 +71,7 @@ #include "nsIDOMHTMLDocument.h" #include "nsLayoutCID.h" #include "nsIDOMRange.h" +#include "nsIFrameReflow.h" #include "nsMultiMixedConv.h" // for #include "nsIRegistry.h" @@ -186,6 +187,7 @@ public: NS_IMETHOD Destroy(void); NS_IMETHOD GetBounds(PRInt32 &x, PRInt32 &y, PRInt32 &w, PRInt32 &h); NS_IMETHOD SetBounds(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h); + NS_IMETHOD SizeToContent(); NS_IMETHOD MoveTo(PRInt32 aX, PRInt32 aY); NS_IMETHOD Show(); NS_IMETHOD Hide(); @@ -1354,6 +1356,62 @@ nsWebShell::SetBounds(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h) return NS_OK; } +NS_IMETHODIMP +nsWebShell::SizeToContent() +{ + nsresult rv; + + // get the presentation shell + nsCOMPtr cv; + GetContentViewer(getter_AddRefs(cv)); + if (cv) { + nsCOMPtr dv = do_QueryInterface(cv); + if (dv) { + nsCOMPtr pcx; + dv->GetPresContext(*getter_AddRefs(pcx)); + if (pcx) { + nsCOMPtr pshell; + pcx->GetShell(getter_AddRefs(pshell)); + + // whew! so resize the presentation shell + if (pshell) { + nsRect shellArea; + PRInt32 width, height; + float pixelScale; + + rv = pshell->ResizeReflow(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + + // so how big is it? + pcx->GetVisibleArea(shellArea); + pcx->GetTwipsToPixels(&pixelScale); + width = PRInt32((float)shellArea.width*pixelScale); + height = PRInt32((float)shellArea.height*pixelScale); + + // if we're the outermost webshell for this window, size the window + if (mContainer) { + nsCOMPtr browser = do_QueryInterface(mContainer); + if (browser) { + nsCOMPtr browserWebShell; + PRInt32 oldX, oldY, oldWidth, oldHeight, + widthDelta, heightDelta; + nsRect windowBounds; + + GetBounds(oldX, oldY, oldWidth, oldHeight); + widthDelta = width - oldWidth; + heightDelta = height - oldHeight; + browser->GetWindowBounds(windowBounds); + browser->SizeWindowTo(windowBounds.width + widthDelta, + windowBounds.height + heightDelta); + } + } + } + } + } + } + + return rv; +} + NS_IMETHODIMP nsWebShell::MoveTo(PRInt32 aX, PRInt32 aY) { diff --git a/xpfe/browser/samples/dexparamdialog.xul b/xpfe/browser/samples/dexparamdialog.xul index fc47552f1281..4ab1437a2efb 100644 --- a/xpfe/browser/samples/dexparamdialog.xul +++ b/xpfe/browser/samples/dexparamdialog.xul @@ -213,6 +213,11 @@ Startup from Params + + + Size To Content + + Dump Window