WebView.mm 198 KB
Newer Older
ddkilzer's avatar
WebKit:  
ddkilzer committed
1
/*
2
 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3
 * Copyright (C) 2006 David Smith (catfish.man@gmail.com)
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 * 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.
 */
29

darin's avatar
darin committed
30
#import "WebViewInternal.h"
weinig@apple.com's avatar
WebKit:  
weinig@apple.com committed
31
#import "WebViewData.h"
darin's avatar
darin committed
32

darin@apple.com's avatar
darin@apple.com committed
33 34
#import "DOMCSSStyleDeclarationInternal.h"
#import "DOMNodeInternal.h"
ggaren's avatar
ggaren committed
35
#import "DOMRangeInternal.h"
beidson's avatar
beidson committed
36
#import "WebBackForwardListInternal.h"
37
#import "WebCache.h"
ggaren's avatar
ggaren committed
38
#import "WebChromeClient.h"
aroben's avatar
aroben committed
39
#import "WebContextMenuClient.h"
darin's avatar
darin committed
40
#import "WebDOMOperationsPrivate.h"
mjs's avatar
mjs committed
41
#import "WebDataSourceInternal.h"
darin@apple.com's avatar
darin@apple.com committed
42
#import "WebDatabaseManagerInternal.h"
darin's avatar
darin committed
43 44 45
#import "WebDefaultEditingDelegate.h"
#import "WebDefaultPolicyDelegate.h"
#import "WebDefaultUIDelegate.h"
weinig@apple.com's avatar
WebKit:  
weinig@apple.com committed
46
#import "WebDelegateImplementationCaching.h"
darin's avatar
darin committed
47 48 49 50
#import "WebDocument.h"
#import "WebDocumentInternal.h"
#import "WebDownload.h"
#import "WebDownloadInternal.h"
51
#import "WebDragClient.h"
darin@apple.com's avatar
darin@apple.com committed
52
#import "WebDynamicScrollBarsViewInternal.h"
darin's avatar
darin committed
53
#import "WebEditingDelegate.h"
ggaren's avatar
ggaren committed
54
#import "WebEditorClient.h"
darin's avatar
darin committed
55 56 57 58 59
#import "WebFormDelegatePrivate.h"
#import "WebFrameInternal.h"
#import "WebFrameViewInternal.h"
#import "WebHTMLRepresentation.h"
#import "WebHTMLViewInternal.h"
beidson's avatar
beidson committed
60
#import "WebHistoryItemInternal.h"
beidson's avatar
beidson committed
61
#import "WebIconDatabaseInternal.h"
timothy@apple.com's avatar
timothy@apple.com committed
62
#import "WebInspector.h"
aroben's avatar
aroben committed
63
#import "WebInspectorClient.h"
darin's avatar
darin committed
64 65 66 67
#import "WebKitErrors.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
#import "WebKitStatisticsPrivate.h"
ggaren's avatar
gtk:  
ggaren committed
68
#import "WebKitSystemBits.h"
bdakin's avatar
bdakin committed
69
#import "WebKitVersionChecks.h"
darin's avatar
darin committed
70 71 72 73 74 75 76 77 78 79 80 81
#import "WebLocalizableStrings.h"
#import "WebNSDataExtras.h"
#import "WebNSDataExtrasPrivate.h"
#import "WebNSDictionaryExtras.h"
#import "WebNSEventExtras.h"
#import "WebNSObjectExtras.h"
#import "WebNSPasteboardExtras.h"
#import "WebNSPrintOperationExtras.h"
#import "WebNSURLExtras.h"
#import "WebNSURLRequestExtras.h"
#import "WebNSUserDefaultsExtras.h"
#import "WebNSViewExtras.h"
weinig@apple.com's avatar
WebKit:  
weinig@apple.com committed
82
#import "WebNodeHighlight.h"
darin@apple.com's avatar
darin@apple.com committed
83
#import "WebPDFView.h"
beidson's avatar
beidson committed
84
#import "WebPanelAuthenticationHandler.h"
85
#import "WebPasteboardHelper.h"
darin's avatar
darin committed
86 87
#import "WebPluginDatabase.h"
#import "WebPolicyDelegate.h"
88
#import "WebPreferenceKeysPrivate.h"
darin's avatar
darin committed
89
#import "WebPreferencesPrivate.h"
90
#import "WebScriptDebugDelegate.h"
91
#import "WebSystemInterface.h"
darin@apple.com's avatar
darin@apple.com committed
92
#import "WebTextCompletionController.h"
bdakin@apple.com's avatar
bdakin@apple.com committed
93
#import "WebTextIterator.h"
darin's avatar
darin committed
94 95 96 97
#import "WebUIDelegate.h"
#import "WebUIDelegatePrivate.h"
#import <CoreFoundation/CFSet.h>
#import <Foundation/NSURLConnection.h>
andersca@apple.com's avatar
andersca@apple.com committed
98
#import <WebCore/ApplicationCacheStorage.h>
ggaren's avatar
ggaren committed
99
#import <WebCore/Cache.h>
sullivan's avatar
sullivan committed
100
#import <WebCore/ColorMac.h>
101
#import <WebCore/Cursor.h>
ggaren's avatar
ggaren committed
102
#import <WebCore/Document.h>
ggaren's avatar
ggaren committed
103
#import <WebCore/DocumentLoader.h>
104 105
#import <WebCore/DragController.h>
#import <WebCore/DragData.h>
ggaren's avatar
ggaren committed
106
#import <WebCore/Editor.h>
107
#import <WebCore/EventHandler.h>
108
#import <WebCore/ExceptionHandlers.h>
109
#import <WebCore/FocusController.h>
mjs's avatar
mjs committed
110
#import <WebCore/Frame.h>
ggaren's avatar
ggaren committed
111
#import <WebCore/FrameLoader.h>
darin's avatar
darin committed
112
#import <WebCore/FrameTree.h>
weinig@apple.com's avatar
weinig@apple.com committed
113
#import <WebCore/FrameView.h>
114
#import <WebCore/GCController.h>
darin's avatar
darin committed
115
#import <WebCore/HTMLNames.h>
beidson's avatar
beidson committed
116
#import <WebCore/HistoryItem.h>
darin@apple.com's avatar
darin@apple.com committed
117
#import <WebCore/IconDatabase.h>
ggaren's avatar
ggaren committed
118
#import <WebCore/Logging.h>
beidson's avatar
beidson committed
119
#import <WebCore/MIMETypeRegistry.h>
darin's avatar
darin committed
120
#import <WebCore/Page.h>
ggaren's avatar
ggaren committed
121
#import <WebCore/PageCache.h>
beidson@apple.com's avatar
beidson@apple.com committed
122
#import <WebCore/PageGroup.h>
123
#import <WebCore/PlatformMouseEvent.h>
andersca's avatar
andersca committed
124
#import <WebCore/ProgressTracker.h>
weinig@apple.com's avatar
weinig@apple.com committed
125
#import <WebCore/ResourceHandle.h>
126
#import <WebCore/RuntimeApplicationChecks.h>
127
#import <WebCore/ScriptController.h>
128
#import <WebCore/ScriptValue.h>
abarth@webkit.org's avatar
abarth@webkit.org committed
129
#import <WebCore/SecurityOrigin.h>
ggaren's avatar
ggaren committed
130
#import <WebCore/SelectionController.h>
ggaren's avatar
ggaren committed
131
#import <WebCore/Settings.h>
darin's avatar
darin committed
132
#import <WebCore/TextResourceDecoder.h>
133
#import <WebCore/ThreadCheck.h>
thatcher's avatar
thatcher committed
134
#import <WebCore/WebCoreObjCExtras.h>
kocienda's avatar
kocienda committed
135
#import <WebCore/WebCoreView.h>
bdakin@apple.com's avatar
bdakin@apple.com committed
136
#import <WebCore/Widget.h>
darin's avatar
darin committed
137 138
#import <WebKit/DOM.h>
#import <WebKit/DOMExtensions.h>
darin's avatar
darin committed
139
#import <WebKit/DOMPrivate.h>
darin's avatar
darin committed
140
#import <WebKitSystemInterface.h>
141 142 143
#import <mach-o/dyld.h>
#import <objc/objc-auto.h>
#import <objc/objc-runtime.h>
144 145
#import <runtime/ArrayPrototype.h>
#import <runtime/DateInstance.h>
146 147
#import <runtime/InitializeThreading.h>
#import <runtime/JSLock.h>
barraclough@apple.com's avatar
barraclough@apple.com committed
148
#import <runtime/JSValue.h>
149 150
#import <wtf/Assertions.h>
#import <wtf/HashTraits.h>
151
#import <wtf/RefCountedLeakCounter.h>
152
#import <wtf/RefPtr.h>
153
#import <wtf/StdLibExtras.h>
154

ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
155 156 157 158
#if ENABLE(DASHBOARD_SUPPORT)
#import <WebKit/WebDashboardRegion.h>
#endif

