Attachment #523743: patch 0: implement step-start, step-end, and steps() for bug #435442

View | Details | Raw Unified | Return to bug 435442
Collapse All | Expand All

(-)a/layout/base/nsStyleConsts.h (+2 lines)
Line     Link Here 
 Lines 642-657   static inline mozilla::css::Side operato Link Here 
642
#define NS_STYLE_TEXT_TRANSFORM_UPPERCASE       3
642
#define NS_STYLE_TEXT_TRANSFORM_UPPERCASE       3
643
643
644
// See nsStyleDisplay
644
// See nsStyleDisplay
645
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE         0
645
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE         0
646
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR       1
646
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR       1
647
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN      2
647
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN      2
648
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT     3
648
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT     3
649
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT  4
649
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT  4
650
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START   5
651
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END     6
650
652
651
// See nsStyleText
653
// See nsStyleText
652
// Note: these values pickup after the text-align values because there
654
// Note: these values pickup after the text-align values because there
653
// are a few html cases where an object can have both types of
655
// are a few html cases where an object can have both types of
654
// alignment applied with a single attribute
656
// alignment applied with a single attribute
655
#define NS_STYLE_VERTICAL_ALIGN_BASELINE             11
657
#define NS_STYLE_VERTICAL_ALIGN_BASELINE             11
656
#define NS_STYLE_VERTICAL_ALIGN_SUB                  12
658
#define NS_STYLE_VERTICAL_ALIGN_SUB                  12
657
#define NS_STYLE_VERTICAL_ALIGN_SUPER                13
659
#define NS_STYLE_VERTICAL_ALIGN_SUPER                13
(-)a/layout/style/nsCSSKeywordList.h (+2 lines)
Line     Link Here 
 Lines 432-447   CSS_KEY(small-caption, small_caption) Link Here 
432
CSS_KEY(smaller, smaller)
432
CSS_KEY(smaller, smaller)
433
CSS_KEY(soft, soft)
433
CSS_KEY(soft, soft)
434
CSS_KEY(solid, solid)
434
CSS_KEY(solid, solid)
435
CSS_KEY(spell-out, spell_out)
435
CSS_KEY(spell-out, spell_out)
436
CSS_KEY(square, square)
436
CSS_KEY(square, square)
437
CSS_KEY(start, start)
437
CSS_KEY(start, start)
438
CSS_KEY(static, static)
438
CSS_KEY(static, static)
439
CSS_KEY(status-bar, status_bar)
439
CSS_KEY(status-bar, status_bar)
440
CSS_KEY(step-end, step_end)
441
CSS_KEY(step-start, step_start)
440
CSS_KEY(stretch, stretch)
442
CSS_KEY(stretch, stretch)
441
CSS_KEY(stretch-to-fit, stretch_to_fit)
443
CSS_KEY(stretch-to-fit, stretch_to_fit)
442
CSS_KEY(stroke, stroke)
444
CSS_KEY(stroke, stroke)
443
CSS_KEY(sub, sub)
445
CSS_KEY(sub, sub)
444
CSS_KEY(super, super)
446
CSS_KEY(super, super)
445
CSS_KEY(sw-resize, sw_resize)
447
CSS_KEY(sw-resize, sw_resize)
446
CSS_KEY(table, table)
448
CSS_KEY(table, table)
447
CSS_KEY(table-caption, table_caption)
449
CSS_KEY(table-caption, table_caption)
(-)a/layout/style/nsCSSParser.cpp (-5 / +54 lines)
Line     Link Here 
 Lines 108-124   namespace css = mozilla::css; Link Here 
108
#define VARIANT_ATTR            0x001000  //
108
#define VARIANT_ATTR            0x001000  //
109
#define VARIANT_IDENTIFIER      0x002000  // D
109
#define VARIANT_IDENTIFIER      0x002000  // D
110
#define VARIANT_AUTO            0x010000  // A
110
#define VARIANT_AUTO            0x010000  // A
111
#define VARIANT_INHERIT         0x020000  // H eCSSUnit_Initial, eCSSUnit_Inherit
111
#define VARIANT_INHERIT         0x020000  // H eCSSUnit_Initial, eCSSUnit_Inherit
112
#define VARIANT_NONE            0x040000  // O
112
#define VARIANT_NONE            0x040000  // O
113
#define VARIANT_NORMAL          0x080000  // M
113
#define VARIANT_NORMAL          0x080000  // M
114
#define VARIANT_SYSFONT         0x100000  // eCSSUnit_System_Font
114
#define VARIANT_SYSFONT         0x100000  // eCSSUnit_System_Font
115
#define VARIANT_GRADIENT        0x200000  // eCSSUnit_Gradient
115
#define VARIANT_GRADIENT        0x200000  // eCSSUnit_Gradient
116
#define VARIANT_CUBIC_BEZIER    0x400000  // CSS transition timing function
116
#define VARIANT_TIMING_FUNCTION 0x400000  // cubic-bezier() and steps()
117
#define VARIANT_ALL             0x800000  //
117
#define VARIANT_ALL             0x800000  //
118
#define VARIANT_IMAGE_RECT    0x01000000  // eCSSUnit_Function
118
#define VARIANT_IMAGE_RECT    0x01000000  // eCSSUnit_Function
119
// This is an extra bit that says that a VARIANT_ANGLE allows unitless zero:
119
// This is an extra bit that says that a VARIANT_ANGLE allows unitless zero:
120
#define VARIANT_ZERO_ANGLE    0x02000000  // unitless zero for angles
120
#define VARIANT_ZERO_ANGLE    0x02000000  // unitless zero for angles
121
#define VARIANT_CALC          0x04000000  // eCSSUnit_Calc
121
#define VARIANT_CALC          0x04000000  // eCSSUnit_Calc
122
#define VARIANT_ELEMENT       0x08000000  // eCSSUnit_Element
122
#define VARIANT_ELEMENT       0x08000000  // eCSSUnit_Element
123
123
124
// Common combinations of variants
124
// Common combinations of variants
 Lines 149-165   namespace css = mozilla::css; Link Here 
149
#define VARIANT_HUK  (VARIANT_HK | VARIANT_URL)
149
#define VARIANT_HUK  (VARIANT_HK | VARIANT_URL)
150
#define VARIANT_HUO  (VARIANT_INHERIT | VARIANT_URL | VARIANT_NONE)
150
#define VARIANT_HUO  (VARIANT_INHERIT | VARIANT_URL | VARIANT_NONE)
151
#define VARIANT_AHUO (VARIANT_AUTO | VARIANT_HUO)
151
#define VARIANT_AHUO (VARIANT_AUTO | VARIANT_HUO)
152
#define VARIANT_HPN  (VARIANT_INHERIT | VARIANT_PERCENT | VARIANT_NUMBER)
152
#define VARIANT_HPN  (VARIANT_INHERIT | VARIANT_PERCENT | VARIANT_NUMBER)
153
#define VARIANT_HN   (VARIANT_INHERIT | VARIANT_NUMBER)
153
#define VARIANT_HN   (VARIANT_INHERIT | VARIANT_NUMBER)
154
#define VARIANT_HON  (VARIANT_HN | VARIANT_NONE)
154
#define VARIANT_HON  (VARIANT_HN | VARIANT_NONE)
155
#define VARIANT_HOS  (VARIANT_INHERIT | VARIANT_NONE | VARIANT_STRING)
155
#define VARIANT_HOS  (VARIANT_INHERIT | VARIANT_NONE | VARIANT_STRING)
156
#define VARIANT_LPN  (VARIANT_LP | VARIANT_NUMBER)
156
#define VARIANT_LPN  (VARIANT_LP | VARIANT_NUMBER)
157
#define VARIANT_TIMING_FUNCTION (VARIANT_KEYWORD | VARIANT_CUBIC_BEZIER)
158
#define VARIANT_UK   (VARIANT_URL | VARIANT_KEYWORD)
157
#define VARIANT_UK   (VARIANT_URL | VARIANT_KEYWORD)
159
#define VARIANT_UO   (VARIANT_URL | VARIANT_NONE)
158
#define VARIANT_UO   (VARIANT_URL | VARIANT_NONE)
160
#define VARIANT_ANGLE_OR_ZERO (VARIANT_ANGLE | VARIANT_ZERO_ANGLE)
159
#define VARIANT_ANGLE_OR_ZERO (VARIANT_ANGLE | VARIANT_ZERO_ANGLE)
161
#define VARIANT_TRANSFORM_LPCALC (VARIANT_LP | VARIANT_CALC)
160
#define VARIANT_TRANSFORM_LPCALC (VARIANT_LP | VARIANT_CALC)
162
#define VARIANT_IMAGE (VARIANT_URL | VARIANT_NONE | VARIANT_GRADIENT | \
161
#define VARIANT_IMAGE (VARIANT_URL | VARIANT_NONE | VARIANT_GRADIENT | \
163
                       VARIANT_IMAGE_RECT | VARIANT_ELEMENT)
