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

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

darin@apple.com's avatar
darin@apple.com committed
34 35
#import "DOMCSSStyleDeclarationInternal.h"
#import "DOMNodeInternal.h"
ggaren's avatar
ggaren committed
36
#import "DOMRangeInternal.h"
37
#import "WebApplicationCache.h"
beidson's avatar
beidson committed
38
#import "WebBackForwardListInternal.h"
kdecker@apple.com's avatar
kdecker@apple.com committed
39
#import "WebBaseNetscapePluginView.h"
40
#import "WebCache.h"
ggaren's avatar
ggaren committed
41
#import "WebChromeClient.h"
aroben's avatar
aroben committed
42
#import "WebContextMenuClient.h"
darin's avatar
darin committed
43
#import "WebDOMOperationsPrivate.h"
mjs's avatar
mjs committed
44
#import "WebDataSourceInternal.h"
darin@apple.com's avatar
darin@apple.com committed
45
#import "WebDatabaseManagerInternal.h"
darin's avatar
darin committed
46 47 48
#import "WebDefaultEditingDelegate.h"
#import "WebDefaultPolicyDelegate.h"
#import "WebDefaultUIDelegate.h"
weinig@apple.com's avatar
WebKit:  
weinig@apple.com committed
49
#import "WebDelegateImplementationCaching.h"
50 51
#import "WebDeviceOrientationClient.h"
#import "WebDeviceOrientationProvider.h"
darin's avatar
darin committed
52 53 54 55
#import "WebDocument.h"
#import "WebDocumentInternal.h"
#import "WebDownload.h"
#import "WebDownloadInternal.h"
56
#import "WebDragClient.h"
darin@apple.com's avatar
darin@apple.com committed
57
#import "WebDynamicScrollBarsViewInternal.h"
darin's avatar
darin committed
58
#import "WebEditingDelegate.h"
ggaren's avatar
ggaren committed
59
#import "WebEditorClient.h"
darin's avatar
darin committed
60 61 62
#import "WebFormDelegatePrivate.h"
#import "WebFrameInternal.h"
#import "WebFrameViewInternal.h"
63
#import "WebFullScreenController.h"
64
#import "WebGeolocationClient.h"
65
#import "WebGeolocationPositionInternal.h"
darin's avatar
darin committed
66 67
#import "WebHTMLRepresentation.h"
#import "WebHTMLViewInternal.h"
beidson's avatar
beidson committed
68
#import "WebHistoryItemInternal.h"
beidson's avatar
beidson committed
69
#import "WebIconDatabaseInternal.h"
timothy@apple.com's avatar
timothy@apple.com committed
70
#import "WebInspector.h"
aroben's avatar
aroben committed
71
#import "WebInspectorClient.h"
darin's avatar
darin committed
72 73 74 75
#import "WebKitErrors.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
#import "WebKitStatisticsPrivate.h"
ggaren's avatar
gtk:  
ggaren committed
76
#import "WebKitSystemBits.h"
bdakin's avatar
bdakin committed
77
#import "WebKitVersionChecks.h"
darin's avatar
darin committed
78 79 80 81 82 83 84 85 86 87 88 89
#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
90
#import "WebNodeHighlight.h"
darin@apple.com's avatar
darin@apple.com committed
91
#import "WebPDFView.h"
beidson's avatar
beidson committed
92
#import "WebPanelAuthenticationHandler.h"
93
#import "WebPlatformStrategies.h"
darin's avatar
darin committed
94
#import "WebPluginDatabase.h"
95
#import "WebPluginHalterClient.h"
darin's avatar
darin committed
96
#import "WebPolicyDelegate.h"
97
#import "WebPreferenceKeysPrivate.h"
darin's avatar
darin committed
98
#import "WebPreferencesPrivate.h"
99
#import "WebScriptDebugDelegate.h"
100
#import "WebScriptWorldInternal.h"
101
#import "WebSystemInterface.h"
darin@apple.com's avatar
darin@apple.com committed
102
#import "WebTextCompletionController.h"
bdakin@apple.com's avatar
bdakin@apple.com committed
103
#import "WebTextIterator.h"
darin's avatar
darin committed
104 105
#import "WebUIDelegate.h"
#import "WebUIDelegatePrivate.h"
106
#import "WebVideoFullscreenController.h"
darin's avatar
darin committed
107 108
#import <CoreFoundation/CFSet.h>
#import <Foundation/NSURLConnection.h>
109 110
#import <JavaScriptCore/APICast.h>
#import <JavaScriptCore/JSValueRef.h>
111
#import <WebCore/AbstractDatabase.h>
andersca@apple.com's avatar
andersca@apple.com committed
112
#import <WebCore/ApplicationCacheStorage.h>
113
#import <WebCore/BackForwardListImpl.h>
114
#import <WebCore/MemoryCache.h>
sullivan's avatar
sullivan committed
115
#import <WebCore/ColorMac.h>
116
#import <WebCore/CSSComputedStyleDeclaration.h>
117
#import <WebCore/Cursor.h>
ggaren's avatar
ggaren committed
118
#import <WebCore/Document.h>
ggaren's avatar
ggaren committed
119
#import <WebCore/DocumentLoader.h>
120 121
#import <WebCore/DragController.h>
#import <WebCore/DragData.h>
ggaren's avatar
ggaren committed
122
#import <WebCore/Editor.h>
123
#import <WebCore/EventHandler.h>
124
#import <WebCore/ExceptionHandlers.h>
125
#import <WebCore/FocusController.h>
mjs's avatar
mjs committed
126
#import <WebCore/Frame.h>
ggaren's avatar
ggaren committed
127
#import <WebCore/FrameLoader.h>
darin's avatar
darin committed
128
#import <WebCore/FrameTree.h>
weinig@apple.com's avatar
weinig@apple.com committed
129
#import <WebCore/FrameView.h>
130
#import <WebCore/GCController.h>
131
#import <WebCore/HTMLMediaElement.h>
darin's avatar
darin committed
132
#import <WebCore/HTMLNames.h>
beidson's avatar
beidson committed
133
#import <WebCore/HistoryItem.h>
darin@apple.com's avatar
darin@apple.com committed
134
#import <WebCore/IconDatabase.h>
135
#import <WebCore/JSCSSStyleDeclaration.h>
136
#import <WebCore/JSDocument.h>
137
#import <WebCore/JSElement.h>
138
#import <WebCore/JSNodeList.h>
ggaren's avatar
ggaren committed
139
#import <WebCore/Logging.h>
beidson's avatar
beidson committed
140
#import <WebCore/MIMETypeRegistry.h>
141
#import <WebCore/NodeList.h>
darin's avatar
darin committed
142
#import <WebCore/Page.h>
ggaren's avatar
ggaren committed
143
#import <WebCore/PageCache.h>
beidson@apple.com's avatar
beidson@apple.com committed
144
#import <WebCore/PageGroup.h>
145
#import <WebCore/PlatformMouseEvent.h>
andersca's avatar
andersca committed
146
#import <WebCore/ProgressTracker.h>
147
#import <WebCore/RenderView.h>
kdecker@apple.com's avatar
kdecker@apple.com committed
148
#import <WebCore/RenderWidget.h>
weinig@apple.com's avatar
weinig@apple.com committed
149
#import <WebCore/ResourceHandle.h>
150
#import <WebCore/ResourceLoadScheduler.h>
151
#import <WebCore/RuntimeApplicationChecks.h>
152
#import <WebCore/SchemeRegistry.h>
153
#import <WebCore/ScriptController.h>
154
#import <WebCore/ScriptValue.h>
abarth@webkit.org's avatar
abarth@webkit.org committed
155
#import <WebCore/SecurityOrigin.h>
ggaren's avatar
ggaren committed
156
#import <WebCore/SelectionController.h>
ggaren's avatar
ggaren committed
157
#import <WebCore/Settings.h>
darin's avatar
darin committed
158
#import <WebCore/TextResourceDecoder.h>
159
#import <WebCore/ThreadCheck.h>
thatcher's avatar
thatcher committed
160
#import <WebCore/WebCoreObjCExtras.h>
kocienda's avatar
kocienda committed
161
#import <WebCore/WebCoreView.h>
bdakin@apple.com's avatar
bdakin@apple.com committed
162
#import <WebCore/Widget.h>
darin's avatar
darin committed
163 164
#import <WebKit/DOM.h>
#import <WebKit/DOMExtensions.h>
darin's avatar
darin committed
165
#import <WebKit/DOMPrivate.h>
darin's avatar
darin committed
166
#import <WebKitSystemInterface.h>
167 168 169
#import <mach-o/dyld.h>
#import <objc/objc-auto.h>
#import <objc/objc-runtime.h>
170 171
#import <runtime/ArrayPrototype.h>
#import <runtime/DateInstance.h>
172
#import <runtime/InitializeThreading.h>
173
#import <runtime/JSLock.h>
barraclough@apple.com's avatar
barraclough@apple.com committed
174
#import <runtime/JSValue.h>
175 176
#import <wtf/Assertions.h>
#import <wtf/HashTraits.h>
177
#import <wtf/RefCountedLeakCounter.h>
178
#import <wtf/RefPtr.h>
179
#import <wtf/StdLibExtras.h>
180
#import <wtf/Threading.h>
181

