1 /* 2 * (C) 1999-2003 Lars Knoll (knoll (at) kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 4 * Copyright (C) 2013 Intel Corporation. All rights reserved. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 */ 21 22 #include "config.h" 23 #include "core/StylePropertyShorthand.h" 24 25 namespace blink { 26 27 const StylePropertyShorthand& borderShorthandForParsing() 28 { 29 static const CSSPropertyID borderShorthandProperties[] = { CSSPropertyBorderWidth, CSSPropertyBorderStyle, CSSPropertyBorderColor }; 30 static const StylePropertyShorthand* propertiesForInitialization[] = { 31 &borderWidthShorthand(), 32 &borderStyleShorthand(), 33 &borderColorShorthand(), 34 }; 35 DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderForParsingLonghands, (CSSPropertyBorder, borderShorthandProperties, propertiesForInitialization, WTF_ARRAY_LENGTH(borderShorthandProperties))); 36 return borderForParsingLonghands; 37 } 38 39 const StylePropertyShorthand& animationShorthandForParsing() 40 { 41 // When we parse the animation shorthand we need to look for animation-name 42 // last because otherwise it might match against the keywords for fill mode, 43 // timing functions and infinite iteration. This means that animation names 44 // that are the same as keywords (e.g. 'forwards') won't always match in the 45 // shorthand. In that case the authors should be using longhands (or 46 // reconsidering their approach). This is covered by the animations spec 47 // bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=14790 48 // And in the spec (editor's draft) at: 49 // http://dev.w3.org/csswg/css3-animations/#animation-shorthand-property 50 static const CSSPropertyID animationPropertiesForParsing[] = { 51 CSSPropertyAnimationDuration, 52 CSSPropertyAnimationTimingFunction, 53 CSSPropertyAnimationDelay, 54 CSSPropertyAnimationIterationCount, 55 CSSPropertyAnimationDirection, 56 CSSPropertyAnimationFillMode, 57 CSSPropertyAnimationPlayState, 58 CSSPropertyAnimationName 59 }; 60 DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitAnimationLonghandsForParsing, (CSSPropertyAnimation, animationPropertiesForParsing, WTF_ARRAY_LENGTH(animationPropertiesForParsing))); 61 return webkitAnimationLonghandsForParsing; 62 } 63 64 const StylePropertyShorthand& webkitAnimationShorthandForParsing() 65 { 66 // When we parse the animation shorthand we need to look for animation-name 67 // last because otherwise it might match against the keywords for fill mode, 68 // timing functions and infinite iteration. This means that animation names 69 // that are the same as keywords (e.g. 'forwards') won't always match in the 70 // shorthand. In that case the authors should be using longhands (or 71 // reconsidering their approach). This is covered by the animations spec 72 // bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=14790 73 // And in the spec (editor's draft) at: 74 // http://dev.w3.org/csswg/css3-animations/#animation-shorthand-property 75 static const CSSPropertyID animationPropertiesForParsing[] = { 76 CSSPropertyWebkitAnimationDuration, 77 CSSPropertyWebkitAnimationTimingFunction, 78 CSSPropertyWebkitAnimationDelay, 79 CSSPropertyWebkitAnimationIterationCount, 80 CSSPropertyWebkitAnimationDirection, 81 CSSPropertyWebkitAnimationFillMode, 82 CSSPropertyWebkitAnimationPlayState, 83 CSSPropertyWebkitAnimationName 84 }; 85 DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitAnimationLonghandsForParsing, (CSSPropertyWebkitAnimation, animationPropertiesForParsing, WTF_ARRAY_LENGTH(animationPropertiesForParsing))); 86 return webkitAnimationLonghandsForParsing; 87 } 88 89 // Similar to animations, we have property after timing-function and delay after duration 90 const StylePropertyShorthand& transitionShorthandForParsing() 91 { 92 static const CSSPropertyID transitionProperties[] = { 93 CSSPropertyTransitionDuration, 94 CSSPropertyTransitionTimingFunction, 95 CSSPropertyTransitionDelay, 96 CSSPropertyTransitionProperty 97 }; 98 DEFINE_STATIC_LOCAL(StylePropertyShorthand, transitionLonghands, (CSSPropertyTransition, transitionProperties, WTF_ARRAY_LENGTH(transitionProperties))); 99 return transitionLonghands; 100 } 101 102 const StylePropertyShorthand& webkitTransitionShorthandForParsing() 103 { 104 static const CSSPropertyID webkitTransitionProperties[] = { 105 CSSPropertyWebkitTransitionDuration, 106 CSSPropertyWebkitTransitionTimingFunction, 107 CSSPropertyWebkitTransitionDelay, 108 CSSPropertyWebkitTransitionProperty 109 }; 110 DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitTransitionLonghands, (CSSPropertyWebkitTransition, webkitTransitionProperties, WTF_ARRAY_LENGTH(webkitTransitionProperties))); 111 return webkitTransitionLonghands; 112 } 113 114 // Returns an empty list if the property is not a shorthand, otherwise the list of longhands for parsing. 115 const StylePropertyShorthand& parsingShorthandForProperty(CSSPropertyID propertyID) 116 { 117 switch (propertyID) { 118 case CSSPropertyAnimation: 119 return animationShorthandForParsing(); 120 case CSSPropertyBorder: 121 return borderShorthandForParsing(); 122 case CSSPropertyWebkitAnimation: 123 return webkitAnimationShorthandForParsing(); 124 case CSSPropertyTransition: 125 return transitionShorthandForParsing(); 126 case CSSPropertyWebkitTransition: 127 return webkitTransitionShorthandForParsing(); 128 default: 129 return shorthandForProperty(propertyID); 130 } 131 } 132 133 bool isExpandedShorthand(CSSPropertyID id) 134 { 135 // The system fonts bypass the normal style resolution by using RenderTheme, 136 // thus we need to special case it here. FIXME: This is a violation of CSS 3 Fonts 137 // as we should still be able to change the longhands. 138 // DON'T ADD ANY SHORTHAND HERE UNLESS IT ISN'T ALWAYS EXPANDED AT PARSE TIME (which is wrong). 139 if (id == CSSPropertyFont) 140 return false; 141 142 return shorthandForProperty(id).length(); 143 } 144 145 bool isExpandedShorthandForAll(CSSPropertyID propertyId) 146 { 147 // FIXME: isExpandedShorthand says "font" is not an expanded shorthand, 148 // but font is expanded to font-family, font-size, and so on. 149 // StylePropertySerializer::asText should not generate css text like 150 // "font: initial; font-family: initial;...". To avoid this, we need to 151 // treat "font" as an expanded shorthand. 152 // And while applying "all" property, we cannot apply "font" property 153 // directly. This causes ASSERT crash, because StyleBuilder assume that 154 // all given properties are not expanded shorthands. 155 // "marker" has the same issue. 156 if (propertyId == CSSPropertyMarker || propertyId == CSSPropertyFont) 157 return true; 158 return shorthandForProperty(propertyId).length(); 159 } 160 161 unsigned indexOfShorthandForLonghand(CSSPropertyID shorthandID, const Vector<StylePropertyShorthand, 4>& shorthands) 162 { 163 for (unsigned i = 0; i < shorthands.size(); ++i) { 164 if (shorthands.at(i).id() == shorthandID) 165 return i; 166 } 167 ASSERT_NOT_REACHED(); 168 return 0; 169 } 170 171 } // namespace blink 172