162
                       VARIANT_IMAGE_RECT | VARIANT_ELEMENT)
164
163
165
// This lives here because it depends on the above macros.
164
// This lives here because it depends on the above macros.
 Lines 512-527   protected: Link Here 
512
  PRBool ParseShadowItem(nsCSSValue& aValue, PRBool aIsBoxShadow);
511
  PRBool ParseShadowItem(nsCSSValue& aValue, PRBool aIsBoxShadow);
513
  PRBool ParseShadowList(nsCSSProperty aProperty);
512
  PRBool ParseShadowList(nsCSSProperty aProperty);
514
  PRBool ParseTransitionProperty();
513
  PRBool ParseTransitionProperty();
515
  PRBool ParseTransition();
514
  PRBool ParseTransition();
516
  PRBool ParseTransitionTimingFunctionValues(nsCSSValue& aValue);
515
  PRBool ParseTransitionTimingFunctionValues(nsCSSValue& aValue);
517
  PRBool ParseTransitionTimingFunctionValueComponent(float& aComponent,
516
  PRBool ParseTransitionTimingFunctionValueComponent(float& aComponent,
518
                                                     char aStop,
517
                                                     char aStop,
519
                                                     PRBool aCheckRange);
518
                                                     PRBool aCheckRange);
519
  PRBool ParseTransitionStepTimingFunctionValues(nsCSSValue& aValue);
520
520
521
#ifdef MOZ_SVG
521
#ifdef MOZ_SVG
522
  PRBool ParsePaint(nsCSSProperty aPropID);
522
  PRBool ParsePaint(nsCSSProperty aPropID);
523
  PRBool ParseDasharray();
523
  PRBool ParseDasharray();
524
  PRBool ParseMarker();
524
  PRBool ParseMarker();
525
#endif
525
#endif
526
526
527
  // Reused utility parsing routines
527
  // Reused utility parsing routines
 Lines 4222-4238   CSSParserImpl::TranslateDimension(nsCSSV Link Here 
4222
  VARIANT_ATTR | \
4222
  VARIANT_ATTR | \
4223
  VARIANT_IDENTIFIER | \
4223
  VARIANT_IDENTIFIER | \
4224
  VARIANT_AUTO | \
4224
  VARIANT_AUTO | \
4225
  VARIANT_INHERIT | \
4225
  VARIANT_INHERIT | \
4226
  VARIANT_NONE | \
4226
  VARIANT_NONE | \
4227
  VARIANT_NORMAL | \
4227
  VARIANT_NORMAL | \
4228
  VARIANT_SYSFONT | \
4228
  VARIANT_SYSFONT | \
4229
  VARIANT_GRADIENT | \
4229
  VARIANT_GRADIENT | \
4230
  VARIANT_CUBIC_BEZIER | \
4230
  VARIANT_TIMING_FUNCTION | \
4231
  VARIANT_ALL | \
4231
  VARIANT_ALL | \
4232
  VARIANT_CALC
4232
  VARIANT_CALC
4233
4233
4234
// Note that callers passing VARIANT_CALC in aVariantMask will get
4234
// Note that callers passing VARIANT_CALC in aVariantMask will get
4235
// full-range parsing inside the calc() expression, and the code that
4235
// full-range parsing inside the calc() expression, and the code that
4236
// computes the calc will be required to clamp the resulting value to an
4236
// computes the calc will be required to clamp the resulting value to an
4237
// appropriate range.
4237
// appropriate range.
4238
PRBool
4238
PRBool
 Lines 4494-4518   CSSParserImpl::ParseVariant(nsCSSValue& Link Here 
4494
      (eCSSToken_Function == tk->mType) &&
4494
      (eCSSToken_Function == tk->mType) &&
4495
      tk->mIdent.LowerCaseEqualsLiteral("attr")) {
4495
      tk->mIdent.LowerCaseEqualsLiteral("attr")) {
4496
    if (!ParseAttr(aValue)) {
4496
    if (!ParseAttr(aValue)) {
4497
      SkipUntil(')');
4497
      SkipUntil(')');
4498
      return PR_FALSE;
4498
      return PR_FALSE;
4499
    }
4499
    }
4500
    return PR_TRUE;
4500
    return PR_TRUE;
4501
  }
4501
  }
4502
  if (((aVariantMask & VARIANT_CUBIC_BEZIER) != 0) &&
4502
  if (((aVariantMask & VARIANT_TIMING_FUNCTION) != 0) &&
4503
      (eCSSToken_Function == tk->mType)) {
4503
      (eCSSToken_Function == tk->mType)) {
4504
     if (tk->mIdent.LowerCaseEqualsLiteral("cubic-bezier")) {
4504
    if (tk->mIdent.LowerCaseEqualsLiteral("cubic-bezier")) {
4505
      if (!ParseTransitionTimingFunctionValues(aValue)) {
4505
      if (!ParseTransitionTimingFunctionValues(aValue)) {
4506
        SkipUntil(')');
4506
        SkipUntil(')');
4507
        return PR_FALSE;
4507
        return PR_FALSE;
4508
      }
4508
      }
4509
      return PR_TRUE;
4509
      return PR_TRUE;
4510
    }
4510
    }
4511
    if (tk->mIdent.LowerCaseEqualsLiteral("steps")) {
4512
      if (!ParseTransitionStepTimingFunctionValues(aValue)) {
4513
        SkipUntil(')');
4514
        return PR_FALSE;
4515
      }
4516
      return PR_TRUE;
4517
    }
4511
  }
4518
  }
4512
  if ((aVariantMask & VARIANT_CALC) &&
4519
  if ((aVariantMask & VARIANT_CALC) &&
4513
      (eCSSToken_Function == tk->mType) &&
4520
      (eCSSToken_Function == tk->mType) &&
4514
      tk->mIdent.LowerCaseEqualsLiteral("-moz-calc")) {
4521
      tk->mIdent.LowerCaseEqualsLiteral("-moz-calc")) {
4515
    // calc() currently allows only lengths and percents inside it.
4522
    // calc() currently allows only lengths and percents inside it.
4516
    return ParseCalc(aValue, aVariantMask & VARIANT_LP);
4523
    return ParseCalc(aValue, aVariantMask & VARIANT_LP);
4517
  }
4524
  }
4518
4525
 Lines 7963-7978   CSSParserImpl::ParseTransitionTimingFunc Link Here 
7963
    aComponent = num;
7970
    aComponent = num;
7964
    if (ExpectSymbol(aStop, PR_TRUE)) {
7971
    if (ExpectSymbol(aStop, PR_TRUE)) {
7965
      return PR_TRUE;
7972
      return PR_TRUE;
7966
    }
7973
    }
7967
  }
7974
  }
7968
  return PR_FALSE;
7975
  return PR_FALSE;