182 183 184 185
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
#import <AppKit/NSTextChecker.h>
#endif

ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
186 187 188 189
#if ENABLE(DASHBOARD_SUPPORT)
#import <WebKit/WebDashboardRegion.h>
#endif

190 191 192 193 194
#if ENABLE(CLIENT_BASED_GEOLOCATION)
#import <WebCore/GeolocationController.h>
#import <WebCore/GeolocationError.h>
#endif

195
#if ENABLE(GLIB_SUPPORT)
196 197 198
#import <glib.h>
#endif

darin@apple.com's avatar
darin@apple.com committed
199 200 201 202 203 204 205 206 207 208 209 210
@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;
211
- (void)_enableScreenUpdatesIfNeeded;
212
- (BOOL)_wrapsCarbonWindow;
darin@apple.com's avatar
darin@apple.com committed
213 214
@end

darin's avatar
darin committed
215
using namespace WebCore;
216
using namespace JSC;
217

218
#if defined(__ppc__) || defined(__ppc64__)
vicki's avatar
vicki committed
219
#define PROCESSOR "PPC"
220
#elif defined(__i386__) || defined(__x86_64__)
vicki's avatar
vicki committed
221 222 223 224 225
#define PROCESSOR "Intel"
#else
#error Unknown architecture
#endif

