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

Side by Side Diff: Source/core/page/FocusController.cpp

Issue 1204213002: Avoid tail recursion to mitigate stack exhaustion (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: lower the loop threshold from 100000 to 50000 Created 5 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « LayoutTests/fast/dom/shadow/focus-controller-recursion-crash-expected.txt ('k') | no next file » | 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) 2006, 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nuanti Ltd. 3 * Copyright (C) 2008 Nuanti Ltd.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 inline Element* findFocusableElementInternal(WebFocusType type, const FocusNavig ationScope& scope, Node* node) 376 inline Element* findFocusableElementInternal(WebFocusType type, const FocusNavig ationScope& scope, Node* node)
377 { 377 {
378 Element* found = (type == WebFocusTypeForward) ? nextFocusableElement(scope, node) : previousFocusableElement(scope, node); 378 Element* found = (type == WebFocusTypeForward) ? nextFocusableElement(scope, node) : previousFocusableElement(scope, node);
379 return found; 379 return found;
380 } 380 }
381 381
382 Element* findFocusableElementRecursivelyForward(const FocusNavigationScope& scop e, Node* start) 382 Element* findFocusableElementRecursivelyForward(const FocusNavigationScope& scop e, Node* start)
383 { 383 {
384 // Starting node is exclusive. 384 // Starting node is exclusive.
385 Element* found = findFocusableElementInternal(WebFocusTypeForward, scope, st art); 385 Element* found = findFocusableElementInternal(WebFocusTypeForward, scope, st art);
386 if (!found) 386 while (found) {
387 return nullptr; 387 if (isShadowHostDelegatesFocus(*found)) {
388 if (isShadowHostDelegatesFocus(*found)) { 388 // If tabindex is positive, find focusable node inside its shadow tr ee.
389 // If tabindex is positive, find focusable node inside its shadow tree. 389 if (found->tabIndex() >= 0 && isShadowHostWithoutCustomFocusLogic(*f ound)) {
390 if (found->tabIndex() >= 0 && isShadowHostWithoutCustomFocusLogic(*found )) { 390 FocusNavigationScope innerScope = FocusNavigationScope::ownedByS hadowHost(*found);
391 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShado wHost(*found); 391 if (Element* foundInInnerFocusScope = findFocusableElementRecurs ivelyForward(innerScope, nullptr))
392 if (Element* foundInInnerFocusScope = findFocusableElementRecursivel yForward(innerScope, nullptr)) 392 return foundInInnerFocusScope;
393 return foundInInnerFocusScope; 393 }
394 // Skip to the next node in the same scope.
395 found = findFocusableElementInternal(WebFocusTypeForward, scope, fou nd);
396 continue;
394 } 397 }
395 // Skip to the next node in the same scope. 398 if (!isNonFocusableFocusScopeOwner(*found))
396 found = findFocusableElementRecursivelyForward(scope, found); 399 return found;
400
401 // Now |found| is on a non focusable scope owner (either shadow host or <shadow>)
402 // Find inside the inward scope and return it if found. Otherwise contin ue searching in the same
403 // scope.
404 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusa bleFocusScopeOwner(*found);
405 if (Element* foundInInnerFocusScope = findFocusableElementRecursivelyFor ward(innerScope, nullptr))
406 return foundInInnerFocusScope;
407
408 found = findFocusableElementInternal(WebFocusTypeForward, scope, found);
397 } 409 }
398 if (!found || !isNonFocusableFocusScopeOwner(*found)) 410 return nullptr;
399 return found;
400
401 // Now |found| is on a non focusable scope owner (either shadow host or <sha dow>)
402 // Find inside the inward scope and return it if found. Otherwise continue s earching in the same
403 // scope.
404 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusableF ocusScopeOwner(*found);
405 if (Element* foundInInnerFocusScope = findFocusableElementRecursivelyForward (innerScope, nullptr))
406 return foundInInnerFocusScope;
407 return findFocusableElementRecursivelyForward(scope, found);
408 } 411 }
409 412
410 Element* findFocusableElementRecursivelyBackward(const FocusNavigationScope& sco pe, Node* start) 413 Element* findFocusableElementRecursivelyBackward(const FocusNavigationScope& sco pe, Node* start)
411 { 414 {
412 // Starting node is exclusive. 415 // Starting node is exclusive.
413 Element* found = findFocusableElementInternal(WebFocusTypeBackward, scope, s tart); 416 Element* found = findFocusableElementInternal(WebFocusTypeBackward, scope, s tart);
414 if (!found) 417 while (found) {
415 return nullptr; 418 // Now |found| is on a focusable shadow host.
419 // Find inside shadow backwards. If any focusable element is found, retu rn it, otherwise return
420 // the host itself.
421 if (isKeyboardFocusableShadowHost(*found)) {
422 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShado wHost(*found);
423 Element* foundInInnerFocusScope = findFocusableElementRecursivelyBac kward(innerScope, nullptr);
424 if (foundInInnerFocusScope)
425 return foundInInnerFocusScope;
426 if (isShadowHostDelegatesFocus(*found)) {
427 found = findFocusableElementInternal(WebFocusTypeBackward, scope , found);
428 continue;
429 }
430 return found;
431 }
416 432
417 // Now |found| is on a focusable shadow host. 433 // If delegatesFocus is true and tabindex is negative, skip the whole sh adow tree under the
418 // Find inside shadow backwards. If any focusable element is found, return i t, otherwise return 434 // shadow host.
419 // the host itself. 435 if (isShadowHostDelegatesFocus(*found) && found->tabIndex() < 0) {
420 if (isKeyboardFocusableShadowHost(*found)) { 436 found = findFocusableElementInternal(WebFocusTypeBackward, scope, fo und);
421 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHos t(*found); 437 continue;
422 Element* foundInInnerFocusScope = findFocusableElementRecursivelyBackwar d(innerScope, nullptr); 438 }
423 if (foundInInnerFocusScope) 439
424 return foundInInnerFocusScope; 440 // Now |found| is on a non focusable scope owner (either shadow host or <shadow>).
425 if (isShadowHostDelegatesFocus(*found)) 441 // Find focusable node in descendant scope. If not found, find next focu sable node within the
426 found = findFocusableElementRecursivelyBackward(scope, found); 442 // current scope.
427 return found; 443 if (isNonFocusableFocusScopeOwner(*found)) {
444 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFo cusableFocusScopeOwner(*found);
445 Element* foundInInnerFocusScope = findFocusableElementRecursivelyBac kward(innerScope, nullptr);
446 if (foundInInnerFocusScope)
447 return foundInInnerFocusScope;
448 found = findFocusableElementInternal(WebFocusTypeBackward, scope, fo und);
449 continue;
450 }
451 if (!isShadowHostDelegatesFocus(*found))
452 return found;
453 found = findFocusableElementInternal(WebFocusTypeBackward, scope, found) ;
428 } 454 }
429 455 return nullptr;
430 // If delegatesFocus is true and tabindex is negative, skip the whole shadow tree under the
431 // shadow host.
432 if (isShadowHostDelegatesFocus(*found) && found->tabIndex() < 0)
433 return findFocusableElementRecursivelyBackward(scope, found);
434
435 // Now |found| is on a non focusable scope owner (either shadow host or <sha dow>).
436 // Find focusable node in descendant scope. If not found, find next focusabl e node within the
437 // current scope.
438 if (isNonFocusableFocusScopeOwner(*found)) {
439 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusa bleFocusScopeOwner(*found);
440 Element* foundInInnerFocusScope = findFocusableElementRecursivelyBackwar d(innerScope, nullptr);
441 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableEl ementRecursivelyBackward(scope, found);
442 }
443
444 return !isShadowHostDelegatesFocus(*found) ? found : findFocusableElementRec ursivelyBackward(scope, found);
445 } 456 }
446 457
447 Element* findFocusableElementRecursively(WebFocusType type, const FocusNavigatio nScope& scope, Node* start) 458 Element* findFocusableElementRecursively(WebFocusType type, const FocusNavigatio nScope& scope, Node* start)
448 { 459 {
449 return (type == WebFocusTypeForward) ? 460 return (type == WebFocusTypeForward) ?
450 findFocusableElementRecursivelyForward(scope, start) : 461 findFocusableElementRecursivelyForward(scope, start) :
451 findFocusableElementRecursivelyBackward(scope, start); 462 findFocusableElementRecursivelyBackward(scope, start);
452 } 463 }
453 464
454 Element* findFocusableElementDescendingDownIntoFrameDocument(WebFocusType type, Element* element) 465 Element* findFocusableElementDescendingDownIntoFrameDocument(WebFocusType type, Element* element)
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 return consumed; 1048 return consumed;
1038 } 1049 }
1039 1050
1040 DEFINE_TRACE(FocusController) 1051 DEFINE_TRACE(FocusController)
1041 { 1052 {
1042 visitor->trace(m_page); 1053 visitor->trace(m_page);
1043 visitor->trace(m_focusedFrame); 1054 visitor->trace(m_focusedFrame);
1044 } 1055 }
1045 1056
1046 } // namespace blink 1057 } // namespace blink
OLDNEW
« no previous file with comments | « LayoutTests/fast/dom/shadow/focus-controller-recursion-crash-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698