Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/style/nsROCSSPrimitiveValue.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
/* DOM object representing values in DOM computed style */
8
9
#include "nsROCSSPrimitiveValue.h"
10
11
#include "nsPresContext.h"
12
#include "nsStyleUtil.h"
13
#include "nsDOMCSSRGBColor.h"
14
#include "nsDOMCSSRect.h"
15
#include "nsIURI.h"
16
#include "nsError.h"
17
18
using namespace mozilla;
19
using namespace mozilla::dom;
20
21
nsROCSSPrimitiveValue::nsROCSSPrimitiveValue()
22
  : CSSValue(), mType(CSS_PX)
23
0
{
24
0
  mValue.mAppUnits = 0;
25
0
}
26
27
28
nsROCSSPrimitiveValue::~nsROCSSPrimitiveValue()
29
0
{
30
0
  Reset();
31
0
}
32
33
nsresult
34
nsROCSSPrimitiveValue::GetCssText(nsAString& aCssText)
35
0
{
36
0
  nsAutoString tmpStr;
37
0
  aCssText.Truncate();
38
0
  nsresult result = NS_OK;
39
0
40
0
  switch (mType) {
41
0
    case CSS_PX:
42
0
      {
43
0
        float val = nsPresContext::AppUnitsToFloatCSSPixels(mValue.mAppUnits);
44
0
        nsStyleUtil::AppendCSSNumber(val, tmpStr);
45
0
        tmpStr.AppendLiteral("px");
46
0
        break;
47
0
      }
48
0
    case CSS_IDENT:
49
0
      {
50
0
        AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue.mKeyword),
51
0
                          tmpStr);
52
0
        break;
53
0
      }
54
0
    case CSS_STRING:
55
0
    case CSS_COUNTER: /* FIXME: COUNTER should use an object */
56
0
      {
57
0
        tmpStr.Append(mValue.mString);
58
0
        break;
59
0
      }
60
0
    case CSS_URI:
61
0
      {
62
0
        if (mValue.mURI) {
63
0
          nsAutoCString specUTF8;
64
0
          nsresult rv = mValue.mURI->GetSpec(specUTF8);
65
0
          NS_ENSURE_SUCCESS(rv, rv);
66
0
67
0
          tmpStr.AssignLiteral("url(");
68
0
          nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(specUTF8),
69
0
                                              tmpStr);
70
0
          tmpStr.Append(')');
71
0
        } else {
72
0
          // http://dev.w3.org/csswg/css3-values/#attr defines
73
0
          // 'about:invalid' as the default value for url attributes,
74
0
          // so let's also use it here as the default computed value
75
0
          // for invalid URLs.
76
0
          tmpStr.AssignLiteral(u"url(about:invalid)");
77
0
        }
78
0
        break;
79
0
      }
80
0
    case CSS_ATTR:
81
0
      {
82
0
        tmpStr.AppendLiteral("attr(");
83
0
        tmpStr.Append(mValue.mString);
84
0
        tmpStr.Append(char16_t(')'));
85
0
        break;
86
0
      }
87
0
    case CSS_PERCENTAGE:
88
0
      {
89
0
        nsStyleUtil::AppendCSSNumber(mValue.mFloat * 100, tmpStr);
90
0
        tmpStr.Append(char16_t('%'));
91
0
        break;
92
0
      }
93
0
    case CSS_NUMBER:
94
0
      {
95
0
        nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
96
0
        break;
97
0
      }
98
0
    case CSS_NUMBER_INT32:
99
0
      {
100
0
        tmpStr.AppendInt(mValue.mInt32);
101
0
        break;
102
0
      }
103
0
    case CSS_NUMBER_UINT32:
104
0
      {
105
0
        tmpStr.AppendInt(mValue.mUint32);
106
0
        break;
107
0
      }
108
0
    case CSS_DEG:
109
0
      {
110
0
        nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
111
0
        tmpStr.AppendLiteral("deg");
112
0
        break;
113
0
      }
114
0
    case CSS_GRAD:
115
0
      {
116
0
        nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
117
0
        tmpStr.AppendLiteral("grad");
118
0
        break;
119
0
      }
120
0
    case CSS_RAD:
121
0
      {
122
0
        nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
123
0
        tmpStr.AppendLiteral("rad");
124
0
        break;
125
0
      }
126
0
    case CSS_TURN:
