bool StylePropertySet::removeShorthandProperty(CSSPropertyID propertyID) { StylePropertyShorthand shorthand = shorthandForProperty(propertyID); if (!shorthand.length()) return false; return removePropertiesInSet(shorthand.properties(), shorthand.length()); }
bool StylePropertySerializer::isPropertyShorthandAvailable(const StylePropertyShorthand& shorthand) const { ASSERT(shorthand.length() > 0); for (unsigned i = 0; i < shorthand.length(); ++i) { RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]); if (!value || (value->isInitialValue() && !value->isImplicitInitialValue()) || value->isInheritedValue()) return false; } return true; }
bool StylePropertySet::shorthandIsImportant(CSSPropertyID propertyID) const { StylePropertyShorthand shorthand = shorthandForProperty(propertyID); if (!shorthand.length()) return false; for (unsigned i = 0; i < shorthand.length(); ++i) { if (!propertyIsImportant(shorthand.properties()[i])) return false; } return true; }
void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtrWillBeRawPtr<CSSValue> prpValue, bool important) { StylePropertyShorthand shorthand = shorthandForProperty(propertyID); if (!shorthand.length()) { setProperty(CSSProperty(propertyID, prpValue, important)); return; } removePropertiesInSet(shorthand.properties(), shorthand.length()); RefPtrWillBeRawPtr<CSSValue> value = prpValue; for (unsigned i = 0; i < shorthand.length(); ++i) m_propertyVector.append(CSSProperty(shorthand.properties()[i], value, important)); }
bool MutableStylePropertySet::removeShorthandProperty(CSSPropertyID propertyID) { StylePropertyShorthand shorthand = shorthandForProperty(propertyID); if (!shorthand.length()) return false; bool ret = removePropertiesInSet(shorthand.properties(), shorthand.length()); CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(propertyID); if (prefixingVariant == propertyID) return ret; StylePropertyShorthand shorthandPrefixingVariant = shorthandForProperty(prefixingVariant); return removePropertiesInSet(shorthandPrefixingVariant.properties(), shorthandPrefixingVariant.length()); }
bool StylePropertySet::propertyIsImportant(CSSPropertyID propertyID) const { int foundPropertyIndex = findPropertyIndex(propertyID); if (foundPropertyIndex != -1) return propertyAt(foundPropertyIndex).isImportant(); StylePropertyShorthand shorthand = shorthandForProperty(propertyID); if (!shorthand.length()) return false; for (unsigned i = 0; i < shorthand.length(); ++i) { if (!propertyIsImportant(shorthand.properties()[i])) return false; } return true; }
String StylePropertySet::getShorthandValue(const StylePropertyShorthand& shorthand) const { String commonValue; StringBuilder result; for (unsigned i = 0; i < shorthand.length(); ++i) { if (!isPropertyImplicit(shorthand.properties()[i])) { RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]); if (!value) return String(); String valueText = value->cssText(); if (!i) commonValue = valueText; else if (!commonValue.isNull() && commonValue != valueText) commonValue = String(); if (value->isInitialValue()) continue; if (!result.isEmpty()) result.append(' '); result.append(valueText); } else commonValue = String(); } if (isInitialOrInherit(commonValue)) return commonValue; if (result.isEmpty()) return String(); return result.toString(); }
bool StylePropertySerializer::shorthandHasOnlyInitialOrInheritedValue(const StylePropertyShorthand& shorthand) const { ASSERT(shorthand.length() > 0); bool isInitialValue = true; bool isInheritedValue = true; for (unsigned i = 0; i < shorthand.length(); ++i) { RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]); if (!value) return false; if (!value->isInitialValue()) isInitialValue = false; if (!value->isInheritedValue()) isInheritedValue = false; } return isInitialValue || isInheritedValue; }
bool StylePropertySet::propertyIsImportant(CSSPropertyID propertyID) const { const CSSProperty* property = findPropertyWithId(propertyID); if (property) return property->isImportant(); StylePropertyShorthand shorthand = shorthandForProperty(propertyID); if (!shorthand.length()) return false; for (unsigned i = 0; i < shorthand.length(); ++i) { if (!propertyIsImportant(shorthand.properties()[i])) return false; } return true; }
void CSSVariableResolver::resolveAndApplyVariableReferences(StyleResolverState& state, CSSPropertyID id, const CSSVariableReferenceValue& value) { CSSVariableResolver resolver(state.style()->variables()); Vector<CSSParserToken> tokens; if (resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens)) { CSSParserContext context(HTMLStandardMode, 0); HeapVector<CSSProperty, 256> parsedProperties; // TODO: Non-shorthands should just call CSSPropertyParser::parseSingleValue if (CSSPropertyParser::parseValue(id, false, CSSParserTokenRange(tokens), context, parsedProperties, StyleRule::RuleType::Style)) { unsigned parsedPropertiesCount = parsedProperties.size(); for (unsigned i = 0; i < parsedPropertiesCount; ++i) StyleBuilder::applyProperty(parsedProperties[i].id(), state, parsedProperties[i].value()); return; } } RawPtr<CSSUnsetValue> unset = cssValuePool().createUnsetValue(); if (isShorthandProperty(id)) { StylePropertyShorthand shorthand = shorthandForProperty(id); for (unsigned i = 0; i < shorthand.length(); i++) StyleBuilder::applyProperty(shorthand.properties()[i], state, unset.get()); return; } StyleBuilder::applyProperty(id, state, unset.get()); }
String StylePropertySet::getShorthandValue(const StylePropertyShorthand& shorthand) const { String res; for (unsigned i = 0; i < shorthand.length(); ++i) { if (!isPropertyImplicit(shorthand.properties()[i])) { RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]); // FIXME: provide default value if !value or value is initial value if (value && !value->isInitialValue()) { if (!res.isNull()) res += " "; res += value->cssText(); } } } return res; }
String StylePropertySet::getShorthandValue(const StylePropertyShorthand& shorthand) const { String res; for (unsigned i = 0; i < shorthand.length(); ++i) { if (!isPropertyImplicit(shorthand.properties()[i])) { RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]); if (!value) return String(); if (value->isInitialValue()) continue; if (!res.isNull()) res += " "; res += value->cssText(); } } return res; }
// only returns a non-null value if all properties have the same, non-null value String StylePropertySerializer::getCommonValue(const StylePropertyShorthand& shorthand) const { String res; for (unsigned i = 0; i < shorthand.length(); ++i) { RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]); // FIXME: CSSInitialValue::cssText should generate the right value. if (!value) return String(); String text = value->cssText(); if (text.isNull()) return String(); if (res.isNull()) res = text; else if (res != text) return String(); } return res; }
// only returns a non-null value if all properties have the same, non-null value String StylePropertySet::getCommonValue(const StylePropertyShorthand& shorthand) const { String res; bool lastPropertyWasImportant = false; for (unsigned i = 0; i < shorthand.length(); ++i) { RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]); // FIXME: CSSInitialValue::cssText should generate the right value. if (!value) return String(); String text = value->cssText(); if (text.isNull()) return String(); if (res.isNull()) res = text; else if (res != text) return String(); bool currentPropertyIsImportant = propertyIsImportant(shorthand.properties()[i]); if (i && lastPropertyWasImportant != currentPropertyIsImportant) return String(); lastPropertyWasImportant = currentPropertyIsImportant; } return res; }
String StylePropertySet::getLayeredShorthandValue(const StylePropertyShorthand& shorthand) const { StringBuilder result; const unsigned size = shorthand.length(); // Begin by collecting the properties into an array. Vector< RefPtr<CSSValue> > values(size); size_t numLayers = 0; for (unsigned i = 0; i < size; ++i) { values[i] = getPropertyCSSValue(shorthand.properties()[i]); if (values[i]) { if (values[i]->isBaseValueList()) { CSSValueList* valueList = static_cast<CSSValueList*>(values[i].get()); numLayers = max(valueList->length(), numLayers); } else numLayers = max<size_t>(1U, numLayers); } } String commonValue; bool commonValueInitialized = false; // Now stitch the properties together. Implicit initial values are flagged as such and // can safely be omitted. for (size_t i = 0; i < numLayers; i++) { StringBuilder layerResult; bool useRepeatXShorthand = false; bool useRepeatYShorthand = false; bool useSingleWordShorthand = false; bool foundPositionYCSSProperty = false; for (unsigned j = 0; j < size; j++) { RefPtr<CSSValue> value; if (values[j]) { if (values[j]->isBaseValueList()) value = static_cast<CSSValueList*>(values[j].get())->item(i); else { value = values[j]; // Color only belongs in the last layer. if (shorthand.properties()[j] == CSSPropertyBackgroundColor) { if (i != numLayers - 1) value = 0; } else if (i != 0) // Other singletons only belong in the first layer. value = 0; } } // We need to report background-repeat as it was written in the CSS. If the property is implicit, // then it was written with only one value. Here we figure out which value that was so we can // report back correctly. if ((shorthand.properties()[j] == CSSPropertyBackgroundRepeatX && isPropertyImplicit(shorthand.properties()[j])) || (shorthand.properties()[j] == CSSPropertyWebkitMaskRepeatX && isPropertyImplicit(shorthand.properties()[j]))) { // BUG 49055: make sure the value was not reset in the layer check just above. if ((j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyBackgroundRepeatY && value) || (j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyWebkitMaskRepeatY && value)) { RefPtr<CSSValue> yValue; RefPtr<CSSValue> nextValue = values[j + 1]; if (nextValue->isValueList()) yValue = static_cast<CSSValueList*>(nextValue.get())->itemWithoutBoundsCheck(i); else yValue = nextValue; int xId = static_cast<CSSPrimitiveValue*>(value.get())->getIdent(); int yId = static_cast<CSSPrimitiveValue*>(yValue.get())->getIdent(); if (xId != yId) { if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { useRepeatXShorthand = true; ++j; } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { useRepeatYShorthand = true; continue; } } else { useSingleWordShorthand = true; ++j; } } } String valueText; if (value && !value->isImplicitInitialValue()) { if (!layerResult.isEmpty()) layerResult.append(' '); if (foundPositionYCSSProperty && (shorthand.properties()[j] == CSSPropertyBackgroundSize || shorthand.properties()[j] == CSSPropertyWebkitMaskSize)) layerResult.appendLiteral("/ "); if (!foundPositionYCSSProperty && (shorthand.properties()[j] == CSSPropertyBackgroundSize || shorthand.properties()[j] == CSSPropertyWebkitMaskSize)) continue; if (useRepeatXShorthand) { useRepeatXShorthand = false; layerResult.append(getValueName(CSSValueRepeatX)); } else if (useRepeatYShorthand) { useRepeatYShorthand = false; layerResult.append(getValueName(CSSValueRepeatY)); } else { if (useSingleWordShorthand) useSingleWordShorthand = false; valueText = value->cssText(); layerResult.append(valueText); } if (shorthand.properties()[j] == CSSPropertyBackgroundPositionY || shorthand.properties()[j] == CSSPropertyWebkitMaskPositionY) { foundPositionYCSSProperty = true; // background-position is a special case: if only the first offset is specified, // the second one defaults to "center", not the same value. if (commonValueInitialized && commonValue != "initial" && commonValue != "inherit") commonValue = String(); } } if (!commonValueInitialized) { commonValue = valueText; commonValueInitialized = true; } else if (!commonValue.isNull() && commonValue != valueText) commonValue = String(); } if (!layerResult.isEmpty()) { if (!result.isEmpty()) result.appendLiteral(", "); result.append(layerResult); } } if (isInitialOrInherit(commonValue)) return commonValue; if (result.isEmpty()) return String(); return result.toString(); }
String StylePropertySet::getLayeredShorthandValue(const StylePropertyShorthand& shorthand) const { String res; const unsigned size = shorthand.length(); // Begin by collecting the properties into an array. Vector< RefPtr<CSSValue> > values(size); size_t numLayers = 0; for (unsigned i = 0; i < size; ++i) { values[i] = getPropertyCSSValue(shorthand.properties()[i]); if (values[i]) { if (values[i]->isValueList()) { CSSValueList* valueList = static_cast<CSSValueList*>(values[i].get()); numLayers = max(valueList->length(), numLayers); } else numLayers = max<size_t>(1U, numLayers); } } // Now stitch the properties together. Implicit initial values are flagged as such and // can safely be omitted. for (size_t i = 0; i < numLayers; i++) { String layerRes; bool useRepeatXShorthand = false; bool useRepeatYShorthand = false; bool useSingleWordShorthand = false; for (unsigned j = 0; j < size; j++) { RefPtr<CSSValue> value; if (values[j]) { if (values[j]->isValueList()) value = static_cast<CSSValueList*>(values[j].get())->item(i); else { value = values[j]; // Color only belongs in the last layer. if (shorthand.properties()[j] == CSSPropertyBackgroundColor) { if (i != numLayers - 1) value = 0; } else if (i != 0) // Other singletons only belong in the first layer. value = 0; } } // We need to report background-repeat as it was written in the CSS. If the property is implicit, // then it was written with only one value. Here we figure out which value that was so we can // report back correctly. if (shorthand.properties()[j] == CSSPropertyBackgroundRepeatX && isPropertyImplicit(shorthand.properties()[j])) { // BUG 49055: make sure the value was not reset in the layer check just above. if (j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyBackgroundRepeatY && value) { RefPtr<CSSValue> yValue; RefPtr<CSSValue> nextValue = values[j + 1]; if (nextValue->isValueList()) yValue = static_cast<CSSValueList*>(nextValue.get())->itemWithoutBoundsCheck(i); else yValue = nextValue; int xId = static_cast<CSSPrimitiveValue*>(value.get())->getIdent(); int yId = static_cast<CSSPrimitiveValue*>(yValue.get())->getIdent(); if (xId != yId) { if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { useRepeatXShorthand = true; ++j; } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { useRepeatYShorthand = true; continue; } } else { useSingleWordShorthand = true; ++j; } } } if (value && !value->isImplicitInitialValue()) { if (!layerRes.isNull()) layerRes += " "; if (useRepeatXShorthand) { useRepeatXShorthand = false; layerRes += getValueName(CSSValueRepeatX); } else if (useRepeatYShorthand) { useRepeatYShorthand = false; layerRes += getValueName(CSSValueRepeatY); } else if (useSingleWordShorthand) { useSingleWordShorthand = false; layerRes += value->cssText(); } else layerRes += value->cssText(); } } if (!layerRes.isNull()) { if (!res.isNull()) res += ", "; res += layerRes; } } return res; }