226 227 228 229 230 231 232 233
#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
234
macro(changeBaseWritingDirection) \
mitz@apple.com's avatar
mitz@apple.com committed
235 236
macro(changeBaseWritingDirectionToLTR) \
macro(changeBaseWritingDirectionToRTL) \
237 238 239
macro(changeColor) \
macro(changeDocumentBackgroundColor) \
macro(changeFont) \
darin@apple.com's avatar
darin@apple.com committed
240
macro(changeSpelling) \
241 242 243 244 245 246 247 248 249 250 251 252 253
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
254
macro(deleteToMark) \
255 256 257 258 259
macro(deleteWordBackward) \
macro(deleteWordForward) \
macro(ignoreSpelling) \
macro(indent) \
macro(insertBacktab) \
darin@apple.com's avatar
darin@apple.com committed
260
macro(insertLineBreak) \
261 262 263 264 265 266
macro(insertNewline) \
macro(insertNewlineIgnoringFieldEditor) \
macro(insertParagraphSeparator) \
macro(insertTab) \
macro(insertTabIgnoringFieldEditor) \
macro(lowercaseWord) \
mitz@apple.com's avatar
mitz@apple.com committed
267 268
macro(makeBaseWritingDirectionLeftToRight) \
macro(makeBaseWritingDirectionRightToLeft) \
mitz@apple.com's avatar
mitz@apple.com committed
269 270 271
macro(makeTextWritingDirectionLeftToRight) \
macro(makeTextWritingDirectionNatural) \
macro(makeTextWritingDirectionRightToLeft) \
272 273 274 275 276 277 278 279
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
280 281
macro(moveParagraphBackwardAndModifySelection) \
macro(moveParagraphForwardAndModifySelection) \
282 283 284 285 286 287 288 289
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
290 291
macro(moveToBeginningOfSentence) \
macro(moveToBeginningOfSentenceAndModifySelection) \
292 293 294 295 296 297
macro(moveToEndOfDocument) \
macro(moveToEndOfDocumentAndModifySelection) \
macro(moveToEndOfLine) \
macro(moveToEndOfLineAndModifySelection) \
macro(moveToEndOfParagraph) \
macro(moveToEndOfParagraphAndModifySelection) \
harrison's avatar
harrison committed
298 299
macro(moveToEndOfSentence) \
macro(moveToEndOfSentenceAndModifySelection) \
darin@apple.com's avatar
darin@apple.com committed
300 301 302 303
macro(moveToLeftEndOfLine) \
macro(moveToLeftEndOfLineAndModifySelection) \
macro(moveToRightEndOfLine) \
macro(moveToRightEndOfLineAndModifySelection) \
304 305 306 307 308 309 310 311 312 313
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
314
macro(outdent) \
justin.garcia@apple.com's avatar
justin.garcia@apple.com committed
315
macro(orderFrontSubstitutionsPanel) \
316
macro(pageDown) \
darin@apple.com's avatar
darin@apple.com committed
317
macro(pageDownAndModifySelection) \
318
macro(pageUp) \
darin@apple.com's avatar
darin@apple.com committed
319
macro(pageUpAndModifySelection) \
320 321 322 323 324 325 326 327 328
macro(paste) \
macro(pasteAsPlainText) \
macro(pasteAsRichText) \
macro(pasteFont) \
macro(performFindPanelAction) \
macro(scrollLineDown) \
macro(scrollLineUp) \
macro(scrollPageDown) \
macro(scrollPageUp) \
sullivan's avatar
sullivan committed
329 330
macro(scrollToBeginningOfDocument) \
macro(scrollToEndOfDocument) \
331 332 333
macro(selectAll) \
macro(selectLine) \
macro(selectParagraph) \
darin@apple.com's avatar
darin@apple.com committed
334 335 336 337
macro(selectSentence) \
macro(selectToMark) \
macro(selectWord) \
macro(setMark) \
338 339 340 341 342
macro(showGuessPanel) \
macro(startSpeaking) \
macro(stopSpeaking) \
macro(subscript) \
macro(superscript) \
darin@apple.com's avatar
darin@apple.com committed
343 344 345 346
macro(swapWithMark) \
macro(takeFindStringFromSelection) \
macro(toggleBaseWritingDirection) \
macro(transpose) \
347 348 349 350 351 352
macro(underline) \
macro(unscript) \
macro(uppercaseWord) \
macro(yank) \
macro(yankAndSelect) \