127
0
      {
128
0
        nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
129
0
        tmpStr.AppendLiteral("turn");
130
0
        break;
131
0
      }
132
0
    case CSS_RECT:
133
0
      {
134
0
        NS_ASSERTION(mValue.mRect, "mValue.mRect should never be null");
135
0
        NS_NAMED_LITERAL_STRING(comma, ", ");
136
0
        nsAutoString sideValue;
137
0
        tmpStr.AssignLiteral("rect(");
138
0
        // get the top
139
0
        result = mValue.mRect->Top()->GetCssText(sideValue);
140
0
        if (NS_FAILED(result))
141
0
          break;
142
0
        tmpStr.Append(sideValue + comma);
143
0
        // get the right
144
0
        result = mValue.mRect->Right()->GetCssText(sideValue);
145
0
        if (NS_FAILED(result))
146
0
          break;
147
0
        tmpStr.Append(sideValue + comma);
148
0
        // get the bottom
149
0
        result = mValue.mRect->Bottom()->GetCssText(sideValue);
150
0
        if (NS_FAILED(result))
151
0
          break;
152
0
        tmpStr.Append(sideValue + comma);
153
0
        // get the left
154
0
        result = mValue.mRect->Left()->GetCssText(sideValue);
155
0
        if (NS_FAILED(result))
156
0
          break;
157
0
        tmpStr.Append(sideValue + NS_LITERAL_STRING(")"));
158
0
        break;
159
0
      }
160
0
    case CSS_RGBCOLOR:
161
0
      {
162
0
        NS_ASSERTION(mValue.mColor, "mValue.mColor should never be null");
163
0
        ErrorResult error;
164
0
        NS_NAMED_LITERAL_STRING(comma, ", ");
165
0
        nsAutoString colorValue;
166
0
        if (mValue.mColor->HasAlpha())
167
0
          tmpStr.AssignLiteral("rgba(");
168
0
        else
169
0
          tmpStr.AssignLiteral("rgb(");
170
0
171
0
        // get the red component
172
0
        mValue.mColor->Red()->GetCssText(colorValue, error);
173
0
        if (error.Failed())
174
0
          break;
175
0
        tmpStr.Append(colorValue + comma);
176
0
177
0
        // get the green component
178
0
        mValue.mColor->Green()->GetCssText(colorValue, error);
179
0
        if (error.Failed())
180
0
          break;
181
0
        tmpStr.Append(colorValue + comma);
182
0
183
0
        // get the blue component
184
0
        mValue.mColor->Blue()->GetCssText(colorValue, error);
185
0
        if (error.Failed())
186
0
          break;
187
0
        tmpStr.Append(colorValue);
188
0
189
0
        if (mValue.mColor->HasAlpha()) {
190
0
          // get the alpha component
191
0
          mValue.mColor->Alpha()->GetCssText(colorValue, error);
192
0
          if (error.Failed())
193
0
            break;
194
0
          tmpStr.Append(comma + colorValue);
195
0
        }
196
0
197
0
        tmpStr.Append(')');
198
0
199
0
        break;
200
0
      }
201
0
    case CSS_S:
202
0
      {
203
0
        nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
204
0
        tmpStr.Append('s');
205
0
        break;
206
0
      }
207
0
    case CSS_CM:
208
0
    case CSS_MM:
209
0
    case CSS_IN:
210
0
    case CSS_PT:
211
0
    case CSS_PC:
212
0
    case CSS_UNKNOWN:
213
0
    case CSS_EMS:
214
0
    case CSS_EXS:
215
0
    case CSS_MS:
216
0
    case CSS_HZ:
217
0
    case CSS_KHZ:
218
0
    case CSS_DIMENSION:
219
0
      NS_ERROR("We have a bogus value set.  This should not happen");
220
0
      return NS_ERROR_DOM_INVALID_ACCESS_ERR;
221
0
  }
222
0
223
0
  if (NS_SUCCEEDED(result)) {
224
0
    aCssText.Assign(tmpStr);
225
0
  }
226
0
227
0
  return NS_OK;
228
0
}
229
230
void
231
nsROCSSPrimitiveValue::GetCssText(nsString& aText, ErrorResult& aRv)
232
0
{
233
0
  aRv = GetCssText(aText);
234
0
}
235
236
void
237
nsROCSSPrimitiveValue::SetCssText(const nsAString& aText, ErrorResult& aRv)
238
0
{
239
0
  aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
240
0
}
241
242
uint16_t
243
nsROCSSPrimitiveValue::CssValueType() const
244
0
{
245
0
  return CSSValue::CSS_PRIMITIVE_VALUE;
246
0
}
247
248
void
249
nsROCSSPrimitiveValue::SetFloatValue(uint16_t aType, float aVal,
250
                                     ErrorResult& aRv)