darin@apple.com's avatar
darin@apple.com committed
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
@class NSTextInputContext;

@interface NSResponder (WebNSResponderDetails)
- (NSTextInputContext *)inputContext;
@end

@interface NSSpellChecker (WebNSSpellCheckerDetails)
- (void)_preflightChosenSpellServer;
@end

@interface NSView (WebNSViewDetails)
- (NSView *)_hitTest:(NSPoint *)aPoint dragTypes:(NSSet *)types;
- (void)_autoscrollForDraggingInfo:(id)dragInfo timeDelta:(NSTimeInterval)repeatDelta;
- (BOOL)_shouldAutoscrollForDraggingInfo:(id)dragInfo;
@end

@interface NSWindow (WebNSWindowDetails) 
- (id)_oldFirstResponderBeforeBecoming;
@end

darin's avatar
darin committed
179
using namespace WebCore;
180
using namespace JSC;
181

182
#if defined(__ppc__) || defined(__ppc64__)
vicki's avatar
vicki committed
183
#define PROCESSOR "PPC"
184
#elif defined(__i386__) || defined(__x86_64__)
vicki's avatar
vicki committed
185 186 187 188 189
#define PROCESSOR "Intel"
#else
#error Unknown architecture
#endif

190 191 192 193 194 195 196 197
#define FOR_EACH_RESPONDER_SELECTOR(macro) \
macro(alignCenter) \
macro(alignJustified) \
macro(alignLeft) \
macro(alignRight) \
macro(capitalizeWord) \
macro(centerSelectionInVisibleArea) \
macro(changeAttributes) \
darin@apple.com's avatar
darin@apple.com committed
198
macro(changeBaseWritingDirection) \
mitz@apple.com's avatar
mitz@apple.com committed
199 200
macro(changeBaseWritingDirectionToLTR) \
macro(changeBaseWritingDirectionToRTL) \
201 202 203
macro(changeColor) \
macro(changeDocumentBackgroundColor) \
macro(changeFont) \
darin@apple.com's avatar
darin@apple.com committed
204
macro(changeSpelling) \
205 206 207 208 209 210 211 212 213 214 215 216 217
macro(checkSpelling) \
macro(complete) \
macro(copy) \
macro(copyFont) \
macro(cut) \
macro(delete) \
macro(deleteBackward) \
macro(deleteBackwardByDecomposingPreviousCharacter) \
macro(deleteForward) \
macro(deleteToBeginningOfLine) \
macro(deleteToBeginningOfParagraph) \
macro(deleteToEndOfLine) \
macro(deleteToEndOfParagraph) \
darin@apple.com's avatar
darin@apple.com committed
218
macro(deleteToMark) \
219 220 221 222 223
macro(deleteWordBackward) \
macro(deleteWordForward) \
macro(ignoreSpelling) \
macro(indent) \
macro(insertBacktab) \
darin@apple.com's avatar
darin@apple.com committed
224
macro(insertLineBreak) \
225 226 227 228 229 230
macro(insertNewline) \
macro(insertNewlineIgnoringFieldEditor) \
macro(insertParagraphSeparator) \
macro(insertTab) \
macro(insertTabIgnoringFieldEditor) \
macro(lowercaseWord) \
mitz@apple.com's avatar
mitz@apple.com committed
231 232
macro(makeBaseWritingDirectionLeftToRight) \
macro(makeBaseWritingDirectionRightToLeft) \
mitz@apple.com's avatar
mitz@apple.com committed
233 234 235
macro(makeTextWritingDirectionLeftToRight) \
macro(makeTextWritingDirectionNatural) \
macro(makeTextWritingDirectionRightToLeft) \
236 237 238 239 240 241 242 243
macro(moveBackward) \
macro(moveBackwardAndModifySelection) \
macro(moveDown) \
macro(moveDownAndModifySelection) \
macro(moveForward) \
macro(moveForwardAndModifySelection) \
macro(moveLeft) \
macro(moveLeftAndModifySelection) \
darin@apple.com's avatar
darin@apple.com committed
244 245
macro(moveParagraphBackwardAndModifySelection) \
macro(moveParagraphForwardAndModifySelection) \
246 247 248 249 250 251 252 253
macro(moveRight) \
macro(moveRightAndModifySelection) \
macro(moveToBeginningOfDocument) \
macro(moveToBeginningOfDocumentAndModifySelection) \
macro(moveToBeginningOfLine) \
macro(moveToBeginningOfLineAndModifySelection) \
macro(moveToBeginningOfParagraph) \
macro(moveToBeginningOfParagraphAndModifySelection) \
darin@apple.com's avatar
darin@apple.com committed
254 255
macro(moveToBeginningOfSentence) \
macro(moveToBeginningOfSentenceAndModifySelection) \
256 257 258 259 260 261
macro(moveToEndOfDocument) \
macro(moveToEndOfDocumentAndModifySelection) \
macro(moveToEndOfLine) \
macro(moveToEndOfLineAndModifySelection) \
macro(moveToEndOfParagraph) \
macro(moveToEndOfParagraphAndModifySelection) \
harrison's avatar
harrison committed
262 263
macro(moveToEndOfSentence) \
macro(moveToEndOfSentenceAndModifySelection) \
darin@apple.com's avatar
darin@apple.com committed
264 265 266 267
macro(moveToLeftEndOfLine) \
macro(moveToLeftEndOfLineAndModifySelection) \
macro(moveToRightEndOfLine) \
macro(moveToRightEndOfLineAndModifySelection) \
268 269 270 271 272 273 274 275 276 277
macro(moveUp) \
macro(moveUpAndModifySelection) \
macro(moveWordBackward) \
macro(moveWordBackwardAndModifySelection) \
macro(moveWordForward) \
macro(moveWordForwardAndModifySelection) \
macro(moveWordLeft) \
macro(moveWordLeftAndModifySelection) \
macro(moveWordRight) \
macro(moveWordRightAndModifySelection) \
thatcher's avatar
thatcher committed
278
macro(outdent) \
justin.garcia@apple.com's avatar
justin.garcia@apple.com committed
279
macro(orderFrontSubstitutionsPanel) \
280
macro(pageDown) \
darin@apple.com's avatar
darin@apple.com committed
281
macro(pageDownAndModifySelection) \
282
macro(pageUp) \
darin@apple.com's avatar
darin@apple.com committed
283
macro(pageUpAndModifySelection) \
284 285 286 287 288 289 290 291 292
macro(paste) \
macro(pasteAsPlainText) \
macro(pasteAsRichText) \
macro(pasteFont) \
macro(performFindPanelAction) \
macro(scrollLineDown) \
macro(scrollLineUp) \
macro(scrollPageDown) \
macro(scrollPageUp) \
sullivan's avatar
sullivan committed
293 294
macro(scrollToBeginningOfDocument) \
macro(scrollToEndOfDocument) \
295 296 297
macro(selectAll) \
macro(selectLine) \
macro(selectParagraph) \
darin@apple.com's avatar
darin@apple.com committed
298 299 300 301
macro(selectSentence) \
macro(selectToMark) \
macro(selectWord) \
macro(setMark) \
302 303 304 305 306
macro(showGuessPanel) \
macro(startSpeaking) \
macro(stopSpeaking) \
macro(subscript) \
macro(superscript) \
darin@apple.com's avatar
darin@apple.com committed
307 308 309 310
macro(swapWithMark) \
macro(takeFindStringFromSelection) \
macro(toggleBaseWritingDirection) \
macro(transpose) \
311 312 313 314 315 316
macro(underline) \
macro(unscript) \
macro(uppercaseWord) \
macro(yank) \
macro(yankAndSelect) \

