Commit d6103887 authored by pdr@chromium.org's avatar pdr@chromium.org

Check before setting initial border image styles

Border-image and its friend mask-box-image are shorthands that
expand out into 4 css properties[1]. When setting the initial values
for these we would blindly create a new NinePieceBorderImage which
is large and contains non-trivial destructors. This patch first
checks whether the current value is already equal to the initial value
before setting.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/border-image

Review URL: https://codereview.chromium.org/340703004

git-svn-id: svn://svn.chromium.org/blink/trunk@176492 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 0f480a31
...@@ -156,27 +156,75 @@ namespace WebCore { ...@@ -156,27 +156,75 @@ namespace WebCore {
{{apply_auto('CSSPropertyWidows')}} {{apply_auto('CSSPropertyWidows')}}
{{apply_auto('CSSPropertyZIndex')}} {{apply_auto('CSSPropertyZIndex')}}
static bool lengthTypeAndValueMatch(const Length& length, LengthType type, float value)
{
return length.type() == type && length.value() == value;
}
static bool lengthTypeAndValueMatch(const LengthBox& lengthBox, LengthType type, float value)
{
return (lengthTypeAndValueMatch(lengthBox.left(), type, value)
&& lengthTypeAndValueMatch(lengthBox.right(), type, value)
&& lengthTypeAndValueMatch(lengthBox.top(), type, value)
&& lengthTypeAndValueMatch(lengthBox.bottom(), type, value));
}
static bool lengthTypeAndValueMatch(const BorderImageLength& borderImageLength, LengthType type, float value)
{
return borderImageLength.isLength() && lengthTypeAndValueMatch(borderImageLength.length(), type, value);
}
static bool lengthTypeAndValueMatch(const BorderImageLengthBox& borderImageLengthBox, LengthType type, float value)
{
return (lengthTypeAndValueMatch(borderImageLengthBox.left(), type, value)
&& lengthTypeAndValueMatch(borderImageLengthBox.right(), type, value)
&& lengthTypeAndValueMatch(borderImageLengthBox.top(), type, value)
&& lengthTypeAndValueMatch(borderImageLengthBox.bottom(), type, value));
}
{% macro apply_border_image_modifier(property_id, modifier_type) %} {% macro apply_border_image_modifier(property_id, modifier_type) %}
{% set is_mask_box = 'MaskBox' in property_id %} {% set is_mask_box = 'MaskBox' in property_id %}
{% set getter = 'maskBoxImage' if is_mask_box else 'borderImage' %} {% set getter = 'maskBoxImage' if is_mask_box else 'borderImage' %}
{% set setter = 'setMaskBoxImage' if is_mask_box else 'setBorderImage' %} {% set setter = 'setMaskBoxImage' if is_mask_box else 'setBorderImage' %}
{{ declare_initial_function(property_id) }} {{ declare_initial_function(property_id) }}
{ {
NinePieceImage image(state.style()->{{getter}}()); const NinePieceImage& currentImage = state.style()->{{getter}}();
{# Check for equality in case we can bail out before creating a new NinePieceImage. #}
{% if modifier_type == 'Outset' %}
if (lengthTypeAndValueMatch(currentImage.outset(), Fixed, 0))
return;
{% elif modifier_type == 'Repeat' %}
if (currentImage.horizontalRule() == StretchImageRule && currentImage.verticalRule() == StretchImageRule)
return;
{% elif modifier_type == 'Slice' and is_mask_box %}
// Masks have a different initial value for slices. Preserve the value of 0 for backwards compatibility.
if (currentImage.fill() == true && lengthTypeAndValueMatch(currentImage.imageSlices(), Fixed, 0))
return;
{% elif modifier_type == 'Slice' and not is_mask_box %}
if (currentImage.fill() == false && lengthTypeAndValueMatch(currentImage.imageSlices(), Percent, 100))
return;
{% elif modifier_type == 'Width' and is_mask_box %}
// Masks have a different initial value for widths. Preserve the value of 'auto' for backwards compatibility.
if (lengthTypeAndValueMatch(currentImage.borderSlices(), Auto, 0))
return;
{% elif modifier_type == 'Width' and not is_mask_box %}
if (lengthTypeAndValueMatch(currentImage.borderSlices(), Fixed, 1))
return;
{% endif %}
NinePieceImage image(currentImage);
{% if modifier_type == 'Outset' %} {% if modifier_type == 'Outset' %}
image.setOutset(Length(0, Fixed)); image.setOutset(Length(0, Fixed));
{% elif modifier_type == 'Repeat' %} {% elif modifier_type == 'Repeat' %}
image.setHorizontalRule(StretchImageRule); image.setHorizontalRule(StretchImageRule);
image.setVerticalRule(StretchImageRule); image.setVerticalRule(StretchImageRule);
{% elif modifier_type == 'Slice' and is_mask_box %} {% elif modifier_type == 'Slice' and is_mask_box %}
// Masks have a different initial value for slices. Preserve the value of 0 for backwards compatibility.
image.setImageSlices(LengthBox({{ (['Length(0, Fixed)']*4) | join(', ') }})); image.setImageSlices(LengthBox({{ (['Length(0, Fixed)']*4) | join(', ') }}));
image.setFill(true); image.setFill(true);
{% elif modifier_type == 'Slice' and not is_mask_box %} {% elif modifier_type == 'Slice' and not is_mask_box %}
image.setImageSlices(LengthBox({{ (['Length(100, Percent)']*4) | join(', ') }})); image.setImageSlices(LengthBox({{ (['Length(100, Percent)']*4) | join(', ') }}));
image.setFill(false); image.setFill(false);
{% elif modifier_type == 'Width' %} {% elif modifier_type == 'Width' %}
// Masks have a different initial value for widths. Preserve the value of 'auto' for backwards compatibility.
image.setBorderSlices({{ 'Length(Auto)' if is_mask_box else '1.0' }}); image.setBorderSlices({{ 'Length(Auto)' if is_mask_box else '1.0' }});
{% endif %} {% endif %}
state.style()->{{setter}}(image); state.style()->{{setter}}(image);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment