Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (291689 => 291690)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2022-03-22 19:54:50 UTC (rev 291690)
@@ -1,3 +1,16 @@
+2022-03-22 Commit Queue <commit-qu...@webkit.org>
+
+ Unreviewed, reverting r291546.
+ https://bugs.webkit.org/show_bug.cgi?id=238218
+
+ 7% regression in Speedometer2/jQuery-TodoMVC
+
+ Reverted changeset:
+
+ "Fix CSS cascade regarding logical properties"
+ https://bugs.webkit.org/show_bug.cgi?id=236199
+ https://commits.webkit.org/r291546
+
2022-03-22 Ziran Sun <z...@igalia.com>
[selection] Change form's selection attribute to unsigned long
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animation-004-expected.txt (291689 => 291690)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animation-004-expected.txt 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animation-004-expected.txt 2022-03-22 19:54:50 UTC (rev 291690)
@@ -11,7 +11,7 @@
PASS Filling transitions update when the writing-mode is changed
PASS The number of interpolating properties can be increased when the writing-mode is changed
PASS The number of interpolating properties can be decreased when the writing-mode is changed
-PASS Transitions update when the writing-mode is changed through a CSS variable
+FAIL Transitions update when the writing-mode is changed through a CSS variable assert_equals: expected "50px" but got "0px"
PASS Transitions update when the direction is changed
PASS Transitions from logical to physical update when the direction is changed
PASS Transitions from physical to logical update when the direction is changed
Deleted: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-logical/logicalprops-with-deferred-writing-mode-expected.txt (291689 => 291690)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-logical/logicalprops-with-deferred-writing-mode-expected.txt 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-logical/logicalprops-with-deferred-writing-mode-expected.txt 2022-03-22 19:54:50 UTC (rev 291690)
@@ -1,8 +0,0 @@
-
-PASS Writing mode with variable
-PASS Writing mode with nested variables
-PASS Writing mode with 'inherit'
-PASS Writing mode with 'initial'
-PASS Writing mode with 'revert'
-PASS Writing mode with 'revert-layer'
-
Deleted: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-logical/logicalprops-with-deferred-writing-mode.html (291689 => 291690)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-logical/logicalprops-with-deferred-writing-mode.html 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-logical/logicalprops-with-deferred-writing-mode.html 2022-03-22 19:54:50 UTC (rev 291690)
@@ -1,175 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Logical properties with deferred <code>writing-mode</code></title>
-<link rel="author" title="Oriol Brufau" href="" />
-<link rel="help" href=""
-<link rel="help" href=""
-<link rel="help" href=""
-<meta name="assert" content="Checks that logical properties are resolved correctly when the writing mode isn't known until computed-value time.">
-<style>
-#parent {
- writing-mode: vertical-lr;
-}
-
-@layer {
- .revert-layer {
- writing-mode: vertical-rl;
- }
-}
-@layer {
- .revert-layer {
- writing-mode: horizontal-tb;
- writing-mode: revert-layer;
- }
-}
-</style>
-<div id="parent">
- <div id="target"></div>
-</div>
-<script src=""
-<script src=""
-<script>
-const target = document.getElementById("target");
-const computedStyle = getComputedStyle(target);
-
-function check(expected) {
- for (let [prop, value] of Object.entries(expected)) {
- assert_equals(computedStyle.getPropertyValue(prop), value, prop);
- }
-}
-
-test(function() {
- target.style.cssText = `
- --wm: vertical-rl;
- writing-mode: var(--wm);
- margin-block-start: 1px;
- margin-block-end: 2px;
- margin-inline-start: 3px;
- margin-inline-end: 4px;
- `;
- check({
- // Logicals
- "margin-block-start": "1px",
- "margin-block-end": "2px",
- "margin-inline-start": "3px",
- "margin-inline-end": "4px",
- // Physicals
- "margin-right": "1px",
- "margin-left": "2px",
- "margin-top": "3px",
- "margin-bottom": "4px",
- });
-}, "Writing mode with variable");
-
-test(function() {
- target.style.cssText = `
- --wm1: vertical-rl;
- --wm2: var(--wm1);
- writing-mode: var(--wm2);
- margin-block-start: 1px;
- margin-block-end: 2px;
- margin-inline-start: 3px;
- margin-inline-end: 4px;
- `;
- check({
- // Logicals
- "margin-block-start": "1px",
- "margin-block-end": "2px",
- "margin-inline-start": "3px",
- "margin-inline-end": "4px",
- // Physicals
- "margin-right": "1px",
- "margin-left": "2px",
- "margin-top": "3px",
- "margin-bottom": "4px",
- });
-}, "Writing mode with nested variables");
-
-test(function() {
- target.style.cssText = `
- writing-mode: inherit;
- margin-block-start: 1px;
- margin-block-end: 2px;
- margin-inline-start: 3px;
- margin-inline-end: 4px;
- `;
- check({
- // Logicals
- "margin-block-start": "1px",
- "margin-block-end": "2px",
- "margin-inline-start": "3px",
- "margin-inline-end": "4px",
- // Physicals
- "margin-left": "1px",
- "margin-right": "2px",
- "margin-top": "3px",
- "margin-bottom": "4px",
- });
-}, "Writing mode with 'inherit'");
-
-test(function() {
- target.style.cssText = `
- writing-mode: initial;
- margin-block-start: 1px;
- margin-block-end: 2px;
- margin-inline-start: 3px;
- margin-inline-end: 4px;
- `;
- check({
- // Logicals
- "margin-block-start": "1px",
- "margin-block-end": "2px",
- "margin-inline-start": "3px",
- "margin-inline-end": "4px",
- // Physicals
- "margin-top": "1px",
- "margin-bottom": "2px",
- "margin-left": "3px",
- "margin-right": "4px",
- });
-}, "Writing mode with 'initial'");
-
-test(function() {
- target.style.cssText = `
- writing-mode: revert;
- margin-block-start: 1px;
- margin-block-end: 2px;
- margin-inline-start: 3px;
- margin-inline-end: 4px;
- `;
- check({
- // Logicals
- "margin-block-start": "1px",
- "margin-block-end": "2px",
- "margin-inline-start": "3px",
- "margin-inline-end": "4px",
- // Physicals
- "margin-left": "1px",
- "margin-right": "2px",
- "margin-top": "3px",
- "margin-bottom": "4px",
- });
-}, "Writing mode with 'revert'");
-
-test(function() {
- target.className = "revert-layer";
- target.style.cssText = `
- margin-block-start: 1px;
- margin-block-end: 2px;
- margin-inline-start: 3px;
- margin-inline-end: 4px;
- `;
- check({
- // Logicals
- "margin-block-start": "1px",
- "margin-block-end": "2px",
- "margin-inline-start": "3px",
- "margin-inline-end": "4px",
- // Physicals
- "margin-right": "1px",
- "margin-left": "2px",
- "margin-top": "3px",
- "margin-bottom": "4px",
- });
-}, "Writing mode with 'revert-layer'");
-</script>
Modified: trunk/Source/WebCore/ChangeLog (291689 => 291690)
--- trunk/Source/WebCore/ChangeLog 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/Source/WebCore/ChangeLog 2022-03-22 19:54:50 UTC (rev 291690)
@@ -1,3 +1,16 @@
+2022-03-22 Commit Queue <commit-qu...@webkit.org>
+
+ Unreviewed, reverting r291546.
+ https://bugs.webkit.org/show_bug.cgi?id=238218
+
+ 7% regression in Speedometer2/jQuery-TodoMVC
+
+ Reverted changeset:
+
+ "Fix CSS cascade regarding logical properties"
+ https://bugs.webkit.org/show_bug.cgi?id=236199
+ https://commits.webkit.org/r291546
+
2022-03-22 Chris Dumez <cdu...@apple.com>
REGRESSION (iOS 15.1 / r280824) QuickLook - model not loading when passing extra parameters
Modified: trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp (291689 => 291690)
--- trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp 2022-03-22 19:54:50 UTC (rev 291690)
@@ -4034,10 +4034,6 @@
}
case CSSPropertyBorderBlockColor:
return getCSSPropertyValuesFor2SidesShorthand(borderBlockColorShorthand());
- case CSSPropertyBorderBlockEnd:
- return getCSSPropertyValuesForShorthandProperties(borderBlockEndShorthand());
- case CSSPropertyBorderBlockStart:
- return getCSSPropertyValuesForShorthandProperties(borderBlockStartShorthand());
case CSSPropertyBorderBlockStyle:
return getCSSPropertyValuesFor2SidesShorthand(borderBlockStyleShorthand());
case CSSPropertyBorderBlockWidth:
@@ -4058,10 +4054,6 @@
}
case CSSPropertyBorderInlineColor:
return getCSSPropertyValuesFor2SidesShorthand(borderInlineColorShorthand());
- case CSSPropertyBorderInlineEnd:
- return getCSSPropertyValuesForShorthandProperties(borderInlineEndShorthand());
- case CSSPropertyBorderInlineStart:
- return getCSSPropertyValuesForShorthandProperties(borderInlineStartShorthand());
case CSSPropertyBorderInlineStyle:
return getCSSPropertyValuesFor2SidesShorthand(borderInlineStyleShorthand());
case CSSPropertyBorderInlineWidth:
@@ -4213,17 +4205,21 @@
break;
/* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
+ case CSSPropertyBorderBlockEnd:
case CSSPropertyBorderBlockEndColor:
case CSSPropertyBorderBlockEndStyle:
case CSSPropertyBorderBlockEndWidth:
+ case CSSPropertyBorderBlockStart:
case CSSPropertyBorderBlockStartColor:
case CSSPropertyBorderBlockStartStyle:
case CSSPropertyBorderBlockStartWidth:
- case CSSPropertyBorderEndEndRadius:
- case CSSPropertyBorderEndStartRadius:
+ case CSSPropertyBorderEndEndRadius:
+ case CSSPropertyBorderEndStartRadius:
+ case CSSPropertyBorderInlineEnd:
case CSSPropertyBorderInlineEndColor:
case CSSPropertyBorderInlineEndStyle:
case CSSPropertyBorderInlineEndWidth:
+ case CSSPropertyBorderInlineStart:
case CSSPropertyBorderInlineStartColor:
case CSSPropertyBorderInlineStartStyle:
case CSSPropertyBorderInlineStartWidth:
Modified: trunk/Source/WebCore/css/CSSProperties.json (291689 => 291690)
--- trunk/Source/WebCore/css/CSSProperties.json 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/Source/WebCore/css/CSSProperties.json 2022-03-22 19:54:50 UTC (rev 291690)
@@ -1342,7 +1342,11 @@
"border-block-end-width",
"border-block-end-style",
"border-block-end-color"
- ]
+ ],
+ "logical-property-group": {
+ "name": "border",
+ "resolver": "block-end"
+ }
},
"specification": {
"category": "css-logical-props",
@@ -1419,7 +1423,11 @@
"border-block-start-width",
"border-block-start-style",
"border-block-start-color"
- ]
+ ],
+ "logical-property-group": {
+ "name": "border",
+ "resolver": "block-start"
+ }
},
"specification": {
"category": "css-logical-props",
@@ -1517,7 +1525,11 @@
"border-bottom-width",
"border-bottom-style",
"border-bottom-color"
- ]
+ ],
+ "logical-property-group": {
+ "name": "border",
+ "resolver": "bottom"
+ }
},
"specification": {
"category": "css-backgrounds",
@@ -1758,7 +1770,11 @@
"border-inline-end-width",
"border-inline-end-style",
"border-inline-end-color"
- ]
+ ],
+ "logical-property-group": {
+ "name": "border",
+ "resolver": "inline-end"
+ }
},
"specification": {
"category": "css-logical-props",
@@ -1835,7 +1851,11 @@
"border-inline-start-width",
"border-inline-start-style",
"border-inline-start-color"
- ]
+ ],
+ "logical-property-group": {
+ "name": "border",
+ "resolver": "inline-start"
+ }
},
"specification": {
"category": "css-logical-props",
@@ -1933,7 +1953,11 @@
"border-left-width",
"border-left-style",
"border-left-color"
- ]
+ ],
+ "logical-property-group": {
+ "name": "border",
+ "resolver": "left"
+ }
},
"specification": {
"category": "css-backgrounds",
@@ -2014,7 +2038,11 @@
"border-right-width",
"border-right-style",
"border-right-color"
- ]
+ ],
+ "logical-property-group": {
+ "name": "border",
+ "resolver": "right"
+ }
},
"specification": {
"category": "css-backgrounds",
@@ -2134,7 +2162,11 @@
"border-top-width",
"border-top-style",
"border-top-color"
- ]
+ ],
+ "logical-property-group": {
+ "name": "border",
+ "resolver": "top"
+ }
},
"specification": {
"category": "css-backgrounds",
Modified: trunk/Source/WebCore/css/parser/CSSParser.cpp (291689 => 291690)
--- trunk/Source/WebCore/css/parser/CSSParser.cpp 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/Source/WebCore/css/parser/CSSParser.cpp 2022-03-22 19:54:50 UTC (rev 291690)
@@ -213,7 +213,10 @@
return nullptr;
for (auto& property : parsedProperties) {
- if (property.id() == propID)
+ CSSPropertyID currentId = property.id();
+ if (CSSProperty::isDirectionAwareProperty(currentId))
+ currentId = CSSProperty::resolveDirectionAwareProperty(currentId, direction, writingMode);
+ if (currentId == propID)
return property.value();
}
Modified: trunk/Source/WebCore/style/PropertyCascade.cpp (291689 => 291690)
--- trunk/Source/WebCore/style/PropertyCascade.cpp 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/Source/WebCore/style/PropertyCascade.cpp 2022-03-22 19:54:50 UTC (rev 291690)
@@ -58,14 +58,15 @@
case CSSPropertyBoxShadow:
return true;
default:
- return CSSProperty::isInLogicalPropertyGroup(propertyID);
+ return false;
}
}
-PropertyCascade::PropertyCascade(const MatchResult& matchResult, CascadeLevel maximumCascadeLevel, IncludedProperties includedProperties)
+PropertyCascade::PropertyCascade(const MatchResult& matchResult, CascadeLevel maximumCascadeLevel, IncludedProperties includedProperties, Direction direction)
: m_matchResult(matchResult)
, m_includedProperties(includedProperties)
, m_maximumCascadeLevel(maximumCascadeLevel)
+ , m_direction(direction)
{
buildCascade();
}
@@ -75,6 +76,8 @@
, m_includedProperties(parent.m_includedProperties)
, m_maximumCascadeLevel(maximumCascadeLevel)
, m_maximumCascadeLayerPriorityForRollback(maximumCascadeLayerPriorityForRollback)
+ , m_direction(parent.direction())
+ , m_directionIsUnresolved(false)
{
buildCascade();
}
@@ -119,7 +122,11 @@
void PropertyCascade::set(CSSPropertyID id, CSSValue& cssValue, const MatchedProperties& matchedProperties, CascadeLevel cascadeLevel)
{
- ASSERT(!CSSProperty::isDirectionAwareProperty(id));
+ if (CSSProperty::isDirectionAwareProperty(id)) {
+ auto direction = this->direction();
+ id = CSSProperty::resolveDirectionAwareProperty(id, direction.textDirection, direction.writingMode);
+ }
+
ASSERT(!shouldApplyPropertyInParseOrder(id));
auto& property = m_properties[id];
@@ -150,6 +157,7 @@
void PropertyCascade::setDeferred(CSSPropertyID id, CSSValue& cssValue, const MatchedProperties& matchedProperties, CascadeLevel cascadeLevel)
{
+ ASSERT(!CSSProperty::isDirectionAwareProperty(id));
ASSERT(shouldApplyPropertyInParseOrder(id));
Property property;
@@ -286,5 +294,50 @@
addMatch(matchedDeclarations[match.index], cascadeLevel, true);
}
+PropertyCascade::Direction PropertyCascade::resolveDirectionAndWritingMode(Direction inheritedDirection) const
+{
+ Direction result = inheritedDirection;
+
+ bool hadImportantWritingMode = false;
+ bool hadImportantDirection = false;
+
+ for (auto cascadeLevel : { CascadeLevel::UserAgent, CascadeLevel::User, CascadeLevel::Author }) {
+ for (const auto& matchedProperties : declarationsForCascadeLevel(m_matchResult, cascadeLevel)) {
+ for (unsigned i = 0, count = matchedProperties.properties->propertyCount(); i < count; ++i) {
+ auto property = matchedProperties.properties->propertyAt(i);
+ if (!property.value()->isPrimitiveValue() || property.value()->isCSSWideKeyword())
+ continue;
+ switch (property.id()) {
+ case CSSPropertyWritingMode:
+ if (!hadImportantWritingMode || property.isImportant()) {
+ result.writingMode = downcast<CSSPrimitiveValue>(*property.value());
+ hadImportantWritingMode = property.isImportant();
+ }
+ break;
+ case CSSPropertyDirection:
+ if (!hadImportantDirection || property.isImportant()) {
+ result.textDirection = downcast<CSSPrimitiveValue>(*property.value());
+ hadImportantDirection = property.isImportant();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return result;
}
+
+PropertyCascade::Direction PropertyCascade::direction() const
+{
+ if (m_directionIsUnresolved) {
+ m_direction = resolveDirectionAndWritingMode(m_direction);
+ m_directionIsUnresolved = false;
+ }
+ return m_direction;
}
+
+}
+}
Modified: trunk/Source/WebCore/style/PropertyCascade.h (291689 => 291690)
--- trunk/Source/WebCore/style/PropertyCascade.h 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/Source/WebCore/style/PropertyCascade.h 2022-03-22 19:54:50 UTC (rev 291690)
@@ -40,7 +40,12 @@
public:
enum IncludedProperties { All, InheritedOnly };
- PropertyCascade(const MatchResult&, CascadeLevel, IncludedProperties);
+ struct Direction {
+ TextDirection textDirection;
+ WritingMode writingMode;
+ };
+
+ PropertyCascade(const MatchResult&, CascadeLevel, IncludedProperties, Direction);
PropertyCascade(const PropertyCascade&, CascadeLevel, std::optional<CascadeLayerPriority> maximumCascadeLayerPriorityForRollback = { });
~PropertyCascade();
@@ -58,7 +63,6 @@
const Property& property(CSSPropertyID) const;
bool hasDeferredProperty(CSSPropertyID) const;
- bool areDeferredInOrder(CSSPropertyID, CSSPropertyID) const;
const Property& deferredProperty(CSSPropertyID) const;
bool hasCustomProperty(const String&) const;
@@ -67,6 +71,8 @@
const Vector<Property, 8>& deferredProperties() const { return m_deferredProperties; }
const HashMap<AtomString, Property>& customProperties() const { return m_customProperties; }
+ Direction direction() const;
+
private:
void buildCascade();
bool addNormalMatches(CascadeLevel);
@@ -77,10 +83,14 @@
void setDeferred(CSSPropertyID, CSSValue&, const MatchedProperties&, CascadeLevel);
static void setPropertyInternal(Property&, CSSPropertyID, CSSValue&, const MatchedProperties&, CascadeLevel);
+ Direction resolveDirectionAndWritingMode(Direction inheritedDirection) const;
+
const MatchResult& m_matchResult;
const IncludedProperties m_includedProperties;
const CascadeLevel m_maximumCascadeLevel;
const std::optional<CascadeLayerPriority> m_maximumCascadeLayerPriorityForRollback;
+ mutable Direction m_direction;
+ mutable bool m_directionIsUnresolved { true };
Property m_properties[numCSSProperties + 2];
std::bitset<numCSSProperties + 2> m_propertyIsPresent;
@@ -107,13 +117,6 @@
return m_deferredPropertiesIndices.contains(id);
}
-inline bool PropertyCascade::areDeferredInOrder(CSSPropertyID id1, CSSPropertyID id2) const
-{
- ASSERT(hasDeferredProperty(id1));
- ASSERT(hasDeferredProperty(id2));
- return m_deferredPropertiesIndices.get(id1) < m_deferredPropertiesIndices.get(id2);
-}
-
inline const PropertyCascade::Property& PropertyCascade::deferredProperty(CSSPropertyID id) const
{
ASSERT(hasDeferredProperty(id));
Modified: trunk/Source/WebCore/style/StyleBuilder.cpp (291689 => 291690)
--- trunk/Source/WebCore/style/StyleBuilder.cpp 2022-03-22 19:51:52 UTC (rev 291689)
+++ trunk/Source/WebCore/style/StyleBuilder.cpp 2022-03-22 19:54:50 UTC (rev 291690)
@@ -48,6 +48,11 @@
static const CSSPropertyID firstLowPriorityProperty = static_cast<CSSPropertyID>(lastHighPriorityProperty + 1);
+inline PropertyCascade::Direction directionFromStyle(const RenderStyle& style)
+{
+ return { style.direction(), style.writingMode() };
+}
+
inline bool isValidVisitedLinkProperty(CSSPropertyID id)
{
switch (id) {
@@ -76,7 +81,7 @@
}
Builder::Builder(RenderStyle& style, BuilderContext&& context, const MatchResult& matchResult, CascadeLevel cascadeLevel, PropertyCascade::IncludedProperties includedProperties)
- : m_cascade(matchResult, cascadeLevel, includedProperties)
+ : m_cascade(matchResult, cascadeLevel, includedProperties, directionFromStyle(style))
, m_state(*this, style, WTFMove(context))
{
}
@@ -268,8 +273,8 @@
auto valueToApply = resolveValue(id, value);
if (CSSProperty::isDirectionAwareProperty(id)) {
- auto& style = m_state.style();
- CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, style.direction(), style.writingMode());
+ auto direction = m_cascade.direction();
+ CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, direction.textDirection, direction.writingMode);
ASSERT(newId != id);
return applyProperty(newId, valueToApply.get(), linkMatchMask);
}
@@ -315,19 +320,6 @@
auto& property = rollbackCascade->property(id);
applyRollbackCascadeProperty(property, linkMatchMask);
return;
- } else if (CSSProperty::isInLogicalPropertyGroup(id)) {
- ASSERT(!CSSProperty::isDirectionAwareProperty(id));
- auto& style = m_state.style();
- auto logicalId = CSSProperty::unresolvePhysicalProperty(id, style.direction(), style.writingMode());
- bool hasPhysical = rollbackCascade->hasDeferredProperty(id);
- bool hasLogical = rollbackCascade->hasDeferredProperty(logicalId);
- if (hasPhysical || hasLogical) {
- if (hasLogical && (!hasPhysical || rollbackCascade->areDeferredInOrder(id, logicalId)))
- id = logicalId;
- auto& property = rollbackCascade->deferredProperty(id);
- applyRollbackCascadeProperty(property, linkMatchMask);
- return;
- }
} else if (rollbackCascade->hasDeferredProperty(id)) {
auto& property = rollbackCascade->deferredProperty(id);
applyRollbackCascadeProperty(property, linkMatchMask);