Changeset 281798 in webkit
- Timestamp:
- Aug 31, 2021 4:48:10 AM (11 months ago)
- Location:
- trunk
- Files:
-
- 5 edited
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/layer-basic-expected.txt (modified) (2 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/style/RuleSet.cpp (modified) (7 diffs)
-
Source/WebCore/style/RuleSet.h (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r281796 r281798 1 2021-08-31 Antti Koivisto <antti@apple.com> 2 3 [CSS Cascade Layers] Compute order correctly for late added sublayers 4 https://bugs.webkit.org/show_bug.cgi?id=229666 5 6 Reviewed by Simon Fraser. 7 8 * web-platform-tests/css/css-cascade/layer-basic-expected.txt: 9 1 10 2021-08-31 Youenn Fablet <youenn@apple.com> 2 11 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/layer-basic-expected.txt
r281701 r281798 18 18 PASS B8 Named layers 19 19 PASS B9 Named layers 20 FAIL B10 Named layers assert_equals: B10 Named layers, target 'first' expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)" 20 PASS B10 Named layers 21 21 PASS C1 Named layers shorthand 22 22 PASS C2 Named layers shorthand 23 FAIL C3 Named layers shorthand assert_equals: C3 Named layers shorthand, target 'first' expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)" 23 PASS C3 Named layers shorthand 24 24 PASS C4 Named layers shorthand 25 FAIL C5 Named layers shorthand assert_equals: C5 Named layers shorthand, target 'first' expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)" 25 PASS C5 Named layers shorthand 26 26 PASS D1 Mixed named and anonymous layers 27 27 PASS D2 Mixed named and anonymous layers 28 28 PASS D3 Mixed named and anonymous layers 29 FAIL D4 Mixed named and anonymous layers assert_equals: D4 Mixed named and anonymous layers, target 'first' expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)" 29 PASS D4 Mixed named and anonymous layers 30 30 PASS D5 Mixed named and anonymous layers 31 31 PASS E1 Statement syntax … … 33 33 PASS E3 Statement syntax 34 34 PASS E4 Statement syntax 35 FAIL E5 Statement syntax assert_equals: E5 Statement syntax, target 'first' expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)" 35 PASS E5 Statement syntax 36 36 -
trunk/Source/WebCore/ChangeLog
r281797 r281798 1 2021-08-31 Antti Koivisto <antti@apple.com> 2 3 [CSS Cascade Layers] Compute order correctly for late added sublayers 4 https://bugs.webkit.org/show_bug.cgi?id=229666 5 6 Reviewed by Simon Fraser. 7 8 In cases like 9 10 @layer a.b { ... } 11 @layer c { ... } 12 @layer a.d { ... } 13 14 'c' should have higher priority than 'a.d'. 15 16 Replace the per-RuleData layer order vector with references (indexes) to layer entry vector. 17 These entries have order field that can be recomputed. 18 19 * style/RuleSet.cpp: 20 (WebCore::Style::RuleSet::addRule): 21 (WebCore::Style::RuleSet::Builder::addStyleRule): 22 (WebCore::Style::RuleSet::Builder::pushCascadeLayer): 23 24 Instead of computing order directly we just give each layer an identifier and add an entry for it to the layer vector. 25 26 (WebCore::Style::RuleSet::Builder::popCascadeLayer): 27 (WebCore::Style::RuleSet::Builder::~Builder): 28 29 Compute layer order after building for all layers. 30 31 (WebCore::Style::RuleSet::shrinkToFit): 32 * style/RuleSet.h: 33 (WebCore::Style::RuleSet::cascadeLayerForIdentifier): 34 (WebCore::Style::RuleSet::cascadeLayerForIdentifier const): 35 (WebCore::Style::RuleSet::cascadeLayerOrderFor const): 36 1 37 2021-08-31 Philippe Normand <pnormand@igalia.com> 2 38 -
trunk/Source/WebCore/style/RuleSet.cpp
r281742 r281798 84 84 } 85 85 86 void RuleSet::addRule(const StyleRule& rule, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayer Order, MediaQueryCollector* mediaQueryCollector)86 void RuleSet::addRule(const StyleRule& rule, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayerIdentifier, MediaQueryCollector* mediaQueryCollector) 87 87 { 88 88 RuleData ruleData(rule, selectorIndex, selectorListIndex, m_ruleCount++); 89 89 90 if (cascadeLayer Order) {91 auto oldSize = m_cascadeLayer OrderForPosition.size();92 m_cascadeLayer OrderForPosition.grow(m_ruleCount);93 std::fill(m_cascadeLayer OrderForPosition.begin() + oldSize, m_cascadeLayerOrderForPosition.end(), 0);94 m_cascadeLayer OrderForPosition.last() = cascadeLayerOrder;90 if (cascadeLayerIdentifier) { 91 auto oldSize = m_cascadeLayerIdentifierForRulePosition.size(); 92 m_cascadeLayerIdentifierForRulePosition.grow(m_ruleCount); 93 std::fill(m_cascadeLayerIdentifierForRulePosition.begin() + oldSize, m_cascadeLayerIdentifierForRulePosition.end(), 0); 94 m_cascadeLayerIdentifierForRulePosition.last() = cascadeLayerIdentifier; 95 95 } 96 96 … … 386 386 } 387 387 388 RuleSet::Builder::~Builder() 389 { 390 if (mode == Mode::Normal && !cascadeLayerIdentifierMap.isEmpty()) 391 updateCascadeLayerOrder(); 392 } 393 388 394 void RuleSet::Builder::addStyleRule(const StyleRule& rule) 389 395 { … … 393 399 unsigned selectorListIndex = 0; 394 400 for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex)) 395 ruleSet->addRule(rule, selectorIndex, selectorListIndex++, c ascadeLayerOrder, &mediaQueryCollector);401 ruleSet->addRule(rule, selectorIndex, selectorListIndex++, currentCascadeLayerIdentifier, &mediaQueryCollector); 396 402 } 397 403 … … 400 406 if (mode != Mode::Normal) 401 407 return; 408 409 if (cascadeLayerIdentifierMap.isEmpty() && !ruleSet->m_cascadeLayers.isEmpty()) { 410 // For incremental build, reconstruct the name->identifier map. 411 CascadeLayerIdentifier identifier = 0; 412 for (auto& layer : ruleSet->m_cascadeLayers) 413 cascadeLayerIdentifierMap.add(layer.resolvedName, ++identifier); 414 } 415 402 416 auto nameResolvingAnonymous = [&] { 403 417 if (name.isEmpty()) { … … 412 426 for (auto& nameSegment : nameResolvingAnonymous()) { 413 427 resolvedCascadeLayerName.append(nameSegment); 414 cascadeLayerOrder = ruleSet->m_cascadeLayerOrderMap.ensure(resolvedCascadeLayerName, [&] { 415 // FIXME: This is not correct when adding a sublayer to an already registered layer after it has gained siblings. 416 return ruleSet->m_cascadeLayerOrderMap.size() + 1; 428 currentCascadeLayerIdentifier = cascadeLayerIdentifierMap.ensure(resolvedCascadeLayerName, [&] { 429 // Previously unseen layer. 430 ruleSet->m_cascadeLayers.append({ resolvedCascadeLayerName, currentCascadeLayerIdentifier }); 431 return ruleSet->m_cascadeLayers.size(); 417 432 }).iterator->value; 418 433 } … … 423 438 if (mode != Mode::Normal) 424 439 return; 425 auto size = name.isEmpty() ? 1 : name.size(); 426 resolvedCascadeLayerName.shrink(resolvedCascadeLayerName.size() - size); 427 cascadeLayerOrder = resolvedCascadeLayerName.isEmpty() ? 0 : ruleSet->m_cascadeLayerOrderMap.get(resolvedCascadeLayerName); 440 441 for (auto size = name.isEmpty() ? 1 : name.size(); size--;) { 442 resolvedCascadeLayerName.removeLast(); 443 currentCascadeLayerIdentifier = ruleSet->cascadeLayerForIdentifier(currentCascadeLayerIdentifier).parentIdentifier; 444 } 445 } 446 447 void RuleSet::Builder::updateCascadeLayerOrder() 448 { 449 auto compare = [&](CascadeLayerIdentifier a, CascadeLayerIdentifier b) { 450 while (a && b) { 451 // Identifiers are in parse order which almost corresponds to the layer priority order. 452 // The only exception is when a sublayer gets added to a layer after adding other non-sublayers. 453 // To resolve this we need look for a shared ancestor layer. 454 auto aParent = ruleSet->cascadeLayerForIdentifier(a).parentIdentifier; 455 auto bParent = ruleSet->cascadeLayerForIdentifier(b).parentIdentifier; 456 if (aParent == bParent || aParent == b || bParent == a) 457 break; 458 if (aParent > bParent) 459 a = aParent; 460 else 461 b = bParent; 462 } 463 return a < b; 464 }; 465 466 Vector<CascadeLayerIdentifier> orderVector; 467 auto layerCount = ruleSet->m_cascadeLayers.size(); 468 orderVector.reserveInitialCapacity(layerCount); 469 for (CascadeLayerIdentifier identifier = 1; identifier <= layerCount; ++identifier) 470 orderVector.uncheckedAppend(identifier); 471 472 std::sort(orderVector.begin(), orderVector.end(), compare); 473 474 for (unsigned i = 0; i < orderVector.size(); ++i) 475 ruleSet->cascadeLayerForIdentifier(orderVector[i]).order = i + 1; 428 476 } 429 477 … … 562 610 shrinkDynamicRules(m_dynamicMediaQueryRules); 563 611 564 m_cascadeLayerOrderForPosition.shrinkToFit(); 612 m_cascadeLayers.shrinkToFit(); 613 m_cascadeLayerIdentifierForRulePosition.shrinkToFit(); 565 614 } 566 615 -
trunk/Source/WebCore/style/RuleSet.h
r281742 r281798 151 151 RuleSet(); 152 152 153 using CascadeLayerIdentifier = unsigned; 154 153 155 struct Builder { 154 156 enum class Mode { Normal, ResolverMutationScan }; … … 159 161 Mode mode { Mode::Normal }; 160 162 CascadeLayerName resolvedCascadeLayerName { }; 161 unsigned cascadeLayerOrder { 0 }; 163 HashMap<CascadeLayerName, CascadeLayerIdentifier> cascadeLayerIdentifierMap { }; 164 CascadeLayerIdentifier currentCascadeLayerIdentifier { 0 }; 162 165 163 166 void addRulesFromSheet(const StyleSheetContents&); 167 168 ~Builder(); 164 169 165 170 private: … … 169 174 void pushCascadeLayer(const CascadeLayerName&); 170 175 void popCascadeLayer(const CascadeLayerName&); 176 void updateCascadeLayerOrder(); 171 177 }; 172 178 … … 179 185 180 186 template<typename Function> void traverseRuleDatas(Function&&); 187 188 struct CascadeLayer { 189 CascadeLayerName resolvedName; 190 CascadeLayerIdentifier parentIdentifier; 191 unsigned order { 0 }; 192 }; 193 CascadeLayer& cascadeLayerForIdentifier(CascadeLayerIdentifier identifier) { return m_cascadeLayers[identifier - 1]; } 194 const CascadeLayer& cascadeLayerForIdentifier(CascadeLayerIdentifier identifier) const { return m_cascadeLayers[identifier - 1]; } 181 195 182 196 AtomRuleMap m_idRules; … … 200 214 unsigned m_ruleCount { 0 }; 201 215 202 HashMap<CascadeLayerName, unsigned> m_cascadeLayerOrderMap;203 // This is a side vector to hold layer orderwithout bloating RuleData.204 Vector< unsigned> m_cascadeLayerOrderForPosition;216 Vector<CascadeLayer> m_cascadeLayers; 217 // This is a side vector to hold layer identifiers without bloating RuleData. 218 Vector<CascadeLayerIdentifier> m_cascadeLayerIdentifierForRulePosition; 205 219 206 220 bool m_hasHostPseudoClassRulesMatchingInShadowTree { false }; … … 221 235 inline unsigned RuleSet::cascadeLayerOrderFor(const RuleData& ruleData) const 222 236 { 223 if (m_cascadeLayerOrderForPosition.size() > ruleData.position()) 224 return m_cascadeLayerOrderForPosition[ruleData.position()]; 225 return 0; 237 if (m_cascadeLayerIdentifierForRulePosition.size() <= ruleData.position()) 238 return 0; 239 auto identifier = m_cascadeLayerIdentifierForRulePosition[ruleData.position()]; 240 if (!identifier) 241 return 0; 242 return cascadeLayerForIdentifier(identifier).order; 226 243 } 227 228 244 229 245 } // namespace Style
Note: See TracChangeset
for help on using the changeset viewer.