Changeset 283488 in webkit
- Timestamp:
- Oct 3, 2021, 11:37:45 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 5 edited
-
ChangeLog (modified) (1 diff)
-
Sources.txt (modified) (1 diff)
-
WebCore.xcodeproj/project.pbxproj (modified) (4 diffs)
-
style/RuleSet.cpp (modified) (7 diffs)
-
style/RuleSet.h (modified) (5 diffs)
-
style/RuleSetBuilder.cpp (added)
-
style/RuleSetBuilder.h (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r283486 r283488 1 2021-10-03 Antti Koivisto <antti@apple.com> 2 3 Move RuleSet builder to a file of its own 4 https://bugs.webkit.org/show_bug.cgi?id=231137 5 6 Reviewed by Alan Bujtas. 7 8 There is quite a bit of code for it. 9 10 There is lots of room for refactoring and cleanups here. This patch does none of it. 11 12 * Sources.txt: 13 * WebCore.xcodeproj/project.pbxproj: 14 * style/RuleSet.cpp: 15 (WebCore::Style::RuleSet::addRule): 16 (WebCore::Style::RuleSet::addRulesFromSheet): 17 (WebCore::Style::RuleSet::Builder::addChildRules): Deleted. 18 (WebCore::Style::RuleSet::Builder::addRulesFromSheet): Deleted. 19 (WebCore::Style::RuleSet::Builder::~Builder): Deleted. 20 (WebCore::Style::RuleSet::Builder::addStyleRule): Deleted. 21 (WebCore::Style::RuleSet::Builder::registerLayers): Deleted. 22 (WebCore::Style::RuleSet::Builder::pushCascadeLayer): Deleted. 23 (WebCore::Style::RuleSet::Builder::popCascadeLayer): Deleted. 24 (WebCore::Style::RuleSet::Builder::updateCascadeLayerOrder): Deleted. 25 (WebCore::Style::RuleSet::Builder::addMutatingRulesToResolver): Deleted. 26 (WebCore::Style::RuleSet::MediaQueryCollector::pushAndEvaluate): Deleted. 27 (WebCore::Style::RuleSet::MediaQueryCollector::pop): Deleted. 28 (WebCore::Style::RuleSet::MediaQueryCollector::didMutateResolver): Deleted. 29 (WebCore::Style::RuleSet::MediaQueryCollector::addRuleIfNeeded): Deleted. 30 31 MediaQueryCollector (an implementation detail of the Builder) moves too. 32 33 * style/RuleSet.h: 34 * style/RuleSetBuilder.cpp: Added. 35 (WebCore::Style::RuleSetBuilder::~RuleSetBuilder): 36 (WebCore::Style::RuleSetBuilder::addChildRules): 37 (WebCore::Style::RuleSetBuilder::addRulesFromSheet): 38 (WebCore::Style::RuleSetBuilder::addStyleRule): 39 (WebCore::Style::RuleSetBuilder::registerLayers): 40 (WebCore::Style::RuleSetBuilder::pushCascadeLayer): 41 (WebCore::Style::RuleSetBuilder::popCascadeLayer): 42 (WebCore::Style::RuleSetBuilder::updateCascadeLayerOrder): 43 (WebCore::Style::RuleSetBuilder::addMutatingRulesToResolver): 44 (WebCore::Style::RuleSetMediaQueryCollector::pushAndEvaluate): 45 (WebCore::Style::RuleSetMediaQueryCollector::pop): 46 (WebCore::Style::RuleSetMediaQueryCollector::didMutateResolver): 47 (WebCore::Style::RuleSetMediaQueryCollector::addRuleIfNeeded): 48 * style/RuleSetBuilder.h: Added. 49 1 50 2021-10-03 Alan Bujtas <zalan@apple.com> 2 51 -
trunk/Source/WebCore/Sources.txt
r283464 r283488 2481 2481 style/RuleFeature.cpp 2482 2482 style/RuleSet.cpp 2483 style/RuleSetBuilder.cpp 2483 2484 style/StyleAdjuster.cpp 2484 2485 style/StyleBuilder.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r283464 r283488 5272 5272 E47C39331FE6E10800BBBC6B /* RenderTreeBuilderMultiColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39271FE6E0DC00BBBC6B /* RenderTreeBuilderMultiColumn.h */; }; 5273 5273 E47CEBC92706EF5200B8D8F5 /* InlineWalker.h in Headers */ = {isa = PBXBuildFile; fileRef = E47CEBC72706EF5100B8D8F5 /* InlineWalker.h */; }; 5274 E47CEBEA2709DFD100B8D8F5 /* RuleSetBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = E47CEBE82709DFD000B8D8F5 /* RuleSetBuilder.h */; }; 5274 5275 E47CEBE12709916D00B8D8F5 /* InlineIteratorTextBox.h in Headers */ = {isa = PBXBuildFile; fileRef = E47CEBE02709916D00B8D8F5 /* InlineIteratorTextBox.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5275 5276 E47E276516036ED200EE2AFB /* ExtensionStyleSheets.h in Headers */ = {isa = PBXBuildFile; fileRef = E47E276416036ED200EE2AFB /* ExtensionStyleSheets.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 16532 16533 E47C392C1FE6E0DF00BBBC6B /* RenderTreeUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeUpdater.h; sourceTree = "<group>"; }; 16533 16534 E47CEBC72706EF5100B8D8F5 /* InlineWalker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineWalker.h; sourceTree = "<group>"; }; 16535 E47CEBE82709DFD000B8D8F5 /* RuleSetBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuleSetBuilder.h; sourceTree = "<group>"; }; 16536 E47CEBEB2709DFDC00B8D8F5 /* RuleSetBuilder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RuleSetBuilder.cpp; sourceTree = "<group>"; }; 16534 16537 E47CEBDE2709916400B8D8F5 /* InlineIteratorTextBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineIteratorTextBox.cpp; sourceTree = "<group>"; }; 16535 16538 E47CEBE02709916D00B8D8F5 /* InlineIteratorTextBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineIteratorTextBox.h; sourceTree = "<group>"; }; … … 29404 29407 A79BAD9F161E7F3F00C2E652 /* RuleSet.cpp */, 29405 29408 A79BADA0161E7F3F00C2E652 /* RuleSet.h */, 29409 E47CEBEB2709DFDC00B8D8F5 /* RuleSetBuilder.cpp */, 29410 E47CEBE82709DFD000B8D8F5 /* RuleSetBuilder.h */, 29406 29411 7173DEBD2614DF040097DF32 /* Styleable.cpp */, 29407 29412 713922BC2518AB70005DB3C2 /* Styleable.h */, … … 35002 35007 A79BADA2161E7F3F00C2E652 /* RuleFeature.h in Headers */, 35003 35008 A79BADA4161E7F3F00C2E652 /* RuleSet.h in Headers */, 35009 E47CEBEA2709DFD100B8D8F5 /* RuleSetBuilder.h in Headers */, 35004 35010 51BA947123AC305300444846 /* RunJavaScriptParameters.h in Headers */, 35005 35011 2D76BB821945632400CFD29A /* RunLoopObserver.h in Headers */, -
trunk/Source/WebCore/style/RuleSet.cpp
r283216 r283488 36 36 #include "HTMLNames.h" 37 37 #include "MediaQueryEvaluator.h" 38 #include "RuleSetBuilder.h" 38 39 #include "SecurityOrigin.h" 39 40 #include "SelectorChecker.h" … … 84 85 } 85 86 86 void RuleSet::addRule(const StyleRule& rule, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayerIdentifier, MediaQueryCollector* mediaQueryCollector)87 void RuleSet::addRule(const StyleRule& rule, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayerIdentifier, RuleSetMediaQueryCollector* mediaQueryCollector) 87 88 { 88 89 RuleData ruleData(rule, selectorIndex, selectorListIndex, m_ruleCount++); … … 274 275 void RuleSet::addRulesFromSheet(const StyleSheetContents& sheet, const MediaQueryEvaluator& evaluator) 275 276 { 276 Builder builder { *this,MediaQueryCollector { evaluator } };277 RuleSetBuilder builder { *this, RuleSetMediaQueryCollector { evaluator } }; 277 278 builder.addRulesFromSheet(sheet); 278 279 … … 284 285 { 285 286 auto canUseDynamicMediaQueryResolution = [&] { 286 Builder builder { *this, MediaQueryCollector { evaluator, true }, nullptr,Builder::Mode::ResolverMutationScan };287 RuleSetBuilder builder { *this, RuleSetMediaQueryCollector { evaluator, true }, nullptr, RuleSetBuilder::Mode::ResolverMutationScan }; 287 288 if (builder.mediaQueryCollector.pushAndEvaluate(sheetQuery)) 288 289 builder.addRulesFromSheet(sheet); … … 291 292 }(); 292 293 293 Builder builder { *this,MediaQueryCollector { evaluator, canUseDynamicMediaQueryResolution }, &resolver };294 RuleSetBuilder builder { *this, RuleSetMediaQueryCollector { evaluator, canUseDynamicMediaQueryResolution }, &resolver }; 294 295 295 296 if (builder.mediaQueryCollector.pushAndEvaluate(sheetQuery)) … … 309 310 if (m_autoShrinkToFitEnabled) 310 311 shrinkToFit(); 311 }312 313 void RuleSet::Builder::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules)314 {315 for (auto& rule : rules) {316 if (mode == Mode::ResolverMutationScan && mediaQueryCollector.didMutateResolverWithinDynamicMediaQuery)317 break;318 319 if (is<StyleRule>(*rule)) {320 if (mode == Mode::Normal)321 addStyleRule(downcast<StyleRule>(*rule));322 continue;323 }324 if (is<StyleRulePage>(*rule)) {325 if (mode == Mode::Normal)326 ruleSet->addPageRule(downcast<StyleRulePage>(*rule));327 continue;328 }329 if (is<StyleRuleMedia>(*rule)) {330 auto& mediaRule = downcast<StyleRuleMedia>(*rule);331 if (mediaQueryCollector.pushAndEvaluate(&mediaRule.mediaQueries()))332 addChildRules(mediaRule.childRules());333 mediaQueryCollector.pop(&mediaRule.mediaQueries());334 continue;335 }336 if (is<StyleRuleLayer>(*rule)) {337 auto& layerRule = downcast<StyleRuleLayer>(*rule);338 if (layerRule.isStatement()) {339 // Statement syntax just registers the layers.340 registerLayers(layerRule.nameList());341 continue;342 }343 // Block syntax.344 pushCascadeLayer(layerRule.name());345 addChildRules(layerRule.childRules());346 popCascadeLayer(layerRule.name());347 continue;348 }349 if (is<StyleRuleFontFace>(*rule) || is<StyleRuleFontPaletteValues>(*rule) || is<StyleRuleKeyframes>(*rule)) {350 if (mode == Mode::ResolverMutationScan) {351 mediaQueryCollector.didMutateResolver();352 continue;353 }354 if (resolver)355 collectedResolverMutatingRules.append({ *rule, currentCascadeLayerIdentifier });356 continue;357 }358 if (is<StyleRuleSupports>(*rule) && downcast<StyleRuleSupports>(*rule).conditionIsSupported()) {359 addChildRules(downcast<StyleRuleSupports>(*rule).childRules());360 continue;361 }362 }363 }364 365 void RuleSet::Builder::addRulesFromSheet(const StyleSheetContents& sheet)366 {367 for (auto& rule : sheet.layerRulesBeforeImportRules())368 registerLayers(rule->nameList());369 370 for (auto& rule : sheet.importRules()) {371 if (!rule->styleSheet())372 continue;373 374 if (mediaQueryCollector.pushAndEvaluate(rule->mediaQueries())) {375 auto& cascadeLayerName = rule->cascadeLayerName();376 if (cascadeLayerName)377 pushCascadeLayer(*cascadeLayerName);378 379 addRulesFromSheet(*rule->styleSheet());380 381 if (cascadeLayerName)382 popCascadeLayer(*cascadeLayerName);383 }384 mediaQueryCollector.pop(rule->mediaQueries());385 }386 387 addChildRules(sheet.childRules());388 }389 390 RuleSet::Builder::~Builder()391 {392 if (mode == Mode::ResolverMutationScan)393 return;394 395 updateCascadeLayerOrder();396 addMutatingRulesToResolver();397 }398 399 void RuleSet::Builder::addStyleRule(const StyleRule& rule)400 {401 auto& selectorList = rule.selectorList();402 if (selectorList.isEmpty())403 return;404 unsigned selectorListIndex = 0;405 for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex))406 ruleSet->addRule(rule, selectorIndex, selectorListIndex++, currentCascadeLayerIdentifier, &mediaQueryCollector);407 }408 409 void RuleSet::Builder::registerLayers(const Vector<CascadeLayerName>& names)410 {411 for (auto& name : names) {412 pushCascadeLayer(name);413 popCascadeLayer(name);414 }415 }416 417 void RuleSet::Builder::pushCascadeLayer(const CascadeLayerName& name)418 {419 if (mode != Mode::Normal)420 return;421 422 if (cascadeLayerIdentifierMap.isEmpty() && !ruleSet->m_cascadeLayers.isEmpty()) {423 // For incremental build, reconstruct the name->identifier map.424 CascadeLayerIdentifier identifier = 0;425 for (auto& layer : ruleSet->m_cascadeLayers)426 cascadeLayerIdentifierMap.add(layer.resolvedName, ++identifier);427 }428 429 auto nameResolvingAnonymous = [&] {430 if (name.isEmpty()) {431 // Make unique name for an anonymous layer.432 unsigned long long random = randomNumber() * std::numeric_limits<unsigned long long>::max();433 return CascadeLayerName { "anon_"_s + String::number(random) };434 }435 return name;436 };437 438 // For hierarchical names we register the containing layers individually first.439 for (auto& nameSegment : nameResolvingAnonymous()) {440 resolvedCascadeLayerName.append(nameSegment);441 currentCascadeLayerIdentifier = cascadeLayerIdentifierMap.ensure(resolvedCascadeLayerName, [&] {442 // Previously unseen layer.443 ruleSet->m_cascadeLayers.append({ resolvedCascadeLayerName, currentCascadeLayerIdentifier });444 return ruleSet->m_cascadeLayers.size();445 }).iterator->value;446 }447 }448 449 void RuleSet::Builder::popCascadeLayer(const CascadeLayerName& name)450 {451 if (mode != Mode::Normal)452 return;453 454 for (auto size = name.isEmpty() ? 1 : name.size(); size--;) {455 resolvedCascadeLayerName.removeLast();456 currentCascadeLayerIdentifier = ruleSet->cascadeLayerForIdentifier(currentCascadeLayerIdentifier).parentIdentifier;457 }458 }459 460 void RuleSet::Builder::updateCascadeLayerOrder()461 {462 if (cascadeLayerIdentifierMap.isEmpty())463 return;464 465 auto compare = [&](CascadeLayerIdentifier a, CascadeLayerIdentifier b) {466 while (a && b) {467 // Identifiers are in parse order which almost corresponds to the layer priority order.468 // The only exception is when a sublayer gets added to a layer after adding other non-sublayers.469 // To resolve this we need look for a shared ancestor layer.470 auto aParent = ruleSet->cascadeLayerForIdentifier(a).parentIdentifier;471 auto bParent = ruleSet->cascadeLayerForIdentifier(b).parentIdentifier;472 if (aParent == bParent || aParent == b || bParent == a)473 break;474 if (aParent > bParent)475 a = aParent;476 else477 b = bParent;478 }479 return a < b;480 };481 482 Vector<CascadeLayerIdentifier> orderVector;483 auto layerCount = ruleSet->m_cascadeLayers.size();484 orderVector.reserveInitialCapacity(layerCount);485 for (CascadeLayerIdentifier identifier = 1; identifier <= layerCount; ++identifier)486 orderVector.uncheckedAppend(identifier);487 488 std::sort(orderVector.begin(), orderVector.end(), compare);489 490 for (unsigned i = 0; i < orderVector.size(); ++i)491 ruleSet->cascadeLayerForIdentifier(orderVector[i]).order = i + 1;492 }493 494 void RuleSet::Builder::addMutatingRulesToResolver()495 {496 if (!resolver)497 return;498 499 auto compareLayers = [&](const ResolverMutatingRule& a, const ResolverMutatingRule& b) {500 auto aOrder = ruleSet->cascadeLayerOrderForIdentifier(a.layerIdentifier);501 auto bOrder = ruleSet->cascadeLayerOrderForIdentifier(b.layerIdentifier);502 return aOrder < bOrder;503 };504 505 // The order may change so we need to reprocess resolver mutating rules from earlier stylesheets.506 auto rulesToAdd = std::exchange(ruleSet->m_resolverMutatingRulesInLayers, { });507 rulesToAdd.appendVector(WTFMove(collectedResolverMutatingRules));508 509 if (!cascadeLayerIdentifierMap.isEmpty())510 std::stable_sort(rulesToAdd.begin(), rulesToAdd.end(), compareLayers);511 512 for (auto& collectedRule : rulesToAdd) {513 if (collectedRule.layerIdentifier)514 ruleSet->m_resolverMutatingRulesInLayers.append(collectedRule);515 516 auto& rule = collectedRule.rule;517 if (is<StyleRuleFontFace>(rule)) {518 resolver->document().fontSelector().addFontFaceRule(downcast<StyleRuleFontFace>(rule.get()), false);519 resolver->invalidateMatchedDeclarationsCache();520 continue;521 }522 if (is<StyleRuleFontPaletteValues>(rule)) {523 resolver->document().fontSelector().addFontPaletteValuesRule(downcast<StyleRuleFontPaletteValues>(rule.get()));524 resolver->invalidateMatchedDeclarationsCache();525 continue;526 }527 if (is<StyleRuleKeyframes>(rule)) {528 resolver->addKeyframeStyle(downcast<StyleRuleKeyframes>(rule.get()));529 continue;530 }531 }532 312 } 533 313 … … 671 451 } 672 452 673 RuleSet::MediaQueryCollector::~MediaQueryCollector() = default;674 675 bool RuleSet::MediaQueryCollector::pushAndEvaluate(const MediaQuerySet* set)676 {677 if (!set)678 return true;679 680 // Only evaluate static expressions that require style rebuild.681 MediaQueryDynamicResults dynamicResults;682 auto mode = collectDynamic ? MediaQueryEvaluator::Mode::AlwaysMatchDynamic : MediaQueryEvaluator::Mode::Normal;683 684 bool result = evaluator.evaluate(*set, &dynamicResults, mode);685 686 if (!dynamicResults.viewport.isEmpty())687 hasViewportDependentMediaQueries = true;688 689 if (!dynamicResults.isEmpty())690 dynamicContextStack.append({ *set });691 692 return result;693 }694 695 void RuleSet::MediaQueryCollector::pop(const MediaQuerySet* set)696 {697 if (!set || dynamicContextStack.isEmpty() || set != &dynamicContextStack.last().set.get())698 return;699 700 if (!dynamicContextStack.last().affectedRulePositions.isEmpty() || !collectDynamic) {701 DynamicMediaQueryRules rules;702 for (auto& context : dynamicContextStack)703 rules.mediaQuerySets.append(context.set.get());704 705 if (collectDynamic) {706 rules.affectedRulePositions.appendVector(dynamicContextStack.last().affectedRulePositions);707 rules.ruleFeatures = WTFMove(dynamicContextStack.last().ruleFeatures);708 rules.ruleFeatures.shrinkToFit();709 } else710 rules.requiresFullReset = true;711 712 dynamicMediaQueryRules.append(WTFMove(rules));713 }714 715 dynamicContextStack.removeLast();716 }717 718 void RuleSet::MediaQueryCollector::didMutateResolver()719 {720 if (dynamicContextStack.isEmpty())721 return;722 didMutateResolverWithinDynamicMediaQuery = true;723 }724 725 void RuleSet::MediaQueryCollector::addRuleIfNeeded(const RuleData& ruleData)726 {727 if (dynamicContextStack.isEmpty())728 return;729 730 auto& context = dynamicContextStack.last();731 context.affectedRulePositions.append(ruleData.position());732 context.ruleFeatures.append({ ruleData });733 }734 735 453 } // namespace Style 736 454 } // namespace WebCore -
trunk/Source/WebCore/style/RuleSet.h
r283216 r283488 1 1 /* 2 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 * Copyright (C) 2003-20 19Apple Inc. All rights reserved.3 * Copyright (C) 2003-2021 Apple Inc. All rights reserved. 4 4 * 5 5 * This library is free software; you can redistribute it and/or … … 43 43 class Resolver; 44 44 class RuleSet; 45 struct RuleSetMediaQueryCollector; 45 46 46 47 using InvalidationRuleSetVector = Vector<RefPtr<const RuleSet>, 1>; … … 86 87 }; 87 88 88 struct MediaQueryCollector {89 ~MediaQueryCollector();90 91 const MediaQueryEvaluator& evaluator;92 const bool collectDynamic { false };93 94 struct DynamicContext {95 Ref<const MediaQuerySet> set;96 Vector<size_t> affectedRulePositions { };97 RuleFeatureVector ruleFeatures { };98 };99 Vector<DynamicContext> dynamicContextStack { };100 101 Vector<DynamicMediaQueryRules> dynamicMediaQueryRules { };102 bool didMutateResolverWithinDynamicMediaQuery { false };103 bool hasViewportDependentMediaQueries { false };104 105 bool pushAndEvaluate(const MediaQuerySet*);106 void pop(const MediaQuerySet*);107 void didMutateResolver();108 void addRuleIfNeeded(const RuleData&);109 };110 111 89 void addRulesFromSheet(const StyleSheetContents&, const MediaQueryEvaluator&); 112 90 void addRulesFromSheet(const StyleSheetContents&, const MediaQuerySet* sheetQuery, const MediaQueryEvaluator&, Style::Resolver&); 113 91 114 void addRule(const StyleRule&, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayerOrder = 0, MediaQueryCollector* = nullptr);92 void addRule(const StyleRule&, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayerOrder = 0, RuleSetMediaQueryCollector* = nullptr); 115 93 void addPageRule(StyleRulePage&); 116 94 … … 149 127 150 128 private: 129 friend struct RuleSetBuilder; 130 151 131 RuleSet(); 152 132 … … 156 136 Ref<StyleRuleBase> rule; 157 137 CascadeLayerIdentifier layerIdentifier; 158 };159 160 struct Builder {161 enum class Mode { Normal, ResolverMutationScan };162 163 Ref<RuleSet> ruleSet;164 MediaQueryCollector mediaQueryCollector;165 Style::Resolver* resolver { nullptr };166 Mode mode { Mode::Normal };167 CascadeLayerName resolvedCascadeLayerName { };168 HashMap<CascadeLayerName, CascadeLayerIdentifier> cascadeLayerIdentifierMap { };169 CascadeLayerIdentifier currentCascadeLayerIdentifier { 0 };170 Vector<ResolverMutatingRule> collectedResolverMutatingRules { };171 172 void addRulesFromSheet(const StyleSheetContents&);173 174 ~Builder();175 176 private:177 void addChildRules(const Vector<RefPtr<StyleRuleBase>>&);178 void addStyleRule(const StyleRule&);179 180 void registerLayers(const Vector<CascadeLayerName>&);181 void pushCascadeLayer(const CascadeLayerName&);182 void popCascadeLayer(const CascadeLayerName&);183 void updateCascadeLayerOrder();184 void addMutatingRulesToResolver();185 138 }; 186 139
Note:
See TracChangeset
for help on using the changeset viewer.