Changeset 197439 in webkit
- Timestamp:
- Mar 1, 2016 9:31:28 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r197435 r197439 1 2016-02-26 Ryosuke Niwa <rniwa@webkit.org> 2 3 Contents inside a shadow host with a negative tabindex should not be tab focusable 4 https://bugs.webkit.org/show_bug.cgi?id=154769 5 6 Reviewed by Antti Koivisto. 7 8 Added a test for navigating across shadow boundaries. 9 10 * fast/shadow-dom/negative-tabindex-on-shadow-host-expected.txt: Added. 11 * fast/shadow-dom/negative-tabindex-on-shadow-host.html: Added. 12 * platform/ios-simulator/TestExpectations: 13 1 14 2016-03-01 Myles C. Maxfield <mmaxfield@apple.com> 2 15 -
trunk/LayoutTests/platform/ios-simulator/TestExpectations
r197258 r197439 235 235 webkit.org/b/149441 fast/shadow-dom/css-scoping-shadow-slotted-rule.html [ ImageOnlyFailure ] 236 236 webkit.org/b/149441 fast/shadow-dom/css-scoping-shadow-slot-display-override.html [ ImageOnlyFailure ] 237 238 # No tab navigation support on iOS 239 fast/shadow-dom/negative-tabindex-on-shadow-host.html [ Failure ] 237 240 238 241 webkit.org/b/150225 fast/custom-elements [ Pass ] -
trunk/Source/WebCore/ChangeLog
r197437 r197439 1 2016-02-26 Ryosuke Niwa <rniwa@webkit.org> 2 3 Contents inside a shadow host with a negative tabindex should not be tab focusable 4 https://bugs.webkit.org/show_bug.cgi?id=154769 5 6 Reviewed by Antti Koivisto. 7 8 Contents inside a shadow host with a negative tabindex content attribute should not be included in 9 the sequential focus navigation order as discussed on https://github.com/w3c/webcomponents/issues/399. 10 11 Test: fast/shadow-dom/negative-tabindex-on-shadow-host.html 12 13 * dom/Element.cpp: 14 (WebCore::Element::tabIndexSetExplicitly): Added. 15 * dom/Element.h: 16 * page/FocusController.cpp: 17 (WebCore::shadowAdjustedTabIndex): Renamed from adjustedTabIndex. Return 0 when tabindex content attribute 18 is not explicitly set since element.tabIndex() would return -1 for HTML elements in such case. 19 (WebCore::isFocusableOrHasShadowTreeWithoutCustomFocusLogic): Renamed from shouldVisit. 20 (WebCore::FocusController::findElementWithExactTabIndex): 21 (WebCore::nextElementWithGreaterTabIndex): 22 (WebCore::previousElementWithLowerTabIndex): 23 (WebCore::FocusController::nextFocusableElement): 24 (WebCore::FocusController::previousFocusableElement): 25 1 26 2016-03-01 Michael Saboff <msaboff@apple.com> 2 27 -
trunk/Source/WebCore/dom/Element.cpp
r197401 r197439 213 213 } 214 214 215 bool Element::tabIndexSetExplicitly() const 216 { 217 return hasRareData() && elementRareData()->tabIndexSetExplicitly(); 218 } 219 215 220 bool Element::supportsFocus() const 216 221 { 217 return hasRareData() && elementRareData()->tabIndexSetExplicitly();222 return tabIndexSetExplicitly(); 218 223 } 219 224 -
trunk/Source/WebCore/dom/Element.h
r197401 r197439 267 267 virtual void setFocus(bool flag); 268 268 269 bool tabIndexSetExplicitly() const; 269 270 virtual bool supportsFocus() const; 270 271 virtual bool isFocusable() const; -
trunk/Source/WebCore/page/FocusController.cpp
r197055 r197439 215 215 } 216 216 217 static inline int adjustedTabIndex(Node& node, KeyboardEvent& event) 218 { 219 if (!is<Element>(node)) 220 return 0; 221 return isNonFocusableShadowHost(downcast<Element>(node), event) ? 0 : downcast<Element>(node).tabIndex(); 222 } 223 224 static inline bool shouldVisit(Element& element, KeyboardEvent& event) 217 static inline int shadowAdjustedTabIndex(Element& element, KeyboardEvent& event) 218 { 219 if (isNonFocusableShadowHost(element, event)) { 220 if (!element.tabIndexSetExplicitly()) 221 return 0; // Treat a shadow host without tabindex if it has tabindex=0 even though HTMLElement::tabIndex returns -1 on such an element. 222 } 223 return element.tabIndex(); 224 } 225 226 static inline bool isFocusableOrHasShadowTreeWithoutCustomFocusLogic(Element& element, KeyboardEvent& event) 225 227 { 226 228 return element.isKeyboardFocusable(&event) || isNonFocusableShadowHost(element, event); … … 480 482 continue; 481 483 Element& element = downcast<Element>(*node); 482 if ( shouldVisit(element, *event) && adjustedTabIndex(element, *event) == tabIndex)484 if (isFocusableOrHasShadowTreeWithoutCustomFocusLogic(element, *event) && shadowAdjustedTabIndex(element, *event) == tabIndex) 483 485 return &element; 484 486 } … … 495 497 continue; 496 498 Element& element = downcast<Element>(*node); 497 if ( shouldVisit(element, event) && element.tabIndex() > tabIndex && element.tabIndex() < winningTabIndex) {499 if (isFocusableOrHasShadowTreeWithoutCustomFocusLogic(element, event) && element.tabIndex() > tabIndex && element.tabIndex() < winningTabIndex) { 498 500 winner = &element; 499 501 winningTabIndex = element.tabIndex(); … … 513 515 continue; 514 516 Element& element = downcast<Element>(*node); 515 int currentTabIndex = adjustedTabIndex(element, event);516 if (( shouldVisit(element, event) || isNonFocusableShadowHost(element, event)) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) {517 int currentTabIndex = shadowAdjustedTabIndex(element, event); 518 if ((isFocusableOrHasShadowTreeWithoutCustomFocusLogic(element, event) || isNonFocusableShadowHost(element, event)) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) { 517 519 winner = &element; 518 520 winningTabIndex = currentTabIndex; … … 536 538 Element* FocusController::nextFocusableElement(const FocusNavigationScope& scope, Node* start, KeyboardEvent* event) 537 539 { 540 int startTabIndex = 0; 541 if (start && is<Element>(*start)) 542 startTabIndex = shadowAdjustedTabIndex(downcast<Element>(*start), *event); 543 538 544 if (start) { 539 int tabIndex = adjustedTabIndex(*start, *event);540 545 // If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order 541 if ( tabIndex < 0) {546 if (startTabIndex < 0) { 542 547 for (Node* node = scope.nextInScope(start); node; node = scope.nextInScope(node)) { 543 548 if (!is<Element>(*node)) 544 549 continue; 545 550 Element& element = downcast<Element>(*node); 546 if ( shouldVisit(element, *event) && adjustedTabIndex(element, *event) >= 0)551 if (isFocusableOrHasShadowTreeWithoutCustomFocusLogic(element, *event) && shadowAdjustedTabIndex(element, *event) >= 0) 547 552 return &element; 548 553 } … … 550 555 551 556 // First try to find a node with the same tabindex as start that comes after start in the scope. 552 if (Element* winner = findElementWithExactTabIndex(scope, scope.nextInScope(start), tabIndex, event, FocusDirectionForward))557 if (Element* winner = findElementWithExactTabIndex(scope, scope.nextInScope(start), startTabIndex, event, FocusDirectionForward)) 553 558 return winner; 554 559 555 if (!tabIndex) 556 // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order. 557 return 0; 560 if (!startTabIndex) 561 return nullptr; // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order. 558 562 } 559 563 … … 561 565 // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and 562 566 // 2) comes first in the scope, if there's a tie. 563 if (Element* winner = nextElementWithGreaterTabIndex(scope, start ? adjustedTabIndex(*start, *event) : 0, *event))567 if (Element* winner = nextElementWithGreaterTabIndex(scope, startTabIndex, *event)) 564 568 return winner; 565 569 … … 579 583 // If start is null, find the last node in the scope with a tabindex of 0. 580 584 Node* startingNode; 581 int startingTabIndex ;585 int startingTabIndex = 0; 582 586 if (start) { 583 587 startingNode = scope.previousInScope(start); 584 startingTabIndex = adjustedTabIndex(*start, *event); 585 } else { 588 if (is<Element>(*start)) 589 startingTabIndex = shadowAdjustedTabIndex(downcast<Element>(*start), *event); 590 } else 586 591 startingNode = last; 587 startingTabIndex = 0;588 }589 592 590 593 // However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order … … 594 597 continue; 595 598 Element& element = downcast<Element>(*node); 596 if ( shouldVisit(element, *event) && adjustedTabIndex(element, *event) >= 0)599 if (isFocusableOrHasShadowTreeWithoutCustomFocusLogic(element, *event) && shadowAdjustedTabIndex(element, *event) >= 0) 597 600 return &element; 598 601 }
Note: See TracChangeset
for help on using the changeset viewer.