diff options
Diffstat (limited to 'WebKit/mac/WebView')
24 files changed, 849 insertions, 309 deletions
diff --git a/WebKit/mac/WebView/WebArchive.mm b/WebKit/mac/WebView/WebArchive.mm index c6cc9b1..89c8335 100644 --- a/WebKit/mac/WebView/WebArchive.mm +++ b/WebKit/mac/WebView/WebArchive.mm @@ -53,7 +53,7 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; NSArray *cachedSubresources; NSArray *cachedSubframeArchives; @private - LegacyWebArchive* coreArchive; + RefPtr<LegacyWebArchive> coreArchive; } - (id)initWithCoreArchive:(PassRefPtr<LegacyWebArchive>)coreArchive; @@ -76,7 +76,7 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; self = [super init]; if (!self) return nil; - coreArchive = LegacyWebArchive::create().releaseRef(); + coreArchive = LegacyWebArchive::create(); return self; } @@ -87,33 +87,26 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; [self release]; return nil; } - coreArchive = _coreArchive.releaseRef(); + coreArchive = _coreArchive; return self; } - (LegacyWebArchive*)coreArchive { - return coreArchive; + return coreArchive.get(); } - (void)setCoreArchive:(PassRefPtr<LegacyWebArchive>)newCoreArchive { ASSERT(coreArchive); ASSERT(newCoreArchive); - if (coreArchive) - coreArchive->deref(); - coreArchive = newCoreArchive.releaseRef(); + coreArchive = newCoreArchive; } - (void)dealloc { if (WebCoreObjCScheduleDeallocateOnMainThread([WebArchivePrivate class], self)) return; - - if (coreArchive) { - coreArchive->deref(); - coreArchive = 0; - } [cachedMainResource release]; [cachedSubresources release]; @@ -122,23 +115,13 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; [super dealloc]; } -- (void)finalize -{ - if (coreArchive) { - coreArchive->deref(); - coreArchive = 0; - } - - [super finalize]; -} - @end @implementation WebArchive - (id)init { - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); self = [super init]; if (!self) @@ -166,7 +149,7 @@ static BOOL isArrayOfClass(id object, Class elementClass) return [[self _webkit_invokeOnMainThread] initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); self = [super init]; if (!self) @@ -219,7 +202,7 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (id)initWithData:(NSData *)data { - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); self = [super init]; if (!self) @@ -296,7 +279,7 @@ static BOOL isArrayOfClass(id object, Class elementClass) return [[self _webkit_invokeOnMainThread] mainResource]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); // Currently from WebKit API perspective, WebArchives are entirely immutable once created // If they ever become mutable, we'll need to rethink this. @@ -316,7 +299,7 @@ static BOOL isArrayOfClass(id object, Class elementClass) return [[self _webkit_invokeOnMainThread] subresources]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); // Currently from WebKit API perspective, WebArchives are entirely immutable once created // If they ever become mutable, we'll need to rethink this. @@ -337,8 +320,9 @@ static BOOL isArrayOfClass(id object, Class elementClass) } } } - - return [[_private->cachedSubresources retain] autorelease]; + // Maintain the WebKit 3 behavior of this API, which is documented and + // relied upon by some clients, of returning nil if there are no subresources. + return [_private->cachedSubresources count] ? [[_private->cachedSubresources retain] autorelease] : nil; } - (NSArray *)subframeArchives @@ -348,7 +332,7 @@ static BOOL isArrayOfClass(id object, Class elementClass) return [[self _webkit_invokeOnMainThread] subframeArchives]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); // Currently from WebKit API perspective, WebArchives are entirely immutable once created // If they ever become mutable, we'll need to rethink this. @@ -373,7 +357,7 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (NSData *)data { - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); #if !LOG_DISABLED CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); @@ -396,7 +380,7 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (id)_initWithCoreLegacyWebArchive:(PassRefPtr<WebCore::LegacyWebArchive>)coreLegacyWebArchive { - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); self = [super init]; if (!self) @@ -413,7 +397,7 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (WebCore::LegacyWebArchive *)_coreLegacyWebArchive { - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); return [_private coreArchive]; } diff --git a/WebKit/mac/WebView/WebDataSource.mm b/WebKit/mac/WebView/WebDataSource.mm index 12afcb3..57347d3 100644 --- a/WebKit/mac/WebView/WebDataSource.mm +++ b/WebKit/mac/WebView/WebDataSource.mm @@ -88,9 +88,12 @@ using namespace WebCore; if (WebCoreObjCScheduleDeallocateOnMainThread([WebDataSourcePrivate class], self)) return; - ASSERT(!loader->isLoading()); - loader->detachDataSource(); - loader->deref(); + ASSERT(loader); + if (loader) { + ASSERT(!loader->isLoading()); + loader->detachDataSource(); + loader->deref(); + } [representation release]; @@ -101,9 +104,12 @@ using namespace WebCore; { ASSERT_MAIN_THREAD(); - ASSERT(!loader->isLoading()); - loader->detachDataSource(); - loader->deref(); + ASSERT(loader); + if (loader) { + ASSERT(!loader->isLoading()); + loader->detachDataSource(); + loader->deref(); + } [super finalize]; } @@ -484,9 +490,14 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl _private->loader->getSubresources(coreSubresources); NSMutableArray *subresources = [[NSMutableArray alloc] initWithCapacity:coreSubresources.size()]; - for (unsigned i = 0; i < coreSubresources.size(); ++i) - [subresources addObject:[[[WebResource alloc] _initWithCoreResource:coreSubresources[i]] autorelease]]; - + for (unsigned i = 0; i < coreSubresources.size(); ++i) { + WebResource *resource = [[WebResource alloc] _initWithCoreResource:coreSubresources[i]]; + if (resource) { + [subresources addObject:resource]; + [resource release]; + } + } + return [subresources autorelease]; } diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm index 0ac300e..2aa5fab 100644 --- a/WebKit/mac/WebView/WebFrame.mm +++ b/WebKit/mac/WebView/WebFrame.mm @@ -611,7 +611,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) // 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); - _private->coreFrame->adjustPageHeight(&proposedBottom, i, proposedBottom, i); + 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)]; @@ -622,7 +622,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) return pages; } -- (BOOL)_getVisibleRect:(NSRect*)rect; +- (BOOL)_getVisibleRect:(NSRect*)rect { ASSERT_ARG(rect, rect); if (RenderPart* ownerRenderer = _private->coreFrame->ownerRenderer()) { @@ -678,7 +678,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) if (startNode && startNode->renderer()) { RenderLayer *layer = startNode->renderer()->enclosingLayer(); if (layer) - layer->scrollRectToVisible(enclosingIntRect(rangeRect), false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded); + layer->scrollRectToVisible(enclosingIntRect(rangeRect), false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded); } } @@ -701,7 +701,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) RenderView* root = static_cast<RenderView *>(_private->coreFrame->document()->renderer()); if (!root) return nil; - return _private->coreFrame->document()->axObjectCache()->get(root)->wrapper(); + return _private->coreFrame->document()->axObjectCache()->getOrCreate(root)->wrapper(); #else return nil; #endif @@ -715,7 +715,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) SelectionController selection; selection.setSelection(_private->coreFrame->selection()->selection()); selection.modify(alteration, direction, granularity); - return [DOMRange _wrapRange:selection.toRange().get()]; + return [DOMRange _wrapRange:selection.toNormalizedRange().get()]; } - (TextGranularity)_selectionGranularity @@ -793,7 +793,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (DOMRange *)_markDOMRange { - return [DOMRange _wrapRange:_private->coreFrame->mark().toRange().get()]; + return [DOMRange _wrapRange:_private->coreFrame->mark().toNormalizedRange().get()]; } // Given proposedRange, returns an extended range that includes adjacent whitespace that should @@ -824,8 +824,8 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) RefPtr<Range> range = _private->coreFrame->document()->createRange(); int exception = 0; - range->setStart(newStart.node(), newStart.offset(), exception); - range->setEnd(newStart.node(), newStart.offset(), exception); + range->setStart(newStart.node(), newStart.m_offset, exception); + range->setEnd(newStart.node(), newStart.m_offset, exception); return [DOMRange _wrapRange:range.get()]; } @@ -909,15 +909,6 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) return [DOMDocumentFragment _wrapDocumentFragment:createFragmentFromNodes(_private->coreFrame->document(), nodesVector).get()]; } -- (void)_replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle -{ - if (_private->coreFrame->selection()->isNone() || !fragment) - return; - - applyCommand(ReplaceSelectionCommand::create(_private->coreFrame->document(), [fragment _documentFragment], selectReplacement, smartReplace, matchStyle)); - _private->coreFrame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded); -} - - (void)_replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle { DOMDocumentFragment *fragment = [DOMDocumentFragment _wrapDocumentFragment:_private->coreFrame->document()->createDocumentFragment().get()]; @@ -925,41 +916,19 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:matchStyle]; } -- (void)_replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace -{ - DOMDocumentFragment *fragment = [self _documentFragmentWithMarkupString:markupString baseURLString:baseURLString]; - [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:NO]; -} - -- (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace -{ - [self _replaceSelectionWithFragment:kit(createFragmentFromText(_private->coreFrame->selection()->toRange().get(), text).get()) - selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:YES]; -} - - (void)_insertParagraphSeparatorInQuotedContent { if (_private->coreFrame->selection()->isNone()) return; TypingCommand::insertParagraphSeparatorInQuotedContent(_private->coreFrame->document()); - _private->coreFrame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded); + _private->coreFrame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); } - (VisiblePosition)_visiblePositionForPoint:(NSPoint)point { - IntPoint outerPoint(point); - HitTestResult result = _private->coreFrame->eventHandler()->hitTestResultAtPoint(outerPoint, true); - Node* node = result.innerNode(); - if (!node) - return VisiblePosition(); - RenderObject* renderer = node->renderer(); - if (!renderer) - return VisiblePosition(); - VisiblePosition visiblePos = renderer->positionForCoordinates(result.localPoint().x(), result.localPoint().y()); - if (visiblePos.isNull()) - visiblePos = VisiblePosition(Position(node, 0)); - return visiblePos; + // FIXME: Someone with access to Apple's sources could remove this needless wrapper call. + return _private->coreFrame->visiblePositionForPoint(IntPoint(point)); } - (DOMRange *)_characterRangeAtPoint:(NSPoint)point @@ -1094,7 +1063,8 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (BOOL)_isFrameSet { - return _private->coreFrame->isFrameSet(); + Document* document = _private->coreFrame->document(); + return document && document->isFrameSet(); } - (BOOL)_firstLayoutDone @@ -1109,14 +1079,14 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (NSRange)_selectedNSRange { - return [self _convertToNSRange:_private->coreFrame->selection()->toRange().get()]; + return [self _convertToNSRange:_private->coreFrame->selection()->toNormalizedRange().get()]; } - (void)_selectNSRange:(NSRange)range { RefPtr<Range> domRange = [self _convertToDOMRange:range]; if (domRange) - _private->coreFrame->selection()->setSelection(Selection(domRange.get(), SEL_DEFAULT_AFFINITY)); + _private->coreFrame->selection()->setSelection(VisibleSelection(domRange.get(), SEL_DEFAULT_AFFINITY)); } - (BOOL)_isDisplayingStandaloneImage @@ -1217,6 +1187,27 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) return controller->numberOfActiveAnimations(); } +- (void)_replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle +{ + if (_private->coreFrame->selection()->isNone() || !fragment) + return; + + applyCommand(ReplaceSelectionCommand::create(_private->coreFrame->document(), [fragment _documentFragment], selectReplacement, smartReplace, matchStyle)); + _private->coreFrame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); +} + +- (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace +{ + DOMDocumentFragment* fragment = kit(createFragmentFromText(_private->coreFrame->selection()->toNormalizedRange().get(), text).get()); + [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:YES]; +} + +- (void)_replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace +{ + DOMDocumentFragment *fragment = [self _documentFragmentWithMarkupString:markupString baseURLString:baseURLString]; + [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:NO]; +} + @end @implementation WebFrame diff --git a/WebKit/mac/WebView/WebFrameInternal.h b/WebKit/mac/WebView/WebFrameInternal.h index fa17ed9..473e691 100644 --- a/WebKit/mac/WebView/WebFrameInternal.h +++ b/WebKit/mac/WebView/WebFrameInternal.h @@ -167,10 +167,7 @@ WebView *getWebView(WebFrame *webFrame); - (DOMDocumentFragment *)_documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString; - (DOMDocumentFragment *)_documentFragmentWithNodesAsParagraphs:(NSArray *)nodes; -- (void)_replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle; - (void)_replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle; -- (void)_replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace; -- (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace; - (void)_insertParagraphSeparatorInQuotedContent; diff --git a/WebKit/mac/WebView/WebFramePrivate.h b/WebKit/mac/WebView/WebFramePrivate.h index 2ea686e..e3e3540 100644 --- a/WebKit/mac/WebView/WebFramePrivate.h +++ b/WebKit/mac/WebView/WebFramePrivate.h @@ -35,6 +35,7 @@ #define ENABLE_NETSCAPE_PLUGIN_API 1 #endif +@class DOMDocumentFragment; @class DOMNode; @class WebIconFetcher; @class WebScriptObject; @@ -95,4 +96,8 @@ typedef enum { // Returns the total number of currently running animations (includes both CSS transitions and CSS animations). - (unsigned) _numberOfActiveAnimations; +- (void)_replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle; +- (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace; +- (void)_replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace; + @end diff --git a/WebKit/mac/WebView/WebFrameView.mm b/WebKit/mac/WebView/WebFrameView.mm index 132fb93..bc51bb5 100644 --- a/WebKit/mac/WebView/WebFrameView.mm +++ b/WebKit/mac/WebView/WebFrameView.mm @@ -49,6 +49,7 @@ #import "WebNSWindowExtras.h" #import "WebPDFView.h" #import "WebPreferenceKeysPrivate.h" +#import "WebResourceInternal.h" #import "WebSystemInterface.h" #import "WebViewFactory.h" #import "WebViewInternal.h" @@ -314,9 +315,18 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl WKDisableCGDeferredUpdates(); if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_MAIN_THREAD_EXCEPTIONS)) - setDefaultThreadViolationBehavior(LogOnFirstThreadViolation); + setDefaultThreadViolationBehavior(LogOnFirstThreadViolation, ThreadViolationRoundOne); + + bool throwExceptionsForRoundTwo = WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_ROUND_TWO_MAIN_THREAD_EXCEPTIONS); +#ifdef MAIL_THREAD_WORKAROUND + // Even if old Mail is linked with new WebKit, don't throw exceptions. + if (needMailThreadWorkaround()) + throwExceptionsForRoundTwo = false; +#endif + if (!throwExceptionsForRoundTwo) + setDefaultThreadViolationBehavior(LogOnFirstThreadViolation, ThreadViolationRoundTwo); } - + _private = [[WebFrameViewPrivate alloc] init]; WebDynamicScrollBarsView *scrollView = [[WebDynamicScrollBarsView alloc] initWithFrame:NSMakeRect(0.0f, 0.0f, frame.size.width, frame.size.height)]; diff --git a/WebKit/mac/WebView/WebHTMLRepresentation.mm b/WebKit/mac/WebView/WebHTMLRepresentation.mm index 604a17a..3f69870 100644 --- a/WebKit/mac/WebView/WebHTMLRepresentation.mm +++ b/WebKit/mac/WebView/WebHTMLRepresentation.mm @@ -137,7 +137,7 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) [super finalize]; } -- (void)_redirectDataToManualLoader:(id<WebPluginManualLoader>)manualLoader forPluginView:(NSView *)pluginView; +- (void)_redirectDataToManualLoader:(id<WebPluginManualLoader>)manualLoader forPluginView:(NSView *)pluginView { _private->manualLoader = manualLoader; _private->pluginView = pluginView; @@ -150,7 +150,7 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) - (BOOL)_isDisplayingWebArchive { - return [[[_private->dataSource response] MIMEType] _webkit_isCaseInsensitiveEqualToString:@"application/x-webarchive"]; + return [[_private->dataSource _responseMIMEType] _webkit_isCaseInsensitiveEqualToString:@"application/x-webarchive"]; } - (void)receivedData:(NSData *)data withDataSource:(WebDataSource *)dataSource diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm index be4d8db..c4ca174 100644 --- a/WebKit/mac/WebView/WebHTMLView.mm +++ b/WebKit/mac/WebView/WebHTMLView.mm @@ -48,7 +48,6 @@ #import "WebHTMLViewInternal.h" #import "WebKitLogging.h" #import "WebKitNSStringExtras.h" -#import "WebKitPluginContainerView.h" #import "WebKitVersionChecks.h" #import "WebLocalizableStrings.h" #import "WebNodeHighlight.h" @@ -114,6 +113,10 @@ #import <limits> #import <runtime/InitializeThreading.h> +#if USE(ACCELERATED_COMPOSITING) +#import <QuartzCore/QuartzCore.h> +#endif + using namespace WebCore; using namespace HTMLNames; using namespace WTF; @@ -129,6 +132,15 @@ using namespace WTF; } @end +@interface WebResponderChainSink : NSResponder { + NSResponder* _lastResponderInChain; + BOOL _receivedUnhandledCommand; +} +- (id)initWithResponderChain:(NSResponder *)chain; +- (void)detach; +- (BOOL)receivedUnhandledCommand; +@end + static IMP oldSetCursorIMP = NULL; #ifdef BUILDING_ON_TIGER @@ -142,7 +154,7 @@ static void resetCursorRects(NSWindow* self, SEL cmd) if ([view isKindOfClass:[WebHTMLView class]]) { WebHTMLView *htmlView = (WebHTMLView*)view; NSPoint localPoint = [htmlView convertPoint:point fromView:nil]; - NSDictionary *dict = [htmlView elementAtPoint:point allowShadowContent:NO]; + 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]]) @@ -164,7 +176,7 @@ static void setCursor(NSWindow* self, SEL cmd, NSPoint point) if ([view isKindOfClass:[WebHTMLView class]]) { WebHTMLView *htmlView = (WebHTMLView*)view; NSPoint localPoint = [htmlView convertPoint:point fromView:nil]; - NSDictionary *dict = [htmlView elementAtPoint:point allowShadowContent:NO]; + 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]]) @@ -174,6 +186,20 @@ static void setCursor(NSWindow* self, SEL cmd, NSPoint point) } #endif +#if USE(ACCELERATED_COMPOSITING) +@interface WebLayerHostingView : NSView +@end + +@implementation WebLayerHostingView +// Empty NSViews intercept rightMouseDown: to do context menu handling, but we need the WebLayerHostingView to +// let right mouse clicks through. +- (void)rightMouseDown:(NSEvent *)theEvent +{ + [[self nextResponder] performSelector:_cmd withObject:theEvent]; +} +@end +#endif // USE(ACCELERATED_COMPOSITING) + extern "C" { // Need to declare these attribute names because AppKit exports them but does not make them available in API or SPI headers. @@ -289,6 +315,9 @@ static CachedResourceClient* promisedDataClient() - (NSString *)_plainTextFromPasteboard:(NSPasteboard *)pasteboard; - (void)_pasteWithPasteboard:(NSPasteboard *)pasteboard allowPlainText:(BOOL)allowPlainText; - (void)_pasteAsPlainTextWithPasteboard:(NSPasteboard *)pasteboard; +- (void)_removeMouseMovedObserverUnconditionally; +- (void)_removeSuperviewObservers; +- (void)_removeWindowObservers; - (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; @@ -372,9 +401,17 @@ struct WebHTMLViewInterpretKeyEventsParameters { BOOL ignoringMouseDraggedEvents; BOOL printing; BOOL avoidingPrintOrphan; + BOOL observingMouseMovedNotifications; + BOOL observingSuperviewNotifications; + BOOL observingWindowNotifications; + BOOL resigningFirstResponder; id savedSubviews; BOOL subviewsSetAside; + +#if USE(ACCELERATED_COMPOSITING) + NSView *layerHostingView; +#endif NSEvent *mouseDownEvent; // Kept after handling the event. BOOL handlingMouseDownEvent; @@ -523,6 +560,10 @@ static NSCellStateValue kit(TriState state) dataSource = nil; highlighters = nil; promisedDragTIFFDataSource = 0; + +#if USE(ACCELERATED_COMPOSITING) + layerHostingView = nil; +#endif } @end @@ -755,6 +796,49 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) [[self _frame] _replaceSelectionWithText:text selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard]]; } +- (void)_removeMouseMovedObserverUnconditionally +{ + if (!_private || !_private->observingMouseMovedNotifications) + return; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:WKMouseMovedNotification() object:nil]; + _private->observingMouseMovedNotifications = false; +} + +- (void)_removeSuperviewObservers +{ + if (!_private || !_private->observingSuperviewNotifications) + return; + + NSView *superview = [self superview]; + if (!superview || ![self window]) + return; + + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter removeObserver:self name:NSViewFrameDidChangeNotification object:superview]; + [notificationCenter removeObserver:self name:NSViewBoundsDidChangeNotification object:superview]; + + _private->observingSuperviewNotifications = false; +} + +- (void)_removeWindowObservers +{ + if (!_private->observingWindowNotifications) + return; + + NSWindow *window = [self window]; + if (!window) + return; + + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil]; + [notificationCenter removeObserver:self name:NSWindowDidResignKeyNotification object:nil]; + [notificationCenter removeObserver:self name:NSWindowWillCloseNotification object:window]; + [notificationCenter removeObserver:self name:WKWindowWillOrderOnScreenNotification() object:window]; + + _private->observingWindowNotifications = false; +} + - (BOOL)_shouldInsertFragment:(DOMDocumentFragment *)fragment replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action { WebView *webView = [self _webView]; @@ -789,7 +873,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) - (DOMRange *)_selectedRange { Frame* coreFrame = core([self _frame]); - return coreFrame ? kit(coreFrame->selection()->toRange().get()) : nil; + return coreFrame ? kit(coreFrame->selection()->toNormalizedRange().get()) : nil; } - (BOOL)_shouldDeleteRange:(DOMRange *)range @@ -1064,7 +1148,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) NSPoint origin = [[self superview] bounds].origin; if (!NSEqualPoints(_private->lastScrollPosition, origin)) { if (Frame* coreFrame = core([self _frame])) - coreFrame->sendScrollEvent(); + coreFrame->eventHandler()->sendScrollEvent(); [_private->compController endRevertingChange:NO moveLeft:NO]; WebView *webView = [self _webView]; @@ -1088,15 +1172,34 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) ASSERT(!_private->subviewsSetAside); ASSERT(_private->savedSubviews == nil); _private->savedSubviews = _subviews; +#if USE(ACCELERATED_COMPOSITING) + // We need to keep the layer-hosting view in the subviews, otherwise the layers flash. + if (_private->layerHostingView) { + NSArray* newSubviews = [[NSArray alloc] initWithObjects:_private->layerHostingView, nil]; + _subviews = newSubviews; + } else + _subviews = nil; +#else _subviews = nil; +#endif _private->subviewsSetAside = YES; } - (void)_restoreSubviews { ASSERT(_private->subviewsSetAside); +#if USE(ACCELERATED_COMPOSITING) + if (_private->layerHostingView) { + [_subviews release]; + _subviews = _private->savedSubviews; + } else { + ASSERT(_subviews == nil); + _subviews = _private->savedSubviews; + } +#else ASSERT(_subviews == nil); _subviews = _private->savedSubviews; +#endif _private->savedSubviews = nil; _private->subviewsSetAside = NO; } @@ -1111,7 +1214,9 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) - (void)willRemoveSubview:(NSView *)subview { - if (_private->enumeratingSubviews) + // Have to null-check _private, since this can be called via -dealloc when + // cleaning up the the layerHostingView. + if (_private && _private->enumeratingSubviews) LOG(View, "A view of class %s was removed during subview enumeration for layout or printing mode change. We will still do layout or the printing mode change even though this view is no longer in the view hierarchy.", object_getClassName([subview class])); } @@ -1833,7 +1938,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) - (void)close { - // Check for a nil _private here incase we were created with initWithCoder. In that case, the WebView is just throwing + // Check for a nil _private here in case we were created with initWithCoder. In that case, the WebView is just throwing // out the archived WebHTMLView and recreating a new one if needed. So close doesn't need to do anything in that case. if (!_private || _private->closed) return; @@ -1843,14 +1948,21 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) [self _cancelUpdateMouseoverTimer]; [self _cancelUpdateFocusedAndActiveStateTimer]; [self _clearLastHitViewIfSelf]; - // FIXME: This is slow; should remove individual observers instead. - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self _removeMouseMovedObserverUnconditionally]; + [self _removeWindowObservers]; + [self _removeSuperviewObservers]; [_private->pluginController destroyAllPlugins]; [_private->pluginController setDataSource:nil]; // remove tooltips before clearing _private so removeTrackingRect: will work correctly [self removeAllToolTips]; + +#if USE(ACCELERATED_COMPOSITING) + if (_private->layerHostingView) + [[self _webView] _stoppedAcceleratedCompositingForFrame:[self _frame]]; +#endif + [_private clear]; - + Page* page = core([self _webView]); if (page) page->dragController()->setDraggingImageURL(KURL()); @@ -1976,10 +2088,10 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) if (!document) return nil; DOMHTMLAnchorElement *anchor = (DOMHTMLAnchorElement *)[document createElement:@"a"]; - NSString *URLString = [URL _web_originalDataAsString]; + NSString *URLString = [URL _web_originalDataAsString]; // Original data is ASCII-only, so there is no need to precompose. if ([URLString length] == 0) return nil; - NSString *URLTitleString = [pasteboard stringForType:WebURLNamePboardType]; + NSString *URLTitleString = [[pasteboard stringForType:WebURLNamePboardType] precomposedStringWithCanonicalMapping]; DOMText *text = [document createTextNode:URLTitleString]; [anchor setHref:URLString]; [anchor appendChild:text]; @@ -1988,7 +2100,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) return fragment; } if (pboardType == NSStringPboardType) - return kit(createFragmentFromText(core(context), [pasteboard stringForType:NSStringPboardType]).get()); + return kit(createFragmentFromText(core(context), [[pasteboard stringForType:NSStringPboardType] precomposedStringWithCanonicalMapping]).get()); return nil; } @@ -2022,6 +2134,15 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) } #endif +- (BOOL)_isUsingAcceleratedCompositing +{ +#if USE(ACCELERATED_COMPOSITING) + return _private->layerHostingView != nil; +#else + return NO; +#endif +} + @end @implementation NSView (WebHTMLViewFileInternal) @@ -2052,6 +2173,23 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) @end +@interface NSString (WebHTMLViewFileInternal) +- (BOOL)matchesExtensionEquivalent:(NSString *)extension; +@end + +@implementation NSString (WebHTMLViewFileInternal) + +- (BOOL)matchesExtensionEquivalent:(NSString *)extension +{ + if ([self hasSuffix:extension]) + return YES; + else if ([extension isEqualToString:@"jpeg"] && [self hasSuffix:@"jpg"]) + return YES; + return NO; +} + +@end + #ifdef BUILDING_ON_TIGER // The following is a workaround for @@ -2167,8 +2305,8 @@ static String commandNameForSelector(SEL selector) // Remove the trailing colon. const char* selectorName = sel_getName(selector); size_t selectorNameLength = strlen(selectorName); - ASSERT(selectorNameLength >= 2); - ASSERT(selectorName[selectorNameLength - 1] == ':'); + if (selectorNameLength < 2 || selectorName[selectorNameLength - 1] != ':') + return String(); return String(selectorName, selectorNameLength - 1); } @@ -2267,6 +2405,10 @@ WEBCORE_COMMAND(moveToEndOfParagraph) WEBCORE_COMMAND(moveToEndOfParagraphAndModifySelection) WEBCORE_COMMAND(moveToEndOfSentence) WEBCORE_COMMAND(moveToEndOfSentenceAndModifySelection) +WEBCORE_COMMAND(moveToLeftEndOfLine) +WEBCORE_COMMAND(moveToLeftEndOfLineAndModifySelection) +WEBCORE_COMMAND(moveToRightEndOfLine) +WEBCORE_COMMAND(moveToRightEndOfLineAndModifySelection) WEBCORE_COMMAND(moveUp) WEBCORE_COMMAND(moveUpAndModifySelection) WEBCORE_COMMAND(moveWordBackward) @@ -2335,11 +2477,10 @@ WEBCORE_COMMAND(yankAndSelect) - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType { - if (sendType != nil && [[self pasteboardTypesForSelection] containsObject:sendType] && [self _hasSelection]) { - return self; - } else if (returnType != nil && [[[self class] _insertablePasteboardTypes] containsObject:returnType] && [self _isEditable]) { + BOOL isSendTypeOK = !sendType || ([[self pasteboardTypesForSelection] containsObject:sendType] && [self _hasSelection]); + BOOL isReturnTypeOK = !returnType || ([[[self class] _insertablePasteboardTypes] containsObject:returnType] && [self _isEditable]); + if (isSendTypeOK && isReturnTypeOK) return self; - } return [[self nextResponder] validRequestorForSendType:sendType returnType:returnType]; } @@ -2353,7 +2494,7 @@ WEBCORE_COMMAND(yankAndSelect) COMMAND_PROLOGUE if (Frame* coreFrame = core([self _frame])) - coreFrame->revealSelection(RenderLayer::gAlignCenterAlways); + coreFrame->revealSelection(ScrollAlignment::alignCenterAlways); } - (NSCellStateValue)selectionHasStyle:(CSSStyleDeclaration*)style @@ -2426,7 +2567,14 @@ WEBCORE_COMMAND(yankAndSelect) } return [self _canEdit]; } - + + if (action == @selector(makeBaseWritingDirectionNatural:)) { + NSMenuItem *menuItem = (NSMenuItem *)item; + if ([menuItem isKindOfClass:[NSMenuItem class]]) + [menuItem setState:NSOffState]; + return NO; + } + if (action == @selector(toggleBaseWritingDirection:)) { NSMenuItem *menuItem = (NSMenuItem *)item; if ([menuItem isKindOfClass:[NSMenuItem class]]) { @@ -2566,7 +2714,7 @@ WEBCORE_COMMAND(yankAndSelect) - (void)addMouseMovedObserver { - if (!_private->dataSource || ![self _isTopHTMLView]) + if (!_private->dataSource || ![self _isTopHTMLView] || _private->observingMouseMovedNotifications) return; // Unless the Dashboard asks us to do this for all windows, keep an observer going only for the key window. @@ -2580,12 +2728,7 @@ WEBCORE_COMMAND(yankAndSelect) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mouseMovedNotification:) name:WKMouseMovedNotification() object:nil]; [self _frameOrBoundsChanged]; -} - -- (void)removeMouseMovedObserverUnconditionally -{ - [[NSNotificationCenter defaultCenter] removeObserver:self - name:WKMouseMovedNotification() object:nil]; + _private->observingMouseMovedNotifications = true; } - (void)removeMouseMovedObserver @@ -2597,7 +2740,7 @@ WEBCORE_COMMAND(yankAndSelect) #endif [[self _webView] _mouseDidMoveOverElement:nil modifierFlags:0]; - [self removeMouseMovedObserverUnconditionally]; + [self _removeMouseMovedObserverUnconditionally]; } - (void)addSuperviewObservers @@ -2610,66 +2753,48 @@ WEBCORE_COMMAND(yankAndSelect) // to extend the background the full height of the space and because some elements have // sizes that are based on the total size of the view. - NSView *superview = [self superview]; - if (superview && [self window]) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_frameOrBoundsChanged) - name:NSViewFrameDidChangeNotification object:superview]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_frameOrBoundsChanged) - name:NSViewBoundsDidChangeNotification object:superview]; - - // In addition to registering for frame/bounds change notifications, call -_frameOrBoundsChanged. - // It will check the current size/scroll against the previous layout's size/scroll. We need to - // do this here to catch the case where the WebView is laid out at one size, removed from its - // window, resized, and inserted into another window. Our frame/bounds changed notifications - // will not be sent in that situation, since we only watch for changes while in the view hierarchy. - [self _frameOrBoundsChanged]; - } -} + if (_private->observingSuperviewNotifications) + return; -- (void)removeSuperviewObservers -{ NSView *superview = [self superview]; - if (superview && [self window]) { - [[NSNotificationCenter defaultCenter] removeObserver:self - name:NSViewFrameDidChangeNotification object:superview]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:NSViewBoundsDidChangeNotification object:superview]; - } + if (!superview || ![self window]) + return; + + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter addObserver:self selector:@selector(_frameOrBoundsChanged) name:NSViewFrameDidChangeNotification object:superview]; + [notificationCenter addObserver:self selector:@selector(_frameOrBoundsChanged) name:NSViewBoundsDidChangeNotification object:superview]; + + // In addition to registering for frame/bounds change notifications, call -_frameOrBoundsChanged. + // It will check the current size/scroll against the previous layout's size/scroll. We need to + // do this here to catch the case where the WebView is laid out at one size, removed from its + // window, resized, and inserted into another window. Our frame/bounds changed notifications + // will not be sent in that situation, since we only watch for changes while in the view hierarchy. + [self _frameOrBoundsChanged]; + + _private->observingSuperviewNotifications = true; } - (void)addWindowObservers { + if (_private->observingWindowNotifications) + return; + NSWindow *window = [self window]; - if (window) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeKey:) - name:NSWindowDidBecomeKeyNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResignKey:) - name:NSWindowDidResignKeyNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillClose:) - name:NSWindowWillCloseNotification object:window]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillOrderOnScreen:) - name:WKWindowWillOrderOnScreenNotification() object:window]; - } -} - -- (void)removeWindowObservers -{ - NSWindow *window = [self window]; - if (window) { - [[NSNotificationCenter defaultCenter] removeObserver:self - name:NSWindowDidBecomeKeyNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:NSWindowDidResignKeyNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:NSWindowWillCloseNotification object:window]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:WKWindowWillOrderOnScreenNotification() object:window]; - } + if (!window) + return; + + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:nil]; + [notificationCenter addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:nil]; + [notificationCenter addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:window]; + [notificationCenter addObserver:self selector:@selector(windowWillOrderOnScreen:) name:WKWindowWillOrderOnScreenNotification() object:window]; + + _private->observingWindowNotifications = true; } - (void)viewWillMoveToSuperview:(NSView *)newSuperview { - [self removeSuperviewObservers]; + [self _removeSuperviewObservers]; } - (void)viewDidMoveToSuperview @@ -2694,9 +2819,9 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v return; // FIXME: Some of these calls may not work because this view may be already removed from it's superview. - [self removeMouseMovedObserverUnconditionally]; - [self removeWindowObservers]; - [self removeSuperviewObservers]; + [self _removeMouseMovedObserverUnconditionally]; + [self _removeWindowObservers]; + [self _removeSuperviewObservers]; [self _cancelUpdateMouseoverTimer]; [self _cancelUpdateFocusedAndActiveStateTimer]; @@ -2811,12 +2936,14 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v return; } - if (minPageWidth > 0.0) - coreFrame->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize); - else { - coreFrame->forceLayout(!adjustViewSize); - if (adjustViewSize) - coreFrame->view()->adjustViewSize(); + if (FrameView* coreView = coreFrame->view()) { + if (minPageWidth > 0.0) + coreView->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize); + else { + coreView->forceLayout(!adjustViewSize); + if (adjustViewSize) + coreView->adjustViewSize(); + } } _private->needsLayout = NO; @@ -2993,6 +3120,16 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v if (subviewsWereSetAside) [self _setAsideSubviews]; + +#if USE(ACCELERATED_COMPOSITING) + if ([[self _webView] _needsOneShotDrawingSynchronization]) { + // Disable screen updates so that drawing into the NSView and + // CALayer updates appear on the screen at the same time. + [[self window] disableScreenUpdatesUntilFlush]; + [CATransaction flush]; + [[self _webView] _setNeedsOneShotDrawingSynchronization:NO]; + } +#endif } // Turn off the additional clip while computing our visibleRect. @@ -3250,8 +3387,8 @@ done: draggingImageURL = [response URL]; wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease]; NSString* filename = [response suggestedFilename]; - String trueExtension = tiffResource->image()->filenameExtension(); - if (![filename hasSuffix:trueExtension]) + NSString* trueExtension(tiffResource->image()->filenameExtension()); + if (![filename matchesExtensionEquivalent:trueExtension]) filename = [[filename stringByAppendingString:@"."] stringByAppendingString:trueExtension]; [wrapper setPreferredFilename:filename]; } @@ -3356,6 +3493,7 @@ noPromisedData: { BOOL resign = [super resignFirstResponder]; if (resign) { + _private->resigningFirstResponder = YES; [_private->compController endRevertingChange:NO moveLeft:NO]; if (![self maintainsInactiveSelection]) { [self deselectAll]; @@ -3363,6 +3501,7 @@ noPromisedData: [self clearFocus]; } [self _updateFocusedAndActiveState]; + _private->resigningFirstResponder = NO; } return resign; } @@ -3443,7 +3582,8 @@ noPromisedData: [self _setPrinting:YES minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:NO]; float newBottomFloat = *newBottom; - core([self _frame])->adjustPageHeight(&newBottomFloat, oldTop, oldBottom, bottomLimit); + if (FrameView* view = core([self _frame])->view()) + view->adjustPageHeight(&newBottomFloat, oldTop, oldBottom, bottomLimit); #ifdef __LP64__ // If the new bottom is equal to the old bottom (when both are treated as floats), we just copy @@ -3548,7 +3688,7 @@ noPromisedData: Frame* frame = core([self _frame]); if (!frame) return NO; - if (!frame->isFrameSet()) { + if (!frame->document() || !frame->document()->isFrameSet()) { float paperWidth = [self _availablePaperWidthForPrintOperation:[NSPrintOperation currentOperation]]; minLayoutWidth = paperWidth * PrintingMinimumShrinkFactor; maxLayoutWidth = paperWidth * PrintingMaximumShrinkFactor; @@ -3742,7 +3882,7 @@ noPromisedData: COMMAND_PROLOGUE if (Frame* coreFrame = core([self _frame])) - coreFrame->revealSelection(RenderLayer::gAlignCenterAlways); + coreFrame->revealSelection(ScrollAlignment::alignCenterAlways); } - (NSData *)_selectionStartFontAttributesAsRTF @@ -4456,6 +4596,11 @@ static BOOL writingDirectionKeyBindingsEnabled() } #endif +- (void)makeBaseWritingDirectionNatural:(id)sender +{ + LOG_ERROR("Sent from %@.", sender); +} + #if 0 // CSS does not have a way to specify an outline font, which may make this difficult to implement. @@ -4764,6 +4909,27 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) if ([[[self selectedString] _webkit_stringByTrimmingWhitespace] length] == 0) return; + NSAttributedString *attrString = [self selectedAttributedString]; + + Frame* coreFrame = core([self _frame]); + if (!coreFrame) + return; + + NSRect rect = coreFrame->selectionBounds(); + +#ifndef BUILDING_ON_TIGER + NSDictionary *attributes = [attrString fontAttributesInRange:NSMakeRange(0,1)]; + NSFont *font = [attributes objectForKey:NSFontAttributeName]; + if (font) + rect.origin.y += [font ascender]; +#endif + +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + [self showDefinitionForAttributedString:attrString atPoint:rect.origin]; + return; +#endif + + // We soft link to get the function that displays the dictionary (either pop-up window or app) to avoid the performance // penalty of linking to another framework. This function changed signature as well as framework between Tiger and Leopard, // so the two cases are handled separately. @@ -4795,12 +4961,6 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) return; } - NSAttributedString *attrString = [self selectedAttributedString]; - - Frame* coreFrame = core([self _frame]); - if (!coreFrame) - return; - #ifdef BUILDING_ON_TIGER // FIXME: must check for right-to-left here NSWritingDirection writingDirection = NSWritingDirectionLeftToRight; @@ -4808,7 +4968,7 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) // FIXME: the dictionary API expects the rect for the first line of selection. Passing // the rect for the entire selection, as we do here, positions the pop-up window near // the bottom of the selection rather than at the selected word. - NSRect rect = [self convertRect:coreFrame->selectionBounds() toView:nil]; + rect = [self convertRect:rect toView:nil]; rect.origin = [[self window] convertBaseToScreen:rect.origin]; NSData *data = [attrString RTFFromRange:NSMakeRange(0, [attrString length]) documentAttributes:nil]; dictionaryServiceWindowShow(data, rect, (writingDirection == NSWritingDirectionRightToLeft) ? 1 : 0); @@ -4816,19 +4976,12 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) // The HIDictionaryWindowShow function requires the origin, in CG screen coordinates, of the first character of text in the selection. // FIXME 4945808: We approximate this in a way that works well when a single word is selected, and less well in some other cases // (but no worse than we did in Tiger) - NSRect rect = coreFrame->selectionBounds(); - - NSDictionary *attributes = [attrString fontAttributesInRange:NSMakeRange(0,1)]; - NSFont *font = [attributes objectForKey:NSFontAttributeName]; - if (font) - rect.origin.y += [font ascender]; - NSPoint windowPoint = [self convertPoint:rect.origin toView:nil]; NSPoint screenPoint = [[self window] convertBaseToScreen:windowPoint]; dictionaryServiceWindowShow(nil, attrString, CFRangeMake(0, [attrString length]), nil, coreGraphicsScreenPointForAppKitScreenPoint(screenPoint), false, nil); -#endif +#endif } - (void)_hoverFeedbackSuspendedChanged @@ -4877,19 +5030,21 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) if ([self coreCommandBySelector:NSSelectorFromString(commands[i].commandName)].isTextInsertion()) haveTextInsertionCommands = true; } - if (!haveTextInsertionCommands || platformEvent->type() == PlatformKeyboardEvent::Char) - for (size_t i = 0; i < size; ++i) + if (!haveTextInsertionCommands || platformEvent->type() == PlatformKeyboardEvent::Char) { + for (size_t i = 0; i < size; ++i) { if (commands[i].commandName == "insertText:") [self insertText:commands[i].text]; else [self doCommandBySelector:NSSelectorFromString(commands[i].commandName)]; + } + } } _private->interpretKeyEventsParameters = 0; } return (!_private->receivedNOOP && parameters.eventWasHandled) || parameters.consumedByIM; } -- (WebCore::CachedImage*)promisedDragTIFFDataSource +- (WebCore::CachedImage*)promisedDragTIFFDataSource { return _private->promisedDragTIFFDataSource; } @@ -4944,6 +5099,45 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) [[self _pluginController] destroyAllPlugins]; } +- (BOOL)_isResigningFirstResponder +{ + return _private->resigningFirstResponder; +} + +#if USE(ACCELERATED_COMPOSITING) +- (void)attachRootLayer:(CALayer*)layer +{ + if (!_private->layerHostingView) { + WebLayerHostingView* hostingView = [[WebLayerHostingView alloc] initWithFrame:[self bounds]]; + [hostingView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [self addSubview:hostingView]; + [hostingView release]; + // hostingView is owned by being a subview of self + _private->layerHostingView = hostingView; + [[self _webView] _startedAcceleratedCompositingForFrame:[self _frame]]; + } + + // Make a container layer, which will get sized/positioned by AppKit and CA + CALayer* viewLayer = [CALayer layer]; + [_private->layerHostingView setLayer:viewLayer]; + [_private->layerHostingView setWantsLayer:YES]; + + // Parent our root layer in the container layer + [viewLayer addSublayer:layer]; +} + +- (void)detachRootLayer +{ + if (_private->layerHostingView) { + [_private->layerHostingView setLayer:nil]; + [_private->layerHostingView setWantsLayer:NO]; + [_private->layerHostingView removeFromSuperview]; + _private->layerHostingView = nil; + [[self _webView] _stoppedAcceleratedCompositingForFrame:[self _frame]]; + } +} +#endif + @end @implementation WebHTMLView (WebNSTextInputSupport) @@ -5058,7 +5252,11 @@ static BOOL isInPasswordField(Frame* coreFrame) - (NSRange)markedRange { WebFrame *webFrame = [self _frame]; - NSRange result = [webFrame _convertToNSRange:core(webFrame)->editor()->compositionRange().get()]; + Frame* coreFrame = core(webFrame); + if (!coreFrame) + return NSMakeRange(0, 0); + NSRange result = [webFrame _convertToNSRange:coreFrame->editor()->compositionRange().get()]; + LOG(TextInput, "markedRange -> (%u, %u)", result.location, result.length); return result; } @@ -5214,26 +5412,29 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde // Make sure that only direct calls to doCommandBySelector: see the parameters by setting to 0. _private->interpretKeyEventsParameters = 0; - bool eventWasHandled = true; + bool eventWasHandled; WebView *webView = [self _webView]; - Frame* coreFrame = core([self _frame]); - if (![[webView _editingDelegateForwarder] webView:webView doCommandBySelector:selector] && coreFrame) { + if ([[webView _editingDelegateForwarder] webView:webView doCommandBySelector:selector]) + eventWasHandled = true; + else { Editor::Command command = [self coreCommandBySelector:selector]; if (command.isSupported()) eventWasHandled = command.execute(event); - else if ([self _canEdit]) { - // If the command is unsupported and the WebHTMLView is editable, then pass the - // selector to super and say that the event was handled. If the WebHTMLView is - // not editable, then do not say that the event was handled. This is important - // because of selectors like scrollPageDown:, which come as input method events - // when editing is enabled but keyboard events when it is not. These events are - // handled by the next responder in the responder chain. + else { + // If WebKit does not support this command, we need to pass the selector to super. _private->selectorForDoCommandBySelector = selector; + + // The sink does two things: 1) Tells us if the responder went unhandled, and + // 2) prevents any NSBeep; we don't ever want to beep here. + WebResponderChainSink *sink = [[WebResponderChainSink alloc] initWithResponderChain:self]; [super doCommandBySelector:selector]; + eventWasHandled = ![sink receivedUnhandledCommand]; + [sink detach]; + [sink release]; + _private->selectorForDoCommandBySelector = 0; - } else - eventWasHandled = false; + } } if (parameters) @@ -5474,7 +5675,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde // Get preceeding word stem WebFrame *frame = [_view _frame]; - DOMRange *selection = kit(core(frame)->selection()->toRange().get()); + DOMRange *selection = kit(core(frame)->selection()->toNormalizedRange().get()); DOMRange *wholeWord = [frame _rangeByAlteringCurrentSelection:SelectionController::EXTEND direction:SelectionController::BACKWARD granularity:WordGranularity]; DOMRange *prefix = [wholeWord cloneRange]; @@ -5744,7 +5945,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde if (!attributedString) { Frame* coreFrame = core([self _frame]); if (coreFrame) { - RefPtr<Range> range = coreFrame->selection()->selection().toRange(); + RefPtr<Range> range = coreFrame->selection()->selection().toNormalizedRange(); attributedString = [NSAttributedString _web_attributedStringFromRange:range.get()]; } } @@ -5773,7 +5974,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde return [self elementAtPoint:point allowShadowContent:NO]; } -- (NSDictionary *)elementAtPoint:(NSPoint)point allowShadowContent:(BOOL)allow; +- (NSDictionary *)elementAtPoint:(NSPoint)point allowShadowContent:(BOOL)allow { Frame* coreFrame = core([self _frame]); if (!coreFrame) @@ -5847,3 +6048,38 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde } @end + +@implementation WebResponderChainSink + +- (id)initWithResponderChain:(NSResponder *)chain +{ + self = [super init]; + _lastResponderInChain = chain; + while (NSResponder *next = [_lastResponderInChain nextResponder]) + _lastResponderInChain = next; + [_lastResponderInChain setNextResponder:self]; + return self; +} + +- (void)detach +{ + [_lastResponderInChain setNextResponder:nil]; + _lastResponderInChain = nil; +} + +- (BOOL)receivedUnhandledCommand +{ + return _receivedUnhandledCommand; +} + +- (void)noResponderFor:(SEL)selector +{ + _receivedUnhandledCommand = YES; +} + +- (void)doCommandBySelector:(SEL)selector +{ + _receivedUnhandledCommand = YES; +} + +@end diff --git a/WebKit/mac/WebView/WebHTMLViewInternal.h b/WebKit/mac/WebView/WebHTMLViewInternal.h index 0fb0cdc..a32df02 100644 --- a/WebKit/mac/WebView/WebHTMLViewInternal.h +++ b/WebKit/mac/WebView/WebHTMLViewInternal.h @@ -58,4 +58,11 @@ namespace WebCore { - (void)setPromisedDragTIFFDataSource:(WebCore::CachedImage*)source; - (void)_web_layoutIfNeededRecursive; - (void)_destroyAllWebPlugins; +- (BOOL)_isResigningFirstResponder; + +#if USE(ACCELERATED_COMPOSITING) +- (void)attachRootLayer:(CALayer*)layer; +- (void)detachRootLayer; +#endif + @end diff --git a/WebKit/mac/WebView/WebHTMLViewPrivate.h b/WebKit/mac/WebView/WebHTMLViewPrivate.h index 40de97f..0d73884 100644 --- a/WebKit/mac/WebView/WebHTMLViewPrivate.h +++ b/WebKit/mac/WebView/WebHTMLViewPrivate.h @@ -119,6 +119,7 @@ // SPI for DumpRenderTree - (void)_updateFocusedAndActiveState; +- (BOOL)_isUsingAcceleratedCompositing; // SPI for printing (should be converted to API someday). When the WebHTMLView isn't being printed // directly, this method must be called before paginating, or the computed height might be incorrect. diff --git a/WebKit/mac/WebView/WebPDFRepresentation.m b/WebKit/mac/WebView/WebPDFRepresentation.m index 1a2ddab..7eae380 100644 --- a/WebKit/mac/WebView/WebPDFRepresentation.m +++ b/WebKit/mac/WebView/WebPDFRepresentation.m @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import <WebKit/WebDataSource.h> +#import <WebKit/WebDataSourcePrivate.h> #import <WebKit/WebFrame.h> #import <WebKit/WebFrameView.h> #import <WebKit/WebNSObjectExtras.h> @@ -111,7 +111,7 @@ NSData *data = [dataSource data]; NSArray *postScriptMIMETypes = [[self class] postScriptMIMETypes]; - NSString *mimeType = [[dataSource response] MIMEType]; + NSString *mimeType = [dataSource _responseMIMEType]; if ([postScriptMIMETypes containsObject:mimeType]) { data = [self convertPostScriptDataSourceToPDF:data]; if ([data length] == 0) diff --git a/WebKit/mac/WebView/WebPDFView.mm b/WebKit/mac/WebView/WebPDFView.mm index 2cb5374..0c872b9 100644 --- a/WebKit/mac/WebView/WebPDFView.mm +++ b/WebKit/mac/WebView/WebPDFView.mm @@ -341,7 +341,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec NSString *appName = nil; NSImage *appIcon = nil; - _applicationInfoForMIMEType([[dataSource response] MIMEType], &appName, &appIcon); + _applicationInfoForMIMEType([dataSource _responseMIMEType], &appName, &appIcon); if (!appName) appName = UI_STRING("Finder", "Default application name for Open With context menu"); diff --git a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h index 98daec0..e22113c 100644 --- a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h +++ b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h @@ -41,6 +41,7 @@ #define WebKitDefaultFontSizePreferenceKey @"WebKitDefaultFontSize" #define WebKitDefaultFixedFontSizePreferenceKey @"WebKitDefaultFixedFontSize" #define WebKitDefaultTextEncodingNamePreferenceKey @"WebKitDefaultTextEncodingName" +#define WebKitUsesEncodingDetectorPreferenceKey @"WebKitUsesEncodingDetector" #define WebKitUserStyleSheetEnabledPreferenceKey @"WebKitUserStyleSheetEnabledPreferenceKey" #define WebKitUserStyleSheetLocationPreferenceKey @"WebKitUserStyleSheetLocationPreferenceKey" #define WebKitShouldPrintBackgroundsPreferenceKey @"WebKitShouldPrintBackgroundsPreferenceKey" @@ -48,6 +49,8 @@ #define WebKitShrinksStandaloneImagesToFitPreferenceKey @"WebKitShrinksStandaloneImagesToFit" #define WebKitJavaEnabledPreferenceKey @"WebKitJavaEnabled" #define WebKitJavaScriptEnabledPreferenceKey @"WebKitJavaScriptEnabled" +#define WebKitWebSecurityEnabledPreferenceKey @"WebKitWebSecurityEnabled" +#define WebKitAllowUniversalAccessFromFileURLsPreferenceKey @"WebKitAllowUniversalAccessFromFileURLs" #define WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey @"WebKitJavaScriptCanOpenWindowsAutomatically" #define WebKitPluginsEnabledPreferenceKey @"WebKitPluginsEnabled" #define WebKitDatabasesEnabledPreferenceKey @"WebKitDatabasesEnabledPreferenceKey" diff --git a/WebKit/mac/WebView/WebPreferences.mm b/WebKit/mac/WebView/WebPreferences.mm index e595861..6db14bd 100644 --- a/WebKit/mac/WebView/WebPreferences.mm +++ b/WebKit/mac/WebView/WebPreferences.mm @@ -306,6 +306,7 @@ static WebCacheModel cacheModelForMainBundle(void) @"16", WebKitDefaultFontSizePreferenceKey, @"13", WebKitDefaultFixedFontSizePreferenceKey, @"ISO-8859-1", WebKitDefaultTextEncodingNamePreferenceKey, + [NSNumber numberWithBool:NO], WebKitUsesEncodingDetectorPreferenceKey, [NSNumber numberWithBool:NO], WebKitUserStyleSheetEnabledPreferenceKey, @"", WebKitUserStyleSheetLocationPreferenceKey, [NSNumber numberWithBool:NO], WebKitShouldPrintBackgroundsPreferenceKey, @@ -313,6 +314,8 @@ static WebCacheModel cacheModelForMainBundle(void) [NSNumber numberWithBool:NO], WebKitShrinksStandaloneImagesToFitPreferenceKey, [NSNumber numberWithBool:YES], WebKitJavaEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitJavaScriptEnabledPreferenceKey, + [NSNumber numberWithBool:YES], WebKitWebSecurityEnabledPreferenceKey, + [NSNumber numberWithBool:YES], WebKitAllowUniversalAccessFromFileURLsPreferenceKey, [NSNumber numberWithBool:YES], WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey, [NSNumber numberWithBool:YES], WebKitPluginsEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitDatabasesEnabledPreferenceKey, @@ -663,7 +666,7 @@ static WebCacheModel cacheModelForMainBundle(void) return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey]; } -- (void)setAllowsAnimatedImages:(BOOL)flag; +- (void)setAllowsAnimatedImages:(BOOL)flag { [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey]; } @@ -688,7 +691,7 @@ static WebCacheModel cacheModelForMainBundle(void) return [self _boolValueForKey: WebKitDisplayImagesKey]; } -- (void)setAutosaves:(BOOL)flag; +- (void)setAutosaves:(BOOL)flag { _private->autosaves = flag; } @@ -862,6 +865,36 @@ static WebCacheModel cacheModelForMainBundle(void) _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel; } +- (BOOL)usesEncodingDetector +{ + return [self _boolValueForKey: WebKitUsesEncodingDetectorPreferenceKey]; +} + +- (void)setUsesEncodingDetector:(BOOL)flag +{ + [self _setBoolValue: flag forKey: WebKitUsesEncodingDetectorPreferenceKey]; +} + +- (BOOL)isWebSecurityEnabled +{ + return [self _boolValueForKey: WebKitWebSecurityEnabledPreferenceKey]; +} + +- (void)setWebSecurityEnabled:(BOOL)flag +{ + [self _setBoolValue: flag forKey: WebKitWebSecurityEnabledPreferenceKey]; +} + +- (BOOL)allowUniversalAccessFromFileURLs +{ + return [self _boolValueForKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey]; +} + +- (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag +{ + [self _setBoolValue: flag forKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey]; +} + - (NSTimeInterval)_backForwardCacheExpirationInterval { // FIXME: There's probably no good reason to read from the standard user defaults instead of self. @@ -878,7 +911,7 @@ static WebCacheModel cacheModelForMainBundle(void) [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey]; } -- (PDFDisplayMode)PDFDisplayMode; +- (PDFDisplayMode)PDFDisplayMode { PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey]; if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) { diff --git a/WebKit/mac/WebView/WebPreferencesPrivate.h b/WebKit/mac/WebView/WebPreferencesPrivate.h index 99ff49c..ae94cce 100644 --- a/WebKit/mac/WebView/WebPreferencesPrivate.h +++ b/WebKit/mac/WebView/WebPreferencesPrivate.h @@ -59,6 +59,9 @@ extern NSString *WebPreferencesRemovedNotification; - (BOOL)applicationChromeModeEnabled; - (void)setApplicationChromeModeEnabled:(BOOL)flag; +- (BOOL)usesEncodingDetector; +- (void)setUsesEncodingDetector:(BOOL)flag; + - (BOOL)respectStandardStyleKeyEquivalents; - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag; @@ -89,6 +92,12 @@ extern NSString *WebPreferencesRemovedNotification; - (BOOL)localStorageEnabled; - (void)setLocalStorageEnabled:(BOOL)localStorageEnabled; +- (BOOL)isWebSecurityEnabled; +- (void)setWebSecurityEnabled:(BOOL)flag; + +- (BOOL)allowUniversalAccessFromFileURLs; +- (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag; + - (BOOL)zoomsTextOnly; - (void)setZoomsTextOnly:(BOOL)zoomsTextOnly; diff --git a/WebKit/mac/WebView/WebResource.mm b/WebKit/mac/WebView/WebResource.mm index a5caa41..e62ed1e 100644 --- a/WebKit/mac/WebView/WebResource.mm +++ b/WebKit/mac/WebView/WebResource.mm @@ -121,7 +121,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" - (id)initWithCoder:(NSCoder *)decoder { - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); self = [super init]; if (!self) @@ -205,7 +205,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" return [[self _webkit_invokeOnMainThread] data]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); if (!_private->coreResource) return nil; @@ -221,7 +221,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" return [[self _webkit_invokeOnMainThread] URL]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); if (!_private->coreResource) return nil; @@ -236,7 +236,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" return [[self _webkit_invokeOnMainThread] MIMEType]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); if (!_private->coreResource) return nil; @@ -251,7 +251,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" return [[self _webkit_invokeOnMainThread] textEncodingName]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); if (!_private->coreResource) return nil; @@ -266,7 +266,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" return [[self _webkit_invokeOnMainThread] frameName]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); if (!_private->coreResource) return nil; @@ -323,7 +323,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" } #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); if (!_private->coreResource) return; @@ -343,7 +343,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" return [[self _webkit_invokeOnMainThread] _initWithData:data URL:URL MIMEType:MIMEType textEncodingName:textEncodingName frameName:frameName response:response copyData:copyData]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); self = [super init]; if (!self) @@ -379,7 +379,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" return [[self _webkit_invokeOnMainThread] _suggestedFilename]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); if (!_private->coreResource) return nil; @@ -404,7 +404,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" return [[self _webkit_invokeOnMainThread] _response]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); NSURLResponse *response = nil; if (_private->coreResource) @@ -419,7 +419,7 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" return [[self _webkit_invokeOnMainThread] _stringValue]; #endif - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); WebCore::TextEncoding encoding; if (_private->coreResource) @@ -435,12 +435,14 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" #ifdef MAIL_THREAD_WORKAROUND +static const double newMailBundleVersion = 1050.0; + @implementation WebResource (WebMailThreadWorkaround) + (BOOL)_needMailThreadWorkaroundIfCalledOffMainThread { - static BOOL isOldMail = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_MAIL_THREAD_WORKAROUND) - && [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.mail"]; + static BOOL isOldMail = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.mail"] + && [[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey] doubleValue] < newMailBundleVersion; return isOldMail; } diff --git a/WebKit/mac/WebView/WebScriptDebugDelegate.h b/WebKit/mac/WebView/WebScriptDebugDelegate.h index 7334127..823cc35 100644 --- a/WebKit/mac/WebView/WebScriptDebugDelegate.h +++ b/WebKit/mac/WebView/WebScriptDebugDelegate.h @@ -37,7 +37,7 @@ #if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) typedef int WebSourceId; #else -typedef int WebSourceId; // FIXME <rdar://problem/6263293>: Turn this int into an intptr_t once <rdar://problem/6263297> is fixed. +typedef intptr_t WebSourceId; #endif @class WebView; diff --git a/WebKit/mac/WebView/WebScriptDebugger.mm b/WebKit/mac/WebView/WebScriptDebugger.mm index d97cbcf..384f826 100644 --- a/WebKit/mac/WebView/WebScriptDebugger.mm +++ b/WebKit/mac/WebView/WebScriptDebugger.mm @@ -94,7 +94,9 @@ void WebScriptDebugger::initGlobalCallFrame(const DebuggerCallFrame& debuggerCal m_globalCallFrame = m_topCallFrame; WebView *webView = [webFrame webView]; - [[webView _scriptDebugDelegateForwarder] webView:webView didEnterCallFrame:m_topCallFrame.get() sourceId:static_cast<WebSourceId>(0) line:-1 forWebFrame:webFrame]; + WebScriptDebugDelegateImplementationCache* implementations = WebViewGetScriptDebugDelegateImplementations(webView); + if (implementations->didEnterCallFrameFunc) + CallScriptDebugDelegate(implementations->didEnterCallFrameFunc, webView, @selector(webView:didEnterCallFrame:sourceId:line:forWebFrame:), m_topCallFrame.get(), static_cast<NSInteger>(0), -1, webFrame); m_callingDelegate = false; } @@ -112,14 +114,23 @@ void WebScriptDebugger::sourceParsed(ExecState* exec, const SourceCode& source, WebFrame *webFrame = toWebFrame(exec->dynamicGlobalObject()); WebView *webView = [webFrame webView]; + WebScriptDebugDelegateImplementationCache* implementations = WebViewGetScriptDebugDelegateImplementations(webView); + if (errorLine == -1) { - [[webView _scriptDebugDelegateForwarder] webView:webView didParseSource:nsSource baseLineNumber:source.firstLine() fromURL:nsURL sourceId:static_cast<WebSourceId>(source.provider()->asID()) forWebFrame:webFrame]; - [[webView _scriptDebugDelegateForwarder] webView:webView didParseSource:nsSource fromURL:[nsURL absoluteString] sourceId:static_cast<WebSourceId>(source.provider()->asID()) forWebFrame:webFrame]; // deprecated delegate method + if (implementations->didParseSourceFunc) { + if (implementations->didParseSourceExpectsBaseLineNumber) + CallScriptDebugDelegate(implementations->didParseSourceFunc, webView, @selector(webView:didParseSource:baseLineNumber:fromURL:sourceId:forWebFrame:), nsSource, source.firstLine(), nsURL, source.provider()->asID(), webFrame); + else + CallScriptDebugDelegate(implementations->didParseSourceFunc, webView, @selector(webView:didParseSource:fromURL:sourceId:forWebFrame:), nsSource, [nsURL absoluteString], source.provider()->asID(), webFrame); + } } else { NSString* nsErrorMessage = toNSString(errorMsg); NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:nsErrorMessage, WebScriptErrorDescriptionKey, [NSNumber numberWithUnsignedInt:errorLine], WebScriptErrorLineNumberKey, nil]; NSError *error = [[NSError alloc] initWithDomain:WebScriptErrorDomain code:WebScriptGeneralErrorCode userInfo:info]; - [[webView _scriptDebugDelegateForwarder] webView:webView failedToParseSource:nsSource baseLineNumber:source.firstLine() fromURL:nsURL withError:error forWebFrame:webFrame]; + + if (implementations->failedToParseSourceFunc) + CallScriptDebugDelegate(implementations->failedToParseSourceFunc, webView, @selector(webView:failedToParseSource:baseLineNumber:fromURL:withError:forWebFrame:), nsSource, source.firstLine(), nsURL, error, webFrame); + [error release]; [info release]; } @@ -139,7 +150,9 @@ void WebScriptDebugger::callEvent(const DebuggerCallFrame& debuggerCallFrame, in m_topCallFrame.adoptNS([[WebScriptCallFrame alloc] _initWithGlobalObject:core(webFrame)->script()->windowScriptObject() debugger:this caller:m_topCallFrame.get() debuggerCallFrame:debuggerCallFrame]); WebView *webView = [webFrame webView]; - [[webView _scriptDebugDelegateForwarder] webView:webView didEnterCallFrame:m_topCallFrame.get() sourceId:static_cast<WebSourceId>(sourceID) line:lineNumber forWebFrame:webFrame]; + WebScriptDebugDelegateImplementationCache* implementations = WebViewGetScriptDebugDelegateImplementations(webView); + if (implementations->didEnterCallFrameFunc) + CallScriptDebugDelegate(implementations->didEnterCallFrameFunc, webView, @selector(webView:didEnterCallFrame:sourceId:line:forWebFrame:), m_topCallFrame.get(), sourceID, lineNumber, webFrame); m_callingDelegate = false; } @@ -155,7 +168,10 @@ void WebScriptDebugger::atStatement(const DebuggerCallFrame& debuggerCallFrame, WebView *webView = [webFrame webView]; [m_topCallFrame.get() _setDebuggerCallFrame:debuggerCallFrame]; - [[webView _scriptDebugDelegateForwarder] webView:webView willExecuteStatement:m_topCallFrame.get() sourceId:static_cast<WebSourceId>(sourceID) line:lineNumber forWebFrame:webFrame]; + + WebScriptDebugDelegateImplementationCache* implementations = WebViewGetScriptDebugDelegateImplementations(webView); + if (implementations->willExecuteStatementFunc) + CallScriptDebugDelegate(implementations->willExecuteStatementFunc, webView, @selector(webView:willExecuteStatement:sourceId:line:forWebFrame:), m_topCallFrame.get(), sourceID, lineNumber, webFrame); m_callingDelegate = false; } @@ -171,7 +187,10 @@ void WebScriptDebugger::returnEvent(const DebuggerCallFrame& debuggerCallFrame, WebView *webView = [webFrame webView]; [m_topCallFrame.get() _setDebuggerCallFrame:debuggerCallFrame]; - [[webView _scriptDebugDelegateForwarder] webView:webView willLeaveCallFrame:m_topCallFrame.get() sourceId:static_cast<WebSourceId>(sourceID) line:lineNumber forWebFrame:webFrame]; + + WebScriptDebugDelegateImplementationCache* implementations = WebViewGetScriptDebugDelegateImplementations(webView); + if (implementations->willLeaveCallFrameFunc) + CallScriptDebugDelegate(implementations->willLeaveCallFrameFunc, webView, @selector(webView:willLeaveCallFrame:sourceId:line:forWebFrame:), m_topCallFrame.get(), sourceID, lineNumber, webFrame); [m_topCallFrame.get() _clearDebuggerCallFrame]; m_topCallFrame = [m_topCallFrame.get() caller]; @@ -190,7 +209,9 @@ void WebScriptDebugger::exception(const DebuggerCallFrame& debuggerCallFrame, in WebView *webView = [webFrame webView]; [m_topCallFrame.get() _setDebuggerCallFrame:debuggerCallFrame]; - [[webView _scriptDebugDelegateForwarder] webView:webView exceptionWasRaised:m_topCallFrame.get() sourceId:static_cast<WebSourceId>(sourceID) line:lineNumber forWebFrame:webFrame]; + WebScriptDebugDelegateImplementationCache* implementations = WebViewGetScriptDebugDelegateImplementations(webView); + if (implementations->exceptionWasRaisedFunc) + CallScriptDebugDelegate(implementations->exceptionWasRaisedFunc, webView, @selector(webView:exceptionWasRaised:sourceId:line:forWebFrame:), m_topCallFrame.get(), sourceID, lineNumber, webFrame); m_callingDelegate = false; } diff --git a/WebKit/mac/WebView/WebTextIterator.h b/WebKit/mac/WebView/WebTextIterator.h index ab5ca4e..d0c92f9 100644 --- a/WebKit/mac/WebView/WebTextIterator.h +++ b/WebKit/mac/WebView/WebTextIterator.h @@ -44,7 +44,9 @@ /*! @method advance - @abstract Makes the WebTextIterator iterate to the next visible text element. + @abstract Moves the WebTextIterator to the next bit of text or boundary between runs of text. + The iterator can break up runs of text however it finds convenient, so clients need to handle + text runs that are broken up into arbitrary pieces. */ - (void)advance; @@ -55,22 +57,30 @@ - (BOOL)atEnd; /*! - @method currentRange - @result A range, indicating the position within the document of the current text. + @method currentTextLength + @result Length of the current text. Length of zero means that the iterator is at a boundary, + such as an image, that separates runs of text. */ -- (DOMRange *)currentRange; +- (WebNSUInteger)currentTextLength; /*! @method currentTextPointer - @result A pointer to the current text. The pointer becomes invalid after any modification is made to the document; it must be used right away. + @result A pointer to the current text. Like the WebTextIterator itself, the pointer becomes + invalid after any modification is made to the document; it must be used before the document + is changed or the iterator is advanced. */ - (const unichar *)currentTextPointer; /*! - @method currentTextLength - @result lengthPtr Length of the current text. + @method currentRange + @abstract A function that identifies the specific document range that text corresponds to. + This can be quite costly to compute for non-text items, so when possible this should only + be called once the caller has determined that the text is text it wants to process. If you + call currentRange every time you advance the iterator, performance will be extremely slow + due to the cost of computing a DOM range. + @result A DOM range indicating the position within the document of the current text. */ -- (WebNSUInteger)currentTextLength; +- (DOMRange *)currentRange; @end diff --git a/WebKit/mac/WebView/WebUIDelegate.h b/WebKit/mac/WebView/WebUIDelegate.h index 8440bcb..c3dd9ff 100644 --- a/WebKit/mac/WebView/WebUIDelegate.h +++ b/WebKit/mac/WebView/WebUIDelegate.h @@ -133,7 +133,7 @@ typedef enum { @abstract Call this method to return an array of filenames from the file open panel. @param fileNames */ -- (void)chooseFilenames:(NSArray *)fileNames WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_AFTER_WEBKIT_VERSION_3_1); +- (void)chooseFilenames:(NSArray *)fileNames WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_IN_WEBKIT_VERSION_4_0); /*! @method cancel @@ -419,7 +419,7 @@ typedef enum { @discussion This method is passed a callback object instead of giving a return value so that it can be handled with a sheet. */ -- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener allowMultipleFiles:(BOOL)allowMultipleFiles WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_AFTER_WEBKIT_VERSION_3_1); +- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener allowMultipleFiles:(BOOL)allowMultipleFiles WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_IN_WEBKIT_VERSION_4_0); /*! @method webView:mouseDidMoveOverElement:modifierFlags: diff --git a/WebKit/mac/WebView/WebUIDelegatePrivate.h b/WebKit/mac/WebView/WebUIDelegatePrivate.h index bb4d780..8e67963 100644 --- a/WebKit/mac/WebView/WebUIDelegatePrivate.h +++ b/WebKit/mac/WebView/WebUIDelegatePrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -74,6 +74,7 @@ enum { WebMenuItemTagTextDirectionRightToLeft, WebMenuItemTagBaseApplication = 10000 }; +@class WebGeolocation; @class WebSecurityOrigin; @interface NSObject (WebUIDelegatePrivate) @@ -109,5 +110,7 @@ enum { - (BOOL)webView:(WebView *)sender shouldReplaceUploadFile:(NSString *)path usingGeneratedFilename:(NSString **)filename; - (NSString *)webView:(WebView *)sender generateReplacementFile:(NSString *)path; - + +- (BOOL)webView:(WebView *)sender frame:(WebFrame *)frame requestGeolocationPermission:(WebGeolocation *)geolocation securityOrigin:(WebSecurityOrigin *)origin; + @end diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm index d3bbf4e..de3628a 100644 --- a/WebKit/mac/WebView/WebView.mm +++ b/WebKit/mac/WebView/WebView.mm @@ -39,7 +39,6 @@ #import "WebDatabaseManagerInternal.h" #import "WebDefaultEditingDelegate.h" #import "WebDefaultPolicyDelegate.h" -#import "WebDefaultScriptDebugDelegate.h" #import "WebDefaultUIDelegate.h" #import "WebDocument.h" #import "WebDocumentInternal.h" @@ -84,6 +83,7 @@ #import "WebPolicyDelegate.h" #import "WebPreferenceKeysPrivate.h" #import "WebPreferencesPrivate.h" +#import "WebScriptDebugDelegate.h" #import "WebTextIterator.h" #import "WebUIDelegate.h" #import "WebUIDelegatePrivate.h" @@ -92,6 +92,7 @@ #import <WebCore/ApplicationCacheStorage.h> #import <WebCore/Cache.h> #import <WebCore/ColorMac.h> +#import <WebCore/Cursor.h> #import <WebCore/Document.h> #import <WebCore/DocumentLoader.h> #import <WebCore/DragController.h> @@ -128,15 +129,14 @@ #import <WebKit/DOMExtensions.h> #import <WebKit/DOMPrivate.h> #import <WebKitSystemInterface.h> +#import <mach-o/dyld.h> +#import <objc/objc-auto.h> +#import <objc/objc-runtime.h> #import <runtime/ArrayPrototype.h> #import <runtime/DateInstance.h> #import <runtime/InitializeThreading.h> #import <runtime/JSLock.h> #import <runtime/JSValue.h> -#import <mach-o/dyld.h> -#import <objc/objc-auto.h> -#import <objc/objc-runtime.h> -#import <runtime/InitializeThreading.h> #import <wtf/Assertions.h> #import <wtf/HashTraits.h> #import <wtf/RefCountedLeakCounter.h> @@ -232,6 +232,10 @@ macro(moveToEndOfParagraph) \ macro(moveToEndOfParagraphAndModifySelection) \ macro(moveToEndOfSentence) \ macro(moveToEndOfSentenceAndModifySelection) \ +macro(moveToLeftEndOfLine) \ +macro(moveToLeftEndOfLineAndModifySelection) \ +macro(moveToRightEndOfLine) \ +macro(moveToRightEndOfLineAndModifySelection) \ macro(moveUp) \ macro(moveUpAndModifySelection) \ macro(moveWordBackward) \ @@ -287,6 +291,11 @@ macro(yankAndSelect) \ #define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode") #define UniversalAccessDomain CFSTR("com.apple.universalaccess") +#if USE(ACCELERATED_COMPOSITING) +#define UsingAcceleratedCompositingProperty @"_isUsingAcceleratedCompositing" +#endif + + static BOOL s_didSetCacheModel; static WebCacheModel s_cacheModel = WebCacheModelDocumentViewer; @@ -340,7 +349,6 @@ static const char webViewIsOpen[] = "At least one WebView is still open."; id editingDelegate; id editingDelegateForwarder; id scriptDebugDelegate; - id scriptDebugDelegateForwarder; WebInspector *inspector; WebNodeHighlight *currentNodeHighlight; @@ -362,6 +370,7 @@ static const char webViewIsOpen[] = "At least one WebView is still open."; WebResourceDelegateImplementationCache resourceLoadDelegateImplementations; WebFrameLoadDelegateImplementationCache frameLoadDelegateImplementations; + WebScriptDebugDelegateImplementationCache scriptDebugDelegateImplementations; void *observationInfo; @@ -406,6 +415,14 @@ static const char webViewIsOpen[] = "At least one WebView is still open."; // When this flag is set, we will not make any subviews underneath this WebView. This means no WebFrameViews and no WebHTMLViews. BOOL useDocumentViews; + +#if USE(ACCELERATED_COMPOSITING) + // When this flag is set, next time a WebHTMLView draws, it needs to temporarily disable screen updates + // so that the NSView drawing is visually synchronized with CALayer updates. + BOOL needsOneShotDrawingSynchronization; + // Number of WebHTMLViews using accelerated compositing. Used to implement _isUsingAcceleratedCompositing. + int acceleratedFramesCount; +#endif } @end @@ -535,7 +552,6 @@ static BOOL grammarCheckingEnabled; [UIDelegateForwarder release]; [frameLoadDelegateForwarder release]; [editingDelegateForwarder release]; - [scriptDebugDelegateForwarder release]; [mediaStyle release]; @@ -661,6 +677,22 @@ static void WebKitInitializeApplicationCachePathIfNecessary() initialized = YES; } +static bool runningLeopardMail() +{ +#ifdef BUILDING_ON_LEOPARD + return [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.mail"]; +#endif + return NO; +} + +static bool runningTigerMail() +{ +#ifdef BUILDING_ON_TIGER + return [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.mail"]; +#endif + return NO; +} + - (void)_registerDraggedTypes { NSArray *editableTypes = [WebHTMLView _insertablePasteboardTypes]; @@ -678,7 +710,7 @@ static void WebKitInitializeApplicationCachePathIfNecessary() - (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews { - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); #ifndef NDEBUG WTF::RefCountedLeakCounter::suppressMessages(webViewIsOpen); @@ -722,11 +754,15 @@ static void WebKitInitializeApplicationCachePathIfNecessary() [WebFrame _createMainFrameWithPage:_private->page frameName:frameName frameView:frameView]; #ifndef BUILDING_ON_TIGER + NSRunLoop *runLoop = [NSRunLoop mainRunLoop]; +#else + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; +#endif + if (WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOADING_DURING_COMMON_RUNLOOP_MODES)) - [self scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; + [self scheduleInRunLoop:runLoop forMode:(NSString *)kCFRunLoopCommonModes]; else - [self scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; -#endif + [self scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode]; [self _addToAllWebViewsSet]; [self setGroupName:groupName]; @@ -905,7 +941,7 @@ static void WebKitInitializeApplicationCachePathIfNecessary() return uniqueExtensions; } -+ (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType; ++ (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType { MIMEType = [MIMEType lowercaseString]; Class viewClass = [[WebFrameView _viewTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType]; @@ -938,7 +974,7 @@ static void WebKitInitializeApplicationCachePathIfNecessary() return NO; } -- (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType; +- (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType { if ([[self class] _viewClass:vClass andRepresentationClass:rClass forMIMEType:MIMEType]) return YES; @@ -1089,7 +1125,7 @@ static void WebKitInitializeApplicationCachePathIfNecessary() // Need this to make leak messages accurate. if (applicationIsTerminating) { gcController().garbageCollectNow(); - [WebCache empty]; + [WebCache setDisabled:YES]; } #endif } @@ -1296,6 +1332,7 @@ static void WebKitInitializeApplicationCachePathIfNecessary() settings->setDefaultFixedFontSize([preferences defaultFixedFontSize]); settings->setDefaultFontSize([preferences defaultFontSize]); settings->setDefaultTextEncodingName([preferences defaultTextEncodingName]); + settings->setUsesEncodingDetector([preferences usesEncodingDetector]); settings->setFantasyFontFamily([preferences fantasyFontFamily]); settings->setFixedFontFamily([preferences fixedFontFamily]); settings->setForceFTPDirectoryListings([preferences _forceFTPDirectoryListings]); @@ -1303,6 +1340,8 @@ static void WebKitInitializeApplicationCachePathIfNecessary() settings->setLocalStorageDatabasePath([preferences _localStorageDatabasePath]); settings->setJavaEnabled([preferences isJavaEnabled]); settings->setJavaScriptEnabled([preferences isJavaScriptEnabled]); + settings->setWebSecurityEnabled([preferences isWebSecurityEnabled]); + settings->setAllowUniversalAccessFromFileURLs([preferences allowUniversalAccessFromFileURLs]); settings->setJavaScriptCanOpenWindowsAutomatically([preferences javaScriptCanOpenWindowsAutomatically]); settings->setMinimumFontSize([preferences minimumFontSize]); settings->setMinimumLogicalFontSize([preferences minimumLogicalFontSize]); @@ -1332,15 +1371,13 @@ static void WebKitInitializeApplicationCachePathIfNecessary() settings->setUserStyleSheetLocation([NSURL URLWithString:@""]); settings->setNeedsAdobeFrameReloadingQuirk([self _needsAdobeFrameReloadingQuirk]); settings->setNeedsKeyboardEventDisambiguationQuirks([self _needsKeyboardEventDisambiguationQuirks]); + settings->setNeedsLeopardMailQuirks(runningLeopardMail()); + settings->setNeedsTigerMailQuirks(runningTigerMail()); settings->setNeedsSiteSpecificQuirks(_private->useSiteSpecificSpoofing); settings->setWebArchiveDebugModeEnabled([preferences webArchiveDebugModeEnabled]); - settings->disableRangeMutationForOldAppleMail(WKAppVersionCheckLessThan(@"com.apple.mail", -1, 4.0)); settings->setOfflineWebApplicationCacheEnabled([preferences offlineWebApplicationCacheEnabled]); settings->setZoomsTextOnly([preferences zoomsTextOnly]); settings->setEnforceCSSMIMETypeInStrictMode(!WKAppVersionCheckLessThan(@"com.apple.iWeb", -1, 2.1)); -#ifdef BUILDING_ON_LEOPARD - settings->setNeedsIChatMemoryCacheCallsQuirk([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.iChat"]); -#endif } static inline IMP getMethod(id o, SEL s) @@ -1418,6 +1455,37 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati return &webView->_private->frameLoadDelegateImplementations; } +- (void)_cacheScriptDebugDelegateImplementations +{ + WebScriptDebugDelegateImplementationCache *cache = &_private->scriptDebugDelegateImplementations; + id delegate = _private->scriptDebugDelegate; + + if (!delegate) { + bzero(cache, sizeof(WebScriptDebugDelegateImplementationCache)); + return; + } + + cache->didParseSourceFunc = getMethod(delegate, @selector(webView:didParseSource:baseLineNumber:fromURL:sourceId:forWebFrame:)); + if (cache->didParseSourceFunc) + cache->didParseSourceExpectsBaseLineNumber = YES; + else + cache->didParseSourceFunc = getMethod(delegate, @selector(webView:didParseSource:fromURL:sourceId:forWebFrame:)); + + cache->failedToParseSourceFunc = getMethod(delegate, @selector(webView:failedToParseSource:baseLineNumber:fromURL:withError:forWebFrame:)); + cache->didEnterCallFrameFunc = getMethod(delegate, @selector(webView:didEnterCallFrame:sourceId:line:forWebFrame:)); + cache->willExecuteStatementFunc = getMethod(delegate, @selector(webView:willExecuteStatement:sourceId:line:forWebFrame:)); + cache->willLeaveCallFrameFunc = getMethod(delegate, @selector(webView:willLeaveCallFrame:sourceId:line:forWebFrame:)); + cache->exceptionWasRaisedFunc = getMethod(delegate, @selector(webView:exceptionWasRaised:sourceId:line:forWebFrame:)); +} + +WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *webView) +{ + static WebScriptDebugDelegateImplementationCache empty; + if (!webView) + return ∅ + return &webView->_private->scriptDebugDelegateImplementations; +} + - (id)_policyDelegateForwarder { if (!_private->policyDelegateForwarder) @@ -1444,19 +1512,12 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati return _private->editingDelegateForwarder; } -- (id)_scriptDebugDelegateForwarder -{ - if (!_private->scriptDebugDelegateForwarder) - _private->scriptDebugDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:_private->scriptDebugDelegate defaultTarget:[WebDefaultScriptDebugDelegate sharedScriptDebugDelegate] catchExceptions:_private->catchesDelegateExceptions]; - return _private->scriptDebugDelegateForwarder; -} - - (void)_closeWindow { [[self _UIDelegateForwarder] webViewClose:self]; } -+ (void)_unregisterViewClassAndRepresentationClassForMIMEType:(NSString *)MIMEType; ++ (void)_unregisterViewClassAndRepresentationClassForMIMEType:(NSString *)MIMEType { [[WebFrameView _viewTypesAllowImageTypeOmission:NO] removeObjectForKey:MIMEType]; [[WebDataSource _repTypesAllowImageTypeOmission:NO] removeObjectForKey:MIMEType]; @@ -1467,7 +1528,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati MIMETypeRegistry::getSupportedNonImageMIMETypes().remove(MIMEType); } -+ (void)_registerViewClass:(Class)viewClass representationClass:(Class)representationClass forURLScheme:(NSString *)URLScheme; ++ (void)_registerViewClass:(Class)viewClass representationClass:(Class)representationClass forURLScheme:(NSString *)URLScheme { NSString *MIMEType = [self _generatedMIMETypeForURLScheme:URLScheme]; [self registerViewClass:viewClass representationClass:representationClass forMIMEType:MIMEType]; @@ -1559,7 +1620,11 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati static NSSet *manualNotifyKeys = nil; if (!manualNotifyKeys) manualNotifyKeys = [[NSSet alloc] initWithObjects:_WebMainFrameURLKey, _WebIsLoadingKey, _WebEstimatedProgressKey, - _WebCanGoBackKey, _WebCanGoForwardKey, _WebMainFrameTitleKey, _WebMainFrameIconKey, _WebMainFrameDocumentKey, nil]; + _WebCanGoBackKey, _WebCanGoForwardKey, _WebMainFrameTitleKey, _WebMainFrameIconKey, _WebMainFrameDocumentKey, +#if USE(ACCELERATED_COMPOSITING) + UsingAcceleratedCompositingProperty, // used by DRT +#endif + nil]; if ([manualNotifyKeys containsObject:key]) return NO; return YES; @@ -1994,9 +2059,9 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati if (!coreFrame) return nil; - Selection selectionInsideRect(coreFrame->visiblePositionForPoint(rectStart), coreFrame->visiblePositionForPoint(rectEnd)); + VisibleSelection selectionInsideRect(coreFrame->visiblePositionForPoint(rectStart), coreFrame->visiblePositionForPoint(rectEnd)); - return [[[WebTextIterator alloc] initWithRange:[DOMRange _wrapRange:selectionInsideRect.toRange().get()]] autorelease]; + return [[[WebTextIterator alloc] initWithRange:[DOMRange _wrapRange:selectionInsideRect.toNormalizedRange().get()]] autorelease]; } - (void)handleAuthenticationForResource:(id)identifier challenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource @@ -2071,6 +2136,59 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati return _private->page->areMemoryCacheClientCallsEnabled(); } +- (void)_setJavaScriptURLsAreAllowed:(BOOL)areAllowed +{ + _private->page->setJavaScriptURLsAreAllowed(areAllowed); +} + ++ (NSCursor *)_pointingHandCursor +{ + return handCursor().impl(); +} + +#if USE(ACCELERATED_COMPOSITING) +- (BOOL)_needsOneShotDrawingSynchronization +{ + return _private->needsOneShotDrawingSynchronization; +} + +- (void)_setNeedsOneShotDrawingSynchronization:(BOOL)needsSynchronization +{ + _private->needsOneShotDrawingSynchronization = needsSynchronization; +} + +- (void)_startedAcceleratedCompositingForFrame:(WebFrame*)webFrame +{ + BOOL entering = _private->acceleratedFramesCount == 0; + if (entering) + [self willChangeValueForKey:UsingAcceleratedCompositingProperty]; + ++_private->acceleratedFramesCount; + if (entering) + [self didChangeValueForKey:UsingAcceleratedCompositingProperty]; +} + +- (void)_stoppedAcceleratedCompositingForFrame:(WebFrame*)webFrame +{ + BOOL leaving = _private->acceleratedFramesCount == 1; + ASSERT(_private->acceleratedFramesCount > 0); + + if (leaving) + [self willChangeValueForKey:UsingAcceleratedCompositingProperty]; + --_private->acceleratedFramesCount; + if (leaving) + [self didChangeValueForKey:UsingAcceleratedCompositingProperty]; +} +#endif + +- (BOOL)_isUsingAcceleratedCompositing +{ +#if USE(ACCELERATED_COMPOSITING) + return _private->acceleratedFramesCount > 0; +#else + return NO; +#endif +} + @end @implementation _WebSafeForwarder @@ -2270,9 +2388,10 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati static bool needsWebViewInitThreadWorkaround() { - static BOOL isOldInstaller = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_WEBVIEW_INIT_THREAD_WORKAROUND) - && [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.installer"]; - return isOldInstaller && !pthread_main_np(); + static BOOL isOldClient = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_WEBVIEW_INIT_THREAD_WORKAROUND) + && ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.installer"] || + [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Automator"]); + return isOldClient && !pthread_main_np(); } - (id)initWithFrame:(NSRect)f @@ -2285,7 +2404,7 @@ static bool needsWebViewInitThreadWorkaround() if (needsWebViewInitThreadWorkaround()) return [[self _webkit_invokeOnMainThread] initWithFrame:f frameName:frameName groupName:groupName]; - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); return [self _initWithFrame:f frameName:frameName groupName:groupName usesDocumentViews:YES]; } @@ -2294,7 +2413,7 @@ static bool needsWebViewInitThreadWorkaround() if (needsWebViewInitThreadWorkaround()) return [[self _webkit_invokeOnMainThread] initWithCoder:decoder]; - WebCoreThreadViolationCheck(); + WebCoreThreadViolationCheckRoundTwo(); WebView *result = nil; @try { @@ -2500,7 +2619,8 @@ static bool needsWebViewInitThreadWorkaround() [self removeWindowObservers]; [self removeSizeObservers]; - } + } else + _private->page->willMoveOffscreen(); } - (void)viewDidMoveToWindow @@ -2515,6 +2635,7 @@ static bool needsWebViewInitThreadWorkaround() if ([self window]) { [self addWindowObservers]; [self addSizeObservers]; + _private->page->didMoveOnscreen(); } } @@ -2538,10 +2659,14 @@ static bool needsWebViewInitThreadWorkaround() BOOL windowIsKey = [window isKeyWindow]; BOOL windowOrSheetIsKey = windowIsKey || [[window attachedSheet] isKeyWindow]; - NSResponder *firstResponder = [window firstResponder]; + WebFrameView *mainFrameView = [[self mainFrame] frameView]; + id <WebDocumentView> documentView = [mainFrameView documentView]; + BOOL documentViewIsResigningFirstResponder = [documentView isKindOfClass:[WebHTMLView class]] && [(WebHTMLView *)documentView _isResigningFirstResponder]; + + NSResponder *firstResponder = [window firstResponder]; if ([firstResponder isKindOfClass:[NSView class]] - && [(NSView*)firstResponder isDescendantOf:[[self mainFrame] frameView]]) - page->focusController()->setActive(windowIsKey); + && [(NSView *)firstResponder isDescendantOf:mainFrameView]) + page->focusController()->setActive(windowIsKey && !documentViewIsResigningFirstResponder); Frame* focusedFrame = page->focusController()->focusedOrMainFrame(); frame->selection()->setFocused(frame == focusedFrame && windowOrSheetIsKey); @@ -3001,6 +3126,11 @@ static bool needsWebViewInitThreadWorkaround() - (NSWindow *)hostWindow { + // -[WebView hostWindow] can sometimes be called from the WebView's [super dealloc] method + // so we check here to make sure it's not null. + if (!_private) + return nil; + return _private->hostWindow; } @@ -3522,18 +3652,14 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) - (void)scheduleInRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode { -#ifndef BUILDING_ON_TIGER if (runLoop && mode) core(self)->addSchedulePair(SchedulePair::create(runLoop, (CFStringRef)mode)); -#endif } - (void)unscheduleFromRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode { -#ifndef BUILDING_ON_TIGER if (runLoop && mode) core(self)->removeSchedulePair(SchedulePair::create(runLoop, (CFStringRef)mode)); -#endif } - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection @@ -3660,8 +3786,8 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) - (void)setScriptDebugDelegate:(id)delegate { _private->scriptDebugDelegate = delegate; - [_private->scriptDebugDelegateForwarder release]; - _private->scriptDebugDelegateForwarder = nil; + [self _cacheScriptDebugDelegateImplementations]; + if (delegate) [self _attachScriptDebuggerToAllFrames]; else @@ -4058,7 +4184,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValuePtr jsV return kit(page->mainFrame()->editor()->rangeForPoint(IntPoint([self convertPoint:point toView:nil])).get()); } -- (BOOL)_shouldChangeSelectedDOMRange:(DOMRange *)currentRange toDOMRange:(DOMRange *)proposedRange affinity:(NSSelectionAffinity)selectionAffinity stillSelecting:(BOOL)flag; +- (BOOL)_shouldChangeSelectedDOMRange:(DOMRange *)currentRange toDOMRange:(DOMRange *)proposedRange affinity:(NSSelectionAffinity)selectionAffinity stillSelecting:(BOOL)flag { // FIXME: This quirk is needed due to <rdar://problem/4985321> - We can phase it out once Aperture can adopt the new behavior on their end if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_APERTURE_QUIRK) && [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Aperture"]) @@ -4096,7 +4222,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValuePtr jsV Frame* coreFrame = core([self _selectedOrMainFrame]); if (!coreFrame) return nil; - return kit(coreFrame->selection()->toRange().get()); + return kit(coreFrame->selection()->toNormalizedRange().get()); } - (NSSelectionAffinity)selectionAffinity @@ -4370,7 +4496,7 @@ FOR_EACH_RESPONDER_SELECTOR(FORWARD) @implementation WebView (WebViewEditingInMail) -- (void)_insertNewlineInQuotedContent; +- (void)_insertNewlineInQuotedContent { [[self _selectedOrMainFrame] _insertParagraphSeparatorInQuotedContent]; } @@ -5148,6 +5274,20 @@ static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SE return nil; } +static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, NSInteger integer2, id object2) +{ + if (!delegate) + return nil; + if (!self->_private->catchesDelegateExceptions) + return implementation(delegate, selector, self, object1, integer1, integer2, object2); + @try { + return implementation(delegate, selector, self, object1, integer1, integer2, object2); + } @catch(id exception) { + ReportDiscardedDelegateException(selector, exception); + } + return nil; +} + static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3) { if (!delegate) @@ -5162,6 +5302,34 @@ static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SE return nil; } +static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3) +{ + if (!delegate) + return nil; + if (!self->_private->catchesDelegateExceptions) + return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3); + @try { + return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3); + } @catch(id exception) { + ReportDiscardedDelegateException(selector, exception); + } + return nil; +} + +static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4) +{ + if (!delegate) + return nil; + if (!self->_private->catchesDelegateExceptions) + return implementation(delegate, selector, self, object1, integer, object2, object3, object4); + @try { + return implementation(delegate, selector, self, object1, integer, object2, object3, object4); + } @catch(id exception) { + ReportDiscardedDelegateException(selector, exception); + } + return nil; +} + static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSTimeInterval interval, id object2, id object3) { if (!delegate) @@ -5303,6 +5471,26 @@ BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, W return result; } +id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3) +{ + return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, object2, integer, object3); +} + +id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3) +{ + return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, object2, integer2, object3); +} + +id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4) +{ + return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer, object2, object3, object4); +} + +id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, NSInteger integer2, id object2) +{ + return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2); +} + // The form delegate needs to have it's own implementation, because the first argument is never the WebView id CallFormDelegate(WebView *self, SEL selector, id object1, id object2) diff --git a/WebKit/mac/WebView/WebViewInternal.h b/WebKit/mac/WebView/WebViewInternal.h index 25afb64..ad4f19c 100644 --- a/WebKit/mac/WebView/WebViewInternal.h +++ b/WebKit/mac/WebView/WebViewInternal.h @@ -81,7 +81,6 @@ typedef WebCore::Page WebCorePage; - (id)_UIDelegateForwarder; - (id)_editingDelegateForwarder; - (id)_policyDelegateForwarder; -- (id)_scriptDebugDelegateForwarder; - (void)_pushPerformingProgrammaticFocus; - (void)_popPerformingProgrammaticFocus; - (void)_incrementProgressForIdentifier:(id)identifier response:(NSURLResponse *)response; @@ -145,6 +144,13 @@ typedef WebCore::Page WebCorePage; + (BOOL)_canHandleRequest:(NSURLRequest *)request forMainFrame:(BOOL)forMainFrame; +#if USE(ACCELERATED_COMPOSITING) +- (BOOL)_needsOneShotDrawingSynchronization; +- (void)_setNeedsOneShotDrawingSynchronization:(BOOL)needsSynchronization; +- (void)_startedAcceleratedCompositingForFrame:(WebFrame*)webFrame; +- (void)_stoppedAcceleratedCompositingForFrame:(WebFrame*)webFrame; +#endif + @end typedef struct _WebResourceDelegateImplementationCache { @@ -183,8 +189,19 @@ typedef struct _WebFrameLoadDelegateImplementationCache { IMP didFinishDocumentLoadForFrameFunc; } WebFrameLoadDelegateImplementationCache; +typedef struct _WebScriptDebugDelegateImplementationCache { + BOOL didParseSourceExpectsBaseLineNumber; + IMP didParseSourceFunc; + IMP failedToParseSourceFunc; + IMP didEnterCallFrameFunc; + IMP willExecuteStatementFunc; + IMP willLeaveCallFrameFunc; + IMP exceptionWasRaisedFunc; +} WebScriptDebugDelegateImplementationCache; + WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *webView); WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *webView); +WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *webView); #ifdef __cplusplus @@ -220,4 +237,9 @@ id CallResourceLoadDelegate(IMP, WebView *, SEL, id, id, NSInteger, id); BOOL CallResourceLoadDelegateReturningBoolean(BOOL, IMP, WebView *, SEL, id, id); +id CallScriptDebugDelegate(IMP, WebView *, SEL, id, id, NSInteger, id); +id CallScriptDebugDelegate(IMP, WebView *, SEL, id, NSInteger, id, NSInteger, id); +id CallScriptDebugDelegate(IMP, WebView *, SEL, id, NSInteger, id, id, id); +id CallScriptDebugDelegate(IMP, WebView *, SEL, id, NSInteger, NSInteger, id); + #endif diff --git a/WebKit/mac/WebView/WebViewPrivate.h b/WebKit/mac/WebView/WebViewPrivate.h index 95e1249..ada0e01 100644 --- a/WebKit/mac/WebView/WebViewPrivate.h +++ b/WebKit/mac/WebView/WebViewPrivate.h @@ -406,6 +406,13 @@ Could be worth adding to the API. - (void)setMemoryCacheDelegateCallsEnabled:(BOOL)suspend; - (BOOL)areMemoryCacheDelegateCallsEnabled; +- (void)_setJavaScriptURLsAreAllowed:(BOOL)setJavaScriptURLsAreAllowed; + ++ (NSCursor *)_pointingHandCursor; + +// SPI for DumpRenderTree +- (BOOL)_isUsingAcceleratedCompositing; + @end @interface WebView (WebViewPrintingPrivate) |