sullivan's avatar
sullivan committed
317 318 319
#define WebKitOriginalTopPrintingMarginKey @"WebKitOriginalTopMargin"
#define WebKitOriginalBottomPrintingMarginKey @"WebKitOriginalBottomMargin"

darin@apple.com's avatar
darin@apple.com committed
320 321 322 323
#define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange"
#define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode")
#define UniversalAccessDomain CFSTR("com.apple.universalaccess")

324 325 326 327
#if USE(ACCELERATED_COMPOSITING)
#define UsingAcceleratedCompositingProperty @"_isUsingAcceleratedCompositing"
#endif            

ggaren's avatar
gtk:  
ggaren committed
328 329 330
static BOOL s_didSetCacheModel;
static WebCacheModel s_cacheModel = WebCacheModelDocumentViewer;

darin@apple.com's avatar
darin@apple.com committed
331 332
static WebView *lastMouseoverView;

333 334 335 336
#ifndef NDEBUG
static const char webViewIsOpen[] = "At least one WebView is still open.";
#endif

337 338 339 340 341 342 343
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
@interface NSObject (NSTextInputContextDetails)
- (BOOL)wantsToHandleMouseEvents;
- (BOOL)handleMouseEvent:(NSEvent *)event;
@end
#endif

darin@apple.com's avatar
darin@apple.com committed
344
@interface NSObject (WebValidateWithoutDelegate)
thatcher's avatar
thatcher committed
345 346 347
- (BOOL)validateUserInterfaceItemWithoutDelegate:(id <NSValidatedUserInterfaceItem>)item;
@end

