Commit 7e9be09c authored by sullivan's avatar sullivan
Browse files

Reviewed by Tim Omernick.

        - fixed <rdar://problem/3228554> We should enforce one selection per WebView instead of per window

        Note that this checkin does not mean that we will always maintain a selection in a WebView when
        the focus is elsewhere. Instead it means that there should never be more than one frame containing
        a selection in a WebView, and that it's possible to maintain a selection in a WebView when the focus
        is elsewhere.

        * WebView.subproj/WebView.m:
        (-[WebView searchFor:direction:caseSensitive:wrap:]):
        removed unnecessary and somewhat confusing comment
        (-[WebView selectedFrame]):
        now calls the extracted method -_focusedFrame
        (-[WebView _focusedFrame]):
        new method, extracted from -selectedFrame; returns frame containing first responder, if any
        (-[WebView _findSelectedFrameStartingFromFrame:skippingFrame:]):
        added skippingFrame parameter, which is never returned
        (-[WebView _findSelectedFrameSkippingFrame:]):
        new method, starts from main frame and passes a frame to skip
        (-[WebView _findSelectedFrame]):
        now calls _findSelectedFrameSkippingFrame:nil
        (-[WebView _selectedFrameDidChange]):
        new method, called by WebDocumentText protocol implementors; calls -deselectAll on frame that
        formerly displayed a selection, if any

        * WebView.subproj/WebViewInternal.h:
        added category WebDocumentSelectionExtras, with the one method _selectedFrameDidChange

        * WebView.subproj/WebHTMLView.m:
        (-[WebHTMLView becomeFirstResponder]):
        call -[WebView _selectedFrameDidChange]

        * WebView.subproj/WebPDFView.m:
        (-[WebPDFView becomeFirstResponder]):
        call -[WebView _selectedFrameDidChange]
        (-[WebPDFView resignFirstResponder]):
        deselect all unless webview says not to; note that this doesn't work in all cases due to:
        <rdar://problem/4265966> PDFs continue to show a (secondary) selection when the focus moves elsewhere

        * WebView.subproj/WebTextView.m:
        (-[WebTextView becomeFirstResponder]):
        call -[WebView _selectedFrameDidChange]
        (-[WebTextView resignFirstResponder]):
        deselect all unless webview says not to


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@10578 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 51a3ef3f
2005-09-20 John Sullivan <sullivan@apple.com>
Reviewed by Tim Omernick.
- fixed <rdar://problem/3228554> We should enforce one selection per WebView instead of per window
Note that this checkin does not mean that we will always maintain a selection in a WebView when
the focus is elsewhere. Instead it means that there should never be more than one frame containing
a selection in a WebView, and that it's possible to maintain a selection in a WebView when the focus
is elsewhere.
* WebView.subproj/WebView.m:
(-[WebView searchFor:direction:caseSensitive:wrap:]):
removed unnecessary and somewhat confusing comment
(-[WebView selectedFrame]):
now calls the extracted method -_focusedFrame
(-[WebView _focusedFrame]):
new method, extracted from -selectedFrame; returns frame containing first responder, if any
(-[WebView _findSelectedFrameStartingFromFrame:skippingFrame:]):
added skippingFrame parameter, which is never returned
(-[WebView _findSelectedFrameSkippingFrame:]):
new method, starts from main frame and passes a frame to skip
(-[WebView _findSelectedFrame]):
now calls _findSelectedFrameSkippingFrame:nil
(-[WebView _selectedFrameDidChange]):
new method, called by WebDocumentText protocol implementors; calls -deselectAll on frame that
formerly displayed a selection, if any
* WebView.subproj/WebViewInternal.h:
added category WebDocumentSelectionExtras, with the one method _selectedFrameDidChange
* WebView.subproj/WebHTMLView.m:
(-[WebHTMLView becomeFirstResponder]):
call -[WebView _selectedFrameDidChange]
* WebView.subproj/WebPDFView.m:
(-[WebPDFView becomeFirstResponder]):
call -[WebView _selectedFrameDidChange]
(-[WebPDFView resignFirstResponder]):
deselect all unless webview says not to; note that this doesn't work in all cases due to:
<rdar://problem/4265966> PDFs continue to show a (secondary) selection when the focus moves elsewhere
* WebView.subproj/WebTextView.m:
(-[WebTextView becomeFirstResponder]):
call -[WebView _selectedFrameDidChange]
(-[WebTextView resignFirstResponder]):
deselect all unless webview says not to
2005-09-20 Eric Seidel <eseidel@apple.com>
 
