diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:15 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:15 -0800 |
commit | 1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353 (patch) | |
tree | 4457a7306ea5acb43fe05bfe0973b1f7faf97ba2 /WebKit/mac/WebView | |
parent | 9364f22aed35e1a1e9d07c121510f80be3ab0502 (diff) | |
download | external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.zip external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.gz external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'WebKit/mac/WebView')
52 files changed, 4196 insertions, 2599 deletions
diff --git a/WebKit/mac/WebView/WebArchive.m b/WebKit/mac/WebView/WebArchive.m deleted file mode 100644 index bb4bd59..0000000 --- a/WebKit/mac/WebView/WebArchive.m +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "WebArchive.h" - -#import "WebKitLogging.h" -#import "WebResourcePrivate.h" -#import "WebTypesInternal.h" - -NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type"; - -static NSString * const WebMainResourceKey = @"WebMainResource"; -static NSString * const WebSubresourcesKey = @"WebSubresources"; -static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; - -@interface WebArchivePrivate : NSObject -{ - @public - WebResource *mainResource; - NSArray *subresources; - NSArray *subframeArchives; -} -@end - -@implementation WebArchivePrivate - -- (void)dealloc -{ - [mainResource release]; - [subresources release]; - [subframeArchives release]; - [super dealloc]; -} - -@end - -static BOOL isArrayOfClass(id object, Class elementClass) -{ - if (![object isKindOfClass:[NSArray class]]) - return NO; - NSArray *array = (NSArray *)object; - NSUInteger count = [array count]; - for (NSUInteger i = 0; i < count; ++i) - if (![[array objectAtIndex:i] isKindOfClass:elementClass]) - return NO; - return YES; -} - -@implementation WebArchive - -- (id)init -{ - self = [super init]; - if (!self) - return nil; - _private = [[WebArchivePrivate alloc] init]; - return self; -} - -- (id)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives -{ - self = [self init]; - if (!self) - return nil; - - _private->mainResource = [mainResource retain]; - _private->subresources = [subresources retain]; - _private->subframeArchives = [subframeArchives retain]; - - if (!_private->mainResource) { - [self release]; - return nil; - } - - return self; -} - -- (id)_initWithPropertyList:(id)propertyList -{ - self = [self init]; - if (!self) - return nil; - - if (![propertyList isKindOfClass:[NSDictionary class]]) { - [self release]; - return nil; - } - - _private->mainResource = [[WebResource alloc] _initWithPropertyList:[propertyList objectForKey:WebMainResourceKey]]; - if (!_private->mainResource) { - [self release]; - return nil; - } - - _private->subresources = [[WebResource _resourcesFromPropertyLists:[propertyList objectForKey:WebSubresourcesKey]] retain]; - - NSEnumerator *enumerator = [[propertyList objectForKey:WebSubframeArchivesKey] objectEnumerator]; - NSMutableArray *subframeArchives = [[NSMutableArray alloc] init]; - NSDictionary *archivePropertyList; - while ((archivePropertyList = [enumerator nextObject]) != nil) { - WebArchive *archive = [[WebArchive alloc] _initWithPropertyList:archivePropertyList]; - if (archive) { - [subframeArchives addObject:archive]; - [archive release]; - } - } - _private->subframeArchives = subframeArchives; - - return self; -} - -- (id)initWithData:(NSData *)data -{ -#if !LOG_DISABLED - CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); -#endif - NSDictionary *propertyList = [NSPropertyListSerialization propertyListFromData:data - mutabilityOption:NSPropertyListImmutable - format:nil - errorDescription:nil]; -#if !LOG_DISABLED - CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); - CFAbsoluteTime duration = end - start; -#endif - LOG(Timing, "Parsing web archive with [NSPropertyListSerialization propertyListFromData::::] took %f seconds", duration); - - return [self _initWithPropertyList:propertyList]; -} - -- (id)initWithCoder:(NSCoder *)decoder -{ - self = [self init]; - if (!self) - return nil; - - @try { - id object = [decoder decodeObjectForKey:WebMainResourceKey]; - if ([object isKindOfClass:[WebResource class]]) - _private->mainResource = [object retain]; - object = [decoder decodeObjectForKey:WebSubresourcesKey]; - if (isArrayOfClass(object, [WebResource class])) - _private->subresources = [object retain]; - object = [decoder decodeObjectForKey:WebSubframeArchivesKey]; - if (isArrayOfClass(object, [WebArchive class])) - _private->subframeArchives = [object retain]; - } @catch(id) { - [self release]; - return nil; - } - - if (!_private->mainResource) { - [self release]; - return nil; - } - - return self; -} - -- (void)encodeWithCoder:(NSCoder *)encoder -{ - [encoder encodeObject:_private->mainResource forKey:WebMainResourceKey]; - [encoder encodeObject:_private->subresources forKey:WebSubresourcesKey]; - [encoder encodeObject:_private->subframeArchives forKey:WebSubframeArchivesKey]; -} - -- (void)dealloc -{ - [_private release]; - [super dealloc]; -} - -- (id)copyWithZone:(NSZone *)zone -{ - return [self retain]; -} - -- (WebResource *)mainResource -{ - return [[_private->mainResource retain] autorelease]; -} - -- (NSArray *)subresources -{ - return [[_private->subresources retain] autorelease]; -} - -- (NSArray *)subframeArchives -{ - return [[_private->subframeArchives retain] autorelease]; -} - -- (NSDictionary *)_propertyListRepresentation -{ - NSMutableDictionary *propertyList = [NSMutableDictionary dictionary]; - if (_private->mainResource) { - [propertyList setObject:[_private->mainResource _propertyListRepresentation] forKey:WebMainResourceKey]; - } - NSArray *propertyLists = [WebResource _propertyListsFromResources:_private->subresources]; - if ([propertyLists count] > 0) { - [propertyList setObject:propertyLists forKey:WebSubresourcesKey]; - } - NSEnumerator *enumerator = [_private->subframeArchives objectEnumerator]; - NSMutableArray *subarchivePropertyLists = [[NSMutableArray alloc] init]; - WebArchive *archive; - while ((archive = [enumerator nextObject]) != nil) { - [subarchivePropertyLists addObject:[archive _propertyListRepresentation]]; - } - if ([subarchivePropertyLists count] > 0) { - [propertyList setObject:subarchivePropertyLists forKey:WebSubframeArchivesKey]; - } - [subarchivePropertyLists release]; - return propertyList; -} - -- (NSData *)data -{ - NSDictionary *propertyList = [self _propertyListRepresentation]; -#if !LOG_DISABLED - CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); -#endif - NSData *data = [NSPropertyListSerialization dataFromPropertyList:propertyList format:NSPropertyListBinaryFormat_v1_0 errorDescription:nil]; -#if !LOG_DISABLED - CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); - CFAbsoluteTime duration = end - start; -#endif - LOG(Timing, "Serializing web archive with [NSPropertyListSerialization dataFromPropertyList:::] took %f seconds", duration); - return data; -} - -@end diff --git a/WebKit/mac/WebView/WebArchive.mm b/WebKit/mac/WebView/WebArchive.mm new file mode 100644 index 0000000..c989a9a --- /dev/null +++ b/WebKit/mac/WebView/WebArchive.mm @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "WebArchive.h" +#import "WebArchiveInternal.h" + +#import "WebKitLogging.h" +#import "WebResourceInternal.h" +#import "WebResourcePrivate.h" +#import "WebTypesInternal.h" + +#import <WebCore/ArchiveResource.h> +#import <WebCore/LegacyWebArchive.h> +#import <WebCore/WebCoreObjCExtras.h> + +using namespace WebCore; + +NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type"; + +static NSString * const WebMainResourceKey = @"WebMainResource"; +static NSString * const WebSubresourcesKey = @"WebSubresources"; +static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives"; + +@interface WebArchivePrivate : NSObject +{ +@public + WebResource *cachedMainResource; + NSArray *cachedSubresources; + NSArray *cachedSubframeArchives; +@private + LegacyWebArchive* coreArchive; +} + +- (id)initWithCoreArchive:(PassRefPtr<LegacyWebArchive>)coreArchive; +- (LegacyWebArchive*)coreArchive; +- (void)setCoreArchive:(PassRefPtr<LegacyWebArchive>)newCoreArchive; +@end + +@implementation WebArchivePrivate + +#ifndef BUILDING_ON_TIGER ++ (void)initialize +{ + WebCoreObjCFinalizeOnMainThread(self); +} +#endif + +- (id)init +{ + self = [super init]; + if (self) + coreArchive = LegacyWebArchive::create().releaseRef(); + return self; +} + +- (id)initWithCoreArchive:(PassRefPtr<LegacyWebArchive>)_coreArchive +{ + self = [super init]; + if (!self || !_coreArchive) { + [self release]; + return nil; + } + + coreArchive = _coreArchive.releaseRef(); + + return self; +} + +- (LegacyWebArchive*)coreArchive +{ + return coreArchive; +} + +- (void)setCoreArchive:(PassRefPtr<LegacyWebArchive>)newCoreArchive +{ + ASSERT(coreArchive); + ASSERT(newCoreArchive); + coreArchive->deref(); + coreArchive = newCoreArchive.releaseRef(); +} + +- (void)dealloc +{ + if (WebCoreObjCScheduleDeallocateOnMainThread([WebArchivePrivate class], self)) + return; + + ASSERT(coreArchive); + coreArchive->deref(); + coreArchive = 0; + + [cachedMainResource release]; + [cachedSubresources release]; + [cachedSubframeArchives release]; + + [super dealloc]; +} + +- (void)finalize +{ + ASSERT(coreArchive); + coreArchive->deref(); + coreArchive = 0; + + [super finalize]; +} + +@end + +@implementation WebArchive + +- (id)init +{ + self = [super init]; + if (!self) + return nil; + _private = [[WebArchivePrivate alloc] init]; + return self; +} + +static BOOL isArrayOfClass(id object, Class elementClass) +{ + if (![object isKindOfClass:[NSArray class]]) + return NO; + NSArray *array = (NSArray *)object; + NSUInteger count = [array count]; + for (NSUInteger i = 0; i < count; ++i) + if (![[array objectAtIndex:i] isKindOfClass:elementClass]) + return NO; + return YES; +} + +- (id)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives +{ + self = [super init]; + if (!self) + return nil; + + _private = [[WebArchivePrivate alloc] init]; + + _private->cachedMainResource = [mainResource retain]; + if (!_private->cachedMainResource) { + [self release]; + return nil; + } + + if (!subresources || isArrayOfClass(subresources, [WebResource class])) + _private->cachedSubresources = [subresources retain]; + else { + [self release]; + return nil; + } + + if (!subframeArchives || isArrayOfClass(subframeArchives, [WebArchive class])) + _private->cachedSubframeArchives = [subframeArchives retain]; + else { + [self release]; + return nil; + } + + RefPtr<ArchiveResource> coreMainResource = mainResource ? [mainResource _coreResource] : 0; + + Vector<PassRefPtr<ArchiveResource> > coreResources; + NSEnumerator *enumerator = [subresources objectEnumerator]; + WebResource *subresource; + while ((subresource = [enumerator nextObject]) != nil) + coreResources.append([subresource _coreResource]); + + Vector<PassRefPtr<LegacyWebArchive> > coreArchives; + enumerator = [subframeArchives objectEnumerator]; + WebArchive *subframeArchive; + while ((subframeArchive = [enumerator nextObject]) != nil) + coreArchives.append([subframeArchive->_private coreArchive]); + + [_private setCoreArchive:LegacyWebArchive::create(coreMainResource.release(), coreResources, coreArchives)]; + if (![_private coreArchive]) { + [self release]; + return nil; + } + + return self; +} + +- (id)initWithData:(NSData *)data +{ + self = [super init]; + if (!self) + return nil; + +#if !LOG_DISABLED + CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); +#endif + + _private = [[WebArchivePrivate alloc] init]; + [_private setCoreArchive:LegacyWebArchive::create(SharedBuffer::wrapNSData(data).get())]; + +#if !LOG_DISABLED + CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); + CFAbsoluteTime duration = end - start; +#endif + LOG(Timing, "Parsing web archive with [NSPropertyListSerialization propertyListFromData::::] took %f seconds", duration); + + return self; +} + +- (id)initWithCoder:(NSCoder *)decoder +{ + WebResource *mainResource = nil; + NSArray *subresources = nil; + NSArray *subframeArchives = nil; + + @try { + id object = [decoder decodeObjectForKey:WebMainResourceKey]; + if ([object isKindOfClass:[WebResource class]]) + mainResource = [object retain]; + object = [decoder decodeObjectForKey:WebSubresourcesKey]; + if (isArrayOfClass(object, [WebResource class])) + subresources = [object retain]; + object = [decoder decodeObjectForKey:WebSubframeArchivesKey]; + if (isArrayOfClass(object, [WebArchive class])) + subframeArchives = [object retain]; + } @catch(id) { + [self release]; + return nil; + } + + return [self initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives]; +} + +- (void)encodeWithCoder:(NSCoder *)encoder +{ + [encoder encodeObject:[self mainResource] forKey:WebMainResourceKey]; + [encoder encodeObject:[self subresources] forKey:WebSubresourcesKey]; + [encoder encodeObject:[self subframeArchives] forKey:WebSubframeArchivesKey]; +} + +- (void)dealloc +{ + [_private release]; + [super dealloc]; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return [self retain]; +} + +- (WebResource *)mainResource +{ + // 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) { + LegacyWebArchive* coreArchive = [_private coreArchive]; + if (coreArchive) + _private->cachedMainResource = [[WebResource alloc] _initWithCoreResource:coreArchive->mainResource()]; + } + + return [[_private->cachedMainResource retain] autorelease]; +} + +- (NSArray *)subresources +{ + // 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) { + LegacyWebArchive* coreArchive = [_private coreArchive]; + if (!coreArchive) + _private->cachedSubresources = [[NSArray alloc] init]; + else { + const Vector<RefPtr<ArchiveResource> >& subresources(coreArchive->subresources()); + NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:subresources.size()]; + _private->cachedSubresources = mutableArray; + for (unsigned i = 0; i < subresources.size(); ++i) { + WebResource *resource = [[WebResource alloc] _initWithCoreResource:subresources[i].get()]; + if (resource) { + [mutableArray addObject:resource]; + [resource release]; + } + } + } + } + + return [[_private->cachedSubresources retain] autorelease]; +} + +- (NSArray *)subframeArchives +{ + // 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) { + LegacyWebArchive* coreArchive = [_private coreArchive]; + if (!coreArchive) + _private->cachedSubframeArchives = [[NSArray alloc] init]; + else { + const Vector<RefPtr<Archive> >& subframeArchives(coreArchive->subframeArchives()); + NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:subframeArchives.size()]; + _private->cachedSubframeArchives = mutableArray; + for (unsigned i = 0; i < subframeArchives.size(); ++i) { + WebArchive *archive = [[WebArchive alloc] _initWithCoreLegacyWebArchive:(LegacyWebArchive *)subframeArchives[i].get()]; + [mutableArray addObject:archive]; + [archive release]; + } + } + } + + return [[_private->cachedSubframeArchives retain] autorelease]; +} + +- (NSData *)data +{ +#if !LOG_DISABLED + CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); +#endif + + RetainPtr<CFDataRef> data = [_private coreArchive]->rawDataRepresentation(); + +#if !LOG_DISABLED + CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); + CFAbsoluteTime duration = end - start; +#endif + LOG(Timing, "Serializing web archive to raw CFPropertyList data took %f seconds", duration); + + return [[(NSData *)data.get() retain] autorelease]; +} + +@end + +@implementation WebArchive (WebInternal) + +- (id)_initWithCoreLegacyWebArchive:(PassRefPtr<WebCore::LegacyWebArchive>)coreLegacyWebArchive +{ + self = [super init]; + if (!self) + return nil; + + _private = [[WebArchivePrivate alloc] initWithCoreArchive:coreLegacyWebArchive]; + if (!_private) { + [self release]; + return nil; + } + + return self; +} + +- (WebCore::LegacyWebArchive *)_coreLegacyWebArchive +{ + return [_private coreArchive]; +} + +@end diff --git a/WebKit/mac/WebView/WebUnarchivingState.h b/WebKit/mac/WebView/WebArchiveInternal.h index 84d808b..071d4ab 100644 --- a/WebKit/mac/WebView/WebUnarchivingState.h +++ b/WebKit/mac/WebView/WebArchiveInternal.h @@ -1,18 +1,18 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 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 * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -26,20 +26,16 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import <Foundation/Foundation.h> +#import "WebArchive.h" +#import <JavaScriptCore/Forward.h> -@class WebArchive; -@class WebResource; - -@interface WebUnarchivingState : NSObject -{ - NSMutableDictionary *archivedSubframes; - NSMutableDictionary *archivedResources; +namespace WebCore { + class LegacyWebArchive; } -- (void)addArchive:(WebArchive *)archive; -- (void)addResource:(WebResource *)resource; -- (WebResource *)archivedResourceForURL:(NSURL *)URL; -- (WebArchive *)popSubframeArchiveWithFrameName:(NSString *)frameName; +@interface WebArchive (WebInternal) + +- (id)_initWithCoreLegacyWebArchive:(WTF::PassRefPtr<WebCore::LegacyWebArchive>)coreLegacyWebArchive; +- (WebCore::LegacyWebArchive *)_coreLegacyWebArchive; @end diff --git a/WebKit/mac/WebView/WebArchiver.mm b/WebKit/mac/WebView/WebArchiver.mm deleted file mode 100644 index 4c68191..0000000 --- a/WebKit/mac/WebView/WebArchiver.mm +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "WebArchiver.h" - -#import "WebArchive.h" -#import "WebDOMOperationsPrivate.h" -#import "WebDataSource.h" -#import "WebDocument.h" -#import "WebFrame.h" -#import "WebFrameBridge.h" -#import "WebFrameInternal.h" -#import "WebResource.h" -#import <JavaScriptCore/Assertions.h> -#import <WebCore/Frame.h> -#import <WebCore/SelectionController.h> -#import <WebKit/DOM.h> - -using namespace WebCore; - -@implementation WebArchiver - -+ (NSArray *)_subframeArchivesForFrame:(WebFrame *)frame -{ - NSEnumerator *enumerator = [[frame childFrames] objectEnumerator]; - NSMutableArray *subframeArchives = [NSMutableArray array]; - WebFrame *childFrame; - while ((childFrame = [enumerator nextObject])) { - WebArchive *childFrameArchive = [self archiveFrame:childFrame]; - if (childFrameArchive) - [subframeArchives addObject:childFrameArchive]; - } - - return subframeArchives; -} - -+ (WebArchive *)archiveFrame:(WebFrame *)frame; -{ - return [[[WebArchive alloc] initWithMainResource:[[frame _dataSource] mainResource] - subresources:[[frame _dataSource] subresources] - subframeArchives:[self _subframeArchivesForFrame:frame]] autorelease]; -} - -+ (WebArchive *)archiveMainResourceForFrame:(WebFrame *)frame; -{ - return [[[WebArchive alloc] initWithMainResource:[[frame _dataSource] mainResource] - subresources:nil - subframeArchives:nil] autorelease]; -} - -+ (WebArchive *)_archiveCurrentStateForFrame:(WebFrame *)frame -{ - if ([frame DOMDocument]) - return [self archiveNode:[frame DOMDocument]]; - - return [self archiveFrame:frame]; -} - -+ (WebArchive *)_archiveWithMarkupString:(NSString *)markupString fromFrame:(WebFrame *)frame nodes:(NSArray *)nodes -{ - NSURLResponse *response = [[frame _dataSource] response]; - NSURL *responseURL = [response URL]; - - // it's possible to have a response without a URL here - // <rdar://problem/5454935> - if (!responseURL) - responseURL = [NSURL URLWithString:@""]; - - WebResource *mainResource = [[WebResource alloc] initWithData:[markupString dataUsingEncoding:NSUTF8StringEncoding] - URL:responseURL - MIMEType:[response MIMEType] - textEncodingName:@"UTF-8" - frameName:[frame name]]; - - NSMutableArray *subframeArchives = [[NSMutableArray alloc] init]; - NSMutableArray *subresources = [[NSMutableArray alloc] init]; - NSMutableSet *uniqueSubresources = [[NSMutableSet alloc] init]; - NSEnumerator *enumerator = [nodes objectEnumerator]; - DOMNode *node; - while ((node = [enumerator nextObject]) != nil) { - WebFrame *childFrame; - if (([node isKindOfClass:[DOMHTMLFrameElement class]] || - [node isKindOfClass:[DOMHTMLIFrameElement class]] || - [node isKindOfClass:[DOMHTMLObjectElement class]]) && - ((childFrame = [(DOMHTMLFrameElement *)node contentFrame]) != nil)) { - [subframeArchives addObject:[self _archiveCurrentStateForFrame:childFrame]]; - } else { - NSEnumerator *enumerator = [[node _subresourceURLs] objectEnumerator]; - NSURL *URL; - while ((URL = [enumerator nextObject]) != nil) { - if ([uniqueSubresources containsObject:URL]) - continue; - [uniqueSubresources addObject:URL]; - WebResource *subresource = [[frame _dataSource] subresourceForURL:URL]; - if (subresource) - [subresources addObject:subresource]; - else - // FIXME: should do something better than spew to console here - LOG_ERROR("Failed to archive subresource for %@", URL); - } - } - } - - WebArchive *archive = [[[WebArchive alloc] initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives] autorelease]; - [mainResource release]; - [uniqueSubresources release]; - [subresources release]; - [subframeArchives release]; - - return archive; -} - -+ (WebArchive *)archiveRange:(DOMRange *)range -{ - WebFrameBridge *bridge = [range _bridge]; - WebFrame *frame = [bridge webFrame]; - NSArray *nodes; - NSString *markupString = [bridge markupStringFromRange:range nodes:&nodes]; - return [self _archiveWithMarkupString:markupString fromFrame:frame nodes:nodes]; -} - -+ (WebArchive *)archiveNode:(DOMNode *)node -{ - WebFrame *frame = [[node ownerDocument] webFrame]; - WebFrameBridge *bridge = [frame _bridge]; - NSArray *nodes; - NSString *markupString = [bridge markupStringFromNode:node nodes:&nodes]; - return [self _archiveWithMarkupString:markupString fromFrame:frame nodes:nodes]; -} - -+ (WebArchive *)archiveSelectionInFrame:(WebFrame *)frame -{ - Frame* coreFrame = core(frame); - if (!coreFrame) - return nil; - - WebFrameBridge *bridge = [frame _bridge]; - NSArray *nodes; - NSString *markupString = [bridge markupStringFromRange:kit(coreFrame->selectionController()->toRange().get()) nodes:&nodes]; - WebArchive *archive = [self _archiveWithMarkupString:markupString fromFrame:frame nodes:nodes]; - - if (coreFrame->isFrameSet()) { - // Wrap the frameset document in an iframe so it can be pasted into - // another document (which will have a body or frameset of its own). - - NSString *iframeMarkup = [[NSString alloc] initWithFormat:@"<iframe frameborder=\"no\" marginwidth=\"0\" marginheight=\"0\" width=\"98%%\" height=\"98%%\" src=\"%@\"></iframe>", [[[frame _dataSource] response] URL]]; - WebResource *iframeResource = [[WebResource alloc] initWithData:[iframeMarkup dataUsingEncoding:NSUTF8StringEncoding] - URL:[NSURL URLWithString:@"about:blank"] - MIMEType:@"text/html" - textEncodingName:@"UTF-8" - frameName:nil]; - - NSArray *subframeArchives = [NSArray arrayWithObject:archive]; - archive = [[[WebArchive alloc] initWithMainResource:iframeResource subresources:nil subframeArchives:subframeArchives] autorelease]; - - [iframeResource release]; - [iframeMarkup release]; - } - - return archive; -} - -@end - diff --git a/WebKit/mac/WebView/WebClipView.m b/WebKit/mac/WebView/WebClipView.m index 9231932..b551145 100644 --- a/WebKit/mac/WebView/WebClipView.m +++ b/WebKit/mac/WebView/WebClipView.m @@ -28,10 +28,10 @@ #import "WebClipView.h" -#import <JavaScriptCore/Assertions.h> #import <WebKit/WebHTMLView.h> #import <WebKit/WebNSViewExtras.h> #import <WebKit/WebViewPrivate.h> +#import <wtf/Assertions.h> // WebClipView's entire reason for existing is to set the clip used by focus ring redrawing. // There's no easy way to prevent the focus ring from drawing outside the passed-in clip rectangle @@ -104,10 +104,12 @@ { NSView *docView = [self documentView]; if ([docView respondsToSelector:@selector(_webView)]) { +#if ENABLE(DASHBOARD_SUPPORT) WebView *wv = [docView _webView]; if ([wv _dashboardBehavior:WebDashboardBehaviorAllowWheelScrolling]) { [super scrollWheel:event]; } +#endif return; } [super scrollWheel:event]; diff --git a/WebKit/mac/WebView/WebDataSource.mm b/WebKit/mac/WebView/WebDataSource.mm index cd033b1..aeff7d7 100644 --- a/WebKit/mac/WebView/WebDataSource.mm +++ b/WebKit/mac/WebView/WebDataSource.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 @@ -29,11 +29,10 @@ #import "WebDataSource.h" #import "WebArchive.h" -#import "WebArchiver.h" +#import "WebArchiveInternal.h" #import "WebDataSourceInternal.h" #import "WebDocument.h" #import "WebDocumentLoaderMac.h" -#import "WebFrameBridge.h" #import "WebFrameInternal.h" #import "WebFrameLoadDelegate.h" #import "WebFrameLoaderClient.h" @@ -41,23 +40,26 @@ #import "WebKitErrorsPrivate.h" #import "WebKitLogging.h" #import "WebKitStatisticsPrivate.h" +#import "WebKitNSStringExtras.h" #import "WebNSURLExtras.h" #import "WebNSURLRequestExtras.h" #import "WebPDFRepresentation.h" +#import "WebResourceInternal.h" #import "WebResourceLoadDelegate.h" #import "WebResourcePrivate.h" -#import "WebUnarchivingState.h" #import "WebViewInternal.h" -#import <JavaScriptCore/Assertions.h> +#import <WebCore/ApplicationCacheStorage.h> #import <WebCore/FrameLoader.h> #import <WebCore/KURL.h> +#import <WebCore/LegacyWebArchive.h> #import <WebCore/MIMETypeRegistry.h> #import <WebCore/ResourceRequest.h> #import <WebCore/SharedBuffer.h> #import <WebCore/WebCoreObjCExtras.h> +#import <WebCore/WebCoreURLResponse.h> #import <WebKit/DOMHTML.h> #import <WebKit/DOMPrivate.h> -#import <WebKitSystemInterface.h> +#import <wtf/Assertions.h> using namespace WebCore; @@ -67,7 +69,6 @@ using namespace WebCore; id <WebDocumentRepresentation> representation; - WebUnarchivingState *unarchivingState; BOOL representationFinishedLoading; } @end @@ -83,12 +84,14 @@ using namespace WebCore; - (void)dealloc { + if (WebCoreObjCScheduleDeallocateOnMainThread([WebDataSourcePrivate class], self)) + return; + ASSERT(!loader->isLoading()); loader->detachDataSource(); loader->deref(); [representation release]; - [unarchivingState release]; [super dealloc]; } @@ -135,20 +138,6 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl Class repClass; return [WebView _viewClass:nil andRepresentationClass:&repClass forMIMEType:MIMEType] ? repClass : nil; } - -- (NSString *)_MIMETypeOfResponse:(NSURLResponse *)response -{ -#ifdef BUILDING_ON_TIGER - return [response MIMEType]; -#else - // FIXME: This is part of a workaround for <rdar://problem/5321972> REGRESSION: Plain text document from HTTP server detected - // as application/octet-stream - NSString *MIMEType = [response MIMEType]; - if ([MIMEType isEqualToString:@"application/octet-stream"] && [response isKindOfClass:[NSHTTPURLResponse class]] && [[[(NSHTTPURLResponse *)response allHeaderFields] objectForKey:@"Content-Type"] hasPrefix:@"text/plain"]) - return @"text/plain"; - return MIMEType; -#endif -} @end @implementation WebDataSource (WebPrivate) @@ -160,10 +149,14 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (void)_addSubframeArchives:(NSArray *)subframeArchives { + // FIXME: This SPI is poor, poor design. Can we come up with another solution for those who need it? + DocumentLoader* loader = [self _documentLoader]; + ASSERT(loader); + NSEnumerator *enumerator = [subframeArchives objectEnumerator]; WebArchive *archive; while ((archive = [enumerator nextObject]) != nil) - [self _addToUnarchiveState:archive]; + loader->addAllArchiveResources([archive _coreLegacyWebArchive]); } - (NSFileWrapper *)_fileWrapperForURL:(NSURL *)URL @@ -189,11 +182,23 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (NSString *)_responseMIMEType { -#ifdef BUILDING_ON_TIGER - return [[self response] MIMEType]; -#else - return [self _MIMETypeOfResponse:[self response]]; -#endif + return [[self response] _webcore_MIMEType]; +} + +- (BOOL)_transferApplicationCache:(NSString*)destinationBundleIdentifier +{ + DocumentLoader* loader = [self _documentLoader]; + + if (!loader) + return NO; + + ApplicationCache* cache = loader->applicationCache(); + if (!cache) + return YES; + + NSString *cacheDir = [NSString _webkit_localCacheDirectoryWithBundleIdentifier:destinationBundleIdentifier]; + + return ApplicationCacheStorage::storeCopyOfCache(cacheDir, cache); } @end @@ -223,12 +228,6 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl } } -- (void)_clearUnarchivingState -{ - [_private->unarchivingState release]; - _private->unarchivingState = nil; -} - - (void)_revertToProvisionalState { [self _setRepresentation:nil]; @@ -257,18 +256,14 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl return repTypes; } -- (WebResource *)_archivedSubresourceForURL:(NSURL *)URL -{ - return [_private->unarchivingState archivedResourceForURL:URL]; -} - - (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement { DOMDocumentFragment *fragment = [self _documentFragmentWithArchive:archive]; if (fragment) - [[self _bridge] replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:NO matchStyle:NO]; + [[self webFrame] _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:NO matchStyle:NO]; } +// FIXME: There are few reasons why this method and many of its related methods can't be pushed entirely into WebCore in the future. - (DOMDocumentFragment *)_documentFragmentWithArchive:(WebArchive *)archive { ASSERT(archive); @@ -278,8 +273,10 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl if ([WebView canShowMIMETypeAsHTML:MIMEType]) { NSString *markupString = [[NSString alloc] initWithData:[mainResource data] encoding:NSUTF8StringEncoding]; // FIXME: seems poor form to do this as a side effect of getting a document fragment - [self _addToUnarchiveState:archive]; - DOMDocumentFragment *fragment = [[self _bridge] documentFragmentWithMarkupString:markupString baseURLString:[[mainResource URL] _web_originalDataAsString]]; + if (DocumentLoader* loader = [self _documentLoader]) + loader->addAllArchiveResources([archive _coreLegacyWebArchive]); + + DOMDocumentFragment *fragment = [[self webFrame] _documentFragmentWithMarkupString:markupString baseURLString:[[mainResource URL] _web_originalDataAsString]]; [markupString release]; return fragment; } else if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType)) { @@ -319,19 +316,10 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl // May return nil if not initialized with a URL. - (NSURL *)_URL { - KURL URL = _private->loader->url(); - return URL.isEmpty() ? nil : URL.getNSURL(); -} - -- (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName -{ - return [_private->unarchivingState popSubframeArchiveWithFrameName:frameName]; -} - -- (WebFrameBridge *)_bridge -{ - ASSERT(_private->loader->isCommitted()); - return [[self webFrame] _bridge]; + const KURL& url = _private->loader->url(); + if (url.isEmpty()) + return nil; + return url; } - (WebView *)_webView @@ -359,19 +347,12 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl [_private->representation setDataSource:self]; } -- (void)_addToUnarchiveState:(WebArchive *)archive -{ - if (!_private->unarchivingState) - _private->unarchivingState = [[WebUnarchivingState alloc] init]; - [_private->unarchivingState addArchive:archive]; -} - - (DocumentLoader*)_documentLoader { return _private->loader; } -- (id)_initWithDocumentLoader:(WebDocumentLoaderMac *)loader +- (id)_initWithDocumentLoader:(PassRefPtr<WebDocumentLoaderMac>)loader { self = [super init]; if (!self) @@ -379,10 +360,9 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl _private = [[WebDataSourcePrivate alloc] init]; - _private->loader = loader; - loader->ref(); + _private->loader = loader.releaseRef(); - LOG(Loading, "creating datasource for %@", _private->loader->request().url().getNSURL()); + LOG(Loading, "creating datasource for %@", static_cast<NSURL *>(_private->loader->request().url())); ++WebDataSourceCount; @@ -395,7 +375,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (id)initWithRequest:(NSURLRequest *)request { - return [self _initWithDocumentLoader:new WebDocumentLoaderMac(request, SubstituteData())]; + return [self _initWithDocumentLoader:WebDocumentLoaderMac::create(request, SubstituteData())]; } - (void)dealloc @@ -437,7 +417,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (NSURLRequest *)initialRequest { - return _private->loader->initialRequest().nsURLRequest(); + return _private->loader->originalRequest().nsURLRequest(); } - (NSMutableURLRequest *)request @@ -476,8 +456,10 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (NSURL *)unreachableURL { - KURL URL = _private->loader->unreachableURL(); - return URL.isEmpty() ? nil : URL.getNSURL(); + const KURL& unreachableURL = _private->loader->unreachableURL(); + if (unreachableURL.isEmpty()) + return nil; + return unreachableURL; } - (WebArchive *)webArchive @@ -485,58 +467,38 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl // it makes no sense to grab a WebArchive from an uncommitted document. if (!_private->loader->isCommitted()) return nil; - return [WebArchiver archiveFrame:[self webFrame]]; + + return [[[WebArchive alloc] _initWithCoreLegacyWebArchive:LegacyWebArchive::create(core([self webFrame]))] autorelease]; } - (WebResource *)mainResource { - NSURLResponse *response = [self response]; - return [[[WebResource alloc] initWithData:[self data] - URL:[response URL] - MIMEType:[self _responseMIMEType] - textEncodingName:[response textEncodingName] - frameName:[[self webFrame] name]] autorelease]; + RefPtr<ArchiveResource> coreResource = _private->loader->mainResource(); + return [[[WebResource alloc] _initWithCoreResource:coreResource.release()] autorelease]; } - (NSArray *)subresources { - if (!_private->loader->isCommitted()) - return [NSMutableArray array]; - - NSArray *datas; - NSArray *responses; - [[self _bridge] getAllResourceDatas:&datas andResponses:&responses]; - ASSERT([datas count] == [responses count]); - - NSMutableArray *subresources = [[NSMutableArray alloc] initWithCapacity:[datas count]]; - for (unsigned i = 0; i < [datas count]; ++i) { - NSURLResponse *response = [responses objectAtIndex:i]; - [subresources addObject:[[[WebResource alloc] _initWithData:[datas objectAtIndex:i] URL:[response URL] response:response MIMEType:[self _MIMETypeOfResponse:response]] autorelease]]; - } + Vector<PassRefPtr<ArchiveResource> > coreSubresources; + _private->loader->getSubresources(coreSubresources); + NSMutableArray *subresources = [[NSMutableArray alloc] initWithCapacity:coreSubresources.size()]; + for (unsigned i = 0; i < coreSubresources.size(); ++i) + [subresources addObject:[[[WebResource alloc] _initWithCoreResource:coreSubresources[i]] autorelease]]; + return [subresources autorelease]; } - (WebResource *)subresourceForURL:(NSURL *)URL { - if (!_private->loader->isCommitted()) - return nil; - - NSData *data; - NSURLResponse *response; - if (![[self _bridge] getData:&data andResponse:&response forURL:[URL _web_originalDataAsString]]) - return [self _archivedSubresourceForURL:URL]; - - return [[[WebResource alloc] _initWithData:data URL:URL response:response MIMEType:[self _MIMETypeOfResponse:response]] autorelease]; + RefPtr<ArchiveResource> subresource = _private->loader->subresource(URL); + + return subresource ? [[[WebResource alloc] _initWithCoreResource:subresource.get()] autorelease] : nil; } - (void)addSubresource:(WebResource *)subresource -{ - if (subresource) { - if (!_private->unarchivingState) - _private->unarchivingState = [[WebUnarchivingState alloc] init]; - [_private->unarchivingState addResource:subresource]; - } +{ + _private->loader->addArchiveResource([subresource _coreResource]); } @end diff --git a/WebKit/mac/WebView/WebDataSourceInternal.h b/WebKit/mac/WebView/WebDataSourceInternal.h index 94a6fd1..29497d5 100644 --- a/WebKit/mac/WebView/WebDataSourceInternal.h +++ b/WebKit/mac/WebView/WebDataSourceInternal.h @@ -27,48 +27,34 @@ */ #import "WebDataSourcePrivate.h" +#import <wtf/Forward.h> -#ifdef __cplusplus namespace WebCore { class DocumentLoader; } -typedef WebCore::DocumentLoader WebCoreDocumentLoader; + class WebDocumentLoaderMac; -#else -@class WebCoreDocumentLoader; -@class WebDocumentLoaderMac; -#endif @class DOMDocumentFragment; @class DOMElement; -@class NSError; -@class NSURL; @class WebArchive; -@class WebFrameBridge; @class WebResource; @class WebView; -@protocol WebDocumentRepresentation; - @interface WebDataSource (WebInternal) -- (void)_addToUnarchiveState:(WebArchive *)archive; - (void)_makeRepresentation; - (BOOL)_isDocumentHTML; - (WebView *)_webView; -- (WebFrameBridge *)_bridge; -- (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName; - (NSURL *)_URL; - (DOMElement *)_imageElementWithImageResource:(WebResource *)resource; - (DOMDocumentFragment *)_documentFragmentWithImageResource:(WebResource *)resource; - (DOMDocumentFragment *)_documentFragmentWithArchive:(WebArchive *)archive; + (NSMutableDictionary *)_repTypesAllowImageTypeOmission:(BOOL)allowImageTypeOmission; - (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement; -- (WebResource *)_archivedSubresourceForURL:(NSURL *)URL; -- (id)_initWithDocumentLoader:(WebDocumentLoaderMac*)loader; +- (id)_initWithDocumentLoader:(PassRefPtr<WebDocumentLoaderMac>)loader; - (void)_finishedLoading; - (void)_receivedData:(NSData *)data; - (void)_revertToProvisionalState; - (void)_setMainDocumentError:(NSError *)error; -- (void)_clearUnarchivingState; -- (WebCoreDocumentLoader*)_documentLoader; +- (WebCore::DocumentLoader*)_documentLoader; @end diff --git a/WebKit/mac/WebView/WebDataSourcePrivate.h b/WebKit/mac/WebView/WebDataSourcePrivate.h index a394b53..ae8d4cf 100644 --- a/WebKit/mac/WebView/WebDataSourcePrivate.h +++ b/WebKit/mac/WebView/WebDataSourcePrivate.h @@ -31,10 +31,10 @@ @interface WebDataSource (WebPrivate) - (NSFileWrapper *)_fileWrapperForURL:(NSURL *)URL; - - (void)_addSubframeArchives:(NSArray *) archives; - - (NSError *)_mainDocumentError; - - (NSString *)_responseMIMEType; + +- (BOOL)_transferApplicationCache:(NSString*)destinationBundleIdentifier; + @end diff --git a/WebKit/mac/WebView/WebDocumentInternal.h b/WebKit/mac/WebView/WebDocumentInternal.h index 81e961a..191264b 100644 --- a/WebKit/mac/WebView/WebDocumentInternal.h +++ b/WebKit/mac/WebView/WebDocumentInternal.h @@ -36,29 +36,20 @@ #endif /*! -@protocol _WebDocumentTextSizing -@discussion Optional protocol for making text larger and smaller. +@protocol _WebDocumentZooming +@discussion Optional protocol for a view that wants to handle its own zoom. */ -@protocol _WebDocumentTextSizing <NSObject> +@protocol _WebDocumentZooming <NSObject> // Methods to perform the actual commands -- (IBAction)_makeTextSmaller:(id)sender; -- (IBAction)_makeTextLarger:(id)sender; -- (IBAction)_makeTextStandardSize:(id)sender; +- (IBAction)_zoomOut:(id)sender; +- (IBAction)_zoomIn:(id)sender; +- (IBAction)_resetZoom:(id)sender; -// Views that do text sizing come in two flavors. Some will track the common textSizeMultiplier factor stored -// in the WebView. Others (see PDFView) keep their own scaling factor, but still want to play along loosely -// with the smaller/larger commands, which in the user model operate across all frames of the WebView. -- (BOOL)_tracksCommonSizeFactor; - -// Views that track the common size factor need to be told when the WebView itself changed the value. -- (void)_textSizeMultiplierChanged; - -// Views that do not track the common size factor must answer for themselves if they are able to zoom in -// or out. Views that do track it are not sent these messages. -- (BOOL)_canMakeTextSmaller; -- (BOOL)_canMakeTextLarger; -- (BOOL)_canMakeTextStandardSize; +// Whether or not the commands can be executed. +- (BOOL)_canZoomOut; +- (BOOL)_canZoomIn; +- (BOOL)_canResetZoom; @end diff --git a/WebKit/mac/WebView/WebDocumentLoaderMac.h b/WebKit/mac/WebView/WebDocumentLoaderMac.h index 9acba89..83e2bb3 100644 --- a/WebKit/mac/WebView/WebDocumentLoaderMac.h +++ b/WebKit/mac/WebView/WebDocumentLoaderMac.h @@ -39,19 +39,24 @@ namespace WebCore { class WebDocumentLoaderMac : public WebCore::DocumentLoader { public: - WebDocumentLoaderMac(const WebCore::ResourceRequest&, const WebCore::SubstituteData&); + static PassRefPtr<WebDocumentLoaderMac> create(const WebCore::ResourceRequest& request, const WebCore::SubstituteData& data) + { + return adoptRef(new WebDocumentLoaderMac(request, data)); + } void setDataSource(WebDataSource *, WebView*); void detachDataSource(); WebDataSource *dataSource() const; - virtual void attachToFrame(); - virtual void detachFromFrame(); - void increaseLoadCount(unsigned long identifier); void decreaseLoadCount(unsigned long identifier); private: + WebDocumentLoaderMac(const WebCore::ResourceRequest&, const WebCore::SubstituteData&); + + virtual void attachToFrame(); + virtual void detachFromFrame(); + void retainDataSource(); void releaseDataSource(); diff --git a/WebKit/mac/WebView/WebDocumentPrivate.h b/WebKit/mac/WebView/WebDocumentPrivate.h index dff4c03..f09d3bd 100644 --- a/WebKit/mac/WebView/WebDocumentPrivate.h +++ b/WebKit/mac/WebView/WebDocumentPrivate.h @@ -55,14 +55,6 @@ // The text is all black according to the parameter. - (NSImage *)selectionImageForcingBlackText:(BOOL)forceBlackText; -// NSImage of the portion of the selection that's in view. This does not draw backgrounds. -// The text is all white according to the parameter. -// NOTE: This method is deprecated. It has been supplanted by selectionImageForcingBlackText:, -// and implementations typically just call that method, so its name no longer matches its -// behavior. It will be removed when doing so won't cause trouble for people using the latest -// WebKit with beta releases of Safari 3.0. -- (NSImage *)selectionImageForcingWhiteText:(BOOL)forceWhiteText; - // Rect tightly enclosing the entire selected area, in coordinates of selectionView. // NOTE: This method is equivalent to selectionRect and shouldn't be used; use selectionRect instead. - (NSRect)selectionImageRect; diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsView.h b/WebKit/mac/WebView/WebDynamicScrollBarsView.h index 255deb8..a0f8006 100644 --- a/WebKit/mac/WebView/WebDynamicScrollBarsView.h +++ b/WebKit/mac/WebView/WebDynamicScrollBarsView.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2005, 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 @@ -26,46 +26,23 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import <AppKit/NSScrollView.h> +// This is a Private header (containing SPI), despite the fact that its name +// does not contain the word Private. -#import <WebCore/WebCoreFrameView.h> +// FIXME: Does Safari really need to use this any more? AppKit added autohidesScrollers +// in Panther, and that was the original reason we needed this view in Safari. -// FIXME 2980779: This has grown to be more than just a dynamic scroll bar view, -// and it is no longer completely appropriate for use outside of WebKit. +// FIXME: <rdar://problem/5898985> Mail currently expects this header to define WebCoreScrollbarAlwaysOn. +extern const int WebCoreScrollbarAlwaysOn; -@interface WebDynamicScrollBarsView : NSScrollView <WebCoreFrameView> -{ - WebCoreScrollbarMode hScroll; - WebCoreScrollbarMode vScroll; +@interface WebDynamicScrollBarsView : NSScrollView { + int hScroll; // FIXME: Should be WebCore::ScrollbarMode if this was an ObjC++ header. + int vScroll; // Ditto. BOOL hScrollModeLocked; BOOL vScrollModeLocked; BOOL suppressLayout; BOOL suppressScrollers; BOOL inUpdateScrollers; } - -- (void)setAllowsHorizontalScrolling:(BOOL)flag; -- (BOOL)allowsHorizontalScrolling; -- (void)setAllowsVerticalScrolling:(BOOL)flag; -- (BOOL)allowsVerticalScrolling; - -- (void)setHorizontalScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock; -- (void)setVerticalScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock; -- (void)setScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock; - -- (void)setHorizontalScrollingModeLocked:(BOOL)locked; -- (void)setVerticalScrollingModeLocked:(BOOL)locked; -- (void)setScrollingModesLocked:(BOOL)mode; - -- (BOOL)horizontalScrollingModeLocked; -- (BOOL)verticalScrollingModeLocked; - -// Convenience method to affect both scrolling directions at once. -- (void)setAllowsScrolling:(BOOL)flag; - -// Returns YES if either horizontal or vertical scrolling is allowed. -- (BOOL)allowsScrolling; - -- (void)updateScrollers; -- (void)setSuppressLayout: (BOOL)flag; +- (void)setAllowsHorizontalScrolling:(BOOL)flag; // This method is used by Safari, so it cannot be removed. @end diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsView.m b/WebKit/mac/WebView/WebDynamicScrollBarsView.m index 8374725..1eb2d80 100644 --- a/WebKit/mac/WebView/WebDynamicScrollBarsView.m +++ b/WebKit/mac/WebView/WebDynamicScrollBarsView.m @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2005, 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 @@ -26,14 +26,35 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import <WebKit/WebDynamicScrollBarsView.h> +#import "WebDynamicScrollBarsViewInternal.h" -#import <WebKit/WebDocument.h> +#import "WebDocument.h" +#import "WebFrameView.h" #import <WebKitSystemInterface.h> +using namespace WebCore; + +// FIXME: <rdar://problem/5898985> Mail expects a constant of this name to exist. +const int WebCoreScrollbarAlwaysOn = ScrollbarAlwaysOn; + @implementation WebDynamicScrollBarsView -- (void)setSuppressLayout: (BOOL)flag; +- (void)setAllowsHorizontalScrolling:(BOOL)flag +{ + if (hScrollModeLocked) + return; + if (flag && hScroll == ScrollbarAlwaysOff) + hScroll = ScrollbarAuto; + else if (!flag && hScroll != ScrollbarAlwaysOff) + hScroll = ScrollbarAlwaysOff; + [self updateScrollers]; +} + +@end + +@implementation WebDynamicScrollBarsView (WebInternal) + +- (void)setSuppressLayout:(BOOL)flag; { suppressLayout = flag; } @@ -82,7 +103,7 @@ BOOL scrollsVertically; BOOL scrollsHorizontally; - if (!suppressLayout && !suppressScrollers && (hScroll == WebCoreScrollbarAuto || vScroll == WebCoreScrollbarAuto)) { + if (!suppressLayout && !suppressScrollers && (hScroll == ScrollbarAuto || vScroll == ScrollbarAuto)) { // Do a layout if pending, before checking if scrollbars are needed. // This fixes 2969367, although may introduce a slowdown in live resize performance. NSView *documentView = [self documentView]; @@ -99,22 +120,22 @@ NSSize documentSize = [documentView frame].size; NSSize frameSize = [self frame].size; - scrollsVertically = (vScroll == WebCoreScrollbarAlwaysOn) || - (vScroll == WebCoreScrollbarAuto && documentSize.height > frameSize.height); + scrollsVertically = (vScroll == ScrollbarAlwaysOn) || + (vScroll == ScrollbarAuto && documentSize.height > frameSize.height); if (scrollsVertically) - scrollsHorizontally = (hScroll == WebCoreScrollbarAlwaysOn) || - (hScroll == WebCoreScrollbarAuto && documentSize.width + [NSScroller scrollerWidth] > frameSize.width); + scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || + (hScroll == ScrollbarAuto && documentSize.width + [NSScroller scrollerWidth] > frameSize.width); else { - scrollsHorizontally = (hScroll == WebCoreScrollbarAlwaysOn) || - (hScroll == WebCoreScrollbarAuto && documentSize.width > frameSize.width); + scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || + (hScroll == ScrollbarAuto && documentSize.width > frameSize.width); if (scrollsHorizontally) - scrollsVertically = (vScroll == WebCoreScrollbarAlwaysOn) || - (vScroll == WebCoreScrollbarAuto && documentSize.height + [NSScroller scrollerWidth] > frameSize.height); + scrollsVertically = (vScroll == ScrollbarAlwaysOn) || + (vScroll == ScrollbarAuto && documentSize.height + [NSScroller scrollerWidth] > frameSize.height); } } } else { - scrollsHorizontally = (hScroll == WebCoreScrollbarAuto) ? hasHorizontalScroller : (hScroll == WebCoreScrollbarAlwaysOn); - scrollsVertically = (vScroll == WebCoreScrollbarAuto) ? hasVerticalScroller : (vScroll == WebCoreScrollbarAlwaysOn); + scrollsHorizontally = (hScroll == ScrollbarAuto) ? hasHorizontalScroller : (hScroll == ScrollbarAlwaysOn); + scrollsVertically = (vScroll == ScrollbarAuto) ? hasVerticalScroller : (vScroll == ScrollbarAlwaysOn); } if (hasVerticalScroller != scrollsVertically) { @@ -167,126 +188,52 @@ #endif } -- (void)setAllowsScrolling:(BOOL)flag -{ - if (hScrollModeLocked && vScrollModeLocked) - return; - - if (flag && vScroll == WebCoreScrollbarAlwaysOff) - vScroll = WebCoreScrollbarAuto; - else if (!flag && vScroll != WebCoreScrollbarAlwaysOff) - vScroll = WebCoreScrollbarAlwaysOff; - - if (flag && hScroll == WebCoreScrollbarAlwaysOff) - hScroll = WebCoreScrollbarAuto; - else if (!flag && hScroll != WebCoreScrollbarAlwaysOff) - hScroll = WebCoreScrollbarAlwaysOff; - - [self updateScrollers]; -} - -- (BOOL)allowsScrolling -{ - // Returns YES if either horizontal or vertical scrolling is allowed. - return hScroll != WebCoreScrollbarAlwaysOff || vScroll != WebCoreScrollbarAlwaysOff; -} - -- (void)setAllowsHorizontalScrolling:(BOOL)flag -{ - if (hScrollModeLocked) - return; - if (flag && hScroll == WebCoreScrollbarAlwaysOff) - hScroll = WebCoreScrollbarAuto; - else if (!flag && hScroll != WebCoreScrollbarAlwaysOff) - hScroll = WebCoreScrollbarAlwaysOff; - [self updateScrollers]; -} - -- (void)setAllowsVerticalScrolling:(BOOL)flag -{ - if (vScrollModeLocked) - return; - if (flag && vScroll == WebCoreScrollbarAlwaysOff) - vScroll = WebCoreScrollbarAuto; - else if (!flag && vScroll != WebCoreScrollbarAlwaysOff) - vScroll = WebCoreScrollbarAlwaysOff; - [self updateScrollers]; -} - - (BOOL)allowsHorizontalScrolling { - return hScroll != WebCoreScrollbarAlwaysOff; + return hScroll != ScrollbarAlwaysOff; } - (BOOL)allowsVerticalScrolling { - return vScroll != WebCoreScrollbarAlwaysOff; + return vScroll != ScrollbarAlwaysOff; } --(WebCoreScrollbarMode)horizontalScrollingMode +- (void)scrollingModes:(WebCore::ScrollbarMode*)hMode vertical:(WebCore::ScrollbarMode*)vMode { - return hScroll; + *hMode = static_cast<ScrollbarMode>(hScroll); + *vMode = static_cast<ScrollbarMode>(vScroll); } --(WebCoreScrollbarMode)verticalScrollingMode +- (ScrollbarMode)horizontalScrollingMode { - return vScroll; + return static_cast<ScrollbarMode>(hScroll); } -- (void)setHorizontalScrollingMode:(WebCoreScrollbarMode)mode +- (ScrollbarMode)verticalScrollingMode { - [self setHorizontalScrollingMode:mode andLock:NO]; + return static_cast<ScrollbarMode>(vScroll); } -- (void)setHorizontalScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock +- (void)setHorizontalScrollingMode:(ScrollbarMode)horizontalMode andLock:(BOOL)lock { - if (mode == hScroll || hScrollModeLocked) - return; - - hScroll = mode; - - if (lock) - [self setHorizontalScrollingModeLocked:YES]; - - [self updateScrollers]; + [self setScrollingModes:horizontalMode vertical:[self verticalScrollingMode] andLock:lock]; } -- (void)setVerticalScrollingMode:(WebCoreScrollbarMode)mode +- (void)setVerticalScrollingMode:(ScrollbarMode)verticalMode andLock:(BOOL)lock { - [self setVerticalScrollingMode:mode andLock:NO]; + [self setScrollingModes:[self horizontalScrollingMode] vertical:verticalMode andLock:lock]; } -- (void)setVerticalScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock +- (void)setScrollingModes:(ScrollbarMode)horizontalMode vertical:(ScrollbarMode)verticalMode andLock:(BOOL)lock { - if (mode == vScroll || vScrollModeLocked) - return; - - vScroll = mode; - - if (lock) - [self setVerticalScrollingModeLocked:YES]; - - [self updateScrollers]; -} - -- (void)setScrollingMode:(WebCoreScrollbarMode)mode -{ - [self setScrollingMode:mode andLock:NO]; -} - -- (void)setScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock -{ - if ((mode == vScroll && mode == hScroll) || (vScrollModeLocked && hScrollModeLocked)) - return; - BOOL update = NO; - if (mode != vScroll && !vScrollModeLocked) { - vScroll = mode; + if (verticalMode != vScroll && !vScrollModeLocked) { + vScroll = verticalMode; update = YES; } - if (mode != hScroll && !hScrollModeLocked) { - hScroll = mode; + if (horizontalMode != hScroll && !hScrollModeLocked) { + hScroll = horizontalMode; update = YES; } @@ -347,4 +294,13 @@ [super scrollWheel:event]; } +- (BOOL)accessibilityIsIgnored +{ + id docView = [self documentView]; + if ([docView isKindOfClass:[WebFrameView class]] && ![(WebFrameView *)docView allowsScrolling]) + return YES; + + return [super accessibilityIsIgnored]; +} + @end diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsViewInternal.h b/WebKit/mac/WebView/WebDynamicScrollBarsViewInternal.h new file mode 100644 index 0000000..312cf9d --- /dev/null +++ b/WebKit/mac/WebView/WebDynamicScrollBarsViewInternal.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005, 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "WebDynamicScrollBarsView.h" +#import <WebCore/WebCoreFrameView.h> + +@interface WebDynamicScrollBarsView (WebInternal) <WebCoreFrameScrollView> + +- (BOOL)allowsHorizontalScrolling; +- (BOOL)allowsVerticalScrolling; + +- (void)setScrollingModes:(WebCore::ScrollbarMode)hMode vertical:(WebCore::ScrollbarMode)vMode andLock:(BOOL)lock; +- (void)scrollingModes:(WebCore::ScrollbarMode*)hMode vertical:(WebCore::ScrollbarMode*)vMode; + +- (WebCore::ScrollbarMode)horizontalScrollingMode; +- (WebCore::ScrollbarMode)verticalScrollingMode; + +- (void)setHorizontalScrollingMode:(WebCore::ScrollbarMode)mode andLock:(BOOL)lock; +- (void)setVerticalScrollingMode:(WebCore::ScrollbarMode)mode andLock:(BOOL)lock; + +- (void)setHorizontalScrollingModeLocked:(BOOL)locked; +- (void)setVerticalScrollingModeLocked:(BOOL)locked; +- (void)setScrollingModesLocked:(BOOL)mode; + +- (BOOL)horizontalScrollingModeLocked; +- (BOOL)verticalScrollingModeLocked; + +- (void)updateScrollers; +- (void)setSuppressLayout:(BOOL)flag; + +@end diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm index 71ac0eb..13a6ad4 100644 --- a/WebKit/mac/WebView/WebFrame.mm +++ b/WebKit/mac/WebView/WebFrame.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006 Apple Computer, 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 @@ -29,60 +29,64 @@ #import "WebFrameInternal.h" #import "DOMCSSStyleDeclarationInternal.h" +#import "DOMDocumentFragmentInternal.h" #import "DOMDocumentInternal.h" #import "DOMElementInternal.h" #import "DOMHTMLElementInternal.h" #import "DOMNodeInternal.h" #import "DOMRangeInternal.h" -#import "WebBackForwardList.h" +#import "WebArchiveInternal.h" #import "WebChromeClient.h" #import "WebDataSourceInternal.h" -#import "WebDocumentInternal.h" #import "WebDocumentLoaderMac.h" -#import "WebFrameBridge.h" -#import "WebFrameLoadDelegate.h" #import "WebFrameLoaderClient.h" #import "WebFrameViewInternal.h" +#import "WebHTMLView.h" #import "WebHTMLViewInternal.h" -#import "WebHistoryItem.h" -#import "WebHistoryItemInternal.h" -#import "WebHistoryItemPrivate.h" -#import "WebKitLogging.h" +#import "WebIconFetcherInternal.h" #import "WebKitStatisticsPrivate.h" #import "WebNSURLExtras.h" -#import "WebNSURLRequestExtras.h" -#import "WebNetscapePluginEmbeddedView.h" -#import "WebNullPluginView.h" -#import "WebPlugin.h" -#import "WebPluginController.h" -#import "WebPreferencesPrivate.h" -#import "WebScriptDebugDelegatePrivate.h" +#import "WebScriptDebugger.h" #import "WebViewInternal.h" -#import <WebCore/Chrome.h> +#import <JavaScriptCore/APICast.h> +#import <WebCore/AccessibilityObject.h> +#import <WebCore/AXObjectCache.h> #import <WebCore/ColorMac.h> -#import <WebCore/Document.h> -#import <WebCore/Event.h> -#import <WebCore/FrameLoader.h> +#import <WebCore/DOMImplementation.h> +#import <WebCore/DocLoader.h> +#import <WebCore/DocumentFragment.h> +#import <WebCore/EventHandler.h> #import <WebCore/Frame.h> +#import <WebCore/FrameLoader.h> #import <WebCore/FrameTree.h> -#import <WebCore/HistoryItem.h> -#import <WebCore/HTMLFormElement.h> +#import <WebCore/GraphicsContext.h> #import <WebCore/HTMLFrameOwnerElement.h> +#import <WebCore/HistoryItem.h> +#import <WebCore/HitTestResult.h> +#import <WebCore/LegacyWebArchive.h> #import <WebCore/Page.h> -#import <WebCore/SelectionController.h> -#import <WebCore/SharedBuffer.h> -#import <WebCore/FormState.h> -#import <WebCore/ResourceRequest.h> -#import <WebCore/kjs_binding.h> -#import <WebCore/kjs_proxy.h> -#import <WebKit/DOMDocument.h> -#import <WebKit/DOMElement.h> -#import <WebKit/DOMHTMLElement.h> -#import <WebKit/DOMNode.h> -#import <WebKit/DOMRange.h> -#import <JavaScriptCore/APICast.h> - +#import <WebCore/PluginData.h> +#import <WebCore/RenderPart.h> +#import <WebCore/RenderView.h> +#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/markup.h> +#import <WebCore/visible_units.h> +#import <runtime/JSLock.h> + +using namespace std; using namespace WebCore; +using namespace HTMLNames; + +using JSC::JSGlobalObject; +using JSC::JSLock; +using JSC::JSValue; /* Here is the current behavior matrix for four types of navigations: @@ -116,33 +120,31 @@ Repeat load of the same URL (by any other means of navigation other than the rel Add to back/forward list: NO */ -using namespace WebCore; - NSString *WebPageCacheEntryDateKey = @"WebPageCacheEntryDateKey"; NSString *WebPageCacheDataSourceKey = @"WebPageCacheDataSourceKey"; NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey"; -@interface WebFrame (ForwardDecls) -- (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL; -- (WebHistoryItem *)_createItem:(BOOL)useOriginal; -- (WebHistoryItem *)_createItemTreeWithTargetFrame:(WebFrame *)targetFrame clippedAtTarget:(BOOL)doClip; -@end - -@interface NSView (WebFramePluginHosting) -- (void)setWebFrame:(WebFrame *)webFrame; -@end +// FIXME: Remove when this key becomes publicly defined +NSString *NSAccessibilityEnhancedUserInterfaceAttribute = @"AXEnhancedUserInterface"; @implementation WebFramePrivate - (void)dealloc { [webFrameView release]; - - [scriptDebugger release]; + + delete scriptDebugger; [super dealloc]; } +- (void)finalize +{ + delete scriptDebugger; + + [super finalize]; +} + - (void)setWebFrameView:(WebFrameView *)v { [v retain]; @@ -197,6 +199,16 @@ DOMDocument *kit(Document* document) return [DOMDocument _wrapDocument:document]; } +DocumentFragment* core(DOMDocumentFragment *fragment) +{ + return [fragment _documentFragment]; +} + +DOMDocumentFragment *kit(DocumentFragment* fragment) +{ + return [DOMDocumentFragment _wrapDocumentFragment:fragment]; +} + HTMLElement* core(DOMHTMLElement *element) { return [element _HTMLElement]; @@ -217,38 +229,34 @@ DOMRange *kit(Range* range) return [DOMRange _wrapRange:range]; } -WebCore::EditableLinkBehavior core(WebKitEditableLinkBehavior editableLinkBehavior) -{ - return static_cast<WebCore::EditableLinkBehavior>(editableLinkBehavior); -} - -WebKitEditableLinkBehavior kit(WebCore::EditableLinkBehavior editableLinkBehavior) +EditableLinkBehavior core(WebKitEditableLinkBehavior editableLinkBehavior) { - return static_cast<WebKitEditableLinkBehavior>(editableLinkBehavior); + switch (editableLinkBehavior) { + case WebKitEditableLinkDefaultBehavior: + return EditableLinkDefaultBehavior; + case WebKitEditableLinkAlwaysLive: + return EditableLinkAlwaysLive; + case WebKitEditableLinkOnlyLiveWithShiftKey: + return EditableLinkOnlyLiveWithShiftKey; + case WebKitEditableLinkLiveWhenNotFocused: + return EditableLinkLiveWhenNotFocused; + case WebKitEditableLinkNeverLive: + return EditableLinkNeverLive; + } + ASSERT_NOT_REACHED(); + return EditableLinkDefaultBehavior; } @implementation WebFrame (WebInternal) - -static inline WebFrame *frame(WebCoreFrameBridge *bridge) -{ - return ((WebFrameBridge *)bridge)->_frame; -} - Frame* core(WebFrame *frame) { - if (!frame) - return 0; - - if (!frame->_private->bridge) - return 0; - - return frame->_private->bridge->m_frame; + return frame ? frame->_private->coreFrame : 0; } WebFrame *kit(Frame* frame) { - return frame ? ((WebFrameBridge *)frame->bridge())->_frame : nil; + return frame ? static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame() : nil; } Page* core(WebView *webView) @@ -269,156 +277,102 @@ WebView *getWebView(WebFrame *webFrame) return kit(coreFrame->page()); } -/* - In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree. - The item that was the target of the user's navigation is designated as the "targetItem". - When this method is called with doClip=YES we're able to create the whole tree except for the target's children, - which will be loaded in the future. That part of the tree will be filled out as the child loads are committed. -*/ - -+ (CFAbsoluteTime)_timeOfLastCompletedLoad -{ - return FrameLoader::timeOfLastCompletedLoad() - kCFAbsoluteTimeIntervalSince1970; -} - -- (WebFrameBridge *)_bridge ++ (PassRefPtr<Frame>)_createFrameWithPage:(Page*)page frameName:(const String&)name frameView:(WebFrameView *)frameView ownerElement:(HTMLFrameOwnerElement*)ownerElement { - return _private->bridge; -} - -- (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer intoChild:(WebFrame *)childFrame -{ - ASSERT(childFrame); - HistoryItem* parentItem = core(self)->loader()->currentHistoryItem(); - FrameLoadType loadType = [self _frameLoader]->loadType(); - FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory; + WebView *webView = kit(page); - // If we're moving in the backforward list, we might want to replace the content - // of this child frame with whatever was there at that point. - // Reload will maintain the frame contents, LoadSame will not. - if (parentItem && parentItem->children().size() && - (isBackForwardLoadType(loadType) - || loadType == FrameLoadTypeReload - || loadType == FrameLoadTypeReloadAllowingStaleData)) - { - HistoryItem* childItem = parentItem->childItemWithName([childFrame name]); - if (childItem) { - // Use the original URL to ensure we get all the side-effects, such as - // onLoad handlers, of any redirects that happened. An example of where - // this is needed is Radar 3213556. - URL = [NSURL _web_URLWithDataAsString:childItem->originalURLString()]; - // These behaviors implied by these loadTypes should apply to the child frames - childLoadType = loadType; + WebFrame *frame = [[self alloc] _initWithWebFrameView:frameView webView:webView]; + RefPtr<Frame> coreFrame = Frame::create(page, ownerElement, new WebFrameLoaderClient(frame)); + [frame release]; + frame->_private->coreFrame = coreFrame.get(); - if (isBackForwardLoadType(loadType)) - // For back/forward, remember this item so we can traverse any child items as child frames load - core(childFrame)->loader()->setProvisionalHistoryItem(childItem); - else - // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item - core(childFrame)->loader()->setCurrentHistoryItem(childItem); - } + coreFrame->tree()->setName(name); + if (ownerElement) { + ASSERT(ownerElement->document()->frame()); + ownerElement->document()->frame()->tree()->appendChild(coreFrame.get()); } - WebArchive *archive = [[self _dataSource] _popSubframeArchiveWithName:[childFrame name]]; - if (archive) - [childFrame loadArchive:archive]; - else - [childFrame _frameLoader]->load([URL absoluteURL], referrer, childLoadType, - String(), 0, 0); -} + coreFrame->init(); + [webView _setZoomMultiplier:[webView _realZoomMultiplier] isTextOnly:[webView _realZoomMultiplierIsTextOnly]]; -- (void)_viewWillMoveToHostWindow:(NSWindow *)hostWindow -{ - Frame* coreFrame = core(self); - for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) - [[[kit(frame) frameView] documentView] viewWillMoveToHostWindow:hostWindow]; + return coreFrame.release(); } -- (void)_viewDidMoveToHostWindow ++ (void)_createMainFrameWithPage:(Page*)page frameName:(const String&)name frameView:(WebFrameView *)frameView { - Frame* coreFrame = core(self); - for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) - [[[kit(frame) frameView] documentView] viewDidMoveToHostWindow]; + [self _createFrameWithPage:page frameName:name frameView:frameView ownerElement:0]; } -- (void)_addChild:(WebFrame *)child ++ (PassRefPtr<WebCore::Frame>)_createSubframeWithOwnerElement:(HTMLFrameOwnerElement*)ownerElement frameName:(const String&)name frameView:(WebFrameView *)frameView { - core(self)->tree()->appendChild(adoptRef(core(child))); - if ([child _dataSource]) - [[child _dataSource] _documentLoader]->setOverrideEncoding([[self _dataSource] _documentLoader]->overrideEncoding()); + return [self _createFrameWithPage:ownerElement->document()->frame()->page() frameName:name frameView:frameView ownerElement:ownerElement]; } -- (int)_numPendingOrLoadingRequests:(BOOL)recurse +- (void)_attachScriptDebugger { - return core(self)->loader()->numPendingOrLoadingRequests(recurse); -} + ScriptController* scriptController = _private->coreFrame->script(); -- (void)_reloadForPluginChanges -{ - Frame* coreFrame = core(self); - for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { - NSView <WebDocumentView> *documentView = [[kit(frame) frameView] documentView]; - if (([documentView isKindOfClass:[WebHTMLView class]] && coreFrame->loader()->containsPlugins())) - [kit(frame) reload]; + // Calling ScriptController::globalObject() would create a window shell, and dispatch corresponding callbacks, which may be premature + // if the script debugger is attached before a document is created. + if (!scriptController->haveWindowShell()) + return; + + JSGlobalObject* globalObject = scriptController->globalObject(); + if (!globalObject) + return; + + if (_private->scriptDebugger) { + ASSERT(_private->scriptDebugger == globalObject->debugger()); + return; } -} -- (void)_attachScriptDebugger -{ - if (!_private->scriptDebugger && core(self)->scriptProxy()->haveGlobalObject()) - _private->scriptDebugger = [[WebScriptDebugger alloc] initWithWebFrame:self]; + _private->scriptDebugger = new WebScriptDebugger(globalObject); } - (void)_detachScriptDebugger { - if (_private->scriptDebugger) { - id old = _private->scriptDebugger; - _private->scriptDebugger = nil; - [old release]; - } + if (!_private->scriptDebugger) + return; + + delete _private->scriptDebugger; + _private->scriptDebugger = 0; } -- (id)_initWithWebFrameView:(WebFrameView *)fv webView:(WebView *)v bridge:(WebFrameBridge *)bridge +- (id)_initWithWebFrameView:(WebFrameView *)fv webView:(WebView *)v { self = [super init]; if (!self) return nil; _private = [[WebFramePrivate alloc] init]; - _private->bridge = bridge; if (fv) { [_private setWebFrameView:fv]; [fv _setWebFrame:self]; } + _private->shouldCreateRenderers = YES; + ++WebFrameCount; return self; } -- (NSArray *)_documentViews +- (void)_clearCoreFrame { - NSMutableArray *result = [NSMutableArray array]; - Frame* coreFrame = core(self); - for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { - id docView = [[kit(frame) frameView] documentView]; - if (docView) - [result addObject:docView]; - } - return result; + _private->coreFrame = 0; } -- (void)_updateBackground +- (void)_updateBackgroundAndUpdatesWhileOffscreen { - BOOL drawsBackground = [getWebView(self) drawsBackground]; - NSColor *backgroundColor = [getWebView(self) backgroundColor]; + WebView *webView = getWebView(self); + BOOL drawsBackground = [webView drawsBackground]; + NSColor *backgroundColor = [webView backgroundColor]; - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { - WebFrameBridge *bridge = (WebFrameBridge *)frame->bridge(); - WebFrame *webFrame = [bridge webFrame]; + 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. if (!drawsBackground) @@ -429,8 +383,12 @@ WebView *getWebView(WebFrame *webFrame) [documentView setDrawsBackground:drawsBackground]; if ([documentView respondsToSelector:@selector(setBackgroundColor:)]) [documentView setBackgroundColor:backgroundColor]; - [bridge setDrawsBackground:drawsBackground]; - [bridge setBaseBackgroundColor:backgroundColor]; + if (frame && frame->view()) { + frame->view()->setTransparent(!drawsBackground); + Color color = colorFromNSColor([backgroundColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]); + frame->view()->setBaseBackgroundColor(color); + frame->view()->setShouldUpdateWhileOffscreen([webView shouldUpdateWhileOffscreen]); + } } } @@ -447,26 +405,20 @@ WebView *getWebView(WebFrame *webFrame) #ifndef BUILDING_ON_TIGER - (void)_unmarkAllBadGrammar { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { - Document *doc = frame->document(); - if (!doc) - return; - - doc->removeMarkers(DocumentMarker::Grammar); + if (Document* document = frame->document()) + document->removeMarkers(DocumentMarker::Grammar); } } #endif - (void)_unmarkAllMisspellings { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { - Document *doc = frame->document(); - if (!doc) - return; - - doc->removeMarkers(DocumentMarker::Spelling); + if (Document* document = frame->document()) + document->removeMarkers(DocumentMarker::Spelling); } } @@ -476,8 +428,8 @@ WebView *getWebView(WebFrame *webFrame) // optimization for common case to avoid creating potentially large selection string if ([documentView isKindOfClass:[WebHTMLView class]]) - if (Frame* coreFrame = core(self)) - return coreFrame->selectionController()->isRange(); + if (Frame* coreFrame = _private->coreFrame) + return coreFrame->selection()->isRange(); if ([documentView conformsToProtocol:@protocol(WebDocumentText)]) return [[documentView selectedString] length] > 0; @@ -497,7 +449,7 @@ WebView *getWebView(WebFrame *webFrame) { // FIXME: 4186050 is one known case that makes this debug check fail. BOOL found = NO; - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) if ([kit(frame) _hasSelection]) { if (found) @@ -510,10 +462,12 @@ WebView *getWebView(WebFrame *webFrame) - (WebFrame *)_findFrameWithSelection { - Frame* coreFrame = core(self); - for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) - if ([kit(frame) _hasSelection]) - return kit(frame); + Frame* coreFrame = _private->coreFrame; + for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { + WebFrame *webFrame = kit(frame); + if ([webFrame _hasSelection]) + return webFrame; + } return nil; } @@ -530,64 +484,577 @@ WebView *getWebView(WebFrame *webFrame) ASSERT([[getWebView(self) mainFrame] _atMostOneFrameHasSelection]); } -- (BOOL)_isMainFrame +static inline WebDataSource *dataSource(DocumentLoader* loader) { - Frame* coreFrame = core(self); - if (!coreFrame) - return NO; - return coreFrame == coreFrame->page()->mainFrame() ; + return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil; } -- (FrameLoader*)_frameLoader +- (WebDataSource *)_dataSource { - Frame* frame = core(self); - return frame ? frame->loader() : 0; + return dataSource(_private->coreFrame->loader()->documentLoader()); } -static inline WebDataSource *dataSource(DocumentLoader* loader) +- (void)_addData:(NSData *)data { - return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil; + Document* document = _private->coreFrame->document(); + + // Document may be nil if the part is about to redirect + // as a result of JS executing during load, i.e. one frame + // changing another's location before the frame's document + // has been created. + if (!document) + return; + + document->setShouldCreateRenderers(_private->shouldCreateRenderers); + _private->coreFrame->loader()->addData((const char *)[data bytes], [data length]); } -- (WebDataSource *)_dataSourceForDocumentLoader:(DocumentLoader*)loader +- (NSString *)_stringWithDocumentTypeStringAndMarkupString:(NSString *)markupString { - return dataSource(loader); + return _private->coreFrame->documentTypeString() + markupString; } -- (void)_addDocumentLoader:(DocumentLoader*)loader toUnarchiveState:(WebArchive *)archive +- (NSArray *)_nodesFromList:(Vector<Node*> *)nodesVector { - [dataSource(loader) _addToUnarchiveState:archive]; + size_t size = nodesVector->size(); + NSMutableArray *nodes = [NSMutableArray arrayWithCapacity:size]; + for (size_t i = 0; i < size; ++i) + [nodes addObject:[DOMNode _wrapNode:(*nodesVector)[i]]]; + return nodes; } -- (WebDataSource *)_dataSource +- (NSString *)_markupStringFromRange:(DOMRange *)range nodes:(NSArray **)nodes +{ + // FIXME: This is always "for interchange". Is that right? See the previous method. + Vector<Node*> nodeList; + NSString *markupString = createMarkup([range _range], nodes ? &nodeList : 0, AnnotateForInterchange); + if (nodes) + *nodes = [self _nodesFromList:&nodeList]; + + return [self _stringWithDocumentTypeStringAndMarkupString:markupString]; +} + +- (NSString *)_selectedString +{ + String text = _private->coreFrame->selectedText(); + text.replace('\\', _private->coreFrame->backslashAsCurrencySymbol()); + return text; +} + +- (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); + + 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]; +} + +- (void)_drawRect:(NSRect)rect contentsOnly:(BOOL)contentsOnly +{ + PlatformGraphicsContext* platformContext = static_cast<PlatformGraphicsContext*>([[NSGraphicsContext currentContext] graphicsPort]); + ASSERT([[NSGraphicsContext currentContext] isFlipped]); + GraphicsContext context(platformContext); + + if (contentsOnly) + _private->coreFrame->view()->paintContents(&context, enclosingIntRect(rect)); + else + _private->coreFrame->view()->paint(&context, enclosingIntRect(rect)); +} + +// Used by pagination code called from AppKit when a standalone web page is printed. +- (NSArray*)_computePageRectsWithPrintWidthScaleFactor:(float)printWidthScaleFactor printHeight:(float)printHeight +{ + NSMutableArray* pages = [NSMutableArray arrayWithCapacity:5]; + if (printWidthScaleFactor <= 0) { + LOG_ERROR("printWidthScaleFactor has bad value %.2f", printWidthScaleFactor); + return pages; + } + + if (printHeight <= 0) { + LOG_ERROR("printHeight has bad value %.2f", printHeight); + return pages; + } + + if (!_private->coreFrame || !_private->coreFrame->document() || !_private->coreFrame->view()) return pages; + RenderView* root = static_cast<RenderView *>(_private->coreFrame->document()->renderer()); + if (!root) return pages; + + FrameView* view = _private->coreFrame->view(); + if (!view) + return pages; + + NSView* documentView = view->documentView(); + if (!documentView) + return pages; + + float currPageHeight = printHeight; + float docHeight = root->layer()->height(); + float docWidth = root->layer()->width(); + float printWidth = docWidth/printWidthScaleFactor; + + // We need to give the part the opportunity to adjust the page height at each step. + for (float i = 0; i < docHeight; i += currPageHeight) { + float proposedBottom = min(docHeight, i + printHeight); + _private->coreFrame->adjustPageHeight(&proposedBottom, i, proposedBottom, i); + currPageHeight = max(1.0f, proposedBottom - i); + for (float j = 0; j < docWidth; j += printWidth) { + NSValue* val = [NSValue valueWithRect: NSMakeRect(j, i, printWidth, currPageHeight)]; + [pages addObject: val]; + } + } + + return pages; +} + +- (BOOL)_getVisibleRect:(NSRect*)rect; +{ + ASSERT_ARG(rect, rect); + if (RenderPart* ownerRenderer = _private->coreFrame->ownerRenderer()) { + if (ownerRenderer->needsLayout()) + return NO; + *rect = ownerRenderer->absoluteClippedOverflowRect(); + return YES; + } + + return NO; +} + +- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string +{ + return [self _stringByEvaluatingJavaScriptFromString:string forceUserGesture:true]; +} + +- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture +{ + ASSERT(_private->coreFrame->document()); + + JSValue* result = _private->coreFrame->loader()->executeScript(string, forceUserGesture); + + if (!_private->coreFrame) // In case the script removed our frame from the page. + return @""; + + // 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()) + return @""; + + JSLock lock(false); + 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(); +} + +- (NSRect)_firstRectForDOMRange:(DOMRange *)range +{ + return _private->coreFrame->firstRectForRange([range _range]); +} + +- (void)_scrollDOMRangeToVisible:(DOMRange *)range +{ + NSRect rangeRect = [self _firstRectForDOMRange:range]; + Node *startNode = [[range startContainer] _node]; + + if (startNode && startNode->renderer()) { + RenderLayer *layer = startNode->renderer()->enclosingLayer(); + if (layer) + layer->scrollRectToVisible(enclosingIntRect(rangeRect), false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded); + } +} + +- (BOOL)_needsLayout { - FrameLoader* frameLoader = [self _frameLoader]; + return _private->coreFrame->view() ? _private->coreFrame->view()->needsLayout() : false; +} + +- (id)_accessibilityTree +{ + if (!AXObjectCache::accessibilityEnabled()) { + AXObjectCache::enableAccessibility(); + if ([[NSApp accessibilityAttributeValue:NSAccessibilityEnhancedUserInterfaceAttribute] boolValue]) + AXObjectCache::enableEnhancedUserInterfaceAccessibility(); + } - if (!frameLoader) + if (!_private->coreFrame || !_private->coreFrame->document()) + return nil; + RenderView* root = static_cast<RenderView *>(_private->coreFrame->document()->renderer()); + if (!root) + return nil; + return _private->coreFrame->document()->axObjectCache()->get(root)->wrapper(); +} + +- (DOMRange *)_rangeByAlteringCurrentSelection:(SelectionController::EAlteration)alteration direction:(SelectionController::EDirection)direction granularity:(TextGranularity)granularity +{ + if (_private->coreFrame->selection()->isNone()) return nil; - return dataSource(frameLoader->documentLoader()); + SelectionController selection; + selection.setSelection(_private->coreFrame->selection()->selection()); + selection.modify(alteration, direction, granularity); + return [DOMRange _wrapRange:selection.toRange().get()]; +} + +- (TextGranularity)_selectionGranularity +{ + return _private->coreFrame->selectionGranularity(); +} + +- (NSRange)_convertToNSRange:(Range *)range +{ + if (!range || !range->startContainer()) + return NSMakeRange(NSNotFound, 0); + + Element* selectionRoot = _private->coreFrame->selection()->rootEditableElement(); + Element* scope = selectionRoot ? selectionRoot : _private->coreFrame->document()->documentElement(); + + // Mouse events may cause TSM to attempt to create an NSRange for a portion of the view + // that is not inside the current editable region. These checks ensure we don't produce + // potentially invalid data when responding to such requests. + if (range->startContainer() != scope && !range->startContainer()->isDescendantOf(scope)) + return NSMakeRange(NSNotFound, 0); + if (range->endContainer() != scope && !range->endContainer()->isDescendantOf(scope)) + return NSMakeRange(NSNotFound, 0); + + RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset()); + ASSERT(testRange->startContainer() == scope); + int startPosition = TextIterator::rangeLength(testRange.get()); + + ExceptionCode ec; + testRange->setEnd(range->endContainer(), range->endOffset(), ec); + ASSERT(testRange->startContainer() == scope); + int endPosition = TextIterator::rangeLength(testRange.get()); + + return NSMakeRange(startPosition, endPosition - startPosition); +} + +- (PassRefPtr<Range>)_convertToDOMRange:(NSRange)nsrange +{ + if (nsrange.location > INT_MAX) + return 0; + if (nsrange.length > INT_MAX || nsrange.location + nsrange.length > INT_MAX) + nsrange.length = INT_MAX - nsrange.location; + + // our critical assumption is that we are only called by input methods that + // concentrate on a given area containing the selection + // We have to do this because of text fields and textareas. The DOM for those is not + // directly in the document DOM, so serialization is problematic. Our solution is + // to use the root editable element of the selection start as the positional base. + // That fits with AppKit's idea of an input context. + Element* selectionRoot = _private->coreFrame->selection()->rootEditableElement(); + Element* scope = selectionRoot ? selectionRoot : _private->coreFrame->document()->documentElement(); + return TextIterator::rangeFromLocationAndLength(scope, nsrange.location, nsrange.length); +} + +- (DOMRange *)_convertNSRangeToDOMRange:(NSRange)nsrange +{ + return [DOMRange _wrapRange:[self _convertToDOMRange:nsrange].get()]; +} + +- (NSRange)_convertDOMRangeToNSRange:(DOMRange *)range +{ + return [self _convertToNSRange:[range _range]]; +} + +- (DOMRange *)_markDOMRange +{ + return [DOMRange _wrapRange:_private->coreFrame->mark().toRange().get()]; +} + +// Given proposedRange, returns an extended range that includes adjacent whitespace that should +// be deleted along with the proposed range in order to preserve proper spacing and punctuation of +// the text surrounding the deletion. +- (DOMRange *)_smartDeleteRangeForProposedRange:(DOMRange *)proposedRange +{ + Node *startContainer = [[proposedRange startContainer] _node]; + Node *endContainer = [[proposedRange endContainer] _node]; + if (startContainer == nil || endContainer == nil) + return nil; + + ASSERT(startContainer->document() == endContainer->document()); + + _private->coreFrame->document()->updateLayoutIgnorePendingStylesheets(); + + Position start(startContainer, [proposedRange startOffset]); + Position end(endContainer, [proposedRange endOffset]); + Position newStart = start.upstream().leadingWhitespacePosition(DOWNSTREAM, true); + if (newStart.isNull()) + newStart = start; + Position newEnd = end.downstream().trailingWhitespacePosition(DOWNSTREAM, true); + if (newEnd.isNull()) + newEnd = end; + + newStart = rangeCompliantEquivalent(newStart); + newEnd = rangeCompliantEquivalent(newEnd); + + RefPtr<Range> range = _private->coreFrame->document()->createRange(); + int exception = 0; + range->setStart(newStart.node(), newStart.offset(), exception); + range->setEnd(newStart.node(), newStart.offset(), exception); + return [DOMRange _wrapRange:range.get()]; +} + +// Determines whether whitespace needs to be added around aString to preserve proper spacing and +// punctuation when it’s inserted into the receiver’s text over charRange. Returns by reference +// in beforeString and afterString any whitespace that should be added, unless either or both are +// nil. Both are returned as nil if aString is nil or if smart insertion and deletion are disabled. +- (void)_smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)rangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString +{ + // give back nil pointers in case of early returns + if (beforeString) + *beforeString = nil; + if (afterString) + *afterString = nil; + + // inspect destination + Node *startContainer = [[rangeToReplace startContainer] _node]; + Node *endContainer = [[rangeToReplace endContainer] _node]; + + Position startPos(startContainer, [rangeToReplace startOffset]); + Position endPos(endContainer, [rangeToReplace endOffset]); + + VisiblePosition startVisiblePos = VisiblePosition(startPos, VP_DEFAULT_AFFINITY); + VisiblePosition endVisiblePos = VisiblePosition(endPos, VP_DEFAULT_AFFINITY); + + // this check also ensures startContainer, startPos, endContainer, and endPos are non-null + if (startVisiblePos.isNull() || endVisiblePos.isNull()) + return; + + bool addLeadingSpace = startPos.leadingWhitespacePosition(VP_DEFAULT_AFFINITY, true).isNull() && !isStartOfParagraph(startVisiblePos); + if (addLeadingSpace) + if (UChar previousChar = startVisiblePos.previous().characterAfter()) + addLeadingSpace = !isCharacterSmartReplaceExempt(previousChar, true); + + bool addTrailingSpace = endPos.trailingWhitespacePosition(VP_DEFAULT_AFFINITY, true).isNull() && !isEndOfParagraph(endVisiblePos); + if (addTrailingSpace) + if (UChar thisChar = endVisiblePos.characterAfter()) + addTrailingSpace = !isCharacterSmartReplaceExempt(thisChar, false); + + // inspect source + bool hasWhitespaceAtStart = false; + bool hasWhitespaceAtEnd = false; + unsigned pasteLength = [pasteString length]; + if (pasteLength > 0) { + NSCharacterSet *whiteSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + + if ([whiteSet characterIsMember:[pasteString characterAtIndex:0]]) { + hasWhitespaceAtStart = YES; + } + if ([whiteSet characterIsMember:[pasteString characterAtIndex:(pasteLength - 1)]]) { + hasWhitespaceAtEnd = YES; + } + } + + // issue the verdict + if (beforeString && addLeadingSpace && !hasWhitespaceAtStart) + *beforeString = @" "; + if (afterString && addTrailingSpace && !hasWhitespaceAtEnd) + *afterString = @" "; +} + +- (DOMDocumentFragment *)_documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString +{ + if (!_private->coreFrame || !_private->coreFrame->document()) + return 0; + + return [DOMDocumentFragment _wrapDocumentFragment:createFragmentFromMarkup(_private->coreFrame->document(), markupString, baseURLString).get()]; +} + +- (DOMDocumentFragment *)_documentFragmentWithNodesAsParagraphs:(NSArray *)nodes +{ + if (!_private->coreFrame || !_private->coreFrame->document()) + return 0; + + NSEnumerator *nodeEnum = [nodes objectEnumerator]; + Vector<Node*> nodesVector; + DOMNode *node; + while ((node = [nodeEnum nextObject])) + nodesVector.append([node _node]); + + return [DOMDocumentFragment _wrapDocumentFragment:createFragmentFromNodes(_private->coreFrame->document(), nodesVector).get()]; +} + +- (void)_replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle +{ + if (_private->coreFrame->selection()->isNone() || !fragment) + return; + + applyCommand(ReplaceSelectionCommand::create(_private->coreFrame->document(), [fragment _documentFragment], selectReplacement, smartReplace, matchStyle)); + _private->coreFrame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded); +} + +- (void)_replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle +{ + DOMDocumentFragment *fragment = [DOMDocumentFragment _wrapDocumentFragment:_private->coreFrame->document()->createDocumentFragment().get()]; + [fragment appendChild:node]; + [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:matchStyle]; +} + +- (void)_replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace +{ + DOMDocumentFragment *fragment = [self _documentFragmentWithMarkupString:markupString baseURLString:baseURLString]; + [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:NO]; +} + +- (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace +{ + [self _replaceSelectionWithFragment:kit(createFragmentFromText(_private->coreFrame->selection()->toRange().get(), text).get()) + selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:YES]; +} + +- (void)_insertParagraphSeparatorInQuotedContent +{ + if (_private->coreFrame->selection()->isNone()) + return; + + TypingCommand::insertParagraphSeparatorInQuotedContent(_private->coreFrame->document()); + _private->coreFrame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded); +} + +- (VisiblePosition)_visiblePositionForPoint:(NSPoint)point +{ + IntPoint outerPoint(point); + HitTestResult result = _private->coreFrame->eventHandler()->hitTestResultAtPoint(outerPoint, true); + Node* node = result.innerNode(); + if (!node) + return VisiblePosition(); + RenderObject* renderer = node->renderer(); + if (!renderer) + return VisiblePosition(); + VisiblePosition visiblePos = renderer->positionForCoordinates(result.localPoint().x(), result.localPoint().y()); + if (visiblePos.isNull()) + visiblePos = VisiblePosition(Position(node, 0)); + return visiblePos; +} + +- (DOMRange *)_characterRangeAtPoint:(NSPoint)point +{ + VisiblePosition position = [self _visiblePositionForPoint:point]; + if (position.isNull()) + return nil; + + VisiblePosition previous = position.previous(); + if (previous.isNotNull()) { + DOMRange *previousCharacterRange = [DOMRange _wrapRange:makeRange(previous, position).get()]; + NSRect rect = [self _firstRectForDOMRange:previousCharacterRange]; + if (NSPointInRect(point, rect)) + return previousCharacterRange; + } + + VisiblePosition next = position.next(); + if (next.isNotNull()) { + DOMRange *nextCharacterRange = [DOMRange _wrapRange:makeRange(position, next).get()]; + NSRect rect = [self _firstRectForDOMRange:nextCharacterRange]; + if (NSPointInRect(point, rect)) + return nextCharacterRange; + } + + return nil; +} + +- (DOMCSSStyleDeclaration *)_typingStyle +{ + if (!_private->coreFrame || !_private->coreFrame->typingStyle()) + return nil; + return [DOMCSSStyleDeclaration _wrapCSSStyleDeclaration:_private->coreFrame->typingStyle()->copy().get()]; +} + +- (void)_setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(EditAction)undoAction +{ + if (!_private->coreFrame) + return; + _private->coreFrame->computeAndSetTypingStyle([style _CSSStyleDeclaration], undoAction); +} + +- (void)_dragSourceMovedTo:(NSPoint)windowLoc +{ + if (!_private->coreFrame) + return; + FrameView* view = _private->coreFrame->view(); + if (!view) + return; + // FIXME: These are fake modifier keys here, but they should be real ones instead. + PlatformMouseEvent event(IntPoint(windowLoc), globalPoint(windowLoc, [view->platformWidget() window]), + LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime()); + _private->coreFrame->eventHandler()->dragSourceMovedTo(event); +} + +- (void)_dragSourceEndedAt:(NSPoint)windowLoc operation:(NSDragOperation)operation +{ + if (!_private->coreFrame) + return; + FrameView* view = _private->coreFrame->view(); + if (!view) + return; + // FIXME: These are fake modifier keys here, but they should be real ones instead. + PlatformMouseEvent event(IntPoint(windowLoc), globalPoint(windowLoc, [view->platformWidget() window]), + LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime()); + _private->coreFrame->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation); +} + +- (BOOL)_canProvideDocumentSource +{ + String mimeType = _private->coreFrame->loader()->responseMIMEType(); + + if (WebCore::DOMImplementation::isTextMIMEType(mimeType) || + Image::supportsType(mimeType) || + (_private->coreFrame->page() && _private->coreFrame->page()->pluginData()->supportsMimeType(mimeType))) + return NO; + + return YES; +} + +- (BOOL)_canSaveAsWebArchive +{ + // Currently, all documents that we can view source for + // (HTML and XML documents) can also be saved as web archives + return [self _canProvideDocumentSource]; +} + +- (void)_receivedData:(NSData *)data textEncodingName:(NSString *)textEncodingName +{ + // Set the encoding. This only needs to be done once, but it's harmless to do it again later. + String encoding = _private->coreFrame->loader()->documentLoader()->overrideEncoding(); + bool userChosen = !encoding.isNull(); + if (encoding.isNull()) + encoding = textEncodingName; + _private->coreFrame->loader()->setEncoding(encoding, userChosen); + [self _addData:data]; } @end @implementation WebFrame (WebPrivate) -// FIXME: Yhis exists only as a convenience for Safari, consider moving there. +// FIXME: This exists only as a convenience for Safari, consider moving there. - (BOOL)_isDescendantOfFrame:(WebFrame *)ancestor { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; return coreFrame && coreFrame->tree()->isDescendantOf(core(ancestor)); } -- (void)_setShouldCreateRenderers:(BOOL)frame +- (void)_setShouldCreateRenderers:(BOOL)shouldCreateRenderers { - [_private->bridge setShouldCreateRenderers:frame]; + _private->shouldCreateRenderers = shouldCreateRenderers; } - (NSColor *)_bodyBackgroundColor { - Document* document = core(self)->document(); + Document* document = _private->coreFrame->document(); if (!document) return nil; HTMLElement* body = document->body(); @@ -604,20 +1071,61 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (BOOL)_isFrameSet { - return core(self)->isFrameSet(); + return _private->coreFrame->isFrameSet(); } - (BOOL)_firstLayoutDone { - return [self _frameLoader]->firstLayoutDone(); + return _private->coreFrame->loader()->firstLayoutDone(); } - (WebFrameLoadType)_loadType { - return (WebFrameLoadType)[self _frameLoader]->loadType(); + return (WebFrameLoadType)_private->coreFrame->loader()->loadType(); +} + +- (NSRange)_selectedNSRange +{ + return [self _convertToNSRange:_private->coreFrame->selection()->toRange().get()]; +} + +- (void)_selectNSRange:(NSRange)range +{ + RefPtr<Range> domRange = [self _convertToDOMRange:range]; + if (domRange) + _private->coreFrame->selection()->setSelection(Selection(domRange.get(), SEL_DEFAULT_AFFINITY)); +} + +- (BOOL)_isDisplayingStandaloneImage +{ + Document* document = _private->coreFrame->document(); + return document && document->isImageDocument(); } -#ifndef __LP64__ +- (unsigned)_pendingFrameUnloadEventCount +{ + return _private->coreFrame->eventHandler()->pendingFrameUnloadEventCount(); +} + +- (WebIconFetcher *)fetchApplicationIcon:(id)target + selector:(SEL)selector +{ + return [WebIconFetcher _fetchApplicationIconForFrame:self + target:target + selector:selector]; +} + +- (void)_setIsDisconnected:(bool)isDisconnected +{ + _private->coreFrame->setIsDisconnected(isDisconnected); +} + +- (void)_setExcludeFromTextSearch:(bool)exclude +{ + _private->coreFrame->setExcludeFromTextSearch(exclude); +} + +#if ENABLE(NETSCAPE_PLUGIN_API) - (void)_recursive_resumeNullEventsForAllNetscapePlugins { Frame* coreFrame = core(self); @@ -627,9 +1135,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) [(WebHTMLView *)documentView _resumeNullEventsForAllNetscapePlugins]; } } -#endif -#ifndef __LP64__ - (void)_recursive_pauseNullEventsForAllNetscapePlugins { Frame* coreFrame = core(self); @@ -641,22 +1147,6 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) } #endif -- (NSRange)_selectedNSRange -{ - return [_private->bridge selectedNSRange]; -} - -- (void)_selectNSRange:(NSRange)range -{ - [_private->bridge selectNSRange:range]; -} - -- (BOOL)_isDisplayingStandaloneImage -{ - Document* document = core(self)->document(); - return document && document->isImageDocument(); -} - @end @implementation WebFrame @@ -674,7 +1164,6 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (void)dealloc { - ASSERT(_private->bridge == nil); [_private release]; --WebFrameCount; [super dealloc]; @@ -682,14 +1171,13 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (void)finalize { - ASSERT(_private->bridge == nil); --WebFrameCount; [super finalize]; } - (NSString *)name { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; if (!coreFrame) return nil; return coreFrame->tree()->name(); @@ -707,7 +1195,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (DOMDocument *)DOMDocument { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; if (!coreFrame) return nil; @@ -730,7 +1218,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (DOMHTMLElement *)frameElement { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; if (!coreFrame) return nil; return kit(coreFrame->ownerElement()); @@ -738,22 +1226,19 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) - (WebDataSource *)provisionalDataSource { - FrameLoader* frameLoader = [self _frameLoader]; - return frameLoader ? dataSource(frameLoader->provisionalDocumentLoader()) : nil; + Frame* coreFrame = _private->coreFrame; + return coreFrame ? dataSource(coreFrame->loader()->provisionalDocumentLoader()) : nil; } - (WebDataSource *)dataSource { - FrameLoader* loader = [self _frameLoader]; - if (!loader || !loader->frameHasLoaded()) - return nil; - - return [self _dataSource]; + Frame* coreFrame = _private->coreFrame; + return coreFrame && coreFrame->loader()->frameHasLoaded() ? [self _dataSource] : nil; } - (void)loadRequest:(NSURLRequest *)request { - [self _frameLoader]->load(request); + _private->coreFrame->loader()->load(request); } static NSURL *createUniqueWebDataURL() @@ -766,80 +1251,69 @@ static NSURL *createUniqueWebDataURL() return URL; } -- (void)_loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL +- (void)_loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL unreachableURL:(NSURL *)unreachableURL { KURL responseURL; - if (!URL) { - URL = [NSURL URLWithString:@"about:blank"]; + if (!baseURL) { + baseURL = blankURL(); responseURL = createUniqueWebDataURL(); } - ResourceRequest request([URL absoluteURL]); + ResourceRequest request([baseURL absoluteURL]); // hack because Mail checks for this property to detect data / archive loads [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)request.nsURLRequest()]; SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData(data), MIMEType, encodingName, [unreachableURL absoluteURL], responseURL); - [self _frameLoader]->load(request, substituteData); + _private->coreFrame->loader()->load(request, substituteData); } -- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL +- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL { if (!MIMEType) MIMEType = @"text/html"; - [self _loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:URL unreachableURL:nil]; + [self _loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:baseURL unreachableURL:nil]; } -- (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL +- (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL unreachableURL:(NSURL *)unreachableURL { NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; - [self _loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:URL unreachableURL:unreachableURL]; + [self _loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:baseURL unreachableURL:unreachableURL]; } -- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)URL +- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL { - [self _loadHTMLString:string baseURL:URL unreachableURL:nil]; + [self _loadHTMLString:string baseURL:baseURL unreachableURL:nil]; } -- (void)loadAlternateHTMLString:(NSString *)string baseURL:(NSURL *)URL forUnreachableURL:(NSURL *)unreachableURL +- (void)loadAlternateHTMLString:(NSString *)string baseURL:(NSURL *)baseURL forUnreachableURL:(NSURL *)unreachableURL { - [self _loadHTMLString:string baseURL:URL unreachableURL:unreachableURL]; + [self _loadHTMLString:string baseURL:baseURL unreachableURL:unreachableURL]; } - (void)loadArchive:(WebArchive *)archive { - WebResource *mainResource = [archive mainResource]; - if (mainResource) { - SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData([mainResource data]), [mainResource MIMEType], [mainResource textEncodingName], KURL()); - ResourceRequest request([mainResource URL]); - - // hack because Mail checks for this property to detect data / archive loads - [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)request.nsURLRequest()]; - - RefPtr<DocumentLoader> documentLoader = core(self)->loader()->client()->createDocumentLoader(request, substituteData); - - [dataSource(documentLoader.get()) _addToUnarchiveState:archive]; - - [self _frameLoader]->load(documentLoader.get()); - } + if (LegacyWebArchive* coreArchive = [archive _coreLegacyWebArchive]) + _private->coreFrame->loader()->loadArchive(coreArchive); } - (void)stopLoading { - if (FrameLoader* frameLoader = [self _frameLoader]) - frameLoader->stopForUserCancel(); + if (!_private->coreFrame) + return; + _private->coreFrame->loader()->stopForUserCancel(); } - (void)reload { - [self _frameLoader]->reload(); + _private->coreFrame->loader()->reload(); } - (WebFrame *)findFrameNamed:(NSString *)name { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; if (!coreFrame) return nil; return kit(coreFrame->tree()->find(name)); @@ -847,7 +1321,7 @@ static NSURL *createUniqueWebDataURL() - (WebFrame *)parentFrame { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; if (!coreFrame) return nil; return [[kit(coreFrame->tree()->parent()) retain] autorelease]; @@ -855,7 +1329,7 @@ static NSURL *createUniqueWebDataURL() - (NSArray *)childFrames { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; if (!coreFrame) return [NSArray array]; NSMutableArray *children = [NSMutableArray arrayWithCapacity:coreFrame->tree()->childCount()]; @@ -866,18 +1340,18 @@ static NSURL *createUniqueWebDataURL() - (WebScriptObject *)windowObject { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; if (!coreFrame) return 0; - return coreFrame->windowScriptObject(); + return coreFrame->script()->windowScriptObject(); } - (JSGlobalContextRef)globalContext { - Frame* coreFrame = core(self); + Frame* coreFrame = _private->coreFrame; if (!coreFrame) return 0; - return toGlobalRef(coreFrame->scriptProxy()->globalObject()->globalExec()); + return toGlobalRef(coreFrame->script()->globalObject()->globalExec()); } @end diff --git a/WebKit/mac/WebView/WebFrameInternal.h b/WebKit/mac/WebView/WebFrameInternal.h index 89b5b1d..5cf7690 100644 --- a/WebKit/mac/WebView/WebFrameInternal.h +++ b/WebKit/mac/WebView/WebFrameInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006 Apple Computer, 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 @@ -31,21 +31,20 @@ #import "WebFramePrivate.h" #import "WebPreferencesPrivate.h" -#ifdef __cplusplus +#import <WebCore/EditAction.h> #import <WebCore/FrameLoaderTypes.h> +#import <WebCore/SelectionController.h> #import <WebCore/Settings.h> -#endif @class DOMCSSStyleDeclaration; +@class DOMDocumentFragment; @class DOMElement; @class DOMNode; @class DOMRange; @class WebFrameView; -@class WebFrameBridge; @class WebHistoryItem; -@class WebScriptDebugger; -#ifdef __cplusplus +class WebScriptDebugger; namespace WebCore { class CSSStyleDeclaration; @@ -54,9 +53,9 @@ namespace WebCore { class Element; class Frame; class Frame; - class FrameLoader; class HistoryItem; class HTMLElement; + class HTMLFrameOwnerElement; class Node; class Page; class Range; @@ -79,6 +78,9 @@ DOMNode *kit(WebCore::Node*); WebCore::Document* core(DOMDocument *); DOMDocument *kit(WebCore::Document*); +WebCore::DocumentFragment* core(DOMDocumentFragment *); +DOMDocumentFragment *kit(WebCore::DocumentFragment*); + WebCore::HTMLElement* core(DOMHTMLElement *); DOMHTMLElement *kit(WebCore::HTMLElement*); @@ -89,80 +91,100 @@ WebCore::Page* core(WebView *); WebView *kit(WebCore::Page*); WebCore::EditableLinkBehavior core(WebKitEditableLinkBehavior); -WebKitEditableLinkBehavior kit(WebCore::EditableLinkBehavior); WebView *getWebView(WebFrame *webFrame); -@interface WebFramePrivate : NSObject -{ +@interface WebFramePrivate : NSObject { @public + WebCore::Frame* coreFrame; WebFrameView *webFrameView; - - WebFrameBridge *bridge; - - WebScriptDebugger *scriptDebugger; + WebScriptDebugger* scriptDebugger; id internalLoadDelegate; + BOOL shouldCreateRenderers; } @end -#else -struct WebCoreHistoryItem; -#endif +@protocol WebCoreRenderTreeCopier <NSObject> +- (NSObject *)nodeWithName:(NSString *)name position:(NSPoint)position rect:(NSRect)rect view:(NSView *)view children:(NSArray *)children; +@end @interface WebFrame (WebInternal) -- (void)_updateBackground; ++ (void)_createMainFrameWithPage:(WebCore::Page*)page frameName:(const WebCore::String&)name frameView:(WebFrameView *)frameView; ++ (PassRefPtr<WebCore::Frame>)_createSubframeWithOwnerElement:(WebCore::HTMLFrameOwnerElement*)ownerElement frameName:(const WebCore::String&)name frameView:(WebFrameView *)frameView; +- (id)_initWithWebFrameView:(WebFrameView *)webFrameView webView:(WebView *)webView; + +- (void)_clearCoreFrame; + +- (void)_updateBackgroundAndUpdatesWhileOffscreen; - (void)_setInternalLoadDelegate:(id)internalLoadDelegate; - (id)_internalLoadDelegate; #ifndef BUILDING_ON_TIGER - (void)_unmarkAllBadGrammar; #endif - (void)_unmarkAllMisspellings; -// Note that callers should not perform any ops on these views that could change the set of frames -- (NSArray *)_documentViews; - (BOOL)_hasSelection; - (void)_clearSelection; - (WebFrame *)_findFrameWithSelection; - (void)_clearSelectionInOtherFrames; -#ifdef __cplusplus -- (id)_initWithWebFrameView:(WebFrameView *)fv webView:(WebView *)v bridge:(WebFrameBridge *)bridge; -#endif -- (BOOL)_isMainFrame; +- (void)_attachScriptDebugger; +- (void)_detachScriptDebugger; -#ifdef __cplusplus +// dataSource reports null for the initial empty document's data source; this is needed +// to preserve compatibility with Mail and Safari among others. But internal to WebKit, +// we need to be able to get the initial data source as well, so the _dataSource method +// should be used instead. +- (WebDataSource *)_dataSource; -- (WebCore::FrameLoader*)_frameLoader; -- (WebDataSource *)_dataSourceForDocumentLoader:(WebCore::DocumentLoader*)loader; +- (BOOL)_needsLayout; +- (void)_drawRect:(NSRect)rect contentsOnly:(BOOL)contentsOnly; +- (BOOL)_getVisibleRect:(NSRect*)rect; +- (NSArray*)_computePageRectsWithPrintWidthScaleFactor:(float)printWidthScaleFactor printHeight:(float)printHeight; -- (void)_addDocumentLoader:(WebCore::DocumentLoader*)loader toUnarchiveState:(WebArchive *)archive; +- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string; +- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture; -#endif +- (NSString *)_selectedString; +- (NSString *)_stringForRange:(DOMRange *)range; -- (WebFrameBridge *)_bridge; +- (NSString *)_markupStringFromRange:(DOMRange *)range nodes:(NSArray **)nodes; -- (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer intoChild:(WebFrame *)childFrame; +- (NSRect)_caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity; +- (NSRect)_firstRectForDOMRange:(DOMRange *)range; +- (void)_scrollDOMRangeToVisible:(DOMRange *)range; -- (void)_viewWillMoveToHostWindow:(NSWindow *)hostWindow; -- (void)_viewDidMoveToHostWindow; +- (id)_accessibilityTree; -- (void)_addChild:(WebFrame *)child; +- (DOMRange *)_rangeByAlteringCurrentSelection:(WebCore::SelectionController::EAlteration)alteration direction:(WebCore::SelectionController::EDirection)direction granularity:(WebCore::TextGranularity)granularity; +- (void)_smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)charRangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString; +- (NSRange)_convertToNSRange:(WebCore::Range*)range; +- (DOMRange *)_convertNSRangeToDOMRange:(NSRange)range; +- (NSRange)_convertDOMRangeToNSRange:(DOMRange *)range; -+ (CFAbsoluteTime)_timeOfLastCompletedLoad; +- (DOMDocumentFragment *)_documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString; +- (DOMDocumentFragment *)_documentFragmentWithNodesAsParagraphs:(NSArray *)nodes; -- (int)_numPendingOrLoadingRequests:(BOOL)recurse; +- (void)_replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle; +- (void)_replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle; +- (void)_replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace; +- (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace; -- (void)_reloadForPluginChanges; +- (void)_insertParagraphSeparatorInQuotedContent; -- (void)_attachScriptDebugger; -- (void)_detachScriptDebugger; +- (DOMRange *)_characterRangeAtPoint:(NSPoint)point; -// dataSource reports null for the initial empty document's data source; this is needed -// to preserve compatibility with Mail and Safari among others. But internal to WebKit, -// we need to be able to get the initial data source as well, so the _dataSource method -// should be used instead. -- (WebDataSource *)_dataSource; +- (DOMCSSStyleDeclaration *)_typingStyle; +- (void)_setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(WebCore::EditAction)undoAction; + +- (void)_dragSourceMovedTo:(NSPoint)windowLoc; +- (void)_dragSourceEndedAt:(NSPoint)windowLoc operation:(NSDragOperation)operation; + +- (BOOL)_canProvideDocumentSource; +- (BOOL)_canSaveAsWebArchive; + +- (void)_receivedData:(NSData *)data textEncodingName:(NSString *)textEncodingName; @end diff --git a/WebKit/mac/WebView/WebFrameLoadDelegate.h b/WebKit/mac/WebView/WebFrameLoadDelegate.h index b463988..e5f1c7c 100644 --- a/WebKit/mac/WebView/WebFrameLoadDelegate.h +++ b/WebKit/mac/WebView/WebFrameLoadDelegate.h @@ -27,6 +27,7 @@ */ #import <Cocoa/Cocoa.h> +#import <JavaScriptCore/WebKitAvailability.h> @class NSError; @class WebFrame; @@ -191,6 +192,6 @@ @discussion This method is deprecated. Consider using webView:didClearWindowObject:forFrame: instead. */ -- (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject; +- (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0); @end diff --git a/WebKit/mac/WebView/WebFramePrivate.h b/WebKit/mac/WebView/WebFramePrivate.h index 4595572..428c142 100644 --- a/WebKit/mac/WebView/WebFramePrivate.h +++ b/WebKit/mac/WebView/WebFramePrivate.h @@ -31,6 +31,11 @@ #import <WebKit/WebFrame.h> #import <JavaScriptCore/JSBase.h> +#if !defined(ENABLE_NETSCAPE_PLUGIN_API) +#define ENABLE_NETSCAPE_PLUGIN_API 1 +#endif + +@class WebIconFetcher; @class WebScriptObject; // Keys for accessing the values in the page cache dictionary. @@ -57,10 +62,6 @@ typedef enum { - (BOOL)_isFrameSet; - (BOOL)_firstLayoutDone; - (WebFrameLoadType)_loadType; -#ifndef __LP64__ -- (void)_recursive_resumeNullEventsForAllNetscapePlugins; -- (void)_recursive_pauseNullEventsForAllNetscapePlugins; -#endif // These methods take and return NSRanges based on the root editable element as the positional base. // This fits with AppKit's idea of an input context. These methods are slow compared to their DOMRange equivalents. @@ -70,4 +71,17 @@ typedef enum { - (BOOL)_isDisplayingStandaloneImage; +- (unsigned) _pendingFrameUnloadEventCount; + +- (WebIconFetcher *)fetchApplicationIcon:(id)target + selector:(SEL)selector; + +- (void)_setIsDisconnected:(bool)isDisconnected; +- (void)_setExcludeFromTextSearch:(bool)exclude; + +#if ENABLE_NETSCAPE_PLUGIN_API +- (void)_recursive_resumeNullEventsForAllNetscapePlugins; +- (void)_recursive_pauseNullEventsForAllNetscapePlugins; +#endif + @end diff --git a/WebKit/mac/WebView/WebFrameView.mm b/WebKit/mac/WebView/WebFrameView.mm index ef1a4bd..e9c0aae 100644 --- a/WebKit/mac/WebView/WebFrameView.mm +++ b/WebKit/mac/WebView/WebFrameView.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006 Apple Computer, 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 @@ -31,10 +31,9 @@ #import "WebClipView.h" #import "WebDataSourcePrivate.h" #import "WebDocument.h" -#import "WebDynamicScrollBarsView.h" +#import "WebDynamicScrollBarsViewInternal.h" #import "WebFrame.h" #import "WebFrameInternal.h" -#import "WebFrameBridge.h" #import "WebFrameViewInternal.h" #import "WebFrameViewPrivate.h" #import "WebHistoryItemInternal.h" @@ -55,16 +54,18 @@ #import "WebViewInternal.h" #import "WebViewPrivate.h" #import <Foundation/NSURLRequest.h> -#import <JavaScriptCore/Assertions.h> #import <WebCore/DragController.h> +#import <WebCore/EventHandler.h> #import <WebCore/Frame.h> #import <WebCore/FrameView.h> #import <WebCore/HistoryItem.h> #import <WebCore/Page.h> +#import <WebCore/RenderPart.h> #import <WebCore/ThreadCheck.h> #import <WebCore/WebCoreFrameView.h> #import <WebCore/WebCoreView.h> #import <WebKitSystemInterface.h> +#import <wtf/Assertions.h> using namespace WebCore; @@ -81,35 +82,19 @@ enum { SpaceKey = 0x0020 }; -@interface WebFrameView (WebFrameViewFileInternal) <WebCoreBridgeHolder> +@interface WebFrameView (WebFrameViewFileInternal) <WebCoreFrameView> - (float)_verticalKeyboardScrollDistance; -- (WebCoreFrameBridge *) webCoreBridge; @end @interface WebFrameViewPrivate : NSObject { @public WebFrame *webFrame; WebDynamicScrollBarsView *frameScrollView; - - // These margin values are used to temporarily hold the margins of a frame until - // we have the appropriate document view type. - int marginWidth; - int marginHeight; } @end @implementation WebFrameViewPrivate -- init -{ - [super init]; - - marginWidth = -1; - marginHeight = -1; - - return self; -} - - (void)dealloc { [frameScrollView release]; @@ -126,9 +111,9 @@ enum { return [[self _scrollView] verticalLineScroll]; } -- (WebCoreFrameBridge *) webCoreBridge +- (Frame*)_web_frame { - return [_private->webFrame _bridge]; + return core(_private->webFrame); } @end @@ -141,26 +126,6 @@ enum { return [_private->webFrame webView]; } -- (void)_setMarginWidth:(int)w -{ - _private->marginWidth = w; -} - -- (int)_marginWidth -{ - return _private->marginWidth; -} - -- (void)_setMarginHeight:(int)h -{ - _private->marginHeight = h; -} - -- (int)_marginHeight -{ - return _private->marginHeight; -} - - (void)_setDocumentView:(NSView <WebDocumentView> *)view { WebDynamicScrollBarsView *sv = [self _scrollView]; @@ -285,6 +250,33 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl return [WebView _viewClass:&viewClass andRepresentationClass:nil forMIMEType:MIMEType] ? viewClass : nil; } +- (void)_install +{ + ASSERT(_private->webFrame); + ASSERT(_private->frameScrollView); + + Frame* frame = core(_private->webFrame); + + ASSERT(frame); + ASSERT(frame->page()); + + // If this isn't the main frame, it must have an owner element set, or it + // won't ever get installed in the view hierarchy. + ASSERT(frame == frame->page()->mainFrame() || frame->ownerElement()); + + FrameView* view = frame->view(); + + view->setPlatformWidget(_private->frameScrollView); + + // FIXME: Frame tries to do this too. Is this code needed? + if (RenderPart* owner = frame->ownerRenderer()) { + owner->setWidget(view); + // Now the render part owns the view, so we don't any more. + } + + view->initScrollbars(); +} + @end @implementation WebFrameView @@ -373,18 +365,17 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (void)setAllowsScrolling:(BOOL)flag { - WebDynamicScrollBarsView *scrollView = [self _scrollView]; - [scrollView setAllowsScrolling:flag]; WebCore::Frame *frame = core([self webFrame]); - if (WebCore::FrameView *view = frame? frame->view() : 0) { - view->setHScrollbarMode((WebCore::ScrollbarMode)[scrollView horizontalScrollingMode]); - view->setVScrollbarMode((WebCore::ScrollbarMode)[scrollView verticalScrollingMode]); - } + if (WebCore::FrameView *view = frame? frame->view() : 0) + view->setCanHaveScrollbars(flag); } - (BOOL)allowsScrolling { - return [[self _scrollView] allowsScrolling]; + WebCore::Frame *frame = core([self webFrame]); + if (WebCore::FrameView *view = frame? frame->view() : 0) + return view->canHaveScrollbars(); + return YES; } - (NSView <WebDocumentView> *)documentView @@ -467,6 +458,37 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl } } +- (NSRect)visibleRect +{ + // This method can be called beneath -[NSView dealloc] after we have cleared _private. + if (!_private) + return [super visibleRect]; + + // FIXME: <rdar://problem/6213380> This method does not work correctly with transforms, for two reasons: + // 1) [super visibleRect] does not account for the transform, since it is not represented + // in the NSView hierarchy. + // 2) -_getVisibleRect: does not correct for transforms. + + NSRect rendererVisibleRect; + if (![[self webFrame] _getVisibleRect:&rendererVisibleRect]) + return [super visibleRect]; + + if (NSIsEmptyRect(rendererVisibleRect)) + return NSZeroRect; + + NSRect viewVisibleRect = [super visibleRect]; + if (NSIsEmptyRect(viewVisibleRect)) + return NSZeroRect; + + NSRect frame = [self frame]; + // rendererVisibleRect is in the parent's coordinate space, and frame is in the superview's coordinate space. + // The return value from this method needs to be in this view's coordinate space. We get that right by subtracting + // the origins (and correcting for flipping), but when we support transforms, we will need to do better than this. + rendererVisibleRect.origin.x -= frame.origin.x; + rendererVisibleRect.origin.y = NSMaxY(frame) - NSMaxY(rendererVisibleRect); + return NSIntersectionRect(rendererVisibleRect, viewVisibleRect); +} + - (void)setFrameSize:(NSSize)size { if (!NSEqualSizes(size, [self frame].size) && [[[self webFrame] webView] drawsBackground]) { @@ -475,20 +497,20 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl [super setFrameSize:size]; } -- (WebFrameBridge *)_bridge -{ - return [[self webFrame] _bridge]; -} - -- (BOOL)_scrollOverflowInDirection:(WebScrollDirection)direction granularity:(WebScrollGranularity)granularity +- (BOOL)_scrollOverflowInDirection:(ScrollDirection)direction granularity:(ScrollGranularity)granularity { // scrolling overflows is only applicable if we're dealing with an WebHTMLView - return ([[self documentView] isKindOfClass:[WebHTMLView class]] && [[self _bridge] scrollOverflowInDirection:direction granularity:granularity]); + if (![[self documentView] isKindOfClass:[WebHTMLView class]]) + return NO; + Frame* frame = core([self webFrame]); + if (!frame) + return NO; + return frame->eventHandler()->scrollOverflow(direction, granularity); } - (void)scrollToBeginningOfDocument:(id)sender { - if (![self _scrollOverflowInDirection:WebScrollUp granularity:WebScrollDocument]) { + if (![self _scrollOverflowInDirection:ScrollUp granularity:ScrollByDocument]) { if (![self _hasScrollBars]) { [[self _largestChildWithScrollBars] scrollToBeginningOfDocument:sender]; @@ -501,7 +523,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (void)scrollToEndOfDocument:(id)sender { - if (![self _scrollOverflowInDirection:WebScrollDown granularity:WebScrollDocument]) { + if (![self _scrollOverflowInDirection:ScrollDown granularity:ScrollByDocument]) { if (![self _hasScrollBars]) { [[self _largestChildWithScrollBars] scrollToEndOfDocument:sender]; @@ -557,7 +579,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (BOOL)_pageVertically:(BOOL)up { - if ([self _scrollOverflowInDirection:up ? WebScrollUp : WebScrollDown granularity:WebScrollPage]) + if ([self _scrollOverflowInDirection:up ? ScrollUp : ScrollDown granularity:ScrollByPage]) return YES; if (![self _hasScrollBars]) @@ -569,7 +591,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (BOOL)_pageHorizontally:(BOOL)left { - if ([self _scrollOverflowInDirection:left ? WebScrollLeft : WebScrollRight granularity:WebScrollPage]) + if ([self _scrollOverflowInDirection:left ? ScrollLeft : ScrollRight granularity:ScrollByPage]) return YES; if (![self _hasScrollBars]) @@ -581,7 +603,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (BOOL)_scrollLineVertically:(BOOL)up { - if ([self _scrollOverflowInDirection:up ? WebScrollUp : WebScrollDown granularity:WebScrollLine]) + if ([self _scrollOverflowInDirection:up ? ScrollUp : ScrollDown granularity:ScrollByLine]) return YES; if (![self _hasScrollBars]) @@ -593,7 +615,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl - (BOOL)_scrollLineHorizontally:(BOOL)left { - if ([self _scrollOverflowInDirection:left ? WebScrollLeft : WebScrollRight granularity:WebScrollLine]) + if ([self _scrollOverflowInDirection:left ? ScrollLeft : ScrollRight granularity:ScrollByLine]) return YES; if (![self _hasScrollBars]) @@ -645,7 +667,8 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl NSString *characters = [event characters]; int index, count; BOOL callSuper = YES; - BOOL maintainsBackForwardList = core([self webFrame])->page()->backForwardList()->enabled() ? YES : NO; + Frame* coreFrame = [self _web_frame]; + BOOL maintainsBackForwardList = coreFrame && coreFrame->page()->backForwardList()->enabled() ? YES : NO; count = [characters length]; for (index = 0; index < count; ++index) { @@ -928,33 +951,34 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl ASSERT([customClass isSubclassOfClass:[WebDynamicScrollBarsView class]]); if (customClass == [_private->frameScrollView class]) return; - if ([customClass isSubclassOfClass:[WebDynamicScrollBarsView class]]) { - WebDynamicScrollBarsView *oldScrollView = _private->frameScrollView; // already retained - NSView <WebDocumentView> *documentView = [[self documentView] retain]; - - WebDynamicScrollBarsView *scrollView = [[customClass alloc] initWithFrame:[oldScrollView frame]]; - [scrollView setContentView:[[[WebClipView alloc] initWithFrame:[scrollView bounds]] autorelease]]; - [scrollView setDrawsBackground:[oldScrollView drawsBackground]]; - [scrollView setHasVerticalScroller:[oldScrollView hasVerticalScroller]]; - [scrollView setHasHorizontalScroller:[oldScrollView hasHorizontalScroller]]; - [scrollView setAutoresizingMask:[oldScrollView autoresizingMask]]; - [scrollView setLineScroll:[oldScrollView lineScroll]]; - [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. - [super setNextKeyView:scrollView]; - - _private->frameScrollView = scrollView; - - [self _setDocumentView:documentView]; - [[self _bridge] installInFrame:scrollView]; - - [oldScrollView removeFromSuperview]; - [oldScrollView release]; - [documentView release]; - } + if (![customClass isSubclassOfClass:[WebDynamicScrollBarsView class]]) + return; + + WebDynamicScrollBarsView *oldScrollView = _private->frameScrollView; // already retained + NSView <WebDocumentView> *documentView = [[self documentView] retain]; + + WebDynamicScrollBarsView *scrollView = [[customClass alloc] initWithFrame:[oldScrollView frame]]; + [scrollView setContentView:[[[WebClipView alloc] initWithFrame:[scrollView bounds]] autorelease]]; + [scrollView setDrawsBackground:[oldScrollView drawsBackground]]; + [scrollView setHasVerticalScroller:[oldScrollView hasVerticalScroller]]; + [scrollView setHasHorizontalScroller:[oldScrollView hasHorizontalScroller]]; + [scrollView setAutoresizingMask:[oldScrollView autoresizingMask]]; + [scrollView setLineScroll:[oldScrollView lineScroll]]; + [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. + [super setNextKeyView:scrollView]; + + _private->frameScrollView = scrollView; + + [self _setDocumentView:documentView]; + [self _install]; + + [oldScrollView removeFromSuperview]; + [oldScrollView release]; + [documentView release]; } @end diff --git a/WebKit/mac/WebView/WebFrameViewInternal.h b/WebKit/mac/WebView/WebFrameViewInternal.h index 0304617..726b62e 100644 --- a/WebKit/mac/WebView/WebFrameViewInternal.h +++ b/WebKit/mac/WebView/WebFrameViewInternal.h @@ -37,14 +37,11 @@ - (void)_setDocumentView:(NSView <WebDocumentView> *)view; - (NSView <WebDocumentView> *)_makeDocumentViewForDataSource:(WebDataSource *)dataSource; - (void)_setWebFrame:(WebFrame *)webFrame; -- (int)_marginWidth; -- (int)_marginHeight; -- (void)_setMarginWidth:(int)w; -- (void)_setMarginHeight:(int)h; - (float)_verticalPageScrollDistance; + (NSMutableDictionary *)_viewTypesAllowImageTypeOmission:(BOOL)allowImageTypeOmission; + (Class)_viewClassForMIMEType:(NSString *)MIMEType; + (BOOL)_canShowMIMETypeAsHTML:(NSString *)MIMEType; - (WebDynamicScrollBarsView *)_scrollView; +- (void)_install; @end diff --git a/WebKit/mac/WebView/WebHTMLRepresentation.mm b/WebKit/mac/WebView/WebHTMLRepresentation.mm index 1a25ade..4b4d11e 100644 --- a/WebKit/mac/WebView/WebHTMLRepresentation.mm +++ b/WebKit/mac/WebView/WebHTMLRepresentation.mm @@ -34,7 +34,6 @@ #import "WebBasePluginPackage.h" #import "WebDataSourceInternal.h" #import "WebDocumentPrivate.h" -#import "WebFrameBridge.h" #import "WebFrameInternal.h" #import "WebKitNSStringExtras.h" #import "WebKitStatisticsPrivate.h" @@ -43,22 +42,26 @@ #import "WebResourcePrivate.h" #import "WebView.h" #import <Foundation/NSURLResponse.h> -#import <JavaScriptCore/Assertions.h> #import <WebCore/Document.h> #import <WebCore/DocumentLoader.h> #import <WebCore/Frame.h> #import <WebCore/FrameLoader.h> +#import <WebCore/FrameLoaderClient.h> +#import <WebCore/HTMLFormControlElement.h> +#import <WebCore/HTMLInputElement.h> +#import <WebCore/HTMLNames.h> #import <WebCore/MIMETypeRegistry.h> #import <WebCore/Range.h> +#import <WebCore/TextResourceDecoder.h> +#import <WebKit/DOMHTMLInputElement.h> +#import <wtf/Assertions.h> using namespace WebCore; +using namespace HTMLNames; -@interface WebHTMLRepresentationPrivate : NSObject -{ +@interface WebHTMLRepresentationPrivate : NSObject { @public WebDataSource *dataSource; - WebFrameBridge *bridge; - NSData *parsedArchiveData; BOOL hasSentResponseToPlugin; id <WebPluginManualLoader> manualLoader; @@ -67,13 +70,6 @@ using namespace WebCore; @end @implementation WebHTMLRepresentationPrivate - -- (void)dealloc -{ - [parsedArchiveData release]; - [super dealloc]; -} - @end @implementation WebHTMLRepresentation @@ -144,11 +140,6 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) [super finalize]; } -- (WebFrameBridge *)_bridge -{ - return _private->bridge; -} - - (void)_redirectDataToManualLoader:(id<WebPluginManualLoader>)manualLoader forPluginView:(NSView *)pluginView; { _private->manualLoader = manualLoader; @@ -158,7 +149,6 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) - (void)setDataSource:(WebDataSource *)dataSource { _private->dataSource = dataSource; - _private->bridge = [[dataSource webFrame] _bridge]; } - (BOOL)_isDisplayingWebArchive @@ -168,9 +158,15 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) - (void)receivedData:(NSData *)data withDataSource:(WebDataSource *)dataSource { - if ([dataSource webFrame] && ![self _isDisplayingWebArchive]) { + WebFrame *webFrame = [dataSource webFrame]; + if (webFrame) { if (!_private->pluginView) - [_private->bridge receivedData:data textEncodingName:[[_private->dataSource response] textEncodingName]]; + [webFrame _receivedData:data textEncodingName:[[_private->dataSource response] textEncodingName]]; + + // If the document is a stand-alone media document, now is the right time to cancel the WebKit load + Frame* coreFrame = core(webFrame); + if (coreFrame->document() && coreFrame->document()->isMediaDocument()) + coreFrame->loader()->documentLoader()->cancelMainResourceLoad(coreFrame->loader()->client()->pluginWillHandleLoadError(coreFrame->loader()->documentLoader()->response())); if (_private->pluginView) { if (!_private->hasSentResponseToPlugin) { @@ -190,31 +186,6 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) } } -- (void)_loadDataSourceAsWebArchive -{ - WebArchive *archive = [[WebArchive alloc] initWithData:[_private->dataSource data]]; - WebResource *mainResource = [archive mainResource]; - if (!mainResource) { - [archive release]; - return; - } - - NSData *data = [mainResource data]; - [data retain]; - [_private->parsedArchiveData release]; - _private->parsedArchiveData = data; - - [_private->dataSource _addToUnarchiveState:archive]; - [archive release]; - - WebFrame *webFrame = [_private->dataSource webFrame]; - - if (!webFrame) - return; - - core(webFrame)->loader()->continueLoadWithData(SharedBuffer::wrapNSData(data).get(), [mainResource MIMEType], [mainResource textEncodingName], [mainResource URL]); -} - - (void)finishedLoadingWithDataSource:(WebDataSource *)dataSource { WebFrame *frame = [dataSource webFrame]; @@ -225,13 +196,12 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) } if (frame) { - if ([self _isDisplayingWebArchive]) - [self _loadDataSourceAsWebArchive]; - else - // Telling the bridge we received some data and passing nil as the data is our + if (![self _isDisplayingWebArchive]) { + // Telling the frame we received some data and passing nil as the data is our // way to get work done that is normally done when the first bit of data is // received, even for the case of a document with no data (like about:blank). - [_private->bridge receivedData:nil textEncodingName:[[_private->dataSource response] textEncodingName]]; + [frame _receivedData:nil textEncodingName:[[_private->dataSource response] textEncodingName]]; + } WebView *webView = [frame webView]; if ([webView isEditable]) @@ -241,20 +211,37 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) - (BOOL)canProvideDocumentSource { - return [_private->bridge canProvideDocumentSource]; + return [[_private->dataSource webFrame] _canProvideDocumentSource]; } - (BOOL)canSaveAsWebArchive { - return [_private->bridge canSaveAsWebArchive]; + return [[_private->dataSource webFrame] _canSaveAsWebArchive]; } - (NSString *)documentSource { - if ([self _isDisplayingWebArchive]) - return [[[NSString alloc] initWithData:_private->parsedArchiveData encoding:NSUTF8StringEncoding] autorelease]; + if ([self _isDisplayingWebArchive]) { + SharedBuffer *parsedArchiveData = [_private->dataSource _documentLoader]->parsedArchiveData(); + NSData *nsData = parsedArchiveData ? parsedArchiveData->createNSData() : nil; + NSString *result = [[NSString alloc] initWithData:nsData encoding:NSUTF8StringEncoding]; + [nsData release]; + return [result autorelease]; + } - return [_private->bridge stringWithData:[_private->dataSource data]]; + Frame* coreFrame = core([_private->dataSource webFrame]); + if (!coreFrame) + return nil; + Document* document = coreFrame->document(); + if (!document) + return nil; + TextResourceDecoder* decoder = document->decoder(); + if (!decoder) + return nil; + NSData *data = [_private->dataSource data]; + if (!data) + return nil; + return decoder->encoding().decode(reinterpret_cast<const char*>([data bytes]), [data length]); } - (NSString *)title @@ -264,7 +251,7 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) - (DOMDocument *)DOMDocument { - return [[_private->bridge webFrame] DOMDocument]; + return [[_private->dataSource webFrame] DOMDocument]; } - (NSAttributedString *)attributedText @@ -275,48 +262,89 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second) - (NSAttributedString *)attributedStringFrom:(DOMNode *)startNode startOffset:(int)startOffset to:(DOMNode *)endNode endOffset:(int)endOffset { - Range range([startNode _node]->document(), [startNode _node], startOffset, [endNode _node], endOffset); - return [NSAttributedString _web_attributedStringFromRange:&range]; + return [NSAttributedString _web_attributedStringFromRange:Range::create([startNode _node]->document(), [startNode _node], startOffset, [endNode _node], endOffset).get()]; +} + +static HTMLFormElement* formElementFromDOMElement(DOMElement *element) +{ + Node* node = [element _node]; + return node && node->hasTagName(formTag) ? static_cast<HTMLFormElement *>(node) : 0; } - (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form { - return [_private->bridge elementWithName:name inForm:form]; + HTMLFormElement* formElement = formElementFromDOMElement(form); + if (!formElement) + return nil; + Vector<HTMLFormControlElement*>& elements = formElement->formElements; + AtomicString targetName = name; + for (unsigned i = 0; i < elements.size(); i++) { + HTMLFormControlElement* elt = elements[i]; + if (elt->name() == targetName) + return kit(elt); + } + return nil; +} + +static HTMLInputElement* inputElementFromDOMElement(DOMElement* element) +{ + Node* node = [element _node]; + return node && node->hasTagName(inputTag) ? static_cast<HTMLInputElement*>(node) : 0; } - (BOOL)elementDoesAutoComplete:(DOMElement *)element { - return [_private->bridge elementDoesAutoComplete:element]; + HTMLInputElement* inputElement = inputElementFromDOMElement(element); + return inputElement + && inputElement->inputType() == HTMLInputElement::TEXT + && inputElement->autoComplete(); } - (BOOL)elementIsPassword:(DOMElement *)element { - return [_private->bridge elementIsPassword:element]; + HTMLInputElement* inputElement = inputElementFromDOMElement(element); + return inputElement + && inputElement->inputType() == HTMLInputElement::PASSWORD; } - (DOMElement *)formForElement:(DOMElement *)element { - return [_private->bridge formForElement:element]; + HTMLInputElement* inputElement = inputElementFromDOMElement(element); + return inputElement ? kit(inputElement->form()) : 0; } - (DOMElement *)currentForm { - return [_private->bridge currentForm]; + return kit(core([_private->dataSource webFrame])->currentForm()); } - (NSArray *)controlsInForm:(DOMElement *)form { - return [_private->bridge controlsInForm:form]; + HTMLFormElement* formElement = formElementFromDOMElement(form); + if (!formElement) + return nil; + NSMutableArray *results = nil; + Vector<HTMLFormControlElement*>& elements = formElement->formElements; + for (unsigned i = 0; i < elements.size(); i++) { + if (elements[i]->isEnumeratable()) { // Skip option elements, other duds + DOMElement* de = kit(elements[i]); + if (!results) + results = [NSMutableArray arrayWithObject:de]; + else + [results addObject:de]; + } + } + return results; } - (NSString *)searchForLabels:(NSArray *)labels beforeElement:(DOMElement *)element { - return [_private->bridge searchForLabels:labels beforeElement:element]; + return core([_private->dataSource webFrame])->searchForLabelsBeforeElement(labels, core(element)); } - (NSString *)matchLabels:(NSArray *)labels againstElement:(DOMElement *)element { - return [_private->bridge matchLabels:labels againstElement:element]; + return core([_private->dataSource webFrame])->matchLabelsAgainstElement(labels, core(element)); } @end diff --git a/WebKit/mac/WebView/WebScriptDebugDelegatePrivate.h b/WebKit/mac/WebView/WebHTMLRepresentationInternal.h index 6bda4a7..d42b400 100644 --- a/WebKit/mac/WebView/WebScriptDebugDelegatePrivate.h +++ b/WebKit/mac/WebView/WebHTMLRepresentationInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,16 +26,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import <WebKit/WebScriptDebugDelegate.h> -#import <WebCore/WebCoreScriptDebugger.h> - -@interface WebScriptDebugger : NSObject <WebScriptDebugger> -{ -@private - WebFrame *_webFrame; - WebCoreScriptDebugger *_debugger; -} - -- (WebScriptDebugger *)initWithWebFrame:(WebFrame *)webFrame; +#import <WebKit/WebHTMLRepresentationPrivate.h> +@interface WebHTMLRepresentation (WebInternal) ++ (NSArray *)supportedNonImageMIMETypes; @end diff --git a/WebKit/mac/WebView/WebHTMLRepresentationPrivate.h b/WebKit/mac/WebView/WebHTMLRepresentationPrivate.h index 3737bb2..d0c18ab 100644 --- a/WebKit/mac/WebView/WebHTMLRepresentationPrivate.h +++ b/WebKit/mac/WebView/WebHTMLRepresentationPrivate.h @@ -28,11 +28,9 @@ #import <WebKit/WebHTMLRepresentation.h> -@class WebFrameBridge; @protocol WebPluginManualLoader; @interface WebHTMLRepresentation (WebPrivate) -- (WebFrameBridge *)_bridge; - (void)_redirectDataToManualLoader:(id<WebPluginManualLoader>)manualLoader forPluginView:(NSView *)pluginView; - (void)printDOMTree; @end diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm index 987d7df..4d9b3a8 100644 --- a/WebKit/mac/WebView/WebHTMLView.mm +++ b/WebKit/mac/WebView/WebHTMLView.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. * (C) 2006, 2007 Graham Dennis (graham.dennis@gmail.com) * * Redistribution and use in source and binary forms, with or without @@ -32,8 +32,7 @@ #import "DOMNodeInternal.h" #import "DOMRangeInternal.h" #import "WebArchive.h" -#import "WebArchiver.h" -#import "WebBaseNetscapePluginViewInternal.h" +#import "WebBaseNetscapePluginView.h" #import "WebClipView.h" #import "WebDOMOperationsPrivate.h" #import "WebDataSourceInternal.h" @@ -42,7 +41,6 @@ #import "WebDynamicScrollBarsView.h" #import "WebEditingDelegate.h" #import "WebElementDictionary.h" -#import "WebFrameBridge.h" #import "WebFrameInternal.h" #import "WebFramePrivate.h" #import "WebFrameViewInternal.h" @@ -53,6 +51,7 @@ #import "WebKitPluginContainerView.h" #import "WebKitVersionChecks.h" #import "WebLocalizableStrings.h" +#import "WebNodeHighlight.h" #import "WebNSAttributedStringExtras.h" #import "WebNSEventExtras.h" #import "WebNSFileManagerExtras.h" @@ -62,12 +61,12 @@ #import "WebNSPrintOperationExtras.h" #import "WebNSURLExtras.h" #import "WebNSViewExtras.h" -#import "WebNetscapePluginEmbeddedView.h" #import "WebPluginController.h" #import "WebPreferences.h" #import "WebPreferencesPrivate.h" #import "WebResourcePrivate.h" #import "WebStringTruncator.h" +#import "WebTypesInternal.h" #import "WebUIDelegatePrivate.h" #import "WebViewInternal.h" #import <AppKit/NSAccessibility.h> @@ -79,11 +78,11 @@ #import <WebCore/ContextMenu.h> #import <WebCore/ContextMenuController.h> #import <WebCore/Document.h> +#import <WebCore/DocumentFragment.h> #import <WebCore/Editor.h> #import <WebCore/EditorDeleteAction.h> #import <WebCore/Element.h> #import <WebCore/EventHandler.h> -#import <WebCore/EventNames.h> #import <WebCore/ExceptionHandlers.h> #import <WebCore/DragController.h> #import <WebCore/FloatRect.h> @@ -95,6 +94,7 @@ #import <WebCore/HTMLNames.h> #import <WebCore/Image.h> #import <WebCore/KeyboardEvent.h> +#import <WebCore/LegacyWebArchive.h> #import <WebCore/MIMETypeRegistry.h> #import <WebCore/Page.h> #import <WebCore/PlatformKeyboardEvent.h> @@ -102,13 +102,16 @@ #import <WebCore/Range.h> #import <WebCore/SelectionController.h> #import <WebCore/SharedBuffer.h> +#import <WebCore/SimpleFontData.h> #import <WebCore/Text.h> #import <WebCore/WebCoreObjCExtras.h> #import <WebCore/WebCoreTextRenderer.h> +#import <WebCore/markup.h> #import <WebKit/DOM.h> #import <WebKit/DOMExtensions.h> #import <WebKit/DOMPrivate.h> #import <WebKitSystemInterface.h> +#import <limits> using namespace WebCore; using namespace HTMLNames; @@ -174,35 +177,35 @@ extern "C" { // Need to declare these attribute names because AppKit exports them but does not make them available in API or SPI headers. -extern NSString *NSMarkedClauseSegmentAttributeName; -extern NSString *NSTextInputReplacementRangeAttributeName; - +extern NSString *NSMarkedClauseSegmentAttributeName; +extern NSString *NSTextInputReplacementRangeAttributeName; } -@interface NSView (AppKitSecretsIKnowAbout) +@interface NSView (WebNSViewDetails) - (void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)isVisibleRect rectIsVisibleRectForView:(NSView *)visibleView topView:(BOOL)topView; - (void)_recursiveDisplayAllDirtyWithLockFocus:(BOOL)needsLockFocus visRect:(NSRect)visRect; +- (void)_recursive:(BOOL)recurse displayRectIgnoringOpacity:(NSRect)displayRect inContext:(NSGraphicsContext *)context topView:(BOOL)topView; - (NSRect)_dirtyRect; - (void)_setDrawsOwnDescendants:(BOOL)drawsOwnDescendants; - (void)_propagateDirtyRectsToOpaqueAncestors; - (void)_windowChangedKeyState; @end -@interface NSApplication (AppKitSecretsIKnowAbout) +@interface NSApplication (WebNSApplicationDetails) - (void)speakString:(NSString *)string; @end -@interface NSWindow (AppKitSecretsIKnowAbout) +@interface NSWindow (WebNSWindowDetails) - (id)_newFirstResponderAfterResigning; - (void)_setForceActiveControls:(BOOL)flag; @end -@interface NSAttributedString (AppKitSecretsIKnowAbout) -- (id)_initWithDOMRange:(DOMRange *)domRange; +@interface NSAttributedString (WebNSAttributedStringDetails) +- (id)_initWithDOMRange:(DOMRange *)range; - (DOMDocumentFragment *)_documentFromRange:(NSRange)range document:(DOMDocument *)document documentAttributes:(NSDictionary *)dict subresources:(NSArray **)subresources; @end -@interface NSSpellChecker (CurrentlyPrivateForTextView) +@interface NSSpellChecker (WebNSSpellCheckerDetails) - (void)learnWord:(NSString *)word; @end @@ -250,8 +253,8 @@ extern NSString *NSTextInputReplacementRangeAttributeName; #define WebSmartPastePboardType @"NeXT smart paste pasteboard type" #define STANDARD_WEIGHT 5 -#define MIN_BOLD_WEIGHT 9 -#define STANDARD_BOLD_WEIGHT 10 +#define MIN_BOLD_WEIGHT 7 +#define STANDARD_BOLD_WEIGHT 9 // Fake URL scheme. #define WebDataProtocolScheme @"webkit-fake-url" @@ -279,9 +282,6 @@ static CachedResourceClient* promisedDataClient() return staticCachedResourceClient; } -@interface WebHTMLView (WebTextSizing) <_WebDocumentTextSizing> -@end - @interface WebHTMLView (WebHTMLViewFileInternal) - (BOOL)_imageExistsAtPaths:(NSArray *)paths; - (DOMDocumentFragment *)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard inContext:(DOMRange *)context allowPlainText:(BOOL)allowPlainText; @@ -292,13 +292,11 @@ static CachedResourceClient* promisedDataClient() - (BOOL)_shouldInsertText:(NSString *)text replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action; - (BOOL)_shouldReplaceSelectionWithText:(NSString *)text givenAction:(WebViewInsertAction)action; - (float)_calculatePrintHeight; -- (void)_updateTextSizeMultiplier; - (DOMRange *)_selectedRange; - (BOOL)_shouldDeleteRange:(DOMRange *)range; - (NSView *)_hitViewForEvent:(NSEvent *)event; - (void)_writeSelectionWithPasteboardTypes:(NSArray *)types toPasteboard:(NSPasteboard *)pasteboard cachedAttributedString:(NSAttributedString *)attributedString; - (DOMRange *)_documentRange; -- (WebFrameBridge *)_bridge; - (void)_setMouseDownEvent:(NSEvent *)event; - (WebHTMLView *)_topHTMLView; - (BOOL)_isTopHTMLView; @@ -311,9 +309,14 @@ static CachedResourceClient* promisedDataClient() - (void)_setPrinting:(BOOL)printing minimumPageWidth:(float)minPageWidth maximumPageWidth:(float)maxPageWidth adjustViewSize:(BOOL)adjustViewSize; @end -@class NSInputContext; -@interface NSResponder (IMSecretsIKnowAbout) -- (NSInputContext *)inputContext; +@class NSTextInputContext; +@interface NSResponder (AppKitDetails) +- (NSTextInputContext *)inputContext; +@end + +@interface NSObject (NSTextInputContextDetails) +- (BOOL)wantsToHandleMouseEvents; +- (BOOL)handleMouseEvent:(NSEvent *)event; @end @interface WebHTMLView (WebNSTextInputSupport) <NSTextInput> @@ -334,7 +337,7 @@ static CachedResourceClient* promisedDataClient() @end // Handles the complete: text command -@interface WebTextCompleteController : NSObject { +@interface WebTextCompleteController : NSObject <NSTableViewDelegate, NSTableViewDataSource> { @private WebHTMLView *_view; NSWindow *_popupWindow; @@ -360,6 +363,65 @@ struct WebHTMLViewInterpretKeyEventsParameters { BOOL consumedByIM; }; +@interface WebHTMLViewPrivate : NSObject { +@public + BOOL closed; + BOOL needsLayout; + BOOL needsToApplyStyles; + BOOL ignoringMouseDraggedEvents; + BOOL printing; + BOOL avoidingPrintOrphan; + + id savedSubviews; + BOOL subviewsSetAside; + + NSEvent *mouseDownEvent; // Kept after handling the event. + BOOL handlingMouseDownEvent; + NSEvent *keyDownEvent; // Kept after handling the event. + + NSSize lastLayoutSize; + + NSPoint lastScrollPosition; + + WebPluginController *pluginController; + + NSString *toolTip; + NSToolTipTag lastToolTipTag; + id trackingRectOwner; + void *trackingRectUserData; + + NSTimer *autoscrollTimer; + NSEvent *autoscrollTriggerEvent; + + NSArray* pageRects; + + NSMutableDictionary* highlighters; + + BOOL resigningFirstResponder; + BOOL nextResponderDisabledOnce; + + WebTextCompleteController *compController; + + BOOL transparentBackground; + + WebHTMLViewInterpretKeyEventsParameters *interpretKeyEventsParameters; + BOOL receivedNOOP; + + WebDataSource *dataSource; + WebCore::CachedImage *promisedDragTIFFDataSource; + + CFRunLoopTimerRef updateFocusedAndActiveStateTimer; + CFRunLoopTimerRef updateMouseoverTimer; + + SEL selectorForDoCommandBySelector; + +#ifndef NDEBUG + BOOL enumeratingSubviews; +#endif +} +- (void)clear; +@end + static NSCellStateValue kit(TriState state) { switch (state) { @@ -407,6 +469,9 @@ static NSCellStateValue kit(TriState state) - (void)dealloc { + if (WebCoreObjCScheduleDeallocateOnMainThread([WebHTMLViewPrivate class], self)) + return; + ASSERT(!autoscrollTimer); ASSERT(!autoscrollTriggerEvent); ASSERT(!updateFocusedAndActiveStateTimer); @@ -420,7 +485,7 @@ static NSCellStateValue kit(TriState state) [dataSource release]; [highlighters release]; if (promisedDragTIFFDataSource) - promisedDragTIFFDataSource->deref(promisedDataClient()); + promisedDragTIFFDataSource->removeClient(promisedDataClient()); [super dealloc]; } @@ -430,7 +495,7 @@ static NSCellStateValue kit(TriState state) ASSERT_MAIN_THREAD(); if (promisedDragTIFFDataSource) - promisedDragTIFFDataSource->deref(promisedDataClient()); + promisedDragTIFFDataSource->removeClient(promisedDataClient()); [super finalize]; } @@ -445,7 +510,7 @@ static NSCellStateValue kit(TriState state) [dataSource release]; [highlighters release]; if (promisedDragTIFFDataSource) - promisedDragTIFFDataSource->deref(promisedDataClient()); + promisedDragTIFFDataSource->removeClient(promisedDataClient()); mouseDownEvent = nil; keyDownEvent = nil; @@ -485,11 +550,6 @@ static NSCellStateValue kit(TriState state) return _private->dataSource; } -- (WebFrameBridge *)_bridge -{ - return [_private->dataSource _bridge]; -} - - (WebView *)_webView { return [_private->dataSource _webView]; @@ -514,7 +574,7 @@ static NSCellStateValue kit(TriState state) [domNodes addObject:[[[self _frame] DOMDocument] createTextNode: url]]; } - fragment = [[self _bridge] documentFragmentWithNodesAsParagraphs:domNodes]; + fragment = [[self _frame] _documentFragmentWithNodesAsParagraphs:domNodes]; [domNodes release]; @@ -607,7 +667,16 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) inContext:context subresources:0])) return fragment; - + + // 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] && + (fragment = [self _documentFragmentFromPasteboard:pasteboard + forType:(NSString*)kUTTypePNG + inContext:context + subresources:0])) + return fragment; + if ([types containsObject:NSURLPboardType] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:NSURLPboardType @@ -668,9 +737,9 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) DOMRange *range = [self _selectedRange]; DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard inContext:range allowPlainText:allowPlainText]; - WebFrameBridge *bridge = [self _bridge]; + WebFrame *frame = [self _frame]; if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:[self _selectedRange] givenAction:WebViewInsertActionPasted]) { - [bridge replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard] matchStyle:NO]; + [frame _replaceSelectionWithFragment:fragment selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard] matchStyle:NO]; } } @@ -678,7 +747,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) { NSString *text = [self _plainTextFromPasteboard:pasteboard]; if ([self _shouldReplaceSelectionWithText:text givenAction:WebViewInsertActionPasted]) - [[self _bridge] replaceSelectionWithText:text selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard]]; + [[self _frame] _replaceSelectionWithText:text selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard]]; } - (BOOL)_shouldInsertFragment:(DOMDocumentFragment *)fragment replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action @@ -712,15 +781,10 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) return paperSize.height - [pi topMargin] - [pi bottomMargin]; } -- (void)_updateTextSizeMultiplier -{ - [[self _bridge] setTextSizeMultiplier:[[self _webView] textSizeMultiplier]]; -} - - (DOMRange *)_selectedRange { Frame* coreFrame = core([self _frame]); - return coreFrame ? kit(coreFrame->selectionController()->toRange().get()) : nil; + return coreFrame ? kit(coreFrame->selection()->toRange().get()) : nil; } - (BOOL)_shouldDeleteRange:(DOMRange *)range @@ -743,8 +807,10 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) { // Put HTML on the pasteboard. if ([types containsObject:WebArchivePboardType]) { - WebArchive *archive = [WebArchiver archiveSelectionInFrame:[self _frame]]; - [pasteboard setData:[archive data] forType:WebArchivePboardType]; + if (RefPtr<LegacyWebArchive> coreArchive = LegacyWebArchive::createFromSelection(core([self _frame]))) { + if (RetainPtr<CFDataRef> data = coreArchive ? coreArchive->rawDataRepresentation() : 0) + [pasteboard setData:(NSData *)data.get() forType:WebArchivePboardType]; + } } // Put the attributed string on the pasteboard (RTF/RTFD format). @@ -984,7 +1050,8 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) NSPoint origin = [[self superview] bounds].origin; if (!NSEqualPoints(_private->lastScrollPosition, origin)) { - [[self _bridge] sendScrollEvent]; + if (Frame* coreFrame = core([self _frame])) + coreFrame->sendScrollEvent(); [_private->compController endRevertingChange:NO moveLeft:NO]; WebView *webView = [self _webView]; @@ -1072,12 +1139,15 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) // If the WebHTMLView itself is what we're printing, then we will never have to do this. BOOL wasInPrintingMode = _private->printing; BOOL isPrinting = ![NSGraphicsContext currentContextDrawingToScreen]; - if (wasInPrintingMode != isPrinting) { - if (isPrinting) + if (isPrinting) { + if (!wasInPrintingMode) [self _web_setPrintingModeRecursive]; +#ifndef BUILDING_ON_TIGER else - [self _web_clearPrintingModeRecursive]; - } + [self _web_layoutIfNeededRecursive]; +#endif + } else if (wasInPrintingMode) + [self _web_clearPrintingModeRecursive]; #ifdef BUILDING_ON_TIGER @@ -1110,12 +1180,15 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) if (needToSetAsideSubviews) { // This helps when we print as part of a larger print process. // If the WebHTMLView itself is what we're printing, then we will never have to do this. - if (wasInPrintingMode != isPrinting) { - if (isPrinting) + if (isPrinting) { + if (!wasInPrintingMode) [self _web_setPrintingModeRecursive]; +#ifndef BUILDING_ON_TIGER else - [self _web_clearPrintingModeRecursive]; - } + [self _web_layoutIfNeededRecursive]; +#endif + } else if (wasInPrintingMode) + [self _web_clearPrintingModeRecursive]; #ifdef BUILDING_ON_TIGER @@ -1150,6 +1223,19 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) } } +// Don't let AppKit even draw subviews. We take care of that. +- (void)_recursive:(BOOL)recurse displayRectIgnoringOpacity:(NSRect)displayRect inContext:(NSGraphicsContext *)context topView:(BOOL)topView +{ +#ifdef BUILDING_ON_TIGER + // Because Tiger does not have viewWillDraw we need to do layout here. + [self _web_layoutIfNeededRecursive]; +#endif + + [self _setAsideSubviews]; + [super _recursive:recurse displayRectIgnoringOpacity:displayRect inContext:context topView:topView]; + [self _restoreSubviews]; +} + - (BOOL)_insideAnotherHTMLView { return self != [self _topHTMLView]; @@ -1380,7 +1466,8 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) if (!types) { types = [[NSArray alloc] initWithObjects:WebArchivePboardType, NSHTMLPboardType, NSFilenamesPboardType, NSTIFFPboardType, NSPICTPboardType, NSURLPboardType, - NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, NSColorPboardType, nil]; + NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, NSColorPboardType, + kUTTypePNG, nil]; CFRetain(types); } return types; @@ -1522,7 +1609,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) return; } - [[self _bridge] smartInsertForString:pasteString replacingRange:rangeToReplace beforeString:beforeString afterString:afterString]; + [[self _frame] _smartInsertForString:pasteString replacingRange:rangeToReplace beforeString:beforeString afterString:afterString]; } - (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard @@ -1596,25 +1683,25 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) - (BOOL)_hasSelection { Frame* coreFrame = core([self _frame]); - return coreFrame && coreFrame->selectionController()->isRange(); + return coreFrame && coreFrame->selection()->isRange(); } - (BOOL)_hasSelectionOrInsertionPoint { Frame* coreFrame = core([self _frame]); - return coreFrame && coreFrame->selectionController()->isCaretOrRange(); + return coreFrame && coreFrame->selection()->isCaretOrRange(); } - (BOOL)_hasInsertionPoint { Frame* coreFrame = core([self _frame]); - return coreFrame && coreFrame->selectionController()->isCaret(); + return coreFrame && coreFrame->selection()->isCaret(); } - (BOOL)_isEditable { Frame* coreFrame = core([self _frame]); - return coreFrame && coreFrame->selectionController()->isContentEditable(); + return coreFrame && coreFrame->selection()->isContentEditable(); } - (BOOL)_transparentBackground @@ -1708,38 +1795,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) { [self _cancelUpdateFocusedAndActiveStateTimer]; - // This method does the job of updating the view based on the view's firstResponder-ness and - // the window key-ness of the window containing this view. This involves four kinds of - // drawing updates right now. - // - // The four display attributes are as follows: - // - // 1. The background color used to draw behind selected content (active | inactive color) - // 2. Caret blinking (blinks | does not blink) - // 3. The drawing of a focus ring around links in web pages. - // - // Also, this is responsible for letting the bridge know if the window has gained or lost focus - // so we can send focus and blur events. - - Frame* frame = core([self _frame]); - if (!frame) - return; - - Page* page = frame->page(); - if (!page) - return; - - NSWindow *window = [self window]; - BOOL windowIsKey = [window isKeyWindow]; - BOOL windowOrSheetIsKey = windowIsKey || [[window attachedSheet] isKeyWindow]; - - // FIXME: this can move to WebView since active state is Page level, not Frame level. - NSResponder *firstResponder = [window firstResponder]; - if (firstResponder == self || firstResponder == [self _frameView]) - page->focusController()->setActive(!_private->resigningFirstResponder && windowIsKey); - - Frame* focusedFrame = page->focusController()->focusedOrMainFrame(); - frame->selectionController()->setFocused(frame == focusedFrame && windowOrSheetIsKey); + [[self _webView] _updateFocusedAndActiveStateForFrame:[self _frame]]; } - (void)_writeSelectionToPasteboard:(NSPasteboard *)pasteboard @@ -1767,6 +1823,9 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) // out the archived WebHTMLView and recreating a new one if needed. So close doesn't need to do anything in that case. if (!_private || _private->closed) return; + + _private->closed = YES; + [self _cancelUpdateMouseoverTimer]; [self _cancelUpdateFocusedAndActiveStateTimer]; [self _clearLastHitViewIfSelf]; @@ -1777,7 +1836,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) // remove tooltips before clearing _private so removeTrackingRect: will work correctly [self removeAllToolTips]; [_private clear]; - _private->closed = YES; + Page* page = core([self _webView]); if (page) page->dragController()->setDraggingImageURL(KURL()); @@ -1819,7 +1878,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) if ([HTMLString length] == 0) return nil; - return [[self _bridge] documentFragmentWithMarkupString:HTMLString baseURLString:nil]; + return [[self _frame] _documentFragmentWithMarkupString:HTMLString baseURLString:nil]; } // The _hasHTMLDocument clause here is a workaround for a bug in NSAttributedString: Radar 5052369. @@ -1882,6 +1941,18 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) [resource release]; return fragment; } + // 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]) { + WebResource *resource = [[WebResource alloc] initWithData:[pasteboard dataForType:(NSString*)kUTTypePNG] + URL:uniqueURLWithRelativePart(@"image.png") + MIMEType:@"image/png" + textEncodingName:nil + frameName:nil]; + DOMDocumentFragment *fragment = [[self _dataSource] _documentFragmentWithImageResource:resource]; + [resource release]; + return fragment; + } if (pboardType == NSURLPboardType) { NSURL *URL = [NSURL URLFromPasteboard:pasteboard]; DOMDocument* document = [[self _frame] DOMDocument]; @@ -1901,12 +1972,40 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) return fragment; } if (pboardType == NSStringPboardType) - return [[self _bridge] documentFragmentWithText:[pasteboard stringForType:NSStringPboardType] - inContext:context]; - + return kit(createFragmentFromText(core(context), [pasteboard stringForType:NSStringPboardType]).get()); return nil; } +#if ENABLE(NETSCAPE_PLUGIN_API) +- (void)_pauseNullEventsForAllNetscapePlugins +{ + NSArray *subviews = [self subviews]; + unsigned int subviewCount = [subviews count]; + unsigned int subviewIndex; + + for (subviewIndex = 0; subviewIndex < subviewCount; subviewIndex++) { + NSView *subview = [subviews objectAtIndex:subviewIndex]; + if ([subview isKindOfClass:[WebBaseNetscapePluginView class]]) + [(WebBaseNetscapePluginView *)subview stopTimers]; + } +} +#endif + +#if ENABLE(NETSCAPE_PLUGIN_API) +- (void)_resumeNullEventsForAllNetscapePlugins +{ + NSArray *subviews = [self subviews]; + unsigned int subviewCount = [subviews count]; + unsigned int subviewIndex; + + for (subviewIndex = 0; subviewIndex < subviewCount; subviewIndex++) { + NSView *subview = [subviews objectAtIndex:subviewIndex]; + if ([subview isKindOfClass:[WebBaseNetscapePluginView class]]) + [(WebBaseNetscapePluginView *)subview restartTimers]; + } +} +#endif + @end @implementation NSView (WebHTMLViewFileInternal) @@ -1998,6 +2097,9 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info) - (void)dealloc { + if (WebCoreObjCScheduleDeallocateOnMainThread([WebHTMLView class], self)) + return; + // We can't assert that close has already been called because // this view can be removed from it's superview, even though // it could be needed later, so close if needed. @@ -2108,6 +2210,7 @@ WEBCORE_COMMAND(deleteToEndOfParagraph) WEBCORE_COMMAND(deleteToMark) WEBCORE_COMMAND(deleteWordBackward) WEBCORE_COMMAND(deleteWordForward) +WEBCORE_COMMAND(ignoreSpelling) WEBCORE_COMMAND(indent) WEBCORE_COMMAND(insertBacktab) WEBCORE_COMMAND(insertLineBreak) @@ -2203,7 +2306,7 @@ WEBCORE_COMMAND(yankAndSelect) Frame* coreFrame = core([self _frame]); if (!coreFrame) return NO; - if (coreFrame->selectionController()->isContentRichlyEditable()) + if (coreFrame->selection()->isContentRichlyEditable()) [self _pasteWithPasteboard:pasteboard allowPlainText:YES]; else [self _pasteAsPlainTextWithPasteboard:pasteboard]; @@ -2272,7 +2375,9 @@ WEBCORE_COMMAND(yankAndSelect) NSMenuItem *menuItem = (NSMenuItem *)item; if ([menuItem isKindOfClass:[NSMenuItem class]]) { BOOL panelShowing = [[[NSSpellChecker sharedSpellChecker] spellingPanel] isVisible]; - [menuItem setTitle:panelShowing ? UI_STRING("Hide Spelling and Grammar", "menu item title") : UI_STRING("Show Spelling and Grammar", "menu item title")]; + [menuItem setTitle:panelShowing + ? UI_STRING("Hide Spelling and Grammar", "menu item title") + : UI_STRING("Show Spelling and Grammar", "menu item title")]; } #endif return [self _canEdit]; @@ -2284,7 +2389,7 @@ WEBCORE_COMMAND(yankAndSelect) return NO; NSMenuItem *menuItem = (NSMenuItem *)item; if ([menuItem isKindOfClass:[NSMenuItem class]]) { - RefPtr<CSSStyleDeclaration> style = new CSSMutableStyleDeclaration; + RefPtr<CSSStyleDeclaration> style = CSSMutableStyleDeclaration::create(); ExceptionCode ec; style->setProperty("direction", writingDirection == NSWritingDirectionLeftToRight ? "LTR" : "RTL", ec); [menuItem setState:frame->editor()->selectionHasStyle(style.get())]; @@ -2295,11 +2400,11 @@ WEBCORE_COMMAND(yankAndSelect) if (action == @selector(toggleBaseWritingDirection:)) { NSMenuItem *menuItem = (NSMenuItem *)item; if ([menuItem isKindOfClass:[NSMenuItem class]]) { - RefPtr<CSSStyleDeclaration> style = new CSSMutableStyleDeclaration; + RefPtr<CSSStyleDeclaration> style = CSSMutableStyleDeclaration::create(); ExceptionCode ec; style->setProperty("direction", "RTL", ec); - // Take control of the title of the menu item, instead of just checking/unchecking it because otherwise - // we don't know what the check would mean. + // Take control of the title of the menu item instead of just checking/unchecking it because + // a check would be ambiguous. [menuItem setTitle:frame->editor()->selectionHasStyle(style.get()) ? UI_STRING("Left to Right", "Left to Right context menu item") : UI_STRING("Right to Left", "Right to Left context menu item")]; @@ -2335,7 +2440,7 @@ WEBCORE_COMMAND(yankAndSelect) if (action == @selector(pasteAsRichText:)) return frame && (frame->editor()->canDHTMLPaste() - || (frame->editor()->canPaste() && frame->selectionController()->isContentRichlyEditable())); + || (frame->editor()->canPaste() && frame->selection()->isContentRichlyEditable())); if (action == @selector(performFindPanelAction:)) return NO; @@ -2368,6 +2473,10 @@ WEBCORE_COMMAND(yankAndSelect) - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item { + // This can be called during teardown when _webView is nil. Return NO when this happens, because CallUIDelegateReturningBoolean + // assumes the WebVIew is non-nil. + if (![self _webView]) + return NO; BOOL result = [self validateUserInterfaceItemWithoutDelegate:item]; return CallUIDelegateReturningBoolean(result, [self _webView], @selector(webView:validateUserInterfaceItem:defaultValidation:), item, result); } @@ -2418,7 +2527,7 @@ WEBCORE_COMMAND(yankAndSelect) return YES; Frame* coreFrame = core([self _frame]); - bool selectionIsEditable = coreFrame && coreFrame->selectionController()->isContentEditable(); + bool selectionIsEditable = coreFrame && coreFrame->selection()->isContentEditable(); bool nextResponderIsInWebView = [nextResponder isKindOfClass:[NSView class]] && [nextResponder isDescendantOf:[[[self _webView] mainFrame] frameView]]; @@ -2431,7 +2540,11 @@ WEBCORE_COMMAND(yankAndSelect) return; // Unless the Dashboard asks us to do this for all windows, keep an observer going only for the key window. - if (!([[self window] isKeyWindow] || [[self _webView] _dashboardBehavior:WebDashboardBehaviorAlwaysSendMouseEventsToAllWindows])) + if (!([[self window] isKeyWindow] +#if ENABLE(DASHBOARD_SUPPORT) + || [[self _webView] _dashboardBehavior:WebDashboardBehaviorAlwaysSendMouseEventsToAllWindows] +#endif + )) return; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mouseMovedNotification:) @@ -2447,9 +2560,11 @@ WEBCORE_COMMAND(yankAndSelect) - (void)removeMouseMovedObserver { +#if ENABLE(DASHBOARD_SUPPORT) // Don't remove the observer if we're running the Dashboard. if ([[self _webView] _dashboardBehavior:WebDashboardBehaviorAlwaysSendMouseEventsToAllWindows]) return; +#endif [[self _webView] _mouseDidMoveOverElement:nil modifierFlags:0]; [self removeMouseMovedObserverUnconditionally]; @@ -2502,6 +2617,8 @@ WEBCORE_COMMAND(yankAndSelect) name:NSWindowDidResignKeyNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:window]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillOrderOnScreen:) + name:WKWindowWillOrderOnScreenNotification() object:window]; } } @@ -2515,6 +2632,8 @@ WEBCORE_COMMAND(yankAndSelect) name:NSWindowDidResignKeyNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowWillCloseNotification object:window]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:WKWindowWillOrderOnScreenNotification() object:window]; } } @@ -2525,12 +2644,8 @@ WEBCORE_COMMAND(yankAndSelect) - (void)viewDidMoveToSuperview { - // Do this here in case the text size multiplier changed when a non-HTML - // view was installed. - if ([self superview] != nil) { - [self _updateTextSizeMultiplier]; + if ([self superview] != nil) [self addSuperviewObservers]; - } } static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, void *info) @@ -2622,18 +2737,21 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v - (void)reapplyStyles { - if (!_private->needsToApplyStyles) { + if (!_private->needsToApplyStyles) return; - } -#ifdef _KWQ_TIMING +#ifdef LOG_TIMES double start = CFAbsoluteTimeGetCurrent(); #endif - [[self _bridge] reapplyStylesForDeviceType: - _private->printing ? WebCoreDevicePrinter : WebCoreDeviceScreen]; + 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 _KWQ_TIMING +#ifdef LOG_TIMES double thisTime = CFAbsoluteTimeGetCurrent() - start; LOG(Timing, "%s apply style seconds = %f", [self URL], thisTime); #endif @@ -2647,26 +2765,34 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v { [self reapplyStyles]; - if (!_private->needsLayout && ![[self _bridge] needsLayout]) + if (!_private->needsLayout && ![[self _frame] _needsLayout]) return; -#ifdef _KWQ_TIMING +#ifdef LOG_TIMES double start = CFAbsoluteTimeGetCurrent(); #endif LOG(View, "%@ doing layout", self); - if (minPageWidth > 0.0) { - [[self _bridge] forceLayoutWithMinimumPageWidth:minPageWidth maximumPageWidth:maxPageWidth adjustingViewSize:adjustViewSize]; - } else { - [[self _bridge] forceLayoutAdjustingViewSize:adjustViewSize]; + Frame* coreFrame = core([self _frame]); + if (!coreFrame) { + _private->needsLayout = NO; + return; + } + + if (minPageWidth > 0.0) + coreFrame->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize); + else { + coreFrame->forceLayout(!adjustViewSize); + if (adjustViewSize) + coreFrame->view()->adjustViewSize(); } _private->needsLayout = NO; if (!_private->printing) _private->lastLayoutSize = [(NSClipView *)[self superview] documentVisibleRect].size; -#ifdef _KWQ_TIMING +#ifdef LOG_TIMES double thisTime = CFAbsoluteTimeGetCurrent() - start; LOG(Timing, "%s layout seconds = %f", [self URL], thisTime); #endif @@ -2677,6 +2803,14 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v [self layoutToMinimumPageWidth:0.0f maximumPageWidth:0.0f adjustingViewSize:NO]; } +// Deliver mouseup events to the DOM for button 2. +- (void)rightMouseUp:(NSEvent *)event +{ + [super rightMouseUp:event]; + if (Frame* coreframe = core([self _frame])) + coreframe->eventHandler()->mouseUp(event); +} + - (NSMenu *)menuForEvent:(NSEvent *)event { [_private->compController endRevertingChange:NO moveLeft:NO]; @@ -2773,16 +2907,19 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v NSRectFill (rect); } - [[self _bridge] drawRect:rect]; + [[self _frame] _drawRect:rect contentsOnly:YES]; + + WebView *webView = [self _webView]; // This hack is needed for <rdar://problem/5023545>. We can hit a race condition where drawRect will be // called after the WebView has closed. If the client did not properly close the WebView and set the // UIDelegate to nil, then the UIDelegate will be stale and this code will crash. static BOOL version3OrLaterClient = WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_QUICKBOOKS_QUIRK); - if (version3OrLaterClient) { - WebView *webView = [self _webView]; + if (version3OrLaterClient) [[webView _UIDelegateForwarder] webView:webView didDrawRect:[webView convertRect:rect fromView:self]]; - } + + if (WebNodeHighlight *currentHighlight = [webView currentNodeHighlight]) + [currentHighlight setNeedsUpdateInTargetViewRect:[self convertRect:rect toView:[currentHighlight targetView]]]; [(WebClipView *)[self superview] resetAdditionalClip]; @@ -2808,37 +2945,17 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v if (subviewsWereSetAside) [self _restoreSubviews]; -#ifdef _KWQ_TIMING +#ifdef LOG_TIMES double start = CFAbsoluteTimeGetCurrent(); #endif - // If count == 0 here, use the rect passed in for drawing. This is a workaround for: - // <rdar://problem/3908282> REGRESSION (Mail): No drag image dragging selected text in Blot and Mail - // The reason for the workaround is that this method is called explicitly from the code - // to generate a drag image, and at that time, getRectsBeingDrawn:count: will return a zero count. - const int cRectThreshold = 10; - const float cWastedSpaceThreshold = 0.75f; - BOOL useUnionedRect = (count <= 1) || (count > cRectThreshold); - if (!useUnionedRect) { - // Attempt to guess whether or not we should use the unioned rect or the individual rects. - // We do this by computing the percentage of "wasted space" in the union. If that wasted space - // is too large, then we will do individual rect painting instead. - float unionPixels = (rect.size.width * rect.size.height); - float singlePixels = 0; - for (int i = 0; i < count; ++i) - singlePixels += rects[i].size.width * rects[i].size.height; - float wastedSpace = 1 - (singlePixels / unionPixels); - if (wastedSpace <= cWastedSpaceThreshold) - useUnionedRect = YES; - } - - if (useUnionedRect) + if ([[self _webView] _mustDrawUnionedRect:rect singleRects:rects count:count]) [self drawSingleRect:rect]; else for (int i = 0; i < count; ++i) [self drawSingleRect:rects[i]]; -#ifdef _KWQ_TIMING +#ifdef LOG_TIMES double thisTime = CFAbsoluteTimeGetCurrent() - start; LOG(Timing, "%s draw seconds = %f", widget->part()->baseURL().URL().latin1(), thisTime); #endif @@ -2902,6 +3019,12 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v [[self _pluginController] destroyAllPlugins]; } +- (void)windowWillOrderOnScreen:(NSNotification *)notification +{ + if (![[self _webView] shouldUpdateWhileOffscreen]) + [self setNeedsDisplay:YES]; +} + - (void)scrollWheel:(NSEvent *)event { [self retain]; @@ -2922,8 +3045,10 @@ static void _updateFocusedAndActiveStateTimerCallback(CFRunLoopTimerRef timer, v NSView *hitView = [self _hitViewForEvent:event]; WebHTMLView *hitHTMLView = [hitView isKindOfClass:[self class]] ? (WebHTMLView *)hitView : nil; +#if ENABLE(DASHBOARD_SUPPORT) if ([[self _webView] _dashboardBehavior:WebDashboardBehaviorAlwaysAcceptsFirstMouse]) return YES; +#endif if (hitHTMLView) { bool result = false; @@ -3045,7 +3170,7 @@ done: NSPoint windowMouseLoc = NSMakePoint(windowImageLoc.x + dragController->dragOffset().x(), windowImageLoc.y + dragController->dragOffset().y()); } - [[self _bridge] dragSourceMovedTo:windowMouseLoc]; + [[self _frame] _dragSourceMovedTo:windowMouseLoc]; } - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation @@ -3061,7 +3186,7 @@ done: dragController->dragEnded(); } - [[self _bridge] dragSourceEndedAt:windowMouseLoc operation:operation]; + [[self _frame] _dragSourceEndedAt:windowMouseLoc operation:operation]; // Prevent queued mouseDragged events from coming after the drag and fake mouseUp event. _private->ignoringMouseDraggedEvents = YES; @@ -3108,9 +3233,9 @@ noPromisedData: if (!page) return nil; - KURL imageURL = page->dragController()->draggingImageURL(); + const KURL& imageURL = page->dragController()->draggingImageURL(); ASSERT(!imageURL.isEmpty()); - draggingImageURL = imageURL.getNSURL(); + draggingImageURL = imageURL; wrapper = [[self _dataSource] _fileWrapperForURL:draggingImageURL]; } @@ -3276,7 +3401,7 @@ noPromisedData: // This is needed for the case where the webview is embedded in the view that's being printed. // It shouldn't be called when the webview is being printed directly. -- (void)adjustPageHeightNew:(float *)newBottom top:(float)oldTop bottom:(float)oldBottom limit:(float)bottomLimit +- (void)adjustPageHeightNew:(CGFloat *)newBottom top:(CGFloat)oldTop bottom:(CGFloat)oldBottom limit:(CGFloat)bottomLimit { // This helps when we print as part of a larger print process. // If the WebHTMLView itself is what we're printing, then we will never have to do this. @@ -3284,7 +3409,17 @@ noPromisedData: if (!wasInPrintingMode) [self _setPrinting:YES minimumPageWidth:0.0f maximumPageWidth:0.0f adjustViewSize:NO]; - [[self _bridge] adjustPageHeightNew:newBottom top:oldTop bottom:oldBottom limit:bottomLimit]; + float newBottomFloat = *newBottom; + core([self _frame])->adjustPageHeight(&newBottomFloat, oldTop, oldBottom, bottomLimit); + +#ifdef __LP64__ + // If the new bottom is equal to the old bottom (when both are treated as floats), we just copy + // oldBottom over to newBottom. This prevents rounding errors that can occur when converting newBottomFloat to a double. + if (fabs((float)oldBottom - newBottomFloat) <= std::numeric_limits<float>::epsilon()) + *newBottom = oldBottom; + else +#endif + *newBottom = newBottomFloat; if (!wasInPrintingMode) { NSPrintOperation *currenPrintOperation = [NSPrintOperation currentOperation]; @@ -3321,7 +3456,7 @@ noPromisedData: // FIXME 3491344: This is a secret AppKit-internal method that we need to override in order // to get our shrink-to-fit to work with a custom pagination scheme. We can do this better // if AppKit makes it SPI/API. -- (float)_provideTotalScaleFactorForPrintOperation:(NSPrintOperation *)printOperation +- (CGFloat)_provideTotalScaleFactorForPrintOperation:(NSPrintOperation *)printOperation { return [self _scaleFactorForPrintOperation:printOperation]; } @@ -3405,7 +3540,7 @@ noPromisedData: float userScaleFactor = [printOperation _web_pageSetupScaleFactor]; [_private->pageRects release]; float fullPageHeight = floorf([self _calculatePrintHeight]/totalScaleFactor); - NSArray *newPageRects = [[self _bridge] computePageRectsWithPrintWidthScaleFactor:userScaleFactor + NSArray *newPageRects = [[self _frame] _computePageRectsWithPrintWidthScaleFactor:userScaleFactor printHeight:fullPageHeight]; // AppKit gets all messed up if you give it a zero-length page count (see 3576334), so if we @@ -3419,7 +3554,7 @@ noPromisedData: // content onto one fewer page. If it does, use the adjusted scale. If not, use the original scale. float lastPageHeight = NSHeight([[newPageRects lastObject] rectValue]); if (lastPageHeight/fullPageHeight < LastPrintedPageOrphanRatio) { - NSArray *adjustedPageRects = [[self _bridge] computePageRectsWithPrintWidthScaleFactor:userScaleFactor + NSArray *adjustedPageRects = [[self _frame] _computePageRectsWithPrintWidthScaleFactor:userScaleFactor printHeight:fullPageHeight*PrintingOrphanShrinkAdjustment]; // Use the adjusted rects only if the page count went down if ([adjustedPageRects count] < [newPageRects count]) { @@ -3437,7 +3572,7 @@ noPromisedData: } // Return the drawing rectangle for a particular page number -- (NSRect)rectForPage:(int)page +- (NSRect)rectForPage:(NSInteger)page { return [[_private->pageRects objectAtIndex:page - 1] rectValue]; } @@ -3502,11 +3637,12 @@ noPromisedData: { BOOL eventWasSentToWebCore = (_private->keyDownEvent == event); - [self retain]; + RetainPtr<WebHTMLView> selfProtector = self; Frame* coreFrame = core([self _frame]); - if (eventWasSentToWebCore || !coreFrame || !coreFrame->eventHandler()->keyEvent(event)) - [super keyUp:event]; - [self release]; + if (coreFrame && !eventWasSentToWebCore) + coreFrame->eventHandler()->keyEvent(event); + else + [super keyUp:event]; } - (void)flagsChanged:(NSEvent *)event @@ -3518,9 +3654,12 @@ noPromisedData: RetainPtr<WebHTMLView> selfProtector = self; unsigned short keyCode = [event keyCode]; + //Don't make an event from the num lock and function keys - if (coreFrame && keyCode != 0 && keyCode != 10 && keyCode != 63) + if (coreFrame && keyCode != 0 && keyCode != 10 && keyCode != 63) { coreFrame->eventHandler()->keyEvent(PlatformKeyboardEvent(event)); + return; + } [super flagsChanged:event]; } @@ -3528,7 +3667,7 @@ noPromisedData: - (id)accessibilityAttributeValue:(NSString*)attributeName { if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute]) { - id accTree = [[self _bridge] accessibilityTree]; + id accTree = [[self _frame] _accessibilityTree]; if (accTree) return [NSArray arrayWithObject:accTree]; return nil; @@ -3538,7 +3677,7 @@ noPromisedData: - (id)accessibilityFocusedUIElement { - id accTree = [[self _bridge] accessibilityTree]; + id accTree = [[self _frame] _accessibilityTree]; if (accTree) return [accTree accessibilityFocusedUIElement]; return self; @@ -3546,7 +3685,7 @@ noPromisedData: - (id)accessibilityHitTest:(NSPoint)point { - id accTree = [[self _bridge] accessibilityTree]; + id accTree = [[self _frame] _accessibilityTree]; if (accTree) { NSPoint windowCoord = [[self window] convertScreenToBase:point]; return [accTree accessibilityHitTest:[self convertPoint:windowCoord fromView:nil]]; @@ -3556,7 +3695,7 @@ noPromisedData: - (id)_accessibilityParentForSubview:(NSView *)subview { - id accTree = [[self _bridge] accessibilityTree]; + id accTree = [[self _frame] _accessibilityTree]; if (!accTree) return self; id parent = [accTree _accessibilityParentForSubview:subview]; @@ -3652,7 +3791,7 @@ noPromisedData: [style setBackgroundColor:[self _colorAsString:color]]; NSFont *font = [dictionary objectForKey:NSFontAttributeName]; - if (font == nil) { + if (!font) { [style setFontFamily:@"Helvetica"]; [style setFontSize:@"12px"]; [style setFontWeight:@"normal"]; @@ -3663,11 +3802,12 @@ noPromisedData: // with characters like single quote or backslash in their names. [style setFontFamily:[NSString stringWithFormat:@"'%@'", [font familyName]]]; [style setFontSize:[NSString stringWithFormat:@"%0.fpx", [font pointSize]]]; + // FIXME: Map to the entire range of CSS weight values. if ([fm weightOfFont:font] >= MIN_BOLD_WEIGHT) [style setFontWeight:@"bold"]; else [style setFontWeight:@"normal"]; - if (([fm traitsOfFont:font] & NSItalicFontMask) != 0) + if ([fm traitsOfFont:font] & NSItalicFontMask) [style setFontStyle:@"italic"]; else [style setFontStyle:@"normal"]; @@ -3802,7 +3942,7 @@ noPromisedData: - (NSFont *)_originalFontB { - return [[NSFontManager sharedFontManager] fontWithFamily:@"Times" traits:(NSBoldFontMask | NSItalicFontMask) weight:STANDARD_BOLD_WEIGHT size:12.0f]; + return [[NSFontManager sharedFontManager] fontWithFamily:@"Times" traits:NSFontItalicTrait weight:STANDARD_BOLD_WEIGHT size:12.0f]; } - (void)_addToStyle:(DOMCSSStyleDeclaration *)style fontA:(NSFont *)a fontB:(NSFont *)b @@ -3828,8 +3968,6 @@ noPromisedData: int aWeight = [fm weightOfFont:a]; int bWeight = [fm weightOfFont:b]; - BOOL aIsBold = aWeight >= MIN_BOLD_WEIGHT; - BOOL aIsItalic = ([fm traitsOfFont:a] & NSItalicFontMask) != 0; BOOL bIsItalic = ([fm traitsOfFont:b] & NSItalicFontMask) != 0; @@ -3841,18 +3979,13 @@ noPromisedData: // the Postscript name. // Find the font the same way the rendering code would later if it encountered this CSS. - NSFontTraitMask traits = 0; - if (aIsBold) - traits |= NSBoldFontMask; - if (aIsItalic) - traits |= NSItalicFontMask; - NSFont *foundFont = WebCoreFindFont(aFamilyName, traits, aPointSize); + NSFontTraitMask traits = aIsItalic ? NSFontItalicTrait : 0; + NSFont *foundFont = WebCoreFindFont(aFamilyName, traits, aWeight, aPointSize); // If we don't find a font with the same Postscript name, then we'll have to use the // Postscript name to make the CSS specific enough. - if (![[foundFont fontName] isEqualToString:[a fontName]]) { + if (![[foundFont fontName] isEqualToString:[a fontName]]) familyNameForCSS = [a fontName]; - } // FIXME: Need more sophisticated escaping code if we want to handle family names // with characters like single quote or backslash in their names. @@ -3868,7 +4001,7 @@ noPromisedData: [style _setFontSizeDelta:@"1px"]; if (aWeight == bWeight) - [style setFontWeight:aIsBold ? @"bold" : @"normal"]; + [style setFontWeight:aWeight > MIN_BOLD_WEIGHT ? @"bold" : @"normal"]; if (aIsItalic == bIsItalic) [style setFontStyle:aIsItalic ? @"italic" : @"normal"]; @@ -4043,7 +4176,7 @@ NSStrokeColorAttributeName /* NSColor, default nil: same as foreground co // to do the right thing because it works in startSpeaking:, and I know setBackgroundColor: does the // right thing because I tested it with [self _selectedRange]. // FIXME: This won't actually apply the style to the entire range here, because it ends up calling - // [bridge applyStyle:], which operates on the current selection. To make this work right, we'll + // [frame _applyStyle:], which operates on the current selection. To make this work right, we'll // need to save off the selection, temporarily set it to the entire range, make the change, then // restore the old selection. [self _changeCSSColorUsingSelector:@selector(setBackgroundColor:) inRange:[self _documentRange]]; @@ -4067,12 +4200,12 @@ NSStrokeColorAttributeName /* NSColor, default nil: same as foreground co if (![self _canEdit]) return; - WebFrameBridge *bridge = [self _bridge]; + WebFrame *frame = [self _frame]; [self selectWord:nil]; - NSString *word = [[bridge selectedString] performSelector:selector]; + NSString *word = [[frame _selectedString] performSelector:selector]; // FIXME: Does this need a different action context other than "typed"? if ([self _shouldReplaceSelectionWithText:word givenAction:WebViewInsertActionTyped]) - [bridge replaceSelectionWithText:word selectReplacement:NO smartReplace:NO]; + [frame _replaceSelectionWithText:word selectReplacement:NO smartReplace:NO]; } - (void)uppercaseWord:(id)sender @@ -4155,7 +4288,7 @@ NSStrokeColorAttributeName /* NSColor, default nil: same as foreground co return; if ([self _shouldReplaceSelectionWithText:newWord givenAction:WebViewInsertActionPasted]) - [[self _bridge] replaceSelectionWithText:newWord selectReplacement:YES smartReplace:NO]; + [[self _frame] _replaceSelectionWithText:newWord selectReplacement:YES smartReplace:NO]; } - (void)changeSpelling:(id)sender @@ -4165,24 +4298,6 @@ NSStrokeColorAttributeName /* NSColor, default nil: same as foreground co [self _changeSpellingToWord:[[sender selectedCell] stringValue]]; } -- (void)ignoreSpelling:(id)sender -{ - COMMAND_PROLOGUE - - NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker]; - if (!checker) { - LOG_ERROR("No NSSpellChecker"); - return; - } - - NSString *stringToIgnore = [sender stringValue]; - unsigned int length = [stringToIgnore length]; - if (stringToIgnore && length > 0) { - [checker ignoreWord:stringToIgnore inSpellDocumentWithTag:[[self _webView] spellCheckerDocumentTag]]; - // FIXME: Need to clear misspelling marker if the currently selected word is the one we are to ignore? - } -} - - (void)performFindPanelAction:(id)sender { COMMAND_PROLOGUE @@ -4196,11 +4311,11 @@ NSStrokeColorAttributeName /* NSColor, default nil: same as foreground co { COMMAND_PROLOGUE - WebFrameBridge *bridge = [self _bridge]; + WebFrame *frame = [self _frame]; DOMRange *range = [self _selectedRange]; if (!range || [range collapsed]) range = [self _documentRange]; - [NSApp speakString:[bridge stringForRange:range]]; + [NSApp speakString:[frame _stringForRange:range]]; } - (void)stopSpeaking:(id)sender @@ -4221,12 +4336,12 @@ NSStrokeColorAttributeName /* NSColor, default nil: same as foreground co if (!coreFrame) return; - const char* direction = "rtl"; + WritingDirection direction = RightToLeftWritingDirection; switch (coreFrame->baseWritingDirectionForSelectionStart()) { case NSWritingDirectionLeftToRight: break; case NSWritingDirectionRightToLeft: - direction = "ltr"; + direction = LeftToRightWritingDirection; break; // The writingDirectionForSelectionStart method will never return "natural". It // will always return a concrete direction. So, keep the compiler happy, and assert not reached. @@ -4253,7 +4368,7 @@ NSStrokeColorAttributeName /* NSColor, default nil: same as foreground co ASSERT(writingDirection != NSWritingDirectionNatural); if (Frame* coreFrame = core([self _frame])) - coreFrame->editor()->setBaseWritingDirection(writingDirection == NSWritingDirectionLeftToRight ? "ltr" : "rtl"); + coreFrame->editor()->setBaseWritingDirection(writingDirection == NSWritingDirectionLeftToRight ? LeftToRightWritingDirection : RightToLeftWritingDirection); } static BOOL writingDirectionKeyBindingsEnabled() @@ -4275,7 +4390,7 @@ static BOOL writingDirectionKeyBindingsEnabled() } if (Frame* coreFrame = core([self _frame])) - coreFrame->editor()->setBaseWritingDirection(direction == NSWritingDirectionLeftToRight ? "ltr" : "rtl"); + coreFrame->editor()->setBaseWritingDirection(direction == NSWritingDirectionLeftToRight ? LeftToRightWritingDirection : RightToLeftWritingDirection); } - (void)changeBaseWritingDirectionToLTR:(id)sender @@ -4420,63 +4535,15 @@ static BOOL writingDirectionKeyBindingsEnabled() @end -@implementation WebHTMLView (WebTextSizing) - -- (IBAction)_makeTextSmaller:(id)sender -{ - [self _updateTextSizeMultiplier]; -} - -- (IBAction)_makeTextLarger:(id)sender -{ - [self _updateTextSizeMultiplier]; -} - -- (IBAction)_makeTextStandardSize:(id)sender -{ - [self _updateTextSizeMultiplier]; -} - -- (BOOL)_tracksCommonSizeFactor -{ - return YES; -} - -- (void)_textSizeMultiplierChanged -{ - [self _updateTextSizeMultiplier]; -} - -// never sent because we track the common size factor -- (BOOL)_canMakeTextSmaller -{ - ASSERT_NOT_REACHED(); - return NO; -} - -- (BOOL)_canMakeTextLarger -{ - ASSERT_NOT_REACHED(); - return NO; -} - -- (BOOL)_canMakeTextStandardSize -{ - ASSERT_NOT_REACHED(); - return NO; -} - -@end - @implementation NSArray (WebHTMLView) - (void)_web_makePluginViewsPerformSelector:(SEL)selector withObject:(id)object { -#ifndef __LP64__ +#if ENABLE(NETSCAPE_PLUGIN_API) NSEnumerator *enumerator = [self objectEnumerator]; - WebNetscapePluginEmbeddedView *view; + WebBaseNetscapePluginView *view; while ((view = [enumerator nextObject]) != nil) - if ([view isKindOfClass:[WebNetscapePluginEmbeddedView class]]) + if ([view isKindOfClass:[WebBaseNetscapePluginView class]]) [view performSelector:selector withObject:object]; #endif } @@ -4506,8 +4573,13 @@ static BOOL writingDirectionKeyBindingsEnabled() if ([NSApp keyWindow] != window || [window firstResponder] != self) return; - BOOL multiple = NO; - NSFont *font = [[self _bridge] fontForSelection:&multiple]; + bool multipleFonts = false; + NSFont *font = nil; + if (Frame* coreFrame = core([self _frame])) { + if (const SimpleFontData* fd = coreFrame->editor()->fontForSelection(multipleFonts)) + font = fd->getNSFont(); + } + // FIXME: for now, return a bogus font that distinguishes the empty selection from the non-empty // selection. We should be able to remove this once the rest of this code works properly. @@ -4515,8 +4587,7 @@ static BOOL writingDirectionKeyBindingsEnabled() font = [self _hasSelection] ? [NSFont menuFontOfSize:23] : [NSFont toolTipsFontOfSize:17]; ASSERT(font != nil); - NSFontManager *fm = [NSFontManager sharedFontManager]; - [fm setSelectedFont:font isMultiple:multiple]; + [[NSFontManager sharedFontManager] setSelectedFont:font isMultiple:multipleFonts]; // FIXME: we don't keep track of selected attributes, or set them on the font panel. This // appears to have no effect on the UI. E.g., underlined text in Mail or TextEdit is @@ -4525,7 +4596,10 @@ static BOOL writingDirectionKeyBindingsEnabled() - (BOOL)_canSmartCopyOrDelete { - return [[self _webView] smartInsertDeleteEnabled] && [[self _bridge] selectionGranularity] == WordGranularity; + if (![[self _webView] smartInsertDeleteEnabled]) + return NO; + Frame* coreFrame = core([self _frame]); + return coreFrame && coreFrame->selectionGranularity() == WordGranularity; } - (NSEvent *)_mouseDownEvent @@ -4533,36 +4607,6 @@ static BOOL writingDirectionKeyBindingsEnabled() return _private->mouseDownEvent; } -#ifndef __LP64__ -- (void)_pauseNullEventsForAllNetscapePlugins -{ - NSArray *subviews = [self subviews]; - unsigned int subviewCount = [subviews count]; - unsigned int subviewIndex; - - for (subviewIndex = 0; subviewIndex < subviewCount; subviewIndex++) { - NSView *subview = [subviews objectAtIndex:subviewIndex]; - if ([subview isKindOfClass:[WebBaseNetscapePluginView class]]) - [(WebBaseNetscapePluginView *)subview stopNullEvents]; - } -} -#endif - -#ifndef __LP64__ -- (void)_resumeNullEventsForAllNetscapePlugins -{ - NSArray *subviews = [self subviews]; - unsigned int subviewCount = [subviews count]; - unsigned int subviewIndex; - - for (subviewIndex = 0; subviewIndex < subviewCount; subviewIndex++) { - NSView *subview = [subviews objectAtIndex:subviewIndex]; - if ([subview isKindOfClass:[WebBaseNetscapePluginView class]]) - [(WebBaseNetscapePluginView *)subview restartNullEvents]; - } -} -#endif - - (id<WebHTMLHighlighter>)_highlighterForType:(NSString*)type { return [_private->highlighters objectForKey:type]; @@ -4585,7 +4629,7 @@ static BOOL writingDirectionKeyBindingsEnabled() return; // DHTML did the whole operation if (!coreFrame->editor()->canPaste()) return; - if (coreFrame->selectionController()->isContentRichlyEditable()) + if (coreFrame->selection()->isContentRichlyEditable()) [self _pasteWithPasteboard:[NSPasteboard generalPasteboard] allowPlainText:YES]; else coreFrame->editor()->pasteAsPlainText(); @@ -4791,10 +4835,10 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) - (void)setPromisedDragTIFFDataSource:(WebCore::CachedImage*)source { if (source) - source->ref(promisedDataClient()); + source->addClient(promisedDataClient()); if (_private->promisedDragTIFFDataSource) - _private->promisedDragTIFFDataSource->deref(promisedDataClient()); + _private->promisedDragTIFFDataSource->removeClient(promisedDataClient()); _private->promisedDragTIFFDataSource = source; } @@ -4804,7 +4848,7 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) { ASSERT(!_private->subviewsSetAside); - if ([[self _bridge] needsLayout]) + if ([[self _frame] _needsLayout]) _private->needsLayout = YES; if (_private->needsToApplyStyles || _private->needsLayout) [self layout]; @@ -4833,6 +4877,11 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) #endif } +- (void) _destroyAllWebPlugins +{ + [[self _pluginController] destroyAllPlugins]; +} + @end @implementation WebHTMLView (WebNSTextInputSupport) @@ -4859,24 +4908,18 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point) // API when an editable region is not currently focused. static BOOL isTextInput(Frame* coreFrame) { - return coreFrame && !coreFrame->selectionController()->isNone() && coreFrame->selectionController()->isContentEditable(); + return coreFrame && !coreFrame->selection()->isNone() && coreFrame->selection()->isContentEditable(); } -// Work around for <rdar://problem/5522011> -// Some input methods do not properly behave when TSM is in secure input mode -// which can allow the password to be made visible. We prevent this by overriding -// the active context if a password field is focused. -- (NSInputContext *)inputContext +static BOOL isInPasswordField(Frame* coreFrame) { - Frame* coreFrame = core([self _frame]); - if (coreFrame && coreFrame->selectionController()->isInPasswordField()) - return nil; - return [super inputContext]; + return coreFrame && coreFrame->selection()->isInPasswordField(); } - (NSAttributedString *)textStorage { - if (!isTextInput(core([self _frame]))) { + Frame* coreFrame = core([self _frame]); + if (!isTextInput(coreFrame) || isInPasswordField(coreFrame)) { LOG(TextInput, "textStorage -> nil"); return nil; } @@ -4891,26 +4934,26 @@ static BOOL isTextInput(Frame* coreFrame) - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint { NSWindow *window = [self window]; - WebFrameBridge *bridge = [self _bridge]; + WebFrame *frame = [self _frame]; if (window) thePoint = [window convertScreenToBase:thePoint]; thePoint = [self convertPoint:thePoint fromView:nil]; - DOMRange *range = [bridge characterRangeAtPoint:thePoint]; + DOMRange *range = [frame _characterRangeAtPoint:thePoint]; if (!range) { LOG(TextInput, "characterIndexForPoint:(%f, %f) -> NSNotFound", thePoint.x, thePoint.y); return NSNotFound; } - unsigned result = [bridge convertDOMRangeToNSRange:range].location; + unsigned result = [frame _convertDOMRangeToNSRange:range].location; LOG(TextInput, "characterIndexForPoint:(%f, %f) -> %u", thePoint.x, thePoint.y, result); return result; } - (NSRect)firstRectForCharacterRange:(NSRange)theRange { - WebFrameBridge *bridge = [self _bridge]; + WebFrame *frame = [self _frame]; // Just to match NSTextView's behavior. Regression tests cannot detect this; // to reproduce, use a test application from http://bugs.webkit.org/show_bug.cgi?id=4682 @@ -4918,7 +4961,7 @@ static BOOL isTextInput(Frame* coreFrame) if ((theRange.location + theRange.length < theRange.location) && (theRange.location + theRange.length != 0)) theRange.length = 0; - DOMRange *range = [bridge convertNSRangeToDOMRange:theRange]; + DOMRange *range = [frame _convertNSRangeToDOMRange:theRange]; if (!range) { LOG(TextInput, "firstRectForCharacterRange:(%u, %u) -> (0, 0, 0, 0)", theRange.location, theRange.length); return NSMakeRect(0, 0, 0, 0); @@ -4927,7 +4970,7 @@ static BOOL isTextInput(Frame* coreFrame) ASSERT([range startContainer]); ASSERT([range endContainer]); - NSRect resultRect = [bridge firstRectForDOMRange:range]; + NSRect resultRect = [frame _firstRectForDOMRange:range]; resultRect = [self convertRect:resultRect toView:nil]; NSWindow *window = [self window]; @@ -4944,7 +4987,7 @@ static BOOL isTextInput(Frame* coreFrame) LOG(TextInput, "selectedRange -> (NSNotFound, 0)"); return NSMakeRange(NSNotFound, 0); } - NSRange result = [[self _bridge] selectedNSRange]; + NSRange result = [[self _frame] _selectedNSRange]; LOG(TextInput, "selectedRange -> (%u, %u)", result.location, result.length); return result; @@ -4952,19 +4995,21 @@ static BOOL isTextInput(Frame* coreFrame) - (NSRange)markedRange { - NSRange result = [[self _bridge] markedTextNSRange]; + WebFrame *webFrame = [self _frame]; + NSRange result = [webFrame _convertToNSRange:core(webFrame)->editor()->compositionRange().get()]; LOG(TextInput, "markedRange -> (%u, %u)", result.location, result.length); return result; } - (NSAttributedString *)attributedSubstringFromRange:(NSRange)nsRange { - if (!isTextInput(core([self _frame]))) { + WebFrame *frame = [self _frame]; + Frame* coreFrame = core(frame); + if (!isTextInput(coreFrame) || isInPasswordField(coreFrame)) { LOG(TextInput, "attributedSubstringFromRange:(%u, %u) -> nil", nsRange.location, nsRange.length); return nil; } - WebFrameBridge *bridge = [self _bridge]; - DOMRange *domRange = [bridge convertNSRangeToDOMRange:nsRange]; + DOMRange *domRange = [frame _convertNSRangeToDOMRange:nsRange]; if (!domRange) { LOG(TextInput, "attributedSubstringFromRange:(%u, %u) -> nil", nsRange.location, nsRange.length); return nil; @@ -5074,7 +5119,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde // The AppKit adds a 'secret' property to the string that contains the replacement range. // The replacement range is the range of the the text that should be replaced with the new string. if (rangeString) - [[self _bridge] selectNSRange:NSRangeFromString(rangeString)]; + [[self _frame] _selectNSRange:NSRangeFromString(rangeString)]; text = [string string]; extractUnderlines(string, underlines); @@ -5155,7 +5200,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:NULL inRange:NSMakeRange(0, [text length])]; LOG(TextInput, " ReplacementRange: %@", rangeString); if (rangeString) { - [[self _bridge] selectNSRange:NSRangeFromString(rangeString)]; + [[self _frame] _selectNSRange:NSRangeFromString(rangeString)]; isFromInputMethod = YES; } } else @@ -5260,9 +5305,9 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde { // FIXME: 3769654 - We should preserve case of string being inserted, even in prefix (but then also be // able to revert that). Mimic NSText. - WebFrameBridge *bridge = [_view _bridge]; + WebFrame *frame = [_view _frame]; NSString *newText = [match substringFromIndex:prefixLength]; - [bridge replaceSelectionWithText:newText selectReplacement:YES smartReplace:NO]; + [frame _replaceSelectionWithText:newText selectReplacement:YES smartReplace:NO]; } // mostly lifted from NSTextView_KeyBinding.m @@ -5359,9 +5404,9 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde } // Get preceeding word stem - WebFrameBridge *bridge = [_view _bridge]; - DOMRange *selection = kit(core([_view _frame])->selectionController()->toRange().get()); - DOMRange *wholeWord = [bridge rangeByAlteringCurrentSelection:SelectionController::EXTEND + WebFrame *frame = [_view _frame]; + DOMRange *selection = kit(core(frame)->selection()->toRange().get()); + DOMRange *wholeWord = [frame _rangeByAlteringCurrentSelection:SelectionController::EXTEND direction:SelectionController::BACKWARD granularity:WordGranularity]; DOMRange *prefix = [wholeWord cloneRange]; [prefix setEnd:[selection startContainer] offset:[selection startOffset]]; @@ -5371,7 +5416,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde NSBeep(); return; } - NSString *prefixStr = [bridge stringForRange:prefix]; + NSString *prefixStr = [frame _stringForRange:prefix]; NSString *trimmedPrefix = [prefixStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if ([trimmedPrefix length] == 0) { NSBeep(); @@ -5390,9 +5435,9 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde [self _insertMatch:[_completions objectAtIndex:0]]; } else { ASSERT(!_originalString); // this should only be set IFF we have a popup window - _originalString = [[bridge stringForRange:selection] retain]; + _originalString = [[frame _stringForRange:selection] retain]; [self _buildUI]; - NSRect wordRect = [bridge caretRectAtNode:[wholeWord startContainer] offset:[wholeWord startOffset] affinity:NSSelectionAffinityDownstream]; + NSRect wordRect = [frame _caretRectAtNode:[wholeWord startContainer] offset:[wholeWord startOffset] affinity:NSSelectionAffinityDownstream]; // +1 to be under the word, not the caret // FIXME - 3769652 - Wrong positioning for right to left languages. We should line up the upper // right corner with the caret instead of upper left, and the +1 would be a -1. @@ -5415,8 +5460,8 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde _popupWindow = nil; if (revertChange) { - WebFrameBridge *bridge = [_view _bridge]; - [bridge replaceSelectionWithText:_originalString selectReplacement:YES smartReplace:NO]; + WebFrame *frame = [_view _frame]; + [frame _replaceSelectionWithText:_originalString selectReplacement:YES smartReplace:NO]; } else if ([_view _hasSelection]) { if (goLeft) [_view moveBackward:nil]; @@ -5496,12 +5541,12 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde [self endRevertingChange:NO moveLeft:NO]; } -- (int)numberOfRowsInTableView:(NSTableView *)tableView +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { return [_completions count]; } -- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row +- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { return [_completions objectAtIndex:row]; } @@ -5551,13 +5596,6 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde return nil; } -- (NSImage *)selectionImageForcingWhiteText:(BOOL)forceWhiteText -{ - // NOTE: this method is obsolete and doesn't behave as its name suggests. - // See comment in WebDocumentPrivate.h. - return [self selectionImageForcingBlackText:forceWhiteText]; -} - - (NSRect)selectionImageRect { if ([self _hasSelection]) @@ -5585,7 +5623,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde { Frame* coreFrame = core([self _frame]); if (coreFrame) - coreFrame->selectionController()->selectAll(); + coreFrame->selection()->selectAll(); } - (void)deselectAll @@ -5593,12 +5631,12 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde Frame* coreFrame = core([self _frame]); if (!coreFrame) return; - coreFrame->selectionController()->clear(); + coreFrame->selection()->clear(); } - (NSString *)string { - return [[self _bridge] stringForRange:[self _documentRange]]; + return [[self _frame] _stringForRange:[self _documentRange]]; } - (NSAttributedString *)_attributeStringFromDOMRange:(DOMRange *)range @@ -5621,15 +5659,14 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde NSAttributedString *attributedString = [self _attributeStringFromDOMRange:[document _documentRange]]; if (!attributedString) { Document* coreDocument = core(document); - Range range(coreDocument, coreDocument, 0, 0, 0); - attributedString = [NSAttributedString _web_attributedStringFromRange:&range]; + attributedString = [NSAttributedString _web_attributedStringFromRange:Range::create(coreDocument, coreDocument, 0, coreDocument, coreDocument->childNodeCount()).get()]; } return attributedString; } - (NSString *)selectedString { - return [[self _bridge] selectedString]; + return [[self _frame] _selectedString]; } - (NSAttributedString *)selectedAttributedString @@ -5638,7 +5675,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde if (!attributedString) { Frame* coreFrame = core([self _frame]); if (coreFrame) { - RefPtr<Range> range = coreFrame->selectionController()->selection().toRange(); + RefPtr<Range> range = coreFrame->selection()->selection().toRange(); attributedString = [NSAttributedString _web_attributedStringFromRange:range.get()]; } } @@ -5654,8 +5691,8 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde { if (![string length]) return NO; - - return [[self _bridge] searchFor:string direction:forward caseSensitive:caseFlag wrap:wrapFlag startInSelection:startInSelection]; + Frame* coreFrame = core([self _frame]); + return coreFrame && coreFrame->findString(string, forward, caseFlag, wrapFlag, startInSelection); } @end @@ -5669,35 +5706,60 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde - (NSDictionary *)elementAtPoint:(NSPoint)point allowShadowContent:(BOOL)allow; { - Frame* coreframe = core([self _frame]); - if (coreframe) - return [[[WebElementDictionary alloc] initWithHitTestResult:coreframe->eventHandler()->hitTestResultAtPoint(IntPoint(point), allow)] autorelease]; - return nil; + Frame* coreFrame = core([self _frame]); + if (!coreFrame) + return nil; + return [[[WebElementDictionary alloc] initWithHitTestResult:coreFrame->eventHandler()->hitTestResultAtPoint(IntPoint(point), allow)] autorelease]; } - (NSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag limit:(NSUInteger)limit { - return [[self _bridge] markAllMatchesForText:string caseSensitive:caseFlag limit:limit]; + Frame* coreFrame = core([self _frame]); + if (!coreFrame) + return 0; + return coreFrame->markAllMatchesForText(string, caseFlag, limit); } - (void)setMarkedTextMatchesAreHighlighted:(BOOL)newValue { - [[self _bridge] setMarkedTextMatchesAreHighlighted:newValue]; + Frame* coreFrame = core([self _frame]); + if (!coreFrame) + return; + coreFrame->setMarkedTextMatchesAreHighlighted(newValue); } - (BOOL)markedTextMatchesAreHighlighted { - return [[self _bridge] markedTextMatchesAreHighlighted]; + Frame* coreFrame = core([self _frame]); + return coreFrame && coreFrame->markedTextMatchesAreHighlighted(); } - (void)unmarkAllTextMatches { - return [[self _bridge] unmarkAllTextMatches]; + Frame* coreFrame = core([self _frame]); + if (!coreFrame) + return; + Document* document = coreFrame->document(); + if (!document) + return; + document->removeMarkers(DocumentMarker::TextMatch); } - (NSArray *)rectsForTextMatches { - return [[self _bridge] rectsForTextMatches]; + Frame* coreFrame = core([self _frame]); + if (!coreFrame) + return [NSArray array]; + Document* document = coreFrame->document(); + if (!document) + return [NSArray array]; + + Vector<IntRect> rects = document->renderedRectsForMarkers(DocumentMarker::TextMatch); + unsigned count = rects.size(); + NSMutableArray *result = [NSMutableArray arrayWithCapacity:count]; + for (unsigned index = 0; index < count; ++index) + [result addObject:[NSValue valueWithRect:rects[index]]]; + return result; } @end diff --git a/WebKit/mac/WebView/WebHTMLViewInternal.h b/WebKit/mac/WebView/WebHTMLViewInternal.h index e54ab2d..0fb0cdc 100644 --- a/WebKit/mac/WebView/WebHTMLViewInternal.h +++ b/WebKit/mac/WebView/WebHTMLViewInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Apple Computer, 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 @@ -28,95 +28,26 @@ // Things internal to the WebKit framework; not SPI. -#import <WebKit/WebHTMLViewPrivate.h> +#import "WebHTMLViewPrivate.h" -@class WebTextCompleteController; -@class DOMDocumentFragment; -@class DOMElement; +@class WebFrame; namespace WebCore { - class KeyboardEvent; class CachedImage; + class KeyboardEvent; } -struct WebHTMLViewInterpretKeyEventsParameters; - -@interface WebHTMLViewPrivate : NSObject -{ -@public - BOOL closed; - BOOL needsLayout; - BOOL needsToApplyStyles; - BOOL ignoringMouseDraggedEvents; - BOOL printing; - BOOL avoidingPrintOrphan; - - id savedSubviews; - BOOL subviewsSetAside; - - NSEvent *mouseDownEvent; // Kept after handling the event. - BOOL handlingMouseDownEvent; - NSEvent *keyDownEvent; // Kept after handling the event. - - NSSize lastLayoutSize; - - NSPoint lastScrollPosition; - - WebPluginController *pluginController; - - NSString *toolTip; - NSToolTipTag lastToolTipTag; - id trackingRectOwner; - void *trackingRectUserData; - - NSTimer *autoscrollTimer; - NSEvent *autoscrollTriggerEvent; - - NSArray* pageRects; - - NSMutableDictionary* highlighters; - - BOOL resigningFirstResponder; - BOOL nextResponderDisabledOnce; - - WebTextCompleteController *compController; - - BOOL transparentBackground; - - WebHTMLViewInterpretKeyEventsParameters *interpretKeyEventsParameters; - BOOL receivedNOOP; - - WebDataSource *dataSource; - WebCore::CachedImage *promisedDragTIFFDataSource; - - CFRunLoopTimerRef updateFocusedAndActiveStateTimer; - CFRunLoopTimerRef updateMouseoverTimer; - - SEL selectorForDoCommandBySelector; - -#ifndef NDEBUG - BOOL enumeratingSubviews; -#endif -} -- (void)clear; -@end - @interface WebHTMLView (WebInternal) - (void)_selectionChanged; - (void)_updateFontPanel; - (BOOL)_canSmartCopyOrDelete; -#ifndef __LP64__ -- (void)_pauseNullEventsForAllNetscapePlugins; -- (void)_resumeNullEventsForAllNetscapePlugins; -#endif -- (id<WebHTMLHighlighter>)_highlighterForType:(NSString*)type; + +- (id <WebHTMLHighlighter>)_highlighterForType:(NSString*)type; - (WebFrame *)_frame; -- (void)paste:(id)sender; -- (void)closeIfNotCurrentView; - (void)_lookUpInDictionaryFromMenu:(id)sender; - (void)_hoverFeedbackSuspendedChanged; - (BOOL)_interceptEditingKeyEvent:(WebCore::KeyboardEvent *)event shouldSaveCommand:(BOOL)shouldSave; -- (DOMDocumentFragment*)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard; +- (DOMDocumentFragment *)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard; - (NSEvent *)_mouseDownEvent; #ifndef BUILDING_ON_TIGER - (BOOL)isGrammarCheckingEnabled; @@ -126,4 +57,5 @@ struct WebHTMLViewInterpretKeyEventsParameters; - (WebCore::CachedImage*)promisedDragTIFFDataSource; - (void)setPromisedDragTIFFDataSource:(WebCore::CachedImage*)source; - (void)_web_layoutIfNeededRecursive; +- (void)_destroyAllWebPlugins; @end diff --git a/WebKit/mac/WebView/WebHTMLViewPrivate.h b/WebKit/mac/WebView/WebHTMLViewPrivate.h index a2773f4..40de97f 100644 --- a/WebKit/mac/WebView/WebHTMLViewPrivate.h +++ b/WebKit/mac/WebView/WebHTMLViewPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Apple Computer, 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 @@ -28,14 +28,13 @@ #import <WebKit/WebHTMLView.h> +#if !defined(ENABLE_NETSCAPE_PLUGIN_API) +#define ENABLE_NETSCAPE_PLUGIN_API 1 +#endif + @class DOMDocumentFragment; -@class DOMElement; @class DOMNode; @class DOMRange; -@class WebArchive; -@class WebFrameBridge; -@class WebView; -@class WebFrame; @class WebPluginController; @protocol WebHTMLHighlighter @@ -93,11 +92,12 @@ - (BOOL)_isEditable; - (BOOL)_transparentBackground; -- (void)_setTransparentBackground:(BOOL)f; +- (void)_setTransparentBackground:(BOOL)isBackgroundTransparent; - (void)_setToolTip:(NSString *)string; -// SPI's for Mail. +// SPI used by Mail. +// FIXME: These should all be moved to WebView; we won't always have a WebHTMLView. - (NSImage *)_selectionDraggingImage; - (NSRect)_selectionDraggingRect; - (DOMNode *)_insertOrderedList; @@ -108,10 +108,15 @@ - (DOMNode *)_increaseSelectionListLevelOrdered; - (DOMNode *)_increaseSelectionListLevelUnordered; - (void)_decreaseSelectionListLevel; -- (void)_setHighlighter:(id<WebHTMLHighlighter>)highlighter ofType:(NSString*)type; -- (void)_removeHighlighterOfType:(NSString*)type; +- (void)_setHighlighter:(id <WebHTMLHighlighter>)highlighter ofType:(NSString *)type; +- (void)_removeHighlighterOfType:(NSString *)type; - (DOMDocumentFragment *)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard forType:(NSString *)pboardType inContext:(DOMRange *)context subresources:(NSArray **)subresources; +#if ENABLE_NETSCAPE_PLUGIN_API +- (void)_resumeNullEventsForAllNetscapePlugins; +- (void)_pauseNullEventsForAllNetscapePlugins; +#endif + // SPI for DumpRenderTree - (void)_updateFocusedAndActiveState; @@ -122,5 +127,4 @@ - (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard; - @end diff --git a/WebKit/mac/WebView/WebPDFRepresentation.m b/WebKit/mac/WebView/WebPDFRepresentation.m index beba1fa..1a2ddab 100644 --- a/WebKit/mac/WebView/WebPDFRepresentation.m +++ b/WebKit/mac/WebView/WebPDFRepresentation.m @@ -26,13 +26,13 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import <JavaScriptCore/Assertions.h> #import <WebKit/WebDataSource.h> #import <WebKit/WebFrame.h> #import <WebKit/WebFrameView.h> #import <WebKit/WebNSObjectExtras.h> #import <WebKit/WebPDFRepresentation.h> #import <WebKit/WebPDFView.h> +#import <wtf/Assertions.h> #import <PDFKit/PDFDocument.h> diff --git a/WebKit/mac/WebView/WebPDFView.h b/WebKit/mac/WebView/WebPDFView.h index 5d9ce1f..55d2a08 100644 --- a/WebKit/mac/WebView/WebPDFView.h +++ b/WebKit/mac/WebView/WebPDFView.h @@ -32,7 +32,7 @@ @class PDFView; @class WebDataSource; -@interface WebPDFView : NSView <WebDocumentView, WebDocumentSearching, WebDocumentIncrementalSearching, WebMultipleTextMatches, WebDocumentSelection, WebDocumentElement, _WebDocumentViewState, _WebDocumentTextSizing> +@interface WebPDFView : NSView <WebDocumentView, WebDocumentSearching, WebDocumentIncrementalSearching, WebMultipleTextMatches, WebDocumentSelection, WebDocumentElement, _WebDocumentViewState, _WebDocumentZooming> { NSView *previewView; PDFView *PDFSubview; diff --git a/WebKit/mac/WebView/WebPDFView.mm b/WebKit/mac/WebView/WebPDFView.mm index 630b6de..1009cdd 100644 --- a/WebKit/mac/WebView/WebPDFView.mm +++ b/WebKit/mac/WebView/WebPDFView.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 @@ -45,18 +45,18 @@ #import "WebUIDelegatePrivate.h" #import "WebView.h" #import "WebViewInternal.h" -#import <JavaScriptCore/Assertions.h> #import <PDFKit/PDFKit.h> #import <WebCore/EventNames.h> +#import <WebCore/Frame.h> #import <WebCore/FrameLoader.h> +#import <WebCore/FrameLoadRequest.h> #import <WebCore/KURL.h> #import <WebCore/KeyboardEvent.h> #import <WebCore/MouseEvent.h> #import <WebCore/PlatformKeyboardEvent.h> -#import <WebKitSystemInterface.h> +#import <wtf/Assertions.h> using namespace WebCore; -using namespace EventNames; // Redeclarations of PDFKit notifications. We can't use the API since we use a weak link to the framework. #define _webkit_PDFViewDisplayModeChangedNotification @"PDFViewDisplayModeChanged" @@ -491,6 +491,10 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item { + // This can be called during teardown when _webView is nil. Return NO when this happens, because CallUIDelegateReturningBoolean + // assumes the WebVIew is non-nil. + if (![self _webView]) + return NO; BOOL result = [self validateUserInterfaceItemWithoutDelegate:item]; return CallUIDelegateReturningBoolean(result, [self _webView], @selector(webView:validateUserInterfaceItem:defaultValidation:), item, result); } @@ -782,43 +786,32 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec #pragma mark _WebDocumentTextSizing PROTOCOL IMPLEMENTATION -- (IBAction)_makeTextSmaller:(id)sender +- (IBAction)_zoomOut:(id)sender { [PDFSubviewProxy zoomOut:sender]; } -- (IBAction)_makeTextLarger:(id)sender +- (IBAction)_zoomIn:(id)sender { [PDFSubviewProxy zoomIn:sender]; } -- (IBAction)_makeTextStandardSize:(id)sender +- (IBAction)_resetZoom:(id)sender { [PDFSubviewProxy setScaleFactor:1.0f]; } -// never sent because we do not track the common size factor -- (void)_textSizeMultiplierChanged { ASSERT_NOT_REACHED(); } - -- (BOOL)_tracksCommonSizeFactor -{ - // We keep our own scale factor instead of tracking the common one in the WebView for a couple reasons. - // First, PDFs tend to have visually smaller text because they are laid out for a printed page instead of - // the screen. Second, the PDFView feature of AutoScaling means our scaling factor can be quiet variable. - return NO; -} - -- (BOOL)_canMakeTextSmaller +- (BOOL)_canZoomOut { return [PDFSubview canZoomOut]; } -- (BOOL)_canMakeTextLarger +- (BOOL)_canZoomIn { return [PDFSubview canZoomIn]; } -- (BOOL)_canMakeTextStandardSize +- (BOOL)_canResetZoom { return [PDFSubview scaleFactor] != 1.0; } @@ -884,13 +877,6 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec return selectionImage; } -- (NSImage *)selectionImageForcingWhiteText:(BOOL)forceWhiteText -{ - // NOTE: this method is obsolete and doesn't behave as its name suggests. - // See comment in WebDocumentPrivate.h. - return [self selectionImageForcingBlackText:forceWhiteText]; -} - - (NSRect)selectionImageRect { // FIXME: deal with clipping? @@ -948,7 +934,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec case NSKeyDown: { PlatformKeyboardEvent pe(nsEvent); pe.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown); - event = new KeyboardEvent(keydownEvent, true, true, 0, + event = KeyboardEvent::create(eventNames().keydownEvent, true, true, 0, pe.keyIdentifier(), pe.windowsVirtualKeyCode(), pe.ctrlKey(), pe.altKey(), pe.shiftKey(), pe.metaKey(), false); } @@ -956,7 +942,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec break; } if (button != noButton) - event = new MouseEvent(clickEvent, true, true, 0, [nsEvent clickCount], 0, 0, 0, 0, + event = MouseEvent::create(eventNames().clickEvent, true, true, 0, [nsEvent clickCount], 0, 0, 0, 0, [nsEvent modifierFlags] & NSControlKeyMask, [nsEvent modifierFlags] & NSAlternateKeyMask, [nsEvent modifierFlags] & NSShiftKeyMask, @@ -964,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. - [[dataSource webFrame] _frameLoader]->load(URL, event.get()); + core([dataSource webFrame])->loader()->loadFrameRequestWithFormAndValues(ResourceRequest(URL), false, event.get(), 0, HashMap<String, String>()); } - (void)PDFViewOpenPDFInNativeApplication:(PDFView *)sender @@ -973,6 +959,11 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec [self _openWithFinder:sender]; } +- (void)PDFViewPerformPrint:(PDFView *)sender +{ + CallUIDelegate([self _webView], @selector(webView:printFrameView:), [[dataSource webFrame] frameView]); +} + - (void)PDFViewSavePDFToDownloadFolder:(PDFView *)sender { // We don't want to write the file until we have a document to write (see 5267607). diff --git a/WebKit/mac/WebView/WebPolicyDelegate.mm b/WebKit/mac/WebView/WebPolicyDelegate.mm index 147e761..f2df744 100644 --- a/WebKit/mac/WebView/WebPolicyDelegate.mm +++ b/WebKit/mac/WebView/WebPolicyDelegate.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006 Apple Computer, 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 @@ -33,10 +33,11 @@ using namespace WebCore; -NSString *WebActionNavigationTypeKey = @"WebActionNavigationTypeKey"; -NSString *WebActionElementKey = @"WebActionElementKey"; NSString *WebActionButtonKey = @"WebActionButtonKey"; +NSString *WebActionElementKey = @"WebActionElementKey"; +NSString *WebActionFormKey = @"WebActionFormKey"; NSString *WebActionModifierFlagsKey = @"WebActionModifierFlagsKey"; +NSString *WebActionNavigationTypeKey = @"WebActionNavigationTypeKey"; NSString *WebActionOriginalURLKey = @"WebActionOriginalURLKey"; @interface WebPolicyDecisionListenerPrivate : NSObject diff --git a/WebKit/mac/WebView/WebPolicyDelegatePrivate.h b/WebKit/mac/WebView/WebPolicyDelegatePrivate.h index f7bbbd5..45f8f45 100644 --- a/WebKit/mac/WebView/WebPolicyDelegatePrivate.h +++ b/WebKit/mac/WebView/WebPolicyDelegatePrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2005, 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 @@ -31,6 +31,8 @@ @class WebHistoryItem; @class WebPolicyDecisionListenerPrivate; +extern NSString *WebActionFormKey; // HTMLFormElement + typedef enum { WebNavigationTypePlugInRequest = WebNavigationTypeOther + 1 } WebExtraNavigationType; diff --git a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h index d7a798c..bcb17db 100644 --- a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h +++ b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h @@ -64,6 +64,12 @@ #define WebKitForceFTPDirectoryListings @"WebKitForceFTPDirectoryListings" #define WebKitDeveloperExtrasEnabledPreferenceKey @"WebKitDeveloperExtrasEnabledPreferenceKey" #define WebKitAuthorAndUserStylesEnabledPreferenceKey @"WebKitAuthorAndUserStylesEnabledPreferenceKey" +#define WebKitApplicationChromeModeEnabledPreferenceKey @"WebKitApplicationChromeModeEnabledPreferenceKey" +#define WebKitWebArchiveDebugModeEnabledPreferenceKey @"WebKitWebArchiveDebugModeEnabledPreferenceKey" +#define WebKitLocalStorageDatabasePathPreferenceKey @"WebKitLocalStorageDatabasePathPreferenceKey" +#define WebKitEnableFullDocumentTeardownPreferenceKey @"WebKitEnableFullDocumentTeardown" +#define WebKitOfflineWebApplicationCacheEnabledPreferenceKey @"WebKitOfflineWebApplicationCacheEnabled" +#define WebKitZoomsTextOnlyPreferenceKey @"WebKitZoomsTextOnly" // These are private both because callers should be using the cover methods and because the // cover methods themselves are private. @@ -83,3 +89,4 @@ // For debugging only. Don't use these. #define WebKitPageCacheSizePreferenceKey @"WebKitPageCacheSizePreferenceKey" #define WebKitObjectCacheSizePreferenceKey @"WebKitObjectCacheSizePreferenceKey" +#define WebKitDebugFullPageZoomPreferenceKey @"WebKitDebugFullPageZoomPreferenceKey" diff --git a/WebKit/mac/WebView/WebPreferences.m b/WebKit/mac/WebView/WebPreferences.mm index 1d5f480..8b2f43e 100644 --- a/WebKit/mac/WebView/WebPreferences.m +++ b/WebKit/mac/WebView/WebPreferences.mm @@ -330,8 +330,17 @@ static WebCacheModel cacheModelForMainBundle(void) [NSNumber numberWithBool:NO], WebKitDOMPasteAllowedPreferenceKey, [NSNumber numberWithBool:YES], WebKitUsesPageCachePreferenceKey, [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey, - [NSNumber numberWithBool:NO], WebKitDeveloperExtrasEnabledPreferenceKey, + [NSNumber numberWithBool:NO], WebKitDeveloperExtrasEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitAuthorAndUserStylesEnabledPreferenceKey, + [NSNumber numberWithBool:NO], WebKitApplicationChromeModeEnabledPreferenceKey, + [NSNumber numberWithBool:NO], WebKitWebArchiveDebugModeEnabledPreferenceKey, + [NSNumber numberWithBool:NO], WebKitOfflineWebApplicationCacheEnabledPreferenceKey, + [NSNumber numberWithBool:YES], WebKitZoomsTextOnlyPreferenceKey, +#ifndef NDEBUG + // In Release and Production we skip a lot of object teardown during quit to speed up shutdown time. This breaks + // our RefCount Leak tracking, and so for Debug we will use the full document teardown. + [NSNumber numberWithBool:YES], WebKitEnableFullDocumentTeardownPreferenceKey, +#endif nil]; // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above @@ -755,6 +764,46 @@ static WebCacheModel cacheModelForMainBundle(void) [self _setBoolValue:flag forKey:WebKitAuthorAndUserStylesEnabledPreferenceKey]; } +- (BOOL)applicationChromeModeEnabled +{ + return [self _boolValueForKey:WebKitApplicationChromeModeEnabledPreferenceKey]; +} + +- (void)setApplicationChromeModeEnabled:(BOOL)flag +{ + [self _setBoolValue:flag forKey:WebKitApplicationChromeModeEnabledPreferenceKey]; +} + +- (BOOL)webArchiveDebugModeEnabled +{ + return [self _boolValueForKey:WebKitWebArchiveDebugModeEnabledPreferenceKey]; +} + +- (void)setWebArchiveDebugModeEnabled:(BOOL)flag +{ + [self _setBoolValue:flag forKey:WebKitWebArchiveDebugModeEnabledPreferenceKey]; +} + +- (BOOL)offlineWebApplicationCacheEnabled +{ + return [self _boolValueForKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey]; +} + +- (void)setOfflineWebApplicationCacheEnabled:(BOOL)flag +{ + [self _setBoolValue:flag forKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey]; +} + +- (BOOL)zoomsTextOnly +{ + return [self _boolValueForKey:WebKitZoomsTextOnlyPreferenceKey]; +} + +- (void)setZoomsTextOnly:(BOOL)flag +{ + [self _setBoolValue:flag forKey:WebKitZoomsTextOnlyPreferenceKey]; +} + - (BOOL)respectStandardStyleKeyEquivalents { return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey]; @@ -838,7 +887,7 @@ static WebCacheModel cacheModelForMainBundle(void) - (WebKitEditableLinkBehavior)editableLinkBehavior { - WebKitEditableLinkBehavior value = [self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]; + WebKitEditableLinkBehavior value = static_cast<WebKitEditableLinkBehavior> ([self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]); if (value != WebKitEditableLinkDefaultBehavior && value != WebKitEditableLinkAlwaysLive && value != WebKitEditableLinkNeverLive && @@ -917,9 +966,15 @@ static WebCacheModel cacheModelForMainBundle(void) + (void)_setInitialDefaultTextEncodingToSystemEncoding { + NSString *systemEncodingName = (NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding]); + + // CFStringConvertEncodingToIANACharSetName() returns CP949 for kTextEncodingDOSKorean AKA "extended EUC-KR" AKA windows-939. + // ICU uses this name for a different encoding, so we need to change the name to a value that actually gives us windows-939. + // In addition, this value must match what is used in Safari, see <rdar://problem/5579292>. + if ([systemEncodingName isEqualToString:@"CP949"]) + systemEncodingName = @"ks_c_5601-1987"; [[NSUserDefaults standardUserDefaults] registerDefaults: - [NSDictionary dictionaryWithObject:(NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding]) - forKey:WebKitDefaultTextEncodingNamePreferenceKey]]; + [NSDictionary dictionaryWithObject:systemEncodingName forKey:WebKitDefaultTextEncodingNamePreferenceKey]]; } static NSString *classIBCreatorID = nil; @@ -943,12 +998,22 @@ static NSString *classIBCreatorID = nil; - (void)_setFTPDirectoryTemplatePath:(NSString *)path { - [self _setStringValue:path forKey:WebKitFTPDirectoryTemplatePath]; + [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitFTPDirectoryTemplatePath]; +} + +- (NSString *)_localStorageDatabasePath +{ + return [[self _stringValueForKey:WebKitLocalStorageDatabasePathPreferenceKey] stringByStandardizingPath]; +} + +- (void)_setLocalStorageDatabasePath:(NSString *)path +{ + [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitLocalStorageDatabasePathPreferenceKey]; } - (NSString *)_ftpDirectoryTemplatePath { - return [self _stringValueForKey:WebKitFTPDirectoryTemplatePath]; + return [[self _stringValueForKey:WebKitFTPDirectoryTemplatePath] stringByStandardizingPath]; } - (void)_setForceFTPDirectoryListings:(BOOL)force @@ -976,6 +1041,15 @@ static NSString *classIBCreatorID = nil; ++_private->numWebViews; } +- (void)setFullDocumentTeardownEnabled:(BOOL)fullDocumentTeardownEnabled +{ + [self _setBoolValue:fullDocumentTeardownEnabled forKey:WebKitEnableFullDocumentTeardownPreferenceKey]; +} + +- (BOOL)fullDocumentTeardownEnabled +{ + return [self _boolValueForKey:WebKitEnableFullDocumentTeardownPreferenceKey]; +} @end @implementation WebPreferences (WebInternal) diff --git a/WebKit/mac/WebView/WebPreferencesPrivate.h b/WebKit/mac/WebView/WebPreferencesPrivate.h index a6b5cb2..1981290 100644 --- a/WebKit/mac/WebView/WebPreferencesPrivate.h +++ b/WebKit/mac/WebView/WebPreferencesPrivate.h @@ -29,9 +29,8 @@ #import <WebKit/WebPreferences.h> #import <Quartz/Quartz.h> -// WebKitEditableLinkBehavior needs to match the EditableLinkBehavior enum in WebCore typedef enum { - WebKitEditableLinkDefaultBehavior = 0, + WebKitEditableLinkDefaultBehavior, WebKitEditableLinkAlwaysLive, WebKitEditableLinkOnlyLiveWithShiftKey, WebKitEditableLinkLiveWhenNotFocused, @@ -51,6 +50,9 @@ extern NSString *WebPreferencesRemovedNotification; - (BOOL)authorAndUserStylesEnabled; - (void)setAuthorAndUserStylesEnabled:(BOOL)flag; +- (BOOL)applicationChromeModeEnabled; +- (void)setApplicationChromeModeEnabled:(BOOL)flag; + - (BOOL)respectStandardStyleKeyEquivalents; - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag; @@ -69,6 +71,15 @@ extern NSString *WebPreferencesRemovedNotification; - (BOOL)automaticallyDetectsCacheModel; - (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel; +- (BOOL)webArchiveDebugModeEnabled; +- (void)setWebArchiveDebugModeEnabled:(BOOL)webArchiveDebugModeEnabled; + +- (BOOL)offlineWebApplicationCacheEnabled; +- (void)setOfflineWebApplicationCacheEnabled:(BOOL)offlineWebApplicationCacheEnabled; + +- (BOOL)zoomsTextOnly; +- (void)setZoomsTextOnly:(BOOL)zoomsTextOnly; + // zero means do AutoScale - (float)PDFScaleFactor; - (void)setPDFScaleFactor:(float)scale; @@ -90,6 +101,8 @@ extern NSString *WebPreferencesRemovedNotification; - (void)_setFTPDirectoryTemplatePath:(NSString *)path; - (void)_setForceFTPDirectoryListings:(BOOL)force; - (BOOL)_forceFTPDirectoryListings; +- (NSString *)_localStorageDatabasePath; +- (void)_setLocalStorageDatabasePath:(NSString *)path; // Other private methods - (void)_postPreferencesChangesNotification; @@ -105,4 +118,7 @@ extern NSString *WebPreferencesRemovedNotification; - (void)willAddToWebView; - (void)didRemoveFromWebView; +// Force document tear down at application quit +- (void)setFullDocumentTeardownEnabled:(BOOL)fullDocumentTeardownEnabled; +- (BOOL)fullDocumentTeardownEnabled; @end diff --git a/WebKit/mac/WebView/WebRenderNode.mm b/WebKit/mac/WebView/WebRenderNode.mm index 8d626e8..c34ac34 100644 --- a/WebKit/mac/WebView/WebRenderNode.mm +++ b/WebKit/mac/WebView/WebRenderNode.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2005, 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 @@ -28,19 +28,19 @@ #import "WebRenderNode.h" -#import <WebKit/WebFrameBridge.h> -#import <WebKit/WebFrameView.h> -#import <WebKit/WebHTMLView.h> -#import <WebKit/WebDataSourceInternal.h> -#import <WebKit/WebNSViewExtras.h> #import "WebFrameInternal.h" +#import "WebFrameView.h" +#import "WebHTMLView.h" +#import <WebCore/Frame.h> +#import <WebCore/RenderWidget.h> +#import <WebCore/RenderView.h> +#import <WebCore/Widget.h> -@interface WebKitRenderTreeCopier : NSObject <WebCoreRenderTreeCopier> -@end +using namespace WebCore; @implementation WebRenderNode -- initWithName:(NSString *)n position: (NSPoint)p rect:(NSRect)r view:(NSView *)view children:(NSArray *)c +- (id)initWithName:(NSString *)n position:(NSPoint)p rect:(NSRect)r view:(NSView *)view children:(NSArray *)c { NSMutableArray *collectChildren; @@ -71,21 +71,45 @@ return self; } -- initWithWebFrameView:(WebFrameView *)view +static WebRenderNode *copyRenderNode(RenderObject* node) { - WebKitRenderTreeCopier *copier; + NSMutableArray *children = [[NSMutableArray alloc] init]; + for (RenderObject* child = node->firstChild(); child; child = child->nextSibling()) { + WebRenderNode *childCopy = copyRenderNode(child); + [children addObject:childCopy]; + [childCopy release]; + } + + NSString *name = [[NSString alloc] initWithUTF8String:node->renderName()]; + RenderWidget* renderWidget = node->isWidget() ? static_cast<RenderWidget*>(node) : 0; + Widget* widget = renderWidget ? renderWidget->widget() : 0; + NSView *view = widget ? widget->platformWidget() : nil; + + int nx, ny; + node->absolutePosition(nx, ny); + WebRenderNode *result = [[WebRenderNode alloc] initWithName:name + position:NSMakePoint(nx, ny) rect:NSMakeRect(node->xPos(), node->yPos(), node->width(), node->height()) + view:view children:children]; + + [name release]; + [children release]; + + return result; +} + +- (id)initWithWebFrameView:(WebFrameView *)view +{ [self release]; - if (![[view documentView] isMemberOfClass:[WebHTMLView class]]) { + if (![[view documentView] isMemberOfClass:[WebHTMLView class]]) return nil; - } - - copier = [[WebKitRenderTreeCopier alloc] init]; - self = [[[[[view webFrame] _dataSource] _bridge] copyRenderTree:copier] retain]; - [copier release]; - - return self; + + RenderObject* renderer = core([view webFrame])->contentRenderer(); + if (!renderer) + return nil; + + return copyRenderNode(renderer); } - (void)dealloc @@ -126,12 +150,3 @@ } @end - -@implementation WebKitRenderTreeCopier - -- (NSObject *)nodeWithName:(NSString *)name position: (NSPoint)p rect:(NSRect)rect view:(NSView *)view children:(NSArray *)children -{ - return [[[WebRenderNode alloc] initWithName:name position: p rect:rect view:view children:children] autorelease]; -} - -@end diff --git a/WebKit/mac/WebView/WebResource.h b/WebKit/mac/WebView/WebResource.h index 2544d78..7d817b7 100644 --- a/WebKit/mac/WebView/WebResource.h +++ b/WebKit/mac/WebView/WebResource.h @@ -28,7 +28,6 @@ #import <Foundation/Foundation.h> -@class WebMainResourcePrivate; @class WebResourcePrivate; diff --git a/WebKit/mac/WebView/WebResource.mm b/WebKit/mac/WebView/WebResource.mm index 5f2928d..6e0c9f0 100644 --- a/WebKit/mac/WebView/WebResource.mm +++ b/WebKit/mac/WebView/WebResource.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 @@ -28,10 +28,20 @@ #import "WebResourcePrivate.h" -#import "WebFrameBridge.h" +#import "WebFrameInternal.h" #import "WebNSDictionaryExtras.h" #import "WebNSURLExtras.h" +#import <WebCore/ArchiveResource.h> +#import <WebCore/LegacyWebArchive.h> +#import <WebCore/TextEncoding.h> +#import <WebCore/WebCoreObjCExtras.h> +#import <WebCore/WebCoreURLResponse.h> + +#import <wtf/PassRefPtr.h> + +using namespace WebCore; + static NSString * const WebResourceDataKey = @"WebResourceData"; static NSString * const WebResourceFrameNameKey = @"WebResourceFrameName"; static NSString * const WebResourceMIMETypeKey = @"WebResourceMIMEType"; @@ -44,29 +54,55 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" @interface WebResourcePrivate : NSObject { @public - NSData *data; - NSURL *URL; - NSString *frameName; - NSString *MIMEType; - NSString *textEncodingName; - NSURLResponse *response; - BOOL shouldIgnoreWhenUnarchiving; + ArchiveResource* coreResource; } + +- (id)initWithCoreResource:(PassRefPtr<ArchiveResource>)coreResource; @end @implementation WebResourcePrivate +#ifndef BUILDING_ON_TIGER ++ (void)initialize +{ + WebCoreObjCFinalizeOnMainThread(self); +} +#endif + +- (id)init +{ + return [super init]; +} + +- (id)initWithCoreResource:(PassRefPtr<ArchiveResource>)passedResource +{ + self = [super init]; + if (!self) + return self; + + // Acquire the PassRefPtr<>'s ref as our own manual ref + coreResource = passedResource.releaseRef(); + + return self; +} + - (void)dealloc { - [data release]; - [URL release]; - [frameName release]; - [MIMEType release]; - [textEncodingName release]; - [response release]; + if (WebCoreObjCScheduleDeallocateOnMainThread([WebResourcePrivate class], self)) + return; + + if (coreResource) + coreResource->deref(); [super dealloc]; } +- (void)finalize +{ + if (coreResource) + coreResource->deref(); + [super finalize]; +} + @end @implementation WebResource @@ -87,45 +123,68 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" - (id)initWithCoder:(NSCoder *)decoder { - self = [self init]; + self = [super init]; if (!self) return nil; + NSData *data = nil; + NSURL *url = nil; + NSString *mimeType = nil, *textEncoding = nil, *frameName = nil; + NSURLResponse *response = nil; + @try { id object = [decoder decodeObjectForKey:WebResourceDataKey]; if ([object isKindOfClass:[NSData class]]) - _private->data = [object retain]; + data = object; object = [decoder decodeObjectForKey:WebResourceURLKey]; if ([object isKindOfClass:[NSURL class]]) - _private->URL = [object retain]; + url = object; object = [decoder decodeObjectForKey:WebResourceMIMETypeKey]; if ([object isKindOfClass:[NSString class]]) - _private->MIMEType = [object retain]; + mimeType = object; object = [decoder decodeObjectForKey:WebResourceTextEncodingNameKey]; if ([object isKindOfClass:[NSString class]]) - _private->textEncodingName = [object retain]; + textEncoding = object; object = [decoder decodeObjectForKey:WebResourceFrameNameKey]; if ([object isKindOfClass:[NSString class]]) - _private->frameName = [object retain]; + frameName = object; object = [decoder decodeObjectForKey:WebResourceResponseKey]; if ([object isKindOfClass:[NSURLResponse class]]) - _private->response = [object retain]; + response = object; } @catch(id) { [self release]; return nil; } + _private = [[WebResourcePrivate alloc] initWithCoreResource:ArchiveResource::create(SharedBuffer::wrapNSData(data), url, mimeType, textEncoding, frameName, response)]; + return self; } - (void)encodeWithCoder:(NSCoder *)encoder { - [encoder encodeObject:_private->data forKey:WebResourceDataKey]; - [encoder encodeObject:_private->URL forKey:WebResourceURLKey]; - [encoder encodeObject:_private->MIMEType forKey:WebResourceMIMETypeKey]; - [encoder encodeObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey]; - [encoder encodeObject:_private->frameName forKey:WebResourceFrameNameKey]; - [encoder encodeObject:_private->response forKey:WebResourceResponseKey]; + ArchiveResource *resource = _private->coreResource; + + NSData *data = nil; + NSURL *url = nil; + NSString *mimeType = nil, *textEncoding = nil, *frameName = nil; + NSURLResponse *response = nil; + + if (resource) { + if (resource->data()) + data = [resource->data()->createNSData() autorelease]; + url = resource->url(); + mimeType = resource->mimeType(); + textEncoding = resource->textEncoding(); + frameName = resource->frameName(); + response = resource->response().nsURLResponse(); + } + [encoder encodeObject:data forKey:WebResourceDataKey]; + [encoder encodeObject:url forKey:WebResourceURLKey]; + [encoder encodeObject:mimeType forKey:WebResourceMIMETypeKey]; + [encoder encodeObject:textEncoding forKey:WebResourceTextEncodingNameKey]; + [encoder encodeObject:frameName forKey:WebResourceFrameNameKey]; + [encoder encodeObject:response forKey:WebResourceResponseKey]; } - (void)dealloc @@ -141,27 +200,29 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" - (NSData *)data { - return _private->data; + if (_private->coreResource && _private->coreResource->data()) + return [_private->coreResource->data()->createNSData() autorelease]; + return 0; } - (NSURL *)URL { - return _private->URL; + return _private->coreResource ? (NSURL *)_private->coreResource->url() : 0; } - (NSString *)MIMEType { - return _private->MIMEType; + return _private->coreResource ? (NSString *)_private->coreResource->mimeType() : 0; } - (NSString *)textEncodingName { - return _private->textEncodingName; + return _private->coreResource ? (NSString *)_private->coreResource->textEncoding() : 0; } - (NSString *)frameName { - return _private->frameName; + return _private->coreResource ? (NSString *)_private->coreResource->frameName() : 0; } - (id)description @@ -171,46 +232,43 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" @end -@implementation WebResource (WebResourcePrivate) +@implementation WebResource (WebResourceInternal) -// SPI for Mail (5066325) -- (void)_ignoreWhenUnarchiving +- (id)_initWithCoreResource:(PassRefPtr<ArchiveResource>)coreResource { - _private->shouldIgnoreWhenUnarchiving = YES; + self = [super init]; + if (!self) + return nil; + + ASSERT(coreResource); + + // WebResources should not be init'ed with nil data, and doing so breaks certain uses of NSHTMLReader + // See <rdar://problem/5820157> for more info + if (!coreResource->data()) { + [self release]; + return nil; + } + + _private = [[WebResourcePrivate alloc] initWithCoreResource:coreResource]; + + return self; } -- (BOOL)_shouldIgnoreWhenUnarchiving +- (WebCore::ArchiveResource *)_coreResource { - return _private->shouldIgnoreWhenUnarchiving; + return _private->coreResource; } -+ (NSArray *)_resourcesFromPropertyLists:(NSArray *)propertyLists -{ - if (![propertyLists isKindOfClass:[NSArray class]]) { - return nil; - } - NSEnumerator *enumerator = [propertyLists objectEnumerator]; - NSMutableArray *resources = [NSMutableArray array]; - NSDictionary *propertyList; - while ((propertyList = [enumerator nextObject]) != nil) { - WebResource *resource = [[WebResource alloc] _initWithPropertyList:propertyList]; - if (resource) { - [resources addObject:resource]; - [resource release]; - } - } - return resources; -} +@end -+ (NSArray *)_propertyListsFromResources:(NSArray *)resources +@implementation WebResource (WebResourcePrivate) + +// SPI for Mail (5066325) +// FIXME: This "ignoreWhenUnarchiving" concept is an ugly one - can we find a cleaner solution for those who need this SPI? +- (void)_ignoreWhenUnarchiving { - NSEnumerator *enumerator = [resources objectEnumerator]; - NSMutableArray *propertyLists = [NSMutableArray array]; - WebResource *resource; - while ((resource = [enumerator nextObject]) != nil) { - [propertyLists addObject:[resource _propertyListRepresentation]]; - } - return propertyLists; + if (_private->coreResource) + _private->coreResource->ignoreWhenUnarchiving(); } - (id)_initWithData:(NSData *)data @@ -221,128 +279,68 @@ static NSString * const WebResourceResponseKey = @"WebResourceResponse" response:(NSURLResponse *)response copyData:(BOOL)copyData { - [self init]; - - if (!data) { - [self release]; - return nil; - } - _private->data = copyData ? [data copy] : [data retain]; - - if (!URL) { - [self release]; + self = [super init]; + if (!self) return nil; - } - _private->URL = [URL copy]; - if (!MIMEType) { + if (!data || !URL || !MIMEType) { [self release]; return nil; } - _private->MIMEType = [MIMEType copy]; - - _private->textEncodingName = [textEncodingName copy]; - _private->frameName = [frameName copy]; - _private->response = [response retain]; - + + _private = [[WebResourcePrivate alloc] initWithCoreResource:ArchiveResource::create(SharedBuffer::wrapNSData(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response)]; + return self; } -- (id)_initWithData:(NSData *)data URL:(NSURL *)URL response:(NSURLResponse *)response MIMEType:(NSString *)MIMEType +- (id)_initWithData:(NSData *)data URL:(NSURL *)URL response:(NSURLResponse *)response { // Pass NO for copyData since the data doesn't need to be copied since we know that callers will no longer modify it. // Copying it will also cause a performance regression. return [self _initWithData:data URL:URL - MIMEType:MIMEType + MIMEType:[response _webcore_MIMEType] textEncodingName:[response textEncodingName] frameName:nil response:response copyData:NO]; } -- (id)_initWithPropertyList:(id)propertyList +- (NSFileWrapper *)_fileWrapperRepresentation { - if (![propertyList isKindOfClass:[NSDictionary class]]) { - [self release]; - return nil; - } + SharedBuffer* coreData = _private->coreResource ? _private->coreResource->data() : 0; + NSData *data = coreData ? [coreData->createNSData() autorelease] : nil; - NSURLResponse *response = nil; - NSData *responseData = [propertyList objectForKey:WebResourceResponseKey]; - if ([responseData isKindOfClass:[NSData class]]) { - NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData]; - @try { - id responseObject = [unarchiver decodeObjectForKey:WebResourceResponseKey]; - if ([responseObject isKindOfClass:[NSURLResponse class]]) - response = responseObject; - [unarchiver finishDecoding]; - } @catch(id) { - response = nil; - } - [unarchiver release]; + 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]; } - - NSData *data = [propertyList objectForKey:WebResourceDataKey]; - NSString *URLString = [propertyList _webkit_stringForKey:WebResourceURLKey]; - return [self _initWithData:[data isKindOfClass:[NSData class]] ? data : nil - URL:URLString ? [NSURL _web_URLWithDataAsString:URLString] : nil - MIMEType:[propertyList _webkit_stringForKey:WebResourceMIMETypeKey] - textEncodingName:[propertyList _webkit_stringForKey:WebResourceTextEncodingNameKey] - frameName:[propertyList _webkit_stringForKey:WebResourceFrameNameKey] - response:response - copyData:NO]; -} - -- (NSFileWrapper *)_fileWrapperRepresentation -{ - NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:_private->data] autorelease]; - NSString *preferredFilename = [_private->response suggestedFilename]; - if (!preferredFilename || ![preferredFilename length]) - preferredFilename = [_private->URL _webkit_suggestedFilenameWithMIMEType:_private->MIMEType]; + [wrapper setPreferredFilename:preferredFilename]; return wrapper; } -- (id)_propertyListRepresentation -{ - NSMutableDictionary *propertyList = [NSMutableDictionary dictionary]; - [propertyList setObject:_private->data forKey:WebResourceDataKey]; - [propertyList setObject:[_private->URL _web_originalDataAsString] forKey:WebResourceURLKey]; - [propertyList setObject:_private->MIMEType forKey:WebResourceMIMETypeKey]; - if (_private->textEncodingName != nil) { - [propertyList setObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey]; - } - if (_private->frameName != nil) { - [propertyList setObject:_private->frameName forKey:WebResourceFrameNameKey]; - } - if (_private->response != nil) { - NSMutableData *responseData = [[NSMutableData alloc] init]; - NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:responseData]; - [archiver encodeObject:_private->response forKey:WebResourceResponseKey]; - [archiver finishEncoding]; - [archiver release]; - [propertyList setObject:responseData forKey:WebResourceResponseKey]; - [responseData release]; - } - return propertyList; -} - - (NSURLResponse *)_response { - if (_private->response != nil) { - return _private->response; - } - return [[[NSURLResponse alloc] initWithURL:_private->URL - MIMEType:_private->MIMEType - expectedContentLength:[_private->data length] - textEncodingName:_private->textEncodingName] autorelease]; + NSURLResponse *response = nil; + if (_private->coreResource) + response = _private->coreResource->response().nsURLResponse(); + + return response ? response : [[[NSURLResponse alloc] init] autorelease]; } - (NSString *)_stringValue { - NSString *textEncodingName = [self textEncodingName]; - return [WebFrameBridge stringWithData:_private->data textEncodingName:textEncodingName]; + WebCore::TextEncoding encoding(_private->coreResource ? (NSString *)_private->coreResource->textEncoding() : nil); + 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 diff --git a/WebKit/mac/WebView/WebArchiver.h b/WebKit/mac/WebView/WebResourceInternal.h index c91ce5f..84f6aba 100644 --- a/WebKit/mac/WebView/WebArchiver.h +++ b/WebKit/mac/WebView/WebResourceInternal.h @@ -1,18 +1,18 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 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 * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -26,21 +26,17 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import <Foundation/Foundation.h> +#import "WebResource.h" -@class DOMNode; -@class DOMRange; -@class WebArchive; -@class WebFrame; +#import <wtf/PassRefPtr.h> -@interface WebArchiver : NSObject -{ +namespace WebCore { + class ArchiveResource; } -+ (WebArchive *)archiveNode:(DOMNode *)node; -+ (WebArchive *)archiveRange:(DOMRange *)range; -+ (WebArchive *)archiveSelectionInFrame:(WebFrame *)frame; -+ (WebArchive *)archiveFrame:(WebFrame *)frame; -+ (WebArchive *)archiveMainResourceForFrame:(WebFrame *)frame; +@interface WebResource (WebResourceInternal) + +- (id)_initWithCoreResource:(WTF::PassRefPtr<WebCore::ArchiveResource>)coreResource; +- (WebCore::ArchiveResource *)_coreResource; @end diff --git a/WebKit/mac/WebView/WebResourcePrivate.h b/WebKit/mac/WebView/WebResourcePrivate.h index 34ae701..80d9835 100644 --- a/WebKit/mac/WebView/WebResourcePrivate.h +++ b/WebKit/mac/WebView/WebResourcePrivate.h @@ -38,18 +38,11 @@ response:(NSURLResponse *)response copyData:(BOOL)copyData; -- (id)_initWithData:(NSData *)data URL:(NSURL *)URL response:(NSURLResponse *)response MIMEType:(NSString *)MIMEType; +- (id)_initWithData:(NSData *)data URL:(NSURL *)URL response:(NSURLResponse *)response; -- (BOOL)_shouldIgnoreWhenUnarchiving; - (void)_ignoreWhenUnarchiving; -+ (NSArray *)_resourcesFromPropertyLists:(NSArray *)propertyLists; -+ (NSArray *)_propertyListsFromResources:(NSArray *)resources; - -- (id)_initWithPropertyList:(id)propertyList; - - (NSFileWrapper *)_fileWrapperRepresentation; -- (id)_propertyListRepresentation; - (NSURLResponse *)_response; - (NSString *)_stringValue; diff --git a/WebKit/mac/WebView/WebScriptDebugDelegate.h b/WebKit/mac/WebView/WebScriptDebugDelegate.h index 7a4c349..fba48f6 100644 --- a/WebKit/mac/WebView/WebScriptDebugDelegate.h +++ b/WebKit/mac/WebView/WebScriptDebugDelegate.h @@ -37,7 +37,8 @@ @class WebView; @class WebFrame; @class WebScriptCallFrame; -@class WebCoreScriptCallFrame; +@class WebScriptCallFramePrivate; +@class WebScriptObject; extern NSString * const WebScriptErrorDomain; extern NSString * const WebScriptErrorDescriptionKey; @@ -106,8 +107,8 @@ enum { @interface WebScriptCallFrame : NSObject { @private - WebCoreScriptCallFrame *_private; - id _userInfo; + WebScriptCallFramePrivate* _private; + id _userInfo; } // associate user info with frame diff --git a/WebKit/mac/WebView/WebScriptDebugDelegate.mm b/WebKit/mac/WebView/WebScriptDebugDelegate.mm index 71ad1ef..be0a0d5 100644 --- a/WebKit/mac/WebView/WebScriptDebugDelegate.mm +++ b/WebKit/mac/WebView/WebScriptDebugDelegate.mm @@ -26,17 +26,24 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "WebScriptDebugDelegatePrivate.h" - +#import "WebScriptDebugger.h" #import "WebDataSource.h" #import "WebDataSourceInternal.h" -#import "WebFrameBridge.h" #import "WebFrameInternal.h" -#import "WebScriptDebugServerPrivate.h" +#import "WebScriptDebugDelegate.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/WebCoreScriptDebugger.h> +#import <WebCore/WebScriptObjectPrivate.h> +#import <WebCore/ScriptController.h> +#import <WebCore/runtime_root.h> +using namespace JSC; using namespace WebCore; // FIXME: these error strings should be public for future use by WebScriptObject and in WebScriptObject.h @@ -46,100 +53,80 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; @interface WebScriptCallFrame (WebScriptDebugDelegateInternal) -- (WebScriptCallFrame *)_initWithFrame:(WebCoreScriptCallFrame *)frame; +- (id)_convertValueToObjcValue:(JSValue*)value; @end -@implementation WebScriptDebugger - -- (WebScriptDebugger *)initWithWebFrame:(WebFrame *)webFrame -{ - if ((self = [super init])) { - _webFrame = webFrame; - _debugger = [[WebCoreScriptDebugger alloc] initWithDelegate:self]; - } - return self; +@interface WebScriptCallFramePrivate : NSObject { +@public + WebScriptObject *globalObject; // the global object's proxy (not retained) + WebScriptCallFrame *caller; // previous stack frame + DebuggerCallFrame* debuggerCallFrame; } +@end +@implementation WebScriptCallFramePrivate - (void)dealloc { - [_debugger release]; + [caller release]; + delete debuggerCallFrame; [super dealloc]; } +@end -- (WebScriptObject *)globalObject -{ - return core(_webFrame)->windowScriptObject(); -} +// WebScriptCallFrame +// +// One of these is created to represent each stack frame. Additionally, there is a "global" +// frame to represent the outermost scope. This global frame is always the last frame in +// the chain of callers. +// +// The delegate can assign a "wrapper" to each frame object so it can relay calls through its +// own exported interface. This class is private to WebCore (and the delegate). -- (id)newWrapperForFrame:(WebCoreScriptCallFrame *)frame -{ - return [[WebScriptCallFrame alloc] _initWithFrame:frame]; -} +@implementation WebScriptCallFrame (WebScriptDebugDelegateInternal) -- (void)parsedSource:(NSString *)source fromURL:(NSURL *)url sourceId:(int)sid startLine:(int)startLine errorLine:(int)errorLine errorMessage:(NSString *)errorMessage +- (WebScriptCallFrame *)_initWithGlobalObject:(WebScriptObject *)globalObj caller:(WebScriptCallFrame *)caller debuggerCallFrame:(const DebuggerCallFrame&)debuggerCallFrame { - WebView *webView = [_webFrame webView]; - if (errorLine == -1) { - [[webView _scriptDebugDelegateForwarder] webView:webView didParseSource:source baseLineNumber:startLine fromURL:url sourceId:sid forWebFrame:_webFrame]; - [[webView _scriptDebugDelegateForwarder] webView:webView didParseSource:source fromURL:[url absoluteString] sourceId:sid forWebFrame:_webFrame]; // deprecated delegate method - if ([WebScriptDebugServer listenerCount]) - [[WebScriptDebugServer sharedScriptDebugServer] webView:webView didParseSource:source baseLineNumber:startLine fromURL:url sourceId:sid forWebFrame:_webFrame]; - } else { - NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:errorMessage, WebScriptErrorDescriptionKey, [NSNumber numberWithUnsignedInt:errorLine], WebScriptErrorLineNumberKey, nil]; - NSError *error = [[NSError alloc] initWithDomain:WebScriptErrorDomain code:WebScriptGeneralErrorCode userInfo:info]; - [[webView _scriptDebugDelegateForwarder] webView:webView failedToParseSource:source baseLineNumber:startLine fromURL:url withError:error forWebFrame:_webFrame]; - if ([WebScriptDebugServer listenerCount]) - [[WebScriptDebugServer sharedScriptDebugServer] webView:webView failedToParseSource:source baseLineNumber:startLine fromURL:url withError:error forWebFrame:_webFrame]; - [error release]; - [info release]; + if ((self = [super init])) { + _private = [[WebScriptCallFramePrivate alloc] init]; + _private->globalObject = globalObj; + _private->caller = [caller retain]; } + return self; } -- (void)enteredFrame:(WebCoreScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno -{ - WebView *webView = [_webFrame webView]; - [[webView _scriptDebugDelegateForwarder] webView:webView didEnterCallFrame:[frame wrapper] sourceId:sid line:lineno forWebFrame:_webFrame]; - if ([WebScriptDebugServer listenerCount]) - [[WebScriptDebugServer sharedScriptDebugServer] webView:webView didEnterCallFrame:[frame wrapper] sourceId:sid line:lineno forWebFrame:_webFrame]; -} - -- (void)hitStatement:(WebCoreScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno +- (void)_setDebuggerCallFrame:(const DebuggerCallFrame&)debuggerCallFrame { - WebView *webView = [_webFrame webView]; - [[webView _scriptDebugDelegateForwarder] webView:webView willExecuteStatement:[frame wrapper] sourceId:sid line:lineno forWebFrame:_webFrame]; - if ([WebScriptDebugServer listenerCount]) - [[WebScriptDebugServer sharedScriptDebugServer] webView:webView willExecuteStatement:[frame wrapper] sourceId:sid line:lineno forWebFrame:_webFrame]; + if (!_private->debuggerCallFrame) + _private->debuggerCallFrame = new DebuggerCallFrame(debuggerCallFrame); + else + *_private->debuggerCallFrame = debuggerCallFrame; } -- (void)leavingFrame:(WebCoreScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno +- (void)_clearDebuggerCallFrame { - WebView *webView = [_webFrame webView]; - [[webView _scriptDebugDelegateForwarder] webView:webView willLeaveCallFrame:[frame wrapper] sourceId:sid line:lineno forWebFrame:_webFrame]; - if ([WebScriptDebugServer listenerCount]) - [[WebScriptDebugServer sharedScriptDebugServer] webView:webView willLeaveCallFrame:[frame wrapper] sourceId:sid line:lineno forWebFrame:_webFrame]; + delete _private->debuggerCallFrame; + _private->debuggerCallFrame = 0; } -- (void)exceptionRaised:(WebCoreScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno +- (id)_convertValueToObjcValue:(JSValue*)value { - WebView *webView = [_webFrame webView]; - [[webView _scriptDebugDelegateForwarder] webView:webView exceptionWasRaised:[frame wrapper] sourceId:sid line:lineno forWebFrame:_webFrame]; - if ([WebScriptDebugServer listenerCount]) - [[WebScriptDebugServer sharedScriptDebugServer] webView:webView exceptionWasRaised:[frame wrapper] sourceId:sid line:lineno forWebFrame:_webFrame]; -} - -@end + if (!value) + return nil; + WebScriptObject *globalObject = _private->globalObject; + if (value == [globalObject _imp]) + return globalObject; + Bindings::RootObject* root1 = [globalObject _originRootObject]; + if (!root1) + return nil; -@implementation WebScriptCallFrame (WebScriptDebugDelegateInternal) + Bindings::RootObject* root2 = [globalObject _rootObject]; + if (!root2) + return nil; -- (WebScriptCallFrame *)_initWithFrame:(WebCoreScriptCallFrame *)frame -{ - if ((self = [super init])) { - _private = frame; - } - return self; + return [WebScriptObject _convertValueToObjcValue:value originRootObject:root1 rootObject:root2]; } @end @@ -151,6 +138,7 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; - (void) dealloc { [_userInfo release]; + [_private release]; [super dealloc]; } @@ -169,27 +157,75 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber"; - (WebScriptCallFrame *)caller { - return [[_private caller] wrapper]; + return _private->caller; } +// Returns an array of scope objects (most local first). +// The properties of each scope object are the variables for that scope. +// Note that the last entry in the array will _always_ be the global object (windowScriptObject), +// whose properties are the global variables. + - (NSArray *)scopeChain { - return [_private scopeChain]; + if (!_private->debuggerCallFrame) + return [NSArray array]; + + const ScopeChainNode* scopeChain = _private->debuggerCallFrame->scopeChain(); + if (!scopeChain->next) // global frame + return [NSArray arrayWithObject:_private->globalObject]; + + NSMutableArray *scopes = [[NSMutableArray alloc] init]; + + ScopeChainIterator end = scopeChain->end(); + for (ScopeChainIterator it = scopeChain->begin(); it != end; ++it) + [scopes addObject:[self _convertValueToObjcValue:(*it)]]; + + NSArray *result = [NSArray arrayWithArray:scopes]; + [scopes release]; + return result; } +// Returns the name of the function for this frame, if available. +// Returns nil for anonymous functions and for the global frame. + - (NSString *)functionName { - return [_private functionName]; + if (!_private->debuggerCallFrame) + return nil; + + const UString* functionName = _private->debuggerCallFrame->functionName(); + return functionName ? toNSString(*functionName) : nil; } +// Returns the pending exception for this frame (nil if none). + - (id)exception { - return [_private exception]; + if (!_private->debuggerCallFrame) + return nil; + + JSValue* exception = _private->debuggerCallFrame->exception(); + return exception ? [self _convertValueToObjcValue:exception] : nil; } +// Evaluate some JavaScript code in the context of this frame. +// The code is evaluated as if by "eval", and the result is returned. +// If there is an (uncaught) exception, it is returned as though _it_ were the result. +// Calling this method on the global frame is not quite the same as calling the WebScriptObject +// method of the same name, due to the treatment of exceptions. + - (id)evaluateWebScript:(NSString *)script { - return [_private evaluateWebScript:script]; + if (!_private->debuggerCallFrame) + return nil; + + JSLock lock(false); + + JSValue* exception = noValue(); + JSValue* result = _private->debuggerCallFrame->evaluate(String(script), exception); + if (exception) + return [self _convertValueToObjcValue:exception]; + return result ? [self _convertValueToObjcValue:result] : nil; } @end diff --git a/WebKit/mac/WebView/WebScriptDebugger.h b/WebKit/mac/WebView/WebScriptDebugger.h new file mode 100644 index 0000000..caec994 --- /dev/null +++ b/WebKit/mac/WebView/WebScriptDebugger.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebScriptDebugger_h +#define WebScriptDebugger_h + +#include <debugger/Debugger.h> + +#include <wtf/RetainPtr.h> + +namespace JSC { + class DebuggerCallFrame; + class ExecState; + class JSGlobalObject; + class JSObject; + class ArgList; + class UString; +} + +@class WebScriptCallFrame; + +NSString *toNSString(const JSC::UString&); + +class WebScriptDebugger : public JSC::Debugger { +public: + WebScriptDebugger(JSC::JSGlobalObject*); + + 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); + virtual void returnEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber); + virtual void exception(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber); + virtual void willExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno); + virtual void didExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno); + virtual void didReachBreakpoint(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno); + +private: + bool m_callingDelegate; + RetainPtr<WebScriptCallFrame> m_topCallFrame; +}; + +#endif // WebScriptDebugger_h diff --git a/WebKit/mac/WebView/WebScriptDebugger.mm b/WebKit/mac/WebView/WebScriptDebugger.mm new file mode 100644 index 0000000..0dd6b0e --- /dev/null +++ b/WebKit/mac/WebView/WebScriptDebugger.mm @@ -0,0 +1,193 @@ +/* + * Copyright (C) 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "WebScriptDebugger.h" + +#import "WebFrameInternal.h" +#import "WebViewInternal.h" +#import "WebScriptDebugDelegate.h" +#import <runtime/JSGlobalObject.h> +#import <debugger/DebuggerCallFrame.h> +#import <WebCore/DOMWindow.h> +#import <WebCore/Frame.h> +#import <WebCore/JSDOMWindow.h> +#import <WebCore/KURL.h> +#import <WebCore/ScriptController.h> + +using namespace JSC; +using namespace WebCore; + +@interface WebScriptCallFrame (WebScriptDebugDelegateInternal) +- (WebScriptCallFrame *)_initWithGlobalObject:(WebScriptObject *)globalObj caller:(WebScriptCallFrame *)caller debuggerCallFrame:(const DebuggerCallFrame&)debuggerCallFrame; +- (void)_setDebuggerCallFrame:(const DebuggerCallFrame&)debuggerCallFrame; +- (void)_clearDebuggerCallFrame; +@end + +NSString *toNSString(const UString& s) +{ + if (s.isEmpty()) + return nil; + return [NSString stringWithCharacters:reinterpret_cast<const unichar*>(s.data()) length:s.size()]; +} + +NSString *toNSString(const SourceCode& s) +{ + if (!s.length()) + return nil; + return [NSString stringWithCharacters:reinterpret_cast<const unichar*>(s.data()) length:s.length()]; +} + +// convert UString to NSURL +static NSURL *toNSURL(const UString& s) +{ + if (s.isEmpty()) + return nil; + return KURL(s); +} + +static WebFrame *toWebFrame(JSGlobalObject* globalObject) +{ + JSDOMWindow* window = static_cast<JSDOMWindow*>(globalObject); + return kit(window->impl()->frame()); +} + +WebScriptDebugger::WebScriptDebugger(JSGlobalObject* globalObject) + : m_callingDelegate(false) +{ + attach(globalObject); + callEvent(globalObject->globalExec(), 0, -1); +} + +// callbacks - relay to delegate +void WebScriptDebugger::sourceParsed(ExecState* exec, const SourceCode& source, int errorLine, const UString& errorMsg) +{ + if (m_callingDelegate) + return; + + m_callingDelegate = true; + + NSString *nsSource = toNSString(source); + NSURL *nsURL = toNSURL(source.provider()->url()); + + 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 + } else { + NSString* nsErrorMessage = toNSString(errorMsg); + NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:nsErrorMessage, WebScriptErrorDescriptionKey, [NSNumber numberWithUnsignedInt:errorLine], WebScriptErrorLineNumberKey, nil]; + NSError *error = [[NSError alloc] initWithDomain:WebScriptErrorDomain code:WebScriptGeneralErrorCode userInfo:info]; + [[webView _scriptDebugDelegateForwarder] webView:webView failedToParseSource:nsSource baseLineNumber:source.firstLine() fromURL:nsURL withError:error forWebFrame:webFrame]; + [error release]; + [info release]; + } + + m_callingDelegate = false; +} + +void WebScriptDebugger::callEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_callingDelegate) + return; + + m_callingDelegate = true; + + WebFrame *webFrame = toWebFrame(debuggerCallFrame.dynamicGlobalObject()); + + m_topCallFrame.adoptNS([[WebScriptCallFrame alloc] _initWithGlobalObject:core(webFrame)->script()->windowScriptObject() 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]; + + m_callingDelegate = false; +} + +void WebScriptDebugger::atStatement(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_callingDelegate) + return; + + m_callingDelegate = true; + + WebFrame *webFrame = toWebFrame(debuggerCallFrame.dynamicGlobalObject()); + 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]; + + m_callingDelegate = false; +} + +void WebScriptDebugger::returnEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_callingDelegate) + return; + + m_callingDelegate = true; + + WebFrame *webFrame = toWebFrame(debuggerCallFrame.dynamicGlobalObject()); + 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]; + + [m_topCallFrame.get() _clearDebuggerCallFrame]; + m_topCallFrame = [m_topCallFrame.get() caller]; + + m_callingDelegate = false; +} + +void WebScriptDebugger::exception(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_callingDelegate) + return; + + m_callingDelegate = true; + + WebFrame *webFrame = toWebFrame(debuggerCallFrame.dynamicGlobalObject()); + 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]; + + m_callingDelegate = false; +} + +void WebScriptDebugger::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineno) +{ +} + +void WebScriptDebugger::didExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineno) +{ +} + +void WebScriptDebugger::didReachBreakpoint(const DebuggerCallFrame&, intptr_t, int) +{ + return; +} diff --git a/WebKit/mac/WebView/WebTextIterator.h b/WebKit/mac/WebView/WebTextIterator.h new file mode 100644 index 0000000..e6f77ac --- /dev/null +++ b/WebKit/mac/WebView/WebTextIterator.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import <Foundation/Foundation.h> + + +@class DOMRange; +@class DOMNode; +@class WebTextIteratorPrivate; + +@interface WebTextIterator : NSObject +{ +@private + WebTextIteratorPrivate *_private; +} + +- (id)initWithRange:(DOMRange *)range; + +/*! + @method advance: + @abstract Makes the WebTextIterator iterate to the next visible text element. + */ +- (void)advance; + +/*! + @method currentNode: + @result The current DOMNode in the WebTextIterator. + */ +- (DOMNode *)currentNode; + +/*! + @method currentText: + @result The current text in the WebTextIterator. + */ +- (NSString *)currentText; + +/*! + @method atEnd: + @result YES if the WebTextIterator has reached the end of the DOMRange. + */ +- (BOOL)atEnd; + + +@end diff --git a/WebKit/mac/WebView/WebTextIterator.mm b/WebKit/mac/WebView/WebTextIterator.mm new file mode 100644 index 0000000..86db6d3 --- /dev/null +++ b/WebKit/mac/WebView/WebTextIterator.mm @@ -0,0 +1,108 @@ +/* + * Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "WebTextIterator.h" + +#import "DOMNodeInternal.h" +#import "DOMRangeInternal.h" +#import <WebCore/TextIterator.h> +#import <wtf/Vector.h> + +using namespace WebCore; + +@interface WebTextIteratorPrivate : NSObject +{ +@public + TextIterator* m_textIterator; +} +@end + +@implementation WebTextIteratorPrivate + +- (void)dealloc +{ + delete m_textIterator; + [super dealloc]; +} + +- (void)finalize +{ + delete m_textIterator; + [super finalize]; +} + +@end + +@implementation WebTextIterator + +- (void)dealloc +{ + [_private release]; + [super dealloc]; +} + +- (id)initWithRange:(DOMRange *)range +{ + self = [super init]; + if (!self) + return self; + + _private = [[WebTextIteratorPrivate alloc] init]; + _private->m_textIterator = new TextIterator([range _range], true, false); + return self; +} + +- (void)advance +{ + ASSERT(_private->m_textIterator); + + if (_private->m_textIterator->atEnd()) + return; + + _private->m_textIterator->advance(); +} + +- (DOMNode *)currentNode +{ + ASSERT(_private->m_textIterator); + + return [DOMNode _wrapNode:_private->m_textIterator->node()]; +} + +- (NSString *)currentText +{ + ASSERT(_private->m_textIterator); + + return [NSString stringWithCharacters:_private->m_textIterator->characters() length:_private->m_textIterator->length()]; +} + +- (BOOL)atEnd +{ + ASSERT(_private->m_textIterator); + + return _private->m_textIterator->atEnd(); +} + +@end diff --git a/WebKit/mac/WebView/WebUIDelegate.h b/WebKit/mac/WebView/WebUIDelegate.h index 15c4444..8440bcb 100644 --- a/WebKit/mac/WebView/WebUIDelegate.h +++ b/WebKit/mac/WebView/WebUIDelegate.h @@ -28,6 +28,7 @@ #import <Cocoa/Cocoa.h> #import <Foundation/NSURLRequest.h> +#import <JavaScriptCore/WebKitAvailability.h> #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 #define WebNSUInteger unsigned int @@ -128,6 +129,13 @@ typedef enum { - (void)chooseFilename:(NSString *)fileName; /*! + @method chooseFilenames: + @abstract Call this method to return an array of filenames from the file open panel. + @param fileNames +*/ +- (void)chooseFilenames:(NSArray *)fileNames WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_AFTER_WEBKIT_VERSION_3_1); + +/*! @method cancel @abstract Call this method to indicate that the file open panel was cancelled. */ @@ -380,7 +388,7 @@ typedef enum { - (NSString *)webView:(WebView *)sender runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WebFrame *)frame; /*! - @method webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame: + @method webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame: @abstract Display a confirm panel by an "before unload" event handler. @param sender The WebView sending the delegate method. @param message The message to display. @@ -403,6 +411,17 @@ typedef enum { - (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener; /*! + @method webView:runOpenPanelForFileButtonWithResultListener:allowMultipleFiles + @abstract Display a file open panel for a file input control that may allow multiple files to be selected. + @param sender The WebView sending the delegate method. + @param resultListener The object to call back with the results. + @param allowMultipleFiles YES if the open panel should allow myltiple files to be selected, NO if not. + @discussion This method is passed a callback object instead of giving a return + value so that it can be handled with a sheet. +*/ +- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener allowMultipleFiles:(BOOL)allowMultipleFiles WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_AFTER_WEBKIT_VERSION_3_1); + +/*! @method webView:mouseDidMoveOverElement:modifierFlags: @abstract Update the window's feedback for mousing over links to reflect a new item the mouse is over or new modifier flags. @@ -543,13 +562,13 @@ typedef enum { // The following delegate methods are deprecated in favor of the ones above that specify // the WebFrame whose JavaScript initiated this call. -- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message; -- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message; -- (NSString *)webView:(WebView *)sender runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText; +- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0); +- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0); +- (NSString *)webView:(WebView *)sender runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0); // The following delegate methods are deprecated. Content rect calculations are now done automatically. -- (void)webView:(WebView *)sender setContentRect:(NSRect)frame; -- (NSRect)webViewContentRect:(WebView *)sender; +- (void)webView:(WebView *)sender setContentRect:(NSRect)frame WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0); +- (NSRect)webViewContentRect:(WebView *)sender WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0); @end diff --git a/WebKit/mac/WebView/WebUIDelegatePrivate.h b/WebKit/mac/WebView/WebUIDelegatePrivate.h index 62ef3f9..6a3c32f 100644 --- a/WebKit/mac/WebView/WebUIDelegatePrivate.h +++ b/WebKit/mac/WebView/WebUIDelegatePrivate.h @@ -28,6 +28,10 @@ #import <WebKit/WebUIDelegate.h> +#if !defined(ENABLE_DASHBOARD_SUPPORT) +#define ENABLE_DASHBOARD_SUPPORT 1 +#endif + // Mail on Tiger expects the old value for WebMenuItemTagSearchInGoogle #define WebMenuItemTagSearchInGoogle OldWebMenuItemTagSearchWeb @@ -74,8 +78,10 @@ enum { - (NSView *)webView:(WebView *)webView plugInViewWithArguments:(NSDictionary *)arguments; +#if ENABLE_DASHBOARD_SUPPORT // regions is an dictionary whose keys are regions label and values are arrays of WebDashboardRegions. - (void)webView:(WebView *)webView dashboardRegionsChanged:(NSDictionary *)regions; +#endif - (void)webView:(WebView *)sender dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag forView:(NSView *)view; - (void)webView:(WebView *)sender didDrawRect:(NSRect)rect; @@ -97,4 +103,7 @@ enum { - (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request windowFeatures:(NSDictionary *)features; +- (BOOL)webView:(WebView *)sender shouldReplaceUploadFile:(NSString *)path usingGeneratedFilename:(NSString **)filename; +- (NSString *)webView:(WebView *)sender generateReplacementFile:(NSString *)path; + @end diff --git a/WebKit/mac/WebView/WebUnarchivingState.m b/WebKit/mac/WebView/WebUnarchivingState.m deleted file mode 100644 index c1b975a..0000000 --- a/WebKit/mac/WebView/WebUnarchivingState.m +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. - * (C) 2007 Graham Dennis (graham.dennis@gmail.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "WebUnarchivingState.h" - -#import "WebArchive.h" -#import <JavaScriptCore/Assertions.h> -#import "WebResource.h" -#import "WebResourcePrivate.h" -#import "WebNSURLExtras.h" - -@implementation WebUnarchivingState - -- (id)init -{ - if (!(self = [super init])) - return nil; - - archivedSubframes = [[NSMutableDictionary alloc] init]; - archivedResources = [[NSMutableDictionary alloc] init]; - - return self; -} - -- (void)dealloc -{ - [archivedSubframes release]; - [archivedResources release]; - [super dealloc]; -} - -- (void)addArchive:(WebArchive *)archive -{ - NSEnumerator *enumerator = [[archive subresources] objectEnumerator]; - WebResource *subresource; - while ((subresource = [enumerator nextObject]) != nil) - [archivedResources setObject:subresource forKey:[[subresource URL] _web_originalDataAsString]]; - - enumerator = [[archive subframeArchives] objectEnumerator]; - WebArchive *subframeArchive; - while ((subframeArchive = [enumerator nextObject]) != nil) { - NSString *frameName = [[subframeArchive mainResource] frameName]; - if (frameName) - [archivedSubframes setObject:subframeArchive forKey:frameName]; - } -} - -- (void)addResource:(WebResource *)subresource -{ - [archivedResources setObject:subresource forKey:[[subresource URL] _web_originalDataAsString]]; -} - -- (WebResource *)archivedResourceForURL:(NSURL *)URL -{ - WebResource *resource = [archivedResources objectForKey:[URL _web_originalDataAsString]]; - if ([resource _shouldIgnoreWhenUnarchiving]) - return nil; - return resource; -} - -- (WebArchive *)popSubframeArchiveWithFrameName:(NSString *)frameName -{ - ASSERT(frameName != nil); - - WebArchive *archive = [[[archivedSubframes objectForKey:frameName] retain] autorelease]; - if (archive != nil) - [archivedSubframes removeObjectForKey:frameName]; - - return archive; -} - -@end diff --git a/WebKit/mac/WebView/WebView.h b/WebKit/mac/WebView/WebView.h index 6038703..30aa7bd 100644 --- a/WebKit/mac/WebView/WebView.h +++ b/WebKit/mac/WebView/WebView.h @@ -617,6 +617,22 @@ extern NSString *WebViewProgressFinishedNotification; - (BOOL)drawsBackground; /*! + @method setShouldUpdateWhileOffscreen: + @abstract Sets whether the receiver must update even when it is not in a window that is currently visible. + @param updateWhileOffscreen whether the receiver is required to render updates to the web page when it is not in a visible window. + @abstract If set to NO, then whenever the web view is not in a visible window, updates to the web page will not necessarily be rendered in the view. + However, when the window is made visible, the view will be updated automatically. Not updating while hidden can improve performance. If set to is YES, + hidden web views are always updated. This is the default. +*/ +- (void)setShouldUpdateWhileOffscreen:(BOOL)updateWhileOffscreen; + +/*! + @method shouldUpdateWhileOffscreen + @result Returns whether the web view is always updated even when it is not in a window that is currently visible. +*/ +- (BOOL)shouldUpdateWhileOffscreen; + +/*! @method setMainFrameURL: @param URLString The URL to load in the mainFrame. */ diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm index f5285f4..a52d3b5 100644 --- a/WebKit/mac/WebView/WebView.mm +++ b/WebKit/mac/WebView/WebView.mm @@ -30,15 +30,13 @@ #import "WebViewInternal.h" #import "DOMRangeInternal.h" -#import "WebBackForwardList.h" #import "WebBackForwardListInternal.h" #import "WebBaseNetscapePluginView.h" #import "WebChromeClient.h" #import "WebContextMenuClient.h" #import "WebDOMOperationsPrivate.h" -#import "WebDatabaseManagerInternal.h" -#import "WebDatabaseManagerPrivate.h" #import "WebDataSourceInternal.h" +#import "WebDatabaseManagerInternal.h" #import "WebDefaultEditingDelegate.h" #import "WebDefaultPolicyDelegate.h" #import "WebDefaultScriptDebugDelegate.h" @@ -48,17 +46,15 @@ #import "WebDownload.h" #import "WebDownloadInternal.h" #import "WebDragClient.h" -#import "WebDynamicScrollBarsView.h" +#import "WebDynamicScrollBarsViewInternal.h" #import "WebEditingDelegate.h" #import "WebEditorClient.h" #import "WebFormDelegatePrivate.h" -#import "WebFrameBridge.h" #import "WebFrameInternal.h" #import "WebFrameViewInternal.h" #import "WebHTMLRepresentation.h" #import "WebHTMLViewInternal.h" #import "WebHistoryItemInternal.h" -#import "WebIconDatabase.h" #import "WebIconDatabaseInternal.h" #import "WebInspector.h" #import "WebInspectorClient.h" @@ -69,6 +65,7 @@ #import "WebKitSystemBits.h" #import "WebKitVersionChecks.h" #import "WebLocalizableStrings.h" +#import "WebNodeHighlight.h" #import "WebNSDataExtras.h" #import "WebNSDataExtrasPrivate.h" #import "WebNSDictionaryExtras.h" @@ -80,20 +77,19 @@ #import "WebNSURLRequestExtras.h" #import "WebNSUserDefaultsExtras.h" #import "WebNSViewExtras.h" +#import "WebPDFView.h" #import "WebPanelAuthenticationHandler.h" #import "WebPasteboardHelper.h" -#import "WebPDFView.h" #import "WebPluginDatabase.h" #import "WebPolicyDelegate.h" #import "WebPreferenceKeysPrivate.h" #import "WebPreferencesPrivate.h" -#import "WebScriptDebugDelegatePrivate.h" -#import "WebScriptDebugServerPrivate.h" +#import "WebTextIterator.h" #import "WebUIDelegate.h" #import "WebUIDelegatePrivate.h" #import <CoreFoundation/CFSet.h> #import <Foundation/NSURLConnection.h> -#import <JavaScriptCore/Assertions.h> +#import <WebCore/ApplicationCacheStorage.h> #import <WebCore/Cache.h> #import <WebCore/ColorMac.h> #import <WebCore/Document.h> @@ -101,37 +97,52 @@ #import <WebCore/DragController.h> #import <WebCore/DragData.h> #import <WebCore/Editor.h> +#import <WebCore/EventHandler.h> #import <WebCore/ExceptionHandlers.h> +#import <WebCore/FocusController.h> #import <WebCore/Frame.h> #import <WebCore/FrameLoader.h> +#import <WebCore/FrameView.h> #import <WebCore/FrameTree.h> +#import <WebCore/GCController.h> #import <WebCore/HTMLNames.h> #import <WebCore/HistoryItem.h> #import <WebCore/Logging.h> #import <WebCore/MIMETypeRegistry.h> #import <WebCore/Page.h> #import <WebCore/PageCache.h> +#import <WebCore/PageGroup.h> #import <WebCore/PlatformMouseEvent.h> #import <WebCore/ProgressTracker.h> +#import <WebCore/ScriptController.h> #import <WebCore/SelectionController.h> #import <WebCore/Settings.h> #import <WebCore/TextResourceDecoder.h> -#import <WebCore/WebCoreFrameBridge.h> #import <WebCore/WebCoreObjCExtras.h> #import <WebCore/WebCoreTextRenderer.h> #import <WebCore/WebCoreView.h> #import <WebKit/DOM.h> #import <WebKit/DOMExtensions.h> #import <WebKit/DOMPrivate.h> -#import <WebKit/WebDashboardRegion.h> #import <WebKitSystemInterface.h> +#import <runtime/ArrayPrototype.h> +#import <runtime/DateInstance.h> +#import <runtime/InitializeThreading.h> +#import <runtime/JSLock.h> #import <mach-o/dyld.h> #import <objc/objc-auto.h> #import <objc/objc-runtime.h> -#import <wtf/RefPtr.h> +#import <wtf/Assertions.h> #import <wtf/HashTraits.h> +#import <wtf/RefCountedLeakCounter.h> +#import <wtf/RefPtr.h> + +#if ENABLE(DASHBOARD_SUPPORT) +#import <WebKit/WebDashboardRegion.h> +#endif using namespace WebCore; +using namespace JSC; #if defined(__ppc__) || defined(__ppc64__) #define PROCESSOR "PPC" @@ -261,12 +272,20 @@ macro(yankAndSelect) \ #define WebKitOriginalTopPrintingMarginKey @"WebKitOriginalTopMargin" #define WebKitOriginalBottomPrintingMarginKey @"WebKitOriginalBottomMargin" +#define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange" +#define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode") +#define UniversalAccessDomain CFSTR("com.apple.universalaccess") + static BOOL s_didSetCacheModel; static WebCacheModel s_cacheModel = WebCacheModelDocumentViewer; static BOOL applicationIsTerminating; static int pluginDatabaseClientCount = 0; +#ifndef NDEBUG +static const char webViewIsOpen[] = "At least one WebView is still open."; +#endif + @interface NSSpellChecker (AppKitSecretsIKnow) - (void)_preflightChosenSpellServer; @end @@ -294,8 +313,7 @@ static int pluginDatabaseClientCount = 0; - (id)initWithTarget:(id)target defaultTarget:(id)defaultTarget catchExceptions:(BOOL)catchExceptions; @end -@interface WebViewPrivate : NSObject -{ +@interface WebViewPrivate : NSObject { @public Page* page; @@ -314,13 +332,15 @@ static int pluginDatabaseClientCount = 0; id scriptDebugDelegateForwarder; WebInspector *inspector; + WebNodeHighlight *currentNodeHighlight; BOOL allowsUndo; - float textSizeMultiplier; + float zoomMultiplier; + BOOL zoomMultiplierIsTextOnly; NSString *applicationNameForUserAgent; - String* userAgent; + String userAgent; BOOL userAgentOverridden; WebPreferences *preferences; @@ -356,29 +376,36 @@ static int pluginDatabaseClientCount = 0; BOOL smartInsertDeleteEnabled; +#if ENABLE(DASHBOARD_SUPPORT) BOOL dashboardBehaviorAlwaysSendMouseEventsToAllWindows; BOOL dashboardBehaviorAlwaysSendActiveNullEventsToPlugIns; BOOL dashboardBehaviorAlwaysAcceptsFirstMouse; BOOL dashboardBehaviorAllowWheelScrolling; +#endif // WebKit has both a global plug-in database and a separate, per WebView plug-in database. Dashboard uses the per WebView database. WebPluginDatabase *pluginDatabase; - HashMap<unsigned long, RetainPtr<id> >* identifierMap; + HashMap<unsigned long, RetainPtr<id> > identifierMap; + + BOOL _keyboardUIModeAccessed; + KeyboardUIMode _keyboardUIMode; + + BOOL shouldUpdateWhileOffscreen; + + // When this flag is set, we will not make any subviews underneath this WebView. This means no WebFrameViews and no WebHTMLViews. + BOOL useDocumentViews; } @end @interface WebView (WebFileInternal) - (WebFrame *)_selectedOrMainFrame; -- (WebFrameBridge *)_bridgeForSelectedOrMainFrame; - (BOOL)_isLoading; - (WebFrameView *)_frameViewAtWindowPoint:(NSPoint)point; - (WebFrame *)_focusedFrame; + (void)_preflightSpellChecker; - (BOOL)_continuousCheckingAllowed; - (NSResponder *)_responderForResponderOperations; -- (BOOL)_performTextSizingSelector:(SEL)sel withObject:(id)arg onTrackingDocs:(BOOL)doTrackingViews selForNonTrackingDocs:(SEL)testSel newScaleFactor:(float)newScaleFactor; -- (void)_notifyTextSizeMultiplierChanged; @end @interface WebView (WebCallDelegateFunctions) @@ -455,37 +482,40 @@ static BOOL grammarCheckingEnabled; self = [super init]; if (!self) return nil; + JSC::initializeThreading(); allowsUndo = YES; - textSizeMultiplier = 1; + zoomMultiplier = 1; + zoomMultiplierIsTextOnly = YES; +#if ENABLE(DASHBOARD_SUPPORT) dashboardBehaviorAllowWheelScrolling = YES; +#endif shouldCloseWithWindow = objc_collecting_enabled(); continuousSpellCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebContinuousSpellCheckingEnabled]; #ifndef BUILDING_ON_TIGER grammarCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebGrammarCheckingEnabled]; #endif - userAgent = new String; usesPageCache = YES; - identifierMap = new HashMap<unsigned long, RetainPtr<id> >(); pluginDatabaseClientCount++; + shouldUpdateWhileOffscreen = YES; + return self; } - (void)dealloc -{ - ASSERT(!page); - ASSERT(!preferences); - - delete userAgent; - delete identifierMap; +{ + ASSERT(applicationIsTerminating || !page); + ASSERT(applicationIsTerminating || !preferences); [applicationNameForUserAgent release]; [backgroundColor release]; [inspector release]; + [currentNodeHighlight release]; + [hostWindow release]; [policyDelegateForwarder release]; @@ -503,9 +533,6 @@ static BOOL grammarCheckingEnabled; { ASSERT_MAIN_THREAD(); - delete userAgent; - delete identifierMap; - [super finalize]; } @@ -550,37 +577,288 @@ static CFMutableSetRef allWebViewsSet; @implementation WebView (WebPrivate) -#ifdef DEBUG_WIDGET_DRAWING -static bool debugWidget = true; -- (void)drawRect:(NSRect)rect +static inline int callGestalt(OSType selector) +{ + SInt32 value = 0; + Gestalt(selector, &value); + return value; +} + +// Uses underscores instead of dots because if "4." ever appears in a user agent string, old DHTML libraries treat it as Netscape 4. +static NSString *createMacOSXVersionString() +{ + // Can't use -[NSProcessInfo operatingSystemVersionString] because it has too much stuff we don't want. + int major = callGestalt(gestaltSystemVersionMajor); + ASSERT(major); + + int minor = callGestalt(gestaltSystemVersionMinor); + int bugFix = callGestalt(gestaltSystemVersionBugFix); + if (bugFix) + return [[NSString alloc] initWithFormat:@"%d_%d_%d", major, minor, bugFix]; + if (minor) + return [[NSString alloc] initWithFormat:@"%d_%d", major, minor]; + return [[NSString alloc] initWithFormat:@"%d", major]; +} + +static NSString *createUserVisibleWebKitVersionString() { - [[NSColor blueColor] set]; - NSRectFill (rect); + // If the version is 4 digits long or longer, then the first digit represents + // the version of the OS. Our user agent string should not include this first digit, + // so strip it off and report the rest as the version. <rdar://problem/4997547> + NSString *fullVersion = [[NSBundle bundleForClass:[WebView class]] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey]; + NSRange nonDigitRange = [fullVersion rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]; + if (nonDigitRange.location == NSNotFound && [fullVersion length] >= 4) + return [[fullVersion substringFromIndex:1] copy]; + if (nonDigitRange.location != NSNotFound && nonDigitRange.location >= 4) + return [[fullVersion substringFromIndex:1] copy]; + return [fullVersion copy]; +} + ++ (NSString *)_standardUserAgentWithApplicationName:(NSString *)applicationName +{ + // Note: Do *not* move the initialization of osVersion nor webKitVersion into the declaration. + // Garbage collection won't correctly mark the global variable in that case <rdar://problem/5733674>. + static NSString *osVersion; + static NSString *webKitVersion; + if (!osVersion) + osVersion = createMacOSXVersionString(); + if (!webKitVersion) + webKitVersion = createUserVisibleWebKitVersionString(); + NSString *language = [NSUserDefaults _webkit_preferredLanguageCode]; + if ([applicationName length]) + return [NSString stringWithFormat:@"Mozilla/5.0 (Macintosh; U; " PROCESSOR " Mac OS X %@; %@) AppleWebKit/%@ (KHTML, like Gecko) %@", osVersion, language, webKitVersion, applicationName]; + return [NSString stringWithFormat:@"Mozilla/5.0 (Macintosh; U; " PROCESSOR " Mac OS X %@; %@) AppleWebKit/%@ (KHTML, like Gecko)", osVersion, language, webKitVersion]; +} + +static void WebKitInitializeApplicationCachePathIfNecessary() +{ + static BOOL initialized = NO; + if (initialized) + return; + + NSString *appName = [[NSBundle mainBundle] bundleIdentifier]; + if (!appName) + appName = [[NSProcessInfo processInfo] processName]; - NSRect htmlViewRect = [[[[self mainFrame] frameView] documentView] frame]; + ASSERT(appName); - if (debugWidget) { - while (debugWidget) { - sleep (1); - } + NSString* cacheDir = [NSString _webkit_localCacheDirectoryWithBundleIdentifier:appName]; + + cacheStorage().setCacheDirectory(cacheDir); + initialized = YES; +} + +- (void)_registerDraggedTypes +{ + NSArray *editableTypes = [WebHTMLView _insertablePasteboardTypes]; + NSArray *URLTypes = [NSPasteboard _web_dragTypesForURL]; + NSMutableSet *types = [[NSMutableSet alloc] initWithArray:editableTypes]; + [types addObjectsFromArray:URLTypes]; + [self registerForDraggedTypes:[types allObjects]]; + [types release]; +} + +- (BOOL)_usesDocumentViews +{ + return _private->useDocumentViews; +} + +- (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews +{ +#ifndef NDEBUG + WTF::RefCountedLeakCounter::suppressMessages(webViewIsOpen); +#endif + + WebPreferences *standardPreferences = [WebPreferences standardPreferences]; + [standardPreferences willAddToWebView]; + + _private->preferences = [standardPreferences retain]; + _private->catchesDelegateExceptions = YES; + _private->mainFrameDocumentReady = NO; + _private->drawsBackground = YES; + _private->smartInsertDeleteEnabled = YES; + _private->backgroundColor = [[NSColor whiteColor] retain]; + _private->useDocumentViews = usesDocumentViews; + + WebFrameView *frameView = nil; + if (_private->useDocumentViews) { + NSRect f = [self frame]; + frameView = [[WebFrameView alloc] initWithFrame: NSMakeRect(0,0,f.size.width,f.size.height)]; + [frameView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [self addSubview:frameView]; + [frameView release]; } - NSLog (@"%s: rect: (%0.f,%0.f) %0.f %0.f, htmlViewRect: (%0.f,%0.f) %0.f %0.f\n", - __PRETTY_FUNCTION__, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height, - htmlViewRect.origin.x, htmlViewRect.origin.y, htmlViewRect.size.width, htmlViewRect.size.height - ); + WebKitInitializeLoggingChannelsIfNecessary(); + WebCore::InitializeLoggingChannelsIfNecessary(); + [WebHistoryItem initWindowWatcherIfNecessary]; + WebKitInitializeDatabasesIfNecessary(); + WebKitInitializeApplicationCachePathIfNecessary(); + + _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]); + + [WebFrame _createMainFrameWithPage:_private->page frameName:frameName frameView:frameView]; + +#ifndef BUILDING_ON_TIGER + if (WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOADING_DURING_COMMON_RUNLOOP_MODES)) + [self scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; + else + [self scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; +#endif - [super drawRect:rect]; + [self _addToAllWebViewsSet]; + [self setGroupName:groupName]; + + // If there's already a next key view (e.g., from a nib), wire it up to our + // contained frame view. In any case, wire our next key view up to the our + // contained frame view. This works together with our becomeFirstResponder + // and setNextKeyView overrides. + NSView *nextKeyView = [self nextKeyView]; + if (nextKeyView && nextKeyView != frameView) + [frameView setNextKeyView:nextKeyView]; + [super setNextKeyView:frameView]; + + ++WebViewCount; + + [self _registerDraggedTypes]; + + WebPreferences *prefs = [self preferences]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_preferencesChangedNotification:) + name:WebPreferencesChangedNotification object:prefs]; + + // Post a notification so the WebCore settings update. + [[self preferences] _postPreferencesChangesNotification]; + + if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOCAL_RESOURCE_SECURITY_RESTRICTION)) { + // Originally, we allowed all local loads. + FrameLoader::setLocalLoadPolicy(FrameLoader::AllowLocalLoadsForAll); + } else if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_MORE_STRICT_LOCAL_RESOURCE_SECURITY_RESTRICTION)) { + // Later, we allowed local loads for local URLs and documents loaded + // with substitute data. + FrameLoader::setLocalLoadPolicy(FrameLoader::AllowLocalLoadsForLocalAndSubstituteData); + } } + +- (id)_initWithFrame:(NSRect)f frameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews +{ + self = [super initWithFrame:f]; + if (!self) + return nil; + +#ifdef ENABLE_WEBKIT_UNSET_DYLD_FRAMEWORK_PATH + // DYLD_FRAMEWORK_PATH is used so Safari will load the development version of WebKit, which + // may not work with other WebKit applications. Unsetting DYLD_FRAMEWORK_PATH removes the + // need for Safari to unset it to prevent it from being passed to applications it launches. + // Unsetting it when a WebView is first created is as good a place as any. + // See <http://bugs.webkit.org/show_bug.cgi?id=4286> for more details. + if (getenv("WEBKIT_UNSET_DYLD_FRAMEWORK_PATH")) { + unsetenv("DYLD_FRAMEWORK_PATH"); + unsetenv("WEBKIT_UNSET_DYLD_FRAMEWORK_PATH"); + } #endif -+ (BOOL)_scriptDebuggerEnabled + _private = [[WebViewPrivate alloc] init]; + [self _commonInitializationWithFrameName:frameName groupName:groupName usesDocumentViews:usesDocumentViews]; + [self setMaintainsBackForwardList: YES]; + return self; +} + +- (void)_boundsChanged +{ + Frame* frame = core([self mainFrame]); + IntSize oldSize = frame->view()->frameRect().size(); + frame->view()->resize([self bounds].size.width, [self bounds].size.height); + if (oldSize != frame->view()->frameRect().size()) + [self setNeedsDisplay: YES]; +} + +- (BOOL)_mustDrawUnionedRect:(NSRect)rect singleRects:(const NSRect *)rects count:(NSInteger)count +{ + // If count == 0 here, use the rect passed in for drawing. This is a workaround for: + // <rdar://problem/3908282> REGRESSION (Mail): No drag image dragging selected text in Blot and Mail + // The reason for the workaround is that this method is called explicitly from the code + // to generate a drag image, and at that time, getRectsBeingDrawn:count: will return a zero count. + const int cRectThreshold = 10; + const float cWastedSpaceThreshold = 0.75f; + BOOL useUnionedRect = (count <= 1) || (count > cRectThreshold); + if (!useUnionedRect) { + // Attempt to guess whether or not we should use the unioned rect or the individual rects. + // We do this by computing the percentage of "wasted space" in the union. If that wasted space + // is too large, then we will do individual rect painting instead. + float unionPixels = (rect.size.width * rect.size.height); + float singlePixels = 0; + for (int i = 0; i < count; ++i) + singlePixels += rects[i].size.width * rects[i].size.height; + float wastedSpace = 1 - (singlePixels / unionPixels); + if (wastedSpace <= cWastedSpaceThreshold) + useUnionedRect = YES; + } + return useUnionedRect; +} + +- (void)drawSingleRect:(NSRect)rect { -#ifdef NDEBUG - return [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitScriptDebuggerEnabled"]; -#else - return YES; // always enable in debug builds + ASSERT(!_private->useDocumentViews); + + [NSGraphicsContext saveGraphicsState]; + NSRectClip(rect); + + @try { + [[self mainFrame] _drawRect:rect contentsOnly:NO]; + + WebView *webView = [self _webView]; + [[webView _UIDelegateForwarder] webView:webView didDrawRect:rect]; + + if (WebNodeHighlight *currentHighlight = [webView currentNodeHighlight]) + [currentHighlight setNeedsUpdateInTargetViewRect:rect]; + + [NSGraphicsContext restoreGraphicsState]; + } @catch (NSException *localException) { + [NSGraphicsContext restoreGraphicsState]; + LOG_ERROR("Exception caught while drawing: %@", localException); + [localException raise]; + } +} + +- (BOOL)isFlipped +{ + return _private && !_private->useDocumentViews; +} + +#ifndef BUILDING_ON_TIGER + +- (void)viewWillDraw +{ + if (!_private->useDocumentViews) { + Frame* frame = core([self mainFrame]); + if (frame && frame->view()) + frame->view()->layoutIfNeededRecursive(); + } + [super viewWillDraw]; +} + #endif + + +- (void)drawRect:(NSRect)rect +{ + if (_private->useDocumentViews) + return [super drawRect:rect]; + + ASSERT_MAIN_THREAD(); + + const NSRect *rects; + NSInteger count; + [self getRectsBeingDrawn:&rects count:&count]; + + + if ([self _mustDrawUnionedRect:rect singleRects:rects count:count]) + [self drawSingleRect:rect]; + else + for (int i = 0; i < count; ++i) + [self drawSingleRect:rects[i]]; } + (NSArray *)_supportedMIMETypes @@ -661,7 +939,12 @@ static bool debugWidget = true; + (void)_setAlwaysUseATSU:(BOOL)f { - WebCoreSetAlwaysUseATSU(f); + [self _setAlwaysUsesComplexTextCodePath:f]; +} + ++ (void)_setAlwaysUsesComplexTextCodePath:(BOOL)f +{ + WebCoreSetAlwaysUsesComplexTextCodePath(f); } + (BOOL)canShowFile:(NSString *)path @@ -676,22 +959,72 @@ static bool debugWidget = true; - (BOOL)_isClosed { - if (!_private || _private->closed) - return YES; - return NO; + return !_private || _private->closed; } +- (void)_closePluginDatabases +{ + pluginDatabaseClientCount--; + + // Close both sets of plug-in databases because plug-ins need an opportunity to clean up files, etc. + + // Unload the WebView local plug-in database. + if (_private->pluginDatabase) { + [_private->pluginDatabase destroyAllPluginInstanceViews]; + [_private->pluginDatabase close]; + [_private->pluginDatabase release]; + _private->pluginDatabase = nil; + } + + // Keep the global plug-in database active until the app terminates to avoid having to reload plug-in bundles. + if (!pluginDatabaseClientCount && applicationIsTerminating) + [WebPluginDatabase closeSharedDatabase]; +} + +- (void)_closeWithFastTeardown +{ +#ifndef NDEBUG + WTF::RefCountedLeakCounter::suppressMessages("At least one WebView was closed with fast teardown."); +#endif + + // Dispatch unload events. + // FIXME: Shouldn't have to use a RefPtr here -- keeping the frame alive while stopping it + // should be WebCore's responsibility -- but we do as of the time this comment was written. + RefPtr<Frame> mainFrame = core([self mainFrame]); + if (mainFrame && mainFrame->page() && mainFrame->page()->pendingUnloadEventCount()) + mainFrame->loader()->stopLoading(true); + + _private->closed = YES; + + [self _closePluginDatabases]; +} + +// _close is here only for backward compatibility; clients and subclasses should use +// public method -close instead. - (void)_close { if (!_private || _private->closed) return; - FrameLoader* mainFrameLoader = [[self mainFrame] _frameLoader]; - if (mainFrameLoader) - mainFrameLoader->detachFromParent(); +#ifndef NDEBUG + WTF::RefCountedLeakCounter::cancelMessageSuppression(webViewIsOpen); +#endif + + WebPreferences *preferences = _private->preferences; + BOOL fullDocumentTeardown = [preferences fullDocumentTeardownEnabled]; + + // To quit the apps fast we skip document teardown. Two exceptions: + // 1) plugins need to be destroyed and unloaded + // 2) unload events need to be called + if (applicationIsTerminating && !fullDocumentTeardown) { + [self _closeWithFastTeardown]; + return; + } + + if (Frame* mainFrame = core([self mainFrame])) + mainFrame->loader()->detachFromParent(); [self _removeFromAllWebViewsSet]; - [self setGroupName:nil]; [self setHostWindow:nil]; [self setDownloadDelegate:nil]; @@ -721,29 +1054,22 @@ static bool debugWidget = true; _private->hasSpellCheckerDocumentTag = NO; } + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self]; [WebPreferences _removeReferenceForIdentifier:[self preferencesIdentifier]]; - WebPreferences *preferences = _private->preferences; _private->preferences = nil; [preferences didRemoveFromWebView]; [preferences release]; - pluginDatabaseClientCount--; - - // Make sure to close both sets of plug-ins databases because plug-ins need an opportunity to clean up files, etc. - - // Unload the WebView local plug-in database. - if (_private->pluginDatabase) { - [_private->pluginDatabase close]; - [_private->pluginDatabase release]; - _private->pluginDatabase = nil; - } - - // Keep the global plug-in database active until the app terminates to avoid having to reload plug-in bundles. - if (!pluginDatabaseClientCount && applicationIsTerminating) - [WebPluginDatabase closeSharedDatabase]; + [self _closePluginDatabases]; + +#ifndef NDEBUG + // Need this to make leak messages accurate. + if (applicationIsTerminating) + gcController().garbageCollectNow(); +#endif } + (NSString *)_MIMETypeForFile:(NSString *)path @@ -921,7 +1247,7 @@ static bool debugWidget = true; return needsQuirks; needsQuirks = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_IE_COMPATIBLE_KEYBOARD_EVENT_DISPATCH) - && ![[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Safari"]; + && ![[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Safari"]; checked = YES; return needsQuirks; @@ -931,9 +1257,9 @@ static bool debugWidget = true; { WebPreferences *preferences = (WebPreferences *)[notification object]; ASSERT(preferences == [self preferences]); - + if (!_private->userAgentOverridden) - *_private->userAgent = String(); + _private->userAgent = String(); // Cache this value so we don't have to read NSUserDefaults on each page load _private->useSiteSpecificSpoofing = [preferences _useSiteSpecificSpoofing]; @@ -952,6 +1278,7 @@ static bool debugWidget = true; settings->setFixedFontFamily([preferences fixedFontFamily]); settings->setForceFTPDirectoryListings([preferences _forceFTPDirectoryListings]); settings->setFTPDirectoryTemplatePath([preferences _ftpDirectoryTemplatePath]); + settings->setLocalStorageDatabasePath([preferences _localStorageDatabasePath]); settings->setJavaEnabled([preferences isJavaEnabled]); settings->setJavaScriptEnabled([preferences isJavaScriptEnabled]); settings->setJavaScriptCanOpenWindowsAutomatically([preferences javaScriptCanOpenWindowsAutomatically]); @@ -972,6 +1299,7 @@ static bool debugWidget = true; settings->setShowsURLsInToolTips([preferences showsURLsInToolTips]); settings->setDeveloperExtrasEnabled([preferences developerExtrasEnabled]); settings->setAuthorAndUserStylesEnabled([preferences authorAndUserStylesEnabled]); + settings->setApplicationChromeMode([preferences applicationChromeModeEnabled]); if ([preferences userStyleSheetEnabled]) { NSString* location = [[preferences userStyleSheetLocation] _web_originalDataAsString]; settings->setUserStyleSheetLocation([NSURL URLWithString:(location ? location : @"")]); @@ -979,6 +1307,12 @@ static bool debugWidget = true; settings->setUserStyleSheetLocation([NSURL URLWithString:@""]); settings->setNeedsAdobeFrameReloadingQuirk([self _needsAdobeFrameReloadingQuirk]); settings->setNeedsKeyboardEventDisambiguationQuirks([self _needsKeyboardEventDisambiguationQuirks]); + settings->setNeedsSiteSpecificQuirks(_private->useSiteSpecificSpoofing); + settings->setWebArchiveDebugModeEnabled([preferences webArchiveDebugModeEnabled]); + settings->disableRangeMutationForOldAppleMail(WKAppVersionCheckLessThan(@"com.apple.mail", -1, 4.0)); + settings->setOfflineWebApplicationCacheEnabled([preferences offlineWebApplicationCacheEnabled]); + settings->setZoomsTextOnly([preferences zoomsTextOnly]); + settings->setEnforceCSSMIMETypeInStrictMode(!WKAppVersionCheckLessThan(@"com.apple.iWeb", -1, 2.1)); } static inline IMP getMethod(id o, SEL s) @@ -1132,9 +1466,9 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati return [schemesWithRepresentationsSet containsObject:[URLScheme lowercaseString]]; } -+ (BOOL)_canHandleRequest:(NSURLRequest *)request ++ (BOOL)_canHandleRequest:(NSURLRequest *)request forMainFrame:(BOOL)forMainFrame { - // FIXME: If <rdar://problem/5217309> gets fixed, this check can be removed + // FIXME: If <rdar://problem/5217309> gets fixed, this check can be removed. if (!request) return NO; @@ -1143,16 +1477,22 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati NSString *scheme = [[request URL] scheme]; - if ([self _representationExistsForURLScheme:scheme]) + // Representations for URL schemes work at the top level. + if (forMainFrame && [self _representationExistsForURLScheme:scheme]) return YES; - return ([scheme _webkit_isCaseInsensitiveEqualToString:@"applewebdata"]); + return [scheme _webkit_isCaseInsensitiveEqualToString:@"applewebdata"]; +} + ++ (BOOL)_canHandleRequest:(NSURLRequest *)request +{ + return [self _canHandleRequest:request forMainFrame:YES]; } + (NSString *)_decodeData:(NSData *)data { HTMLNames::init(); // this method is used for importing bookmarks at startup, so HTMLNames are likely to be uninitialized yet - RefPtr<TextResourceDecoder> decoder = new TextResourceDecoder("text/html"); // bookmark files are HTML + RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/html"); // bookmark files are HTML String result = decoder->decode(static_cast<const char*>([data bytes]), [data length]); result += decoder->flush(); return result; @@ -1281,11 +1621,6 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati [NSApp setWindowsNeedUpdate:YES]; } -- (void)_reloadForPluginChanges -{ - [[self mainFrame] _reloadForPluginChanges]; -} - - (NSCachedURLResponse *)_cachedResponseForURL:(NSURL *)URL { NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL]; @@ -1322,6 +1657,8 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati _private->page->dragController()->setDidInitiateDrag(initiatedDrag); } +#if ENABLE(DASHBOARD_SUPPORT) + #define DASHBOARD_CONTROL_LABEL @"control" - (void)_addScrollerDashboardRegions:(NSMutableDictionary *)regions from:(NSArray *)views @@ -1371,7 +1708,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (NSDictionary *)_dashboardRegions { // Only return regions from main frame. - Frame* mainFrame = [[[self mainFrame] _bridge] _frame]; + Frame* mainFrame = core([self mainFrame]); if (!mainFrame) return nil; NSMutableDictionary *regions = mainFrame->dashboardRegionsDictionary(); @@ -1433,6 +1770,8 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati return NO; } +#endif /* ENABLE(DASHBOARD_SUPPORT) */ + + (void)_setShouldUseFontSmoothing:(BOOL)f { WebCoreSetShouldUseFontSmoothing(f); @@ -1453,7 +1792,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati return usesTestModeFocusRingColor(); } -// This is only used by older versions of Safari and should be removed in a future release. +// This is only used by versions of Safari up to and including 3.0 and should be removed in a future release. + (NSString *)_minimumRequiredSafariBuildNumber { return @"420+"; @@ -1463,53 +1802,53 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati { WebDynamicScrollBarsView *scrollview = [[[self mainFrame] frameView] _scrollView]; if (flag) { - [scrollview setVerticalScrollingMode:WebCoreScrollbarAlwaysOn andLock:YES]; + [scrollview setVerticalScrollingMode:ScrollbarAlwaysOn andLock:YES]; } else { [scrollview setVerticalScrollingModeLocked:NO]; - [scrollview setVerticalScrollingMode:WebCoreScrollbarAuto]; + [scrollview setVerticalScrollingMode:ScrollbarAuto andLock:NO]; } } - (BOOL)alwaysShowVerticalScroller { WebDynamicScrollBarsView *scrollview = [[[self mainFrame] frameView] _scrollView]; - return [scrollview verticalScrollingModeLocked] && [scrollview verticalScrollingMode] == WebCoreScrollbarAlwaysOn; + return [scrollview verticalScrollingModeLocked] && [scrollview verticalScrollingMode] == ScrollbarAlwaysOn; } - (void)setAlwaysShowHorizontalScroller:(BOOL)flag { WebDynamicScrollBarsView *scrollview = [[[self mainFrame] frameView] _scrollView]; if (flag) { - [scrollview setHorizontalScrollingMode:WebCoreScrollbarAlwaysOn andLock:YES]; + [scrollview setHorizontalScrollingMode:ScrollbarAlwaysOn andLock:YES]; } else { [scrollview setHorizontalScrollingModeLocked:NO]; - [scrollview setHorizontalScrollingMode:WebCoreScrollbarAuto]; + [scrollview setHorizontalScrollingMode:ScrollbarAuto andLock:NO]; } } - (void)setProhibitsMainFrameScrolling:(BOOL)prohibits { - Frame* mainFrame = [[[self mainFrame] _bridge] _frame]; + Frame* mainFrame = core([self mainFrame]); if (mainFrame) - mainFrame->setProhibitsScrolling(prohibits); + mainFrame->view()->setProhibitsScrolling(prohibits); } - (BOOL)alwaysShowHorizontalScroller { WebDynamicScrollBarsView *scrollview = [[[self mainFrame] frameView] _scrollView]; - return [scrollview horizontalScrollingModeLocked] && [scrollview horizontalScrollingMode] == WebCoreScrollbarAlwaysOn; + return [scrollview horizontalScrollingModeLocked] && [scrollview horizontalScrollingMode] == ScrollbarAlwaysOn; } - (void)_setInViewSourceMode:(BOOL)flag { - Frame* mainFrame = [[[self mainFrame] _bridge] _frame]; + Frame* mainFrame = core([self mainFrame]); if (mainFrame) mainFrame->setInViewSourceMode(flag); } - (BOOL)_inViewSourceMode { - Frame* mainFrame = [[[self mainFrame] _bridge] _frame]; + Frame* mainFrame = core([self mainFrame]); return mainFrame && mainFrame->inViewSourceMode(); } @@ -1528,6 +1867,19 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati return NO; } +- (BOOL)_cookieEnabled +{ + if (_private->page) + return _private->page->cookieEnabled(); + return YES; +} + +- (void)_setCookieEnabled:(BOOL)enable +{ + if (_private->page) + _private->page->setCookieEnabled(enable); +} + - (void)_setAdditionalWebPlugInPaths:(NSArray *)newPaths { if (!_private->pluginDatabase) @@ -1558,7 +1910,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati _private->backgroundColor = [backgroundColor retain]; [old release]; - [[self mainFrame] _updateBackground]; + [[self mainFrame] _updateBackgroundAndUpdatesWhileOffscreen]; } - (NSColor *)backgroundColor @@ -1596,6 +1948,20 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati [[self preferences] _postPreferencesChangesNotification]; } +- (WebTextIterator *)textIteratorForRect:(NSRect)rect +{ + IntPoint rectStart(rect.origin.x, rect.origin.y); + IntPoint rectEnd(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); + + Frame* coreFrame = core([self mainFrame]); + if (!coreFrame) + return nil; + + Selection selectionInsideRect(coreFrame->visiblePositionForPoint(rectStart), coreFrame->visiblePositionForPoint(rectEnd)); + + return [[[WebTextIterator alloc] initWithRange:[DOMRange _wrapRange:selectionInsideRect.toRange().get()]] autorelease]; +} + - (void)handleAuthenticationForResource:(id)identifier challenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource { NSWindow *window = [self hostWindow] ? [self hostWindow] : [self window]; @@ -1621,12 +1987,31 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (void)_executeCoreCommandByName:(NSString *)name value:(NSString *)value { - Frame* coreFrame = [[[self mainFrame] _bridge] _frame]; + Frame* coreFrame = core([self mainFrame]); if (!coreFrame) return; coreFrame->editor()->command(name).execute(value); } +- (void)_setCustomHTMLTokenizerTimeDelay:(double)timeDelay +{ + if (!_private->page) + return; + return _private->page->setCustomHTMLTokenizerTimeDelay(timeDelay); +} + +- (void)_setCustomHTMLTokenizerChunkSize:(int)chunkSize +{ + if (!_private->page) + return; + return _private->page->setCustomHTMLTokenizerChunkSize(chunkSize); +} + +- (void)_clearMainFrameName +{ + _private->page->mainFrame()->tree()->clearName(); +} + @end @implementation _WebSafeForwarder @@ -1682,7 +2067,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillTerminate) name:NSApplicationWillTerminateNotification object:NSApp]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_preferencesChangedNotification:) name:WebPreferencesChangedNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_preferencesRemovedNotification:) name:WebPreferencesRemovedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_preferencesRemovedNotification:) name:WebPreferencesRemovedNotification object:nil]; } + (void)_applicationWillTerminate @@ -1690,6 +2075,8 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati applicationIsTerminating = YES; if (!pluginDatabaseClientCount) [WebPluginDatabase closeSharedDatabase]; + + PageGroup::closeLocalStorage(); } + (BOOL)canShowMIMEType:(NSString *)MIMEType @@ -1721,6 +2108,25 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati return nil; } +- (void)addPluginInstanceView:(NSView *)view +{ + if (!_private->pluginDatabase) + _private->pluginDatabase = [[WebPluginDatabase alloc] init]; + [_private->pluginDatabase addPluginInstanceView:view]; +} + +- (void)removePluginInstanceView:(NSView *)view +{ + if (_private->pluginDatabase) + [_private->pluginDatabase removePluginInstanceView:view]; +} + +- (void)removePluginInstanceViewsFor:(WebFrame*)webFrame +{ + if (_private->pluginDatabase) + [_private->pluginDatabase removePluginInstanceViewsFor:webFrame]; +} + - (BOOL)_isMIMETypeRegisteredAsPlugin:(NSString *)MIMEType { if ([[WebPluginDatabase sharedDatabase] isMIMETypeRegistered:MIMEType]) @@ -1786,101 +2192,14 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati FrameLoader::registerURLSchemeAsLocal(protocol); } -- (void)_registerDraggedTypes -{ - NSArray *editableTypes = [WebHTMLView _insertablePasteboardTypes]; - NSArray *URLTypes = [NSPasteboard _web_dragTypesForURL]; - NSMutableSet *types = [[NSMutableSet alloc] initWithArray:editableTypes]; - [types addObjectsFromArray:URLTypes]; - [self registerForDraggedTypes:[types allObjects]]; - [types release]; -} - -- (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName -{ - WebPreferences *standardPreferences = [WebPreferences standardPreferences]; - [standardPreferences willAddToWebView]; - - _private->preferences = [standardPreferences retain]; - _private->catchesDelegateExceptions = YES; - _private->mainFrameDocumentReady = NO; - _private->drawsBackground = YES; - _private->smartInsertDeleteEnabled = YES; - _private->backgroundColor = [[NSColor whiteColor] retain]; - - NSRect f = [self frame]; - WebFrameView *frameView = [[WebFrameView alloc] initWithFrame: NSMakeRect(0,0,f.size.width,f.size.height)]; - [frameView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [self addSubview:frameView]; - [frameView release]; - - WebKitInitializeLoggingChannelsIfNecessary(); - WebCore::InitializeLoggingChannelsIfNecessary(); - [WebHistoryItem initWindowWatcherIfNecessary]; - WebKitInitializeDatabasesIfNecessary(); - - _private->page = new Page(new WebChromeClient(self), new WebContextMenuClient(self), new WebEditorClient(self), new WebDragClient(self), new WebInspectorClient(self)); - [[[WebFrameBridge alloc] initMainFrameWithPage:_private->page frameName:frameName frameView:frameView] release]; - - [self _addToAllWebViewsSet]; - [self setGroupName:groupName]; - - // If there's already a next key view (e.g., from a nib), wire it up to our - // contained frame view. In any case, wire our next key view up to the our - // contained frame view. This works together with our becomeFirstResponder - // and setNextKeyView overrides. - NSView *nextKeyView = [self nextKeyView]; - if (nextKeyView != nil && nextKeyView != frameView) { - [frameView setNextKeyView:nextKeyView]; - } - [super setNextKeyView:frameView]; - - ++WebViewCount; - - [self _registerDraggedTypes]; - - // initialize WebScriptDebugServer here so listeners can register before any pages are loaded. - if ([WebView _scriptDebuggerEnabled]) - [WebScriptDebugServer sharedScriptDebugServer]; - - WebPreferences *prefs = [self preferences]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_preferencesChangedNotification:) - name:WebPreferencesChangedNotification object:prefs]; - - // Post a notification so the WebCore settings update. - [[self preferences] _postPreferencesChangesNotification]; - - if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOCAL_RESOURCE_SECURITY_RESTRICTION)) - FrameLoader::setRestrictAccessToLocal(false); -} - - (id)initWithFrame:(NSRect)f { return [self initWithFrame:f frameName:nil groupName:nil]; } -- (id)initWithFrame:(NSRect)f frameName:(NSString *)frameName groupName:(NSString *)groupName; +- (id)initWithFrame:(NSRect)f frameName:(NSString *)frameName groupName:(NSString *)groupName { - self = [super initWithFrame:f]; - if (!self) - return nil; - -#ifdef ENABLE_WEBKIT_UNSET_DYLD_FRAMEWORK_PATH - // DYLD_FRAMEWORK_PATH is used so Safari will load the development version of WebKit, which - // may not work with other WebKit applications. Unsetting DYLD_FRAMEWORK_PATH removes the - // need for Safari to unset it to prevent it from being passed to applications it launches. - // Unsetting it when a WebView is first created is as good a place as any. - // See <http://bugs.webkit.org/show_bug.cgi?id=4286> for more details. - if (getenv("WEBKIT_UNSET_DYLD_FRAMEWORK_PATH")) { - unsetenv("DYLD_FRAMEWORK_PATH"); - unsetenv("WEBKIT_UNSET_DYLD_FRAMEWORK_PATH"); - } -#endif - - _private = [[WebViewPrivate alloc] init]; - [self _commonInitializationWithFrameName:frameName groupName:groupName]; - [self setMaintainsBackForwardList: YES]; - return self; + return [self _initWithFrame:f frameName:frameName groupName:groupName usesDocumentViews:YES]; } - (id)initWithCoder:(NSCoder *)decoder @@ -1930,7 +2249,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati preferences = nil; LOG(Encoding, "FrameName = %@, GroupName = %@, useBackForwardList = %d\n", frameName, groupName, (int)useBackForwardList); - [result _commonInitializationWithFrameName:frameName groupName:groupName]; + [result _commonInitializationWithFrameName:frameName groupName:groupName usesDocumentViews:YES]; [result page]->backForwardList()->setEnabled(useBackForwardList); result->_private->allowsUndo = allowsUndo; if (preferences) @@ -1977,9 +2296,12 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (void)dealloc { + if (WebCoreObjCScheduleDeallocateOnMainThread([WebView class], self)) + return; + // call close to ensure we tear-down completely // this maintains our old behavior for existing applications - [self _close]; + [self close]; --WebViewCount; @@ -2001,6 +2323,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (void)close { + // _close existed first, and some clients might be calling or overriding it, so call through. [self _close]; } @@ -2014,29 +2337,149 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati return _private->shouldCloseWithWindow; } +- (void)removeSizeObservers +{ + if (!_private->useDocumentViews && [self window]) { + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSViewFrameDidChangeNotification object:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSViewBoundsDidChangeNotification object:self]; + } +} + +- (void)addSizeObservers +{ + if (!_private->useDocumentViews && [self window]) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_boundsChanged) + name:NSViewFrameDidChangeNotification object:self]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_boundsChanged) + name:NSViewBoundsDidChangeNotification object:self]; + [self _boundsChanged]; + } +} + +- (void)addWindowObservers +{ + NSWindow *window = [self window]; + if (!_private->useDocumentViews && window) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidBecomeKey:) + name:NSWindowDidBecomeKeyNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidResignKey:) + name:NSWindowDidResignKeyNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowWillOrderOnScreen:) + name:WKWindowWillOrderOnScreenNotification() object:window]; + } +} + +- (void)removeWindowObservers +{ + NSWindow *window = [self window]; + if (!_private->useDocumentViews && window) { + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSWindowDidBecomeKeyNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSWindowDidResignKeyNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:WKWindowWillOrderOnScreenNotification() object:window]; + } +} + - (void)viewWillMoveToWindow:(NSWindow *)window { - // Don't do anything if we aren't initialized. This happens when decoding a WebView. + // Don't do anything if the WebView isn't initialized. + // This happens when decoding a WebView in a nib. + // FIXME: What sets up the observer of NSWindowWillCloseNotification in this case? if (!_private) return; + + if (_private->closed) + return; - if ([self window]) + if ([self window] && [self window] != [self hostWindow]) [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowWillCloseNotification object:[self window]]; if (window) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowWillClose:) name:NSWindowWillCloseNotification object:window]; - - // Ensure that we will receive the events that WebHTMLView (at least) needs. It's expensive enough - // that we don't want to call it over and over. + + // Ensure that we will receive the events that WebHTMLView (at least) needs. + // The following are expensive enough that we don't want to call them over + // and over, so do them when we move into a window. [window setAcceptsMouseMovedEvents:YES]; WKSetNSWindowShouldPostEventNotifications(window, YES); + + [self removeWindowObservers]; + [self removeSizeObservers]; } } +- (void)viewDidMoveToWindow +{ + // Don't do anything if we aren't initialized. This happens + // when decoding a WebView. When WebViews are decoded their subviews + // are created by initWithCoder: and so won't be normally + // initialized. The stub views are discarded by WebView. + if (!_private || _private->closed) + return; + + if ([self window]) { + [self addWindowObservers]; + [self addSizeObservers]; + } +} + +- (void)_updateFocusedAndActiveState +{ + ASSERT(!_private->useDocumentViews); + [self _updateFocusedAndActiveStateForFrame:[self mainFrame]]; +} + +- (void)_updateFocusedAndActiveStateForFrame:(WebFrame *)webFrame +{ + Frame* frame = core(webFrame); + if (!frame) + return; + + Page* page = frame->page(); + if (!page) + return; + + NSWindow *window = [self window]; + BOOL windowIsKey = [window isKeyWindow]; + BOOL windowOrSheetIsKey = windowIsKey || [[window attachedSheet] isKeyWindow]; + + page->focusController()->setActive(windowIsKey); + + Frame* focusedFrame = page->focusController()->focusedOrMainFrame(); + frame->selection()->setFocused(frame == focusedFrame && windowOrSheetIsKey); +} + +- (void)_windowDidBecomeKey:(NSNotification *)notification +{ + ASSERT(!_private->useDocumentViews); + NSWindow *keyWindow = [notification object]; + if (keyWindow == [self window] || keyWindow == [[self window] attachedSheet]) + [self _updateFocusedAndActiveState]; +} + +- (void)_windowDidResignKey:(NSNotification *)notification +{ + ASSERT(!_private->useDocumentViews); + NSWindow *formerKeyWindow = [notification object]; + if (formerKeyWindow == [self window] || formerKeyWindow == [[self window] attachedSheet]) + [self _updateFocusedAndActiveState]; +} + +- (void)_windowWillOrderOnScreen:(NSNotification *)notification +{ + ASSERT(!_private->useDocumentViews); + if (![self shouldUpdateWhileOffscreen]) + [self setNeedsDisplay:YES]; +} + - (void)_windowWillClose:(NSNotification *)notification { if ([self shouldCloseWithWindow] && ([self window] == [self hostWindow] || ([self window] && ![self hostWindow]) || (![self window] && [self hostWindow]))) - [self _close]; + [self close]; } - (void)setPreferences:(WebPreferences *)prefs @@ -2213,17 +2656,120 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (void)setTextSizeMultiplier:(float)m { + [self _setZoomMultiplier:m isTextOnly:![[NSUserDefaults standardUserDefaults] boolForKey:WebKitDebugFullPageZoomPreferenceKey]]; +} + +- (float)textSizeMultiplier +{ + return _private->zoomMultiplierIsTextOnly ? _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>) - if (_private->textSizeMultiplier == m) - return; + _private->zoomMultiplier = m; + _private->zoomMultiplierIsTextOnly = isTextOnly; + Frame* coreFrame = core([self mainFrame]); + if (coreFrame) + coreFrame->setZoomFactor(m, isTextOnly); +} - _private->textSizeMultiplier = m; - [self _notifyTextSizeMultiplierChanged]; +- (float)_zoomMultiplier:(BOOL)isTextOnly +{ + if (isTextOnly != _private->zoomMultiplierIsTextOnly) + return 1.0f; + return _private->zoomMultiplier; } -- (float)textSizeMultiplier +- (float)_realZoomMultiplier +{ + return _private->zoomMultiplier; +} + +- (BOOL)_realZoomMultiplierIsTextOnly { - return _private->textSizeMultiplier; + return _private->zoomMultiplierIsTextOnly; +} + +#define MinimumZoomMultiplier 0.5f +#define MaximumZoomMultiplier 3.0f +#define ZoomMultiplierRatio 1.2f + +- (BOOL)_canZoomOut:(BOOL)isTextOnly +{ + id docView = [[[self mainFrame] frameView] documentView]; + if ([docView conformsToProtocol:@protocol(_WebDocumentZooming)]) { + id <_WebDocumentZooming> zoomingDocView = (id <_WebDocumentZooming>)docView; + return [zoomingDocView _canZoomOut]; + } + return [self _zoomMultiplier:isTextOnly] / ZoomMultiplierRatio > MinimumZoomMultiplier; +} + + +- (BOOL)_canZoomIn:(BOOL)isTextOnly +{ + id docView = [[[self mainFrame] frameView] documentView]; + if ([docView conformsToProtocol:@protocol(_WebDocumentZooming)]) { + id <_WebDocumentZooming> zoomingDocView = (id <_WebDocumentZooming>)docView; + return [zoomingDocView _canZoomIn]; + } + return [self _zoomMultiplier:isTextOnly] * ZoomMultiplierRatio < MaximumZoomMultiplier; +} + +- (IBAction)_zoomOut:(id)sender isTextOnly:(BOOL)isTextOnly +{ + id docView = [[[self mainFrame] frameView] documentView]; + if ([docView conformsToProtocol:@protocol(_WebDocumentZooming)]) { + id <_WebDocumentZooming> zoomingDocView = (id <_WebDocumentZooming>)docView; + return [zoomingDocView _zoomOut:sender]; + } + float newScale = [self _zoomMultiplier:isTextOnly] / ZoomMultiplierRatio; + if (newScale > MinimumZoomMultiplier) + [self _setZoomMultiplier:newScale isTextOnly:isTextOnly]; +} + +- (IBAction)_zoomIn:(id)sender isTextOnly:(BOOL)isTextOnly +{ + id docView = [[[self mainFrame] frameView] documentView]; + if ([docView conformsToProtocol:@protocol(_WebDocumentZooming)]) { + id <_WebDocumentZooming> zoomingDocView = (id <_WebDocumentZooming>)docView; + return [zoomingDocView _zoomIn:sender]; + } + float newScale = [self _zoomMultiplier:isTextOnly] * ZoomMultiplierRatio; + if (newScale < MaximumZoomMultiplier) + [self _setZoomMultiplier:newScale isTextOnly:isTextOnly]; +} + +- (BOOL)_canResetZoom:(BOOL)isTextOnly +{ + id docView = [[[self mainFrame] frameView] documentView]; + if ([docView conformsToProtocol:@protocol(_WebDocumentZooming)]) { + id <_WebDocumentZooming> zoomingDocView = (id <_WebDocumentZooming>)docView; + return [zoomingDocView _canResetZoom]; + } + return [self _zoomMultiplier:isTextOnly] != 1.0f; +} + +- (IBAction)_resetZoom:(id)sender isTextOnly:(BOOL)isTextOnly +{ + id docView = [[[self mainFrame] frameView] documentView]; + if ([docView conformsToProtocol:@protocol(_WebDocumentZooming)]) { + id <_WebDocumentZooming> zoomingDocView = (id <_WebDocumentZooming>)docView; + return [zoomingDocView _resetZoom:sender]; + } + if ([self _zoomMultiplier:isTextOnly] != 1.0f) + [self _setZoomMultiplier:1.0f isTextOnly:isTextOnly]; +} + +- (void)viewWillMoveToSuperview:(NSView *)newSuperview +{ + [self removeSizeObservers]; +} + +- (void)viewDidMoveToSuperview +{ + if ([self superview] != nil) + [self addSizeObservers]; } - (void)setApplicationNameForUserAgent:(NSString *)applicationName @@ -2232,7 +2778,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati [_private->applicationNameForUserAgent release]; _private->applicationNameForUserAgent = name; if (!_private->userAgentOverridden) - *_private->userAgent = String(); + _private->userAgent = String(); } - (NSString *)applicationNameForUserAgent @@ -2242,7 +2788,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (void)setCustomUserAgent:(NSString *)userAgentString { - *_private->userAgent = userAgentString; + _private->userAgent = userAgentString; _private->userAgentOverridden = userAgentString != nil; } @@ -2250,7 +2796,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati { if (!_private->userAgentOverridden) return nil; - return *_private->userAgent; + return _private->userAgent; } - (void)setMediaStyle:(NSString *)mediaStyle @@ -2278,9 +2824,8 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati NSString *oldEncoding = [self customTextEncodingName]; if (encoding == oldEncoding || [encoding isEqualToString:oldEncoding]) return; - FrameLoader* mainFrameLoader = [[self mainFrame] _frameLoader]; - if (mainFrameLoader) - mainFrameLoader->reloadAllowingStaleData(encoding); + if (Frame* mainFrame = core([self mainFrame])) + mainFrame->loader()->reloadAllowingStaleData(encoding); } - (NSString *)_mainFrameOverrideEncoding @@ -2310,7 +2855,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati script = [script substringFromIndex:returnStringRange.location + returnStringRange.length]; } - NSString *result = [[[self mainFrame] _bridge] stringByEvaluatingJavaScriptFromString:script]; + NSString *result = [[self mainFrame] _stringByEvaluatingJavaScriptFromString:script]; // The only way stringByEvaluatingJavaScriptFromString can return nil is if the frame was removed by the script // Since there's no way to get rid of the main frame, result will never ever be nil here. ASSERT(result); @@ -2323,7 +2868,7 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati Frame* coreFrame = core([self mainFrame]); if (!coreFrame) return nil; - return coreFrame->windowScriptObject(); + return coreFrame->script()->windowScriptObject(); } // Get the appropriate user-agent string for a particular URL. @@ -2334,16 +2879,22 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (void)setHostWindow:(NSWindow *)hostWindow { - if (!_private->closed && hostWindow != _private->hostWindow) { - [[self mainFrame] _viewWillMoveToHostWindow:hostWindow]; - if (_private->hostWindow) - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowWillCloseNotification object:_private->hostWindow]; - if (hostWindow) - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowWillClose:) name:NSWindowWillCloseNotification object:hostWindow]; - [_private->hostWindow release]; - _private->hostWindow = [hostWindow retain]; - [[self mainFrame] _viewDidMoveToHostWindow]; - } + if (_private->closed) + return; + if (hostWindow == _private->hostWindow) + return; + + Frame* coreFrame = core([self mainFrame]); + for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) + [[[kit(frame) frameView] documentView] viewWillMoveToHostWindow:hostWindow]; + if (_private->hostWindow && [self window] != _private->hostWindow) + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowWillCloseNotification object:_private->hostWindow]; + if (hostWindow) + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowWillClose:) name:NSWindowWillCloseNotification object:hostWindow]; + [_private->hostWindow release]; + _private->hostWindow = [hostWindow retain]; + for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) + [[[kit(frame) frameView] documentView] viewDidMoveToHostWindow]; } - (NSWindow *)hostWindow @@ -2402,22 +2953,30 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)draggingInfo { + Page* page = core(self); + if (!page) + return NSDragOperationNone; + NSView <WebDocumentView>* view = [self documentViewAtWindowPoint:[draggingInfo draggingLocation]]; WebPasteboardHelper helper([view isKindOfClass:[WebHTMLView class]] ? (WebHTMLView*)view : nil); IntPoint client([draggingInfo draggingLocation]); IntPoint global(globalPoint([draggingInfo draggingLocation], [self window])); DragData dragData(draggingInfo, client, global, (DragOperation)[draggingInfo draggingSourceOperationMask], &helper); - return core(self)->dragController()->dragUpdated(&dragData); + return page->dragController()->dragUpdated(&dragData); } - (void)draggingExited:(id <NSDraggingInfo>)draggingInfo { + Page* page = core(self); + if (!page) + return; + NSView <WebDocumentView>* view = [self documentViewAtWindowPoint:[draggingInfo draggingLocation]]; WebPasteboardHelper helper([view isKindOfClass:[WebHTMLView class]] ? (WebHTMLView*)view : nil); IntPoint client([draggingInfo draggingLocation]); IntPoint global(globalPoint([draggingInfo draggingLocation], [self window])); DragData dragData(draggingInfo, client, global, (DragOperation)[draggingInfo draggingSourceOperationMask], &helper); - core(self)->dragController()->dragExited(&dragData); + page->dragController()->dragExited(&dragData); } - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)draggingInfo @@ -2659,7 +3218,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) if (_private->drawsBackground == drawsBackground) return; _private->drawsBackground = drawsBackground; - [[self mainFrame] _updateBackground]; + [[self mainFrame] _updateBackgroundAndUpdatesWhileOffscreen]; } - (BOOL)drawsBackground @@ -2667,6 +3226,31 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) return _private->drawsBackground; } +- (void)setShouldUpdateWhileOffscreen:(BOOL)updateWhileOffscreen +{ + if (_private->shouldUpdateWhileOffscreen == updateWhileOffscreen) + return; + _private->shouldUpdateWhileOffscreen = updateWhileOffscreen; + [[self mainFrame] _updateBackgroundAndUpdatesWhileOffscreen]; +} + +- (BOOL)shouldUpdateWhileOffscreen +{ + return _private->shouldUpdateWhileOffscreen; +} + +- (void)setCurrentNodeHighlight:(WebNodeHighlight *)nodeHighlight +{ + id old = _private->currentNodeHighlight; + _private->currentNodeHighlight = [nodeHighlight retain]; + [old release]; +} + +- (WebNodeHighlight *)currentNodeHighlight +{ + return _private->currentNodeHighlight; +} + @end @implementation WebView (WebIBActions) @@ -2714,34 +3298,36 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) [[self mainFrame] reload]; } -#define MinimumTextSizeMultiplier 0.5f -#define MaximumTextSizeMultiplier 3.0f -#define TextSizeMultiplierRatio 1.2f - +// 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 { - BOOL canShrinkMore = _private->textSizeMultiplier/TextSizeMultiplierRatio > MinimumTextSizeMultiplier; - return [self _performTextSizingSelector:(SEL)0 withObject:nil onTrackingDocs:canShrinkMore selForNonTrackingDocs:@selector(_canMakeTextSmaller) newScaleFactor:0]; + return [self _canZoomOut:![[NSUserDefaults standardUserDefaults] boolForKey:WebKitDebugFullPageZoomPreferenceKey]]; } -- (BOOL)canMakeTextLarger +- (IBAction)makeTextSmaller:(id)sender { - BOOL canGrowMore = _private->textSizeMultiplier*TextSizeMultiplierRatio < MaximumTextSizeMultiplier; - return [self _performTextSizingSelector:(SEL)0 withObject:nil onTrackingDocs:canGrowMore selForNonTrackingDocs:@selector(_canMakeTextLarger) newScaleFactor:0]; + return [self _zoomOut:sender isTextOnly:![[NSUserDefaults standardUserDefaults] boolForKey:WebKitDebugFullPageZoomPreferenceKey]]; } -- (IBAction)makeTextSmaller:(id)sender +- (BOOL)canMakeTextLarger { - float newScale = _private->textSizeMultiplier / TextSizeMultiplierRatio; - BOOL canShrinkMore = newScale > MinimumTextSizeMultiplier; - [self _performTextSizingSelector:@selector(_makeTextSmaller:) withObject:sender onTrackingDocs:canShrinkMore selForNonTrackingDocs:@selector(_canMakeTextSmaller) newScaleFactor:newScale]; + return [self _canZoomIn:![[NSUserDefaults standardUserDefaults] boolForKey:WebKitDebugFullPageZoomPreferenceKey]]; } - (IBAction)makeTextLarger:(id)sender { - float newScale = _private->textSizeMultiplier*TextSizeMultiplierRatio; - BOOL canGrowMore = newScale < MaximumTextSizeMultiplier; - [self _performTextSizingSelector:@selector(_makeTextLarger:) withObject:sender onTrackingDocs:canGrowMore selForNonTrackingDocs:@selector(_canMakeTextLarger) newScaleFactor:newScale]; + return [self _zoomIn:sender isTextOnly:![[NSUserDefaults standardUserDefaults] boolForKey:WebKitDebugFullPageZoomPreferenceKey]]; +} + +- (BOOL)canMakeTextStandardSize +{ + return [self _canResetZoom:![[NSUserDefaults standardUserDefaults] boolForKey:WebKitDebugFullPageZoomPreferenceKey]]; +} + +- (IBAction)makeTextStandardSize:(id)sender +{ + return [self _resetZoom:sender isTextOnly:![[NSUserDefaults standardUserDefaults] boolForKey:WebKitDebugFullPageZoomPreferenceKey]]; } - (IBAction)toggleSmartInsertDelete:(id)sender @@ -2767,18 +3353,6 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) return NO; } -- (BOOL)canMakeTextStandardSize -{ - BOOL notAlreadyStandard = _private->textSizeMultiplier != 1.0f; - return [self _performTextSizingSelector:(SEL)0 withObject:nil onTrackingDocs:notAlreadyStandard selForNonTrackingDocs:@selector(_canMakeTextStandardSize) newScaleFactor:0.0f]; -} - -- (IBAction)makeTextStandardSize:(id)sender -{ - BOOL notAlreadyStandard = _private->textSizeMultiplier != 1.0f; - [self _performTextSizingSelector:@selector(_makeTextStandardSize:) withObject:sender onTrackingDocs:notAlreadyStandard selForNonTrackingDocs:@selector(_canMakeTextStandardSize) newScaleFactor:1.0f]; -} - #define VALIDATE(name) \ else if (action == @selector(name:)) { return [self _responderValidateUserInterfaceItem:item]; } @@ -2837,6 +3411,22 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) @implementation WebView (WebPendingPublic) +- (void)scheduleInRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode +{ +#ifndef BUILDING_ON_TIGER + if (runLoop && mode) + core(self)->addSchedulePair(SchedulePair::create(runLoop, (CFStringRef)mode)); +#endif +} + +- (void)unscheduleFromRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode +{ +#ifndef BUILDING_ON_TIGER + if (runLoop && mode) + core(self)->removeSchedulePair(SchedulePair::create(runLoop, (CFStringRef)mode)); +#endif +} + - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection { if (_private->closed) @@ -2982,9 +3572,73 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) return coreFrame->shouldClose(); } +static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* 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(); + 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 (object->inherits(&DateInstance::info)) { + DateInstance* date = static_cast<DateInstance*>(object); + double ms = 0; + int tzOffset = 0; + if (date->getTime(ms, tzOffset)) { + CFAbsoluteTime utcSeconds = ms / 1000 - kCFAbsoluteTimeIntervalSince1970; + LongDateTime ldt; + if (noErr == UCConvertCFAbsoluteTimeToLongDateTime(utcSeconds, &ldt)) + return [NSAppleEventDescriptor descriptorWithDescriptorType:typeLongDateTime bytes:&ldt length:sizeof(ldt)]; + } + } + else if (object->inherits(&JSArray::info)) { + static HashSet<JSObject*> visitedElems; + if (!visitedElems.contains(object)) { + visitedElems.add(object); + + JSArray* array = static_cast<JSArray*>(object); + aeDesc = [NSAppleEventDescriptor listDescriptor]; + unsigned numItems = array->length(); + for (unsigned i = 0; i < numItems; ++i) + [aeDesc insertDescriptor:aeDescFromJSValue(exec, array->get(exec, i)) atIndex:0]; + + visitedElems.remove(object); + return aeDesc; + } + } + JSValue* primitive = object->toPrimitive(exec); + if (exec->hadException()) { + exec->clearException(); + return [NSAppleEventDescriptor nullDescriptor]; + } + return aeDescFromJSValue(exec, primitive); + } + if (jsValue->isUndefined()) + return [NSAppleEventDescriptor descriptorWithTypeCode:cMissingValue]; + ASSERT(jsValue->isNull()); + return [NSAppleEventDescriptor nullDescriptor]; +} + - (NSAppleEventDescriptor *)aeDescByEvaluatingJavaScriptFromString:(NSString *)script { - return [[[self mainFrame] _bridge] aeDescByEvaluatingJavaScriptFromString:script]; + Frame* coreFrame = core([self mainFrame]); + if (!coreFrame) + return nil; + if (!coreFrame->document()) + return nil; + JSValue* result = coreFrame->loader()->executeScript(script, true); + if (!result) // FIXME: pass errors + return 0; + JSLock lock(false); + return aeDescFromJSValue(coreFrame->script()->globalObject()->globalExec(), result); } - (BOOL)canMarkAllTextMatches @@ -3075,7 +3729,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) - (void)scrollDOMRangeToVisible:(DOMRange *)range { - [[[range startContainer] _bridge] scrollDOMRangeToVisible:range]; + [[[[range startContainer] ownerDocument] webFrame] _scrollDOMRangeToVisible:range]; } - (BOOL)allowsUndo @@ -3088,6 +3742,46 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) _private->allowsUndo = flag; } +- (void)setPageSizeMultiplier:(float)m +{ + [self _setZoomMultiplier:m isTextOnly:NO]; +} + +- (float)pageSizeMultiplier +{ + return !_private->zoomMultiplierIsTextOnly ? _private->zoomMultiplier : 1.0f; +} + +- (BOOL)canZoomPageIn +{ + return [self _canZoomIn:NO]; +} + +- (IBAction)zoomPageIn:(id)sender +{ + return [self _zoomIn:sender isTextOnly:NO]; +} + +- (BOOL)canZoomPageOut +{ + return [self _canZoomOut:NO]; +} + +- (IBAction)zoomPageOut:(id)sender +{ + return [self _zoomOut:sender isTextOnly:NO]; +} + +- (BOOL)canResetPageZoom +{ + return [self _canResetZoom:NO]; +} + +- (IBAction)resetPageZoom:(id)sender +{ + return [self _resetZoom:sender isTextOnly:NO]; +} + @end @implementation WebView (WebViewPrintingPrivate) @@ -3261,16 +3955,16 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) return; if (range == nil) - coreFrame->selectionController()->clear(); + coreFrame->selection()->clear(); else { // Derive the frame to use from the range passed in. - // Using _bridgeForSelectedOrMainFrame could give us a different document than + // Using _selectedOrMainFrame could give us a different document than // the one the range uses. coreFrame = core([range startContainer])->document()->frame(); if (!coreFrame) return; - coreFrame->selectionController()->setSelectedRange([range _range], core(selectionAffinity), true); + coreFrame->selection()->setSelectedRange([range _range], core(selectionAffinity), true); } } @@ -3279,7 +3973,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) Frame* coreFrame = core([self _selectedOrMainFrame]); if (!coreFrame) return nil; - return kit(coreFrame->selectionController()->toRange().get()); + return kit(coreFrame->selection()->toRange().get()); } - (NSSelectionAffinity)selectionAffinity @@ -3287,7 +3981,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) Frame* coreFrame = core([self _selectedOrMainFrame]); if (!coreFrame) return NSSelectionAffinityDownstream; - return kit(coreFrame->selectionController()->affinity()); + return kit(coreFrame->selection()->affinity()); } - (void)setEditable:(BOOL)flag @@ -3296,7 +3990,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) _private->editable = flag; if (!_private->tabKeyCyclesThroughElementsChanged && _private->page) _private->page->setTabKeyCyclesThroughElements(!flag); - Frame* mainFrame = [[[self mainFrame] _bridge] _frame]; + Frame* mainFrame = core([self mainFrame]); if (mainFrame) { if (flag) { mainFrame->applyEditingStyleToBodyElement(); @@ -3318,12 +4012,12 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) { // We don't know enough at thls level to pass in a relevant WebUndoAction; we'd have to // change the API to allow this. - [[self _bridgeForSelectedOrMainFrame] setTypingStyle:style withUndoAction:EditActionUnspecified]; + [[self _selectedOrMainFrame] _setTypingStyle:style withUndoAction:EditActionUnspecified]; } - (DOMCSSStyleDeclaration *)typingStyle { - return [[self _bridgeForSelectedOrMainFrame] typingStyle]; + return [[self _selectedOrMainFrame] _typingStyle]; } - (void)setSmartInsertDeleteEnabled:(BOOL)flag @@ -3471,22 +4165,22 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag) - (void)replaceSelectionWithNode:(DOMNode *)node { - [[self _bridgeForSelectedOrMainFrame] replaceSelectionWithNode:node selectReplacement:YES smartReplace:NO matchStyle:NO]; + [[self _selectedOrMainFrame] _replaceSelectionWithNode:node selectReplacement:YES smartReplace:NO matchStyle:NO]; } - (void)replaceSelectionWithText:(NSString *)text { - [[self _bridgeForSelectedOrMainFrame] replaceSelectionWithText:text selectReplacement:YES smartReplace:NO]; + [[self _selectedOrMainFrame] _replaceSelectionWithText:text selectReplacement:YES smartReplace:NO]; } - (void)replaceSelectionWithMarkupString:(NSString *)markupString { - [[self _bridgeForSelectedOrMainFrame] replaceSelectionWithMarkupString:markupString baseURLString:nil selectReplacement:YES smartReplace:NO]; + [[self _selectedOrMainFrame] _replaceSelectionWithMarkupString:markupString baseURLString:nil selectReplacement:YES smartReplace:NO]; } - (void)replaceSelectionWithArchive:(WebArchive *)archive { - [[[[self _bridgeForSelectedOrMainFrame] webFrame] _dataSource] _replaceSelectionWithArchive:archive selectReplacement:YES]; + [[[self _selectedOrMainFrame] _dataSource] _replaceSelectionWithArchive:archive selectReplacement:YES]; } - (void)deleteSelection @@ -3553,12 +4247,12 @@ FOR_EACH_RESPONDER_SELECTOR(FORWARD) - (void)_insertNewlineInQuotedContent; { - [[self _bridgeForSelectedOrMainFrame] insertParagraphSeparatorInQuotedContent]; + [[self _selectedOrMainFrame] _insertParagraphSeparatorInQuotedContent]; } - (void)_replaceSelectionWithNode:(DOMNode *)node matchStyle:(BOOL)matchStyle { - [[self _bridgeForSelectedOrMainFrame] replaceSelectionWithNode:node selectReplacement:YES smartReplace:NO matchStyle:matchStyle]; + [[self _selectedOrMainFrame] _replaceSelectionWithNode:node selectReplacement:YES smartReplace:NO matchStyle:matchStyle]; } @end @@ -3583,13 +4277,14 @@ static WebFrameView *containingFrameView(NSView *view) // As a fudge factor, use 1000 instead of 1024, in case the reported byte // count doesn't align exactly to a megabyte boundary. - vm_size_t memSize = WebMemorySize() / 1024 / 1000; + uint64_t memSize = WebMemorySize() / 1024 / 1000; unsigned long long diskFreeSize = WebVolumeFreeSize(nsurlCacheDirectory) / 1024 / 1000; NSURLCache *nsurlCache = [NSURLCache sharedURLCache]; unsigned cacheTotalCapacity = 0; unsigned cacheMinDeadCapacity = 0; unsigned cacheMaxDeadCapacity = 0; + double deadDecodedDataDeletionInterval = 0; unsigned pageCacheCapacity = 0; @@ -3602,11 +4297,7 @@ static WebFrameView *containingFrameView(NSView *view) pageCacheCapacity = 0; // Object cache capacities (in bytes) - if (memSize >= 4096) - cacheTotalCapacity = 256 * 1024 * 1024; - else if (memSize >= 3072) - cacheTotalCapacity = 192 * 1024 * 1024; - else if (memSize >= 2048) + if (memSize >= 2048) cacheTotalCapacity = 128 * 1024 * 1024; else if (memSize >= 1536) cacheTotalCapacity = 86 * 1024 * 1024; @@ -3640,11 +4331,7 @@ static WebFrameView *containingFrameView(NSView *view) pageCacheCapacity = 0; // Object cache capacities (in bytes) - if (memSize >= 4096) - cacheTotalCapacity = 256 * 1024 * 1024; - else if (memSize >= 3072) - cacheTotalCapacity = 192 * 1024 * 1024; - else if (memSize >= 2048) + if (memSize >= 2048) cacheTotalCapacity = 128 * 1024 * 1024; else if (memSize >= 1536) cacheTotalCapacity = 86 * 1024 * 1024; @@ -3683,11 +4370,7 @@ static WebFrameView *containingFrameView(NSView *view) case WebCacheModelPrimaryWebBrowser: { // Page cache capacity (in pages) // (Research indicates that value / page drops substantially after 3 pages.) - if (memSize >= 8192) - pageCacheCapacity = 7; - if (memSize >= 4096) - pageCacheCapacity = 6; - else if (memSize >= 2048) + if (memSize >= 2048) pageCacheCapacity = 5; else if (memSize >= 1024) pageCacheCapacity = 4; @@ -3702,11 +4385,7 @@ static WebFrameView *containingFrameView(NSView *view) // (Testing indicates that value / MB depends heavily on content and // browsing pattern. Even growth above 128MB can have substantial // value / MB for some content / browsing patterns.) - if (memSize >= 4096) - cacheTotalCapacity = 512 * 1024 * 1024; - else if (memSize >= 3072) - cacheTotalCapacity = 384 * 1024 * 1024; - else if (memSize >= 2048) + if (memSize >= 2048) cacheTotalCapacity = 256 * 1024 * 1024; else if (memSize >= 1536) cacheTotalCapacity = 172 * 1024 * 1024; @@ -3724,6 +4403,8 @@ static WebFrameView *containingFrameView(NSView *view) // can prove that the overall system gain would justify the regression. cacheMaxDeadCapacity = max(24u, cacheMaxDeadCapacity); + deadDecodedDataDeletionInterval = 60; + // Foundation memory cache capacity (in bytes) // (These values are small because WebCore does most caching itself.) if (memSize >= 1024) @@ -3765,10 +4446,11 @@ static WebFrameView *containingFrameView(NSView *view) nsurlCacheDiskCapacity = max(nsurlCacheDiskCapacity, [nsurlCache diskCapacity]); cache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity); + cache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval); pageCache()->setCapacity(pageCacheCapacity); [nsurlCache setMemoryCapacity:nsurlCacheMemoryCapacity]; [nsurlCache setDiskCapacity:nsurlCacheDiskCapacity]; - + s_cacheModel = cacheModel; s_didSetCacheModel = YES; } @@ -3833,11 +4515,6 @@ static WebFrameView *containingFrameView(NSView *view) return result; } -- (WebFrameBridge *)_bridgeForSelectedOrMainFrame -{ - return [[self _selectedOrMainFrame] _bridge]; -} - - (BOOL)_isLoading { WebFrame *mainFrame = [self mainFrame]; @@ -3907,8 +4584,9 @@ static WebFrameView *containingFrameView(NSView *view) NSDictionary *element = [sender representedObject]; ASSERT([element isKindOfClass:[NSDictionary class]]); - - NSURLRequest *request = [[[[element objectForKey:WebElementFrameKey] dataSource] request] copy]; + + WebDataSource *dataSource = [[element objectForKey:WebElementFrameKey] dataSource]; + NSURLRequest *request = [[dataSource request] copy]; ASSERT(request); [self _openNewWindowWithRequest:request]; @@ -3953,68 +4631,6 @@ static WebFrameView *containingFrameView(NSView *view) (void)HISearchWindowShow((CFStringRef)selectedString, kNilOptions); } - -// Slightly funky method that lets us have one copy of the logic for finding docViews that can do -// text sizing. It returns whether it found any "suitable" doc views. It sends sel to any suitable -// doc views, or if sel==0 we do nothing to them. For doc views that track our size factor, they are -// suitable if doTrackingViews==YES (which in practice means that our size factor isn't at its max or -// min). For doc views that don't track it, we send them testSel to determine suitablility. If we -// do find any suitable tracking doc views and newScaleFactor!=0, we will set the common scale factor -// to that new factor before we send sel to any of them. -- (BOOL)_performTextSizingSelector:(SEL)sel withObject:(id)arg onTrackingDocs:(BOOL)doTrackingViews selForNonTrackingDocs:(SEL)testSel newScaleFactor:(float)newScaleFactor -{ - if ([[self mainFrame] _dataSource] == nil) - return NO; - - BOOL foundSome = NO; - NSArray *docViews = [[self mainFrame] _documentViews]; - for (int i = [docViews count]-1; i >= 0; i--) { - id docView = [docViews objectAtIndex:i]; - if ([docView conformsToProtocol:@protocol(_WebDocumentTextSizing)]) { - id <_WebDocumentTextSizing> sizingDocView = (id <_WebDocumentTextSizing>)docView; - BOOL isSuitable; - if ([sizingDocView _tracksCommonSizeFactor]) { - isSuitable = doTrackingViews; - if (isSuitable && newScaleFactor != 0) - _private->textSizeMultiplier = newScaleFactor; - } else { - // Incantation to perform a selector returning a BOOL. - isSuitable = ((BOOL(*)(id, SEL))objc_msgSend)(sizingDocView, testSel); - } - - if (isSuitable) { - if (sel != 0) { - foundSome = YES; - [sizingDocView performSelector:sel withObject:arg]; - } else { - // if we're just called for the benefit of the return value, we can return at first match - return YES; - } - } - } - } - - return foundSome; -} - -- (void)_notifyTextSizeMultiplierChanged -{ - if ([[self mainFrame] _dataSource] == nil) - return; - - NSArray *docViews = [[self mainFrame] _documentViews]; - for (int i = [docViews count]-1; i >= 0; i--) { - id docView = [docViews objectAtIndex:i]; - if ([docView conformsToProtocol:@protocol(_WebDocumentTextSizing)] == NO) - continue; - - id <_WebDocumentTextSizing> sizingDocView = (id <_WebDocumentTextSizing>)docView; - if ([sizingDocView _tracksCommonSizeFactor]) - [sizingDocView _textSizeMultiplierChanged]; - } - -} - @end @implementation WebView (WebViewInternal) @@ -4065,104 +4681,87 @@ static WebFrameView *containingFrameView(NSView *view) [self _didChangeValueForKey:_WebMainFrameIconKey]; } -- (NSString *)_userVisibleBundleVersionFromFullVersion:(NSString *)fullVersion -{ - // If the version is 4 digits long or longer, then the first digit represents - // the version of the OS. Our user agent string should not include this first digit, - // so strip it off and report the rest as the version. <rdar://problem/4997547> - NSRange nonDigitRange = [fullVersion rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]; - if (nonDigitRange.location == NSNotFound && [fullVersion length] >= 4) - return [fullVersion substringFromIndex:1]; - if (nonDigitRange.location != NSNotFound && nonDigitRange.location >= 4) - return [fullVersion substringFromIndex:1]; - return fullVersion; -} - -static inline int callGestalt(OSType selector) -{ - SInt32 value = 0; - Gestalt(selector, &value); - return value; -} - -// Uses underscores instead of dots because if "4." ever appears in a user agent string, old DHTML libraries treat it as Netscape 4. -static NSString *createMacOSXVersionString() -{ - // Can't use -[NSProcessInfo operatingSystemVersionString] because it has too much stuff we don't want. - int major = callGestalt(gestaltSystemVersionMajor); - ASSERT(major); - - int minor = callGestalt(gestaltSystemVersionMinor); - int bugFix = callGestalt(gestaltSystemVersionBugFix); - if (bugFix) - return [[NSString alloc] initWithFormat:@"%d_%d_%d", major, minor, bugFix]; - if (minor) - return [[NSString alloc] initWithFormat:@"%d_%d", major, minor]; - return [[NSString alloc] initWithFormat:@"%d", major]; -} - -- (NSString *)_userAgentWithApplicationName:(NSString *)applicationName andWebKitVersion:(NSString *)version -{ - static NSString *osVersion = createMacOSXVersionString(); - NSString *language = [NSUserDefaults _webkit_preferredLanguageCode]; - if ([applicationName length]) - return [NSString stringWithFormat:@"Mozilla/5.0 (Macintosh; U; " PROCESSOR " Mac OS X %@; %@) AppleWebKit/%@ (KHTML, like Gecko) %@", - osVersion, language, version, applicationName]; - return [NSString stringWithFormat:@"Mozilla/5.0 (Macintosh; U; " PROCESSOR " Mac OS X %@; %@) AppleWebKit/%@ (KHTML, like Gecko)", - osVersion, language, version]; -} - // Get the appropriate user-agent string for a particular URL. - (WebCore::String)_userAgentForURL:(const WebCore::KURL&)url { if (_private->useSiteSpecificSpoofing) { // No current site-specific spoofs. } - - if (_private->userAgent->isNull()) { - NSString *sourceVersion = [[NSBundle bundleForClass:[WebView class]] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey]; - sourceVersion = [self _userVisibleBundleVersionFromFullVersion:sourceVersion]; - *_private->userAgent = [self _userAgentWithApplicationName:_private->applicationNameForUserAgent andWebKitVersion:sourceVersion]; - } - return *_private->userAgent; + if (_private->userAgent.isNull()) + _private->userAgent = [[self class] _standardUserAgentWithApplicationName:_private->applicationNameForUserAgent]; + + return _private->userAgent; } - (void)_addObject:(id)object forIdentifier:(unsigned long)identifier { - ASSERT(!_private->identifierMap->contains(identifier)); + ASSERT(!_private->identifierMap.contains(identifier)); // If the identifier map is initially empty it means we're starting a load // of something. The semantic is that the web view should be around as long // as something is loading. Because of that we retain the web view. - if (_private->identifierMap->isEmpty()) + if (_private->identifierMap.isEmpty()) CFRetain(self); - _private->identifierMap->set(identifier, object); + _private->identifierMap.set(identifier, object); } - (id)_objectForIdentifier:(unsigned long)identifier { - return _private->identifierMap->get(identifier).get(); + return _private->identifierMap.get(identifier).get(); } - (void)_removeObjectForIdentifier:(unsigned long)identifier { - HashMap<unsigned long, RetainPtr<id> >::iterator it = _private->identifierMap->find(identifier); - - // FIXME: This is currently needed because of a bug that causes didFail to be sent twice - // sometimes, see <rdar://problem/5009627> for more information. - if (it == _private->identifierMap->end()) - return; - - _private->identifierMap->remove(it); + ASSERT(_private->identifierMap.contains(identifier)); + _private->identifierMap.remove(identifier); // If the identifier map is now empty it means we're no longer loading anything // and we should release the web view. - if (_private->identifierMap->isEmpty()) + if (_private->identifierMap.isEmpty()) CFRelease(self); } +- (void)_retrieveKeyboardUIModeFromPreferences:(NSNotification *)notification +{ + CFPreferencesAppSynchronize(UniversalAccessDomain); + + Boolean keyExistsAndHasValidFormat; + int mode = CFPreferencesGetAppIntegerValue(AppleKeyboardUIMode, UniversalAccessDomain, &keyExistsAndHasValidFormat); + + // The keyboard access mode is reported by two bits: + // Bit 0 is set if feature is on + // Bit 1 is set if full keyboard access works for any control, not just text boxes and lists + // We require both bits to be on. + // I do not know that we would ever get one bit on and the other off since + // checking the checkbox in system preferences which is marked as "Turn on full keyboard access" + // turns on both bits. + _private->_keyboardUIMode = (mode & 0x2) ? KeyboardAccessFull : KeyboardAccessDefault; + + // check for tabbing to links + if ([_private->preferences tabsToLinks]) + _private->_keyboardUIMode = (KeyboardUIMode)(_private->_keyboardUIMode | KeyboardAccessTabsToLinks); +} + +- (KeyboardUIMode)_keyboardUIMode +{ + if (!_private->_keyboardUIModeAccessed) { + _private->_keyboardUIModeAccessed = YES; + + [self _retrieveKeyboardUIModeFromPreferences:nil]; + + [[NSDistributedNotificationCenter defaultCenter] + addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:) + name:KeyboardUIModeDidChangeNotification object:nil]; + + [[NSNotificationCenter defaultCenter] + addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:) + name:WebPreferencesChangedNotification object:nil]; + } + return _private->_keyboardUIMode; +} + @end // We use these functions to call the delegates and block exceptions. These functions are @@ -4171,9 +4770,11 @@ static NSString *createMacOSXVersionString() @implementation WebView (WebCallDelegateFunctions) -#if !(defined(__i386__) || defined(__x86_64__)) -typedef double (*ObjCMsgSendFPRet)(id, SEL, ...); -static const ObjCMsgSendFPRet objc_msgSend_fpret = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend); +typedef float (*ObjCMsgSendFPRet)(id, SEL, ...); +#if defined(__i386__) +static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend_fpret); +#else +static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend); #endif static inline id CallDelegate(WebView *self, id delegate, SEL selector) @@ -4279,9 +4880,9 @@ static inline float CallDelegateReturningFloat(WebView *self, id delegate, SEL s if (!delegate || ![delegate respondsToSelector:selector]) return 0.0f; if (!self->_private->catchesDelegateExceptions) - return static_cast<float>(objc_msgSend_fpret(delegate, selector, self)); + return objc_msgSend_float_return(delegate, selector, self); @try { - return static_cast<float>(objc_msgSend_fpret(delegate, selector, self)); + return objc_msgSend_float_return(delegate, selector, self); } @catch(id exception) { ReportDiscardedDelegateException(selector, exception); } diff --git a/WebKit/mac/WebView/WebViewInternal.h b/WebKit/mac/WebView/WebViewInternal.h index b6addad..39b3ef5 100644 --- a/WebKit/mac/WebView/WebViewInternal.h +++ b/WebKit/mac/WebView/WebViewInternal.h @@ -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 @@ -26,13 +26,17 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// This header contains WebView declarations that can be used anywhere in the Web Kit, but are neither SPI nor API. +// This header contains WebView declarations that can be used anywhere in WebKit, but are neither SPI nor API. #import "WebPreferences.h" #import "WebViewPrivate.h" #import "WebTypesInternal.h" #ifdef __cplusplus +#import <WebCore/WebCoreKeyboardUIMode.h> +#endif + +#ifdef __cplusplus namespace WebCore { class KeyboardEvent; class KURL; @@ -48,6 +52,7 @@ typedef WebCore::Page WebCorePage; @class WebBasePluginPackage; @class WebDownload; +@class WebNodeHighlight; @interface WebView (WebViewEditingExtras) - (BOOL)_interceptEditingKeyEvent:(WebCoreKeyboardEvent *)event shouldSaveCommand:(BOOL)shouldSave; @@ -63,6 +68,7 @@ typedef WebCore::Page WebCorePage; @interface WebView (WebViewInternal) #ifdef __cplusplus - (WebCore::String)_userAgentForURL:(const WebCore::KURL&)url; +- (WebCore::KeyboardUIMode)_keyboardUIMode; #endif @end @@ -108,6 +114,13 @@ typedef WebCore::Page WebCorePage; - (WebBasePluginPackage *)_pluginForExtension:(NSString *)extension; - (BOOL)_isMIMETypeRegisteredAsPlugin:(NSString *)MIMEType; +- (void)setCurrentNodeHighlight:(WebNodeHighlight *)nodeHighlight; +- (WebNodeHighlight *)currentNodeHighlight; + +- (void)addPluginInstanceView:(NSView *)view; +- (void)removePluginInstanceView:(NSView *)view; +- (void)removePluginInstanceViewsFor:(WebFrame*)webFrame; + - (void)_addObject:(id)object forIdentifier:(unsigned long)identifier; - (id)_objectForIdentifier:(unsigned long)identifier; - (void)_removeObjectForIdentifier:(unsigned long)identifier; @@ -116,6 +129,22 @@ typedef WebCore::Page WebCorePage; - (void)_registerForIconNotification:(BOOL)listen; - (void)_dispatchDidReceiveIconFromWebFrame:(WebFrame *)webFrame; +- (void)_setZoomMultiplier:(float)m isTextOnly:(BOOL)isTextOnly; +- (float)_zoomMultiplier:(BOOL)isTextOnly; +- (float)_realZoomMultiplier; +- (BOOL)_realZoomMultiplierIsTextOnly; +- (BOOL)_canZoomOut:(BOOL)isTextOnly; +- (BOOL)_canZoomIn:(BOOL)isTextOnly; +- (IBAction)_zoomOut:(id)sender isTextOnly:(BOOL)isTextOnly; +- (IBAction)_zoomIn:(id)sender isTextOnly:(BOOL)isTextOnly; +- (BOOL)_canResetZoom:(BOOL)isTextOnly; +- (IBAction)_resetZoom:(id)sender isTextOnly:(BOOL)isTextOnly; + +- (BOOL)_mustDrawUnionedRect:(NSRect)rect singleRects:(const NSRect *)rects count:(NSInteger)count; +- (void)_updateFocusedAndActiveStateForFrame:(WebFrame *)webFrame; + ++ (BOOL)_canHandleRequest:(NSURLRequest *)request forMainFrame:(BOOL)forMainFrame; + @end typedef struct _WebResourceDelegateImplementationCache { diff --git a/WebKit/mac/WebView/WebViewPrivate.h b/WebKit/mac/WebView/WebViewPrivate.h index 9c95ab0..3a33bf9 100644 --- a/WebKit/mac/WebView/WebViewPrivate.h +++ b/WebKit/mac/WebView/WebViewPrivate.h @@ -29,6 +29,10 @@ #import <WebKit/WebView.h> #import <WebKit/WebFramePrivate.h> +#if !defined(ENABLE_DASHBOARD_SUPPORT) +#define ENABLE_DASHBOARD_SUPPORT 1 +#endif + #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 #define WebNSInteger int #define WebNSUInteger unsigned int @@ -41,6 +45,7 @@ @class WebFrame; @class WebInspector; @class WebPreferences; +@class WebTextIterator; @protocol WebFormDelegate; @@ -61,6 +66,7 @@ extern NSString *WebElementIsContentEditableKey; // NSNumber indicating whether // other WebElementDictionary keys extern NSString *WebElementLinkIsLiveKey; // NSNumber of BOOL indictating whether the link is live or not +#if ENABLE_DASHBOARD_SUPPORT typedef enum { WebDashboardBehaviorAlwaysSendMouseEventsToAllWindows, WebDashboardBehaviorAlwaysSendActiveNullEventsToPlugIns, @@ -68,6 +74,7 @@ typedef enum { WebDashboardBehaviorAllowWheelScrolling, WebDashboardBehaviorUseBackwardCompatibilityMode } WebDashboardBehavior; +#endif @interface WebController : NSTreeController { IBOutlet WebView *webView; @@ -84,6 +91,9 @@ typedef enum { @interface WebView (WebPendingPublic) +- (void)scheduleInRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode; +- (void)unscheduleFromRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode; + /*! @method searchFor:direction:caseSensitive:wrap:startInSelection: @abstract Searches a document view for a string and highlights the string if it is found. @@ -146,12 +156,31 @@ typedef enum { - (BOOL)allowsUndo; - (void)setAllowsUndo:(BOOL)flag; +/*! + @method setPageSizeMultiplier: + @abstract Change the zoom factor of the page in views managed by this webView. + @param multiplier A fractional percentage value, 1.0 is 100%. +*/ +- (void)setPageSizeMultiplier:(float)multiplier; + +/*! + @method pageSizeMultiplier + @result The page size multipler. +*/ +- (float)pageSizeMultiplier; + +// Commands for doing page zoom. Will end up in WebView (WebIBActions) <NSUserInterfaceValidations> +- (BOOL)canZoomPageIn; +- (IBAction)zoomPageIn:(id)sender; +- (BOOL)canZoomPageOut; +- (IBAction)zoomPageOut:(id)sender; +- (BOOL)canResetPageZoom; +- (IBAction)resetPageZoom:(id)sender; + @end @interface WebView (WebPrivate) -+ (BOOL)_scriptDebuggerEnabled; - - (WebInspector *)inspector; /*! @@ -196,11 +225,16 @@ Could be worth adding to the API. */ + (NSString *)suggestedFileExtensionForMIMEType: (NSString *)MIMEType; ++ (NSString *)_standardUserAgentWithApplicationName:(NSString *)applicationName; + // May well become public - (void)_setFormDelegate:(id<WebFormDelegate>)delegate; - (id<WebFormDelegate>)_formDelegate; - (BOOL)_isClosed; + +// _close is now replaced by public method -close. It remains here only for backward compatibility +// until callers can be weaned off of it. - (void)_close; /*! @@ -232,15 +266,19 @@ Could be worth adding to the API. + (NSString *)_decodeData:(NSData *)data; ++ (void)_setAlwaysUsesComplexTextCodePath:(BOOL)f; +// This is the old name of the above method. Needed for Safari versions that call it. + (void)_setAlwaysUseATSU:(BOOL)f; - (NSCachedURLResponse *)_cachedResponseForURL:(NSURL *)URL; +#if ENABLE_DASHBOARD_SUPPORT - (void)_addScrollerDashboardRegions:(NSMutableDictionary *)regions; - (NSDictionary *)_dashboardRegions; - (void)_setDashboardBehavior:(WebDashboardBehavior)behavior to:(BOOL)flag; - (BOOL)_dashboardBehavior:(WebDashboardBehavior)behavior; +#endif + (void)_setShouldUseFontSmoothing:(BOOL)f; + (BOOL)_shouldUseFontSmoothing; @@ -324,9 +362,18 @@ Could be worth adding to the API. - (BOOL)usesPageCache; - (void)setUsesPageCache:(BOOL)usesPageCache; +/*! + @method textIteratorForRect: + @param rectangle from which we want the WebTextIterator to load text from + @result a WebtextIterator object. + */ +- (WebTextIterator *)textIteratorForRect:(NSRect)rect; + +#if ENABLE_DASHBOARD_SUPPORT // <rdar://problem/5217124> Clients other than dashboard, don't use this. // Do not remove until Dashboard has moved off it - (void)handleAuthenticationForResource:(id)identifier challenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource; +#endif - (void)_clearUndoRedoOperations; @@ -334,8 +381,18 @@ Could be worth adding to the API. - (BOOL)_inFastImageScalingMode; - (void)_setUseFastImageScalingMode:(BOOL)flag; +- (BOOL)_cookieEnabled; +- (void)_setCookieEnabled:(BOOL)enable; + // SPI for DumpRenderTree - (void)_executeCoreCommandByName:(NSString *)name value:(NSString *)value; +- (void)_clearMainFrameName; + +- (void)_setCustomHTMLTokenizerTimeDelay:(double)timeDelay; +- (void)_setCustomHTMLTokenizerChunkSize:(int)chunkSize; + +- (id)_initWithFrame:(NSRect)f frameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews; +- (BOOL)_usesDocumentViews; @end |