Diff
Modified: trunk/LayoutTests/ChangeLog (169568 => 169569)
--- trunk/LayoutTests/ChangeLog 2014-06-03 21:09:07 UTC (rev 169568)
+++ trunk/LayoutTests/ChangeLog 2014-06-03 21:26:50 UTC (rev 169569)
@@ -1,3 +1,15 @@
+2014-06-03 Yusuke Suzuki <utatane....@gmail.com>
+
+ CSS JIT: add support for the "any" pseudo class
+ https://bugs.webkit.org/show_bug.cgi?id=133473
+
+ Reviewed by Benjamin Poulain.
+
+ Add support for the :any pseudo class.
+
+ * fast/selectors/pseudo-class-any-expected.txt: Added.
+ * fast/selectors/pseudo-class-any.html: Added.
+
2014-06-02 Jer Noble <jer.no...@apple.com>
Update PlatformTimeRanges to use MediaTime rather than doubles for time values.
Added: trunk/LayoutTests/fast/selectors/pseudo-class-any-expected.txt (0 => 169569)
--- trunk/LayoutTests/fast/selectors/pseudo-class-any-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/pseudo-class-any-expected.txt 2014-06-03 21:26:50 UTC (rev 169569)
@@ -0,0 +1,41 @@
+The pseudo class :any
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+simple :any selector list matched.
+PASS getComputedStyle(document.getElementById("target1")).backgroundColor is "rgb(1, 2, 3)"
+simple :any selector list matched.
+PASS getComputedStyle(document.getElementById("target2")).backgroundColor is "rgb(1, 2, 3)"
+simple :any selector unmatched.
+PASS getComputedStyle(document.getElementById("target3")).backgroundColor is "rgb(0, 0, 0)"
+multiple :any selector list matched.
+PASS getComputedStyle(document.getElementById("target4")).backgroundColor is "rgb(2, 3, 4)"
+multiple :any selector list matched.
+PASS getComputedStyle(document.getElementById("target5")).backgroundColor is "rgb(2, 3, 4)"
+multiple :any selector list unmatched.
+PASS getComputedStyle(document.getElementById("target6")).backgroundColor is "rgb(0, 0, 0)"
+multiple :any selector list unmatched.
+PASS getComputedStyle(document.getElementById("target7")).backgroundColor is "rgb(0, 0, 0)"
+multiple :any selector list unmatched.
+PASS getComputedStyle(document.getElementById("target8")).backgroundColor is "rgb(0, 0, 0)"
+simple :any selector list including :not matched.
+PASS getComputedStyle(document.getElementById("target9")).backgroundColor is "rgb(3, 4, 5)"
+simple :any selector list including :not matched.
+PASS getComputedStyle(document.getElementById("target10")).backgroundColor is "rgb(3, 4, 5)"
+simple :any selector list including :not matched.
+PASS getComputedStyle(document.getElementById("target11")).backgroundColor is "rgb(3, 4, 5)"
+simple :any selector list including :not unmatched.
+PASS getComputedStyle(document.getElementById("target12")).backgroundColor is "rgb(0, 0, 0)"
+simple :any selector list including :not unmatched.
+PASS getComputedStyle(document.getElementById("target13")).backgroundColor is "rgb(0, 0, 0)"
+:any selector including attributes matched.
+PASS getComputedStyle(document.getElementById("target14")).backgroundColor is "rgb(4, 5, 6)"
+:any selector including attributes matched.
+PASS getComputedStyle(document.getElementById("target15")).backgroundColor is "rgb(4, 5, 6)"
+:any selector including attributes unmatched.
+PASS getComputedStyle(document.getElementById("target16")).backgroundColor is "rgb(0, 0, 0)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/selectors/pseudo-class-any.html (0 => 169569)
--- trunk/LayoutTests/fast/selectors/pseudo-class-any.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/pseudo-class-any.html 2014-06-03 21:26:50 UTC (rev 169569)
@@ -0,0 +1,183 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<style>
+span.target {
+ background-color:rgb(0,0,0);
+}
+
+a:-webkit-any(.house, .horse) span.target {
+ background-color:rgb(1,2,3);
+}
+
+b.rabbit:-webkit-any(.house, .horse):-webkit-any(.cocoa, .cappuccino) span.target {
+ background-color:rgb(2,3,4);
+}
+
+c.rabbit:-webkit-any(.house, :not(.horse)) span.target {
+ background-color:rgb(3,4,5);
+}
+
+/* Maximum register case */
+d > d:-webkit-any([rel="drink"][data-cocoa][data-cappuccino], .ok) > d > d span.target {
+ background-color:rgb(4,5,6);
+}
+</style>
+</head>
+<body>
+<div style="display:none">
+ <!-- a:any(.house, .horse) span.target -->
+ <test1>
+ <a class="house">
+ <span class="target" id="target1"></span>
+ </a>
+
+ <a class="house">
+ <span class="target" id="target2"></span>
+ </a>
+
+ <a>
+ <span class="target" id="target3"></span>
+ </a>
+ </test1>
+
+ <!-- b.rabbit:-webkit-any(.house, .horse):-webkit-any(.cocoa, .cappuccino) span.target -->
+ <test2>
+ <b class="rabbit horse cocoa">
+ <span class="target" id="target4"></span>
+ </b>
+
+ <b class="rabbit house cappuccino">
+ <span class="target" id="target5"></span>
+ </b>
+
+ <b class="rabbit house horse">
+ <span class="target" id="target6"></span>
+ </b>
+
+ <b class="horse cocoa">
+ <span class="target" id="target7"></span>
+ </b>
+
+ <b class="rabbit cocoa cappuccino">
+ <span class="target" id="target8"></span>
+ </b>
+ </test2>
+
+ <!-- c.rabbit:-webkit-any(.house, :not(.horse)) span.target -->
+ <test3>
+ <c class="rabbit house">
+ <span class="target" id="target9"></span>
+ </c>
+
+ <c class="rabbit cappuccino">
+ <span class="target" id="target10"></span>
+ </c>
+
+ <c class="rabbit">
+ <span class="target" id="target11"></span>
+ </c>
+
+ <c class="rabbit horse">
+ <span class="target" id="target12"></span>
+ </c>
+
+ <c class="house">
+ <span class="target" id="target13"></span>
+ </c>
+ </test3>
+
+ <!-- d > d:-webkit-any([rel="drink"][data-cocoa][data-cappuccino], .ok) > d > d span.target -->
+ <test4>
+ <d> <!-- Matched. -->
+ <d rel="drink" data-cocoa data-cappuccino>
+ <d data-cocoa> <!-- Failed. Backtracking from the tail. -->
+ <d>
+ <d>
+ <span class="target" id="target14"></span>
+ </d>
+ </d>
+ </d>
+ </d>
+ </d>
+
+ <d> <!-- Matched. -->
+ <d class="ok">
+ <d data-cocoa> <!-- Failed. Backtracking from the tail. -->
+ <d>
+ <d>
+ <span class="target" id="target15"></span>
+ </d>
+ </d>
+ </d>
+ </d>
+ </d>
+
+ <a> <!-- Failed. -->
+ <d class="ok">
+ <d data-cocoa> <!-- Failed. Backtracking from the tail. -->
+ <d>
+ <d>
+ <span class="target" id="target16"></span>
+ </d>
+ </d>
+ </d>
+ </d>
+ </a>
+ </test4>
+</div>
+</body>
+<script>
+description('The pseudo class :any');
+
+debug("simple :any selector list matched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target1")).backgroundColor', 'rgb(1, 2, 3)');
+
+debug("simple :any selector list matched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target2")).backgroundColor', 'rgb(1, 2, 3)');
+
+debug("simple :any selector unmatched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target3")).backgroundColor', 'rgb(0, 0, 0)');
+
+debug("multiple :any selector list matched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target4")).backgroundColor', 'rgb(2, 3, 4)');
+
+debug("multiple :any selector list matched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target5")).backgroundColor', 'rgb(2, 3, 4)');
+
+debug("multiple :any selector list unmatched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target6")).backgroundColor', 'rgb(0, 0, 0)');
+
+debug("multiple :any selector list unmatched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target7")).backgroundColor', 'rgb(0, 0, 0)');
+
+debug("multiple :any selector list unmatched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target8")).backgroundColor', 'rgb(0, 0, 0)');
+
+debug("simple :any selector list including :not matched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target9")).backgroundColor', 'rgb(3, 4, 5)');
+
+debug("simple :any selector list including :not matched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target10")).backgroundColor', 'rgb(3, 4, 5)');
+
+debug("simple :any selector list including :not matched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target11")).backgroundColor', 'rgb(3, 4, 5)');
+
+debug("simple :any selector list including :not unmatched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target12")).backgroundColor', 'rgb(0, 0, 0)');
+
+debug("simple :any selector list including :not unmatched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target13")).backgroundColor', 'rgb(0, 0, 0)');
+
+debug(":any selector including attributes matched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target14")).backgroundColor', 'rgb(4, 5, 6)');
+
+debug(":any selector including attributes matched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target15")).backgroundColor', 'rgb(4, 5, 6)');
+
+debug(":any selector including attributes unmatched.");
+shouldBeEqualToString('getComputedStyle(document.getElementById("target16")).backgroundColor', 'rgb(0, 0, 0)');
+</script>
+<script src=""
+</html>
Modified: trunk/Source/WebCore/ChangeLog (169568 => 169569)
--- trunk/Source/WebCore/ChangeLog 2014-06-03 21:09:07 UTC (rev 169568)
+++ trunk/Source/WebCore/ChangeLog 2014-06-03 21:26:50 UTC (rev 169569)
@@ -1,3 +1,20 @@
+2014-06-03 Yusuke Suzuki <utatane....@gmail.com>
+
+ CSS JIT: add support for the "any" pseudo class
+ https://bugs.webkit.org/show_bug.cgi?id=133473
+
+ Reviewed by Benjamin Poulain.
+
+ Add support for the :any pseudo class.
+
+ Test: fast/selectors/pseudo-class-any.html
+
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::addPseudoClassType):
+ (WebCore::SelectorCompiler::minimumRegisterRequirements):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatchesAnyPseudoClass):
+
2014-06-02 Jer Noble <jer.no...@apple.com>
Update PlatformTimeRanges to use MediaTime rather than doubles for time values.
Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (169568 => 169569)
--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2014-06-03 21:09:07 UTC (rev 169568)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2014-06-03 21:26:50 UTC (rev 169569)
@@ -157,6 +157,7 @@
Vector<AttributeMatchingInfo> attributes;
Vector<std::pair<int, int>> nthChildFilters;
Vector<SelectorFragment> notFilters;
+ Vector<Vector<SelectorFragment>> anyFilters;
bool inFunctionalPseudoClass;
};
@@ -229,6 +230,7 @@
void generateElementIsLink(Assembler::JumpList& failureCases);
void generateElementIsNthChild(Assembler::JumpList& failureCases, const SelectorFragment&);
void generateElementMatchesNotPseudoClass(Assembler::JumpList& failureCases, const SelectorFragment&);
+ void generateElementMatchesAnyPseudoClass(Assembler::JumpList& failureCases, const SelectorFragment&);
void generateElementIsRoot(Assembler::JumpList& failureCases);
void generateElementIsTarget(Assembler::JumpList& failureCases);
@@ -441,6 +443,42 @@
return functionType;
}
+ case CSSSelector::PseudoClassAny:
+ {
+ Vector<SelectorFragment> anyFragments;
+ FunctionType functionType = FunctionType::SimpleSelectorChecker;
+ for (const CSSSelector* rootSelector = selector.selectorList()->first(); rootSelector; rootSelector = CSSSelectorList::next(rootSelector)) {
+ SelectorFragmentList fragmentList;
+ FunctionType subFunctionType = constructFragments(rootSelector, selectorContext, fragmentList);
+
+ // Since this fragment always unmatch against the element, don't insert it to anyFragments.
+ if (subFunctionType == FunctionType::CannotMatchAnything)
+ continue;
+
+ if (subFunctionType == FunctionType::CannotCompile)
+ return FunctionType::CannotCompile;
+
+ // :any() may not contain complex selectors which have combinators.
+ ASSERT(fragmentList.size() == 1);
+ if (fragmentList.size() != 1)
+ return FunctionType::CannotCompile;
+
+ SelectorFragment subFragment = fragmentList.first();
+ subFragment.inFunctionalPseudoClass = true;
+ anyFragments.append(subFragment);
+ functionType = mostRestrictiveFunctionType(functionType, subFunctionType);
+ }
+
+ // Since all fragments in :any() cannot match anything, this :any() filter cannot match anything.
+ if (anyFragments.isEmpty())
+ return FunctionType::CannotMatchAnything;
+
+ ASSERT(!anyFragments.isEmpty());
+ fragment.anyFilters.append(anyFragments);
+
+ return functionType;
+ }
+
default:
break;
}
@@ -594,6 +632,15 @@
unsigned notFilterMinimum = minimumRegisterRequirements(subFragment) + backtrackingRegisterRequirements;
minimum = std::max(minimum, notFilterMinimum);
}
+
+ // :any pseudo class filters cause some register pressure.
+ for (const auto& subFragments : selectorFragment.anyFilters) {
+ for (const SelectorFragment& subFragment : subFragments) {
+ unsigned anyFilterMinimum = minimumRegisterRequirements(subFragment) + backtrackingRegisterRequirements;
+ minimum = std::max(minimum, anyFilterMinimum);
+ }
+ }
+
return minimum;
}
@@ -1654,6 +1701,8 @@
generateElementIsNthChild(matchingPostTagNameFailureCases, fragment);
if (!fragment.notFilters.isEmpty())
generateElementMatchesNotPseudoClass(matchingPostTagNameFailureCases, fragment);
+ if (!fragment.anyFilters.isEmpty())
+ generateElementMatchesAnyPseudoClass(matchingPostTagNameFailureCases, fragment);
}
void SelectorCodeGenerator::generateElementDataMatching(Assembler::JumpList& failureCases, const SelectorFragment& fragment)
@@ -2566,6 +2615,26 @@
}
}
+void SelectorCodeGenerator::generateElementMatchesAnyPseudoClass(Assembler::JumpList& failureCases, const SelectorFragment& fragment)
+{
+ for (const auto& subFragments : fragment.anyFilters) {
+ RELEASE_ASSERT(!subFragments.isEmpty());
+
+ // Don't handle the last fragment in this loop.
+ Assembler::JumpList successCases;
+ for (unsigned i = 0; i < subFragments.size() - 1; ++i) {
+ Assembler::JumpList localFailureCases;
+ generateElementMatching(localFailureCases, localFailureCases, subFragments[i]);
+ successCases.append(m_assembler.jump());
+ localFailureCases.link(&m_assembler);
+ }
+
+ // At the last fragment, optimize the failure jump to jump to the non-local failure directly.
+ generateElementMatching(failureCases, failureCases, subFragments.last());
+ successCases.link(&m_assembler);
+ }
+}
+
void SelectorCodeGenerator::generateElementIsRoot(Assembler::JumpList& failureCases)
{
LocalRegister document(m_registerAllocator);