sullivan's avatar
sullivan committed
353 354 355
#define WebKitOriginalTopPrintingMarginKey @"WebKitOriginalTopMargin"
#define WebKitOriginalBottomPrintingMarginKey @"WebKitOriginalBottomMargin"

darin@apple.com's avatar
darin@apple.com committed
356 357 358 359
#define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange"
#define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode")
#define UniversalAccessDomain CFSTR("com.apple.universalaccess")

ggaren's avatar
gtk:  
ggaren committed
360 361 362
static BOOL s_didSetCacheModel;
static WebCacheModel s_cacheModel = WebCacheModelDocumentViewer;

363 364 365 366
#ifndef NDEBUG
static const char webViewIsOpen[] = "At least one WebView is still open.";
#endif

darin@apple.com's avatar
darin@apple.com committed
367
@interface NSObject (WebValidateWithoutDelegate)
thatcher's avatar
thatcher committed
368 369 370
- (BOOL)validateUserInterfaceItemWithoutDelegate:(id <NSValidatedUserInterfaceItem>)item;
@end

thatcher's avatar
thatcher committed
371 372 373 374 375 376 377 378 379
@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
380
@interface WebView (WebFileInternal)
sullivan's avatar
sullivan committed
381 382
- (BOOL)_isLoading;
- (WebFrameView *)_frameViewAtWindowPoint:(NSPoint)point;
sullivan's avatar
sullivan committed
383
- (WebFrame *)_focusedFrame;
mjs's avatar
mjs committed
384
+ (void)_preflightSpellChecker;
darin's avatar
darin committed
385
- (BOOL)_continuousCheckingAllowed;
386
- (NSResponder *)_responderForResponderOperations;
387
#if USE(ACCELERATED_COMPOSITING)
388
- (void)_clearLayerSyncLoopObserver;
389
#endif
390
#if ENABLE(GLIB_SUPPORT)
391 392
- (void)_clearGlibLoopObserver;
#endif
darin's avatar
darin committed
393 394
@end

395 396
static void patchMailRemoveAttributesMethod();

