/*
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cobalt/cssom/computed_style.h"

#include <vector>

#include "base/memory/scoped_ptr.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/cssom/absolute_url_value.h"
#include "cobalt/cssom/calc_value.h"
#include "cobalt/cssom/css_computed_style_data.h"
#include "cobalt/cssom/css_computed_style_declaration.h"
#include "cobalt/cssom/font_weight_value.h"
#include "cobalt/cssom/keyword_value.h"
#include "cobalt/cssom/length_value.h"
#include "cobalt/cssom/linear_gradient_value.h"
#include "cobalt/cssom/matrix_function.h"
#include "cobalt/cssom/number_value.h"
#include "cobalt/cssom/percentage_value.h"
#include "cobalt/cssom/property_list_value.h"
#include "cobalt/cssom/property_value_visitor.h"
#include "cobalt/cssom/radial_gradient_value.h"
#include "cobalt/cssom/rotate_function.h"
#include "cobalt/cssom/scale_function.h"
#include "cobalt/cssom/shadow_value.h"
#include "cobalt/cssom/transform_function.h"
#include "cobalt/cssom/transform_function_list_value.h"
#include "cobalt/cssom/transform_function_visitor.h"
#include "cobalt/cssom/translate_function.h"
#include "cobalt/cssom/url_value.h"

namespace cobalt {
namespace cssom {

namespace {

scoped_refptr<LengthValue> ProvideAbsoluteLength(
    const scoped_refptr<LengthValue>& specified_length,
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size,
    const math::Size& viewport_size) {
  switch (specified_length->unit()) {
    // "px" is an absolute unit.
    //   https://www.w3.org/TR/css3-values/#absolute-lengths
    case kPixelsUnit:
      return scoped_refptr<LengthValue>(specified_length);

    // "em" equals to the computed value of the "font-size" property of
    // the element on which it is used.
    //   https://www.w3.org/TR/css3-values/#font-relative-lengths
    case kFontSizesAkaEmUnit: {
      DCHECK_EQ(kPixelsUnit, computed_font_size->unit());

      return new LengthValue(
          computed_font_size->value() * specified_length->value(), kPixelsUnit);
    }

    // "rem" equals to the computed value of font-size on the root element.
    //   https://www.w3.org/TR/css3-values/#font-relative-lengths
    case kRootElementFontSizesAkaRemUnit: {
      DCHECK_EQ(kPixelsUnit, root_computed_font_size->unit());

      return new LengthValue(
          root_computed_font_size->value() * specified_length->value(),
          kPixelsUnit);
    }

    // "vw" equal to 1% of the width of the initial containing block.
    //   https://www.w3.org/TR/css3-values/#viewport-relative-lengths
    case kViewportWidthPercentsAkaVwUnit: {
      return new LengthValue(
          viewport_size.width() * specified_length->value() / 100.0f,
          kPixelsUnit);
    }

    // "vh" equal to 1% of the height of the initial containing block.
    //   https://www.w3.org/TR/css3-values/#viewport-relative-lengths
    case kViewportHeightPercentsAkaVhUnit: {
      return new LengthValue(
          viewport_size.height() * specified_length->value() / 100.0f,
          kPixelsUnit);
    }

    default:
      NOTREACHED();
      return NULL;
  }
}

// For values that can be either lengths or percentages, this function will
// return a value that, if the original value was a length, is now
// absolutized.
scoped_refptr<PropertyValue> ProvideAbsoluteLengthIfNonNullLength(
    const scoped_refptr<PropertyValue>& specified_value,
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size,
    const math::Size& viewport_size) {
  if (!specified_value) {
    return specified_value;
  }

  if (specified_value->GetTypeId() == base::GetTypeId<LengthValue>()) {
    LengthValue* value_as_length =
        base::polymorphic_downcast<LengthValue*>(specified_value.get());

    return ProvideAbsoluteLength(value_as_length, computed_font_size,
                                 root_computed_font_size, viewport_size);
  } else {
    return specified_value;
  }
}

// Applices ProvideAbsoluteLengthIfNonNullLength() for every item in a
// PropertyValueList.
scoped_refptr<PropertyListValue> ProvideAbsoluteLengthsForNonNullLengthsInList(
    const scoped_refptr<PropertyListValue>& specified_value,
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size,
    const math::Size& viewport_size) {
  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());
  builder->reserve(specified_value->value().size());

  for (PropertyListValue::Builder::const_iterator iter =
           specified_value->value().begin();
       iter != specified_value->value().end(); ++iter) {
    builder->push_back(ProvideAbsoluteLengthIfNonNullLength(
        *iter, computed_font_size, root_computed_font_size, viewport_size));
  }

  return new PropertyListValue(builder.Pass());
}

// Computed value: absolute length;
//                 '0' if the border style is 'none' or 'hidden'.
//   https://www.w3.org/TR/css3-background/#border-width
class ComputedBorderWidthProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedBorderWidthProvider(const LengthValue* computed_font_size,
                              const LengthValue* root_computed_font_size,
                              const math::Size& viewport_size,
                              const PropertyValue* border_style);

  void VisitLength(LengthValue* length) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_border_width() const {
    return computed_border_width_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;
  const PropertyValue* border_style_;

  scoped_refptr<PropertyValue> computed_border_width_;

  DISALLOW_COPY_AND_ASSIGN(ComputedBorderWidthProvider);
};

ComputedBorderWidthProvider::ComputedBorderWidthProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size,
    const PropertyValue* border_style)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size),
      border_style_(border_style) {}

void ComputedBorderWidthProvider::VisitLength(LengthValue* specified_length) {
  if (border_style_ == KeywordValue::GetNone().get() ||
      border_style_ == KeywordValue::GetHidden().get()) {
    computed_border_width_ = new LengthValue(0, kPixelsUnit);
  } else {
    DCHECK_EQ(border_style_, KeywordValue::GetSolid().get());
    computed_border_width_ =
        ProvideAbsoluteLength(specified_length, computed_font_size_,
                              root_computed_font_size_, viewport_size_);
  }
}

// Computed value: numeric weight value.
//   https://www.w3.org/TR/css3-fonts/#font-weight-prop
class ComputedFontWeightProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedFontWeightProvider() {}

  void VisitFontWeight(FontWeightValue* weight) OVERRIDE;

  const scoped_refptr<FontWeightValue>& computed_font_weight() const {
    return computed_font_weight_;
  }

 private:
  scoped_refptr<FontWeightValue> computed_font_weight_;

  DISALLOW_COPY_AND_ASSIGN(ComputedFontWeightProvider);
};

// TODO: Support bolder and lighter. Match the weight with font face.
// Quite often there are only a few weights available for a particular font
// family. When a weight is specified for which no face exists, a face with a
// nearby weight is used.
//   https://www.w3.org/TR/css3-fonts/#font-matching-algorithm
void ComputedFontWeightProvider::VisitFontWeight(
    FontWeightValue* specified_weight) {
  computed_font_weight_ = specified_weight;
}

// Computed value: absolute length.
//   https://www.w3.org/TR/css3-fonts/#font-size-prop
class ComputedFontSizeProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedFontSizeProvider(const LengthValue* parent_computed_font_size,
                           const LengthValue* root_computed_font_size,
                           const math::Size& viewport_size);

  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;

  const scoped_refptr<LengthValue>& computed_font_size() const {
    return computed_font_size_;
  }

 private:
  const LengthValue* parent_computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<LengthValue> computed_font_size_;

  DISALLOW_COPY_AND_ASSIGN(ComputedFontSizeProvider);
};

ComputedFontSizeProvider::ComputedFontSizeProvider(
    const LengthValue* parent_computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : parent_computed_font_size_(parent_computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedFontSizeProvider::VisitLength(LengthValue* specified_length) {
  // "em" on "font-size" is calculated relatively to the inherited value
  // of "font-size".
  //   https://www.w3.org/TR/css3-values/#font-relative-lengths
  computed_font_size_ =
      ProvideAbsoluteLength(specified_length, parent_computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedFontSizeProvider::VisitPercentage(
    PercentageValue* specified_percentage) {
  // A percentage value specifies an absolute font size relative to the parent
  // element's fonts size.
  //   https://www.w3.org/TR/css3-fonts/#percentage-size-value
  computed_font_size_ = new LengthValue(
      parent_computed_font_size_->value() * specified_percentage->value(),
      kPixelsUnit);
}

// Computed value: for length and percentage the absolute value;
//                 otherwise as specified.
//   https://www.w3.org/TR/CSS21/visudet.html#line-height
class ComputedLineHeightProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedLineHeightProvider(const LengthValue* computed_font_size,
                             const LengthValue* root_computed_font_size,
                             const math::Size& viewport_size);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitNumber(NumberValue* number) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_line_height() const {
    return computed_line_height_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_line_height_;

  DISALLOW_COPY_AND_ASSIGN(ComputedLineHeightProvider);
};

ComputedLineHeightProvider::ComputedLineHeightProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedLineHeightProvider::VisitLength(LengthValue* specified_length) {
  computed_line_height_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedLineHeightProvider::VisitNumber(NumberValue* specified_number) {
  // The computed value is the same as the specified value.
  //   https://www.w3.org/TR/CSS2/visudet.html#line-height
  computed_line_height_ = specified_number;
}

void ComputedLineHeightProvider::VisitPercentage(PercentageValue* percentage) {
  // The computed value of the property is this percentage multiplied by the
  // element's computed font size. Negative values are illegal.
  //   https://www.w3.org/TR/CSS21/visudet.html#line-height
  computed_line_height_ = new LengthValue(
      computed_font_size_->value() * percentage->value(), kPixelsUnit);
}

void ComputedLineHeightProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kNormal:
      computed_line_height_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kAuto:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kForwards:
    case KeywordValue::kFixed:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNone:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

// Computed value: the percentage as specified or the absolute length.
//   https://www.w3.org/TR/CSS21/box.html#margin-properties
//   https://www.w3.org/TR/CSS21/box.html#padding-properties
class ComputedMarginOrPaddingEdgeProvider
    : public NotReachedPropertyValueVisitor {
 public:
  ComputedMarginOrPaddingEdgeProvider(
      const LengthValue* computed_font_size,
      const LengthValue* root_computed_font_size,
      const math::Size& viewport_size);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_margin_or_padding_edge() const {
    return computed_margin_or_padding_edge_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_margin_or_padding_edge_;

  DISALLOW_COPY_AND_ASSIGN(ComputedMarginOrPaddingEdgeProvider);
};

ComputedMarginOrPaddingEdgeProvider::ComputedMarginOrPaddingEdgeProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedMarginOrPaddingEdgeProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kAuto:
      computed_margin_or_padding_edge_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNone:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

void ComputedMarginOrPaddingEdgeProvider::VisitLength(
    LengthValue* specified_length) {
  computed_margin_or_padding_edge_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedMarginOrPaddingEdgeProvider::VisitPercentage(
    PercentageValue* percentage) {
  computed_margin_or_padding_edge_ = percentage;
}

class ComputedPositionOffsetProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedPositionOffsetProvider(const LengthValue* computed_font_size,
                                 const LengthValue* root_computed_font_size,
                                 const math::Size& viewport_size);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_position_offset() const {
    return computed_position_offset_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_position_offset_;

  DISALLOW_COPY_AND_ASSIGN(ComputedPositionOffsetProvider);
};

void ComputedPositionOffsetProvider::VisitLength(
    LengthValue* specified_length) {
  computed_position_offset_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedPositionOffsetProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kAuto:
      computed_position_offset_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNone:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

void ComputedPositionOffsetProvider::VisitPercentage(
    PercentageValue* percentage) {
  computed_position_offset_ = percentage;
}

ComputedPositionOffsetProvider::ComputedPositionOffsetProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

// Computed value: the percentage or "auto" or the absolute length.
//   https://www.w3.org/TR/CSS21/visudet.html#the-height-property
class ComputedHeightProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedHeightProvider(const PropertyValue* parent_computed_height,
                         const LengthValue* computed_font_size,
                         const LengthValue* root_computed_font_size,
                         const math::Size& viewport_size, bool out_of_flow);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_height() const {
    return computed_height_;
  }

 private:
  const PropertyValue* parent_computed_height_;
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;
  bool out_of_flow_;

  scoped_refptr<PropertyValue> computed_height_;

  DISALLOW_COPY_AND_ASSIGN(ComputedHeightProvider);
};

ComputedHeightProvider::ComputedHeightProvider(
    const PropertyValue* parent_computed_height,
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size,
    bool out_of_flow)
    : parent_computed_height_(parent_computed_height),
      computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size),
      out_of_flow_(out_of_flow) {}

void ComputedHeightProvider::VisitLength(LengthValue* specified_length) {
  computed_height_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedHeightProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kAuto:
      computed_height_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonospace:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kNone:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

void ComputedHeightProvider::VisitPercentage(PercentageValue* percentage) {
  const scoped_refptr<PropertyValue>& auto_value = KeywordValue::GetAuto();

  // If the height of the containing block is not specified explicitly
  // (i.e., it depends on content height), and this element is not absolutely
  // positioned, the value computes to "auto".
  //   https://www.w3.org/TR/CSS21/visudet.html#the-height-property
  computed_height_ = (parent_computed_height_ == auto_value && !out_of_flow_)
                         ? auto_value
                         : percentage;
}

// Computed value: the percentage or "auto" or the absolute length.
//   https://www.w3.org/TR/CSS2/visudet.html#propdef-max-height
class ComputedMaxHeightProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedMaxHeightProvider(const PropertyValue* parent_computed_max_height,
                            const LengthValue* computed_font_size,
                            const LengthValue* root_computed_font_size,
                            const math::Size& viewport_size, bool out_of_flow);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_max_height() const {
    return computed_max_height_;
  }

 private:
  const PropertyValue* parent_computed_max_height_;
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;
  bool out_of_flow_;

  scoped_refptr<PropertyValue> computed_max_height_;

  DISALLOW_COPY_AND_ASSIGN(ComputedMaxHeightProvider);
};

ComputedMaxHeightProvider::ComputedMaxHeightProvider(
    const PropertyValue* parent_computed_max_height,
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size,
    bool out_of_flow)
    : parent_computed_max_height_(parent_computed_max_height),
      computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size),
      out_of_flow_(out_of_flow) {}

void ComputedMaxHeightProvider::VisitLength(LengthValue* specified_length) {
  computed_max_height_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedMaxHeightProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kAuto:
    case KeywordValue::kNone:
      computed_max_height_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCursive:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

void ComputedMaxHeightProvider::VisitPercentage(PercentageValue* percentage) {
  const scoped_refptr<PropertyValue>& auto_value = KeywordValue::GetAuto();
  const scoped_refptr<PropertyValue>& none_value = KeywordValue::GetNone();

  // If the max_height of the containing block is not specified explicitly
  // (i.e., it depends on content max_height), and this element is not
  // absolutely positioned, the percentage value is treated as 'none'.
  //   https://www.w3.org/TR/CSS2/visudet.html#propdef-max-height
  computed_max_height_ =
      (parent_computed_max_height_ == auto_value && !out_of_flow_) ? none_value
                                                                   : percentage;
}

// Computed value: the percentage or "auto" or the absolute length.
//   https://www.w3.org/TR/CSS2/visudet.html#propdef-min-height
class ComputedMinHeightProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedMinHeightProvider(const PropertyValue* parent_computed_min_max_height,
                            const LengthValue* computed_font_size,
                            const LengthValue* root_computed_font_size,
                            const math::Size& viewport_size, bool out_of_flow);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_min_height() const {
    return computed_min_height_;
  }

 private:
  const PropertyValue* parent_computed_min_max_height_;
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;
  bool out_of_flow_;

  scoped_refptr<PropertyValue> computed_min_height_;

  DISALLOW_COPY_AND_ASSIGN(ComputedMinHeightProvider);
};

ComputedMinHeightProvider::ComputedMinHeightProvider(
    const PropertyValue* parent_computed_min_max_height,
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size,
    bool out_of_flow)
    : parent_computed_min_max_height_(parent_computed_min_max_height),
      computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size),
      out_of_flow_(out_of_flow) {}

void ComputedMinHeightProvider::VisitLength(LengthValue* specified_length) {
  computed_min_height_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedMinHeightProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kAuto:
      computed_min_height_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNone:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

void ComputedMinHeightProvider::VisitPercentage(PercentageValue* percentage) {
  const scoped_refptr<PropertyValue>& auto_value = KeywordValue::GetAuto();

  // If the min_height of the containing block is not specified explicitly
  // (i.e., it depends on content min_height), and this element is not
  // absolutely positioned, the percentage value is treated as '0'.
  //   https://www.w3.org/TR/CSS2/visudet.html#propdef-min-height
  if (parent_computed_min_max_height_ == auto_value && !out_of_flow_) {
    computed_min_height_ = new LengthValue(0, kPixelsUnit);
  } else {
    computed_min_height_ = percentage;
  }
}

// Computed value: the percentage or "auto" as specified or the absolute length.
//   https://www.w3.org/TR/CSS21/visudet.html#the-width-property
class ComputedWidthProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedWidthProvider(const LengthValue* computed_font_size,
                        const LengthValue* root_computed_font_size,
                        const math::Size& viewport_size);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_width() const {
    return computed_width_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_width_;

  DISALLOW_COPY_AND_ASSIGN(ComputedWidthProvider);
};

ComputedWidthProvider::ComputedWidthProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedWidthProvider::VisitLength(LengthValue* specified_length) {
  computed_width_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedWidthProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kAuto:
      computed_width_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNone:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

void ComputedWidthProvider::VisitPercentage(PercentageValue* percentage) {
  computed_width_ = percentage;
}

// Computed value: the percentage or "auto" as specified or the absolute length.
//   https://www.w3.org/TR/CSS2/visudet.html#min-max-widths
class ComputedMinMaxWidthProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedMinMaxWidthProvider(PropertyValue* parent_computed_min_max_height,
                              const LengthValue* computed_font_size,
                              const LengthValue* root_computed_font_size,
                              const math::Size& viewport_size);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_min_max_width() const {
    return computed_min_max_width_;
  }

 private:
  PropertyValue* parent_computed_min_max_width_;
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_min_max_width_;

  DISALLOW_COPY_AND_ASSIGN(ComputedMinMaxWidthProvider);
};

ComputedMinMaxWidthProvider::ComputedMinMaxWidthProvider(
    PropertyValue* parent_computed_min_max_width,
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : parent_computed_min_max_width_(parent_computed_min_max_width),
      computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedMinMaxWidthProvider::VisitLength(LengthValue* specified_length) {
  computed_min_max_width_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedMinMaxWidthProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kAuto:
    case KeywordValue::kNone:
      computed_min_max_width_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonospace:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

class ComputedLengthIsNegativeProvider : public DefaultingPropertyValueVisitor {
 public:
  ComputedLengthIsNegativeProvider() : computed_length_is_negative_(false) {}

  void VisitLength(LengthValue* length_value) OVERRIDE {
    switch (length_value->unit()) {
      case kPixelsUnit:
      case kFontSizesAkaEmUnit:
      case kRootElementFontSizesAkaRemUnit:
      case kViewportWidthPercentsAkaVwUnit:
      case kViewportHeightPercentsAkaVhUnit:
        computed_length_is_negative_ = length_value->value() < 0;
        break;
      default:
        NOTREACHED();
    }
  }

  void VisitDefault(PropertyValue* property_value) OVERRIDE {
    UNREFERENCED_PARAMETER(property_value);
  }

  bool computed_length_is_negative() { return computed_length_is_negative_; }

 private:
  bool computed_length_is_negative_;
};

void ComputedMinMaxWidthProvider::VisitPercentage(PercentageValue* percentage) {
  ComputedLengthIsNegativeProvider computed_length_is_negative_provider;
  parent_computed_min_max_width_->Accept(&computed_length_is_negative_provider);
  // If the containing block's width is negative, the used value is zero.
  //   https://www.w3.org/TR/CSS2/visudet.html#min-max-widths
  if (computed_length_is_negative_provider.computed_length_is_negative()) {
    computed_min_max_width_ = new LengthValue(0, kPixelsUnit);
  } else {
    computed_min_max_width_ = percentage;
  }
}

namespace {

// Helper class for |ComputedBackgroundPositionProvider| and
// |ComputedTransformOriginProvider| to resolve the computed value of position
// part.
//   https://www.w3.org/TR/css3-background/#the-background-position
//   https://www.w3.org/TR/css3-transforms/#propdef-transform-origin
class ComputedPositionHelper {
 public:
  ComputedPositionHelper(const LengthValue* computed_font_size,
                         const LengthValue* root_computed_font_size,
                         const math::Size& viewport_size);

  // Forwards the call on to the appropriate method depending on the number
  // of parameters in |input_position_builder|.
  void ComputePosition(const PropertyListValue::Builder& input_position_builder,
                       PropertyListValue::Builder* output_position_builder);

  // Only resolve the first value of |input_position_builder|, other than the
  // first value would be ignored.
  void ComputeOneValuePosition(
      const PropertyListValue::Builder& input_position_builder,
      PropertyListValue::Builder* output_position_builder);

  // Only resolve the first two values of |input_position_builder|, other than
  // the first two values would be ignored.
  void ComputeTwoValuesPosition(
      const PropertyListValue::Builder& input_position_builder,
      PropertyListValue::Builder* output_position_builder);

  // Only resolve three or four values of |input_position_builder|.
  void ComputeThreeOrFourValuesPosition(
      const PropertyListValue::Builder& input_position_builder,
      PropertyListValue::Builder* output_position_builder);

 private:
  enum Direction {
    kHorizontal,
    kVertical,
    kCenter,
    kNone,
  };

  struct OriginInfo {
    OriginInfo(float origin_as_percentage, int offset_multiplier,
               Direction direction)
        : origin_as_percentage(origin_as_percentage),
          offset_multiplier(offset_multiplier),
          direction(direction) {}

    float origin_as_percentage;
    int offset_multiplier;
    Direction direction;
  };

  const OriginInfo ConvertToOriginInfo(
      const scoped_refptr<PropertyValue>& keyword) const;

  scoped_refptr<CalcValue> ProvideCalcValueFromOriginAndOffset(
      OriginInfo* origin_info, const scoped_refptr<PropertyValue>& offset);

  void FillPositionBuilderFromOriginAndOffset(
      const scoped_refptr<PropertyValue>& origin,
      const scoped_refptr<PropertyValue>& offset,
      PropertyListValue::Builder* position_builder);

  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  DISALLOW_COPY_AND_ASSIGN(ComputedPositionHelper);
};

ComputedPositionHelper::ComputedPositionHelper(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedPositionHelper::ComputePosition(
    const PropertyListValue::Builder& input_position_builder,
    PropertyListValue::Builder* output_position_builder) {
  switch (input_position_builder.size()) {
    case 1:
      ComputeOneValuePosition(input_position_builder, output_position_builder);
      break;
    case 2:
      ComputeTwoValuesPosition(input_position_builder, output_position_builder);
      break;
    case 3:  // fall-through
    case 4:
      ComputeThreeOrFourValuesPosition(input_position_builder,
                                       output_position_builder);
      break;
    default:
      NOTREACHED();
      break;
  }
}

// If only one value is specified, the second value is assumed to be center.
void ComputedPositionHelper::ComputeOneValuePosition(
    const PropertyListValue::Builder& input_position_builder,
    PropertyListValue::Builder* output_position_builder) {
  DCHECK_GE(input_position_builder.size(), 1u);

  PropertyListValue::Builder position_builder;
  position_builder.push_back(input_position_builder[0]);
  position_builder.push_back(KeywordValue::GetCenter());

  ComputeTwoValuesPosition(position_builder, output_position_builder);
}

// If two position values are given, a length or percentage as the
// first value represents the horizontal position (or offset) and a length or
// percentage as the second value represents the vertical position (or offset).
void ComputedPositionHelper::ComputeTwoValuesPosition(
    const PropertyListValue::Builder& input_position_builder,
    PropertyListValue::Builder* output_position_builder) {
  DCHECK_GE(input_position_builder.size(), 2u);

  for (size_t i = 0; i < 2; ++i) {
    scoped_refptr<PropertyValue> current_value = input_position_builder[i];

    if (current_value->GetTypeId() == base::GetTypeId<CalcValue>()) {
      // If it is already a CalcValue, nothing needs to be done.
      (*output_position_builder)[i] = current_value;
    } else if (current_value->GetTypeId() == base::GetTypeId<KeywordValue>()) {
      FillPositionBuilderFromOriginAndOffset(current_value, NULL,
                                             output_position_builder);
    } else {
      OriginInfo default_origin = OriginInfo(0.0f, 1, kNone);
      (*output_position_builder)[i] =
          ProvideCalcValueFromOriginAndOffset(&default_origin, current_value);
    }
  }
}

// If three values are given, then there are two cases:
// 1. <KeywordValue Length/Percentage KeywordValue>
// 2. <KeywordValue KeywordValue Length/Percentage>
// If four values are given, then each <percentage> or <length> represents
// an offset and must be preceded by a keyword, which specifies from which
// edge the offset is given. Keyword cannot be 'center'. The pattern is
// <KeywordValue Length/Percentage KeywordValue Length/Percentage>
void ComputedPositionHelper::ComputeThreeOrFourValuesPosition(
    const PropertyListValue::Builder& input_position_builder,
    PropertyListValue::Builder* output_position_builder) {
  DCHECK_GT(input_position_builder.size(), 2u);
  DCHECK_LE(input_position_builder.size(), 4u);

  for (size_t i = 0; i < input_position_builder.size(); ++i) {
    scoped_refptr<PropertyValue> previous_value =
        (i == 0) ? NULL : input_position_builder[i - 1];

    scoped_refptr<PropertyValue> current_value = input_position_builder[i];

    if (current_value->GetTypeId() == base::GetTypeId<KeywordValue>()) {
      FillPositionBuilderFromOriginAndOffset(current_value, NULL,
                                             output_position_builder);
    } else {
      DCHECK(previous_value);
      DCHECK(previous_value->GetTypeId() == base::GetTypeId<KeywordValue>());
      FillPositionBuilderFromOriginAndOffset(previous_value, current_value,
                                             output_position_builder);
    }
  }
}

// 1) 'top' computes to '0%' for the vertical position if one or two values are
//     given, otherwise specifies the top edge as the origin for the next
//     offset.
// 2) 'right' computes to '100%' for the horizontal position if one or two
//     values are given, otherwise specifies the right edge as the origin for
//     the next offset.
// 3) 'bottom' computes to '100%' for the vertical position if one or two values
//     are given, otherwise specifies the bottom edge as the origin for the
//     the next offset.
// 4) 'left' computes to '0%' for the horizontal position if one or two values
//     are given, otherwise specifies the left edge as the origin for the next
//     offset.
// 5) 'center' computes to '50%' (left 50%) for the horizontal position if
//     horizontal position is not specified, or '50%' (right 50%) for the
//     vertical position is not specified.
const ComputedPositionHelper::OriginInfo
ComputedPositionHelper::ConvertToOriginInfo(
    const scoped_refptr<PropertyValue>& keyword) const {
  DCHECK(keyword->GetTypeId() == base::GetTypeId<KeywordValue>());

  if (keyword == KeywordValue::GetLeft()) {
    return OriginInfo(0.0f, 1, kHorizontal);
  } else if (keyword == KeywordValue::GetRight()) {
    return OriginInfo(1.0f, -1, kHorizontal);
  } else if (keyword == KeywordValue::GetTop()) {
    return OriginInfo(0.0f, 1, kVertical);
  } else if (keyword == KeywordValue::GetBottom()) {
    return OriginInfo(1.0f, -1, kVertical);
  } else {
    return OriginInfo(0.5f, 1, kCenter);
  }
}

// If the |offset| is specified, the |origin| specifies from which edge
// the offset is given. Otherwise, the |origin| indicates the corresponding
// percentage value to the upper left corner for the horizontal/vertical
// position. The horizontal and vertical values are stored as CalcValue in
// computed style. eg: (background-position: bottom 20px left 40%;) would be
// computed as Calc(0px, 40%), Calc(-20px, 100%)
scoped_refptr<CalcValue>
ComputedPositionHelper::ProvideCalcValueFromOriginAndOffset(
    OriginInfo* origin_info, const scoped_refptr<PropertyValue>& offset) {
  DCHECK(origin_info);

  if (!offset) {
    return new CalcValue(
        new PercentageValue(origin_info->origin_as_percentage));
  }

  scoped_refptr<LengthValue> length_value;
  scoped_refptr<PercentageValue> percentage_value;
  if (offset->GetTypeId() == base::GetTypeId<LengthValue>()) {
    scoped_refptr<LengthValue> length_provider = ProvideAbsoluteLength(
        base::polymorphic_downcast<LengthValue*>(offset.get()),
        computed_font_size_, root_computed_font_size_, viewport_size_);
    length_value = new LengthValue(
        origin_info->offset_multiplier * length_provider->value(),
        length_provider->unit());
    percentage_value = new PercentageValue(origin_info->origin_as_percentage);

    return new CalcValue(length_value, percentage_value);
  } else {
    DCHECK(offset->GetTypeId() == base::GetTypeId<PercentageValue>());
    PercentageValue* percentage =
        base::polymorphic_downcast<PercentageValue*>(offset.get());
    percentage_value = new PercentageValue(origin_info->origin_as_percentage +
                                           origin_info->offset_multiplier *
                                               percentage->value());

    return new CalcValue(percentage_value);
  }
}

void ComputedPositionHelper::FillPositionBuilderFromOriginAndOffset(
    const scoped_refptr<PropertyValue>& origin,
    const scoped_refptr<PropertyValue>& offset,
    PropertyListValue::Builder* output_position_builder) {
  DCHECK(origin->GetTypeId() == base::GetTypeId<KeywordValue>());

  OriginInfo origin_info = ConvertToOriginInfo(origin);
  switch (origin_info.direction) {
    case kHorizontal: {
      (*output_position_builder)[0] =
          ProvideCalcValueFromOriginAndOffset(&origin_info, offset);
      break;
    }
    case kVertical: {
      (*output_position_builder)[1] =
          ProvideCalcValueFromOriginAndOffset(&origin_info, offset);
      break;
    }
    case kCenter: {
      if (!(*output_position_builder)[0]) {
        (*output_position_builder)[0] =
            ProvideCalcValueFromOriginAndOffset(&origin_info, offset);
      }
      if (!(*output_position_builder)[1]) {
        (*output_position_builder)[1] =
            ProvideCalcValueFromOriginAndOffset(&origin_info, offset);
      }
      break;
    }
    case kNone:  // fall-through
    default:
      NOTREACHED();
      break;
  }
}

}  // namespace

// Absolutizes the value of "background-image" property.
// Computed value: as specified, but with URIs made absolute.
//   https://www.w3.org/TR/css3-background/#the-background-image
class ComputedBackgroundImageSingleLayerProvider
    : public NotReachedPropertyValueVisitor {
 public:
  ComputedBackgroundImageSingleLayerProvider(
      const GURL& base_url, const LengthValue* computed_font_size,
      const LengthValue* root_computed_font_size,
      const math::Size& viewport_size)
      : base_url_(base_url),
        computed_font_size_(computed_font_size),
        root_computed_font_size_(root_computed_font_size),
        viewport_size_(viewport_size) {}

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitLinearGradient(LinearGradientValue* linear_gradient_value) OVERRIDE;
  void VisitRadialGradient(RadialGradientValue* radial_gradient_value) OVERRIDE;
  void VisitURL(URLValue* url_value) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_background_image() const {
    return computed_background_image_;
  }

 private:
  const GURL base_url_;
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_background_image_;
};

void ComputedBackgroundImageSingleLayerProvider::VisitKeyword(
    KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kNone:
      computed_background_image_ = keyword;
      break;
    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kAuto:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
      break;
  }
}

namespace {
ColorStopList ComputeColorStopList(const ColorStopList& color_stops,
                                   const LengthValue* computed_font_size,
                                   const LengthValue* root_computed_font_size,
                                   const math::Size& viewport_size) {
  ColorStopList computed_color_stops;
  computed_color_stops.reserve(color_stops.size());

  for (ColorStopList::const_iterator iter = color_stops.begin();
       iter != color_stops.end(); ++iter) {
    const ColorStop& color_stop = **iter;

    computed_color_stops.push_back(new ColorStop(
        color_stop.rgba(), ProvideAbsoluteLengthIfNonNullLength(
                               color_stop.position(), computed_font_size,
                               root_computed_font_size, viewport_size)));
  }

  return computed_color_stops.Pass();
}
}  // namespace

void ComputedBackgroundImageSingleLayerProvider::VisitLinearGradient(
    LinearGradientValue* linear_gradient_value) {
  // We must walk through the list of color stop positions and absolutize the
  // any length values.
  ColorStopList computed_color_stops = ComputeColorStopList(
      linear_gradient_value->color_stop_list(), computed_font_size_,
      root_computed_font_size_, viewport_size_);

  if (linear_gradient_value->angle_in_radians()) {
    computed_background_image_ =
        new LinearGradientValue(*linear_gradient_value->angle_in_radians(),
                                computed_color_stops.Pass());
  } else {
    computed_background_image_ = new LinearGradientValue(
        *linear_gradient_value->side_or_corner(), computed_color_stops.Pass());
  }
}

namespace {
scoped_refptr<PropertyListValue> CalculateComputedRadialGradientPosition(
    const scoped_refptr<PropertyListValue>& specified_position,
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size,
    const math::Size& viewport_size) {
  if (!specified_position) {
    // If no position is specified, we default to 'center'.
    scoped_ptr<PropertyListValue::Builder> builder(
        new PropertyListValue::Builder(2, new PercentageValue(0.5f)));
    return new PropertyListValue(builder.Pass());
  }

  size_t size = specified_position->value().size();
  DCHECK_GE(size, 1u);
  DCHECK_LE(size, 4u);

  ComputedPositionHelper position_helper(
      computed_font_size, root_computed_font_size, viewport_size);
  scoped_ptr<PropertyListValue::Builder> computed_position_builder(
      new PropertyListValue::Builder(2, scoped_refptr<PropertyValue>()));
  position_helper.ComputePosition(specified_position->value(),
                                  computed_position_builder.get());

  return new PropertyListValue(computed_position_builder.Pass());
}
}  // namespace

void ComputedBackgroundImageSingleLayerProvider::VisitRadialGradient(
    RadialGradientValue* radial_gradient_value) {
  // We must walk through the list of color stop positions and absolutize the
  // any length values.
  ColorStopList computed_color_stops = ComputeColorStopList(
      radial_gradient_value->color_stop_list(), computed_font_size_,
      root_computed_font_size_, viewport_size_);

  // The center of the gradient must be absolutized if it is a length.
  scoped_refptr<PropertyListValue> computed_position =
      CalculateComputedRadialGradientPosition(
          radial_gradient_value->position(), computed_font_size_,
          root_computed_font_size_, viewport_size_);

  // If the radial gradient specifies size values, they must also be absolutized
  // if they are lengths.
  if (radial_gradient_value->size_value()) {
    computed_background_image_ = new RadialGradientValue(
        radial_gradient_value->shape(),
        ProvideAbsoluteLengthsForNonNullLengthsInList(
            radial_gradient_value->size_value(), computed_font_size_,
            root_computed_font_size_, viewport_size_),
        computed_position, computed_color_stops.Pass());
  } else {
    computed_background_image_ = new RadialGradientValue(
        radial_gradient_value->shape(), *radial_gradient_value->size_keyword(),
        computed_position, computed_color_stops.Pass());
  }
}

void ComputedBackgroundImageSingleLayerProvider::VisitURL(URLValue* url_value) {
  if (url_value->value().empty()) {
    // No need to convert URLValue into AbsoluteURLValue.
    computed_background_image_ = KeywordValue::GetNone();
    return;
  }

  GURL absolute_url;
  if (url_value->is_absolute()) {
    absolute_url = GURL(url_value->value());
  } else {
    absolute_url = url_value->Resolve(base_url_);
  }

  if (!absolute_url.is_valid()) {
    DLOG(WARNING) << "Invalid url: " << absolute_url.spec();
    // No further process is needed if the url is invalid.
    computed_background_image_ = KeywordValue::GetNone();
    return;
  }

  computed_background_image_ = new AbsoluteURLValue(absolute_url);
}

class ComputedBackgroundImageProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedBackgroundImageProvider(const GURL& base_url,
                                  const LengthValue* computed_font_size,
                                  const LengthValue* root_computed_font_size,
                                  const math::Size& viewport_size)
      : base_url_(base_url),
        computed_font_size_(computed_font_size),
        root_computed_font_size_(root_computed_font_size),
        viewport_size_(viewport_size) {}

  void VisitPropertyList(PropertyListValue* property_list_value) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_background_image() const {
    return computed_background_image_;
  }

 private:
  const GURL base_url_;
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_background_image_;
};

void ComputedBackgroundImageProvider::VisitPropertyList(
    PropertyListValue* property_list_value) {
  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());
  builder->reserve(property_list_value->value().size());

  ComputedBackgroundImageSingleLayerProvider single_layer_provider(
      base_url_, computed_font_size_, root_computed_font_size_, viewport_size_);
  for (size_t i = 0; i < property_list_value->value().size(); ++i) {
    property_list_value->value()[i]->Accept(&single_layer_provider);
    scoped_refptr<PropertyValue> computed_background_image =
        single_layer_provider.computed_background_image();
    builder->push_back(computed_background_image);
  }

  computed_background_image_ = new PropertyListValue(builder.Pass());
}

class ComputedBackgroundSizeSingleValueProvider
    : public NotReachedPropertyValueVisitor {
 public:
  ComputedBackgroundSizeSingleValueProvider(
      const LengthValue* computed_font_size,
      const LengthValue* root_computed_font_size,
      const math::Size& viewport_size);

  void VisitLength(LengthValue* length) OVERRIDE;
  void VisitPercentage(PercentageValue* percentage) OVERRIDE;
  void VisitKeyword(KeywordValue* keyword) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_background_size() const {
    return computed_background_size_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_background_size_;

  DISALLOW_COPY_AND_ASSIGN(ComputedBackgroundSizeSingleValueProvider);
};

ComputedBackgroundSizeSingleValueProvider::
    ComputedBackgroundSizeSingleValueProvider(
        const LengthValue* computed_font_size,
        const LengthValue* root_computed_font_size,
        const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedBackgroundSizeSingleValueProvider::VisitLength(
    LengthValue* length) {
  computed_background_size_ = ProvideAbsoluteLength(
      length, computed_font_size_, root_computed_font_size_, viewport_size_);
}

void ComputedBackgroundSizeSingleValueProvider::VisitPercentage(
    PercentageValue* percentage) {
  computed_background_size_ = percentage;
}

void ComputedBackgroundSizeSingleValueProvider::VisitKeyword(
    KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kAuto:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
      computed_background_size_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNone:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

// ComputedBackgroundPositionProvider provides a property list which has two
// CalcValue. Each of CalcValue has two parts <percentage> and <length>.
// <percentage> and <length> values here represent an offset of the top left
// corner of the background image from the top left corner of the background
// positioning area.
//   https://www.w3.org/TR/css3-background/#the-background-position
class ComputedBackgroundPositionProvider
    : public NotReachedPropertyValueVisitor {
 public:
  ComputedBackgroundPositionProvider(const LengthValue* computed_font_size,
                                     const LengthValue* root_computed_font_size,
                                     const math::Size& viewport_size);

  void VisitPropertyList(PropertyListValue* property_list_value) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_background_position() const {
    return computed_background_position_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_background_position_;

  DISALLOW_COPY_AND_ASSIGN(ComputedBackgroundPositionProvider);
};

ComputedBackgroundPositionProvider::ComputedBackgroundPositionProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedBackgroundPositionProvider::VisitPropertyList(
    PropertyListValue* property_list_value) {
  size_t size = property_list_value->value().size();
  DCHECK_GE(size, 1u);
  DCHECK_LE(size, 4u);

  ComputedPositionHelper position_helper(
      computed_font_size_, root_computed_font_size_, viewport_size_);
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder(2, scoped_refptr<PropertyValue>()));

  position_helper.ComputePosition(property_list_value->value(),
                                  background_position_builder.get());

  computed_background_position_ =
      new PropertyListValue(background_position_builder.Pass());
}

class ComputedBackgroundSizeProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedBackgroundSizeProvider(const LengthValue* computed_font_size,
                                 const LengthValue* root_computed_font_size,
                                 const math::Size& viewport_size);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitPropertyList(PropertyListValue* property_list_value) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_background_size() const {
    return computed_background_size_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_background_size_;

  DISALLOW_COPY_AND_ASSIGN(ComputedBackgroundSizeProvider);
};

ComputedBackgroundSizeProvider::ComputedBackgroundSizeProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedBackgroundSizeProvider::VisitKeyword(KeywordValue* keyword) {
  computed_background_size_ = keyword;
}

void ComputedBackgroundSizeProvider::VisitPropertyList(
    PropertyListValue* property_list_value) {
  ComputedBackgroundSizeSingleValueProvider left_value_provider(
      computed_font_size_, root_computed_font_size_, viewport_size_);
  property_list_value->value()[0]->Accept(&left_value_provider);

  ComputedBackgroundSizeSingleValueProvider right_value_provider(
      computed_font_size_, root_computed_font_size_, viewport_size_);
  property_list_value->value()[1]->Accept(&right_value_provider);

  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());
  builder->reserve(2);
  builder->push_back(left_value_provider.computed_background_size());
  builder->push_back(right_value_provider.computed_background_size());
  computed_background_size_ = new PropertyListValue(builder.Pass());
}

//    https://www.w3.org/TR/css3-background/#border-radius
class ComputedBorderRadiusProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedBorderRadiusProvider(const LengthValue* computed_font_size,
                               const LengthValue* root_computed_font_size,
                               const math::Size& viewport_size);

  void VisitLength(LengthValue* specified_length);
  void VisitPercentage(PercentageValue* percentage);

  const scoped_refptr<PropertyValue>& computed_border_radius() const {
    return computed_border_radius_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_border_radius_;

  DISALLOW_COPY_AND_ASSIGN(ComputedBorderRadiusProvider);
};

ComputedBorderRadiusProvider::ComputedBorderRadiusProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedBorderRadiusProvider::VisitLength(LengthValue* specified_length) {
  computed_border_radius_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

void ComputedBorderRadiusProvider::VisitPercentage(
    PercentageValue* percentage) {
  computed_border_radius_ = percentage;
}

// Computed value: any <length> made absolute; any specified color computed;
// otherwise as specified.
//   https://www.w3.org/TR/css3-background/#box-shadow
//   https://www.w3.org/TR/css-text-decor-3/#text-shadow-property
class ComputedShadowProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedShadowProvider(const LengthValue* computed_font_size,
                         const LengthValue* root_computed_font_size,
                         const math::Size& viewport_size,
                         const RGBAColorValue* computed_color);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitPropertyList(PropertyListValue* property_list_value) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_shadow() const {
    return computed_shadow_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;
  const RGBAColorValue* computed_color_;

  scoped_refptr<PropertyValue> computed_shadow_;

  DISALLOW_COPY_AND_ASSIGN(ComputedShadowProvider);
};

ComputedShadowProvider::ComputedShadowProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size,
    const RGBAColorValue* computed_color)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size),
      computed_color_(computed_color) {}

void ComputedShadowProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kNone:
      computed_shadow_ = keyword;
      break;

    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kAuto:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kForwards:
    case KeywordValue::kFixed:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNormal:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

void ComputedShadowProvider::VisitPropertyList(
    PropertyListValue* property_list_value) {
  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());
  builder->reserve(property_list_value->value().size());

  for (size_t i = 0; i < property_list_value->value().size(); ++i) {
    ShadowValue* shadow_value = base::polymorphic_downcast<ShadowValue*>(
        property_list_value->value()[i].get());

    scoped_refptr<LengthValue> computed_lengths[ShadowValue::kMaxLengths];
    for (int j = 0; j < ShadowValue::kMaxLengths; ++j) {
      LengthValue* specified_length = shadow_value->lengths()[j].get();
      if (specified_length) {
        computed_lengths[j] =
            ProvideAbsoluteLength(specified_length, computed_font_size_,
                                  root_computed_font_size_, viewport_size_);
      }
    }

    scoped_refptr<RGBAColorValue> color = shadow_value->color();
    if (!color) {
      color = new RGBAColorValue(computed_color_->value());
    }

    builder->push_back(
        new ShadowValue(computed_lengths, color, shadow_value->has_inset()));
  }

  computed_shadow_ = new PropertyListValue(builder.Pass());
}

// Computed value: for length of translation transforms.
//   https://www.w3.org/TR/css3-transforms/#propdef-transform
class ComputedTransformFunctionProvider : public TransformFunctionVisitor {
 public:
  ComputedTransformFunctionProvider(const LengthValue* computed_font_size,
                                    const LengthValue* root_computed_font_size,
                                    const math::Size& viewport_size);

  void VisitMatrix(const MatrixFunction* matrix_function) OVERRIDE;
  void VisitRotate(const RotateFunction* rotate_function) OVERRIDE;
  void VisitScale(const ScaleFunction* scale_function) OVERRIDE;
  void VisitTranslate(const TranslateFunction* translate_function) OVERRIDE;

  scoped_ptr<TransformFunction> PassComputedTransformFunction() {
    return computed_transform_function_.Pass();
  }

 private:
  scoped_ptr<TransformFunction> computed_transform_function_;
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;
};

ComputedTransformFunctionProvider::ComputedTransformFunctionProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedTransformFunctionProvider::VisitMatrix(
    const MatrixFunction* matrix_function) {
  computed_transform_function_.reset(new MatrixFunction(*matrix_function));
}

void ComputedTransformFunctionProvider::VisitRotate(
    const RotateFunction* rotate_function) {
  computed_transform_function_.reset(new RotateFunction(*rotate_function));
}

void ComputedTransformFunctionProvider::VisitScale(
    const ScaleFunction* scale_function) {
  computed_transform_function_.reset(new ScaleFunction(*scale_function));
}

void ComputedTransformFunctionProvider::VisitTranslate(
    const TranslateFunction* translate_function) {
  switch (translate_function->offset_type()) {
    case TranslateFunction::kLength: {
      computed_transform_function_.reset(new TranslateFunction(
          translate_function->axis(),
          ProvideAbsoluteLength(translate_function->offset_as_length(),
                                computed_font_size_, root_computed_font_size_,
                                viewport_size_)));
    } break;
    case TranslateFunction::kPercentage: {
      computed_transform_function_.reset(
          new TranslateFunction(*translate_function));
    } break;
    case TranslateFunction::kCalc: {
      scoped_refptr<CalcValue> calc_value =
          translate_function->offset_as_calc();
      computed_transform_function_.reset(new TranslateFunction(
          translate_function->axis(),
          new CalcValue(ProvideAbsoluteLength(
                            calc_value->length_value(), computed_font_size_,
                            root_computed_font_size_, viewport_size_),
                        calc_value->percentage_value())));
    } break;
    default: { NOTREACHED(); }
  }
}

// Absolutizes the value of "text-indent" property.
class ComputedTextIndentProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedTextIndentProvider(const LengthValue* computed_font_size,
                             const LengthValue* root_computed_font_size,
                             const math::Size& viewport_size);

  void VisitLength(LengthValue* length) OVERRIDE;

  const scoped_refptr<LengthValue>& computed_text_indent() const {
    return computed_text_indent_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<LengthValue> computed_text_indent_;

  DISALLOW_COPY_AND_ASSIGN(ComputedTextIndentProvider);
};

ComputedTextIndentProvider::ComputedTextIndentProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedTextIndentProvider::VisitLength(LengthValue* specified_length) {
  computed_text_indent_ =
      ProvideAbsoluteLength(specified_length, computed_font_size_,
                            root_computed_font_size_, viewport_size_);
}

// ComputedTransformOriginProvider provides a property list which has three
// PropertyValues. The first two PropertyValues are CalcValue to represent
// the horizontal position (or offset) and the vertical position (or offset).
// The third value always represents the Z position (or offset) and must be a
// LengthValue.
//  https://www.w3.org/TR/css3-transforms/#propdef-transform-origin
class ComputedTransformOriginProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedTransformOriginProvider(const LengthValue* computed_font_size,
                                  const LengthValue* root_computed_font_size,
                                  const math::Size& viewport_size);

  void VisitPropertyList(PropertyListValue* property_list_value) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_transform_origin() const {
    return computed_transform_origin_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_transform_origin_;

  DISALLOW_COPY_AND_ASSIGN(ComputedTransformOriginProvider);
};

ComputedTransformOriginProvider::ComputedTransformOriginProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedTransformOriginProvider::VisitPropertyList(
    PropertyListValue* property_list_value) {
  size_t size = property_list_value->value().size();
  DCHECK_GE(size, 1u);
  DCHECK_LE(size, 3u);

  ComputedPositionHelper position_helper(
      computed_font_size_, root_computed_font_size_, viewport_size_);
  scoped_ptr<PropertyListValue::Builder> transform_origin_builder(
      new PropertyListValue::Builder(3, scoped_refptr<PropertyValue>()));

  // If one or two values are specified, the third value is assumed to be 0px.
  switch (size) {
    case 1:
    case 2:
      position_helper.ComputePosition(property_list_value->value(),
                                      transform_origin_builder.get());
      (*transform_origin_builder)[2] = new LengthValue(0.0f, kPixelsUnit);
      break;
    case 3:
      position_helper.ComputeTwoValuesPosition(property_list_value->value(),
                                               transform_origin_builder.get());
      // The third value must be LengthValue type.
      (*transform_origin_builder)[2] = ProvideAbsoluteLength(
          base::polymorphic_downcast<LengthValue*>(
              property_list_value->value()[2].get()),
          computed_font_size_, root_computed_font_size_, viewport_size_);
      break;
    default:
      NOTREACHED();
  }

  computed_transform_origin_ =
      new PropertyListValue(transform_origin_builder.Pass());
}

namespace {

// Functionality to check if a transform contains any relative units, such as
// "em" or "rem".

class TransformFunctionContainsRelativeUnitVisitor
    : public TransformFunctionVisitor {
 public:
  TransformFunctionContainsRelativeUnitVisitor()
      : contains_relative_unit_(false) {}

  void VisitMatrix(const MatrixFunction* matrix_function) OVERRIDE {
    UNREFERENCED_PARAMETER(matrix_function);
  }
  void VisitRotate(const RotateFunction* rotate_function) OVERRIDE {
    UNREFERENCED_PARAMETER(rotate_function);
  }
  void VisitScale(const ScaleFunction* scale_function) OVERRIDE {
    UNREFERENCED_PARAMETER(scale_function);
  }
  void VisitTranslate(const TranslateFunction* translate_function) OVERRIDE {
    contains_relative_unit_ =
        translate_function->offset_type() == TranslateFunction::kLength &&
        translate_function->offset_as_length()->IsUnitRelative();
  }

  bool contains_relative_unit() const { return contains_relative_unit_; }

 private:
  bool contains_relative_unit_;
};

bool TransformListContainsRelativeUnits(
    TransformFunctionListValue* transform_function_list) {
  for (TransformFunctionListValue::Builder::const_iterator iter =
           transform_function_list->value().begin();
       iter != transform_function_list->value().end(); ++iter) {
    TransformFunction* transform_function = *iter;

    TransformFunctionContainsRelativeUnitVisitor contains_ems_visitor;
    transform_function->Accept(&contains_ems_visitor);
    if (contains_ems_visitor.contains_relative_unit()) {
      return true;
    }
  }
  return false;
}

}  // namespace

class ComputedTransformProvider : public NotReachedPropertyValueVisitor {
 public:
  ComputedTransformProvider(const LengthValue* computed_font_size,
                            const LengthValue* root_computed_font_size,
                            const math::Size& viewport_size);

  void VisitKeyword(KeywordValue* keyword) OVERRIDE;
  void VisitTransformFunctionList(
      TransformFunctionListValue* transform_function_list) OVERRIDE;

  const scoped_refptr<PropertyValue>& computed_transform_list() const {
    return computed_transform_list_;
  }

 private:
  const LengthValue* computed_font_size_;
  const LengthValue* root_computed_font_size_;
  const math::Size& viewport_size_;

  scoped_refptr<PropertyValue> computed_transform_list_;

  DISALLOW_COPY_AND_ASSIGN(ComputedTransformProvider);
};

ComputedTransformProvider::ComputedTransformProvider(
    const LengthValue* computed_font_size,
    const LengthValue* root_computed_font_size, const math::Size& viewport_size)
    : computed_font_size_(computed_font_size),
      root_computed_font_size_(root_computed_font_size),
      viewport_size_(viewport_size) {}

void ComputedTransformProvider::VisitTransformFunctionList(
    TransformFunctionListValue* transform_function_list) {
  if (!TransformListContainsRelativeUnits(transform_function_list)) {
    // If the transform list contains no transforms that use relative units,
    // then we do not need to do anything and we can pass through the existing
    // transform.
    computed_transform_list_ = transform_function_list;
  } else {
    // The transform list contains at least one transform with relative units.
    // In this case, rebuild the transform list with computed length values.
    TransformFunctionListValue::Builder computed_list_builder;

    for (TransformFunctionListValue::Builder::const_iterator iter =
             transform_function_list->value().begin();
         iter != transform_function_list->value().end(); ++iter) {
      TransformFunction* transform_function = *iter;

      ComputedTransformFunctionProvider computed_transform_function_provider(
          computed_font_size_, root_computed_font_size_, viewport_size_);
      transform_function->Accept(&computed_transform_function_provider);

      computed_list_builder.push_back(
          computed_transform_function_provider.PassComputedTransformFunction()
              .release());
    }

    computed_transform_list_ =
        new TransformFunctionListValue(computed_list_builder.Pass());
  }
}

void ComputedTransformProvider::VisitKeyword(KeywordValue* keyword) {
  switch (keyword->value()) {
    case KeywordValue::kNone:
      computed_transform_list_ = keyword;
      break;
    case KeywordValue::kAbsolute:
    case KeywordValue::kAlternate:
    case KeywordValue::kAlternateReverse:
    case KeywordValue::kAuto:
    case KeywordValue::kBackwards:
    case KeywordValue::kBaseline:
    case KeywordValue::kBlock:
    case KeywordValue::kBoth:
    case KeywordValue::kBottom:
    case KeywordValue::kBreakWord:
    case KeywordValue::kCenter:
    case KeywordValue::kClip:
    case KeywordValue::kContain:
    case KeywordValue::kCover:
    case KeywordValue::kCurrentColor:
    case KeywordValue::kCursive:
    case KeywordValue::kEllipsis:
    case KeywordValue::kEnd:
    case KeywordValue::kFantasy:
    case KeywordValue::kFixed:
    case KeywordValue::kForwards:
    case KeywordValue::kHidden:
    case KeywordValue::kInfinite:
    case KeywordValue::kInherit:
    case KeywordValue::kInitial:
    case KeywordValue::kInline:
    case KeywordValue::kInlineBlock:
    case KeywordValue::kLeft:
    case KeywordValue::kLineThrough:
    case KeywordValue::kMiddle:
    case KeywordValue::kMonoscopic:
    case KeywordValue::kMonospace:
    case KeywordValue::kNoRepeat:
    case KeywordValue::kNormal:
    case KeywordValue::kNoWrap:
    case KeywordValue::kPre:
    case KeywordValue::kPreLine:
    case KeywordValue::kPreWrap:
    case KeywordValue::kRelative:
    case KeywordValue::kRepeat:
    case KeywordValue::kReverse:
    case KeywordValue::kRight:
    case KeywordValue::kSansSerif:
    case KeywordValue::kSerif:
    case KeywordValue::kSolid:
    case KeywordValue::kStart:
    case KeywordValue::kStatic:
    case KeywordValue::kStereoscopicLeftRight:
    case KeywordValue::kStereoscopicTopBottom:
    case KeywordValue::kTop:
    case KeywordValue::kUppercase:
    case KeywordValue::kVisible:
    default:
      NOTREACHED();
  }
}

// This helper class creates a context within which cascaded style properties
// can be efficiently promoted to computed properties.
// In particular, some computed style calculations depend on other computed
// styles, and this class manages the caching of those dependent values so that
// if they are depended upon more than once, they are quickly recalled, and if
// they are never depended upon, no extra time is spend resolving them.  For
// example, many properties depend on font size, and so they can simply call
// CalculateComputedStyleContext::GetFontSize() to obtain that value, and all
// computations will be handled internally.
class CalculateComputedStyleContext {
 public:
  CalculateComputedStyleContext(
      CSSComputedStyleData* cascaded_style,
      const scoped_refptr<CSSComputedStyleDeclaration>&
          parent_computed_style_declaration,
      const scoped_refptr<const CSSComputedStyleData>& root_computed_style,
      const math::Size& viewport_size,
      GURLMap* const property_key_to_base_url_map)
      : cascaded_style_(cascaded_style),
        parent_computed_style_(*parent_computed_style_declaration->data()),
        root_computed_style_(*root_computed_style),
        viewport_size_(viewport_size),
        property_key_to_base_url_map_(property_key_to_base_url_map) {
    cascaded_style_->SetParentComputedStyleDeclaration(
        parent_computed_style_declaration);
  }

  // Updates the property specified by the iterator to its computed value.
  void SetComputedStyleForProperty(PropertyKey key,
                                   scoped_refptr<PropertyValue>* value);

 private:
  // Immediately promote the specified property key to computed value (if
  // necessary).
  void ComputeValue(PropertyKey key);

  // Check if the property value is set to inherit or initial, and assign it
  // an appropriate computed value in this case.
  bool HandleInheritOrInitial(PropertyKey key,
                              scoped_refptr<PropertyValue>* value);

  // Check what property property we are dealing with, and promote it to
  // a computed value accordingly (e.g. by invoking one of the many different
  // computed style computations defined above.)
  void HandleSpecifiedValue(PropertyKey key,
                            scoped_refptr<PropertyValue>* value);

  // If the modified value was a (potentially) dependent property value, cache
  // its computed value so that we know it has been computed.
  void OnComputedStyleCalculated(PropertyKey key,
                                 const scoped_refptr<PropertyValue>& value);

  // Helper function to determine if the computed style implies absolute
  // positioning.
  bool IsAbsolutelyPositioned();

  // Helper function to return the computed font size.
  LengthValue* GetFontSize();
  // Helper function to return the computed font size of root element.
  LengthValue* GetRootFontSize();
  // Helper function to return one percent of the viewport size .
  const math::Size& GetViewportSizeOnePercent();

  // Helper function to return the computed border style for an edge based on
  // border width properties.
  PropertyValue* GetBorderStyleBasedOnWidth(PropertyKey key);
  PropertyValue* GetBorderBottomStyle();
  PropertyValue* GetBorderLeftStyle();
  PropertyValue* GetBorderRightStyle();
  PropertyValue* GetBorderTopStyle();

  // Helper function to return the computed color.
  RGBAColorValue* GetColor();

  // The style that, during the scope of CalculateComputedStyleContext, is
  // promoted from being a cascaded style to a computed style.
  CSSComputedStyleData* cascaded_style_;

  // The parent computed style.
  const CSSComputedStyleData& parent_computed_style_;
  // The root computed style.
  const CSSComputedStyleData& root_computed_style_;

  // One percent of width and height of viewport size.
  const math::Size& viewport_size_;

  // Provides a base URL for each property key.  This is used by properties
  // that deal with URLs, such as background-image, to resolve relative URLs
  // based on which style sheet they were specified from.
  GURLMap* const property_key_to_base_url_map_;

  // Cached computed values for a small specific set of properties that other
  // properties computed style calculations depend upon.  These are lazily
  // computed.
  scoped_refptr<PropertyValue> computed_border_bottom_style_;
  scoped_refptr<PropertyValue> computed_border_left_style_;
  scoped_refptr<PropertyValue> computed_border_right_style_;
  scoped_refptr<PropertyValue> computed_border_top_style_;
  scoped_refptr<PropertyValue> computed_color_;
  scoped_refptr<PropertyValue> computed_font_size_;
  scoped_refptr<PropertyValue> computed_position_;
};

void CalculateComputedStyleContext::SetComputedStyleForProperty(
    PropertyKey key, scoped_refptr<PropertyValue>* value) {
  // If a property has keyword value 'inherit' or 'initial', it must be
  // set to the corresponding inherited or initial value.  In this case,
  // the parent's value is already computed so we can skip the computation
  // step.
  if (!HandleInheritOrInitial(key, value)) {
    HandleSpecifiedValue(key, value);
  }
  OnComputedStyleCalculated(key, *value);
}

bool CalculateComputedStyleContext::IsAbsolutelyPositioned() {
  // An absolutely positioned element (or its box) implies that the element's
  // 'position' property has the value 'absolute' or 'fixed'.
  //   https://www.w3.org/TR/CSS21/visuren.html#absolutely-positioned
  if (!computed_position_) {
    ComputeValue(kPositionProperty);
  }

  DCHECK(computed_position_);
  return computed_position_ == KeywordValue::GetAbsolute() ||
         computed_position_ == KeywordValue::GetFixed();
}

LengthValue* CalculateComputedStyleContext::GetFontSize() {
  if (!computed_font_size_) {
    ComputeValue(kFontSizeProperty);
  }

  DCHECK(computed_font_size_);
  return base::polymorphic_downcast<LengthValue*>(computed_font_size_.get());
}

LengthValue* CalculateComputedStyleContext::GetRootFontSize() {
  return base::polymorphic_downcast<LengthValue*>(
      root_computed_style_.font_size().get());
}

const math::Size& CalculateComputedStyleContext::GetViewportSizeOnePercent() {
  return viewport_size_;
}

PropertyValue* CalculateComputedStyleContext::GetBorderStyleBasedOnWidth(
    PropertyKey key) {
  if (key == kBorderBottomWidthProperty) {
    return GetBorderBottomStyle();
  } else if (key == kBorderLeftWidthProperty) {
    return GetBorderLeftStyle();
  } else if (key == kBorderRightWidthProperty) {
    return GetBorderRightStyle();
  } else {
    DCHECK_EQ(key, kBorderTopWidthProperty);
    return GetBorderTopStyle();
  }
}

PropertyValue* CalculateComputedStyleContext::GetBorderBottomStyle() {
  if (!computed_border_bottom_style_) {
    ComputeValue(kBorderBottomStyleProperty);
  }

  DCHECK(computed_border_bottom_style_);
  return computed_border_bottom_style_.get();
}

PropertyValue* CalculateComputedStyleContext::GetBorderLeftStyle() {
  if (!computed_border_left_style_) {
    ComputeValue(kBorderLeftStyleProperty);
  }

  DCHECK(computed_border_left_style_);
  return computed_border_left_style_.get();
}

PropertyValue* CalculateComputedStyleContext::GetBorderRightStyle() {
  if (!computed_border_right_style_) {
    ComputeValue(kBorderRightStyleProperty);
  }

  DCHECK(computed_border_right_style_);
  return computed_border_right_style_.get();
}

PropertyValue* CalculateComputedStyleContext::GetBorderTopStyle() {
  if (!computed_border_top_style_) {
    ComputeValue(kBorderTopStyleProperty);
  }

  DCHECK(computed_border_top_style_);
  return computed_border_top_style_.get();
}

RGBAColorValue* CalculateComputedStyleContext::GetColor() {
  if (!computed_color_) {
    ComputeValue(kColorProperty);
  }

  DCHECK(computed_color_);
  return base::polymorphic_downcast<RGBAColorValue*>(computed_color_.get());
}

void CalculateComputedStyleContext::ComputeValue(PropertyKey key) {
  if (cascaded_style_->IsDeclared(key)) {
    scoped_refptr<PropertyValue>& cascaded_value =
        cascaded_style_->GetDeclaredPropertyValueReference(key);
    SetComputedStyleForProperty(key, &cascaded_value);
  } else {
    const scoped_refptr<PropertyValue>& computed_value =
        cascaded_style_->GetPropertyValueReference(key);
    OnComputedStyleCalculated(key, computed_value);
  }
}

bool CalculateComputedStyleContext::HandleInheritOrInitial(
    PropertyKey key, scoped_refptr<PropertyValue>* value) {
  if (*value == KeywordValue::GetInherit()) {
    // Add this property to the list of those that inherited their declared
    // value from the parent. This allows the computed style to later determine
    // if a value that was explicitly inherited from the parent is no longer
    // valid.
    cascaded_style_->AddDeclaredPropertyInheritedFromParent(key);
    *value = parent_computed_style_.GetPropertyValue(key);
    return true;
  } else if (*value == KeywordValue::GetInitial()) {
    *value = GetPropertyInitialValue(key);
    // If the initial value is current color, it still requires to do further
    // processing.
    return *value == KeywordValue::GetCurrentColor() ? false : true;
  } else {
    return false;
  }
}

void CalculateComputedStyleContext::HandleSpecifiedValue(
    PropertyKey key, scoped_refptr<PropertyValue>* value) {
  switch (key) {
    case kBackgroundPositionProperty: {
      ComputedBackgroundPositionProvider background_position_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&background_position_provider);
      const scoped_refptr<PropertyValue>& computed_background_position =
          background_position_provider.computed_background_position();
      if (computed_background_position) {
        *value = computed_background_position;
      }
    } break;
    case kBorderBottomColorProperty:
    case kBorderLeftColorProperty:
    case kBorderRightColorProperty:
    case kBorderTopColorProperty:
    case kTextDecorationColorProperty: {
      if (*value == KeywordValue::GetCurrentColor()) {
        // The computed value of the 'currentColor' keyword is the computed
        // value of the 'color' property.
        *value = GetColor();
      }
    } break;
    case kBorderBottomWidthProperty:
    case kBorderLeftWidthProperty:
    case kBorderRightWidthProperty:
    case kBorderTopWidthProperty: {
      ComputedBorderWidthProvider border_width_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent(),
          GetBorderStyleBasedOnWidth(key));
      (*value)->Accept(&border_width_provider);
      *value = border_width_provider.computed_border_width();
    } break;
    case kBoxShadowProperty:
    case kTextShadowProperty: {
      ComputedShadowProvider shadow_provider(GetFontSize(), GetRootFontSize(),
                                             GetViewportSizeOnePercent(),
                                             GetColor());
      (*value)->Accept(&shadow_provider);
      *value = shadow_provider.computed_shadow();
    } break;
    case kDisplayProperty: {
      // According to https://www.w3.org/TR/CSS21/visuren.html#dis-pos-flo,
      // "inline" and "inline-block" values of "display" become "block" if
      // "position" is "absolute" or "fixed".
      // TODO: Modify this logic so that the original display value is
      // not lost. Being unable to determine the original value breaks static
      // positioning of "inline" and "inline-block" values with absolute
      // positioning, because they are treated as block boxes but are supposed
      // to placed at the position they would be in the normal flow.
      // https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
      if ((*value == KeywordValue::GetInline() ||
           *value == KeywordValue::GetInlineBlock()) &&
          IsAbsolutelyPositioned()) {
        *value = KeywordValue::GetBlock();
      }
    } break;
    case kFontSizeProperty: {
      // Only compute this if computed_font_size_ isn't set, otherwise that
      // is an indication that it was previously computed as a dependency for
      // another property value computation.
      if (!computed_font_size_) {
        ComputedFontSizeProvider font_size_provider(
            base::polymorphic_downcast<LengthValue*>(
                parent_computed_style_.font_size().get()),
            GetRootFontSize(), GetViewportSizeOnePercent());
        (*value)->Accept(&font_size_provider);
        if (font_size_provider.computed_font_size()) {
          *value = font_size_provider.computed_font_size();
        }
      }
    } break;
    case kFontWeightProperty: {
      ComputedFontWeightProvider font_weight_provider;
      (*value)->Accept(&font_weight_provider);
      *value = font_weight_provider.computed_font_weight();
    } break;
    case kHeightProperty: {
      ComputedHeightProvider height_provider(
          parent_computed_style_.height().get(), GetFontSize(),
          GetRootFontSize(), GetViewportSizeOnePercent(),
          IsAbsolutelyPositioned());
      (*value)->Accept(&height_provider);
      *value = height_provider.computed_height();
    } break;
    case kLineHeightProperty: {
      ComputedLineHeightProvider line_height_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&line_height_provider);
      *value = line_height_provider.computed_line_height();
    } break;
    case kMarginBottomProperty:
    case kMarginLeftProperty:
    case kMarginRightProperty:
    case kMarginTopProperty: {
      ComputedMarginOrPaddingEdgeProvider margin_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&margin_provider);
      *value = margin_provider.computed_margin_or_padding_edge();
    } break;
    case kPaddingBottomProperty:
    case kPaddingLeftProperty:
    case kPaddingRightProperty:
    case kPaddingTopProperty: {
      ComputedMarginOrPaddingEdgeProvider padding_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&padding_provider);
      *value = padding_provider.computed_margin_or_padding_edge();
    } break;
    case kMaxHeightProperty: {
      ComputedMaxHeightProvider max_height_provider(
          parent_computed_style_.height().get(), GetFontSize(),
          GetRootFontSize(), GetViewportSizeOnePercent(),
          IsAbsolutelyPositioned());
      (*value)->Accept(&max_height_provider);
      *value = max_height_provider.computed_max_height();
    } break;
    case kMinHeightProperty: {
      ComputedMinHeightProvider min_height_provider(
          parent_computed_style_.height().get(), GetFontSize(),
          GetRootFontSize(), GetViewportSizeOnePercent(),
          IsAbsolutelyPositioned());
      (*value)->Accept(&min_height_provider);
      *value = min_height_provider.computed_min_height();
    } break;
    case kMaxWidthProperty:
    case kMinWidthProperty: {
      ComputedMinMaxWidthProvider min_max_width_provider(
          parent_computed_style_.width().get(), GetFontSize(),
          GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&min_max_width_provider);
      *value = min_max_width_provider.computed_min_max_width();
    } break;
    case kWidthProperty: {
      ComputedWidthProvider width_provider(GetFontSize(), GetRootFontSize(),
                                           GetViewportSizeOnePercent());
      (*value)->Accept(&width_provider);
      *value = width_provider.computed_width();
    } break;
    case kBackgroundImageProperty: {
      if (property_key_to_base_url_map_) {
        ComputedBackgroundImageProvider background_image_provider(
            (*property_key_to_base_url_map_)[kBackgroundImageProperty],
            GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
        (*value)->Accept(&background_image_provider);
        *value = background_image_provider.computed_background_image();
      }
    } break;
    case kBackgroundSizeProperty: {
      ComputedBackgroundSizeProvider background_size_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&background_size_provider);
      *value = background_size_provider.computed_background_size();
    } break;
    case kBorderRadiusProperty: {
      ComputedBorderRadiusProvider border_radius_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&border_radius_provider);
      *value = border_radius_provider.computed_border_radius();
    } break;
    case kTextIndentProperty: {
      ComputedTextIndentProvider text_indent_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&text_indent_provider);
      *value = text_indent_provider.computed_text_indent();
    } break;
    case kTransformOriginProperty: {
      ComputedTransformOriginProvider transform_origin_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&transform_origin_provider);
      *value = transform_origin_provider.computed_transform_origin();
    } break;
    case kTransformProperty: {
      ComputedTransformProvider transform_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&transform_provider);
      *value = transform_provider.computed_transform_list();
    } break;
    case kBottomProperty:
    case kLeftProperty:
    case kRightProperty:
    case kTopProperty: {
      ComputedPositionOffsetProvider position_offset_provider(
          GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent());
      (*value)->Accept(&position_offset_provider);
      *value = position_offset_provider.computed_position_offset();
    } break;
    case kAnimationDelayProperty:
    case kAnimationDirectionProperty:
    case kAnimationDurationProperty:
    case kAnimationFillModeProperty:
    case kAnimationIterationCountProperty:
    case kAnimationNameProperty:
    case kAnimationTimingFunctionProperty:
    case kBackgroundColorProperty:
    case kBackgroundRepeatProperty:
    case kBorderBottomStyleProperty:
    case kBorderLeftStyleProperty:
    case kBorderRightStyleProperty:
    case kBorderTopStyleProperty:
    case kColorProperty:
    case kContentProperty:
    case kFilterProperty:
    case kFontFamilyProperty:
    case kFontStyleProperty:
    case kOpacityProperty:
    case kOverflowProperty:
    case kOverflowWrapProperty:
    case kPositionProperty:
    case kTextAlignProperty:
    case kTextDecorationLineProperty:
    case kTextOverflowProperty:
    case kTextTransformProperty:
    case kTransitionDelayProperty:
    case kTransitionDurationProperty:
    case kTransitionPropertyProperty:
    case kTransitionTimingFunctionProperty:
    case kVerticalAlignProperty:
    case kVisibilityProperty:
    case kWhiteSpaceProperty:
    case kWordWrapProperty:
    case kZIndexProperty:
      // Nothing.
      break;
    case kNoneProperty:
    case kAllProperty:
    case kAnimationProperty:
    case kBackgroundProperty:
    case kBorderBottomProperty:
    case kBorderColorProperty:
    case kBorderLeftProperty:
    case kBorderProperty:
    case kBorderRightProperty:
    case kBorderStyleProperty:
    case kBorderTopProperty:
    case kBorderWidthProperty:
    case kFontProperty:
    case kMarginProperty:
    case kPaddingProperty:
    case kSrcProperty:
    case kTextDecorationProperty:
    case kTransitionProperty:
    case kUnicodeRangeProperty:
    default:
      NOTREACHED();
      break;
  }
}

void CalculateComputedStyleContext::OnComputedStyleCalculated(
    PropertyKey key, const scoped_refptr<PropertyValue>& value) {
  switch (key) {
    case kFontSizeProperty:
      computed_font_size_ = value;
      break;
    case kPositionProperty:
      computed_position_ = value;
      break;
    case kBorderBottomStyleProperty:
      computed_border_bottom_style_ = value;
      break;
    case kBorderLeftStyleProperty:
      computed_border_left_style_ = value;
      break;
    case kBorderRightStyleProperty:
      computed_border_right_style_ = value;
      break;
    case kBorderTopStyleProperty:
      computed_border_top_style_ = value;
      break;
    case kColorProperty:
      computed_color_ = value;
      break;

    case kAllProperty:
    case kAnimationDelayProperty:
    case kAnimationDirectionProperty:
    case kAnimationDurationProperty:
    case kAnimationFillModeProperty:
    case kAnimationIterationCountProperty:
    case kAnimationNameProperty:
    case kAnimationProperty:
    case kAnimationTimingFunctionProperty:
    case kBackgroundColorProperty:
    case kBackgroundImageProperty:
    case kBackgroundPositionProperty:
    case kBackgroundProperty:
    case kBackgroundRepeatProperty:
    case kBackgroundSizeProperty:
    case kBorderBottomProperty:
    case kBorderBottomColorProperty:
    case kBorderBottomWidthProperty:
    case kBorderColorProperty:
    case kBorderLeftProperty:
    case kBorderLeftColorProperty:
    case kBorderLeftWidthProperty:
    case kBorderRadiusProperty:
    case kBorderRightProperty:
    case kBorderRightColorProperty:
    case kBorderRightWidthProperty:
    case kBorderStyleProperty:
    case kBorderTopProperty:
    case kBorderTopColorProperty:
    case kBorderTopWidthProperty:
    case kBorderProperty:
    case kBorderWidthProperty:
    case kBottomProperty:
    case kBoxShadowProperty:
    case kContentProperty:
    case kDisplayProperty:
    case kFilterProperty:
    case kFontFamilyProperty:
    case kFontProperty:
    case kFontStyleProperty:
    case kFontWeightProperty:
    case kHeightProperty:
    case kLeftProperty:
    case kLineHeightProperty:
    case kMarginBottomProperty:
    case kMarginLeftProperty:
    case kMarginProperty:
    case kMarginRightProperty:
    case kMarginTopProperty:
    case kMaxHeightProperty:
    case kMaxWidthProperty:
    case kMinHeightProperty:
    case kMinWidthProperty:
    case kNoneProperty:
    case kOpacityProperty:
    case kOverflowProperty:
    case kOverflowWrapProperty:
    case kPaddingBottomProperty:
    case kPaddingLeftProperty:
    case kPaddingProperty:
    case kPaddingRightProperty:
    case kPaddingTopProperty:
    case kRightProperty:
    case kSrcProperty:
    case kTextAlignProperty:
    case kTextDecorationColorProperty:
    case kTextDecorationLineProperty:
    case kTextDecorationProperty:
    case kTextIndentProperty:
    case kTextOverflowProperty:
    case kTextShadowProperty:
    case kTextTransformProperty:
    case kTopProperty:
    case kTransformOriginProperty:
    case kTransformProperty:
    case kTransitionDelayProperty:
    case kTransitionDurationProperty:
    case kTransitionProperty:
    case kTransitionPropertyProperty:
    case kTransitionTimingFunctionProperty:
    case kUnicodeRangeProperty:
    case kVerticalAlignProperty:
    case kVisibilityProperty:
    case kWhiteSpaceProperty:
    case kWidthProperty:
    case kWordWrapProperty:
    case kZIndexProperty:
      break;
  }
}

}  // namespace

void PromoteToComputedStyle(
    const scoped_refptr<CSSComputedStyleData>& cascaded_style,
    const scoped_refptr<CSSComputedStyleDeclaration>&
        parent_computed_style_declaration,
    const scoped_refptr<const CSSComputedStyleData>& root_computed_style,
    const math::Size& viewport_size,
    GURLMap* const property_key_to_base_url_map) {
  DCHECK(cascaded_style);
  DCHECK(parent_computed_style_declaration);
  DCHECK(root_computed_style);

  // Create a context for calculating the computed style.  This object is useful
  // because it can cache computed style values that are depended upon by other
  // properties' computed style calculations.
  CalculateComputedStyleContext calculate_computed_style_context(
      cascaded_style.get(), parent_computed_style_declaration,
      root_computed_style, viewport_size, property_key_to_base_url_map);

  // For each inherited, animatable property, set the property value to
  // inherited if it is not already declared. This causes the value to be
  // explicitly set within the CSSComputedStyleData and ensures that the
  // original value will be available for transitions (which need to know the
  // before and after state of the property) even when the property is inherited
  // from a parent that has changed.
  const PropertyKeyVector& inherited_animatable_properties =
      GetInheritedAnimatableProperties();
  for (PropertyKeyVector::const_iterator iter =
           inherited_animatable_properties.begin();
       iter != inherited_animatable_properties.end(); ++iter) {
    if (!cascaded_style->IsDeclared(*iter)) {
      cascaded_style->SetPropertyValue(*iter, KeywordValue::GetInherit());
    }
  }

  // Go through all declared values and calculate their computed values.
  CSSComputedStyleData::PropertyValues* declared_property_values =
      cascaded_style->declared_property_values();
  for (CSSComputedStyleData::PropertyValues::iterator property_value_iterator =
           declared_property_values->begin();
       property_value_iterator != declared_property_values->end();
       ++property_value_iterator) {
    calculate_computed_style_context.SetComputedStyleForProperty(
        property_value_iterator->first, &property_value_iterator->second);
  }
}

scoped_refptr<CSSComputedStyleData> GetComputedStyleOfAnonymousBox(
    const scoped_refptr<CSSComputedStyleDeclaration>&
        parent_computed_style_declaration) {
  scoped_refptr<CSSComputedStyleData> computed_style =
      new CSSComputedStyleData();
  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style_declaration->data(),
                         math::Size(), NULL);
  return computed_style;
}

}  // namespace cssom
}  // namespace cobalt
