Changeset 18610 in webkit


Ignore:
Timestamp:
Jan 4, 2007 10:18:36 PM (17 years ago)
Author:
aroben
Message:

LayoutTests:

Reviewed by Geoff.

Added new tests for tabindex and tabbing into/out of subframes.

  • fast/dom/tabindex-clamp-expected.txt: Added.
  • fast/dom/tabindex-clamp.html: Added.
  • fast/events/frame-click-focus-expected.txt: Added.
  • fast/events/frame-click-focus.html: Added.
  • fast/events/frame-tab-focus-expected.txt: Added.
  • fast/events/frame-tab-focus.html: Added.
  • fast/events/resources/frame-tab-focus-child.html: Added.
  • fast/events/resources/frame-tab-focus-empty-child.html: Added.
  • fast/events/resources/frame-tab-focus-empty-middle.html: Added.
  • fast/events/resources/frame-tab-focus-middle.html: Added.
  • fast/events/resources/frame-tab-focus-upper.html: Added.
  • fast/html/tab-order-expected.txt: Added.
  • fast/html/tab-order.html: Added.

Updated test to match new behavior.

  • fast/forms/focus2-expected.txt: Updated results.
  • fast/forms/focus2.html: Fixed typo, and reduced the number of tab events dispatched now that frames containing focusable elements aren't themselves in the tab order.

WebCore:

Reviewed by Geoff.

Fix: <rdar://4800335> REGRESSION: shift-tabbing from location field
goes to first field rather than last (businessweek.com)

Fix: <rdar://4800373> REGRESSION: tabbing from last control focuses
nothing visible (busniessweek.com)

Handle tabbing into/out of subframes in WebCore instead of letting
AppKit do the dirty work. This change also fixes a number of bugs and
changes some behavior to match other browsers:

  • No frames receive a focus event when the page is first loaded.
  • When a frame is clicked or focused with the keyboard, it receives a focus event and all other frames receive a blur event.
  • tabindex values are clamped to the range of a signed short, rather than overflowing within an unsigned short.
  • tabindex is respected on frame owner elements, even though HTML4 says it shouldn't be.
  • Subframes will be focused when tabbing if they don't contain any focusable elements within them (it would be nice to only focus the frame if it has scrollbars).

Renamed SelectionDirection to FocusDirection and put it in its own file.

  • page/FocusDirection.h: Added. (WebCore::):
  • page/mac/WebCoreFrameBridge.mm: Updated for renames. (-[WebCoreFrameBridge nextKeyView]): (-[WebCoreFrameBridge previousKeyView]): (-[WebCoreFrameBridge nextKeyViewInsideWebFrameViews]): (-[WebCoreFrameBridge previousKeyViewInsideWebFrameViews]):

Moved advanceFocus from EventHandler to FocusController and added
support for moving into/out of subframes..

  • page/EventHandler.cpp: Moved advanceFocus to FocusController.
  • page/EventHandler.h: Ditto.
  • page/FocusController.cpp: (WebCore::deepFocusableNode): Static helper function to find focusable nodes nested within frames. (WebCore::FocusController::advanceFocus): Moved from EventHandler and rewritten to handle subframes.
  • page/FocusController.h: Added advanceFocus declaration.
  • dom/EventTargetNode.cpp: (WebCore::EventTargetNode::defaultEventHandler): Updated for the move of advanceFocus to FocusController.
  • html/HTMLFrameOwnerElement.h: (WebCore::HTMLFrameOwnerElement::isFrameOwnerElement): New method. (WebCore::HTMLFrameOwnerElement::isKeyboardFocusable): New virtual implementation used to trick Document::nextFocusableNode so that we can focus frames.

Rewrote/renamed
Document::nextFocusableNode/Document::previousFocusableNode.

  • dom/Document.cpp: (WebCore::nextNodeWithExactTabIndex): New static helper function. (WebCore::previousNodeWithExactTabIndex): Ditto. (WebCore::nextNodeWithGreaterTabIndex): Ditto. (WebCore::previousNodeWithLowerTabIndex): Ditto. (WebCore::Document::nextFocusableNode): Renamed from nextFocusedNode, and rewritten with much simpler logic. (WebCore::Document::previousFocusableNode): Ditto.
  • dom/Document.h: Updated declarations for renames.
  • page/mac/EventHandlerMac.mm: Updated for rename of SelectionDirection to FocusDirection. (WebCore::EventHandler::nextKeyViewInFrame): Updated for renames. (WebCore::EventHandler::nextKeyViewInFrameHierarchy): Ditto. (WebCore::EventHandler::nextKeyView): Ditto. (WebCore::EventHandler::focusDocumentView): Added call to setFocusedFrame when focusing the document view. (WebCore::EventHandler::passMouseDownEventToWidget): Removed LOG_ERROR when a nil NSView is returned from AppKit, as this is a fairly common occurrence when a RenderWidget has a border. (WebCore::EventHandler::passWheelEventToWidget): Added a nil-check of the hit-tested NSView.

