/*
 * 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/css_style_declaration.h"

#include "base/string_util.h"
#include "cobalt/base/source_location.h"
#include "cobalt/cssom/css_declaration_util.h"
#include "cobalt/cssom/css_rule.h"
#include "cobalt/cssom/property_definitions.h"

namespace cobalt {
namespace cssom {

std::string CSSStyleDeclaration::animation(
    script::ExceptionState* /*exception_state*/) const {
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_animation(
    const std::string& animation, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kAnimationProperty, animation, exception_state);
}

std::string CSSStyleDeclaration::animation_delay(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kAnimationDelayProperty);
}

void CSSStyleDeclaration::set_animation_delay(
    const std::string& animation_delay,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kAnimationDelayProperty, animation_delay,
                              exception_state);
}

std::string CSSStyleDeclaration::animation_direction(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kAnimationDirectionProperty);
}

void CSSStyleDeclaration::set_animation_direction(
    const std::string& animation_direction,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kAnimationDirectionProperty, animation_direction,
                              exception_state);
}

std::string CSSStyleDeclaration::animation_duration(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kAnimationDurationProperty);
}

void CSSStyleDeclaration::set_animation_duration(
    const std::string& animation_duration,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kAnimationDurationProperty, animation_duration,
                              exception_state);
}

std::string CSSStyleDeclaration::animation_fill_mode(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kAnimationFillModeProperty);
}

void CSSStyleDeclaration::set_animation_fill_mode(
    const std::string& animation_fill_mode,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kAnimationFillModeProperty, animation_fill_mode,
                              exception_state);
}

std::string CSSStyleDeclaration::animation_iteration_count(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kAnimationIterationCountProperty);
}

void CSSStyleDeclaration::set_animation_iteration_count(
    const std::string& animation_iteration_count,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kAnimationIterationCountProperty,
                              animation_iteration_count, exception_state);
}

std::string CSSStyleDeclaration::animation_name(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kAnimationNameProperty);
}

void CSSStyleDeclaration::set_animation_name(
    const std::string& animation_name,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kAnimationNameProperty, animation_name,
                              exception_state);
}

std::string CSSStyleDeclaration::animation_timing_function(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kAnimationTimingFunctionProperty);
}

void CSSStyleDeclaration::set_animation_timing_function(
    const std::string& animation_timing_function,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kAnimationTimingFunctionProperty,
                              animation_timing_function, exception_state);
}

std::string CSSStyleDeclaration::background(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other background properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_background(
    const std::string& background, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBackgroundProperty, background, exception_state);
}

std::string CSSStyleDeclaration::background_color(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBackgroundColorProperty);
}

void CSSStyleDeclaration::set_background_color(
    const std::string& background_color,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBackgroundColorProperty, background_color,
                              exception_state);
}

std::string CSSStyleDeclaration::background_image(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBackgroundImageProperty);
}

void CSSStyleDeclaration::set_background_image(
    const std::string& background_image,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBackgroundImageProperty, background_image,
                              exception_state);
}

std::string CSSStyleDeclaration::background_position(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBackgroundPositionProperty);
}

void CSSStyleDeclaration::set_background_position(
    const std::string& background_position,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBackgroundPositionProperty, background_position,
                              exception_state);
}

std::string CSSStyleDeclaration::background_repeat(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBackgroundRepeatProperty);
}

void CSSStyleDeclaration::set_background_repeat(
    const std::string& background_repeat,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBackgroundRepeatProperty, background_repeat,
                              exception_state);
}

std::string CSSStyleDeclaration::background_size(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBackgroundSizeProperty);
}

void CSSStyleDeclaration::set_background_size(
    const std::string& background_size,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBackgroundSizeProperty, background_size,
                              exception_state);
}

std::string CSSStyleDeclaration::border(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other border properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_border(const std::string& border,
                                     script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderProperty, border, exception_state);
}

std::string CSSStyleDeclaration::border_bottom(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other border bottom properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_border_bottom(
    const std::string& border_bottom, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderBottomProperty, border_bottom,
                              exception_state);
}

std::string CSSStyleDeclaration::border_left(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other border left properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_border_left(
    const std::string& border_left, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderLeftProperty, border_left,
                              exception_state);
}

std::string CSSStyleDeclaration::border_right(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other border right properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_border_right(
    const std::string& border_right, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderRightProperty, border_right,
                              exception_state);
}

std::string CSSStyleDeclaration::border_top(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other border top properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_border_top(
    const std::string& border_top, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderTopProperty, border_top, exception_state);
}

