diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp | 224 |
1 files changed, 0 insertions, 224 deletions
diff --git a/chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp b/chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp deleted file mode 100644 index 557f0438a56..00000000000 --- a/chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) - * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) - * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. - * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> - * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> - * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) - * Copyright (c) 2011, Code Aurora Forum. All rights reserved. - * Copyright (C) Research In Motion Limited 2011. All rights reserved. - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "core/css/SelectorCheckerFastPath.h" - -#include "HTMLNames.h" -#include "core/dom/Element.h" -#include "core/html/HTMLDocument.h" - -namespace WebCore { - -using namespace HTMLNames; - -namespace { - -template <bool checkValue(const Element&, const CSSSelector*)> -inline bool fastCheckSingleSelector(const CSSSelector*& selector, const Element*& element, const CSSSelector*& topChildOrSubselector, const Element*& topChildOrSubselectorMatchElement) -{ - for (; element; element = element->parentElement()) { - if (checkValue(*element, selector)) { - if (selector->relation() == CSSSelector::Descendant) - topChildOrSubselector = 0; - else if (!topChildOrSubselector) { - ASSERT(selector->relation() == CSSSelector::Child || selector->relation() == CSSSelector::SubSelector); - topChildOrSubselector = selector; - topChildOrSubselectorMatchElement = element; - } - if (selector->relation() != CSSSelector::SubSelector) - element = element->parentElement(); - selector = selector->tagHistory(); - return true; - } - if (topChildOrSubselector) { - // Child or subselector check failed. - // If the match element is null, topChildOrSubselector was also the very topmost selector and had to match - // the original element we were checking. - if (!topChildOrSubselectorMatchElement) - return false; - // There may be other matches down the ancestor chain. - // Rewind to the topmost child or subselector and the element it matched, continue checking ancestors. - selector = topChildOrSubselector; - element = topChildOrSubselectorMatchElement->parentElement(); - topChildOrSubselector = 0; - return true; - } - } - return false; -} - -inline bool checkClassValue(const Element& element, const CSSSelector* selector) -{ - return element.hasClass() && element.classNames().contains(selector->value()); -} - -inline bool checkIDValue(const Element& element, const CSSSelector* selector) -{ - return element.hasID() && element.idForStyleResolution() == selector->value(); -} - -inline bool checkExactAttributeValue(const Element& element, const CSSSelector* selector) -{ - return SelectorChecker::checkExactAttribute(element, selector->attribute(), selector->value().impl()); -} - -inline bool checkTagValue(const Element& element, const CSSSelector* selector) -{ - return SelectorChecker::tagMatches(element, selector->tagQName()); -} - -} - -SelectorCheckerFastPath::SelectorCheckerFastPath(const CSSSelector* selector, const Element& element) - : m_selector(selector) - , m_element(element) -{ -} - -bool SelectorCheckerFastPath::matchesRightmostSelector(SelectorChecker::VisitedMatchType visitedMatchType) const -{ - ASSERT(SelectorCheckerFastPath::canUse(m_selector)); - - switch (m_selector->m_match) { - case CSSSelector::Tag: - return checkTagValue(m_element, m_selector); - case CSSSelector::Class: - return checkClassValue(m_element, m_selector); - case CSSSelector::Id: - return checkIDValue(m_element, m_selector); - case CSSSelector::Exact: - case CSSSelector::Set: - return checkExactAttributeValue(m_element, m_selector); - case CSSSelector::PseudoClass: - return commonPseudoClassSelectorMatches(visitedMatchType); - default: - ASSERT_NOT_REACHED(); - } - return false; -} - -bool SelectorCheckerFastPath::matches() const -{ - ASSERT(matchesRightmostSelector(SelectorChecker::VisitedMatchEnabled)); - const CSSSelector* selector = m_selector; - const Element* element = &m_element; - - const CSSSelector* topChildOrSubselector = 0; - const Element* topChildOrSubselectorMatchElement = 0; - if (selector->relation() == CSSSelector::Child || selector->relation() == CSSSelector::SubSelector) - topChildOrSubselector = selector; - - if (selector->relation() != CSSSelector::SubSelector) - element = element->parentElement(); - - selector = selector->tagHistory(); - - // We know this compound selector has descendant, child and subselector combinators only and all components are simple. - while (selector) { - switch (selector->m_match) { - case CSSSelector::Class: - if (!fastCheckSingleSelector<checkClassValue>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement)) - return false; - break; - case CSSSelector::Id: - if (!fastCheckSingleSelector<checkIDValue>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement)) - return false; - break; - case CSSSelector::Tag: - if (!fastCheckSingleSelector<checkTagValue>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement)) - return false; - break; - case CSSSelector::Set: - case CSSSelector::Exact: - if (!fastCheckSingleSelector<checkExactAttributeValue>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement)) - return false; - break; - default: - ASSERT_NOT_REACHED(); - } - } - return true; -} - -static inline bool isFastCheckableRelation(CSSSelector::Relation relation) -{ - return relation == CSSSelector::Descendant || relation == CSSSelector::Child || relation == CSSSelector::SubSelector; -} - -static inline bool isFastCheckableMatch(const CSSSelector* selector) -{ - if (selector->m_match == CSSSelector::Set) { - // Style attribute is generated lazily but the fast path doesn't trigger it. - // Disallow them here rather than making the fast path more branchy. - return selector->attribute() != styleAttr; - } - if (selector->m_match == CSSSelector::Exact) - return selector->attribute() != styleAttr && HTMLDocument::isCaseSensitiveAttribute(selector->attribute()); - return selector->m_match == CSSSelector::Tag || selector->m_match == CSSSelector::Id || selector->m_match == CSSSelector::Class; -} - -static inline bool isFastCheckableRightmostSelector(const CSSSelector* selector) -{ - if (!isFastCheckableRelation(selector->relation())) - return false; - return isFastCheckableMatch(selector) || SelectorChecker::isCommonPseudoClassSelector(selector); -} - -bool SelectorCheckerFastPath::canUse(const CSSSelector* selector) -{ - if (!isFastCheckableRightmostSelector(selector)) - return false; - for (selector = selector->tagHistory(); selector; selector = selector->tagHistory()) { - if (!isFastCheckableRelation(selector->relation())) - return false; - if (!isFastCheckableMatch(selector)) - return false; - } - return true; -} - -bool SelectorCheckerFastPath::commonPseudoClassSelectorMatches(SelectorChecker::VisitedMatchType visitedMatchType) const -{ - ASSERT(SelectorChecker::isCommonPseudoClassSelector(m_selector)); - switch (m_selector->pseudoType()) { - case CSSSelector::PseudoLink: - case CSSSelector::PseudoAnyLink: - return m_element.isLink(); - case CSSSelector::PseudoVisited: - return m_element.isLink() && visitedMatchType == SelectorChecker::VisitedMatchEnabled; - case CSSSelector::PseudoFocus: - return SelectorChecker::matchesFocusPseudoClass(m_element); - default: - ASSERT_NOT_REACHED(); - } - return true; -} - - -} |