Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/css/parser/CSSParserImpl.h" | 5 #include "core/css/parser/CSSParserImpl.h" |
| 6 | 6 |
| 7 #include "core/css/CSSCustomPropertyDeclaration.h" | 7 #include "core/css/CSSCustomPropertyDeclaration.h" |
| 8 #include "core/css/CSSKeyframesRule.h" | 8 #include "core/css/CSSKeyframesRule.h" |
| 9 #include "core/css/CSSStyleSheet.h" | 9 #include "core/css/CSSStyleSheet.h" |
| 10 #include "core/css/StylePropertySet.h" | 10 #include "core/css/StylePropertySet.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 bool CSSParserImpl::parseVariableValue(MutableStylePropertySet* declaration, con st AtomicString& propertyName, const String& value, bool important, const CSSPar serContext& context) | 54 bool CSSParserImpl::parseVariableValue(MutableStylePropertySet* declaration, con st AtomicString& propertyName, const String& value, bool important, const CSSPar serContext& context) |
| 55 { | 55 { |
| 56 CSSParserImpl parser(context); | 56 CSSParserImpl parser(context); |
| 57 CSSTokenizer::Scope scope(value); | 57 CSSTokenizer::Scope scope(value); |
| 58 parser.consumeVariableValue(scope.tokenRange(), propertyName, important); | 58 parser.consumeVariableValue(scope.tokenRange(), propertyName, important); |
| 59 if (parser.m_parsedProperties.isEmpty()) | 59 if (parser.m_parsedProperties.isEmpty()) |
| 60 return false; | 60 return false; |
| 61 return declaration->addParsedProperties(parser.m_parsedProperties); | 61 return declaration->addParsedProperties(parser.m_parsedProperties); |
| 62 } | 62 } |
| 63 | 63 |
| 64 static inline void filterProperties(bool important, const WillBeHeapVector<CSSPr operty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedE ntries, BitArray<numCSSProperties>& seenProperties) | 64 static inline void filterProperties(bool important, const WillBeHeapVector<CSSPr operty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedE ntries, BitArray<numCSSProperties>& seenProperties, HashSet<AtomicString>& seenC ustomProperties) |
| 65 { | 65 { |
| 66 // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found. | 66 // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found. |
| 67 for (size_t i = input.size(); i--; ) { | 67 for (size_t i = input.size(); i--; ) { |
| 68 const CSSProperty& property = input[i]; | 68 const CSSProperty& property = input[i]; |
| 69 if (property.isImportant() != important) | 69 if (property.isImportant() != important) |
| 70 continue; | 70 continue; |
| 71 const unsigned propertyIDIndex = property.id() - firstCSSProperty; | 71 const unsigned propertyIDIndex = property.id() - firstCSSProperty; |
| 72 // All custom properties use the same CSSPropertyID so we can't remove r epeated definitions | 72 |
| 73 if (property.id() != CSSPropertyVariable) { | 73 if (property.id() != CSSPropertyVariable) { |
|
Timothy Loh
2016/02/18 01:19:32
uhhh... I think it's better to negate this conditi
shans
2016/02/18 04:28:59
Done.
| |
| 74 if (seenProperties.get(propertyIDIndex)) | 74 if (seenProperties.get(propertyIDIndex)) |
| 75 continue; | 75 continue; |
| 76 seenProperties.set(propertyIDIndex); | 76 seenProperties.set(propertyIDIndex); |
| 77 } else { | |
| 78 const AtomicString& name = toCSSCustomPropertyDeclaration(property.v alue())->name(); | |
| 79 if (seenCustomProperties.contains(name)) | |
| 80 continue; | |
| 81 seenCustomProperties.add(name); | |
| 77 } | 82 } |
| 78 output[--unusedEntries] = property; | 83 output[--unusedEntries] = property; |
| 79 } | 84 } |
| 80 } | 85 } |
| 81 | 86 |
| 82 static PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> createStylePropertySet( WillBeHeapVector<CSSProperty, 256>& parsedProperties, CSSParserMode mode) | 87 static PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> createStylePropertySet( WillBeHeapVector<CSSProperty, 256>& parsedProperties, CSSParserMode mode) |
| 83 { | 88 { |
| 84 BitArray<numCSSProperties> seenProperties; | 89 BitArray<numCSSProperties> seenProperties; |
| 85 size_t unusedEntries = parsedProperties.size(); | 90 size_t unusedEntries = parsedProperties.size(); |
| 86 WillBeHeapVector<CSSProperty, 256> results(unusedEntries); | 91 WillBeHeapVector<CSSProperty, 256> results(unusedEntries); |
| 92 HashSet<AtomicString> seenCustomProperties; | |
| 87 | 93 |
| 88 filterProperties(true, parsedProperties, results, unusedEntries, seenPropert ies); | 94 filterProperties(true, parsedProperties, results, unusedEntries, seenPropert ies, seenCustomProperties); |
| 89 filterProperties(false, parsedProperties, results, unusedEntries, seenProper ties); | 95 filterProperties(false, parsedProperties, results, unusedEntries, seenProper ties, seenCustomProperties); |
| 90 | 96 |
| 91 RefPtrWillBeRawPtr<ImmutableStylePropertySet> result = ImmutableStylePropert ySet::create(results.data() + unusedEntries, results.size() - unusedEntries, mod e); | 97 RefPtrWillBeRawPtr<ImmutableStylePropertySet> result = ImmutableStylePropert ySet::create(results.data() + unusedEntries, results.size() - unusedEntries, mod e); |
| 92 parsedProperties.clear(); | 98 parsedProperties.clear(); |
| 93 return result.release(); | 99 return result.release(); |
| 94 } | 100 } |
| 95 | 101 |
| 96 PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> CSSParserImpl::parseInlineStyl eDeclaration(const String& string, Element* element) | 102 PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> CSSParserImpl::parseInlineStyl eDeclaration(const String& string, Element* element) |
| 97 { | 103 { |
| 98 Document& document = element->document(); | 104 Document& document = element->document(); |
| 99 CSSParserContext context = CSSParserContext(document.elementSheet().contents ()->parserContext(), UseCounter::getFrom(&document)); | 105 CSSParserContext context = CSSParserContext(document.elementSheet().contents ()->parserContext(), UseCounter::getFrom(&document)); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 112 if (declaration->cssParserMode() == CSSViewportRuleMode) | 118 if (declaration->cssParserMode() == CSSViewportRuleMode) |
| 113 ruleType = StyleRule::Viewport; | 119 ruleType = StyleRule::Viewport; |
| 114 CSSTokenizer::Scope scope(string); | 120 CSSTokenizer::Scope scope(string); |
| 115 parser.consumeDeclarationList(scope.tokenRange(), ruleType); | 121 parser.consumeDeclarationList(scope.tokenRange(), ruleType); |
| 116 if (parser.m_parsedProperties.isEmpty()) | 122 if (parser.m_parsedProperties.isEmpty()) |
| 117 return false; | 123 return false; |
| 118 | 124 |
| 119 BitArray<numCSSProperties> seenProperties; | 125 BitArray<numCSSProperties> seenProperties; |
| 120 size_t unusedEntries = parser.m_parsedProperties.size(); | 126 size_t unusedEntries = parser.m_parsedProperties.size(); |
| 121 WillBeHeapVector<CSSProperty, 256> results(unusedEntries); | 127 WillBeHeapVector<CSSProperty, 256> results(unusedEntries); |
| 122 filterProperties(true, parser.m_parsedProperties, results, unusedEntries, se enProperties); | 128 HashSet<AtomicString> seenCustomProperties; |
| 123 filterProperties(false, parser.m_parsedProperties, results, unusedEntries, s eenProperties); | 129 filterProperties(true, parser.m_parsedProperties, results, unusedEntries, se enProperties, seenCustomProperties); |
| 130 filterProperties(false, parser.m_parsedProperties, results, unusedEntries, s eenProperties, seenCustomProperties); | |
| 124 if (unusedEntries) | 131 if (unusedEntries) |
| 125 results.remove(0, unusedEntries); | 132 results.remove(0, unusedEntries); |
| 126 return declaration->addParsedProperties(results); | 133 return declaration->addParsedProperties(results); |
| 127 } | 134 } |
| 128 | 135 |
| 129 PassRefPtrWillBeRawPtr<StyleRuleBase> CSSParserImpl::parseRule(const String& str ing, const CSSParserContext& context, StyleSheetContents* styleSheet, AllowedRul esType allowedRules) | 136 PassRefPtrWillBeRawPtr<StyleRuleBase> CSSParserImpl::parseRule(const String& str ing, const CSSParserContext& context, StyleSheetContents* styleSheet, AllowedRul esType allowedRules) |
| 130 { | 137 { |
| 131 CSSParserImpl parser(context, styleSheet); | 138 CSSParserImpl parser(context, styleSheet); |
| 132 CSSTokenizer::Scope scope(string); | 139 CSSTokenizer::Scope scope(string); |
| 133 CSSParserTokenRange range = scope.tokenRange(); | 140 CSSParserTokenRange range = scope.tokenRange(); |
| (...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 768 else | 775 else |
| 769 return nullptr; // Parser error, invalid value in keyframe selector | 776 return nullptr; // Parser error, invalid value in keyframe selector |
| 770 if (range.atEnd()) | 777 if (range.atEnd()) |
| 771 return result.release(); | 778 return result.release(); |
| 772 if (range.consume().type() != CommaToken) | 779 if (range.consume().type() != CommaToken) |
| 773 return nullptr; // Parser error | 780 return nullptr; // Parser error |
| 774 } | 781 } |
| 775 } | 782 } |
| 776 | 783 |
| 777 } // namespace blink | 784 } // namespace blink |
| OLD | NEW |