cblu's avatar
cblu committed
397
NSString *WebElementDOMNodeKey =            @"WebElementDOMNode";
cblu's avatar
cblu committed
398 399 400 401 402 403 404
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
405
NSString *WebElementLinkTargetFrameKey =    @"WebElementTargetFrame";
cblu's avatar
cblu committed
406
NSString *WebElementLinkTitleKey =          @"WebElementLinkTitle";
sullivan's avatar
sullivan committed
407
NSString *WebElementLinkURLKey =            @"WebElementLinkURL";
408
NSString *WebElementMediaURLKey =           @"WebElementMediaURL";
sullivan's avatar
sullivan committed
409 410
NSString *WebElementSpellingToolTipKey =    @"WebElementSpellingToolTip";
NSString *WebElementTitleKey =              @"WebElementTitle";
gdennis's avatar
gdennis committed
411
NSString *WebElementLinkIsLiveKey =         @"WebElementLinkIsLive";
412
NSString *WebElementIsInScrollBarKey =      @"WebElementIsInScrollBar";
bdakin's avatar
bdakin committed
413
NSString *WebElementIsContentEditableKey =  @"WebElementIsContentEditableKey";
cblu's avatar
cblu committed
414

415 416 417
NSString *WebViewProgressStartedNotification =          @"WebProgressStartedNotification";
NSString *WebViewProgressEstimateChangedNotification =  @"WebProgressEstimateChangedNotification";
NSString *WebViewProgressFinishedNotification =         @"WebProgressFinishedNotification";
rjw's avatar
WebKit:  
rjw committed
418

kocienda's avatar
kocienda committed
419 420 421 422 423 424
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
425
enum { WebViewVersion = 4 };
rjw's avatar
WebKit:  
rjw committed
426

427
#define timedLayoutSize 4096
428 429 430

static NSMutableSet *schemesWithRepresentationsSet;

431 432 433 434 435 436 437
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
438
NSString *_WebMainFrameDocumentKey =    @"mainFrameDocument";
439

440 441
NSString *_WebViewDidStartAcceleratedCompositingNotification = @"_WebViewDidStartAcceleratedCompositing";

442 443 444 445 446 447 448 449 450 451 452
@interface WebProgressItem : NSObject
{
@public
    long long bytesReceived;
    long long estimatedLength;
}
@end

@implementation WebProgressItem
@end

453
static BOOL continuousSpellCheckingEnabled;
bdash's avatar
bdash committed
454
#ifndef BUILDING_ON_TIGER
sullivan's avatar
sullivan committed
455 456
static BOOL grammarCheckingEnabled;
#endif
adele@apple.com's avatar
adele@apple.com committed
457 458 459 460 461 462 463
#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
464

mjs's avatar
mjs committed
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
@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
495
        allWebViewsSet = CFSetCreateMutable(NULL, 0, &NonRetainingSetCallbacks);
mjs's avatar
mjs committed
496 497 498 499 500 501

    CFSetSetValue(allWebViewsSet, self);
}

@end

502 503
@implementation WebView (WebPrivate)

504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
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];
}

541
+ (NSString *)_standardUserAgentWithApplicationName:(NSString *)applicationName
542
{
543
    // Note: Do *not* move the initialization of osVersion nor webKitVersion into the declaration.
544 545
    // Garbage collection won't correctly mark the global variable in that case <rdar://problem/5733674>.
    static NSString *osVersion;
546
    static NSString *webKitVersion;
547 548
    if (!osVersion)
        osVersion = createMacOSXVersionString();
549 550
    if (!webKitVersion)
        webKitVersion = createUserVisibleWebKitVersionString();
551 552
    NSString *language = [NSUserDefaults _webkit_preferredLanguageCode];
    if ([applicationName length])
553 554
        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];
555 556
}

557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
+ (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));
}

572
static void WebKitInitializeApplicationCachePathIfNecessary()
hyatt@apple.com's avatar
hyatt@apple.com committed
573
{
andersca@apple.com's avatar
andersca@apple.com committed
574
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
575 576 577 578 579 580 581 582 583 584 585 586 587 588
    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;
andersca@apple.com's avatar
andersca@apple.com committed
589
#endif
hyatt@apple.com's avatar
hyatt@apple.com committed
590 591
}