std::string CSSStyleDeclaration::border_color(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other border color properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_border_color(
    const std::string& border_color, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderColorProperty, border_color,
                              exception_state);
}

std::string CSSStyleDeclaration::border_top_color(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderTopColorProperty);
}

void CSSStyleDeclaration::set_border_top_color(
    const std::string& border_top_color,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderTopColorProperty, border_top_color,
                              exception_state);
}

std::string CSSStyleDeclaration::border_right_color(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderRightColorProperty);
}

void CSSStyleDeclaration::set_border_right_color(
    const std::string& border_right_color,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderRightColorProperty, border_right_color,
                              exception_state);
}

std::string CSSStyleDeclaration::border_bottom_color(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderBottomColorProperty);
}

void CSSStyleDeclaration::set_border_bottom_color(
    const std::string& border_bottom_color,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderBottomColorProperty, border_bottom_color,
                              exception_state);
}

std::string CSSStyleDeclaration::border_left_color(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderLeftColorProperty);
}

void CSSStyleDeclaration::set_border_left_color(
    const std::string& border_left_color,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderLeftColorProperty, border_left_color,
                              exception_state);
}

std::string CSSStyleDeclaration::border_style(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other border style properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_border_style(
    const std::string& border_style, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderStyleProperty, border_style,
                              exception_state);
}

std::string CSSStyleDeclaration::border_top_style(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderTopStyleProperty);
}

void CSSStyleDeclaration::set_border_top_style(
    const std::string& border_top_style,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderTopStyleProperty, border_top_style,
                              exception_state);
}

std::string CSSStyleDeclaration::border_right_style(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderRightStyleProperty);
}

void CSSStyleDeclaration::set_border_right_style(
    const std::string& border_right_style,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderRightStyleProperty, border_right_style,
                              exception_state);
}

std::string CSSStyleDeclaration::border_bottom_style(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderBottomStyleProperty);
}

void CSSStyleDeclaration::set_border_bottom_style(
    const std::string& border_bottom_style,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderBottomStyleProperty, border_bottom_style,
                              exception_state);
}

std::string CSSStyleDeclaration::border_left_style(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderLeftStyleProperty);
}

void CSSStyleDeclaration::set_border_left_style(
    const std::string& border_left_style,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderLeftStyleProperty, border_left_style,
                              exception_state);
}

std::string CSSStyleDeclaration::border_width(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other border width properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_border_width(
    const std::string& border_width, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderWidthProperty, border_width,
                              exception_state);
}

std::string CSSStyleDeclaration::border_top_width(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderTopWidthProperty);
}

void CSSStyleDeclaration::set_border_top_width(
    const std::string& border_top_width,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderTopWidthProperty, border_top_width,
                              exception_state);
}

std::string CSSStyleDeclaration::border_right_width(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderRightWidthProperty);
}

void CSSStyleDeclaration::set_border_right_width(
    const std::string& border_right_width,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderRightWidthProperty, border_right_width,
                              exception_state);
}

std::string CSSStyleDeclaration::border_bottom_width(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderBottomWidthProperty);
}

void CSSStyleDeclaration::set_border_bottom_width(
    const std::string& border_bottom_width,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderBottomWidthProperty, border_bottom_width,
                              exception_state);
}

std::string CSSStyleDeclaration::border_left_width(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderLeftWidthProperty);
}

void CSSStyleDeclaration::set_border_left_width(
    const std::string& border_left_width,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderLeftWidthProperty, border_left_width,
                              exception_state);
}

std::string CSSStyleDeclaration::border_radius(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBorderRadiusProperty);
}

void CSSStyleDeclaration::set_border_radius(
    const std::string& border_radius, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBorderRadiusProperty, border_radius,
                              exception_state);
}

std::string CSSStyleDeclaration::bottom(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBottomProperty);
}

void CSSStyleDeclaration::set_bottom(const std::string& bottom,
                                     script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBottomProperty, bottom, exception_state);
}

std::string CSSStyleDeclaration::box_shadow(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kBoxShadowProperty);
}

void CSSStyleDeclaration::set_box_shadow(
    const std::string& box_shadow, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kBoxShadowProperty, box_shadow, exception_state);
}

std::string CSSStyleDeclaration::color(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kColorProperty);
}

void CSSStyleDeclaration::set_color(const std::string& color,
                                    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kColorProperty, color, exception_state);
}

std::string CSSStyleDeclaration::content(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kContentProperty);
}

