1 /* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "core/dom/shadow/SelectRuleFeatureSet.h" 33 34 #include "core/css/CSSSelector.h" 35 #include "core/css/CSSSelectorList.h" 36 37 #include "wtf/BitVector.h" 38 39 namespace blink { 40 41 void SelectRuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector) 42 { 43 for (const CSSSelector* current = &selector; current; current = current->tagHistory()) { 44 if (invalidationSetForSelector(*current)) 45 continue; 46 47 if (!current->selectorList()) 48 continue; 49 50 for (const CSSSelector* selector = current->selectorList()->first(); selector; selector = CSSSelectorList::next(*selector)) 51 collectFeaturesFromSelector(*selector); 52 } 53 } 54 55 bool SelectRuleFeatureSet::checkSelectorsForClassChange(const SpaceSplitString& changedClasses) const 56 { 57 unsigned changedSize = changedClasses.size(); 58 for (unsigned i = 0; i < changedSize; ++i) { 59 if (hasSelectorForClass(changedClasses[i])) 60 return true; 61 } 62 return false; 63 } 64 65 bool SelectRuleFeatureSet::checkSelectorsForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses) const 66 { 67 if (!oldClasses.size()) 68 return checkSelectorsForClassChange(newClasses); 69 70 // Class vectors tend to be very short. This is faster than using a hash table. 71 BitVector remainingClassBits; 72 remainingClassBits.ensureSize(oldClasses.size()); 73 74 for (unsigned i = 0; i < newClasses.size(); ++i) { 75 bool found = false; 76 for (unsigned j = 0; j < oldClasses.size(); ++j) { 77 if (newClasses[i] == oldClasses[j]) { 78 // Mark each class that is still in the newClasses so we can skip doing 79 // an n^2 search below when looking for removals. We can't break from 80 // this loop early since a class can appear more than once. 81 remainingClassBits.quickSet(j); 82 found = true; 83 } 84 } 85 // Class was added. 86 if (!found) { 87 if (hasSelectorForClass(newClasses[i])) 88 return true; 89 } 90 } 91 92 for (unsigned i = 0; i < oldClasses.size(); ++i) { 93 if (remainingClassBits.quickGet(i)) 94 continue; 95 96 // Class was removed. 97 if (hasSelectorForClass(oldClasses[i])) 98 return true; 99 } 100 return false; 101 } 102 103 } 104 105