String StylePropertySerializer::fontValue() const { int fontSizePropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontSize); int fontFamilyPropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontFamily); if (fontSizePropertyIndex == -1 || fontFamilyPropertyIndex == -1) return emptyString(); StylePropertySet::PropertyReference fontSizeProperty = m_propertySet.propertyAt(fontSizePropertyIndex); StylePropertySet::PropertyReference fontFamilyProperty = m_propertySet.propertyAt(fontFamilyPropertyIndex); if (fontSizeProperty.isImplicit() || fontFamilyProperty.isImplicit()) return emptyString(); String commonValue = fontSizeProperty.value()->cssText(); StringBuilder result; appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result, commonValue); appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result, commonValue); appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result, commonValue); if (!result.isEmpty()) result.append(' '); result.append(fontSizeProperty.value()->cssText()); appendFontLonghandValueIfExplicit(CSSPropertyLineHeight, result, commonValue); if (!result.isEmpty()) result.append(' '); result.append(fontFamilyProperty.value()->cssText()); if (isInitialOrInherit(commonValue)) return commonValue; return result.toString(); }
String AbstractPropertySetCSSStyleDeclaration::item(unsigned i) const { if (i >= propertySet().propertyCount()) return ""; StylePropertySet::PropertyReference property = propertySet().propertyAt(i); if (property.id() == CSSPropertyVariable) return toCSSCustomPropertyDeclaration(property.value()).name(); if (property.id() == CSSPropertyApplyAtRule) return "@apply"; return getPropertyName(property.id()); }
void StyleResolver::applyProperties(StyleResolverState& state, const StylePropertySet* properties, bool inheritedOnly) { unsigned propertyCount = properties->propertyCount(); for (unsigned i = 0; i < propertyCount; ++i) { StylePropertySet::PropertyReference current = properties->propertyAt(i); if (inheritedOnly && !current.isInherited()) { // If the property value is explicitly inherited, we need to apply further non-inherited properties // as they might override the value inherited here. For this reason we don't allow declarations with // explicitly inherited properties to be cached. ASSERT(!current.value()->isInheritedValue()); continue; } CSSPropertyID property = current.id(); if (!isPropertyForPass<pass>(property)) continue; if (pass == HighPriorityProperties && property == CSSPropertyLineHeight) state.setLineHeightValue(current.value()); else StyleBuilder::applyProperty(current.id(), state, current.value()); } }
PropertyHandleSet StringKeyframe::properties() const { // This is not used in time-critical code, so we probably don't need to // worry about caching this result. PropertyHandleSet properties; for (unsigned i = 0; i < m_cssPropertyMap->propertyCount(); ++i) { StylePropertySet::PropertyReference propertyReference = m_cssPropertyMap->propertyAt(i); ASSERT_WITH_MESSAGE( !isShorthandProperty(propertyReference.id()) || propertyReference.value()->isVariableReferenceValue(), "Web Animations: Encountered unexpanded shorthand CSS property (%d).", propertyReference.id()); properties.add(PropertyHandle(propertyReference.id(), false)); } for (unsigned i = 0; i < m_presentationAttributeMap->propertyCount(); ++i) properties.add(PropertyHandle(m_presentationAttributeMap->propertyAt(i).id(), true)); for (const auto& key: m_svgAttributeMap.keys()) properties.add(PropertyHandle(*key)); return properties; }
void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& ruleData) { const StylePropertySet& propertySet = ruleData.rule()->properties(); int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent); if (propertyIndex == -1) return; StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt(propertyIndex); CSSValue* contentValue = contentProperty.value(); if (!contentValue->isValueList()) return; for (auto& item : toCSSValueList(*contentValue)) { if (!item->isFunctionValue()) continue; CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); if (functionValue->functionType() != CSSValueAttr) continue; ensureAttributeInvalidationSet(AtomicString(toCSSPrimitiveValue(functionValue->item(0))->getStringValue())).setInvalidatesSelf(); } }
String StylePropertySerializer::asText() const { StringBuilder result; BitArray<numCSSProperties> shorthandPropertyUsed; BitArray<numCSSProperties> shorthandPropertyAppeared; unsigned size = m_propertySet.propertyCount(); unsigned numDecls = 0; for (unsigned n = 0; n < size; ++n) { StylePropertySet::PropertyReference property = m_propertySet.propertyAt(n); CSSPropertyID propertyID = property.id(); // Only enabled or internal properties should be part of the style. ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID) || isInternalProperty(propertyID)); CSSPropertyID shorthandPropertyID = CSSPropertyInvalid; CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid; String value; switch (propertyID) { case CSSPropertyBackgroundAttachment: case CSSPropertyBackgroundClip: case CSSPropertyBackgroundColor: case CSSPropertyBackgroundImage: case CSSPropertyBackgroundOrigin: case CSSPropertyBackgroundPositionX: case CSSPropertyBackgroundPositionY: case CSSPropertyBackgroundSize: case CSSPropertyBackgroundRepeatX: case CSSPropertyBackgroundRepeatY: shorthandPropertyAppeared.set(CSSPropertyBackground - firstCSSProperty); continue; case CSSPropertyContent: if (property.value()->isValueList()) value = toCSSValueList(property.value())->customCSSText(AlwaysQuoteCSSString); break; case CSSPropertyBorderTopWidth: case CSSPropertyBorderRightWidth: case CSSPropertyBorderBottomWidth: case CSSPropertyBorderLeftWidth: if (!borderFallbackShorthandProperty) borderFallbackShorthandProperty = CSSPropertyBorderWidth; case CSSPropertyBorderTopStyle: case CSSPropertyBorderRightStyle: case CSSPropertyBorderBottomStyle: case CSSPropertyBorderLeftStyle: if (!borderFallbackShorthandProperty) borderFallbackShorthandProperty = CSSPropertyBorderStyle; case CSSPropertyBorderTopColor: case CSSPropertyBorderRightColor: case CSSPropertyBorderBottomColor: case CSSPropertyBorderLeftColor: if (!borderFallbackShorthandProperty) borderFallbackShorthandProperty = CSSPropertyBorderColor; // FIXME: Deal with cases where only some of border-(top|right|bottom|left) are specified. if (!shorthandPropertyAppeared.get(CSSPropertyBorder - firstCSSProperty)) { value = borderPropertyValue(ReturnNullOnUncommonValues); if (value.isNull()) shorthandPropertyAppeared.set(CSSPropertyBorder - firstCSSProperty); else shorthandPropertyID = CSSPropertyBorder; } else if (shorthandPropertyUsed.get(CSSPropertyBorder - firstCSSProperty)) shorthandPropertyID = CSSPropertyBorder; if (!shorthandPropertyID) shorthandPropertyID = borderFallbackShorthandProperty; break; case CSSPropertyWebkitBorderHorizontalSpacing: case CSSPropertyWebkitBorderVerticalSpacing: shorthandPropertyID = CSSPropertyBorderSpacing; break; case CSSPropertyFontFamily: case CSSPropertyLineHeight: case CSSPropertyFontSize: case CSSPropertyFontStyle: case CSSPropertyFontVariant: case CSSPropertyFontWeight: // Don't use CSSPropertyFont because old UAs can't recognize them but are important for editing. break; case CSSPropertyListStyleType: case CSSPropertyListStylePosition: case CSSPropertyListStyleImage: shorthandPropertyID = CSSPropertyListStyle; break; case CSSPropertyMarginTop: case CSSPropertyMarginRight: case CSSPropertyMarginBottom: case CSSPropertyMarginLeft: shorthandPropertyID = CSSPropertyMargin; break; case CSSPropertyOutlineWidth: case CSSPropertyOutlineStyle: case CSSPropertyOutlineColor: shorthandPropertyID = CSSPropertyOutline; break; case CSSPropertyOverflowX: case CSSPropertyOverflowY: shorthandPropertyID = CSSPropertyOverflow; break; case CSSPropertyPaddingTop: case CSSPropertyPaddingRight: case CSSPropertyPaddingBottom: case CSSPropertyPaddingLeft: shorthandPropertyID = CSSPropertyPadding; break; case CSSPropertyTransitionProperty: case CSSPropertyTransitionDuration: case CSSPropertyTransitionTimingFunction: case CSSPropertyTransitionDelay: shorthandPropertyID = CSSPropertyTransition; break; case CSSPropertyWebkitAnimationName: case CSSPropertyWebkitAnimationDuration: case CSSPropertyWebkitAnimationTimingFunction: case CSSPropertyWebkitAnimationDelay: case CSSPropertyWebkitAnimationIterationCount: case CSSPropertyWebkitAnimationDirection: case CSSPropertyWebkitAnimationFillMode: shorthandPropertyID = CSSPropertyWebkitAnimation; break; case CSSPropertyFlexDirection: case CSSPropertyFlexWrap: shorthandPropertyID = CSSPropertyFlexFlow; break; case CSSPropertyFlexBasis: case CSSPropertyFlexGrow: case CSSPropertyFlexShrink: shorthandPropertyID = CSSPropertyFlex; break; case CSSPropertyWebkitMaskPositionX: case CSSPropertyWebkitMaskPositionY: case CSSPropertyWebkitMaskRepeatX: case CSSPropertyWebkitMaskRepeatY: case CSSPropertyWebkitMaskImage: case CSSPropertyWebkitMaskRepeat: case CSSPropertyWebkitMaskPosition: case CSSPropertyWebkitMaskClip: case CSSPropertyWebkitMaskOrigin: shorthandPropertyID = CSSPropertyWebkitMask; break; case CSSPropertyWebkitTransformOriginX: case CSSPropertyWebkitTransformOriginY: case CSSPropertyWebkitTransformOriginZ: shorthandPropertyID = CSSPropertyWebkitTransformOrigin; break; case CSSPropertyWebkitTransitionProperty: case CSSPropertyWebkitTransitionDuration: case CSSPropertyWebkitTransitionTimingFunction: case CSSPropertyWebkitTransitionDelay: shorthandPropertyID = CSSPropertyWebkitTransition; break; default: break; } unsigned shortPropertyIndex = shorthandPropertyID - firstCSSProperty; if (shorthandPropertyID) { if (shorthandPropertyUsed.get(shortPropertyIndex)) continue; if (!shorthandPropertyAppeared.get(shortPropertyIndex) && value.isNull()) value = m_propertySet.getPropertyValue(shorthandPropertyID); shorthandPropertyAppeared.set(shortPropertyIndex); } if (!value.isNull()) { if (shorthandPropertyID) { propertyID = shorthandPropertyID; shorthandPropertyUsed.set(shortPropertyIndex); } } else value = property.value()->cssText(); if (value == "initial" && !CSSProperty::isInheritedProperty(propertyID)) continue; result.append(getPropertyText(propertyID, value, property.isImportant(), numDecls++)); } if (shorthandPropertyAppeared.get(CSSPropertyBackground - firstCSSProperty)) appendBackgroundPropertyAsText(result, numDecls); ASSERT(!numDecls ^ !result.isEmpty()); return result.toString(); }
String StylePropertySerializer::get4Values(const StylePropertyShorthand& shorthand) const { // Assume the properties are in the usual order top, right, bottom, left. int topValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[0]); int rightValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[1]); int bottomValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[2]); int leftValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[3]); if (topValueIndex == -1 || rightValueIndex == -1 || bottomValueIndex == -1 || leftValueIndex == -1) return String(); StylePropertySet::PropertyReference top = m_propertySet.propertyAt(topValueIndex); StylePropertySet::PropertyReference right = m_propertySet.propertyAt(rightValueIndex); StylePropertySet::PropertyReference bottom = m_propertySet.propertyAt(bottomValueIndex); StylePropertySet::PropertyReference left = m_propertySet.propertyAt(leftValueIndex); // All 4 properties must be specified. if (!top.value() || !right.value() || !bottom.value() || !left.value()) return String(); if (top.isInherited() && right.isInherited() && bottom.isInherited() && left.isInherited()) return getValueName(CSSValueInherit); if (top.value()->isInitialValue() || right.value()->isInitialValue() || bottom.value()->isInitialValue() || left.value()->isInitialValue()) { if (top.value()->isInitialValue() && right.value()->isInitialValue() && bottom.value()->isInitialValue() && left.value()->isInitialValue() && !top.isImplicit()) { // All components are "initial" and "top" is not implicit. return getValueName(CSSValueInitial); } return String(); } if (top.isImportant() != right.isImportant() || right.isImportant() != bottom.isImportant() || bottom.isImportant() != left.isImportant()) return String(); bool showLeft = !right.value()->equals(*left.value()); bool showBottom = !top.value()->equals(*bottom.value()) || showLeft; bool showRight = !top.value()->equals(*right.value()) || showBottom; StringBuilder result; result.append(top.value()->cssText()); if (showRight) { result.append(' '); result.append(right.value()->cssText()); } if (showBottom) { result.append(' '); result.append(bottom.value()->cssText()); } if (showLeft) { result.append(' '); result.append(left.value()->cssText()); } return result.toString(); }