thatcher's avatar
thatcher committed
348 349 350 351 352 353 354 355 356
@interface _WebSafeForwarder : NSObject
{
    id target; // Non-retained. Don't retain delegates.
    id defaultTarget;
    BOOL catchExceptions;
}
- (id)initWithTarget:(id)target defaultTarget:(id)defaultTarget catchExceptions:(BOOL)catchExceptions;
@end

darin's avatar
darin committed
357
@interface WebView (WebFileInternal)
sullivan's avatar
sullivan committed
358 359 360
- (WebFrame *)_selectedOrMainFrame;
- (BOOL)_isLoading;
- (WebFrameView *)_frameViewAtWindowPoint:(NSPoint)point;
sullivan's avatar
sullivan committed
361
- (WebFrame *)_focusedFrame;
mjs's avatar
mjs committed
362
+ (void)_preflightSpellChecker;
darin's avatar
darin committed
363
- (BOOL)_continuousCheckingAllowed;
364
- (NSResponder *)_responderForResponderOperations;
365
#if USE(ACCELERATED_COMPOSITING)
366
- (void)_clearLayerSyncLoopObserver;
367
#endif
darin's avatar
darin committed
368 369
@end

370 371
static void patchMailRemoveAttributesMethod();

cblu's avatar
cblu committed
372
NSString *WebElementDOMNodeKey =            @"WebElementDOMNode";
cblu's avatar
cblu committed
373 374 375 376 377 378 379
NSString *WebElementFrameKey =              @"WebElementFrame";
NSString *WebElementImageKey =              @"WebElementImage";
NSString *WebElementImageAltStringKey =     @"WebElementImageAltString";
NSString *WebElementImageRectKey =          @"WebElementImageRect";
NSString *WebElementImageURLKey =           @"WebElementImageURL";
NSString *WebElementIsSelectedKey =         @"WebElementIsSelected";
NSString *WebElementLinkLabelKey =          @"WebElementLinkLabel";
sullivan's avatar
sullivan committed
380
NSString *WebElementLinkTargetFrameKey =    @"WebElementTargetFrame";
cblu's avatar
cblu committed
381
NSString *WebElementLinkTitleKey =          @"WebElementLinkTitle";
sullivan's avatar
sullivan committed
382 383 384
NSString *WebElementLinkURLKey =            @"WebElementLinkURL";
NSString *WebElementSpellingToolTipKey =    @"WebElementSpellingToolTip";
NSString *WebElementTitleKey =              @"WebElementTitle";
gdennis's avatar
gdennis committed
385
NSString *WebElementLinkIsLiveKey =         @"WebElementLinkIsLive";
bdakin's avatar
bdakin committed
386
NSString *WebElementIsContentEditableKey =  @"WebElementIsContentEditableKey";
cblu's avatar
cblu committed
387

388 389 390
NSString *WebViewProgressStartedNotification =          @"WebProgressStartedNotification";
NSString *WebViewProgressEstimateChangedNotification =  @"WebProgressEstimateChangedNotification";
NSString *WebViewProgressFinishedNotification =         @"WebProgressFinishedNotification";
rjw's avatar
WebKit:  
rjw committed
391

kocienda's avatar
kocienda committed
392 393 394 395 396 397
NSString * const WebViewDidBeginEditingNotification =         @"WebViewDidBeginEditingNotification";
NSString * const WebViewDidChangeNotification =               @"WebViewDidChangeNotification";
NSString * const WebViewDidEndEditingNotification =           @"WebViewDidEndEditingNotification";
NSString * const WebViewDidChangeTypingStyleNotification =    @"WebViewDidChangeTypingStyleNotification";
NSString * const WebViewDidChangeSelectionNotification =      @"WebViewDidChangeSelectionNotification";

thatcher's avatar
thatcher committed
398
enum { WebViewVersion = 4 };
rjw's avatar
WebKit:  
rjw committed
399

400
#define timedLayoutSize 4096
401 402 403

static NSMutableSet *schemesWithRepresentationsSet;

404 405 406 407 408 409 410
NSString *_WebCanGoBackKey =            @"canGoBack";
NSString *_WebCanGoForwardKey =         @"canGoForward";
NSString *_WebEstimatedProgressKey =    @"estimatedProgress";
NSString *_WebIsLoadingKey =            @"isLoading";
NSString *_WebMainFrameIconKey =        @"mainFrameIcon";
NSString *_WebMainFrameTitleKey =       @"mainFrameTitle";
NSString *_WebMainFrameURLKey =         @"mainFrameURL";
thatcher's avatar
thatcher committed
411
NSString *_WebMainFrameDocumentKey =    @"mainFrameDocument";
412 413 414 415 416 417 418 419 420 421 422 423

