Changeset 90004 in webkit
- Timestamp:
- Jun 29, 2011 2:39:58 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r90002 r90004 1 2011-06-29 Hayato Ito <hayato@chromium.org> 2 3 Reviewed by Hajime Morita. 4 5 Make a shadow host transfer a focus to the first focusable element in the shadow root when its focus() is called. 6 https://bugs.webkit.org/show_bug.cgi?id=62358. 7 8 This patch doesn't take an effect on the following elements to keep a compatibility. 9 - <input>, <textarea>, <video> and <audio> elements 10 We'll address these elements separately after re-targeting focus events 11 (bug 61421) is implemented. 12 13 A shadow root's <content> is not considered in this patch. 14 That should be addressed in another patch. See bug 63522. 15 16 * fast/dom/shadow/shadow-host-transfer-focus-expected.txt: Added. 17 * fast/dom/shadow/shadow-host-transfer-focus.html: Added. 18 1 19 2011-06-29 Roland Steiner <rolandsteiner@chromium.org> 2 20 -
trunk/Source/WebCore/ChangeLog
r90003 r90004 1 2011-06-29 Hayato Ito <hayato@chromium.org> 2 3 Reviewed by Hajime Morita. 4 5 Make a shadow host transfer a focus to the first focusable element in the shadow root when its focus() is called. 6 https://bugs.webkit.org/show_bug.cgi?id=62358. 7 8 This patch doesn't take an effect on the following elements to keep a compatibility. 9 - <input>, <textarea>, <video> and <audio> elements 10 We'll address these elements separately after re-targeting focus events 11 (bug 61421) is implemented. 12 13 A shadow root's <content> is not considered in this patch. 14 That should be addressed in another patch. See bug 63522. 15 16 Test: fast/dom/shadow/shadow-host-transfer-focus.html 17 18 * dom/Element.cpp: 19 (WebCore::Element::focus): 20 * page/FocusController.cpp: 21 (WebCore::shadowRoot): 22 (WebCore::isTreeScopeOwner): 23 (WebCore::FocusController::transferFocusToElementInShadowRoot): 24 (WebCore::hasCustomFocusLogic): 25 (WebCore::FocusController::findFocusableNodeDecendingDownIntoFrameDocumentOrShadowRoot): 26 (WebCore::FocusController::advanceFocusInDocumentOrder): 27 (WebCore::ownerOfTreeScope): 28 (WebCore::FocusController::findFocusableNodeAcrossTreeScope): 29 * page/FocusController.h: 30 1 31 2011-06-29 Ryan Sleevi <rsleevi@chromium.org> 2 32 -
trunk/Source/WebCore/dom/Element.cpp
r89989 r90004 1611 1611 // does not make sense to continue and update appearence. 1612 1612 protect = this; 1613 if (shadowRoot() && page->focusController()->transferFocusToElementInShadowRoot(this, restorePreviousSelection)) 1614 return; 1613 1615 if (!page->focusController()->setFocusedNode(this, doc->frame())) 1614 1616 return; -
trunk/Source/WebCore/page/FocusController.cpp
r88421 r90004 147 147 } 148 148 149 inline staticShadowRoot* shadowRoot(Node* node)149 static inline ShadowRoot* shadowRoot(Node* node) 150 150 { 151 151 return node->isElementNode() ? toElement(node)->shadowRoot() : 0; 152 152 } 153 153 154 inline staticbool isTreeScopeOwner(Node* node)154 static inline bool isTreeScopeOwner(Node* node) 155 155 { 156 156 return node && (node->isFrameOwnerElement() || shadowRoot(node)); 157 157 } 158 158 159 Node* FocusController::deepFocusableNode(FocusDirection direction, Node* node, KeyboardEvent* event) 159 bool FocusController::transferFocusToElementInShadowRoot(Element* shadowHost, bool restorePreviousSelection) 160 { 161 ASSERT(shadowRoot(shadowHost)); 162 Node* node = findFocusableNodeDecendingDownIntoFrameDocumentOrShadowRoot(FocusDirectionForward, shadowHost, 0); 163 if (shadowHost == node) 164 return false; 165 toElement(node)->focus(restorePreviousSelection); 166 return true; 167 } 168 169 static inline bool hasCustomFocusLogic(Node* node) 170 { 171 return node->hasTagName(inputTag) || node->hasTagName(textareaTag) || node->hasTagName(videoTag) || node->hasTagName(audioTag); 172 } 173 174 Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocumentOrShadowRoot(FocusDirection direction, Node* node, KeyboardEvent* event) 160 175 { 161 176 // The node we found might be a HTMLFrameOwnerElement or a shadow host, so descend down the tree until we find either: … … 171 186 foundNode = findFocusableNode(direction, document, 0, event); 172 187 } else { 188 // FIXME: Until a focus re-targeting (bug 61421) is implemented, 189 // skipping these elements is the safest way to keep a compatibility. 190 if (hasCustomFocusLogic(node)) 191 break; 173 192 ASSERT(shadowRoot(node)); 174 // FIXME: Some elements (e.g. HTMLInputElement and HTMLTextAreaElement) do extra work in their focus() methods.175 // Skipping these elements is the safest fix until we find a better way.176 if (node->hasTagName(inputTag) || node->hasTagName(textareaTag))177 break;178 193 foundNode = findFocusableNode(direction, shadowRoot(node), 0, event); 179 194 } … … 245 260 // Chrome doesn't want focus, so we should wrap focus. 246 261 node = findFocusableNode(direction, m_page->mainFrame()->document(), 0, event); 247 node = deepFocusableNode(direction, node, event);262 node = findFocusableNodeDecendingDownIntoFrameDocumentOrShadowRoot(direction, node, event); 248 263 249 264 if (!node) … … 295 310 static_cast<Element*>(node)->focus(false); 296 311 return true; 312 } 313 314 static inline Node* ownerOfTreeScope(TreeScope* scope) 315 { 316 ASSERT(scope); 317 if (scope->isShadowRoot()) 318 return scope->shadowHost(); 319 if (scope->document()->frame()) 320 return scope->document()->frame()->ownerElement(); 321 return 0; 297 322 } 298 323 … … 308 333 scope = owner->treeScope(); 309 334 } 310 node = deepFocusableNode(direction, node, event);335 node = findFocusableNodeDecendingDownIntoFrameDocumentOrShadowRoot(direction, node, event); 311 336 return node; 312 337 } … … 430 455 startingTabIndex = (start && start->tabIndex()) ? start->tabIndex() : std::numeric_limits<short>::max(); 431 456 return previousNodeWithLowerTabIndex(last, startingTabIndex, event); 432 }433 434 Node* FocusController::ownerOfTreeScope(TreeScope* scope)435 {436 ASSERT(scope);437 if (scope->isShadowRoot())438 return scope->shadowHost();439 if (scope->document()->frame())440 return scope->document()->frame()->ownerElement();441 return 0;442 457 } 443 458 -
trunk/Source/WebCore/page/FocusController.h
r88421 r90004 35 35 36 36 struct FocusCandidate; 37 class Element; 37 38 class Frame; 38 39 class IntRect; … … 62 63 bool isFocused() const { return m_isFocused; } 63 64 65 bool transferFocusToElementInShadowRoot(Element* shadowHost, bool restorePreviousSelection); 66 64 67 private: 65 68 bool advanceFocusDirectionally(FocusDirection, KeyboardEvent*); … … 67 70 68 71 Node* findFocusableNodeAcrossTreeScope(FocusDirection, TreeScope* startScope, Node* start, KeyboardEvent*); 69 Node* deepFocusableNode(FocusDirection, Node*, KeyboardEvent*); 70 Node* ownerOfTreeScope(TreeScope*); 72 Node* findFocusableNodeDecendingDownIntoFrameDocumentOrShadowRoot(FocusDirection, Node*, KeyboardEvent*); 71 73 72 74 // Searches through the given tree scope, starting from start node, for the next/previous selectable element that comes after/before start node.
Note: See TracChangeset
for help on using the changeset viewer.