adele@apple.com's avatar
adele@apple.com committed
592 593 594
static bool runningLeopardMail()
{
#ifdef BUILDING_ON_LEOPARD
595
    return applicationIsAppleMail();
adele@apple.com's avatar
adele@apple.com committed
596 597 598 599 600 601 602
#endif
    return NO;
}

static bool runningTigerMail()
{
#ifdef BUILDING_ON_TIGER
603
    return applicationIsAppleMail();
adele@apple.com's avatar
adele@apple.com committed
604 605 606 607
#endif
    return NO;    
}

608 609 610 611 612 613 614 615 616 617
static bool coreVideoHas7228836Fix()
{
#ifdef BUILDING_ON_LEOPARD
    NSBundle* coreVideoFrameworkBundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/CoreVideo.framework"];
    double version = [[coreVideoFrameworkBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey] doubleValue];
    return (version >= 48);
#endif
    return true;
}

ap@apple.com's avatar
ap@apple.com committed
618 619 620 621 622
static bool shouldEnableLoadDeferring()
{
    return !applicationIsAdobeInstaller();
}

623 624
- (void)_dispatchPendingLoadRequests
{
625
    resourceLoadScheduler()->servePendingRequests();
626 627
}

628 629 630 631 632 633 634 635 636
- (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];
}
637

638
- (BOOL)_usesDocumentViews
639
{
darin@apple.com's avatar
darin@apple.com committed
640
    return _private->usesDocumentViews;
641 642
}

643
static NSString *leakMailQuirksUserScriptPath()
644 645 646 647 648 649 650
{
    NSString *scriptPath = [[NSBundle bundleForClass:[WebView class]] pathForResource:@"MailQuirksUserScript" ofType:@"js"];
    return [[NSString alloc] initWithContentsOfFile:scriptPath];
}

- (void)_injectMailQuirksScript
{
651
    static NSString *mailQuirksScriptPath = leakMailQuirksUserScriptPath();
652
    core(self)->group().addUserScriptToWorld(core([WebScriptWorld world]),
653
        mailQuirksScriptPath, KURL(), 0, 0, InjectAtDocumentEnd, InjectInAllFrames);
654 655
}

656 657
- (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews
{
658
    WebCoreThreadViolationCheckRoundTwo();
659

660 661 662 663 664 665 666 667 668 669 670
#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
671
    _private->backgroundColor = [[NSColor colorWithDeviceWhite:1 alpha:1] retain];
darin@apple.com's avatar
darin@apple.com committed
672
    _private->usesDocumentViews = usesDocumentViews;
673
    _private->includesFlattenedCompositingLayersWhenDrawingToBitmap = YES;
674 675

    WebFrameView *frameView = nil;
darin@apple.com's avatar
darin@apple.com committed
676
    if (_private->usesDocumentViews) {
677 678 679 680 681 682 683
        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];
    }

684 685 686 687 688
    static bool didOneTimeInitialization = false;
    if (!didOneTimeInitialization) {
        WebKitInitializeLoggingChannelsIfNecessary();
        WebCore::InitializeLoggingChannelsIfNecessary();
        [WebHistoryItem initWindowWatcherIfNecessary];
689
#if ENABLE(DATABASE)
690
        WebKitInitializeDatabasesIfNecessary();
691
#endif
692 693
        WebKitInitializeApplicationCachePathIfNecessary();
        patchMailRemoveAttributesMethod();
694 695 696
        
        // Initialize our platform strategies.
        WebPlatformStrategies::initialize();
697
        Settings::setMinDOMTimerInterval(0.004);
698

699 700 701
        didOneTimeInitialization = true;
    }

702 703 704 705 706 707 708
    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);
709
#if ENABLE(CLIENT_BASED_GEOLOCATION)
710
    pageClients.geolocationClient = new WebGeolocationClient(self);
711 712 713
#endif
#if ENABLE(DEVICE_ORIENTATION)
    pageClients.deviceOrientationClient = new WebDeviceOrientationClient(self);
714
#endif
715
    _private->page = new Page(pageClients);
716

717
    _private->page->setCanStartMedia([self window]);
718
    _private->page->settings()->setLocalStorageDatabasePath([[self preferences] _localStorageDatabasePath]);
719 720 721

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

timothy@apple.com's avatar
timothy@apple.com committed
722 723 724 725 726 727
#ifndef BUILDING_ON_TIGER
    NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
#else
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
#endif

728
    if (WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOADING_DURING_COMMON_RUNLOOP_MODES))