void CSSStyleDeclaration::set_content(const std::string& content,
                                      script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kContentProperty, content, exception_state);
}

std::string CSSStyleDeclaration::display(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kDisplayProperty);
}

void CSSStyleDeclaration::set_display(const std::string& display,
                                      script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kDisplayProperty, display, exception_state);
}

std::string CSSStyleDeclaration::font(
    script::ExceptionState* /*exception_state*/) const {
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_font(const std::string& font,
                                   script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kFontProperty, font, exception_state);
}

std::string CSSStyleDeclaration::font_family(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kFontFamilyProperty);
}

void CSSStyleDeclaration::set_font_family(
    const std::string& font_family, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kFontFamilyProperty, font_family,
                              exception_state);
}

std::string CSSStyleDeclaration::font_size(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kFontSizeProperty);
}

void CSSStyleDeclaration::set_font_size(
    const std::string& font_size, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kFontSizeProperty, font_size, exception_state);
}

std::string CSSStyleDeclaration::font_style(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kFontStyleProperty);
}

void CSSStyleDeclaration::set_font_style(
    const std::string& font_style, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kFontStyleProperty, font_style, exception_state);
}

std::string CSSStyleDeclaration::font_weight(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kFontWeightProperty);
}

void CSSStyleDeclaration::set_font_weight(
    const std::string& font_weight, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kFontWeightProperty, font_weight,
                              exception_state);
}

std::string CSSStyleDeclaration::height(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kHeightProperty);
}

void CSSStyleDeclaration::set_height(const std::string& height,
                                     script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kHeightProperty, height, exception_state);
}

std::string CSSStyleDeclaration::left(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kLeftProperty);
}

void CSSStyleDeclaration::set_left(const std::string& left,
                                   script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kLeftProperty, left, exception_state);
}

std::string CSSStyleDeclaration::line_height(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kLineHeightProperty);
}

void CSSStyleDeclaration::set_line_height(
    const std::string& line_height, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kLineHeightProperty, line_height,
                              exception_state);
}

std::string CSSStyleDeclaration::margin(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other margin properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_margin(const std::string& margin,
                                     script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kMarginProperty, margin, exception_state);
}

std::string CSSStyleDeclaration::margin_bottom(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kMarginBottomProperty);
}

void CSSStyleDeclaration::set_margin_bottom(
    const std::string& margin_bottom, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kMarginBottomProperty, margin_bottom,
                              exception_state);
}

std::string CSSStyleDeclaration::margin_left(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kMarginLeftProperty);
}

void CSSStyleDeclaration::set_margin_left(
    const std::string& margin_left, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kMarginLeftProperty, margin_left,
                              exception_state);
}

std::string CSSStyleDeclaration::margin_right(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kMarginRightProperty);
}

void CSSStyleDeclaration::set_margin_right(
    const std::string& margin_right, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kMarginRightProperty, margin_right,
                              exception_state);
}

std::string CSSStyleDeclaration::margin_top(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kMarginTopProperty);
}

void CSSStyleDeclaration::set_margin_top(
    const std::string& margin_top, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kMarginTopProperty, margin_top, exception_state);
}

std::string CSSStyleDeclaration::max_height(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kMaxHeightProperty);
}

void CSSStyleDeclaration::set_max_height(
    const std::string& max_height, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kMaxHeightProperty, max_height, exception_state);
}

std::string CSSStyleDeclaration::max_width(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kMaxWidthProperty);
}

void CSSStyleDeclaration::set_max_width(
    const std::string& max_width, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kMaxWidthProperty, max_width, exception_state);
}

std::string CSSStyleDeclaration::min_height(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kMinHeightProperty);
}

void CSSStyleDeclaration::set_min_height(
    const std::string& min_height, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kMinHeightProperty, min_height, exception_state);
}

std::string CSSStyleDeclaration::min_width(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kMinWidthProperty);
}

void CSSStyleDeclaration::set_min_width(
    const std::string& min_width, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kMinWidthProperty, min_width, exception_state);
}

std::string CSSStyleDeclaration::opacity(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kOpacityProperty);
}

void CSSStyleDeclaration::set_opacity(const std::string& opacity,
                                      script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kOpacityProperty, opacity, exception_state);
}

std::string CSSStyleDeclaration::overflow(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kOverflowProperty);
}

void CSSStyleDeclaration::set_overflow(
    const std::string& overflow, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kOverflowProperty, overflow, exception_state);
}

std::string CSSStyleDeclaration::overflow_wrap(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kOverflowWrapProperty);
}

