2009-03-17 Darin Adler <darin@apple.com>
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Mar 2009 00:06:25 +0000 (00:06 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Mar 2009 00:06:25 +0000 (00:06 +0000)
        Reviewed by Adele Peterson.

        Bug 24477: REGRESSION (r41467): Page Down key scrolls two pages
        https://bugs.webkit.org/show_bug.cgi?id=24477
        rdar://problem/6674184

        * WebView/WebHTMLView.mm:
        (responderChainRespondsToSelector): Added.
        (-[WebHTMLView doCommandBySelector:]): Set eventWasHandled based on whether we
        can find a responder that responds to this selector rather than always assuming
        the selector will not be handled.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@41793 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/mac/ChangeLog
WebKit/mac/WebView/WebHTMLView.mm

index 4801386..92ead93 100644 (file)
@@ -1,3 +1,17 @@
+2009-03-17  Darin Adler  <darin@apple.com>
+
+        Reviewed by Adele Peterson.
+
+        Bug 24477: REGRESSION (r41467): Page Down key scrolls two pages
+        https://bugs.webkit.org/show_bug.cgi?id=24477
+        rdar://problem/6674184
+
+        * WebView/WebHTMLView.mm:
+        (responderChainRespondsToSelector): Added.
+        (-[WebHTMLView doCommandBySelector:]): Set eventWasHandled based on whether we
+        can find a responder that responds to this selector rather than always assuming
+        the selector will not be handled.
+
 2009-03-17  Mark Rowe  <mrowe@apple.com>
 
         Fix the build.
index 36192cf..5466892 100644 (file)
@@ -5369,6 +5369,15 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
     coreFrame->editor()->setComposition(text, underlines, newSelRange.location, NSMaxRange(newSelRange));
 }
 
+static bool responderChainRespondsToSelector(NSResponder *firstResponder, SEL selector)
+{
+    for (NSResponder *responder = firstResponder; responder; responder = [responder nextResponder]) {
+        if ([responder respondsToSelector:selector])
+            return true;
+    }
+    return false;
+}
+
 - (void)doCommandBySelector:(SEL)selector
 {
     LOG(TextInput, "doCommandBySelector:\"%s\"", sel_getName(selector));
@@ -5402,14 +5411,16 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
             if (command.isSupported())
                 eventWasHandled = command.execute(event);
             else {
-                _private->selectorForDoCommandBySelector = selector;
                 // If WebKit does not support this command, we need to pass the selector to super.
+                _private->selectorForDoCommandBySelector = selector;
+                // We'll get the wrong value for eventWasHandled if respondsToSelector: doesn't
+                // exactly reflect what doCommandBySelector: does, for example an unusual class might
+                // not even pass the selector along to the next responder, or might handle a selector
+                // even though respondsToSelector: return NO. When that happens, there's a risk the
+                // event might end up handled twice. We know of no real-world examples of this.
+                eventWasHandled = responderChainRespondsToSelector(self, selector);
                 [super doCommandBySelector:selector];
                 _private->selectorForDoCommandBySelector = 0;
-                // In theory, [super doCommandBySelector:] can do some action that would cause WebKit 
-                // to need to consider the event handled.  But in practice, I've found no
-                // example of that happening and causing broken behavior.
-                eventWasHandled = false;
             }
         }