729
        [self scheduleInRunLoop:runLoop forMode:(NSString *)kCFRunLoopCommonModes];
730
    else
timothy@apple.com's avatar
timothy@apple.com committed
731
        [self scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];
732 733 734 735 736 737 738 739 740 741 742 743 744

    [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];

745 746
    if ([[self class] shouldIncludeInWebKitStatistics])
        ++WebViewCount;
747 748 749 750 751 752 753 754 755 756 757 758

    [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.
759
        SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForAll);
760 761 762
    } 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.
763
        SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData);
764
    }
weinig@apple.com's avatar
weinig@apple.com committed
765 766 767

    if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_CONTENT_SNIFFING_FOR_FILE_URLS))
        ResourceHandle::forceContentSniffing();
768

769
#if ENABLE(GLIB_SUPPORT)
770 771 772
    [self _scheduleGlibContextIterations];
#endif

773 774
    if (runningTigerMail() || runningLeopardMail())
        [self _injectMailQuirksScript];
775 776
}

777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
- (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");
    }
793 794
#endif

795 796 797 798 799 800
    _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
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
- (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
826
{
darin@apple.com's avatar
darin@apple.com committed
827
    ASSERT(!_private->usesDocumentViews);
rjw's avatar
WebKit:  
rjw committed
828
    
hyatt@apple.com's avatar
hyatt@apple.com committed
829 830
    [NSGraphicsContext saveGraphicsState];
    NSRectClip(rect);
rjw's avatar
WebKit:  
rjw committed
831

hyatt@apple.com's avatar
hyatt@apple.com committed
832 833 834
    @try {
        [[self mainFrame] _drawRect:rect contentsOnly:NO];

835
        [[self _UIDelegateForwarder] webView:self didDrawRect:rect];
hyatt@apple.com's avatar
hyatt@apple.com committed
836

837
        if (WebNodeHighlight *currentHighlight = [self currentNodeHighlight])
hyatt@apple.com's avatar
hyatt@apple.com committed
838 839 840 841 842 843 844
            [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
845
    }
hyatt@apple.com's avatar
hyatt@apple.com committed
846 847
}

848 849
- (BOOL)isFlipped 
{
darin@apple.com's avatar
darin@apple.com committed
850
    return _private && !_private->usesDocumentViews;
851 852
}

hyatt@apple.com's avatar
hyatt@apple.com committed
853 854
- (void)setFrameSize:(NSSize)size
{
mitz@apple.com's avatar
mitz@apple.com committed
855
    if (!_private->usesDocumentViews && !NSEqualSizes(_private->lastLayoutSize, size)) {
darin@apple.com's avatar
darin@apple.com committed
856
        Frame* frame = [self _mainCoreFrame];
hyatt@apple.com's avatar
hyatt@apple.com committed
857 858 859 860
        // 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
861
        frame->view()->resize(IntSize(size));
hyatt@apple.com's avatar
hyatt@apple.com committed
862 863 864 865 866 867 868 869
        frame->view()->setNeedsLayout();
        [self setNeedsDisplay:YES];
        _private->lastLayoutSize = size;
    }

    [super setFrameSize:size];
}

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

872 873
- (void)_viewWillDrawInternal
{
darin@apple.com's avatar
darin@apple.com committed
874
    Frame* frame = [self _mainCoreFrame];
875
    if (frame && frame->view())
876
        frame->view()->updateLayoutAndStyleIfNeededRecursive();
877
}
darin@apple.com's avatar
darin@apple.com committed
878

879 880
#endif

881 882 883 884
#ifndef BUILDING_ON_TIGER

- (void)viewWillDraw
{
darin@apple.com's avatar
darin@apple.com committed
885
    if (!_private->usesDocumentViews)
886
        [self _viewWillDrawInternal];
887 888 889 890 891 892
    [super viewWillDraw];
}

#endif


hyatt@apple.com's avatar
hyatt@apple.com committed
893 894
- (void)drawRect:(NSRect)rect
{
darin@apple.com's avatar
darin@apple.com committed
895
    if (_private->usesDocumentViews)
hyatt@apple.com's avatar
hyatt@apple.com committed
896 897 898
        return [super drawRect:rect];
    
    ASSERT_MAIN_THREAD();
rjw's avatar
WebKit:  
rjw committed
899

hyatt@apple.com's avatar
hyatt@apple.com committed
900 901 902
    const NSRect *rects;
    NSInteger count;
    [self getRectsBeingDrawn:&rects count:&count];
rjw's avatar
WebKit:  
rjw committed
903

hyatt@apple.com's avatar
hyatt@apple.com committed
904 905 906 907 908 909
    
    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
910 911
}

cblu's avatar
WebKit:  
cblu committed
912 913 914
+ (NSArray *)_supportedMIMETypes
{
    // Load the plug-in DB allowing plug-ins to install types.
ggaren's avatar
ggaren committed
915
    [WebPluginDatabase sharedDatabase];
cblu's avatar
WebKit:  
cblu committed
916 917 918 919 920 921 922 923 924 925
    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
926
        NSArray *extensionsForType = WKGetExtensionsForMIMEType(MIMEType);
darin's avatar
darin committed
927 928
        if (extensionsForType) {
            [extensions addObjectsFromArray:extensionsForType];
cblu's avatar
WebKit:  
cblu committed
929 930 931 932 933 934 935
        }
    }
    NSArray *uniqueExtensions = [extensions allObjects];
    [extensions release];
    return uniqueExtensions;
}

936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954
static NSMutableSet *knownPluginMIMETypes()
{
    static NSMutableSet *mimeTypes = [[NSMutableSet alloc] init];
    
    return mimeTypes;
}

+ (void)_registerPluginMIMEType:(NSString *)MIMEType
{
    [WebView registerViewClass:[WebHTMLView class] representationClass:[WebHTMLRepresentation class] forMIMEType:MIMEType];
    [knownPluginMIMETypes() addObject:MIMEType];
}

+ (void)_unregisterPluginMIMEType:(NSString *)MIMEType
{
    [self _unregisterViewClassAndRepresentationClassForMIMEType:MIMEType];
    [knownPluginMIMETypes() removeObject:MIMEType];
}

955
+ (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType allowingPlugins:(BOOL)allowPlugins
956 957
{
    MIMEType = [MIMEType lowercaseString];
eseidel's avatar
eseidel committed
958 959
    Class viewClass = [[WebFrameView _viewTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
    Class repClass = [[WebDataSource _repTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
960 961

    if (!viewClass || !repClass || [[WebPDFView supportedMIMETypes] containsObject:MIMEType]) {
eseidel's avatar
eseidel committed
962
        // Our optimization to avoid loading the plug-in DB and image types for the HTML case failed.
963 964 965 966 967 968

        if (allowPlugins) {
            // Load the plug-in DB allowing plug-ins to install types.
            [WebPluginDatabase sharedDatabase];
        }

eseidel's avatar
eseidel committed
969 970 971
        // 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];
972 973 974
    }
    
    if (viewClass && repClass) {
975 976 977 978 979 980 981 982 983 984 985 986 987 988
        if (viewClass == [WebHTMLView class] && repClass == [WebHTMLRepresentation class]) {
            // Special-case WebHTMLView for text types that shouldn't be shown.
            if ([[WebHTMLView unsupportedTextMIMETypes] containsObject:MIMEType])
                return NO;

            // If the MIME type is a known plug-in we might not want to load it.
            if (!allowPlugins && [knownPluginMIMETypes() containsObject:MIMEType]) {
                BOOL isSupportedByWebKit = [[WebHTMLView supportedNonImageMIMETypes] containsObject:MIMEType] ||
                    [[WebHTMLView supportedMIMETypes] containsObject:MIMEType];
                
                // If this is a known plug-in MIME type and WebKit can't show it natively, we don't want to show it.
                if (!isSupportedByWebKit)
                    return NO;
            }
989
        }
eseidel's avatar
eseidel committed
990
        if (vClass)
991
            *vClass = viewClass;
eseidel's avatar
eseidel committed
992
        if (rClass)
993 994 995 996 997 998 999
            *rClass = repClass;
        return YES;
    }
    
    return NO;
}

1000
- (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType
tomernic's avatar
tomernic committed
1001
{
1002
    if ([[self class] _viewClass:vClass andRepresentationClass:rClass forMIMEType:MIMEType allowingPlugins:[_private->preferences arePlugInsEnabled]])
tomernic's avatar
tomernic committed
1003 1004 1005 1006 1007 1008