Changed storage of tabIndex to a signed short, and added clamping of
tabindex attribute values to match Firefox's behavior.

  • dom/Node.h: Use a signed short to store m_tabIndex. (WebCore::Node::isFrameOwnerElement): New method. (WebCore::Node::tabIndex): Updated for signedness. (WebCore::Node::setTabIndex): Ditto.
  • html/HTMLAnchorElement.cpp: Remove implementation of tabIndex() so that Node::tabIndex() will be called instead and return the clamped value (which matches Firefox's behavior).
  • html/HTMLAnchorElement.h: Ditto.
  • html/HTMLAreaElement.cpp: Ditto.
  • html/HTMLAreaElement.h: Ditto.
  • html/HTMLGenericFormElement.cpp: Ditto.
  • html/HTMLGenericFormElement.h: Ditto.
  • html/HTMLObjectElement.cpp: Ditto.
  • html/HTMLObjectElement.h: Ditto.
  • html/HTMLElement.cpp: (WebCore::HTMLElement::parseMappedAttribute): Clamp tabIndex to the range of a signed short to match Firefox.

Added two new Chrome methods for transferring focus out of the
WebView.

  • page/Chrome.cpp: (WebCore::Chrome::canTakeFocus): (WebCore::Chrome::takeFocus):
  • page/Chrome.h:
  • page/ChromeClient.h:
  • platform/graphics/svg/SVGImageEmptyClients.h: Fixed typo "CromeClient" -> "ChromeClient". (WebCore::SVGEmptyChromeClient::~SVGEmptyChromeClient): (WebCore::SVGEmptyChromeClient::canTakeFocus): (WebCore::SVGEmptyChromeClient::takeFocus):
  • platform/graphics/svg/SVGImage.cpp: (WebCore::SVGImage::setData): Fixed typo.

Miscellaneous:

  • WebCore.exp: Updated/sorted symbols.
  • WebCore.xcodeproj/project.pbxproj: Made FocusController.h Private so WebKit can access it.

WebKit:

Reviewed by Geoff.

Remove WebKit/AppKit from handling tabbing between subframes.

  • WebCoreSupport/WebChromeClient.h: Added new ChromeClient methods for moving focus out of the WebView.
  • WebCoreSupport/WebChromeClient.mm: Ditto. (WebChromeClient::canTakeFocus): (WebChromeClient::takeFocus):
  • WebCoreSupport/WebFrameBridge.mm: (-[WebFrameBridge webView]): Added null-check of m_frame.
  • WebView/WebHTMLView.m: Removed -[WebHTMLView nextValidKeyView]. (-[WebHTMLView _updateActiveState]): Changed to focus the frame if WebCore believes it to be the focused frame. (-[WebHTMLView becomeFirstResponder]): Rewrote to call into FocusController to place focus correctly within the WebView.
Location:
trunk
Files:
14 added
36 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r18602 r18610  
     12007-01-04  Adam Roben  <aroben@apple.com>
     2
     3        Reviewed by Geoff.
     4
     5        Added new tests for tabindex and tabbing into/out of subframes.
     6
     7        * fast/dom/tabindex-clamp-expected.txt: Added.
     8        * fast/dom/tabindex-clamp.html: Added.
     9        * fast/events/frame-click-focus-expected.txt: Added.
     10        * fast/events/frame-click-focus.html: Added.
     11        * fast/events/frame-tab-focus-expected.txt: Added.
     12        * fast/events/frame-tab-focus.html: Added.
     13        * fast/events/resources/frame-tab-focus-child.html: Added.
     14        * fast/events/resources/frame-tab-focus-empty-child.html: Added.
     15        * fast/events/resources/frame-tab-focus-empty-middle.html: Added.
     16        * fast/events/resources/frame-tab-focus-middle.html: Added.
     17        * fast/events/resources/frame-tab-focus-upper.html: Added.
     18        * fast/html/tab-order-expected.txt: Added.
     19        * fast/html/tab-order.html: Added.
     20
     21        Updated test to match new behavior.
     22
     23        * fast/forms/focus2-expected.txt: Updated results.
     24        * fast/forms/focus2.html: Fixed typo, and reduced the number of tab
     25        events dispatched now that frames containing focusable elements aren't
     26        themselves in the tab order.
     27
    1282007-01-04  Mitz Pettel  <mitz@webkit.org>
    229
     
    2350        * editing/pasteboard/4861080.html: Added.
    2451
    25 2007-01-03  Adele Peterson  <adele@apple.com>
     522007-01-04  Adele Peterson  <adele@apple.com>
    2653
    2754        Reviewed by Darin.
  • trunk/LayoutTests/fast/forms/focus2-expected.txt

    r18229 r18610  
    4141keypress event: [to] DIV
    4242blur event: [to] DIV
    43 keypress event: [to] DIV
    44 focus event: [to] IFRAME
     43focus event: [to] ANCHOR
     44blur event: [to] ANCHOR
    4545
    4646IFRAME DOCUMENT:
     47focus event: [to] BUTTON
     48keypress event: [to] BUTTON
    4749focus event: [to] BUTTON
    4850keypress event: [to] BUTTON
     
    7981blur event: [to] TEXTAREA
    8082focus event: [to] DIV
    81 keypress event: [to] DIV
    82 blur event: [to] DIV
    83 keypress event: [to] DIV
    8483
  • trunk/LayoutTests/fast/forms/focus2.html

    r18175 r18610  
    102102    anchor.innerHTML = "anchor";
    103103    anchor.href = "javascript:";
    104     addEventListeners(input);
     104    addEventListeners(anchor);
    105105    parentElement.appendChild(anchor);
    106106}
     
    128128log('PARENT DOCUMENT:\n');
    129129document.getElementsByTagName('input')[0].focus();
    130 for (var i = 0; i < 13; ++i) //>
     130for (var i = 0; i < 12; ++i) //>
    131131    dispatchOptionTab(lastFocusedElement, false);
     132
     133lastFocusedElement.blur();
    132134
    133135log('\nIFRAME DOCUMENT:\n');
    134136document.getElementById('testIframe').contentDocument.getElementsByTagName('input')[0].focus();
    135 for (var i = 0; i < 13; ++i) //>
     137for (var i = 0; i < 12; ++i) //>
    136138    dispatchOptionTab(lastFocusedElement, false);
    137139</script>
  • trunk/WebCore/ChangeLog

    r18609 r18610  
     12007-01-04  Adam Roben  <aroben@apple.com>
     2
     3        Reviewed by Geoff.
     4
     5        Fix: <rdar://4800335> REGRESSION: shift-tabbing from location field
     6        goes to first field rather than last (businessweek.com)
     7
     8        Fix: <rdar://4800373> REGRESSION: tabbing from last control focuses
     9        nothing visible (busniessweek.com)
     10
     11        Handle tabbing into/out of subframes in WebCore instead of letting
     12        AppKit do the dirty work. This change also fixes a number of bugs and
     13        changes some behavior to match other browsers:
     14          - No frames receive a focus event when the page is first loaded.
     15          - When a frame is clicked or focused with the keyboard, it receives
     16            a focus event and all other frames receive a blur event.
     17          - tabindex values are clamped to the range of a signed short, rather
     18            than overflowing within an unsigned short.
     19          - tabindex is respected on frame owner elements, even though HTML4
     20            says it shouldn't be.
     21          - Subframes will be focused when tabbing if they don't contain any
     22            focusable elements within them (it would be nice to only focus the
     23            frame if it has scrollbars).
     24
     25        Renamed SelectionDirection to FocusDirection and put it in its own file.
     26
     27        * page/FocusDirection.h: Added.
     28        (WebCore::):
     29        * page/mac/WebCoreFrameBridge.mm: Updated for renames.
     30        (-[WebCoreFrameBridge nextKeyView]):
     31        (-[WebCoreFrameBridge previousKeyView]):
     32        (-[WebCoreFrameBridge nextKeyViewInsideWebFrameViews]):
     33        (-[WebCoreFrameBridge previousKeyViewInsideWebFrameViews]):
     34
     35        Moved advanceFocus from EventHandler to FocusController and added
     36        support for moving into/out of subframes..
     37
     38        * page/EventHandler.cpp: Moved advanceFocus to FocusController.
     39        * page/EventHandler.h: Ditto.
     40        * page/FocusController.cpp:
     41        (WebCore::deepFocusableNode): Static helper function to find focusable
     42        nodes nested within frames.
     43        (WebCore::FocusController::advanceFocus): Moved from EventHandler and
     44        rewritten to handle subframes.
     45        * page/FocusController.h: Added advanceFocus declaration.
     46        * dom/EventTargetNode.cpp:
     47        (WebCore::EventTargetNode::defaultEventHandler): Updated for the move
     48        of advanceFocus to FocusController.
     49        * html/HTMLFrameOwnerElement.h:
     50        (WebCore::HTMLFrameOwnerElement::isFrameOwnerElement): New method.
     51        (WebCore::HTMLFrameOwnerElement::isKeyboardFocusable): New virtual
     52        implementation used to trick Document::nextFocusableNode so that we
     53        can focus frames.
     54
     55        Rewrote/renamed
     56        Document::nextFocusableNode/Document::previousFocusableNode.
     57
     58        * dom/Document.cpp:
     59        (WebCore::nextNodeWithExactTabIndex): New static helper
     60        function.
     61        (WebCore::previousNodeWithExactTabIndex): Ditto.
     62        (WebCore::nextNodeWithGreaterTabIndex): Ditto.
     63        (WebCore::previousNodeWithLowerTabIndex): Ditto.
     64        (WebCore::Document::nextFocusableNode): Renamed from nextFocusedNode,
     65        and rewritten with much simpler logic.
     66        (WebCore::Document::previousFocusableNode): Ditto.
     67        * dom/Document.h: Updated declarations for renames.
     68        * page/mac/EventHandlerMac.mm: Updated for rename of SelectionDirection
     69        to FocusDirection.
     70        (WebCore::EventHandler::nextKeyViewInFrame): Updated for renames.
     71        (WebCore::EventHandler::nextKeyViewInFrameHierarchy): Ditto.
     72        (WebCore::EventHandler::nextKeyView): Ditto.
     73        (WebCore::EventHandler::focusDocumentView): Added call to
     74        setFocusedFrame when focusing the document view.
     75        (WebCore::EventHandler::passMouseDownEventToWidget): Removed LOG_ERROR
     76        when a nil NSView is returned from AppKit, as this is a fairly common
     77        occurrence when a RenderWidget has a border.
     78        (WebCore::EventHandler::passWheelEventToWidget): Added a nil-check of
     79        the hit-tested NSView.
     80
     81        Changed storage of tabIndex to a signed short, and added clamping of
     82        tabindex attribute values to match Firefox's behavior.
     83
     84        * dom/Node.h: Use a signed short to store m_tabIndex.
     85        (WebCore::Node::isFrameOwnerElement): New method.
     86        (WebCore::Node::tabIndex): Updated for signedness.
     87        (WebCore::Node::setTabIndex): Ditto.
     88        * html/HTMLAnchorElement.cpp: Remove implementation of tabIndex() so
     89        that Node::tabIndex() will be called instead and return the clamped
     90        value (which matches Firefox's behavior).
     91        * html/HTMLAnchorElement.h: Ditto.
     92        * html/HTMLAreaElement.cpp: Ditto.
     93        * html/HTMLAreaElement.h: Ditto.
     94        * html/HTMLGenericFormElement.cpp: Ditto.
     95        * html/HTMLGenericFormElement.h: Ditto.
     96        * html/HTMLObjectElement.cpp: Ditto.
     97        * html/HTMLObjectElement.h: Ditto.
     98        * html/HTMLElement.cpp:
     99        (WebCore::HTMLElement::parseMappedAttribute): Clamp tabIndex to the
     100        range of a signed short to match Firefox.
     101
     102        Added two new Chrome methods for transferring focus out of the
     103        WebView.
     104
     105        * page/Chrome.cpp:
     106        (WebCore::Chrome::canTakeFocus):
     107        (WebCore::Chrome::takeFocus):
     108        * page/Chrome.h:
     109        * page/ChromeClient.h:
     110        * platform/graphics/svg/SVGImageEmptyClients.h: Fixed typo "CromeClient" -> "ChromeClient".
     111        (WebCore::SVGEmptyChromeClient::~SVGEmptyChromeClient):
     112        (WebCore::SVGEmptyChromeClient::canTakeFocus):
     113        (WebCore::SVGEmptyChromeClient::takeFocus):
     114        * platform/graphics/svg/SVGImage.cpp:
     115        (WebCore::SVGImage::setData): Fixed typo.
     116
     117        Miscellaneous:
     118
     119        * WebCore.exp: Updated/sorted symbols.
     120        * WebCore.xcodeproj/project.pbxproj: Made FocusController.h Private so
     121        WebKit can access it.
     122
    11232007-01-04  Brady Eidson  <beidson@apple.com>
    2124
  • trunk/WebCore/WebCore.exp

    r18586 r18610  
    130130__ZN7WebCore10MouseEventC1ERKNS_12AtomicStringEbbPNS_9DOMWindowEiiiiibbbbtPNS_15EventTargetNodeEPNS_9ClipboardEb
    131131__ZN7WebCore10StringImplD1Ev
    132 __ZNK7WebCore6String6lengthEv
    133132__ZN7WebCore11ContextMenu22setPlatformDescriptionEP14NSMutableArray
    134133__ZN7WebCore11EditCommand7reapplyEv
    135134__ZN7WebCore11EditCommand7unapplyEv
    136 __ZN7WebCore9PageCache12documentViewEv
    137 __ZN7WebCore9PageCache9pageStateEv
    138 __ZN7WebCore11HistoryItem9pageCacheEv
    139 __ZN7WebCore9PageCache12setPageStateEN3WTF10PassRefPtrINS_9PageStateEEE
    140 __ZN7WebCore9PageCache15setDocumentViewEP11objc_object
    141 __ZN7WebCore9PageCache17setDocumentLoaderEN3WTF10PassRefPtrINS_14DocumentLoaderEEE
    142 __ZN7WebCore9PageCache17setTimeStampToNowEv
    143 __ZN7WebCore9PageCacheD1Ev
    144 __ZN7WebCore9PageCache14documentLoaderEv
    145 __ZN7WebCore9PageState6createEPNS_4PageE
    146 __ZN7WebCore9PageStateD1Ev
    147135__ZN7WebCore11FrameLoader11completeURLERKNS_6StringE
    148136__ZN7WebCore11FrameLoader12canCachePageEv
     
    152140__ZN7WebCore11FrameLoader14stopAllLoadersEv
    153141__ZN7WebCore11FrameLoader16detachFromParentEv
     142__ZN7WebCore11FrameLoader18currentHistoryItemEv
    154143__ZN7WebCore11FrameLoader21addPlugInStreamLoaderEPNS_14ResourceLoaderE
     144__ZN7WebCore11FrameLoader21setCurrentHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
    155145__ZN7WebCore11FrameLoader22cancelMainResourceLoadERKNS_13ResourceErrorE
     146__ZN7WebCore11FrameLoader22setPreviousHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
    156147__ZN7WebCore11FrameLoader23reloadAllowingStaleDataERKNS_6StringE
    157148__ZN7WebCore11FrameLoader23timeOfLastCompletedLoadEv
    158149__ZN7WebCore11FrameLoader24removePlugInStreamLoaderEPNS_14ResourceLoaderE
    159150__ZN7WebCore11FrameLoader25provisionalDocumentLoaderEv
     151__ZN7WebCore11FrameLoader25setProvisionalHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
     152__ZN7WebCore11FrameLoader26saveDocumentAndScrollStateEv
     153__ZN7WebCore11FrameLoader36saveScrollPositionAndViewStateToItemEPNS_11HistoryItemE
    160154__ZN7WebCore11FrameLoader4loadEPNS_14DocumentLoaderE
    161155__ZN7WebCore11FrameLoader4loadEPNS_14DocumentLoaderENS_13FrameLoadTypeEN3WTF10PassRefPtrINS_9FormStateEEE
     
    168162__ZN7WebCore11FrameLoader6reloadEv
    169163__ZN7WebCore11FrameLoader7canLoadERKNS_4KURLERKNS_6StringERb
     164__ZN7WebCore11HistoryItem12addChildItemEN3WTF10PassRefPtrIS0_EE
     165__ZN7WebCore11HistoryItem12setURLStringERKNS_6StringE
     166__ZN7WebCore11HistoryItem12setViewStateEP11objc_object
     167__ZN7WebCore11HistoryItem13setVisitCountEi
     168__ZN7WebCore11HistoryItem14setScrollPointERKNS_8IntPointE
     169__ZN7WebCore11HistoryItem15setHasPageCacheEb
     170__ZN7WebCore11HistoryItem15setIsTargetItemEb
     171__ZN7WebCore11HistoryItem17setAlternateTitleERKNS_6StringE
     172__ZN7WebCore11HistoryItem18setLastVisitedTimeEd
     173__ZN7WebCore11HistoryItem18setRSSFeedReferrerERKNS_6StringE
     174__ZN7WebCore11HistoryItem20setOriginalURLStringERKNS_6StringE
     175__ZN7WebCore11HistoryItem20setTransientPropertyERKNS_6StringEP11objc_object
     176__ZN7WebCore11HistoryItem22mergeAutoCompleteHintsEPS0_
     177__ZN7WebCore11HistoryItem23recurseToFindTargetItemEv
     178__ZN7WebCore11HistoryItem27releaseAllPendingPageCachesEv
     179__ZN7WebCore11HistoryItem30setAlwaysAttemptToUsePageCacheEb
     180__ZN7WebCore11HistoryItem6setURLERKNS_4KURLE
     181__ZN7WebCore11HistoryItem8formDataEv
     182__ZN7WebCore11HistoryItem8setTitleERKNS_6StringE
     183__ZN7WebCore11HistoryItem9pageCacheEv
     184__ZN7WebCore11HistoryItem9setParentERKNS_6StringE
     185__ZN7WebCore11HistoryItem9setTargetERKNS_6StringE
     186__ZN7WebCore11HistoryItemC1ERKNS_4KURLERKNS_6StringES6_S6_
     187__ZN7WebCore11HistoryItemC1ERKNS_6StringES3_d
     188__ZN7WebCore11HistoryItemC1Ev
     189__ZN7WebCore11HistoryItemD1Ev
    170190__ZN7WebCore11RenderLayer18gAlignCenterAlwaysE
    171191__ZN7WebCore11selectRangeEPNS_19SelectionControllerEPNS_5RangeENS_9EAffinityEb
     
    215235__ZN7WebCore14ResourceHandle12releaseProxyEv
    216236__ZN7WebCore14ResourceLoader14cancelledErrorEv
     237__ZN7WebCore15BackForwardList10removeItemEPNS_11HistoryItemE
     238__ZN7WebCore15BackForwardList11currentItemEv
     239__ZN7WebCore15BackForwardList11forwardItemEv
     240__ZN7WebCore15BackForwardList11itemAtIndexEi
     241__ZN7WebCore15BackForwardList11setCapacityEi
     242__ZN7WebCore15BackForwardList12containsItemEPNS_11HistoryItemE
     243__ZN7WebCore15BackForwardList13backListCountEv
     244__ZN7WebCore15BackForwardList13pageCacheSizeEv
     245__ZN7WebCore15BackForwardList13usesPageCacheEv
     246__ZN7WebCore15BackForwardList14clearPageCacheEv
     247__ZN7WebCore15BackForwardList16forwardListCountEv
     248__ZN7WebCore15BackForwardList16setPageCacheSizeEj
     249__ZN7WebCore15BackForwardList17backListWithLimitEiRN3WTF6VectorINS1_6RefPtrINS_11HistoryItemEEELm0EEE
     250__ZN7WebCore15BackForwardList20forwardListWithLimitEiRN3WTF6VectorINS1_6RefPtrINS_11HistoryItemEEELm0EEE
     251__ZN7WebCore15BackForwardList23setDefaultPageCacheSizeEj
     252__ZN7WebCore15BackForwardList5closeEv
     253__ZN7WebCore15BackForwardList6closedEv
     254__ZN7WebCore15BackForwardList6goBackEv
     255__ZN7WebCore15BackForwardList7addItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
     256__ZN7WebCore15BackForwardList7entriesEv
     257__ZN7WebCore15BackForwardList8backItemEv
     258__ZN7WebCore15BackForwardList8capacityEv
     259__ZN7WebCore15BackForwardList8goToItemEPNS_11HistoryItemE
     260__ZN7WebCore15BackForwardList9goForwardEv
     261__ZN7WebCore15BackForwardListC1Ev
     262__ZN7WebCore15BackForwardListD1Ev
    217263__ZN7WebCore15ContextMenuItem26releasePlatformDescriptionEv
     264__ZN7WebCore15FocusController12advanceFocusEPNS_13KeyboardEventE
     265__ZN7WebCore15FocusController15setFocusedFrameEN3WTF10PassRefPtrINS_5FrameEEE
     266__ZN7WebCore15FocusController18focusedOrMainFrameEv
    218267__ZN7WebCore16DeprecatedString6appendENS_14DeprecatedCharE
    219268__ZN7WebCore16DeprecatedString6appendERKS0_
     
    235284__ZN7WebCore21findEventWithKeyStateEPNS_5EventE
    236285__ZN7WebCore21isBackForwardLoadTypeENS_13FrameLoadTypeE
     286__ZN7WebCore24notifyHistoryItemChangedE
    237287__ZN7WebCore26NetscapePlugInStreamLoader6createEPNS_5FrameEP11objc_object
    238288__ZN7WebCore36InitializeLoggingChannelsIfNecessaryEv
     
    241291__ZN7WebCore4KURLC1Ev
    242292__ZN7WebCore4Page12setGroupNameERKNS_6StringE
     293__ZN7WebCore4Page15backForwardListEv
    243294__ZN7WebCore4Page16setDefersLoadingEb
     295__ZN7WebCore4Page6goBackEv
     296__ZN7WebCore4Page8goToItemEPNS_11HistoryItemENS_13FrameLoadTypeE
     297__ZN7WebCore4Page9goForwardEv
    244298__ZN7WebCore4PageC1EPNS_12ChromeClientEPNS_17ContextMenuClientEPNS_12EditorClientE
    245299__ZN7WebCore4PageD1Ev
     
    257311__ZN7WebCore5RangeD1Ev
    258312__ZN7WebCore5cacheEv
     313__ZN7WebCore5equalEPKNS_10StringImplES2_
    259314__ZN7WebCore6Editor10applyStyleEPNS_19CSSStyleDeclarationENS_10EditActionE
    260315__ZN7WebCore6Editor11canDHTMLCutEv
     
    348403__ZN7WebCore9HTMLNames7srcAttrE
    349404__ZN7WebCore9HTMLNames8hrefAttrE
     405__ZN7WebCore9PageCache12documentViewEv
     406__ZN7WebCore9PageCache12setPageStateEN3WTF10PassRefPtrINS_9PageStateEEE
     407__ZN7WebCore9PageCache14documentLoaderEv
     408__ZN7WebCore9PageCache15setDocumentViewEP11objc_object
     409__ZN7WebCore9PageCache17setDocumentLoaderEN3WTF10PassRefPtrINS_14DocumentLoaderEEE
     410__ZN7WebCore9PageCache17setTimeStampToNowEv
     411__ZN7WebCore9PageCache9pageStateEv
     412__ZN7WebCore9PageCacheD1Ev
    350413__ZN7WebCore9PageState5clearEv
     414__ZN7WebCore9PageState6createEPNS_4PageE
     415__ZN7WebCore9PageStateD1Ev
    351416__ZN7WebCore9Selection22expandUsingGranularityENS_15TextGranularityE
    352417__ZN7WebCore9TimerBase4stopEv
     
    354419__ZN7WebCore9TimerBaseC2Ev
    355420__ZN7WebCore9TimerBaseD2Ev
     421__ZN7WebCoreeqERKNS_4KURLES2_
    356422__ZNK7WebCore10StringImplcvP8NSStringEv
    357423__ZNK7WebCore11CachedImage5imageEv
     
    367433__ZNK7WebCore11FrameLoader6clientEv
    368434__ZNK7WebCore11FrameLoader8loadTypeEv
     435__ZNK7WebCore11HistoryItem10visitCountEv
     436__ZNK7WebCore11HistoryItem11hasChildrenEv
     437__ZNK7WebCore11HistoryItem11scrollPointEv
     438__ZNK7WebCore11HistoryItem12isTargetItemEv
     439__ZNK7WebCore11HistoryItem14alternateTitleEv
     440__ZNK7WebCore11HistoryItem15lastVisitedTimeEv
     441__ZNK7WebCore11HistoryItem15rssFeedReferrerEv
     442__ZNK7WebCore11HistoryItem17childItemWithNameERKNS_6StringE
     443__ZNK7WebCore11HistoryItem17originalURLStringEv
     444__ZNK7WebCore11HistoryItem20getTransientPropertyERKNS_6StringE
     445__ZNK7WebCore11HistoryItem3urlEv
     446__ZNK7WebCore11HistoryItem4copyEv
     447__ZNK7WebCore11HistoryItem4iconEv
     448__ZNK7WebCore11HistoryItem5titleEv
     449__ZNK7WebCore11HistoryItem6targetEv
     450__ZNK7WebCore11HistoryItem8childrenEv
     451__ZNK7WebCore11HistoryItem9urlStringEv
     452__ZNK7WebCore11HistoryItem9viewStateEv
    369453__ZNK7WebCore12AtomicString16deprecatedStringEv
    370454__ZNK7WebCore12EventHandler17eventMayStartDragEP7NSEvent
     455__ZNK7WebCore12EventHandler20currentKeyboardEventEv
    371456__ZNK7WebCore12RenderObject25backslashAsCurrencySymbolEv
    372457__ZNK7WebCore13HitTestResult10isLiveLinkEv
     
    404489__ZNK7WebCore15ResourceRequest3urlEv
    405490__ZNK7WebCore15ResourceRequest7isEmptyEv
    406 __ZNK7WebCore16ResourceResponse13nsURLResponseEv
    407491__ZNK7WebCore16DeprecatedString11getNSStringEv
    408492__ZNK7WebCore16DeprecatedString2atEj
    409493__ZNK7WebCore16DeprecatedString3midEjj
     494__ZNK7WebCore16ResourceResponse13nsURLResponseEv
    410495__ZNK7WebCore16ResourceResponse3urlEv
    411496__ZNK7WebCore19SelectionController17isInPasswordFieldEv
     
    444529__ZNK7WebCore6Editor9canDeleteEv
    445530__ZNK7WebCore6String16deprecatedStringEv
     531__ZNK7WebCore6String6lengthEv
    446532__ZNK7WebCore6String7isEmptyEv
    447533__ZNK7WebCore7Element12getAttributeERKNS_13QualifiedNameE
    448534__ZNK7WebCore7IntRectcv7_NSRectEv
     535__ZNK7WebCore8Document11defaultViewEv
    449536__ZNK7WebCore8Document5frameEv
    450537__ZNK7WebCore8FrameMac14selectionImageEb
    451538__ZNK7WebCore8FrameMac31fontAttributesForSelectionStartEv
     539__ZNK7WebCore8IntPointcv8_NSPointEv
    452540__ZNK7WebCore9FloatRectcv7_NSRectEv
    453541__ZNK7WebCore9FrameTree12traverseNextEPKNS_5FrameE
     
    461549__ZNK7WebCore9Selection7toRangeEv
    462550__ZNK7WebCore9TimerBase8isActiveEv
    463 __ZN7WebCore11HistoryItem27releaseAllPendingPageCachesEv
    464 __ZN7WebCore11HistoryItem12setURLStringERKNS_6StringE
    465 __ZN7WebCore11HistoryItem12setViewStateEP11objc_object
    466 __ZN7WebCore11HistoryItem13setVisitCountEi
    467 __ZN7WebCore11HistoryItem15setHasPageCacheEb
    468 __ZN7WebCore11HistoryItem15setIsTargetItemEb
    469 __ZN7WebCore11HistoryItem17setAlternateTitleERKNS_6StringE
    470 __ZN7WebCore11HistoryItem18setRSSFeedReferrerERKNS_6StringE
    471 __ZN7WebCore11HistoryItem20setOriginalURLStringERKNS_6StringE
    472 __ZN7WebCore11HistoryItem30setAlwaysAttemptToUsePageCacheEb
    473 __ZN7WebCore11HistoryItem6setURLERKNS_4KURLE
    474 __ZN7WebCore11HistoryItem8formDataEv
    475 __ZN7WebCore11HistoryItem8setTitleERKNS_6StringE
    476 __ZN7WebCore11HistoryItem9setParentERKNS_6StringE
    477 __ZN7WebCore11HistoryItem9setTargetERKNS_6StringE
    478 __ZN7WebCore11HistoryItemC1ERKNS_4KURLERKNS_6StringES6_S6_
    479 __ZN7WebCore11HistoryItemC1ERKNS_6StringES3_d
    480 __ZN7WebCore11HistoryItemD1Ev
    481 __ZN7WebCore11HistoryItem20setTransientPropertyERKNS_6StringEP11objc_object
    482 __ZN7WebCore11HistoryItem23recurseToFindTargetItemEv
    483 __ZN7WebCore4Page9goForwardEv
    484 __ZNK7WebCore8IntPointcv8_NSPointEv
    485 __ZN7WebCore5equalEPKNS_10StringImplES2_
    486 __ZN7WebCore4Page15backForwardListEv
    487 __ZN7WebCoreeqERKNS_4KURLES2_
    488 __ZN7WebCore11HistoryItem14setScrollPointERKNS_8IntPointE
    489 __ZN7WebCore15BackForwardList10removeItemEPNS_11HistoryItemE
    490 __ZN7WebCore15BackForwardList11currentItemEv
    491 __ZN7WebCore15BackForwardList11forwardItemEv
    492 __ZN7WebCore15BackForwardList11itemAtIndexEi
    493 __ZN7WebCore15BackForwardList11setCapacityEi
    494 __ZN7WebCore15BackForwardList12containsItemEPNS_11HistoryItemE
    495 __ZN7WebCore15BackForwardList13backListCountEv
    496 __ZN7WebCore15BackForwardList13pageCacheSizeEv
    497 __ZN7WebCore15BackForwardList13usesPageCacheEv
    498 __ZN7WebCore15BackForwardList14clearPageCacheEv
    499 __ZN7WebCore15BackForwardList16forwardListCountEv
    500 __ZN7WebCore15BackForwardList16setPageCacheSizeEj
    501 __ZN7WebCore15BackForwardList17backListWithLimitEiRN3WTF6VectorINS1_6RefPtrINS_11HistoryItemEEELm0EEE
    502 __ZN7WebCore15BackForwardList20forwardListWithLimitEiRN3WTF6VectorINS1_6RefPtrINS_11HistoryItemEEELm0EEE
    503 __ZN7WebCore15BackForwardList5closeEv
    504 __ZN7WebCore15BackForwardList6closedEv
    505 __ZN7WebCore15BackForwardList6goBackEv
    506 __ZN7WebCore15BackForwardList7addItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
    507 __ZN7WebCore15BackForwardList7entriesEv
    508 __ZN7WebCore15BackForwardList8backItemEv
    509 __ZN7WebCore15BackForwardList8capacityEv
    510 __ZN7WebCore15BackForwardList9goForwardEv
    511 __ZN7WebCore15BackForwardListC1Ev
    512 __ZN7WebCore15BackForwardListD1Ev
    513 __ZN7WebCore15BackForwardList23setDefaultPageCacheSizeEj
    514 __ZN7WebCore11HistoryItemC1Ev
    515 __ZN7WebCore11HistoryItem12addChildItemEN3WTF10PassRefPtrIS0_EE
    516 __ZN7WebCore11HistoryItem22mergeAutoCompleteHintsEPS0_
    517 __ZNK7WebCore11HistoryItem10visitCountEv
    518 __ZNK7WebCore11HistoryItem11hasChildrenEv
    519 __ZNK7WebCore11HistoryItem12isTargetItemEv
    520 __ZNK7WebCore11HistoryItem14alternateTitleEv
    521 __ZNK7WebCore11HistoryItem15rssFeedReferrerEv
    522 __ZNK7WebCore11HistoryItem17originalURLStringEv
    523 __ZNK7WebCore11HistoryItem20getTransientPropertyERKNS_6StringE
    524 __ZNK7WebCore11HistoryItem3urlEv
    525 __ZNK7WebCore11HistoryItem4copyEv
    526 __ZNK7WebCore11HistoryItem4iconEv
    527 __ZNK7WebCore11HistoryItem5titleEv
    528 __ZNK7WebCore11HistoryItem6targetEv
    529 __ZNK7WebCore11HistoryItem9urlStringEv
    530 __ZN7WebCore11FrameLoader18currentHistoryItemEv
    531 __ZN7WebCore11FrameLoader21setCurrentHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
    532 __ZN7WebCore11FrameLoader25setProvisionalHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
    533 __ZNK7WebCore11HistoryItem17childItemWithNameERKNS_6StringE
    534 __ZN7WebCore11FrameLoader26saveDocumentAndScrollStateEv
    535 __ZN7WebCore4Page8goToItemEPNS_11HistoryItemENS_13FrameLoadTypeE
    536 __ZN7WebCore11FrameLoader22setPreviousHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
    537 __ZN7WebCore11FrameLoader36saveScrollPositionAndViewStateToItemEPNS_11HistoryItemE
    538 __ZNK7WebCore11HistoryItem11scrollPointEv
    539 __ZNK7WebCore11HistoryItem9viewStateEv
    540 __ZN7WebCore11HistoryItem18setLastVisitedTimeEd
    541 __ZNK7WebCore11HistoryItem15lastVisitedTimeEv
    542 __ZN7WebCore24notifyHistoryItemChangedE
    543 __ZN7WebCore15BackForwardList8goToItemEPNS_11HistoryItemE
    544 __ZNK7WebCore11HistoryItem8childrenEv
    545 __ZN7WebCore4Page6goBackEv
    546551_canonicalURL
    547552_stringIsFileURL
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r18560 r18610  
    2424                06027CAD0B1CBFC000884B2D /* ContextMenuItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 06027CAC0B1CBFC000884B2D /* ContextMenuItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
    2525                06027CB30B1CC03D00884B2D /* ContextMenuItemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 06027CB20B1CC03D00884B2D /* ContextMenuItemMac.mm */; };
     26                062287840B4DB322000C34DF /* FocusDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 062287830B4DB322000C34DF /* FocusDirection.h */; settings = {ATTRIBUTES = (Private, ); }; };
    2627                065AD4F50B0C2EDA005A2B1D /* ContextMenuClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 065AD4F20B0C2EDA005A2B1D /* ContextMenuClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
    2728                065AD4F60B0C2EDA005A2B1D /* ContextMenuController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 065AD4F30B0C2EDA005A2B1D /* ContextMenuController.cpp */; };
     
    5152                148CF65E0B00561400A997FC /* Screen.h in Headers */ = {isa = PBXBuildFile; fileRef = 148CF65D0B00561400A997FC /* Screen.h */; settings = {ATTRIBUTES = (Private, ); }; };
    5253                14993BE50B2F2B1C0050497F /* FocusController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14993BE30B2F2B1C0050497F /* FocusController.cpp */; };
    53                 14993BE60B2F2B1C0050497F /* FocusController.h in Headers */ = {isa = PBXBuildFile; fileRef = 14993BE40B2F2B1C0050497F /* FocusController.h */; };
     54                14993BE60B2F2B1C0050497F /* FocusController.h in Headers */ = {isa = PBXBuildFile; fileRef = 14993BE40B2F2B1C0050497F /* FocusController.h */; settings = {ATTRIBUTES = (Private, ); }; };
    5455                14C9A5EA0B3D105F005A0232 /* Settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14C9A5E90B3D105F005A0232 /* Settings.cpp */; };
    5556                14CF78A409F58CBF00EB3665 /* JSCSSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14CF78A309F58CBF00EB3665 /* JSCSSValue.cpp */; };
     
    30203021                06027CAC0B1CBFC000884B2D /* ContextMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ContextMenuItem.h; sourceTree = "<group>"; };
    30213022                06027CB20B1CC03D00884B2D /* ContextMenuItemMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ContextMenuItemMac.mm; sourceTree = "<group>"; };
     3023                062287830B4DB322000C34DF /* FocusDirection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FocusDirection.h; sourceTree = "<group>"; };
    30223024                065AD4F20B0C2EDA005A2B1D /* ContextMenuClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ContextMenuClient.h; sourceTree = "<group>"; };
    30233025                065AD4F30B0C2EDA005A2B1D /* ContextMenuController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ContextMenuController.cpp; sourceTree = "<group>"; };
     
    67676769                                14993BE40B2F2B1C0050497F /* FocusController.h */,
    67686770                                14993BE30B2F2B1C0050497F /* FocusController.cpp */,
     6771                                062287830B4DB322000C34DF /* FocusDirection.h */,
    67696772                                65BF02290974816300C43196 /* Frame.cpp */,
    67706773                                65BF022A0974816300C43196 /* Frame.h */,
     
    1093610939                                B25AE5600B49D6630074C726 /* RadialGradientAttributes.h in Headers */,
    1093710940                                A82422700B4A16C50084722B /* SVGAnimateMotionElement.h in Headers */,
     10941                                062287840B4DB322000C34DF /* FocusDirection.h in Headers */,
    1093810942                        );
    1093910943                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/WebCore/dom/Document.cpp

    r18500 r18610  
    15101510}
    15111511
    1512 Node* Document::nextFocusedNode(Node* fromNode, KeyboardEvent* event)
    1513 {
    1514     unsigned short fromTabIndex;
    1515 
    1516     if (!fromNode) {
    1517         // No starting node supplied; begin with the top of the document
    1518 
    1519         int lowestTabIndex = 65535;
    1520         for (Node* n = this; n; n = n->traverseNextNode())
    1521             if (n->isKeyboardFocusable(event) && n->tabIndex() > 0 && n->tabIndex() < lowestTabIndex)
    1522                 lowestTabIndex = n->tabIndex();
    1523 
    1524         if (lowestTabIndex == 65535)
    1525             lowestTabIndex = 0;
    1526 
    1527         // Go to the first node in the document that has the desired tab index
    1528         for (Node* n = this; n; n = n->traverseNextNode())
    1529             if (n->isKeyboardFocusable(event) && n->tabIndex() == lowestTabIndex)
    1530                 return n;
    1531 
    1532         return 0;
    1533     }
    1534 
    1535     fromTabIndex = fromNode->tabIndex();
    1536 
    1537     if (fromTabIndex == 0) {
    1538         // Just need to find the next selectable node after fromNode (in document order) that has a tab index of 0
    1539         Node* n;
    1540         for (n = fromNode->traverseNextNode(); n; n = n->traverseNextNode())
    1541             if (n->isKeyboardFocusable(event) && n->tabIndex() == 0)
    1542                 break;
    1543        
    1544         return n;
    1545     }
    1546    
    1547     // Find the lowest tab index out of all the nodes except fromNode, that is greater than or equal to fromNode's
    1548     // tab index. For nodes with the same tab index as fromNode, we are only interested in those that come after
    1549     // fromNode in document order.
    1550     // If we don't find a suitable tab index, the next focus node will be one with a tab index of 0.
    1551     unsigned short lowestSuitableTabIndex = 65535;
    1552 
    1553     bool reachedFromNode = false;
    1554     for (Node* n = this; n; n = n->traverseNextNode()) {
    1555         if (n == fromNode)
    1556             reachedFromNode = true;
    1557         else if (n->isKeyboardFocusable(event)
    1558                  && ((reachedFromNode && n->tabIndex() >= fromTabIndex)
    1559                      || (!reachedFromNode && n->tabIndex() > fromTabIndex)))
    1560             // We found a selectable node with a tab index at least as high as fromNode's. Keep searching though,
    1561             // as there may be another node which has a lower tab index but is still suitable for use.
    1562             lowestSuitableTabIndex = min(lowestSuitableTabIndex, n->tabIndex());
    1563     }
    1564 
    1565     if (lowestSuitableTabIndex == 65535) {
    1566         // No next node with a tab index -> just take first node with tab index of 0
    1567         Node* n;
    1568         for (n = this; n; n = n->traverseNextNode())
    1569             if (n->isKeyboardFocusable(event) && n->tabIndex() == 0)
    1570                 break;
    1571        
    1572         return n;
    1573     }
    1574 
    1575     // Search forwards from fromNode
    1576     for (Node* n = fromNode->traverseNextNode(); n; n = n->traverseNextNode())
    1577         if (n->isKeyboardFocusable(event) && n->tabIndex() == lowestSuitableTabIndex)
     1512static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
     1513{
     1514    // Search is inclusive of start
     1515    for (Node* n = start; n; n = n->traverseNextNode())
     1516        if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
    15781517            return n;
    1579 
    1580     // The next node isn't after fromNode, start from the beginning of the document
    1581     for (Node* n = this; n != fromNode; n = n->traverseNextNode())
    1582         if (n->isKeyboardFocusable(event) && n->tabIndex() == lowestSuitableTabIndex)
     1518   
     1519    return 0;
     1520}
     1521
     1522static Node* previousNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
     1523{
     1524    // Search is inclusive of start
     1525    for (Node* n = start; n; n = n->traversePreviousNode())
     1526        if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
    15831527            return n;
    1584 
    1585     ASSERT_NOT_REACHED();
     1528   
    15861529    return 0;
    15871530}
    15881531
    1589 Node* Document::previousFocusedNode(Node* fromNode, KeyboardEvent* event)
    1590 {
    1591     Node* lastNode;
    1592     for (lastNode = this; lastNode->lastChild(); lastNode = lastNode->lastChild());
    1593    
    1594     if (!fromNode) {
    1595         // No starting node supplied; begin with the very last node in the document
    1596 
    1597         int highestTabIndex = 0;
    1598         for (Node* n = lastNode; n; n = n->traversePreviousNode()) {
    1599             if (n->isKeyboardFocusable(event)) {
    1600                 if (n->tabIndex() == 0)
    1601                     return n;
    1602                 else if (n->tabIndex() > highestTabIndex)
    1603                     highestTabIndex = n->tabIndex();
    1604             }
    1605         }
    1606 
    1607         // No node with a tab index of 0; just go to the last node with the highest tab index
    1608         for (Node* n = lastNode; n; n = n->traversePreviousNode())
    1609             if (n->isKeyboardFocusable(event) && n->tabIndex() == highestTabIndex)
    1610                 return n;
    1611 
    1612         return 0;
    1613     }
    1614    
    1615     unsigned short fromTabIndex = fromNode->tabIndex();
    1616 
    1617     if (fromTabIndex == 0) {
    1618         // Find the previous selectable node before fromNode (in document order) that has a tab index of 0
    1619         Node* n;
    1620         for (n = fromNode->traversePreviousNode(); n; n = n->traversePreviousNode())
    1621             if (n->isKeyboardFocusable(event) && n->tabIndex() == 0)
    1622                 break;
    1623        
    1624         if (n)
    1625             return n;
    1626 
    1627         // No previous nodes with a 0 tab index, go to the last node in the document that has the highest tab index
    1628         int highestTabIndex = 0;
    1629         for (n = this; n; n = n->traverseNextNode())
    1630             if (n->isKeyboardFocusable(event) && n->tabIndex() > highestTabIndex)
    1631                 highestTabIndex = n->tabIndex();
    1632 
    1633         if (!highestTabIndex)
     1532static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
     1533{
     1534    // Search is inclusive of start
     1535    int winningTabIndex = SHRT_MAX + 1;
     1536    Node* winner = 0;
     1537    for (Node* n = start; n; n = n->traverseNextNode())
     1538        if (n->isKeyboardFocusable(event) && n->tabIndex() > tabIndex && n->tabIndex() < winningTabIndex) {
     1539            winner = n;
     1540            winningTabIndex = n->tabIndex();
     1541        }
     1542   
     1543    return winner;
     1544}
     1545
     1546static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
     1547{
     1548    // Search is inclusive of start
     1549    int winningTabIndex = 0;
     1550    Node* winner = 0;
     1551    for (Node* n = start; n; n = n->traversePreviousNode())
     1552        if (n->isKeyboardFocusable(event) && n->tabIndex() < tabIndex && n->tabIndex() > winningTabIndex) {
     1553            winner = n;
     1554            winningTabIndex = n->tabIndex();
     1555        }
     1556   
     1557    return winner;
     1558}
     1559
     1560Node* Document::nextFocusableNode(Node* start, KeyboardEvent* event)
     1561{
     1562    if (start) {
     1563        // First try to find a node with the same tabindex as start that comes after start in the document.
     1564        if (Node* winner = nextNodeWithExactTabIndex(start->traverseNextNode(), start->tabIndex(), event))
     1565            return winner;
     1566
     1567        if (start->tabIndex() == 0)
     1568            // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
    16341569            return 0;
    1635 
    1636         for (n = lastNode; n; n = n->traversePreviousNode())
    1637             if (n->isKeyboardFocusable(event) && n->tabIndex() == highestTabIndex)
    1638                 return n;
    1639 
    1640         ASSERT_NOT_REACHED();
    1641         return 0;
    1642     }
    1643    
    1644     // Find the lowest tab index out of all the nodes except fromNode, that is less than or equal to fromNode's
    1645     // tab index. For nodes with the same tab index as fromNode, we are only interested in those before
    1646     // fromNode.
    1647     // If we don't find a suitable tab index, then there will be no previous focus node.
    1648     unsigned short highestSuitableTabIndex = 0;
    1649 
    1650     bool reachedFromNode = false;
    1651     for (Node* n = this; n; n = n->traverseNextNode()) {
    1652         if (n->isKeyboardFocusable(event) &&
    1653             ((!reachedFromNode && (n->tabIndex() <= fromTabIndex)) ||
    1654              (reachedFromNode && (n->tabIndex() < fromTabIndex)))  &&
    1655             (n->tabIndex() > highestSuitableTabIndex) &&
    1656             (n != fromNode)) {
    1657 
    1658             // We found a selectable node with a tab index no higher than fromNode's. Keep searching though, as
    1659             // there may be another node which has a higher tab index but is still suitable for use.
    1660             highestSuitableTabIndex = n->tabIndex();
    1661         }
    1662 
    1663         if (n == fromNode)
    1664             reachedFromNode = true;
    1665     }
    1666 
    1667     if (highestSuitableTabIndex == 0)
    1668         // No previous node with a tab index. Since the order specified by HTML is nodes with tab index > 0
    1669         // first, this means that there is no previous node.
    1670         return 0;
    1671 
    1672     // Search backwards from fromNode
    1673     for (Node* n = fromNode->traversePreviousNode(); n; n = n->traversePreviousNode())
    1674         if (n->isKeyboardFocusable(event) && (n->tabIndex() == highestSuitableTabIndex))
    1675             return n;
    1676    
    1677     // The previous node isn't before fromNode, start from the end of the document
    1678     for (Node* n = lastNode; n != fromNode; n = n->traversePreviousNode())
    1679         if (n->isKeyboardFocusable(event) && (n->tabIndex() == highestSuitableTabIndex))
    1680             return n;
    1681 
    1682     ASSERT_NOT_REACHED();
    1683     return 0;
     1570    }
     1571
     1572    // Look for the first node in the document that:
     1573    // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
     1574    // 2) comes first in the document, if there's a tie.
     1575    if (Node* winner = nextNodeWithGreaterTabIndex(this, start ? start->tabIndex() : 0, event))
     1576        return winner;
     1577
     1578    // There are no nodes with a tabindex greater than start's tabindex,
     1579    // so find the first node with a tabindex of 0.
     1580    return nextNodeWithExactTabIndex(this, 0, event);
     1581}
     1582
     1583Node* Document::previousFocusableNode(Node* start, KeyboardEvent* event)
     1584{
     1585    Node* last;
     1586    for (last = this; last->lastChild(); last = last->lastChild())
     1587        ; // Empty loop.
     1588
     1589    // First try to find the last node in the document that comes before start and has the same tabindex as start.
     1590    // If start is null, find the last node in the document with a tabindex of 0.
     1591    Node* startingNode;
     1592    int startingTabIndex;
     1593    if (start) {
     1594        startingNode = start->traversePreviousNode();
     1595        startingTabIndex = start->tabIndex();
     1596    } else {
     1597        startingNode = last;
     1598        startingTabIndex = 0;
     1599    }
     1600
     1601    if (Node* winner = previousNodeWithExactTabIndex(startingNode, startingTabIndex, event))
     1602        return winner;
     1603
     1604    // There are no nodes before start with the same tabindex as start, so look for a node that:
     1605    // 1) has the highest non-zero tabindex (that is less than start's tabindex), and
     1606    // 2) comes last in the document, if there's a tie.
     1607    startingTabIndex = (start && start->tabIndex()) ? start->tabIndex() : SHRT_MAX;
     1608    return previousNodeWithLowerTabIndex(last, startingTabIndex, event);
    16841609}
    16851610
  • trunk/WebCore/dom/Document.h

    r18485 r18610  
    474474     * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
    475475     */
    476     Node* nextFocusedNode(Node* fromNode, KeyboardEvent*);
     476    Node* nextFocusableNode(Node* start, KeyboardEvent*);
    477477
    478478    /**
     
    487487     * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
    488488     */
    489     Node* previousFocusedNode(Node* fromNode, KeyboardEvent*);
     489    Node* previousFocusableNode(Node* start, KeyboardEvent*);
    490490
    491491    int nodeAbsIndex(Node*);
  • trunk/WebCore/dom/EventTargetNode.cpp

    r18592 r18610  
    3434#include "EventListener.h"
    3535#include "EventNames.h"
     36#include "FocusController.h"
    3637#include "Frame.h"
    3738#include "FrameView.h"
     
    563564        KeyboardEvent* keyEvent = static_cast<KeyboardEvent*>(event);
    564565        if (keyEvent->keyIdentifier() == "U+000009") {
    565             Frame* frame = document()->frame();
    566             if (frame && frame->view() && frame->eventHandler()->advanceFocus(keyEvent))
    567                 event->setDefaultHandled();
     566            if (Page* page = document()->page())
     567                if (page->focusController()->advanceFocus(keyEvent))
     568                    event->setDefaultHandled();
    568569        }
    569570    } else if (eventType == clickEvent) {
  • trunk/WebCore/dom/Node.h

    r18261 r18610  
    136136#endif
    137137    virtual bool isStyledElement() const { return false; }
     138    virtual bool isFrameOwnerElement() const { return false; }
    138139    virtual bool isAttributeNode() const { return false; }
    139140    virtual bool isTextNode() const { return false; }
     
    232233    virtual void setHovered(bool b = true) { m_hovered = b; }
    233234
    234     unsigned short tabIndex() const { return m_tabIndex; }
    235     void setTabIndex(unsigned short i) { m_tabIndex = i; }
     235    short tabIndex() const { return m_tabIndex; }
     236    void setTabIndex(short i) { m_tabIndex = i; }
    236237
    237238    /**
     
    446447    NodeListSet* m_nodeLists;
    447448
    448     unsigned short m_tabIndex : 15;
    449     bool m_hasTabIndex : 1;
     449    short m_tabIndex;
    450450
    451451    bool m_hasId : 1;
  • trunk/WebCore/html/HTMLAnchorElement.cpp

    r18417 r18610  
    390390}
    391391
    392 int HTMLAnchorElement::tabIndex() const
    393 {
    394     return getAttribute(tabindexAttr).toInt();
    395 }
    396 
    397392void HTMLAnchorElement::setTabIndex(int tabIndex)
    398393{
  • trunk/WebCore/html/HTMLAnchorElement.h

    r17674 r18610  
    7878    void setShape(const String&);
    7979
    80     int tabIndex() const;
    8180    void setTabIndex(int);
    8281
  • trunk/WebCore/html/HTMLAreaElement.cpp

    r17426 r18610  
    210210}
    211211
    212 int HTMLAreaElement::tabIndex() const
    213 {
    214     return getAttribute(tabindexAttr).toInt();
    215 }
    216 
    217212void HTMLAreaElement::setTabIndex(int tabIndex)
    218213{
  • trunk/WebCore/html/HTMLAreaElement.h

    r17399 r18610  
    7070    void setShape(const String&);
    7171
    72     int tabIndex() const;
    7372    void setTabIndex(int);
    7473
  • trunk/WebCore/html/HTMLElement.cpp

    r18328 r18610  
    4747using namespace HTMLNames;
    4848
     49using std::min;
     50using std::max;
     51
    4952HTMLElement::HTMLElement(const QualifiedName& tagName, Document *doc)
    5053    : StyledElement(tagName, doc)
     
    135138        indexstring = getAttribute(tabindexAttr);
    136139        if (indexstring.length())
    137             setTabIndex(indexstring.toInt());
     140            // Clamp tabindex to the range of 'short' to match Firefox's behavior.
     141            setTabIndex(max(static_cast<int>(std::numeric_limits<short>::min()), min(indexstring.toInt(), static_cast<int>(std::numeric_limits<short>::max()))));
    138142    } else if (attr->name() == langAttr) {
    139143        // FIXME: Implement
  • trunk/WebCore/html/HTMLFrameOwnerElement.h

    r18163 r18610  
    2727
    2828class Frame;
     29class KeyboardEvent;
    2930
    3031class HTMLFrameOwnerElement : public HTMLElement {
     
    3839    Document* contentDocument() const;
    3940
     41    virtual bool isFrameOwnerElement() const { return true; }
     42    virtual bool isKeyboardFocusable(KeyboardEvent*) const { return m_contentFrame; }
     43
    4044private:
    4145    friend class Frame;
  • trunk/WebCore/html/HTMLGenericFormElement.cpp

    r17958 r18610  
    258258}
    259259
    260 int HTMLGenericFormElement::tabIndex() const
    261 {
    262     return getAttribute(tabindexAttr).toInt();
    263 }
    264 
    265260void HTMLGenericFormElement::setTabIndex(int value)
    266261{
  • trunk/WebCore/html/HTMLGenericFormElement.h

    r18560 r18610  
    9999    virtual void setActivatedSubmit(bool flag) { }
    100100
    101     int tabIndex() const;
    102101    void setTabIndex(int);
    103102
  • trunk/WebCore/html/HTMLObjectElement.cpp

    r18163 r18610  
    441441}
    442442
    443 int HTMLObjectElement::tabIndex() const
    444 {
    445     return getAttribute(tabindexAttr).toInt();
    446 }
    447 
    448443void HTMLObjectElement::setTabIndex(int tabIndex)
    449444{
  • trunk/WebCore/html/HTMLObjectElement.h

    r18163 r18610  
    102102    void setStandby(const String&);
    103103
    104     int tabIndex() const;
    105104    void setTabIndex(int);
    106105
  • trunk/WebCore/page/Chrome.cpp

    r18302 r18610  
    7474}
    7575
     76bool Chrome::canTakeFocus(FocusDirection direction) const
     77{
     78    return m_client->canTakeFocus(direction);
     79}
     80
     81void Chrome::takeFocus(FocusDirection direction) const
     82{
     83    m_client->takeFocus(direction);
     84}
     85
    7686Page* Chrome::createWindow(const FrameLoadRequest& request) const
    7787{
  • trunk/WebCore/page/Chrome.h

    r18302 r18610  
    2222#define Chrome_h
    2323
     24#include "FocusDirection.h"
    2425#include <wtf/Forward.h>
    2526#include <wtf/RefPtr.h>
     
    3334    class Page;
    3435    class String;
     36   
    3537    struct FrameLoadRequest;
    3638   
     
    5153        void focus() const;
    5254        void unfocus() const;
     55
     56        bool canTakeFocus(FocusDirection) const;
     57        void takeFocus(FocusDirection) const;
    5358
    5459        Page* createWindow(const FrameLoadRequest&) const;
  • trunk/WebCore/page/ChromeClient.h

    r18302 r18610  
    2121#ifndef ChromeClient_h
    2222#define ChromeClient_h
     23
     24#include "FocusDirection.h"
    2325
    2426namespace WebCore {
     
    4547        virtual void focus() = 0;
    4648        virtual void unfocus() = 0;
     49
     50        virtual bool canTakeFocus(FocusDirection) = 0;
     51        virtual void takeFocus(FocusDirection) = 0;
    4752
    4853        virtual Page* createWindow(const FrameLoadRequest&) = 0;
  • trunk/WebCore/page/EventHandler.cpp

    r18417 r18610  
    982982}
    983983
    984 bool EventHandler::advanceFocus(KeyboardEvent* event)
    985 {
    986     Document* document = m_frame->document();
    987     if (!document)
    988         return false;
    989 
    990     Node* node = event->shiftKey()
    991         ? document->previousFocusedNode(document->focusedNode(), event)
    992         : document->nextFocusedNode(document->focusedNode(), event);
    993 
    994     if (!node)
    995         // FIXME: Need to support tabbing out of the document to the UI.
    996         return false;
    997 
    998     if (!node->isElementNode())
    999         // FIXME: May need a way to focus a document here.
    1000         return false;
    1001 
    1002     static_cast<Element*>(node)->focus();
    1003     return true;
    1004 }
    1005 
    1006984MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mev)
    1007985{
  • trunk/WebCore/page/EventHandler.h

    r18319 r18610  
    2727#define EventHandler_h
    2828
     29#include "FocusDirection.h"
    2930#include "PlatformMouseEvent.h"
    3031#include "ScrollTypes.h"
     
    6768struct HitTestRequest;
    6869
    69 enum SelectionDirection { SelectingNext, SelectingPrevious };
    70 
    7170extern const float LinkDragHysteresis;
    7271extern const float ImageDragHysteresis;
     
    9796    void setCapturingMouseEventsNode(PassRefPtr<Node>);
    9897
    99     bool advanceFocus(KeyboardEvent*);
    100 
    10198    bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
    10299    void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
     
    130127#if PLATFORM(MAC)
    131128
    132     NSView *nextKeyView(Node*, SelectionDirection);
    133     NSView *nextKeyViewInFrameHierarchy(Node*, SelectionDirection);
    134     static NSView *nextKeyView(Widget*, SelectionDirection);
     129    NSView *nextKeyView(Node*, FocusDirection);
     130    NSView *nextKeyViewInFrameHierarchy(Node*, FocusDirection);
     131    static NSView *nextKeyView(Widget*, FocusDirection);
    135132
    136133    PassRefPtr<KeyboardEvent> currentKeyboardEvent() const;
     
    224221
    225222    NSView *mouseDownViewIfStillGood();
    226     NSView *nextKeyViewInFrame(Node*, SelectionDirection, bool* focusCallResultedInViewBeingCreated = 0);
     223    NSView *nextKeyViewInFrame(Node*, FocusDirection, bool* focusCallResultedInViewBeingCreated = 0);
    227224#endif
    228225
  • trunk/WebCore/page/FocusController.cpp

    r18229 r18610  
    2828
    2929#include "AXObjectCache.h"
     30#include "Chrome.h"
    3031#include "Document.h"
    3132#include "Editor.h"
     
    3435#include "EventHandler.h"
    3536#include "EventNames.h"
     37#include "FocusDirection.h"
    3638#include "Frame.h"
    3739#include "FrameView.h"
     40#include "FrameTree.h"
     41#include "HTMLFrameOwnerElement.h"
     42#include "KeyboardEvent.h"
    3843#include "Page.h"
    3944#include "Range.h"
     
    8085}
    8186
     87static Node* deepFocusableNode(FocusDirection direction, Node* node, KeyboardEvent* event)
     88{
     89    // The node we found might be a HTMLFrameOwnerElement, so descend down the frame tree until we find either:
     90    // 1) a focusable node, or
     91    // 2) the deepest-nested HTMLFrameOwnerElement
     92    while (node && node->isFrameOwnerElement()) {
     93        HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(node);
     94        if (!owner->contentFrame())
     95            break;
     96
     97        Document* document = owner->contentFrame()->document();
     98        if (!document)
     99            break;
     100
     101        node = (direction == FocusDirectionForward)
     102            ? document->nextFocusableNode(0, event)
     103            : document->previousFocusableNode(0, event);
     104        if (!node) {
     105            node = owner;
     106            break;
     107        }
     108    }
     109
     110    return node;
     111}
     112
     113
     114bool FocusController::advanceFocus(KeyboardEvent* event)
     115{
     116    ASSERT(event);
     117   
     118    if (!focusedFrame()) {
     119        setFocusedFrame(m_page->mainFrame());
     120        if (Document* document = focusedFrame()->document())
     121            document->setFocusedNode(0);
     122
     123        return true;
     124    }
     125
     126    Frame* focusedFrame = this->focusedFrame();
     127    Document* document = focusedFrame->document();
     128    if (!document)
     129        return false;
     130
     131    FocusDirection direction = event->shiftKey() ? FocusDirectionBackward : FocusDirectionForward;
     132
     133    Node* node = (direction == FocusDirectionForward)
     134        ? document->nextFocusableNode(document->focusedNode(), event)
     135        : document->previousFocusableNode(document->focusedNode(), event);
     136           
     137    // If there's no focusable node to advance to, move up the frame tree until we find one.
     138    Frame* frame = focusedFrame;
     139    while (!node && frame) {
     140        Frame* parentFrame = frame->tree()->parent();
     141        if (!parentFrame)
     142            break;
     143
     144        Document* parentDocument = parentFrame->document();
     145        if (!parentDocument)
     146            break;
     147
     148        HTMLFrameOwnerElement* owner = frame->ownerElement();
     149        if (!owner)
     150            break;
     151
     152        node = (direction == FocusDirectionForward)
     153            ? parentDocument->nextFocusableNode(owner, event)
     154            : parentDocument->previousFocusableNode(owner, event);
     155
     156        frame = parentFrame;
     157    }
     158
     159    node = deepFocusableNode(direction, node, event);
     160
     161    if (!node) {
     162        // We didn't find a node to focus, so we should try to pass focus to Chrome.
     163        if (m_page->chrome()->canTakeFocus(direction)) {
     164            document->setFocusedNode(0);
     165            m_page->chrome()->takeFocus(direction);
     166            return true;
     167        }
     168
     169        // Chrome doesn't want focus, so we should wrap focus.
     170        if (Document* d = m_page->mainFrame()->document())
     171            node = (direction == FocusDirectionForward)
     172                ? d->nextFocusableNode(0, event)
     173                : d->previousFocusableNode(0, event);
     174
     175        node = deepFocusableNode(direction, node, event);
     176
     177        if (!node)
     178            return false;
     179    }
     180
     181    ASSERT(node);
     182
     183    if (node == document->focusedNode())
     184        // Focus wrapped around to the same node.
     185        return true;
     186
     187    if (!node->isElementNode())
     188        // FIXME: May need a way to focus a document here.
     189        return false;
     190
     191    if (node->isFrameOwnerElement()) {
     192        // We focus frames rather than frame owners.
     193        // FIXME: We should not focus frames that have no scrollbars, as focusing them isn't useful to the user.
     194        HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(node);
     195        if (!owner->contentFrame())
     196            return false;
     197
     198        document->setFocusedNode(0);
     199        setFocusedFrame(owner->contentFrame());
     200        return true;
     201    }
     202
     203    Document* newDocument = node->document();
     204
     205    if (newDocument != document)
     206        // Focus is going away from this document, so clear the focused node.
     207        document->setFocusedNode(0);
     208
     209    if (newDocument)
     210        setFocusedFrame(newDocument->frame());
     211
     212    static_cast<Element*>(node)->focus();
     213    return true;
     214}
     215
    82216} // namespace WebCore
  • trunk/WebCore/page/FocusController.h

    r18229 r18610  
    3434
    3535    class Frame;
     36    class KeyboardEvent;
    3637    class Node;
    3738    class Page;
    38    
     39
    3940    class FocusController {
    4041    public:
     
    4445        Frame* focusedFrame() const { return m_focusedFrame.get(); }
    4546        Frame* focusedOrMainFrame();
     47
     48        bool advanceFocus(KeyboardEvent*);
    4649
    4750    private:
  • trunk/WebCore/page/mac/EventHandlerMac.mm

    r18169 r18610  
    3333#include "EventNames.h"
    3434#include "FloatPoint.h"
     35#include "FocusController.h"
    3536#include "FoundationExtras.h"
    3637#include "FrameLoader.h"
     
    9495}
    9596
    96 NSView* EventHandler::nextKeyViewInFrame(Node* n, SelectionDirection direction, bool* focusCallResultedInViewBeingCreated)
     97NSView* EventHandler::nextKeyViewInFrame(Node* n, FocusDirection direction, bool* focusCallResultedInViewBeingCreated)
    9798{
    9899    Document* doc = m_frame->document();
     
    104105    RefPtr<Node> node = n;
    105106    for (;;) {
    106         node = direction == SelectingNext
    107             ? doc->nextFocusedNode(node.get(), event.get())
    108             : doc->previousFocusedNode(node.get(), event.get());
     107        node = (direction == FocusDirectionForward)
     108            ? doc->nextFocusableNode(node.get(), event.get())
     109            : doc->previousFocusableNode(node.get(), event.get());
    109110        if (!node)
    110111            return nil;
     
    140141}
    141142
    142 NSView *EventHandler::nextKeyViewInFrameHierarchy(Node* node, SelectionDirection direction)
     143NSView *EventHandler::nextKeyViewInFrameHierarchy(Node* node, FocusDirection direction)
    143144{
    144145    bool focusCallResultedInViewBeingCreated = false;
     
    170171}
    171172
    172 NSView *EventHandler::nextKeyView(Node* node, SelectionDirection direction)
     173NSView *EventHandler::nextKeyView(Node* node, FocusDirection direction)
    173174{
    174175    BEGIN_BLOCK_OBJC_EXCEPTIONS;
     
    179180
    180181    // Look at views from the top level part up, looking for a next key view that we can use.
    181     next = direction == SelectingNext
     182    next = (direction == FocusDirectionForward)
    182183        ? [Mac(m_frame)->bridge() nextKeyViewOutsideWebFrameViews]
    183184        : [Mac(m_frame)->bridge() previousKeyViewOutsideWebFrameViews];
     
    191192}
    192193
    193 NSView *EventHandler::nextKeyView(Widget* startingWidget, SelectionDirection direction)
     194NSView *EventHandler::nextKeyView(Widget* startingWidget, FocusDirection direction)
    194195{
    195196    WidgetClient* client = startingWidget->client();
     
    344345        [Mac(m_frame)->bridge() makeFirstResponder:view];
    345346    END_BLOCK_OBJC_EXCEPTIONS;
     347    if (Page* page = m_frame->page())
     348        page->focusController()->setFocusedFrame(m_frame);
    346349}
    347350
     
    380383    ASSERT([nodeView superview]);
    381384    NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentEvent locationInWindow] fromView:nil]];
    382     if (view == nil) {
    383         LOG_ERROR("KHTML says we hit a RenderWidget, but AppKit doesn't agree we hit the corresponding NSView");
     385    if (!view)
     386        // We probably hit the border of a RenderWidget
    384387        return true;
    385     }
    386388   
    387389    if ([Mac(m_frame)->bridge() firstResponder] == view) {
     
    783785    ASSERT([nodeView superview]);
    784786    NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentEvent locationInWindow] fromView:nil]];
    785 
    786     ASSERT(view);
     787    if (!view)
     788        // We probably hit the border of a RenderWidget
     789        return true;
     790
    787791    m_sendingEventToSubview = true;
    788792    [view scrollWheel:currentEvent];
  • trunk/WebCore/page/mac/WebCoreFrameBridge.mm

    r18601 r18610  
    732732    if (!doc)
    733733        return nil;
    734     return m_frame->eventHandler()->nextKeyView(doc->focusedNode(), SelectingNext);
     734    return m_frame->eventHandler()->nextKeyView(doc->focusedNode(), FocusDirectionForward);
    735735}
    736736
     
    740740    if (!doc)
    741741        return nil;
    742     return m_frame->eventHandler()->nextKeyView(doc->focusedNode(), SelectingPrevious);
     742    return m_frame->eventHandler()->nextKeyView(doc->focusedNode(), FocusDirectionBackward);
    743743}
    744744
     
    748748    if (!doc)
    749749        return nil;
    750     return m_frame->eventHandler()->nextKeyViewInFrameHierarchy(doc->focusedNode(), SelectingNext);
     750    return m_frame->eventHandler()->nextKeyViewInFrameHierarchy(doc->focusedNode(), FocusDirectionForward);
    751751}
    752752
     
    756756    if (!doc)
    757757        return nil;
    758     return m_frame->eventHandler()->nextKeyViewInFrameHierarchy(doc->focusedNode(), SelectingPrevious);
     758    return m_frame->eventHandler()->nextKeyViewInFrameHierarchy(doc->focusedNode(), FocusDirectionBackward);
    759759}
    760760
  • trunk/WebCore/platform/graphics/svg/SVGImage.cpp

    r18606 r18610  
    120120   
    121121    if (allDataReceived) {
    122         static ChromeClient* dummyChromeClient = new SVGEmptyCromeClient;
     122        static ChromeClient* dummyChromeClient = new SVGEmptyChromeClient;
    123123        static FrameLoaderClient* dummyFrameLoaderClient =  new SVGEmptyFrameLoaderClient;
    124124        static EditorClient* dummyEditorClient = new SVGEmptyEditorClient;
  • trunk/WebCore/platform/graphics/svg/SVGImageEmptyClients.h

    r18605 r18610  
    3232#include "ContextMenuClient.h"
    3333#include "EditorClient.h"
     34#include "FocusDirection.h"
    3435#include "FrameLoaderClient.h"
    3536
     
    4849namespace WebCore {
    4950
    50 class SVGEmptyCromeClient : public ChromeClient {
     51class SVGEmptyChromeClient : public ChromeClient {
    5152public:
    52     virtual ~SVGEmptyCromeClient() { }
     53    virtual ~SVGEmptyChromeClient() { }
    5354    virtual void chromeDestroyed() { }
    5455   
     
    6263    virtual void focus() { }
    6364    virtual void unfocus() { }
     65   
     66    virtual bool canTakeFocus(FocusDirection) { return false; }
     67    virtual void takeFocus(FocusDirection) { }
    6468   
    6569    virtual Page* createWindow(const FrameLoadRequest&) { return 0; }
  • trunk/WebKit/ChangeLog

    r18605 r18610  
     12007-01-04  Adam Roben  <aroben@apple.com>
     2
     3        Reviewed by Geoff.
     4
     5        Remove WebKit/AppKit from handling tabbing between subframes.
     6
     7        * WebCoreSupport/WebChromeClient.h: Added new ChromeClient methods for
     8        moving focus out of the WebView.
     9        * WebCoreSupport/WebChromeClient.mm: Ditto.
     10        (WebChromeClient::canTakeFocus):
     11        (WebChromeClient::takeFocus):
     12        * WebCoreSupport/WebFrameBridge.mm:
     13        (-[WebFrameBridge webView]): Added null-check of m_frame.
     14        * WebView/WebHTMLView.m: Removed -[WebHTMLView nextValidKeyView].
     15        (-[WebHTMLView _updateActiveState]): Changed to focus the frame if
     16        WebCore believes it to be the focused frame.
     17        (-[WebHTMLView becomeFirstResponder]): Rewrote to call into
     18        FocusController to place focus correctly within the WebView.
     19
    1202007-01-04  Anders Carlsson  <acarlsson@apple.com>
    221
  • trunk/WebKit/WebCoreSupport/WebChromeClient.h

    r18302 r18610  
    2828
    2929#import <WebCore/ChromeClient.h>
     30#import <WebCore/FocusDirection.h>
    3031#import <wtf/Forward.h>
    3132
     
    4849    virtual void focus();
    4950    virtual void unfocus();
     51   
     52    virtual bool canTakeFocus(WebCore::FocusDirection);
     53    virtual void takeFocus(WebCore::FocusDirection);
    5054
    5155    virtual WebCore::Page* createWindow(const WebCore::FrameLoadRequest&);
  • trunk/WebKit/WebCoreSupport/WebChromeClient.mm

    r18302 r18610  
    3232#import "WebFrameInternal.h"
    3333#import "WebFrameView.h"
     34#import "WebHTMLView.h"
    3435#import "WebNSURLRequestExtras.h"
    3536#import "WebUIDelegate.h"
     
    4445#import <wtf/PassRefPtr.h>
    4546
     47@interface NSView (AppKitSecretsWebBridgeKnowsAbout)
     48- (NSView *)_findLastViewInKeyViewLoop;
     49@end
     50
    4651using namespace WebCore;
    4752
     
    9095{
    9196    [[m_webView _UIDelegateForwarder] webViewUnfocus:m_webView];
     97}
     98
     99bool WebChromeClient::canTakeFocus(FocusDirection)
     100{
     101    // There's unfortunately no way to determine if we will become first responder again
     102    // once we give it up, so we just have to guess that we won't.
     103    return true;
     104}
     105
     106void WebChromeClient::takeFocus(FocusDirection direction)
     107{
     108    if (direction == FocusDirectionForward) {
     109        // Since we're trying to move focus out of m_webView, and because
     110        // m_webView may contain subviews within it, we ask it for the next key
     111        // view of the last view in its key view loop. This makes m_webView
     112        // behave as if it had no subviews, which is the behavior we want.
     113        NSView *lastView = [m_webView _findLastViewInKeyViewLoop];
     114        [[m_webView window] selectKeyViewFollowingView:lastView];
     115    } else
     116        [[m_webView window] selectKeyViewPrecedingView:m_webView];
    92117}
    93118
  • trunk/WebKit/WebCoreSupport/WebFrameBridge.mm

    r18541 r18610  
    118118- (WebView *)webView
    119119{
     120    if (!m_frame)
     121        return nil;
     122   
    120123    return kit(m_frame->page());
    121124}
  • trunk/WebKit/WebView/WebHTMLView.m

    r18597 r18610  
    7575#import <WebCore/EditorDeleteAction.h>
    7676#import <WebCore/EventHandler.h>
     77#import <WebCore/EventNames.h>
    7778#import <WebCore/ExceptionHandlers.h>
    7879#import <WebCore/FloatRect.h>
     80#import <WebCore/FocusController.h>
    7981#import <WebCore/FrameMac.h>
    8082#import <WebCore/HitTestResult.h>
     83#import <WebCore/KeyboardEvent.h>
    8184#import <WebCore/Page.h>
    8285#import <WebCore/Range.h>
     
    17391742    // so we can send focus and blur events.
    17401743
     1744    Frame* frame = core([self _frame]);
     1745    if (!frame)
     1746        return;
     1747   
     1748    Page* page = frame->page();
     1749    if (!page)
     1750        return;
     1751
    17411752    NSWindow *window = [self window];
    17421753    BOOL windowIsKey = [window isKeyWindow];
     
    17441755
    17451756    BOOL isActive = !_private->resigningFirstResponder && windowIsKey && (_private->descendantBecomingFirstResponder || [self _web_firstResponderCausesFocusDisplay]);
    1746 
    1747     if (Frame* coreFrame = core([self _frame])) {
    1748         coreFrame->setWindowHasFocus(windowOrSheetIsKey);
    1749         coreFrame->setIsActive(isActive);
    1750     }
     1757    frame->setIsActive(isActive);           
     1758
     1759    Frame* focusedFrame = page->focusController()->focusedOrMainFrame();
     1760    frame->setWindowHasFocus(frame == focusedFrame && windowOrSheetIsKey);
    17511761}
    17521762
     
    25422552    if (handledEvent && coreframe) {
    25432553        if (Page* page = coreframe->page()) {
    2544             ContextMenu* coreMenu = page->contextMenuController()->contextMenu();
    2545             NSArray* menuItems = coreMenu->platformDescription();
     2554            NSArray* menuItems = page->contextMenuController()->contextMenu()->platformDescription();
    25462555            NSMenu* menu = nil;
    25472556            if (menuItems && [menuItems count] > 0) {
     
    25612570                [menuItem setAction:@selector(_inspectElement:)];
    25622571                [menuItem setTitle:UI_STRING("Inspect Element", "Inspect Element context menu item")];
    2563                 [menuItem setRepresentedObject:[[[WebElementDictionary alloc] initWithHitTestResult:
    2564                     coreMenu->hitTestResult()] autorelease]];
     2572                NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
     2573                [menuItem setRepresentedObject:[self elementAtPoint:point]];
    25652574                [menu addItem:menuItem];
    25662575            }
     
    29882997}
    29892998
    2990 - (NSView *)nextValidKeyView
    2991 {
    2992     NSView *view = nil;
    2993     BOOL lookInsideWebFrameViews = YES;
    2994     if ([self isHiddenOrHasHiddenAncestor]) {
    2995         lookInsideWebFrameViews = NO;
    2996     } else if ([self _frame] == [[self _webView] mainFrame]) {
    2997         // Check for case where first responder is last frame in a frameset, and we are
    2998         // the top-level documentView.
    2999         NSResponder *firstResponder = [[self window] firstResponder];
    3000         if ((firstResponder != self) && [firstResponder isKindOfClass:[WebHTMLView class]] && ([(NSView *)firstResponder nextKeyView] == nil)) {
    3001             lookInsideWebFrameViews = NO;
    3002         }
    3003     }
    3004    
    3005     if (lookInsideWebFrameViews) {
    3006         view = [[self _bridge] nextKeyViewInsideWebFrameViews];
    3007     }
    3008    
    3009     if (view == nil) {
    3010         view = [super nextValidKeyView];
    3011         // If there's no next view wired up, we must be in the last subframe, or we are
    3012         // being called at an unusual time when the views have not yet been wired together.
    3013         // There's no direct link to the next valid key view; get it from the bridge.
    3014         // Note that view == self here when nextKeyView returns nil, due to AppKit oddness.
    3015         // We'll check for both nil and self in case the AppKit oddness goes away.
    3016         // WebFrameView has this same kind of logic for the previousValidKeyView case.
    3017         if (view == nil || view == self) {
    3018             view = [[self _bridge] nextValidKeyViewOutsideWebFrameViews];
    3019         }
    3020     }
    3021        
    3022     return view;
    3023 }
    3024 
    30252999- (NSView *)previousValidKeyView
    30263000{
     
    30353009- (BOOL)becomeFirstResponder
    30363010{
    3037     NSView *view = nil;
    3038     if (![[self _webView] _isPerformingProgrammaticFocus] && !_private->willBecomeFirstResponderForNodeFocus) {
    3039         switch ([[self window] keyViewSelectionDirection]) {
    3040             case NSDirectSelection:
    3041                 break;
    3042             case NSSelectingNext:
    3043                 view = [[self _bridge] nextKeyViewInsideWebFrameViews];
    3044                 break;
    3045             case NSSelectingPrevious:
    3046                 view = [[self _bridge] previousKeyViewInsideWebFrameViews];
    3047                 break;
    3048         }
    3049     }
     3011    NSSelectionDirection direction = NSDirectSelection;
     3012    if (![[self _webView] _isPerformingProgrammaticFocus] && !_private->willBecomeFirstResponderForNodeFocus)
     3013        direction = [[self window] keyViewSelectionDirection];
    30503014    _private->willBecomeFirstResponderForNodeFocus = NO;
    3051     if (view)
    3052         [[self window] makeFirstResponder:view];
     3015
    30533016    [self _updateActiveState];
    30543017    [self _updateFontPanel];
    3055     if (core([self _frame]))
    3056         core([self _frame])->editor()->setStartNewKillRingSequence(true);
     3018   
     3019    Frame* frame = core([self _frame]);
     3020    if (!frame)
     3021        return YES;
     3022   
     3023    frame->editor()->setStartNewKillRingSequence(true);
     3024
     3025    if (direction == NSDirectSelection)
     3026        return YES;
     3027
     3028    Page* page = frame->page();
     3029    if (!page)
     3030        return YES;
     3031
     3032    page->focusController()->setFocusedFrame(frame);
     3033    if (Document* document = frame->document())
     3034        document->setFocusedNode(0);
     3035   
     3036    BOOL createdFakeEvent = NO;
     3037    KeyboardEvent* currentEvent = frame->eventHandler()->currentKeyboardEvent().get();
     3038    if (!currentEvent) {
     3039        // If we didn't get an event (for example, when using eventSender.keyDown() under DumpRenderTree), just fake a Tab keydown.
     3040        currentEvent = new KeyboardEvent(EventNames::keydownEvent, true, true,
     3041                                         frame->document() ? frame->document()->defaultView() : 0,
     3042                                         "U+000009", KeyboardEvent::DOM_KEY_LOCATION_STANDARD, false, false, false, false, false);
     3043        createdFakeEvent = YES;
     3044    }
     3045   
     3046    page->focusController()->advanceFocus(currentEvent);
     3047   
     3048    if (createdFakeEvent)
     3049        delete currentEvent;
    30573050
    30583051    return YES;
Note: See TracChangeset for help on using the changeset viewer.