7969
}
7976
}
7970
7977
7978
PRBool
7979
CSSParserImpl::ParseTransitionStepTimingFunctionValues(nsCSSValue& aValue)
7980
{
7981
  NS_ASSERTION(!mHavePushBack &&
7982
               mToken.mType == eCSSToken_Function &&
7983
               mToken.mIdent.LowerCaseEqualsLiteral("steps"),
7984
               "unexpected initial state");
7985
7986
  nsRefPtr<nsCSSValue::Array> val = nsCSSValue::Array::Create(2);
7987
7988
  if (!ParsePositiveNonZeroVariant(val->Item(0), VARIANT_INTEGER, nsnull)) {
7989
    return PR_FALSE;
7990
  }
7991
7992
  PRInt32 type = NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END;
7993
  if (ExpectSymbol(',', PR_TRUE)) {
7994
    if (!GetToken(PR_TRUE)) {
7995
      return PR_FALSE;
7996
    }
7997
    type = -1;
7998
    if (mToken.mType == eCSSToken_Ident) {
7999
      if (mToken.mIdent.LowerCaseEqualsLiteral("start")) {
8000
        type = NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START;
8001
      } else if (mToken.mIdent.LowerCaseEqualsLiteral("end")) {
8002
        type = NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END;
8003
      }
8004
    }
8005
    if (type == -1) {
8006
      UngetToken();
8007
      return PR_FALSE;
8008
    }
8009
  }
8010
  val->Item(1).SetIntValue(type, eCSSUnit_Enumerated);
8011
8012
  if (!ExpectSymbol(')', PR_TRUE)) {
8013
    return PR_FALSE;
8014
  }
8015
8016
  aValue.SetArrayValue(val, eCSSUnit_Steps);
8017
  return PR_TRUE;
8018
}
8019
7971
static nsCSSValueList*
8020
static nsCSSValueList*
7972
AppendValueToList(nsCSSValue& aContainer,
8021
AppendValueToList(nsCSSValue& aContainer,
7973
                  nsCSSValueList* aTail,
8022
                  nsCSSValueList* aTail,
7974
                  const nsCSSValue& aValue)
8023
                  const nsCSSValue& aValue)
7975
{
8024
{
7976
  nsCSSValueList* entry;
8025
  nsCSSValueList* entry;
7977
  if (aContainer.GetUnit() == eCSSUnit_Null) {
8026
  if (aContainer.GetUnit() == eCSSUnit_Null) {
7978
    NS_ABORT_IF_FALSE(!aTail, "should not have an entry");
8027
    NS_ABORT_IF_FALSE(!aTail, "should not have an entry");
(-)a/layout/style/nsCSSPropList.h (-1 / +1 lines)
Line     Link Here 
 Lines 2283-2299   CSS_PROP_DISPLAY( Link Here 
2283
    CSS_PROP_NO_OFFSET,
2283
    CSS_PROP_NO_OFFSET,
2284
    eStyleAnimType_None)
2284
    eStyleAnimType_None)
2285
CSS_PROP_DISPLAY(
2285
CSS_PROP_DISPLAY(
2286
    -moz-transition-timing-function,
2286
    -moz-transition-timing-function,
2287
    transition_timing_function,
2287
    transition_timing_function,
2288
    CSS_PROP_DOMPROP_PREFIXED(TransitionTimingFunction),
2288
    CSS_PROP_DOMPROP_PREFIXED(TransitionTimingFunction),
2289
    CSS_PROPERTY_PARSE_VALUE_LIST |
2289
    CSS_PROPERTY_PARSE_VALUE_LIST |
2290
        CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
2290
        CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
2291
    VARIANT_TIMING_FUNCTION, // used by list parsing
2291
    VARIANT_KEYWORD | VARIANT_TIMING_FUNCTION, // used by list parsing
2292
    kTransitionTimingFunctionKTable,
2292
    kTransitionTimingFunctionKTable,
2293
    CSS_PROP_NO_OFFSET,
2293
    CSS_PROP_NO_OFFSET,
2294
    eStyleAnimType_None)
2294
    eStyleAnimType_None)
2295
CSS_PROP_TEXTRESET(
2295
CSS_PROP_TEXTRESET(
2296
    unicode-bidi,
2296
    unicode-bidi,
2297
    unicode_bidi,
2297
    unicode_bidi,
2298
    UnicodeBidi,
2298
    UnicodeBidi,
2299
    CSS_PROPERTY_PARSE_VALUE,
2299
    CSS_PROPERTY_PARSE_VALUE,
(-)a/layout/style/nsCSSProps.cpp (+2 lines)
Line     Link Here 
 Lines 1257-1272   const PRInt32 nsCSSProps::kTextTransform Link Here 
1257
};
1257
};
1258
1258
1259
const PRInt32 nsCSSProps::kTransitionTimingFunctionKTable[] = {
1259
const PRInt32 nsCSSProps::kTransitionTimingFunctionKTable[] = {
1260
  eCSSKeyword_ease, NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE,
1260
  eCSSKeyword_ease, NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE,
1261
  eCSSKeyword_linear, NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR,
1261
  eCSSKeyword_linear, NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR,
1262
  eCSSKeyword_ease_in, NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN,
1262
  eCSSKeyword_ease_in, NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN,
1263
  eCSSKeyword_ease_out, NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT,
1263
  eCSSKeyword_ease_out, NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT,
1264
  eCSSKeyword_ease_in_out, NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT,
1264
  eCSSKeyword_ease_in_out, NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT,
1265
  eCSSKeyword_step_start, NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START,
1266
  eCSSKeyword_step_end, NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END,
1265
  eCSSKeyword_UNKNOWN,-1
1267
  eCSSKeyword_UNKNOWN,-1
1266
};
1268
};
1267
1269
1268
const PRInt32 nsCSSProps::kUnicodeBidiKTable[] = {
1270
const PRInt32 nsCSSProps::kUnicodeBidiKTable[] = {
1269
  eCSSKeyword_normal, NS_STYLE_UNICODE_BIDI_NORMAL,
1271
  eCSSKeyword_normal, NS_STYLE_UNICODE_BIDI_NORMAL,
1270
  eCSSKeyword_embed, NS_STYLE_UNICODE_BIDI_EMBED,
1272
  eCSSKeyword_embed, NS_STYLE_UNICODE_BIDI_EMBED,
1271
  eCSSKeyword_bidi_override, NS_STYLE_UNICODE_BIDI_OVERRIDE,
1273
  eCSSKeyword_bidi_override, NS_STYLE_UNICODE_BIDI_OVERRIDE,
1272
  eCSSKeyword_UNKNOWN,-1
1274
  eCSSKeyword_UNKNOWN,-1
(-)a/layout/style/nsCSSValue.cpp (-1 / +18 lines)
Line     Link Here 
 Lines 686-706   nsCSSValue::AppendToString(nsCSSProperty Link Here 
686
      nsStyleUtil::AppendEscapedCSSString(buffer, aResult);
686
      nsStyleUtil::AppendEscapedCSSString(buffer, aResult);
687
    } else if (unit == eCSSUnit_Families) {
687
    } else if (unit == eCSSUnit_Families) {
688
      // XXX We really need to do *some* escaping.
688
      // XXX We really need to do *some* escaping.
689
      aResult.Append(buffer);
689
      aResult.Append(buffer);
690
    } else {
690
    } else {
691
      nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
691
      nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
692
    }
692
    }
693
  }
693
  }
694
  else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Cubic_Bezier) {
694
  else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Steps) {
695
    switch (unit) {
695
    switch (unit) {
696
      case eCSSUnit_Counter:  aResult.AppendLiteral("counter(");  break;
696
      case eCSSUnit_Counter:  aResult.AppendLiteral("counter(");  break;
697
      case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break;
697
      case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break;
698
      case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break;
698
      case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break;
699
      case eCSSUnit_Steps: aResult.AppendLiteral("steps("); break;
699
      default: break;
700
      default: break;
700
    }
701
    }
701
702
702
    nsCSSValue::Array *array = GetArrayValue();
703
    nsCSSValue::Array *array = GetArrayValue();
703
    PRBool mark = PR_FALSE;
704
    PRBool mark = PR_FALSE;
704
    for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) {
705
    for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) {
705
      if (aProperty == eCSSProperty_border_image && i >= 5) {
706
      if (aProperty == eCSSProperty_border_image && i >= 5) {
706
        if (array->Item(i).GetUnit() == eCSSUnit_Null) {
707
        if (array->Item(i).GetUnit() == eCSSUnit_Null) {
 Lines 712-727   nsCSSValue::AppendToString(nsCSSProperty Link Here 
712
      }
713
      }
713
      if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) {
714
      if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) {
714
        if (unit == eCSSUnit_Array &&
715
        if (unit == eCSSUnit_Array &&
715
            eCSSProperty_transition_timing_function != aProperty)
716
            eCSSProperty_transition_timing_function != aProperty)
716
          aResult.AppendLiteral(" ");
717
          aResult.AppendLiteral(" ");
717
        else
718
        else
718
          aResult.AppendLiteral(", ");
719
          aResult.AppendLiteral(", ");
719
      }
720
      }
721
      if (unit == eCSSUnit_Steps && i == 1) {
722
        NS_ABORT_IF_FALSE(array->Item(i).GetUnit() == eCSSUnit_Enumerated &&
723
                          (array->Item(i).GetIntValue() ==
724
                            NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
725
                           array->Item(i).GetIntValue() ==
726
                            NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END),
727
                          "unexpected value");
728
        if (array->Item(i).GetIntValue() ==
729
              NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START) {
730
          aResult.AppendLiteral("start");
731
        } else {
732
          aResult.AppendLiteral("end");
733
        }
734
        continue;
735
      }
720
      nsCSSProperty prop =
736
      nsCSSProperty prop =
721
        ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) &&
737
        ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) &&
722
         i == array->Count() - 1)