251
0
{
252
0
  aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
253
0
}
254
255
float
256
nsROCSSPrimitiveValue::GetFloatValue(uint16_t aUnitType, ErrorResult& aRv)
257
0
{
258
0
  switch(aUnitType) {
259
0
    case CSS_PX:
260
0
      if (mType == CSS_PX) {
261
0
        return nsPresContext::AppUnitsToFloatCSSPixels(mValue.mAppUnits);
262
0
      }
263
0
264
0
      break;
265
0
    case CSS_CM:
266
0
      if (mType == CSS_PX) {
267
0
        return mValue.mAppUnits * CM_PER_INCH_FLOAT / AppUnitsPerCSSInch();
268
0
      }
269
0
270
0
      break;
271
0
    case CSS_MM:
272
0
      if (mType == CSS_PX) {
273
0
        return mValue.mAppUnits * MM_PER_INCH_FLOAT / AppUnitsPerCSSInch();
274
0
      }
275
0
276
0
      break;
277
0
    case CSS_IN:
278
0
      if (mType == CSS_PX) {
279
0
        return mValue.mAppUnits / AppUnitsPerCSSInch();
280
0
      }
281
0
282
0
      break;
283
0
    case CSS_PT:
284
0
      if (mType == CSS_PX) {
285
0
        return mValue.mAppUnits * POINTS_PER_INCH_FLOAT / AppUnitsPerCSSInch();
286
0
      }
287
0
288
0
      break;
289
0
    case CSS_PC:
290
0
      if (mType == CSS_PX) {
291
0
        return mValue.mAppUnits * 6.0f / AppUnitsPerCSSInch();
292
0
      }
293
0
294
0
      break;
295
0
    case CSS_PERCENTAGE:
296
0
      if (mType == CSS_PERCENTAGE) {
297
0
        return mValue.mFloat * 100;
298
0
      }
299
0
300
0
      break;
301
0
    case CSS_NUMBER:
302
0
      if (mType == CSS_NUMBER) {
303
0
        return mValue.mFloat;
304
0
      }
305
0
      if (mType == CSS_NUMBER_INT32) {
306
0
        return mValue.mInt32;
307
0
      }
308
0
      if (mType == CSS_NUMBER_UINT32) {
309
0
        return mValue.mUint32;
310
0
      }
311
0
312
0
      break;
313
0
    case CSS_UNKNOWN:
314
0
    case CSS_EMS:
315
0
    case CSS_EXS:
316
0
    case CSS_DEG:
317
0
    case CSS_RAD:
318
0
    case CSS_GRAD:
319
0
    case CSS_MS:
320
0
    case CSS_S:
321
0
    case CSS_HZ:
322
0
    case CSS_KHZ:
323
0
    case CSS_DIMENSION:
324
0
    case CSS_STRING:
325
0
    case CSS_URI:
326
0
    case CSS_IDENT:
327
0
    case CSS_ATTR:
328
0
    case CSS_COUNTER:
329
0
    case CSS_RECT:
330
0
    case CSS_RGBCOLOR:
331
0
      break;
332
0
  }
333
0
334
0
  aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
335
0
  return 0;
336
0
}
337
338
void
339
nsROCSSPrimitiveValue::SetStringValue(uint16_t aType, const nsAString& aString,
340
                                      mozilla::ErrorResult& aRv)
341
0
{
342
0
  aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
343
0
}
344
345
void
346
nsROCSSPrimitiveValue::GetStringValue(nsString& aReturn, ErrorResult& aRv)
347
0
{
348
0
  switch (mType) {
349
0
    case CSS_IDENT:
350
0
      CopyUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue.mKeyword), aReturn);
351
0
      break;
352
0
    case CSS_STRING:
353
0
    case CSS_ATTR:
354
0
      aReturn.Assign(mValue.mString);
355
0
      break;