@interface WebProgressItem : NSObject
{
@public
    long long bytesReceived;
    long long estimatedLength;
}
@end

@implementation WebProgressItem
@end

424
static BOOL continuousSpellCheckingEnabled;
bdash's avatar
bdash committed
425
#ifndef BUILDING_ON_TIGER
sullivan's avatar
sullivan committed
426 427
static BOOL grammarCheckingEnabled;
#endif
adele@apple.com's avatar
adele@apple.com committed
428 429 430 431 432 433 434
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
static BOOL automaticQuoteSubstitutionEnabled;
static BOOL automaticLinkDetectionEnabled;
static BOOL automaticDashSubstitutionEnabled;
static BOOL automaticTextReplacementEnabled;
static BOOL automaticSpellingCorrectionEnabled;
#endif
435

mjs's avatar
mjs committed
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
@implementation WebView (AllWebViews)

static CFSetCallBacks NonRetainingSetCallbacks = {
    0,
    NULL,
    NULL,
    CFCopyDescription,
    CFEqual,
    CFHash
};

static CFMutableSetRef allWebViewsSet;

+ (void)_makeAllWebViewsPerformSelector:(SEL)selector
{
    if (!allWebViewsSet)
        return;

    [(NSMutableSet *)allWebViewsSet makeObjectsPerformSelector:selector];
}

- (void)_removeFromAllWebViewsSet
{
    if (allWebViewsSet)
        CFSetRemoveValue(allWebViewsSet, self);
}

- (void)_addToAllWebViewsSet
{
    if (!allWebViewsSet)
darin's avatar
darin committed
466
        allWebViewsSet = CFSetCreateMutable(NULL, 0, &NonRetainingSetCallbacks);
mjs's avatar
mjs committed
467 468 469 470 471 472

    CFSetSetValue(allWebViewsSet, self);
}

@end

473 474
@implementation WebView (WebPrivate)

475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
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()
{
    // 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];
}

512
+ (NSString *)_standardUserAgentWithApplicationName:(NSString *)applicationName
513
{
514
    // Note: Do *not* move the initialization of osVersion nor webKitVersion into the declaration.
515 516
    // Garbage collection won't correctly mark the global variable in that case <rdar://problem/5733674>.
    static NSString *osVersion;
517
    static NSString *webKitVersion;
518 519
    if (!osVersion)
        osVersion = createMacOSXVersionString();
520 521
    if (!webKitVersion)
        webKitVersion = createUserVisibleWebKitVersionString();
522 523
    NSString *language = [NSUserDefaults _webkit_preferredLanguageCode];
    if ([applicationName length])
524 525
        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];
526 527
}

528
static void WebKitInitializeApplicationCachePathIfNecessary()
hyatt@apple.com's avatar
hyatt@apple.com committed
529
{
530 531 532 533 534 535 536 537 538 539 540 541 542 543
    static BOOL initialized = NO;
    if (initialized)
        return;

    NSString *appName = [[NSBundle mainBundle] bundleIdentifier];
    if (!appName)
        appName = [[NSProcessInfo processInfo] processName];
    
    ASSERT(appName);

    NSString* cacheDir = [NSString _webkit_localCacheDirectoryWithBundleIdentifier:appName];

    cacheStorage().setCacheDirectory(cacheDir);
    initialized = YES;
hyatt@apple.com's avatar
hyatt@apple.com committed
544 545
}

adele@apple.com's avatar
adele@apple.com committed
546 547 548
static bool runningLeopardMail()
{
#ifdef BUILDING_ON_LEOPARD
549
    return applicationIsAppleMail();
adele@apple.com's avatar
adele@apple.com committed
550 551 552 553 554 555 556
#endif
    return NO;
}

static bool runningTigerMail()
{
#ifdef BUILDING_ON_TIGER
557
    return applicationIsAppleMail();
adele@apple.com's avatar
adele@apple.com committed
558 559 560 561
#endif
    return NO;    
}

562 563 564 565 566
- (void)_dispatchPendingLoadRequests
{
    cache()->loader()->servePendingRequests();
}

567 568 569 570 571 572 573 574 575
- (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];
}
576

577
- (BOOL)_usesDocumentViews
578
{
darin@apple.com's avatar
darin@apple.com committed
579
    return _private->usesDocumentViews;
580 581 582 583
}

- (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews
{
584
    WebCoreThreadViolationCheckRoundTwo();
585

586 587 588 589 590 591 592 593 594 595 596
#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;
mitz@apple.com's avatar
mitz@apple.com committed
597
    _private->backgroundColor = [[NSColor colorWithDeviceWhite:1 alpha:1] retain];
darin@apple.com's avatar
darin@apple.com committed
598
    _private->usesDocumentViews = usesDocumentViews;
599 600

    WebFrameView *frameView = nil;
darin@apple.com's avatar
darin@apple.com committed
601
    if (_private->usesDocumentViews) {
602 603 604 605 606 607 608
        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];
    }

609 610 611 612 613
    static bool didOneTimeInitialization = false;
    if (!didOneTimeInitialization) {
        WebKitInitializeLoggingChannelsIfNecessary();
        WebCore::InitializeLoggingChannelsIfNecessary();
        [WebHistoryItem initWindowWatcherIfNecessary];
614
#if ENABLE(DATABASE)
615
        WebKitInitializeDatabasesIfNecessary();
616
#endif
617 618 619 620 621
        WebKitInitializeApplicationCachePathIfNecessary();
        patchMailRemoveAttributesMethod();
        didOneTimeInitialization = true;
    }

622
    _private->page = new Page(new WebChromeClient(self), new WebContextMenuClient(self), new WebEditorClient(self), new WebDragClient(self), new WebInspectorClient(self), 0);
623 624 625 626 627

    _private->page->settings()->setLocalStorageDatabasePath([[self preferences] _localStorageDatabasePath]);

    [WebFrame _createMainFrameWithPage:_private->page frameName:frameName frameView:frameView];

timothy@apple.com's avatar
timothy@apple.com committed
628 629 630 631 632 633
#ifndef BUILDING_ON_TIGER
    NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
#else
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
#endif

634
    if (WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOADING_DURING_COMMON_RUNLOOP_MODES))
