diff options
Diffstat (limited to 'WebKit/mac/WebView')
30 files changed, 755 insertions, 337 deletions
diff --git a/WebKit/mac/WebView/WebArchive.mm b/WebKit/mac/WebView/WebArchive.mm index 89c8335..86e29c8 100644 --- a/WebKit/mac/WebView/WebArchive.mm +++ b/WebKit/mac/WebView/WebArchive.mm @@ -239,13 +239,13 @@ static BOOL isArrayOfClass(id object, Class elementClass) @try { id object = [decoder decodeObjectForKey:WebMainResourceKey]; if ([object isKindOfClass:[WebResource class]]) - mainResource = [object retain]; + mainResource = object; object = [decoder decodeObjectForKey:WebSubresourcesKey]; if (isArrayOfClass(object, [WebResource class])) - subresources = [object retain]; + subresources = object; object = [decoder decodeObjectForKey:WebSubframeArchivesKey]; if (isArrayOfClass(object, [WebArchive class])) - subframeArchives = [object retain]; + subframeArchives = object; } @catch(id) { [self release]; return nil; diff --git a/WebKit/mac/WebView/WebDocumentPrivate.h b/WebKit/mac/WebView/WebDocumentPrivate.h index f09d3bd..a495e4b 100644 --- a/WebKit/mac/WebView/WebDocumentPrivate.h +++ b/WebKit/mac/WebView/WebDocumentPrivate.h @@ -30,6 +30,7 @@ #import <WebKit/WebHTMLView.h> @class DOMDocument; +@class PDFDocument; @protocol WebDocumentImage <NSObject> - (NSImage *)image; @@ -64,6 +65,10 @@ - (NSView *)selectionView; @end +@protocol WebDocumentPDF <WebDocumentText> +- (PDFDocument *)PDFDocument; +@end + @protocol WebDocumentIncrementalSearching /*! @method searchFor:direction:caseSensitive:wrap:startInSelection: diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsView.h b/WebKit/mac/WebView/WebDynamicScrollBarsView.h index 15ed7e4..c289a04 100644 --- a/WebKit/mac/WebView/WebDynamicScrollBarsView.h +++ b/WebKit/mac/WebView/WebDynamicScrollBarsView.h @@ -1,53 +1,61 @@ /* - * Copyright (C) 2005, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2008, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ // This is a Private header (containing SPI), despite the fact that its name // does not contain the word Private. -// This was once used by Safari, but has not been for a long time. +#import <AppKit/NSScrollView.h> // FIXME: <rdar://problem/5898985> Mail currently expects this header to define WebCoreScrollbarAlwaysOn. extern const int WebCoreScrollbarAlwaysOn; +struct WebDynamicScrollBarsViewPrivate; @interface WebDynamicScrollBarsView : NSScrollView { - int hScroll; // FIXME: Should be WebCore::ScrollbarMode if this was an ObjC++ header. - int vScroll; // Ditto. - BOOL hScrollModeLocked; - BOOL vScrollModeLocked; - BOOL suppressLayout; - BOOL suppressScrollers; - BOOL inUpdateScrollers; - BOOL verticallyPinnedByPreviousWheelEvent; - BOOL horizontallyPinnedByPreviousWheelEvent; - unsigned inUpdateScrollersLayoutPass; +@private + struct WebDynamicScrollBarsViewPrivate *_private; + +#ifndef __OBJC2__ + // We need to pad the class out to its former size. See <rdar://problem/7814899> for more information. + char padding[16]; +#endif } // This was originally added for Safari's benefit, but Safari has not used it for a long time. // Perhaps it can be removed. - (void)setAllowsHorizontalScrolling:(BOOL)flag; + +// Determines whether the scrollers should be drawn outside of the content (as in normal scroll views) +// or should overlap the content. +- (void)setAllowsScrollersToOverlapContent:(BOOL)flag; + +// These methods hide the scrollers in a way that does not prevent scrolling. +- (void)setAlwaysHideHorizontalScroller:(BOOL)flag; +- (void)setAlwaysHideVerticalScroller:(BOOL)flag; + +// These methods return YES if the scrollers are visible, or if the only reason that they are not +// visible is that they have been suppressed by setAlwaysHideHorizontal/VerticalScroller:. +- (BOOL)horizontalScrollingAllowed; +- (BOOL)verticalScrollingAllowed; @end diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsView.mm b/WebKit/mac/WebView/WebDynamicScrollBarsView.mm index b4424e1..3aaea46 100644 --- a/WebKit/mac/WebView/WebDynamicScrollBarsView.mm +++ b/WebKit/mac/WebView/WebDynamicScrollBarsView.mm @@ -1,29 +1,26 @@ /* - * Copyright (C) 2005, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2008, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #import "WebDynamicScrollBarsViewInternal.h" @@ -41,31 +38,150 @@ using namespace WebCore; // FIXME: <rdar://problem/5898985> Mail expects a constant of this name to exist. const int WebCoreScrollbarAlwaysOn = ScrollbarAlwaysOn; +#ifndef __OBJC2__ +// In <rdar://problem/7814899> we saw crashes because WebDynamicScrollBarsView increased in size, breaking ABI compatiblity. +COMPILE_ASSERT(sizeof(WebDynamicScrollBarsView) == 0x8c, WebDynamicScrollBarsView_is_expected_size); +#endif + +struct WebDynamicScrollBarsViewPrivate { + unsigned inUpdateScrollersLayoutPass; + + WebCore::ScrollbarMode hScroll; + WebCore::ScrollbarMode vScroll; + + bool hScrollModeLocked; + bool vScrollModeLocked; + bool suppressLayout; + bool suppressScrollers; + bool inUpdateScrollers; + bool verticallyPinnedByPreviousWheelEvent; + bool horizontallyPinnedByPreviousWheelEvent; + + bool allowsScrollersToOverlapContent; + bool alwaysHideHorizontalScroller; + bool alwaysHideVerticalScroller; + bool horizontalScrollingAllowedButScrollerHidden; + bool verticalScrollingAllowedButScrollerHidden; +}; + @implementation WebDynamicScrollBarsView +- (id)initWithFrame:(NSRect)frame +{ + if (!(self = [super initWithFrame:frame])) + return nil; + + _private = new WebDynamicScrollBarsViewPrivate; + memset(_private, 0, sizeof(WebDynamicScrollBarsViewPrivate)); + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + if (!(self = [super initWithCoder:aDecoder])) + return nil; + + _private = new WebDynamicScrollBarsViewPrivate; + memset(_private, 0, sizeof(WebDynamicScrollBarsViewPrivate)); + return self; +} + +- (void)dealloc +{ + delete _private; + [super dealloc]; +} + +- (void)finalize +{ + delete _private; + [super finalize]; +} + - (void)setAllowsHorizontalScrolling:(BOOL)flag { - if (hScrollModeLocked) + if (_private->hScrollModeLocked) return; - if (flag && hScroll == ScrollbarAlwaysOff) - hScroll = ScrollbarAuto; - else if (!flag && hScroll != ScrollbarAlwaysOff) - hScroll = ScrollbarAlwaysOff; + if (flag && _private->hScroll == ScrollbarAlwaysOff) + _private->hScroll = ScrollbarAuto; + else if (!flag && _private->hScroll != ScrollbarAlwaysOff) + _private->hScroll = ScrollbarAlwaysOff; [self updateScrollers]; } +- (void)setAllowsScrollersToOverlapContent:(BOOL)flag +{ + if (_private->allowsScrollersToOverlapContent == flag) + return; + + _private->allowsScrollersToOverlapContent = flag; + + [[self contentView] setFrame:[self contentViewFrame]]; + [[self documentView] setNeedsLayout:YES]; + [[self documentView] layout]; +} + +- (void)setAlwaysHideHorizontalScroller:(BOOL)shouldBeHidden +{ + if (_private->alwaysHideHorizontalScroller == shouldBeHidden) + return; + + _private->alwaysHideHorizontalScroller = shouldBeHidden; + [self updateScrollers]; +} + +- (void)setAlwaysHideVerticalScroller:(BOOL)shouldBeHidden +{ + if (_private->alwaysHideVerticalScroller == shouldBeHidden) + return; + + _private->alwaysHideVerticalScroller = shouldBeHidden; + [self updateScrollers]; +} + +- (BOOL)horizontalScrollingAllowed +{ + return _private->horizontalScrollingAllowedButScrollerHidden || [self hasHorizontalScroller]; +} + +- (BOOL)verticalScrollingAllowed +{ + return _private->verticalScrollingAllowedButScrollerHidden || [self hasVerticalScroller]; +} + @end @implementation WebDynamicScrollBarsView (WebInternal) +- (NSRect)contentViewFrame +{ + NSRect frame = [[self contentView] frame]; + + if ([self hasHorizontalScroller]) + frame.size.height = (_private->allowsScrollersToOverlapContent ? NSMaxY([[self horizontalScroller] frame]) : NSMinY([[self horizontalScroller] frame])); + if ([self hasVerticalScroller]) + frame.size.width = (_private->allowsScrollersToOverlapContent ? NSMaxX([[self verticalScroller] frame]) : NSMinX([[self verticalScroller] frame])); + return frame; +} + +- (void)tile +{ + [super tile]; + + // [super tile] sets the contentView size so that it does not overlap with the scrollers, + // we want to re-set the contentView to overlap scrollers before displaying. + if (_private->allowsScrollersToOverlapContent) + [[self contentView] setFrame:[self contentViewFrame]]; +} + - (void)setSuppressLayout:(BOOL)flag; { - suppressLayout = flag; + _private->suppressLayout = flag; } - (void)setScrollBarsSuppressed:(BOOL)suppressed repaintOnUnsuppress:(BOOL)repaint { - suppressScrollers = suppressed; + _private->suppressScrollers = suppressed; // This code was originally changes for a Leopard performance imporvement. We decided to // ifdef it to fix correctness issues on Tiger documented in <rdar://problem/5441823>. @@ -74,13 +190,13 @@ const int WebCoreScrollbarAlwaysOn = ScrollbarAlwaysOn; [[self verticalScroller] setNeedsDisplay:NO]; [[self horizontalScroller] setNeedsDisplay:NO]; } - + if (!suppressed && repaint) [super reflectScrolledClipView:[self contentView]]; #else - if (suppressed || repaint) { - [[self verticalScroller] setNeedsDisplay: !suppressed]; - [[self horizontalScroller] setNeedsDisplay: !suppressed]; + if (suppressed || repaint) { + [[self verticalScroller] setNeedsDisplay:!suppressed]; + [[self horizontalScroller] setNeedsDisplay:!suppressed]; } #endif } @@ -94,42 +210,50 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; // If we came in here with the view already needing a layout, then go ahead and do that // first. (This will be the common case, e.g., when the page changes due to window resizing for example). // This layout will not re-enter updateScrollers and does not count towards our max layout pass total. - if (!suppressLayout && !suppressScrollers && [documentView isKindOfClass:[WebHTMLView class]]) { + if (!_private->suppressLayout && !_private->suppressScrollers && [documentView isKindOfClass:[WebHTMLView class]]) { WebHTMLView* htmlView = (WebHTMLView*)documentView; if ([htmlView _needsLayout]) { - inUpdateScrollers = YES; + _private->inUpdateScrollers = YES; [(id <WebDocumentView>)documentView layout]; - inUpdateScrollers = NO; + _private->inUpdateScrollers = NO; } } BOOL hasHorizontalScroller = [self hasHorizontalScroller]; BOOL hasVerticalScroller = [self hasVerticalScroller]; - + BOOL newHasHorizontalScroller = hasHorizontalScroller; BOOL newHasVerticalScroller = hasVerticalScroller; - + if (!documentView) { newHasHorizontalScroller = NO; newHasVerticalScroller = NO; - } + } - if (hScroll != ScrollbarAuto) - newHasHorizontalScroller = (hScroll == ScrollbarAlwaysOn); - if (vScroll != ScrollbarAuto) - newHasVerticalScroller = (vScroll == ScrollbarAlwaysOn); - - if (!documentView || suppressLayout || suppressScrollers || (hScroll != ScrollbarAuto && vScroll != ScrollbarAuto)) { - inUpdateScrollers = YES; + if (_private->hScroll != ScrollbarAuto) + newHasHorizontalScroller = (_private->hScroll == ScrollbarAlwaysOn); + if (_private->vScroll != ScrollbarAuto) + newHasVerticalScroller = (_private->vScroll == ScrollbarAlwaysOn); + + if (!documentView || _private->suppressLayout || _private->suppressScrollers || (_private->hScroll != ScrollbarAuto && _private->vScroll != ScrollbarAuto)) { + _private->horizontalScrollingAllowedButScrollerHidden = newHasHorizontalScroller && _private->alwaysHideHorizontalScroller; + if (_private->horizontalScrollingAllowedButScrollerHidden) + newHasHorizontalScroller = NO; + + _private->verticalScrollingAllowedButScrollerHidden = newHasVerticalScroller && _private->alwaysHideVerticalScroller; + if (_private->verticalScrollingAllowedButScrollerHidden) + newHasVerticalScroller = NO; + + _private->inUpdateScrollers = YES; if (hasHorizontalScroller != newHasHorizontalScroller) [self setHasHorizontalScroller:newHasHorizontalScroller]; if (hasVerticalScroller != newHasVerticalScroller) [self setHasVerticalScroller:newHasVerticalScroller]; - if (suppressScrollers) { + if (_private->suppressScrollers) { [[self verticalScroller] setNeedsDisplay:NO]; [[self horizontalScroller] setNeedsDisplay:NO]; } - inUpdateScrollers = NO; + _private->inUpdateScrollers = NO; return; } @@ -139,42 +263,50 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; NSSize visibleSize = [self documentVisibleRect].size; NSSize frameSize = [self frame].size; - if (hScroll == ScrollbarAuto) { + if (_private->hScroll == ScrollbarAuto) { newHasHorizontalScroller = documentSize.width > visibleSize.width; - if (newHasHorizontalScroller && !inUpdateScrollersLayoutPass && documentSize.height <= frameSize.height && documentSize.width <= frameSize.width) + if (newHasHorizontalScroller && !_private->inUpdateScrollersLayoutPass && documentSize.height <= frameSize.height && documentSize.width <= frameSize.width) newHasHorizontalScroller = NO; } - - if (vScroll == ScrollbarAuto) { + + if (_private->vScroll == ScrollbarAuto) { newHasVerticalScroller = documentSize.height > visibleSize.height; - if (newHasVerticalScroller && !inUpdateScrollersLayoutPass && documentSize.height <= frameSize.height && documentSize.width <= frameSize.width) + if (newHasVerticalScroller && !_private->inUpdateScrollersLayoutPass && documentSize.height <= frameSize.height && documentSize.width <= frameSize.width) newHasVerticalScroller = NO; } // Unless in ScrollbarsAlwaysOn mode, if we ever turn one scrollbar off, always turn the other one off too. // Never ever try to both gain/lose a scrollbar in the same pass. - if (!newHasHorizontalScroller && hasHorizontalScroller && vScroll != ScrollbarAlwaysOn) + if (!newHasHorizontalScroller && hasHorizontalScroller && _private->vScroll != ScrollbarAlwaysOn) newHasVerticalScroller = NO; - if (!newHasVerticalScroller && hasVerticalScroller && hScroll != ScrollbarAlwaysOn) + if (!newHasVerticalScroller && hasVerticalScroller && _private->hScroll != ScrollbarAlwaysOn) + newHasHorizontalScroller = NO; + + _private->horizontalScrollingAllowedButScrollerHidden = newHasHorizontalScroller && _private->alwaysHideHorizontalScroller; + if (_private->horizontalScrollingAllowedButScrollerHidden) newHasHorizontalScroller = NO; + _private->verticalScrollingAllowedButScrollerHidden = newHasVerticalScroller && _private->alwaysHideVerticalScroller; + if (_private->verticalScrollingAllowedButScrollerHidden) + newHasVerticalScroller = NO; + if (hasHorizontalScroller != newHasHorizontalScroller) { - inUpdateScrollers = YES; + _private->inUpdateScrollers = YES; [self setHasHorizontalScroller:newHasHorizontalScroller]; - inUpdateScrollers = NO; + _private->inUpdateScrollers = NO; needsLayout = YES; } if (hasVerticalScroller != newHasVerticalScroller) { - inUpdateScrollers = YES; + _private->inUpdateScrollers = YES; [self setHasVerticalScroller:newHasVerticalScroller]; - inUpdateScrollers = NO; + _private->inUpdateScrollers = NO; needsLayout = YES; } - if (needsLayout && inUpdateScrollersLayoutPass < cMaxUpdateScrollbarsPass && + if (needsLayout && _private->inUpdateScrollersLayoutPass < cMaxUpdateScrollbarsPass && [documentView conformsToProtocol:@protocol(WebDocumentView)]) { - inUpdateScrollersLayoutPass++; + _private->inUpdateScrollersLayoutPass++; [(id <WebDocumentView>)documentView setNeedsLayout:YES]; [(id <WebDocumentView>)documentView layout]; NSSize newDocumentSize = [documentView frame].size; @@ -184,7 +316,7 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; // Recur manually. [self updateScrollers]; } - inUpdateScrollersLayoutPass--; + _private->inUpdateScrollersLayoutPass--; } } @@ -192,6 +324,10 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; - (void)reflectScrolledClipView:(NSClipView *)clipView { if (clipView == [self contentView]) { + // Prevent appearance of trails because of overlapping views + if (_private->allowsScrollersToOverlapContent) + [self setDrawsBackground:NO]; + // FIXME: This hack here prevents infinite recursion that takes place when we // gyrate between having a vertical scroller and not having one. A reproducible // case is clicking on the "the Policy Routing text" link at @@ -199,7 +335,7 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; // The underlying cause is some problem in the NSText machinery, but I was not // able to pin it down. NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; - if (!inUpdateScrollers && (!currentContext || [currentContext isDrawingToScreen])) + if (!_private->inUpdateScrollers && (!currentContext || [currentContext isDrawingToScreen])) [self updateScrollers]; } @@ -207,15 +343,15 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; // ifdef it to fix correctness issues on Tiger documented in <rdar://problem/5441823>. #ifndef BUILDING_ON_TIGER // Update the scrollers if they're not being suppressed. - if (!suppressScrollers) + if (!_private->suppressScrollers) [super reflectScrolledClipView:clipView]; #else - [super reflectScrolledClipView:clipView]; - - // Validate the scrollers if they're being suppressed. - if (suppressScrollers) { - [[self verticalScroller] setNeedsDisplay: NO]; - [[self horizontalScroller] setNeedsDisplay: NO]; + [super reflectScrolledClipView:clipView]; + + // Validate the scrollers if they're being suppressed. + if (_private->suppressScrollers) { + [[self verticalScroller] setNeedsDisplay:NO]; + [[self horizontalScroller] setNeedsDisplay:NO]; } #endif @@ -231,28 +367,28 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; - (BOOL)allowsHorizontalScrolling { - return hScroll != ScrollbarAlwaysOff; + return _private->hScroll != ScrollbarAlwaysOff; } - (BOOL)allowsVerticalScrolling { - return vScroll != ScrollbarAlwaysOff; + return _private->vScroll != ScrollbarAlwaysOff; } - (void)scrollingModes:(WebCore::ScrollbarMode*)hMode vertical:(WebCore::ScrollbarMode*)vMode { - *hMode = static_cast<ScrollbarMode>(hScroll); - *vMode = static_cast<ScrollbarMode>(vScroll); + *hMode = _private->hScroll; + *vMode = _private->vScroll; } - (ScrollbarMode)horizontalScrollingMode { - return static_cast<ScrollbarMode>(hScroll); + return _private->hScroll; } - (ScrollbarMode)verticalScrollingMode { - return static_cast<ScrollbarMode>(vScroll); + return _private->vScroll; } - (void)setHorizontalScrollingMode:(ScrollbarMode)horizontalMode andLock:(BOOL)lock @@ -274,13 +410,13 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; - (void)setScrollingModes:(ScrollbarMode)horizontalMode vertical:(ScrollbarMode)verticalMode andLock:(BOOL)lock { BOOL update = NO; - if (verticalMode != vScroll && !vScrollModeLocked) { - vScroll = verticalMode; + if (verticalMode != _private->vScroll && !_private->vScrollModeLocked) { + _private->vScroll = verticalMode; update = YES; } - if (horizontalMode != hScroll && !hScrollModeLocked) { - hScroll = horizontalMode; + if (horizontalMode != _private->hScroll && !_private->hScrollModeLocked) { + _private->hScroll = horizontalMode; update = YES; } @@ -293,27 +429,27 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; - (void)setHorizontalScrollingModeLocked:(BOOL)locked { - hScrollModeLocked = locked; + _private->hScrollModeLocked = locked; } - (void)setVerticalScrollingModeLocked:(BOOL)locked { - vScrollModeLocked = locked; + _private->vScrollModeLocked = locked; } - (void)setScrollingModesLocked:(BOOL)locked { - hScrollModeLocked = vScrollModeLocked = locked; + _private->hScrollModeLocked = _private->vScrollModeLocked = locked; } - (BOOL)horizontalScrollingModeLocked { - return hScrollModeLocked; + return _private->hScrollModeLocked; } - (BOOL)verticalScrollingModeLocked { - return vScrollModeLocked; + return _private->vScrollModeLocked; } - (BOOL)autoforwardsScrollWheelEvents @@ -325,8 +461,10 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; { float deltaX; float deltaY; + float wheelTicksX; + float wheelTicksY; BOOL isContinuous; - WKGetWheelEventDeltas(event, &deltaX, &deltaY, &isContinuous); + WKGetWheelEventDeltas(event, &deltaX, &deltaY, &wheelTicksX, &wheelTicksY, &isContinuous); BOOL isLatchingEvent = WKIsLatchingWheelEvent(event); @@ -336,7 +474,7 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; return; } - if (isLatchingEvent && !verticallyPinnedByPreviousWheelEvent) { + if (isLatchingEvent && !_private->verticallyPinnedByPreviousWheelEvent) { double verticalPosition = [[self verticalScroller] doubleValue]; if ((deltaY >= 0.0 && verticalPosition == 0.0) || (deltaY <= 0.0 && verticalPosition == 1.0)) return; @@ -347,7 +485,7 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; return; } - if (isLatchingEvent && !horizontallyPinnedByPreviousWheelEvent) { + if (isLatchingEvent && !_private->horizontallyPinnedByPreviousWheelEvent) { double horizontalPosition = [[self horizontalScroller] doubleValue]; if ((deltaX >= 0.0 && horizontalPosition == 0.0) || (deltaX <= 0.0 && horizontalPosition == 1.0)) return; @@ -364,8 +502,8 @@ static const unsigned cMaxUpdateScrollbarsPass = 2; double verticalPosition = [[self verticalScroller] doubleValue]; double horizontalPosition = [[self horizontalScroller] doubleValue]; - verticallyPinnedByPreviousWheelEvent = (verticalPosition == 0.0 || verticalPosition == 1.0); - horizontallyPinnedByPreviousWheelEvent = (horizontalPosition == 0.0 || horizontalPosition == 1.0); + _private->verticallyPinnedByPreviousWheelEvent = (verticalPosition == 0.0 || verticalPosition == 1.0); + _private->horizontallyPinnedByPreviousWheelEvent = (horizontalPosition == 0.0 || horizontalPosition == 1.0); } [self release]; diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsViewInternal.h b/WebKit/mac/WebView/WebDynamicScrollBarsViewInternal.h index 312cf9d..40be88d 100644 --- a/WebKit/mac/WebView/WebDynamicScrollBarsViewInternal.h +++ b/WebKit/mac/WebView/WebDynamicScrollBarsViewInternal.h @@ -53,4 +53,6 @@ - (void)updateScrollers; - (void)setSuppressLayout:(BOOL)flag; +// Calculate the appropriate frame for the contentView based on allowsScrollersToOverlapContent. +- (NSRect)contentViewFrame; @end diff --git a/WebKit/mac/WebView/WebFrame.h b/WebKit/mac/WebView/WebFrame.h index a6cdebb..64015fd 100644 --- a/WebKit/mac/WebView/WebFrame.h +++ b/WebKit/mac/WebView/WebFrame.h @@ -213,5 +213,4 @@ bridge between the WebKit and JavaScriptCore APIs. */ - (JSGlobalContextRef)globalContext; - @end diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm index 267d319..b4169b6 100644 --- a/WebKit/mac/WebView/WebFrame.mm +++ b/WebKit/mac/WebView/WebFrame.mm @@ -39,6 +39,7 @@ #import "WebChromeClient.h" #import "WebDataSourceInternal.h" #import "WebDocumentLoaderMac.h" +#import "WebDynamicScrollBarsView.h" #import "WebFrameLoaderClient.h" #import "WebFrameViewInternal.h" #import "WebHTMLView.h" @@ -73,6 +74,7 @@ #import <WebCore/LegacyWebArchive.h> #import <WebCore/Page.h> #import <WebCore/PluginData.h> +#import <WebCore/PrintContext.h> #import <WebCore/RenderLayer.h> #import <WebCore/RenderPart.h> #import <WebCore/RenderView.h> @@ -581,22 +583,16 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) if (!documentView) return pages; - float currPageHeight = printHeight; - float docHeight = root->layer()->height(); float docWidth = root->layer()->width(); - float printWidth = docWidth/printWidthScaleFactor; - - // We need to give the part the opportunity to adjust the page height at each step. - for (float i = 0; i < docHeight; i += currPageHeight) { - float proposedBottom = min(docHeight, i + printHeight); - view->adjustPageHeight(&proposedBottom, i, proposedBottom, i); - currPageHeight = max(1.0f, proposedBottom - i); - for (float j = 0; j < docWidth; j += printWidth) { - NSValue* val = [NSValue valueWithRect: NSMakeRect(j, i, printWidth, currPageHeight)]; - [pages addObject: val]; - } - } - + float printWidth = docWidth / printWidthScaleFactor; + + PrintContext printContext(_private->coreFrame); + printContext.computePageRectsWithPageSize(FloatSize(printWidth, printHeight), true); + + const Vector<IntRect>& pageRects = printContext.pageRects(); + const size_t pageCount = pageRects.size(); + for (size_t pageNumber = 0; pageNumber < pageCount; ++pageNumber) + [pages addObject: [NSValue valueWithRect: NSRect(pageRects[pageNumber])]]; return pages; } @@ -634,7 +630,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) return @""; JSLock lock(SilenceAssertionsOnly); - return String(result.toString(_private->coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec())); + return ustringToString(result.toString(_private->coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec())); } - (NSRect)_caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity @@ -965,7 +961,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (BOOL)_canProvideDocumentSource { Frame* frame = _private->coreFrame; - String mimeType = frame->loader()->responseMIMEType(); + String mimeType = frame->loader()->writer()->mimeType(); PluginData* pluginData = frame->page() ? frame->page()->pluginData() : 0; if (WebCore::DOMImplementation::isTextMIMEType(mimeType) || @@ -990,7 +986,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) bool userChosen = !encoding.isNull(); if (encoding.isNull()) encoding = textEncodingName; - _private->coreFrame->loader()->setEncoding(encoding, userChosen); + _private->coreFrame->loader()->writer()->setEncoding(encoding, userChosen); [self _addData:data]; } @@ -1267,7 +1263,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) return @""; JSLock lock(SilenceAssertionsOnly); - return String(result.toString(anyWorldGlobalObject->globalExec())); + return ustringToString(result.toString(anyWorldGlobalObject->globalExec())); } - (JSGlobalContextRef)_globalContextForScriptWorld:(WebScriptWorld *)world @@ -1281,6 +1277,48 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) return toGlobalRef(coreFrame->script()->globalObject(coreWorld)->globalExec()); } +- (void)setAllowsScrollersToOverlapContent:(BOOL)flag +{ + ASSERT([[[self frameView] _scrollView] isKindOfClass:[WebDynamicScrollBarsView class]]); + [(WebDynamicScrollBarsView *)[[self frameView] _scrollView] setAllowsScrollersToOverlapContent:flag]; +} + +- (void)setAlwaysHideHorizontalScroller:(BOOL)flag +{ + ASSERT([[[self frameView] _scrollView] isKindOfClass:[WebDynamicScrollBarsView class]]); + [(WebDynamicScrollBarsView *)[[self frameView] _scrollView] setAlwaysHideHorizontalScroller:flag]; +} +- (void)setAlwaysHideVerticalScroller:(BOOL)flag +{ + ASSERT([[[self frameView] _scrollView] isKindOfClass:[WebDynamicScrollBarsView class]]); + [(WebDynamicScrollBarsView *)[[self frameView] _scrollView] setAlwaysHideVerticalScroller:flag]; +} + +- (void)setAccessibleName:(NSString *)name +{ +#if HAVE(ACCESSIBILITY) + if (!AXObjectCache::accessibilityEnabled()) + return; + + RenderView* root = toRenderView(_private->coreFrame->document()->renderer()); + if (!root) + return; + + AccessibilityObject* rootObject = _private->coreFrame->document()->axObjectCache()->getOrCreate(root); + String strName(name); + rootObject->setAccessibleName(strName); +#endif +} + +- (NSString*)_layerTreeAsText +{ + Frame* coreFrame = _private->coreFrame; + if (!coreFrame) + return @""; + + return coreFrame->layerTreeAsText(); +} + @end @implementation WebFrame diff --git a/WebKit/mac/WebView/WebFramePrivate.h b/WebKit/mac/WebView/WebFramePrivate.h index 462686f..0bda966 100644 --- a/WebKit/mac/WebView/WebFramePrivate.h +++ b/WebKit/mac/WebView/WebFramePrivate.h @@ -120,4 +120,20 @@ typedef enum { - (NSMutableDictionary *)_cacheabilityDictionary; - (BOOL)_allowsFollowingLink:(NSURL *)URL; + +// Sets whether the scrollbars, if any, should be shown inside the document's border +// (thus overlapping some content) or outside the webView's border (default behavior). +// Changing this flag changes the size of the contentView and maintains the size of the frameView. +- (void)setAllowsScrollersToOverlapContent:(BOOL)flag; + +// Sets if the scrollbar is always hidden, regardless of other scrollbar visibility settings. +// This does not affect the scrollability of the document. +- (void)setAlwaysHideHorizontalScroller:(BOOL)flag; +- (void)setAlwaysHideVerticalScroller:(BOOL)flag; + +// Sets the name presented to accessibility clients for the web area object. +- (void)setAccessibleName:(NSString *)name; + +- (NSString*)_layerTreeAsText; + @end diff --git a/WebKit/mac/WebView/WebFrameView.mm b/WebKit/mac/WebView/WebFrameView.mm index 422b605..9ded8e1 100644 --- a/WebKit/mac/WebView/WebFrameView.mm +++ b/WebKit/mac/WebView/WebFrameView.mm @@ -532,7 +532,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl { if ([self _scrollOverflowInDirection:ScrollUp granularity:ScrollByDocument]) return YES; - if (![self _hasScrollBars]) + if (![self _isScrollable]) return NO; NSPoint point = [[[self _scrollView] documentView] frame].origin; return [[self _contentView] _scrollTo:&point animate:YES]; @@ -542,7 +542,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl { if ([self _scrollOverflowInDirection:ScrollDown granularity:ScrollByDocument]) return YES; - if (![self _hasScrollBars]) + if (![self _isScrollable]) return NO; NSRect frame = [[[self _scrollView] documentView] frame]; NSPoint point = NSMakePoint(frame.origin.x, NSMaxY(frame)); @@ -554,7 +554,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl if ([self _scrollToBeginningOfDocument]) return; - if (WebFrameView *child = [self _largestChildWithScrollBars]) { + if (WebFrameView *child = [self _largestScrollableChild]) { if ([child _scrollToBeginningOfDocument]) return; } @@ -566,7 +566,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl if ([self _scrollToEndOfDocument]) return; - if (WebFrameView *child = [self _largestChildWithScrollBars]) { + if (WebFrameView *child = [self _largestScrollableChild]) { if ([child _scrollToEndOfDocument]) return; } @@ -619,8 +619,8 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl if ([self _scrollOverflowInDirection:up ? ScrollUp : ScrollDown granularity:ScrollByPage]) return YES; - if (![self _hasScrollBars]) - return [[self _largestChildWithScrollBars] _pageVertically:up]; + if (![self _isScrollable]) + return [[self _largestScrollableChild] _pageVertically:up]; float delta = [self _verticalPageScrollDistance]; return [self _scrollVerticallyBy:up ? -delta : delta]; @@ -631,8 +631,8 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl if ([self _scrollOverflowInDirection:left ? ScrollLeft : ScrollRight granularity:ScrollByPage]) return YES; - if (![self _hasScrollBars]) - return [[self _largestChildWithScrollBars] _pageHorizontally:left]; + if (![self _isScrollable]) + return [[self _largestScrollableChild] _pageHorizontally:left]; float delta = [self _horizontalPageScrollDistance]; return [self _scrollHorizontallyBy:left ? -delta : delta]; @@ -643,8 +643,8 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl if ([self _scrollOverflowInDirection:up ? ScrollUp : ScrollDown granularity:ScrollByLine]) return YES; - if (![self _hasScrollBars]) - return [[self _largestChildWithScrollBars] _scrollLineVertically:up]; + if (![self _isScrollable]) + return [[self _largestScrollableChild] _scrollLineVertically:up]; float delta = [self _verticalKeyboardScrollDistance]; return [self _scrollVerticallyBy:up ? -delta : delta]; @@ -655,8 +655,8 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl if ([self _scrollOverflowInDirection:left ? ScrollLeft : ScrollRight granularity:ScrollByLine]) return YES; - if (![self _hasScrollBars]) - return [[self _largestChildWithScrollBars] _scrollLineHorizontally:left]; + if (![self _isScrollable]) + return [[self _largestScrollableChild] _scrollLineHorizontally:left]; float delta = [self _horizontalKeyboardScrollDistance]; return [self _scrollHorizontallyBy:left ? -delta : delta]; @@ -730,7 +730,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl // Checking for a control will allow events to percolate // correctly when the focus is on a form control and we // are in full keyboard access mode. - if ((![self allowsScrolling] && ![self _largestChildWithScrollBars]) || [self _firstResponderIsFormControl]) { + if ((![self allowsScrolling] && ![self _largestScrollableChild]) || [self _firstResponderIsFormControl]) { callSuper = YES; break; } @@ -742,7 +742,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl callSuper = NO; break; case NSPageUpFunctionKey: - if (![self allowsScrolling] && ![self _largestChildWithScrollBars]) { + if (![self allowsScrolling] && ![self _largestScrollableChild]) { callSuper = YES; break; } @@ -750,7 +750,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl callSuper = NO; break; case NSPageDownFunctionKey: - if (![self allowsScrolling] && ![self _largestChildWithScrollBars]) { + if (![self allowsScrolling] && ![self _largestScrollableChild]) { callSuper = YES; break; } @@ -758,7 +758,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl callSuper = NO; break; case NSHomeFunctionKey: - if (![self allowsScrolling] && ![self _largestChildWithScrollBars]) { + if (![self allowsScrolling] && ![self _largestScrollableChild]) { callSuper = YES; break; } @@ -766,7 +766,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl callSuper = NO; break; case NSEndFunctionKey: - if (![self allowsScrolling] && ![self _largestChildWithScrollBars]) { + if (![self allowsScrolling] && ![self _largestScrollableChild]) { callSuper = YES; break; } @@ -779,7 +779,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl callSuper = YES; break; } - if ((![self allowsScrolling] && ![self _largestChildWithScrollBars]) || + if ((![self allowsScrolling] && ![self _largestScrollableChild]) || [[[self window] firstResponder] isKindOfClass:[NSPopUpButton class]]) { // Let arrow keys go through to pop up buttons // <rdar://problem/3455910>: hitting up or down arrows when focus is on a @@ -802,7 +802,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl callSuper = YES; break; } - if ((![self allowsScrolling] && ![self _largestChildWithScrollBars]) || + if ((![self allowsScrolling] && ![self _largestScrollableChild]) || [[[self window] firstResponder] isKindOfClass:[NSPopUpButton class]]) { // Let arrow keys go through to pop up buttons // <rdar://problem/3455910>: hitting up or down arrows when focus is on a @@ -834,7 +834,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl [self _goBack]; } else { // Now check scrolling related keys. - if ((![self allowsScrolling] && ![self _largestChildWithScrollBars])) { + if ((![self allowsScrolling] && ![self _largestScrollableChild])) { callSuper = YES; break; } @@ -862,7 +862,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl [self _goForward]; } else { // Now check scrolling related keys. - if ((![self allowsScrolling] && ![self _largestChildWithScrollBars])) { + if ((![self allowsScrolling] && ![self _largestScrollableChild])) { callSuper = YES; break; } @@ -939,14 +939,52 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl return frame.size.height * frame.size.width; } +- (BOOL)_isScrollable +{ + WebDynamicScrollBarsView *scrollView = [self _scrollView]; + return [scrollView horizontalScrollingAllowed] || [scrollView verticalScrollingAllowed]; +} + +- (WebFrameView *)_largestScrollableChild +{ + WebFrameView *largest = nil; + NSArray *frameChildren = [[self webFrame] childFrames]; + + unsigned i; + for (i=0; i < [frameChildren count]; i++) { + WebFrameView *childFrameView = [[frameChildren objectAtIndex:i] frameView]; + WebFrameView *scrollableFrameView = [childFrameView _isScrollable] ? childFrameView : [childFrameView _largestScrollableChild]; + if (!scrollableFrameView) + continue; + + // Some ads lurk in child frames of zero width and height, see radar 4406994. These don't count as scrollable. + // Maybe someday we'll discover that this minimum area check should be larger, but this covers the known cases. + float area = [scrollableFrameView _area]; + if (area < 1.0) + continue; + + if (!largest || (area > [largest _area])) { + largest = scrollableFrameView; + } + } + + return largest; +} + - (BOOL)_hasScrollBars { + // FIXME: This method was used by Safari 4.0.x and older versions, but has not been used by any other WebKit + // clients to my knowledge, and will not be used by future versions of Safari. It can probably be removed + // once we no longer need to keep nightly WebKit builds working with Safari 4.0.x and earlier. NSScrollView *scrollView = [self _scrollView]; return [scrollView hasHorizontalScroller] || [scrollView hasVerticalScroller]; } - (WebFrameView *)_largestChildWithScrollBars { + // FIXME: This method was used by Safari 4.0.x and older versions, but has not been used by any other WebKit + // clients to my knowledge, and will not be used by future versions of Safari. It can probably be removed + // once we no longer need to keep nightly WebKit builds working with Safari 4.0.x and earlier. WebFrameView *largest = nil; NSArray *frameChildren = [[self webFrame] childFrames]; diff --git a/WebKit/mac/WebView/WebFrameViewPrivate.h b/WebKit/mac/WebView/WebFrameViewPrivate.h index 47c053e..93d36ec 100644 --- a/WebKit/mac/WebView/WebFrameViewPrivate.h +++ b/WebKit/mac/WebView/WebFrameViewPrivate.h @@ -30,13 +30,19 @@ @interface WebFrameView (WebPrivate) +// FIXME: This method was used by Safari 4.0.x and older versions, but has not been used by any other WebKit +// clients to my knowledge, and will not be used by future versions of Safari. It can probably be removed +// once we no longer need to keep nightly WebKit builds working with Safari 4.0.x and earlier. /*! @method _largestChildWithScrollBars @abstract Of the child WebFrameViews that are displaying scroll bars, determines which has the largest area. @result A child WebFrameView that is displaying scroll bars, or nil if none. -*/ + */ - (WebFrameView *)_largestChildWithScrollBars; +// FIXME: This method was used by Safari 4.0.x and older versions, but has not been used by any other WebKit +// clients to my knowledge, and will not be used by future versions of Safari. It can probably be removed +// once we no longer need to keep nightly WebKit builds working with Safari 4.0.x and earlier. /*! @method _hasScrollBars @result YES if at least one scroll bar is currently displayed @@ -44,6 +50,21 @@ - (BOOL)_hasScrollBars; /*! + @method _largestScrollableChild + @abstract Of the child WebFrameViews that allow scrolling, determines which has the largest area. + @result A child WebFrameView that is scrollable, or nil if none. + */ +- (WebFrameView *)_largestScrollableChild; + +/*! + @method _isScrollable + @result YES if scrolling is currently possible, whether or not scroll bars are currently showing. This + differs from -allowsScrolling in that the latter method only checks whether scrolling has been + explicitly disallowed via a call to setAllowsScrolling:NO. + */ +- (BOOL)_isScrollable; + +/*! @method _contentView @result The content view (NSClipView) of the WebFrameView's scroll view. */ diff --git a/WebKit/mac/WebView/WebHTMLRepresentation.mm b/WebKit/mac/WebView/WebHTMLRepresentation.mm index 3aaa914..2684004 100644 --- a/WebKit/mac/WebView/WebHTMLRepresentation.mm +++ b/WebKit/mac/WebView/WebHTMLRepresentation.mm @@ -302,7 +302,8 @@ static HTMLInputElement* inputElementFromDOMElement(DOMElement* element) { HTMLInputElement* inputElement = inputElementFromDOMElement(element); return inputElement - && inputElement->inputType() == HTMLInputElement::TEXT + && inputElement->isTextField() + && inputElement->inputType() != HTMLInputElement::PASSWORD && inputElement->autoComplete(); } diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm index aa65920..daeeb10 100644 --- a/WebKit/mac/WebView/WebHTMLView.mm +++ b/WebKit/mac/WebView/WebHTMLView.mm @@ -148,26 +148,52 @@ using namespace std; - (BOOL)receivedUnhandledCommand; @end -static IMP oldSetCursorIMP = NULL; +// if YES, do the standard NSView hit test (which can't give the right result when HTML overlaps a view) +static BOOL forceNSViewHitTest; -#ifdef BUILDING_ON_TIGER +// if YES, do the "top WebHTMLView" hit test (which we'd like to do all the time but can't because of Java requirements [see bug 4349721]) +static BOOL forceWebHTMLViewHitTest; + +static WebHTMLView *lastHitView; + +static bool needsCursorRectsSupportAtPoint(NSWindow* window, NSPoint point) +{ + forceNSViewHitTest = YES; + NSView* view = [[window _web_borderView] hitTest:point]; + forceNSViewHitTest = NO; + + // WebHTMLView doesn't use cursor rects. + if ([view isKindOfClass:[WebHTMLView class]]) + return false; + + // Neither do NPAPI plug-ins. + if ([view isKindOfClass:[WebBaseNetscapePluginView class]]) + return false; + + // Non-Web content, WebPDFView, and WebKit plug-ins use normal cursor handling. + return true; +} + +#ifndef BUILDING_ON_TIGER + +static IMP oldSetCursorForMouseLocationIMP; + +// Overriding an internal method is a hack; <rdar://problem/7662987> tracks finding a better solution. +static void setCursor(NSWindow* self, SEL cmd, NSPoint point) +{ + if (needsCursorRectsSupportAtPoint(self, point)) + oldSetCursorForMouseLocationIMP(self, cmd, point); +} + +#else -static IMP oldResetCursorRectsIMP = NULL; +static IMP oldResetCursorRectsIMP; +static IMP oldSetCursorIMP; static BOOL canSetCursor = YES; static void resetCursorRects(NSWindow* self, SEL cmd) { - NSPoint point = [self mouseLocationOutsideOfEventStream]; - NSView* view = [[self _web_borderView] hitTest:point]; - if ([view isKindOfClass:[WebHTMLView class]]) { - WebHTMLView *htmlView = (WebHTMLView*)view; - NSPoint localPoint = [htmlView convertPoint:point fromView:nil]; - NSDictionary *dict = [htmlView elementAtPoint:localPoint allowShadowContent:NO]; - DOMElement *element = [dict objectForKey:WebElementDOMNodeKey]; - if (![element isKindOfClass:[DOMHTMLAppletElement class]] && ![element isKindOfClass:[DOMHTMLObjectElement class]] && - ![element isKindOfClass:[DOMHTMLEmbedElement class]]) - canSetCursor = NO; - } + canSetCursor = needsCursorRectsSupportAtPoint(self, [self mouseLocationOutsideOfEventStream]); oldResetCursorRectsIMP(self, cmd); canSetCursor = YES; } @@ -178,23 +204,6 @@ static void setCursor(NSCursor* self, SEL cmd) oldSetCursorIMP(self, cmd); } -#else - -static void setCursor(NSWindow* self, SEL cmd, NSPoint point) -{ - NSView* view = [[self _web_borderView] hitTest:point]; - if ([view isKindOfClass:[WebHTMLView class]]) { - WebHTMLView *htmlView = (WebHTMLView*)view; - NSPoint localPoint = [htmlView convertPoint:point fromView:nil]; - NSDictionary *dict = [htmlView elementAtPoint:localPoint allowShadowContent:NO]; - DOMElement *element = [dict objectForKey:WebElementDOMNodeKey]; - if (![element isKindOfClass:[DOMHTMLAppletElement class]] && ![element isKindOfClass:[DOMHTMLObjectElement class]] && - ![element isKindOfClass:[DOMHTMLEmbedElement class]]) - return; - } - oldSetCursorIMP(self, cmd, point); -} - #endif extern "C" { @@ -241,13 +250,13 @@ extern NSString *NSTextInputReplacementRangeAttributeName; // print in IE and Camino. This lets them use fewer sheets than they // would otherwise, which is presumably why other browsers do this. // Wide pages will be scaled down more than this. -#define PrintingMinimumShrinkFactor 1.25f +const float _WebHTMLViewPrintingMinimumShrinkFactor = 1.25; // This number determines how small we are willing to reduce the page content // in order to accommodate the widest line. If the page would have to be // reduced smaller to make the widest line fit, we just clip instead (this // behavior matches MacIE and Mozilla, at least) -#define PrintingMaximumShrinkFactor 2.0f +const float _WebHTMLViewPrintingMaximumShrinkFactor = 2; // This number determines how short the last printed page of a multi-page print session // can be before we try to shrink the scale in order to reduce the number of pages, and @@ -294,14 +303,6 @@ extern NSString *NSTextInputReplacementRangeAttributeName; @implementation WebCoreScrollView @end -// if YES, do the standard NSView hit test (which can't give the right result when HTML overlaps a view) -static BOOL forceNSViewHitTest; - -// if YES, do the "top WebHTMLView" hit test (which we'd like to do all the time but can't because of Java requirements [see bug 4349721]) -static BOOL forceWebHTMLViewHitTest; - -static WebHTMLView *lastHitView; - // We need this to be able to safely reference the CachedImage for the promised drag data static CachedResourceClient* promisedDataClient() { @@ -321,7 +322,6 @@ static CachedResourceClient* promisedDataClient() - (BOOL)_shouldInsertFragment:(DOMDocumentFragment *)fragment replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action; - (BOOL)_shouldInsertText:(NSString *)text replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action; - (BOOL)_shouldReplaceSelectionWithText:(NSString *)text givenAction:(WebViewInsertAction)action; -- (float)_calculatePrintHeight; - (DOMRange *)_selectedRange; - (BOOL)_shouldDeleteRange:(DOMRange *)range; - (NSView *)_hitViewForEvent:(NSEvent *)event; @@ -428,6 +428,9 @@ struct WebHTMLViewInterpretKeyEventsParameters { BOOL exposeInputContext; NSPoint lastScrollPosition; +#ifndef BUILDING_ON_TIGER + BOOL inScrollPositionChanged; +#endif WebPluginController *pluginController; @@ -490,20 +493,21 @@ static NSCellStateValue kit(TriState state) #ifndef BUILDING_ON_TIGER WebCoreObjCFinalizeOnMainThread(self); #endif - + +#ifndef BUILDING_ON_TIGER + if (!oldSetCursorForMouseLocationIMP) { + Method setCursorMethod = class_getInstanceMethod([NSWindow class], @selector(_setCursorForMouseLocation:)); + ASSERT(setCursorMethod); + oldSetCursorForMouseLocationIMP = method_setImplementation(setCursorMethod, (IMP)setCursor); + ASSERT(oldSetCursorForMouseLocationIMP); + } +#else if (!oldSetCursorIMP) { -#ifdef BUILDING_ON_TIGER Method setCursorMethod = class_getInstanceMethod([NSCursor class], @selector(set)); -#else - Method setCursorMethod = class_getInstanceMethod([NSWindow class], @selector(_setCursorForMouseLocation:)); -#endif ASSERT(setCursorMethod); - oldSetCursorIMP = method_setImplementation(setCursorMethod, (IMP)setCursor); ASSERT(oldSetCursorIMP); } - -#ifdef BUILDING_ON_TIGER if (!oldResetCursorRectsIMP) { Method resetCursorRectsMethod = class_getInstanceMethod([NSWindow class], @selector(resetCursorRects)); ASSERT(resetCursorRectsMethod); @@ -896,17 +900,6 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) return [self _shouldInsertText:text replacingDOMRange:[self _selectedRange] givenAction:action]; } -// Calculate the vertical size of the view that fits on a single page -- (float)_calculatePrintHeight -{ - // Obtain the print info object for the current operation - NSPrintInfo *pi = [[NSPrintOperation currentOperation] printInfo]; - - // Calculate the page height in points - NSSize paperSize = [pi paperSize]; - return paperSize.height - [pi topMargin] - [pi bottomMargin]; -} - - (DOMRange *)_selectedRange { Frame* coreFrame = core([self _frame]); @@ -1169,8 +1162,15 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) NSPoint origin = [[self superview] bounds].origin; if (!NSEqualPoints(_private->lastScrollPosition, origin)) { if (Frame* coreFrame = core([self _frame])) { - if (FrameView* coreView = coreFrame->view()) + if (FrameView* coreView = coreFrame->view()) { +#ifndef BUILDING_ON_TIGER + _private->inScrollPositionChanged = YES; +#endif coreView->scrollPositionChanged(); +#ifndef BUILDING_ON_TIGER + _private->inScrollPositionChanged = NO; +#endif + } } [_private->completionController endRevertingChange:NO moveLeft:NO]; @@ -1290,11 +1290,15 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) // There are known cases where -viewWillDraw is not called on all views being drawn. // See <rdar://problem/6964278> for example. Performing layout at this point prevents us from // trying to paint without layout (which WebCore now refuses to do, instead bailing out without - // drawing at all), but we may still fail to update and regions dirtied by the layout which are + // drawing at all), but we may still fail to update any regions dirtied by the layout which are // not already dirty. if ([self _needsLayout]) { - LOG_ERROR("View needs layout. Either -viewWillDraw wasn't called or layout was invalidated during the display operation. Performing layout now."); - [self _web_layoutIfNeededRecursive]; + NSInteger rectCount; + [self getRectsBeingDrawn:0 count:&rectCount]; + if (rectCount) { + LOG_ERROR("View needs layout. Either -viewWillDraw wasn't called or layout was invalidated during the display operation. Performing layout now."); + [self _web_layoutIfNeededRecursive]; + } } #else // Because Tiger does not have viewWillDraw we need to do layout here. @@ -1421,6 +1425,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) else if (forceWebHTMLViewHitTest) captureHitsOnSubviews = YES; else { + // FIXME: Why doesn't this include mouse entered/exited events, or other mouse button events? NSEvent *event = [[self window] currentEvent]; captureHitsOnSubviews = !([event type] == NSMouseMoved || [event type] == NSRightMouseDown @@ -2185,6 +2190,59 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) #endif } +- (BOOL)_isInPrintMode +{ + return _private->printing; +} + +- (BOOL)_beginPrintModeWithPageWidth:(float)pageWidth shrinkToFit:(BOOL)shrinkToFit +{ + Frame* frame = core([self _frame]); + if (!frame) + return NO; + + float minLayoutWidth = 0; + float maxLayoutWidth = 0; + + // If we are a frameset just print with the layout we have onscreen, otherwise relayout + // according to the page width. + if (!frame->document() || !frame->document()->isFrameSet()) { + minLayoutWidth = shrinkToFit ? pageWidth * _WebHTMLViewPrintingMinimumShrinkFactor : pageWidth; + maxLayoutWidth = shrinkToFit ? pageWidth * _WebHTMLViewPrintingMaximumShrinkFactor : pageWidth; + } + [self _setPrinting:YES minimumPageWidth:minLayoutWidth maximumPageWidth:maxLayoutWidth adjustViewSize:YES]; + + return YES; +} + +- (void)_endPrintMode +{ + [self _setPrinting:NO minimumPageWidth:0 maximumPageWidth:0 adjustViewSize:YES]; +} + +- (CGFloat)_adjustedBottomOfPageWithTop:(CGFloat)top bottom:(CGFloat)bottom limit:(CGFloat)bottomLimit +{ + Frame* frame = core([self _frame]); + if (!frame) + return bottom; + + FrameView* view = frame->view(); + if (!view) + return bottom; + + float newBottom; + view->adjustPageHeight(&newBottom, top, bottom, bottomLimit); + +#ifdef __LP64__ + // If the new bottom is equal to the old bottom (when both are treated as floats), we just return the original + // bottom. This prevents rounding errors that can occur when converting newBottom to a double. + if (fabs(static_cast<float>(bottom) - newBottom) <= numeric_limits<float>::epsilon()) + return bottom; + else +#endif + return newBottom; +} + @end @implementation NSView (WebHTMLViewFileInternal) @@ -2522,7 +2580,13 @@ WEBCORE_COMMAND(yankAndSelect) - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType { BOOL isSendTypeOK = !sendType || ([[self pasteboardTypesForSelection] containsObject:sendType] && [self _hasSelection]); - BOOL isReturnTypeOK = !returnType || ([[[self class] _insertablePasteboardTypes] containsObject:returnType] && [self _isEditable]); + BOOL isReturnTypeOK = NO; + if (!returnType) + isReturnTypeOK = YES; + else if ([[[self class] _insertablePasteboardTypes] containsObject:returnType] && [self _isEditable]) { + // We can insert strings in any editable context. We can insert other types, like images, only in rich edit contexts. + isReturnTypeOK = [returnType isEqualToString:NSStringPboardType] || [self _canEditRichly]; + } if (isSendTypeOK && isReturnTypeOK) return self; return [[self nextResponder] validRequestorForSendType:sendType returnType:returnType]; @@ -3130,11 +3194,29 @@ WEBCORE_COMMAND(yankAndSelect) return [[self _webView] drawsBackground]; } +#if !LOG_DISABLED - (void)setNeedsDisplay:(BOOL)flag { LOG(View, "%@ setNeedsDisplay:%@", self, flag ? @"YES" : @"NO"); [super setNeedsDisplay:flag]; } +#endif + +#ifndef BUILDING_ON_TIGER +- (void)setNeedsDisplayInRect:(NSRect)invalidRect +{ + if (_private->inScrollPositionChanged) { + // When scrolling, the dirty regions are adjusted for the scroll only + // after NSViewBoundsDidChangeNotification is sent. Translate the invalid + // rect to pre-scrolled coordinates in order to get the right dirty region + // after adjustment. See <rdar://problem/7678927>. + NSPoint origin = [[self superview] bounds].origin; + invalidRect.origin.x -= _private->lastScrollPosition.x - origin.x; + invalidRect.origin.y -= _private->lastScrollPosition.y - origin.y; + } + [super setNeedsDisplayInRect:invalidRect]; +} +#endif - (void)setNeedsLayout: (BOOL)flag { @@ -3720,7 +3802,7 @@ static BOOL isInPasswordField(Frame* coreFrame) } } - if (printing != _private->printing) { + if (printing || _private->printing) { [_private->pageRects release]; _private->pageRects = nil; _private->printing = printing; @@ -3751,21 +3833,8 @@ static BOOL isInPasswordField(Frame* coreFrame) if (!wasInPrintingMode) [self _setPrinting:YES minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:NO]; - float newBottomFloat = *newBottom; - if (Frame* frame = core([self _frame])) { - if (FrameView* view = frame->view()) - view->adjustPageHeight(&newBottomFloat, oldTop, oldBottom, bottomLimit); - } + *newBottom = [self _adjustedBottomOfPageWithTop:oldTop bottom:oldBottom limit:bottomLimit]; -#ifdef __LP64__ - // If the new bottom is equal to the old bottom (when both are treated as floats), we just copy - // oldBottom over to newBottom. This prevents rounding errors that can occur when converting newBottomFloat to a double. - if (fabs((float)oldBottom - newBottomFloat) <= numeric_limits<float>::epsilon()) - *newBottom = oldBottom; - else -#endif - *newBottom = newBottomFloat; - if (!wasInPrintingMode) { NSPrintOperation *currenPrintOperation = [NSPrintOperation currentOperation]; if (currenPrintOperation) @@ -3777,12 +3846,6 @@ static BOOL isInPasswordField(Frame* coreFrame) } } -- (float)_availablePaperWidthForPrintOperation:(NSPrintOperation *)printOperation -{ - NSPrintInfo *printInfo = [printOperation printInfo]; - return [printInfo paperSize].width - [printInfo leftMargin] - [printInfo rightMargin]; -} - - (float)_scaleFactorForPrintOperation:(NSPrintOperation *)printOperation { float viewWidth = NSWidth([self bounds]); @@ -3792,8 +3855,8 @@ static BOOL isInPasswordField(Frame* coreFrame) } float userScaleFactor = [printOperation _web_pageSetupScaleFactor]; - float maxShrinkToFitScaleFactor = 1.0f / PrintingMaximumShrinkFactor; - float shrinkToFitScaleFactor = [self _availablePaperWidthForPrintOperation:printOperation]/viewWidth; + float maxShrinkToFitScaleFactor = 1.0f / _WebHTMLViewPrintingMaximumShrinkFactor; + float shrinkToFitScaleFactor = [printOperation _web_availablePaperWidth] / viewWidth; float shrinkToAvoidOrphan = _private->avoidingPrintOrphan ? (1.0f / PrintingOrphanShrinkAdjustment) : 1.0f; return userScaleFactor * max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor) * shrinkToAvoidOrphan; } @@ -3813,9 +3876,9 @@ static BOOL isInPasswordField(Frame* coreFrame) [self _setPrinting:YES minimumPageWidth:pageWidth maximumPageWidth:pageWidth adjustViewSize:YES]; } -- (void)_endPrintMode +- (void)_endPrintModeAndRestoreWindowAutodisplay { - [self _setPrinting:NO minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:YES]; + [self _endPrintMode]; [[self window] setAutodisplay:YES]; } @@ -3841,7 +3904,7 @@ static BOOL isInPasswordField(Frame* coreFrame) // cancelled, beginDocument and endDocument must not have been called, and we need to clean up // the print mode here. ASSERT(currentOperation == nil); - [self _endPrintMode]; + [self _endPrintModeAndRestoreWindowAutodisplay]; } } @@ -3851,22 +3914,12 @@ static BOOL isInPasswordField(Frame* coreFrame) // Must do this explicit display here, because otherwise the view might redisplay while the print // sheet was up, using printer fonts (and looking different). [self displayIfNeeded]; - [[self window] setAutodisplay:NO]; - - // If we are a frameset just print with the layout we have onscreen, otherwise relayout - // according to the paper size - float minLayoutWidth = 0.0f; - float maxLayoutWidth = 0.0f; - Frame* frame = core([self _frame]); - if (!frame) - return NO; - if (!frame->document() || !frame->document()->isFrameSet()) { - float paperWidth = [self _availablePaperWidthForPrintOperation:[NSPrintOperation currentOperation]]; - minLayoutWidth = paperWidth * PrintingMinimumShrinkFactor; - maxLayoutWidth = paperWidth * PrintingMaximumShrinkFactor; - } - [self _setPrinting:YES minimumPageWidth:minLayoutWidth maximumPageWidth:maxLayoutWidth adjustViewSize:YES]; // will relayout + [[self window] setAutodisplay:NO]; + NSPrintOperation *printOperation = [NSPrintOperation currentOperation]; + if (![self _beginPrintModeWithPageWidth:[printOperation _web_availablePaperWidth] shrinkToFit:YES]) + return NO; + // 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. @@ -3884,9 +3937,9 @@ static BOOL isInPasswordField(Frame* coreFrame) float totalScaleFactor = [self _scaleFactorForPrintOperation:printOperation]; float userScaleFactor = [printOperation _web_pageSetupScaleFactor]; [_private->pageRects release]; - float fullPageHeight = floorf([self _calculatePrintHeight]/totalScaleFactor); - NSArray *newPageRects = [[self _frame] _computePageRectsWithPrintWidthScaleFactor:userScaleFactor - printHeight:fullPageHeight]; + float fullPageHeight = floorf([printOperation _web_availablePaperHeight] / totalScaleFactor); + WebFrame *frame = [self _frame]; + NSArray *newPageRects = [frame _computePageRectsWithPrintWidthScaleFactor:userScaleFactor printHeight:fullPageHeight]; // AppKit gets all messed up if you give it a zero-length page count (see 3576334), so if we // hit that case we'll pass along a degenerate 1 pixel square to print. This will print @@ -3899,8 +3952,7 @@ static BOOL isInPasswordField(Frame* coreFrame) // content onto one fewer page. If it does, use the adjusted scale. If not, use the original scale. float lastPageHeight = NSHeight([[newPageRects lastObject] rectValue]); if (lastPageHeight/fullPageHeight < LastPrintedPageOrphanRatio) { - NSArray *adjustedPageRects = [[self _frame] _computePageRectsWithPrintWidthScaleFactor:userScaleFactor - printHeight:fullPageHeight*PrintingOrphanShrinkAdjustment]; + NSArray *adjustedPageRects = [frame _computePageRectsWithPrintWidthScaleFactor:userScaleFactor printHeight:fullPageHeight * PrintingOrphanShrinkAdjustment]; // Use the adjusted rects only if the page count went down if ([adjustedPageRects count] < [newPageRects count]) { newPageRects = adjustedPageRects; @@ -3940,7 +3992,7 @@ static BOOL isInPasswordField(Frame* coreFrame) } @catch (NSException *localException) { // Exception during [super beginDocument] means that endDocument will not get called, // so we need to clean up our "print mode" here. - [self _endPrintMode]; + [self _endPrintModeAndRestoreWindowAutodisplay]; } } @@ -3948,7 +4000,7 @@ static BOOL isInPasswordField(Frame* coreFrame) { [super endDocument]; // Note sadly at this point [NSGraphicsContext currentContextDrawingToScreen] is still NO - [self _endPrintMode]; + [self _endPrintModeAndRestoreWindowAutodisplay]; } - (void)keyDown:(NSEvent *)event @@ -4986,22 +5038,21 @@ static BOOL writingDirectionKeyBindingsEnabled() { // FIXME: NSTextView bails out if becoming or resigning first responder, for which it has ivar flags. Not // sure if we need to do something similar. - + if (![self _canEdit]) return; - + NSWindow *window = [self window]; // FIXME: is this first-responder check correct? What happens if a subframe is editable and is first responder? - if ([NSApp keyWindow] != window || [window firstResponder] != self) + if (![window isKeyWindow] || [window firstResponder] != self) return; - + bool multipleFonts = false; NSFont *font = nil; if (Frame* coreFrame = core([self _frame])) { if (const SimpleFontData* fd = coreFrame->editor()->fontForSelection(multipleFonts)) font = fd->getNSFont(); } - // FIXME: for now, return a bogus font that distinguishes the empty selection from the non-empty // selection. We should be able to remove this once the rest of this code works properly. diff --git a/WebKit/mac/WebView/WebHTMLViewPrivate.h b/WebKit/mac/WebView/WebHTMLViewPrivate.h index cb121d8..3beb0d6 100644 --- a/WebKit/mac/WebView/WebHTMLViewPrivate.h +++ b/WebKit/mac/WebView/WebHTMLViewPrivate.h @@ -32,6 +32,12 @@ #define ENABLE_NETSCAPE_PLUGIN_API 1 #endif +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 +#define WebCGFloat float +#else +#define WebCGFloat CGFloat +#endif + @class DOMDocumentFragment; @class DOMNode; @class DOMRange; @@ -46,6 +52,9 @@ - (void)paintHighlightForBox:(NSRect)boxRect onLine:(NSRect)lineRect behindText:(BOOL)text entireLine:(BOOL)line; @end +extern const float _WebHTMLViewPrintingMinimumShrinkFactor; +extern const float _WebHTMLViewPrintingMaximumShrinkFactor; + @interface WebHTMLView (WebPrivate) + (NSArray *)supportedMIMETypes; @@ -124,7 +133,13 @@ // directly, this method must be called before paginating, or the computed height might be incorrect. // Typically this would be called from inside an override of -[NSView knowsPageRange:]. - (void)_layoutForPrinting; +- (WebCGFloat)_adjustedBottomOfPageWithTop:(WebCGFloat)top bottom:(WebCGFloat)bottom limit:(WebCGFloat)bottomLimit; +- (BOOL)_isInPrintMode; +- (BOOL)_beginPrintModeWithPageWidth:(float)pageWidth shrinkToFit:(BOOL)shrinkToFit; +- (void)_endPrintMode; - (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard; @end + +#undef WebCGFloat diff --git a/WebKit/mac/WebView/WebPDFView.h b/WebKit/mac/WebView/WebPDFView.h index bdd2a6e..e480a1b 100644 --- a/WebKit/mac/WebView/WebPDFView.h +++ b/WebKit/mac/WebView/WebPDFView.h @@ -32,7 +32,7 @@ @class PDFView; @class WebDataSource; -@interface WebPDFView : NSView <WebDocumentView, WebDocumentSearching, WebDocumentIncrementalSearching, WebMultipleTextMatches, WebDocumentSelection, WebDocumentElement, _WebDocumentViewState, _WebDocumentZooming> +@interface WebPDFView : NSView <WebDocumentView, WebDocumentSearching, WebDocumentIncrementalSearching, WebMultipleTextMatches, WebDocumentSelection, WebDocumentElement, WebDocumentPDF, _WebDocumentViewState, _WebDocumentZooming> { NSView *previewView; PDFView *PDFSubview; @@ -51,5 +51,6 @@ + (NSBundle *)PDFKitBundle; - (void)setPDFDocument:(PDFDocument *)doc; +- (PDFDocument *)PDFDocument; @end diff --git a/WebKit/mac/WebView/WebPDFView.mm b/WebKit/mac/WebView/WebPDFView.mm index a38412e..1be3033 100644 --- a/WebKit/mac/WebView/WebPDFView.mm +++ b/WebKit/mac/WebView/WebPDFView.mm @@ -182,6 +182,11 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec _ignoreScaleAndDisplayModeAndPageNotifications = NO; } +- (PDFDocument *)PDFDocument +{ + return [PDFSubview document]; +} + #pragma mark NSObject OVERRIDES - (void)dealloc diff --git a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h index 150a020..e74d0e5 100644 --- a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h +++ b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h @@ -91,7 +91,7 @@ #define WebKitWebGLEnabledPreferenceKey @"WebKitWebGLEnabled" #define WebKitUsesProxiedOpenPanelPreferenceKey @"WebKitUsesProxiedOpenPanel" #define WebKitPluginAllowedRunTimePreferenceKey @"WebKitPluginAllowedRunTime" -#define WebKitFrameSetFlatteningEnabledPreferenceKey @"WebKitFrameSetFlatteningEnabled" +#define WebKitFrameFlatteningEnabledPreferenceKey @"WebKitFrameFlatteningEnabled" // These are private both because callers should be using the cover methods and because the // cover methods themselves are private. diff --git a/WebKit/mac/WebView/WebPreferences.mm b/WebKit/mac/WebView/WebPreferences.mm index bd3c2a7..84a6e9e 100644 --- a/WebKit/mac/WebView/WebPreferences.mm +++ b/WebKit/mac/WebView/WebPreferences.mm @@ -357,7 +357,7 @@ static WebCacheModel cacheModelForMainBundle(void) [NSNumber numberWithBool:NO], WebKitWebGLEnabledPreferenceKey, [NSNumber numberWithBool:NO], WebKitUsesProxiedOpenPanelPreferenceKey, [NSNumber numberWithUnsignedInt:4], WebKitPluginAllowedRunTimePreferenceKey, - [NSNumber numberWithBool:NO], WebKitFrameSetFlatteningEnabledPreferenceKey, + [NSNumber numberWithBool:NO], WebKitFrameFlatteningEnabledPreferenceKey, nil]; // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above @@ -1216,14 +1216,14 @@ static NSString *classIBCreatorID = nil; return [self _setIntegerValue:allowedRunTime forKey:WebKitPluginAllowedRunTimePreferenceKey]; } -- (BOOL)isFrameSetFlatteningEnabled +- (BOOL)isFrameFlatteningEnabled { - return [self _boolValueForKey:WebKitFrameSetFlatteningEnabledPreferenceKey]; + return [self _boolValueForKey:WebKitFrameFlatteningEnabledPreferenceKey]; } -- (void)setFrameSetFlatteningEnabled:(BOOL)flag +- (void)setFrameFlatteningEnabled:(BOOL)flag { - [self _setBoolValue:flag forKey:WebKitFrameSetFlatteningEnabledPreferenceKey]; + [self _setBoolValue:flag forKey:WebKitFrameFlatteningEnabledPreferenceKey]; } - (void)didRemoveFromWebView diff --git a/WebKit/mac/WebView/WebPreferencesPrivate.h b/WebKit/mac/WebView/WebPreferencesPrivate.h index b516640..0b5f969 100644 --- a/WebKit/mac/WebView/WebPreferencesPrivate.h +++ b/WebKit/mac/WebView/WebPreferencesPrivate.h @@ -116,8 +116,8 @@ extern NSString *WebPreferencesRemovedNotification; - (unsigned)pluginAllowedRunTime; - (void)setPluginAllowedRunTime:(unsigned)allowedRunTime; -- (BOOL)isFrameSetFlatteningEnabled; -- (void)setFrameSetFlatteningEnabled:(BOOL)flag; +- (BOOL)isFrameFlatteningEnabled; +- (void)setFrameFlatteningEnabled:(BOOL)flag; // zero means do AutoScale - (float)PDFScaleFactor; diff --git a/WebKit/mac/WebView/WebRenderNode.mm b/WebKit/mac/WebView/WebRenderNode.mm index 4a839a5..eff1929 100644 --- a/WebKit/mac/WebView/WebRenderNode.mm +++ b/WebKit/mac/WebView/WebRenderNode.mm @@ -118,8 +118,15 @@ static WebRenderNode *copyRenderNode(RenderObject* node) IntRect box = text->linesBoundingBox(); width = box.width(); height = box.height(); + } else if (node->isRenderInline()) { + RenderBoxModelObject* inlineFlow = toRenderBoxModelObject(node); + IntRect boundingBox = inlineFlow->borderBoundingBox(); + x = boundingBox.x(); + y = boundingBox.y(); + width = boundingBox.width(); + height = boundingBox.height(); } - + WebRenderNode *result = [[WebRenderNode alloc] _initWithName:name position:absPos rect:NSMakeRect(x, y, width, height) coreFrame:frame children:children]; diff --git a/WebKit/mac/WebView/WebScriptDebugDelegate.mm b/WebKit/mac/WebView/WebScriptDebugDelegate.mm index 8489c9b..9ffd36e 100644 --- a/WebKit/mac/WebView/WebScriptDebugDelegate.mm +++ b/WebKit/mac/WebView/WebScriptDebugDelegate.mm @@ -242,14 +242,14 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; DynamicGlobalObjectScope globalObjectScope(globalObject->globalExec(), globalObject); JSValue exception; - JSValue result = evaluateInGlobalCallFrame(String(script), exception, globalObject); + JSValue result = evaluateInGlobalCallFrame(stringToUString(script), exception, globalObject); if (exception) return [self _convertValueToObjcValue:exception]; return result ? [self _convertValueToObjcValue:result] : nil; } JSValue exception; - JSValue result = _private->debuggerCallFrame->evaluate(String(script), exception); + JSValue result = _private->debuggerCallFrame->evaluate(stringToUString(script), exception); if (exception) return [self _convertValueToObjcValue:exception]; return result ? [self _convertValueToObjcValue:result] : nil; diff --git a/WebKit/mac/WebView/WebScriptDebugger.mm b/WebKit/mac/WebView/WebScriptDebugger.mm index a71d78b..c5e0ac8 100644 --- a/WebKit/mac/WebView/WebScriptDebugger.mm +++ b/WebKit/mac/WebView/WebScriptDebugger.mm @@ -69,7 +69,7 @@ static NSURL *toNSURL(const UString& s) { if (s.isEmpty()) return nil; - return KURL(ParsedURLString, s); + return KURL(ParsedURLString, ustringToString(s)); } static WebFrame *toWebFrame(JSGlobalObject* globalObject) diff --git a/WebKit/mac/WebView/WebScriptWorld.h b/WebKit/mac/WebView/WebScriptWorld.h index 7059b76..9a05f7f 100644 --- a/WebKit/mac/WebView/WebScriptWorld.h +++ b/WebKit/mac/WebView/WebScriptWorld.h @@ -36,4 +36,6 @@ typedef struct OpaqueJSContext* JSGlobalContextRef; + (WebScriptWorld *)scriptWorldForGlobalContext:(JSGlobalContextRef)globalContext; +- (void)unregisterWorld; + @end diff --git a/WebKit/mac/WebView/WebScriptWorld.mm b/WebKit/mac/WebView/WebScriptWorld.mm index 7dab1b3..8ca6f44 100644 --- a/WebKit/mac/WebView/WebScriptWorld.mm +++ b/WebKit/mac/WebView/WebScriptWorld.mm @@ -75,6 +75,11 @@ static WorldMap& allWorlds() return [self initWithWorld:ScriptController::createWorld()]; } +- (void)unregisterWorld +{ + _private->world->unregisterWorld(); +} + - (void)dealloc { ASSERT(allWorlds().contains(_private->world.get())); diff --git a/WebKit/mac/WebView/WebTextCompletionController.mm b/WebKit/mac/WebView/WebTextCompletionController.mm index 4f8e6e0..2421fd7 100644 --- a/WebKit/mac/WebView/WebTextCompletionController.mm +++ b/WebKit/mac/WebView/WebTextCompletionController.mm @@ -84,8 +84,7 @@ using namespace std; NSRect scrollFrame = NSMakeRect(0, 0, 100, 100); NSRect tableFrame = NSZeroRect; tableFrame.size = [NSScrollView contentSizeForFrameSize:scrollFrame.size hasHorizontalScroller:NO hasVerticalScroller:YES borderType:NSNoBorder]; - // Added cast to work around problem with multiple Foundation initWithIdentifier: methods with different parameter types. - NSTableColumn *column = [(NSTableColumn *)[NSTableColumn alloc] initWithIdentifier:[NSNumber numberWithInt:0]]; + NSTableColumn *column = [[NSTableColumn alloc] init]; [column setWidth:tableFrame.size.width]; [column setEditable:NO]; diff --git a/WebKit/mac/WebView/WebVideoFullscreenController.mm b/WebKit/mac/WebView/WebVideoFullscreenController.mm index e5fde5e..21e4814 100644 --- a/WebKit/mac/WebView/WebVideoFullscreenController.mm +++ b/WebKit/mac/WebView/WebVideoFullscreenController.mm @@ -37,7 +37,7 @@ #import <wtf/UnusedParam.h> SOFT_LINK_FRAMEWORK(QTKit) -SOFT_LINK_CLASS(QTKit, QTMovieView) +SOFT_LINK_CLASS(QTKit, QTMovieLayer) SOFT_LINK_POINTER(QTKit, QTMovieRateDidChangeNotification, NSString *) @@ -85,17 +85,20 @@ SOFT_LINK_POINTER(QTKit, QTMovieRateDidChangeNotification, NSString *) - (void)windowDidLoad { +#ifdef BUILDING_ON_TIGER + // WebVideoFullscreenController is not supported on Tiger: + ASSERT_NOT_REACHED(); +#else WebVideoFullscreenWindow *window = [self fullscreenWindow]; - QTMovieView *view = [[getQTMovieViewClass() alloc] init]; - [view setFillColor:[NSColor clearColor]]; - [window setContentView:view]; - [view setControllerVisible:NO]; - [view setPreservesAspectRatio:YES]; + QTMovieLayer *layer = [[getQTMovieLayerClass() alloc] init]; + [[window contentView] setLayer:layer]; + [[window contentView] setWantsLayer:YES]; if (_mediaElement) - [view setMovie:_mediaElement->platformMedia().qtMovie]; + [layer setMovie:_mediaElement->platformMedia().qtMovie]; [window setHasShadow:YES]; // This is nicer with a shadow. [window setLevel:NSPopUpMenuWindowLevel-1]; - [view release]; + [layer release]; +#endif } - (WebCore::HTMLMediaElement*)mediaElement; @@ -105,19 +108,24 @@ SOFT_LINK_POINTER(QTKit, QTMovieRateDidChangeNotification, NSString *) - (void)setMediaElement:(WebCore::HTMLMediaElement*)mediaElement; { +#ifdef BUILDING_ON_TIGER + // WebVideoFullscreenController is not supported on Tiger: + ASSERT_NOT_REACHED(); +#else _mediaElement = mediaElement; if ([self isWindowLoaded]) { - QTMovieView *movieView = (QTMovieView *)[[self fullscreenWindow] contentView]; QTMovie *movie = _mediaElement->platformMedia().qtMovie; + QTMovieLayer *movieLayer = (QTMovieLayer *)[[[self fullscreenWindow] contentView] layer]; - ASSERT(movieView && [movieView isKindOfClass:[getQTMovieViewClass() class]]); + ASSERT(movieLayer && [movieLayer isKindOfClass:[getQTMovieLayerClass() class]]); ASSERT(movie); - [movieView setMovie:movie]; + [movieLayer setMovie:movie]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rateChanged:) name:QTMovieRateDidChangeNotification object:movie]; } +#endif } - (id <WebVideoFullscreenControllerDelegate>)delegate diff --git a/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm index 83e2d09..1aa501e 100644 --- a/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm +++ b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm @@ -346,9 +346,9 @@ static NSTextField *createTimeTextField(NSRect frame) static const CGFloat volumeButtonHeight = 16; static const CGFloat volumeUpButtonLeftMargin = 4; static const CGFloat volumeControlsTopMargin = 13; - static const CGFloat exitFullScreenButtonWidth = 25; - static const CGFloat exitFullScreenButtonHeight = 21; - static const CGFloat exitFullScreenButtonTopMargin = 11; + static const CGFloat exitFullscreenButtonWidth = 25; + static const CGFloat exitFullscreenButtonHeight = 21; + static const CGFloat exitFullscreenButtonTopMargin = 11; static const CGFloat timelineWidth = 315; static const CGFloat timelineHeight = 14; static const CGFloat timelineBottomMargin = 7; @@ -380,8 +380,8 @@ static NSTextField *createTimeTextField(NSRect frame) [_playButton setAction:@selector(togglePlaying:)]; [contentView addSubview:_playButton]; - CGFloat closeToRight = windowWidth - horizontalMargin - exitFullScreenButtonWidth; - NSControl *exitFullscreenButton = createControlWithMediaUIControlType(WKMediaUIControlExitFullscreenButton, NSMakeRect(closeToRight, windowHeight - exitFullScreenButtonTopMargin - exitFullScreenButtonHeight, exitFullScreenButtonWidth, exitFullScreenButtonHeight)); + CGFloat closeToRight = windowWidth - horizontalMargin - exitFullscreenButtonWidth; + NSControl *exitFullscreenButton = createControlWithMediaUIControlType(WKMediaUIControlExitFullscreenButton, NSMakeRect(closeToRight, windowHeight - exitFullscreenButtonTopMargin - exitFullscreenButtonHeight, exitFullscreenButtonWidth, exitFullscreenButtonHeight)); [exitFullscreenButton setAction:@selector(exitFullscreen:)]; [exitFullscreenButton setTarget:self]; [contentView addSubview:exitFullscreenButton]; diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm index 44d4b58..b1b5c38 100644 --- a/WebKit/mac/WebView/WebView.mm +++ b/WebKit/mac/WebView/WebView.mm @@ -101,11 +101,15 @@ #import "WebVideoFullscreenController.h" #import <CoreFoundation/CFSet.h> #import <Foundation/NSURLConnection.h> +#import <JavaScriptCore/APICast.h> +#import <JavaScriptCore/JSValueRef.h> #import <WebCore/ApplicationCacheStorage.h> #import <WebCore/BackForwardList.h> #import <WebCore/Cache.h> #import <WebCore/ColorMac.h> +#import <WebCore/CSSComputedStyleDeclaration.h> #import <WebCore/Cursor.h> +#import <WebCore/Database.h> #import <WebCore/Document.h> #import <WebCore/DocumentLoader.h> #import <WebCore/DragController.h> @@ -123,6 +127,8 @@ #import <WebCore/HTMLNames.h> #import <WebCore/HistoryItem.h> #import <WebCore/IconDatabase.h> +#import <WebCore/JSCSSStyleDeclaration.h> +#import <WebCore/JSElement.h> #import <WebCore/Logging.h> #import <WebCore/MIMETypeRegistry.h> #import <WebCore/Page.h> @@ -558,6 +564,16 @@ static bool runningTigerMail() return NO; } +static bool coreVideoHas7228836Fix() +{ +#ifdef BUILDING_ON_LEOPARD + NSBundle* coreVideoFrameworkBundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/CoreVideo.framework"]; + double version = [[coreVideoFrameworkBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey] doubleValue]; + return (version >= 48); +#endif + return true; +} + static bool shouldEnableLoadDeferring() { return !applicationIsAdobeInstaller(); @@ -964,8 +980,6 @@ static bool shouldEnableLoadDeferring() WTF::RefCountedLeakCounter::suppressMessages("At least one WebView was closed with fast teardown."); #endif - _private->closed = YES; - [[NSDistributedNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self]; @@ -998,6 +1012,8 @@ static bool fastDocumentTeardownEnabled() if (!_private || _private->closed) return; + _private->closed = YES; + [self _closingEventHandling]; #ifndef NDEBUG @@ -1031,9 +1047,6 @@ static bool fastDocumentTeardownEnabled() [_private->inspector webViewClosed]; - // setHostWindow:nil must be called before this value is set (see 5408186) - _private->closed = YES; - // To avoid leaks, call removeDragCaret in case it wasn't called after moveDragCaretToPoint. [self removeDragCaret]; @@ -1294,7 +1307,9 @@ static bool fastDocumentTeardownEnabled() settings->setMinimumFontSize([preferences minimumFontSize]); settings->setMinimumLogicalFontSize([preferences minimumLogicalFontSize]); settings->setPluginsEnabled([preferences arePlugInsEnabled]); - settings->setDatabasesEnabled([preferences databasesEnabled]); +#if ENABLE(DATABASE) + Database::setIsAvailable([preferences databasesEnabled]); +#endif settings->setLocalStorageEnabled([preferences localStorageEnabled]); settings->setExperimentalNotificationsEnabled([preferences experimentalNotificationsEnabled]); settings->setPrivateBrowsingEnabled([preferences privateBrowsingEnabled]); @@ -1329,16 +1344,19 @@ static bool fastDocumentTeardownEnabled() settings->setWebArchiveDebugModeEnabled([preferences webArchiveDebugModeEnabled]); settings->setLocalFileContentSniffingEnabled([preferences localFileContentSniffingEnabled]); settings->setOfflineWebApplicationCacheEnabled([preferences offlineWebApplicationCacheEnabled]); - settings->setZoomsTextOnly([preferences zoomsTextOnly]); + settings->setZoomMode([preferences zoomsTextOnly] ? ZoomTextOnly : ZoomPage); settings->setXSSAuditorEnabled([preferences isXSSAuditorEnabled]); settings->setEnforceCSSMIMETypeInStrictMode(!WKAppVersionCheckLessThan(@"com.apple.iWeb", -1, 2.1)); - settings->setAcceleratedCompositingEnabled([preferences acceleratedCompositingEnabled]); + + // FIXME: Enabling accelerated compositing when WebGL is enabled causes tests to fail on Leopard which expect HW compositing to be disabled. + // Until we fix that, I will comment out the test (CFM) + settings->setAcceleratedCompositingEnabled((coreVideoHas7228836Fix() || [preferences webGLEnabled]) && [preferences acceleratedCompositingEnabled]); settings->setShowDebugBorders([preferences showDebugBorders]); settings->setShowRepaintCounter([preferences showRepaintCounter]); settings->setPluginAllowedRunTime([preferences pluginAllowedRunTime]); settings->setWebGLEnabled([preferences webGLEnabled]); settings->setLoadDeferringEnabled(shouldEnableLoadDeferring()); - settings->setFrameSetFlatteningEnabled([preferences isFrameSetFlatteningEnabled]); + settings->setFrameFlatteningEnabled([preferences isFrameFlatteningEnabled]); } static inline IMP getMethod(id o, SEL s) @@ -2229,14 +2247,19 @@ static WebBaseNetscapePluginView *_pluginViewForNode(DOMNode *node) return _private ? _private->insertionPasteboard : nil; } -+ (void)_whiteListAccessFromOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains ++ (void)_addOriginAccessWhitelistEntryWithSourceOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains { - SecurityOrigin::whiteListAccessFromOrigin(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); + SecurityOrigin::addOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); } -+(void)_resetOriginAccessWhiteLists ++ (void)_removeOriginAccessWhitelistEntryWithSourceOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains { - SecurityOrigin::resetOriginAccessWhiteLists(); + SecurityOrigin::removeOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); +} + ++(void)_resetOriginAccessWhitelists +{ + SecurityOrigin::resetOriginAccessWhitelists(); } - (void)_updateActiveState @@ -2378,6 +2401,11 @@ static PassOwnPtr<Vector<String> > toStringVector(NSArray* patterns) SecurityOrigin::setDomainRelaxationForbiddenForURLScheme(forbidden, scheme); } ++ (void)_registerURLSchemeAsSecure:(NSString *)scheme +{ + SecurityOrigin::registerURLSchemeAsSecure(scheme); +} + @end @implementation _WebSafeForwarder @@ -3105,13 +3133,13 @@ static bool needsWebViewInitThreadWorkaround() _private->zoomMultiplier = m; ASSERT(_private->page); if (_private->page) - _private->page->settings()->setZoomsTextOnly(isTextOnly); + _private->page->settings()->setZoomMode(isTextOnly ? ZoomTextOnly : ZoomPage); // FIXME: it would be nice to rework this code so that _private->zoomMultiplier doesn't exist and callers // all access _private->page->settings(). Frame* coreFrame = [self _mainCoreFrame]; if (coreFrame) - coreFrame->setZoomFactor(m, isTextOnly); + coreFrame->setZoomFactor(m, isTextOnly ? ZoomTextOnly : ZoomPage); } - (float)_zoomMultiplier:(BOOL)isTextOnly @@ -3131,7 +3159,7 @@ static bool needsWebViewInitThreadWorkaround() if (!_private->page) return NO; - return _private->page->settings()->zoomsTextOnly(); + return _private->page->settings()->zoomMode() == ZoomTextOnly; } #define MinimumZoomMultiplier 0.5f @@ -3318,7 +3346,7 @@ static bool needsWebViewInitThreadWorkaround() - (void)setHostWindow:(NSWindow *)hostWindow { - if (_private->closed) + if (_private->closed && hostWindow) return; if (hostWindow == _private->hostWindow) return; @@ -4130,7 +4158,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue jsValu if (jsValue.isBoolean()) return [NSAppleEventDescriptor descriptorWithBoolean:jsValue.getBoolean()]; if (jsValue.isString()) - return [NSAppleEventDescriptor descriptorWithString:String(jsValue.getString(exec))]; + return [NSAppleEventDescriptor descriptorWithString:ustringToString(jsValue.getString(exec))]; if (jsValue.isNumber()) { double value = jsValue.uncheckedGetNumber(); int intValue = value; @@ -5681,6 +5709,25 @@ static void layerSyncRunLoopObserverCallBack(CFRunLoopObserverRef, CFRunLoopActi @end +@implementation WebView (WebViewPrivateStyleInfo) + +- (JSValueRef)_computedStyleIncludingVisitedInfo:(JSContextRef)context forElement:(JSValueRef)value +{ + JSLock lock(SilenceAssertionsOnly); + ExecState* exec = toJS(context); + if (!value) + return JSValueMakeUndefined(context); + JSValue jsValue = toJS(exec, value); + if (!jsValue.inherits(&JSElement::s_info)) + return JSValueMakeUndefined(context); + JSElement* jsElement = static_cast<JSElement*>(asObject(jsValue)); + Element* element = jsElement->impl(); + RefPtr<CSSComputedStyleDeclaration> style = computedStyle(element, true); + return toRef(exec, toJS(exec, jsElement->globalObject(), style.get())); +} + +@end + #ifdef BUILDING_ON_LEOPARD static IMP originalRecursivelyRemoveMailAttributesImp; diff --git a/WebKit/mac/WebView/WebViewData.mm b/WebKit/mac/WebView/WebViewData.mm index 21ba4c8..bf81dad 100644 --- a/WebKit/mac/WebView/WebViewData.mm +++ b/WebKit/mac/WebView/WebViewData.mm @@ -65,7 +65,11 @@ int pluginDatabaseClientCount = 0; dashboardBehaviorAllowWheelScrolling = YES; #endif - shouldCloseWithWindow = objc_collecting_enabled(); +#if !defined(BUILDING_ON_TIGER) + shouldCloseWithWindow = objc_collectingEnabled(); +#else + shouldCloseWithWindow = NO; +#endif smartInsertDeleteEnabled = ![[NSUserDefaults standardUserDefaults] objectForKey:WebSmartInsertDeleteEnabled] || [[NSUserDefaults standardUserDefaults] boolForKey:WebSmartInsertDeleteEnabled]; diff --git a/WebKit/mac/WebView/WebViewInternal.h b/WebKit/mac/WebView/WebViewInternal.h index 3f38d58..a2ce646 100644 --- a/WebKit/mac/WebView/WebViewInternal.h +++ b/WebKit/mac/WebView/WebViewInternal.h @@ -174,4 +174,6 @@ namespace WebCore { - (void)_exitFullscreen; #endif +- (JSValueRef)_computedStyleIncludingVisitedInfo:(JSContextRef)context forElement:(JSValueRef)value; + @end diff --git a/WebKit/mac/WebView/WebViewPrivate.h b/WebKit/mac/WebView/WebViewPrivate.h index b0a7039..327743a 100644 --- a/WebKit/mac/WebView/WebViewPrivate.h +++ b/WebKit/mac/WebView/WebViewPrivate.h @@ -489,10 +489,11 @@ Could be worth adding to the API. // - destinationProtocol: The protocol to grant access to. // - destinationHost: The host to grant access to. // - allowDestinationSubdomains: If host is a domain, setting this to YES will whitelist host and all its subdomains, recursively. -+ (void)_whiteListAccessFromOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains; ++ (void)_addOriginAccessWhitelistEntryWithSourceOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains; ++ (void)_removeOriginAccessWhitelistEntryWithSourceOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains; -// Removes all white list entries created with _whiteListAccessFromOrigin. -+ (void)_resetOriginAccessWhiteLists; +// Removes all white list entries created with _addOriginAccessWhitelistEntryWithSourceOrigin. ++ (void)_resetOriginAccessWhitelists; + (void)_addUserScriptToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist injectionTime:(WebUserScriptInjectionTime)injectionTime; + (void)_addUserStyleSheetToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist; @@ -517,6 +518,7 @@ Could be worth adding to the API. - (void)setCSSAnimationsSuspended:(BOOL)suspended; + (void)_setDomainRelaxationForbidden:(BOOL)forbidden forURLScheme:(NSString *)scheme; ++ (void)_registerURLSchemeAsSecure:(NSString *)scheme; @end @@ -598,6 +600,10 @@ Could be worth adding to the API. - (void)_geolocationDidFailWithError:(NSError *)error; @end +@interface WebView (WebViewPrivateStyleInfo) +- (JSValueRef)_computedStyleIncludingVisitedInfo:(JSContextRef)context forElement:(JSValueRef)value; +@end + @interface NSObject (WebFrameLoadDelegatePrivate) - (void)webView:(WebView *)sender didFirstLayoutInFrame:(WebFrame *)frame; |