Title: [211160] trunk/Source/WebKit2
Revision
211160
Author
[email protected]
Date
2017-01-25 12:48:41 -0800 (Wed, 25 Jan 2017)

Log Message

[iOS] Move WKPDFView's password view to WKWebView
https://bugs.webkit.org/show_bug.cgi?id=167401

Reviewed by Tim Horton.

r210943 moved the PDF password view into the new class WKPasswordView but left it as a
subview of the WKPDFView. To show the password view for Web content, my original plan was to
teach WKContentView to host its own password view, but this turned out not to work. Since
QuickLook needs to unlock a document before determining its preview's MIME type, we have to
ask for a password during provisional navigation, but if the still-committed document is a
PDF then the WKContentView will not be in the view hierarchy.

To ensure password view visibility, this patch moves the ownership of WKPasswordView to
WKWebView and creates an internal API for showing and hiding it. When
-_showPasswordViewWithDocumentName:passwordHandler: is called, WKWebView inserts a new
WKPasswordView as a subview of the scroll view and hides the current content view. The
password view is removed and the current content view is unhidden by -_hidePasswordView.

This also fixes a bug in WKPDFView where a PDF document is laid out incorrectly if the view
size changes while the password view is displayed.

* UIProcess/API/Cocoa/WKWebView.mm: Declared _passwordView.
(-[WKWebView _processDidExit]): Hid the password view.
(-[WKWebView _didCommitLayerTree:]): Ignored if not showing the standard content view.
(-[WKWebView _restorePageScrollPosition:scrollOrigin:previousObscuredInset:scale:]): Ditto.
(-[WKWebView _restorePageStateToUnobscuredCenter:scale:]): Ditto.
(-[WKWebView usesStandardContentView]): Changed to return false if _passwordView is non-nil.
(-[WKWebView _updateContentRectsWithState:]): Updated _passwordView's frame with the current
bounds size.
(-[WKWebView _showPasswordViewWithDocumentName:passwordHandler:]): Created a WKPasswordView,
called -showInScrollView:, and hid _currentContentView.
(-[WKWebView _hidePasswordView]): Removed _passwordView from its superview, set
_passwordView to nil, and unhid _currentContentView.
(-[WKWebView _passwordView]): Returned _passwordView.
(-[WKWebView _beginAnimatedResizeWithUpdates:]): Called -usesStandardContentView instead of
checking for a non-nil _customContentView when deciding whether to do a non-animated resize.
* UIProcess/API/Cocoa/WKWebViewInternal.h:
* UIProcess/ios/WKPDFView.mm: Removed _passwordView.
(-[WKPDFView web_setMinimumSize:]): Set m_minimumSize and updated the frame size even when a
password view is displayed.
(-[WKPDFView _computePageAndDocumentFrames]): Removed password view code.
(-[WKPDFView _showPasswordEntryField]): Ditto.
(-[WKPDFView _passwordViewFrame]): Deleted.
* UIProcess/ios/WKPasswordView.h:
* UIProcess/ios/WKPasswordView.mm:
(-[WKPasswordView initWithFrame:documentName:]): Stored a copy of documentName in
_documentName.
(-[WKPasswordView documentName]): Added. Returns _documentName.
(-[WKPasswordView showInScrollView:]): Renamed from displayInContentView:. Started saving
zoomScale and contentSize.
(-[WKPasswordView hide]): Started restoring zoomeScale and contentSize.
(-[WKPasswordView showPasswordFailureAlert]): Renamed from -displayPasswordFailureAlert.
(-[WKPasswordView displayInContentView:]): Renamed to -showInScrollView:
(-[WKPasswordView displayPasswordFailureAlert]): Renamed to -showPasswordFailureAlert.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (211159 => 211160)


