Patch by Trey Matteson <trey@usa.net>
authorsullivan <sullivan@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Jul 2005 21:36:42 +0000 (21:36 +0000)
committersullivan <sullivan@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Jul 2005 21:36:42 +0000 (21:36 +0000)
        Reviewed by me.

        Fixed http://bugzilla.opendarwin.org/show_bug.cgi?id=4015
          PDF views should remember viewing mode, scroll position across back/forward
          Note this doesn't work within frames because of a PDFKit bug - see 4164
        Fixed http://bugzilla.opendarwin.org/show_bug.cgi?id=4091
          PDF views should keep a separate scaling factor from shared text scaling factor

        Basic idea #1 is that we now have a general mechanism for a WebDocView to save/restore some UI
        state to the WebHistoryItem.
        Basic idea #2 is that _WebDocumentTextSizing is expanded to allow for the case of a WebDocView
        keeping its own notion of a scaling factor.  WebPDFView's -_tracksCommonSizeFactor has justification.

        * History.subproj/WebHistoryItem.m:
        (-[WebHistoryItem setViewState:]):  New methods to hold PList of arbitrary WebView state
        (-[WebHistoryItem viewState]):
        * History.subproj/WebHistoryItemPrivate.h:
        * WebKit.xcodeproj/project.pbxproj:  Add Quartz to framework path so we can import PDFKit files
        * WebView.subproj/WebDocumentInternal.h:  New methods added to _WebDocumentTextSizing.
          Also the _ prefix is sufficient instead of _web_WebDocumentTextSizing.
          Added _WebDocumentViewState protocol.
        * WebView.subproj/WebFrame.m:
        (-[WebFrame _createItemTreeWithTargetFrame:clippedAtTarget:]):  Rename of save/restore methods.
        (-[WebFrame _detachFromParent]):  Ditto
        (-[WebFrame _transitionToCommitted:]):  Ditto
        (-[WebFrame _checkLoadCompleteForThisFrame]):  Ditto
        (-[WebFrame _loadItem:withLoadType:]):  Ditto
        (-[WebFrame _recursiveGoToItem:fromItem:withLoadType:]):  Ditto
        (-[WebFrame _saveViewStateToItem:]):  Call doc view to retrieve view state.
        (-[WebFrame _restoreViewState]):  Call doc view to set view state.
        (-[WebFrame _scrollToTop]):  Nuked dead code.
        (-[WebFrame _textSizeMultiplierChanged]):  This work now appears in WebView.
        (-[WebFrame _saveDocumentAndScrollState]):  Same rename, one code cleanup.
        (-[WebFrame _accumulateDocumentViews:]): Add our docview to the array, call kids.
        (-[WebFrame _documentViews]):  New helper to return all docviews.
        (-[WebFrame _didFirstLayout]):  Same name change.
        * WebView.subproj/WebFrameInternal.h:
        * WebView.subproj/WebFramePrivate.h:
        * WebView.subproj/WebHTMLView.m:  Removed redundant category decl.
        (-[WebHTMLView _makeTextSmaller:]):  Implement new protocol.
        (-[WebHTMLView _makeTextLarger:]):
        (-[WebHTMLView _makeTextStandardSize:]):
        (-[WebHTMLView _tracksCommonSizeFactor]):
        * WebView.subproj/WebPDFRepresentation.m:  Tweak #imports.
        * WebView.subproj/WebPDFView.h:
        * WebView.subproj/WebPDFView.m:
        (-[WebPDFView _menuItemsFromPDFKitForEvent:]):  No longer intercept context menu text sizing items.
        (-[WebPDFView setDataSource:]):  No longer track the WebView's scaling factor.
        (-[WebPDFView scrollPoint]):  Dig through PDFKit view tree to get real scroll position
        (-[WebPDFView setScrollPoint:]):  Ditto
        (-[WebPDFView viewState]):  Return bundle of viewing params
        (-[WebPDFView setViewState:]):  Restore bundle of viewing params
        (-[WebPDFView _makeTextSmaller:]):  Implement new text sizing protocol
        (-[WebPDFView _makeTextLarger:]):
        (-[WebPDFView _makeTextStandardSize:]):
        (-[WebPDFView _tracksCommonSizeFactor]):
        (-[WebPDFView _canMakeTextSmaller]):
        (-[WebPDFView _canMakeTextLarger]):
        (-[WebPDFView _canMakeTextStandardSize]):
        * WebView.subproj/WebTextView.m:
        (-[WebTextView _makeTextSmaller:]):  Implement new text sizing protocol
        (-[WebTextView _makeTextLarger:]):
        (-[WebTextView _makeTextStandardSize:]):
        (-[WebTextView _tracksCommonSizeFactor]):
        * WebView.subproj/WebView.m:
        (-[WebView setTextSizeMultiplier:]):  Calling docViews is now more complicates than just posting
           a notification to the frame.
        (-[WebView _performTextSizingSelector:withObject:onTrackingDocs:selForNonTrackingDocs:]):  Workhorse
           that sends the text sizing method to the right doc views.
        (-[WebView canMakeTextSmaller]):  Call workhorse.
        (-[WebView canMakeTextLarger]):  Ditto
        (-[WebView makeTextSmaller:]):  Ditto
        (-[WebView makeTextLarger:]):  Ditto
        (-[WebView canMakeTextStandardSize]):  Ditto
        (-[WebView makeTextStandardSize:]):  Ditto

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

14 files changed:
WebKit/ChangeLog
WebKit/History.subproj/WebHistoryItem.m
WebKit/History.subproj/WebHistoryItemPrivate.h
WebKit/WebKit.xcodeproj/project.pbxproj
WebKit/WebView.subproj/WebDocumentInternal.h
WebKit/WebView.subproj/WebFrame.m
WebKit/WebView.subproj/WebFrameInternal.h
WebKit/WebView.subproj/WebFramePrivate.h
WebKit/WebView.subproj/WebHTMLView.m
WebKit/WebView.subproj/WebPDFRepresentation.m
WebKit/WebView.subproj/WebPDFView.h
WebKit/WebView.subproj/WebPDFView.m
WebKit/WebView.subproj/WebTextView.m
WebKit/WebView.subproj/WebView.m

