[webkit-reviews] patch take 2 for webview bustage after trying to print invalid page range

John Sullivan info at ribbitphotography.com
Mon Jun 13 17:50:09 PDT 2005


2005-06-13  John Sullivan  <sullivan at apple.com>

         Reviewed by NOBODY (OOPS!).

         * WebView.subproj/WebHTMLView.m:
         (-[WebHTMLView _endPrintMode]):
         new method, extracted from identical code in beginDocument  
and endDocument. This method must be called
         once to counterbalance the code called from knowsPageRange  
that turns on "printing mode".
         (-[WebHTMLView _delayedEndPrintMode:]):
         new method, called from "perform after delay". Checks  
whether the same print operation is still underway
         and, if so, delays further. Otherwise calls _endPrintMode  
directly.
         (-[WebHTMLView knowsPageRange:]):
         after turning on "printing mode", queue up a delayed call to  
_delayedEndPrintMode:. If there's an early
         error in the print mechanism such that beginDocument is  
never called, this will cleanly end "printing
         mode" and make the webview usable again.
         (-[WebHTMLView beginDocument]):
         cancel any delayed call to _delayedEndPrintMode:. If we get  
this far along in printing, then we don't need
         the failsafe call to _delayedEndPrintMode: that was set up  
in knowsPageRange:. Also, call extracted method.
         (-[WebHTMLView endDocument]):
         call extracted method

Index: WebView.subproj/WebHTMLView.m
===================================================================
RCS file: /cvs/root/WebKit/WebView.subproj/WebHTMLView.m,v
retrieving revision 1.449
diff -u -r1.449 WebHTMLView.m
--- WebView.subproj/WebHTMLView.m    13 Jun 2005 03:28:08 -0000    1.449
+++ WebView.subproj/WebHTMLView.m    14 Jun 2005 00:32:59 -0000
@@ -3148,6 +3148,22 @@
      [self _setPrinting:YES minimumPageWidth:pageWidth  
maximumPageWidth:pageWidth adjustViewSize:YES];
}
+- (void)_endPrintMode
+{
+    [self _setPrinting:NO minimumPageWidth:0.0 maximumPageWidth:0.0  
adjustViewSize:YES];
+    [[self window] setAutodisplay:YES];
+}
+
+- (void)_delayedEndPrintMode:(NSPrintOperation *)initiatingOperation
+{
+    ASSERT_ARG(initiatingOperation, initiatingOperation != nil);
+    // If the operation that initiated this is still underway, delay  
further
+    if (initiatingOperation == [NSPrintOperation currentOperation]) {
+        [self performSelector:@selector(_delayedEndPrintMode:)  
withObject:nil afterDelay:0];
+    } else {
+        [self _endPrintMode];
+    }
+}
// Return the number of pages available for printing
- (BOOL)knowsPageRange:(NSRangePointer)range {
@@ -3166,6 +3182,14 @@
          maxLayoutWidth = paperWidth*PrintingMaximumShrinkFactor;
      }
      [self _setPrinting:YES minimumPageWidth:minLayoutWidth  
maximumPageWidth:maxLayoutWidth adjustViewSize:YES]; // will relayout
+    NSPrintOperation *printOperation = [NSPrintOperation  
currentOperation];
+    // Certain types of errors, including invalid page ranges, can  
cause beginDocument and
+    // endDocument to be skipped after we've put ourselves in print  
mode (see 4145905). In those cases
+    // we need to get out of print mode without relying on any more  
callbacks from the printing mechanism.
+    // If we get as far as beginDocument without trouble, then this  
delayed request will be cancelled.
+    // If not cancelled, this delayed call will be invoked in the  
next pass through the main event loop,
+    // which is after beginDocument and endDocument would be called.
+    [self performSelector:@selector(_delayedEndPrintMode:)  
withObject:printOperation afterDelay:0];
      [[self _webView] _adjustPrintingMarginsForHeaderAndFooter];

      // There is a theoretical chance that someone could do some  
drawing between here and endDocument,
@@ -3173,7 +3197,6 @@
      // you'd simply see the printer fonts on screen. As of this  
writing, this does not happen with Safari.
      range->location = 1;
-    NSPrintOperation *printOperation = [NSPrintOperation  
currentOperation];
      float totalScaleFactor = [self  
_scaleFactorForPrintOperation:printOperation];
      float userScaleFactor = [printOperation  
_web_pageSetupScaleFactor];
      [_private->pageRects release];
@@ -3207,12 +3230,16 @@
- (void)beginDocument
{
      NS_DURING
+        // From now on we'll get a chance to call _endPrintMode in  
either beginDocument or
+        // endDocument, so we can cancel the "just in case" pending  
call.
+        [NSObject cancelPreviousPerformRequestsWithTarget:self
+                                                 selector:@selector 
(_delayedEndPrintMode:)
+                                                   object: 
[NSPrintOperation currentOperation]];
          [super beginDocument];
      NS_HANDLER
          // Exception during [super beginDocument] means that  
endDocument will not get called,
          // so we need to clean up our "print mode" here.
-        [self _setPrinting:NO minimumPageWidth:0.0 maximumPageWidth: 
0.0 adjustViewSize:YES];
-        [[self window] setAutodisplay:YES];
+        [self _endPrintMode];
      NS_ENDHANDLER
}
@@ -3220,8 +3247,7 @@
{
      [super endDocument];
      // Note sadly at this point [NSGraphicsContext  
currentContextDrawingToScreen] is still NO
-    [self _setPrinting:NO minimumPageWidth:0.0 maximumPageWidth:0.0  
adjustViewSize:YES];
-    [[self window] setAutodisplay:YES];
+    [self _endPrintMode];
}
- (BOOL)_interceptEditingKeyEvent:(NSEvent *)event
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/webkit-reviews/attachments/20050613/e954c04a/attachment.html


More information about the webkit-reviews mailing list