356
0
    case CSS_URI: {
357
0
      nsAutoCString spec;
358
0
      if (mValue.mURI) {
359
0
        nsresult rv = mValue.mURI->GetSpec(spec);
360
0
        if (NS_FAILED(rv)) {
361
0
          aRv.Throw(rv);
362
0
          return;
363
0
        }
364
0
      }
365
0
      CopyUTF8toUTF16(spec, aReturn);
366
0
      break;
367
0
    }
368
0
    default:
369
0
      aReturn.Truncate();
370
0
      aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
371
0
      return;
372
0
  }
373
0
}
374
375
void
376
nsROCSSPrimitiveValue::GetCounterValue(ErrorResult& aRv)
377
0
{
378
0
  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
379
0
}
380
381
nsDOMCSSRect*
382
nsROCSSPrimitiveValue::GetRectValue(ErrorResult& aRv)
383
0
{
384
0
  if (mType != CSS_RECT) {
385
0
    aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
386
0
    return nullptr;
387
0
  }
388
0
389
0
  NS_ASSERTION(mValue.mRect, "mValue.mRect should never be null");
390
0
  return mValue.mRect;
391
0
}
392
393
nsDOMCSSRGBColor*
394
nsROCSSPrimitiveValue::GetRGBColorValue(ErrorResult& aRv)
395
0
{
396
0
  if (mType != CSS_RGBCOLOR) {
397
0
    aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
398
0
    return nullptr;
399
0
  }
400
0
401
0
  NS_ASSERTION(mValue.mColor, "mValue.mColor should never be null");
402
0
  return mValue.mColor;
403
0
}
404
405
void
406
nsROCSSPrimitiveValue::SetNumber(float aValue)
407
0
{
408
0
  Reset();
409
0
  mValue.mFloat = aValue;
410
0
  mType = CSS_NUMBER;
411
0
}
412
413
void
414
nsROCSSPrimitiveValue::SetNumber(int32_t aValue)
415
0
{
416
0
  Reset();
417
0
  mValue.mInt32 = aValue;
418
0
  mType = CSS_NUMBER_INT32;
419
0
}
420
421
void
422
nsROCSSPrimitiveValue::SetNumber(uint32_t aValue)
423
0
{
424
0
  Reset();
425
0
  mValue.mUint32 = aValue;
426
0
  mType = CSS_NUMBER_UINT32;
427
0
}
428
429
void
430
nsROCSSPrimitiveValue::SetPercent(float aValue)
431
0
{
432
0
  Reset();
433
0
  mValue.mFloat = aValue;
434
0
  mType = CSS_PERCENTAGE;
435
0
}
436
437
void
438
nsROCSSPrimitiveValue::SetDegree(float aValue)
439
0
{
440
0
  Reset();
441
0
  mValue.mFloat = aValue;
442
0
  mType = CSS_DEG;
443
0
}
444
445
void
446
nsROCSSPrimitiveValue::SetGrad(float aValue)
447
0
{
448
0
  Reset();
449
0
  mValue.mFloat = aValue;
450
0
  mType = CSS_GRAD;
451
0
}
452
453
void
454
nsROCSSPrimitiveValue::SetRadian(float aValue)
455
0
{
456
0
  Reset();
457
0
  mValue.mFloat = aValue;
458
0
  mType = CSS_RAD;
459
0
}
460
461
void
462
nsROCSSPrimitiveValue::SetTurn(float aValue)
463
0
{
464
0
  Reset();
465
0
  mValue.mFloat = aValue;
466
0
  mType = CSS_TURN;
467
0
}
468
469
void
470
nsROCSSPrimitiveValue::SetAppUnits(nscoord aValue)
471
0
{
472
0
  Reset();
473
0
  mValue.mAppUnits = aValue;
474
0
  mType = CSS_PX;
475
0
}
476
477
void
478
nsROCSSPrimitiveValue::SetAppUnits(float aValue)
479
0
{
480
0
  SetAppUnits(NSToCoordRound(aValue));
481
0
}
482
483
void
484
nsROCSSPrimitiveValue::SetIdent(nsCSSKeyword aKeyword)
485
0
{
486
0
  MOZ_ASSERT(aKeyword != eCSSKeyword_UNKNOWN &&
487
0
             0 <= aKeyword && aKeyword < eCSSKeyword_COUNT,
488
0
             "bad keyword");
489
0
  Reset();
490
0
  mValue.mKeyword = aKeyword;
491
0
  mType = CSS_IDENT;
492
0
}
493
494
// FIXME: CSS_STRING should imply a string with "" and a need for escaping.
495
void
496
nsROCSSPrimitiveValue::SetString(const nsACString& aString, uint16_t aType)
497
0
{
498
0
  Reset();
499
0
  mValue.mString = ToNewUnicode(aString);
500
0
  if (mValue.mString) {
501
0
    mType = aType;
502
0
  } else {
503
0
    // XXXcaa We should probably let the caller know we are out of memory
504
0
    mType = CSS_UNKNOWN;
505
0
  }
506
0
}
507
508
// FIXME: CSS_STRING should imply a string with "" and a need for escaping.
509
void
510
nsROCSSPrimitiveValue::SetString(const nsAString& aString, uint16_t aType)
511
0
{
512
0
  Reset();
513
0
  mValue.mString = ToNewUnicode(aString);
514
0
  if (mValue.mString) {
515
0
    mType = aType;
516
0
  } else {
517
0
    // XXXcaa We should probably let the caller know we are out of memory
518
0
    mType = CSS_UNKNOWN;
519
0
  }
520
0
}
521
522
void
523
nsROCSSPrimitiveValue::SetURI(nsIURI *aURI)
524
0
{
525
0
  Reset();
526
0
  mValue.mURI = aURI;
527
0
  NS_IF_ADDREF(mValue.mURI);
528
0
  mType = CSS_URI;
529
0
}
530
531
void
532
nsROCSSPrimitiveValue::SetColor(nsDOMCSSRGBColor* aColor)
533
0
{
534
0
  MOZ_ASSERT(aColor, "Null RGBColor being set!");
535
0
536
0
  Reset();
537
0
  mValue.mColor = aColor;
538
0
  if (mValue.mColor) {
539
0
    NS_ADDREF(mValue.mColor);
540
0
    mType = CSS_RGBCOLOR;
541
0
  }
542
0
  else {
543
0
    mType = CSS_UNKNOWN;
544
0
  }
545
0
}
546
547
void
548
nsROCSSPrimitiveValue::SetRect(nsDOMCSSRect* aRect)
549
0
{
550
0
  MOZ_ASSERT(aRect, "Null rect being set!");
551
0
552
0
  Reset();
553
0
  mValue.mRect = aRect;
554
0
  if (mValue.mRect) {
555
0
    NS_ADDREF(mValue.mRect);
556
0
    mType = CSS_RECT;
557
0
  }
558
0
  else {
559
0
    mType = CSS_UNKNOWN;
560
0
  }
561
0
}
562
563
void
564
nsROCSSPrimitiveValue::SetTime(float aValue)
565
0
{
566
0
  Reset();
567
0
  mValue.mFloat = aValue;
568
0
  mType = CSS_S;
569
0
}
570
571
void
572
nsROCSSPrimitiveValue::Reset()
573
0
{
574
0
  switch (mType) {
575
0
    case CSS_IDENT:
576
0
      break;
577
0
    case CSS_STRING:
578
0
    case CSS_ATTR:
579
0
    case CSS_COUNTER: // FIXME: Counter should use an object
580
0
      NS_ASSERTION(mValue.mString, "Null string should never happen");
581
0
      free(mValue.mString);
582
0
      mValue.mString = nullptr;
583
0
      break;
584
0
    case CSS_URI:
585
0
      NS_IF_RELEASE(mValue.mURI);
586
0
      break;
587
0
    case CSS_RECT:
588
0
      NS_ASSERTION(mValue.mRect, "Null Rect should never happen");
589
0
      NS_RELEASE(mValue.mRect);
590
0
      break;
591
0
    case CSS_RGBCOLOR:
592
0
      NS_ASSERTION(mValue.mColor, "Null RGBColor should never happen");
593
0
      NS_RELEASE(mValue.mColor);
594
0
      break;
595
0
  }
596
0
597
0
  mType = CSS_UNKNOWN;
598
0
}
599
600
uint16_t
601
nsROCSSPrimitiveValue::PrimitiveType()
602
0
{
603
0
  // New value types were introduced but not added to CSS OM.
604
0
  // Return CSS_UNKNOWN to avoid exposing CSS_TURN to content.
605
0
  if (mType > CSS_RGBCOLOR) {
606
0
    if (mType == CSS_NUMBER_INT32 || mType == CSS_NUMBER_UINT32) {
607
0
      return CSS_NUMBER;
608
0
    }
609
0
    return CSS_UNKNOWN;
610
0
  }
611
0
  return mType;
612
0
}