Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: sky/engine/core/css/SelectorChecker.cpp

Issue 840163003: Make SelectorChecker a const operation over element. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/engine/core/css/SelectorChecker.h ('k') | sky/engine/core/dom/Element.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
(...skipping 21 matching lines...) Expand all
32 #include "sky/engine/core/dom/Document.h" 32 #include "sky/engine/core/dom/Document.h"
33 #include "sky/engine/core/dom/shadow/ShadowRoot.h" 33 #include "sky/engine/core/dom/shadow/ShadowRoot.h"
34 #include "sky/engine/core/editing/FrameSelection.h" 34 #include "sky/engine/core/editing/FrameSelection.h"
35 #include "sky/engine/core/frame/LocalFrame.h" 35 #include "sky/engine/core/frame/LocalFrame.h"
36 #include "sky/engine/core/html/parser/HTMLParserIdioms.h" 36 #include "sky/engine/core/html/parser/HTMLParserIdioms.h"
37 #include "sky/engine/core/page/FocusController.h" 37 #include "sky/engine/core/page/FocusController.h"
38 #include "sky/engine/core/rendering/style/RenderStyle.h" 38 #include "sky/engine/core/rendering/style/RenderStyle.h"
39 39
40 namespace blink { 40 namespace blink {
41 41
42 SelectorChecker::SelectorChecker(Document& document, Mode mode) 42 SelectorChecker::SelectorChecker()
43 : m_mode(mode) 43 : m_matchedAttributeSelector(false)
44 , m_matchedFocusSelector(false)
45 , m_matchedHoverSelector(false)
46 , m_matchedActiveSelector(false)
44 { 47 {
45 } 48 }
46 49
47 static bool scopeContainsLastMatchedElement(const SelectorChecker::SelectorCheck ingContext& context) 50 static bool scopeContainsLastMatchedElement(const SelectorChecker::SelectorCheck ingContext& context)
48 { 51 {
49 if (!context.scope) 52 if (!context.scope)
50 return true; 53 return true;
51 54
52 ASSERT(context.scope); 55 ASSERT(context.scope);
53 if (context.scope->treeScope() == context.element->treeScope()) 56 if (context.scope->treeScope() == context.element->treeScope())
54 return true; 57 return true;
55 58
56 // Because Blink treats a shadow host's TreeScope as a separate one from its descendent shadow roots, 59 // Because Blink treats a shadow host's TreeScope as a separate one from its descendent shadow roots,
57 // if the last matched element is a shadow host, the condition above isn't m et, even though it 60 // if the last matched element is a shadow host, the condition above isn't m et, even though it
58 // should be. 61 // should be.
59 return context.element == context.scope->shadowHost(); 62 return context.element == context.scope->shadowHost();
60 } 63 }
61 64
62 bool SelectorChecker::match(const SelectorCheckingContext& context) const 65 bool SelectorChecker::match(const SelectorCheckingContext& context)
63 { 66 {
64 // FIXME(sky): Get rid of SelectorCheckingContext. 67 // FIXME(sky): Get rid of SelectorCheckingContext.
65 SelectorCheckingContext matchContext(context); 68 SelectorCheckingContext matchContext(context);
66 69
67 bool isShadowHost = isHostInItsShadowTree(*context.element, context.scope); 70 bool isShadowHost = isHostInItsShadowTree(*context.element, context.scope);
68 71
69 while (true) { 72 while (true) {
70 const CSSSelector& selector = *matchContext.selector; 73 const CSSSelector& selector = *matchContext.selector;
71 // Only :host and :host-context() should match the host: 74 // Only :host and :host-context() should match the host:
72 // http://drafts.csswg.org/css-scoping/#host-element 75 // http://drafts.csswg.org/css-scoping/#host-element
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 if (value.length() != selectorValue.length() && value[selectorValue.leng th()] != '-') 156 if (value.length() != selectorValue.length() && value[selectorValue.leng th()] != '-')
154 return false; 157 return false;
155 break; 158 break;
156 default: 159 default:
157 break; 160 break;
158 } 161 }
159 162
160 return true; 163 return true;
161 } 164 }
162 165
163 static bool anyAttributeMatches(Element& element, CSSSelector::Match match, cons t CSSSelector& selector) 166 static bool anyAttributeMatches(const Element& element, CSSSelector::Match match , const CSSSelector& selector)
164 { 167 {
165 const QualifiedName& selectorAttr = selector.attribute(); 168 const QualifiedName& selectorAttr = selector.attribute();
166 ASSERT(selectorAttr.localName() != starAtom); // Should not be possible from the CSS grammar. 169 ASSERT(selectorAttr.localName() != starAtom); // Should not be possible from the CSS grammar.
167 170
168 // Synchronize the attribute in case it is lazy-computed. 171 // Synchronize the attribute in case it is lazy-computed.
169 element.synchronizeAttribute(selectorAttr.localName()); 172 element.synchronizeAttribute(selectorAttr.localName());
170 173
171 const AtomicString& selectorValue = selector.value(); 174 const AtomicString& selectorValue = selector.value();
172 bool caseInsensitive = selector.attributeMatchType() == CSSSelector::CaseIns ensitive; 175 bool caseInsensitive = selector.attributeMatchType() == CSSSelector::CaseIns ensitive;
173 176
174 AttributeCollection attributes = element.attributesWithoutUpdate(); 177 AttributeCollection attributes = element.attributesWithoutUpdate();
175 AttributeCollection::iterator end = attributes.end(); 178 AttributeCollection::iterator end = attributes.end();
176 for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) { 179 for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
177 const Attribute& attributeItem = *it; 180 const Attribute& attributeItem = *it;
178 181
179 if (!attributeItem.matches(selectorAttr)) 182 if (!attributeItem.matches(selectorAttr))
180 continue; 183 continue;
181 184
182 if (attributeValueMatches(attributeItem, match, selectorValue, !caseInse nsitive)) 185 if (attributeValueMatches(attributeItem, match, selectorValue, !caseInse nsitive))
183 return true; 186 return true;
184 } 187 }
185 188
186 return false; 189 return false;
187 } 190 }
188 191
189 bool SelectorChecker::checkOne(const SelectorCheckingContext& context) const 192 bool SelectorChecker::checkOne(const SelectorCheckingContext& context)
190 { 193 {
191 ASSERT(context.element); 194 ASSERT(context.element);
192 Element& element = *context.element; 195 const Element& element = *context.element;
193 ASSERT(context.selector); 196 ASSERT(context.selector);
194 const CSSSelector& selector = *context.selector; 197 const CSSSelector& selector = *context.selector;
195 198
196 switch (selector.match()) { 199 switch (selector.match()) {
197 case CSSSelector::Tag: 200 case CSSSelector::Tag:
198 return tagMatches(element, selector.tagQName()); 201 return tagMatches(element, selector.tagQName());
199 case CSSSelector::Class: 202 case CSSSelector::Class:
200 return element.hasClass() && element.classNames().contains(selector.valu e()); 203 return element.hasClass() && element.classNames().contains(selector.valu e());
201 case CSSSelector::Id: 204 case CSSSelector::Id:
202 return element.hasID() && element.idForStyleResolution() == selector.val ue(); 205 return element.hasID() && element.idForStyleResolution() == selector.val ue();
203 case CSSSelector::Exact: 206 case CSSSelector::Exact:
204 case CSSSelector::Set: 207 case CSSSelector::Set:
205 case CSSSelector::Hyphen: 208 case CSSSelector::Hyphen:
206 case CSSSelector::List: 209 case CSSSelector::List:
207 case CSSSelector::Contain: 210 case CSSSelector::Contain:
208 case CSSSelector::Begin: 211 case CSSSelector::Begin:
209 case CSSSelector::End: 212 case CSSSelector::End:
210 if (anyAttributeMatches(element, selector.match(), selector)) { 213 if (anyAttributeMatches(element, selector.match(), selector)) {
211 if (m_mode == ResolvingStyle && context.elementStyle) 214 m_matchedAttributeSelector = true;
212 context.elementStyle->setUnique();
213 return true; 215 return true;
214 } 216 }
215 return false; 217 return false;
216 case CSSSelector::PseudoClass: 218 case CSSSelector::PseudoClass:
217 return checkPseudoClass(context); 219 return checkPseudoClass(context);
218 // FIXME(sky): Remove pseudo elements completely. 220 // FIXME(sky): Remove pseudo elements completely.
219 case CSSSelector::PseudoElement: 221 case CSSSelector::PseudoElement:
220 case CSSSelector::Unknown: 222 case CSSSelector::Unknown:
221 return false; 223 return false;
222 } 224 }
223 ASSERT_NOT_REACHED(); 225 ASSERT_NOT_REACHED();
224 return false; 226 return false;
225 } 227 }
226 228
227 bool SelectorChecker::checkPseudoClass(const SelectorCheckingContext& context) c onst 229 bool SelectorChecker::checkPseudoClass(const SelectorCheckingContext& context)
228 { 230 {
229 ASSERT(context.element); 231 ASSERT(context.element);
230 Element& element = *context.element; 232 const Element& element = *context.element;
231 ASSERT(context.selector); 233 ASSERT(context.selector);
232 const CSSSelector& selector = *context.selector; 234 const CSSSelector& selector = *context.selector;
233 ASSERT(selector.match() == CSSSelector::PseudoClass); 235 ASSERT(selector.match() == CSSSelector::PseudoClass);
234 236
235 // Normal element pseudo class checking. 237 // Normal element pseudo class checking.
236 switch (selector.pseudoType()) { 238 switch (selector.pseudoType()) {
237 case CSSSelector::PseudoFocus: 239 case CSSSelector::PseudoFocus:
238 if (m_mode == ResolvingStyle) { 240 m_matchedFocusSelector = true;
239 if (context.elementStyle)
240 context.elementStyle->setAffectedByFocus();
241 }
242 return matchesFocusPseudoClass(element); 241 return matchesFocusPseudoClass(element);
243 242
244 case CSSSelector::PseudoHover: 243 case CSSSelector::PseudoHover:
245 if (m_mode == ResolvingStyle) { 244 m_matchedHoverSelector = true;
246 if (context.elementStyle)
247 context.elementStyle->setAffectedByHover();
248 }
249 return element.hovered(); 245 return element.hovered();
250 246
251 case CSSSelector::PseudoActive: 247 case CSSSelector::PseudoActive:
252 if (m_mode == ResolvingStyle) { 248 m_matchedActiveSelector = true;
253 if (context.elementStyle)
254 context.elementStyle->setAffectedByActive();
255 }
256 return element.active(); 249 return element.active();
257 250
258 case CSSSelector::PseudoLang: 251 case CSSSelector::PseudoLang:
259 { 252 {
260 AtomicString value = element.computeInheritedLanguage(); 253 AtomicString value = element.computeInheritedLanguage();
261 const AtomicString& argument = selector.argument(); 254 const AtomicString& argument = selector.argument();
262 if (value.isEmpty() || !value.startsWith(argument, false)) 255 if (value.isEmpty() || !value.startsWith(argument, false))
263 break; 256 break;
264 if (value.length() != argument.length() && value[argument.length()] != '-') 257 if (value.length() != argument.length() && value[argument.length()] != '-')
265 break; 258 break;
266 return true; 259 return true;
267 } 260 }
268 261
269 case CSSSelector::PseudoUnresolved: 262 case CSSSelector::PseudoUnresolved:
270 return element.isUnresolvedCustomElement(); 263 return element.isUnresolvedCustomElement();
271 264
272 case CSSSelector::PseudoHost: 265 case CSSSelector::PseudoHost:
273 { 266 {
274 if (m_mode == SharingRules)
eseidel1 2015/01/09 02:04:17 Do we care about removal of this early-out?
275 return true;
276 // :host only matches a shadow host when :host is in a shadow tree o f the shadow host. 267 // :host only matches a shadow host when :host is in a shadow tree o f the shadow host.
277 if (!context.scope) 268 if (!context.scope)
278 return false; 269 return false;
279 const ContainerNode* shadowHost = context.scope->shadowHost(); 270 const ContainerNode* shadowHost = context.scope->shadowHost();
280 if (!shadowHost || shadowHost != element) 271 if (!shadowHost || shadowHost != element)
281 return false; 272 return false;
282 ASSERT(element.shadow()); 273 ASSERT(element.shadow());
283 274
284 // For empty parameter case, i.e. just :host or :host(). 275 // For empty parameter case, i.e. just :host or :host().
285 if (!selector.selectorList()) 276 if (!selector.selectorList())
(...skipping 27 matching lines...) Expand all
313 return false; 304 return false;
314 LocalFrame* frame = element.document().frame(); 305 LocalFrame* frame = element.document().frame();
315 if (!frame) 306 if (!frame)
316 return false; 307 return false;
317 if (!frame->selection().isFocusedAndActive()) 308 if (!frame->selection().isFocusedAndActive())
318 return false; 309 return false;
319 return true; 310 return true;
320 } 311 }
321 312
322 } 313 }
OLDNEW
« no previous file with comments | « sky/engine/core/css/SelectorChecker.h ('k') | sky/engine/core/dom/Element.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698