Index: base/nsCSSFrameConstructor.cpp
===================================================================
RCS file: /mozilla/layout/base/nsCSSFrameConstructor.cpp,v
retrieving revision 1.1266
diff -pu -r1.1266 base/nsCSSFrameConstructor.cpp
--- base/nsCSSFrameConstructor.cpp
+++ base/nsCSSFrameConstructor.cpp
@@ -4468,11 +4468,16 @@ nsCSSFrameConstructor::PropagateScrollTo
   htmlDoc->GetBody(getter_AddRefs(body));
   nsCOMPtr<nsIContent> bodyElement = do_QueryInterface(body);
   
-  if (!bodyElement ||
-      !bodyElement->NodeInfo()->Equals(nsHTMLAtoms::body)) {
+  if (!bodyElement) {
+    return nsnull;
+  }
+
+#if 0
+  if (!bodyElement->NodeInfo()->Equals(nsHTMLAtoms::body)) {
     // The body is not a <body> tag, it's a <frameset>.
     return nsnull;
   }
+#endif
 
   nsRefPtr<nsStyleContext> bodyStyle;
   bodyStyle = styleSet->ResolveStyleFor(bodyElement, rootStyle);
@@ -4819,12 +4824,14 @@ nsCSSFrameConstructor::ConstructRootFram
   // Never create scrollbars for XUL documents
   PRBool isScrollable = !isXUL;
 
+#if 0
   // Never create scrollbars for frameset documents.
   if (isHTML) {
     nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
     if (htmlDoc && htmlDoc->GetIsFrameset())
       isScrollable = PR_FALSE;
   }
+#endif
 
   if (isPaginated) {
     isScrollable = presContext->HasPaginatedScrolling();
Index: generic/nsFrameSetFrame.cpp
===================================================================
RCS file: /mozilla/layout/generic/nsFrameSetFrame.cpp,v
retrieving revision 3.185
diff -pu -r3.185 generic/nsFrameSetFrame.cpp
--- generic/nsFrameSetFrame.cpp
+++ generic/nsFrameSetFrame.cpp
@@ -545,8 +545,16 @@ void nsHTMLFramesetFrame::CalculateRowCo
                                           nscoord               aSize, 
                                           PRInt32               aNumSpecs, 
                                           const nsFramesetSpec* aSpecs, 
-                                          nscoord*              aValues)
+                                          nscoord*              aValues,
+PRBool aSkipScaling)
 {
+printf("nsHTMLFramesetFrame::CalculateRowCol(nsPresContext* aPresContext: %p, nscoord aSize, PRInt32 aNumSpecs: %d, const nsFramesetSpec* aSpecs: %p, nscoord* aValues: %p, PRBool aSkipScaling: %d)\n",
+(void*)aPresContext,
+aNumSpecs,
+(const void*)aSpecs,
+(void*)aValues,
+aSkipScaling
+);
   PRInt32  fixedTotal = 0;
   PRInt32  numFixed = 0;
   PRInt32* fixed = new PRInt32[aNumSpecs];
@@ -568,22 +576,45 @@ void nsHTMLFramesetFrame::CalculateRowCo
         fixedTotal += aValues[i];
         fixed[numFixed] = i;
         numFixed++;
+				printf("i: %d, aV[i]:  %d, fT: %d f[nF]: %d, nF: %d\n",
+               i,
+               aValues[i],
+               fixedTotal,
+               fixed[numFixed],
+               numFixed);
         break;
       case eFramesetUnit_Percent:
         percent[numPercent] = i;
         numPercent++;
+printf(
+"p[nP]: %d nP: %d\n",
+percent[numPercent],
+numPercent);
         break;
       case eFramesetUnit_Relative:
         relative[numRelative] = i;
         numRelative++;
         relativeSums += aSpecs[i].mValue;
+printf(
+"r[nR]: %d nR: %d rS: %d\n",
+relative[numRelative],
+numRelative,
+relativeSums);
         break;
     }
   }
 
+/* XXX timeless 25.9.2006 */
   // scale the fixed sizes if they total too much (or too little and there aren't any percent or relative)
-  if ((fixedTotal > aSize) || ((fixedTotal < aSize) && (0 == numPercent) && (0 == numRelative))) { 
+  if (
+(fixedTotal > aSize) ||
+((fixedTotal < aSize) && (0 == numPercent) && (0 == numRelative))
+) { 
+if (!aSkipScaling)
     Scale(aSize, numFixed, fixed, aNumSpecs, aValues);
+printf(
+"Scale(aSize: %d, numFixed: %d, fixed: %%, aNumSpecs: %d, aValues, %%);\n",
+aSize, numFixed,        aNumSpecs         );
     delete [] fixed; delete [] percent; delete [] relative;
     return;
   }
@@ -598,8 +629,15 @@ void nsHTMLFramesetFrame::CalculateRowCo
   }
 
   // scale the percent sizes if they total too much (or too little and there aren't any relative)