738
         i == array->Count() - 1)
723
        ? eCSSProperty_list_style_type : aProperty;
739
        ? eCSSProperty_list_style_type : aProperty;
724
      if (array->Item(i).GetUnit() != eCSSUnit_Null) {
740
      if (array->Item(i).GetUnit() != eCSSUnit_Null) {
725
        array->Item(i).AppendToString(prop, aResult);
741
        array->Item(i).AppendToString(prop, aResult);
726
        mark = PR_TRUE;
742
        mark = PR_TRUE;
727
      }
743
      }
 Lines 976-991   nsCSSValue::AppendToString(nsCSSProperty Link Here 
976
    case eCSSUnit_Ident:        break;
992
    case eCSSUnit_Ident:        break;
977
    case eCSSUnit_Families:     break;
993
    case eCSSUnit_Families:     break;
978
    case eCSSUnit_URL:          break;
994
    case eCSSUnit_URL:          break;
979
    case eCSSUnit_Image:        break;
995
    case eCSSUnit_Image:        break;
980
    case eCSSUnit_Element:      break;
996
    case eCSSUnit_Element:      break;
981
    case eCSSUnit_Array:        break;
997
    case eCSSUnit_Array:        break;
982
    case eCSSUnit_Attr:
998
    case eCSSUnit_Attr:
983
    case eCSSUnit_Cubic_Bezier:
999
    case eCSSUnit_Cubic_Bezier:
1000
    case eCSSUnit_Steps:
984
    case eCSSUnit_Counter:
1001
    case eCSSUnit_Counter:
985
    case eCSSUnit_Counters:     aResult.Append(PRUnichar(')'));    break;
1002
    case eCSSUnit_Counters:     aResult.Append(PRUnichar(')'));    break;
986
    case eCSSUnit_Local_Font:   break;
1003
    case eCSSUnit_Local_Font:   break;
987
    case eCSSUnit_Font_Format:  break;
1004
    case eCSSUnit_Font_Format:  break;
988
    case eCSSUnit_Function:     break;
1005
    case eCSSUnit_Function:     break;
989
    case eCSSUnit_Calc:         break;
1006
    case eCSSUnit_Calc:         break;
990
    case eCSSUnit_Calc_Plus:    break;
1007
    case eCSSUnit_Calc_Plus:    break;
991
    case eCSSUnit_Calc_Minus:   break;
1008
    case eCSSUnit_Calc_Minus:   break;
(-)a/layout/style/nsCSSValue.h (-7 / +8 lines)
Line     Link Here 
 Lines 110-145   enum nsCSSUnit { Link Here 
110
  eCSSUnit_Local_Font   = 15,     // (PRUnichar*) a local font name
110
  eCSSUnit_Local_Font   = 15,     // (PRUnichar*) a local font name
111
  eCSSUnit_Font_Format  = 16,     // (PRUnichar*) a font format name
111
  eCSSUnit_Font_Format  = 16,     // (PRUnichar*) a font format name
112
  eCSSUnit_Element      = 17,     // (PRUnichar*) an element id
112
  eCSSUnit_Element      = 17,     // (PRUnichar*) an element id
113
113
114
  eCSSUnit_Array        = 20,     // (nsCSSValue::Array*) a list of values
114
  eCSSUnit_Array        = 20,     // (nsCSSValue::Array*) a list of values
115
  eCSSUnit_Counter      = 21,     // (nsCSSValue::Array*) a counter(string,[string]) value
115
  eCSSUnit_Counter      = 21,     // (nsCSSValue::Array*) a counter(string,[string]) value
116
  eCSSUnit_Counters     = 22,     // (nsCSSValue::Array*) a counters(string,string[,string]) value
116
  eCSSUnit_Counters     = 22,     // (nsCSSValue::Array*) a counters(string,string[,string]) value
117
  eCSSUnit_Cubic_Bezier = 23,     // (nsCSSValue::Array*) a list of float values
117
  eCSSUnit_Cubic_Bezier = 23,     // (nsCSSValue::Array*) a list of float values
118
  eCSSUnit_Function     = 24,     // (nsCSSValue::Array*) a function with
118
  eCSSUnit_Steps        = 24,     // (nsCSSValue::Array*) a list of (integer, enumerated)
119
  eCSSUnit_Function     = 25,     // (nsCSSValue::Array*) a function with
119
                                  //  parameters.  First elem of array is name,
120
                                  //  parameters.  First elem of array is name,
120
                                  //  the rest of the values are arguments.
121
                                  //  the rest of the values are arguments.
121
122
122
  // The top level of a calc() expression is eCSSUnit_Calc.  All
123
  // The top level of a calc() expression is eCSSUnit_Calc.  All
123
  // remaining eCSSUnit_Calc_* units only occur inside these toplevel
124
  // remaining eCSSUnit_Calc_* units only occur inside these toplevel
124
  // calc values.
125
  // calc values.
125
126
126
  // eCSSUnit_Calc has an array with exactly 1 element.  eCSSUnit_Calc
127
  // eCSSUnit_Calc has an array with exactly 1 element.  eCSSUnit_Calc
127
  // exists so we can distinguish calc(2em) from 2em as specified values
128
  // exists so we can distinguish calc(2em) from 2em as specified values
128
  // (but we drop this distinction for nsStyleCoord when we store
129
  // (but we drop this distinction for nsStyleCoord when we store
129
  // computed values).
130
  // computed values).
130
  eCSSUnit_Calc         = 25,     // (nsCSSValue::Array*) calc() value
131
  eCSSUnit_Calc         = 30,     // (nsCSSValue::Array*) calc() value
131
  // Plus, Minus, Times_* and Divided have arrays with exactly 2
132
  // Plus, Minus, Times_* and Divided have arrays with exactly 2
132
  // elements.  a + b + c + d is grouped as ((a + b) + c) + d
133
  // elements.  a + b + c + d is grouped as ((a + b) + c) + d
133
  eCSSUnit_Calc_Plus    = 26,     // (nsCSSValue::Array*) + node within calc()
134
  eCSSUnit_Calc_Plus    = 31,     // (nsCSSValue::Array*) + node within calc()
134
  eCSSUnit_Calc_Minus   = 27,     // (nsCSSValue::Array*) - within calc
135
  eCSSUnit_Calc_Minus   = 32,     // (nsCSSValue::Array*) - within calc
135
  eCSSUnit_Calc_Times_L = 28,     // (nsCSSValue::Array*) num * val within calc
136
  eCSSUnit_Calc_Times_L = 33,     // (nsCSSValue::Array*) num * val within calc
136
  eCSSUnit_Calc_Times_R = 29,     // (nsCSSValue::Array*) val * num within calc
137
  eCSSUnit_Calc_Times_R = 34,     // (nsCSSValue::Array*) val * num within calc
137
  eCSSUnit_Calc_Divided = 30,     // (nsCSSValue::Array*) / within calc
138
  eCSSUnit_Calc_Divided = 35,     // (nsCSSValue::Array*) / within calc
138
139
139
  eCSSUnit_URL          = 40,     // (nsCSSValue::URL*) value
140
  eCSSUnit_URL          = 40,     // (nsCSSValue::URL*) value
140
  eCSSUnit_Image        = 41,     // (nsCSSValue::Image*) value
141
  eCSSUnit_Image        = 41,     // (nsCSSValue::Image*) value
141
  eCSSUnit_Gradient     = 42,     // (nsCSSValueGradient*) value
142
  eCSSUnit_Gradient     = 42,     // (nsCSSValueGradient*) value
142
143
143
  eCSSUnit_Pair         = 50,     // (nsCSSValuePair*) pair of values
144
  eCSSUnit_Pair         = 50,     // (nsCSSValuePair*) pair of values
144
  eCSSUnit_Rect         = 51,     // (nsCSSRect*) rectangle (four values)
145
  eCSSUnit_Rect         = 51,     // (nsCSSRect*) rectangle (four values)
145
  eCSSUnit_List         = 52,     // (nsCSSValueList*) list of values
146
  eCSSUnit_List         = 52,     // (nsCSSValueList*) list of values
(-)a/layout/style/nsComputedDOMStyle.cpp (-10 / +31 lines)
Line     Link Here 
 Lines 3877-3913   nsComputedDOMStyle::DoGetTransitionPrope Link Here 
3877
    }
3877
    }