--- trunk/Source/WebKit2/ChangeLog	2017-01-25 20:42:10 UTC (rev 211159)
+++ trunk/Source/WebKit2/ChangeLog	2017-01-25 20:48:41 UTC (rev 211160)
@@ -1,3 +1,60 @@
+2017-01-25  Andy Estes  <[email protected]>
+
+        [iOS] Move WKPDFView's password view to WKWebView
+        https://bugs.webkit.org/show_bug.cgi?id=167401
+
+        Reviewed by Tim Horton.
+
+        r210943 moved the PDF password view into the new class WKPasswordView but left it as a
+        subview of the WKPDFView. To show the password view for Web content, my original plan was to
+        teach WKContentView to host its own password view, but this turned out not to work. Since
+        QuickLook needs to unlock a document before determining its preview's MIME type, we have to
+        ask for a password during provisional navigation, but if the still-committed document is a
+        PDF then the WKContentView will not be in the view hierarchy.
+
+        To ensure password view visibility, this patch moves the ownership of WKPasswordView to
+        WKWebView and creates an internal API for showing and hiding it. When
+        -_showPasswordViewWithDocumentName:passwordHandler: is called, WKWebView inserts a new
+        WKPasswordView as a subview of the scroll view and hides the current content view. The
+        password view is removed and the current content view is unhidden by -_hidePasswordView.
+
+        This also fixes a bug in WKPDFView where a PDF document is laid out incorrectly if the view
+        size changes while the password view is displayed.
+
+        * UIProcess/API/Cocoa/WKWebView.mm: Declared _passwordView.
+        (-[WKWebView _processDidExit]): Hid the password view.
+        (-[WKWebView _didCommitLayerTree:]): Ignored if not showing the standard content view.
+        (-[WKWebView _restorePageScrollPosition:scrollOrigin:previousObscuredInset:scale:]): Ditto.
+        (-[WKWebView _restorePageStateToUnobscuredCenter:scale:]): Ditto.
+        (-[WKWebView usesStandardContentView]): Changed to return false if _passwordView is non-nil.
+        (-[WKWebView _updateContentRectsWithState:]): Updated _passwordView's frame with the current
+        bounds size.
+        (-[WKWebView _showPasswordViewWithDocumentName:passwordHandler:]): Created a WKPasswordView,
+        called -showInScrollView:, and hid _currentContentView.
+        (-[WKWebView _hidePasswordView]): Removed _passwordView from its superview, set
+        _passwordView to nil, and unhid _currentContentView.
+        (-[WKWebView _passwordView]): Returned _passwordView.
+        (-[WKWebView _beginAnimatedResizeWithUpdates:]): Called -usesStandardContentView instead of
+        checking for a non-nil _customContentView when deciding whether to do a non-animated resize.
+        * UIProcess/API/Cocoa/WKWebViewInternal.h:
+        * UIProcess/ios/WKPDFView.mm: Removed _passwordView.
+        (-[WKPDFView web_setMinimumSize:]): Set m_minimumSize and updated the frame size even when a
+        password view is displayed.
+        (-[WKPDFView _computePageAndDocumentFrames]): Removed password view code.
+        (-[WKPDFView _showPasswordEntryField]): Ditto.
+        (-[WKPDFView _passwordViewFrame]): Deleted.
+        * UIProcess/ios/WKPasswordView.h:
+        * UIProcess/ios/WKPasswordView.mm:
+        (-[WKPasswordView initWithFrame:documentName:]): Stored a copy of documentName in
+        _documentName.
+        (-[WKPasswordView documentName]): Added. Returns _documentName.
+        (-[WKPasswordView showInScrollView:]): Renamed from displayInContentView:. Started saving
+        zoomScale and contentSize.
+        (-[WKPasswordView hide]): Started restoring zoomeScale and contentSize.
+        (-[WKPasswordView showPasswordFailureAlert]): Renamed from -displayPasswordFailureAlert.
+        (-[WKPasswordView displayInContentView:]): Renamed to -showInScrollView:
+        (-[WKPasswordView displayPasswordFailureAlert]): Renamed to -showPasswordFailureAlert.
+
 2017-01-25  Wenson Hsieh  <[email protected]>
 
         Add support for named pasteboards, pasteboard strategies and platform pasteboards

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (211159 => 211160)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2017-01-25 20:42:10 UTC (rev 211159)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2017-01-25 20:48:41 UTC (rev 211160)
@@ -57,6 +57,7 @@
 #import "WKNSURLExtras.h"
 #import "WKNavigationDelegate.h"
 #import "WKNavigationInternal.h"