index c4f86f8..d33f9b0 100644 (file)
@@ -1,3 +1,82 @@
+2005-07-27  John Sullivan  <sullivan@apple.com>
+
+       Patch by Trey Matteson <trey@usa.net>
+        Reviewed by me.
+
+        Fixed http://bugzilla.opendarwin.org/show_bug.cgi?id=4015
+          PDF views should remember viewing mode, scroll position across back/forward
+          Note this doesn't work within frames because of a PDFKit bug - see 4164
+        Fixed http://bugzilla.opendarwin.org/show_bug.cgi?id=4091
+          PDF views should keep a separate scaling factor from shared text scaling factor
+
+        Basic idea #1 is that we now have a general mechanism for a WebDocView to save/restore some UI
+        state to the WebHistoryItem.
+        Basic idea #2 is that _WebDocumentTextSizing is expanded to allow for the case of a WebDocView
+        keeping its own notion of a scaling factor.  WebPDFView's -_tracksCommonSizeFactor has justification.
+
+        * History.subproj/WebHistoryItem.m:
+        (-[WebHistoryItem setViewState:]):  New methods to hold PList of arbitrary WebView state
+        (-[WebHistoryItem viewState]):
+        * History.subproj/WebHistoryItemPrivate.h:
+        * WebKit.xcodeproj/project.pbxproj:  Add Quartz to framework path so we can import PDFKit files
+        * WebView.subproj/WebDocumentInternal.h:  New methods added to _WebDocumentTextSizing.
+          Also the _ prefix is sufficient instead of _web_WebDocumentTextSizing.
+          Added _WebDocumentViewState protocol.
+        * WebView.subproj/WebFrame.m:
+        (-[WebFrame _createItemTreeWithTargetFrame:clippedAtTarget:]):  Rename of save/restore methods.
+        (-[WebFrame _detachFromParent]):  Ditto
+        (-[WebFrame _transitionToCommitted:]):  Ditto
+        (-[WebFrame _checkLoadCompleteForThisFrame]):  Ditto
+        (-[WebFrame _loadItem:withLoadType:]):  Ditto
+        (-[WebFrame _recursiveGoToItem:fromItem:withLoadType:]):  Ditto
+        (-[WebFrame _saveViewStateToItem:]):  Call doc view to retrieve view state.
+        (-[WebFrame _restoreViewState]):  Call doc view to set view state.
+        (-[WebFrame _scrollToTop]):  Nuked dead code.
+        (-[WebFrame _textSizeMultiplierChanged]):  This work now appears in WebView.
+        (-[WebFrame _saveDocumentAndScrollState]):  Same rename, one code cleanup.
+        (-[WebFrame _accumulateDocumentViews:]): Add our docview to the array, call kids.
+        (-[WebFrame _documentViews]):  New helper to return all docviews.
+        (-[WebFrame _didFirstLayout]):  Same name change.
+        * WebView.subproj/WebFrameInternal.h:
+        * WebView.subproj/WebFramePrivate.h:
+        * WebView.subproj/WebHTMLView.m:  Removed redundant category decl.
+        (-[WebHTMLView _makeTextSmaller:]):  Implement new protocol.
+        (-[WebHTMLView _makeTextLarger:]):
+        (-[WebHTMLView _makeTextStandardSize:]):
+        (-[WebHTMLView _tracksCommonSizeFactor]):
+        * WebView.subproj/WebPDFRepresentation.m:  Tweak #imports.
+        * WebView.subproj/WebPDFView.h:
+        * WebView.subproj/WebPDFView.m:
+        (-[WebPDFView _menuItemsFromPDFKitForEvent:]):  No longer intercept context menu text sizing items.
+        (-[WebPDFView setDataSource:]):  No longer track the WebView's scaling factor.
+        (-[WebPDFView scrollPoint]):  Dig through PDFKit view tree to get real scroll position
+        (-[WebPDFView setScrollPoint:]):  Ditto
+        (-[WebPDFView viewState]):  Return bundle of viewing params
+        (-[WebPDFView setViewState:]):  Restore bundle of viewing params
+        (-[WebPDFView _makeTextSmaller:]):  Implement new text sizing protocol
+        (-[WebPDFView _makeTextLarger:]):
+        (-[WebPDFView _makeTextStandardSize:]):
+        (-[WebPDFView _tracksCommonSizeFactor]):
+        (-[WebPDFView _canMakeTextSmaller]):
+        (-[WebPDFView _canMakeTextLarger]):
+        (-[WebPDFView _canMakeTextStandardSize]):
+        * WebView.subproj/WebTextView.m:
+        (-[WebTextView _makeTextSmaller:]):  Implement new text sizing protocol
+        (-[WebTextView _makeTextLarger:]):
+        (-[WebTextView _makeTextStandardSize:]):
+        (-[WebTextView _tracksCommonSizeFactor]):
+        * WebView.subproj/WebView.m:
+        (-[WebView setTextSizeMultiplier:]):  Calling docViews is now more complicates than just posting
+           a notification to the frame.
+        (-[WebView _performTextSizingSelector:withObject:onTrackingDocs:selForNonTrackingDocs:]):  Workhorse
+           that sends the text sizing method to the right doc views.
+        (-[WebView canMakeTextSmaller]):  Call workhorse.
+        (-[WebView canMakeTextLarger]):  Ditto
+        (-[WebView makeTextSmaller:]):  Ditto
+        (-[WebView makeTextLarger:]):  Ditto
+        (-[WebView canMakeTextStandardSize]):  Ditto
+        (-[WebView makeTextStandardSize:]):  Ditto
+
 2005-07-26  Justin Garcia  <justin.garcia@apple.com>
 
         Patch by Trey Matteson <trey@usa.net>