3878
    else
3878
    else
3879
      property->SetString(nsCSSProps::GetStringValue(cssprop));
3879
      property->SetString(nsCSSProps::GetStringValue(cssprop));
3880
  } while (++i < display->mTransitionPropertyCount);
3880
  } while (++i < display->mTransitionPropertyCount);
3881
3881
3882
  return valueList;
3882
  return valueList;
3883
}
3883
}
3884
3884
3885
void
3886
nsComputedDOMStyle::AppendTimingFunction(nsDOMCSSValueList *aValueList,
3887
                                         const nsTimingFunction& aTimingFunction)
3888
{
3889
  nsROCSSPrimitiveValue* timingFunction = GetROCSSPrimitiveValue();
3890
  aValueList->AppendCSSValue(timingFunction);
3891
3892
  if (aTimingFunction.mType == nsTimingFunction::Function) {
3893
    // set the value from the cubic-bezier control points
3894
    // (We could try to regenerate the keywords if we want.)
3895
    timingFunction->SetString(
3896
      nsPrintfCString(64, "cubic-bezier(%f, %f, %f, %f)",
3897
                          aTimingFunction.mFunc.mX1,
3898
                          aTimingFunction.mFunc.mY1,
3899
                          aTimingFunction.mFunc.mX2,
3900
                          aTimingFunction.mFunc.mY2));
3901
  } else {
3902
    nsString tmp;
3903
    tmp.AppendLiteral("steps(");
3904
    tmp.AppendInt(aTimingFunction.mSteps);
3905
    if (aTimingFunction.mType == nsTimingFunction::StepStart) {
3906
      tmp.AppendLiteral(", start)");
3907
    } else {
3908
      tmp.AppendLiteral(", end)");
3909
    }
3910
    timingFunction->SetString(tmp);
3911
  }
3912
}
3913
3885
nsIDOMCSSValue*
3914
nsIDOMCSSValue*
3886
nsComputedDOMStyle::DoGetTransitionTimingFunction()
3915
nsComputedDOMStyle::DoGetTransitionTimingFunction()
3887
{
3916
{
3888
  const nsStyleDisplay* display = GetStyleDisplay();
3917
  const nsStyleDisplay* display = GetStyleDisplay();
3889
3918
3890
  nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE);
3919
  nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE);
3891
3920
3892
  NS_ABORT_IF_FALSE(display->mTransitionTimingFunctionCount > 0,
3921
  NS_ABORT_IF_FALSE(display->mTransitionTimingFunctionCount > 0,
3893
                    "first item must be explicit");
3922
                    "first item must be explicit");
3894
  PRUint32 i = 0;
3923
  PRUint32 i = 0;
3895
  do {
3924
  do {
3896
    const nsTransition *transition = &display->mTransitions[i];
3925
    AppendTimingFunction(valueList,
3897
    nsROCSSPrimitiveValue* timingFunction = GetROCSSPrimitiveValue();
3926
                         display->mTransitions[i].GetTimingFunction());
3898
    valueList->AppendCSSValue(timingFunction);
3899
3900
    // set the value from the cubic-bezier control points
3901
    // (We could try to regenerate the keywords if we want.)
3902
    const nsTimingFunction& tf = transition->GetTimingFunction();
3903
    timingFunction->SetString(
3904
      nsPrintfCString(64, "cubic-bezier(%f, %f, %f, %f)",
3905
                          tf.mX1, tf.mY1, tf.mX2, tf.mY2));
3906
  } while (++i < display->mTransitionTimingFunctionCount);
3927
  } while (++i < display->mTransitionTimingFunctionCount);
3907
3928
3908
  return valueList;
3929
  return valueList;
3909
}
3930
}
3910
3931
3911
#define COMPUTED_STYLE_MAP_ENTRY(_prop, _method)              \
3932
#define COMPUTED_STYLE_MAP_ENTRY(_prop, _method)              \
3912
  { eCSSProperty_##_prop, &nsComputedDOMStyle::DoGet##_method, PR_FALSE }
3933
  { eCSSProperty_##_prop, &nsComputedDOMStyle::DoGet##_method, PR_FALSE }
3913
#define COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_prop, _method)       \
3934
#define COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_prop, _method)       \
(-)a/layout/style/nsComputedDOMStyle.h (+2 lines)
Line     Link Here 
 Lines 163-178   private: Link Here 
163
                                    PRUint32 nsStyleBackground::* aCount,
163
                                    PRUint32 nsStyleBackground::* aCount,
164
                                    const PRInt32 aTable[]);
164
                                    const PRInt32 aTable[]);
165
165
166
  void GetCSSGradientString(const nsStyleGradient* aGradient,
166
  void GetCSSGradientString(const nsStyleGradient* aGradient,
167
                            nsAString& aString);
167
                            nsAString& aString);
168
  void GetImageRectString(nsIURI* aURI,
168
  void GetImageRectString(nsIURI* aURI,
169
                          const nsStyleSides& aCropRect,
169
                          const nsStyleSides& aCropRect,
170
                          nsString& aString);
170
                          nsString& aString);
171
  void AppendTimingFunction(nsDOMCSSValueList *aValueList,
172
                            const nsTimingFunction& aTimingFunction);
171
173
172
  /* Properties queryable as CSSValues.
174
  /* Properties queryable as CSSValues.
173
   * To avoid a name conflict with nsIDOM*CSS2Properties, these are all
175
   * To avoid a name conflict with nsIDOM*CSS2Properties, these are all
174
   * DoGetXXX instead of GetXXX.
176
   * DoGetXXX instead of GetXXX.
175
   */
177
   */
176
178
177
  nsIDOMCSSValue* DoGetAppearance();
179
  nsIDOMCSSValue* DoGetAppearance();
178
180
(-)a/layout/style/nsRuleNode.cpp (+22 lines)
Line     Link Here 
 Lines 3833-3848   nsRuleNode::ComputeDisplayData(void* aSt Link Here 
3833
                         "Need 4 control points");
3833
                         "Need 4 control points");
3834
            transition->SetTimingFunction(
3834
            transition->SetTimingFunction(
3835
              nsTimingFunction(array->Item(0).GetFloatValue(),
3835
              nsTimingFunction(array->Item(0).GetFloatValue(),
3836
                               array->Item(1).GetFloatValue(),
3836
                               array->Item(1).GetFloatValue(),
3837
                               array->Item(2).GetFloatValue(),
3837
                               array->Item(2).GetFloatValue(),
3838
                               array->Item(3).GetFloatValue()));
3838
                               array->Item(3).GetFloatValue()));
3839
          }
3839
          }
3840
          break;
3840
          break;
3841
        case eCSSUnit_Steps:
3842
          {
3843
            nsCSSValue::Array* array =
3844
              timingFunction.list->mValue.GetArrayValue();
3845
            NS_ASSERTION(array && array->Count() == 2,
3846
                         "Need 2 items");
3847
            NS_ASSERTION(array->Item(0).GetUnit() == eCSSUnit_Integer,
3848
                         "unexpected first value");
3849
            NS_ASSERTION(array->Item(1).GetUnit() == eCSSUnit_Enumerated &&
3850
                         (array->Item(1).GetIntValue() ==
3851
                           NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
3852
                          array->Item(1).GetIntValue() ==
3853
                           NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END),
3854
                         "unexpected second value");
3855
            transition->SetTimingFunction(
3856
              nsTimingFunction((
3857
                array->Item(1).GetIntValue() ==
3858
                  NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END)
3859
                  ? nsTimingFunction::StepEnd : nsTimingFunction::StepStart,
3860
                array->Item(0).GetIntValue()));
3861
          }