+#import "WKPasswordView.h"
 #import "WKPreferencesInternal.h"
 #import "WKProcessPoolInternal.h"
 #import "WKSharedAPICast.h"
@@ -273,6 +274,8 @@
 
     Vector<std::function<void ()>> _snapshotsDeferredDuringResize;
     RetainPtr<NSMutableArray> _stableStatePresentationUpdateCallbacks;
+
+    RetainPtr<WKPasswordView> _passwordView;
 #endif
 #if PLATFORM(MAC)
     std::unique_ptr<WebKit::WebViewImpl> _impl;
@@ -1192,6 +1195,7 @@
 
 - (void)_processDidExit
 {
+    [self _hidePasswordView];
     if (!_customContentView && _dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing) {
         NSUInteger indexOfResizeAnimationView = [[_scrollView subviews] indexOfObject:_resizeAnimationView.get()];
         [_scrollView insertSubview:_contentView.get() atIndex:indexOfResizeAnimationView];
@@ -1268,7 +1272,7 @@
 
 - (void)_didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
 {
-    if (_customContentView)
+    if (![self usesStandardContentView])
         return;
 
     if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing) {
@@ -1406,7 +1410,7 @@
     if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing)
         return;
 
-    if (_customContentView)
+    if (![self usesStandardContentView])
         return;
 
     _needsToRestoreUnobscuredCenter = NO;
@@ -1423,7 +1427,7 @@
     if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing)
         return;
 
-    if (_customContentView)
+    if (![self usesStandardContentView])
         return;
 
     _needsToRestoreScrollPosition = NO;
@@ -1834,7 +1838,7 @@
 
 - (BOOL)usesStandardContentView
 {
-    return !_customContentView;
+    return !_customContentView && !_passwordView;
 }
 
 - (CGSize)scrollView:(UIScrollView*)scrollView contentSizeForZoomScale:(CGFloat)scale withProposedSize:(CGSize)proposedSize
@@ -2111,6 +2115,7 @@
 - (void)_updateContentRectsWithState:(BOOL)inStableState
 {
     if (![self usesStandardContentView]) {
+        [_passwordView setFrame:self.bounds];
         [_customContentView web_computedContentInsetDidChange];
         return;
     }
@@ -2331,6 +2336,27 @@
     _frozenUnobscuredContentRect = std::nullopt;
 }
 
+- (void)_showPasswordViewWithDocumentName:(NSString *)documentName passwordHandler:(void (^)(NSString *))passwordHandler
+{
+    ASSERT(!_passwordView);
+    _passwordView = adoptNS([[WKPasswordView alloc] initWithFrame:self.bounds documentName:documentName]);
+    [_passwordView setUserDidEnterPassword:passwordHandler];
+    [_passwordView showInScrollView:_scrollView.get()];
+    self._currentContentView.hidden = YES;
+}
+
+- (void)_hidePasswordView
+{
+    self._currentContentView.hidden = NO;
+    [_passwordView removeFromSuperview];
+    _passwordView = nil;
+}
+
+- (WKPasswordView *)_passwordView
+{
+    return _passwordView.get();
+}
+
 #endif // PLATFORM(IOS)
 
 #pragma mark OS X-specific methods
@@ -4212,7 +4238,7 @@
     CGRect oldBounds = self.bounds;
     WebCore::FloatRect oldUnobscuredContentRect = _page->unobscuredContentRect();
 
-    if (_customContentView || !_hasCommittedLoadForMainFrame || CGRectIsEmpty(oldBounds) || oldUnobscuredContentRect.isEmpty()) {
+    if (![self usesStandardContentView] || !_hasCommittedLoadForMainFrame || CGRectIsEmpty(oldBounds) || oldUnobscuredContentRect.isEmpty()) {
         updateBlock();
         return;
     }

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h (211159 => 211160)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h	2017-01-25 20:42:10 UTC (rev 211159)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h	2017-01-25 20:48:41 UTC (rev 211160)
@@ -56,6 +56,7 @@
 }
 
 @class WKWebViewContentProviderRegistry;
+@class WKPasswordView;
 @class _WKFrameHandle;
 @protocol _WKWebViewPrintProvider;
 
@@ -116,6 +117,11 @@
 - (void)_navigationGestureDidEnd;
 - (BOOL)_isNavigationSwipeGestureRecognizer:(UIGestureRecognizer *)recognizer;
 
+- (void)_showPasswordViewWithDocumentName:(NSString *)documentName passwordHandler:(void (^)(NSString *))passwordHandler;
+- (void)_hidePasswordView;
+
+@property (nonatomic, readonly) WKPasswordView *_passwordView;
+
 @property (nonatomic, readonly) BOOL _isBackground;
 
 @property (nonatomic, readonly) WKWebViewContentProviderRegistry *_contentProviderRegistry;

Modified: trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm (211159 => 211160)


--- trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm	2017-01-25 20:42:10 UTC (rev 211159)
+++ trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm	2017-01-25 20:48:41 UTC (rev 211160)
@@ -76,8 +76,6 @@
     RetainPtr<NSString> _suggestedFilename;
     RetainPtr<WKPDFPageNumberIndicator> _pageNumberIndicator;
 
-    RetainPtr<WKPasswordView> _passwordView;
-
     Vector<PDFPageInfo> _pages;
     unsigned _centerPageNumber;
 
@@ -205,13 +203,13 @@
 
 - (void)web_setMinimumSize:(CGSize)size
 {
-    if (_passwordView) {
-        [_passwordView setFrame:[self _passwordViewFrame]];
+    _minimumSize = size;
+
+    if (_webView._passwordView) {
+        self.frame = { self.frame.origin, size };
         return;
     }
 
-    _minimumSize = size;
-
     CGFloat oldDocumentLeftFraction = 0;
     CGFloat oldDocumentTopFraction = 0;
     CGSize contentSize = _scrollView.contentSize;
@@ -361,9 +359,6 @@
 
 - (void)_computePageAndDocumentFrames
 {
-    if (_passwordView)
-        return;
-
     NSUInteger pageCount = [_pdfDocument numberOfPages];
     [_pageNumberIndicator setPageCount:pageCount];
     
@@ -746,28 +741,17 @@
 
 #pragma mark Password protection UI
 
-- (CGRect)_passwordViewFrame
-{
-    CGRect webViewBounds = _webView.bounds;
-    return CGRectMake(0, 0, webViewBounds.size.width, webViewBounds.size.height);
-}
-
 - (void)_showPasswordEntryField
 {
-    _passwordView = adoptNS([[WKPasswordView alloc] initWithFrame:[self _passwordViewFrame] documentName:_suggestedFilename.get()]);
-
-    [_passwordView setUserDidEnterPassword:[retainedSelf = retainPtr(self)](NSString *password) {
+    [_webView _showPasswordViewWithDocumentName:_suggestedFilename.get() passwordHandler:[retainedSelf = retainPtr(self), webView = retainPtr(_webView)](NSString *password) {
         if (!CGPDFDocumentUnlockWithPassword(retainedSelf->_cgPDFDocument.get(), password.UTF8String)) {
-            [retainedSelf->_passwordView displayPasswordFailureAlert];
+            [[webView _passwordView] showPasswordFailureAlert];
             return;
         }
 
-        [retainedSelf->_passwordView hide];
-        retainedSelf->_passwordView = nil;
+        [webView _hidePasswordView];
         [retainedSelf _didLoadPDFDocument];
     }];
-
-    [_passwordView displayInContentView:self];
 }
 
 - (void)willMoveToWindow:(UIWindow *)newWindow

Modified: trunk/Source/WebKit2/UIProcess/ios/WKPasswordView.h (211159 => 211160)


--- trunk/Source/WebKit2/UIProcess/ios/WKPasswordView.h	2017-01-25 20:42:10 UTC (rev 211159)
+++ trunk/Source/WebKit2/UIProcess/ios/WKPasswordView.h	2017-01-25 20:48:41 UTC (rev 211160)
@@ -30,10 +30,11 @@
 @interface WKPasswordView : UIView
 
 - (instancetype)initWithFrame:(CGRect)frame documentName:(NSString *)documentName;
-- (void)displayInContentView:(UIView *)contentView;
+- (void)showInScrollView:(UIScrollView *)scrollView;
 - (void)hide;
-- (void)displayPasswordFailureAlert;
+- (void)showPasswordFailureAlert;
 
+@property (nonatomic, readonly) NSString *documentName;
 @property (nonatomic, copy) void (^userDidEnterPassword)(NSString *);
 
 @end

Modified: trunk/Source/WebKit2/UIProcess/ios/WKPasswordView.mm (211159 => 211160)


--- trunk/Source/WebKit2/UIProcess/ios/WKPasswordView.mm	2017-01-25 20:42:10 UTC (rev 211159)
+++ trunk/Source/WebKit2/UIProcess/ios/WKPasswordView.mm	2017-01-25 20:48:41 UTC (rev 211160)
@@ -41,10 +41,13 @@
 @end
 
 @implementation WKPasswordView {
+    RetainPtr<NSString> _documentName;
     RetainPtr<UIScrollView> _scrollView;
     RetainPtr<UIDocumentPasswordView> _passwordView;
     CGFloat _savedMinimumZoomScale;
     CGFloat _savedMaximumZoomScale;
+    CGFloat _savedZoomScale;
+    CGSize _savedContentSize;
     RetainPtr<UIColor> _savedBackgroundColor;
 }
 
@@ -54,7 +57,8 @@
     if (!self)
         return nil;
 
-    _passwordView = adoptNS([[UIDocumentPasswordView alloc] initWithDocumentName:documentName]);
+    _documentName = adoptNS([documentName copy]);
+    _passwordView = adoptNS([[UIDocumentPasswordView alloc] initWithDocumentName:_documentName.get()]);
     [_passwordView setFrame:self.bounds];
     [_passwordView setPasswordDelegate:self];
     [_passwordView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
@@ -65,6 +69,11 @@
     return self;
 }
 
+- (NSString *)documentName
+{
+    return _documentName.get();
+}
+
 - (void)layoutSubviews
 {
     if (_scrollView)
@@ -71,22 +80,23 @@
         [_scrollView setContentSize:self.frame.size];
 }
 
-- (void)displayInContentView:(UIView *)contentView
+- (void)showInScrollView:(UIScrollView *)scrollView
 {
-    ASSERT([contentView isKindOfClass:[WKContentView class]] || [contentView conformsToProtocol:@protocol(WKWebViewContentProvider)]);
-    ASSERT([contentView.superview isKindOfClass:[UIScrollView class]]);
-    _scrollView = (UIScrollView *)contentView.superview;
+    _scrollView = scrollView;
 
     _savedMinimumZoomScale = [_scrollView minimumZoomScale];
     _savedMaximumZoomScale = [_scrollView maximumZoomScale];
+    _savedZoomScale = [_scrollView zoomScale];
+    _savedContentSize = [_scrollView contentSize];
     _savedBackgroundColor = [_scrollView backgroundColor];
 
     [_scrollView setMinimumZoomScale:1];
     [_scrollView setMaximumZoomScale:1];
+    [_scrollView setZoomScale:1];
     [_scrollView setContentSize:self.frame.size];
     [_scrollView setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
 
-    [contentView addSubview:self];
+    [scrollView addSubview:self];
 }
 
 - (void)hide
@@ -93,6 +103,8 @@
 {
     [_scrollView setMinimumZoomScale:_savedMinimumZoomScale];
     [_scrollView setMaximumZoomScale:_savedMaximumZoomScale];
+    [_scrollView setZoomScale:_savedZoomScale];
+    [_scrollView setContentSize:_savedContentSize];
     [_scrollView setBackgroundColor:_savedBackgroundColor.get()];
 
     _scrollView = nil;
@@ -101,7 +113,7 @@
     [self removeFromSuperview];
 }
 
-- (void)displayPasswordFailureAlert
+- (void)showPasswordFailureAlert
 {
     [[_passwordView passwordField] setText:@""];
     UIAlertController *alert = [UIAlertController alertControllerWithTitle:WEB_UI_STRING("The document could not be opened with that password.", "document password failure alert message") message:@"" preferredStyle:UIAlertControllerStyleAlert];
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to