index 2b182eb..d8c301c 100644 (file)
@@ -79,6 +79,7 @@ NSString *WebHistoryItemChangedNotification = @"WebHistoryItemChangedNotificatio
     NSString *formReferrer;
     // info used to support RSS feeds
     NSString *RSSFeedReferrer;
+    id viewState;
 }
 @end
 
@@ -430,6 +431,18 @@ NSString *WebHistoryItemChangedNotification = @"WebHistoryItemChangedNotificatio
     _private->scrollPoint = scrollPoint;
 }
 
+- (void)setViewState:(id)statePList;
+{
+    id copy = [statePList copy];
+    [_private->viewState release];
+    _private->viewState = copy;
+}
+
+- (id)viewState
+{
+    return _private->viewState;
+}
+
 - (BOOL)isTargetItem
 {
     return _private->isTargetItem;
index e5cc4cb..91b4366 100644 (file)
@@ -57,6 +57,7 @@
 - (NSString *)formReferrer;
 - (NSString *)RSSFeedReferrer;
 - (int)visitCount;
+- (id)viewState;
 
 - (void)_mergeAutoCompleteHints:(WebHistoryItem *)otherItem;
 
@@ -72,6 +73,7 @@
 - (void)_setFormInfoFromRequest:(NSURLRequest *)request;
 - (void)setRSSFeedReferrer:(NSString *)referrer;
 - (void)setVisitCount:(int)count;
+- (void)setViewState:(id)statePList;
 
 - (NSArray *)children;
 - (void)addChildItem:(WebHistoryItem *)item;
index 61c1ac3..d58e48f 100644 (file)
                                        /System/Library/Frameworks/WebKit.framework/Frameworks,
                                        /System/Library/Frameworks/ApplicationServices.framework/Frameworks,
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Frameworks",
+                                       /System/Library/Frameworks/Quartz.framework/Frameworks,
                                        /System/Library/PrivateFrameworks,
                                );
                                GCC_ENABLE_OBJC_GC = YES;
                                        /System/Library/Frameworks/WebKit.framework/Frameworks,
                                        /System/Library/Frameworks/ApplicationServices.framework/Frameworks,
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Frameworks",
+                                       /System/Library/Frameworks/Quartz.framework/Frameworks,
                                        /System/Library/PrivateFrameworks,
                                );
                                GCC_ENABLE_OBJC_GC = YES;
                                        /System/Library/Frameworks/WebKit.framework/Frameworks,
                                        /System/Library/Frameworks/ApplicationServices.framework/Frameworks,
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Frameworks",
+                                       /System/Library/Frameworks/Quartz.framework/Frameworks,
                                        /System/Library/PrivateFrameworks,
                                );
                                GCC_ENABLE_OBJC_GC = YES;
                                        /System/Library/Frameworks/WebKit.framework/Frameworks,
                                        /System/Library/Frameworks/ApplicationServices.framework/Frameworks,
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Frameworks",
+                                       /System/Library/Frameworks/Quartz.framework/Frameworks,
                                        /System/Library/PrivateFrameworks,
                                );
                                GCC_ENABLE_OBJC_GC = YES;
index 16de340..219ec86 100644 (file)
 #import <WebKit/WebDocumentPrivate.h>
 
 /*!
-@protocol _web_WebDocumentTextSizing
-@discussion Optional protocol for making text larger and smaller 
+@protocol _WebDocumentTextSizing
+@discussion Optional protocol for making text larger and smaller.
 */
-@protocol _web_WebDocumentTextSizing <NSObject>
+@protocol _WebDocumentTextSizing <NSObject>
+
+// Methods to perform the actual commands
+- (IBAction)_makeTextSmaller:(id)sender;
+- (IBAction)_makeTextLarger:(id)sender;
+- (IBAction)_makeTextStandardSize:(id)sender;
+
+// Views that do text sizing come in two flavors.  Some will track the common textSizeMultiplier factor stored
+// in the WebView.  Others (see PDFView) keep their own scaling factor, but still want to play along loosely
+// with the smaller/larger commands, which in the user model operate across all frames of the WebView.
+- (BOOL)_tracksCommonSizeFactor;
+
+// Views that do not track the common size factor must answer for themselves if they are able to zoom in
+// or out.  Views that do track it are not sent these messages.
+- (BOOL)_canMakeTextSmaller;
+- (BOOL)_canMakeTextLarger;
+- (BOOL)_canMakeTextStandardSize;
 
-/*!
-@method _web_textSizeMultiplierChanged
-@abstract Called when the text size multiplier has been changed. -[WebView textSizeMultiplier] returns the current value.
-*/
-- (void)_web_textSizeMultiplierChanged;
 @end
 
 @protocol WebDocumentDragging <NSObject>
 @protocol WebDocumentElement <NSObject>
 - (NSDictionary *)elementAtPoint:(NSPoint)point;
 @end