635
        [self scheduleInRunLoop:runLoop forMode:(NSString *)kCFRunLoopCommonModes];
636
    else
timothy@apple.com's avatar
timothy@apple.com committed
637
        [self scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668

    [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);
669
    }
weinig@apple.com's avatar
weinig@apple.com committed
670 671 672

    if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_CONTENT_SNIFFING_FOR_FILE_URLS))
        ResourceHandle::forceContentSniffing();
673 674
}

675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
- (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");
    }
691 692
#endif

693 694 695 696 697 698
    _private = [[WebViewPrivate alloc] init];
    [self _commonInitializationWithFrameName:frameName groupName:groupName usesDocumentViews:usesDocumentViews];
    [self setMaintainsBackForwardList: YES];
    return self;
}

hyatt@apple.com's avatar
hyatt@apple.com committed
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
- (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
rjw's avatar
WebKit:  
rjw committed
724
{
darin@apple.com's avatar
darin@apple.com committed
725
    ASSERT(!_private->usesDocumentViews);
rjw's avatar
WebKit:  
rjw committed
726
    
hyatt@apple.com's avatar
hyatt@apple.com committed
727 728
    [NSGraphicsContext saveGraphicsState];
    NSRectClip(rect);
rjw's avatar
WebKit:  
rjw committed
729

hyatt@apple.com's avatar
hyatt@apple.com committed
730 731 732 733 734 735 736 737 738 739 740 741 742 743
    @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];
rjw's avatar
WebKit:  
rjw committed
744
    }
hyatt@apple.com's avatar
hyatt@apple.com committed
745 746
}

747 748
- (BOOL)isFlipped 
{
darin@apple.com's avatar
darin@apple.com committed
749
    return _private && !_private->usesDocumentViews;
750 751
}

hyatt@apple.com's avatar
hyatt@apple.com committed
752 753
- (void)setFrameSize:(NSSize)size
{
mitz@apple.com's avatar
mitz@apple.com committed
754
    if (!_private->usesDocumentViews && !NSEqualSizes(_private->lastLayoutSize, size)) {
darin@apple.com's avatar
darin@apple.com committed
755
        Frame* frame = [self _mainCoreFrame];
hyatt@apple.com's avatar
hyatt@apple.com committed
756 757 758 759
        // FIXME: Viewless WebKit is broken with Safari banners (e.g., the Find banner).  We'll have to figure out a way for
        // Safari to communicate that this space is being consumed.  For WebKit with document views, there's no
        // need to do an explicit resize, since WebFrameViews have auto resizing turned on and will handle changing
        // their bounds automatically. See <rdar://problem/6835573> for details.
mitz@apple.com's avatar
mitz@apple.com committed
760
        frame->view()->resize(IntSize(size));
hyatt@apple.com's avatar
hyatt@apple.com committed
761 762 763 764 765 766 767 768
        frame->view()->setNeedsLayout();
        [self setNeedsDisplay:YES];
        _private->lastLayoutSize = size;
    }

    [super setFrameSize:size];
}

769
#if USE(ACCELERATED_COMPOSITING) || !defined(BUILDING_ON_TIGER)
darin@apple.com's avatar
darin@apple.com committed
770

771 772
- (void)_viewWillDrawInternal
{
darin@apple.com's avatar
darin@apple.com committed
773
    Frame* frame = [self _mainCoreFrame];
774 775 776
    if (frame && frame->view())
        frame->view()->layoutIfNeededRecursive();
}
darin@apple.com's avatar
darin@apple.com committed
777

778 779
#endif

780 781 782 783
#ifndef BUILDING_ON_TIGER

- (void)viewWillDraw
{
darin@apple.com's avatar
darin@apple.com committed
784
    if (!_private->usesDocumentViews)
785
        [self _viewWillDrawInternal];
786 787 788 789 790 791
    [super viewWillDraw];
}

#endif


hyatt@apple.com's avatar
hyatt@apple.com committed
792 793
- (void)drawRect:(NSRect)rect
{
darin@apple.com's avatar
darin@apple.com committed
794
    if (_private->usesDocumentViews)
hyatt@apple.com's avatar
hyatt@apple.com committed
795 796 797
        return [super drawRect:rect];
    
    ASSERT_MAIN_THREAD();
rjw's avatar
WebKit:  
rjw committed
798

hyatt@apple.com's avatar
hyatt@apple.com committed
799 800 801
    const NSRect *rects;
    NSInteger count;
    [self getRectsBeingDrawn:&rects count:&count];
rjw's avatar
WebKit:  
rjw committed
802

hyatt@apple.com's avatar
hyatt@apple.com committed
803 804 805 806 807 808
    
    if ([self _mustDrawUnionedRect:rect singleRects:rects count:count])
        [self drawSingleRect:rect];
    else
        for (int i = 0; i < count; ++i)
            [self drawSingleRect:rects[i]];
rjw's avatar
WebKit:  
rjw committed
809 810
}