3862
          break;
3841
        default:
3863
        default:
3842
          NS_NOTREACHED("Invalid transition property unit");
3864
          NS_NOTREACHED("Invalid transition property unit");
3843
      }
3865
      }
3844
    }
3866
    }
3845
3867
3846
    FOR_ALL_TRANSITION_PROPS(p) {
3868
    FOR_ALL_TRANSITION_PROPS(p) {
3847
      const TransitionPropInfo& info = transitionPropInfo[p];
3869
      const TransitionPropInfo& info = transitionPropInfo[p];
3848
      TransitionPropData& d = transitionPropData[p];
3870
      TransitionPropData& d = transitionPropData[p];
(-)a/layout/style/nsStyleStruct.cpp (-4 / +18 lines)
Line     Link Here 
 Lines 1916-1951   nsStyleBackground::Layer::operator==(con Link Here 
1916
         mImage == aOther.mImage;
1916
         mImage == aOther.mImage;
1917
}
1917
}
1918
1918
1919
// --------------------
1919
// --------------------
1920
// nsStyleDisplay
1920
// nsStyleDisplay
1921
//
1921
//
1922
void nsTimingFunction::AssignFromKeyword(PRInt32 aTimingFunctionType)
1922
void nsTimingFunction::AssignFromKeyword(PRInt32 aTimingFunctionType)
1923
{
1923
{
1924
  switch (aTimingFunctionType) {
1925
    case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START:
1926
      mType = StepStart;
1927
      mSteps = 1;
1928
      return;
1929
    case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END:
1930
      mType = StepEnd;
1931
      mSteps = 1;
1932
      return;
1933
    default:
1934
      mType = Function;
1935
      break;
1936
  }
1937
1924
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE == 0);
1938
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE == 0);
1925
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR == 1);
1939
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR == 1);
1926
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN == 2);
1940
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN == 2);
1927
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT == 3);
1941
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT == 3);
1928
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT == 4);
1942
  PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT == 4);
1929
1943
1930
  static const float timingFunctionValues[5][4] = {
1944
  static const float timingFunctionValues[5][4] = {
1931
    { 0.25, 0.10, 0.25, 1.00 }, // ease
1945
    { 0.25, 0.10, 0.25, 1.00 }, // ease
1932
    { 0.00, 0.00, 1.00, 1.00 }, // linear
1946
    { 0.00, 0.00, 1.00, 1.00 }, // linear
1933
    { 0.42, 0.00, 1.00, 1.00 }, // ease-in
1947
    { 0.42, 0.00, 1.00, 1.00 }, // ease-in
1934
    { 0.00, 0.00, 0.58, 1.00 }, // ease-out
1948
    { 0.00, 0.00, 0.58, 1.00 }, // ease-out
1935
    { 0.42, 0.00, 0.58, 1.00 }  // ease-in-out
1949
    { 0.42, 0.00, 0.58, 1.00 }  // ease-in-out
1936
  };
1950
  };
1937
1951
1938
  NS_ABORT_IF_FALSE(0 <= aTimingFunctionType && aTimingFunctionType < 5,
1952
  NS_ABORT_IF_FALSE(0 <= aTimingFunctionType && aTimingFunctionType < 5,
1939
                    "keyword out of range");
1953
                    "keyword out of range");
1940
  mX1 = timingFunctionValues[aTimingFunctionType][0];
1954
  mFunc.mX1 = timingFunctionValues[aTimingFunctionType][0];
1941
  mY1 = timingFunctionValues[aTimingFunctionType][1];
1955
  mFunc.mY1 = timingFunctionValues[aTimingFunctionType][1];
1942
  mX2 = timingFunctionValues[aTimingFunctionType][2];
1956
  mFunc.mX2 = timingFunctionValues[aTimingFunctionType][2];
1943
  mY2 = timingFunctionValues[aTimingFunctionType][3];
1957
  mFunc.mY2 = timingFunctionValues[aTimingFunctionType][3];
1944
}
1958
}
1945
1959
1946
nsTransition::nsTransition(const nsTransition& aCopy)
1960
nsTransition::nsTransition(const nsTransition& aCopy)
1947
  : mTimingFunction(aCopy.mTimingFunction)
1961
  : mTimingFunction(aCopy.mTimingFunction)
1948
  , mDuration(aCopy.mDuration)
1962
  , mDuration(aCopy.mDuration)
1949
  , mDelay(aCopy.mDelay)
1963
  , mDelay(aCopy.mDelay)
1950
  , mProperty(aCopy.mProperty)
1964
  , mProperty(aCopy.mProperty)
1951
  , mUnknownProperty(aCopy.mUnknownProperty)
1965
  , mUnknownProperty(aCopy.mUnknownProperty)
