From 65f03d4f644ce73618e5f4f50dd694b26f55ae12 Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Fri, 13 May 2011 16:23:25 +0100 Subject: Merge WebKit at r75993: Initial merge by git. Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3 --- Source/WebCore/platform/mac/DragDataMac.mm | 76 +++++++++++++++++-------- Source/WebCore/platform/mac/PasteboardMac.mm | 45 ++++++++++++++- Source/WebCore/platform/mac/ThemeMac.mm | 12 +++- Source/WebCore/platform/mac/WheelEventMac.mm | 25 ++++++++- Source/WebCore/platform/mac/WidgetMac.mm | 84 +++++++++++++++++++++++----- 5 files changed, 204 insertions(+), 38 deletions(-) (limited to 'Source/WebCore/platform/mac') diff --git a/Source/WebCore/platform/mac/DragDataMac.mm b/Source/WebCore/platform/mac/DragDataMac.mm index 9cb4836..64376b1 100644 --- a/Source/WebCore/platform/mac/DragDataMac.mm +++ b/Source/WebCore/platform/mac/DragDataMac.mm @@ -33,41 +33,52 @@ #import "DOMDocumentFragmentInternal.h" #import "MIMETypeRegistry.h" #import "Pasteboard.h" -#import "PasteboardHelper.h" +#import "Range.h" namespace WebCore { DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, - DragOperation sourceOperationMask, PasteboardHelper* pasteboardHelper) + DragOperation sourceOperationMask, DragApplicationFlags flags) : m_clientPosition(clientPosition) , m_globalPosition(globalPosition) , m_platformDragData(data) , m_draggingSourceOperationMask(sourceOperationMask) - , m_pasteboardHelper(pasteboardHelper) + , m_applicationFlags(flags) + , m_pasteboard([m_platformDragData draggingPasteboard]) +{ +} + +DragData::DragData(const String& dragStorageName, const IntPoint& clientPosition, const IntPoint& globalPosition, + DragOperation sourceOperationMask, DragApplicationFlags flags) + : m_clientPosition(clientPosition) + , m_globalPosition(globalPosition) + , m_platformDragData(0) + , m_draggingSourceOperationMask(sourceOperationMask) + , m_applicationFlags(flags) + , m_pasteboard([NSPasteboard pasteboardWithName:dragStorageName]) { - ASSERT(pasteboardHelper); } bool DragData::canSmartReplace() const { //Need to call this so that the various Pasteboard type strings are intialised Pasteboard::generalPasteboard(); - return [[[m_platformDragData draggingPasteboard] types] containsObject:WebSmartPastePboardType]; + return [[m_pasteboard.get() types] containsObject:WebSmartPastePboardType]; } bool DragData::containsColor() const { - return [[[m_platformDragData draggingPasteboard] types] containsObject:NSColorPboardType]; + return [[m_pasteboard.get() types] containsObject:NSColorPboardType]; } bool DragData::containsFiles() const { - return [[[m_platformDragData draggingPasteboard] types] containsObject:NSFilenamesPboardType]; + return [[m_pasteboard.get() types] containsObject:NSFilenamesPboardType]; } void DragData::asFilenames(Vector& result) const { - NSArray *filenames = [[m_platformDragData draggingPasteboard] propertyListForType:NSFilenamesPboardType]; + NSArray *filenames = [m_pasteboard.get() propertyListForType:NSFilenamesPboardType]; NSEnumerator *fileEnumerator = [filenames objectEnumerator]; while (NSString *filename = [fileEnumerator nextObject]) @@ -76,19 +87,19 @@ void DragData::asFilenames(Vector& result) const bool DragData::containsPlainText() const { - NSPasteboard *pasteboard = [m_platformDragData draggingPasteboard]; - NSArray *types = [pasteboard types]; + NSArray *types = [m_pasteboard.get() types]; return [types containsObject:NSStringPboardType] || [types containsObject:NSRTFDPboardType] || [types containsObject:NSRTFPboardType] || [types containsObject:NSFilenamesPboardType] - || [NSURL URLFromPasteboard:pasteboard]; + || [NSURL URLFromPasteboard:m_pasteboard.get()]; } -String DragData::asPlainText() const +String DragData::asPlainText(Frame *frame) const { - return m_pasteboardHelper->plainTextFromPasteboard([m_platformDragData draggingPasteboard]); + Pasteboard pasteboard(m_pasteboard.get()); + return pasteboard.plainText(frame); } Color DragData::asColor() const @@ -98,29 +109,50 @@ Color DragData::asColor() const (int)([color blueComponent] * 255.0 + 0.5), (int)([color alphaComponent] * 255.0 + 0.5)); } +static NSArray *insertablePasteboardTypes() +{ + static NSArray *types = nil; + if (!types) { + types = [[NSArray alloc] initWithObjects:WebArchivePboardType, NSHTMLPboardType, NSFilenamesPboardType, NSTIFFPboardType, NSPDFPboardType, +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) + NSPICTPboardType, +#endif + NSURLPboardType, NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, NSColorPboardType, kUTTypePNG, nil]; + CFRetain(types); + } + return types; +} + bool DragData::containsCompatibleContent() const { - NSPasteboard *pasteboard = [m_platformDragData draggingPasteboard]; - NSMutableSet *types = [NSMutableSet setWithArray:[pasteboard types]]; - [types intersectSet:[NSSet setWithArray:m_pasteboardHelper->insertablePasteboardTypes()]]; + NSMutableSet *types = [NSMutableSet setWithArray:[m_pasteboard.get() types]]; + [types intersectSet:[NSSet setWithArray:insertablePasteboardTypes()]]; return [types count] != 0; } -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame* frame, FilenameConversionPolicy filenamePolicy) const { - return !asURL(filenamePolicy).isEmpty(); + return !asURL(frame, filenamePolicy).isEmpty(); } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +String DragData::asURL(Frame* frame, FilenameConversionPolicy filenamePolicy, String* title) const { // FIXME: Use filenamePolicy. (void)filenamePolicy; - return m_pasteboardHelper->urlFromPasteboard([m_platformDragData draggingPasteboard], title); + + if (title) { + if (NSString *URLTitleString = [[m_platformDragData draggingPasteboard] stringForType:WebURLNamePboardType]) + *title = URLTitleString; + } + Pasteboard pasteboard(m_pasteboard.get()); + return pasteboard.asURL(frame); } -PassRefPtr DragData::asFragment(Document*) const +PassRefPtr DragData::asFragment(Frame* frame, PassRefPtr range, bool allowPlainText, bool& chosePlainText) const { - return core(m_pasteboardHelper->fragmentFromPasteboard([m_platformDragData draggingPasteboard])); + Pasteboard pasteboard(m_pasteboard.get()); + + return pasteboard.documentFragment(frame, range, allowPlainText, chosePlainText); } } // namespace WebCore diff --git a/Source/WebCore/platform/mac/PasteboardMac.mm b/Source/WebCore/platform/mac/PasteboardMac.mm index 0625287..71e4046 100644 --- a/Source/WebCore/platform/mac/PasteboardMac.mm +++ b/Source/WebCore/platform/mac/PasteboardMac.mm @@ -191,7 +191,7 @@ void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, if ([types containsObject:NSStringPboardType]) { // Map   to a plain old space because this is better for source code, other browsers do it, // and because HTML forces you to do this any time you want two spaces in a row. - String text = selectedRange->text(); + String text = frame->editor()->selectedText(); NSMutableString *s = [[[(NSString*)text copy] autorelease] mutableCopy]; NSString *NonBreakingSpaceString = [NSString stringWithCharacters:&noBreakSpace length:1]; @@ -436,7 +436,50 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) return URL; } + +NSURL *Pasteboard::getBestURL(Frame* frame) +{ + NSArray *types = [m_pasteboard.get() types]; + + // FIXME: using the editorClient to call into webkit, for now, since + // calling webkit_canonicalize from WebCore involves migrating a sizable amount of + // helper code that should either be done in a separate patch or figured out in another way. + + if ([types containsObject:NSURLPboardType]) { + NSURL *URLFromPasteboard = [NSURL URLFromPasteboard:m_pasteboard.get()]; + NSString *scheme = [URLFromPasteboard scheme]; + if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) { + return frame->editor()->client()->canonicalizeURL(URLFromPasteboard); + } + } + + if ([types containsObject:NSStringPboardType]) { + NSString *URLString = [m_pasteboard.get() stringForType:NSStringPboardType]; + NSURL *URL = frame->editor()->client()->canonicalizeURLString(URLString); + if (URL) + return URL; + } + + if ([types containsObject:NSFilenamesPboardType]) { + NSArray *files = [m_pasteboard.get() propertyListForType:NSFilenamesPboardType]; + // FIXME: Maybe it makes more sense to allow multiple files and only use the first one? + if ([files count] == 1) { + NSString *file = [files objectAtIndex:0]; + BOOL isDirectory; + if ([[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory] && isDirectory) + return nil; + return frame->editor()->client()->canonicalizeURL([NSURL fileURLWithPath:file]); + } + } + return nil; +} + +String Pasteboard::asURL(Frame* frame) +{ + return [getBestURL(frame) absoluteString]; +} + PassRefPtr Pasteboard::documentFragment(Frame* frame, PassRefPtr context, bool allowPlainText, bool& chosePlainText) { NSArray *types = [m_pasteboard.get() types]; diff --git a/Source/WebCore/platform/mac/ThemeMac.mm b/Source/WebCore/platform/mac/ThemeMac.mm index 75cbd36..e510ea7 100644 --- a/Source/WebCore/platform/mac/ThemeMac.mm +++ b/Source/WebCore/platform/mac/ThemeMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2010, 2011 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -52,6 +52,16 @@ using namespace std; return nil; } +- (NSRect)_focusRingVisibleRect +{ + return [self visibleRect]; +} + +- (NSView *)_focusRingClipAncestor +{ + return self; +} + @end // FIXME: Default buttons really should be more like push buttons and not like buttons. diff --git a/Source/WebCore/platform/mac/WheelEventMac.mm b/Source/WebCore/platform/mac/WheelEventMac.mm index d9663b9..d4fc698 100644 --- a/Source/WebCore/platform/mac/WheelEventMac.mm +++ b/Source/WebCore/platform/mac/WheelEventMac.mm @@ -29,9 +29,31 @@ #import "PlatformMouseEvent.h" #import "Scrollbar.h" #import "WebCoreSystemInterface.h" +#import namespace WebCore { +static PlatformWheelEventPhase phaseForEvent(NSEvent *event) +{ +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + uint32_t phase = PlatformWheelEventPhaseNone; + if ([event momentumPhase] & NSEventPhaseBegan) + phase |= PlatformWheelEventPhaseBegan; + if ([event momentumPhase] & NSEventPhaseStationary) + phase |= PlatformWheelEventPhaseStationary; + if ([event momentumPhase] & NSEventPhaseChanged) + phase |= PlatformWheelEventPhaseChanged; + if ([event momentumPhase] & NSEventPhaseEnded) + phase |= PlatformWheelEventPhaseEnded; + if ([event momentumPhase] & NSEventPhaseCancelled) + phase |= PlatformWheelEventPhaseCancelled; + return static_cast(phase); +#else + UNUSED_PARAM(event); + return PlatformWheelEventPhaseNone; +#endif +} + PlatformWheelEvent::PlatformWheelEvent(NSEvent* event, NSView *windowView) : m_position(pointForEvent(event, windowView)) , m_globalPosition(globalPointForEvent(event)) @@ -41,9 +63,10 @@ PlatformWheelEvent::PlatformWheelEvent(NSEvent* event, NSView *windowView) , m_ctrlKey([event modifierFlags] & NSControlKeyMask) , m_altKey([event modifierFlags] & NSAlternateKeyMask) , m_metaKey([event modifierFlags] & NSCommandKeyMask) + , m_phase(phaseForEvent(event)) { BOOL continuous; - + wkGetWheelEventDeltas(event, &m_deltaX, &m_deltaY, &continuous); if (continuous) { m_wheelTicksX = m_deltaX / static_cast(Scrollbar::pixelsPerLineStep()); diff --git a/Source/WebCore/platform/mac/WidgetMac.mm b/Source/WebCore/platform/mac/WidgetMac.mm index e8bb81d..f3c951a 100644 --- a/Source/WebCore/platform/mac/WidgetMac.mm +++ b/Source/WebCore/platform/mac/WidgetMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2008, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2008, 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,6 +34,7 @@ #import "Chrome.h" #import "Cursor.h" #import "Document.h" +#import "FloatConversion.h" #import "Font.h" #import "Frame.h" #import "GraphicsContext.h" @@ -170,25 +171,48 @@ void Widget::setFrameRect(const IntRect& rect) m_frame = rect; BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSView *v = getOuterView(); - if (!v) + NSView *outerView = getOuterView(); + if (!outerView) return; - NSRect visibleRect = [v visibleRect]; + // Take a reference to this Widget, because sending messages to outerView can invoke arbitrary + // code, which can deref it. + RefPtr protectedThis(this); + + NSRect visibleRect = [outerView visibleRect]; NSRect f = rect; - if (!NSEqualRects(f, [v frame])) { - [v setFrame:f]; - [v setNeedsDisplay:NO]; - } else if (!NSEqualRects(visibleRect, m_data->previousVisibleRect) && [v respondsToSelector:@selector(visibleRectDidChange)]) - [v visibleRectDidChange]; + if (!NSEqualRects(f, [outerView frame])) { + [outerView setFrame:f]; + [outerView setNeedsDisplay:NO]; + } else if (!NSEqualRects(visibleRect, m_data->previousVisibleRect) && [outerView respondsToSelector:@selector(visibleRectDidChange)]) + [outerView visibleRectDidChange]; m_data->previousVisibleRect = visibleRect; END_BLOCK_OBJC_EXCEPTIONS; } -NSView* Widget::getOuterView() const +void Widget::setBoundsSize(const IntSize& size) { - NSView* view = platformWidget(); + NSSize nsSize = size; + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + NSView *outerView = getOuterView(); + if (!outerView) + return; + + // Take a reference to this Widget, because sending messages to outerView can invoke arbitrary + // code, which can deref it. + RefPtr protectedThis(this); + if (!NSEqualSizes(nsSize, [outerView bounds].size)) { + [outerView setBoundsSize:nsSize]; + [outerView setNeedsDisplay:NO]; + } + END_BLOCK_OBJC_EXCEPTIONS; +} + +NSView *Widget::getOuterView() const +{ + NSView *view = platformWidget(); // If this widget's view is a WebCoreFrameScrollView then we // resize its containing view, a WebFrameView. @@ -205,11 +229,35 @@ void Widget::paint(GraphicsContext* p, const IntRect& r) if (p->paintingDisabled()) return; NSView *view = getOuterView(); + + // Take a reference to this Widget, because sending messages to the views can invoke arbitrary + // code, which can deref it. + RefPtr protectedThis(this); + + IntPoint transformOrigin = frameRect().location(); + AffineTransform widgetToViewTranform = makeMapBetweenRects(IntRect(IntPoint(), frameRect().size()), [view bounds]); + NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; if (currentContext == [[view window] graphicsContext] || ![currentContext isDrawingToScreen]) { // This is the common case of drawing into a window or printing. BEGIN_BLOCK_OBJC_EXCEPTIONS; - [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]]]; + + CGContextRef context = (CGContextRef)[currentContext graphicsPort]; + + CGContextSaveGState(context); + CGContextTranslateCTM(context, transformOrigin.x(), transformOrigin.y()); + CGContextScaleCTM(context, narrowPrecisionToFloat(widgetToViewTranform.xScale()), narrowPrecisionToFloat(widgetToViewTranform.yScale())); + CGContextTranslateCTM(context, -transformOrigin.x(), -transformOrigin.y()); + + IntRect dirtyRect = r; + dirtyRect.move(-transformOrigin.x(), -transformOrigin.y()); + if (![view isFlipped]) + dirtyRect.setY([view bounds].size.height - dirtyRect.bottom()); + + [view displayRectIgnoringOpacity:dirtyRect]; + + CGContextRestoreGState(context); + END_BLOCK_OBJC_EXCEPTIONS; } else { // This is the case of drawing into a bitmap context other than a window backing store. It gets hit beneath @@ -234,6 +282,10 @@ void Widget::paint(GraphicsContext* p, const IntRect& r) ASSERT(cgContext == [currentContext graphicsPort]); CGContextSaveGState(cgContext); + CGContextTranslateCTM(cgContext, transformOrigin.x(), transformOrigin.y()); + CGContextScaleCTM(cgContext, narrowPrecisionToFloat(widgetToViewTranform.xScale()), narrowPrecisionToFloat(widgetToViewTranform.yScale())); + CGContextTranslateCTM(cgContext, -transformOrigin.x(), -transformOrigin.y()); + NSRect viewFrame = [view frame]; NSRect viewBounds = [view bounds]; // Set up the translation and (flipped) orientation of the graphics context. In normal drawing, AppKit does it as it descends down @@ -241,13 +293,18 @@ void Widget::paint(GraphicsContext* p, const IntRect& r) CGContextTranslateCTM(cgContext, viewFrame.origin.x - viewBounds.origin.x, viewFrame.origin.y + viewFrame.size.height + viewBounds.origin.y); CGContextScaleCTM(cgContext, 1, -1); + IntRect dirtyRect = r; + dirtyRect.move(-transformOrigin.x(), -transformOrigin.y()); + if (![view isFlipped]) + dirtyRect.setY([view bounds].size.height - dirtyRect.bottom()); + BEGIN_BLOCK_OBJC_EXCEPTIONS; { #ifdef BUILDING_ON_TIGER AutodrainedPool pool; #endif NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]; - [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]] inContext:nsContext]; + [view displayRectIgnoringOpacity:dirtyRect inContext:nsContext]; } END_BLOCK_OBJC_EXCEPTIONS; @@ -261,6 +318,7 @@ void Widget::paint(GraphicsContext* p, const IntRect& r) void Widget::setIsSelected(bool isSelected) { NSView *view = platformWidget(); + BEGIN_BLOCK_OBJC_EXCEPTIONS; if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)]) [view webPlugInSetIsSelected:isSelected]; -- cgit v1.1