Reviewed by mjs.
......@@ -2947,14 +2947,13 @@ - (BOOL)becomeFirstResponder
if (view) {
[[self window] makeFirstResponder:view];
}
[[self _webView] _selectedFrameDidChange];
[self updateFocusState];
[self _updateFontPanel];
_private->startNewKillRingSequence = YES;
return YES;
}
// This approach could be relaxed when dealing with 3228554.
// Some alteration to the selection behavior was done to deal with 3672088.
- (BOOL)resignFirstResponder
{
BOOL resign = [super resignFirstResponder];
......
......@@ -40,6 +40,7 @@
#import <WebKit/WebPDFView.h>
#import <WebKit/WebUIDelegate.h>
#import <WebKit/WebView.h>
#import <WebKit/WebViewInternal.h>
#import <WebKit/WebViewPrivate.h>
#import <WebKit/WebPreferencesPrivate.h>
#import <WebKit/WebPDFRepresentation.h>
......@@ -724,6 +725,24 @@ - (void)writeSelectionWithPasteboardTypes:(NSArray *)types toPasteboard:(NSPaste
}
}
- (BOOL)becomeFirstResponder
{
BOOL result = [super becomeFirstResponder];
if (result) {
[[self _webView] _selectedFrameDidChange];
}
return result;
}
- (BOOL)resignFirstResponder
{
BOOL resign = [super resignFirstResponder];
if (resign && ![[self _web_parentWebView] maintainsInactiveSelection]) {
[self deselectAll];
}
return resign;
}
@end
@implementation PDFPrefUpdatingProxy
......
......@@ -34,13 +34,13 @@
#import <WebKit/WebDocumentInternal.h>
#import <WebKit/WebFramePrivate.h>
#import <WebKit/WebFrameInternal.h>
#import <WebKit/WebFrameView.h>
#import <WebKit/WebNSObjectExtras.h>
#import <WebKit/WebNSURLExtras.h>
#import <WebKit/WebNSViewExtras.h>
#import <WebKit/WebPreferences.h>
#import <WebKit/WebTextRendererFactory.h>
#import <WebKit/WebViewInternal.h>
#import <WebKit/WebViewPrivate.h>
#import <WebKit/WebTextRepresentation.h>
......@@ -345,11 +345,19 @@ - (NSMenu *)menuForEvent:(NSEvent *)event
return [webView _menuForElement:[self _elementAtWindowPoint:[event locationInWindow]] defaultItems:nil];
}
// This approach could be relaxed when dealing with 3228554
- (BOOL)becomeFirstResponder
{
BOOL result = [super becomeFirstResponder];
if (result) {
[[self _web_parentWebView] _selectedFrameDidChange];
}
return result;
}
- (BOOL)resignFirstResponder
{
BOOL resign = [super resignFirstResponder];
if (resign) {
if (resign && ![[self _web_parentWebView] maintainsInactiveSelection]) {
[self deselectAll];
}
return resign;
......
......@@ -206,12 +206,14 @@ @interface WebView (WebFileInternal)
- (void)_debugCheckForMultipleSelectedFrames;
#endif
- (WebFrame *)_findSelectedFrame;
- (WebFrame *)_findSelectedFrameSkippingFrame:(WebFrame *)frameToSkip;
- (WebFrame *)_selectedOrMainFrame;
- (WebBridge *)_bridgeForSelectedOrMainFrame;
- (BOOL)_isLoading;
- (WebFrameView *)_frameViewAtWindowPoint:(NSPoint)point;
- (WebBridge *)_bridgeAtPoint:(NSPoint)point;
- (void)_deselectFrame:(WebFrame *)frame;
- (WebFrame *)_focusedFrame;
- (BOOL)_frameIsSelected:(WebFrame *)frame;
- (void)_preflightSpellChecker;
- (BOOL)_continuousCheckingAllowed;
......@@ -2213,8 +2215,6 @@ - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL
startSearchView = searchView;
}
// Note at this point we are assuming the search will be done top-to-bottom,
// not starting at any selection that exists. See 3228554.
if ([searchView searchFor:string direction:forward caseSensitive:caseFlag wrap:NO]) {
WebFrame *newSelectedFrame = [(WebFrameView *)[searchView _web_superviewOfClass:[WebFrameView class]] webFrame];
if (newSelectedFrame != startFrame) {
......@@ -2517,18 +2517,14 @@ - (WebFrame *)selectedFrame
// If the first responder is a view in our tree, we get the frame containing the first responder.
// This is faster than searching the frame hierarchy, and will give us a result even in the case
// where the focused frame doesn't actually contain a selection.
NSResponder *resp = [[self window] firstResponder];
if (resp && [resp isKindOfClass:[NSView class]] && [(NSView *)resp isDescendantOf:self]) {
WebFrameView *frameView = [resp isKindOfClass:[WebFrameView class]]
? (WebFrameView *)resp
: (WebFrameView *)[(NSView *)resp _web_superviewOfClass:[WebFrameView class]];
ASSERT(frameView != nil);
WebFrame *focusedFrame = [self _focusedFrame];
if (focusedFrame != nil) {
#ifndef NDEBUG
WebFrame *frameWithSelection = [self _findSelectedFrame];
ASSERT(frameWithSelection == nil || frameWithSelection == [frameView webFrame]);
ASSERT(frameWithSelection == nil || frameWithSelection == focusedFrame);
[self _debugCheckForMultipleSelectedFrames];
#endif
return [frameView webFrame];
return focusedFrame;
}
// If the first responder is outside of our view tree, we search for a frame containing a selection.
......@@ -2971,6 +2967,20 @@ - (void)_setSelectWordBeforeMenuEvent:(BOOL)flag
@implementation WebView (WebFileInternal)
- (WebFrame *)_focusedFrame
{
NSResponder *resp = [[self window] firstResponder];
if (resp && [resp isKindOfClass:[NSView class]] && [(NSView *)resp isDescendantOf:self]) {
WebFrameView *frameView = [resp isKindOfClass:[WebFrameView class]]
? (WebFrameView *)resp
: (WebFrameView *)[(NSView *)resp _web_superviewOfClass:[WebFrameView class]];
ASSERT(frameView != nil);
return [frameView webFrame];
}
return nil;
}
- (BOOL)_frameIsSelected:(WebFrame *)frame
{
id documentView = [[frame frameView] documentView];
......@@ -2996,9 +3006,9 @@ - (void)_deselectFrame:(WebFrame *)frame
}
}
- (WebFrame *)_findSelectedFrameStartingFromFrame:(WebFrame *)frame
- (WebFrame *)_findSelectedFrameStartingFromFrame:(WebFrame *)frame skippingFrame:(WebFrame *)frameToSkip
{
if ([self _frameIsSelected:frame]) {
if (frame != frameToSkip && [self _frameIsSelected:frame]) {
return frame;
}
......@@ -3006,7 +3016,7 @@ - (WebFrame *)_findSelectedFrameStartingFromFrame:(WebFrame *)frame
int i;
int count = [frames count];
for (i = 0; i < count; i++) {
WebFrame *selectedChildFrame = [self _findSelectedFrameStartingFromFrame:[frames objectAtIndex:i]];
WebFrame *selectedChildFrame = [self _findSelectedFrameStartingFromFrame:[frames objectAtIndex:i] skippingFrame:frameToSkip];
if (selectedChildFrame != nil) {
return selectedChildFrame;
}
......@@ -3015,9 +3025,14 @@ - (WebFrame *)_findSelectedFrameStartingFromFrame:(WebFrame *)frame
return nil;
}
- (WebFrame *)_findSelectedFrameSkippingFrame:(WebFrame *)frameToSkip
{
return [self _findSelectedFrameStartingFromFrame:[self mainFrame] skippingFrame:frameToSkip];
}
- (WebFrame *)_findSelectedFrame
{
return [self _findSelectedFrameStartingFromFrame:[self mainFrame]];
return [self _findSelectedFrameSkippingFrame:nil];
}
#ifndef DEBUG
......@@ -3205,3 +3220,20 @@ - (BOOL)_performTextSizingSelector:(SEL)sel withObject:(id)arg onTrackingDocs:(B
}
@end
@implementation WebView (WebDocumentSelectionExtras)
- (void)_selectedFrameDidChange
{
// We rely on WebDocumentSelection protocol implementors to call this method when they become first
// responder. It would be nicer to just notice first responder changes here instead, but there's no
// notification sent when the first responder changes in general (Radar 2573089).
[self _deselectFrame:[self _findSelectedFrameSkippingFrame:[self _focusedFrame]]];
#ifndef NDEBUG
// While we're in the general area of selection and frames, check that there is only one now.
[self _debugCheckForMultipleSelectedFrames];
#endif
}
@end
......@@ -127,3 +127,8 @@
- (BOOL)_shouldEndEditingInDOMRange:(DOMRange *)range;
- (BOOL)_canPaste;
@end
@interface WebView (WebDocumentSelectionExtras)
// WebDocumentSelection protocol implementors should call this in becomeFirstResponder
- (void)_selectedFrameDidChange;
@end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment