layout/style/nsCSSValue.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 /* representation of simple property values within CSS declarations */
michael@0 8
michael@0 9 #include "nsCSSValue.h"
michael@0 10
michael@0 11 #include "mozilla/Likely.h"
michael@0 12 #include "mozilla/MemoryReporting.h"
michael@0 13 #include "mozilla/css/ImageLoader.h"
michael@0 14 #include "CSSCalc.h"
michael@0 15 #include "gfxFontConstants.h"
michael@0 16 #include "imgIRequest.h"
michael@0 17 #include "imgRequestProxy.h"
michael@0 18 #include "nsIDocument.h"
michael@0 19 #include "nsIPrincipal.h"
michael@0 20 #include "nsCSSProps.h"
michael@0 21 #include "nsCSSStyleSheet.h"
michael@0 22 #include "nsNetUtil.h"
michael@0 23 #include "nsPresContext.h"
michael@0 24 #include "nsStyleUtil.h"
michael@0 25 #include "nsDeviceContext.h"
michael@0 26
michael@0 27 using namespace mozilla;
michael@0 28
michael@0 29 nsCSSValue::nsCSSValue(int32_t aValue, nsCSSUnit aUnit)
michael@0 30 : mUnit(aUnit)
michael@0 31 {
michael@0 32 NS_ABORT_IF_FALSE(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
michael@0 33 aUnit == eCSSUnit_EnumColor, "not an int value");
michael@0 34 if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
michael@0 35 aUnit == eCSSUnit_EnumColor) {
michael@0 36 mValue.mInt = aValue;
michael@0 37 }
michael@0 38 else {
michael@0 39 mUnit = eCSSUnit_Null;
michael@0 40 mValue.mInt = 0;
michael@0 41 }
michael@0 42 }
michael@0 43
michael@0 44 nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit)
michael@0 45 : mUnit(aUnit)
michael@0 46 {
michael@0 47 NS_ABORT_IF_FALSE(eCSSUnit_Percent <= aUnit, "not a float value");
michael@0 48 if (eCSSUnit_Percent <= aUnit) {
michael@0 49 mValue.mFloat = aValue;
michael@0 50 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
michael@0 51 }
michael@0 52 else {
michael@0 53 mUnit = eCSSUnit_Null;
michael@0 54 mValue.mInt = 0;
michael@0 55 }
michael@0 56 }
michael@0 57
michael@0 58 nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit)
michael@0 59 : mUnit(aUnit)
michael@0 60 {
michael@0 61 NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
michael@0 62 if (UnitHasStringValue()) {
michael@0 63 mValue.mString = BufferFromString(aValue).take();
michael@0 64 }
michael@0 65 else {
michael@0 66 mUnit = eCSSUnit_Null;
michael@0 67 mValue.mInt = 0;
michael@0 68 }
michael@0 69 }
michael@0 70
michael@0 71 nsCSSValue::nsCSSValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
michael@0 72 : mUnit(aUnit)
michael@0 73 {
michael@0 74 NS_ABORT_IF_FALSE(UnitHasArrayValue(), "bad unit");
michael@0 75 mValue.mArray = aValue;
michael@0 76 mValue.mArray->AddRef();
michael@0 77 }
michael@0 78
michael@0 79 nsCSSValue::nsCSSValue(mozilla::css::URLValue* aValue)
michael@0 80 : mUnit(eCSSUnit_URL)
michael@0 81 {
michael@0 82 mValue.mURL = aValue;
michael@0 83 mValue.mURL->AddRef();
michael@0 84 }
michael@0 85
michael@0 86 nsCSSValue::nsCSSValue(mozilla::css::ImageValue* aValue)
michael@0 87 : mUnit(eCSSUnit_Image)
michael@0 88 {
michael@0 89 mValue.mImage = aValue;
michael@0 90 mValue.mImage->AddRef();
michael@0 91 }
michael@0 92
michael@0 93 nsCSSValue::nsCSSValue(nsCSSValueGradient* aValue)
michael@0 94 : mUnit(eCSSUnit_Gradient)
michael@0 95 {
michael@0 96 mValue.mGradient = aValue;
michael@0 97 mValue.mGradient->AddRef();
michael@0 98 }
michael@0 99
michael@0 100 nsCSSValue::nsCSSValue(nsCSSValueTokenStream* aValue)
michael@0 101 : mUnit(eCSSUnit_TokenStream)
michael@0 102 {
michael@0 103 mValue.mTokenStream = aValue;
michael@0 104 mValue.mTokenStream->AddRef();
michael@0 105 }
michael@0 106
michael@0 107 nsCSSValue::nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue)
michael@0 108 : mUnit(eCSSUnit_GridTemplateAreas)
michael@0 109 {
michael@0 110 mValue.mGridTemplateAreas = aValue;
michael@0 111 mValue.mGridTemplateAreas->AddRef();
michael@0 112 }
michael@0 113
michael@0 114 nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
michael@0 115 : mUnit(aCopy.mUnit)
michael@0 116 {
michael@0 117 if (mUnit <= eCSSUnit_DummyInherit) {
michael@0 118 // nothing to do, but put this important case first
michael@0 119 }
michael@0 120 else if (eCSSUnit_Percent <= mUnit) {
michael@0 121 mValue.mFloat = aCopy.mValue.mFloat;
michael@0 122 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
michael@0 123 }
michael@0 124 else if (UnitHasStringValue()) {
michael@0 125 mValue.mString = aCopy.mValue.mString;
michael@0 126 mValue.mString->AddRef();
michael@0 127 }
michael@0 128 else if (eCSSUnit_Integer <= mUnit && mUnit <= eCSSUnit_EnumColor) {
michael@0 129 mValue.mInt = aCopy.mValue.mInt;
michael@0 130 }
michael@0 131 else if (IsIntegerColorUnit()) {
michael@0 132 mValue.mColor = aCopy.mValue.mColor;
michael@0 133 }
michael@0 134 else if (IsFloatColorUnit()) {
michael@0 135 mValue.mFloatColor = aCopy.mValue.mFloatColor;
michael@0 136 mValue.mFloatColor->AddRef();
michael@0 137 }
michael@0 138 else if (UnitHasArrayValue()) {
michael@0 139 mValue.mArray = aCopy.mValue.mArray;
michael@0 140 mValue.mArray->AddRef();
michael@0 141 }
michael@0 142 else if (eCSSUnit_URL == mUnit) {
michael@0 143 mValue.mURL = aCopy.mValue.mURL;
michael@0 144 mValue.mURL->AddRef();
michael@0 145 }
michael@0 146 else if (eCSSUnit_Image == mUnit) {
michael@0 147 mValue.mImage = aCopy.mValue.mImage;
michael@0 148 mValue.mImage->AddRef();
michael@0 149 }
michael@0 150 else if (eCSSUnit_Gradient == mUnit) {
michael@0 151 mValue.mGradient = aCopy.mValue.mGradient;
michael@0 152 mValue.mGradient->AddRef();
michael@0 153 }
michael@0 154 else if (eCSSUnit_TokenStream == mUnit) {
michael@0 155 mValue.mTokenStream = aCopy.mValue.mTokenStream;
michael@0 156 mValue.mTokenStream->AddRef();
michael@0 157 }
michael@0 158 else if (eCSSUnit_Pair == mUnit) {
michael@0 159 mValue.mPair = aCopy.mValue.mPair;
michael@0 160 mValue.mPair->AddRef();
michael@0 161 }
michael@0 162 else if (eCSSUnit_Triplet == mUnit) {
michael@0 163 mValue.mTriplet = aCopy.mValue.mTriplet;
michael@0 164 mValue.mTriplet->AddRef();
michael@0 165 }
michael@0 166 else if (eCSSUnit_Rect == mUnit) {
michael@0 167 mValue.mRect = aCopy.mValue.mRect;
michael@0 168 mValue.mRect->AddRef();
michael@0 169 }
michael@0 170 else if (eCSSUnit_List == mUnit) {
michael@0 171 mValue.mList = aCopy.mValue.mList;
michael@0 172 mValue.mList->AddRef();
michael@0 173 }
michael@0 174 else if (eCSSUnit_ListDep == mUnit) {
michael@0 175 mValue.mListDependent = aCopy.mValue.mListDependent;
michael@0 176 }
michael@0 177 else if (eCSSUnit_SharedList == mUnit) {
michael@0 178 mValue.mSharedList = aCopy.mValue.mSharedList;
michael@0 179 mValue.mSharedList->AddRef();
michael@0 180 }
michael@0 181 else if (eCSSUnit_PairList == mUnit) {
michael@0 182 mValue.mPairList = aCopy.mValue.mPairList;
michael@0 183 mValue.mPairList->AddRef();
michael@0 184 }
michael@0 185 else if (eCSSUnit_PairListDep == mUnit) {
michael@0 186 mValue.mPairListDependent = aCopy.mValue.mPairListDependent;
michael@0 187 }
michael@0 188 else if (eCSSUnit_GridTemplateAreas == mUnit) {
michael@0 189 mValue.mGridTemplateAreas = aCopy.mValue.mGridTemplateAreas;
michael@0 190 mValue.mGridTemplateAreas->AddRef();
michael@0 191 }
michael@0 192 else {
michael@0 193 NS_ABORT_IF_FALSE(false, "unknown unit");
michael@0 194 }
michael@0 195 }
michael@0 196
michael@0 197 nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy)
michael@0 198 {
michael@0 199 if (this != &aCopy) {
michael@0 200 Reset();
michael@0 201 new (this) nsCSSValue(aCopy);
michael@0 202 }
michael@0 203 return *this;
michael@0 204 }
michael@0 205
michael@0 206 bool nsCSSValue::operator==(const nsCSSValue& aOther) const
michael@0 207 {
michael@0 208 NS_ABORT_IF_FALSE(mUnit != eCSSUnit_ListDep &&
michael@0 209 aOther.mUnit != eCSSUnit_ListDep &&
michael@0 210 mUnit != eCSSUnit_PairListDep &&
michael@0 211 aOther.mUnit != eCSSUnit_PairListDep,
michael@0 212 "don't use operator== with dependent lists");
michael@0 213
michael@0 214 if (mUnit == aOther.mUnit) {
michael@0 215 if (mUnit <= eCSSUnit_DummyInherit) {
michael@0 216 return true;
michael@0 217 }
michael@0 218 else if (UnitHasStringValue()) {
michael@0 219 return (NS_strcmp(GetBufferValue(mValue.mString),
michael@0 220 GetBufferValue(aOther.mValue.mString)) == 0);
michael@0 221 }
michael@0 222 else if ((eCSSUnit_Integer <= mUnit) && (mUnit <= eCSSUnit_EnumColor)) {
michael@0 223 return mValue.mInt == aOther.mValue.mInt;
michael@0 224 }
michael@0 225 else if (IsIntegerColorUnit()) {
michael@0 226 return mValue.mColor == aOther.mValue.mColor;
michael@0 227 }
michael@0 228 else if (IsFloatColorUnit()) {
michael@0 229 return *mValue.mFloatColor == *aOther.mValue.mFloatColor;
michael@0 230 }
michael@0 231 else if (UnitHasArrayValue()) {
michael@0 232 return *mValue.mArray == *aOther.mValue.mArray;
michael@0 233 }
michael@0 234 else if (eCSSUnit_URL == mUnit) {
michael@0 235 return *mValue.mURL == *aOther.mValue.mURL;
michael@0 236 }
michael@0 237 else if (eCSSUnit_Image == mUnit) {
michael@0 238 return *mValue.mImage == *aOther.mValue.mImage;
michael@0 239 }
michael@0 240 else if (eCSSUnit_Gradient == mUnit) {
michael@0 241 return *mValue.mGradient == *aOther.mValue.mGradient;
michael@0 242 }
michael@0 243 else if (eCSSUnit_TokenStream == mUnit) {
michael@0 244 return *mValue.mTokenStream == *aOther.mValue.mTokenStream;
michael@0 245 }
michael@0 246 else if (eCSSUnit_Pair == mUnit) {
michael@0 247 return *mValue.mPair == *aOther.mValue.mPair;
michael@0 248 }
michael@0 249 else if (eCSSUnit_Triplet == mUnit) {
michael@0 250 return *mValue.mTriplet == *aOther.mValue.mTriplet;
michael@0 251 }
michael@0 252 else if (eCSSUnit_Rect == mUnit) {
michael@0 253 return *mValue.mRect == *aOther.mValue.mRect;
michael@0 254 }
michael@0 255 else if (eCSSUnit_List == mUnit) {
michael@0 256 return *mValue.mList == *aOther.mValue.mList;
michael@0 257 }
michael@0 258 else if (eCSSUnit_SharedList == mUnit) {
michael@0 259 return *mValue.mSharedList == *aOther.mValue.mSharedList;
michael@0 260 }
michael@0 261 else if (eCSSUnit_PairList == mUnit) {
michael@0 262 return *mValue.mPairList == *aOther.mValue.mPairList;
michael@0 263 }
michael@0 264 else if (eCSSUnit_GridTemplateAreas == mUnit) {
michael@0 265 return *mValue.mGridTemplateAreas == *aOther.mValue.mGridTemplateAreas;
michael@0 266 }
michael@0 267 else {
michael@0 268 return mValue.mFloat == aOther.mValue.mFloat;
michael@0 269 }
michael@0 270 }
michael@0 271 return false;
michael@0 272 }
michael@0 273
michael@0 274 double nsCSSValue::GetAngleValueInRadians() const
michael@0 275 {
michael@0 276 double angle = GetFloatValue();
michael@0 277
michael@0 278 switch (GetUnit()) {
michael@0 279 case eCSSUnit_Radian: return angle;
michael@0 280 case eCSSUnit_Turn: return angle * 2 * M_PI;
michael@0 281 case eCSSUnit_Degree: return angle * M_PI / 180.0;
michael@0 282 case eCSSUnit_Grad: return angle * M_PI / 200.0;
michael@0 283
michael@0 284 default:
michael@0 285 NS_ABORT_IF_FALSE(false, "unrecognized angular unit");
michael@0 286 return 0.0;
michael@0 287 }
michael@0 288 }
michael@0 289
michael@0 290 imgRequestProxy* nsCSSValue::GetImageValue(nsIDocument* aDocument) const
michael@0 291 {
michael@0 292 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value");
michael@0 293 return mValue.mImage->mRequests.GetWeak(aDocument);
michael@0 294 }
michael@0 295
michael@0 296 nscoord nsCSSValue::GetFixedLength(nsPresContext* aPresContext) const
michael@0 297 {
michael@0 298 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_PhysicalMillimeter,
michael@0 299 "not a fixed length unit");
michael@0 300
michael@0 301 float inches = mValue.mFloat / MM_PER_INCH_FLOAT;
michael@0 302 return NSToCoordFloorClamped(inches *
michael@0 303 float(aPresContext->DeviceContext()->AppUnitsPerPhysicalInch()));
michael@0 304 }
michael@0 305
michael@0 306 nscoord nsCSSValue::GetPixelLength() const
michael@0 307 {
michael@0 308 NS_ABORT_IF_FALSE(IsPixelLengthUnit(), "not a fixed length unit");
michael@0 309
michael@0 310 double scaleFactor;
michael@0 311 switch (mUnit) {
michael@0 312 case eCSSUnit_Pixel: return nsPresContext::CSSPixelsToAppUnits(mValue.mFloat);
michael@0 313 case eCSSUnit_Pica: scaleFactor = 16.0; break;
michael@0 314 case eCSSUnit_Point: scaleFactor = 4/3.0; break;
michael@0 315 case eCSSUnit_Inch: scaleFactor = 96.0; break;
michael@0 316 case eCSSUnit_Millimeter: scaleFactor = 96/25.4; break;
michael@0 317 case eCSSUnit_Centimeter: scaleFactor = 96/2.54; break;
michael@0 318 default:
michael@0 319 NS_ERROR("should never get here");
michael@0 320 return 0;
michael@0 321 }
michael@0 322 return nsPresContext::CSSPixelsToAppUnits(float(mValue.mFloat*scaleFactor));
michael@0 323 }
michael@0 324
michael@0 325 void nsCSSValue::DoReset()
michael@0 326 {
michael@0 327 if (UnitHasStringValue()) {
michael@0 328 mValue.mString->Release();
michael@0 329 } else if (IsFloatColorUnit()) {
michael@0 330 mValue.mFloatColor->Release();
michael@0 331 } else if (UnitHasArrayValue()) {
michael@0 332 mValue.mArray->Release();
michael@0 333 } else if (eCSSUnit_URL == mUnit) {
michael@0 334 mValue.mURL->Release();
michael@0 335 } else if (eCSSUnit_Image == mUnit) {
michael@0 336 mValue.mImage->Release();
michael@0 337 } else if (eCSSUnit_Gradient == mUnit) {
michael@0 338 mValue.mGradient->Release();
michael@0 339 } else if (eCSSUnit_TokenStream == mUnit) {
michael@0 340 mValue.mTokenStream->Release();
michael@0 341 } else if (eCSSUnit_Pair == mUnit) {
michael@0 342 mValue.mPair->Release();
michael@0 343 } else if (eCSSUnit_Triplet == mUnit) {
michael@0 344 mValue.mTriplet->Release();
michael@0 345 } else if (eCSSUnit_Rect == mUnit) {
michael@0 346 mValue.mRect->Release();
michael@0 347 } else if (eCSSUnit_List == mUnit) {
michael@0 348 mValue.mList->Release();
michael@0 349 } else if (eCSSUnit_SharedList == mUnit) {
michael@0 350 mValue.mSharedList->Release();
michael@0 351 } else if (eCSSUnit_PairList == mUnit) {
michael@0 352 mValue.mPairList->Release();
michael@0 353 } else if (eCSSUnit_GridTemplateAreas == mUnit) {
michael@0 354 mValue.mGridTemplateAreas->Release();
michael@0 355 }
michael@0 356 mUnit = eCSSUnit_Null;
michael@0 357 }
michael@0 358
michael@0 359 void nsCSSValue::SetIntValue(int32_t aValue, nsCSSUnit aUnit)
michael@0 360 {
michael@0 361 NS_ABORT_IF_FALSE(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
michael@0 362 aUnit == eCSSUnit_EnumColor, "not an int value");
michael@0 363 Reset();
michael@0 364 if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
michael@0 365 aUnit == eCSSUnit_EnumColor) {
michael@0 366 mUnit = aUnit;
michael@0 367 mValue.mInt = aValue;
michael@0 368 }
michael@0 369 }
michael@0 370
michael@0 371 void nsCSSValue::SetPercentValue(float aValue)
michael@0 372 {
michael@0 373 Reset();
michael@0 374 mUnit = eCSSUnit_Percent;
michael@0 375 mValue.mFloat = aValue;
michael@0 376 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
michael@0 377 }
michael@0 378
michael@0 379 void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
michael@0 380 {
michael@0 381 NS_ABORT_IF_FALSE(eCSSUnit_Number <= aUnit, "not a float value");
michael@0 382 Reset();
michael@0 383 if (eCSSUnit_Number <= aUnit) {
michael@0 384 mUnit = aUnit;
michael@0 385 mValue.mFloat = aValue;
michael@0 386 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
michael@0 387 }
michael@0 388 }
michael@0 389
michael@0 390 void nsCSSValue::SetStringValue(const nsString& aValue,
michael@0 391 nsCSSUnit aUnit)
michael@0 392 {
michael@0 393 Reset();
michael@0 394 mUnit = aUnit;
michael@0 395 NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string unit");
michael@0 396 if (UnitHasStringValue()) {
michael@0 397 mValue.mString = BufferFromString(aValue).take();
michael@0 398 } else
michael@0 399 mUnit = eCSSUnit_Null;
michael@0 400 }
michael@0 401
michael@0 402 void nsCSSValue::SetColorValue(nscolor aValue)
michael@0 403 {
michael@0 404 SetIntegerColorValue(aValue, eCSSUnit_RGBAColor);
michael@0 405 }
michael@0 406
michael@0 407 void nsCSSValue::SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit)
michael@0 408 {
michael@0 409 Reset();
michael@0 410 mUnit = aUnit;
michael@0 411 NS_ABORT_IF_FALSE(IsIntegerColorUnit(), "bad unit");
michael@0 412 mValue.mColor = aValue;
michael@0 413 }
michael@0 414
michael@0 415 void nsCSSValue::SetFloatColorValue(float aComponent1,
michael@0 416 float aComponent2,
michael@0 417 float aComponent3,
michael@0 418 float aAlpha,
michael@0 419 nsCSSUnit aUnit)
michael@0 420 {
michael@0 421 Reset();
michael@0 422 mUnit = aUnit;
michael@0 423 NS_ABORT_IF_FALSE(IsFloatColorUnit(), "bad unit");
michael@0 424 mValue.mFloatColor =
michael@0 425 new nsCSSValueFloatColor(aComponent1, aComponent2, aComponent3, aAlpha);
michael@0 426 mValue.mFloatColor->AddRef();
michael@0 427 }
michael@0 428
michael@0 429 void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
michael@0 430 {
michael@0 431 Reset();
michael@0 432 mUnit = aUnit;
michael@0 433 NS_ABORT_IF_FALSE(UnitHasArrayValue(), "bad unit");
michael@0 434 mValue.mArray = aValue;
michael@0 435 mValue.mArray->AddRef();
michael@0 436 }
michael@0 437
michael@0 438 void nsCSSValue::SetURLValue(mozilla::css::URLValue* aValue)
michael@0 439 {
michael@0 440 Reset();
michael@0 441 mUnit = eCSSUnit_URL;
michael@0 442 mValue.mURL = aValue;
michael@0 443 mValue.mURL->AddRef();
michael@0 444 }
michael@0 445
michael@0 446 void nsCSSValue::SetImageValue(mozilla::css::ImageValue* aValue)
michael@0 447 {
michael@0 448 Reset();
michael@0 449 mUnit = eCSSUnit_Image;
michael@0 450 mValue.mImage = aValue;
michael@0 451 mValue.mImage->AddRef();
michael@0 452 }
michael@0 453
michael@0 454 void nsCSSValue::SetGradientValue(nsCSSValueGradient* aValue)
michael@0 455 {
michael@0 456 Reset();
michael@0 457 mUnit = eCSSUnit_Gradient;
michael@0 458 mValue.mGradient = aValue;
michael@0 459 mValue.mGradient->AddRef();
michael@0 460 }
michael@0 461
michael@0 462 void nsCSSValue::SetTokenStreamValue(nsCSSValueTokenStream* aValue)
michael@0 463 {
michael@0 464 Reset();
michael@0 465 mUnit = eCSSUnit_TokenStream;
michael@0 466 mValue.mTokenStream = aValue;
michael@0 467 mValue.mTokenStream->AddRef();
michael@0 468 }
michael@0 469
michael@0 470 void nsCSSValue::SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue)
michael@0 471 {
michael@0 472 Reset();
michael@0 473 mUnit = eCSSUnit_GridTemplateAreas;
michael@0 474 mValue.mGridTemplateAreas = aValue;
michael@0 475 mValue.mGridTemplateAreas->AddRef();
michael@0 476 }
michael@0 477
michael@0 478 void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue)
michael@0 479 {
michael@0 480 // pairs should not be used for null/inherit/initial values
michael@0 481 NS_ABORT_IF_FALSE(aValue &&
michael@0 482 aValue->mXValue.GetUnit() != eCSSUnit_Null &&
michael@0 483 aValue->mYValue.GetUnit() != eCSSUnit_Null &&
michael@0 484 aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 485 aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 486 aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
michael@0 487 aValue->mYValue.GetUnit() != eCSSUnit_Initial &&
michael@0 488 aValue->mXValue.GetUnit() != eCSSUnit_Unset &&
michael@0 489 aValue->mYValue.GetUnit() != eCSSUnit_Unset,
michael@0 490 "missing or inappropriate pair value");
michael@0 491 Reset();
michael@0 492 mUnit = eCSSUnit_Pair;
michael@0 493 mValue.mPair = new nsCSSValuePair_heap(aValue->mXValue, aValue->mYValue);
michael@0 494 mValue.mPair->AddRef();
michael@0 495 }
michael@0 496
michael@0 497 void nsCSSValue::SetPairValue(const nsCSSValue& xValue,
michael@0 498 const nsCSSValue& yValue)
michael@0 499 {
michael@0 500 NS_ABORT_IF_FALSE(xValue.GetUnit() != eCSSUnit_Null &&
michael@0 501 yValue.GetUnit() != eCSSUnit_Null &&
michael@0 502 xValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 503 yValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 504 xValue.GetUnit() != eCSSUnit_Initial &&
michael@0 505 yValue.GetUnit() != eCSSUnit_Initial &&
michael@0 506 xValue.GetUnit() != eCSSUnit_Unset &&
michael@0 507 yValue.GetUnit() != eCSSUnit_Unset,
michael@0 508 "inappropriate pair value");
michael@0 509 Reset();
michael@0 510 mUnit = eCSSUnit_Pair;
michael@0 511 mValue.mPair = new nsCSSValuePair_heap(xValue, yValue);
michael@0 512 mValue.mPair->AddRef();
michael@0 513 }
michael@0 514
michael@0 515 void nsCSSValue::SetTripletValue(const nsCSSValueTriplet* aValue)
michael@0 516 {
michael@0 517 // triplet should not be used for null/inherit/initial values
michael@0 518 NS_ABORT_IF_FALSE(aValue &&
michael@0 519 aValue->mXValue.GetUnit() != eCSSUnit_Null &&
michael@0 520 aValue->mYValue.GetUnit() != eCSSUnit_Null &&
michael@0 521 aValue->mZValue.GetUnit() != eCSSUnit_Null &&
michael@0 522 aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 523 aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 524 aValue->mZValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 525 aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
michael@0 526 aValue->mYValue.GetUnit() != eCSSUnit_Initial &&
michael@0 527 aValue->mZValue.GetUnit() != eCSSUnit_Initial &&
michael@0 528 aValue->mXValue.GetUnit() != eCSSUnit_Unset &&
michael@0 529 aValue->mYValue.GetUnit() != eCSSUnit_Unset &&
michael@0 530 aValue->mZValue.GetUnit() != eCSSUnit_Unset,
michael@0 531 "missing or inappropriate triplet value");
michael@0 532 Reset();
michael@0 533 mUnit = eCSSUnit_Triplet;
michael@0 534 mValue.mTriplet = new nsCSSValueTriplet_heap(aValue->mXValue, aValue->mYValue, aValue->mZValue);
michael@0 535 mValue.mTriplet->AddRef();
michael@0 536 }
michael@0 537
michael@0 538 void nsCSSValue::SetTripletValue(const nsCSSValue& xValue,
michael@0 539 const nsCSSValue& yValue,
michael@0 540 const nsCSSValue& zValue)
michael@0 541 {
michael@0 542 // Only allow Null for the z component
michael@0 543 NS_ABORT_IF_FALSE(xValue.GetUnit() != eCSSUnit_Null &&
michael@0 544 yValue.GetUnit() != eCSSUnit_Null &&
michael@0 545 xValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 546 yValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 547 zValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 548 xValue.GetUnit() != eCSSUnit_Initial &&
michael@0 549 yValue.GetUnit() != eCSSUnit_Initial &&
michael@0 550 zValue.GetUnit() != eCSSUnit_Initial &&
michael@0 551 xValue.GetUnit() != eCSSUnit_Unset &&
michael@0 552 yValue.GetUnit() != eCSSUnit_Unset &&
michael@0 553 zValue.GetUnit() != eCSSUnit_Unset,
michael@0 554 "inappropriate triplet value");
michael@0 555 Reset();
michael@0 556 mUnit = eCSSUnit_Triplet;
michael@0 557 mValue.mTriplet = new nsCSSValueTriplet_heap(xValue, yValue, zValue);
michael@0 558 mValue.mTriplet->AddRef();
michael@0 559 }
michael@0 560
michael@0 561 nsCSSRect& nsCSSValue::SetRectValue()
michael@0 562 {
michael@0 563 Reset();
michael@0 564 mUnit = eCSSUnit_Rect;
michael@0 565 mValue.mRect = new nsCSSRect_heap;
michael@0 566 mValue.mRect->AddRef();
michael@0 567 return *mValue.mRect;
michael@0 568 }
michael@0 569
michael@0 570 nsCSSValueList* nsCSSValue::SetListValue()
michael@0 571 {
michael@0 572 Reset();
michael@0 573 mUnit = eCSSUnit_List;
michael@0 574 mValue.mList = new nsCSSValueList_heap;
michael@0 575 mValue.mList->AddRef();
michael@0 576 return mValue.mList;
michael@0 577 }
michael@0 578
michael@0 579 void nsCSSValue::SetSharedListValue(nsCSSValueSharedList* aList)
michael@0 580 {
michael@0 581 Reset();
michael@0 582 mUnit = eCSSUnit_SharedList;
michael@0 583 mValue.mSharedList = aList;
michael@0 584 mValue.mSharedList->AddRef();
michael@0 585 }
michael@0 586
michael@0 587 void nsCSSValue::SetDependentListValue(nsCSSValueList* aList)
michael@0 588 {
michael@0 589 Reset();
michael@0 590 if (aList) {
michael@0 591 mUnit = eCSSUnit_ListDep;
michael@0 592 mValue.mListDependent = aList;
michael@0 593 }
michael@0 594 }
michael@0 595
michael@0 596 nsCSSValuePairList* nsCSSValue::SetPairListValue()
michael@0 597 {
michael@0 598 Reset();
michael@0 599 mUnit = eCSSUnit_PairList;
michael@0 600 mValue.mPairList = new nsCSSValuePairList_heap;
michael@0 601 mValue.mPairList->AddRef();
michael@0 602 return mValue.mPairList;
michael@0 603 }
michael@0 604
michael@0 605 void nsCSSValue::SetDependentPairListValue(nsCSSValuePairList* aList)
michael@0 606 {
michael@0 607 Reset();
michael@0 608 if (aList) {
michael@0 609 mUnit = eCSSUnit_PairListDep;
michael@0 610 mValue.mPairListDependent = aList;
michael@0 611 }
michael@0 612 }
michael@0 613
michael@0 614 void nsCSSValue::SetAutoValue()
michael@0 615 {
michael@0 616 Reset();
michael@0 617 mUnit = eCSSUnit_Auto;
michael@0 618 }
michael@0 619
michael@0 620 void nsCSSValue::SetInheritValue()
michael@0 621 {
michael@0 622 Reset();
michael@0 623 mUnit = eCSSUnit_Inherit;
michael@0 624 }
michael@0 625
michael@0 626 void nsCSSValue::SetInitialValue()
michael@0 627 {
michael@0 628 Reset();
michael@0 629 mUnit = eCSSUnit_Initial;
michael@0 630 }
michael@0 631
michael@0 632 void nsCSSValue::SetUnsetValue()
michael@0 633 {
michael@0 634 Reset();
michael@0 635 mUnit = eCSSUnit_Unset;
michael@0 636 }
michael@0 637
michael@0 638 void nsCSSValue::SetNoneValue()
michael@0 639 {
michael@0 640 Reset();
michael@0 641 mUnit = eCSSUnit_None;
michael@0 642 }
michael@0 643
michael@0 644 void nsCSSValue::SetAllValue()
michael@0 645 {
michael@0 646 Reset();
michael@0 647 mUnit = eCSSUnit_All;
michael@0 648 }
michael@0 649
michael@0 650 void nsCSSValue::SetNormalValue()
michael@0 651 {
michael@0 652 Reset();
michael@0 653 mUnit = eCSSUnit_Normal;
michael@0 654 }
michael@0 655
michael@0 656 void nsCSSValue::SetSystemFontValue()
michael@0 657 {
michael@0 658 Reset();
michael@0 659 mUnit = eCSSUnit_System_Font;
michael@0 660 }
michael@0 661
michael@0 662 void nsCSSValue::SetDummyValue()
michael@0 663 {
michael@0 664 Reset();
michael@0 665 mUnit = eCSSUnit_Dummy;
michael@0 666 }
michael@0 667
michael@0 668 void nsCSSValue::SetDummyInheritValue()
michael@0 669 {
michael@0 670 Reset();
michael@0 671 mUnit = eCSSUnit_DummyInherit;
michael@0 672 }
michael@0 673
michael@0 674 void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const
michael@0 675 {
michael@0 676 NS_ABORT_IF_FALSE(eCSSUnit_URL == mUnit, "Not a URL value!");
michael@0 677 mozilla::css::ImageValue* image =
michael@0 678 new mozilla::css::ImageValue(mValue.mURL->GetURI(),
michael@0 679 mValue.mURL->mString,
michael@0 680 mValue.mURL->mReferrer,
michael@0 681 mValue.mURL->mOriginPrincipal,
michael@0 682 aDocument);
michael@0 683
michael@0 684 nsCSSValue* writable = const_cast<nsCSSValue*>(this);
michael@0 685 writable->SetImageValue(image);
michael@0 686 }
michael@0 687
michael@0 688 nscolor nsCSSValue::GetColorValue() const
michael@0 689 {
michael@0 690 NS_ABORT_IF_FALSE(IsNumericColorUnit(), "not a color value");
michael@0 691 if (IsFloatColorUnit()) {
michael@0 692 return mValue.mFloatColor->GetColorValue(mUnit);
michael@0 693 }
michael@0 694 return mValue.mColor;
michael@0 695 }
michael@0 696
michael@0 697 bool nsCSSValue::IsNonTransparentColor() const
michael@0 698 {
michael@0 699 // We have the value in the form it was specified in at this point, so we
michael@0 700 // have to look for both the keyword 'transparent' and its equivalent in
michael@0 701 // rgba notation.
michael@0 702 nsDependentString buf;
michael@0 703 return
michael@0 704 (IsIntegerColorUnit() && NS_GET_A(GetColorValue()) > 0) ||
michael@0 705 (IsFloatColorUnit() && mValue.mFloatColor->IsNonTransparentColor()) ||
michael@0 706 (mUnit == eCSSUnit_Ident &&
michael@0 707 !nsGkAtoms::transparent->Equals(GetStringValue(buf))) ||
michael@0 708 (mUnit == eCSSUnit_EnumColor);
michael@0 709 }
michael@0 710
michael@0 711 nsCSSValue::Array*
michael@0 712 nsCSSValue::InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs)
michael@0 713 {
michael@0 714 nsRefPtr<nsCSSValue::Array> func = Array::Create(aNumArgs + 1);
michael@0 715 func->Item(0).SetIntValue(aFunctionId, eCSSUnit_Enumerated);
michael@0 716 SetArrayValue(func, eCSSUnit_Function);
michael@0 717 return func;
michael@0 718 }
michael@0 719
michael@0 720 bool
michael@0 721 nsCSSValue::EqualsFunction(nsCSSKeyword aFunctionId) const
michael@0 722 {
michael@0 723 if (mUnit != eCSSUnit_Function) {
michael@0 724 return false;
michael@0 725 }
michael@0 726
michael@0 727 nsCSSValue::Array* func = mValue.mArray;
michael@0 728 NS_ABORT_IF_FALSE(func && func->Count() >= 1 &&
michael@0 729 func->Item(0).GetUnit() == eCSSUnit_Enumerated,
michael@0 730 "illegally structured function value");
michael@0 731
michael@0 732 nsCSSKeyword thisFunctionId = func->Item(0).GetKeywordValue();
michael@0 733 return thisFunctionId == aFunctionId;
michael@0 734 }
michael@0 735
michael@0 736 // static
michael@0 737 already_AddRefed<nsStringBuffer>
michael@0 738 nsCSSValue::BufferFromString(const nsString& aValue)
michael@0 739 {
michael@0 740 nsRefPtr<nsStringBuffer> buffer = nsStringBuffer::FromString(aValue);
michael@0 741 if (buffer) {
michael@0 742 return buffer.forget();
michael@0 743 }
michael@0 744
michael@0 745 nsString::size_type length = aValue.Length();
michael@0 746
michael@0 747 // NOTE: Alloc prouduces a new, already-addref'd (refcnt = 1) buffer.
michael@0 748 // NOTE: String buffer allocation is currently fallible.
michael@0 749 buffer = nsStringBuffer::Alloc((length + 1) * sizeof(char16_t));
michael@0 750 if (MOZ_UNLIKELY(!buffer)) {
michael@0 751 NS_RUNTIMEABORT("out of memory");
michael@0 752 }
michael@0 753
michael@0 754 char16_t* data = static_cast<char16_t*>(buffer->Data());
michael@0 755 nsCharTraits<char16_t>::copy(data, aValue.get(), length);
michael@0 756 // Null-terminate.
michael@0 757 data[length] = 0;
michael@0 758 return buffer.forget();
michael@0 759 }
michael@0 760
michael@0 761 namespace {
michael@0 762
michael@0 763 struct CSSValueSerializeCalcOps {
michael@0 764 CSSValueSerializeCalcOps(nsCSSProperty aProperty, nsAString& aResult,
michael@0 765 nsCSSValue::Serialization aSerialization)
michael@0 766 : mProperty(aProperty),
michael@0 767 mResult(aResult),
michael@0 768 mValueSerialization(aSerialization)
michael@0 769 {
michael@0 770 }
michael@0 771
michael@0 772 typedef nsCSSValue input_type;
michael@0 773 typedef nsCSSValue::Array input_array_type;
michael@0 774
michael@0 775 static nsCSSUnit GetUnit(const input_type& aValue) {
michael@0 776 return aValue.GetUnit();
michael@0 777 }
michael@0 778
michael@0 779 void Append(const char* aString)
michael@0 780 {
michael@0 781 mResult.AppendASCII(aString);
michael@0 782 }
michael@0 783
michael@0 784 void AppendLeafValue(const input_type& aValue)
michael@0 785 {
michael@0 786 NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Percent ||
michael@0 787 aValue.IsLengthUnit(), "unexpected unit");
michael@0 788 aValue.AppendToString(mProperty, mResult, mValueSerialization);
michael@0 789 }
michael@0 790
michael@0 791 void AppendNumber(const input_type& aValue)
michael@0 792 {
michael@0 793 NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit");
michael@0 794 aValue.AppendToString(mProperty, mResult, mValueSerialization);
michael@0 795 }
michael@0 796
michael@0 797 private:
michael@0 798 nsCSSProperty mProperty;
michael@0 799 nsAString &mResult;
michael@0 800 nsCSSValue::Serialization mValueSerialization;
michael@0 801 };
michael@0 802
michael@0 803 } // anonymous namespace
michael@0 804
michael@0 805 void
michael@0 806 nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
michael@0 807 Serialization aSerialization) const
michael@0 808 {
michael@0 809 // eCSSProperty_UNKNOWN gets used for some recursive calls below.
michael@0 810 NS_ABORT_IF_FALSE((0 <= aProperty &&
michael@0 811 aProperty <= eCSSProperty_COUNT_no_shorthands) ||
michael@0 812 aProperty == eCSSProperty_UNKNOWN,
michael@0 813 "property ID out of range");
michael@0 814
michael@0 815 nsCSSUnit unit = GetUnit();
michael@0 816 if (unit == eCSSUnit_Null) {
michael@0 817 return;
michael@0 818 }
michael@0 819
michael@0 820 if (eCSSUnit_String <= unit && unit <= eCSSUnit_Attr) {
michael@0 821 if (unit == eCSSUnit_Attr) {
michael@0 822 aResult.AppendLiteral("attr(");
michael@0 823 }
michael@0 824 nsAutoString buffer;
michael@0 825 GetStringValue(buffer);
michael@0 826 if (unit == eCSSUnit_String) {
michael@0 827 nsStyleUtil::AppendEscapedCSSString(buffer, aResult);
michael@0 828 } else if (unit == eCSSUnit_Families) {
michael@0 829 // XXX We really need to do *some* escaping.
michael@0 830 aResult.Append(buffer);
michael@0 831 } else {
michael@0 832 nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
michael@0 833 }
michael@0 834 }
michael@0 835 else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Steps) {
michael@0 836 switch (unit) {
michael@0 837 case eCSSUnit_Counter: aResult.AppendLiteral("counter("); break;
michael@0 838 case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break;
michael@0 839 case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break;
michael@0 840 case eCSSUnit_Steps: aResult.AppendLiteral("steps("); break;
michael@0 841 default: break;
michael@0 842 }
michael@0 843
michael@0 844 nsCSSValue::Array *array = GetArrayValue();
michael@0 845 bool mark = false;
michael@0 846 for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) {
michael@0 847 if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) {
michael@0 848 if (unit == eCSSUnit_Array &&
michael@0 849 eCSSProperty_transition_timing_function != aProperty)
michael@0 850 aResult.AppendLiteral(" ");
michael@0 851 else
michael@0 852 aResult.AppendLiteral(", ");
michael@0 853 }
michael@0 854 if (unit == eCSSUnit_Steps && i == 1) {
michael@0 855 NS_ABORT_IF_FALSE(array->Item(i).GetUnit() == eCSSUnit_Enumerated &&
michael@0 856 (array->Item(i).GetIntValue() ==
michael@0 857 NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
michael@0 858 array->Item(i).GetIntValue() ==
michael@0 859 NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END),
michael@0 860 "unexpected value");
michael@0 861 if (array->Item(i).GetIntValue() ==
michael@0 862 NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START) {
michael@0 863 aResult.AppendLiteral("start");
michael@0 864 } else {
michael@0 865 aResult.AppendLiteral("end");
michael@0 866 }
michael@0 867 continue;
michael@0 868 }
michael@0 869 nsCSSProperty prop =
michael@0 870 ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) &&
michael@0 871 i == array->Count() - 1)
michael@0 872 ? eCSSProperty_list_style_type : aProperty;
michael@0 873 if (array->Item(i).GetUnit() != eCSSUnit_Null) {
michael@0 874 array->Item(i).AppendToString(prop, aResult, aSerialization);
michael@0 875 mark = true;
michael@0 876 }
michael@0 877 }
michael@0 878 if (eCSSUnit_Array == unit &&
michael@0 879 aProperty == eCSSProperty_transition_timing_function) {
michael@0 880 aResult.AppendLiteral(")");
michael@0 881 }
michael@0 882 }
michael@0 883 /* Although Function is backed by an Array, we'll handle it separately
michael@0 884 * because it's a bit quirky.
michael@0 885 */
michael@0 886 else if (eCSSUnit_Function == unit) {
michael@0 887 const nsCSSValue::Array* array = GetArrayValue();
michael@0 888 NS_ABORT_IF_FALSE(array->Count() >= 1,
michael@0 889 "Functions must have at least one element for the name.");
michael@0 890
michael@0 891 /* Append the function name. */
michael@0 892 const nsCSSValue& functionName = array->Item(0);
michael@0 893 if (functionName.GetUnit() == eCSSUnit_Enumerated) {
michael@0 894 // We assume that the first argument is always of nsCSSKeyword type.
michael@0 895 const nsCSSKeyword functionId = functionName.GetKeywordValue();
michael@0 896 NS_ConvertASCIItoUTF16 ident(nsCSSKeywords::GetStringValue(functionId));
michael@0 897 // Bug 721136: Normalize the identifier to lowercase, except that things
michael@0 898 // like scaleX should have the last character capitalized. This matches
michael@0 899 // what other browsers do.
michael@0 900 switch (functionId) {
michael@0 901 case eCSSKeyword_rotatex:
michael@0 902 case eCSSKeyword_scalex:
michael@0 903 case eCSSKeyword_skewx:
michael@0 904 case eCSSKeyword_translatex:
michael@0 905 ident.Replace(ident.Length() - 1, 1, char16_t('X'));
michael@0 906 break;
michael@0 907
michael@0 908 case eCSSKeyword_rotatey:
michael@0 909 case eCSSKeyword_scaley:
michael@0 910 case eCSSKeyword_skewy:
michael@0 911 case eCSSKeyword_translatey:
michael@0 912 ident.Replace(ident.Length() - 1, 1, char16_t('Y'));
michael@0 913 break;
michael@0 914
michael@0 915 case eCSSKeyword_rotatez:
michael@0 916 case eCSSKeyword_scalez:
michael@0 917 case eCSSKeyword_translatez:
michael@0 918 ident.Replace(ident.Length() - 1, 1, char16_t('Z'));
michael@0 919 break;
michael@0 920
michael@0 921 default:
michael@0 922 break;
michael@0 923 }
michael@0 924 nsStyleUtil::AppendEscapedCSSIdent(ident, aResult);
michael@0 925 } else {
michael@0 926 MOZ_ASSERT(false, "should no longer have non-enumerated functions");
michael@0 927 }
michael@0 928 aResult.AppendLiteral("(");
michael@0 929
michael@0 930 /* Now, step through the function contents, writing each of them as we go. */
michael@0 931 for (size_t index = 1; index < array->Count(); ++index) {
michael@0 932 array->Item(index).AppendToString(aProperty, aResult,
michael@0 933 aSerialization);
michael@0 934
michael@0 935 /* If we're not at the final element, append a comma. */
michael@0 936 if (index + 1 != array->Count())
michael@0 937 aResult.AppendLiteral(", ");
michael@0 938 }
michael@0 939
michael@0 940 /* Finally, append the closing parenthesis. */
michael@0 941 aResult.AppendLiteral(")");
michael@0 942 }
michael@0 943 else if (IsCalcUnit()) {
michael@0 944 NS_ABORT_IF_FALSE(GetUnit() == eCSSUnit_Calc, "unexpected unit");
michael@0 945 CSSValueSerializeCalcOps ops(aProperty, aResult, aSerialization);
michael@0 946 css::SerializeCalc(*this, ops);
michael@0 947 }
michael@0 948 else if (eCSSUnit_Integer == unit) {
michael@0 949 aResult.AppendInt(GetIntValue(), 10);
michael@0 950 }
michael@0 951 else if (eCSSUnit_Enumerated == unit) {
michael@0 952 int32_t intValue = GetIntValue();
michael@0 953 switch(aProperty) {
michael@0 954
michael@0 955
michael@0 956 case eCSSProperty_text_combine_upright:
michael@0 957 if (intValue <= NS_STYLE_TEXT_COMBINE_UPRIGHT_ALL) {
michael@0 958 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
michael@0 959 aResult);
michael@0 960 } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_2) {
michael@0 961 aResult.AppendLiteral("digits 2");
michael@0 962 } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_3) {
michael@0 963 aResult.AppendLiteral("digits 3");
michael@0 964 } else {
michael@0 965 aResult.AppendLiteral("digits 4");
michael@0 966 }
michael@0 967 break;
michael@0 968
michael@0 969 case eCSSProperty_text_decoration_line:
michael@0 970 if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) {
michael@0 971 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
michael@0 972 aResult);
michael@0 973 } else {
michael@0 974 // Ignore the "override all" internal value.
michael@0 975 // (It doesn't have a string representation.)
michael@0 976 intValue &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
michael@0 977 nsStyleUtil::AppendBitmaskCSSValue(
michael@0 978 aProperty, intValue,
michael@0 979 NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
michael@0 980 NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS,
michael@0 981 aResult);
michael@0 982 }
michael@0 983 break;
michael@0 984
michael@0 985 case eCSSProperty_marks:
michael@0 986 if (intValue == NS_STYLE_PAGE_MARKS_NONE) {
michael@0 987 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
michael@0 988 aResult);
michael@0 989 } else {
michael@0 990 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
michael@0 991 NS_STYLE_PAGE_MARKS_CROP,
michael@0 992 NS_STYLE_PAGE_MARKS_REGISTER,
michael@0 993 aResult);
michael@0 994 }
michael@0 995 break;
michael@0 996
michael@0 997 case eCSSProperty_paint_order:
michael@0 998 static_assert
michael@0 999 (NS_STYLE_PAINT_ORDER_BITWIDTH * NS_STYLE_PAINT_ORDER_LAST_VALUE <= 8,
michael@0 1000 "SVGStyleStruct::mPaintOrder and the following cast not big enough");
michael@0 1001 nsStyleUtil::AppendPaintOrderValue(static_cast<uint8_t>(GetIntValue()),
michael@0 1002 aResult);
michael@0 1003 break;
michael@0 1004
michael@0 1005 case eCSSProperty_font_synthesis:
michael@0 1006 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
michael@0 1007 NS_FONT_SYNTHESIS_WEIGHT,
michael@0 1008 NS_FONT_SYNTHESIS_STYLE,
michael@0 1009 aResult);
michael@0 1010 break;
michael@0 1011
michael@0 1012 case eCSSProperty_font_variant_east_asian:
michael@0 1013 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
michael@0 1014 NS_FONT_VARIANT_EAST_ASIAN_JIS78,
michael@0 1015 NS_FONT_VARIANT_EAST_ASIAN_RUBY,
michael@0 1016 aResult);
michael@0 1017 break;
michael@0 1018
michael@0 1019 case eCSSProperty_font_variant_ligatures:
michael@0 1020 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
michael@0 1021 NS_FONT_VARIANT_LIGATURES_NONE,
michael@0 1022 NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL,
michael@0 1023 aResult);
michael@0 1024 break;
michael@0 1025
michael@0 1026 case eCSSProperty_font_variant_numeric:
michael@0 1027 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
michael@0 1028 NS_FONT_VARIANT_NUMERIC_LINING,
michael@0 1029 NS_FONT_VARIANT_NUMERIC_ORDINAL,
michael@0 1030 aResult);
michael@0 1031 break;
michael@0 1032
michael@0 1033 case eCSSProperty_grid_auto_flow:
michael@0 1034 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
michael@0 1035 NS_STYLE_GRID_AUTO_FLOW_NONE,
michael@0 1036 NS_STYLE_GRID_AUTO_FLOW_DENSE,
michael@0 1037 aResult);
michael@0 1038 break;
michael@0 1039
michael@0 1040 case eCSSProperty_grid_auto_position:
michael@0 1041 case eCSSProperty_grid_column_start:
michael@0 1042 case eCSSProperty_grid_column_end:
michael@0 1043 case eCSSProperty_grid_row_start:
michael@0 1044 case eCSSProperty_grid_row_end:
michael@0 1045 // "span" is the only enumerated-unit value for these properties
michael@0 1046 aResult.AppendLiteral("span");
michael@0 1047 break;
michael@0 1048
michael@0 1049 case eCSSProperty_touch_action:
michael@0 1050 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
michael@0 1051 NS_STYLE_TOUCH_ACTION_NONE,
michael@0 1052 NS_STYLE_TOUCH_ACTION_MANIPULATION,
michael@0 1053 aResult);
michael@0 1054 break;
michael@0 1055
michael@0 1056 default:
michael@0 1057 const nsAFlatCString& name = nsCSSProps::LookupPropertyValue(aProperty, intValue);
michael@0 1058 AppendASCIItoUTF16(name, aResult);
michael@0 1059 break;
michael@0 1060 }
michael@0 1061 }
michael@0 1062 else if (eCSSUnit_EnumColor == unit) {
michael@0 1063 // we can lookup the property in the ColorTable and then
michael@0 1064 // get a string mapping the name
michael@0 1065 nsAutoCString str;
michael@0 1066 if (nsCSSProps::GetColorName(GetIntValue(), str)){
michael@0 1067 AppendASCIItoUTF16(str, aResult);
michael@0 1068 } else {
michael@0 1069 NS_ABORT_IF_FALSE(false, "bad color value");
michael@0 1070 }
michael@0 1071 }
michael@0 1072 else if (IsNumericColorUnit(unit)) {
michael@0 1073 if (aSerialization == eNormalized ||
michael@0 1074 unit == eCSSUnit_RGBColor ||
michael@0 1075 unit == eCSSUnit_RGBAColor) {
michael@0 1076 nscolor color = GetColorValue();
michael@0 1077 if (aSerialization == eNormalized &&
michael@0 1078 color == NS_RGBA(0, 0, 0, 0)) {
michael@0 1079 // Use the strictest match for 'transparent' so we do correct
michael@0 1080 // round-tripping of all other rgba() values.
michael@0 1081 aResult.AppendLiteral("transparent");
michael@0 1082 } else {
michael@0 1083 uint8_t a = NS_GET_A(color);
michael@0 1084 bool showAlpha =
michael@0 1085 (aSerialization == eNormalized && a < 255) ||
michael@0 1086 (aSerialization == eAuthorSpecified &&
michael@0 1087 unit == eCSSUnit_RGBAColor);
michael@0 1088 if (showAlpha) {
michael@0 1089 aResult.AppendLiteral("rgba(");
michael@0 1090 } else {
michael@0 1091 aResult.AppendLiteral("rgb(");
michael@0 1092 }
michael@0 1093
michael@0 1094 NS_NAMED_LITERAL_STRING(comma, ", ");
michael@0 1095
michael@0 1096 aResult.AppendInt(NS_GET_R(color), 10);
michael@0 1097 aResult.Append(comma);
michael@0 1098 aResult.AppendInt(NS_GET_G(color), 10);
michael@0 1099 aResult.Append(comma);
michael@0 1100 aResult.AppendInt(NS_GET_B(color), 10);
michael@0 1101 if (showAlpha) {
michael@0 1102 aResult.Append(comma);
michael@0 1103 aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
michael@0 1104 }
michael@0 1105 aResult.Append(char16_t(')'));
michael@0 1106 }
michael@0 1107 } else if (eCSSUnit_HexColor == unit) {
michael@0 1108 nscolor color = GetColorValue();
michael@0 1109 aResult.Append('#');
michael@0 1110 aResult.AppendPrintf("%02x", NS_GET_R(color));
michael@0 1111 aResult.AppendPrintf("%02x", NS_GET_G(color));
michael@0 1112 aResult.AppendPrintf("%02x", NS_GET_B(color));
michael@0 1113 } else if (eCSSUnit_ShortHexColor == unit) {
michael@0 1114 nscolor color = GetColorValue();
michael@0 1115 aResult.Append('#');
michael@0 1116 aResult.AppendInt(NS_GET_R(color) / 0x11, 16);
michael@0 1117 aResult.AppendInt(NS_GET_G(color) / 0x11, 16);
michael@0 1118 aResult.AppendInt(NS_GET_B(color) / 0x11, 16);
michael@0 1119 } else {
michael@0 1120 MOZ_ASSERT(IsFloatColorUnit());
michael@0 1121 mValue.mFloatColor->AppendToString(unit, aResult);
michael@0 1122 }
michael@0 1123 }
michael@0 1124 else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
michael@0 1125 aResult.Append(NS_LITERAL_STRING("url("));
michael@0 1126 nsStyleUtil::AppendEscapedCSSString(
michael@0 1127 nsDependentString(GetOriginalURLValue()), aResult);
michael@0 1128 aResult.Append(NS_LITERAL_STRING(")"));
michael@0 1129 }
michael@0 1130 else if (eCSSUnit_Element == unit) {
michael@0 1131 aResult.Append(NS_LITERAL_STRING("-moz-element(#"));
michael@0 1132 nsAutoString tmpStr;
michael@0 1133 GetStringValue(tmpStr);
michael@0 1134 nsStyleUtil::AppendEscapedCSSIdent(tmpStr, aResult);
michael@0 1135 aResult.Append(NS_LITERAL_STRING(")"));
michael@0 1136 }
michael@0 1137 else if (eCSSUnit_Percent == unit) {
michael@0 1138 aResult.AppendFloat(GetPercentValue() * 100.0f);
michael@0 1139 }
michael@0 1140 else if (eCSSUnit_Percent < unit) { // length unit
michael@0 1141 aResult.AppendFloat(GetFloatValue());
michael@0 1142 }
michael@0 1143 else if (eCSSUnit_Gradient == unit) {
michael@0 1144 nsCSSValueGradient* gradient = GetGradientValue();
michael@0 1145
michael@0 1146 if (gradient->mIsLegacySyntax) {
michael@0 1147 aResult.AppendLiteral("-moz-");
michael@0 1148 }
michael@0 1149 if (gradient->mIsRepeating) {
michael@0 1150 aResult.AppendLiteral("repeating-");
michael@0 1151 }
michael@0 1152 if (gradient->mIsRadial) {
michael@0 1153 aResult.AppendLiteral("radial-gradient(");
michael@0 1154 } else {
michael@0 1155 aResult.AppendLiteral("linear-gradient(");
michael@0 1156 }
michael@0 1157
michael@0 1158 bool needSep = false;
michael@0 1159 if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
michael@0 1160 if (!gradient->mIsExplicitSize) {
michael@0 1161 if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
michael@0 1162 NS_ABORT_IF_FALSE(gradient->GetRadialShape().GetUnit() ==
michael@0 1163 eCSSUnit_Enumerated,
michael@0 1164 "bad unit for radial gradient shape");
michael@0 1165 int32_t intValue = gradient->GetRadialShape().GetIntValue();
michael@0 1166 NS_ABORT_IF_FALSE(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
michael@0 1167 "radial gradient with linear shape?!");
michael@0 1168 AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
michael@0 1169 nsCSSProps::kRadialGradientShapeKTable),
michael@0 1170 aResult);
michael@0 1171 needSep = true;
michael@0 1172 }
michael@0 1173
michael@0 1174 if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) {
michael@0 1175 if (needSep) {
michael@0 1176 aResult.AppendLiteral(" ");
michael@0 1177 }
michael@0 1178 NS_ABORT_IF_FALSE(gradient->GetRadialSize().GetUnit() ==
michael@0 1179 eCSSUnit_Enumerated,
michael@0 1180 "bad unit for radial gradient size");
michael@0 1181 int32_t intValue = gradient->GetRadialSize().GetIntValue();
michael@0 1182 AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
michael@0 1183 nsCSSProps::kRadialGradientSizeKTable),
michael@0 1184 aResult);
michael@0 1185 needSep = true;
michael@0 1186 }
michael@0 1187 } else {
michael@0 1188 NS_ABORT_IF_FALSE(gradient->GetRadiusX().GetUnit() != eCSSUnit_None,
michael@0 1189 "bad unit for radial gradient explicit size");
michael@0 1190 gradient->GetRadiusX().AppendToString(aProperty, aResult,
michael@0 1191 aSerialization);
michael@0 1192 if (gradient->GetRadiusY().GetUnit() != eCSSUnit_None) {
michael@0 1193 aResult.AppendLiteral(" ");
michael@0 1194 gradient->GetRadiusY().AppendToString(aProperty, aResult,
michael@0 1195 aSerialization);
michael@0 1196 }
michael@0 1197 needSep = true;
michael@0 1198 }
michael@0 1199 }
michael@0 1200 if (!gradient->mIsRadial && !gradient->mIsLegacySyntax) {
michael@0 1201 if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
michael@0 1202 gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) {
michael@0 1203 MOZ_ASSERT(gradient->mAngle.GetUnit() == eCSSUnit_None);
michael@0 1204 NS_ABORT_IF_FALSE(gradient->mBgPos.mXValue.GetUnit() == eCSSUnit_Enumerated &&
michael@0 1205 gradient->mBgPos.mYValue.GetUnit() == eCSSUnit_Enumerated,
michael@0 1206 "unexpected unit");
michael@0 1207 aResult.AppendLiteral("to");
michael@0 1208 if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) {
michael@0 1209 aResult.AppendLiteral(" ");
michael@0 1210 gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
michael@0 1211 aResult, aSerialization);
michael@0 1212 }
michael@0 1213 if (!(gradient->mBgPos.mYValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) {
michael@0 1214 aResult.AppendLiteral(" ");
michael@0 1215 gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
michael@0 1216 aResult, aSerialization);
michael@0 1217 }
michael@0 1218 needSep = true;
michael@0 1219 } else if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
michael@0 1220 gradient->mAngle.AppendToString(aProperty, aResult, aSerialization);
michael@0 1221 needSep = true;
michael@0 1222 }
michael@0 1223 } else if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
michael@0 1224 gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None ||
michael@0 1225 gradient->mAngle.GetUnit() != eCSSUnit_None) {
michael@0 1226 if (needSep) {
michael@0 1227 aResult.AppendLiteral(" ");
michael@0 1228 }
michael@0 1229 if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
michael@0 1230 aResult.AppendLiteral("at ");
michael@0 1231 }
michael@0 1232 if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
michael@0 1233 gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
michael@0 1234 aResult, aSerialization);
michael@0 1235 aResult.AppendLiteral(" ");
michael@0 1236 }
michael@0 1237 if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
michael@0 1238 gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
michael@0 1239 aResult, aSerialization);
michael@0 1240 aResult.AppendLiteral(" ");
michael@0 1241 }
michael@0 1242 if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
michael@0 1243 NS_ABORT_IF_FALSE(gradient->mIsLegacySyntax,
michael@0 1244 "angle is allowed only for legacy syntax");
michael@0 1245 gradient->mAngle.AppendToString(aProperty, aResult, aSerialization);
michael@0 1246 }
michael@0 1247 needSep = true;
michael@0 1248 }
michael@0 1249
michael@0 1250 if (gradient->mIsRadial && gradient->mIsLegacySyntax &&
michael@0 1251 (gradient->GetRadialShape().GetUnit() != eCSSUnit_None ||
michael@0 1252 gradient->GetRadialSize().GetUnit() != eCSSUnit_None)) {
michael@0 1253 MOZ_ASSERT(!gradient->mIsExplicitSize);
michael@0 1254 if (needSep) {
michael@0 1255 aResult.AppendLiteral(", ");
michael@0 1256 }
michael@0 1257 if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
michael@0 1258 NS_ABORT_IF_FALSE(gradient->GetRadialShape().GetUnit() ==
michael@0 1259 eCSSUnit_Enumerated,
michael@0 1260 "bad unit for radial gradient shape");
michael@0 1261 int32_t intValue = gradient->GetRadialShape().GetIntValue();
michael@0 1262 NS_ABORT_IF_FALSE(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
michael@0 1263 "radial gradient with linear shape?!");
michael@0 1264 AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
michael@0 1265 nsCSSProps::kRadialGradientShapeKTable),
michael@0 1266 aResult);
michael@0 1267 aResult.AppendLiteral(" ");
michael@0 1268 }
michael@0 1269
michael@0 1270 if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) {
michael@0 1271 NS_ABORT_IF_FALSE(gradient->GetRadialSize().GetUnit() ==
michael@0 1272 eCSSUnit_Enumerated,
michael@0 1273 "bad unit for radial gradient size");
michael@0 1274 int32_t intValue = gradient->GetRadialSize().GetIntValue();
michael@0 1275 AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
michael@0 1276 nsCSSProps::kRadialGradientSizeKTable),
michael@0 1277 aResult);
michael@0 1278 }
michael@0 1279 needSep = true;
michael@0 1280 }
michael@0 1281 if (needSep) {
michael@0 1282 aResult.AppendLiteral(", ");
michael@0 1283 }
michael@0 1284
michael@0 1285 for (uint32_t i = 0 ;;) {
michael@0 1286 gradient->mStops[i].mColor.AppendToString(aProperty, aResult,
michael@0 1287 aSerialization);
michael@0 1288 if (gradient->mStops[i].mLocation.GetUnit() != eCSSUnit_None) {
michael@0 1289 aResult.AppendLiteral(" ");
michael@0 1290 gradient->mStops[i].mLocation.AppendToString(aProperty, aResult,
michael@0 1291 aSerialization);
michael@0 1292 }
michael@0 1293 if (++i == gradient->mStops.Length()) {
michael@0 1294 break;
michael@0 1295 }
michael@0 1296 aResult.AppendLiteral(", ");
michael@0 1297 }
michael@0 1298
michael@0 1299 aResult.AppendLiteral(")");
michael@0 1300 } else if (eCSSUnit_TokenStream == unit) {
michael@0 1301 nsCSSProperty shorthand = mValue.mTokenStream->mShorthandPropertyID;
michael@0 1302 if (shorthand == eCSSProperty_UNKNOWN ||
michael@0 1303 nsCSSProps::PropHasFlags(shorthand, CSS_PROPERTY_IS_ALIAS) ||
michael@0 1304 aProperty == eCSSProperty__x_system_font) {
michael@0 1305 // We treat serialization of aliases like '-moz-transform' as a special
michael@0 1306 // case, since it really wants to be serialized as if it were a longhand
michael@0 1307 // even though it is implemented as a shorthand.
michael@0 1308 aResult.Append(mValue.mTokenStream->mTokenStream);
michael@0 1309 }
michael@0 1310 } else if (eCSSUnit_Pair == unit) {
michael@0 1311 if (eCSSProperty_font_variant_alternates == aProperty) {
michael@0 1312 int32_t intValue = GetPairValue().mXValue.GetIntValue();
michael@0 1313 nsAutoString out;
michael@0 1314
michael@0 1315 // simple, enumerated values
michael@0 1316 nsStyleUtil::AppendBitmaskCSSValue(aProperty,
michael@0 1317 intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK,
michael@0 1318 NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
michael@0 1319 NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
michael@0 1320 out);
michael@0 1321
michael@0 1322 // functional values
michael@0 1323 const nsCSSValueList *list = GetPairValue().mYValue.GetListValue();
michael@0 1324 nsAutoTArray<gfxAlternateValue,8> altValues;
michael@0 1325
michael@0 1326 nsStyleUtil::ComputeFunctionalAlternates(list, altValues);
michael@0 1327 nsStyleUtil::SerializeFunctionalAlternates(altValues, out);
michael@0 1328 aResult.Append(out);
michael@0 1329 } else if (eCSSProperty_grid_auto_position == aProperty) {
michael@0 1330 GetPairValue().mXValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1331 aResult.AppendLiteral(" / ");
michael@0 1332 GetPairValue().mYValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1333 } else {
michael@0 1334 GetPairValue().AppendToString(aProperty, aResult, aSerialization);
michael@0 1335 }
michael@0 1336 } else if (eCSSUnit_Triplet == unit) {
michael@0 1337 GetTripletValue().AppendToString(aProperty, aResult, aSerialization);
michael@0 1338 } else if (eCSSUnit_Rect == unit) {
michael@0 1339 GetRectValue().AppendToString(aProperty, aResult, aSerialization);
michael@0 1340 } else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) {
michael@0 1341 GetListValue()->AppendToString(aProperty, aResult, aSerialization);
michael@0 1342 } else if (eCSSUnit_SharedList == unit) {
michael@0 1343 GetSharedListValue()->AppendToString(aProperty, aResult, aSerialization);
michael@0 1344 } else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) {
michael@0 1345 switch (aProperty) {
michael@0 1346 case eCSSProperty_font_feature_settings:
michael@0 1347 nsStyleUtil::AppendFontFeatureSettings(*this, aResult);
michael@0 1348 break;
michael@0 1349 default:
michael@0 1350 GetPairListValue()->AppendToString(aProperty, aResult, aSerialization);
michael@0 1351 break;
michael@0 1352 }
michael@0 1353 } else if (eCSSUnit_GridTemplateAreas == unit) {
michael@0 1354 const mozilla::css::GridTemplateAreasValue* areas = GetGridTemplateAreas();
michael@0 1355 MOZ_ASSERT(!areas->mTemplates.IsEmpty(),
michael@0 1356 "Unexpected empty array in GridTemplateAreasValue");
michael@0 1357 nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[0], aResult);
michael@0 1358 for (uint32_t i = 1; i < areas->mTemplates.Length(); i++) {
michael@0 1359 aResult.Append(char16_t(' '));
michael@0 1360 nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], aResult);
michael@0 1361 }
michael@0 1362 }
michael@0 1363
michael@0 1364 switch (unit) {
michael@0 1365 case eCSSUnit_Null: break;
michael@0 1366 case eCSSUnit_Auto: aResult.AppendLiteral("auto"); break;
michael@0 1367 case eCSSUnit_Inherit: aResult.AppendLiteral("inherit"); break;
michael@0 1368 case eCSSUnit_Initial: aResult.AppendLiteral("initial"); break;
michael@0 1369 case eCSSUnit_Unset: aResult.AppendLiteral("unset"); break;
michael@0 1370 case eCSSUnit_None: aResult.AppendLiteral("none"); break;
michael@0 1371 case eCSSUnit_Normal: aResult.AppendLiteral("normal"); break;
michael@0 1372 case eCSSUnit_System_Font: aResult.AppendLiteral("-moz-use-system-font"); break;
michael@0 1373 case eCSSUnit_All: aResult.AppendLiteral("all"); break;
michael@0 1374 case eCSSUnit_Dummy:
michael@0 1375 case eCSSUnit_DummyInherit:
michael@0 1376 NS_ABORT_IF_FALSE(false, "should never serialize");
michael@0 1377 break;
michael@0 1378
michael@0 1379 case eCSSUnit_String: break;
michael@0 1380 case eCSSUnit_Ident: break;
michael@0 1381 case eCSSUnit_Families: break;
michael@0 1382 case eCSSUnit_URL: break;
michael@0 1383 case eCSSUnit_Image: break;
michael@0 1384 case eCSSUnit_Element: break;
michael@0 1385 case eCSSUnit_Array: break;
michael@0 1386 case eCSSUnit_Attr:
michael@0 1387 case eCSSUnit_Cubic_Bezier:
michael@0 1388 case eCSSUnit_Steps:
michael@0 1389 case eCSSUnit_Counter:
michael@0 1390 case eCSSUnit_Counters: aResult.Append(char16_t(')')); break;
michael@0 1391 case eCSSUnit_Local_Font: break;
michael@0 1392 case eCSSUnit_Font_Format: break;
michael@0 1393 case eCSSUnit_Function: break;
michael@0 1394 case eCSSUnit_Calc: break;
michael@0 1395 case eCSSUnit_Calc_Plus: break;
michael@0 1396 case eCSSUnit_Calc_Minus: break;
michael@0 1397 case eCSSUnit_Calc_Times_L: break;
michael@0 1398 case eCSSUnit_Calc_Times_R: break;
michael@0 1399 case eCSSUnit_Calc_Divided: break;
michael@0 1400 case eCSSUnit_Integer: break;
michael@0 1401 case eCSSUnit_Enumerated: break;
michael@0 1402 case eCSSUnit_EnumColor: break;
michael@0 1403 case eCSSUnit_RGBColor: break;
michael@0 1404 case eCSSUnit_RGBAColor: break;
michael@0 1405 case eCSSUnit_HexColor: break;
michael@0 1406 case eCSSUnit_ShortHexColor: break;
michael@0 1407 case eCSSUnit_PercentageRGBColor: break;
michael@0 1408 case eCSSUnit_PercentageRGBAColor: break;
michael@0 1409 case eCSSUnit_HSLColor: break;
michael@0 1410 case eCSSUnit_HSLAColor: break;
michael@0 1411 case eCSSUnit_Percent: aResult.Append(char16_t('%')); break;
michael@0 1412 case eCSSUnit_Number: break;
michael@0 1413 case eCSSUnit_Gradient: break;
michael@0 1414 case eCSSUnit_TokenStream: break;
michael@0 1415 case eCSSUnit_Pair: break;
michael@0 1416 case eCSSUnit_Triplet: break;
michael@0 1417 case eCSSUnit_Rect: break;
michael@0 1418 case eCSSUnit_List: break;
michael@0 1419 case eCSSUnit_ListDep: break;
michael@0 1420 case eCSSUnit_SharedList: break;
michael@0 1421 case eCSSUnit_PairList: break;
michael@0 1422 case eCSSUnit_PairListDep: break;
michael@0 1423 case eCSSUnit_GridTemplateAreas: break;
michael@0 1424
michael@0 1425 case eCSSUnit_Inch: aResult.AppendLiteral("in"); break;
michael@0 1426 case eCSSUnit_Millimeter: aResult.AppendLiteral("mm"); break;
michael@0 1427 case eCSSUnit_PhysicalMillimeter: aResult.AppendLiteral("mozmm"); break;
michael@0 1428 case eCSSUnit_Centimeter: aResult.AppendLiteral("cm"); break;
michael@0 1429 case eCSSUnit_Point: aResult.AppendLiteral("pt"); break;
michael@0 1430 case eCSSUnit_Pica: aResult.AppendLiteral("pc"); break;
michael@0 1431
michael@0 1432 case eCSSUnit_ViewportWidth: aResult.AppendLiteral("vw"); break;
michael@0 1433 case eCSSUnit_ViewportHeight: aResult.AppendLiteral("vh"); break;
michael@0 1434 case eCSSUnit_ViewportMin: aResult.AppendLiteral("vmin"); break;
michael@0 1435 case eCSSUnit_ViewportMax: aResult.AppendLiteral("vmax"); break;
michael@0 1436
michael@0 1437 case eCSSUnit_EM: aResult.AppendLiteral("em"); break;
michael@0 1438 case eCSSUnit_XHeight: aResult.AppendLiteral("ex"); break;
michael@0 1439 case eCSSUnit_Char: aResult.AppendLiteral("ch"); break;
michael@0 1440 case eCSSUnit_RootEM: aResult.AppendLiteral("rem"); break;
michael@0 1441
michael@0 1442 case eCSSUnit_Pixel: aResult.AppendLiteral("px"); break;
michael@0 1443
michael@0 1444 case eCSSUnit_Degree: aResult.AppendLiteral("deg"); break;
michael@0 1445 case eCSSUnit_Grad: aResult.AppendLiteral("grad"); break;
michael@0 1446 case eCSSUnit_Radian: aResult.AppendLiteral("rad"); break;
michael@0 1447 case eCSSUnit_Turn: aResult.AppendLiteral("turn"); break;
michael@0 1448
michael@0 1449 case eCSSUnit_Hertz: aResult.AppendLiteral("Hz"); break;
michael@0 1450 case eCSSUnit_Kilohertz: aResult.AppendLiteral("kHz"); break;
michael@0 1451
michael@0 1452 case eCSSUnit_Seconds: aResult.Append(char16_t('s')); break;
michael@0 1453 case eCSSUnit_Milliseconds: aResult.AppendLiteral("ms"); break;
michael@0 1454
michael@0 1455 case eCSSUnit_FlexFraction: aResult.AppendLiteral("fr"); break;
michael@0 1456 }
michael@0 1457 }
michael@0 1458
michael@0 1459 size_t
michael@0 1460 nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 1461 {
michael@0 1462 size_t n = 0;
michael@0 1463
michael@0 1464 switch (GetUnit()) {
michael@0 1465 // No value: nothing extra to measure.
michael@0 1466 case eCSSUnit_Null:
michael@0 1467 case eCSSUnit_Auto:
michael@0 1468 case eCSSUnit_Inherit:
michael@0 1469 case eCSSUnit_Initial:
michael@0 1470 case eCSSUnit_Unset:
michael@0 1471 case eCSSUnit_None:
michael@0 1472 case eCSSUnit_Normal:
michael@0 1473 case eCSSUnit_System_Font:
michael@0 1474 case eCSSUnit_All:
michael@0 1475 case eCSSUnit_Dummy:
michael@0 1476 case eCSSUnit_DummyInherit:
michael@0 1477 break;
michael@0 1478
michael@0 1479 // String
michael@0 1480 case eCSSUnit_String:
michael@0 1481 case eCSSUnit_Ident:
michael@0 1482 case eCSSUnit_Families:
michael@0 1483 case eCSSUnit_Attr:
michael@0 1484 case eCSSUnit_Local_Font:
michael@0 1485 case eCSSUnit_Font_Format:
michael@0 1486 case eCSSUnit_Element:
michael@0 1487 n += mValue.mString->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
michael@0 1488 break;
michael@0 1489
michael@0 1490 // Array
michael@0 1491 case eCSSUnit_Array:
michael@0 1492 case eCSSUnit_Counter:
michael@0 1493 case eCSSUnit_Counters:
michael@0 1494 case eCSSUnit_Cubic_Bezier:
michael@0 1495 case eCSSUnit_Steps:
michael@0 1496 case eCSSUnit_Function:
michael@0 1497 case eCSSUnit_Calc:
michael@0 1498 case eCSSUnit_Calc_Plus:
michael@0 1499 case eCSSUnit_Calc_Minus:
michael@0 1500 case eCSSUnit_Calc_Times_L:
michael@0 1501 case eCSSUnit_Calc_Times_R:
michael@0 1502 case eCSSUnit_Calc_Divided:
michael@0 1503 break;
michael@0 1504
michael@0 1505 // URL
michael@0 1506 case eCSSUnit_URL:
michael@0 1507 n += mValue.mURL->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1508 break;
michael@0 1509
michael@0 1510 // Image
michael@0 1511 case eCSSUnit_Image:
michael@0 1512 // Not yet measured. Measurement may be added later if DMD finds it
michael@0 1513 // worthwhile.
michael@0 1514 break;
michael@0 1515
michael@0 1516 // Gradient
michael@0 1517 case eCSSUnit_Gradient:
michael@0 1518 n += mValue.mGradient->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1519 break;
michael@0 1520
michael@0 1521 // TokenStream
michael@0 1522 case eCSSUnit_TokenStream:
michael@0 1523 n += mValue.mTokenStream->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1524 break;
michael@0 1525
michael@0 1526 // Pair
michael@0 1527 case eCSSUnit_Pair:
michael@0 1528 n += mValue.mPair->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1529 break;
michael@0 1530
michael@0 1531 // Triplet
michael@0 1532 case eCSSUnit_Triplet:
michael@0 1533 n += mValue.mTriplet->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1534 break;
michael@0 1535
michael@0 1536 // Rect
michael@0 1537 case eCSSUnit_Rect:
michael@0 1538 n += mValue.mRect->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1539 break;
michael@0 1540
michael@0 1541 // List
michael@0 1542 case eCSSUnit_List:
michael@0 1543 n += mValue.mList->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1544 break;
michael@0 1545
michael@0 1546 // ListDep: not measured because it's non-owning.
michael@0 1547 case eCSSUnit_ListDep:
michael@0 1548 break;
michael@0 1549
michael@0 1550 // SharedList
michael@0 1551 case eCSSUnit_SharedList:
michael@0 1552 // Makes more sense not to measure, since it most cases the list
michael@0 1553 // will be shared.
michael@0 1554 break;
michael@0 1555
michael@0 1556 // PairList
michael@0 1557 case eCSSUnit_PairList:
michael@0 1558 n += mValue.mPairList->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1559 break;
michael@0 1560
michael@0 1561 // PairListDep: not measured because it's non-owning.
michael@0 1562 case eCSSUnit_PairListDep:
michael@0 1563 break;
michael@0 1564
michael@0 1565 // GridTemplateAreas
michael@0 1566 case eCSSUnit_GridTemplateAreas:
michael@0 1567 n += mValue.mGridTemplateAreas->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1568 break;
michael@0 1569
michael@0 1570 // Int: nothing extra to measure.
michael@0 1571 case eCSSUnit_Integer:
michael@0 1572 case eCSSUnit_Enumerated:
michael@0 1573 case eCSSUnit_EnumColor:
michael@0 1574 break;
michael@0 1575
michael@0 1576 // Integer Color: nothing extra to measure.
michael@0 1577 case eCSSUnit_RGBColor:
michael@0 1578 case eCSSUnit_RGBAColor:
michael@0 1579 case eCSSUnit_HexColor:
michael@0 1580 case eCSSUnit_ShortHexColor:
michael@0 1581 break;
michael@0 1582
michael@0 1583 // Float Color
michael@0 1584 case eCSSUnit_PercentageRGBColor:
michael@0 1585 case eCSSUnit_PercentageRGBAColor:
michael@0 1586 case eCSSUnit_HSLColor:
michael@0 1587 case eCSSUnit_HSLAColor:
michael@0 1588 n += mValue.mFloatColor->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1589 break;
michael@0 1590
michael@0 1591 // Float: nothing extra to measure.
michael@0 1592 case eCSSUnit_Percent:
michael@0 1593 case eCSSUnit_Number:
michael@0 1594 case eCSSUnit_PhysicalMillimeter:
michael@0 1595 case eCSSUnit_ViewportWidth:
michael@0 1596 case eCSSUnit_ViewportHeight:
michael@0 1597 case eCSSUnit_ViewportMin:
michael@0 1598 case eCSSUnit_ViewportMax:
michael@0 1599 case eCSSUnit_EM:
michael@0 1600 case eCSSUnit_XHeight:
michael@0 1601 case eCSSUnit_Char:
michael@0 1602 case eCSSUnit_RootEM:
michael@0 1603 case eCSSUnit_Point:
michael@0 1604 case eCSSUnit_Inch:
michael@0 1605 case eCSSUnit_Millimeter:
michael@0 1606 case eCSSUnit_Centimeter:
michael@0 1607 case eCSSUnit_Pica:
michael@0 1608 case eCSSUnit_Pixel:
michael@0 1609 case eCSSUnit_Degree:
michael@0 1610 case eCSSUnit_Grad:
michael@0 1611 case eCSSUnit_Turn:
michael@0 1612 case eCSSUnit_Radian:
michael@0 1613 case eCSSUnit_Hertz:
michael@0 1614 case eCSSUnit_Kilohertz:
michael@0 1615 case eCSSUnit_Seconds:
michael@0 1616 case eCSSUnit_Milliseconds:
michael@0 1617 case eCSSUnit_FlexFraction:
michael@0 1618 break;
michael@0 1619
michael@0 1620 default:
michael@0 1621 NS_ABORT_IF_FALSE(false, "bad nsCSSUnit");
michael@0 1622 break;
michael@0 1623 }
michael@0 1624
michael@0 1625 return n;
michael@0 1626 }
michael@0 1627
michael@0 1628 // --- nsCSSValueList -----------------
michael@0 1629
michael@0 1630 nsCSSValueList::~nsCSSValueList()
michael@0 1631 {
michael@0 1632 MOZ_COUNT_DTOR(nsCSSValueList);
michael@0 1633 NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, this, mNext);
michael@0 1634 }
michael@0 1635
michael@0 1636 nsCSSValueList*
michael@0 1637 nsCSSValueList::Clone() const
michael@0 1638 {
michael@0 1639 nsCSSValueList* result = new nsCSSValueList(*this);
michael@0 1640 nsCSSValueList* dest = result;
michael@0 1641 const nsCSSValueList* src = this->mNext;
michael@0 1642 while (src) {
michael@0 1643 dest->mNext = new nsCSSValueList(*src);
michael@0 1644 dest = dest->mNext;
michael@0 1645 src = src->mNext;
michael@0 1646 }
michael@0 1647 return result;
michael@0 1648 }
michael@0 1649
michael@0 1650 void
michael@0 1651 nsCSSValueList::CloneInto(nsCSSValueList* aList) const
michael@0 1652 {
michael@0 1653 NS_ASSERTION(!aList->mNext, "Must be an empty list!");
michael@0 1654 aList->mValue = mValue;
michael@0 1655 aList->mNext = mNext ? mNext->Clone() : nullptr;
michael@0 1656 }
michael@0 1657
michael@0 1658 static void
michael@0 1659 AppendValueListToString(const nsCSSValueList* val,
michael@0 1660 nsCSSProperty aProperty, nsAString& aResult,
michael@0 1661 nsCSSValue::Serialization aSerialization)
michael@0 1662 {
michael@0 1663 for (;;) {
michael@0 1664 val->mValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1665 val = val->mNext;
michael@0 1666 if (!val)
michael@0 1667 break;
michael@0 1668
michael@0 1669 if (nsCSSProps::PropHasFlags(aProperty,
michael@0 1670 CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
michael@0 1671 aResult.Append(char16_t(','));
michael@0 1672 aResult.Append(char16_t(' '));
michael@0 1673 }
michael@0 1674 }
michael@0 1675
michael@0 1676 static void
michael@0 1677 AppendGridTemplateToString(const nsCSSValueList* val,
michael@0 1678 nsCSSProperty aProperty, nsAString& aResult,
michael@0 1679 nsCSSValue::Serialization aSerialization)
michael@0 1680 {
michael@0 1681 // This is called for the "list" that's the top-level value of the property.
michael@0 1682 bool isSubgrid = false;
michael@0 1683 for (;;) {
michael@0 1684 bool addSpaceSeparator = true;
michael@0 1685 nsCSSUnit unit = val->mValue.GetUnit();
michael@0 1686
michael@0 1687 if (unit == eCSSUnit_Enumerated &&
michael@0 1688 val->mValue.GetIntValue() == NS_STYLE_GRID_TEMPLATE_SUBGRID) {
michael@0 1689 isSubgrid = true;
michael@0 1690 aResult.AppendLiteral("subgrid");
michael@0 1691
michael@0 1692 } else if (unit == eCSSUnit_Null) {
michael@0 1693 // Empty or omitted <line-names>.
michael@0 1694 if (isSubgrid) {
michael@0 1695 aResult.AppendLiteral("()");
michael@0 1696 } else {
michael@0 1697 // Serializes to nothing.
michael@0 1698 addSpaceSeparator = false; // Avoid a double space.
michael@0 1699 }
michael@0 1700
michael@0 1701 } else if (unit == eCSSUnit_List || unit == eCSSUnit_ListDep) {
michael@0 1702 // Non-empty <line-names>
michael@0 1703 aResult.AppendLiteral("(");
michael@0 1704 AppendValueListToString(val->mValue.GetListValue(), aProperty,
michael@0 1705 aResult, aSerialization);
michael@0 1706 aResult.AppendLiteral(")");
michael@0 1707
michael@0 1708 } else {
michael@0 1709 // <track-size>
michael@0 1710 val->mValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1711 if (!isSubgrid &&
michael@0 1712 val->mNext &&
michael@0 1713 val->mNext->mValue.GetUnit() == eCSSUnit_Null &&
michael@0 1714 !val->mNext->mNext) {
michael@0 1715 // Break out of the loop early to avoid a trailing space.
michael@0 1716 break;
michael@0 1717 }
michael@0 1718 }
michael@0 1719
michael@0 1720 val = val->mNext;
michael@0 1721 if (!val) {
michael@0 1722 break;
michael@0 1723 }
michael@0 1724
michael@0 1725 if (addSpaceSeparator) {
michael@0 1726 aResult.Append(char16_t(' '));
michael@0 1727 }
michael@0 1728 }
michael@0 1729 }
michael@0 1730
michael@0 1731 void
michael@0 1732 nsCSSValueList::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
michael@0 1733 nsCSSValue::Serialization aSerialization) const
michael@0 1734 {
michael@0 1735 if (aProperty == eCSSProperty_grid_template_columns ||
michael@0 1736 aProperty == eCSSProperty_grid_template_rows) {
michael@0 1737 AppendGridTemplateToString(this, aProperty, aResult, aSerialization);
michael@0 1738 } else {
michael@0 1739 AppendValueListToString(this, aProperty, aResult, aSerialization);
michael@0 1740 }
michael@0 1741 }
michael@0 1742
michael@0 1743 bool
michael@0 1744 nsCSSValueList::operator==(const nsCSSValueList& aOther) const
michael@0 1745 {
michael@0 1746 if (this == &aOther)
michael@0 1747 return true;
michael@0 1748
michael@0 1749 const nsCSSValueList *p1 = this, *p2 = &aOther;
michael@0 1750 for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
michael@0 1751 if (p1->mValue != p2->mValue)
michael@0 1752 return false;
michael@0 1753 }
michael@0 1754 return !p1 && !p2; // true if same length, false otherwise
michael@0 1755 }
michael@0 1756
michael@0 1757 size_t
michael@0 1758 nsCSSValueList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 1759 {
michael@0 1760 size_t n = 0;
michael@0 1761 const nsCSSValueList* v = this;
michael@0 1762 while (v) {
michael@0 1763 n += aMallocSizeOf(v);
michael@0 1764 n += v->mValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1765 v = v->mNext;
michael@0 1766 }
michael@0 1767 return n;
michael@0 1768 }
michael@0 1769
michael@0 1770 size_t
michael@0 1771 nsCSSValueList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 1772 {
michael@0 1773 size_t n = aMallocSizeOf(this);
michael@0 1774 n += mValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1775 n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
michael@0 1776 return n;
michael@0 1777 }
michael@0 1778
michael@0 1779 // --- nsCSSValueSharedList -----------------
michael@0 1780
michael@0 1781 nsCSSValueSharedList::~nsCSSValueSharedList()
michael@0 1782 {
michael@0 1783 MOZ_COUNT_DTOR(nsCSSValueSharedList);
michael@0 1784 if (mHead) {
michael@0 1785 NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, mHead, mNext);
michael@0 1786 delete mHead;
michael@0 1787 }
michael@0 1788 }
michael@0 1789
michael@0 1790 void
michael@0 1791 nsCSSValueSharedList::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
michael@0 1792 nsCSSValue::Serialization aSerialization) const
michael@0 1793 {
michael@0 1794 if (mHead) {
michael@0 1795 mHead->AppendToString(aProperty, aResult, aSerialization);
michael@0 1796 }
michael@0 1797 }
michael@0 1798
michael@0 1799 bool
michael@0 1800 nsCSSValueSharedList::operator==(const nsCSSValueSharedList& aOther) const
michael@0 1801 {
michael@0 1802 return !mHead == !aOther.mHead &&
michael@0 1803 (!mHead || *mHead == *aOther.mHead);
michael@0 1804 }
michael@0 1805
michael@0 1806 size_t
michael@0 1807 nsCSSValueSharedList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 1808 {
michael@0 1809 size_t n = 0;
michael@0 1810 n += aMallocSizeOf(this);
michael@0 1811 n += mHead->SizeOfIncludingThis(aMallocSizeOf);
michael@0 1812 return n;
michael@0 1813 }
michael@0 1814
michael@0 1815 // --- nsCSSRect -----------------
michael@0 1816
michael@0 1817 nsCSSRect::nsCSSRect(void)
michael@0 1818 {
michael@0 1819 MOZ_COUNT_CTOR(nsCSSRect);
michael@0 1820 }
michael@0 1821
michael@0 1822 nsCSSRect::nsCSSRect(const nsCSSRect& aCopy)
michael@0 1823 : mTop(aCopy.mTop),
michael@0 1824 mRight(aCopy.mRight),
michael@0 1825 mBottom(aCopy.mBottom),
michael@0 1826 mLeft(aCopy.mLeft)
michael@0 1827 {
michael@0 1828 MOZ_COUNT_CTOR(nsCSSRect);
michael@0 1829 }
michael@0 1830
michael@0 1831 nsCSSRect::~nsCSSRect()
michael@0 1832 {
michael@0 1833 MOZ_COUNT_DTOR(nsCSSRect);
michael@0 1834 }
michael@0 1835
michael@0 1836 void
michael@0 1837 nsCSSRect::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
michael@0 1838 nsCSSValue::Serialization aSerialization) const
michael@0 1839 {
michael@0 1840 NS_ABORT_IF_FALSE(mTop.GetUnit() != eCSSUnit_Null &&
michael@0 1841 mTop.GetUnit() != eCSSUnit_Inherit &&
michael@0 1842 mTop.GetUnit() != eCSSUnit_Initial &&
michael@0 1843 mTop.GetUnit() != eCSSUnit_Unset,
michael@0 1844 "parser should have used a bare value");
michael@0 1845
michael@0 1846 if (eCSSProperty_border_image_slice == aProperty ||
michael@0 1847 eCSSProperty_border_image_width == aProperty ||
michael@0 1848 eCSSProperty_border_image_outset == aProperty) {
michael@0 1849 NS_NAMED_LITERAL_STRING(space, " ");
michael@0 1850
michael@0 1851 mTop.AppendToString(aProperty, aResult, aSerialization);
michael@0 1852 aResult.Append(space);
michael@0 1853 mRight.AppendToString(aProperty, aResult, aSerialization);
michael@0 1854 aResult.Append(space);
michael@0 1855 mBottom.AppendToString(aProperty, aResult, aSerialization);
michael@0 1856 aResult.Append(space);
michael@0 1857 mLeft.AppendToString(aProperty, aResult, aSerialization);
michael@0 1858 } else {
michael@0 1859 NS_NAMED_LITERAL_STRING(comma, ", ");
michael@0 1860
michael@0 1861 aResult.AppendLiteral("rect(");
michael@0 1862 mTop.AppendToString(aProperty, aResult, aSerialization);
michael@0 1863 aResult.Append(comma);
michael@0 1864 mRight.AppendToString(aProperty, aResult, aSerialization);
michael@0 1865 aResult.Append(comma);
michael@0 1866 mBottom.AppendToString(aProperty, aResult, aSerialization);
michael@0 1867 aResult.Append(comma);
michael@0 1868 mLeft.AppendToString(aProperty, aResult, aSerialization);
michael@0 1869 aResult.Append(char16_t(')'));
michael@0 1870 }
michael@0 1871 }
michael@0 1872
michael@0 1873 void nsCSSRect::SetAllSidesTo(const nsCSSValue& aValue)
michael@0 1874 {
michael@0 1875 mTop = aValue;
michael@0 1876 mRight = aValue;
michael@0 1877 mBottom = aValue;
michael@0 1878 mLeft = aValue;
michael@0 1879 }
michael@0 1880
michael@0 1881 size_t
michael@0 1882 nsCSSRect_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 1883 {
michael@0 1884 size_t n = aMallocSizeOf(this);
michael@0 1885 n += mTop .SizeOfExcludingThis(aMallocSizeOf);
michael@0 1886 n += mRight .SizeOfExcludingThis(aMallocSizeOf);
michael@0 1887 n += mBottom.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1888 n += mLeft .SizeOfExcludingThis(aMallocSizeOf);
michael@0 1889 return n;
michael@0 1890 }
michael@0 1891
michael@0 1892 static_assert(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
michael@0 1893 NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3,
michael@0 1894 "box side constants not top/right/bottom/left == 0/1/2/3");
michael@0 1895
michael@0 1896 /* static */ const nsCSSRect::side_type nsCSSRect::sides[4] = {
michael@0 1897 &nsCSSRect::mTop,
michael@0 1898 &nsCSSRect::mRight,
michael@0 1899 &nsCSSRect::mBottom,
michael@0 1900 &nsCSSRect::mLeft,
michael@0 1901 };
michael@0 1902
michael@0 1903 // --- nsCSSValuePair -----------------
michael@0 1904
michael@0 1905 void
michael@0 1906 nsCSSValuePair::AppendToString(nsCSSProperty aProperty,
michael@0 1907 nsAString& aResult,
michael@0 1908 nsCSSValue::Serialization aSerialization) const
michael@0 1909 {
michael@0 1910 mXValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1911 if (mYValue.GetUnit() != eCSSUnit_Null) {
michael@0 1912 aResult.Append(char16_t(' '));
michael@0 1913 mYValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1914 }
michael@0 1915 }
michael@0 1916
michael@0 1917 size_t
michael@0 1918 nsCSSValuePair::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 1919 {
michael@0 1920 size_t n = 0;
michael@0 1921 n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1922 n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1923 return n;
michael@0 1924 }
michael@0 1925
michael@0 1926 size_t
michael@0 1927 nsCSSValuePair_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 1928 {
michael@0 1929 size_t n = aMallocSizeOf(this);
michael@0 1930 n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1931 n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1932 return n;
michael@0 1933 }
michael@0 1934
michael@0 1935 // --- nsCSSValueTriplet -----------------
michael@0 1936
michael@0 1937 void
michael@0 1938 nsCSSValueTriplet::AppendToString(nsCSSProperty aProperty,
michael@0 1939 nsAString& aResult,
michael@0 1940 nsCSSValue::Serialization aSerialization) const
michael@0 1941 {
michael@0 1942 mXValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1943 if (mYValue.GetUnit() != eCSSUnit_Null) {
michael@0 1944 aResult.Append(char16_t(' '));
michael@0 1945 mYValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1946 if (mZValue.GetUnit() != eCSSUnit_Null) {
michael@0 1947 aResult.Append(char16_t(' '));
michael@0 1948 mZValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1949 }
michael@0 1950 }
michael@0 1951 }
michael@0 1952
michael@0 1953 size_t
michael@0 1954 nsCSSValueTriplet_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 1955 {
michael@0 1956 size_t n = aMallocSizeOf(this);
michael@0 1957 n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1958 n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1959 n += mZValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 1960 return n;
michael@0 1961 }
michael@0 1962
michael@0 1963 // --- nsCSSValuePairList -----------------
michael@0 1964
michael@0 1965 nsCSSValuePairList::~nsCSSValuePairList()
michael@0 1966 {
michael@0 1967 MOZ_COUNT_DTOR(nsCSSValuePairList);
michael@0 1968 NS_CSS_DELETE_LIST_MEMBER(nsCSSValuePairList, this, mNext);
michael@0 1969 }
michael@0 1970
michael@0 1971 nsCSSValuePairList*
michael@0 1972 nsCSSValuePairList::Clone() const
michael@0 1973 {
michael@0 1974 nsCSSValuePairList* result = new nsCSSValuePairList(*this);
michael@0 1975 nsCSSValuePairList* dest = result;
michael@0 1976 const nsCSSValuePairList* src = this->mNext;
michael@0 1977 while (src) {
michael@0 1978 dest->mNext = new nsCSSValuePairList(*src);
michael@0 1979 dest = dest->mNext;
michael@0 1980 src = src->mNext;
michael@0 1981 }
michael@0 1982 return result;
michael@0 1983 }
michael@0 1984
michael@0 1985 void
michael@0 1986 nsCSSValuePairList::AppendToString(nsCSSProperty aProperty,
michael@0 1987 nsAString& aResult,
michael@0 1988 nsCSSValue::Serialization aSerialization) const
michael@0 1989 {
michael@0 1990 const nsCSSValuePairList* item = this;
michael@0 1991 for (;;) {
michael@0 1992 NS_ABORT_IF_FALSE(item->mXValue.GetUnit() != eCSSUnit_Null,
michael@0 1993 "unexpected null unit");
michael@0 1994 item->mXValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 1995 if (item->mXValue.GetUnit() != eCSSUnit_Inherit &&
michael@0 1996 item->mXValue.GetUnit() != eCSSUnit_Initial &&
michael@0 1997 item->mXValue.GetUnit() != eCSSUnit_Unset &&
michael@0 1998 item->mYValue.GetUnit() != eCSSUnit_Null) {
michael@0 1999 aResult.Append(char16_t(' '));
michael@0 2000 item->mYValue.AppendToString(aProperty, aResult, aSerialization);
michael@0 2001 }
michael@0 2002 item = item->mNext;
michael@0 2003 if (!item)
michael@0 2004 break;
michael@0 2005
michael@0 2006 if (nsCSSProps::PropHasFlags(aProperty,
michael@0 2007 CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
michael@0 2008 aResult.Append(char16_t(','));
michael@0 2009 aResult.Append(char16_t(' '));
michael@0 2010 }
michael@0 2011 }
michael@0 2012
michael@0 2013 bool
michael@0 2014 nsCSSValuePairList::operator==(const nsCSSValuePairList& aOther) const
michael@0 2015 {
michael@0 2016 if (this == &aOther)
michael@0 2017 return true;
michael@0 2018
michael@0 2019 const nsCSSValuePairList *p1 = this, *p2 = &aOther;
michael@0 2020 for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
michael@0 2021 if (p1->mXValue != p2->mXValue ||
michael@0 2022 p1->mYValue != p2->mYValue)
michael@0 2023 return false;
michael@0 2024 }
michael@0 2025 return !p1 && !p2; // true if same length, false otherwise
michael@0 2026 }
michael@0 2027
michael@0 2028 size_t
michael@0 2029 nsCSSValuePairList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 2030 {
michael@0 2031 size_t n = 0;
michael@0 2032 const nsCSSValuePairList* v = this;
michael@0 2033 while (v) {
michael@0 2034 n += aMallocSizeOf(v);
michael@0 2035 n += v->mXValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 2036 n += v->mYValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 2037 v = v->mNext;
michael@0 2038 }
michael@0 2039 return n;
michael@0 2040 }
michael@0 2041
michael@0 2042 size_t
michael@0 2043 nsCSSValuePairList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 2044 {
michael@0 2045 size_t n = aMallocSizeOf(this);
michael@0 2046 n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 2047 n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
michael@0 2048 n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
michael@0 2049 return n;
michael@0 2050 }
michael@0 2051
michael@0 2052 size_t
michael@0 2053 nsCSSValue::Array::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 2054 {
michael@0 2055 size_t n = aMallocSizeOf(this);
michael@0 2056 for (size_t i = 0; i < mCount; i++) {
michael@0 2057 n += mArray[i].SizeOfExcludingThis(aMallocSizeOf);
michael@0 2058 }
michael@0 2059 return n;
michael@0 2060 }
michael@0 2061
michael@0 2062 css::URLValue::URLValue(nsIURI* aURI, nsStringBuffer* aString,
michael@0 2063 nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
michael@0 2064 : mURI(aURI),
michael@0 2065 mString(aString),
michael@0 2066 mReferrer(aReferrer),
michael@0 2067 mOriginPrincipal(aOriginPrincipal),
michael@0 2068 mURIResolved(true)
michael@0 2069 {
michael@0 2070 NS_ABORT_IF_FALSE(aOriginPrincipal, "Must have an origin principal");
michael@0 2071 mString->AddRef();
michael@0 2072 }
michael@0 2073
michael@0 2074 css::URLValue::URLValue(nsStringBuffer* aString, nsIURI* aBaseURI,
michael@0 2075 nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
michael@0 2076 : mURI(aBaseURI),
michael@0 2077 mString(aString),
michael@0 2078 mReferrer(aReferrer),
michael@0 2079 mOriginPrincipal(aOriginPrincipal),
michael@0 2080 mURIResolved(false)
michael@0 2081 {
michael@0 2082 NS_ABORT_IF_FALSE(aOriginPrincipal, "Must have an origin principal");
michael@0 2083 mString->AddRef();
michael@0 2084 }
michael@0 2085
michael@0 2086 css::URLValue::~URLValue()
michael@0 2087 {
michael@0 2088 mString->Release();
michael@0 2089 }
michael@0 2090
michael@0 2091 bool
michael@0 2092 css::URLValue::operator==(const URLValue& aOther) const
michael@0 2093 {
michael@0 2094 bool eq;
michael@0 2095 return NS_strcmp(nsCSSValue::GetBufferValue(mString),
michael@0 2096 nsCSSValue::GetBufferValue(aOther.mString)) == 0 &&
michael@0 2097 (GetURI() == aOther.GetURI() || // handles null == null
michael@0 2098 (mURI && aOther.mURI &&
michael@0 2099 NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) &&
michael@0 2100 eq)) &&
michael@0 2101 (mOriginPrincipal == aOther.mOriginPrincipal ||
michael@0 2102 (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal,
michael@0 2103 &eq)) && eq));
michael@0 2104 }
michael@0 2105
michael@0 2106 bool
michael@0 2107 css::URLValue::URIEquals(const URLValue& aOther) const
michael@0 2108 {
michael@0 2109 NS_ABORT_IF_FALSE(mURIResolved && aOther.mURIResolved,
michael@0 2110 "How do you know the URIs aren't null?");
michael@0 2111 bool eq;
michael@0 2112 // Worth comparing GetURI() to aOther.GetURI() and mOriginPrincipal to
michael@0 2113 // aOther.mOriginPrincipal, because in the (probably common) case when this
michael@0 2114 // value was one of the ones that in fact did not change this will be our
michael@0 2115 // fast path to equality
michael@0 2116 return (mURI == aOther.mURI ||
michael@0 2117 (NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && eq)) &&
michael@0 2118 (mOriginPrincipal == aOther.mOriginPrincipal ||
michael@0 2119 (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal,
michael@0 2120 &eq)) && eq));
michael@0 2121 }
michael@0 2122
michael@0 2123 nsIURI*
michael@0 2124 css::URLValue::GetURI() const
michael@0 2125 {
michael@0 2126 if (!mURIResolved) {
michael@0 2127 mURIResolved = true;
michael@0 2128 // Be careful to not null out mURI before we've passed it as the base URI
michael@0 2129 nsCOMPtr<nsIURI> newURI;
michael@0 2130 NS_NewURI(getter_AddRefs(newURI),
michael@0 2131 NS_ConvertUTF16toUTF8(nsCSSValue::GetBufferValue(mString)),
michael@0 2132 nullptr, mURI);
michael@0 2133 newURI.swap(mURI);
michael@0 2134 }
michael@0 2135
michael@0 2136 return mURI;
michael@0 2137 }
michael@0 2138
michael@0 2139 size_t
michael@0 2140 css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 2141 {
michael@0 2142 size_t n = aMallocSizeOf(this);
michael@0 2143
michael@0 2144 // This string is unshared.
michael@0 2145 n += mString->SizeOfIncludingThisMustBeUnshared(aMallocSizeOf);
michael@0 2146
michael@0 2147 // Measurement of the following members may be added later if DMD finds it is
michael@0 2148 // worthwhile:
michael@0 2149 // - mURI
michael@0 2150 // - mReferrer
michael@0 2151 // - mOriginPrincipal
michael@0 2152
michael@0 2153 return n;
michael@0 2154 }
michael@0 2155
michael@0 2156
michael@0 2157 css::ImageValue::ImageValue(nsIURI* aURI, nsStringBuffer* aString,
michael@0 2158 nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal,
michael@0 2159 nsIDocument* aDocument)
michael@0 2160 : URLValue(aURI, aString, aReferrer, aOriginPrincipal)
michael@0 2161 {
michael@0 2162 // NB: If aDocument is not the original document, we may not be able to load
michael@0 2163 // images from aDocument. Instead we do the image load from the original doc
michael@0 2164 // and clone it to aDocument.
michael@0 2165 nsIDocument* loadingDoc = aDocument->GetOriginalDocument();
michael@0 2166 if (!loadingDoc) {
michael@0 2167 loadingDoc = aDocument;
michael@0 2168 }
michael@0 2169
michael@0 2170 loadingDoc->StyleImageLoader()->LoadImage(aURI, aOriginPrincipal, aReferrer,
michael@0 2171 this);
michael@0 2172
michael@0 2173 if (loadingDoc != aDocument) {
michael@0 2174 aDocument->StyleImageLoader()->MaybeRegisterCSSImage(this);
michael@0 2175 }
michael@0 2176 }
michael@0 2177
michael@0 2178 static PLDHashOperator
michael@0 2179 ClearRequestHashtable(nsISupports* aKey, nsRefPtr<imgRequestProxy>& aValue,
michael@0 2180 void* aClosure)
michael@0 2181 {
michael@0 2182 mozilla::css::ImageValue* image =
michael@0 2183 static_cast<mozilla::css::ImageValue*>(aClosure);
michael@0 2184 nsIDocument* doc = static_cast<nsIDocument*>(aKey);
michael@0 2185
michael@0 2186 #ifdef DEBUG
michael@0 2187 {
michael@0 2188 nsCOMPtr<nsIDocument> slowDoc = do_QueryInterface(aKey);
michael@0 2189 MOZ_ASSERT(slowDoc == doc);
michael@0 2190 }
michael@0 2191 #endif
michael@0 2192
michael@0 2193 if (doc) {
michael@0 2194 doc->StyleImageLoader()->DeregisterCSSImage(image);
michael@0 2195 }
michael@0 2196
michael@0 2197 if (aValue) {
michael@0 2198 aValue->CancelAndForgetObserver(NS_BINDING_ABORTED);
michael@0 2199 }
michael@0 2200
michael@0 2201 return PL_DHASH_REMOVE;
michael@0 2202 }
michael@0 2203
michael@0 2204 css::ImageValue::~ImageValue()
michael@0 2205 {
michael@0 2206 mRequests.Enumerate(&ClearRequestHashtable, this);
michael@0 2207 }
michael@0 2208
michael@0 2209 nsCSSValueGradientStop::nsCSSValueGradientStop()
michael@0 2210 : mLocation(eCSSUnit_None),
michael@0 2211 mColor(eCSSUnit_Null)
michael@0 2212 {
michael@0 2213 MOZ_COUNT_CTOR(nsCSSValueGradientStop);
michael@0 2214 }
michael@0 2215
michael@0 2216 nsCSSValueGradientStop::nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther)
michael@0 2217 : mLocation(aOther.mLocation),
michael@0 2218 mColor(aOther.mColor)
michael@0 2219 {
michael@0 2220 MOZ_COUNT_CTOR(nsCSSValueGradientStop);
michael@0 2221 }
michael@0 2222
michael@0 2223 nsCSSValueGradientStop::~nsCSSValueGradientStop()
michael@0 2224 {
michael@0 2225 MOZ_COUNT_DTOR(nsCSSValueGradientStop);
michael@0 2226 }
michael@0 2227
michael@0 2228 size_t
michael@0 2229 nsCSSValueGradientStop::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 2230 {
michael@0 2231 size_t n = 0;
michael@0 2232 n += mLocation.SizeOfExcludingThis(aMallocSizeOf);
michael@0 2233 n += mColor .SizeOfExcludingThis(aMallocSizeOf);
michael@0 2234 return n;
michael@0 2235 }
michael@0 2236
michael@0 2237 nsCSSValueGradient::nsCSSValueGradient(bool aIsRadial,
michael@0 2238 bool aIsRepeating)
michael@0 2239 : mIsRadial(aIsRadial),
michael@0 2240 mIsRepeating(aIsRepeating),
michael@0 2241 mIsLegacySyntax(false),
michael@0 2242 mIsExplicitSize(false),
michael@0 2243 mBgPos(eCSSUnit_None),
michael@0 2244 mAngle(eCSSUnit_None)
michael@0 2245 {
michael@0 2246 mRadialValues[0].SetNoneValue();
michael@0 2247 mRadialValues[1].SetNoneValue();
michael@0 2248 }
michael@0 2249
michael@0 2250 size_t
michael@0 2251 nsCSSValueGradient::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 2252 {
michael@0 2253 size_t n = aMallocSizeOf(this);
michael@0 2254 n += mBgPos.SizeOfExcludingThis(aMallocSizeOf);
michael@0 2255 n += mAngle.SizeOfExcludingThis(aMallocSizeOf);
michael@0 2256 n += mRadialValues[0].SizeOfExcludingThis(aMallocSizeOf);
michael@0 2257 n += mRadialValues[1].SizeOfExcludingThis(aMallocSizeOf);
michael@0 2258 n += mStops.SizeOfExcludingThis(aMallocSizeOf);
michael@0 2259 for (uint32_t i = 0; i < mStops.Length(); i++) {
michael@0 2260 n += mStops[i].SizeOfExcludingThis(aMallocSizeOf);
michael@0 2261 }
michael@0 2262 return n;
michael@0 2263 }
michael@0 2264
michael@0 2265 // --- nsCSSValueTokenStream ------------
michael@0 2266
michael@0 2267 nsCSSValueTokenStream::nsCSSValueTokenStream()
michael@0 2268 : mPropertyID(eCSSProperty_UNKNOWN)
michael@0 2269 , mShorthandPropertyID(eCSSProperty_UNKNOWN)
michael@0 2270 {
michael@0 2271 MOZ_COUNT_CTOR(nsCSSValueTokenStream);
michael@0 2272 }
michael@0 2273
michael@0 2274 nsCSSValueTokenStream::~nsCSSValueTokenStream()
michael@0 2275 {
michael@0 2276 MOZ_COUNT_DTOR(nsCSSValueTokenStream);
michael@0 2277 }
michael@0 2278
michael@0 2279 size_t
michael@0 2280 nsCSSValueTokenStream::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 2281 {
michael@0 2282 size_t n = aMallocSizeOf(this);
michael@0 2283 n += mTokenStream.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
michael@0 2284 return n;
michael@0 2285 }
michael@0 2286
michael@0 2287 // --- nsCSSValueFloatColor -------------
michael@0 2288
michael@0 2289 bool
michael@0 2290 nsCSSValueFloatColor::operator==(nsCSSValueFloatColor& aOther) const
michael@0 2291 {
michael@0 2292 return mComponent1 == aOther.mComponent1 &&
michael@0 2293 mComponent2 == aOther.mComponent2 &&
michael@0 2294 mComponent3 == aOther.mComponent3 &&
michael@0 2295 mAlpha == aOther.mAlpha;
michael@0 2296 }
michael@0 2297
michael@0 2298 nscolor
michael@0 2299 nsCSSValueFloatColor::GetColorValue(nsCSSUnit aUnit) const
michael@0 2300 {
michael@0 2301 MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit");
michael@0 2302
michael@0 2303 if (aUnit == eCSSUnit_PercentageRGBColor ||
michael@0 2304 aUnit == eCSSUnit_PercentageRGBAColor) {
michael@0 2305 return NS_RGBA(NSToIntRound(mComponent1 * 255.0f),
michael@0 2306 NSToIntRound(mComponent2 * 255.0f),
michael@0 2307 NSToIntRound(mComponent3 * 255.0f),
michael@0 2308 NSToIntRound(mAlpha * 255.0f));
michael@0 2309 }
michael@0 2310
michael@0 2311 // HSL color
michael@0 2312 MOZ_ASSERT(aUnit == eCSSUnit_HSLColor ||
michael@0 2313 aUnit == eCSSUnit_HSLAColor);
michael@0 2314 nscolor hsl = NS_HSL2RGB(mComponent1, mComponent2, mComponent3);
michael@0 2315 return NS_RGBA(NS_GET_R(hsl),
michael@0 2316 NS_GET_G(hsl),
michael@0 2317 NS_GET_B(hsl),
michael@0 2318 NSToIntRound(mAlpha * 255.0f));
michael@0 2319 }
michael@0 2320
michael@0 2321 bool
michael@0 2322 nsCSSValueFloatColor::IsNonTransparentColor() const
michael@0 2323 {
michael@0 2324 return mAlpha > 0.0f;
michael@0 2325 }
michael@0 2326
michael@0 2327 void
michael@0 2328 nsCSSValueFloatColor::AppendToString(nsCSSUnit aUnit, nsAString& aResult) const
michael@0 2329 {
michael@0 2330 MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit");
michael@0 2331
michael@0 2332 bool hasAlpha = aUnit == eCSSUnit_PercentageRGBAColor ||
michael@0 2333 aUnit == eCSSUnit_HSLAColor;
michael@0 2334 bool isHSL = aUnit == eCSSUnit_HSLColor ||
michael@0 2335 aUnit == eCSSUnit_HSLAColor;
michael@0 2336
michael@0 2337 if (isHSL) {
michael@0 2338 aResult.AppendLiteral("hsl");
michael@0 2339 } else {
michael@0 2340 aResult.AppendLiteral("rgb");
michael@0 2341 }
michael@0 2342 if (hasAlpha) {
michael@0 2343 aResult.AppendLiteral("a(");
michael@0 2344 } else {
michael@0 2345 aResult.Append('(');
michael@0 2346 }
michael@0 2347 if (isHSL) {
michael@0 2348 aResult.AppendFloat(mComponent1 * 360.0f);
michael@0 2349 aResult.AppendLiteral(", ");
michael@0 2350 } else {
michael@0 2351 aResult.AppendFloat(mComponent1 * 100.0f);
michael@0 2352 aResult.AppendLiteral("%, ");
michael@0 2353 }
michael@0 2354 aResult.AppendFloat(mComponent2 * 100.0f);
michael@0 2355 aResult.AppendLiteral("%, ");
michael@0 2356 aResult.AppendFloat(mComponent3 * 100.0f);
michael@0 2357 if (hasAlpha) {
michael@0 2358 aResult.AppendLiteral("%, ");
michael@0 2359 aResult.AppendFloat(mAlpha);
michael@0 2360 aResult.Append(')');
michael@0 2361 } else {
michael@0 2362 aResult.AppendLiteral("%)");
michael@0 2363 }
michael@0 2364 }
michael@0 2365
michael@0 2366 size_t
michael@0 2367 nsCSSValueFloatColor::SizeOfIncludingThis(
michael@0 2368 mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 2369 {
michael@0 2370 size_t n = aMallocSizeOf(this);
michael@0 2371 return n;
michael@0 2372 }
michael@0 2373
michael@0 2374 // --- nsCSSCornerSizes -----------------
michael@0 2375
michael@0 2376 nsCSSCornerSizes::nsCSSCornerSizes(void)
michael@0 2377 {
michael@0 2378 MOZ_COUNT_CTOR(nsCSSCornerSizes);
michael@0 2379 }
michael@0 2380
michael@0 2381 nsCSSCornerSizes::nsCSSCornerSizes(const nsCSSCornerSizes& aCopy)
michael@0 2382 : mTopLeft(aCopy.mTopLeft),
michael@0 2383 mTopRight(aCopy.mTopRight),
michael@0 2384 mBottomRight(aCopy.mBottomRight),
michael@0 2385 mBottomLeft(aCopy.mBottomLeft)
michael@0 2386 {
michael@0 2387 MOZ_COUNT_CTOR(nsCSSCornerSizes);
michael@0 2388 }
michael@0 2389
michael@0 2390 nsCSSCornerSizes::~nsCSSCornerSizes()
michael@0 2391 {
michael@0 2392 MOZ_COUNT_DTOR(nsCSSCornerSizes);
michael@0 2393 }
michael@0 2394
michael@0 2395 void
michael@0 2396 nsCSSCornerSizes::Reset()
michael@0 2397 {
michael@0 2398 NS_FOR_CSS_FULL_CORNERS(corner) {
michael@0 2399 this->GetCorner(corner).Reset();
michael@0 2400 }
michael@0 2401 }
michael@0 2402
michael@0 2403 static_assert(NS_CORNER_TOP_LEFT == 0 && NS_CORNER_TOP_RIGHT == 1 &&
michael@0 2404 NS_CORNER_BOTTOM_RIGHT == 2 && NS_CORNER_BOTTOM_LEFT == 3,
michael@0 2405 "box corner constants not tl/tr/br/bl == 0/1/2/3");
michael@0 2406
michael@0 2407 /* static */ const nsCSSCornerSizes::corner_type
michael@0 2408 nsCSSCornerSizes::corners[4] = {
michael@0 2409 &nsCSSCornerSizes::mTopLeft,
michael@0 2410 &nsCSSCornerSizes::mTopRight,
michael@0 2411 &nsCSSCornerSizes::mBottomRight,
michael@0 2412 &nsCSSCornerSizes::mBottomLeft,
michael@0 2413 };
michael@0 2414
michael@0 2415 size_t
michael@0 2416 mozilla::css::GridTemplateAreasValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 2417 {
michael@0 2418 size_t n = mNamedAreas.SizeOfExcludingThis(aMallocSizeOf);
michael@0 2419 n += mTemplates.SizeOfIncludingThis(aMallocSizeOf);
michael@0 2420 return n;
michael@0 2421 }

mercurial