cblu's avatar
WebKit:  
cblu committed
811 812 813
+ (NSArray *)_supportedMIMETypes
{
    // Load the plug-in DB allowing plug-ins to install types.
ggaren's avatar
ggaren committed
814
    [WebPluginDatabase sharedDatabase];
cblu's avatar
WebKit:  
cblu committed
815 816 817 818 819 820 821 822 823 824
    return [[WebFrameView _viewTypesAllowImageTypeOmission:NO] allKeys];
}

+ (NSArray *)_supportedFileExtensions
{
    NSMutableSet *extensions = [[NSMutableSet alloc] init];
    NSArray *MIMETypes = [self _supportedMIMETypes];
    NSEnumerator *enumerator = [MIMETypes objectEnumerator];
    NSString *MIMEType;
    while ((MIMEType = [enumerator nextObject]) != nil) {
mjs's avatar
mjs committed
825
        NSArray *extensionsForType = WKGetExtensionsForMIMEType(MIMEType);
darin's avatar
darin committed
826 827
        if (extensionsForType) {
            [extensions addObjectsFromArray:extensionsForType];
cblu's avatar
WebKit:  
cblu committed
828 829 830 831 832 833 834
        }
    }
    NSArray *uniqueExtensions = [extensions allObjects];
    [extensions release];
    return uniqueExtensions;
}

835
+ (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType
836 837
{
    MIMEType = [MIMEType lowercaseString];
eseidel's avatar
eseidel committed
838 839
    Class viewClass = [[WebFrameView _viewTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
    Class repClass = [[WebDataSource _repTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
840
    
ap's avatar
ap committed
841
    if (!viewClass || !repClass || [[WebPDFView supportedMIMETypes] containsObject:MIMEType]) {
eseidel's avatar
eseidel committed
842 843
        // Our optimization to avoid loading the plug-in DB and image types for the HTML case failed.
        // Load the plug-in DB allowing plug-ins to install types.
ggaren's avatar
ggaren committed
844
        [WebPluginDatabase sharedDatabase];
eseidel's avatar
eseidel committed
845 846 847 848
            
        // Load the image types and get the view class and rep class. This should be the fullest picture of all handled types.
        viewClass = [[WebFrameView _viewTypesAllowImageTypeOmission:NO] _webkit_objectForMIMEType:MIMEType];
        repClass = [[WebDataSource _repTypesAllowImageTypeOmission:NO] _webkit_objectForMIMEType:MIMEType];
849 850 851
    }
    
    if (viewClass && repClass) {
andersca's avatar
andersca committed
852 853 854 855
        // Special-case WebHTMLView for text types that shouldn't be shown.
        if (viewClass == [WebHTMLView class] &&
            repClass == [WebHTMLRepresentation class] &&
            [[WebHTMLView unsupportedTextMIMETypes] containsObject:MIMEType]) {
856 857
            return NO;
        }
eseidel's avatar
eseidel committed
858
        if (vClass)
859
            *vClass = viewClass;
eseidel's avatar
eseidel committed
860
        if (rClass)
861 862 863 864 865 866 867
            *rClass = repClass;
        return YES;
    }
    
    return NO;
}

868
- (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType
tomernic's avatar
tomernic committed
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886
{
    if ([[self class] _viewClass:vClass andRepresentationClass:rClass forMIMEType:MIMEType])
        return YES;

    if (_private->pluginDatabase) {
        WebBasePluginPackage *pluginPackage = [_private->pluginDatabase pluginForMIMEType:MIMEType];
        if (pluginPackage) {
            if (vClass)
                *vClass = [WebHTMLView class];
            if (rClass)
                *rClass = [WebHTMLRepresentation class];
            return YES;
        }
    }
    
    return NO;
}

rjw's avatar
rjw committed
887 888
+ (void)_setAlwaysUseATSU:(BOOL)f
{
mitz@apple.com's avatar
mitz@apple.com committed
889 890 891 892 893
    [self _setAlwaysUsesComplexTextCodePath:f];
}

+ (void)_setAlwaysUsesComplexTextCodePath:(BOOL)f
{
mitz@apple.com's avatar
mitz@apple.com committed
894
    Font::setCodePath(f ? Font::Complex : Font::Auto);
rjw's avatar
rjw committed
895 896
}

897 898 899 900 901 902 903 904 905 906 907 908 909 910 911
+ (BOOL)canCloseAllWebViews
{
    return DOMWindow::dispatchAllPendingBeforeUnloadEvents();
}

+ (void)closeAllWebViews
{
    DOMWindow::dispatchAllPendingUnloadEvents();

    // This will close the WebViews in a random order. Change this if close order is important.
    NSEnumerator *enumerator = [(NSMutableSet *)allWebViewsSet objectEnumerator];
    while (WebView *webView = [enumerator nextObject])
        [webView close];
}

912 913
+ (BOOL)canShowFile:(NSString *)path
{
cblu's avatar
cblu committed
914
    return [[self class] canShowMIMEType:[WebView _MIMETypeForFile:path]];
915 916
}

cblu's avatar
cblu committed
917
+ (NSString *)suggestedFileExtensionForMIMEType:(NSString *)type
918
{
mjs's avatar
mjs committed
919
    return WKGetPreferredExtensionForMIMEType(type);
920 921
}

aroben's avatar
aroben committed
922 923
- (BOOL)_isClosed
{
924
    return !_private || _private->closed;
aroben's avatar
aroben committed
925 926
}

927
- (void)_closePluginDatabases
928 929
{
    pluginDatabaseClientCount--;
930 931 932

    // Close both sets of plug-in databases because plug-ins need an opportunity to clean up files, etc.

933 934
    // Unload the WebView local plug-in database. 
    if (_private->pluginDatabase) {
935
        [_private->pluginDatabase destroyAllPluginInstanceViews];
936 937 938 939 940 941 942 943 944 945
        [_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];
}

946 947
- (void)_closeWithFastTeardown 
{
948 949 950 951
#ifndef NDEBUG
    WTF::RefCountedLeakCounter::suppressMessages("At least one WebView was closed with fast teardown.");
#endif

952
    _private->closed = YES;
953 954 955
    
    [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
956 957 958 959

    [self _closePluginDatabases];
}

960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
static bool fastDocumentTeardownEnabled()
{
#ifdef NDEBUG
    static bool enabled = ![[NSUserDefaults standardUserDefaults] boolForKey:WebKitEnableFullDocumentTeardownPreferenceKey];
#else
    static bool initialized = false;
    static bool enabled = false;
    if (!initialized) {
        // This allows debug builds to default to not have fast teardown, so leak checking still works.
        // But still allow the WebKitEnableFullDocumentTeardown default to override it if present.
        NSNumber *setting = [[NSUserDefaults standardUserDefaults] objectForKey:WebKitEnableFullDocumentTeardownPreferenceKey];
        if (setting)
            enabled = ![setting boolValue];
        initialized = true;
    }
#endif
    return enabled;
}

979 980
// _close is here only for backward compatibility; clients and subclasses should use
// public method -close instead.
981 982
- (void)_close
{
thatcher's avatar
thatcher committed
983
    if (!_private || _private->closed)
thatcher's avatar
thatcher committed
984
        return;
985

darin@apple.com's avatar
darin@apple.com committed
986 987 988
    if (lastMouseoverView == self)
        lastMouseoverView = nil;

989 990 991
#ifndef NDEBUG
    WTF::RefCountedLeakCounter::cancelMessageSuppression(webViewIsOpen);
#endif
992 993 994 995

    // To quit the apps fast we skip document teardown, except plugins
    // need to be destroyed and unloaded.
    if (applicationIsTerminating && fastDocumentTeardownEnabled()) {
996
        [self _closeWithFastTeardown];
997 998
        return;
    }
thatcher's avatar
thatcher committed
999

darin@apple.com's avatar
darin@apple.com committed
1000
    if (Frame* mainFrame = [self _mainCoreFrame])
darin@apple.com's avatar
darin@apple.com committed
1001
        mainFrame->loader()->detachFromParent();
thatcher's avatar
thatcher committed
1002

ggaren's avatar
ggaren committed
1003
    [self _removeFromAllWebViewsSet];
thatcher's avatar
thatcher committed
1004
    [self setHostWindow:nil];
ggaren's avatar
ggaren committed
1005

thatcher's avatar
thatcher committed
1006 1007 1008 1009 1010 1011 1012
    [self setDownloadDelegate:nil];
    [self setEditingDelegate:nil];
    [self setFrameLoadDelegate:nil];
    [self setPolicyDelegate:nil];
    [self setResourceLoadDelegate:nil];
    [self setScriptDebugDelegate:nil];
    [self setUIDelegate:nil];
timothy@apple.com's avatar
timothy@apple.com committed
1013 1014 1015

    [_private->inspector webViewClosed];

sullivan's avatar
sullivan committed
1016 1017
    // setHostWindow:nil must be called before this value is set (see 5408186)
    _private->closed = YES;
1018

cblu's avatar
cblu committed
1019 1020
    // To avoid leaks, call removeDragCaret in case it wasn't called after moveDragCaretToPoint.
    [self removeDragCaret];
thatcher's avatar
thatcher committed
1021

beidson's avatar
beidson committed
1022 1023 1024
    // 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.
ggaren's avatar
ggaren committed
1025 1026
    delete _private->page;
    _private->page = 0;
thatcher's avatar
thatcher committed
1027

trey's avatar
Tests:  
trey committed
1028 1029 1030 1031
    if (_private->hasSpellCheckerDocumentTag) {
        [[NSSpellChecker sharedSpellChecker] closeSpellDocumentWithTag:_private->spellCheckerDocumentTag];
        _private->hasSpellCheckerDocumentTag = NO;
    }
1032 1033

#if USE(ACCELERATED_COMPOSITING)
1034
    [self _clearLayerSyncLoopObserver];
1035
#endif
kdecker's avatar
 
kdecker committed
1036
    
darin@apple.com's avatar
darin@apple.com committed
1037
    [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
kdecker's avatar
 
kdecker committed
1038
    [[NSNotificationCenter defaultCenter] removeObserver:self];
ggaren's avatar
gtk:  
ggaren committed
1039 1040 1041

    [WebPreferences _removeReferenceForIdentifier:[self preferencesIdentifier]];

1042
    WebPreferences *preferences = _private->preferences;
ggaren's avatar
gtk:  
ggaren committed
1043 1044 1045 1046
    _private->preferences = nil;
    [preferences didRemoveFromWebView];
    [preferences release];

1047
    [self _closePluginDatabases];
1048 1049 1050

#ifndef NDEBUG
    // Need this to make leak messages accurate.
1051
    if (applicationIsTerminating) {
1052
        gcController().garbageCollectNow();
1053
        [WebCache setDisabled:YES];
1054
    }
1055
#endif
1056 1057
}

bolsinga@apple.com's avatar
bolsinga@apple.com committed
1058 1059 1060 1061 1062 1063 1064
// Indicates if the WebView is in the midst of a user gesture.
- (BOOL)_isProcessingUserGesture
{
    WebFrame *frame = [self mainFrame];
    return core(frame)->loader()->isProcessingUserGesture();
}