/*
* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2006 David Smith (catfish.man@gmail.com)
+ * Copyright (C) 2010 Igalia S.L
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#import "DOMCSSStyleDeclarationInternal.h"
#import "DOMNodeInternal.h"
#import "DOMRangeInternal.h"
+#import "WebApplicationCache.h"
#import "WebBackForwardListInternal.h"
#import "WebBaseNetscapePluginView.h"
#import "WebCache.h"
#import "WebDefaultPolicyDelegate.h"
#import "WebDefaultUIDelegate.h"
#import "WebDelegateImplementationCaching.h"
+#import "WebDeviceOrientationClient.h"
+#import "WebDeviceOrientationProvider.h"
#import "WebDocument.h"
#import "WebDocumentInternal.h"
#import "WebDownload.h"
#import "WebPDFView.h"
#import "WebPanelAuthenticationHandler.h"
#import "WebPasteboardHelper.h"
+#import "WebPlatformStrategies.h"
#import "WebPluginDatabase.h"
#import "WebPluginHalterClient.h"
#import "WebPolicyDelegate.h"
#import <Foundation/NSURLConnection.h>
#import <JavaScriptCore/APICast.h>
#import <JavaScriptCore/JSValueRef.h>
+#import <WebCore/AbstractDatabase.h>
#import <WebCore/ApplicationCacheStorage.h>
-#import <WebCore/BackForwardList.h>
+#import <WebCore/BackForwardListImpl.h>
#import <WebCore/Cache.h>
#import <WebCore/ColorMac.h>
#import <WebCore/CSSComputedStyleDeclaration.h>
#import <WebCore/Cursor.h>
-#import <WebCore/Database.h>
#import <WebCore/Document.h>
#import <WebCore/DocumentLoader.h>
#import <WebCore/DragController.h>
#import <WebCore/HistoryItem.h>
#import <WebCore/IconDatabase.h>
#import <WebCore/JSCSSStyleDeclaration.h>
+#import <WebCore/JSDocument.h>
#import <WebCore/JSElement.h>
+#import <WebCore/JSNodeList.h>
#import <WebCore/Logging.h>
#import <WebCore/MIMETypeRegistry.h>
+#import <WebCore/NodeList.h>
#import <WebCore/Page.h>
#import <WebCore/PageCache.h>
#import <WebCore/PageGroup.h>
#import <WebCore/PlatformMouseEvent.h>
#import <WebCore/ProgressTracker.h>
+#import <WebCore/RenderView.h>
#import <WebCore/RenderWidget.h>
#import <WebCore/ResourceHandle.h>
#import <WebCore/RuntimeApplicationChecks.h>
+#import <WebCore/SchemeRegistry.h>
#import <WebCore/ScriptController.h>
#import <WebCore/ScriptValue.h>
#import <WebCore/SecurityOrigin.h>
#import <wtf/StdLibExtras.h>
#import <wtf/Threading.h>
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+#import <AppKit/NSTextChecker.h>
+#endif
+
#if ENABLE(DASHBOARD_SUPPORT)
#import <WebKit/WebDashboardRegion.h>
#endif
#import <WebCore/GeolocationError.h>
#endif
+#if ENABLE(GLIB_SUPPORT)
+#import <glib.h>
+#endif
+
@interface NSSpellChecker (WebNSSpellCheckerDetails)
- (void)_preflightChosenSpellServer;
@end
@interface NSWindow (WebNSWindowDetails)
- (id)_oldFirstResponderBeforeBecoming;
- (void)_enableScreenUpdatesIfNeeded;
+- (BOOL)_wrapsCarbonWindow;
@end
using namespace WebCore;
#if USE(ACCELERATED_COMPOSITING)
- (void)_clearLayerSyncLoopObserver;
#endif
+#if ENABLE(GLIB_SUPPORT)
+- (void)_clearGlibLoopObserver;
+#endif
@end
static void patchMailRemoveAttributesMethod();
NSString *WebElementLinkTargetFrameKey = @"WebElementTargetFrame";
NSString *WebElementLinkTitleKey = @"WebElementLinkTitle";
NSString *WebElementLinkURLKey = @"WebElementLinkURL";
+NSString *WebElementMediaURLKey = @"WebElementMediaURL";
NSString *WebElementSpellingToolTipKey = @"WebElementSpellingToolTip";
NSString *WebElementTitleKey = @"WebElementTitle";
NSString *WebElementLinkIsLiveKey = @"WebElementLinkIsLive";
return [NSString stringWithFormat:@"Mozilla/5.0 (Macintosh; U; " PROCESSOR " Mac OS X %@; %@) AppleWebKit/%@ (KHTML, like Gecko)", osVersion, language, webKitVersion];
}
++ (void)_reportException:(JSValueRef)exception inContext:(JSContextRef)context
+{
+ if (!exception || !context)
+ return;
+
+ JSLock lock(SilenceAssertionsOnly);
+ JSC::ExecState* execState = toJS(context);
+
+ // Make sure the context has a DOMWindow global object, otherwise this context didn't originate from a WebView.
+ if (!toJSDOMWindow(execState->lexicalGlobalObject()))
+ return;
+
+ reportException(execState, toJS(execState, exception));
+}
+
static void WebKitInitializeApplicationCachePathIfNecessary()
{
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
return _private->usesDocumentViews;
}
+static NSString *leakMailQuirksUserScriptPath()
+{
+ NSString *scriptPath = [[NSBundle bundleForClass:[WebView class]] pathForResource:@"MailQuirksUserScript" ofType:@"js"];
+ return [[NSString alloc] initWithContentsOfFile:scriptPath];
+}
+
+- (void)_injectMailQuirksScript
+{
+ static NSString *mailQuirksScriptPath = leakMailQuirksUserScriptPath();
+ core(self)->group().addUserScriptToWorld(core([WebScriptWorld world]),
+ mailQuirksScriptPath, KURL(), 0, 0, InjectAtDocumentEnd, InjectInAllFrames);
+}
+
- (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews
{
WebCoreThreadViolationCheckRoundTwo();
#endif
WebKitInitializeApplicationCachePathIfNecessary();
patchMailRemoveAttributesMethod();
+
+ // Initialize our platform strategies.
+ WebPlatformStrategies::initialize();
+ Settings::setMinDOMTimerInterval(0.004);
+
didOneTimeInitialization = true;
}
+ Page::PageClients pageClients;
+ pageClients.chromeClient = new WebChromeClient(self);
+ pageClients.contextMenuClient = new WebContextMenuClient(self);
+ pageClients.editorClient = new WebEditorClient(self);
+ pageClients.dragClient = new WebDragClient(self);
+ pageClients.inspectorClient = new WebInspectorClient(self);
+ pageClients.pluginHalterClient = new WebPluginHalterClient(self);
#if ENABLE(CLIENT_BASED_GEOLOCATION)
- WebGeolocationControllerClient* geolocationControllerClient = new WebGeolocationControllerClient(self);
-#else
- WebGeolocationControllerClient* geolocationControllerClient = 0;
+ pageClients.geolocationControllerClient = new WebGeolocationControllerClient(self);
#endif
- _private->page = new Page(new WebChromeClient(self), new WebContextMenuClient(self), new WebEditorClient(self), new WebDragClient(self), new WebInspectorClient(self), new WebPluginHalterClient(self), geolocationControllerClient);
+#if ENABLE(DEVICE_ORIENTATION)
+ pageClients.deviceOrientationClient = new WebDeviceOrientationClient(self);
+#endif
+ _private->page = new Page(pageClients);
_private->page->setCanStartMedia([self window]);
_private->page->settings()->setLocalStorageDatabasePath([[self preferences] _localStorageDatabasePath]);
if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_CONTENT_SNIFFING_FOR_FILE_URLS))
ResourceHandle::forceContentSniffing();
+
+#if ENABLE(GLIB_SUPPORT)
+ [self _scheduleGlibContextIterations];
+#endif
+
+ if (runningTigerMail() || runningLeopardMail())
+ [self _injectMailQuirksScript];
}
- (id)_initWithFrame:(NSRect)f frameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews
{
Frame* frame = [self _mainCoreFrame];
if (frame && frame->view())
- frame->view()->layoutIfNeededRecursive();
+ frame->view()->updateLayoutAndStyleIfNeededRecursive();
}
#endif
// Deleteing the WebCore::Page will clear the page cache so we call destroy on
// all the plug-ins in the page cache to break any retain cycles.
// See comment in HistoryItem::releaseAllPendingPageCaches() for more information.
- delete _private->page;
+ Page* page = _private->page;
_private->page = 0;
+ delete page;
if (_private->hasSpellCheckerDocumentTag) {
[[NSSpellChecker sharedSpellChecker] closeSpellDocumentWithTag:_private->spellCheckerDocumentTag];
[self _clearLayerSyncLoopObserver];
#endif
+#if ENABLE(GLIB_SUPPORT)
+ [self _clearGlibLoopObserver];
+#endif
+
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:self];
return needsQuirk;
}
+
+- (BOOL)_needsPreHTML5ParserQuirks
+{
+ // AOL Instant Messenger and Microsoft My Day contain markup incompatible
+ // with the new HTML5 parser. If these applications were linked against a
+ // version of WebKit prior to the introduction of the HTML5 parser, enable
+ // parser quirks to maintain compatibility. For details, see
+ // <https://bugs.webkit.org/show_bug.cgi?id=46134> and
+ // <https://bugs.webkit.org/show_bug.cgi?id=46334>.
+ static bool isApplicationNeedingParserQuirks = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_HTML5_PARSER)
+ && (applicationIsAOLInstantMessenger() || applicationIsMicrosoftMyDay());
+
+ return isApplicationNeedingParserQuirks
+#if ENABLE(DASHBOARD_SUPPORT)
+ // Pre-HTML5 parser quirks are required to remain compatible with many
+ // Dashboard widgets. See <rdar://problem/8175982>.
+ || (_private->page && _private->page->settings()->usesDashboardBackwardCompatibilityMode())
+#endif
+ || [[self preferences] usePreHTML5ParserQuirks];
+}
+
+- (BOOL)_needsUnrestrictedGetMatchedCSSRules
+{
+ static bool needsUnrestrictedGetMatchedCSSRules = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_GET_MATCHED_CSS_RULES_RESTRICTIONS) && applicationIsSafari();
+ return needsUnrestrictedGetMatchedCSSRules;
+}
+
- (void)_preferencesChangedNotification:(NSNotification *)notification
{
WebPreferences *preferences = (WebPreferences *)[notification object];
settings->setMinimumLogicalFontSize([preferences minimumLogicalFontSize]);
settings->setPluginsEnabled([preferences arePlugInsEnabled]);
#if ENABLE(DATABASE)
- Database::setIsAvailable([preferences databasesEnabled]);
+ AbstractDatabase::setIsAvailable([preferences databasesEnabled]);
#endif
settings->setLocalStorageEnabled([preferences localStorageEnabled]);
settings->setExperimentalNotificationsEnabled([preferences experimentalNotificationsEnabled]);
settings->setTextAreasAreResizable([preferences textAreasAreResizable]);
settings->setShrinksStandaloneImagesToFit([preferences shrinksStandaloneImagesToFit]);
settings->setEditableLinkBehavior(core([preferences editableLinkBehavior]));
+ settings->setEditingBehaviorType(core([preferences editingBehavior]));
settings->setTextDirectionSubmenuInclusionBehavior(core([preferences textDirectionSubmenuInclusionBehavior]));
settings->setDOMPasteAllowed([preferences isDOMPasteAllowed]);
settings->setUsesPageCache([self usesPageCache]);
settings->setWebArchiveDebugModeEnabled([preferences webArchiveDebugModeEnabled]);
settings->setLocalFileContentSniffingEnabled([preferences localFileContentSniffingEnabled]);
settings->setOfflineWebApplicationCacheEnabled([preferences offlineWebApplicationCacheEnabled]);
- settings->setZoomMode([preferences zoomsTextOnly] ? ZoomTextOnly : ZoomPage);
settings->setJavaScriptCanAccessClipboard([preferences javaScriptCanAccessClipboard]);
settings->setXSSAuditorEnabled([preferences isXSSAuditorEnabled]);
- settings->setEnforceCSSMIMETypeInStrictMode(!WKAppVersionCheckLessThan(@"com.apple.iWeb", -1, 2.1));
+ settings->setEnforceCSSMIMETypeInNoQuirksMode(!WKAppVersionCheckLessThan(@"com.apple.iWeb", -1, 2.1));
+ settings->setDNSPrefetchingEnabled([preferences isDNSPrefetchingEnabled]);
// FIXME: Enabling accelerated compositing when WebGL is enabled causes tests to fail on Leopard which expect HW compositing to be disabled.
// Until we fix that, I will comment out the test (CFM)
- settings->setAcceleratedCompositingEnabled((coreVideoHas7228836Fix() || [preferences webGLEnabled]) && [preferences acceleratedCompositingEnabled]);
+ settings->setAcceleratedCompositingEnabled((coreVideoHas7228836Fix() || [preferences webGLEnabled] ||
+ [preferences accelerated2dCanvasEnabled]) && [preferences acceleratedCompositingEnabled]);
settings->setShowDebugBorders([preferences showDebugBorders]);
settings->setShowRepaintCounter([preferences showRepaintCounter]);
settings->setPluginAllowedRunTime([preferences pluginAllowedRunTime]);
settings->setWebGLEnabled([preferences webGLEnabled]);
+ settings->setAccelerated2dCanvasEnabled([preferences accelerated2dCanvasEnabled]);
settings->setLoadDeferringEnabled(shouldEnableLoadDeferring());
settings->setFrameFlatteningEnabled([preferences isFrameFlatteningEnabled]);
+ settings->setSpatialNavigationEnabled([preferences isSpatialNavigationEnabled]);
+ settings->setPaginateDuringLayoutEnabled([preferences paginateDuringLayoutEnabled]);
+#if ENABLE(FULLSCREEN_API)
+ settings->setFullScreenEnabled([preferences fullScreenEnabled]);
+#endif
+ settings->setMemoryInfoEnabled([preferences memoryInfoEnabled]);
+ settings->setHyperlinkAuditingEnabled([preferences hyperlinkAuditingEnabled]);
+ settings->setUsePreHTML5ParserQuirks([self _needsPreHTML5ParserQuirks]);
+ settings->setCrossOriginCheckInGetMatchedCSSRulesDisabled([self _needsUnrestrictedGetMatchedCSSRules]);
+
+ // Application Cache Preferences are stored on the global cache storage manager, not in Settings.
+ [WebApplicationCache setDefaultOriginQuota:[preferences applicationCacheDefaultOriginQuota]];
+
+ BOOL zoomsTextOnly = [preferences zoomsTextOnly];
+ if (_private->zoomsTextOnly != zoomsTextOnly)
+ [self _setZoomMultiplier:_private->zoomMultiplier isTextOnly:zoomsTextOnly];
}
static inline IMP getMethod(id o, SEL s)
Frame* mainFrame = [self _mainCoreFrame];
if (!mainFrame)
return nil;
- NSMutableDictionary *regions = mainFrame->dashboardRegionsDictionary();
- [self _addScrollerDashboardRegions:regions];
- return regions;
+
+ const Vector<DashboardRegionValue>& regions = mainFrame->document()->dashboardRegions();
+ size_t size = regions.size();
+
+ NSMutableDictionary *webRegions = [NSMutableDictionary dictionaryWithCapacity:size];
+ for (size_t i = 0; i < size; i++) {
+ const DashboardRegionValue& region = regions[i];
+
+ if (region.type == StyleDashboardRegion::None)
+ continue;
+
+ NSString *label = region.label;
+ WebDashboardRegionType type = WebDashboardRegionTypeNone;
+ if (region.type == StyleDashboardRegion::Circle)
+ type = WebDashboardRegionTypeCircle;
+ else if (region.type == StyleDashboardRegion::Rectangle)
+ type = WebDashboardRegionTypeRectangle;
+ NSMutableArray *regionValues = [webRegions objectForKey:label];
+ if (!regionValues) {
+ regionValues = [[NSMutableArray alloc] initWithCapacity:1];
+ [webRegions setObject:regionValues forKey:label];
+ [regionValues release];
+ }
+
+ WebDashboardRegion *webRegion = [[WebDashboardRegion alloc] initWithRect:region.bounds clip:region.clip type:type];
+ [regionValues addObject:webRegion];
+ [webRegion release];
+ }
+
+ [self _addScrollerDashboardRegions:webRegions];
+
+ return webRegions;
}
- (void)_setDashboardBehavior:(WebDashboardBehavior)behavior to:(BOOL)flag
break;
}
}
+
+ // Pre-HTML5 parser quirks should be enabled if Dashboard is in backward
+ // compatibility mode. See <rdar://problem/8175982>.
+ if (_private->page)
+ _private->page->settings()->setUsePreHTML5ParserQuirks([self _needsPreHTML5ParserQuirks]);
}
- (BOOL)_dashboardBehavior:(WebDashboardBehavior)behavior
+ (NSCursor *)_pointingHandCursor
{
- return handCursor().impl();
+ return handCursor().platformCursor();
}
- (BOOL)_postsAcceleratedCompositingNotifications
return _private->includesFlattenedCompositingLayersWhenDrawingToBitmap;
}
+#if ENABLE(NETSCAPE_PLUGIN_API)
static WebBaseNetscapePluginView *_pluginViewForNode(DOMNode *node)
{
if (!node)
return (WebBaseNetscapePluginView *)view;
}
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+ (BOOL)_isNodeHaltedPlugin:(DOMNode *)node
{
+#if ENABLE(NETSCAPE_PLUGIN_API)
return [_pluginViewForNode(node) isHalted];
+#else
+ return YES;
+#endif
}
+ (BOOL)_hasPluginForNodeBeenHalted:(DOMNode *)node
{
+#if ENABLE(NETSCAPE_PLUGIN_API)
return [_pluginViewForNode(node) hasBeenHalted];
+#else
+ return YES;
+#endif
}
+ (void)_restartHaltedPluginForNode:(DOMNode *)node
{
+#if ENABLE(NETSCAPE_PLUGIN_API)
if (!node)
return;
[_pluginViewForNode(node) resumeFromHalt];
+#endif
}
- (NSPasteboard *)_insertionPasteboard
}
+ (void)_addUserScriptToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url
- whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist injectionTime:(WebUserScriptInjectionTime)injectionTime
+ whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist
+ injectionTime:(WebUserScriptInjectionTime)injectionTime
+{
+ [WebView _addUserScriptToGroup:groupName world:world source:source url:url whitelist:whitelist blacklist:blacklist injectionTime:injectionTime injectedFrames:WebInjectInAllFrames];
+}
+
++ (void)_addUserScriptToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url
+ whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist
+ injectionTime:(WebUserScriptInjectionTime)injectionTime
+ injectedFrames:(WebUserContentInjectedFrames)injectedFrames
{
String group(groupName);
if (group.isEmpty())
return;
pageGroup->addUserScriptToWorld(core(world), source, url, toStringVector(whitelist), toStringVector(blacklist),
- injectionTime == WebInjectAtDocumentStart ? InjectAtDocumentStart : InjectAtDocumentEnd);
+ injectionTime == WebInjectAtDocumentStart ? InjectAtDocumentStart : InjectAtDocumentEnd,
+ injectedFrames == WebInjectInAllFrames ? InjectInAllFrames : InjectInTopFrameOnly);
+}
+
++ (void)_addUserStyleSheetToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url
+ whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist
+{
+ [WebView _addUserStyleSheetToGroup:groupName world:world source:source url:url whitelist:whitelist blacklist:blacklist injectedFrames:WebInjectInAllFrames];
}
+ (void)_addUserStyleSheetToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url
whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist
+ injectedFrames:(WebUserContentInjectedFrames)injectedFrames
{
String group(groupName);
if (group.isEmpty())
if (!pageGroup)
return;
- pageGroup->addUserStyleSheetToWorld(core(world), source, url, toStringVector(whitelist), toStringVector(blacklist));
+ pageGroup->addUserStyleSheetToWorld(core(world), source, url, toStringVector(whitelist), toStringVector(blacklist), injectedFrames == WebInjectInAllFrames ? InjectInAllFrames : InjectInTopFrameOnly);
}
+ (void)_removeUserScriptFromGroup:(NSString *)groupName world:(WebScriptWorld *)world url:(NSURL *)url
+ (void)_registerURLSchemeAsSecure:(NSString *)scheme
{
- SecurityOrigin::registerURLSchemeAsSecure(scheme);
+ SchemeRegistry::registerURLSchemeAsSecure(scheme);
+}
+
+- (void)_scaleWebView:(float)scale
+{
+ Frame* coreFrame = [self _mainCoreFrame];
+ if (!coreFrame)
+ return;
+
+ coreFrame->scalePage(scale);
+}
+
+- (float)_viewScaleFactor
+{
+ Frame* coreFrame = [self _mainCoreFrame];
+ if (!coreFrame)
+ return 1;
+
+ return coreFrame->pageScaleFactor();
}
@end
automaticTextReplacementEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticTextReplacementEnabled];
automaticSpellingCorrectionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticSpellingCorrectionEnabled];
#endif
+
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+ if (![[NSUserDefaults standardUserDefaults] objectForKey:WebAutomaticTextReplacementEnabled])
+ automaticTextReplacementEnabled = [NSSpellChecker isAutomaticTextReplacementEnabled];
+ if (![[NSUserDefaults standardUserDefaults] objectForKey:WebAutomaticSpellingCorrectionEnabled])
+ automaticSpellingCorrectionEnabled = [NSSpellChecker isAutomaticSpellingCorrectionEnabled];
+#endif
}
+ (void)_applicationWillTerminate
return nil;
}
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+- (WebBasePluginPackage *)_videoProxyPluginForMIMEType:(NSString *)MIMEType
+{
+ WebBasePluginPackage *pluginPackage = [[WebPluginDatabase sharedDatabase] pluginForMIMEType:MIMEType];
+ if (pluginPackage)
+ return pluginPackage;
+
+ if (_private->pluginDatabase)
+ return [_private->pluginDatabase pluginForMIMEType:MIMEType];
+
+ return nil;
+}
+#endif
+
- (WebBasePluginPackage *)_pluginForExtension:(NSString *)extension
{
if (![_private->preferences arePlugInsEnabled])
+ (void)registerURLSchemeAsLocal:(NSString *)protocol
{
- SecurityOrigin::registerURLSchemeAsLocal(protocol);
+ SchemeRegistry::registerURLSchemeAsLocal(protocol);
}
- (id)_initWithArguments:(NSDictionary *) arguments
LOG(Encoding, "FrameName = %@, GroupName = %@, useBackForwardList = %d\n", frameName, groupName, (int)useBackForwardList);
[result _commonInitializationWithFrameName:frameName groupName:groupName usesDocumentViews:YES];
- [result page]->backForwardList()->setEnabled(useBackForwardList);
+ static_cast<BackForwardListImpl*>([result page]->backForwardList())->setEnabled(useBackForwardList);
result->_private->allowsUndo = allowsUndo;
if (preferences)
[result setPreferences:preferences];
// Restore the subviews we set aside.
_subviews = originalSubviews;
- BOOL useBackForwardList = _private->page && _private->page->backForwardList()->enabled();
+ BOOL useBackForwardList = _private->page && static_cast<BackForwardListImpl*>(_private->page->backForwardList())->enabled();
if ([encoder allowsKeyedCoding]) {
[encoder encodeObject:[[self mainFrame] name] forKey:@"FrameName"];
[encoder encodeObject:[self groupName] forKey:@"GroupName"];
_private->UIDelegateForwarder = nil;
}
-- UIDelegate
+- (id)UIDelegate
{
return _private->UIDelegate;
}
[self _cacheResourceLoadDelegateImplementations];
}
-- resourceLoadDelegate
+- (id)resourceLoadDelegate
{
return _private->resourceProgressDelegate;
}
}
-- downloadDelegate
+- (id)downloadDelegate
{
return _private->downloadDelegate;
}
_private->policyDelegateForwarder = nil;
}
-- policyDelegate
+- (id)policyDelegate
{
return _private->policyDelegate;
}
#endif
}
-- frameLoadDelegate
+- (id)frameLoadDelegate
{
return _private->frameLoadDelegate;
}
{
if (!_private->page)
return nil;
- if (!_private->page->backForwardList()->enabled())
+ BackForwardListImpl* list = static_cast<BackForwardListImpl*>(_private->page->backForwardList());
+ if (!list->enabled())
return nil;
- return kit(_private->page->backForwardList());
+ return kit(list);
}
- (void)setMaintainsBackForwardList:(BOOL)flag
{
if (!_private->page)
return;
- _private->page->backForwardList()->setEnabled(flag);
+ static_cast<BackForwardListImpl*>(_private->page->backForwardList())->setEnabled(flag);
}
- (BOOL)goBack
return [self _realZoomMultiplierIsTextOnly] ? _private->zoomMultiplier : 1.0f;
}
-- (void)_setZoomMultiplier:(float)m isTextOnly:(BOOL)isTextOnly
+- (void)_setZoomMultiplier:(float)multiplier isTextOnly:(BOOL)isTextOnly
{
// NOTE: This has no visible effect when viewing a PDF (see <rdar://problem/4737380>)
- _private->zoomMultiplier = m;
- ASSERT(_private->page);
- if (_private->page)
- _private->page->settings()->setZoomMode(isTextOnly ? ZoomTextOnly : ZoomPage);
-
- // FIXME: it would be nice to rework this code so that _private->zoomMultiplier doesn't exist and callers
- // all access _private->page->settings().
+ _private->zoomMultiplier = multiplier;
+ _private->zoomsTextOnly = isTextOnly;
+
+ // FIXME: It might be nice to rework this code so that _private->zoomMultiplier doesn't exist
+ // and instead the zoom factors stored in Frame are used.
Frame* coreFrame = [self _mainCoreFrame];
- if (coreFrame)
- coreFrame->setZoomFactor(m, isTextOnly ? ZoomTextOnly : ZoomPage);
+ if (coreFrame) {
+ if (_private->zoomsTextOnly)
+ coreFrame->setPageAndTextZoomFactors(1, multiplier);
+ else
+ coreFrame->setPageAndTextZoomFactors(multiplier, 1);
+ }
}
- (float)_zoomMultiplier:(BOOL)isTextOnly
if (!_private->page)
return NO;
- return _private->page->settings()->zoomMode() == ZoomTextOnly;
+ return _private->zoomsTextOnly;
}
#define MinimumZoomMultiplier 0.5f
- (BOOL)canGoBack
{
- if (!_private->page)
+ if (!_private->page || _private->page->defersLoading())
return NO;
return !!_private->page->backForwardList()->backItem();
- (BOOL)canGoForward
{
- if (!_private->page)
+ if (!_private->page || _private->page->defersLoading())
return NO;
return !!_private->page->backForwardList()->forwardItem();
Frame* coreFrame = [self _mainCoreFrame];
if (!coreFrame)
return YES;
- return coreFrame->shouldClose();
+ return coreFrame->loader()->shouldClose();
}
static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue jsValue)
- (BOOL)canMarkAllTextMatches
{
+ if (_private->closed)
+ return NO;
+
WebFrame *frame = [self mainFrame];
do {
id <WebDocumentView> view = [[frame frameView] documentView];
- (NSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(NSUInteger)limit
{
+ if (_private->closed)
+ return 0;
+
+ return [self countMatchesForText:string caseSensitive:caseFlag highlight:highlight limit:limit markMatches:YES];
+}
+
+- (NSUInteger)countMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(NSUInteger)limit markMatches:(BOOL)markMatches
+{
+ if (_private->closed)
+ return 0;
+
WebFrame *frame = [self mainFrame];
unsigned matchCount = 0;
do {
id <WebDocumentView> view = [[frame frameView] documentView];
if ([view conformsToProtocol:@protocol(WebMultipleTextMatches)]) {
- [(NSView <WebMultipleTextMatches>*)view setMarkedTextMatchesAreHighlighted:highlight];
+ if (markMatches)
+ [(NSView <WebMultipleTextMatches>*)view setMarkedTextMatchesAreHighlighted:highlight];
ASSERT(limit == 0 || matchCount < limit);
- matchCount += [(NSView <WebMultipleTextMatches>*)view markAllMatchesForText:string caseSensitive:caseFlag limit:limit == 0 ? 0 : limit - matchCount];
+ matchCount += [(NSView <WebMultipleTextMatches>*)view countMatchesForText:string caseSensitive:caseFlag limit:limit == 0 ? 0 : limit - matchCount markMatches:markMatches];
// Stop looking if we've reached the limit. A limit of 0 means no limit.
if (limit > 0 && matchCount >= limit)
- (void)unmarkAllTextMatches
{
+ if (_private->closed)
+ return;
+
WebFrame *frame = [self mainFrame];
do {
id <WebDocumentView> view = [[frame frameView] documentView];
- (NSArray *)rectsForTextMatches
{
+ if (_private->closed)
+ return [NSArray array];
+
NSMutableArray *result = [NSMutableArray array];
WebFrame *frame = [self mainFrame];
do {
Frame* mainFrame = [self _mainCoreFrame];
if (mainFrame) {
if (flag) {
- mainFrame->applyEditingStyleToBodyElement();
+ mainFrame->editor()->applyEditingStyleToBodyElement();
// If the WebView is made editable and the selection is empty, set it to something.
if (![self selectedDOMRange])
- mainFrame->setSelectionFromNone();
- } else
- mainFrame->removeEditingStyleFromBodyElement();
+ mainFrame->selection()->setSelectionFromNone();
+ }
}
}
}
@implementation WebView (WebFileInternal)
+static inline uint64_t roundUpToPowerOf2(uint64_t num)
+{
+ return powf(2.0, ceilf(log2f(num)));
+}
+
+ (void)_setCacheModel:(WebCacheModel)cacheModel
{
if (s_didSetCacheModel && cacheModel == s_cacheModel)
if (!nsurlCacheDirectory)
nsurlCacheDirectory = NSHomeDirectory();
- // As a fudge factor, use 1000 instead of 1024, in case the reported byte
- // count doesn't align exactly to a megabyte boundary.
- uint64_t memSize = WebMemorySize() / 1024 / 1000;
+ static uint64_t memSize = roundUpToPowerOf2(WebMemorySize() / 1024 / 1024);
unsigned long long diskFreeSize = WebVolumeFreeSize(nsurlCacheDirectory) / 1024 / 1000;
NSURLCache *nsurlCache = [NSURLCache sharedURLCache];
pageCacheCapacity = 0;
// Object cache capacities (in bytes)
- if (memSize >= 2048)
+ if (memSize >= 4096)
+ cacheTotalCapacity = 128 * 1024 * 1024;
+ else if (memSize >= 2048)
cacheTotalCapacity = 96 * 1024 * 1024;
- else if (memSize >= 1536)
- cacheTotalCapacity = 64 * 1024 * 1024;
else if (memSize >= 1024)
cacheTotalCapacity = 32 * 1024 * 1024;
else if (memSize >= 512)
pageCacheCapacity = 0;
// Object cache capacities (in bytes)
- if (memSize >= 2048)
+ if (memSize >= 4096)
+ cacheTotalCapacity = 128 * 1024 * 1024;
+ else if (memSize >= 2048)
cacheTotalCapacity = 96 * 1024 * 1024;
- else if (memSize >= 1536)
- cacheTotalCapacity = 64 * 1024 * 1024;
else if (memSize >= 1024)
cacheTotalCapacity = 32 * 1024 * 1024;
else if (memSize >= 512)
// (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 >= 2048)
+ if (memSize >= 4096)
+ cacheTotalCapacity = 192 * 1024 * 1024;
+ else if (memSize >= 2048)
cacheTotalCapacity = 128 * 1024 * 1024;
- else if (memSize >= 1536)
- cacheTotalCapacity = 96 * 1024 * 1024;
else if (memSize >= 1024)
cacheTotalCapacity = 64 * 1024 * 1024;
else if (memSize >= 512)
NSDictionary *element = [sender representedObject];
ASSERT([element isKindOfClass:[NSDictionary class]]);
- WebDataSource *dataSource = [[element objectForKey:WebElementFrameKey] dataSource];
+ WebDataSource *dataSource = [(WebFrame *)[element objectForKey:WebElementFrameKey] dataSource];
NSURLRequest *request = [[dataSource request] copy];
ASSERT(request);
_private->layerSyncRunLoopObserver = 0;
}
#endif
+
+#if ENABLE(GLIB_SUPPORT)
+- (void)_clearGlibLoopObserver
+{
+ if (!_private->glibRunLoopObserver)
+ return;
+
+ CFRunLoopObserverInvalidate(_private->glibRunLoopObserver);
+ CFRelease(_private->glibRunLoopObserver);
+ _private->glibRunLoopObserver = 0;
+}
+#endif
@end
@implementation WebView (WebViewInternal)
// An NSWindow may not display in the next runloop cycle after dirtying due to delayed window display logic,
// in which case this observer can fire first. So if the window is due for a display, don't commit
// layer changes, otherwise they'll show on screen before the view drawing.
- if ([window viewsNeedDisplay])
+ bool viewsNeedDisplay;
+#ifndef __LP64__
+ if (window && [window _wrapsCarbonWindow])
+ viewsNeedDisplay = HIViewGetNeedsDisplay(HIViewGetRoot(static_cast<WindowRef>([window windowRef])));
+ else
+#endif
+ viewsNeedDisplay = [window viewsNeedDisplay];
+
+ if (viewsNeedDisplay)
return;
if ([webView _syncCompositingChanges]) {
- (void)_scheduleCompositingLayerSync
{
+ CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
+
+ // Make sure we wake up the loop or the observer could be delayed until some other source fires.
+ CFRunLoopWakeUp(currentRunLoop);
+
if (_private->layerSyncRunLoopObserver)
return;
kCFRunLoopBeforeWaiting | kCFRunLoopExit, true /* repeats */,
runLoopOrder, layerSyncRunLoopObserverCallBack, &context);
- CFRunLoopAddObserver(CFRunLoopGetCurrent(), _private->layerSyncRunLoopObserver, kCFRunLoopCommonModes);
+ CFRunLoopAddObserver(currentRunLoop, _private->layerSyncRunLoopObserver, kCFRunLoopCommonModes);
}
#endif
#endif
+#if ENABLE(GLIB_SUPPORT)
+
+static void glibContextIterationCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*)
+{
+ g_main_context_iteration(0, FALSE);
+}
+
+- (void)_scheduleGlibContextIterations
+{
+ if (_private->glibRunLoopObserver)
+ return;
+
+ NSRunLoop* myRunLoop = [NSRunLoop currentRunLoop];
+
+ // Create a run loop observer and attach it to the run loop.
+ CFRunLoopObserverContext context = {0, self, 0, 0, 0};
+ _private->glibRunLoopObserver = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, YES, 0, &glibContextIterationCallback, &context);
+
+ if (_private->glibRunLoopObserver) {
+ CFRunLoopRef cfLoop = [myRunLoop getCFRunLoop];
+ CFRunLoopAddObserver(cfLoop, _private->glibRunLoopObserver, kCFRunLoopDefaultMode);
+ }
+
+}
+#endif
+
+
+@end
+
+@implementation WebView (WebViewDeviceOrientation)
+
+- (void)_setDeviceOrientationProvider:(id<WebDeviceOrientationProvider>)deviceOrientationProvider
+{
+ if (_private)
+ _private->m_deviceOrientationProvider = deviceOrientationProvider;
+}
+
+- (id<WebDeviceOrientationProvider>)_deviceOrientationProvider
+{
+ if (_private)
+ return _private->m_deviceOrientationProvider;
+ return nil;
+}
+
@end
@implementation WebView (WebViewGeolocation)
return nil;
}
-- (void)_geolocationDidChangePosition:(WebGeolocationPosition *)position;
+- (void)_geolocationDidChangePosition:(WebGeolocationPosition *)position
{
#if ENABLE(CLIENT_BASED_GEOLOCATION)
if (_private && _private->page)
@end
+@implementation WebView (WebViewPrivateNodesFromRect)
+
+- (JSValueRef)_nodesFromRect:(JSContextRef)context forDocument:(JSValueRef)value x:(int)x y:(int)y top:(unsigned)top right:(unsigned)right bottom:(unsigned)bottom left:(unsigned)left ignoreClipping:(BOOL)ignoreClipping
+{
+ JSLock lock(SilenceAssertionsOnly);
+ ExecState* exec = toJS(context);
+ if (!value)
+ return JSValueMakeUndefined(context);
+ JSValue jsValue = toJS(exec, value);
+ if (!jsValue.inherits(&JSDocument::s_info))
+ return JSValueMakeUndefined(context);
+ JSDocument* jsDocument = static_cast<JSDocument*>(asObject(jsValue));
+ Document* document = jsDocument->impl();
+ RefPtr<NodeList> nodes = document->nodesFromRect(x, y, top, right, bottom, left, ignoreClipping);
+ return toRef(exec, toJS(exec, jsDocument->globalObject(), nodes.get()));
+}
+
+@end
+
#ifdef BUILDING_ON_LEOPARD
static IMP originalRecursivelyRemoveMailAttributesImp;