diff options
Diffstat (limited to 'WebKit/mac/WebView')
29 files changed, 1022 insertions, 321 deletions
diff --git a/WebKit/mac/WebView/WebArchive.mm b/WebKit/mac/WebView/WebArchive.mm index c989a9a..c6cc9b1 100644 --- a/WebKit/mac/WebView/WebArchive.mm +++ b/WebKit/mac/WebView/WebArchive.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,12 +30,13 @@ #import "WebArchiveInternal.h" #import "WebKitLogging.h" +#import "WebNSObjectExtras.h" #import "WebResourceInternal.h" -#import "WebResourcePrivate.h" #import "WebTypesInternal.h" - +#import <JavaScriptCore/InitializeThreading.h> #import <WebCore/ArchiveResource.h> #import <WebCore/LegacyWebArchive.h> +#import <WebCore/ThreadCheck.h> #import <WebCore/WebCoreObjCExtras.h> using namespace WebCore; @@ -46,8 +47,7 @@ static NSString * const WebMainResourceKey = @"WebMainResource"; static NSString * const WebSubresourcesKey = @"WebSubresources"; static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; -@interface WebArchivePrivate : NSObject -{ +@interface WebArchivePrivate : NSObject { @public WebResource *cachedMainResource; NSArray *cachedSubresources; @@ -63,18 +63,20 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; @implementation WebArchivePrivate -#ifndef BUILDING_ON_TIGER + (void)initialize { + JSC::initializeThreading(); +#ifndef BUILDING_ON_TIGER WebCoreObjCFinalizeOnMainThread(self); -} #endif +} - (id)init { self = [super init]; - if (self) - coreArchive = LegacyWebArchive::create().releaseRef(); + if (!self) + return nil; + coreArchive = LegacyWebArchive::create().releaseRef(); return self; } @@ -85,9 +87,7 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; [self release]; return nil; } - coreArchive = _coreArchive.releaseRef(); - return self; } @@ -100,7 +100,8 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; { ASSERT(coreArchive); ASSERT(newCoreArchive); - coreArchive->deref(); + if (coreArchive) + coreArchive->deref(); coreArchive = newCoreArchive.releaseRef(); } @@ -109,9 +110,10 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; if (WebCoreObjCScheduleDeallocateOnMainThread([WebArchivePrivate class], self)) return; - ASSERT(coreArchive); - coreArchive->deref(); - coreArchive = 0; + if (coreArchive) { + coreArchive->deref(); + coreArchive = 0; + } [cachedMainResource release]; [cachedSubresources release]; @@ -122,9 +124,10 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; - (void)finalize { - ASSERT(coreArchive); - coreArchive->deref(); - coreArchive = 0; + if (coreArchive) { + coreArchive->deref(); + coreArchive = 0; + } [super finalize]; } @@ -135,6 +138,8 @@ static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; - (id)init { + WebCoreThreadViolationCheck(); + self = [super init]; if (!self) return nil; @@ -156,6 +161,13 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (id)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives { +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives]; +#endif + + WebCoreThreadViolationCheck(); + self = [super init]; if (!self) return nil; @@ -207,6 +219,8 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (id)initWithData:(NSData *)data { + WebCoreThreadViolationCheck(); + self = [super init]; if (!self) return nil; @@ -216,7 +230,13 @@ static BOOL isArrayOfClass(id object, Class elementClass) #endif _private = [[WebArchivePrivate alloc] init]; - [_private setCoreArchive:LegacyWebArchive::create(SharedBuffer::wrapNSData(data).get())]; + RefPtr<LegacyWebArchive> coreArchive = LegacyWebArchive::create(SharedBuffer::wrapNSData(data).get()); + if (!coreArchive) { + [self release]; + return nil; + } + + [_private setCoreArchive:coreArchive.release()]; #if !LOG_DISABLED CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); @@ -271,6 +291,13 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (WebResource *)mainResource { +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] mainResource]; +#endif + + WebCoreThreadViolationCheck(); + // Currently from WebKit API perspective, WebArchives are entirely immutable once created // If they ever become mutable, we'll need to rethink this. if (!_private->cachedMainResource) { @@ -284,6 +311,13 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (NSArray *)subresources { +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] subresources]; +#endif + + WebCoreThreadViolationCheck(); + // Currently from WebKit API perspective, WebArchives are entirely immutable once created // If they ever become mutable, we'll need to rethink this. if (!_private->cachedSubresources) { @@ -309,6 +343,13 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (NSArray *)subframeArchives { +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] subframeArchives]; +#endif + + WebCoreThreadViolationCheck(); + // Currently from WebKit API perspective, WebArchives are entirely immutable once created // If they ever become mutable, we'll need to rethink this. if (!_private->cachedSubframeArchives) { @@ -332,6 +373,8 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (NSData *)data { + WebCoreThreadViolationCheck(); + #if !LOG_DISABLED CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); #endif @@ -353,6 +396,8 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (id)_initWithCoreLegacyWebArchive:(PassRefPtr<WebCore::LegacyWebArchive>)coreLegacyWebArchive { + WebCoreThreadViolationCheck(); + self = [super init]; if (!self) return nil; @@ -368,6 +413,8 @@ static BOOL isArrayOfClass(id object, Class elementClass) - (WebCore::LegacyWebArchive *)_coreLegacyWebArchive { + WebCoreThreadViolationCheck(); + return [_private coreArchive]; } diff --git a/WebKit/mac/WebView/WebDataSource.mm b/WebKit/mac/WebView/WebDataSource.mm index aeff7d7..12afcb3 100644 --- a/WebKit/mac/WebView/WebDataSource.mm +++ b/WebKit/mac/WebView/WebDataSource.mm @@ -46,7 +46,6 @@ #import "WebPDFRepresentation.h" #import "WebResourceInternal.h" #import "WebResourceLoadDelegate.h" -#import "WebResourcePrivate.h" #import "WebViewInternal.h" #import <WebCore/ApplicationCacheStorage.h> #import <WebCore/FrameLoader.h> @@ -59,6 +58,7 @@ #import <WebCore/WebCoreURLResponse.h> #import <WebKit/DOMHTML.h> #import <WebKit/DOMPrivate.h> +#import <runtime/InitializeThreading.h> #import <wtf/Assertions.h> using namespace WebCore; @@ -75,12 +75,13 @@ using namespace WebCore; @implementation WebDataSourcePrivate -#ifndef BUILDING_ON_TIGER + (void)initialize { + JSC::initializeThreading(); +#ifndef BUILDING_ON_TIGER WebCoreObjCFinalizeOnMainThread(self); -} #endif +} - (void)dealloc { diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsView.m b/WebKit/mac/WebView/WebDynamicScrollBarsView.m index 1eb2d80..de19ef6 100644 --- a/WebKit/mac/WebView/WebDynamicScrollBarsView.m +++ b/WebKit/mac/WebView/WebDynamicScrollBarsView.m @@ -224,6 +224,12 @@ const int WebCoreScrollbarAlwaysOn = ScrollbarAlwaysOn; [self setScrollingModes:[self horizontalScrollingMode] vertical:verticalMode andLock:lock]; } +// Mail uses this method, so we cannot remove it. +- (void)setVerticalScrollingMode:(ScrollbarMode)verticalMode +{ + [self setScrollingModes:[self horizontalScrollingMode] vertical:verticalMode andLock:NO]; +} + - (void)setScrollingModes:(ScrollbarMode)horizontalMode vertical:(ScrollbarMode)verticalMode andLock:(BOOL)lock { BOOL update = NO; diff --git a/WebKit/mac/WebView/WebFrame.h b/WebKit/mac/WebView/WebFrame.h index e435087..a6cdebb 100644 --- a/WebKit/mac/WebView/WebFrame.h +++ b/WebKit/mac/WebView/WebFrame.h @@ -165,10 +165,17 @@ /*! @method reload + @discussion Performs HTTP/1.1 end-to-end revalidation using cache-validating conditionals if possible. */ - (void)reload; /*! + @method reloadFromOrigin + @discussion Performs HTTP/1.1 end-to-end reload. +*/ +- (void)reloadFromOrigin; + +/*! @method findFrameNamed: @discussion This method returns a frame with the given name. findFrameNamed returns self for _self and _current, the parent frame for _parent and the main frame for _top. diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm index 13a6ad4..0ac300e 100644 --- a/WebKit/mac/WebView/WebFrame.mm +++ b/WebKit/mac/WebView/WebFrame.mm @@ -45,11 +45,13 @@ #import "WebHTMLViewInternal.h" #import "WebIconFetcherInternal.h" #import "WebKitStatisticsPrivate.h" +#import "WebKitVersionChecks.h" #import "WebNSURLExtras.h" #import "WebScriptDebugger.h" #import "WebViewInternal.h" #import <JavaScriptCore/APICast.h> #import <WebCore/AccessibilityObject.h> +#import <WebCore/AnimationController.h> #import <WebCore/AXObjectCache.h> #import <WebCore/ColorMac.h> #import <WebCore/DOMImplementation.h> @@ -71,14 +73,16 @@ #import <WebCore/RenderLayer.h> #import <WebCore/ReplaceSelectionCommand.h> #import <WebCore/SmartReplace.h> -#import <WebCore/SystemTime.h> #import <WebCore/TextIterator.h> #import <WebCore/TypingCommand.h> #import <WebCore/htmlediting.h> #import <WebCore/ScriptController.h> +#import <WebCore/ScriptValue.h> #import <WebCore/markup.h> #import <WebCore/visible_units.h> #import <runtime/JSLock.h> +#import <runtime/JSValue.h> +#include <wtf/CurrentTime.h> using namespace std; using namespace WebCore; @@ -86,7 +90,7 @@ using namespace HTMLNames; using JSC::JSGlobalObject; using JSC::JSLock; -using JSC::JSValue; +using JSC::JSValuePtr; /* Here is the current behavior matrix for four types of navigations: @@ -184,11 +188,6 @@ DOMNode *kit(Node* node) return [DOMNode _wrapNode:node]; } -DOMNode *kit(PassRefPtr<Node> node) -{ - return [DOMNode _wrapNode:node.get()]; -} - Document* core(DOMDocument *document) { return [document _document]; @@ -247,6 +246,20 @@ EditableLinkBehavior core(WebKitEditableLinkBehavior editableLinkBehavior) return EditableLinkDefaultBehavior; } +TextDirectionSubmenuInclusionBehavior core(WebTextDirectionSubmenuInclusionBehavior behavior) +{ + switch (behavior) { + case WebTextDirectionSubmenuNeverIncluded: + return TextDirectionSubmenuNeverIncluded; + case WebTextDirectionSubmenuAutomaticallyIncluded: + return TextDirectionSubmenuAutomaticallyIncluded; + case WebTextDirectionSubmenuAlwaysIncluded: + return TextDirectionSubmenuAlwaysIncluded; + } + ASSERT_NOT_REACHED(); + return TextDirectionSubmenuNeverIncluded; +} + @implementation WebFrame (WebInternal) Frame* core(WebFrame *frame) @@ -373,8 +386,8 @@ WebView *getWebView(WebFrame *webFrame) Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { WebFrame *webFrame = kit(frame); - // Never call setDrawsBackground:YES here on the scroll view or the background color will - // flash between pages loads. setDrawsBackground:YES will be called in _frameLoadCompleted. + // Don't call setDrawsBackground:YES here because it may be NO because of a load + // in progress; WebFrameLoaderClient keeps it set to NO during the load process. if (!drawsBackground) [[[webFrame frameView] _scrollView] setDrawsBackground:NO]; [[[webFrame frameView] _scrollView] setBackgroundColor:backgroundColor]; @@ -536,25 +549,17 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (NSString *)_selectedString { - String text = _private->coreFrame->selectedText(); - text.replace('\\', _private->coreFrame->backslashAsCurrencySymbol()); - return text; + return _private->coreFrame->displayStringModifiedByEncoding(_private->coreFrame->selectedText()); } - (NSString *)_stringForRange:(DOMRange *)range { // This will give a system malloc'd buffer that can be turned directly into an NSString unsigned length; - UChar* buf = plainTextToMallocAllocatedBuffer([range _range], length); + UChar* buf = plainTextToMallocAllocatedBuffer([range _range], length, true); if (!buf) return [NSString string]; - - UChar backslashAsCurrencySymbol = _private->coreFrame->backslashAsCurrencySymbol(); - if (backslashAsCurrencySymbol != '\\') - for (unsigned n = 0; n < length; n++) - if (buf[n] == '\\') - buf[n] = backslashAsCurrencySymbol; // Transfer buffer ownership to NSString return [[[NSString alloc] initWithCharactersNoCopy:buf length:length freeWhenDone:YES] autorelease]; @@ -639,7 +644,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) { ASSERT(_private->coreFrame->document()); - JSValue* result = _private->coreFrame->loader()->executeScript(string, forceUserGesture); + JSValuePtr result = _private->coreFrame->loader()->executeScript(string, forceUserGesture).jsValue(); if (!_private->coreFrame) // In case the script removed our frame from the page. return @""; @@ -647,17 +652,17 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) // This bizarre set of rules matches behavior from WebKit for Safari 2.0. // If you don't like it, use -[WebScriptObject evaluateWebScript:] or // JSEvaluateScript instead, since they have less surprising semantics. - if (!result || !result->isBoolean() && !result->isString() && !result->isNumber()) + if (!result || !result.isBoolean() && !result.isString() && !result.isNumber()) return @""; JSLock lock(false); - return String(result->toString(_private->coreFrame->script()->globalObject()->globalExec())); + return String(result.toString(_private->coreFrame->script()->globalObject()->globalExec())); } - (NSRect)_caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity { VisiblePosition visiblePosition([node _node], offset, static_cast<EAffinity>(affinity)); - return visiblePosition.caretRect(); + return visiblePosition.absoluteCaretBounds(); } - (NSRect)_firstRectForDOMRange:(DOMRange *)range @@ -684,6 +689,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (id)_accessibilityTree { +#if HAVE(ACCESSIBILITY) if (!AXObjectCache::accessibilityEnabled()) { AXObjectCache::enableAccessibility(); if ([[NSApp accessibilityAttributeValue:NSAccessibilityEnhancedUserInterfaceAttribute] boolValue]) @@ -696,6 +702,9 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) if (!root) return nil; return _private->coreFrame->document()->axObjectCache()->get(root)->wrapper(); +#else + return nil; +#endif } - (DOMRange *)_rangeByAlteringCurrentSelection:(SelectionController::EAlteration)alteration direction:(SelectionController::EDirection)direction granularity:(TextGranularity)granularity @@ -760,11 +769,23 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) return TextIterator::rangeFromLocationAndLength(scope, nsrange.location, nsrange.length); } +- (DOMRange *)convertNSRangeToDOMRange:(NSRange)nsrange +{ + // This method exists to maintain compatibility with Leopard's Dictionary.app. <rdar://problem/6002160> + return [self _convertNSRangeToDOMRange:nsrange]; +} + - (DOMRange *)_convertNSRangeToDOMRange:(NSRange)nsrange { return [DOMRange _wrapRange:[self _convertToDOMRange:nsrange].get()]; } +- (NSRange)convertDOMRangeToNSRange:(DOMRange *)range +{ + // This method exists to maintain compatibility with Leopard's Dictionary.app. <rdar://problem/6002160> + return [self _convertDOMRangeToNSRange:range]; +} + - (NSRange)_convertDOMRangeToNSRange:(DOMRange *)range { return [self _convertToNSRange:[range _range]]; @@ -1008,13 +1029,15 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (BOOL)_canProvideDocumentSource { - String mimeType = _private->coreFrame->loader()->responseMIMEType(); - + Frame* frame = _private->coreFrame; + String mimeType = frame->loader()->responseMIMEType(); + PluginData* pluginData = frame->page() ? frame->page()->pluginData() : 0; + if (WebCore::DOMImplementation::isTextMIMEType(mimeType) || Image::supportsType(mimeType) || - (_private->coreFrame->page() && _private->coreFrame->page()->pluginData()->supportsMimeType(mimeType))) + (pluginData && pluginData->supportsMimeType(mimeType))) return NO; - + return YES; } @@ -1147,6 +1170,53 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) } #endif +- (BOOL)_pauseAnimation:(NSString*)name onNode:(DOMNode *)node atTime:(NSTimeInterval)time +{ + Frame* frame = core(self); + if (!frame) + return false; + + AnimationController* controller = frame->animation(); + if (!controller) + return false; + + Node* coreNode = [node _node]; + if (!coreNode || !coreNode->renderer()) + return false; + + return controller->pauseAnimationAtTime(coreNode->renderer(), name, time); +} + +- (BOOL)_pauseTransitionOfProperty:(NSString*)name onNode:(DOMNode*)node atTime:(NSTimeInterval)time +{ + Frame* frame = core(self); + if (!frame) + return false; + + AnimationController* controller = frame->animation(); + if (!controller) + return false; + + Node* coreNode = [node _node]; + if (!coreNode || !coreNode->renderer()) + return false; + + return controller->pauseTransitionAtTime(coreNode->renderer(), name, time); +} + +- (unsigned) _numberOfActiveAnimations +{ + Frame* frame = core(self); + if (!frame) + return false; + + AnimationController* controller = frame->animation(); + if (!controller) + return false; + + return controller->numberOfActiveAnimations(); +} + @end @implementation WebFrame @@ -1238,7 +1308,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (void)loadRequest:(NSURLRequest *)request { - _private->coreFrame->loader()->load(request); + _private->coreFrame->loader()->load(request, false); } static NSURL *createUniqueWebDataURL() @@ -1266,7 +1336,7 @@ static NSURL *createUniqueWebDataURL() SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData(data), MIMEType, encodingName, [unreachableURL absoluteURL], responseURL); - _private->coreFrame->loader()->load(request, substituteData); + _private->coreFrame->loader()->load(request, substituteData, false); } @@ -1308,7 +1378,16 @@ static NSURL *createUniqueWebDataURL() - (void)reload { - _private->coreFrame->loader()->reload(); + if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_RELOAD_FROM_ORIGIN) && + [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Safari"]) + _private->coreFrame->loader()->reload(GetCurrentKeyModifiers() & shiftKey); + else + _private->coreFrame->loader()->reload(false); +} + +- (void)reloadFromOrigin +{ + _private->coreFrame->loader()->reload(true); } - (WebFrame *)findFrameNamed:(NSString *)name diff --git a/WebKit/mac/WebView/WebFrameInternal.h b/WebKit/mac/WebView/WebFrameInternal.h index 5cf7690..fa17ed9 100644 --- a/WebKit/mac/WebView/WebFrameInternal.h +++ b/WebKit/mac/WebView/WebFrameInternal.h @@ -91,6 +91,7 @@ WebCore::Page* core(WebView *); WebView *kit(WebCore::Page*); WebCore::EditableLinkBehavior core(WebKitEditableLinkBehavior); +WebCore::TextDirectionSubmenuInclusionBehavior core(WebTextDirectionSubmenuInclusionBehavior); WebView *getWebView(WebFrame *webFrame); diff --git a/WebKit/mac/WebView/WebFramePrivate.h b/WebKit/mac/WebView/WebFramePrivate.h index 428c142..2ea686e 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 DOMNode; @class WebIconFetcher; @class WebScriptObject; @@ -51,8 +52,9 @@ typedef enum { WebFrameLoadTypeReload, WebFrameLoadTypeReloadAllowingStaleData, WebFrameLoadTypeSame, // user loads same URL again (but not reload button) - WebFrameLoadTypeInternal, // maps to WebCore::FrameLoadTypeRedirectWithLockedHistory - WebFrameLoadTypeReplace + WebFrameLoadTypeInternal, // maps to WebCore::FrameLoadTypeRedirectWithLockedBackForwardList + WebFrameLoadTypeReplace, + WebFrameLoadTypeReloadFromOrigin } WebFrameLoadType; @interface WebFrame (WebPrivate) @@ -84,4 +86,13 @@ typedef enum { - (void)_recursive_pauseNullEventsForAllNetscapePlugins; #endif +// Pause a given CSS animation or transition on the target node at a specific time. +// If the animation or transition is already paused, it will update its pause time. +// This method is only intended to be used for testing the CSS animation and transition system. +- (BOOL)_pauseAnimation:(NSString*)name onNode:(DOMNode *)node atTime:(NSTimeInterval)time; +- (BOOL)_pauseTransitionOfProperty:(NSString*)name onNode:(DOMNode*)node atTime:(NSTimeInterval)time; + +// Returns the total number of currently running animations (includes both CSS transitions and CSS animations). +- (unsigned) _numberOfActiveAnimations; + @end diff --git a/WebKit/mac/WebView/WebFrameView.mm b/WebKit/mac/WebView/WebFrameView.mm index e9c0aae..132fb93 100644 --- a/WebKit/mac/WebView/WebFrameView.mm +++ b/WebKit/mac/WebView/WebFrameView.mm @@ -189,11 +189,10 @@ enum { - (WebDynamicScrollBarsView *)_scrollView { - // this can be called by [super dealloc] when cleaning up the keyview loop, + // This can be called by [super dealloc] when cleaning up the key view loop, // after _private has been nilled out. - if (_private == nil) { + if (_private == nil) return nil; - } return _private->frameScrollView; } @@ -300,9 +299,8 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl didFirstTimeInitialization = true; InitWebCoreSystemInterface(); - // Need to tell WebCore what function to call for the - // "History Item has Changed" notification - // Note: We also do this in WebHistoryItem's init method + // Need to tell WebCore what function to call for the "History Item has Changed" notification. + // Note: We also do this in WebHistoryItem's init method. WebCore::notifyHistoryItemChanged = WKNotifyHistoryItemChanged; [WebViewFactory createSharedFactory]; @@ -310,9 +308,8 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - // CoreGraphics deferred updates are disabled if WebKitEnableCoalescedUpdatesPreferenceKey is set - // to NO, or has no value. For compatibility with Mac OS X 10.4.6, deferred updates are OFF by - // default. + // CoreGraphics deferred updates are disabled if WebKitEnableCoalescedUpdatesPreferenceKey is NO + // or has no value. For compatibility with Mac OS X 10.4.6, deferred updates are off by default. if (![defaults boolForKey:WebKitEnableDeferredUpdatesPreferenceKey]) WKDisableCGDeferredUpdates(); @@ -322,7 +319,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl _private = [[WebFrameViewPrivate alloc] init]; - WebDynamicScrollBarsView *scrollView = [[WebDynamicScrollBarsView alloc] initWithFrame:NSMakeRect(0.0f, 0.0f, frame.size.width, frame.size.height)]; + WebDynamicScrollBarsView *scrollView = [[WebDynamicScrollBarsView alloc] initWithFrame:NSMakeRect(0.0f, 0.0f, frame.size.width, frame.size.height)]; _private->frameScrollView = scrollView; [scrollView setContentView:[[[WebClipView alloc] initWithFrame:[scrollView bounds]] autorelease]]; [scrollView setDrawsBackground:NO]; @@ -331,9 +328,10 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl [scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [scrollView setLineScroll:40.0f]; [self addSubview:scrollView]; - // don't call our overridden version here; we need to make the standard NSView link between us - // and our subview so that previousKeyView and previousValidKeyView work as expected. This works - // together with our becomeFirstResponder and setNextKeyView overrides. + + // Don't call our overridden version of setNextKeyView here; we need to make the standard NSView + // link between us and our subview so that previousKeyView and previousValidKeyView work as expected. + // This works together with our becomeFirstResponder and setNextKeyView overrides. [super setNextKeyView:scrollView]; ++WebFrameViewCount; @@ -396,29 +394,22 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl // the key loop similar to the way NSScrollView does this. Note that // WebView has similar code. - // If the scrollView won't accept first-responderness now, then we just become - // the first responder ourself like a normal view. This lets us be the first - // responder in cases where no page has yet been loaded (see 3469791). - if ([[self _scrollView] acceptsFirstResponder]) { - NSWindow *window = [self window]; - if ([window keyViewSelectionDirection] == NSSelectingPrevious) { - NSView *previousValidKeyView = [self previousValidKeyView]; - // If we couldn't find a previous valid key view, ask the webview. This handles frameset - // cases like 3748628. Note that previousValidKeyView should never be self but can be - // due to AppKit oddness (mentioned in 3748628). - if (previousValidKeyView == nil || previousValidKeyView == self) { - previousValidKeyView = [[[self webFrame] webView] previousValidKeyView]; - } - // I don't know if the following cases ever occur anymore, but I'm leaving in the old test for - // now to avoid causing trouble just before shipping Tiger. - ASSERT((previousValidKeyView != self) && (previousValidKeyView != [self _scrollView])); - if ((previousValidKeyView != self) && (previousValidKeyView != [self _scrollView])) { - [window makeFirstResponder:previousValidKeyView]; - } - } else { + NSWindow *window = [self window]; + if ([window keyViewSelectionDirection] == NSSelectingPrevious) { + NSView *previousValidKeyView = [self previousValidKeyView]; + // If we couldn't find a previous valid key view, ask the WebView. This handles frameset + // cases (one is mentioned in Radar bug 3748628). Note that previousValidKeyView should + // never be self but can be due to AppKit oddness (mentioned in Radar bug 3748628). + if (previousValidKeyView == nil || previousValidKeyView == self) + previousValidKeyView = [[[self webFrame] webView] previousValidKeyView]; + [window makeFirstResponder:previousValidKeyView]; + } else { + // If the scroll view won't accept first-responderness now, then just become + // the first responder ourself like a normal view. This lets us be the first + // responder in cases where no page has yet been loaded. + if ([[self _scrollView] acceptsFirstResponder]) [window makeFirstResponder:[self _scrollView]]; - } - } + } return YES; } @@ -491,12 +482,21 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (void)setFrameSize:(NSSize)size { - if (!NSEqualSizes(size, [self frame].size) && [[[self webFrame] webView] drawsBackground]) { + // See WebFrameLoaderClient::provisionalLoadStarted. + if (!NSEqualSizes(size, [self frame].size) && [[[self webFrame] webView] drawsBackground]) [[self _scrollView] setDrawsBackground:YES]; - } [super setFrameSize:size]; } +- (void)viewDidMoveToWindow +{ + // See WebFrameLoaderClient::provisionalLoadStarted. + // Need to check _private for nil because this can be called inside -[WebView initWithCoder:]. + if (_private && [[[self webFrame] webView] drawsBackground]) + [[self _scrollView] setDrawsBackground:YES]; + [super viewDidMoveToWindow]; +} + - (BOOL)_scrollOverflowInDirection:(ScrollDirection)direction granularity:(ScrollGranularity)granularity { // scrolling overflows is only applicable if we're dealing with an WebHTMLView diff --git a/WebKit/mac/WebView/WebHTMLRepresentation.mm b/WebKit/mac/WebView/WebHTMLRepresentation.mm index 4b4d11e..604a17a 100644 --- a/WebKit/mac/WebView/WebHTMLRepresentation.mm +++ b/WebKit/mac/WebView/WebHTMLRepresentation.mm @@ -39,7 +39,6 @@ #import "WebKitStatisticsPrivate.h" #import "WebNSAttributedStringExtras.h" #import "WebNSObjectExtras.h" -#import "WebResourcePrivate.h" #import "WebView.h" #import <Foundation/NSURLResponse.h> #import <WebCore/Document.h> @@ -55,6 +54,7 @@ #import <WebCore/TextResourceDecoder.h> #import <WebKit/DOMHTMLInputElement.h> #import <wtf/Assertions.h> +#import <wtf/StdLibExtras.h> using namespace WebCore; using namespace HTMLNames; @@ -92,22 +92,19 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) + (NSArray *)supportedMIMETypes { - static RetainPtr<NSArray> staticSupportedMIMETypes = - concatenateArrays([self supportedNonImageMIMETypes], [self supportedImageMIMETypes]); + DEFINE_STATIC_LOCAL(RetainPtr<NSArray>, staticSupportedMIMETypes, (concatenateArrays([self supportedNonImageMIMETypes], [self supportedImageMIMETypes]))); return staticSupportedMIMETypes.get(); } + (NSArray *)supportedNonImageMIMETypes { - static RetainPtr<NSArray> staticSupportedNonImageMIMETypes = - stringArray(MIMETypeRegistry::getSupportedNonImageMIMETypes()); + DEFINE_STATIC_LOCAL(RetainPtr<NSArray>, staticSupportedNonImageMIMETypes, (stringArray(MIMETypeRegistry::getSupportedNonImageMIMETypes()))); return staticSupportedNonImageMIMETypes.get(); } + (NSArray *)supportedImageMIMETypes { - static RetainPtr<NSArray> staticSupportedImageMIMETypes = - stringArray(MIMETypeRegistry::getSupportedImageMIMETypes()); + DEFINE_STATIC_LOCAL(RetainPtr<NSArray>, staticSupportedImageMIMETypes, (stringArray(MIMETypeRegistry::getSupportedImageMIMETypes()))); return staticSupportedImageMIMETypes.get(); } diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm index 4d9b3a8..be4d8db 100644 --- a/WebKit/mac/WebView/WebHTMLView.mm +++ b/WebKit/mac/WebView/WebHTMLView.mm @@ -32,7 +32,7 @@ #import "DOMNodeInternal.h" #import "DOMRangeInternal.h" #import "WebArchive.h" -#import "WebBaseNetscapePluginView.h" +#import "WebNetscapePluginView.h" #import "WebClipView.h" #import "WebDOMOperationsPrivate.h" #import "WebDataSourceInternal.h" @@ -112,6 +112,7 @@ #import <WebKit/DOMPrivate.h> #import <WebKitSystemInterface.h> #import <limits> +#import <runtime/InitializeThreading.h> using namespace WebCore; using namespace HTMLNames; @@ -380,7 +381,7 @@ struct WebHTMLViewInterpretKeyEventsParameters { NSEvent *keyDownEvent; // Kept after handling the event. NSSize lastLayoutSize; - + NSPoint lastScrollPosition; WebPluginController *pluginController; @@ -393,22 +394,23 @@ struct WebHTMLViewInterpretKeyEventsParameters { NSTimer *autoscrollTimer; NSEvent *autoscrollTriggerEvent; - NSArray* pageRects; + NSArray *pageRects; - NSMutableDictionary* highlighters; + NSMutableDictionary *highlighters; - BOOL resigningFirstResponder; +#ifdef BUILDING_ON_TIGER BOOL nextResponderDisabledOnce; +#endif WebTextCompleteController *compController; BOOL transparentBackground; - WebHTMLViewInterpretKeyEventsParameters *interpretKeyEventsParameters; + WebHTMLViewInterpretKeyEventsParameters* interpretKeyEventsParameters; BOOL receivedNOOP; WebDataSource *dataSource; - WebCore::CachedImage *promisedDragTIFFDataSource; + WebCore::CachedImage* promisedDragTIFFDataSource; CFRunLoopTimerRef updateFocusedAndActiveStateTimer; CFRunLoopTimerRef updateMouseoverTimer; @@ -440,6 +442,7 @@ static NSCellStateValue kit(TriState state) + (void)initialize { + JSC::initializeThreading(); #ifndef BUILDING_ON_TIGER WebCoreObjCFinalizeOnMainThread(self); #endif @@ -661,13 +664,15 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) subresources:0])) return fragment; +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) if ([types containsObject:NSPICTPboardType] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:NSPICTPboardType inContext:context subresources:0])) return fragment; - +#endif + // Only 10.5 and higher support setting and retrieving pasteboard types with UTIs, but we don't believe // that any applications on Tiger put types for which we only have a UTI, like PNG, on the pasteboard. if ([types containsObject:(NSString*)kUTTypePNG] && @@ -1018,6 +1023,14 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) userInfo:[NSDictionary dictionaryWithObject:fakeEvent forKey:@"NSEvent"]]; } +- (id)_bridge +{ + // This method exists to maintain compatibility with Leopard's Dictionary.app, since it + // calls _bridge to get access to convertNSRangeToDOMRange: and convertDOMRangeToNSRange:. + // Return the WebFrame, which implements the compatibility methods. <rdar://problem/6002160> + return [self _frame]; +} + - (void)_updateMouseoverWithFakeEvent { [self _cancelUpdateMouseoverTimer]; @@ -1464,10 +1477,11 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) { static NSArray *types = nil; if (!types) { - types = [[NSArray alloc] initWithObjects:WebArchivePboardType, NSHTMLPboardType, - NSFilenamesPboardType, NSTIFFPboardType, NSPICTPboardType, NSURLPboardType, - NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, NSColorPboardType, - kUTTypePNG, nil]; + types = [[NSArray alloc] initWithObjects:WebArchivePboardType, NSHTMLPboardType, NSFilenamesPboardType, NSTIFFPboardType, +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) + NSPICTPboardType, +#endif + NSURLPboardType, NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, NSColorPboardType, kUTTypePNG, nil]; CFRetain(types); } return types; @@ -1517,7 +1531,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) NSImage *dragImage = [[[NSImage alloc] initWithSize: imageSize] autorelease]; [dragImage lockFocus]; - [[NSColor colorWithCalibratedRed: 0.7f green: 0.7f blue: 0.7f alpha: 0.8f] set]; + [[NSColor colorWithDeviceRed: 0.7f green: 0.7f blue: 0.7f alpha: 0.8f] set]; // Drag a rectangle with rounded corners/ NSBezierPath *path = [NSBezierPath bezierPath]; @@ -1531,8 +1545,8 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) [path appendBezierPathWithRect: NSMakeRect(imageSize.width - DRAG_LABEL_RADIUS - 20.0f, DRAG_LABEL_RADIUS, DRAG_LABEL_RADIUS + 20.0f, imageSize.height - 2.0f * DRAG_LABEL_RADIUS)]; [path fill]; - NSColor *topColor = [NSColor colorWithCalibratedWhite:0.0f alpha:0.75f]; - NSColor *bottomColor = [NSColor colorWithCalibratedWhite:1.0f alpha:0.5f]; + NSColor *topColor = [NSColor colorWithDeviceWhite:0.0f alpha:0.75f]; + NSColor *bottomColor = [NSColor colorWithDeviceWhite:1.0f alpha:0.5f]; if (drawURLString) { if (clipURLString) urlString = [WebStringTruncator centerTruncateString: urlString toWidth:imageSize.width - (DRAG_LABEL_BORDER_X * 2.0f) withFont:urlFont]; @@ -1931,6 +1945,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) [resource release]; return fragment; } +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) if (pboardType == NSPICTPboardType) { WebResource *resource = [[WebResource alloc] initWithData:[pasteboard dataForType:NSPICTPboardType] URL:uniqueURLWithRelativePart(@"image.pict") @@ -1941,6 +1956,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) [resource release]; return fragment; } +#endif // Only 10.5 and higher support setting and retrieving pasteboard types with UTIs, but we don't believe // that any applications on Tiger put types for which we only have a UTI, like PNG, on the pasteboard. if ([pboardType isEqualToString:(NSString*)kUTTypePNG]) { @@ -2071,6 +2087,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) { [NSApp registerServicesMenuSendTypes:[[self class] _selectionPasteboardTypes] returnTypes:[[self class] _insertablePasteboardTypes]]; + JSC::initializeThreading(); #ifndef BUILDING_ON_TIGER WebCoreObjCFinalizeOnMainThread(self); #endif @@ -2219,6 +2236,9 @@ WEBCORE_COMMAND(insertNewlineIgnoringFieldEditor) WEBCORE_COMMAND(insertParagraphSeparator) WEBCORE_COMMAND(insertTab) WEBCORE_COMMAND(insertTabIgnoringFieldEditor) +WEBCORE_COMMAND(makeTextWritingDirectionLeftToRight) +WEBCORE_COMMAND(makeTextWritingDirectionNatural) +WEBCORE_COMMAND(makeTextWritingDirectionRightToLeft) WEBCORE_COMMAND(moveBackward) WEBCORE_COMMAND(moveBackwardAndModifySelection) WEBCORE_COMMAND(moveDown) @@ -2383,10 +2403,20 @@ WEBCORE_COMMAND(yankAndSelect) return [self _canEdit]; } - if (action == @selector(changeBaseWritingDirection:)) { - NSWritingDirection writingDirection = static_cast<NSWritingDirection>([item tag]); - if (writingDirection == NSWritingDirectionNatural) - return NO; + if (action == @selector(changeBaseWritingDirection:) + || action == @selector(makeBaseWritingDirectionLeftToRight:) + || action == @selector(makeBaseWritingDirectionRightToLeft:)) { + NSWritingDirection writingDirection; + + if (action == @selector(changeBaseWritingDirection:)) { + writingDirection = static_cast<NSWritingDirection>([item tag]); + if (writingDirection == NSWritingDirectionNatural) + return NO; + } else if (action == @selector(makeBaseWritingDirectionLeftToRight:)) + writingDirection = NSWritingDirectionLeftToRight; + else + writingDirection = NSWritingDirectionRightToLeft; + NSMenuItem *menuItem = (NSMenuItem *)item; if ([menuItem isKindOfClass:[NSMenuItem class]]) { RefPtr<CSSStyleDeclaration> style = CSSMutableStyleDeclaration::create(); @@ -2421,7 +2451,7 @@ WEBCORE_COMMAND(yankAndSelect) || action == @selector(lowercaseWord:) || action == @selector(uppercaseWord:)) return [self _hasSelection] && [self _isEditable]; - + if (action == @selector(centerSelectionInVisibleArea:) || action == @selector(jumpToSelection:) || action == @selector(copyFont:)) @@ -2744,12 +2774,13 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v double start = CFAbsoluteTimeGetCurrent(); #endif - Frame* coreFrame = core([self _frame]); - if (FrameView* coreView = coreFrame->view()) - coreView->setMediaType(_private->printing ? "print" : "screen"); - if (Document* document = coreFrame->document()) - document->setPrinting(_private->printing); - coreFrame->reapplyStyles(); + if (Frame* coreFrame = core([self _frame])) { + if (FrameView* coreView = coreFrame->view()) + coreView->setMediaType(_private->printing ? "print" : "screen"); + if (Document* document = coreFrame->document()) + document->setPrinting(_private->printing); + coreFrame->reapplyStyles(); + } #ifdef LOG_TIMES double thisTime = CFAbsoluteTimeGetCurrent() - start; @@ -3208,9 +3239,9 @@ done: NSFileWrapper *wrapper = nil; NSURL *draggingImageURL = nil; - if (WebCore::CachedResource* tiffResource = [self promisedDragTIFFDataSource]) { + if (WebCore::CachedImage* tiffResource = [self promisedDragTIFFDataSource]) { - SharedBuffer *buffer = tiffResource->data(); + SharedBuffer *buffer = static_cast<CachedResource*>(tiffResource)->data(); if (!buffer) goto noPromisedData; @@ -3218,7 +3249,11 @@ done: NSURLResponse *response = tiffResource->response().nsURLResponse(); draggingImageURL = [response URL]; wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease]; - [wrapper setPreferredFilename:[response suggestedFilename]]; + NSString* filename = [response suggestedFilename]; + String trueExtension = tiffResource->image()->filenameExtension(); + if (![filename hasSuffix:trueExtension]) + filename = [[filename stringByAppendingString:@"."] stringByAppendingString:trueExtension]; + [wrapper setPreferredFilename:filename]; } noPromisedData: @@ -3322,14 +3357,12 @@ noPromisedData: BOOL resign = [super resignFirstResponder]; if (resign) { [_private->compController endRevertingChange:NO moveLeft:NO]; - _private->resigningFirstResponder = YES; if (![self maintainsInactiveSelection]) { [self deselectAll]; if (![[self _webView] _isPerformingProgrammaticFocus]) [self clearFocus]; } [self _updateFocusedAndActiveState]; - _private->resigningFirstResponder = NO; } return resign; } @@ -3744,7 +3777,7 @@ noPromisedData: - (NSString *)_colorAsString:(NSColor *)color { - NSColor *rgbColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + NSColor *rgbColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace]; // FIXME: If color is non-nil and rgbColor is nil, that means we got some kind // of fancy color that can't be converted to RGB. Changing that to "transparent" // might not be great, but it's probably OK. @@ -4373,8 +4406,12 @@ NSStrokeColorAttributeName /* NSColor, default nil: same as foreground co static BOOL writingDirectionKeyBindingsEnabled() { +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + return YES; +#else NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; return [defaults boolForKey:@"NSAllowsBaseWritingDirectionKeyBindings"] || [defaults boolForKey:@"AppleTextDirection"]; +#endif } - (void)_changeBaseWritingDirectionTo:(NSWritingDirection)direction @@ -4393,20 +4430,32 @@ static BOOL writingDirectionKeyBindingsEnabled() coreFrame->editor()->setBaseWritingDirection(direction == NSWritingDirectionLeftToRight ? LeftToRightWritingDirection : RightToLeftWritingDirection); } -- (void)changeBaseWritingDirectionToLTR:(id)sender +- (void)makeBaseWritingDirectionLeftToRight:(id)sender { COMMAND_PROLOGUE [self _changeBaseWritingDirectionTo:NSWritingDirectionLeftToRight]; } -- (void)changeBaseWritingDirectionToRTL:(id)sender +- (void)makeBaseWritingDirectionRightToLeft:(id)sender { COMMAND_PROLOGUE [self _changeBaseWritingDirectionTo:NSWritingDirectionRightToLeft]; } +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) +- (void)changeBaseWritingDirectionToLTR:(id)sender +{ + [self makeBaseWritingDirectionLeftToRight:sender]; +} + +- (void)changeBaseWritingDirectionToRTL:(id)sender +{ + [self makeBaseWritingDirectionRightToLeft:sender]; +} +#endif + #if 0 // CSS does not have a way to specify an outline font, which may make this difficult to implement. @@ -4430,8 +4479,19 @@ static BOOL writingDirectionKeyBindingsEnabled() #endif +#ifndef BUILDING_ON_TIGER + +// Override this so that AppKit will send us arrow keys as key down events so we can +// support them via the key bindings mechanism. +- (BOOL)_wantsKeyDownForEvent:(NSEvent *)event +{ + return YES; +} + +#else + // Super-hack alert. -// Workaround for bug 3789278. +// All this code accomplishes the same thing as the _wantsKeyDownForEvent method above. // Returns a selector only if called while: // 1) first responder is self @@ -4497,6 +4557,8 @@ static BOOL writingDirectionKeyBindingsEnabled() return [super nextResponder]; } +#endif + // Despite its name, this is called at different times than windowDidBecomeKey is. // It takes into account all the other factors that determine when NSCell draws // with different tints, so it's the right call to use for control tints. We'd prefer @@ -4541,7 +4603,7 @@ static BOOL writingDirectionKeyBindingsEnabled() { #if ENABLE(NETSCAPE_PLUGIN_API) NSEnumerator *enumerator = [self objectEnumerator]; - WebBaseNetscapePluginView *view; + WebNetscapePluginView *view; while ((view = [enumerator nextObject]) != nil) if ([view isKindOfClass:[WebBaseNetscapePluginView class]]) [view performSelector:selector withObject:object]; @@ -4746,7 +4808,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->selectionRect() toView:nil]; + NSRect rect = [self convertRect:coreFrame->selectionBounds() 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); @@ -4754,7 +4816,7 @@ 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->selectionRect(); + NSRect rect = coreFrame->selectionBounds(); NSDictionary *attributes = [attrString fontAttributesInRange:NSMakeRange(0,1)]; NSFont *font = [attributes objectForKey:NSFontAttributeName]; @@ -5160,11 +5222,18 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde Editor::Command command = [self coreCommandBySelector:selector]; if (command.isSupported()) eventWasHandled = command.execute(event); - else { + 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. _private->selectorForDoCommandBySelector = selector; [super doCommandBySelector:selector]; _private->selectorForDoCommandBySelector = 0; - } + } else + eventWasHandled = false; } if (parameters) @@ -5225,7 +5294,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde String eventText = text; eventText.replace(NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore - if (coreFrame) { + if (coreFrame && coreFrame->editor()->canEdit()) { if (!coreFrame->editor()->hasComposition()) eventHandled = coreFrame->editor()->insertText(eventText, event); else { @@ -5563,7 +5632,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde - (NSRect)selectionRect { if ([self _hasSelection]) - return core([self _frame])->selectionRect(); + return core([self _frame])->selectionBounds(); return NSZeroRect; } @@ -5599,7 +5668,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde - (NSRect)selectionImageRect { if ([self _hasSelection]) - return core([self _frame])->selectionRect(); + return core([self _frame])->selectionBounds(); return NSZeroRect; } diff --git a/WebKit/mac/WebView/WebPDFView.mm b/WebKit/mac/WebView/WebPDFView.mm index 1009cdd..2cb5374 100644 --- a/WebKit/mac/WebView/WebPDFView.mm +++ b/WebKit/mac/WebView/WebPDFView.mm @@ -950,7 +950,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec button, 0, 0, true); // Call to the frame loader because this is where our security checks are made. - core([dataSource webFrame])->loader()->loadFrameRequestWithFormAndValues(ResourceRequest(URL), false, event.get(), 0, HashMap<String, String>()); + core([dataSource webFrame])->loader()->loadFrameRequestWithFormAndValues(ResourceRequest(URL), false, false, event.get(), 0, HashMap<String, String>()); } - (void)PDFViewOpenPDFInNativeApplication:(PDFView *)sender diff --git a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h index bcb17db..98daec0 100644 --- a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h +++ b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h @@ -50,6 +50,8 @@ #define WebKitJavaScriptEnabledPreferenceKey @"WebKitJavaScriptEnabled" #define WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey @"WebKitJavaScriptCanOpenWindowsAutomatically" #define WebKitPluginsEnabledPreferenceKey @"WebKitPluginsEnabled" +#define WebKitDatabasesEnabledPreferenceKey @"WebKitDatabasesEnabledPreferenceKey" +#define WebKitLocalStorageEnabledPreferenceKey @"WebKitLocalStorageEnabledPreferenceKey" #define WebKitAllowAnimatedImagesPreferenceKey @"WebKitAllowAnimatedImagesPreferenceKey" #define WebKitAllowAnimatedImageLoopingPreferenceKey @"WebKitAllowAnimatedImageLoopingPreferenceKey" #define WebKitDisplayImagesKey @"WebKitDisplayImagesKey" @@ -80,6 +82,7 @@ #define WebKitUseSiteSpecificSpoofingPreferenceKey @"WebKitUseSiteSpecificSpoofing" #define WebKitEditableLinkBehaviorPreferenceKey @"WebKitEditableLinkBehavior" #define WebKitCacheModelPreferenceKey @"WebKitCacheModelPreferenceKey" +#define WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey @"WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey" // CoreGraphics deferred updates are disabled if WebKitEnableCoalescedUpdatesPreferenceKey is set // to NO, or has no value. For compatibility with Mac OS X 10.4.6, deferred updates are OFF by diff --git a/WebKit/mac/WebView/WebPreferences.mm b/WebKit/mac/WebView/WebPreferences.mm index 8b2f43e..e595861 100644 --- a/WebKit/mac/WebView/WebPreferences.mm +++ b/WebKit/mac/WebView/WebPreferences.mm @@ -315,6 +315,8 @@ static WebCacheModel cacheModelForMainBundle(void) [NSNumber numberWithBool:YES], WebKitJavaScriptEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey, [NSNumber numberWithBool:YES], WebKitPluginsEnabledPreferenceKey, + [NSNumber numberWithBool:YES], WebKitDatabasesEnabledPreferenceKey, + [NSNumber numberWithBool:YES], WebKitLocalStorageEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitAllowAnimatedImagesPreferenceKey, [NSNumber numberWithBool:YES], WebKitAllowAnimatedImageLoopingPreferenceKey, [NSNumber numberWithBool:YES], WebKitDisplayImagesKey, @@ -327,6 +329,12 @@ static WebCacheModel cacheModelForMainBundle(void) @"0", WebKitPDFScaleFactorPreferenceKey, @"0", WebKitUseSiteSpecificSpoofingPreferenceKey, [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey, +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + [NSNumber numberWithInt:WebTextDirectionSubmenuAutomaticallyIncluded], +#else + [NSNumber numberWithInt:WebTextDirectionSubmenuNeverIncluded], +#endif + WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey, [NSNumber numberWithBool:NO], WebKitDOMPasteAllowedPreferenceKey, [NSNumber numberWithBool:YES], WebKitUsesPageCachePreferenceKey, [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey, @@ -905,6 +913,23 @@ static WebCacheModel cacheModelForMainBundle(void) [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey]; } +- (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior +{ + WebTextDirectionSubmenuInclusionBehavior value = static_cast<WebTextDirectionSubmenuInclusionBehavior>([self _integerValueForKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]); + if (value != WebTextDirectionSubmenuNeverIncluded && + value != WebTextDirectionSubmenuAutomaticallyIncluded && + value != WebTextDirectionSubmenuAlwaysIncluded) { + // Ensure that a valid result is returned. + value = WebTextDirectionSubmenuNeverIncluded; + } + return value; +} + +- (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior +{ + [self _setIntegerValue:behavior forKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]; +} + - (BOOL)_useSiteSpecificSpoofing { return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey]; @@ -915,6 +940,26 @@ static WebCacheModel cacheModelForMainBundle(void) [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey]; } +- (BOOL)databasesEnabled +{ + return [self _boolValueForKey:WebKitDatabasesEnabledPreferenceKey]; +} + +- (void)setDatabasesEnabled:(BOOL)databasesEnabled +{ + [self _setBoolValue:databasesEnabled forKey:WebKitDatabasesEnabledPreferenceKey]; +} + +- (BOOL)localStorageEnabled +{ + return [self _boolValueForKey:WebKitLocalStorageEnabledPreferenceKey]; +} + +- (void)setLocalStorageEnabled:(BOOL)localStorageEnabled +{ + [self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey]; +} + + (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident { LOG(Encoding, "requesting for %@\n", ident); diff --git a/WebKit/mac/WebView/WebPreferencesPrivate.h b/WebKit/mac/WebView/WebPreferencesPrivate.h index 1981290..99ff49c 100644 --- a/WebKit/mac/WebView/WebPreferencesPrivate.h +++ b/WebKit/mac/WebView/WebPreferencesPrivate.h @@ -37,6 +37,12 @@ typedef enum { WebKitEditableLinkNeverLive } WebKitEditableLinkBehavior; +typedef enum { + WebTextDirectionSubmenuNeverIncluded, + WebTextDirectionSubmenuAutomaticallyIncluded, + WebTextDirectionSubmenuAlwaysIncluded +} WebTextDirectionSubmenuInclusionBehavior; + extern NSString *WebPreferencesChangedNotification; extern NSString *WebPreferencesRemovedNotification; @@ -77,6 +83,12 @@ extern NSString *WebPreferencesRemovedNotification; - (BOOL)offlineWebApplicationCacheEnabled; - (void)setOfflineWebApplicationCacheEnabled:(BOOL)offlineWebApplicationCacheEnabled; +- (BOOL)databasesEnabled; +- (void)setDatabasesEnabled:(BOOL)databasesEnabled; + +- (BOOL)localStorageEnabled; +- (void)setLocalStorageEnabled:(BOOL)localStorageEnabled; + - (BOOL)zoomsTextOnly; - (void)setZoomsTextOnly:(BOOL)zoomsTextOnly; @@ -87,6 +99,9 @@ extern NSString *WebPreferencesRemovedNotification; - (WebKitEditableLinkBehavior)editableLinkBehavior; - (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior; +- (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior; +- (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior; + // If site-specific spoofing is enabled, some pages that do inappropriate user-agent string checks will be // passed a nonstandard user-agent string to get them to work correctly. This method might be removed in // the future when there's no more need for it. diff --git a/WebKit/mac/WebView/WebRenderNode.mm b/WebKit/mac/WebView/WebRenderNode.mm index c34ac34..65ee13c 100644 --- a/WebKit/mac/WebView/WebRenderNode.mm +++ b/WebKit/mac/WebView/WebRenderNode.mm @@ -32,6 +32,7 @@ #import "WebFrameView.h" #import "WebHTMLView.h" #import <WebCore/Frame.h> +#import <WebCore/RenderText.h> #import <WebCore/RenderWidget.h> #import <WebCore/RenderView.h> #import <WebCore/Widget.h> @@ -86,10 +87,30 @@ static WebRenderNode *copyRenderNode(RenderObject* node) Widget* widget = renderWidget ? renderWidget->widget() : 0; NSView *view = widget ? widget->platformWidget() : nil; - int nx, ny; - node->absolutePosition(nx, ny); + // FIXME: broken with transforms + FloatPoint absPos = node->localToAbsolute(FloatPoint()); + int x = 0; + int y = 0; + int width = 0; + int height = 0; + if (node->isBox()) { + RenderBox* box = toRenderBox(node); + x = box->x(); + y = box->y(); + width = box->width(); + height = box->height(); + } else if (node->isText()) { + // FIXME: Preserve old behavior even though it's strange. + RenderText* text = toRenderText(node); + x = text->firstRunX(); + y = text->firstRunY(); + IntRect box = text->linesBoundingBox(); + width = box.width(); + height = box.height(); + } + WebRenderNode *result = [[WebRenderNode alloc] initWithName:name - position:NSMakePoint(nx, ny) rect:NSMakeRect(node->xPos(), node->yPos(), node->width(), node->height()) + position:absPos rect:NSMakeRect(x, y, width, height) view:view children:children]; [name release]; diff --git a/WebKit/mac/WebView/WebResource.mm b/WebKit/mac/WebView/WebResource.mm index 6e0c9f0..a5caa41 100644 --- a/WebKit/mac/WebView/WebResource.mm +++ b/WebKit/mac/WebView/WebResource.mm @@ -26,20 +26,23 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "WebResourcePrivate.h" +#import "WebResourceInternal.h" #import "WebFrameInternal.h" +#import "WebKitLogging.h" +#import "WebKitVersionChecks.h" #import "WebNSDictionaryExtras.h" +#import "WebNSObjectExtras.h" #import "WebNSURLExtras.h" - +#import <JavaScriptCore/InitializeThreading.h> +#import <JavaScriptCore/PassRefPtr.h> #import <WebCore/ArchiveResource.h> #import <WebCore/LegacyWebArchive.h> #import <WebCore/TextEncoding.h> +#import <WebCore/ThreadCheck.h> #import <WebCore/WebCoreObjCExtras.h> #import <WebCore/WebCoreURLResponse.h> -#import <wtf/PassRefPtr.h> - using namespace WebCore; static NSString * const WebResourceDataKey = @"WebResourceData"; @@ -49,25 +52,22 @@ static NSString * const WebResourceURLKey = @"WebResourceURL"; static NSString * const WebResourceTextEncodingNameKey = @"WebResourceTextEncodingName"; static NSString * const WebResourceResponseKey = @"WebResourceResponse"; -#define WebResourceVersion 1 - -@interface WebResourcePrivate : NSObject -{ +@interface WebResourcePrivate : NSObject { @public ArchiveResource* coreResource; } - - (id)initWithCoreResource:(PassRefPtr<ArchiveResource>)coreResource; @end @implementation WebResourcePrivate -#ifndef BUILDING_ON_TIGER + (void)initialize { + JSC::initializeThreading(); +#ifndef BUILDING_ON_TIGER WebCoreObjCFinalizeOnMainThread(self); -} #endif +} - (id)init { @@ -78,11 +78,9 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" { self = [super init]; if (!self) - return self; - + return nil; // Acquire the PassRefPtr<>'s ref as our own manual ref coreResource = passedResource.releaseRef(); - return self; } @@ -123,6 +121,8 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" - (id)initWithCoder:(NSCoder *)decoder { + WebCoreThreadViolationCheck(); + self = [super init]; if (!self) return nil; @@ -200,29 +200,78 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" - (NSData *)data { - if (_private->coreResource && _private->coreResource->data()) - return [_private->coreResource->data()->createNSData() autorelease]; - return 0; +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] data]; +#endif + + WebCoreThreadViolationCheck(); + + if (!_private->coreResource) + return nil; + if (!_private->coreResource->data()) + return nil; + return [_private->coreResource->data()->createNSData() autorelease]; } - (NSURL *)URL { - return _private->coreResource ? (NSURL *)_private->coreResource->url() : 0; +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] URL]; +#endif + + WebCoreThreadViolationCheck(); + + if (!_private->coreResource) + return nil; + NSURL *url = _private->coreResource->url(); + return url; } - (NSString *)MIMEType { - return _private->coreResource ? (NSString *)_private->coreResource->mimeType() : 0; +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] MIMEType]; +#endif + + WebCoreThreadViolationCheck(); + + if (!_private->coreResource) + return nil; + NSString *mimeType = _private->coreResource->mimeType(); + return mimeType; } - (NSString *)textEncodingName { - return _private->coreResource ? (NSString *)_private->coreResource->textEncoding() : 0; +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] textEncodingName]; +#endif + + WebCoreThreadViolationCheck(); + + if (!_private->coreResource) + return nil; + NSString *textEncodingName = _private->coreResource->textEncoding(); + return textEncodingName; } - (NSString *)frameName { - return _private->coreResource ? (NSString *)_private->coreResource->frameName() : 0; +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] frameName]; +#endif + + WebCoreThreadViolationCheck(); + + if (!_private->coreResource) + return nil; + NSString *frameName = _private->coreResource->frameName(); + return frameName; } - (id)description @@ -267,8 +316,18 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" // FIXME: This "ignoreWhenUnarchiving" concept is an ugly one - can we find a cleaner solution for those who need this SPI? - (void)_ignoreWhenUnarchiving { - if (_private->coreResource) - _private->coreResource->ignoreWhenUnarchiving(); +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) { + [[self _webkit_invokeOnMainThread] _ignoreWhenUnarchiving]; + return; + } +#endif + + WebCoreThreadViolationCheck(); + + if (!_private->coreResource) + return; + _private->coreResource->ignoreWhenUnarchiving(); } - (id)_initWithData:(NSData *)data @@ -279,6 +338,13 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" response:(NSURLResponse *)response copyData:(BOOL)copyData { +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] _initWithData:data URL:URL MIMEType:MIMEType textEncodingName:textEncodingName frameName:frameName response:response copyData:copyData]; +#endif + + WebCoreThreadViolationCheck(); + self = [super init]; if (!self) return nil; @@ -287,9 +353,9 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" [self release]; return nil; } - + _private = [[WebResourcePrivate alloc] initWithCoreResource:ArchiveResource::create(SharedBuffer::wrapNSData(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response)]; - + return self; } @@ -303,44 +369,81 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" textEncodingName:[response textEncodingName] frameName:nil response:response - copyData:NO]; + copyData:NO]; +} + +- (NSString *)_suggestedFilename +{ +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] _suggestedFilename]; +#endif + + WebCoreThreadViolationCheck(); + + if (!_private->coreResource) + return nil; + NSString *suggestedFilename = _private->coreResource->response().suggestedFilename(); + return suggestedFilename; } - (NSFileWrapper *)_fileWrapperRepresentation { - SharedBuffer* coreData = _private->coreResource ? _private->coreResource->data() : 0; - NSData *data = coreData ? [coreData->createNSData() autorelease] : nil; - - NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease]; - NSString *preferredFilename = _private->coreResource ? (NSString *)_private->coreResource->response().suggestedFilename() : nil; - if (!preferredFilename || ![preferredFilename length]) { - NSURL *url = _private->coreResource ? (NSURL *)_private->coreResource->url() : nil; - NSString *mimeType = _private->coreResource ? (NSString *)_private->coreResource->mimeType() : nil; - preferredFilename = [url _webkit_suggestedFilenameWithMIMEType:mimeType]; - } - - [wrapper setPreferredFilename:preferredFilename]; + NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[self data]] autorelease]; + NSString *filename = [self _suggestedFilename]; + if (!filename || ![filename length]) + filename = [[self URL] _webkit_suggestedFilenameWithMIMEType:[self MIMEType]]; + [wrapper setPreferredFilename:filename]; return wrapper; } - (NSURLResponse *)_response { +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] _response]; +#endif + + WebCoreThreadViolationCheck(); + NSURLResponse *response = nil; if (_private->coreResource) response = _private->coreResource->response().nsURLResponse(); - return response ? response : [[[NSURLResponse alloc] init] autorelease]; } - (NSString *)_stringValue { - WebCore::TextEncoding encoding(_private->coreResource ? (NSString *)_private->coreResource->textEncoding() : nil); +#ifdef MAIL_THREAD_WORKAROUND + if (needMailThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] _stringValue]; +#endif + + WebCoreThreadViolationCheck(); + + WebCore::TextEncoding encoding; + if (_private->coreResource) + encoding = _private->coreResource->textEncoding(); if (!encoding.isValid()) encoding = WindowsLatin1Encoding(); SharedBuffer* coreData = _private->coreResource ? _private->coreResource->data() : 0; - return encoding.decode(reinterpret_cast<const char*>(coreData ? coreData->data() : 0), coreData ? coreData->size() : 0); } @end + +#ifdef MAIL_THREAD_WORKAROUND + +@implementation WebResource (WebMailThreadWorkaround) + ++ (BOOL)_needMailThreadWorkaroundIfCalledOffMainThread +{ + static BOOL isOldMail = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_MAIL_THREAD_WORKAROUND) + && [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.mail"]; + return isOldMail; +} + +@end + +#endif diff --git a/WebKit/mac/WebView/WebResourceInternal.h b/WebKit/mac/WebView/WebResourceInternal.h index 84f6aba..d135197 100644 --- a/WebKit/mac/WebView/WebResourceInternal.h +++ b/WebKit/mac/WebView/WebResourceInternal.h @@ -26,17 +26,31 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "WebResource.h" - +#import "WebResourcePrivate.h" #import <wtf/PassRefPtr.h> +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) +#define MAIL_THREAD_WORKAROUND 1 +#endif + namespace WebCore { class ArchiveResource; } @interface WebResource (WebResourceInternal) +- (id)_initWithCoreResource:(PassRefPtr<WebCore::ArchiveResource>)coreResource; +- (WebCore::ArchiveResource*)_coreResource; +@end -- (id)_initWithCoreResource:(WTF::PassRefPtr<WebCore::ArchiveResource>)coreResource; -- (WebCore::ArchiveResource *)_coreResource; +#ifdef MAIL_THREAD_WORKAROUND +@interface WebResource (WebMailThreadWorkaround) ++ (BOOL)_needMailThreadWorkaroundIfCalledOffMainThread; @end + +inline bool needMailThreadWorkaround() +{ + return !pthread_main_np() && [WebResource _needMailThreadWorkaroundIfCalledOffMainThread]; +} + +#endif diff --git a/WebKit/mac/WebView/WebResourceLoadDelegatePrivate.h b/WebKit/mac/WebView/WebResourceLoadDelegatePrivate.h index 5fd13ee..6dc3f2d 100644 --- a/WebKit/mac/WebView/WebResourceLoadDelegatePrivate.h +++ b/WebKit/mac/WebView/WebResourceLoadDelegatePrivate.h @@ -41,6 +41,7 @@ @interface NSObject (WebResourceLoadDelegatePrivate) - (void)webView:(WebView *)webView didLoadResourceFromMemoryCache:(NSURLRequest *)request response:(NSURLResponse *)response length:(WebNSInteger)length fromDataSource:(WebDataSource *)dataSource; +- (BOOL)webView:(WebView *)webView resource:(id)identifier shouldUseCredentialStorageForDataSource:(WebDataSource *)dataSource; @end diff --git a/WebKit/mac/WebView/WebScriptDebugDelegate.h b/WebKit/mac/WebView/WebScriptDebugDelegate.h index fba48f6..7334127 100644 --- a/WebKit/mac/WebView/WebScriptDebugDelegate.h +++ b/WebKit/mac/WebView/WebScriptDebugDelegate.h @@ -34,6 +34,12 @@ #define WebNSUInteger NSUInteger #endif +#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. +#endif + @class WebView; @class WebFrame; @class WebScriptCallFrame; @@ -56,14 +62,14 @@ enum { // this delegate method is deprecated, please switch to the new version below - (void)webView:(WebView *)webView didParseSource:(NSString *)source fromURL:(NSString *)url - sourceId:(int)sid + sourceId:(WebSourceId)sid forWebFrame:(WebFrame *)webFrame; // some source was parsed, establishing a "source ID" (>= 0) for future reference - (void)webView:(WebView *)webView didParseSource:(NSString *)source baseLineNumber:(WebNSUInteger)lineNumber fromURL:(NSURL *)url - sourceId:(int)sid + sourceId:(WebSourceId)sid forWebFrame:(WebFrame *)webFrame; // some source failed to parse @@ -75,25 +81,25 @@ enum { // just entered a stack frame (i.e. called a function, or started global scope) - (void)webView:(WebView *)webView didEnterCallFrame:(WebScriptCallFrame *)frame - sourceId:(int)sid + sourceId:(WebSourceId)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame; // about to execute some code - (void)webView:(WebView *)webView willExecuteStatement:(WebScriptCallFrame *)frame - sourceId:(int)sid + sourceId:(WebSourceId)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame; // about to leave a stack frame (i.e. return from a function) - (void)webView:(WebView *)webView willLeaveCallFrame:(WebScriptCallFrame *)frame - sourceId:(int)sid + sourceId:(WebSourceId)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame; // exception is being thrown - (void)webView:(WebView *)webView exceptionWasRaised:(WebScriptCallFrame *)frame - sourceId:(int)sid + sourceId:(WebSourceId)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame; @end @@ -135,3 +141,4 @@ enum { @end #undef WebNSUInteger + diff --git a/WebKit/mac/WebView/WebScriptDebugDelegate.mm b/WebKit/mac/WebView/WebScriptDebugDelegate.mm index be0a0d5..0b47e26 100644 --- a/WebKit/mac/WebView/WebScriptDebugDelegate.mm +++ b/WebKit/mac/WebView/WebScriptDebugDelegate.mm @@ -26,22 +26,24 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "WebScriptDebugger.h" #import "WebDataSource.h" #import "WebDataSourceInternal.h" #import "WebFrameInternal.h" #import "WebScriptDebugDelegate.h" +#import "WebScriptDebugger.h" #import "WebViewInternal.h" -#import <debugger/DebuggerCallFrame.h> -#import <runtime/ExecState.h> -#import <runtime/JSGlobalObject.h> -#import <runtime/JSFunction.h> -#import <runtime/JSLock.h> -#import <kjs/interpreter.h> #import <WebCore/Frame.h> -#import <WebCore/WebScriptObjectPrivate.h> #import <WebCore/ScriptController.h> +#import <WebCore/WebScriptObjectPrivate.h> #import <WebCore/runtime_root.h> +#import <debugger/Debugger.h> +#import <debugger/DebuggerActivation.h> +#import <debugger/DebuggerCallFrame.h> +#import <interpreter/CallFrame.h> +#import <runtime/Completion.h> +#import <runtime/JSFunction.h> +#import <runtime/JSGlobalObject.h> +#import <runtime/JSLock.h> using namespace JSC; using namespace WebCore; @@ -53,7 +55,7 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; @interface WebScriptCallFrame (WebScriptDebugDelegateInternal) -- (id)_convertValueToObjcValue:(JSValue*)value; +- (id)_convertValueToObjcValue:(JSValuePtr)value; @end @@ -62,6 +64,7 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; WebScriptObject *globalObject; // the global object's proxy (not retained) WebScriptCallFrame *caller; // previous stack frame DebuggerCallFrame* debuggerCallFrame; + WebScriptDebugger* debugger; } @end @@ -85,12 +88,13 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; @implementation WebScriptCallFrame (WebScriptDebugDelegateInternal) -- (WebScriptCallFrame *)_initWithGlobalObject:(WebScriptObject *)globalObj caller:(WebScriptCallFrame *)caller debuggerCallFrame:(const DebuggerCallFrame&)debuggerCallFrame +- (WebScriptCallFrame *)_initWithGlobalObject:(WebScriptObject *)globalObj debugger:(WebScriptDebugger *)debugger caller:(WebScriptCallFrame *)caller debuggerCallFrame:(const DebuggerCallFrame&)debuggerCallFrame { if ((self = [super init])) { _private = [[WebScriptCallFramePrivate alloc] init]; _private->globalObject = globalObj; _private->caller = [caller retain]; + _private->debugger = debugger; } return self; } @@ -109,7 +113,7 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; _private->debuggerCallFrame = 0; } -- (id)_convertValueToObjcValue:(JSValue*)value +- (id)_convertValueToObjcValue:(JSValuePtr)value { if (!value) return nil; @@ -177,8 +181,12 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; NSMutableArray *scopes = [[NSMutableArray alloc] init]; ScopeChainIterator end = scopeChain->end(); - for (ScopeChainIterator it = scopeChain->begin(); it != end; ++it) - [scopes addObject:[self _convertValueToObjcValue:(*it)]]; + for (ScopeChainIterator it = scopeChain->begin(); it != end; ++it) { + JSObject* object = *it; + if (object->isActivationObject()) + object = new (scopeChain->globalData) DebuggerActivation(object); + [scopes addObject:[self _convertValueToObjcValue:object]]; + } NSArray *result = [NSArray arrayWithArray:scopes]; [scopes release]; @@ -204,7 +212,7 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; if (!_private->debuggerCallFrame) return nil; - JSValue* exception = _private->debuggerCallFrame->exception(); + JSValuePtr exception = _private->debuggerCallFrame->exception(); return exception ? [self _convertValueToObjcValue:exception] : nil; } @@ -221,8 +229,25 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; JSLock lock(false); - JSValue* exception = noValue(); - JSValue* result = _private->debuggerCallFrame->evaluate(String(script), exception); + // If this is the global call frame and there is no dynamic global object, + // Dashcode is attempting to execute JS in the evaluator using a stale + // WebScriptCallFrame. Instead, we need to set the dynamic global object + // and evaluate the JS in the global object's global call frame. + JSGlobalObject* globalObject = _private->debugger->globalObject(); + if (self == _private->debugger->globalCallFrame() && !globalObject->globalData()->dynamicGlobalObject) { + JSGlobalObject* globalObject = _private->debugger->globalObject(); + + DynamicGlobalObjectScope globalObjectScope(globalObject->globalExec(), globalObject); + + JSValuePtr exception = noValue(); + JSValuePtr result = evaluateInGlobalCallFrame(String(script), exception, globalObject); + if (exception) + return [self _convertValueToObjcValue:exception]; + return result ? [self _convertValueToObjcValue:result] : nil; + } + + JSValuePtr exception = noValue(); + JSValuePtr result = _private->debuggerCallFrame->evaluate(String(script), exception); if (exception) return [self _convertValueToObjcValue:exception]; return result ? [self _convertValueToObjcValue:result] : nil; diff --git a/WebKit/mac/WebView/WebScriptDebugger.h b/WebKit/mac/WebView/WebScriptDebugger.h index caec994..1213ab2 100644 --- a/WebKit/mac/WebView/WebScriptDebugger.h +++ b/WebKit/mac/WebView/WebScriptDebugger.h @@ -30,6 +30,7 @@ #define WebScriptDebugger_h #include <debugger/Debugger.h> +#include <runtime/Protect.h> #include <wtf/RetainPtr.h> @@ -50,6 +51,8 @@ class WebScriptDebugger : public JSC::Debugger { public: WebScriptDebugger(JSC::JSGlobalObject*); + void initGlobalCallFrame(const JSC::DebuggerCallFrame&); + virtual void sourceParsed(JSC::ExecState*, const JSC::SourceCode&, int errorLine, const JSC::UString& errorMsg); virtual void callEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber); virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber); @@ -59,9 +62,15 @@ public: virtual void didExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno); virtual void didReachBreakpoint(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno); + JSC::JSGlobalObject* globalObject() const { return m_globalObject.get(); } + WebScriptCallFrame *globalCallFrame() const { return m_globalCallFrame.get(); } + private: bool m_callingDelegate; RetainPtr<WebScriptCallFrame> m_topCallFrame; + + JSC::ProtectedPtr<JSC::JSGlobalObject> m_globalObject; + RetainPtr<WebScriptCallFrame> m_globalCallFrame; }; #endif // WebScriptDebugger_h diff --git a/WebKit/mac/WebView/WebScriptDebugger.mm b/WebKit/mac/WebView/WebScriptDebugger.mm index 0dd6b0e..d97cbcf 100644 --- a/WebKit/mac/WebView/WebScriptDebugger.mm +++ b/WebKit/mac/WebView/WebScriptDebugger.mm @@ -43,7 +43,7 @@ using namespace JSC; using namespace WebCore; @interface WebScriptCallFrame (WebScriptDebugDelegateInternal) -- (WebScriptCallFrame *)_initWithGlobalObject:(WebScriptObject *)globalObj caller:(WebScriptCallFrame *)caller debuggerCallFrame:(const DebuggerCallFrame&)debuggerCallFrame; +- (WebScriptCallFrame *)_initWithGlobalObject:(WebScriptObject *)globalObj debugger:(WebScriptDebugger *)debugger caller:(WebScriptCallFrame *)caller debuggerCallFrame:(const DebuggerCallFrame&)debuggerCallFrame; - (void)_setDebuggerCallFrame:(const DebuggerCallFrame&)debuggerCallFrame; - (void)_clearDebuggerCallFrame; @end @@ -55,7 +55,7 @@ NSString *toNSString(const UString& s) return [NSString stringWithCharacters:reinterpret_cast<const unichar*>(s.data()) length:s.size()]; } -NSString *toNSString(const SourceCode& s) +static NSString *toNSString(const SourceCode& s) { if (!s.length()) return nil; @@ -78,9 +78,25 @@ static WebFrame *toWebFrame(JSGlobalObject* globalObject) WebScriptDebugger::WebScriptDebugger(JSGlobalObject* globalObject) : m_callingDelegate(false) + , m_globalObject(globalObject) { attach(globalObject); - callEvent(globalObject->globalExec(), 0, -1); + initGlobalCallFrame(globalObject->globalExec()); +} + +void WebScriptDebugger::initGlobalCallFrame(const DebuggerCallFrame& debuggerCallFrame) +{ + m_callingDelegate = true; + + WebFrame *webFrame = toWebFrame(debuggerCallFrame.dynamicGlobalObject()); + + m_topCallFrame.adoptNS([[WebScriptCallFrame alloc] _initWithGlobalObject:core(webFrame)->script()->windowScriptObject() debugger:this caller:m_topCallFrame.get() debuggerCallFrame:debuggerCallFrame]); + 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]; + + m_callingDelegate = false; } // callbacks - relay to delegate @@ -97,8 +113,8 @@ void WebScriptDebugger::sourceParsed(ExecState* exec, const SourceCode& source, WebFrame *webFrame = toWebFrame(exec->dynamicGlobalObject()); WebView *webView = [webFrame webView]; if (errorLine == -1) { - [[webView _scriptDebugDelegateForwarder] webView:webView didParseSource:nsSource baseLineNumber:source.firstLine() fromURL:nsURL sourceId:static_cast<int>(source.provider()->asID()) forWebFrame:webFrame]; - [[webView _scriptDebugDelegateForwarder] webView:webView didParseSource:nsSource fromURL:[nsURL absoluteString] sourceId:static_cast<int>(source.provider()->asID()) forWebFrame:webFrame]; // deprecated delegate method + [[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 } else { NSString* nsErrorMessage = toNSString(errorMsg); NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:nsErrorMessage, WebScriptErrorDescriptionKey, [NSNumber numberWithUnsignedInt:errorLine], WebScriptErrorLineNumberKey, nil]; @@ -120,10 +136,10 @@ void WebScriptDebugger::callEvent(const DebuggerCallFrame& debuggerCallFrame, in WebFrame *webFrame = toWebFrame(debuggerCallFrame.dynamicGlobalObject()); - m_topCallFrame.adoptNS([[WebScriptCallFrame alloc] _initWithGlobalObject:core(webFrame)->script()->windowScriptObject() caller:m_topCallFrame.get() debuggerCallFrame:debuggerCallFrame]); + 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<int>(sourceID) line:lineNumber forWebFrame:webFrame]; + [[webView _scriptDebugDelegateForwarder] webView:webView didEnterCallFrame:m_topCallFrame.get() sourceId:static_cast<WebSourceId>(sourceID) line:lineNumber forWebFrame:webFrame]; m_callingDelegate = false; } @@ -139,7 +155,7 @@ 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<int>(sourceID) line:lineNumber forWebFrame:webFrame]; + [[webView _scriptDebugDelegateForwarder] webView:webView willExecuteStatement:m_topCallFrame.get() sourceId:static_cast<WebSourceId>(sourceID) line:lineNumber forWebFrame:webFrame]; m_callingDelegate = false; } @@ -155,7 +171,7 @@ 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<int>(sourceID) line:lineNumber forWebFrame:webFrame]; + [[webView _scriptDebugDelegateForwarder] webView:webView willLeaveCallFrame:m_topCallFrame.get() sourceId:static_cast<WebSourceId>(sourceID) line:lineNumber forWebFrame:webFrame]; [m_topCallFrame.get() _clearDebuggerCallFrame]; m_topCallFrame = [m_topCallFrame.get() caller]; @@ -174,7 +190,7 @@ 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<int>(sourceID) line:lineNumber forWebFrame:webFrame]; + [[webView _scriptDebugDelegateForwarder] webView:webView exceptionWasRaised:m_topCallFrame.get() sourceId:static_cast<WebSourceId>(sourceID) line:lineNumber forWebFrame:webFrame]; m_callingDelegate = false; } diff --git a/WebKit/mac/WebView/WebTextIterator.h b/WebKit/mac/WebView/WebTextIterator.h index e6f77ac..ab5ca4e 100644 --- a/WebKit/mac/WebView/WebTextIterator.h +++ b/WebKit/mac/WebView/WebTextIterator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 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 @@ -25,13 +25,17 @@ #import <Foundation/Foundation.h> +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 +#define WebNSUInteger unsigned int +#else +#define WebNSUInteger NSUInteger +#endif @class DOMRange; @class DOMNode; @class WebTextIteratorPrivate; -@interface WebTextIterator : NSObject -{ +@interface WebTextIterator : NSObject { @private WebTextIteratorPrivate *_private; } @@ -39,28 +43,53 @@ - (id)initWithRange:(DOMRange *)range; /*! - @method advance: + @method advance @abstract Makes the WebTextIterator iterate to the next visible text element. */ - (void)advance; /*! - @method currentNode: - @result The current DOMNode in the WebTextIterator. + @method atEnd + @result YES if the WebTextIterator has reached the end of the DOMRange. */ -- (DOMNode *)currentNode; +- (BOOL)atEnd; /*! - @method currentText: - @result The current text in the WebTextIterator. + @method currentRange + @result A range, indicating the position within the document of the current text. */ -- (NSString *)currentText; +- (DOMRange *)currentRange; /*! - @method atEnd: - @result YES if the WebTextIterator has reached the end of the DOMRange. + @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. */ -- (BOOL)atEnd; +- (const unichar *)currentTextPointer; + +/*! + @method currentTextLength + @result lengthPtr Length of the current text. + */ +- (WebNSUInteger)currentTextLength; + +@end + +@interface WebTextIterator (WebTextIteratorDeprecated) +/*! + @method currentNode + @abstract A convenience method that finds the first node in currentRange; it's almost always better to use currentRange instead. + @result The current DOMNode in the WebTextIterator + */ +- (DOMNode *)currentNode; + +/*! + @method currentText + @abstract A convenience method that makes an NSString out of the current text; it's almost always better to use currentTextPointer and currentTextLength instead. + @result The current text in the WebTextIterator. + */ +- (NSString *)currentText; @end + +#undef WebNSUInteger diff --git a/WebKit/mac/WebView/WebTextIterator.mm b/WebKit/mac/WebView/WebTextIterator.mm index 86db6d3..15eeb5f 100644 --- a/WebKit/mac/WebView/WebTextIterator.mm +++ b/WebKit/mac/WebView/WebTextIterator.mm @@ -27,30 +27,27 @@ #import "DOMNodeInternal.h" #import "DOMRangeInternal.h" +#import "WebTypesInternal.h" +#import <JavaScriptCore/Vector.h> #import <WebCore/TextIterator.h> -#import <wtf/Vector.h> +#import <WebCore/WebCoreObjCExtras.h> +using namespace JSC; using namespace WebCore; -@interface WebTextIteratorPrivate : NSObject -{ +@interface WebTextIteratorPrivate : NSObject { @public - TextIterator* m_textIterator; + OwnPtr<TextIterator> _textIterator; } @end @implementation WebTextIteratorPrivate -- (void)dealloc -{ - delete m_textIterator; - [super dealloc]; -} - -- (void)finalize ++ (void)initialize { - delete m_textIterator; - [super finalize]; +#ifndef BUILDING_ON_TIGER + WebCoreObjCFinalizeOnMainThread(self); +#endif } @end @@ -70,39 +67,47 @@ using namespace WebCore; return self; _private = [[WebTextIteratorPrivate alloc] init]; - _private->m_textIterator = new TextIterator([range _range], true, false); + _private->_textIterator.set(new TextIterator([range _range], true, false)); return self; } - (void)advance { - ASSERT(_private->m_textIterator); - - if (_private->m_textIterator->atEnd()) - return; - - _private->m_textIterator->advance(); + _private->_textIterator->advance(); } -- (DOMNode *)currentNode +- (BOOL)atEnd { - ASSERT(_private->m_textIterator); - - return [DOMNode _wrapNode:_private->m_textIterator->node()]; + return _private->_textIterator->atEnd(); } -- (NSString *)currentText +- (DOMRange *)currentRange { - ASSERT(_private->m_textIterator); - - return [NSString stringWithCharacters:_private->m_textIterator->characters() length:_private->m_textIterator->length()]; + return [DOMRange _wrapRange:_private->_textIterator->range().get()]; } -- (BOOL)atEnd +- (const unichar *)currentTextPointer { - ASSERT(_private->m_textIterator); - - return _private->m_textIterator->atEnd(); + return _private->_textIterator->characters(); +} + +- (NSUInteger)currentTextLength +{ + return _private->_textIterator->length(); +} + +@end + +@implementation WebTextIterator (WebTextIteratorDeprecated) + +- (DOMNode *)currentNode +{ + return [DOMNode _wrapNode:_private->_textIterator->node()]; +} + +- (NSString *)currentText +{ + return [NSString stringWithCharacters:_private->_textIterator->characters() length:_private->_textIterator->length()]; } @end diff --git a/WebKit/mac/WebView/WebUIDelegatePrivate.h b/WebKit/mac/WebView/WebUIDelegatePrivate.h index 6a3c32f..bb4d780 100644 --- a/WebKit/mac/WebView/WebUIDelegatePrivate.h +++ b/WebKit/mac/WebView/WebUIDelegatePrivate.h @@ -68,6 +68,10 @@ enum { WebMenuItemPDFSinglePageScrolling, WebMenuItemPDFFacingPagesScrolling, WebMenuItemTagInspectElement, + WebMenuItemTagTextDirectionMenu, + WebMenuItemTagTextDirectionDefault, + WebMenuItemTagTextDirectionLeftToRight, + WebMenuItemTagTextDirectionRightToLeft, WebMenuItemTagBaseApplication = 10000 }; @class WebSecurityOrigin; diff --git a/WebKit/mac/WebView/WebView.h b/WebKit/mac/WebView/WebView.h index 30aa7bd..17efb5e 100644 --- a/WebKit/mac/WebView/WebView.h +++ b/WebKit/mac/WebView/WebView.h @@ -670,6 +670,7 @@ extern NSString *WebViewProgressFinishedNotification; - (IBAction)takeStringURLFrom:(id)sender; - (IBAction)stopLoading:(id)sender; - (IBAction)reload:(id)sender; +- (IBAction)reloadFromOrigin:(id)sender; - (BOOL)canGoBack; - (IBAction)goBack:(id)sender; - (BOOL)canGoForward; diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm index a52d3b5..d3bbf4e 100644 --- a/WebKit/mac/WebView/WebView.mm +++ b/WebKit/mac/WebView/WebView.mm @@ -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. * Copyright (C) 2006 David Smith (catfish.man@gmail.com) * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ #import "DOMRangeInternal.h" #import "WebBackForwardListInternal.h" -#import "WebBaseNetscapePluginView.h" +#import "WebCache.h" #import "WebChromeClient.h" #import "WebContextMenuClient.h" #import "WebDOMOperationsPrivate.h" @@ -107,6 +107,7 @@ #import <WebCore/GCController.h> #import <WebCore/HTMLNames.h> #import <WebCore/HistoryItem.h> +#import <WebCore/IconDatabase.h> #import <WebCore/Logging.h> #import <WebCore/MIMETypeRegistry.h> #import <WebCore/Page.h> @@ -115,9 +116,11 @@ #import <WebCore/PlatformMouseEvent.h> #import <WebCore/ProgressTracker.h> #import <WebCore/ScriptController.h> +#import <WebCore/ScriptValue.h> #import <WebCore/SelectionController.h> #import <WebCore/Settings.h> #import <WebCore/TextResourceDecoder.h> +#import <WebCore/ThreadCheck.h> #import <WebCore/WebCoreObjCExtras.h> #import <WebCore/WebCoreTextRenderer.h> #import <WebCore/WebCoreView.h> @@ -129,13 +132,16 @@ #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> #import <wtf/RefPtr.h> +#import <wtf/StdLibExtras.h> #if ENABLE(DASHBOARD_SUPPORT) #import <WebKit/WebDashboardRegion.h> @@ -193,6 +199,11 @@ macro(insertParagraphSeparator) \ macro(insertTab) \ macro(insertTabIgnoringFieldEditor) \ macro(lowercaseWord) \ +macro(makeBaseWritingDirectionLeftToRight) \ +macro(makeBaseWritingDirectionRightToLeft) \ +macro(makeTextWritingDirectionLeftToRight) \ +macro(makeTextWritingDirectionNatural) \ +macro(makeTextWritingDirectionRightToLeft) \ macro(moveBackward) \ macro(moveBackwardAndModifySelection) \ macro(moveDown) \ @@ -337,7 +348,6 @@ static const char webViewIsOpen[] = "At least one WebView is still open."; BOOL allowsUndo; float zoomMultiplier; - BOOL zoomMultiplierIsTextOnly; NSString *applicationNameForUserAgent; String userAgent; @@ -375,6 +385,7 @@ static const char webViewIsOpen[] = "At least one WebView is still open."; NSInteger spellCheckerDocumentTag; BOOL smartInsertDeleteEnabled; + BOOL selectTrailingWhitespaceEnabled; #if ENABLE(DASHBOARD_SUPPORT) BOOL dashboardBehaviorAlwaysSendMouseEventsToAllWindows; @@ -411,6 +422,8 @@ static const char webViewIsOpen[] = "At least one WebView is still open."; @interface WebView (WebCallDelegateFunctions) @end +static void patchMailRemoveAttributesMethod(); + NSString *WebElementDOMNodeKey = @"WebElementDOMNode"; NSString *WebElementFrameKey = @"WebElementFrame"; NSString *WebElementImageKey = @"WebElementImage"; @@ -470,12 +483,13 @@ static BOOL grammarCheckingEnabled; @implementation WebViewPrivate -#ifndef BUILDING_ON_TIGER + (void)initialize { + JSC::initializeThreading(); +#ifndef BUILDING_ON_TIGER WebCoreObjCFinalizeOnMainThread(self); -} #endif +} - init { @@ -485,7 +499,6 @@ static BOOL grammarCheckingEnabled; JSC::initializeThreading(); allowsUndo = YES; zoomMultiplier = 1; - zoomMultiplierIsTextOnly = YES; #if ENABLE(DASHBOARD_SUPPORT) dashboardBehaviorAllowWheelScrolling = YES; #endif @@ -665,6 +678,8 @@ static void WebKitInitializeApplicationCachePathIfNecessary() - (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews { + WebCoreThreadViolationCheck(); + #ifndef NDEBUG WTF::RefCountedLeakCounter::suppressMessages(webViewIsOpen); #endif @@ -689,12 +704,17 @@ static void WebKitInitializeApplicationCachePathIfNecessary() [frameView release]; } - WebKitInitializeLoggingChannelsIfNecessary(); - WebCore::InitializeLoggingChannelsIfNecessary(); - [WebHistoryItem initWindowWatcherIfNecessary]; - WebKitInitializeDatabasesIfNecessary(); - WebKitInitializeApplicationCachePathIfNecessary(); - + static bool didOneTimeInitialization = false; + if (!didOneTimeInitialization) { + WebKitInitializeLoggingChannelsIfNecessary(); + WebCore::InitializeLoggingChannelsIfNecessary(); + [WebHistoryItem initWindowWatcherIfNecessary]; + WebKitInitializeDatabasesIfNecessary(); + WebKitInitializeApplicationCachePathIfNecessary(); + patchMailRemoveAttributesMethod(); + didOneTimeInitialization = true; + } + _private->page = new Page(new WebChromeClient(self), new WebContextMenuClient(self), new WebEditorClient(self), new WebDragClient(self), new WebInspectorClient(self)); _private->page->settings()->setLocalStorageDatabasePath([[self preferences] _localStorageDatabasePath]); @@ -1067,8 +1087,10 @@ static void WebKitInitializeApplicationCachePathIfNecessary() #ifndef NDEBUG // Need this to make leak messages accurate. - if (applicationIsTerminating) + if (applicationIsTerminating) { gcController().garbageCollectNow(); + [WebCache empty]; + } #endif } @@ -1285,6 +1307,8 @@ static void WebKitInitializeApplicationCachePathIfNecessary() settings->setMinimumFontSize([preferences minimumFontSize]); settings->setMinimumLogicalFontSize([preferences minimumLogicalFontSize]); settings->setPluginsEnabled([preferences arePlugInsEnabled]); + settings->setDatabasesEnabled([preferences databasesEnabled]); + settings->setLocalStorageEnabled([preferences localStorageEnabled]); settings->setPrivateBrowsingEnabled([preferences privateBrowsingEnabled]); settings->setSansSerifFontFamily([preferences sansSerifFontFamily]); settings->setSerifFontFamily([preferences serifFontFamily]); @@ -1294,6 +1318,7 @@ static void WebKitInitializeApplicationCachePathIfNecessary() settings->setTextAreasAreResizable([preferences textAreasAreResizable]); settings->setShrinksStandaloneImagesToFit([preferences shrinksStandaloneImagesToFit]); settings->setEditableLinkBehavior(core([preferences editableLinkBehavior])); + settings->setTextDirectionSubmenuInclusionBehavior(core([preferences textDirectionSubmenuInclusionBehavior])); settings->setDOMPasteAllowed([preferences isDOMPasteAllowed]); settings->setUsesPageCache([self usesPageCache]); settings->setShowsURLsInToolTips([preferences showsURLsInToolTips]); @@ -1313,6 +1338,9 @@ static void WebKitInitializeApplicationCachePathIfNecessary() 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) @@ -1341,6 +1369,7 @@ static inline IMP getMethod(id o, SEL s) cache->plugInFailedWithErrorFunc = getMethod(delegate, @selector(webView:plugInFailedWithError:dataSource:)); cache->willCacheResponseFunc = getMethod(delegate, @selector(webView:resource:willCacheResponse:fromDataSource:)); cache->willSendRequestFunc = getMethod(delegate, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)); + cache->shouldUseCredentialStorageFunc = getMethod(delegate, @selector(webView:resource:shouldUseCredentialStorageForDataSource:)); } WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *webView) @@ -1370,6 +1399,7 @@ WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementa cache->didFinishDocumentLoadForFrameFunc = getMethod(delegate, @selector(webView:didFinishDocumentLoadForFrame:)); cache->didFinishLoadForFrameFunc = getMethod(delegate, @selector(webView:didFinishLoadForFrame:)); cache->didFirstLayoutInFrameFunc = getMethod(delegate, @selector(webView:didFirstLayoutInFrame:)); + cache->didFirstVisuallyNonEmptyLayoutInFrameFunc = getMethod(delegate, @selector(webView:didFirstVisuallyNonEmptyLayoutInFrame:)); cache->didHandleOnloadEventsForFrameFunc = getMethod(delegate, @selector(webView:didHandleOnloadEventsForFrame:)); cache->didReceiveIconForFrameFunc = getMethod(delegate, @selector(webView:didReceiveIcon:forFrame:)); cache->didReceiveServerRedirectForProvisionalLoadForFrameFunc = getMethod(delegate, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:)); @@ -1948,6 +1978,13 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati [[self preferences] _postPreferencesChangesNotification]; } +- (WebHistoryItem *)_globalHistoryItem +{ + if (!_private->page) + return nil; + return kit(_private->page->globalHistoryItem()); +} + - (WebTextIterator *)textIteratorForRect:(NSRect)rect { IntPoint rectStart(rect.origin.x, rect.origin.y); @@ -2012,6 +2049,28 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati _private->page->mainFrame()->tree()->clearName(); } +- (void)setSelectTrailingWhitespaceEnabled:(BOOL)flag +{ + _private->selectTrailingWhitespaceEnabled = flag; + if (flag) + [self setSmartInsertDeleteEnabled:false]; +} + +- (BOOL)isSelectTrailingWhitespaceEnabled +{ + return _private->selectTrailingWhitespaceEnabled; +} + +- (void)setMemoryCacheDelegateCallsEnabled:(BOOL)enabled +{ + _private->page->setMemoryCacheClientCallsEnabled(enabled); +} + +- (BOOL)areMemoryCacheDelegateCallsEnabled +{ + return _private->page->areMemoryCacheClientCallsEnabled(); +} + @end @implementation _WebSafeForwarder @@ -2192,6 +2251,30 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati FrameLoader::registerURLSchemeAsLocal(protocol); } +- (id)_initWithArguments:(NSDictionary *) arguments +{ + NSCoder *decoder = [arguments objectForKey:@"decoder"]; + if (decoder) { + self = [self initWithCoder:decoder]; + } else { + ASSERT([arguments objectForKey:@"frame"]); + NSValue *frameValue = [arguments objectForKey:@"frame"]; + NSRect frame = (frameValue ? [frameValue rectValue] : NSZeroRect); + NSString *frameName = [arguments objectForKey:@"frameName"]; + NSString *groupName = [arguments objectForKey:@"groupName"]; + self = [self initWithFrame:frame frameName:frameName groupName:groupName]; + } + + return self; +} + +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(); +} + - (id)initWithFrame:(NSRect)f { return [self initWithFrame:f frameName:nil groupName:nil]; @@ -2199,11 +2282,19 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (id)initWithFrame:(NSRect)f frameName:(NSString *)frameName groupName:(NSString *)groupName { + if (needsWebViewInitThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] initWithFrame:f frameName:frameName groupName:groupName]; + + WebCoreThreadViolationCheck(); return [self _initWithFrame:f frameName:frameName groupName:groupName usesDocumentViews:YES]; } - (id)initWithCoder:(NSCoder *)decoder { + if (needsWebViewInitThreadWorkaround()) + return [[self _webkit_invokeOnMainThread] initWithCoder:decoder]; + + WebCoreThreadViolationCheck(); WebView *result = nil; @try { @@ -2447,7 +2538,10 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati BOOL windowIsKey = [window isKeyWindow]; BOOL windowOrSheetIsKey = windowIsKey || [[window attachedSheet] isKeyWindow]; - page->focusController()->setActive(windowIsKey); + NSResponder *firstResponder = [window firstResponder]; + if ([firstResponder isKindOfClass:[NSView class]] + && [(NSView*)firstResponder isDescendantOf:[[self mainFrame] frameView]]) + page->focusController()->setActive(windowIsKey); Frame* focusedFrame = page->focusController()->focusedOrMainFrame(); frame->selection()->setFocused(frame == focusedFrame && windowOrSheetIsKey); @@ -2661,14 +2755,19 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (float)textSizeMultiplier { - return _private->zoomMultiplierIsTextOnly ? _private->zoomMultiplier : 1.0f; + return [self _realZoomMultiplierIsTextOnly] ? _private->zoomMultiplier : 1.0f; } - (void)_setZoomMultiplier:(float)m isTextOnly:(BOOL)isTextOnly { // NOTE: This has no visible effect when viewing a PDF (see <rdar://problem/4737380>) _private->zoomMultiplier = m; - _private->zoomMultiplierIsTextOnly = isTextOnly; + ASSERT(_private->page); + if (_private->page) + _private->page->settings()->setZoomsTextOnly(isTextOnly); + + // FIXME: it would be nice to rework this code so that _private->zoomMultiplier doesn't exist and callers + // all access _private->page->settings(). Frame* coreFrame = core([self mainFrame]); if (coreFrame) coreFrame->setZoomFactor(m, isTextOnly); @@ -2676,7 +2775,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (float)_zoomMultiplier:(BOOL)isTextOnly { - if (isTextOnly != _private->zoomMultiplierIsTextOnly) + if (isTextOnly != [self _realZoomMultiplierIsTextOnly]) return 1.0f; return _private->zoomMultiplier; } @@ -2688,7 +2787,10 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (BOOL)_realZoomMultiplierIsTextOnly { - return _private->zoomMultiplierIsTextOnly; + if (!_private->page) + return NO; + + return _private->page->settings()->zoomsTextOnly(); } #define MinimumZoomMultiplier 0.5f @@ -2825,7 +2927,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati if (encoding == oldEncoding || [encoding isEqualToString:oldEncoding]) return; if (Frame* mainFrame = core([self mainFrame])) - mainFrame->loader()->reloadAllowingStaleData(encoding); + mainFrame->loader()->reloadWithOverrideEncoding(encoding); } - (NSString *)_mainFrameOverrideEncoding @@ -3223,7 +3325,9 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) - (BOOL)drawsBackground { - return _private->drawsBackground; + // This method can be called beneath -[NSView dealloc] after we have cleared _private, + // indirectly via -[WebFrameView viewDidMoveToWindow]. + return !_private || _private->drawsBackground; } - (void)setShouldUpdateWhileOffscreen:(BOOL)updateWhileOffscreen @@ -3298,6 +3402,11 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) [[self mainFrame] reload]; } +- (IBAction)reloadFromOrigin:(id)sender +{ + [[self mainFrame] reloadFromOrigin]; +} + // FIXME: This code should move into WebCore so that it is not duplicated in each WebKit. // (This includes canMakeTextSmaller/Larger, makeTextSmaller/Larger, and canMakeTextStandardSize/makeTextStandardSize) - (BOOL)canMakeTextSmaller @@ -3572,22 +3681,22 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) return coreFrame->shouldClose(); } -static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsValue) +static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValuePtr jsValue) { NSAppleEventDescriptor* aeDesc = 0; - if (jsValue->isBoolean()) - return [NSAppleEventDescriptor descriptorWithBoolean:jsValue->getBoolean()]; - if (jsValue->isString()) - return [NSAppleEventDescriptor descriptorWithString:String(jsValue->getString())]; - if (jsValue->isNumber()) { - double value = jsValue->getNumber(); + if (jsValue.isBoolean()) + return [NSAppleEventDescriptor descriptorWithBoolean:jsValue.getBoolean()]; + if (jsValue.isString()) + return [NSAppleEventDescriptor descriptorWithString:String(jsValue.getString())]; + if (jsValue.isNumber()) { + double value = jsValue.uncheckedGetNumber(); int intValue = value; if (value == intValue) return [NSAppleEventDescriptor descriptorWithDescriptorType:typeSInt32 bytes:&intValue length:sizeof(intValue)]; return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE64BitFloatingPoint bytes:&value length:sizeof(value)]; } - if (jsValue->isObject()) { - JSObject* object = jsValue->getObject(); + if (jsValue.isObject()) { + JSObject* object = jsValue.getObject(); if (object->inherits(&DateInstance::info)) { DateInstance* date = static_cast<DateInstance*>(object); double ms = 0; @@ -3600,7 +3709,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsVal } } else if (object->inherits(&JSArray::info)) { - static HashSet<JSObject*> visitedElems; + DEFINE_STATIC_LOCAL(HashSet<JSObject*>, visitedElems, ()); if (!visitedElems.contains(object)) { visitedElems.add(object); @@ -3614,16 +3723,16 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsVal return aeDesc; } } - JSValue* primitive = object->toPrimitive(exec); + JSValuePtr primitive = object->toPrimitive(exec); if (exec->hadException()) { exec->clearException(); return [NSAppleEventDescriptor nullDescriptor]; } return aeDescFromJSValue(exec, primitive); } - if (jsValue->isUndefined()) + if (jsValue.isUndefined()) return [NSAppleEventDescriptor descriptorWithTypeCode:cMissingValue]; - ASSERT(jsValue->isNull()); + ASSERT(jsValue.isNull()); return [NSAppleEventDescriptor nullDescriptor]; } @@ -3634,7 +3743,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsVal return nil; if (!coreFrame->document()) return nil; - JSValue* result = coreFrame->loader()->executeScript(script, true); + JSValuePtr result = coreFrame->loader()->executeScript(script, true).jsValue(); if (!result) // FIXME: pass errors return 0; JSLock lock(false); @@ -3749,7 +3858,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsVal - (float)pageSizeMultiplier { - return !_private->zoomMultiplierIsTextOnly ? _private->zoomMultiplier : 1.0f; + return ![self _realZoomMultiplierIsTextOnly] ? _private->zoomMultiplier : 1.0f; } - (BOOL)canZoomPageIn @@ -3782,6 +3891,20 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsVal return [self _resetZoom:sender isTextOnly:NO]; } +- (void)setMediaVolume:(float)volume +{ + if (_private->page) + _private->page->setMediaVolume(volume); +} + +- (float)mediaVolume +{ + if (!_private->page) + return 0; + + return _private->page->mediaVolume(); +} + @end @implementation WebView (WebViewPrintingPrivate) @@ -4023,6 +4146,8 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsVal - (void)setSmartInsertDeleteEnabled:(BOOL)flag { _private->smartInsertDeleteEnabled = flag; + if (flag) + [self setSelectTrailingWhitespaceEnabled:false]; } - (BOOL)smartInsertDeleteEnabled @@ -4298,15 +4423,13 @@ static WebFrameView *containingFrameView(NSView *view) // Object cache capacities (in bytes) if (memSize >= 2048) - cacheTotalCapacity = 128 * 1024 * 1024; + cacheTotalCapacity = 96 * 1024 * 1024; else if (memSize >= 1536) - cacheTotalCapacity = 86 * 1024 * 1024; - else if (memSize >= 1024) cacheTotalCapacity = 64 * 1024 * 1024; - else if (memSize >= 512) + else if (memSize >= 1024) cacheTotalCapacity = 32 * 1024 * 1024; - else if (memSize >= 256) - cacheTotalCapacity = 16 * 1024 * 1024; + else if (memSize >= 512) + cacheTotalCapacity = 16 * 1024 * 1024; cacheMinDeadCapacity = 0; cacheMaxDeadCapacity = 0; @@ -4332,15 +4455,13 @@ static WebFrameView *containingFrameView(NSView *view) // Object cache capacities (in bytes) if (memSize >= 2048) - cacheTotalCapacity = 128 * 1024 * 1024; + cacheTotalCapacity = 96 * 1024 * 1024; else if (memSize >= 1536) - cacheTotalCapacity = 86 * 1024 * 1024; - else if (memSize >= 1024) cacheTotalCapacity = 64 * 1024 * 1024; - else if (memSize >= 512) + else if (memSize >= 1024) cacheTotalCapacity = 32 * 1024 * 1024; - else if (memSize >= 256) - cacheTotalCapacity = 16 * 1024 * 1024; + else if (memSize >= 512) + cacheTotalCapacity = 16 * 1024 * 1024; cacheMinDeadCapacity = cacheTotalCapacity / 8; cacheMaxDeadCapacity = cacheTotalCapacity / 4; @@ -4386,15 +4507,13 @@ static WebFrameView *containingFrameView(NSView *view) // browsing pattern. Even growth above 128MB can have substantial // value / MB for some content / browsing patterns.) if (memSize >= 2048) - cacheTotalCapacity = 256 * 1024 * 1024; + cacheTotalCapacity = 128 * 1024 * 1024; else if (memSize >= 1536) - cacheTotalCapacity = 172 * 1024 * 1024; + cacheTotalCapacity = 96 * 1024 * 1024; else if (memSize >= 1024) - cacheTotalCapacity = 128 * 1024 * 1024; - else if (memSize >= 512) cacheTotalCapacity = 64 * 1024 * 1024; - else if (memSize >= 256) - cacheTotalCapacity = 32 * 1024 * 1024; + else if (memSize >= 512) + cacheTotalCapacity = 32 * 1024 * 1024; cacheMinDeadCapacity = cacheTotalCapacity / 4; cacheMaxDeadCapacity = cacheTotalCapacity / 2; @@ -5172,6 +5291,18 @@ id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3); } +BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2) +{ + if (!self->_private->catchesDelegateExceptions) + return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2); + @try { + return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2); + } @catch(id exception) { + ReportDiscardedDelegateException(selector, exception); + } + return result; +} + // 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) @@ -5220,3 +5351,39 @@ BOOL CallFormDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, } @end + +#ifdef BUILDING_ON_LEOPARD + +static IMP originalRecursivelyRemoveMailAttributesImp; + +static id objectElementDataAttribute(DOMHTMLObjectElement *self, SEL) +{ + return [self getAttribute:@"data"]; +} + +static void recursivelyRemoveMailAttributes(DOMNode *self, SEL selector, BOOL a, BOOL b, BOOL c) +{ + // While inside this Mail function, change the behavior of -[DOMHTMLObjectElement data] back to what it used to be + // before we fixed a bug in it (see http://trac.webkit.org/changeset/30044 for that change). + + // It's a little bit strange to patch a method defined by WebKit, but it helps keep this workaround self-contained. + + Method methodToPatch = class_getInstanceMethod(objc_getRequiredClass("DOMHTMLObjectElement"), @selector(data)); + IMP originalDataImp = method_setImplementation(methodToPatch, reinterpret_cast<IMP>(objectElementDataAttribute)); + originalRecursivelyRemoveMailAttributesImp(self, selector, a, b, c); + method_setImplementation(methodToPatch, originalDataImp); +} + +#endif + +static void patchMailRemoveAttributesMethod() +{ +#ifdef BUILDING_ON_LEOPARD + if (!WKAppVersionCheckLessThan(@"com.apple.mail", -1, 4.0)) + return; + Method methodToPatch = class_getInstanceMethod(objc_getRequiredClass("DOMNode"), @selector(recursivelyRemoveMailAttributes:convertObjectsToImages:convertEditableElements:)); + if (!methodToPatch) + return; + originalRecursivelyRemoveMailAttributesImp = method_setImplementation(methodToPatch, reinterpret_cast<IMP>(recursivelyRemoveMailAttributes)); +#endif +} diff --git a/WebKit/mac/WebView/WebViewInternal.h b/WebKit/mac/WebView/WebViewInternal.h index 39b3ef5..25afb64 100644 --- a/WebKit/mac/WebView/WebViewInternal.h +++ b/WebKit/mac/WebView/WebViewInternal.h @@ -159,6 +159,7 @@ typedef struct _WebResourceDelegateImplementationCache { IMP didLoadResourceFromMemoryCacheFunc; IMP willCacheResponseFunc; IMP plugInFailedWithErrorFunc; + IMP shouldUseCredentialStorageFunc; } WebResourceDelegateImplementationCache; typedef struct _WebFrameLoadDelegateImplementationCache { @@ -177,6 +178,7 @@ typedef struct _WebFrameLoadDelegateImplementationCache { IMP didFailLoadWithErrorForFrameFunc; IMP didFinishLoadForFrameFunc; IMP didFirstLayoutInFrameFunc; + IMP didFirstVisuallyNonEmptyLayoutInFrameFunc; IMP didReceiveIconForFrameFunc; IMP didFinishDocumentLoadForFrameFunc; } WebFrameLoadDelegateImplementationCache; @@ -216,4 +218,6 @@ id CallResourceLoadDelegate(IMP, WebView *, SEL, id, id, id, id); id CallResourceLoadDelegate(IMP, WebView *, SEL, id, NSInteger, id); id CallResourceLoadDelegate(IMP, WebView *, SEL, id, id, NSInteger, id); +BOOL CallResourceLoadDelegateReturningBoolean(BOOL, IMP, WebView *, SEL, id, id); + #endif diff --git a/WebKit/mac/WebView/WebViewPrivate.h b/WebKit/mac/WebView/WebViewPrivate.h index 3a33bf9..95e1249 100644 --- a/WebKit/mac/WebView/WebViewPrivate.h +++ b/WebKit/mac/WebView/WebViewPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Apple Computer, 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 @@ -177,6 +177,10 @@ typedef enum { - (BOOL)canResetPageZoom; - (IBAction)resetPageZoom:(id)sender; +// Sets a master volume control for all media elements in the WebView. Valid values are 0..1. +- (void)setMediaVolume:(float)volume; +- (float)mediaVolume; + @end @interface WebView (WebPrivate) @@ -362,6 +366,8 @@ Could be worth adding to the API. - (BOOL)usesPageCache; - (void)setUsesPageCache:(BOOL)usesPageCache; +- (WebHistoryItem *)_globalHistoryItem; + /*! @method textIteratorForRect: @param rectangle from which we want the WebTextIterator to load text from @@ -394,6 +400,12 @@ Could be worth adding to the API. - (id)_initWithFrame:(NSRect)f frameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews; - (BOOL)_usesDocumentViews; +- (void)setSelectTrailingWhitespaceEnabled:(BOOL)flag; +- (BOOL)isSelectTrailingWhitespaceEnabled; + +- (void)setMemoryCacheDelegateCallsEnabled:(BOOL)suspend; +- (BOOL)areMemoryCacheDelegateCallsEnabled; + @end @interface WebView (WebViewPrintingPrivate) @@ -446,6 +458,8 @@ Could be worth adding to the API. // Addresses 4192534. SPI for now. - (void)webView:(WebView *)sender didHandleOnloadEventsForFrame:(WebFrame *)frame; +- (void)webView:(WebView *)sender didFirstVisuallyNonEmptyLayoutInFrame:(WebFrame *)frame; + @end @interface NSObject (WebResourceLoadDelegatePrivate) |