(-)a/layout/style/nsStyleStruct.h (-16 / +52 lines)
Line     Link Here 
 Lines 1304-1346   struct nsStyleVisibility { Link Here 
1304
1304
1305
  PRBool IsVisibleOrCollapsed() const {
1305
  PRBool IsVisibleOrCollapsed() const {
1306
    return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
1306
    return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
1307
            (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
1307
            (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
1308
  }
1308
  }
1309
};
1309
};
1310
1310
1311
struct nsTimingFunction {
1311
struct nsTimingFunction {
1312
  enum Type { Function, StepStart, StepEnd };
1313
1312
  explicit nsTimingFunction(PRInt32 aTimingFunctionType
1314
  explicit nsTimingFunction(PRInt32 aTimingFunctionType
1313
                              = NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE)
1315
                              = NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE)
1314
  {
1316
  {
1315
    AssignFromKeyword(aTimingFunctionType);
1317
    AssignFromKeyword(aTimingFunctionType);
1316
  }
1318
  }
1317
1319
1318
  nsTimingFunction(float x1, float y1, float x2, float y2)
1320
  nsTimingFunction(float x1, float y1, float x2, float y2)
1319
    : mX1(x1)
1321
    : mType(Function)
1320
    , mY1(y1)
1321
    , mX2(x2)
1322
    , mY2(y2)
1323
  {}
1324
1325
  float mX1;
1326
  float mY1;
1327
  float mX2;
1328
  float mY2;
1329
1330
  PRBool operator==(const nsTimingFunction& aOther) const
1331
  {
1322
  {
1332
    return !(*this != aOther);
1323
    mFunc.mX1 = x1;
1324
    mFunc.mY1 = y1;
1325
    mFunc.mX2 = x2;
1326
    mFunc.mY2 = y2;
1333
  }
1327
  }
1334
1328
1335
  PRBool operator!=(const nsTimingFunction& aOther) const
1329
  nsTimingFunction(Type aType, PRUint32 aSteps)
1330
    : mType(aType)
1336
  {
1331
  {
1337
    return mX1 != aOther.mX1 || mY1 != aOther.mY1 ||
1332
    NS_ABORT_IF_FALSE(mType == StepStart || mType == StepEnd, "wrong type");
1338
           mX2 != aOther.mX2 || mY2 != aOther.mY2;
1333
    mSteps = aSteps;
1334
  }
1335
1336
  nsTimingFunction(const nsTimingFunction& aOther)
1337
    : mType(aOther.mType)
1338
  {
1339
    if (mType == Function) {
1340
      mFunc.mX1 = aOther.mFunc.mX1;
1341
      mFunc.mY1 = aOther.mFunc.mY1;
1342
      mFunc.mX2 = aOther.mFunc.mX2;
1343
      mFunc.mY2 = aOther.mFunc.mY2;
1344
    } else {
1345
      mSteps = aOther.mSteps;
1346
    }
1347
  }
1348
1349
  Type mType;
1350
  union {
1351
    struct {
1352
      float mX1;
1353
      float mY1;
1354
      float mX2;
1355
      float mY2;
1356
    } mFunc;
1357
    PRUint32 mSteps;
1358
  };
1359
1360
  bool operator==(const nsTimingFunction& aOther) const
1361
  {
1362
    if (mType != aOther.mType) {
1363
      return false;
1364
    }
1365
    if (mType == Function) {
1366
      return mFunc.mX1 == aOther.mFunc.mX1 && mFunc.mY1 == aOther.mFunc.mY1 &&
1367
             mFunc.mX2 == aOther.mFunc.mX2 && mFunc.mY2 == aOther.mFunc.mY2;
1368
    }
1369
    return mSteps == aOther.mSteps;
1370
  }
1371
1372
  bool operator!=(const nsTimingFunction& aOther) const
1373
  {
1374
    return !(*this == aOther);
1339
  }
1375
  }
1340
1376
1341
private:
1377
private:
1342
  void AssignFromKeyword(PRInt32 aTimingFunctionType);
1378
  void AssignFromKeyword(PRInt32 aTimingFunctionType);
1343
};
1379
};
1344
1380
1345
struct nsTransition {
1381
struct nsTransition {
1346
  nsTransition() { /* leaves uninitialized; see also SetInitialValues */ }
1382
  nsTransition() { /* leaves uninitialized; see also SetInitialValues */ }
(-)a/layout/style/nsTransitionManager.cpp (-3 / +56 lines)
Line     Link Here 
 Lines 60-84   using mozilla::TimeStamp; Link Here 
60
using mozilla::TimeDuration;
60
using mozilla::TimeDuration;
61
61
62
namespace dom = mozilla::dom;
62
namespace dom = mozilla::dom;
63
63
64
/*****************************************************************************
64
/*****************************************************************************
65
 * Per-Element data                                                          *
65
 * Per-Element data                                                          *
66
 *****************************************************************************/
66
 *****************************************************************************/
67
67
68
class ComputedTimingFunction {
69
public:
70
  typedef nsTimingFunction::Type Type;
71
  void Init(const nsTimingFunction &aFunction);
72
  double GetValue(double aPortion) const;
73
private:
74
  Type mType;
75
  nsSMILKeySpline mTimingFunction;
76
  PRUint32 mSteps;
77
};
78
79
void
80
ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
81
{
82
  mType = aFunction.mType;
83
  if (mType == nsTimingFunction::Function) {
84
    mTimingFunction.Init(aFunction.mFunc.mX1, aFunction.mFunc.mY1,
85
                         aFunction.mFunc.mX2, aFunction.mFunc.mY2);
86
  } else {
87
    mSteps = aFunction.mSteps;
88
  }
89
}
90
91
static inline double
92
StepEnd(PRUint32 aSteps, double aPortion)
93
{
94
  NS_ABORT_IF_FALSE(0.0 <= aPortion && aPortion <= 1.0, "out of range");
95
  PRUint32 step = PRUint32(aPortion * aSteps); // floor
96
  return double(step) / double(aSteps);
97
}
98
99
double
100
ComputedTimingFunction::GetValue(double aPortion) const
101
{
102
  switch (mType) {
103
    case nsTimingFunction::Function:
104
      return mTimingFunction.GetSplineValue(aPortion);
105
    case nsTimingFunction::StepStart:
106
      // There are diagrams in the spec that seem to suggest this check
107
      // and the bounds point should not be symmetric with StepEnd, but
108
      // should actually step up at rather than immediately after the
109
      // fraction points.  However, we rely on rounding negative values
110
      // up to zero, so we can't do that.  And it's not clear the spec
111
      // really meant it.
112
      return 1.0 - StepEnd(mSteps, 1.0 - aPortion);
113
    default:
114
      NS_ABORT_IF_FALSE(PR_FALSE, "bad type");
115
      // fall through
116
    case nsTimingFunction::StepEnd:
117
      return StepEnd(mSteps, aPortion);
118
  }
119
}
120
68
struct ElementPropertyTransition
121
struct ElementPropertyTransition
69
{
122
{
70
  nsCSSProperty mProperty;
123
  nsCSSProperty mProperty;
71
  nsStyleAnimation::Value mStartValue, mEndValue;
124
  nsStyleAnimation::Value mStartValue, mEndValue;
72
  TimeStamp mStartTime; // actual start plus transition delay
125
  TimeStamp mStartTime; // actual start plus transition delay
73
126
74
  // data from the relevant nsTransition
127
  // data from the relevant nsTransition
75
  TimeDuration mDuration;
128
  TimeDuration mDuration;
76
  nsSMILKeySpline mTimingFunction;
129
  ComputedTimingFunction mTimingFunction;
77
130
78
  // This is the start value to be used for a check for whether a
131
  // This is the start value to be used for a check for whether a
79
  // transition is being reversed.  Normally the same as mStartValue,
132
  // transition is being reversed.  Normally the same as mStartValue,
80
  // except when this transition started as the reversal of another
133
  // except when this transition started as the reversal of another
81
  // in-progress transition.  Needed so we can handle two reverses in a
134
  // in-progress transition.  Needed so we can handle two reverses in a
82
  // row.
135
  // row.
83
  nsStyleAnimation::Value mStartForReversingTest;
136
  nsStyleAnimation::Value mStartForReversingTest;
84
  // Likewise, the portion (in value space) of the "full" reversed
137
  // Likewise, the portion (in value space) of the "full" reversed
 Lines 129-145   ElementPropertyTransition::ValuePortionF Link Here 
129
  } else {
182
  } else {
130
    timePortion = (aRefreshTime - mStartTime).ToSeconds() / duration;
183
    timePortion = (aRefreshTime - mStartTime).ToSeconds() / duration;
131
    if (timePortion < 0.0)
184
    if (timePortion < 0.0)
132
      timePortion = 0.0; // use start value during transition-delay
185
      timePortion = 0.0; // use start value during transition-delay
133
    if (timePortion > 1.0)
186
    if (timePortion > 1.0)
134
      timePortion = 1.0; // we might be behind on flushing
187
      timePortion = 1.0; // we might be behind on flushing
135
  }
188
  }
136
189
137
  return mTimingFunction.GetSplineValue(timePortion);
190
  return mTimingFunction.GetValue(timePortion);
138
}
191
}
139
192
140
/**
193
/**
141
 * A style rule that maps property-nsStyleAnimation::Value pairs.
194
 * A style rule that maps property-nsStyleAnimation::Value pairs.
142
 */
195
 */
143
class AnimValuesStyleRule : public nsIStyleRule
196
class AnimValuesStyleRule : public nsIStyleRule
144
{
197
{
145
public:
198
public:
 Lines 699-715   nsTransitionManager::ConsiderStartingTra Link Here 
699
      pt.mStartForReversingTest = oldPT.mEndValue;
752
      pt.mStartForReversingTest = oldPT.mEndValue;
700
      pt.mReversePortion = valuePortion;
753
      pt.mReversePortion = valuePortion;
701
    }
754
    }
702
  }
755
  }
703
756
704
  pt.mProperty = aProperty;
757
  pt.mProperty = aProperty;
705
  pt.mStartTime = mostRecentRefresh + TimeDuration::FromMilliseconds(delay);
758
  pt.mStartTime = mostRecentRefresh + TimeDuration::FromMilliseconds(delay);
706
  pt.mDuration = TimeDuration::FromMilliseconds(duration);
759
  pt.mDuration = TimeDuration::FromMilliseconds(duration);
707
  pt.mTimingFunction.Init(tf.mX1, tf.mY1, tf.mX2, tf.mY2);
760
  pt.mTimingFunction.Init(tf);
708
761
709
  if (!aElementTransitions) {
762
  if (!aElementTransitions) {
710
    aElementTransitions =
763
    aElementTransitions =
711
      GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
764
      GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
712
                            PR_TRUE);
765
                            PR_TRUE);
