Back to index

lightning-sunbird  0.9+nobinonly
nsComputedDOMStyle.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Daniel Glazman <glazman@netscape.com>
00024  *   Boris Zbarsky <bzbarsky@mit.edu>
00025  *   Christopher A. Aillon <christopher@aillon.com>
00026  *   Mats Palmgren <mats.palmgren@bredband.net>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either of the GNU General Public License Version 2 or later (the "GPL"),
00030  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #include "nsComputedDOMStyle.h"
00043 
00044 #include "nsDOMError.h"
00045 #include "nsDOMString.h"
00046 #include "nsIDOMCSS2Properties.h"
00047 #include "nsIDOMElement.h"
00048 #include "nsStyleContext.h"
00049 #include "nsIScrollableFrame.h"
00050 #include "nsContentUtils.h"
00051 #include "prprf.h"
00052 
00053 #include "nsCSSProps.h"
00054 #include "nsCSSKeywords.h"
00055 #include "nsDOMCSSRect.h"
00056 #include "nsLayoutAtoms.h"
00057 #include "nsHTMLReflowState.h"
00058 #include "nsThemeConstants.h"
00059 
00060 #include "nsPresContext.h"
00061 #include "nsIDocument.h"
00062 
00063 #include "nsCSSPseudoElements.h"
00064 #include "nsStyleSet.h"
00065 #include "imgIRequest.h"
00066 #include "nsInspectorCSSUtils.h"
00067 
00068 #if defined(DEBUG_bzbarsky) || defined(DEBUG_caillon)
00069 #define DEBUG_ComputedDOMStyle
00070 #endif
00071 
00072 /*
00073  * This is the implementation of the readonly CSSStyleDeclaration that is
00074  * returned by the getComputedStyle() function.
00075  */
00076 
00077 static nsComputedDOMStyle *sCachedComputedDOMStyle;
00078 
00079 nsresult
00080 NS_NewComputedDOMStyle(nsIComputedDOMStyle** aComputedStyle)
00081 {
00082   NS_ENSURE_ARG_POINTER(aComputedStyle);
00083 
00084   if (sCachedComputedDOMStyle) {
00085     // There's an unused nsComputedDOMStyle cached, use it.
00086     // But before we use it, re-initialize the object.
00087 
00088     // Oh yeah baby, placement new!
00089     *aComputedStyle = new (sCachedComputedDOMStyle) nsComputedDOMStyle();
00090 
00091     sCachedComputedDOMStyle = nsnull;
00092   } else {
00093     // No nsComputedDOMStyle cached, create a new one.
00094 
00095     *aComputedStyle = new nsComputedDOMStyle();
00096     NS_ENSURE_TRUE(*aComputedStyle, NS_ERROR_OUT_OF_MEMORY);
00097   }
00098 
00099   NS_ADDREF(*aComputedStyle);
00100 
00101   return NS_OK;
00102 }
00103 
00104 static nsIFrame*
00105 GetContainingBlockFor(nsIFrame* aFrame) {
00106   if (!aFrame) {
00107     return nsnull;
00108   }
00109   return nsHTMLReflowState::GetContainingBlockFor(aFrame);
00110 }
00111 
00112 nsComputedDOMStyle::nsComputedDOMStyle()
00113   : mInner(this), mDocumentWeak(nsnull), mT2P(0.0f)
00114 {
00115 }
00116 
00117 
00118 nsComputedDOMStyle::~nsComputedDOMStyle()
00119 {
00120 }
00121 
00122 void
00123 nsComputedDOMStyle::Shutdown()
00124 {
00125   // We want to de-allocate without calling the dtor since we
00126   // already did that manually in doDestroyComputedDOMStyle(),
00127   // so cast our cached object to something that doesn't know
00128   // about our dtor.
00129   delete NS_REINTERPRET_CAST(char*, sCachedComputedDOMStyle);
00130   sCachedComputedDOMStyle = nsnull;
00131 }
00132 
00133 
00134 // QueryInterface implementation for nsComputedDOMStyle
00135 NS_INTERFACE_MAP_BEGIN(nsComputedDOMStyle)
00136   NS_INTERFACE_MAP_ENTRY(nsIComputedDOMStyle)
00137   NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration)
00138   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
00139   NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIDOMCSS2Properties, &mInner)
00140   NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIDOMNSCSS2Properties, &mInner)
00141   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIComputedDOMStyle)
00142   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(ComputedCSSStyleDeclaration)
00143 NS_INTERFACE_MAP_END
00144 
00145 
00146 static void doDestroyComputedDOMStyle(nsComputedDOMStyle *aComputedStyle)
00147 {
00148   if (!sCachedComputedDOMStyle) {
00149     // The cache is empty, store aComputedStyle in the cache.
00150 
00151     sCachedComputedDOMStyle = aComputedStyle;
00152     sCachedComputedDOMStyle->~nsComputedDOMStyle();
00153   } else {
00154     // The cache is full, delete aComputedStyle
00155 
00156     delete aComputedStyle;
00157   }
00158 }
00159 
00160 NS_IMPL_ADDREF(nsComputedDOMStyle)
00161 NS_IMPL_RELEASE_WITH_DESTROY(nsComputedDOMStyle,
00162                              doDestroyComputedDOMStyle(this))
00163 
00164 
00165 NS_IMETHODIMP
00166 nsComputedDOMStyle::Init(nsIDOMElement *aElement,
00167                          const nsAString& aPseudoElt,
00168                          nsIPresShell *aPresShell)
00169 {
00170   NS_ENSURE_ARG_POINTER(aElement);
00171   NS_ENSURE_ARG_POINTER(aPresShell);
00172 
00173   mDocumentWeak = do_GetWeakReference(aPresShell->GetDocument());
00174 
00175   mContent = do_QueryInterface(aElement);
00176   if (!mContent) {
00177     // This should not happen, all our elements support nsIContent!
00178 
00179     return NS_ERROR_FAILURE;
00180   }
00181 
00182   if (!DOMStringIsNull(aPseudoElt) && !aPseudoElt.IsEmpty() &&
00183       aPseudoElt.First() == PRUnichar(':')) {
00184     // deal with two-colon forms of aPseudoElt
00185     nsAString::const_iterator start, end;
00186     aPseudoElt.BeginReading(start);
00187     aPseudoElt.EndReading(end);
00188     NS_ASSERTION(start != end, "aPseudoElt is not empty!");
00189     ++start;
00190     PRBool haveTwoColons = PR_TRUE;
00191     if (start == end || *start != PRUnichar(':')) {
00192       --start;
00193       haveTwoColons = PR_FALSE;
00194     }
00195     mPseudo = do_GetAtom(Substring(start, end));
00196     NS_ENSURE_TRUE(mPseudo, NS_ERROR_OUT_OF_MEMORY);
00197 
00198     // There aren't any non-CSS2 pseudo-elements with a single ':'
00199     if (!haveTwoColons &&
00200         !nsCSSPseudoElements::IsCSS2PseudoElement(mPseudo)) {
00201       // XXXbz I'd really rather we threw an exception or something, but
00202       // the DOM spec sucks.
00203       mPseudo = nsnull;
00204     }
00205   }
00206 
00207   nsPresContext *presCtx = aPresShell->GetPresContext();
00208   NS_ENSURE_TRUE(presCtx, NS_ERROR_FAILURE);
00209 
00210   mT2P = presCtx->TwipsToPixels();
00211 
00212   return NS_OK;
00213 }
00214 
00215 NS_IMETHODIMP
00216 nsComputedDOMStyle::GetPropertyValue(const nsCSSProperty aPropID,
00217                                      nsAString& aValue)
00218 {
00219   // This is mostly to avoid code duplication with GetPropertyCSSValue(); if
00220   // perf ever becomes an issue here (doubtful), we can look into changing
00221   // this.
00222   return GetPropertyValue(
00223     NS_ConvertASCIItoUTF16(nsCSSProps::GetStringValue(aPropID)),
00224     aValue);
00225 }
00226 
00227 NS_IMETHODIMP
00228 nsComputedDOMStyle::SetPropertyValue(const nsCSSProperty aPropID,
00229                                      const nsAString& aValue)
00230 {
00231   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
00232 }
00233 
00234 
00235 NS_IMETHODIMP
00236 nsComputedDOMStyle::GetCssText(nsAString& aCssText)
00237 {
00238   aCssText.Truncate();
00239 
00240   return NS_OK;
00241 }
00242 
00243 
00244 NS_IMETHODIMP
00245 nsComputedDOMStyle::SetCssText(const nsAString& aCssText)
00246 {
00247   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
00248 }
00249 
00250 
00251 NS_IMETHODIMP
00252 nsComputedDOMStyle::GetLength(PRUint32* aLength)
00253 {
00254   NS_PRECONDITION(aLength, "Null aLength!  Prepare to die!");
00255 
00256   (void)GetQueryablePropertyMap(aLength);
00257 
00258   return NS_OK;
00259 }
00260 
00261 
00262 NS_IMETHODIMP
00263 nsComputedDOMStyle::GetParentRule(nsIDOMCSSRule** aParentRule)
00264 {
00265   NS_ENSURE_ARG_POINTER(aParentRule);
00266   *aParentRule = nsnull;
00267 
00268   return NS_OK;
00269 }
00270 
00271 
00272 NS_IMETHODIMP
00273 nsComputedDOMStyle::GetPropertyValue(const nsAString& aPropertyName,
00274                                      nsAString& aReturn)
00275 {
00276   nsCOMPtr<nsIDOMCSSValue> val;
00277 
00278   aReturn.Truncate();
00279 
00280   nsresult rv = GetPropertyCSSValue(aPropertyName, getter_AddRefs(val));
00281   NS_ENSURE_SUCCESS(rv, rv);
00282 
00283   if (val) {
00284     rv = val->GetCssText(aReturn);
00285   }
00286 
00287   return rv;
00288 }
00289 
00290 
00291 NS_IMETHODIMP
00292 nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName,
00293                                         nsIDOMCSSValue** aReturn)
00294 {
00295   NS_ENSURE_ARG_POINTER(aReturn);
00296   *aReturn = nsnull;
00297 
00298   nsCOMPtr<nsIDocument> document = do_QueryReferent(mDocumentWeak);
00299   NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);
00300 
00301   // Flush _before_ getting the presshell, since that could create a new
00302   // presshell.  Also note that we want to flush the style on the document
00303   // we're computing style in, not on the document mContent is in -- the two
00304   // may be different.
00305   document->FlushPendingNotifications(Flush_Style);
00306 
00307   nsIPresShell* presShell = document->GetShellAt(0);
00308   NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
00309 
00310   nsIFrame *frame = nsnull;
00311   presShell->GetPrimaryFrameFor(mContent, &frame);
00312 
00313   nsresult rv = NS_OK;
00314 
00315   nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName);
00316 
00317   PRUint32 i = 0;
00318   PRUint32 length = 0;
00319   const ComputedStyleMapEntry* propMap = GetQueryablePropertyMap(&length);
00320   for (; i < length; ++i) {
00321     if (prop == propMap[i].mProperty) {
00322       // Call our pointer-to-member-function.
00323       rv = (this->*(propMap[i].mGetter))(frame, aReturn);
00324       break;
00325     }
00326   }
00327 
00328 #ifdef DEBUG_ComputedDOMStyle
00329   if (i == length) {
00330     NS_WARNING(PromiseFlatCString(NS_ConvertUCS2toUTF8(aPropertyName) + 
00331                                   NS_LITERAL_CSTRING(" is not queryable!")).get());
00332   }
00333 #endif
00334 
00335   if (NS_FAILED(rv)) {
00336     *aReturn = nsnull;
00337   }
00338 
00339   // Release the current style context for it should be re-resolved
00340   // whenever a frame is not available.
00341   mStyleContextHolder = nsnull;
00342 
00343   return rv;
00344 }
00345 
00346 
00347 NS_IMETHODIMP
00348 nsComputedDOMStyle::RemoveProperty(const nsAString& aPropertyName,
00349                                    nsAString& aReturn)
00350 {
00351   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
00352 }
00353 
00354 
00355 NS_IMETHODIMP
00356 nsComputedDOMStyle::GetPropertyPriority(const nsAString& aPropertyName,
00357                                         nsAString& aReturn)
00358 {
00359   aReturn.Truncate();
00360 
00361   return NS_OK;
00362 }
00363 
00364 
00365 NS_IMETHODIMP
00366 nsComputedDOMStyle::SetProperty(const nsAString& aPropertyName,
00367                                 const nsAString& aValue,
00368                                 const nsAString& aPriority)
00369 {
00370   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
00371 }
00372 
00373 
00374 NS_IMETHODIMP
00375 nsComputedDOMStyle::Item(PRUint32 aIndex, nsAString& aReturn)
00376 {
00377   aReturn.Truncate();
00378 
00379   PRUint32 length = 0;
00380   const ComputedStyleMapEntry* propMap = GetQueryablePropertyMap(&length);
00381   if (aIndex < length) {
00382     CopyASCIItoUCS2(nsCSSProps::GetStringValue(propMap[aIndex].mProperty),
00383                     aReturn);
00384   }
00385 
00386   return NS_OK;
00387 }
00388 
00389 
00390 // Property getters...
00391 
00392 nsresult
00393 nsComputedDOMStyle::GetBinding(nsIFrame *aFrame,
00394                                nsIDOMCSSValue** aValue)
00395 {
00396   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00397   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00398 
00399   const nsStyleDisplay* display = nsnull;
00400 
00401   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
00402 
00403   if (display && display->mBinding) {
00404     val->SetURI(display->mBinding);
00405   } else {
00406     val->SetIdent(nsLayoutAtoms::none);
00407   }
00408 
00409   return CallQueryInterface(val, aValue);
00410 }
00411 
00412 nsresult
00413 nsComputedDOMStyle::GetClear(nsIFrame *aFrame,
00414                              nsIDOMCSSValue** aValue)
00415 {
00416   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00417   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00418 
00419   const nsStyleDisplay *display = nsnull;
00420   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
00421 
00422   if (display && display->mBreakType != NS_STYLE_CLEAR_NONE) {
00423     const nsAFlatCString& clear =
00424       nsCSSProps::ValueToKeyword(display->mBreakType,
00425                                  nsCSSProps::kClearKTable);
00426     val->SetIdent(clear);
00427   } else {
00428     val->SetIdent(nsLayoutAtoms::none);
00429   }
00430 
00431   return CallQueryInterface(val, aValue);
00432 }
00433 
00434 nsresult
00435 nsComputedDOMStyle::GetCssFloat(nsIFrame *aFrame,
00436                                 nsIDOMCSSValue** aValue)
00437 {
00438   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
00439   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00440 
00441   const nsStyleDisplay* display = nsnull;
00442   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
00443 
00444   if (display && display->mFloats != NS_STYLE_FLOAT_NONE) {
00445     const nsAFlatCString& cssFloat =
00446       nsCSSProps::ValueToKeyword(display->mFloats,
00447                                  nsCSSProps::kFloatKTable);
00448     val->SetIdent(cssFloat);
00449   } else {
00450     val->SetIdent(nsLayoutAtoms::none);
00451   }
00452 
00453   return CallQueryInterface(val, aValue);
00454 }
00455 
00456 nsresult
00457 nsComputedDOMStyle::GetBottom(nsIFrame *aFrame,
00458                               nsIDOMCSSValue** aValue)
00459 {
00460   return GetOffsetWidthFor(NS_SIDE_BOTTOM, aFrame, aValue);
00461 }
00462 
00463 nsDOMCSSRGBColor*
00464 nsComputedDOMStyle::GetDOMCSSRGBColor(nscolor aColor)
00465 {
00466   nsROCSSPrimitiveValue *red   = GetROCSSPrimitiveValue();
00467   nsROCSSPrimitiveValue *green = GetROCSSPrimitiveValue();
00468   nsROCSSPrimitiveValue *blue  = GetROCSSPrimitiveValue();
00469 
00470   if (red && green && blue) {
00471     nsDOMCSSRGBColor *rgbColor = new nsDOMCSSRGBColor(red, green, blue);
00472 
00473     if (rgbColor) {
00474       red->SetNumber(NS_GET_R(aColor));
00475       green->SetNumber(NS_GET_G(aColor));
00476       blue->SetNumber(NS_GET_B(aColor));
00477 
00478       return rgbColor;
00479     }
00480   }
00481 
00482   delete red;
00483   delete green;
00484   delete blue;
00485 
00486   return nsnull;
00487 }
00488 
00489 nsresult
00490 nsComputedDOMStyle::GetColor(nsIFrame *aFrame,
00491                              nsIDOMCSSValue** aValue)
00492 {
00493   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00494   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00495 
00496   const nsStyleColor* color = nsnull;
00497   GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&)color, aFrame);
00498 
00499   nsDOMCSSRGBColor *rgb = nsnull;
00500 
00501   if (color) {
00502     rgb = GetDOMCSSRGBColor(color->mColor);
00503     if (!rgb) {
00504       delete val;
00505 
00506       return NS_ERROR_OUT_OF_MEMORY;
00507     }
00508 
00509     val->SetColor(rgb);
00510   }
00511 
00512   return CallQueryInterface(val, aValue);
00513 }
00514 
00515 nsresult
00516 nsComputedDOMStyle::GetOpacity(nsIFrame *aFrame,
00517                                nsIDOMCSSValue** aValue)
00518 {
00519   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00520   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00521 
00522   const nsStyleDisplay *display = nsnull;
00523   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
00524 
00525   if (display) {
00526     val->SetNumber(display->mOpacity);
00527   }
00528 
00529   return CallQueryInterface(val, aValue);
00530 }
00531 
00532 nsresult
00533 nsComputedDOMStyle::GetColumnCount(nsIFrame *aFrame,
00534                                    nsIDOMCSSValue** aValue)
00535 {
00536   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00537   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00538 
00539   const nsStyleColumn* column = nsnull;
00540   GetStyleData(eStyleStruct_Column, (const nsStyleStruct*&)column, aFrame);
00541 
00542   if (column) {
00543     if (column->mColumnCount == NS_STYLE_COLUMN_COUNT_AUTO) {
00544       val->SetIdent(nsLayoutAtoms::autoAtom);
00545     } else {
00546       val->SetNumber(column->mColumnCount);
00547     }
00548   }
00549 
00550   return CallQueryInterface(val, aValue);
00551 }
00552 
00553 nsresult
00554 nsComputedDOMStyle::GetColumnWidth(nsIFrame *aFrame,
00555                                    nsIDOMCSSValue** aValue)
00556 {
00557   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00558   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00559 
00560   const nsStyleColumn* column = nsnull;
00561   GetStyleData(eStyleStruct_Column, (const nsStyleStruct*&)column, aFrame);
00562 
00563   if (column) {
00564     switch (column->mColumnWidth.GetUnit()) {
00565       case eStyleUnit_Coord:
00566         val->SetTwips(column->mColumnWidth.GetCoordValue());
00567         break;
00568       case eStyleUnit_Auto:
00569         // XXX fix this. When we actually have a column frame, I think
00570         // we should return the computed column width.
00571         val->SetIdent(nsLayoutAtoms::autoAtom);
00572         break;
00573       default:
00574         NS_ERROR("Unexpected column width unit");
00575         val->SetTwips(0);
00576         break;
00577     }
00578   }
00579 
00580   return CallQueryInterface(val, aValue);
00581 }
00582 
00583 nsresult
00584 nsComputedDOMStyle::GetColumnGap(nsIFrame *aFrame,
00585                                  nsIDOMCSSValue** aValue)
00586 {
00587   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00588   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00589 
00590   const nsStyleColumn* column = nsnull;
00591   GetStyleData(eStyleStruct_Column, (const nsStyleStruct*&)column, aFrame);
00592 
00593   if (column) {
00594     switch (column->mColumnGap.GetUnit()) {
00595       case eStyleUnit_Coord:
00596         val->SetTwips(column->mColumnGap.GetCoordValue());
00597         break;
00598       case eStyleUnit_Percent:
00599         if (aFrame) {
00600           val->SetTwips(column->mColumnGap.GetPercentValue()*aFrame->GetSize().width);
00601         } else {
00602           val->SetPercent(column->mColumnGap.GetPercentValue());
00603         }
00604         break;
00605       default:
00606         NS_ERROR("Unexpected column gap unit");
00607         val->SetTwips(0);
00608         break;
00609     }
00610   }
00611 
00612   return CallQueryInterface(val, aValue);
00613 }
00614 
00615 nsresult
00616 nsComputedDOMStyle::GetCounterIncrement(nsIFrame *aFrame,
00617                                         nsIDOMCSSValue** aValue)
00618 {
00619   const nsStyleContent *content = nsnull;
00620   GetStyleData(eStyleStruct_Content, (const nsStyleStruct*&)content, aFrame);
00621 
00622   if (content && content->CounterIncrementCount() == 0) {
00623     nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00624     NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00625     val->SetIdent(nsLayoutAtoms::none);
00626     return CallQueryInterface(val, aValue);
00627   }
00628 
00629   nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
00630   NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
00631 
00632   if (content) {
00633     for (PRUint32 i = 0, i_end = content->CounterIncrementCount(); i < i_end; ++i) {
00634       nsROCSSPrimitiveValue* name = GetROCSSPrimitiveValue();
00635       if (!name) {
00636         delete valueList;
00637         return NS_ERROR_OUT_OF_MEMORY;
00638       }
00639       if (!valueList->AppendCSSValue(name)) {
00640         delete valueList;
00641         delete name;
00642         return NS_ERROR_OUT_OF_MEMORY;
00643       }
00644     
00645       nsROCSSPrimitiveValue* value = GetROCSSPrimitiveValue();
00646       if (!value) {
00647         delete valueList;
00648         return NS_ERROR_OUT_OF_MEMORY;
00649       }
00650       if (!valueList->AppendCSSValue(value)) {
00651         delete valueList;
00652         delete value;
00653         return NS_ERROR_OUT_OF_MEMORY;
00654       }
00655 
00656       const nsStyleCounterData *data = content->GetCounterIncrementAt(i);
00657       name->SetString(data->mCounter);
00658       value->SetNumber(data->mValue); // XXX This should really be integer
00659     }
00660   }
00661 
00662   return CallQueryInterface(valueList, aValue);
00663 }
00664 
00665 nsresult
00666 nsComputedDOMStyle::GetCounterReset(nsIFrame *aFrame,
00667                                     nsIDOMCSSValue** aValue)
00668 {
00669   const nsStyleContent *content = nsnull;
00670   GetStyleData(eStyleStruct_Content, (const nsStyleStruct*&)content, aFrame);
00671 
00672   if (content && content->CounterResetCount() == 0) {
00673     nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00674     NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00675     val->SetIdent(nsLayoutAtoms::none);
00676     return CallQueryInterface(val, aValue);
00677   }
00678 
00679   nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
00680   NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
00681 
00682   if (content) {
00683     for (PRUint32 i = 0, i_end = content->CounterResetCount(); i < i_end; ++i) {
00684       nsROCSSPrimitiveValue* name = GetROCSSPrimitiveValue();
00685       if (!name) {
00686         delete valueList;
00687         return NS_ERROR_OUT_OF_MEMORY;
00688       }
00689       if (!valueList->AppendCSSValue(name)) {
00690         delete valueList;
00691         delete name;
00692         return NS_ERROR_OUT_OF_MEMORY;
00693       }
00694     
00695       nsROCSSPrimitiveValue* value = GetROCSSPrimitiveValue();
00696       if (!value) {
00697         delete valueList;
00698         return NS_ERROR_OUT_OF_MEMORY;
00699       }
00700       if (!valueList->AppendCSSValue(value)) {
00701         delete valueList;
00702         delete value;
00703         return NS_ERROR_OUT_OF_MEMORY;
00704       }
00705 
00706       const nsStyleCounterData *data = content->GetCounterResetAt(i);
00707       name->SetString(data->mCounter);
00708       value->SetNumber(data->mValue); // XXX This should really be integer
00709     }
00710   }
00711 
00712   return CallQueryInterface(valueList, aValue);
00713 }
00714 
00715 nsresult
00716 nsComputedDOMStyle::GetFontFamily(nsIFrame *aFrame,
00717                                   nsIDOMCSSValue** aValue)
00718 {
00719   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
00720   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00721 
00722   const nsStyleFont* font = nsnull;
00723   GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font, aFrame);
00724 
00725   if (font) {
00726     nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocumentWeak);
00727     NS_ASSERTION(doc, "document is required");
00728     nsIPresShell* presShell = doc->GetShellAt(0);
00729     NS_ASSERTION(presShell, "pres shell is required");
00730     nsPresContext *presContext = presShell->GetPresContext();
00731     NS_ASSERTION(presContext, "pres context is required");
00732 
00733     const nsString& fontName = font->mFont.name;
00734     PRUint8 generic = font->mFlags & NS_STYLE_FONT_FACE_MASK;
00735     if (generic == kGenericFont_NONE && !font->mFont.systemFont) { 
00736       const nsFont* defaultFont =
00737         presContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID);
00738 
00739       PRInt32 lendiff = fontName.Length() - defaultFont->name.Length();
00740       if (lendiff > 0) {
00741         val->SetString(Substring(fontName, 0, lendiff-1)); // -1 removes comma
00742       } else {
00743         val->SetString(fontName);
00744       }
00745     } else {
00746       val->SetString(fontName);
00747     }
00748   }
00749 
00750   return CallQueryInterface(val, aValue);
00751 }
00752 
00753 nsresult
00754 nsComputedDOMStyle::GetFontSize(nsIFrame *aFrame,
00755                                 nsIDOMCSSValue** aValue)
00756 {
00757   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
00758   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00759 
00760   const nsStyleFont* font = nsnull;
00761   GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font, aFrame);
00762 
00763   // Note: font->mSize is the 'computed size'; font->mFont.size is the
00764   // 'actual size'
00765   val->SetTwips(font? font->mSize:0);
00766 
00767   return CallQueryInterface(val, aValue);
00768 }
00769 
00770 nsresult
00771 nsComputedDOMStyle::GetFontSizeAdjust(nsIFrame *aFrame,
00772                                       nsIDOMCSSValue** aValue)
00773 {
00774   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00775   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00776 
00777   const nsStyleFont *font = nsnull;
00778   GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font, aFrame);
00779 
00780   if (font && font->mFont.sizeAdjust) {
00781     val->SetNumber(font->mFont.sizeAdjust);
00782   } else {
00783     val->SetIdent(nsLayoutAtoms::none);
00784   }
00785 
00786   return CallQueryInterface(val, aValue);
00787 }
00788 
00789 nsresult
00790 nsComputedDOMStyle::GetFontStyle(nsIFrame *aFrame,
00791                                  nsIDOMCSSValue** aValue)
00792 {
00793   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
00794   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00795 
00796   const nsStyleFont* font = nsnull;
00797   GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font, aFrame);
00798 
00799   if (font && font->mFont.style != NS_STYLE_FONT_STYLE_NORMAL) {
00800     const nsAFlatCString& style=
00801       nsCSSProps::ValueToKeyword(font->mFont.style,
00802                                  nsCSSProps::kFontStyleKTable);
00803     val->SetIdent(style);
00804   } else {
00805     val->SetIdent(nsLayoutAtoms::normal);
00806   }
00807 
00808   return CallQueryInterface(val, aValue);
00809 }
00810 
00811 nsresult
00812 nsComputedDOMStyle::GetFontWeight(nsIFrame *aFrame,
00813                                   nsIDOMCSSValue** aValue)
00814 {
00815   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
00816   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00817 
00818   const nsStyleFont* font = nsnull;
00819   GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font, aFrame);
00820 
00821   if (font) {
00822     const nsAFlatCString& str_weight=
00823       nsCSSProps::ValueToKeyword(font->mFont.weight,
00824                                  nsCSSProps::kFontWeightKTable);
00825     if (!str_weight.IsEmpty()) {
00826       val->SetIdent(str_weight);
00827     } else {
00828       val->SetNumber(font->mFont.weight);
00829     }
00830   }
00831 
00832   return CallQueryInterface(val, aValue);
00833 }
00834 
00835 nsresult
00836 nsComputedDOMStyle::GetFontVariant(nsIFrame *aFrame,
00837                                    nsIDOMCSSValue** aValue)
00838 {
00839   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
00840   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00841 
00842   const nsStyleFont* font = nsnull;
00843   GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font, aFrame);
00844 
00845   if (font && font->mFont.variant != NS_STYLE_FONT_VARIANT_NORMAL) {
00846     const nsAFlatCString& variant=
00847       nsCSSProps::ValueToKeyword(font->mFont.variant,
00848                                  nsCSSProps::kFontVariantKTable);
00849     val->SetIdent(variant);
00850   } else {
00851     val->SetIdent(nsLayoutAtoms::normal);
00852   }
00853 
00854   return CallQueryInterface(val, aValue);
00855 }
00856 
00857 nsresult
00858 nsComputedDOMStyle::GetBackgroundAttachment(nsIFrame *aFrame,
00859                                             nsIDOMCSSValue** aValue)
00860 {
00861   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00862   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00863 
00864   const nsStyleBackground *background = nsnull;
00865   GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)background,
00866                aFrame);
00867 
00868   if (background) {
00869     const nsAFlatCString& backgroundAttachment =
00870       nsCSSProps::ValueToKeyword(background->mBackgroundAttachment,
00871                                  nsCSSProps::kBackgroundAttachmentKTable);
00872     val->SetIdent(backgroundAttachment);
00873   }
00874 
00875   return CallQueryInterface(val, aValue);
00876 }
00877 
00878 nsresult
00879 nsComputedDOMStyle::GetBackgroundClip(nsIFrame *aFrame,
00880                                       nsIDOMCSSValue** aValue)
00881 {
00882   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00883   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00884 
00885   const nsStyleBackground *background = nsnull;
00886   GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)background, aFrame);
00887 
00888   PRUint8 clip = NS_STYLE_BG_CLIP_BORDER;
00889   if (background) {
00890     clip = background->mBackgroundClip;
00891   }
00892 
00893   const nsAFlatCString& backgroundClip =
00894     nsCSSProps::ValueToKeyword(clip,
00895                                nsCSSProps::kBackgroundClipKTable);
00896 
00897   val->SetIdent(backgroundClip);
00898 
00899   return CallQueryInterface(val, aValue);
00900 }
00901 
00902 nsresult
00903 nsComputedDOMStyle::GetBackgroundColor(nsIFrame *aFrame,
00904                                        nsIDOMCSSValue** aValue)
00905 {
00906   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
00907   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00908 
00909   const nsStyleBackground* color = nsnull;
00910   GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)color, aFrame);
00911 
00912   if (color) {
00913     if (color->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) {
00914       const nsAFlatCString& backgroundColor =
00915         nsCSSProps::ValueToKeyword(NS_STYLE_BG_COLOR_TRANSPARENT,
00916                                    nsCSSProps::kBackgroundColorKTable);
00917       val->SetIdent(backgroundColor);
00918     } else {
00919       nsDOMCSSRGBColor *rgb = nsnull;
00920       rgb = GetDOMCSSRGBColor(color->mBackgroundColor);
00921       if (!rgb) {
00922         delete val;
00923 
00924         return NS_ERROR_OUT_OF_MEMORY;
00925       }
00926 
00927       val->SetColor(rgb);
00928     }
00929   }
00930 
00931   return CallQueryInterface(val, aValue);
00932 }
00933 
00934 nsresult
00935 nsComputedDOMStyle::GetBackgroundImage(nsIFrame *aFrame,
00936                                        nsIDOMCSSValue** aValue)
00937 {
00938   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
00939   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00940 
00941   const nsStyleBackground* color = nsnull;
00942   GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)color, aFrame);
00943 
00944   if (color) {
00945     if (color->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) {
00946       val->SetIdent(nsLayoutAtoms::none);
00947     } else {
00948       nsCOMPtr<nsIURI> uri;
00949       if (color->mBackgroundImage) {
00950         color->mBackgroundImage->GetURI(getter_AddRefs(uri));
00951       }
00952       val->SetURI(uri);
00953     }
00954   }
00955 
00956   return CallQueryInterface(val, aValue);
00957 }
00958 
00959 nsresult
00960 nsComputedDOMStyle::GetBackgroundInlinePolicy(nsIFrame *aFrame,
00961                                               nsIDOMCSSValue** aValue)
00962 {
00963   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00964   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00965 
00966   const nsStyleBackground *background = nsnull;
00967   GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)background, aFrame);
00968 
00969   PRUint8 policy = NS_STYLE_BG_INLINE_POLICY_CONTINUOUS;
00970   if (background) {
00971     policy = background->mBackgroundInlinePolicy;
00972   }
00973 
00974   const nsAFlatCString& backgroundPolicy =
00975       nsCSSProps::ValueToKeyword(policy,
00976                                  nsCSSProps::kBackgroundInlinePolicyKTable);
00977 
00978   val->SetIdent(backgroundPolicy);
00979 
00980   return CallQueryInterface(val, aValue);  
00981 }
00982 
00983 nsresult
00984 nsComputedDOMStyle::GetBackgroundOrigin(nsIFrame *aFrame,
00985                                         nsIDOMCSSValue** aValue)
00986 {
00987   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
00988   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
00989 
00990   const nsStyleBackground *background = nsnull;
00991   GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)background, aFrame);
00992 
00993   PRUint8 origin = NS_STYLE_BG_ORIGIN_PADDING;
00994   if (background) {
00995     origin = background->mBackgroundOrigin;
00996   }
00997 
00998   const nsAFlatCString& backgroundOrigin =
00999     nsCSSProps::ValueToKeyword(origin,
01000                                nsCSSProps::kBackgroundOriginKTable);
01001 
01002   val->SetIdent(backgroundOrigin);
01003 
01004   return CallQueryInterface(val, aValue);
01005 }
01006 
01007 nsresult
01008 nsComputedDOMStyle::GetBackgroundRepeat(nsIFrame *aFrame,
01009                                         nsIDOMCSSValue** aValue)
01010 {
01011   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01012   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01013 
01014   const nsStyleBackground *background = nsnull;
01015   GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)background,
01016                aFrame);
01017 
01018   if (background) {
01019     const nsAFlatCString& backgroundRepeat =
01020       nsCSSProps::ValueToKeyword(background->mBackgroundRepeat,
01021                                  nsCSSProps::kBackgroundRepeatKTable);
01022     val->SetIdent(backgroundRepeat);
01023   }
01024 
01025   return CallQueryInterface(val, aValue);
01026 }
01027 
01028 nsresult
01029 nsComputedDOMStyle::GetPadding(nsIFrame *aFrame,
01030                                nsIDOMCSSValue** aValue)
01031 {
01032   // return null per spec.
01033   aValue = nsnull;
01034 
01035   return NS_OK;
01036 }
01037 
01038 nsresult
01039 nsComputedDOMStyle::GetPaddingTop(nsIFrame *aFrame,
01040                                   nsIDOMCSSValue** aValue)
01041 {
01042   return GetPaddingWidthFor(NS_SIDE_TOP, aFrame, aValue);
01043 }
01044 
01045 nsresult
01046 nsComputedDOMStyle::GetPaddingBottom(nsIFrame *aFrame,
01047                                      nsIDOMCSSValue** aValue)
01048 {
01049   return GetPaddingWidthFor(NS_SIDE_BOTTOM, aFrame, aValue);
01050 }
01051 
01052 nsresult
01053 nsComputedDOMStyle::GetPaddingLeft(nsIFrame *aFrame,
01054                                    nsIDOMCSSValue** aValue)
01055 {
01056   return GetPaddingWidthFor(NS_SIDE_LEFT, aFrame, aValue);
01057 }
01058 
01059 nsresult
01060 nsComputedDOMStyle::GetPaddingRight(nsIFrame *aFrame,
01061                                     nsIDOMCSSValue** aValue)
01062 {
01063   return GetPaddingWidthFor(NS_SIDE_RIGHT, aFrame, aValue);
01064 }
01065 
01066 nsresult
01067 nsComputedDOMStyle::GetBorderCollapse(nsIFrame *aFrame,
01068                                       nsIDOMCSSValue** aValue)
01069 {
01070   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01071   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01072 
01073   const nsStyleTableBorder* table = nsnull;
01074   GetStyleData(eStyleStruct_TableBorder, (const nsStyleStruct*&)table, aFrame);
01075 
01076   if (table) {
01077     const nsAFlatCString& ident=
01078       nsCSSProps::ValueToKeyword(table->mBorderCollapse,
01079                                  nsCSSProps::kBorderCollapseKTable);
01080     val->SetIdent(ident);
01081   }
01082 
01083   return CallQueryInterface(val, aValue);
01084 }
01085 
01086 nsresult
01087 nsComputedDOMStyle::GetBorderSpacing(nsIFrame *aFrame,
01088                                      nsIDOMCSSValue** aValue)
01089 {
01090   nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
01091   NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
01092 
01093   const nsStyleTableBorder *border = nsnull;
01094   GetStyleData(eStyleStruct_TableBorder, (const nsStyleStruct*&)border, aFrame);
01095   if (border) {
01096     nsROCSSPrimitiveValue* xSpacing = GetROCSSPrimitiveValue();
01097     if (!xSpacing) {
01098       delete valueList;
01099       return NS_ERROR_OUT_OF_MEMORY;
01100     }
01101     if (!valueList->AppendCSSValue(xSpacing)) {
01102       delete valueList;
01103       delete xSpacing;
01104       return NS_ERROR_OUT_OF_MEMORY;
01105     }
01106     
01107     nsROCSSPrimitiveValue* ySpacing = GetROCSSPrimitiveValue();
01108     if (!ySpacing) {
01109       delete valueList;
01110       return NS_ERROR_OUT_OF_MEMORY;
01111     }
01112     if (!valueList->AppendCSSValue(ySpacing)) {
01113       delete valueList;
01114       delete ySpacing;
01115       return NS_ERROR_OUT_OF_MEMORY;
01116     }
01117 
01118     // border-spacing will always be a coord
01119     xSpacing->SetTwips(border->mBorderSpacingX.GetCoordValue());
01120     ySpacing->SetTwips(border->mBorderSpacingY.GetCoordValue());
01121         
01122   }
01123 
01124   return CallQueryInterface(valueList, aValue);
01125 }
01126 
01127 nsresult
01128 nsComputedDOMStyle::GetCaptionSide(nsIFrame *aFrame,
01129                                    nsIDOMCSSValue** aValue)
01130 {
01131   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01132   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01133 
01134   const nsStyleTableBorder *table = nsnull;
01135   GetStyleData(eStyleStruct_TableBorder, (const nsStyleStruct*&)table, aFrame);
01136 
01137   if (table) {
01138     const nsAFlatCString& side =
01139       nsCSSProps::ValueToKeyword(table->mCaptionSide,
01140                                  nsCSSProps::kCaptionSideKTable);
01141     val->SetIdent(side);
01142   }
01143 
01144   return CallQueryInterface(val, aValue);
01145 }
01146 
01147 nsresult
01148 nsComputedDOMStyle::GetEmptyCells(nsIFrame *aFrame,
01149                                   nsIDOMCSSValue** aValue)
01150 {
01151   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01152   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01153 
01154   const nsStyleTableBorder *table = nsnull;
01155   GetStyleData(eStyleStruct_TableBorder, (const nsStyleStruct*&)table, aFrame);
01156 
01157   if (table) {
01158     const nsAFlatCString& emptyCells =
01159       nsCSSProps::ValueToKeyword(table->mEmptyCells,
01160                                  nsCSSProps::kEmptyCellsKTable);
01161     val->SetIdent(emptyCells);
01162   }
01163 
01164   return CallQueryInterface(val, aValue);
01165 }
01166 
01167 nsresult
01168 nsComputedDOMStyle::GetTableLayout(nsIFrame *aFrame,
01169                                    nsIDOMCSSValue** aValue)
01170 {
01171   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01172   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01173 
01174   const nsStyleTable *table = nsnull;
01175   GetStyleData(eStyleStruct_Table, (const nsStyleStruct*&)table, aFrame);
01176 
01177   if (table && table->mLayoutStrategy != NS_STYLE_TABLE_LAYOUT_AUTO) {
01178     const nsAFlatCString& tableLayout =
01179       nsCSSProps::ValueToKeyword(table->mLayoutStrategy,
01180                                  nsCSSProps::kTableLayoutKTable);
01181     val->SetIdent(tableLayout);
01182   } else {
01183     val->SetIdent(nsLayoutAtoms::autoAtom);
01184   }
01185 
01186   return CallQueryInterface(val, aValue);
01187 }
01188 
01189 nsresult
01190 nsComputedDOMStyle::GetBorderStyle(nsIFrame *aFrame,
01191                                    nsIDOMCSSValue** aValue)
01192 {
01193   // return null per spec.
01194   aValue = nsnull;
01195 
01196   return NS_OK;
01197 }
01198 
01199 nsresult
01200 nsComputedDOMStyle::GetBorderTopStyle(nsIFrame *aFrame,
01201                                       nsIDOMCSSValue** aValue)
01202 {
01203   return GetBorderStyleFor(NS_SIDE_TOP, aFrame, aValue);
01204 }
01205 
01206 nsresult
01207 nsComputedDOMStyle::GetBorderBottomStyle(nsIFrame *aFrame,
01208                                          nsIDOMCSSValue** aValue)
01209 {
01210   return GetBorderStyleFor(NS_SIDE_BOTTOM, aFrame, aValue);
01211 }
01212 nsresult
01213 nsComputedDOMStyle::GetBorderLeftStyle(nsIFrame *aFrame,
01214                                        nsIDOMCSSValue** aValue)
01215 {
01216   return GetBorderStyleFor(NS_SIDE_LEFT, aFrame, aValue);
01217 }
01218 
01219 nsresult
01220 nsComputedDOMStyle::GetBorderRightStyle(nsIFrame *aFrame,
01221                                         nsIDOMCSSValue** aValue)
01222 {
01223   return GetBorderStyleFor(NS_SIDE_RIGHT, aFrame, aValue);
01224 }
01225 
01226 nsresult
01227 nsComputedDOMStyle::GetBorderBottomColors(nsIFrame *aFrame,
01228                                           nsIDOMCSSValue** aValue)
01229 {
01230   return GetBorderColorsFor(NS_SIDE_BOTTOM, aFrame, aValue);
01231 }
01232 
01233 nsresult
01234 nsComputedDOMStyle::GetBorderLeftColors(nsIFrame *aFrame,
01235                                         nsIDOMCSSValue** aValue)
01236 {
01237   return GetBorderColorsFor(NS_SIDE_LEFT, aFrame, aValue);
01238 }
01239 
01240 nsresult
01241 nsComputedDOMStyle::GetBorderRightColors(nsIFrame *aFrame,
01242                                          nsIDOMCSSValue** aValue)
01243 {
01244   return GetBorderColorsFor(NS_SIDE_RIGHT, aFrame, aValue);
01245 }
01246 
01247 
01248 nsresult
01249 nsComputedDOMStyle::GetBorderTopColors(nsIFrame *aFrame,
01250                                        nsIDOMCSSValue** aValue)
01251 {
01252   return GetBorderColorsFor(NS_SIDE_TOP, aFrame, aValue);
01253 }
01254 
01255 
01256 nsresult
01257 nsComputedDOMStyle::GetBorderRadiusBottomLeft(nsIFrame *aFrame,
01258                                               nsIDOMCSSValue** aValue)
01259 {
01260   return GetBorderRadiusFor(NS_SIDE_LEFT, aFrame, aValue);
01261 }
01262 
01263 nsresult
01264 nsComputedDOMStyle::GetBorderRadiusBottomRight(nsIFrame *aFrame,
01265                                                nsIDOMCSSValue** aValue)
01266 {
01267   return GetBorderRadiusFor(NS_SIDE_BOTTOM, aFrame, aValue);
01268 }
01269 
01270 nsresult
01271 nsComputedDOMStyle::GetBorderRadiusTopLeft(nsIFrame *aFrame,
01272                                            nsIDOMCSSValue** aValue)
01273 {
01274   return GetBorderRadiusFor(NS_SIDE_TOP, aFrame, aValue);
01275 }
01276 
01277 nsresult
01278 nsComputedDOMStyle::GetBorderRadiusTopRight(nsIFrame *aFrame,
01279                                             nsIDOMCSSValue** aValue)
01280 {
01281   return GetBorderRadiusFor(NS_SIDE_RIGHT, aFrame, aValue);
01282 }
01283 
01284 nsresult
01285 nsComputedDOMStyle::GetBorderWidth(nsIFrame *aFrame,
01286                                    nsIDOMCSSValue** aValue)
01287 {
01288   // return null per spec.
01289   aValue = nsnull;
01290 
01291   return NS_OK;
01292 }
01293 
01294 nsresult
01295 nsComputedDOMStyle::GetBorderTopWidth(nsIFrame *aFrame,
01296                                       nsIDOMCSSValue** aValue)
01297 {
01298   return GetBorderWidthFor(NS_SIDE_TOP, aFrame, aValue);
01299 }
01300 
01301 nsresult
01302 nsComputedDOMStyle::GetBorderBottomWidth(nsIFrame *aFrame,
01303                                          nsIDOMCSSValue** aValue)
01304 {
01305   return GetBorderWidthFor(NS_SIDE_BOTTOM, aFrame, aValue);
01306 }
01307 
01308 nsresult
01309 nsComputedDOMStyle::GetBorderLeftWidth(nsIFrame *aFrame,
01310                                        nsIDOMCSSValue** aValue)
01311 {
01312   return GetBorderWidthFor(NS_SIDE_LEFT, aFrame, aValue);
01313 }
01314 
01315 nsresult
01316 nsComputedDOMStyle::GetBorderRightWidth(nsIFrame *aFrame,
01317                                         nsIDOMCSSValue** aValue)
01318 {
01319   return GetBorderWidthFor(NS_SIDE_RIGHT, aFrame, aValue);
01320 }
01321 
01322 nsresult
01323 nsComputedDOMStyle::GetBorderTopColor(nsIFrame *aFrame,
01324                                       nsIDOMCSSValue** aValue)
01325 {
01326   return GetBorderColorFor(NS_SIDE_TOP, aFrame, aValue);
01327 }
01328 
01329 nsresult
01330 nsComputedDOMStyle::GetBorderBottomColor(nsIFrame *aFrame,
01331                                          nsIDOMCSSValue** aValue)
01332 {
01333   return GetBorderColorFor(NS_SIDE_BOTTOM, aFrame, aValue);
01334 }
01335 
01336 nsresult
01337 nsComputedDOMStyle::GetBorderLeftColor(nsIFrame *aFrame,
01338                                        nsIDOMCSSValue** aValue)
01339 {
01340   return GetBorderColorFor(NS_SIDE_LEFT, aFrame, aValue);
01341 }
01342 
01343 nsresult
01344 nsComputedDOMStyle::GetBorderRightColor(nsIFrame *aFrame,
01345                                         nsIDOMCSSValue** aValue)
01346 {
01347   return GetBorderColorFor(NS_SIDE_RIGHT, aFrame, aValue);
01348 }
01349 
01350 nsresult
01351 nsComputedDOMStyle::GetMarginWidth(nsIFrame *aFrame,
01352                                    nsIDOMCSSValue** aValue)
01353 {
01354   // return null per spec.
01355   aValue = nsnull;
01356 
01357   return NS_OK;
01358 }
01359 
01360 nsresult
01361 nsComputedDOMStyle::GetMarginTopWidth(nsIFrame *aFrame,
01362                                       nsIDOMCSSValue** aValue)
01363 {
01364   return GetMarginWidthFor(NS_SIDE_TOP, aFrame, aValue);
01365 }
01366 
01367 nsresult
01368 nsComputedDOMStyle::GetMarginBottomWidth(nsIFrame *aFrame,
01369                                          nsIDOMCSSValue** aValue)
01370 {
01371   return GetMarginWidthFor(NS_SIDE_BOTTOM, aFrame, aValue);
01372 }
01373 
01374 nsresult
01375 nsComputedDOMStyle::GetMarginLeftWidth(nsIFrame *aFrame,
01376                                        nsIDOMCSSValue** aValue)
01377 {
01378   return GetMarginWidthFor(NS_SIDE_LEFT, aFrame, aValue);
01379 }
01380 
01381 nsresult
01382 nsComputedDOMStyle::GetMarginRightWidth(nsIFrame *aFrame,
01383                                         nsIDOMCSSValue** aValue)
01384 {
01385   return GetMarginWidthFor(NS_SIDE_RIGHT, aFrame, aValue);
01386 }
01387 
01388 nsresult
01389 nsComputedDOMStyle::GetMarkerOffset(nsIFrame *aFrame,
01390                                     nsIDOMCSSValue** aValue)
01391 {
01392   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01393   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01394 
01395   const nsStyleContent* content = nsnull;
01396   GetStyleData(eStyleStruct_Content, (const nsStyleStruct*&)content, aFrame);
01397 
01398   if (content) {
01399     switch (content->mMarkerOffset.GetUnit()) {
01400       case eStyleUnit_Coord:
01401         val->SetTwips(content->mMarkerOffset.GetCoordValue());
01402         break;
01403       case eStyleUnit_Auto:
01404         val->SetIdent(nsLayoutAtoms::autoAtom);
01405         break;
01406       case eStyleUnit_Null:
01407         val->SetIdent(nsLayoutAtoms::none);
01408         break;
01409       default:
01410         NS_ERROR("Unexpected marker offset unit");
01411         val->SetTwips(0);
01412         break;
01413     }
01414   }
01415 
01416   return CallQueryInterface(val, aValue);
01417 }
01418 
01419 nsresult
01420 nsComputedDOMStyle::GetOutline(nsIFrame *aFrame,
01421                                nsIDOMCSSValue** aValue)
01422 {
01423   // return null per spec.
01424   aValue = nsnull;
01425 
01426   return NS_OK;
01427 }
01428 
01429 nsresult
01430 nsComputedDOMStyle::GetOutlineWidth(nsIFrame *aFrame,
01431                                     nsIDOMCSSValue** aValue)
01432 {
01433   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01434   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01435 
01436   const nsStyleOutline* outline = nsnull;
01437   GetStyleData(eStyleStruct_Outline, (const nsStyleStruct*&)outline, aFrame);
01438 
01439   if (outline) {
01440     nsStyleCoord coord;
01441     PRUint8 outlineStyle = outline->GetOutlineStyle();
01442     if (outlineStyle == NS_STYLE_BORDER_STYLE_NONE) {
01443       coord.SetCoordValue(0);
01444     } else {
01445       coord = outline->mOutlineWidth;
01446     }
01447     switch (coord.GetUnit()) {
01448       case eStyleUnit_Coord:
01449         val->SetTwips(coord.GetCoordValue());
01450         break;
01451       case eStyleUnit_Enumerated:
01452         {
01453           const nsAFlatCString& width =
01454             nsCSSProps::ValueToKeyword(coord.GetIntValue(),
01455                                        nsCSSProps::kBorderWidthKTable);
01456           val->SetIdent(width);
01457           break;
01458         }
01459       case eStyleUnit_Chars:
01460         // XXX we need a frame and a rendering context to calculate this, bug 281972, bug 282126.
01461         val->SetTwips(0);
01462         break;
01463       default:
01464         NS_ERROR("Unexpected outline width unit");
01465         val->SetTwips(0);
01466         break;
01467     }
01468   }
01469 
01470   return CallQueryInterface(val, aValue);
01471 }
01472 
01473 nsresult
01474 nsComputedDOMStyle::GetOutlineStyle(nsIFrame *aFrame,
01475                                     nsIDOMCSSValue** aValue)
01476 {
01477   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01478   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01479 
01480   const nsStyleOutline* outline = nsnull;
01481   GetStyleData(eStyleStruct_Outline, (const nsStyleStruct*&)outline, aFrame);
01482 
01483   if (outline) {
01484     PRUint8 outlineStyle = outline->GetOutlineStyle();
01485     switch (outlineStyle) {
01486       case NS_STYLE_BORDER_STYLE_NONE:
01487         val->SetIdent(nsLayoutAtoms::none);
01488         break;
01489       case NS_STYLE_BORDER_STYLE_AUTO:
01490         val->SetIdent(nsLayoutAtoms::autoAtom);
01491         break;
01492       default:
01493         const nsAFlatCString& style =
01494           nsCSSProps::ValueToKeyword(outlineStyle,
01495                                      nsCSSProps::kOutlineStyleKTable);
01496         val->SetIdent(style);
01497     }
01498   }
01499 
01500   return CallQueryInterface(val, aValue);
01501 }
01502 
01503 nsresult
01504 nsComputedDOMStyle::GetOutlineOffset(nsIFrame *aFrame,
01505                                      nsIDOMCSSValue** aValue)
01506 {
01507   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01508   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01509 
01510   const nsStyleOutline* outline = nsnull;
01511   GetStyleData(eStyleStruct_Outline, (const nsStyleStruct*&)outline, aFrame);
01512 
01513   if (outline) {
01514     switch (outline->mOutlineOffset.GetUnit()) {
01515       case eStyleUnit_Coord:
01516         val->SetTwips(outline->mOutlineOffset.GetCoordValue());
01517         break;
01518       case eStyleUnit_Chars:
01519         // XXX we need a frame and a rendering context to calculate this, bug 281972, bug 282126.
01520         val->SetTwips(0);
01521         break;
01522       default:
01523         NS_ERROR("Unexpected outline offset unit");
01524         val->SetTwips(0);
01525         break;
01526     }
01527   }
01528 
01529   return CallQueryInterface(val, aValue);
01530 }
01531 
01532 nsresult
01533 nsComputedDOMStyle::GetOutlineRadiusBottomLeft(nsIFrame *aFrame,
01534                                               nsIDOMCSSValue** aValue)
01535 {
01536   return GetOutlineRadiusFor(NS_SIDE_LEFT, aFrame, aValue);
01537 }
01538 
01539 nsresult
01540 nsComputedDOMStyle::GetOutlineRadiusBottomRight(nsIFrame *aFrame,
01541                                                nsIDOMCSSValue** aValue)
01542 {
01543   return GetOutlineRadiusFor(NS_SIDE_BOTTOM, aFrame, aValue);
01544 }
01545 
01546 nsresult
01547 nsComputedDOMStyle::GetOutlineRadiusTopLeft(nsIFrame *aFrame,
01548                                            nsIDOMCSSValue** aValue)
01549 {
01550   return GetOutlineRadiusFor(NS_SIDE_TOP, aFrame, aValue);
01551 }
01552 
01553 nsresult
01554 nsComputedDOMStyle::GetOutlineRadiusTopRight(nsIFrame *aFrame,
01555                                             nsIDOMCSSValue** aValue)
01556 {
01557   return GetOutlineRadiusFor(NS_SIDE_RIGHT, aFrame, aValue);
01558 }
01559 
01560 nsresult
01561 nsComputedDOMStyle::GetOutlineColor(nsIFrame *aFrame,
01562                                     nsIDOMCSSValue** aValue)
01563 {
01564   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01565   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01566 
01567   const nsStyleOutline* outline = nsnull;
01568   GetStyleData(eStyleStruct_Outline, (const nsStyleStruct*&)outline, aFrame);
01569 
01570   if (outline) {
01571     nscolor color;
01572     outline->GetOutlineColor(color);
01573 
01574     nsDOMCSSRGBColor *rgb = nsnull;
01575     rgb = GetDOMCSSRGBColor(color);
01576     if (!rgb) {
01577       delete val;
01578 
01579       return NS_ERROR_OUT_OF_MEMORY;
01580     }
01581 
01582     val->SetColor(rgb);
01583   }
01584 
01585   return CallQueryInterface(val, aValue);
01586 }
01587 
01588 nsresult
01589 nsComputedDOMStyle::GetOutlineRadiusFor(PRUint8 aSide, nsIFrame *aFrame,
01590                                         nsIDOMCSSValue** aValue)
01591 {
01592   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01593   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01594 
01595   const nsStyleOutline *outline = nsnull;
01596   GetStyleData(eStyleStruct_Outline, (const nsStyleStruct*&)outline, aFrame);
01597 
01598   if (outline) {
01599     nsStyleCoord coord;
01600     outline->mOutlineRadius.Get(aSide, coord);
01601 
01602     switch (coord.GetUnit()) {
01603       case eStyleUnit_Coord:
01604         val->SetTwips(coord.GetCoordValue());
01605         break;
01606       case eStyleUnit_Percent:
01607         if (aFrame) {
01608           val->SetTwips(coord.GetPercentValue() * aFrame->GetSize().width);
01609         } else {
01610           val->SetPercent(coord.GetPercentValue());
01611         }
01612         break;
01613       default:
01614         NS_ERROR("Unexpected outline radius unit");
01615         break;
01616     }
01617   } else {
01618     val->SetTwips(0);
01619   }
01620 
01621   return CallQueryInterface(val, aValue);
01622 }
01623 
01624 nsresult
01625 nsComputedDOMStyle::GetZIndex(nsIFrame *aFrame,
01626                               nsIDOMCSSValue** aValue)
01627 {
01628   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01629   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01630 
01631   const nsStylePosition* position = nsnull;
01632 
01633   GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position, aFrame);
01634   if (position) {
01635     switch (position->mZIndex.GetUnit()) {
01636       case eStyleUnit_Integer:
01637         val->SetNumber(position->mZIndex.GetIntValue());
01638         break;
01639       default:
01640         NS_ERROR("Unexpected z-index unit");
01641         // fall through
01642       case eStyleUnit_Auto:
01643         val->SetIdent(nsLayoutAtoms::autoAtom);
01644         break;
01645     }
01646   }
01647     
01648   return CallQueryInterface(val, aValue);
01649 }
01650 
01651 nsresult
01652 nsComputedDOMStyle::GetListStyleImage(nsIFrame *aFrame,
01653                                       nsIDOMCSSValue** aValue)
01654 {
01655   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01656   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01657 
01658   const nsStyleList* list = nsnull;
01659   GetStyleData(eStyleStruct_List, (const nsStyleStruct*&)list, aFrame);
01660 
01661   if (list) {
01662     if (!list->mListStyleImage) {
01663       val->SetIdent(nsLayoutAtoms::none);
01664     } else {
01665       nsCOMPtr<nsIURI> uri;
01666       if (list->mListStyleImage) {
01667         list->mListStyleImage->GetURI(getter_AddRefs(uri));
01668       }
01669       val->SetURI(uri);
01670     }
01671   }
01672     
01673   return CallQueryInterface(val, aValue);
01674 }
01675 
01676 nsresult
01677 nsComputedDOMStyle::GetListStylePosition(nsIFrame *aFrame,
01678                                          nsIDOMCSSValue** aValue)
01679 {
01680   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01681   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01682 
01683   const nsStyleList *list = nsnull;
01684   GetStyleData(eStyleStruct_List, (const nsStyleStruct*&)list, aFrame);
01685 
01686   if (list) {
01687     const nsAFlatCString& style =
01688       nsCSSProps::ValueToKeyword(list->mListStylePosition,
01689                                  nsCSSProps::kListStylePositionKTable);
01690     val->SetIdent(style);
01691   }
01692 
01693   return CallQueryInterface(val, aValue);
01694 }
01695 
01696 nsresult
01697 nsComputedDOMStyle::GetListStyleType(nsIFrame *aFrame,
01698                                      nsIDOMCSSValue** aValue)
01699 {
01700   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01701   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01702 
01703   const nsStyleList *list = nsnull;
01704   GetStyleData(eStyleStruct_List, (const nsStyleStruct*&)list, aFrame);
01705 
01706   if (list) {
01707     if (list->mListStyleType == NS_STYLE_LIST_STYLE_NONE) {
01708       val->SetIdent(nsLayoutAtoms::none);
01709     } else {
01710       const nsAFlatCString& style =
01711         nsCSSProps::ValueToKeyword(list->mListStyleType,
01712                                    nsCSSProps::kListStyleKTable);
01713       val->SetIdent(style);
01714     }
01715   }
01716 
01717   return CallQueryInterface(val, aValue);
01718 }
01719 
01720 nsresult
01721 nsComputedDOMStyle::GetImageRegion(nsIFrame *aFrame,
01722                                    nsIDOMCSSValue** aValue)
01723 {
01724   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01725   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01726 
01727   const nsStyleList* list = nsnull;
01728 
01729   GetStyleData(eStyleStruct_List, (const nsStyleStruct*&)list, aFrame);
01730 
01731   nsresult rv = NS_OK;
01732   nsROCSSPrimitiveValue *topVal = nsnull;
01733   nsROCSSPrimitiveValue *rightVal = nsnull;
01734   nsROCSSPrimitiveValue *bottomVal = nsnull;
01735   nsROCSSPrimitiveValue *leftVal = nsnull;
01736   if (list) {
01737     if (list->mImageRegion.width <= 0 || list->mImageRegion.height <= 0) {
01738       val->SetIdent(nsLayoutAtoms::autoAtom);
01739     } else {
01740       // create the cssvalues for the sides, stick them in the rect object
01741       topVal = GetROCSSPrimitiveValue();
01742       rightVal = GetROCSSPrimitiveValue();
01743       bottomVal = GetROCSSPrimitiveValue();
01744       leftVal = GetROCSSPrimitiveValue();
01745       if (topVal && rightVal && bottomVal && leftVal) {
01746         nsDOMCSSRect * domRect = new nsDOMCSSRect(topVal, rightVal,
01747                                                   bottomVal, leftVal);
01748         if (domRect) {
01749           topVal->SetTwips(list->mImageRegion.y);
01750           rightVal->SetTwips(list->mImageRegion.width + list->mImageRegion.x);
01751           bottomVal->SetTwips(list->mImageRegion.height + list->mImageRegion.y);
01752           leftVal->SetTwips(list->mImageRegion.x);
01753           val->SetRect(domRect);
01754         } else {
01755           rv = NS_ERROR_OUT_OF_MEMORY;
01756         }
01757       } else {
01758         rv = NS_ERROR_OUT_OF_MEMORY;
01759       }
01760     }
01761   }
01762 
01763   if (NS_FAILED(rv)) {
01764     delete topVal;
01765     delete rightVal;
01766     delete bottomVal;
01767     delete leftVal;
01768     delete val;
01769 
01770     return rv;
01771   }
01772   
01773   return CallQueryInterface(val, aValue);
01774 }
01775 
01776 nsresult
01777 nsComputedDOMStyle::GetLineHeight(nsIFrame *aFrame,
01778                                   nsIDOMCSSValue** aValue)
01779 {
01780   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01781   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01782 
01783   const nsStyleText *text = nsnull;
01784   GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)text, aFrame);
01785 
01786   nscoord lineHeight;
01787   nsresult rv = GetLineHeightCoord(aFrame, text, lineHeight);
01788 
01789   if (NS_SUCCEEDED(rv)) {
01790     val->SetTwips(lineHeight);
01791   } else if (text) {
01792     switch (text->mLineHeight.GetUnit()) {
01793       case eStyleUnit_Percent:
01794         val->SetPercent(text->mLineHeight.GetPercentValue());
01795         break;
01796       case eStyleUnit_Factor:
01797         val->SetNumber(text->mLineHeight.GetFactorValue());
01798         break;
01799       default:
01800         NS_ERROR("Unexpected line-height unit");
01801         val->SetIdent(nsLayoutAtoms::normal);
01802         break;
01803     }
01804   }
01805 
01806   return CallQueryInterface(val, aValue);
01807 }
01808 
01809 nsresult
01810 nsComputedDOMStyle::GetVerticalAlign(nsIFrame *aFrame,
01811                                      nsIDOMCSSValue** aValue)
01812 {
01813   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01814   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01815 
01816   const nsStyleTextReset *text = nsnull;
01817   GetStyleData(eStyleStruct_TextReset, (const nsStyleStruct*&)text, aFrame);
01818 
01819   if (text) {
01820     switch (text->mVerticalAlign.GetUnit()) {
01821       case eStyleUnit_Coord:
01822         val->SetTwips(text->mVerticalAlign.GetCoordValue());
01823         break;
01824       case eStyleUnit_Enumerated:
01825         {
01826           const nsAFlatCString& align =
01827             nsCSSProps::ValueToKeyword(text->mVerticalAlign.GetIntValue(),
01828                                        nsCSSProps::kVerticalAlignKTable);
01829           val->SetIdent(align);
01830           break;
01831         }
01832       case eStyleUnit_Percent:
01833         {
01834           const nsStyleText *textData = nsnull;
01835           GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)textData,
01836                        aFrame);
01837 
01838           nscoord lineHeight = 0;
01839           nsresult rv = GetLineHeightCoord(aFrame, textData, lineHeight);
01840 
01841           if (NS_SUCCEEDED(rv)) {
01842             val->SetTwips(lineHeight * text->mVerticalAlign.GetPercentValue());
01843           } else {
01844             val->SetPercent(text->mVerticalAlign.GetPercentValue());
01845           }
01846 
01847           break;
01848         }
01849       default:
01850         NS_ERROR("double check the vertical-align");
01851         break;
01852     }
01853   }
01854 
01855   return CallQueryInterface(val, aValue);
01856 }
01857 
01858 nsresult
01859 nsComputedDOMStyle::GetTextAlign(nsIFrame *aFrame,
01860                                  nsIDOMCSSValue** aValue)
01861 {
01862   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01863   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01864 
01865   const nsStyleText* text = nsnull;
01866   GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)text, aFrame);
01867 
01868   if (text) {
01869     const nsAFlatCString& align=
01870       nsCSSProps::ValueToKeyword(text->mTextAlign,
01871                                  nsCSSProps::kTextAlignKTable);
01872     val->SetIdent(align);
01873   }
01874 
01875   return CallQueryInterface(val, aValue);
01876 }
01877 
01878 nsresult
01879 nsComputedDOMStyle::GetTextDecoration(nsIFrame *aFrame,
01880                                       nsIDOMCSSValue** aValue)
01881 {
01882   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
01883   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01884 
01885   const nsStyleTextReset* text = nsnull;
01886   GetStyleData(eStyleStruct_TextReset, (const nsStyleStruct*&)text, aFrame);
01887 
01888   if (text) {
01889     if (NS_STYLE_TEXT_DECORATION_NONE == text->mTextDecoration) {
01890       const nsAFlatCString& decoration=
01891         nsCSSKeywords::GetStringValue(eCSSKeyword_none);
01892       val->SetIdent(decoration);
01893     } else {
01894       nsAutoString decorationString;
01895       if (text->mTextDecoration & NS_STYLE_TEXT_DECORATION_UNDERLINE) {
01896         const nsAFlatCString& decoration=
01897           nsCSSProps::ValueToKeyword(NS_STYLE_TEXT_DECORATION_UNDERLINE,
01898                                      nsCSSProps::kTextDecorationKTable);
01899         decorationString.AppendWithConversion(decoration.get());
01900       }
01901       if (text->mTextDecoration & NS_STYLE_TEXT_DECORATION_OVERLINE) {
01902         if (!decorationString.IsEmpty()) {
01903           decorationString.Append(PRUnichar(' '));
01904         }
01905         const nsAFlatCString& decoration=
01906           nsCSSProps::ValueToKeyword(NS_STYLE_TEXT_DECORATION_OVERLINE,
01907                                      nsCSSProps::kTextDecorationKTable);
01908         decorationString.AppendWithConversion(decoration.get());
01909       }
01910       if (text->mTextDecoration & NS_STYLE_TEXT_DECORATION_LINE_THROUGH) {
01911         if (!decorationString.IsEmpty()) {
01912           decorationString.Append(PRUnichar(' '));
01913         }
01914         const nsAFlatCString& decoration=
01915           nsCSSProps::ValueToKeyword(NS_STYLE_TEXT_DECORATION_LINE_THROUGH,
01916                                      nsCSSProps::kTextDecorationKTable);
01917         decorationString.AppendWithConversion(decoration.get());
01918       }
01919       if (text->mTextDecoration & NS_STYLE_TEXT_DECORATION_BLINK) {
01920         if (!decorationString.IsEmpty()) {
01921           decorationString.Append(PRUnichar(' '));
01922         }
01923         const nsAFlatCString& decoration=
01924           nsCSSProps::ValueToKeyword(NS_STYLE_TEXT_DECORATION_BLINK,
01925                                      nsCSSProps::kTextDecorationKTable);
01926         decorationString.AppendWithConversion(decoration.get());
01927       }
01928       val->SetString(decorationString);
01929     }
01930   }
01931 
01932   return CallQueryInterface(val, aValue);
01933 }
01934 
01935 nsresult
01936 nsComputedDOMStyle::GetTextIndent(nsIFrame *aFrame,
01937                                   nsIDOMCSSValue** aValue)
01938 {
01939   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01940   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01941 
01942   const nsStyleText *text = nsnull;
01943   GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)text, aFrame);
01944 
01945   FlushPendingReflows();
01946 
01947   if (text) {
01948     switch (text->mTextIndent.GetUnit()) {
01949       case eStyleUnit_Coord:
01950         val->SetTwips(text->mTextIndent.GetCoordValue());
01951         break;
01952       case eStyleUnit_Percent:
01953         {
01954           nsIFrame *container = GetContainingBlockFor(aFrame);
01955           if (container) {
01956             val->SetTwips(container->GetSize().width *
01957                           text->mTextIndent.GetPercentValue());
01958           } else {
01959             // no containing block
01960             val->SetPercent(text->mTextIndent.GetPercentValue());
01961           }
01962           break;
01963         }
01964       default:
01965         val->SetTwips(0);
01966         break;
01967     }
01968   }
01969 
01970   return CallQueryInterface(val, aValue);
01971 }
01972 
01973 nsresult
01974 nsComputedDOMStyle::GetTextTransform(nsIFrame *aFrame,
01975                                      nsIDOMCSSValue** aValue)
01976 {
01977   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
01978   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
01979 
01980   const nsStyleText *text = nsnull;
01981   GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)text, aFrame);
01982 
01983   if (text && text->mTextTransform != NS_STYLE_TEXT_TRANSFORM_NONE) {
01984     const nsAFlatCString& textTransform =
01985       nsCSSProps::ValueToKeyword(text->mTextTransform,
01986                                  nsCSSProps::kTextTransformKTable);
01987     val->SetIdent(textTransform);
01988   } else {
01989     val->SetIdent(nsLayoutAtoms::none);
01990   }
01991 
01992   return CallQueryInterface(val, aValue);
01993 }
01994 
01995 nsresult
01996 nsComputedDOMStyle::GetLetterSpacing(nsIFrame *aFrame,
01997                                      nsIDOMCSSValue** aValue)
01998 {
01999   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02000   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02001 
02002   const nsStyleText *text = nsnull;
02003   GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)text, aFrame);
02004 
02005   if (text && text->mLetterSpacing.GetUnit() == eStyleUnit_Coord) {
02006     val->SetTwips(text->mLetterSpacing.GetCoordValue());
02007   } else {
02008     val->SetIdent(nsLayoutAtoms::normal);
02009   }
02010 
02011   return CallQueryInterface(val, aValue);
02012 }
02013 
02014 nsresult
02015 nsComputedDOMStyle::GetWordSpacing(nsIFrame *aFrame,
02016                                    nsIDOMCSSValue** aValue)
02017 {
02018   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02019   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02020 
02021   const nsStyleText *text = nsnull;
02022   GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)text, aFrame);
02023 
02024   if (text && text->mWordSpacing.GetUnit() == eStyleUnit_Coord) {
02025     val->SetTwips(text->mWordSpacing.GetCoordValue());
02026   } else {
02027     val->SetIdent(nsLayoutAtoms::normal);
02028   }
02029 
02030   return CallQueryInterface(val, aValue);
02031 }
02032 
02033 nsresult
02034 nsComputedDOMStyle::GetWhiteSpace(nsIFrame *aFrame,
02035                                   nsIDOMCSSValue** aValue)
02036 {
02037   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02038   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02039 
02040   const nsStyleText *text = nsnull;
02041   GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)text, aFrame);
02042 
02043   if (text && text->mWhiteSpace != NS_STYLE_WHITESPACE_NORMAL) {
02044     const nsAFlatCString& whiteSpace =
02045       nsCSSProps::ValueToKeyword(text->mWhiteSpace,
02046                                  nsCSSProps::kWhitespaceKTable);
02047     val->SetIdent(whiteSpace);
02048   } else {
02049     val->SetIdent(nsLayoutAtoms::normal);
02050   }
02051 
02052   return CallQueryInterface(val, aValue);
02053 }
02054 
02055 nsresult
02056 nsComputedDOMStyle::GetVisibility(nsIFrame *aFrame,
02057                                   nsIDOMCSSValue** aValue)
02058 {
02059   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
02060   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02061 
02062   const nsStyleVisibility* visibility = nsnull;
02063   GetStyleData(eStyleStruct_Visibility, (const nsStyleStruct*&)visibility,
02064                aFrame);
02065 
02066   if (visibility) {
02067     const nsAFlatCString& value=
02068       nsCSSProps::ValueToKeyword(visibility->mVisible,
02069                                  nsCSSProps::kVisibilityKTable);
02070     val->SetIdent(value);
02071   }
02072 
02073   return CallQueryInterface(val, aValue);
02074 }
02075 
02076 nsresult
02077 nsComputedDOMStyle::GetDirection(nsIFrame *aFrame,
02078                                  nsIDOMCSSValue** aValue)
02079 {
02080   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02081   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02082 
02083   const nsStyleVisibility *visibility = nsnull;
02084   GetStyleData(eStyleStruct_Visibility, (const nsStyleStruct*&)visibility,
02085                aFrame);
02086 
02087   if (visibility) {
02088     const nsAFlatCString & direction =
02089       nsCSSProps::ValueToKeyword(visibility->mDirection,
02090                                  nsCSSProps::kDirectionKTable);
02091     val->SetIdent(direction);
02092   }
02093 
02094   return CallQueryInterface(val, aValue);
02095 }
02096 
02097 nsresult
02098 nsComputedDOMStyle::GetUnicodeBidi(nsIFrame *aFrame,
02099                                    nsIDOMCSSValue** aValue)
02100 {
02101   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02102   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02103 
02104   const nsStyleTextReset *text = nsnull;
02105   GetStyleData(eStyleStruct_TextReset, (const nsStyleStruct*&)text, aFrame);
02106 
02107   if (text && text->mUnicodeBidi != NS_STYLE_UNICODE_BIDI_NORMAL) {
02108     const nsAFlatCString& bidi =
02109       nsCSSProps::ValueToKeyword(text->mUnicodeBidi,
02110                                  nsCSSProps::kUnicodeBidiKTable);
02111     val->SetIdent(bidi);
02112   } else {
02113     val->SetIdent(nsLayoutAtoms::normal);
02114   }
02115 
02116   return CallQueryInterface(val, aValue);
02117 }
02118 
02119 nsresult
02120 nsComputedDOMStyle::GetCursor(nsIFrame *aFrame,
02121                               nsIDOMCSSValue** aValue)
02122 {
02123   nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE);
02124   NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
02125 
02126   const nsStyleUserInterface *ui = nsnull;
02127   GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)ui, aFrame);
02128 
02129   if (ui) {
02130     for (nsCursorImage *item = ui->mCursorArray,
02131                    *item_end = ui->mCursorArray + ui->mCursorArrayLength;
02132          item < item_end; ++item) {
02133       nsDOMCSSValueList *itemList = GetROCSSValueList(PR_FALSE);
02134       if (!itemList || !valueList->AppendCSSValue(itemList)) {
02135         delete itemList;
02136         delete valueList;
02137         return NS_ERROR_OUT_OF_MEMORY;
02138       }
02139 
02140       nsCOMPtr<nsIURI> uri;
02141       item->mImage->GetURI(getter_AddRefs(uri));
02142 
02143       nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02144       if (!val || !itemList->AppendCSSValue(val)) {
02145         delete val;
02146         delete valueList;
02147         return NS_ERROR_OUT_OF_MEMORY;
02148       }
02149       val->SetURI(uri);
02150 
02151       if (item->mHaveHotspot) {
02152         nsROCSSPrimitiveValue *valX = GetROCSSPrimitiveValue();
02153         if (!valX || !itemList->AppendCSSValue(valX)) {
02154           delete valX;
02155           delete valueList;
02156           return NS_ERROR_OUT_OF_MEMORY;
02157         }
02158         nsROCSSPrimitiveValue *valY = GetROCSSPrimitiveValue();
02159         if (!valY || !itemList->AppendCSSValue(valY)) {
02160           delete valY;
02161           delete valueList;
02162           return NS_ERROR_OUT_OF_MEMORY;
02163         }
02164 
02165         valX->SetNumber(item->mHotspotX);
02166         valY->SetNumber(item->mHotspotY);
02167       }
02168     }
02169 
02170     nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02171     if (!val) {
02172       delete valueList;
02173       return NS_ERROR_OUT_OF_MEMORY;
02174     }
02175 
02176     if (ui->mCursor == NS_STYLE_CURSOR_AUTO) {
02177       val->SetIdent(nsLayoutAtoms::autoAtom);
02178     } else {
02179       const nsAFlatCString& cursor =
02180         nsCSSProps::ValueToKeyword(ui->mCursor,
02181                                    nsCSSProps::kCursorKTable);
02182       val->SetIdent(cursor);
02183     }
02184     if (!valueList->AppendCSSValue(val)) {
02185       delete valueList;
02186       delete val;
02187       return NS_ERROR_OUT_OF_MEMORY;
02188     }
02189   }
02190 
02191   return CallQueryInterface(valueList, aValue);
02192 }
02193 
02194 nsresult
02195 nsComputedDOMStyle::GetAppearance(nsIFrame *aFrame,
02196                                   nsIDOMCSSValue** aValue)
02197 {
02198   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02199   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02200 
02201   const nsStyleDisplay *displayData = nsnull;
02202   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)displayData,
02203                aFrame);
02204 
02205   PRUint8 appearance = NS_THEME_NONE;
02206   if (displayData) {
02207     appearance = displayData->mAppearance;
02208   }
02209 
02210   const nsAFlatCString& appearanceIdent =
02211     nsCSSProps::ValueToKeyword(appearance,
02212                                nsCSSProps::kAppearanceKTable);
02213   val->SetIdent(appearanceIdent);
02214 
02215   return CallQueryInterface(val, aValue);
02216 }
02217 
02218 
02219 nsresult
02220 nsComputedDOMStyle::GetBoxAlign(nsIFrame *aFrame,
02221                                 nsIDOMCSSValue** aValue)
02222 {
02223   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02224   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02225 
02226   const nsStyleXUL *xul = nsnull;
02227   GetStyleData(eStyleStruct_XUL, (const nsStyleStruct*&)xul, aFrame);
02228 
02229   PRUint8 boxAlign = NS_STYLE_BOX_ALIGN_STRETCH;
02230   if (xul) {
02231     boxAlign = xul->mBoxAlign;
02232   }
02233 
02234   const nsAFlatCString& boxAlignIdent =
02235     nsCSSProps::ValueToKeyword(boxAlign,
02236                                nsCSSProps::kBoxAlignKTable);
02237   val->SetIdent(boxAlignIdent);
02238 
02239   return CallQueryInterface(val, aValue);
02240 }
02241 
02242 nsresult
02243 nsComputedDOMStyle::GetBoxDirection(nsIFrame *aFrame,
02244                                     nsIDOMCSSValue** aValue)
02245 {
02246   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02247   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02248 
02249   const nsStyleXUL *xul = nsnull;
02250   GetStyleData(eStyleStruct_XUL, (const nsStyleStruct*&)xul, aFrame);
02251 
02252   PRUint8 boxDirection = NS_STYLE_BOX_DIRECTION_NORMAL;
02253   if (xul) {
02254     boxDirection = xul->mBoxDirection;
02255   }
02256 
02257   const nsAFlatCString& boxDirectionIdent =
02258     nsCSSProps::ValueToKeyword(boxDirection,
02259                                nsCSSProps::kBoxDirectionKTable);
02260   val->SetIdent(boxDirectionIdent);
02261 
02262   return CallQueryInterface(val, aValue);
02263 }
02264 
02265 nsresult
02266 nsComputedDOMStyle::GetBoxFlex(nsIFrame *aFrame,
02267                                nsIDOMCSSValue** aValue)
02268 {
02269   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02270   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02271 
02272   const nsStyleXUL *xul = nsnull;
02273   GetStyleData(eStyleStruct_XUL, (const nsStyleStruct*&)xul, aFrame);
02274 
02275   float boxFlex = 0.0f;
02276   if (xul) {
02277     boxFlex = xul->mBoxFlex;
02278   }
02279 
02280   val->SetNumber(boxFlex);
02281 
02282   return CallQueryInterface(val, aValue);
02283 }
02284 
02285 nsresult
02286 nsComputedDOMStyle::GetBoxOrdinalGroup(nsIFrame *aFrame,
02287                                        nsIDOMCSSValue** aValue)
02288 {
02289   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02290   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02291 
02292   const nsStyleXUL *xul = nsnull;
02293   GetStyleData(eStyleStruct_XUL, (const nsStyleStruct*&)xul, aFrame);
02294 
02295   PRUint32 boxOrdinalGroup = 1;
02296   if (xul) {
02297     boxOrdinalGroup = xul->mBoxOrdinal;
02298   }
02299 
02300   val->SetNumber(boxOrdinalGroup);
02301 
02302   return CallQueryInterface(val, aValue);
02303 }
02304 
02305 nsresult
02306 nsComputedDOMStyle::GetBoxOrient(nsIFrame *aFrame,
02307                                  nsIDOMCSSValue** aValue)
02308 {
02309   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02310   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02311 
02312   const nsStyleXUL *xul = nsnull;
02313   GetStyleData(eStyleStruct_XUL, (const nsStyleStruct*&)xul, aFrame);
02314 
02315   PRUint8 boxOrient = NS_STYLE_BOX_ORIENT_HORIZONTAL;
02316   if (xul) {
02317     boxOrient = xul->mBoxOrient;
02318   }
02319 
02320   const nsAFlatCString& boxOrientIdent =
02321     nsCSSProps::ValueToKeyword(boxOrient,
02322                                nsCSSProps::kBoxOrientKTable);
02323   val->SetIdent(boxOrientIdent);
02324 
02325   return CallQueryInterface(val, aValue);
02326 }
02327 
02328 nsresult
02329 nsComputedDOMStyle::GetBoxPack(nsIFrame *aFrame,
02330                                nsIDOMCSSValue** aValue)
02331 {
02332   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02333   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02334 
02335   const nsStyleXUL *xul = nsnull;
02336   GetStyleData(eStyleStruct_XUL, (const nsStyleStruct*&)xul, aFrame);
02337 
02338   PRUint8 boxPack = NS_STYLE_BOX_PACK_START;
02339   if (xul) {
02340     boxPack = xul->mBoxPack;
02341   }
02342 
02343   const nsAFlatCString& boxPackIdent =
02344     nsCSSProps::ValueToKeyword(boxPack,
02345                                nsCSSProps::kBoxPackKTable);
02346   val->SetIdent(boxPackIdent);
02347 
02348   return CallQueryInterface(val, aValue);
02349 }
02350 
02351 nsresult
02352 nsComputedDOMStyle::GetBoxSizing(nsIFrame *aFrame,
02353                                  nsIDOMCSSValue** aValue)
02354 {
02355   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02356   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02357 
02358   const nsStylePosition *positionData = nsnull;
02359   GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData,
02360                aFrame);
02361 
02362   PRUint8 boxSizing = NS_STYLE_BOX_SIZING_CONTENT;
02363   if (positionData) {
02364     boxSizing = positionData->mBoxSizing;
02365   }
02366 
02367   const nsAFlatCString& boxSizingIdent =
02368     nsCSSProps::ValueToKeyword(boxSizing,
02369                                nsCSSProps::kBoxSizingKTable);
02370   val->SetIdent(boxSizingIdent);
02371 
02372   return CallQueryInterface(val, aValue);
02373 }
02374 
02375 nsresult
02376 nsComputedDOMStyle::GetFloatEdge(nsIFrame *aFrame,
02377                                  nsIDOMCSSValue** aValue)
02378 {
02379   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02380   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02381 
02382   const nsStyleBorder *borderData = nsnull;
02383   GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData, aFrame);
02384 
02385   PRUint8 floatEdge = NS_STYLE_FLOAT_EDGE_CONTENT;
02386   if (borderData) {
02387     floatEdge = borderData->mFloatEdge;
02388   }
02389 
02390   const nsAFlatCString& floatEdgeIdent =
02391     nsCSSProps::ValueToKeyword(floatEdge,
02392                                nsCSSProps::kFloatEdgeKTable);
02393   val->SetIdent(floatEdgeIdent);
02394 
02395   return CallQueryInterface(val, aValue);
02396 }
02397 
02398 
02399 nsresult
02400 nsComputedDOMStyle::GetUserFocus(nsIFrame *aFrame,
02401                                  nsIDOMCSSValue** aValue)
02402 {
02403   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02404   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02405 
02406   const nsStyleUserInterface *uiData = nsnull;
02407   GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)uiData,
02408                aFrame);
02409 
02410   if (uiData && uiData->mUserFocus != NS_STYLE_USER_FOCUS_NONE) {
02411     if (uiData->mUserFocus == NS_STYLE_USER_FOCUS_NORMAL) {
02412       const nsAFlatCString& userFocusIdent =
02413               nsCSSKeywords::GetStringValue(eCSSKeyword_normal);
02414       val->SetIdent(userFocusIdent);
02415     } else {
02416       const nsAFlatCString& userFocusIdent =
02417         nsCSSProps::ValueToKeyword(uiData->mUserFocus,
02418                                    nsCSSProps::kUserFocusKTable);
02419       val->SetIdent(userFocusIdent);
02420     }
02421   } else {
02422     const nsAFlatCString& userFocusIdent =
02423             nsCSSKeywords::GetStringValue(eCSSKeyword_none);
02424     val->SetIdent(userFocusIdent);
02425   }
02426 
02427   return CallQueryInterface(val, aValue);
02428 }
02429 
02430 nsresult
02431 nsComputedDOMStyle::GetUserInput(nsIFrame *aFrame,
02432                                  nsIDOMCSSValue** aValue)
02433 {
02434   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02435   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02436 
02437   const nsStyleUserInterface *uiData = nsnull;
02438   GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)uiData,
02439                aFrame);
02440 
02441   if (uiData && uiData->mUserInput != NS_STYLE_USER_INPUT_AUTO) {
02442     if (uiData->mUserInput == NS_STYLE_USER_INPUT_NONE) {
02443       const nsAFlatCString& userInputIdent =
02444         nsCSSKeywords::GetStringValue(eCSSKeyword_none);
02445       val->SetIdent(userInputIdent);
02446     } else {
02447       const nsAFlatCString& userInputIdent =
02448         nsCSSProps::ValueToKeyword(uiData->mUserInput,
02449                                    nsCSSProps::kUserInputKTable);
02450       val->SetIdent(userInputIdent);
02451     }
02452   } else {
02453     const nsAFlatCString& userInputIdent =
02454             nsCSSKeywords::GetStringValue(eCSSKeyword_auto);
02455     val->SetIdent(userInputIdent);
02456   }
02457 
02458   return CallQueryInterface(val, aValue);
02459 }
02460 
02461 nsresult
02462 nsComputedDOMStyle::GetUserModify(nsIFrame *aFrame,
02463                                   nsIDOMCSSValue** aValue)
02464 {
02465   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02466   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02467 
02468   const nsStyleUserInterface *uiData = nsnull;
02469   GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)uiData,
02470                aFrame);
02471 
02472   PRUint8 userModify = NS_STYLE_USER_MODIFY_READ_ONLY;
02473   if (uiData) {
02474     userModify = uiData->mUserModify;
02475   }
02476 
02477   const nsAFlatCString& userModifyIdent =
02478     nsCSSProps::ValueToKeyword(userModify,
02479                                nsCSSProps::kUserModifyKTable);
02480   val->SetIdent(userModifyIdent);
02481 
02482   return CallQueryInterface(val, aValue);
02483 }
02484 
02485 nsresult
02486 nsComputedDOMStyle::GetUserSelect(nsIFrame *aFrame,
02487                                   nsIDOMCSSValue** aValue)
02488 {
02489   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02490   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02491 
02492   const nsStyleUIReset *uiData = nsnull;
02493   GetStyleData(eStyleStruct_UIReset, (const nsStyleStruct*&)uiData, aFrame);
02494 
02495   if (uiData && uiData->mUserSelect != NS_STYLE_USER_SELECT_AUTO) {
02496     if (uiData->mUserSelect == NS_STYLE_USER_SELECT_NONE) {
02497       const nsAFlatCString& userSelectIdent =
02498         nsCSSKeywords::GetStringValue(eCSSKeyword_none);
02499       val->SetIdent(userSelectIdent);
02500     } else {
02501       const nsAFlatCString& userSelectIdent =
02502         nsCSSProps::ValueToKeyword(uiData->mUserSelect,
02503                                    nsCSSProps::kUserSelectKTable);
02504       val->SetIdent(userSelectIdent);
02505     }
02506   } else {
02507     const nsAFlatCString& userSelectIdent =
02508             nsCSSKeywords::GetStringValue(eCSSKeyword_auto);
02509     val->SetIdent(userSelectIdent);
02510   }
02511 
02512   return CallQueryInterface(val, aValue);
02513 }
02514 
02515 nsresult
02516 nsComputedDOMStyle::GetDisplay(nsIFrame *aFrame,
02517                                nsIDOMCSSValue** aValue)
02518 {
02519   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02520   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02521 
02522   const nsStyleDisplay *displayData = nsnull;
02523   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)displayData,
02524                aFrame);
02525 
02526   if (displayData) {
02527     if (displayData->mDisplay == NS_STYLE_DISPLAY_NONE) {
02528       val->SetIdent(nsLayoutAtoms::none);
02529     } else {
02530       const nsAFlatCString& display =
02531         nsCSSProps::ValueToKeyword(displayData->mDisplay,
02532                                    nsCSSProps::kDisplayKTable);
02533       val->SetIdent(display);
02534     }
02535   }
02536 
02537   return CallQueryInterface(val, aValue);
02538 }
02539 
02540 nsresult
02541 nsComputedDOMStyle::GetPosition(nsIFrame *aFrame,
02542                                 nsIDOMCSSValue** aValue)
02543 {
02544   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02545   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02546 
02547   const nsStyleDisplay* display = nsnull;
02548 
02549   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
02550 
02551   if (display) {
02552     const nsAFlatCString& position =
02553       nsCSSProps::ValueToKeyword(display->mPosition,
02554                                  nsCSSProps::kPositionKTable);
02555     val->SetIdent(position);
02556   }
02557 
02558   return CallQueryInterface(val, aValue);
02559 }
02560 
02561 nsresult
02562 nsComputedDOMStyle::GetClip(nsIFrame *aFrame,
02563                             nsIDOMCSSValue** aValue)
02564 {
02565   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02566   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02567 
02568   const nsStyleDisplay* display = nsnull;
02569 
02570   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
02571 
02572   nsresult rv = NS_OK;
02573   nsROCSSPrimitiveValue *topVal = nsnull;
02574   nsROCSSPrimitiveValue *rightVal = nsnull;
02575   nsROCSSPrimitiveValue *bottomVal = nsnull;
02576   nsROCSSPrimitiveValue *leftVal = nsnull;
02577   if (display) {
02578     if (display->mClipFlags == NS_STYLE_CLIP_AUTO ||
02579         display->mClipFlags == (NS_STYLE_CLIP_TOP_AUTO |
02580                                 NS_STYLE_CLIP_RIGHT_AUTO |
02581                                 NS_STYLE_CLIP_BOTTOM_AUTO |
02582                                 NS_STYLE_CLIP_LEFT_AUTO)) {
02583       val->SetIdent(nsLayoutAtoms::autoAtom);
02584     } else {
02585       // create the cssvalues for the sides, stick them in the rect object
02586       topVal = GetROCSSPrimitiveValue();
02587       rightVal = GetROCSSPrimitiveValue();
02588       bottomVal = GetROCSSPrimitiveValue();
02589       leftVal = GetROCSSPrimitiveValue();
02590       if (topVal && rightVal && bottomVal && leftVal) {
02591         nsDOMCSSRect * domRect = new nsDOMCSSRect(topVal, rightVal,
02592                                                   bottomVal, leftVal);
02593         if (domRect) {
02594           if (display->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) {
02595             topVal->SetIdent(nsLayoutAtoms::autoAtom);
02596           } else {
02597             topVal->SetTwips(display->mClip.y);
02598           }
02599         
02600           if (display->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) {
02601             rightVal->SetIdent(nsLayoutAtoms::autoAtom);
02602           } else {
02603             rightVal->SetTwips(display->mClip.width + display->mClip.x);
02604           }
02605         
02606           if (display->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) {
02607             bottomVal->SetIdent(nsLayoutAtoms::autoAtom);
02608           } else {
02609             bottomVal->SetTwips(display->mClip.height + display->mClip.y);
02610           }
02611           
02612           if (display->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) {
02613             leftVal->SetIdent(nsLayoutAtoms::autoAtom);
02614           } else {
02615             leftVal->SetTwips(display->mClip.x);
02616           }
02617 
02618           val->SetRect(domRect);
02619         } else {
02620           rv = NS_ERROR_OUT_OF_MEMORY;
02621         }
02622       } else {
02623         rv = NS_ERROR_OUT_OF_MEMORY;
02624       }
02625     }
02626   }
02627 
02628   if (NS_FAILED(rv)) {
02629     delete topVal;
02630     delete rightVal;
02631     delete bottomVal;
02632     delete leftVal;
02633     delete val;
02634 
02635     return rv;
02636   }
02637   
02638   return CallQueryInterface(val, aValue);
02639 }
02640 
02641 nsresult
02642 nsComputedDOMStyle::GetOverflow(nsIFrame *aFrame,
02643                                 nsIDOMCSSValue** aValue)
02644 {
02645   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
02646   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02647 
02648   const nsStyleDisplay* display = nsnull;
02649   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
02650 
02651   if (display && display->mOverflowX == display->mOverflowY) {
02652     if (display->mOverflowX != NS_STYLE_OVERFLOW_AUTO) {
02653       const nsAFlatCString& overflow =
02654         nsCSSProps::ValueToKeyword(display->mOverflowX,
02655                                    nsCSSProps::kOverflowKTable);
02656       val->SetIdent(overflow);
02657     } else {
02658       val->SetIdent(nsLayoutAtoms::autoAtom);
02659     }
02660   } // XXX else what?
02661 
02662   return CallQueryInterface(val, aValue);
02663 }
02664 
02665 nsresult
02666 nsComputedDOMStyle::GetOverflowX(nsIFrame *aFrame,
02667                                  nsIDOMCSSValue** aValue)
02668 {
02669   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
02670   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02671 
02672   const nsStyleDisplay* display = nsnull;
02673   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
02674 
02675   if (display && display->mOverflowX != NS_STYLE_OVERFLOW_AUTO) {
02676     const nsAFlatCString& overflow =
02677       nsCSSProps::ValueToKeyword(display->mOverflowX,
02678                                  nsCSSProps::kOverflowSubKTable);
02679     val->SetIdent(overflow);
02680   } else {
02681     val->SetIdent(nsLayoutAtoms::autoAtom);
02682   }
02683 
02684   return CallQueryInterface(val, aValue);
02685 }
02686 
02687 nsresult
02688 nsComputedDOMStyle::GetOverflowY(nsIFrame *aFrame,
02689                                  nsIDOMCSSValue** aValue)
02690 {
02691   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
02692   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02693 
02694   const nsStyleDisplay* display = nsnull;
02695   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
02696 
02697   if (display && display->mOverflowY != NS_STYLE_OVERFLOW_AUTO) {
02698     const nsAFlatCString& overflow =
02699       nsCSSProps::ValueToKeyword(display->mOverflowY,
02700                                  nsCSSProps::kOverflowSubKTable);
02701     val->SetIdent(overflow);
02702   } else {
02703     val->SetIdent(nsLayoutAtoms::autoAtom);
02704   }
02705 
02706   return CallQueryInterface(val, aValue);
02707 }
02708 
02709 nsresult
02710 nsComputedDOMStyle::GetHeight(nsIFrame *aFrame,
02711                               nsIDOMCSSValue** aValue)
02712 {
02713   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02714   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02715 
02716   PRBool calcHeight = PR_FALSE;
02717   
02718   if (aFrame) {
02719     calcHeight = PR_TRUE;
02720 
02721     FlushPendingReflows();
02722   
02723     const nsStyleDisplay* displayData = nsnull;
02724     GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)displayData,
02725                  aFrame);
02726     if (displayData && displayData->mDisplay == NS_STYLE_DISPLAY_INLINE
02727         && !(aFrame->GetStateBits() & NS_FRAME_REPLACED_ELEMENT)) {
02728       calcHeight = PR_FALSE;
02729     }
02730   }
02731 
02732   if (calcHeight) {
02733     nsMargin padding;
02734     nsMargin border;
02735     nsSize size = aFrame->GetSize();
02736     const nsStylePadding* paddingData = nsnull;
02737     GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData,
02738                  aFrame);
02739     if (paddingData) {
02740       paddingData->CalcPaddingFor(aFrame, padding);
02741     }
02742     const nsStyleBorder* borderData = nsnull;
02743     GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData,
02744                  aFrame);
02745     if (borderData) {
02746       borderData->CalcBorderFor(aFrame, border);
02747     }
02748   
02749     val->SetTwips(size.height - padding.top - padding.bottom -
02750                   border.top - border.bottom);
02751   } else {
02752     // Just return the value in the style context
02753     const nsStylePosition* positionData = nsnull;
02754     GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData,
02755                  aFrame);
02756     if (positionData) {
02757       switch (positionData->mHeight.GetUnit()) {
02758         case eStyleUnit_Coord:
02759           val->SetTwips(positionData->mHeight.GetCoordValue());
02760           break;
02761         case eStyleUnit_Percent:
02762           val->SetPercent(positionData->mHeight.GetPercentValue());
02763           break;
02764         case eStyleUnit_Auto:
02765           val->SetIdent(nsLayoutAtoms::autoAtom);
02766           break;
02767         default:
02768           NS_ERROR("Unexpected height unit");
02769           val->SetTwips(0);
02770           break;
02771       }
02772     }
02773   }
02774   
02775   return CallQueryInterface(val, aValue);
02776 }
02777 
02778 nsresult
02779 nsComputedDOMStyle::GetWidth(nsIFrame *aFrame,
02780                              nsIDOMCSSValue** aValue)
02781 {
02782   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02783   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02784 
02785   PRBool calcWidth = PR_FALSE;
02786 
02787   if (aFrame) {
02788     calcWidth = PR_TRUE;
02789 
02790     FlushPendingReflows();
02791 
02792     const nsStyleDisplay *displayData = nsnull;
02793     GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)displayData,
02794                  aFrame);
02795     if (displayData && displayData->mDisplay == NS_STYLE_DISPLAY_INLINE
02796         && !(aFrame->GetStateBits() & NS_FRAME_REPLACED_ELEMENT)) {
02797       calcWidth = PR_FALSE;
02798     }
02799   }
02800 
02801   if (calcWidth) {
02802     nsSize size = aFrame->GetSize();
02803     nsMargin padding;
02804     nsMargin border;
02805     const nsStylePadding *paddingData = nsnull;
02806     GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData,
02807                  aFrame);
02808     if (paddingData) {
02809       paddingData->CalcPaddingFor(aFrame, padding);
02810     }
02811     const nsStyleBorder *borderData = nsnull;
02812     GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData,
02813                  aFrame);
02814     if (borderData) {
02815       borderData->CalcBorderFor(aFrame, border);
02816     }
02817     val->SetTwips(size.width - padding.left - padding.right -
02818                   border.left - border.right);
02819   } else {
02820     // Just return the value in the style context
02821     const nsStylePosition *positionData = nsnull;
02822     GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData,
02823                  aFrame);
02824     if (positionData) {
02825       switch (positionData->mWidth.GetUnit()) {
02826         case eStyleUnit_Coord:
02827           val->SetTwips(positionData->mWidth.GetCoordValue());
02828           break;
02829         case eStyleUnit_Percent:
02830           val->SetPercent(positionData->mWidth.GetPercentValue());
02831           break;
02832         case eStyleUnit_Auto:
02833           val->SetIdent(nsLayoutAtoms::autoAtom);
02834           break;
02835         default:
02836           NS_ERROR("Unexpected width unit");
02837           val->SetTwips(0);
02838           break;
02839       }
02840     }
02841   }
02842 
02843   return CallQueryInterface(val, aValue);
02844 }
02845 
02846 nsresult
02847 nsComputedDOMStyle::GetMaxHeight(nsIFrame *aFrame,
02848                                  nsIDOMCSSValue** aValue)
02849 {
02850   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02851   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02852 
02853   const nsStylePosition *positionData = nsnull;
02854   GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData,
02855                aFrame);
02856 
02857   FlushPendingReflows();
02858 
02859   if (positionData) {
02860     nsIFrame *container = nsnull;
02861     nsSize size;
02862     nscoord minHeight = 0;
02863 
02864     if (positionData->mMinHeight.GetUnit() == eStyleUnit_Percent) {
02865       container = GetContainingBlockFor(aFrame);
02866       if (container) {
02867         size = container->GetSize();
02868         minHeight = nscoord(size.height *
02869                             positionData->mMinHeight.GetPercentValue());
02870       }
02871     } else if (positionData->mMinHeight.GetUnit() == eStyleUnit_Coord) {
02872       minHeight = positionData->mMinHeight.GetCoordValue();
02873     }
02874 
02875     switch (positionData->mMaxHeight.GetUnit()) {
02876       case eStyleUnit_Coord:
02877         val->SetTwips(PR_MAX(minHeight,
02878                              positionData->mMaxHeight.GetCoordValue()));
02879         break;
02880       case eStyleUnit_Percent:
02881         if (!container) {
02882           container = GetContainingBlockFor(aFrame);
02883           if (container) {
02884             size = container->GetSize();
02885           } else {
02886             // no containing block
02887             val->SetPercent(positionData->mMaxHeight.GetPercentValue());
02888           }
02889         }
02890         if (container) {
02891           val->SetTwips(PR_MAX(minHeight, size.height *
02892                                positionData->mMaxHeight.GetPercentValue()));
02893         }
02894 
02895         break;
02896       default:
02897         val->SetIdent(nsLayoutAtoms::none);
02898 
02899         break;
02900     }
02901   }
02902 
02903   return CallQueryInterface(val, aValue);
02904 }
02905 
02906 nsresult
02907 nsComputedDOMStyle::GetMaxWidth(nsIFrame *aFrame,
02908                                 nsIDOMCSSValue** aValue)
02909 {
02910   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02911   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02912 
02913   const nsStylePosition *positionData = nsnull;
02914   GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData,
02915                aFrame);
02916 
02917   FlushPendingReflows();
02918 
02919   if (positionData) {
02920     nsIFrame *container = nsnull;
02921     nsSize size;
02922     nscoord minWidth = 0;
02923 
02924     if (positionData->mMinWidth.GetUnit() == eStyleUnit_Percent) {
02925       container = GetContainingBlockFor(aFrame);
02926       if (container) {
02927         size = container->GetSize();
02928         minWidth = nscoord(size.width *
02929                            positionData->mMinWidth.GetPercentValue());
02930       }
02931     } else if (positionData->mMinWidth.GetUnit() == eStyleUnit_Coord) {
02932       minWidth = positionData->mMinWidth.GetCoordValue();
02933     }
02934 
02935     switch (positionData->mMaxWidth.GetUnit()) {
02936       case eStyleUnit_Coord:
02937         val->SetTwips(PR_MAX(minWidth,
02938                              positionData->mMaxWidth.GetCoordValue()));
02939         break;
02940       case eStyleUnit_Percent:
02941         if (!container) {
02942           container = GetContainingBlockFor(aFrame);
02943           if (container) {
02944             size = container->GetSize();
02945           } else {
02946             // no containing block
02947             val->SetPercent(positionData->mMaxWidth.GetPercentValue());
02948           }
02949         }
02950         if (container) {
02951           val->SetTwips(PR_MAX(minWidth, size.width *
02952                                positionData->mMaxWidth.GetPercentValue()));
02953         }
02954 
02955         break;
02956       default:
02957         val->SetIdent(nsLayoutAtoms::none);
02958 
02959         break;
02960     }
02961   }
02962 
02963   return CallQueryInterface(val, aValue);
02964 }
02965 
02966 nsresult
02967 nsComputedDOMStyle::GetMinHeight(nsIFrame *aFrame,
02968                                  nsIDOMCSSValue** aValue)
02969 {
02970   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
02971   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
02972 
02973   const nsStylePosition *positionData = nsnull;
02974   GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData,
02975                aFrame);
02976 
02977   FlushPendingReflows();
02978 
02979   if (positionData) {
02980     nsIFrame *container = nsnull;
02981     switch (positionData->mMinHeight.GetUnit()) {
02982       case eStyleUnit_Coord:
02983         val->SetTwips(positionData->mMinHeight.GetCoordValue());
02984         break;
02985       case eStyleUnit_Percent:
02986         container = GetContainingBlockFor(aFrame);
02987         if (container) {
02988           val->SetTwips(container->GetSize().height *
02989                         positionData->mMinHeight.GetPercentValue());
02990         } else {
02991           // no containing block
02992           val->SetPercent(positionData->mMinHeight.GetPercentValue());
02993         }
02994 
02995         break;
02996       default:
02997         val->SetTwips(0);
02998 
02999         break;
03000     }
03001   }
03002 
03003   return CallQueryInterface(val, aValue);
03004 }
03005 
03006 nsresult
03007 nsComputedDOMStyle::GetMinWidth(nsIFrame *aFrame,
03008                                 nsIDOMCSSValue** aValue)
03009 {
03010   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
03011   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03012 
03013   const nsStylePosition *positionData = nsnull;
03014   GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData,
03015                aFrame);
03016 
03017   FlushPendingReflows();
03018 
03019   if (positionData) {
03020     nsIFrame *container = nsnull;
03021     switch (positionData->mMinWidth.GetUnit()) {
03022       case eStyleUnit_Coord:
03023         val->SetTwips(positionData->mMinWidth.GetCoordValue());
03024         break;
03025       case eStyleUnit_Percent:
03026         container = GetContainingBlockFor(aFrame);
03027         if (container) {
03028           val->SetTwips(container->GetSize().width *
03029                         positionData->mMinWidth.GetPercentValue());
03030         } else {
03031           // no containing block
03032           val->SetPercent(positionData->mMinWidth.GetPercentValue());
03033         }
03034         break;
03035       default:
03036         val->SetTwips(0);
03037         break;
03038     }
03039   }
03040 
03041   return CallQueryInterface(val, aValue);
03042 }
03043 
03044 nsresult
03045 nsComputedDOMStyle::GetLeft(nsIFrame *aFrame, nsIDOMCSSValue** aValue)
03046 {
03047   return GetOffsetWidthFor(NS_SIDE_LEFT, aFrame, aValue);
03048 }
03049 
03050 nsresult
03051 nsComputedDOMStyle::GetRight(nsIFrame *aFrame, nsIDOMCSSValue** aValue)
03052 {
03053   return GetOffsetWidthFor(NS_SIDE_RIGHT, aFrame, aValue);
03054 }
03055 
03056 nsresult
03057 nsComputedDOMStyle::GetTop(nsIFrame *aFrame, nsIDOMCSSValue** aValue)
03058 {
03059   return GetOffsetWidthFor(NS_SIDE_TOP, aFrame, aValue);
03060 }
03061 
03062 nsROCSSPrimitiveValue*
03063 nsComputedDOMStyle::GetROCSSPrimitiveValue()
03064 {
03065   nsROCSSPrimitiveValue *primitiveValue = new nsROCSSPrimitiveValue(mT2P);
03066 
03067   NS_ASSERTION(primitiveValue != 0, "ran out of memory");
03068 
03069   return primitiveValue;
03070 }
03071 
03072 nsDOMCSSValueList*
03073 nsComputedDOMStyle::GetROCSSValueList(PRBool aCommaDelimited)
03074 {
03075   nsDOMCSSValueList *valueList = new nsDOMCSSValueList(aCommaDelimited,
03076                                                        PR_TRUE);
03077   NS_ASSERTION(valueList != 0, "ran out of memory");
03078 
03079   return valueList;
03080 }
03081 
03082 nsresult
03083 nsComputedDOMStyle::GetOffsetWidthFor(PRUint8 aSide, nsIFrame* aFrame,
03084                                       nsIDOMCSSValue** aValue)
03085 {
03086   const nsStyleDisplay* display = nsnull;
03087   GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display, aFrame);
03088 
03089   FlushPendingReflows();
03090 
03091   nsresult rv = NS_OK;
03092   if (display) {
03093     switch (display->mPosition) {
03094       case NS_STYLE_POSITION_STATIC:
03095         rv = GetStaticOffset(aSide, aFrame, aValue);
03096         break;
03097       case NS_STYLE_POSITION_RELATIVE:
03098         rv = GetRelativeOffset(aSide, aFrame, aValue);
03099         break;
03100       case NS_STYLE_POSITION_ABSOLUTE:
03101       case NS_STYLE_POSITION_FIXED:
03102         rv = GetAbsoluteOffset(aSide, aFrame, aValue);
03103         break;
03104       default:
03105         NS_ERROR("Invalid position");
03106         break;
03107     }
03108   }
03109 
03110   return rv;
03111 }
03112 
03113 nsresult
03114 nsComputedDOMStyle::GetAbsoluteOffset(PRUint8 aSide, nsIFrame* aFrame,
03115                                       nsIDOMCSSValue** aValue)
03116 {
03117   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
03118   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03119 
03120   nsIFrame* container = GetContainingBlockFor(aFrame);
03121   if (container) {
03122     nscoord margin = GetMarginWidthCoordFor(aSide, aFrame);
03123     nscoord border = GetBorderWidthCoordFor(aSide, container);
03124     nsMargin scrollbarSizes(0, 0, 0, 0);
03125     nsRect rect = aFrame->GetRect();
03126     nsRect containerRect = container->GetRect();
03127       
03128     if (container->GetType() == nsLayoutAtoms::viewportFrame) {
03129       // For absolutely positioned frames scrollbars are taken into
03130       // account by virtue of getting a containing block that does
03131       // _not_ include the scrollbars.  For fixed positioned frames,
03132       // the containing block is the viewport, which _does_ include
03133       // scrollbars.  We have to do some extra work.
03134       // the first child in the default frame list is what we want
03135       nsIFrame* scrollingChild = container->GetFirstChild(nsnull);
03136       nsCOMPtr<nsIScrollableFrame> scrollFrame =
03137         do_QueryInterface(scrollingChild);
03138       if (scrollFrame) {
03139         scrollbarSizes = scrollFrame->GetActualScrollbarSizes();
03140       }
03141     }
03142 
03143     nscoord offset = 0;
03144     switch (aSide) {
03145       case NS_SIDE_TOP:
03146         offset = rect.y - margin - border - scrollbarSizes.top;
03147 
03148         break;
03149       case NS_SIDE_RIGHT:
03150         offset = containerRect.width - rect.width -
03151           rect.x - margin - border - scrollbarSizes.right;
03152 
03153         break;
03154       case NS_SIDE_BOTTOM:
03155         offset = containerRect.height - rect.height -
03156           rect.y - margin - border - scrollbarSizes.bottom;
03157 
03158         break;
03159       case NS_SIDE_LEFT:
03160         offset = rect.x - margin - border - scrollbarSizes.left;
03161 
03162         break;
03163       default:
03164         NS_ERROR("Invalid side");
03165         break;
03166     }
03167     val->SetTwips(offset);
03168   } else {
03169     // XXX no frame.  This property makes no sense
03170     val->SetTwips(0);
03171   }
03172 
03173   return CallQueryInterface(val, aValue);
03174 }
03175 
03176 
03177 #if (NS_SIDE_TOP == 0) && (NS_SIDE_RIGHT == 1) && (NS_SIDE_BOTTOM == 2) && (NS_SIDE_LEFT == 3)
03178 #define NS_OPPOSITE_SIDE(s_) (((s_) + 2) & 3)
03179 #else
03180 #error "Somebody changed the side constants."
03181 #endif
03182 
03183 nsresult
03184 nsComputedDOMStyle::GetRelativeOffset(PRUint8 aSide, nsIFrame* aFrame,
03185                                       nsIDOMCSSValue** aValue)
03186 {
03187   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
03188   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03189 
03190   const nsStylePosition* positionData = nsnull;
03191   GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData,
03192                aFrame);
03193   if (positionData) {
03194     nsStyleCoord coord;
03195     PRInt32 sign = 1;
03196     positionData->mOffset.Get(aSide, coord);
03197     if (coord.GetUnit() != eStyleUnit_Coord &&
03198         coord.GetUnit() != eStyleUnit_Percent) {
03199       positionData->mOffset.Get(NS_OPPOSITE_SIDE(aSide), coord);
03200       sign = -1;
03201     }
03202     nsIFrame* container = nsnull;
03203     switch(coord.GetUnit()) {
03204       case eStyleUnit_Coord:
03205         val->SetTwips(sign * coord.GetCoordValue());
03206         break;
03207       case eStyleUnit_Percent:
03208         container = GetContainingBlockFor(aFrame);
03209         if (container) {
03210           nsMargin border;
03211           nsMargin padding;
03212           container->GetStyleBorder()->CalcBorderFor(container, border);
03213           container->GetStylePadding()->CalcPaddingFor(container, padding);
03214           nsSize size = container->GetSize();
03215           if (aSide == NS_SIDE_LEFT || aSide == NS_SIDE_RIGHT) {
03216             val->SetTwips(sign * coord.GetPercentValue() *
03217                           (size.width - border.left - border.right -
03218                            padding.left - padding.right));
03219           } else {
03220             val->SetTwips(sign * coord.GetPercentValue() *
03221                           (size.height - border.top - border.bottom -
03222                            padding.top - padding.bottom));
03223           }
03224         } else {
03225           // XXX no containing block.
03226           val->SetTwips(0);
03227         }
03228         break;
03229       default:
03230         NS_ERROR("Unexpected left/right/top/bottom unit");
03231         val->SetTwips(0);
03232         break;
03233     }
03234   }
03235 
03236   return CallQueryInterface(val, aValue);
03237 }
03238 
03239 nsresult
03240 nsComputedDOMStyle::GetStaticOffset(PRUint8 aSide, nsIFrame* aFrame,
03241                                     nsIDOMCSSValue** aValue)
03242 
03243 {
03244   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
03245   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03246 
03247   const nsStylePosition* positionData = nsnull;
03248   GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)positionData,
03249                aFrame);
03250   if (positionData) {
03251     nsStyleCoord coord;
03252     positionData->mOffset.Get(aSide, coord);
03253     switch(coord.GetUnit()) {
03254       case eStyleUnit_Coord:
03255         val->SetTwips(coord.GetCoordValue());
03256 
03257         break;
03258       case eStyleUnit_Percent:
03259         val->SetPercent(coord.GetPercentValue());
03260 
03261         break;
03262       case eStyleUnit_Auto:
03263         val->SetIdent(nsLayoutAtoms::autoAtom);
03264 
03265         break;
03266       default:
03267         NS_ERROR("Unexpected left/right/top/bottom unit");
03268         val->SetTwips(0);
03269 
03270         break;
03271     }
03272   }
03273   
03274   return CallQueryInterface(val, aValue);
03275 }
03276 
03277 void
03278 nsComputedDOMStyle::FlushPendingReflows()
03279 {
03280   // Flush all pending notifications so that our frames are up to date
03281   nsCOMPtr<nsIDocument> document = mContent->GetDocument();
03282   if (document) {
03283     document->FlushPendingNotifications(Flush_Layout);
03284   }
03285 }
03286 
03287 nsresult
03288 nsComputedDOMStyle::GetStyleData(nsStyleStructID aID,
03289                                  const nsStyleStruct*& aStyleStruct,
03290                                  nsIFrame* aFrame)
03291 {
03292   if (aFrame && !mPseudo) {
03293     aStyleStruct = aFrame->GetStyleData(aID);
03294   } else if (mStyleContextHolder) {
03295     aStyleStruct = mStyleContextHolder->GetStyleData(aID);    
03296   } else {
03297     nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocumentWeak);
03298     NS_ENSURE_TRUE(doc, NS_ERROR_NOT_AVAILABLE);
03299 
03300     nsIPresShell* presShell = doc->GetShellAt(0);
03301     NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
03302 
03303     mStyleContextHolder =
03304       nsInspectorCSSUtils::GetStyleContextForContent(mContent,
03305                                                      mPseudo,
03306                                                      presShell);
03307     if (mStyleContextHolder) {
03308       aStyleStruct = mStyleContextHolder->GetStyleData(aID);
03309     }
03310   }
03311   NS_ASSERTION(aStyleStruct, "Failed to get a style struct");
03312 
03313   return NS_OK;
03314 }
03315 
03316 nsresult
03317 nsComputedDOMStyle::GetPaddingWidthFor(PRUint8 aSide, nsIFrame *aFrame,
03318                                        nsIDOMCSSValue** aValue)
03319 {
03320   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
03321   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03322 
03323   FlushPendingReflows();
03324   
03325   nscoord width = GetPaddingWidthCoordFor(aSide, aFrame);
03326   val->SetTwips(width);
03327 
03328   return CallQueryInterface(val, aValue);
03329 }
03330 
03331 nscoord
03332 nsComputedDOMStyle::GetPaddingWidthCoordFor(PRUint8 aSide, nsIFrame* aFrame)
03333 {
03334   const nsStylePadding* paddingData = nsnull;
03335   GetStyleData(eStyleStruct_Padding, (const nsStyleStruct*&)paddingData,
03336                aFrame);
03337 
03338   if (paddingData) {
03339     nsMargin padding;
03340     paddingData->CalcPaddingFor(aFrame, padding);
03341     switch(aSide) {
03342       case NS_SIDE_TOP    :
03343         return padding.top;
03344       case NS_SIDE_BOTTOM :
03345         return padding.bottom;
03346       case NS_SIDE_LEFT   :
03347         return padding.left;
03348       case NS_SIDE_RIGHT  :
03349         return padding.right;
03350       default:
03351         NS_ERROR("Invalid side");
03352         break;
03353     }
03354   }
03355 
03356   return 0;
03357 }
03358 
03359 nscoord
03360 nsComputedDOMStyle::GetBorderWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame)
03361 {
03362   const nsStyleBorder* borderData = nsnull;
03363   GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData, aFrame);
03364 
03365   if (borderData) {
03366     nsMargin border;
03367     borderData->CalcBorderFor(aFrame, border);
03368     switch(aSide) {
03369       case NS_SIDE_TOP    :
03370         return border.top;
03371       case NS_SIDE_BOTTOM :
03372         return border.bottom;
03373       case NS_SIDE_LEFT   :
03374         return border.left;
03375       case NS_SIDE_RIGHT  :
03376         return border.right;
03377       default:
03378         NS_ERROR("Invalid side");
03379         break;
03380     }
03381   }
03382 
03383   return 0;
03384 }
03385 
03386 nsresult
03387 nsComputedDOMStyle::GetLineHeightCoord(nsIFrame *aFrame,
03388                                        const nsStyleText *aText,
03389                                        nscoord& aCoord)
03390 {
03391   nsresult rv = NS_ERROR_FAILURE;
03392 
03393   if (aText) {
03394     const nsStyleFont *font = nsnull;
03395     GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font, aFrame);
03396     switch (aText->mLineHeight.GetUnit()) {
03397       case eStyleUnit_Coord:
03398         aCoord = aText->mLineHeight.GetCoordValue();
03399         rv = NS_OK;
03400         break;
03401       case eStyleUnit_Percent:
03402         if (font) {
03403           aCoord = nscoord(aText->mLineHeight.GetPercentValue() * font->mSize);
03404           rv = NS_OK;
03405         }
03406         break;
03407       case eStyleUnit_Factor:
03408         if (font) {
03409           aCoord = nscoord(aText->mLineHeight.GetFactorValue() * font->mSize);
03410           rv = NS_OK;
03411         }
03412         break;
03413       default:
03414         break;
03415     }
03416   }
03417 
03418   if (NS_FAILED(rv))
03419     aCoord = 0;
03420 
03421   return rv;
03422 }
03423 
03424 nsresult
03425 nsComputedDOMStyle::GetBorderColorsFor(PRUint8 aSide, nsIFrame *aFrame,
03426                                        nsIDOMCSSValue** aValue)
03427 {
03428   const nsStyleBorder *border = nsnull;
03429   GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)border, aFrame);
03430 
03431   if (border && border->mBorderColors) {
03432     nsBorderColors* borderColors = border->mBorderColors[aSide];
03433     if (borderColors) {
03434       nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
03435       NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
03436 
03437       do {
03438         nsROCSSPrimitiveValue *primitive = GetROCSSPrimitiveValue();
03439         if (!primitive) {
03440           delete valueList;
03441 
03442           return NS_ERROR_OUT_OF_MEMORY;
03443         }
03444         if (borderColors->mTransparent) {
03445           primitive->SetIdent(nsLayoutAtoms::transparent);
03446         } else {
03447           nsDOMCSSRGBColor *rgb = GetDOMCSSRGBColor(borderColors->mColor);
03448           if (rgb) {
03449             primitive->SetColor(rgb);
03450           } else {
03451             delete valueList;
03452             delete primitive;
03453 
03454             return NS_ERROR_OUT_OF_MEMORY;
03455           }
03456         }
03457 
03458         PRBool success = valueList->AppendCSSValue(primitive);
03459         if (!success) {
03460           delete valueList;
03461           delete primitive;
03462 
03463           return NS_ERROR_OUT_OF_MEMORY;
03464         }
03465         borderColors = borderColors->mNext;
03466       } while (borderColors);
03467 
03468       return CallQueryInterface(valueList, aValue);
03469     }
03470   }
03471 
03472   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
03473   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03474 
03475   val->SetIdent(nsLayoutAtoms::none);
03476 
03477   return CallQueryInterface(val, aValue);
03478 }
03479 
03480 nsresult
03481 nsComputedDOMStyle::GetBorderRadiusFor(PRUint8 aSide, nsIFrame *aFrame,
03482                                        nsIDOMCSSValue** aValue)
03483 {
03484   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
03485   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03486 
03487   const nsStyleBorder *border = nsnull;
03488   GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)border, aFrame);
03489 
03490   if (border) {
03491     nsStyleCoord coord;
03492     border->mBorderRadius.Get(aSide, coord);
03493     
03494     switch (coord.GetUnit()) {
03495       case eStyleUnit_Coord:
03496         val->SetTwips(coord.GetCoordValue());
03497         break;
03498       case eStyleUnit_Percent:
03499         if (aFrame) {
03500           val->SetTwips(coord.GetPercentValue() * aFrame->GetSize().width);
03501         } else {
03502           val->SetPercent(coord.GetPercentValue());
03503         }
03504         break;
03505       default:
03506         NS_ERROR("Unexpected border radius unit");
03507         break;
03508     }
03509   } else {
03510     val->SetTwips(0);
03511   }
03512 
03513   return CallQueryInterface(val, aValue);
03514 }
03515 
03516 nsresult
03517 nsComputedDOMStyle::GetBorderWidthFor(PRUint8 aSide, nsIFrame *aFrame,
03518                                       nsIDOMCSSValue** aValue)
03519 {
03520   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
03521   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03522 
03523   const nsStyleBorder* border = nsnull;
03524   GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)border, aFrame);
03525 
03526   if (border) {
03527     nscoord width;
03528     border->CalcBorderFor(aFrame, aSide, width);
03529     val->SetTwips(width);
03530   }
03531 
03532   return CallQueryInterface(val, aValue);
03533 }
03534 
03535 nsresult
03536 nsComputedDOMStyle::GetBorderColorFor(PRUint8 aSide, nsIFrame *aFrame,
03537                                       nsIDOMCSSValue** aValue)
03538 {
03539   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
03540   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03541 
03542   const nsStyleBorder* border = nsnull;
03543   GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)border, aFrame);
03544 
03545   if (border) {
03546     nscolor color; 
03547     PRBool transparent;
03548     PRBool foreground;
03549     border->GetBorderColor(aSide, color, transparent, foreground);
03550     if (transparent) {
03551       val->SetIdent(nsLayoutAtoms::transparent);
03552     } else {
03553       if (foreground) {
03554         const nsStyleColor* colorStruct = nsnull;
03555         GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&)colorStruct,
03556                      aFrame);
03557         color = colorStruct->mColor;
03558       }
03559 
03560       nsDOMCSSRGBColor *rgb = GetDOMCSSRGBColor(color);
03561       if (!rgb) {
03562         delete val;
03563 
03564         return NS_ERROR_OUT_OF_MEMORY;
03565       }
03566 
03567       val->SetColor(rgb);
03568     }
03569   }
03570 
03571   return CallQueryInterface(val, aValue);
03572 }
03573 
03574 nsresult
03575 nsComputedDOMStyle::GetMarginWidthFor(PRUint8 aSide, nsIFrame *aFrame,
03576                                       nsIDOMCSSValue** aValue)
03577 {
03578   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
03579   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03580 
03581   FlushPendingReflows();
03582 
03583   nscoord width = GetMarginWidthCoordFor(aSide, aFrame);
03584   val->SetTwips(width);
03585 
03586   return CallQueryInterface(val, aValue);
03587 }
03588 
03589 nscoord
03590 nsComputedDOMStyle::GetMarginWidthCoordFor(PRUint8 aSide, nsIFrame *aFrame)
03591 {
03592   const nsStyleMargin* marginData = nsnull;
03593   GetStyleData(eStyleStruct_Margin, (const nsStyleStruct*&)marginData, aFrame);
03594   if (marginData) {
03595     nsMargin margin;
03596     marginData->CalcMarginFor(aFrame, margin);
03597     switch(aSide) {
03598       case NS_SIDE_TOP    :
03599         return margin.top;
03600       case NS_SIDE_BOTTOM :
03601         return margin.bottom;
03602       case NS_SIDE_LEFT   :
03603         return margin.left;
03604       case NS_SIDE_RIGHT  :
03605         return margin.right;
03606       default:
03607         NS_ERROR("Invalid side");
03608         break;
03609     }
03610   }
03611 
03612   return 0;
03613 }
03614 
03615 nsresult
03616 nsComputedDOMStyle::GetBorderStyleFor(PRUint8 aSide, nsIFrame *aFrame,
03617                                       nsIDOMCSSValue** aValue)
03618 {
03619   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
03620   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
03621 
03622   const nsStyleBorder* border = nsnull;
03623   GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)border, aFrame);
03624 
03625   PRUint8 borderStyle = NS_STYLE_BORDER_STYLE_NONE;
03626 
03627   if (border) {
03628     borderStyle = border->GetBorderStyle(aSide);
03629   }
03630 
03631   if (borderStyle != NS_STYLE_BORDER_STYLE_NONE) {
03632     const nsAFlatCString& style=
03633       nsCSSProps::ValueToKeyword(borderStyle,
03634                                  nsCSSProps::kBorderStyleKTable);
03635     val->SetIdent(style);
03636   } else {
03637     val->SetIdent(nsLayoutAtoms::none);
03638   }
03639 
03640   return CallQueryInterface(val, aValue);
03641 }
03642 
03643 
03644 #define COMPUTED_STYLE_MAP_ENTRY(_prop, _method)  \
03645   { eCSSProperty_##_prop, &nsComputedDOMStyle::Get##_method }
03646 
03647 const nsComputedDOMStyle::ComputedStyleMapEntry*
03648 nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
03649 {
03650   /* ******************************************************************* *\
03651    * Properties below are listed in alphabetical order.                  *
03652    * Please keep them that way.                                          *
03653    *                                                                     *
03654    * Properties commented out with // are not yet implemented            *
03655    * Properties commented out with //// are shorthands and not queryable *
03656   \* ******************************************************************* */
03657   static
03658 #ifndef XP_MACOSX
03659     // XXX If this actually fixes the bustage, replace this with an
03660     // autoconf test.
03661   const
03662 #endif
03663   ComputedStyleMapEntry map[] = {
03664     /* ****************************** *\
03665      * Implementations of CSS2 styles *
03666     \* ****************************** */
03667 
03668     // COMPUTED_STYLE_MAP_ENTRY(azimuth,                    Azimuth),
03670     COMPUTED_STYLE_MAP_ENTRY(background_attachment,         BackgroundAttachment),
03671     COMPUTED_STYLE_MAP_ENTRY(background_color,              BackgroundColor),
03672     COMPUTED_STYLE_MAP_ENTRY(background_image,              BackgroundImage),
03674     COMPUTED_STYLE_MAP_ENTRY(background_repeat,             BackgroundRepeat),
03677     COMPUTED_STYLE_MAP_ENTRY(border_bottom_color,           BorderBottomColor),
03678     COMPUTED_STYLE_MAP_ENTRY(border_bottom_style,           BorderBottomStyle),
03679     COMPUTED_STYLE_MAP_ENTRY(border_bottom_width,           BorderBottomWidth),
03680     COMPUTED_STYLE_MAP_ENTRY(border_collapse,               BorderCollapse),
03683     COMPUTED_STYLE_MAP_ENTRY(border_left_color,             BorderLeftColor),
03684     COMPUTED_STYLE_MAP_ENTRY(border_left_style,             BorderLeftStyle),
03685     COMPUTED_STYLE_MAP_ENTRY(border_left_width,             BorderLeftWidth),
03687     COMPUTED_STYLE_MAP_ENTRY(border_right_color,            BorderRightColor),
03688     COMPUTED_STYLE_MAP_ENTRY(border_right_style,            BorderRightStyle),
03689     COMPUTED_STYLE_MAP_ENTRY(border_right_width,            BorderRightWidth),
03690     COMPUTED_STYLE_MAP_ENTRY(border_spacing,                BorderSpacing),
03693     COMPUTED_STYLE_MAP_ENTRY(border_top_color,              BorderTopColor),
03694     COMPUTED_STYLE_MAP_ENTRY(border_top_style,              BorderTopStyle),
03695     COMPUTED_STYLE_MAP_ENTRY(border_top_width,              BorderTopWidth),
03697     COMPUTED_STYLE_MAP_ENTRY(bottom,                        Bottom),
03698     COMPUTED_STYLE_MAP_ENTRY(caption_side,                  CaptionSide),
03699     COMPUTED_STYLE_MAP_ENTRY(clear,                         Clear),
03700     COMPUTED_STYLE_MAP_ENTRY(clip,                          Clip),
03701     COMPUTED_STYLE_MAP_ENTRY(color,                         Color),
03702     // COMPUTED_STYLE_MAP_ENTRY(content,                    Content),
03703     COMPUTED_STYLE_MAP_ENTRY(counter_increment,             CounterIncrement),
03704     COMPUTED_STYLE_MAP_ENTRY(counter_reset,                 CounterReset),
03706     // COMPUTED_STYLE_MAP_ENTRY(cue_after,                  CueAfter),
03707     // COMPUTED_STYLE_MAP_ENTRY(cue_before,                 CueBefore),
03708     COMPUTED_STYLE_MAP_ENTRY(cursor,                        Cursor),
03709     COMPUTED_STYLE_MAP_ENTRY(direction,                     Direction),
03710     COMPUTED_STYLE_MAP_ENTRY(display,                       Display),
03711     // COMPUTED_STYLE_MAP_ENTRY(elevation,                  Elevation),
03712     COMPUTED_STYLE_MAP_ENTRY(empty_cells,                   EmptyCells),
03713     COMPUTED_STYLE_MAP_ENTRY(float,                         CssFloat),
03715     COMPUTED_STYLE_MAP_ENTRY(font_family,                   FontFamily),
03716     COMPUTED_STYLE_MAP_ENTRY(font_size,                     FontSize),
03717     COMPUTED_STYLE_MAP_ENTRY(font_size_adjust,              FontSizeAdjust),
03718     // COMPUTED_STYLE_MAP_ENTRY(font_stretch,               FontStretch),
03719     COMPUTED_STYLE_MAP_ENTRY(font_style,                    FontStyle),
03720     COMPUTED_STYLE_MAP_ENTRY(font_variant,                  FontVariant),
03721     COMPUTED_STYLE_MAP_ENTRY(font_weight,                   FontWeight),
03722     COMPUTED_STYLE_MAP_ENTRY(height,                        Height),
03723     COMPUTED_STYLE_MAP_ENTRY(left,                          Left),
03724     COMPUTED_STYLE_MAP_ENTRY(letter_spacing,                LetterSpacing),
03725     COMPUTED_STYLE_MAP_ENTRY(line_height,                   LineHeight),
03727     COMPUTED_STYLE_MAP_ENTRY(list_style_image,              ListStyleImage),
03728     COMPUTED_STYLE_MAP_ENTRY(list_style_position,           ListStylePosition),
03729     COMPUTED_STYLE_MAP_ENTRY(list_style_type,               ListStyleType),
03731     COMPUTED_STYLE_MAP_ENTRY(margin_bottom,                 MarginBottomWidth),
03732     COMPUTED_STYLE_MAP_ENTRY(margin_left,                   MarginLeftWidth),
03733     COMPUTED_STYLE_MAP_ENTRY(margin_right,                  MarginRightWidth),
03734     COMPUTED_STYLE_MAP_ENTRY(margin_top,                    MarginTopWidth),
03735     COMPUTED_STYLE_MAP_ENTRY(marker_offset,                 MarkerOffset),
03736     // COMPUTED_STYLE_MAP_ENTRY(marks,                      Marks),
03737     COMPUTED_STYLE_MAP_ENTRY(max_height,                    MaxHeight),
03738     COMPUTED_STYLE_MAP_ENTRY(max_width,                     MaxWidth),
03739     COMPUTED_STYLE_MAP_ENTRY(min_height,                    MinHeight),
03740     COMPUTED_STYLE_MAP_ENTRY(min_width,                     MinWidth),
03741     // COMPUTED_STYLE_MAP_ENTRY(orphans,                    Orphans),
03743     COMPUTED_STYLE_MAP_ENTRY(outline_color,                 OutlineColor),
03744     COMPUTED_STYLE_MAP_ENTRY(outline_style,                 OutlineStyle),
03745     COMPUTED_STYLE_MAP_ENTRY(outline_width,                 OutlineWidth),
03746     COMPUTED_STYLE_MAP_ENTRY(outline_offset,                OutlineOffset),
03747     COMPUTED_STYLE_MAP_ENTRY(overflow,                      Overflow),
03748     COMPUTED_STYLE_MAP_ENTRY(overflow_x,                    OverflowX),
03749     COMPUTED_STYLE_MAP_ENTRY(overflow_y,                    OverflowY),
03751     COMPUTED_STYLE_MAP_ENTRY(padding_bottom,                PaddingBottom),
03752     COMPUTED_STYLE_MAP_ENTRY(padding_left,                  PaddingLeft),
03753     COMPUTED_STYLE_MAP_ENTRY(padding_right,                 PaddingRight),
03754     COMPUTED_STYLE_MAP_ENTRY(padding_top,                   PaddingTop),
03755     // COMPUTED_STYLE_MAP_ENTRY(page,                       Page),
03756     // COMPUTED_STYLE_MAP_ENTRY(page_break_after,           PageBreakAfter),
03757     // COMPUTED_STYLE_MAP_ENTRY(page_break_before,          PageBreakBefore),
03758     // COMPUTED_STYLE_MAP_ENTRY(page_break_inside,          PageBreakInside),
03760     // COMPUTED_STYLE_MAP_ENTRY(pause_after,                PauseAfter),
03761     // COMPUTED_STYLE_MAP_ENTRY(pause_before,               PauseBefore),
03762     // COMPUTED_STYLE_MAP_ENTRY(pitch,                      Pitch),
03763     // COMPUTED_STYLE_MAP_ENTRY(pitch_range,                PitchRange),
03764     COMPUTED_STYLE_MAP_ENTRY(position,                      Position),
03765     // COMPUTED_STYLE_MAP_ENTRY(quotes,                     Quotes),
03766     // COMPUTED_STYLE_MAP_ENTRY(richness,                   Richness),
03767     COMPUTED_STYLE_MAP_ENTRY(right,                         Right),
03769     // COMPUTED_STYLE_MAP_ENTRY(speak,                      Speak),
03770     // COMPUTED_STYLE_MAP_ENTRY(speak_header,               SpeakHeader),
03771     // COMPUTED_STYLE_MAP_ENTRY(speak_numeral,              SpeakNumeral),
03772     // COMPUTED_STYLE_MAP_ENTRY(speak_punctuation,          SpeakPunctuation),
03773     // COMPUTED_STYLE_MAP_ENTRY(speech_rate,                SpeechRate),
03774     // COMPUTED_STYLE_MAP_ENTRY(stress,                     Stress),
03775     COMPUTED_STYLE_MAP_ENTRY(table_layout,                  TableLayout),
03776     COMPUTED_STYLE_MAP_ENTRY(text_align,                    TextAlign),
03777     COMPUTED_STYLE_MAP_ENTRY(text_decoration,               TextDecoration),
03778     COMPUTED_STYLE_MAP_ENTRY(text_indent,                   TextIndent),
03779     // COMPUTED_STYLE_MAP_ENTRY(text_shadow,                TextShadow),
03780     COMPUTED_STYLE_MAP_ENTRY(text_transform,                TextTransform),
03781     COMPUTED_STYLE_MAP_ENTRY(top,                           Top),
03782     COMPUTED_STYLE_MAP_ENTRY(unicode_bidi,                  UnicodeBidi),
03783     COMPUTED_STYLE_MAP_ENTRY(vertical_align,                VerticalAlign),
03784     COMPUTED_STYLE_MAP_ENTRY(visibility,                    Visibility),
03785     // COMPUTED_STYLE_MAP_ENTRY(voice_family,               VoiceFamily),
03786     // COMPUTED_STYLE_MAP_ENTRY(volume,                     Volume),
03787     COMPUTED_STYLE_MAP_ENTRY(white_space,                   WhiteSpace),
03788     // COMPUTED_STYLE_MAP_ENTRY(widows,                     Widows),
03789     COMPUTED_STYLE_MAP_ENTRY(width,                         Width),
03790     COMPUTED_STYLE_MAP_ENTRY(word_spacing,                  WordSpacing),
03791     COMPUTED_STYLE_MAP_ENTRY(z_index,                       ZIndex),
03792 
03793     /* ******************************* *\
03794      * Implementations of -moz- styles *
03795     \* ******************************* */
03796 
03797     COMPUTED_STYLE_MAP_ENTRY(appearance,                    Appearance),
03798     COMPUTED_STYLE_MAP_ENTRY(_moz_background_clip,          BackgroundClip),
03799     COMPUTED_STYLE_MAP_ENTRY(_moz_background_inline_policy, BackgroundInlinePolicy),
03800     COMPUTED_STYLE_MAP_ENTRY(_moz_background_origin,        BackgroundOrigin),
03801     COMPUTED_STYLE_MAP_ENTRY(binding,                       Binding),
03802     COMPUTED_STYLE_MAP_ENTRY(border_bottom_colors,          BorderBottomColors),
03803     COMPUTED_STYLE_MAP_ENTRY(border_left_colors,            BorderLeftColors),
03804     COMPUTED_STYLE_MAP_ENTRY(border_right_colors,           BorderRightColors),
03805     COMPUTED_STYLE_MAP_ENTRY(border_top_colors,             BorderTopColors),
03806     COMPUTED_STYLE_MAP_ENTRY(_moz_border_radius_bottomLeft, BorderRadiusBottomLeft),
03807     COMPUTED_STYLE_MAP_ENTRY(_moz_border_radius_bottomRight,BorderRadiusBottomRight),
03808     COMPUTED_STYLE_MAP_ENTRY(_moz_border_radius_topLeft,    BorderRadiusTopLeft),
03809     COMPUTED_STYLE_MAP_ENTRY(_moz_border_radius_topRight,   BorderRadiusTopRight),
03810     COMPUTED_STYLE_MAP_ENTRY(box_align,                     BoxAlign),
03811     COMPUTED_STYLE_MAP_ENTRY(box_direction,                 BoxDirection),
03812     COMPUTED_STYLE_MAP_ENTRY(box_flex,                      BoxFlex),
03813     COMPUTED_STYLE_MAP_ENTRY(box_ordinal_group,             BoxOrdinalGroup),
03814     COMPUTED_STYLE_MAP_ENTRY(box_orient,                    BoxOrient),
03815     COMPUTED_STYLE_MAP_ENTRY(box_pack,                      BoxPack),
03816     COMPUTED_STYLE_MAP_ENTRY(box_sizing,                    BoxSizing),
03817     COMPUTED_STYLE_MAP_ENTRY(_moz_column_count,             ColumnCount),
03818     COMPUTED_STYLE_MAP_ENTRY(_moz_column_width,             ColumnWidth),
03819     COMPUTED_STYLE_MAP_ENTRY(_moz_column_gap,               ColumnGap),
03820     COMPUTED_STYLE_MAP_ENTRY(float_edge,                    FloatEdge),
03821     COMPUTED_STYLE_MAP_ENTRY(image_region,                  ImageRegion),
03822     COMPUTED_STYLE_MAP_ENTRY(opacity,                       Opacity),
03823     COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_bottomLeft, OutlineRadiusBottomLeft),
03824     COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_bottomRight,OutlineRadiusBottomRight),
03825     COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_topLeft,    OutlineRadiusTopLeft),
03826     COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_topRight,   OutlineRadiusTopRight),
03827     COMPUTED_STYLE_MAP_ENTRY(user_focus,                    UserFocus),
03828     COMPUTED_STYLE_MAP_ENTRY(user_input,                    UserInput),
03829     COMPUTED_STYLE_MAP_ENTRY(user_modify,                   UserModify),
03830     COMPUTED_STYLE_MAP_ENTRY(user_select,                   UserSelect)
03831   };
03832 
03833   *aLength = NS_ARRAY_LENGTH(map);
03834 
03835   return map;
03836 }
03837