void CSSStyleDeclaration::set_overflow_wrap(
    const std::string& overflow_wrap, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kOverflowWrapProperty, overflow_wrap,
                              exception_state);
}

std::string CSSStyleDeclaration::padding(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other padding properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_padding(const std::string& padding,
                                      script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kPaddingProperty, padding, exception_state);
}

std::string CSSStyleDeclaration::padding_bottom(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kPaddingBottomProperty);
}

void CSSStyleDeclaration::set_padding_bottom(
    const std::string& padding_bottom,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kPaddingBottomProperty, padding_bottom,
                              exception_state);
}

std::string CSSStyleDeclaration::padding_left(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kPaddingLeftProperty);
}

void CSSStyleDeclaration::set_padding_left(
    const std::string& padding_left, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kPaddingLeftProperty, padding_left,
                              exception_state);
}

std::string CSSStyleDeclaration::padding_right(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kPaddingRightProperty);
}

void CSSStyleDeclaration::set_padding_right(
    const std::string& padding_right, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kPaddingRightProperty, padding_right,
                              exception_state);
}

std::string CSSStyleDeclaration::padding_top(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kPaddingTopProperty);
}

void CSSStyleDeclaration::set_padding_top(
    const std::string& padding_top, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kPaddingTopProperty, padding_top,
                              exception_state);
}

std::string CSSStyleDeclaration::position(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kPositionProperty);
}

void CSSStyleDeclaration::set_position(
    const std::string& position, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kPositionProperty, position, exception_state);
}

std::string CSSStyleDeclaration::right(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kRightProperty);
}

void CSSStyleDeclaration::set_right(const std::string& right,
                                    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kRightProperty, right, exception_state);
}

std::string CSSStyleDeclaration::text_align(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTextAlignProperty);
}

void CSSStyleDeclaration::set_text_align(
    const std::string& text_align, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTextAlignProperty, text_align, exception_state);
}

std::string CSSStyleDeclaration::text_decoration(
    script::ExceptionState* /*exception_state*/) const {
  // TODO: Redirect text decoration to text decoration line for now and
  // change it when fully implement text decoration.
  return GetDeclaredPropertyValueStringByKey(kTextDecorationLineProperty);
}

void CSSStyleDeclaration::set_text_decoration(
    const std::string& text_decoration,
    script::ExceptionState* exception_state) {
  // TODO: Redirect text decoration to text decoration line for now and
  // change it when fully implement text decoration.
  SetPropertyValueStringByKey(kTextDecorationLineProperty, text_decoration,
                              exception_state);
}

std::string CSSStyleDeclaration::text_decoration_color(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTextDecorationColorProperty);
}

void CSSStyleDeclaration::set_text_decoration_color(
    const std::string& text_decoration_color,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTextDecorationColorProperty,
                              text_decoration_color, exception_state);
}

std::string CSSStyleDeclaration::text_decoration_line(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTextDecorationLineProperty);
}

void CSSStyleDeclaration::set_text_decoration_line(
    const std::string& text_decoration_line,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTextDecorationLineProperty, text_decoration_line,
                              exception_state);
}

std::string CSSStyleDeclaration::text_indent(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTextIndentProperty);
}

void CSSStyleDeclaration::set_text_indent(
    const std::string& text_indent, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTextIndentProperty, text_indent,
                              exception_state);
}

std::string CSSStyleDeclaration::text_overflow(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTextOverflowProperty);
}

void CSSStyleDeclaration::set_text_overflow(
    const std::string& text_overflow, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTextOverflowProperty, text_overflow,
                              exception_state);
}

std::string CSSStyleDeclaration::text_shadow(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTextShadowProperty);
}

void CSSStyleDeclaration::set_text_shadow(
    const std::string& text_shadow, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTextShadowProperty, text_shadow,
                              exception_state);
}

std::string CSSStyleDeclaration::text_transform(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTextTransformProperty);
}

void CSSStyleDeclaration::set_text_transform(
    const std::string& text_transform,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTextTransformProperty, text_transform,
                              exception_state);
}

std::string CSSStyleDeclaration::top(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTopProperty);
}

void CSSStyleDeclaration::set_top(const std::string& top,
                                  script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTopProperty, top, exception_state);
}

std::string CSSStyleDeclaration::transform(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTransformProperty);
}

void CSSStyleDeclaration::set_transform(
    const std::string& transform, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTransformProperty, transform, exception_state);
}