713
    if (!aElementTransitions) {
766
    if (!aElementTransitions) {
714
      NS_WARNING("allocating ElementTransitions failed");
767
      NS_WARNING("allocating ElementTransitions failed");
715
      return;
768
      return;
(-)a/layout/style/test/Makefile.in (+1 lines)
Line     Link Here 
 Lines 174-189   _TEST_FILES = test_acid3_test46.html \ Link Here 
174
		test_system_font_serialization.html \
174
		test_system_font_serialization.html \
175
		test_transitions_and_zoom.html \
175
		test_transitions_and_zoom.html \
176
		test_transitions_cancel_near_end.html \
176
		test_transitions_cancel_near_end.html \
177
		test_transitions_computed_values.html \
177
		test_transitions_computed_values.html \
178
		test_transitions_computed_value_combinations.html \
178
		test_transitions_computed_value_combinations.html \
179
		test_transitions_events.html \
179
		test_transitions_events.html \
180
		test_transitions.html \
180
		test_transitions.html \
181
		test_transitions_per_property.html \
181
		test_transitions_per_property.html \
182
		test_transitions_step_functions.html \
182
		test_transitions_dynamic_changes.html \
183
		test_transitions_dynamic_changes.html \
183
		test_transitions_bug537151.html \
184
		test_transitions_bug537151.html \
184
		test_unclosed_parentheses.html \
185
		test_unclosed_parentheses.html \
185
		test_units_angle.html \
186
		test_units_angle.html \
186
		test_units_frequency.html \
187
		test_units_frequency.html \
187
		test_units_length.html \
188
		test_units_length.html \
188
		test_units_time.html \
189
		test_units_time.html \
189
		test_value_cloning.html \
190
		test_value_cloning.html \
(-)a/layout/style/test/property_database.js (-2 / +2 lines)
Line     Link Here 
 Lines 2636-2653   var gCSSProperties = { Link Here 
2636
		other_values: [ "none", "left", "top", "color", "width, height, opacity", "foobar", "auto", "\\32width", "-width", "-\\32width", "\\32 0width", "-\\32 0width", "\\2width", "-\\2width" ],
2636
		other_values: [ "none", "left", "top", "color", "width, height, opacity", "foobar", "auto", "\\32width", "-width", "-\\32width", "\\32 0width", "-\\32 0width", "\\2width", "-\\2width" ],
2637
		invalid_values: [ "none, none", "all, all", "color, none", "none, color", "all, color", "color, all", "inherit, color", "color, inherit", "initial, color", "color, initial", "none, color", "color, none", "all, color", "color, all" ]
2637
		invalid_values: [ "none, none", "all, all", "color, none", "none, color", "all, color", "color, all", "inherit, color", "color, inherit", "initial, color", "color, initial", "none, color", "color, none", "all, color", "color, all" ]
2638
	},
2638
	},
2639
	"-moz-transition-timing-function": {
2639
	"-moz-transition-timing-function": {
2640
		domProp: "MozTransitionTimingFunction",
2640
		domProp: "MozTransitionTimingFunction",
2641
		inherited: false,
2641
		inherited: false,
2642
		type: CSS_TYPE_LONGHAND,
2642
		type: CSS_TYPE_LONGHAND,
2643
		initial_values: [ "ease", "cubic-bezier(0.25, 0.1, 0.25, 1.0)" ],
2643
		initial_values: [ "ease", "cubic-bezier(0.25, 0.1, 0.25, 1.0)" ],
2644
		other_values: [ "linear", "ease-in", "ease-out", "ease-in-out", "linear, ease-in, cubic-bezier(0.1, 0.2, 0.8, 0.9)", "cubic-bezier(0.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.25, 1.5, 0.75, -0.5)" ],
2644
		other_values: [ "linear", "ease-in", "ease-out", "ease-in-out", "linear, ease-in, cubic-bezier(0.1, 0.2, 0.8, 0.9)", "cubic-bezier(0.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.25, 1.5, 0.75, -0.5)", "step-start", "step-end", "steps(1)", "steps(2, start)", "steps(386)", "steps(3, end)" ],
2645
		invalid_values: [ "none", "auto", "cubic-bezier(0.25, 0.1, 0.25)", "cubic-bezier(0.25, 0.1, 0.25, 0.25, 1.0)", "cubic-bezier(-0.5, 0.5, 0.5, 0.5)", "cubic-bezier(1.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.5, 0.5, -0.5, 0.5)", "cubic-bezier(0.5, 0.5, 1.5, 0.5)" ]
2645
		invalid_values: [ "none", "auto", "cubic-bezier(0.25, 0.1, 0.25)", "cubic-bezier(0.25, 0.1, 0.25, 0.25, 1.0)", "cubic-bezier(-0.5, 0.5, 0.5, 0.5)", "cubic-bezier(1.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.5, 0.5, -0.5, 0.5)", "cubic-bezier(0.5, 0.5, 1.5, 0.5)", "steps(2, step-end)", "steps(0)", "steps(-2)", "steps(0, step-end, 1)" ]
2646
	},
2646
	},
2647
	"unicode-bidi": {
2647
	"unicode-bidi": {
2648
		domProp: "unicodeBidi",
2648
		domProp: "unicodeBidi",
2649
		inherited: false,
2649
		inherited: false,
2650
		type: CSS_TYPE_LONGHAND,
2650
		type: CSS_TYPE_LONGHAND,
2651
		initial_values: [ "normal" ],
2651
		initial_values: [ "normal" ],
2652
		other_values: [ "embed", "bidi-override" ],
2652
		other_values: [ "embed", "bidi-override" ],
2653
		invalid_values: [ "auto", "none" ]
2653
		invalid_values: [ "auto", "none" ]
(-)a/layout/style/test/test_transitions_step_functions.html (+98 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE HTML>
2
<html>
3
<!--
4
https://bugzilla.mozilla.org/show_bug.cgi?id=435441
5
-->
6
<head>
7
  <title>Test for Bug 435441</title>
8
  <script type="application/javascript" src="/MochiKit/packed.js"></script>
9
  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
10
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
11
  <style type="text/css">
12
13
  p.transition {
14
    -moz-transition: margin-top 100s linear;
15
  }
16
17
  </style>
18
</head>
19
<body>
20
<div id="display">
21
22
</div>
23
<pre id="test">
24
<script type="application/javascript">
25
26
/** Test for transition step functions **/
27
28
function px_to_num(str)
29
{
30
    return Number(String(str).match(/^([\d.]+)px$/)[1]);
31
}
32
33
var display = document.getElementById("display");
34
35
function run_test(tf, percent, value)
36
{
37
  var p = document.createElement("p");
38
  p.className = "transition";
39
  p.style.marginTop = "0px";
40
  // be this percent of the way through a 100s transition
41
  p.style.MozTransitionDelay = (percent * -100) + "s";
42
  p.style.MozTransitionTimingFunction = tf;
43
  display.appendChild(p);
44
  var cs = getComputedStyle(p, "");
45
  var flush1 = cs.marginTop;
46
47
  p.style.marginTop = "1000px";
48
  var result = px_to_num(cs.marginTop) / 1000
49
50
  is(result, value, 100 * percent + "% of the way through " + tf);
51
52
  display.removeChild(p);
53
}
54
55
run_test("step-start", 0, 0);
56
run_test("step-start", 0.001, 1);
57
run_test("step-start", 0.999, 1);
58
run_test("step-start", 1, 1);
59
run_test("step-end", 0, 0);
60
run_test("step-end", 0.001, 0);
61
run_test("step-end", 0.999, 0);
62
run_test("step-end", 1, 1);
63
64
run_test("steps(2)", 0.00, 0.0);
65
run_test("steps(2)", 0.49, 0.0);
66
run_test("steps(2)", 0.50, 0.5);
67
run_test("steps(2)", 0.99, 0.5);
68
run_test("steps(2)", 1.00, 1.0);
69
70
run_test("steps(2, end)", 0.00, 0.0);
71
run_test("steps(2, end)", 0.49, 0.0);
72
run_test("steps(2, end)", 0.50, 0.5);
73
run_test("steps(2, end)", 0.99, 0.5);
74
run_test("steps(2, end)", 1.00, 1.0);
75
76
run_test("steps(2, start)", 0.00, 0.0);
77
run_test("steps(2, start)", 0.01, 0.5);
78
run_test("steps(2, start)", 0.50, 0.5);
79
run_test("steps(2, start)", 0.51, 1.0);
80
run_test("steps(2, start)", 1.00, 1.0);
81
82
run_test("steps(8,end)", 0.00, 0.0);
83
run_test("steps(8,end)", 0.10, 0.0);
84
run_test("steps(8,end)", 0.20, 0.125);
85
run_test("steps(8,end)", 0.30, 0.25);
86
run_test("steps(8,end)", 0.40, 0.375);
87
run_test("steps(8,end)", 0.49, 0.375);
88
run_test("steps(8,end)", 0.50, 0.5);
89
run_test("steps(8,end)", 0.60, 0.5);
90
run_test("steps(8,end)", 0.70, 0.625);
91
run_test("steps(8,end)", 0.80, 0.75);
92
run_test("steps(8,end)", 0.90, 0.875);
93
run_test("steps(8,end)", 1.00, 1.0);
94
95
</script>
96
</pre>
97
</body>
98
</html>

Return to bug 435442