+
+/* Used to save and restore state in the view, typically when going back/forward */
+@protocol _WebDocumentViewState <NSObject>
+- (NSPoint)scrollPoint;
+- (void)setScrollPoint:(NSPoint)p;
+- (id)viewState;
+- (void)setViewState:(id)statePList;
+@end
index 19f6119..940ad49 100644 (file)
@@ -176,8 +176,8 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
 - (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL;
 - (NSDictionary *)_actionInformationForLoadType:(WebFrameLoadType)loadType isFormSubmission:(BOOL)isFormSubmission event:(NSEvent *)event originalURL:(NSURL *)URL;
 
-- (void)_saveScrollPositionToItem:(WebHistoryItem *)item;
-- (void)_restoreScrollPosition;
+- (void)_saveScrollPositionAndViewStateToItem:(WebHistoryItem *)item;
+- (void)_restoreScrollPositionAndViewState;
 
 - (WebHistoryItem *)_createItem: (BOOL)useOriginal;
 - (WebHistoryItem *)_createItemTreeWithTargetFrame:(WebFrame *)targetFrame clippedAtTarget:(BOOL)doClip;
@@ -443,7 +443,7 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
 {
     WebHistoryItem *bfItem = [self _createItem: [self parentFrame]?YES:NO];
 
-    [self _saveScrollPositionToItem:[_private previousItem]];
+    [self _saveScrollPositionAndViewStateToItem:[_private previousItem]];
     if (!(doClip && self == targetFrame)) {
         // save frame state for items that aren't loading (khtml doesn't save those)
         [_private->bridge saveDocumentState];
@@ -609,7 +609,7 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
     _private->bridge = nil;
 
     [self stopLoading];
-    [self _saveScrollPositionToItem:[_private currentItem]];
+    [self _saveScrollPositionAndViewStateToItem:[_private currentItem]];
 
     [bridge closeURL];
 
@@ -781,7 +781,7 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
             case WebFrameLoadTypeIndexedBackForward:
                 if ([[self webView] backForwardList]) {
                     // Must grab the current scroll position before disturbing it
-                    [self _saveScrollPositionToItem:[_private previousItem]];
+                    [self _saveScrollPositionAndViewStateToItem:[_private previousItem]];
                     
                     // Create a document view for this document, or used the cached view.
                     if (pageCache){
@@ -802,7 +802,7 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
                 // FIXME: rjw sez this cache clearing is no longer needed
                 [currItem setHasPageCache:NO];
                 if (loadType == WebFrameLoadTypeReload) {
-                    [self _saveScrollPositionToItem:currItem];
+                    [self _saveScrollPositionAndViewStateToItem:currItem];
                 }
                 NSURLRequest *request = [ds request];
                 if ([request _webDataRequestUnreachableURL] == nil) {
@@ -1181,7 +1181,7 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
                     case WebFrameLoadTypeBack:
                     case WebFrameLoadTypeIndexedBackForward:
                     case WebFrameLoadTypeReload:
-                        [self _restoreScrollPosition];
+                        [self _restoreScrollPositionAndViewState];
                         break;
 
                     case WebFrameLoadTypeStandard:
@@ -1345,7 +1345,7 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
         [self _loadURL:itemURL referrer:[[[self dataSource] request] HTTPReferrer] loadType:loadType target:nil triggeringEvent:nil form:nil formValues:nil];
 #endif
         // must do this maintenance here, since we don't go through a real page reload
-        [self _saveScrollPositionToItem:[_private currentItem]];
+        [self _saveScrollPositionAndViewStateToItem:[_private currentItem]];
         // FIXME: form state might want to be saved here too
 
         // FIXME: Perhaps we can use scrollToAnchorWithURL here instead and remove the older scrollToAnchor:?
@@ -1355,7 +1355,7 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
     
         // must do this maintenance here, since we don't go through a real page reload
         [_private setCurrentItem:item];
-        [self _restoreScrollPosition];
+        [self _restoreScrollPositionAndViewState];
 
         // Fake the URL change by updating the datasource's request.  This will no longer
         // be necessary if we do the better fix described above.
@@ -1480,14 +1480,14 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
         // Save form state (works from currentItem, since prevItem is nil)
         ASSERT(![_private previousItem]);
         [_private->bridge saveDocumentState];
-        [self _saveScrollPositionToItem:[_private currentItem]];
+        [self _saveScrollPositionAndViewStateToItem:[_private currentItem]];
         
         [_private setCurrentItem:item];
 
         // Restore form state (works from currentItem)
         [_private->bridge restoreDocumentState];
         // Restore the scroll position (taken in favor of going back to the anchor)
-        [self _restoreScrollPosition];
+        [self _restoreScrollPositionAndViewState];
         
         NSArray *childItems = [item children];
         int numChildItems = childItems ? [childItems count] : 0;
@@ -2078,14 +2078,26 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
     [[_private currentItem] setTitle:title];
 }
 
-- (void)_saveScrollPositionToItem:(WebHistoryItem *)item
+- (void)_saveScrollPositionAndViewStateToItem:(WebHistoryItem *)item
 {
     if (item) {
-        NSView *clipView = [[[self frameView] documentView] superview];
+        NSView <WebDocumentView> *docView = [[self frameView] documentView];
+        NSView *parent = [docView superview];
         // we might already be detached when this is called from detachFromParent, in which
         // case we don't want to override real data earlier gathered with (0,0)
-        if (clipView) {
-            [item setScrollPoint:[clipView bounds].origin];
+        if (parent) {
+            NSPoint point;
+            if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {
+                // The view has it's own idea of where it is scrolled to, perhaps because it contains its own
+                // ScrollView instead of using the one provided by the WebFrame
+                point = [(id <_WebDocumentViewState>)docView scrollPoint];
+                [item setViewState:[(id <_WebDocumentViewState>)docView viewState]];
+            } else {
+                // Parent is the clipview of the DynamicScrollView the WebFrame installs
+                ASSERT([parent isKindOfClass:[NSClipView class]]);
+                point = [parent bounds].origin;
+            }
+            [item setScrollPoint:point];
         }
     }
 }
@@ -2102,27 +2114,21 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
        fails.  We then successfully restore it when the layout happens.
  */
 
-- (void)_restoreScrollPosition
+- (void)_restoreScrollPositionAndViewState
 {
     ASSERT([_private currentItem]);
-    [[[self frameView] documentView] scrollPoint:[[_private currentItem] scrollPoint]];
-}
-
-- (void)_scrollToTop
-{
-    [[[self frameView] documentView] scrollPoint: NSZeroPoint];
-}
-
-- (void)_textSizeMultiplierChanged
-{
-    NSView <WebDocumentView> *view = [[self frameView] documentView];
-    if ([view conformsToProtocol:@protocol(_web_WebDocumentTextSizing)]) {
-        [(NSView <_web_WebDocumentTextSizing> *)view _web_textSizeMultiplierChanged];
+    NSView <WebDocumentView> *docView = [[self frameView] documentView];
+    NSPoint point = [[_private currentItem] scrollPoint];
+    if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {        
+        id state = [[_private currentItem] viewState];
+        if (state) {
+            [(id <_WebDocumentViewState>)docView setViewState:state];
+        }
+        
+        [(id <_WebDocumentViewState>)docView setScrollPoint:point];
+    } else {
+        [docView scrollPoint:point];
     }
-
-    // It's OK to use the internal version because this method is
-    // guaranteed not to change the set of frames.
-    [[self _internalChildFrames] makeObjectsPerformSelector:@selector(_textSizeMultiplierChanged)];
 }
 
 - (void)_defersCallbacksChanged
@@ -2309,16 +2315,11 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
 - (void)_saveDocumentAndScrollState
 {
     [_private->bridge saveDocumentState];
-    [self _saveScrollPositionToItem:[_private currentItem]];
+    [self _saveScrollPositionAndViewStateToItem:[_private currentItem]];
 
     // It's OK to use the internal version because this method is
     // guaranteed not to change the set of frames.
-    NSArray *frames = [self _internalChildFrames];
-    int count = [frames count];
-    int i;
-    for (i = 0; i < count; i++) {
-        [[frames objectAtIndex:i] _saveDocumentAndScrollState];
-    }
+    [[self _internalChildFrames] makeObjectsPerformSelector:@selector(_saveDocumentAndScrollState)];
 }
 
 // Called after the FormsDelegate is done processing willSubmitForm:
@@ -2585,6 +2586,22 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
 
 @implementation WebFrame (WebInternal)
 
+- (void)_accumulateDocumentViews:(NSMutableArray *)result
+{
+    id docView = [[self frameView] documentView];
+    if (docView) {
+        [result addObject:docView];
+    }
+    [_private->children makeObjectsPerformSelector:@selector(_accumulateDocumentViews:) withObject:result];
+}
+
+- (NSArray *)_documentViews
+{
+    NSMutableArray *result = [NSMutableArray array];
+    [self _accumulateDocumentViews:result];
+    return result;
+}
+
 - (void)_updateDrawsBackground
 {
     BOOL drawsBackground = [[self webView] drawsBackground];
@@ -2719,7 +2736,7 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
             loadType == WebFrameLoadTypeBack ||
             loadType == WebFrameLoadTypeIndexedBackForward)
         {
-            [self _restoreScrollPosition];
+            [self _restoreScrollPositionAndViewState];
         }
     }
 }
index 59bc8f8..763948b 100644 (file)
@@ -37,6 +37,8 @@
 - (id)_internalLoadDelegate;
 - (void)_unmarkAllMisspellings;
 - (void)_didFirstLayout;
+// Note that callers should not perform any ops on these views that could change the set of frames
+- (NSArray *)_documentViews;
 
 - (NSURLRequest *)_requestFromDelegateForRequest:(NSURLRequest *)request identifier:(id *)identifier error:(NSError **)error;
 - (void)_sendRemainingDelegateMessagesWithIdentifier:(id)identifier response:(NSURLResponse *)response length:(unsigned)length error:(NSError *)error;
index 85fc175..c7bb332 100644 (file)
@@ -180,8 +180,6 @@ extern NSString *WebPageCacheDocumentViewKey;
 - (void)_clientRedirectedTo:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date lockHistory:(BOOL)lockHistory isJavaScriptFormAction:(BOOL)isJavaScriptFormAction;
 - (void)_clientRedirectCancelled:(BOOL)cancelWithLoadInProgress;
 
-- (void)_textSizeMultiplierChanged;
-
 - (void)_defersCallbacksChanged;
 
 - (void)_viewWillMoveToHostWindow:(NSWindow *)hostWindow;
index fe7abeb..305fec2 100644 (file)
@@ -169,7 +169,7 @@ void *_NSSoftLinkingGetFrameworkFuncPtr(NSString *inUmbrellaFrameworkName,
                                         const struct mach_header **ioCachedFrameworkImageHeaderPtr);
 
 
-@interface WebHTMLView (WebTextSizing) <_web_WebDocumentTextSizing>
+@interface WebHTMLView (WebTextSizing) <_WebDocumentTextSizing>
 @end
 
 @interface WebHTMLView (WebHTMLViewFileInternal)
@@ -1688,10 +1688,6 @@ static WebHTMLView *lastHitView = nil;
 
 @end
 
-
-@interface WebHTMLView (TextSizing) <_web_WebDocumentTextSizing>
-@end
-
 @interface NSArray (WebHTMLView)
 - (void)_web_makePluginViewsPerformSelector:(SEL)selector withObject:(id)object;
 @end
@@ -4773,11 +4769,31 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
 
 @implementation WebHTMLView (WebTextSizing)
 
-- (void)_web_textSizeMultiplierChanged
+- (IBAction)_makeTextSmaller:(id)sender
+{
+    [self _updateTextSizeMultiplier];
+}
+
+- (IBAction)_makeTextLarger:(id)sender
+{
+    [self _updateTextSizeMultiplier];
+}
+
+- (IBAction)_makeTextStandardSize:(id)sender
 {
     [self _updateTextSizeMultiplier];
 }
 
+- (BOOL)_tracksCommonSizeFactor
+{
+    return YES;
+}
+
+// never sent because we track the common size factor
+- (BOOL)_canMakeTextSmaller          {   ASSERT_NOT_REACHED(); return NO;    }
+- (BOOL)_canMakeTextLarger           {   ASSERT_NOT_REACHED(); return NO;    }
+- (BOOL)_canMakeTextStandardSize     {   ASSERT_NOT_REACHED(); return NO;    }
+
 @end
 
 @implementation NSArray (WebHTMLView)
index ee74a7e..5092016 100644 (file)
@@ -35,7 +35,8 @@
 #import <WebKit/WebPDFRepresentation.h>
 #import <WebKit/WebPDFView.h>
 
-#import <Quartz/Quartz.h>
+#import <PDFKit/PDFDocument.h>
+#import <PDFKit/PDFView.h>
 
 @implementation WebPDFRepresentation
 
index 82fb844..f20b1b0 100644 (file)
 @class PDFView;
 @class WebDataSource;
 
-@protocol _web_WebDocumentTextSizing;
+@protocol _WebDocumentTextSizing;
+@protocol _WebDocumentViewState;
 @protocol WebDocumentSelection;
 @protocol WebDocumentElement;
 
-@interface WebPDFView : NSView <WebDocumentView, WebDocumentSearching, WebDocumentText, _web_WebDocumentTextSizing, WebDocumentSelection, WebDocumentElement>
+@interface WebPDFView : NSView <WebDocumentView, WebDocumentSearching, WebDocumentText, WebDocumentSelection, WebDocumentElement, _WebDocumentViewState, _WebDocumentTextSizing>
 {
     PDFView *PDFSubview;
     WebDataSource *dataSource;
index febef5b..a57aca7 100644 (file)
@@ -45,7 +45,7 @@
 #import <WebKit/WebViewPrivate.h>
 
 #import <WebKitSystemInterface.h>
-#import <Quartz/Quartz.h>
+#import <PDFKit/PDFKit.h>
 
 // QuartzPrivate.h doesn't include the PDFKit private headers, so we can't get at PDFViewPriv.h. (3957971)
 // Even if that was fixed, we'd have to tweak compile options to include QuartzPrivate.h. (3957839)
@@ -246,26 +246,6 @@ static void applicationInfoForMIMEType(NSString *type, NSString **name, NSImage
         } else {
             ERROR("PDF context menu item %@ came with tag %d, so no WebKit tag was applied. This could mean that the item doesn't appear in clients such as Safari.", [itemCopy title], [itemCopy tag]);
         }
-        
-        // Intercept some of these menu items for better WebKit integration.
-        switch (tag) {
-            // Convert the scale-factor-related items to use WebKit's text sizing API instead, so they match other
-            // UI that uses the text sizing API (such as Make Text Larger/Smaller menu items in Safari).
-            case WebMenuItemPDFActualSize:
-                [itemCopy setTarget:[[dataSource webFrame] webView]];
-                [itemCopy setAction:@selector(makeTextStandardSize:)];
-                break;
-            case WebMenuItemPDFZoomIn:
-                [itemCopy setTarget:[[dataSource webFrame] webView]];
-                [itemCopy setAction:@selector(makeTextLarger:)];
-                break;
-            case WebMenuItemPDFZoomOut:
-                [itemCopy setTarget:[[dataSource webFrame] webView]];
-                [itemCopy setAction:@selector(makeTextSmaller:)];
-                break;
-            default:
-                break;
-        }
     }
     
     [actionsToTags release];
@@ -347,22 +327,10 @@ static void applicationInfoForMIMEType(NSString *type, NSString **name, NSImage
     return menu;
 }
 
-- (void)_updateScalingToReflectTextSize
-{
-    WebView *view = [[dataSource webFrame] webView];
-    
-    // The scale factor and text size multiplier conveniently use the same units, so we can just
-    // treat the values as interchangeable.
-    if (view != nil) {
-        [PDFSubview setScaleFactor:[view textSizeMultiplier]];         
-    }  
-}
-
 - (void)setDataSource:(WebDataSource *)ds
 {
     dataSource = ds;
     [self setFrame:[[self superview] frame]];
-    [self _updateScalingToReflectTextSize];
 }
 
 - (void)dataSourceUpdated:(WebDataSource *)dataSource
@@ -402,11 +370,6 @@ static void applicationInfoForMIMEType(NSString *type, NSString **name, NSImage
     }
 }
 
-- (void)_web_textSizeMultiplierChanged
-{
-    [self _updateScalingToReflectTextSize];
-}
-
 // FIXME 4182876: We can eliminate this function in favor if -isEqual: if [PDFSelection isEqual:] is overridden
 // to compare contents.
 static BOOL PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selectionB)
@@ -570,6 +533,107 @@ static BOOL PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *select
     [PDFSubview clearSelection];
 }
 
+/*** WebDocumentViewState protocol implementation ***/
+
+// Even though to WebKit we are the "docView", in reality a PDFView contains its own scrollview and docView.
+// And it even turns out there is another PDFKit view between the docView and its enclosing ScrollView, so
+// we have to be sure to do our calculations based on that view, immediately inside the ClipView.  We try
+// to make as few assumptions about the PDFKit view hierarchy as possible.
+
+- (NSPoint)scrollPoint
+{
+    NSView *realDocView = [PDFSubview documentView];
+    NSClipView *clipView = [[realDocView enclosingScrollView] contentView];
+    return [clipView bounds].origin;
+}
+
+- (void)setScrollPoint:(NSPoint)p
+{
+    WebFrame *frame = [dataSource webFrame];
+    //FIXME:  We only restore scroll state in the non-frames case because otherwise we get a crash due to
+    // PDFKit calling display from within its drawRect:. See bugzilla 4164.
+    if (![frame parentFrame]) {
+        NSView *realDocView = [PDFSubview documentView];
+        [[[realDocView enclosingScrollView] documentView] scrollPoint:p];
+    }
+}
+
+- (id)viewState
+{
+    NSMutableArray *state = [NSMutableArray arrayWithCapacity:4];
+    PDFDisplayMode mode = [PDFSubview displayMode];
+    [state addObject:[NSNumber numberWithInt:mode]];
+    if (mode == kPDFDisplaySinglePage || mode == kPDFDisplayTwoUp) {
+        unsigned int pageIndex = [[PDFSubview document] indexForPage:[PDFSubview currentPage]];
+        [state addObject:[NSNumber numberWithUnsignedInt:pageIndex]];
+    }  // else in continuous modes, scroll position gets us to the right page
+    BOOL autoScaleFlag = [PDFSubview autoScales];
+    [state addObject:[NSNumber numberWithBool:autoScaleFlag]];
+    if (!autoScaleFlag) {
+        [state addObject:[NSNumber numberWithFloat:[PDFSubview scaleFactor]]];
+    }
+    return state;
+}
+
+- (void)setViewState:(id)statePList
+{
+    ASSERT([statePList isKindOfClass:[NSArray class]]);
+    NSArray *state = statePList;
+    int i = 0;
+    PDFDisplayMode mode = [[state objectAtIndex:i++] intValue];
+    [PDFSubview setDisplayMode:mode];
+    if (mode == kPDFDisplaySinglePage || mode == kPDFDisplayTwoUp) {
+        unsigned int pageIndex = [[state objectAtIndex:i++] unsignedIntValue];
+        [PDFSubview goToPage:[[PDFSubview document] pageAtIndex:pageIndex]];
+    }  // else in continuous modes, scroll position gets us to the right page
+    BOOL autoScaleFlag = [[state objectAtIndex:i++] boolValue];
+    [PDFSubview setAutoScales:autoScaleFlag];
+    if (!autoScaleFlag) {
+        [PDFSubview setScaleFactor:[[state objectAtIndex:i++] floatValue]];
+    }
+}
+
+/*** _WebDocumentTextSizing protocol implementation ***/
+
+- (IBAction)_makeTextSmaller:(id)sender
+{
+    [PDFSubview zoomOut:sender];
+}
+
+- (IBAction)_makeTextLarger:(id)sender
+{
+    [PDFSubview zoomIn:sender];
+}
+
+- (IBAction)_makeTextStandardSize:(id)sender
+{
+    [PDFSubview setScaleFactor:1.0];
+}
+
+- (BOOL)_tracksCommonSizeFactor
+{
+    // We keep our own scale factor instead of tracking the common one in the WebView for a couple reasons.
+    // First, PDFs tend to have visually smaller text because they are laid out for a printed page instead of
+    // the screen.  Second, the PDFView feature of AutoScaling means our scaling factor can be quiet variable.
+    return NO;
+}
+
+- (BOOL)_canMakeTextSmaller
+{
+    return [PDFSubview canZoomOut];
+}
+
+- (BOOL)_canMakeTextLarger
+{
+    return [PDFSubview canZoomIn];
+}
+
+- (BOOL)_canMakeTextStandardSize
+{
+    return [PDFSubview scaleFactor] != 1.0;
+}
+
+
 - (NSRect)selectionRect
 {
     NSRect result = NSZeroRect;
index 48c25bf..b79ee65 100644 (file)
@@ -53,7 +53,7 @@
 - (void)_updateTextSizeMultiplier;
 @end
 
-@interface WebTextView (TextSizing) <_web_WebDocumentTextSizing>
+@interface WebTextView (TextSizing) <_WebDocumentTextSizing>
 @end
 
 @implementation WebTextView
 
 @implementation WebTextView (TextSizing)
 
-- (void)_web_textSizeMultiplierChanged
+- (IBAction)_makeTextSmaller:(id)sender
 {
     [self _updateTextSizeMultiplier];
 }
 
+- (IBAction)_makeTextLarger:(id)sender
+{
+    [self _updateTextSizeMultiplier];
+}
+
+- (IBAction)_makeTextStandardSize:(id)sender
+{
+    [self _updateTextSizeMultiplier];
+}
+
+- (BOOL)_tracksCommonSizeFactor
+{
+    return YES;
+}
+
+// never sent because we track the common size factor
+- (BOOL)_canMakeTextSmaller          {   ASSERT_NOT_REACHED(); return NO;    }
+- (BOOL)_canMakeTextLarger           {   ASSERT_NOT_REACHED(); return NO;    }
+- (BOOL)_canMakeTextStandardSize     {   ASSERT_NOT_REACHED(); return NO;    }
+
 @end
index 1489cd7..79b9fab 100644 (file)
@@ -86,6 +86,7 @@
 #import <WebCore/WebCoreView.h>
 
 #import <Foundation/NSURLConnection.h>
+#import <objc/objc-runtime.h>
 
 #if __ppc__
 #define PROCESSOR "PPC"
@@ -213,6 +214,7 @@ macro(yankAndSelect) \
 - (void)_preflightSpellChecker;
 - (BOOL)_continuousCheckingAllowed;
 - (NSResponder *)_responderForResponderOperations;
+- (BOOL)_performTextSizingSelector:(SEL)sel withObject:(id)arg onTrackingDocs:(BOOL)doTrackingViews selForNonTrackingDocs:(SEL)testSel;
 @end
 
 NSString *WebElementDOMNodeKey =            @"WebElementDOMNode";
@@ -1840,7 +1842,6 @@ NS_ENDHANDLER
         return;
     }
     _private->textSizeMultiplier = m;
-    [[self mainFrame] _textSizeMultiplierChanged];
 }
 
 - (float)textSizeMultiplier
@@ -2364,48 +2365,32 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 
 - (BOOL)canMakeTextSmaller
 {
-    if ([[self mainFrame] dataSource] == nil) {
-        return NO;
-    }
-    // FIXME: This will prevent text sizing in subframes if the main frame doesn't support it
-    if (![[[[self mainFrame] frameView] documentView] conformsToProtocol:@protocol(_web_WebDocumentTextSizing)]) {
-        return NO;
-    }
-    if ([self textSizeMultiplier]/TextSizeMultiplierRatio < MinimumTextSizeMultiplier) {
-        return NO;
-    }
-    return YES;
+    BOOL canShrinkMore = _private->textSizeMultiplier/TextSizeMultiplierRatio > MinimumTextSizeMultiplier;
+    return [self _performTextSizingSelector:(SEL)0 withObject:nil onTrackingDocs:canShrinkMore selForNonTrackingDocs:@selector(_canMakeTextSmaller)];
 }
 
 - (BOOL)canMakeTextLarger
 {
-    if ([[self mainFrame] dataSource] == nil) {
-        return NO;
-    }
-    // FIXME: This will prevent text sizing in subframes if the main frame doesn't support it
-    if (![[[[self mainFrame] frameView] documentView] conformsToProtocol:@protocol(_web_WebDocumentTextSizing)]) {
-        return NO;
-    }
-    if ([self textSizeMultiplier]*TextSizeMultiplierRatio > MaximumTextSizeMultiplier) {
-        return NO;
-    }
-    return YES;
+    BOOL canGrowMore = _private->textSizeMultiplier*TextSizeMultiplierRatio < MaximumTextSizeMultiplier;
+    return [self _performTextSizingSelector:(SEL)0 withObject:nil onTrackingDocs:canGrowMore selForNonTrackingDocs:@selector(_canMakeTextLarger)];
 }
 
 - (IBAction)makeTextSmaller:(id)sender
 {
-    if (![self canMakeTextSmaller]) {
-        return;
+    BOOL canShrinkMore = _private->textSizeMultiplier/TextSizeMultiplierRatio > MinimumTextSizeMultiplier;
+    if (canShrinkMore) {
+        [self setTextSizeMultiplier:_private->textSizeMultiplier/TextSizeMultiplierRatio];
     }
-    [self setTextSizeMultiplier:[self textSizeMultiplier]/TextSizeMultiplierRatio];
+    [self _performTextSizingSelector:@selector(_makeTextSmaller:) withObject:sender onTrackingDocs:canShrinkMore selForNonTrackingDocs:@selector(_canMakeTextSmaller)];
 }
 
 - (IBAction)makeTextLarger:(id)sender
 {
-    if (![self canMakeTextLarger]) {
-        return;
+    BOOL canGrowMore = _private->textSizeMultiplier*TextSizeMultiplierRatio < MaximumTextSizeMultiplier;
+    if (canGrowMore) {
+        [self setTextSizeMultiplier:_private->textSizeMultiplier*TextSizeMultiplierRatio];
     }
-    [self setTextSizeMultiplier:[self textSizeMultiplier]*TextSizeMultiplierRatio];
+    [self _performTextSizingSelector:@selector(_makeTextLarger:) withObject:sender onTrackingDocs:canGrowMore selForNonTrackingDocs:@selector(_canMakeTextLarger)];
 }
 
 - (BOOL)_responderValidateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
@@ -2521,27 +2506,6 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
     }
 }
 
-- (BOOL)canMakeTextStandardSize
-{
-    if ([[self mainFrame] dataSource] == nil) {
-        return NO;
-    }
-    // FIXME: This will prevent text sizing in subframes if the main frame doesn't support it
-    if (![[[[self mainFrame] frameView] documentView] conformsToProtocol:@protocol(_web_WebDocumentTextSizing)]) {
-        return NO;
-    }
-    
-    return [self textSizeMultiplier] != 1;
-}
-
-- (IBAction)makeTextStandardSize:(id)sender
-{
-    if (![self canMakeTextStandardSize]) {
-        return;
-    }
-    [self setTextSizeMultiplier:1];
-}
-
 - (BOOL)maintainsInactiveSelection
 {
     return [self isEditable];
@@ -2579,6 +2543,20 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
     return nil;
 }
 
+- (BOOL)canMakeTextStandardSize
+{
+    BOOL notAlreadyStandard = _private->textSizeMultiplier != 1.0;
+    return [self _performTextSizingSelector:(SEL)0 withObject:nil onTrackingDocs:notAlreadyStandard selForNonTrackingDocs:@selector(_canMakeTextStandardSize)];
+}
+
+- (IBAction)makeTextStandardSize:(id)sender
+{
+    BOOL notAlreadyStandard = _private->textSizeMultiplier != 1.0;
+    if (notAlreadyStandard) {
+        [self setTextSizeMultiplier:1.0];
+    }
+    [self _performTextSizingSelector:@selector(_makeTextStandardSize:) withObject:sender onTrackingDocs:notAlreadyStandard selForNonTrackingDocs:@selector(_canMakeTextStandardSize)];
+}
 
 @end
 
@@ -3165,5 +3143,45 @@ FOR_EACH_RESPONDER_SELECTOR(FORWARD)
     (void)HISearchWindowShow((CFStringRef)selectedString, kNilOptions);
 }
 