-  if ((percentTotal > percentMax) || ((percentTotal < percentMax) && (0 == numRelative))) { 
+  if (
+(percentTotal > percentMax) ||
+((percentTotal < percentMax) && (0 == numRelative))
+) { 
+if (!aSkipScaling)
     Scale(percentMax, numPercent, percent, aNumSpecs, aValues);
+printf(
+"Scale(percentMax: %d, numPercent: %d, percent: %%, aNumSpecs:%d, aValues: %%);\n",
+percentMax, numPercent, aNumSpecs);
     delete [] fixed; delete [] percent; delete [] relative;
     return;
   }
@@ -615,7 +653,11 @@ void nsHTMLFramesetFrame::CalculateRowCo
 
   // scale the relative sizes if they take up too much or too little
   if (relativeTotal != relativeMax) { 
+if (!aSkipScaling)
     Scale(relativeMax, numRelative, relative, aNumSpecs, aValues);
+printf(
+"Scale(relativeMax: %d, numRelative: %d, relative: %%, aNumSpecs: %d, aValues: %%);\n",
+relativeMax, numRelative,         aNumSpecs         );
   }
   
   delete [] fixed; delete [] percent; delete [] relative;
@@ -710,7 +752,42 @@ nsHTMLFramesetFrame::GetDesiredSize(nsPr
 {
   nsHTMLFramesetFrame* framesetParent = GetFramesetParent(this);
   if (nsnull == framesetParent) {
-    nsRect area = aPresContext->GetVisibleArea();
+    nsRect area;
+
+/* XXX timeless 22.9.2006 */
+    area = aPresContext->GetVisibleArea();
+printf("[default] area.width: %d [default] area.height: %d\n",
+area.width, area.height);
+    nsAutoString forced;
+    PRInt32 number;
+		nsCOMPtr<nsIAtom> atom = do_GetAtom("_force_width");
+    nsresult rv = mContent->GetAttr(kNameSpaceID_None, atom, forced);
+    if (atom && NS_SUCCEEDED(rv)) {
+      PRInt32 errorCode = 0;
+      number = forced.ToInteger(&errorCode);
+      if (number)
+        area.width = number;
+      if (errorCode != 0)
+        rv = NS_ERROR_FAILURE;
+      atom = do_GetAtom("_force_height"); 
+      if (atom && NS_SUCCEEDED(rv)) {
+        rv = mContent->GetAttr(kNameSpaceID_None, atom, forced);
+        if (NS_SUCCEEDED(rv)) {
+          if (errorCode != 0)
+            rv = NS_ERROR_FAILURE;
+          if (NS_SUCCEEDED(rv)) {
+            number = forced.ToInteger(&errorCode);
+            if (number)
+              area.height = number;
+          }
+        }
+      }
+    }
+printf("area.width: %d area.height: %d\n",
+area.width, area.height);
+if (NS_FAILED(rv)) {
+    area = aPresContext->GetVisibleArea();
+}
 
     aDesiredSize.width = area.width;
     aDesiredSize.height= area.height;
@@ -976,7 +1053,7 @@ nsHTMLFramesetFrame::Reflow(nsPresContex
   nsIPresShell *shell = aPresContext->PresShell();
   nsStyleSet *styleSet = shell->StyleSet();
 
-  //printf("FramesetFrame2::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight); 
+  printf("FramesetFrame2::Reflow %p (%d,%d) \n", (void*)this, aReflowState.availableWidth, aReflowState.availableHeight); 
   // Always get the size so that the caller knows how big we are
   GetDesiredSize(aPresContext, aReflowState, aDesiredSize);
   
@@ -984,6 +1061,10 @@ nsHTMLFramesetFrame::Reflow(nsPresContex
     ? aDesiredSize.width : aReflowState.availableWidth;
   nscoord height = (aDesiredSize.height <= aReflowState.availableHeight)
     ? aDesiredSize.height : aReflowState.availableHeight;
+printf("[old]width: %d, aDesiredSize.width: %d, [old]height: %d, aDesiredSize.height: %d\n",
+width, aDesiredSize.width, height, aDesiredSize.height);
+  width = aDesiredSize.width;
+  height = aDesiredSize.height;
 
   PRBool firstTime = (GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
   if (firstTime) {
@@ -1011,8 +1092,15 @@ nsHTMLFramesetFrame::Reflow(nsPresContex
     const nsFramesetSpec* colSpecs = nsnull;
     ourContent->GetRowSpec(&mNumRows, &rowSpecs);
     ourContent->GetColSpec(&mNumCols, &colSpecs);
-    CalculateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes);
-    CalculateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes);
+PRBool skipScaling = PR_FALSE;
+nsCOMPtr<nsIAtom> atom = do_GetAtom("_force_width");
+skipScaling = atom && mContent->HasAttr(kNameSpaceID_None, atom);
+if (!skipScaling) {
+atom = do_GetAtom("_force_height");
+skipScaling = atom && mContent->HasAttr(kNameSpaceID_None, atom);
+}
+    CalculateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes, skipScaling);
+    CalculateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes, skipScaling);
   }
 
   PRBool*        verBordersVis     = nsnull; // vertical borders visibility
Index: generic/nsFrameSetFrame.h
===================================================================
RCS file: /mozilla/layout/generic/nsFrameSetFrame.h,v
retrieving revision 3.49
diff -pu -r3.49 generic/nsFrameSetFrame.h
--- generic/nsFrameSetFrame.h
+++ generic/nsFrameSetFrame.h
@@ -181,7 +181,8 @@ protected:
                        nscoord               aSize, 
                        PRInt32               aNumSpecs, 
                        const nsFramesetSpec* aSpecs, 
-                       nscoord*              aValues);
+                       nscoord*              aValues,
+PRBool skipScaling = PR_FALSE);
 
   void GenerateRowCol(nsPresContext*       aPresContext,
                       nscoord               aSize,