std::string CSSStyleDeclaration::transform_origin(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTransformOriginProperty);
}

void CSSStyleDeclaration::set_transform_origin(
    const std::string& transform_origin,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTransformOriginProperty, transform_origin,
                              exception_state);
}

std::string CSSStyleDeclaration::transition(
    script::ExceptionState* /*exception_state*/) const {
  // In order to implement this properly we must either save the incoming string
  // values when they are being set, or combine the results of getting the
  // styles from all the other transition properties.
  NOTIMPLEMENTED();
  return "";
}

void CSSStyleDeclaration::set_transition(
    const std::string& transition, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTransitionProperty, transition, exception_state);
}

std::string CSSStyleDeclaration::transition_delay(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTransitionDelayProperty);
}

void CSSStyleDeclaration::set_transition_delay(
    const std::string& transition_delay,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTransitionDelayProperty, transition_delay,
                              exception_state);
}

std::string CSSStyleDeclaration::transition_duration(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTransitionDurationProperty);
}

void CSSStyleDeclaration::set_transition_duration(
    const std::string& transition_duration,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTransitionDurationProperty, transition_duration,
                              exception_state);
}

std::string CSSStyleDeclaration::transition_property(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTransitionPropertyProperty);
}

void CSSStyleDeclaration::set_transition_property(
    const std::string& transition_property,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTransitionPropertyProperty, transition_property,
                              exception_state);
}

std::string CSSStyleDeclaration::transition_timing_function(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kTransitionTimingFunctionProperty);
}

void CSSStyleDeclaration::set_transition_timing_function(
    const std::string& transition_timing_function,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kTransitionTimingFunctionProperty,
                              transition_timing_function, exception_state);
}

std::string CSSStyleDeclaration::vertical_align(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kVerticalAlignProperty);
}

void CSSStyleDeclaration::set_vertical_align(
    const std::string& vertical_align,
    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kVerticalAlignProperty, vertical_align,
                              exception_state);
}

std::string CSSStyleDeclaration::visibility(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kVisibilityProperty);
}

void CSSStyleDeclaration::set_visibility(
    const std::string& visibility, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kVisibilityProperty, visibility, exception_state);
}

std::string CSSStyleDeclaration::white_space(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kWhiteSpaceProperty);
}

void CSSStyleDeclaration::set_white_space(
    const std::string& white_space, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kWhiteSpaceProperty, white_space,
                              exception_state);
}

std::string CSSStyleDeclaration::width(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kWidthProperty);
}

void CSSStyleDeclaration::set_width(const std::string& width,
                                    script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kWidthProperty, width, exception_state);
}

// word-wrap is treated as an alias for overflow-wrap
//   https://www.w3.org/TR/css-text-3/#overflow-wrap
std::string CSSStyleDeclaration::word_wrap(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kOverflowWrapProperty);
}

void CSSStyleDeclaration::set_word_wrap(
    const std::string& word_wrap, script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kWordWrapProperty, word_wrap, exception_state);
}

std::string CSSStyleDeclaration::z_index(
    script::ExceptionState* /*exception_state*/) const {
  return GetDeclaredPropertyValueStringByKey(kZIndexProperty);
}

void CSSStyleDeclaration::set_z_index(const std::string& z_index,
                                      script::ExceptionState* exception_state) {
  SetPropertyValueStringByKey(kZIndexProperty, z_index, exception_state);
}

scoped_refptr<CSSRule> CSSStyleDeclaration::parent_rule() const { return NULL; }

std::string CSSStyleDeclaration::GetPropertyValue(
    const std::string& property_name) {
  PropertyKey key = GetPropertyKey(property_name);
  if (key > kMaxLonghandPropertyKey) {
    // Shorthand properties are never directly stored as declared properties,
    // but are expanded into their longhand property components during parsing.
    // TODO: Implement serialization of css values, see
    // https://www.w3.org/TR/cssom-1/#serializing-css-values
    DCHECK_LE(key, kMaxEveryPropertyKey);
    DLOG(WARNING) << "Unsupported property query for \"" << property_name
                  << "\": Returning of property value strings is only "
                     "supported for longhand properties.";
    return std::string();
  }
  return GetDeclaredPropertyValueStringByKey(key);
}

void CSSStyleDeclaration::SetPropertyValueStringByKey(
    PropertyKey key, const std::string& property_value,
    script::ExceptionState* exception_state) {
  SetPropertyValue(GetPropertyName(key), property_value, exception_state);
}

}  // namespace cssom
}  // namespace cobalt
