Changeset 18187 in webkit
- Timestamp:
- Dec 12, 2006, 2:11:18 PM (18 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r18186 r18187 1 2006-12-12 Geoffrey Garen <ggaren@apple.com> 2 3 Reviewed by Adam Roben, Dave Hyatt, Darin Adler. 4 5 Factored focus control into a FocusController class. I inted to use this 6 class for handling window active state and the focused frame, as well. 7 8 Layout tests pass. 9 10 * WebCore.xcodeproj/project.pbxproj: 11 * dom/Document.cpp: 12 (WebCore::Document::view): 13 (WebCore::Document::page): New helper function. 14 * dom/Document.h: Moved setters before getters. 15 (WebCore::Document::hoverNode): 16 (WebCore::Document::activeNode): 17 * dom/Node.cpp: 18 (WebCore::Node::detach): Use the FocusController. 19 * page/FocusController.cpp: Added. 20 (WebCore::shouldFocus): renamed and refactored this helper function. 21 (WebCore::shouldUnfocus): ditto. 22 * page/FocusController.h: Added. 23 1 24 2006-12-12 Anders Carlsson <acarlsson@apple.com> 2 25 -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r18184 r18187 50 50 148AFDA60AF58360008CC700 /* ExceptionHandlers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 148AFDA40AF58360008CC700 /* ExceptionHandlers.mm */; }; 51 51 148CF65E0B00561400A997FC /* Screen.h in Headers */ = {isa = PBXBuildFile; fileRef = 148CF65D0B00561400A997FC /* Screen.h */; settings = {ATTRIBUTES = (Private, ); }; }; 52 14993BE50B2F2B1C0050497F /* FocusController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14993BE30B2F2B1C0050497F /* FocusController.cpp */; }; 53 14993BE60B2F2B1C0050497F /* FocusController.h in Headers */ = {isa = PBXBuildFile; fileRef = 14993BE40B2F2B1C0050497F /* FocusController.h */; }; 52 54 14CF78A409F58CBF00EB3665 /* JSCSSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14CF78A309F58CBF00EB3665 /* JSCSSValue.cpp */; }; 53 55 14CF78A609F58CD800EB3665 /* JSCSSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 14CF78A509F58CD800EB3665 /* JSCSSValue.h */; }; … … 3030 3032 148AFDA40AF58360008CC700 /* ExceptionHandlers.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ExceptionHandlers.mm; sourceTree = "<group>"; }; 3031 3033 148CF65D0B00561400A997FC /* Screen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Screen.h; sourceTree = "<group>"; }; 3034 14993BE30B2F2B1C0050497F /* FocusController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FocusController.cpp; sourceTree = "<group>"; }; 3035 14993BE40B2F2B1C0050497F /* FocusController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FocusController.h; sourceTree = "<group>"; }; 3032 3036 14CF787109F587CA00EB3665 /* CSSValue.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = CSSValue.idl; sourceTree = "<group>"; }; 3033 3037 14CF78A309F58CBF00EB3665 /* JSCSSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSCSSValue.cpp; sourceTree = "<group>"; }; … … 6696 6700 93C09A520B064DB3005ABD4D /* EventHandler.h */, 6697 6701 93C09A800B064F00005ABD4D /* EventHandler.cpp */, 6702 14993BE40B2F2B1C0050497F /* FocusController.h */, 6703 14993BE30B2F2B1C0050497F /* FocusController.cpp */, 6698 6704 65BF02290974816300C43196 /* Frame.cpp */, 6699 6705 65BF022A0974816300C43196 /* Frame.h */, … … 10841 10847 93E241FF0B2B4E4000C732A1 /* HTMLFrameOwnerElement.h in Headers */, 10842 10848 E11D51930B2E7A5F0056C188 /* Base64.h in Headers */, 10849 14993BE60B2F2B1C0050497F /* FocusController.h in Headers */, 10843 10850 ); 10844 10851 runOnlyForDeploymentPostprocessing = 0; … … 12161 12168 B25DFAAF0B2E2929000E6510 /* JSSVGMatrixCustom.cpp in Sources */, 12162 12169 E11D51940B2E7A5F0056C188 /* Base64.cpp in Sources */, 12170 14993BE50B2F2B1C0050497F /* FocusController.cpp in Sources */, 12163 12171 ); 12164 12172 runOnlyForDeploymentPostprocessing = 0; -
trunk/WebCore/dom/Document.cpp
r18175 r18187 46 46 #include "EventNames.h" 47 47 #include "ExceptionCode.h" 48 #include "FocusController.h" 48 49 #include "Frame.h" 49 50 #include "FrameLoader.h" … … 811 812 } 812 813 814 FrameView* Document::view() const 815 { 816 return m_view; 817 } 818 813 819 Frame* Document::frame() const 814 820 { 815 821 return m_view ? m_view->frame() : 0; 822 } 823 824 Page* Document::page() const 825 { 826 Frame* frame = this->frame(); 827 return frame ? frame->page() : 0; 816 828 } 817 829 … … 1944 1956 } 1945 1957 1958 void Document::focusedNodeDetached(Node* node) 1959 { 1960 Page* page = this->page(); 1961 if (!page) 1962 return; 1963 page->focusController()->focusedNodeDetached(node); 1964 } 1965 1946 1966 void Document::hoveredNodeDetached(Node* node) 1947 1967 { … … 1981 2001 bool Document::setFocusedNode(PassRefPtr<Node> node) 1982 2002 { 1983 Frame* frame = this->frame(); 1984 if (!frame) 1985 return false; 1986 1987 Page* page = frame->page(); 2003 Page* page = this->page(); 1988 2004 if (!page) 1989 2005 return false; 1990 2006 1991 return page-> setFocusedNode(node);2007 return page->focusController()->setFocusedNode(node); 1992 2008 } 1993 2009 1994 2010 Node* Document::focusedNode() const 1995 2011 { 1996 Frame* frame = this->frame(); 1997 if (!frame) 1998 return 0; 1999 2000 Page* page = frame->page(); 2012 Page* page = this->page(); 2001 2013 if (!page) 2002 2014 return 0; 2003 2015 2004 return page->focus edNode();2016 return page->focusController()->focusedNode(); 2005 2017 } 2006 2018 -
trunk/WebCore/dom/Document.h
r18175 r18187 75 75 class NodeIterator; 76 76 class NodeList; 77 class Page; 77 78 class PlatformMouseEvent; 78 79 class ProcessingInstruction; … … 279 280 bool takeStateForFormElement(AtomicStringImpl* name, AtomicStringImpl* type, String& state); 280 281 281 FrameView* view() const { return m_view; } 282 Frame* frame() const; 282 FrameView* view() const; // can be NULL 283 Frame* frame() const; // can be NULL 284 Page* page() const; // can be NULL 283 285 284 286 PassRefPtr<Range> createRange(); … … 403 405 void setSelectedStylesheetSet(const String&); 404 406 407 // Convenience functions for accessing the page's focused node. 405 408 bool setFocusedNode(PassRefPtr<Node>); 406 409 Node* focusedNode() const; 407 410 411 // Hover and active are still per-document, not per-page. 412 void setHoverNode(PassRefPtr<Node>); 408 413 Node* hoverNode() const { return m_hoverNode.get(); } 409 void setHoverNode(PassRefPtr<Node>); 414 415 void setActiveNode(PassRefPtr<Node>); 416 Node* activeNode() const { return m_activeNode.get(); } 417 418 void focusedNodeDetached(Node*); 410 419 void hoveredNodeDetached(Node*); 411 420 void activeChainNodeDetached(Node*); 412 413 Node* activeNode() const { return m_activeNode.get(); }414 void setActiveNode(PassRefPtr<Node>);415 421 416 422 // Updates for :target (CSS3 selector). -
trunk/WebCore/dom/Node.cpp
r18175 r18187 718 718 Document* doc = document(); 719 719 if (m_focused) 720 doc-> setFocusedNode(0);720 doc->focusedNodeDetached(this); 721 721 if (m_hovered) 722 722 doc->hoveredNodeDetached(this); -
trunk/WebCore/page/Page.cpp
r18175 r18187 22 22 #include "Page.h" 23 23 24 #include "AXObjectCache.h"25 24 #include "Chrome.h" 26 25 #include "ChromeClient.h" 27 26 #include "ContextMenuClient.h" 28 27 #include "ContextMenuController.h" 29 #include "Document.h"30 #include "Editor.h"31 28 #include "EditorClient.h" 32 #include "Element.h" 33 #include "Event.h" 34 #include "EventNames.h" 29 #include "FocusController.h" 35 30 #include "Frame.h" 36 31 #include "FrameLoader.h" 37 32 #include "FrameTree.h" 38 #include "FrameView.h"39 #include "RenderWidget.h"40 33 #include "SelectionController.h" 41 34 #include "StringHash.h" … … 52 45 static HashMap<String, HashSet<Page*>*>* frameNamespaces; 53 46 54 using namespace EventNames;55 56 static bool shouldAcquireEditingFocus(Node* node)57 {58 ASSERT(node);59 ASSERT(node->isContentEditable());60 61 Node* root = node->rootEditableElement();62 if (!root || !root->document()->frame())63 return false;64 65 return root->document()->frame()->editor()->shouldBeginEditing(rangeOfContents(root).get());66 }67 68 static bool shouldRelinquishEditingFocus(Node* node)69 {70 ASSERT(node);71 ASSERT(node->isContentEditable());72 73 Node* root = node->rootEditableElement();74 if (!root || !root->document()->frame())75 return false;76 77 return root->document()->frame()->editor()->shouldEndEditing(rangeOfContents(root).get());78 }79 80 static void clearSelectionIfNeeded(Node* oldFocusedNode, Node* newFocusedNode)81 {82 Frame* frame = oldFocusedNode ? oldFocusedNode->document()->frame() : 0;83 if (!frame)84 return;85 86 // Clear the selection when changing the focus node to null or to a node that is not87 // contained by the current selection.88 Node *startContainer = frame->selectionController()->start().node();89 if (!newFocusedNode || (startContainer && startContainer != newFocusedNode && !(startContainer->isDescendantOf(newFocusedNode)) && startContainer->shadowAncestorNode() != newFocusedNode))90 frame->selectionController()->clear();91 }92 93 static Widget* widgetForNode(Node* node)94 {95 if (!node)96 return 0;97 RenderObject* renderer = node->renderer();98 if (!renderer || !renderer->isWidget())99 return 0;100 return static_cast<RenderWidget*>(renderer)->widget();101 }102 103 47 Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient) 104 : m_dragCaretController(new SelectionController(0, true)) 105 , m_chrome(new Chrome(this, chromeClient)) 48 : m_chrome(new Chrome(this, chromeClient)) 49 , m_dragCaretController(new SelectionController(0, true)) 50 , m_focusController(new FocusController) 106 51 , m_contextMenuController(new ContextMenuController(this, contextMenuClient)) 107 52 , m_editorClient(editorClient) … … 169 114 } 170 115 171 bool Page::setFocusedNode(PassRefPtr<Node> newFocusedNode)172 {173 if (m_focusedNode == newFocusedNode)174 return true;175 176 if (m_focusedNode && m_focusedNode == m_focusedNode->rootEditableElement() && !shouldRelinquishEditingFocus(m_focusedNode.get()))177 return false;178 179 bool focusChangeBlocked = false;180 RefPtr<Node> oldFocusedNode = m_focusedNode;181 m_focusedNode = 0;182 clearSelectionIfNeeded(oldFocusedNode.get(), newFocusedNode.get());183 184 // Remove focus from the existing focus node (if any)185 if (oldFocusedNode && !oldFocusedNode->inDetach()) {186 if (oldFocusedNode->active())187 oldFocusedNode->setActive(false);188 189 oldFocusedNode->setFocus(false);190 191 // Dispatch a change event for text fields or textareas that have been edited192 RenderObject *r = static_cast<RenderObject*>(oldFocusedNode->renderer());193 if (r && (r->isTextArea() || r->isTextField()) && r->isEdited()) {194 EventTargetNodeCast(oldFocusedNode.get())->dispatchHTMLEvent(changeEvent, true, false);195 if ((r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer())))196 r->setEdited(false);197 }198 199 // Dispatch the blur event and let the node do any other blur related activities (important for text fields)200 EventTargetNodeCast(oldFocusedNode.get())->dispatchBlurEvent();201 202 if (m_focusedNode) {203 // handler shifted focus204 focusChangeBlocked = true;205 newFocusedNode = 0;206 }207 clearSelectionIfNeeded(oldFocusedNode.get(), newFocusedNode.get());208 EventTargetNodeCast(oldFocusedNode.get())->dispatchUIEvent(DOMFocusOutEvent);209 if (m_focusedNode) {210 // handler shifted focus211 focusChangeBlocked = true;212 newFocusedNode = 0;213 }214 clearSelectionIfNeeded(oldFocusedNode.get(), newFocusedNode.get());215 if ((oldFocusedNode == oldFocusedNode->document()) && oldFocusedNode->hasOneRef())216 return true;217 218 if (oldFocusedNode == oldFocusedNode->rootEditableElement())219 oldFocusedNode->document()->frame()->editor()->didEndEditing();220 }221 222 if (newFocusedNode) {223 if (newFocusedNode == newFocusedNode->rootEditableElement() && !shouldAcquireEditingFocus(newFocusedNode.get())) {224 // delegate blocks focus change225 focusChangeBlocked = true;226 goto SetFocusedNodeDone;227 }228 // Set focus on the new node229 m_focusedNode = newFocusedNode.get();230 231 // Dispatch the focus event and let the node do any other focus related activities (important for text fields)232 EventTargetNodeCast(m_focusedNode.get())->dispatchFocusEvent();233 234 if (m_focusedNode != newFocusedNode) {235 // handler shifted focus236 focusChangeBlocked = true;237 goto SetFocusedNodeDone;238 }239 EventTargetNodeCast(m_focusedNode.get())->dispatchUIEvent(DOMFocusInEvent);240 if (m_focusedNode != newFocusedNode) {241 // handler shifted focus242 focusChangeBlocked = true;243 goto SetFocusedNodeDone;244 }245 m_focusedNode->setFocus();246 247 if (m_focusedNode.get() == m_focusedNode->rootEditableElement())248 m_focusedNode->document()->frame()->editor()->didBeginEditing();249 250 // This only matters for searchfield251 if (m_focusedNode->document()->view()) {252 Widget* focusWidget = widgetForNode(m_focusedNode.get());253 if (focusWidget) {254 // Make sure a widget has the right size before giving it focus.255 // Otherwise, we are testing edge cases of the Widget code.256 // Specifically, in WebCore this does not work well for text fields.257 m_focusedNode->document()->updateLayout();258 // Re-get the widget in case updating the layout changed things.259 focusWidget = widgetForNode(m_focusedNode.get());260 }261 if (focusWidget)262 focusWidget->setFocus();263 else264 m_focusedNode->document()->view()->setFocus();265 }266 }267 268 #if PLATFORM(MAC)269 if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled())270 m_focusedNode->document()->axObjectCache()->handleFocusedUIElementChanged();271 #endif272 273 SetFocusedNodeDone:274 Document::updateDocumentsRendering();275 return !focusChangeBlocked;276 }277 278 116 const HashSet<Page*>* Page::frameNamespace() const 279 117 { -
trunk/WebCore/page/Page.h
r18175 r18187 37 37 class ContextMenuController; 38 38 class EditorClient; 39 class FocusController; 39 40 class Frame; 40 41 class FrameNamespace; … … 58 59 String groupName() const { return m_groupName; } 59 60 60 bool setFocusedNode(PassRefPtr<Node>);61 Node* focusedNode() const { return m_focusedNode.get(); }62 63 61 const HashSet<Page*>* frameNamespace() const; 64 62 static const HashSet<Page*>* frameNamespace(const String&); … … 71 69 static void setNeedsReapplyStylesForSettingsChange(Settings*); 72 70 71 Chrome* chrome() { return m_chrome.get(); } 73 72 SelectionController* dragCaretController() { return m_dragCaretController.get(); } 74 Chrome* chrome() { return m_chrome.get(); }73 FocusController* focusController() { return m_focusController.get(); } 75 74 ContextMenuController* contextMenuController() { return m_contextMenuController.get(); } 76 75 … … 85 84 86 85 private: 86 OwnPtr<Chrome> m_chrome; 87 87 OwnPtr<SelectionController> m_dragCaretController; 88 OwnPtr< Chrome> m_chrome;88 OwnPtr<FocusController> m_focusController; 89 89 OwnPtr<ContextMenuController> m_contextMenuController; 90 90
Note:
See TracChangeset
for help on using the changeset viewer.