Back to index

lightning-sunbird  0.9+nobinonly
nsROCSSPrimitiveValue.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  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsROCSSPrimitiveValue.h"
00039 
00040 #include "nsCOMPtr.h"
00041 #include "nsDOMError.h"
00042 #include "prprf.h"
00043 #include "nsContentUtils.h"
00044 #include "nsXPIDLString.h"
00045 #include "nsCRT.h"
00046 
00047 nsROCSSPrimitiveValue::nsROCSSPrimitiveValue(float aT2P)
00048   : mType(CSS_PX), mT2P(aT2P)
00049 {
00050   mValue.mTwips = 0;
00051 }
00052 
00053 
00054 nsROCSSPrimitiveValue::~nsROCSSPrimitiveValue()
00055 {
00056   Reset();
00057 }
00058 
00059 void
00060 nsROCSSPrimitiveValue::GetEscapedURI(nsIURI *aURI, PRUnichar **aReturn)
00061 {
00062   nsCAutoString specUTF8;
00063   aURI->GetSpec(specUTF8);
00064   NS_ConvertUTF8toUCS2 spec(specUTF8);
00065 
00066   PRUint16 length = spec.Length();
00067   PRUnichar *escaped = (PRUnichar *)nsMemory::Alloc(length * 2 * sizeof(PRUnichar) + sizeof(PRUnichar('\0')));
00068 
00069   if (escaped) {
00070     PRUnichar *ptr = escaped;
00071 
00072     for (PRUint16 i = 0; i < length; ++i) {
00073       switch (spec[i]) {
00074         case ' ' : // space
00075         case '\t': // tab
00076         case '(' : // opening parenthesis
00077         case ')' : // closing parenthesis
00078         case '\'': // single quote
00079         case '"' : // double quote
00080         case ',' : // comma
00081         case '\\': // backslash
00082           // We have one of the above special characters.
00083           // Prepend it with a backslash.
00084           *ptr++ = '\\';
00085           break;
00086         default:
00087           break;
00088       }
00089       *ptr++ = spec[i];
00090     }
00091     *ptr = 0;
00092   }
00093   *aReturn = escaped;
00094 }
00095 
00096 
00097 NS_IMPL_ADDREF(nsROCSSPrimitiveValue)
00098 NS_IMPL_RELEASE(nsROCSSPrimitiveValue)
00099 
00100 
00101 // QueryInterface implementation for nsROCSSPrimitiveValue
00102 NS_INTERFACE_MAP_BEGIN(nsROCSSPrimitiveValue)
00103   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSPrimitiveValue)
00104   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSValue)
00105   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMCSSPrimitiveValue)
00106   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(ROCSSPrimitiveValue)
00107 NS_INTERFACE_MAP_END
00108 
00109 
00110 // nsIDOMCSSValue
00111 
00112 
00113 NS_IMETHODIMP
00114 nsROCSSPrimitiveValue::GetCssText(nsAString& aCssText)
00115 {
00116   nsAutoString tmpStr;
00117   aCssText.Truncate();
00118   nsresult result = NS_OK;
00119 
00120   switch (mType) {
00121     case CSS_PX :
00122       {
00123         float val = NSTwipsToFloatPixels(mValue.mTwips, mT2P);
00124         tmpStr.AppendFloat(val);
00125         tmpStr.AppendLiteral("px");
00126         break;
00127       }
00128     case CSS_CM :
00129       {
00130         float val = NS_TWIPS_TO_CENTIMETERS(mValue.mTwips);
00131         tmpStr.AppendFloat(val);
00132         tmpStr.AppendLiteral("cm");
00133         break;
00134       }
00135     case CSS_MM :
00136       {
00137         float val = NS_TWIPS_TO_MILLIMETERS(mValue.mTwips);
00138         tmpStr.AppendFloat(val);
00139         tmpStr.AppendLiteral("mm");
00140         break;
00141       }
00142     case CSS_IN :
00143       {
00144         float val = NS_TWIPS_TO_INCHES(mValue.mTwips);
00145         tmpStr.AppendFloat(val);
00146         tmpStr.AppendLiteral("in");
00147         break;
00148       }
00149     case CSS_PT :
00150       {
00151         float val = NSTwipsToFloatPoints(mValue.mTwips);
00152         tmpStr.AppendFloat(val);
00153         tmpStr.AppendLiteral("pt");
00154         break;
00155       }
00156     case CSS_IDENT :
00157       {
00158         const char *atomValue;
00159         mValue.mAtom->GetUTF8String(&atomValue);
00160         AppendUTF8toUTF16(atomValue, tmpStr);
00161         break;
00162       }
00163     case CSS_STRING :
00164       {
00165         tmpStr.Append(mValue.mString);
00166         break;
00167       }
00168     case CSS_URI :
00169       {
00170         nsXPIDLString uri;
00171         if (mValue.mURI) {
00172           GetEscapedURI(mValue.mURI, getter_Copies(uri));
00173           tmpStr.Assign(NS_LITERAL_STRING("url(") +
00174                         uri +
00175                         NS_LITERAL_STRING(")"));
00176         } else {
00177           // XXXldb Any better ideas?  It's good to have something that
00178           // doesn't parse so that things round-trip "correctly".
00179           tmpStr.Assign(NS_LITERAL_STRING("url(invalid-url:)"));
00180         }
00181         break;
00182       }
00183     case CSS_PERCENTAGE :
00184       {
00185         tmpStr.AppendFloat(mValue.mFloat * 100);
00186         tmpStr.Append(PRUnichar('%'));
00187         break;
00188       }
00189     case CSS_NUMBER :
00190       {
00191         tmpStr.AppendFloat(mValue.mFloat);
00192         break;
00193       }
00194     case CSS_RECT :
00195       {
00196         NS_ASSERTION(mValue.mRect, "mValue.mRect should never be null");
00197         NS_NAMED_LITERAL_STRING(comma, ", ");
00198         nsCOMPtr<nsIDOMCSSPrimitiveValue> sideCSSValue;
00199         nsAutoString sideValue;
00200         tmpStr.AssignLiteral("rect(");
00201         // get the top
00202         result = mValue.mRect->GetTop(getter_AddRefs(sideCSSValue));
00203         if (NS_FAILED(result))
00204           break;
00205         result = sideCSSValue->GetCssText(sideValue);
00206         if (NS_FAILED(result))
00207           break;
00208         tmpStr.Append(sideValue + comma);
00209         // get the right
00210         result = mValue.mRect->GetRight(getter_AddRefs(sideCSSValue));
00211         if (NS_FAILED(result))
00212           break;
00213         result = sideCSSValue->GetCssText(sideValue);
00214         if (NS_FAILED(result))
00215           break;
00216         tmpStr.Append(sideValue + comma);
00217         // get the bottom
00218         result = mValue.mRect->GetBottom(getter_AddRefs(sideCSSValue));
00219         if (NS_FAILED(result))
00220           break;
00221         result = sideCSSValue->GetCssText(sideValue);
00222         if (NS_FAILED(result))
00223           break;
00224         tmpStr.Append(sideValue + comma);
00225         // get the left
00226         result = mValue.mRect->GetLeft(getter_AddRefs(sideCSSValue));
00227         if (NS_FAILED(result))
00228           break;
00229         result = sideCSSValue->GetCssText(sideValue);
00230         if (NS_FAILED(result))
00231           break;
00232         tmpStr.Append(sideValue + NS_LITERAL_STRING(")"));
00233         break;
00234       }
00235     case CSS_RGBCOLOR :
00236       {
00237         NS_ASSERTION(mValue.mColor, "mValue.mColor should never be null");
00238         NS_NAMED_LITERAL_STRING(comma, ", ");
00239         nsCOMPtr<nsIDOMCSSPrimitiveValue> colorCSSValue;
00240         nsAutoString colorValue;
00241         tmpStr.AssignLiteral("rgb(");
00242 
00243         // get the red component
00244         result = mValue.mColor->GetRed(getter_AddRefs(colorCSSValue));
00245         if (NS_FAILED(result))
00246           break;
00247         result = colorCSSValue->GetCssText(colorValue);
00248         if (NS_FAILED(result))
00249           break;
00250         tmpStr.Append(colorValue + comma);
00251 
00252         // get the green component
00253         result = mValue.mColor->GetGreen(getter_AddRefs(colorCSSValue));
00254         if (NS_FAILED(result))
00255           break;
00256         result = colorCSSValue->GetCssText(colorValue);
00257         if (NS_FAILED(result))
00258           break;
00259         tmpStr.Append(colorValue + comma);
00260 
00261         // get the blue component
00262         result = mValue.mColor->GetBlue(getter_AddRefs(colorCSSValue));
00263         if (NS_FAILED(result))
00264           break;
00265         result = colorCSSValue->GetCssText(colorValue);
00266         if (NS_FAILED(result))
00267           break;
00268         tmpStr.Append(colorValue + NS_LITERAL_STRING(")"));
00269 
00270         break;
00271       }
00272     case CSS_PC :
00273     case CSS_UNKNOWN :
00274     case CSS_EMS :
00275     case CSS_EXS :
00276     case CSS_DEG :
00277     case CSS_RAD :
00278     case CSS_GRAD :
00279     case CSS_MS :
00280     case CSS_S :
00281     case CSS_HZ :
00282     case CSS_KHZ :
00283     case CSS_DIMENSION :
00284     case CSS_ATTR :
00285     case CSS_COUNTER :
00286       NS_ERROR("We have a bogus value set.  This should not happen");
00287       return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00288   }
00289 
00290   if (NS_SUCCEEDED(result)) {
00291     aCssText.Assign(tmpStr);
00292   }
00293 
00294   return NS_OK;
00295 }
00296 
00297 
00298 NS_IMETHODIMP
00299 nsROCSSPrimitiveValue::SetCssText(const nsAString& aCssText)
00300 {
00301   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
00302 }
00303 
00304 
00305 NS_IMETHODIMP
00306 nsROCSSPrimitiveValue::GetCssValueType(PRUint16* aValueType)
00307 {
00308   NS_ENSURE_ARG_POINTER(aValueType);
00309   *aValueType = nsIDOMCSSValue::CSS_PRIMITIVE_VALUE;
00310   return NS_OK;
00311 }
00312 
00313 
00314 // nsIDOMCSSPrimitiveValue
00315 
00316 NS_IMETHODIMP
00317 nsROCSSPrimitiveValue::GetPrimitiveType(PRUint16* aPrimitiveType)
00318 {
00319   NS_ENSURE_ARG_POINTER(aPrimitiveType);
00320   *aPrimitiveType = mType;
00321 
00322   return NS_OK;
00323 }
00324 
00325 
00326 NS_IMETHODIMP
00327 nsROCSSPrimitiveValue::SetFloatValue(PRUint16 aUnitType, float aFloatValue)
00328 {
00329   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
00330 }
00331 
00332 
00333 NS_IMETHODIMP
00334 nsROCSSPrimitiveValue::GetFloatValue(PRUint16 aUnitType, float* aReturn)
00335 {
00336   NS_ENSURE_ARG_POINTER(aReturn);
00337   *aReturn = 0;
00338 
00339   switch(aUnitType) {
00340     case CSS_PX :
00341       if (mType != CSS_PX)
00342         return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00343       *aReturn = NSTwipsToFloatPixels(mValue.mTwips, mT2P);
00344       break;
00345     case CSS_CM :
00346       if (mType != CSS_PX)
00347         return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00348       *aReturn = NS_TWIPS_TO_CENTIMETERS(mValue.mTwips);
00349       break;
00350     case CSS_MM :
00351       if (mType != CSS_PX)
00352         return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00353       *aReturn = NS_TWIPS_TO_MILLIMETERS(mValue.mTwips);
00354       break;
00355     case CSS_IN :
00356       if (mType != CSS_PX)
00357         return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00358       *aReturn = NS_TWIPS_TO_INCHES(mValue.mTwips);
00359       break;
00360     case CSS_PT :
00361       if (mType != CSS_PX)
00362         return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00363       *aReturn = NSTwipsToFloatPoints(mValue.mTwips);
00364       break;
00365     case CSS_PC :
00366       if (mType != CSS_PX)
00367         return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00368       *aReturn = NS_TWIPS_TO_PICAS(mValue.mTwips);
00369       break;
00370     case CSS_PERCENTAGE :
00371       if (mType != CSS_PERCENTAGE)
00372         return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00373       *aReturn = mValue.mFloat * 100;
00374       break;
00375     case CSS_NUMBER :
00376       if (mType != CSS_NUMBER)
00377         return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00378       *aReturn = mValue.mFloat;
00379       break;
00380     case CSS_UNKNOWN :
00381     case CSS_EMS :
00382     case CSS_EXS :
00383     case CSS_DEG :
00384     case CSS_RAD :
00385     case CSS_GRAD :
00386     case CSS_MS :
00387     case CSS_S :
00388     case CSS_HZ :
00389     case CSS_KHZ :
00390     case CSS_DIMENSION :
00391     case CSS_STRING :
00392     case CSS_URI :
00393     case CSS_IDENT :
00394     case CSS_ATTR :
00395     case CSS_COUNTER :
00396     case CSS_RECT :
00397     case CSS_RGBCOLOR :
00398       return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00399   }
00400 
00401   return NS_OK;
00402 }
00403 
00404 
00405 NS_IMETHODIMP
00406 nsROCSSPrimitiveValue::SetStringValue(PRUint16 aStringType,
00407                                       const nsAString& aStringValue)
00408 {
00409   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
00410 }
00411 
00412 
00413 NS_IMETHODIMP
00414 nsROCSSPrimitiveValue::GetStringValue(nsAString& aReturn)
00415 {
00416   switch (mType) {
00417     case CSS_IDENT:
00418       mValue.mAtom->ToString(aReturn);
00419       break;
00420     case CSS_STRING:
00421       aReturn.Assign(mValue.mString);
00422       break;
00423     case CSS_URI: {
00424       nsCAutoString spec;
00425       if (mValue.mURI)
00426         mValue.mURI->GetSpec(spec);
00427       CopyUTF8toUTF16(spec, aReturn);
00428       } break;
00429     case CSS_ATTR:
00430     default:
00431       aReturn.Truncate();
00432       return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00433   }
00434   return NS_OK;
00435 }
00436 
00437 
00438 NS_IMETHODIMP
00439 nsROCSSPrimitiveValue::GetCounterValue(nsIDOMCounter** aReturn)
00440 {
00441   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
00442 }
00443 
00444 
00445 NS_IMETHODIMP
00446 nsROCSSPrimitiveValue::GetRectValue(nsIDOMRect** aReturn)
00447 {
00448   if (mType != CSS_RECT) {
00449     *aReturn = nsnull;
00450     return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00451   }
00452   NS_ASSERTION(mValue.mRect, "mValue.mRect should never be null");
00453   return CallQueryInterface(mValue.mRect, aReturn);
00454 }
00455 
00456 
00457 NS_IMETHODIMP 
00458 nsROCSSPrimitiveValue::GetRGBColorValue(nsIDOMRGBColor** aReturn)
00459 {
00460   if (mType != CSS_RGBCOLOR) {
00461     *aReturn = nsnull;
00462     return NS_ERROR_DOM_INVALID_ACCESS_ERR;
00463   }
00464   NS_ASSERTION(mValue.mColor, "mValue.mColor should never be null");
00465   return CallQueryInterface(mValue.mColor, aReturn);
00466 }
00467