+// Slightly funky method that lets us have one copy of the logic for finding docViews that can do
+// text sizing.  It returns whether it found any "suitable" doc views.  It sends sel to any suitable
+// doc views, or if sel==0 we do nothing to them.  For doc views that track our size factor, they are
+// suitable if doTrackingViews==YES (which in practice means that our size factor isn't at its max or
+// min).  For doc views that don't track it, we send them testSel to determine suitablility.
+- (BOOL)_performTextSizingSelector:(SEL)sel withObject:(id)arg onTrackingDocs:(BOOL)doTrackingViews selForNonTrackingDocs:(SEL)testSel
+{
+    if ([[self mainFrame] dataSource] == nil) {
+        return NO;
+    }
+    
+    BOOL foundSome = NO;
+    NSArray *docViews = [[self mainFrame] _documentViews];
+    int i;
+    for (i = [docViews count]-1; i >= 0; i--) {
+        id docView = [docViews objectAtIndex:i];
+        if ([docView conformsToProtocol:@protocol(_WebDocumentTextSizing)]) {
+            id <_WebDocumentTextSizing> sizingDocView = (id <_WebDocumentTextSizing>)docView;
+            BOOL isSuitable;
+            if ([sizingDocView _tracksCommonSizeFactor]) {
+                isSuitable = doTrackingViews;
+            } else {
+                // Incarnation to perform a selector returning a BOOL from objc/objc-runtime.h
+                isSuitable = (*(BOOL(*)(id, SEL, ...))objc_msgSend)(sizingDocView, testSel);
+            }
+            
+            if (isSuitable) {
+                if (sel != 0) {
+                    foundSome = YES;
+                    [sizingDocView performSelector:sel withObject:arg];
+                } else {
+                    // if we're just called for the benefit of the return value, we can return at first match
+                    return YES;
+                }
+            }
+        }
+    }
+    
+    return foundSome;
+}
 
 @end