WebView.mm 172 KB
Newer Older
ddkilzer's avatar
WebKit:    
ddkilzer committed
1
/*
darin@apple.com's avatar
darin@apple.com committed
2
 * Copyright (C) 2005, 2006, 2007, 2008 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
31
#import "WebViewInternal.h"

ggaren's avatar
ggaren committed
32
#import "DOMRangeInternal.h"
beidson's avatar
beidson committed
33
#import "WebBackForwardListInternal.h"
darin's avatar
darin committed
34
#import "WebBaseNetscapePluginView.h"
ggaren's avatar
ggaren committed
35
#import "WebChromeClient.h"
aroben's avatar
aroben committed
36
#import "WebContextMenuClient.h"
darin's avatar
darin committed
37
#import "WebDOMOperationsPrivate.h"
mjs's avatar
mjs committed
38
#import "WebDataSourceInternal.h"
39
#import "WebDatabaseManagerInternal.h"
darin's avatar
darin committed
40
41
42
43
44
45
46
47
#import "WebDefaultEditingDelegate.h"
#import "WebDefaultPolicyDelegate.h"
#import "WebDefaultScriptDebugDelegate.h"
#import "WebDefaultUIDelegate.h"
#import "WebDocument.h"
#import "WebDocumentInternal.h"
#import "WebDownload.h"
#import "WebDownloadInternal.h"
48
#import "WebDragClient.h"
darin@apple.com's avatar
darin@apple.com committed
49
#import "WebDynamicScrollBarsViewInternal.h"
darin's avatar
darin committed
50
#import "WebEditingDelegate.h"
ggaren's avatar
ggaren committed
51
#import "WebEditorClient.h"
darin's avatar
darin committed
52
53
54
55
56
#import "WebFormDelegatePrivate.h"
#import "WebFrameInternal.h"
#import "WebFrameViewInternal.h"
#import "WebHTMLRepresentation.h"
#import "WebHTMLViewInternal.h"
beidson's avatar
beidson committed
57
#import "WebHistoryItemInternal.h"
beidson's avatar
beidson committed
58
#import "WebIconDatabaseInternal.h"
timothy@apple.com's avatar
timothy@apple.com committed
59
#import "WebInspector.h"
aroben's avatar
aroben committed
60
#import "WebInspectorClient.h"
darin's avatar
darin committed
61
62
63
64
#import "WebKitErrors.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
#import "WebKitStatisticsPrivate.h"
ggaren's avatar
gtk:    
ggaren committed
65
#import "WebKitSystemBits.h"
bdakin's avatar
bdakin committed
66
#import "WebKitVersionChecks.h"
darin's avatar
darin committed
67
68
69
70
71
72
73
74
75
76
77
78
#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"
79
#import "WebPDFView.h"
beidson's avatar
beidson committed
80
#import "WebPanelAuthenticationHandler.h"
81
#import "WebPasteboardHelper.h"
darin's avatar
darin committed
82
83
#import "WebPluginDatabase.h"
#import "WebPolicyDelegate.h"
84
#import "WebPreferenceKeysPrivate.h"
darin's avatar
darin committed
85
#import "WebPreferencesPrivate.h"
thatcher's avatar
thatcher committed
86
#import "WebScriptDebugServerPrivate.h"
darin's avatar
darin committed
87
88
89
90
#import "WebUIDelegate.h"
#import "WebUIDelegatePrivate.h"
#import <CoreFoundation/CFSet.h>
#import <Foundation/NSURLConnection.h>
darin's avatar
darin committed
91
#import <JavaScriptCore/Assertions.h>
92
93
94
95
#import <JavaScriptCore/HashTraits.h>
#import <JavaScriptCore/RefPtr.h>
#import <JavaScriptCore/array_object.h>
#import <JavaScriptCore/date_object.h>
andersca@apple.com's avatar
andersca@apple.com committed
96
#import <WebCore/ApplicationCacheStorage.h>
ggaren's avatar
ggaren committed
97
#import <WebCore/Cache.h>
sullivan's avatar
sullivan committed
98
#import <WebCore/ColorMac.h>
ggaren's avatar
ggaren committed
99
#import <WebCore/Document.h>
ggaren's avatar
ggaren committed
100
#import <WebCore/DocumentLoader.h>
101
102
#import <WebCore/DragController.h>
#import <WebCore/DragData.h>
ggaren's avatar
ggaren committed
103
104
#import <WebCore/Editor.h>
#import <WebCore/ExceptionHandlers.h>
mjs's avatar
mjs committed
105
#import <WebCore/Frame.h>
ggaren's avatar
ggaren committed
106
#import <WebCore/FrameLoader.h>
darin's avatar
darin committed
107
#import <WebCore/FrameTree.h>
darin's avatar
darin committed
108
#import <WebCore/HTMLNames.h>
beidson's avatar
beidson committed
109
#import <WebCore/HistoryItem.h>
ggaren's avatar
ggaren committed
110
#import <WebCore/Logging.h>
beidson's avatar
beidson committed
111
#import <WebCore/MIMETypeRegistry.h>
darin's avatar
darin committed
112
#import <WebCore/Page.h>
ggaren's avatar
ggaren committed
113
#import <WebCore/PageCache.h>
beidson@apple.com's avatar
beidson@apple.com committed
114
#import <WebCore/PageGroup.h>
115
#import <WebCore/PlatformMouseEvent.h>
andersca's avatar
andersca committed
116
#import <WebCore/ProgressTracker.h>
ggaren's avatar
ggaren committed
117
#import <WebCore/SelectionController.h>
ggaren's avatar
ggaren committed
118
#import <WebCore/Settings.h>
darin's avatar
darin committed
119
#import <WebCore/TextResourceDecoder.h>
thatcher's avatar
thatcher committed
120
#import <WebCore/WebCoreObjCExtras.h>
darin's avatar
darin committed
121
#import <WebCore/WebCoreTextRenderer.h>
kocienda's avatar
kocienda committed
122
#import <WebCore/WebCoreView.h>
123
#import <WebCore/kjs_proxy.h>
darin's avatar
darin committed
124
125
#import <WebKit/DOM.h>
#import <WebKit/DOMExtensions.h>
darin's avatar
darin committed
126
#import <WebKit/DOMPrivate.h>
darin's avatar
darin committed
127
#import <WebKitSystemInterface.h>
ap@webkit.org's avatar
ap@webkit.org committed
128
#import <kjs/InitializeThreading.h>
ggaren's avatar
gtk:    
ggaren committed
129
#import <mach-o/dyld.h>
130
#import <objc/objc-auto.h>
131
#import <objc/objc-runtime.h>
andersca@apple.com's avatar
andersca@apple.com committed
132
#import <sys/param.h>
133

ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
134
135
136
137
#if ENABLE(DASHBOARD_SUPPORT)
#import <WebKit/WebDashboardRegion.h>
#endif

darin's avatar
darin committed
138
using namespace WebCore;
139
using namespace KJS;
140

141
#if defined(__ppc__) || defined(__ppc64__)
vicki's avatar
vicki committed
142
#define PROCESSOR "PPC"
143
#elif defined(__i386__) || defined(__x86_64__)
vicki's avatar
vicki committed
144
145
146
147
148
#define PROCESSOR "Intel"
#else
#error Unknown architecture
#endif

149
150
151
152
153
154
155
156
#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
157
macro(changeBaseWritingDirection) \
mitz@apple.com's avatar
mitz@apple.com committed
158
159
macro(changeBaseWritingDirectionToLTR) \
macro(changeBaseWritingDirectionToRTL) \
160
161
162
macro(changeColor) \
macro(changeDocumentBackgroundColor) \
macro(changeFont) \
darin@apple.com's avatar
darin@apple.com committed
163
macro(changeSpelling) \
164
165
166
167
168
169
170
171
172
173
174
175
176
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
177
macro(deleteToMark) \
178
179
180
181
182
macro(deleteWordBackward) \
macro(deleteWordForward) \
macro(ignoreSpelling) \
macro(indent) \
macro(insertBacktab) \
darin@apple.com's avatar
darin@apple.com committed
183
macro(insertLineBreak) \
184
185
186
187
188
189
190
191
192
193
194
195
196
197
macro(insertNewline) \
macro(insertNewlineIgnoringFieldEditor) \
macro(insertParagraphSeparator) \
macro(insertTab) \
macro(insertTabIgnoringFieldEditor) \
macro(lowercaseWord) \
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
198
199
macro(moveParagraphBackwardAndModifySelection) \
macro(moveParagraphForwardAndModifySelection) \
200
201
202
203
204
205
206
207
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
208
209
macro(moveToBeginningOfSentence) \
macro(moveToBeginningOfSentenceAndModifySelection) \
210
211
212
213
214
215
macro(moveToEndOfDocument) \
macro(moveToEndOfDocumentAndModifySelection) \
macro(moveToEndOfLine) \
macro(moveToEndOfLineAndModifySelection) \
macro(moveToEndOfParagraph) \
macro(moveToEndOfParagraphAndModifySelection) \
harrison's avatar
harrison committed
216
217
macro(moveToEndOfSentence) \
macro(moveToEndOfSentenceAndModifySelection) \
218
219
220
221
222
223
224
225
226
227
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
228
macro(outdent) \
229
macro(pageDown) \
darin@apple.com's avatar
darin@apple.com committed
230
macro(pageDownAndModifySelection) \
231
macro(pageUp) \
darin@apple.com's avatar
darin@apple.com committed
232
macro(pageUpAndModifySelection) \
233
234
235
236
237
238
239
240
241
macro(paste) \
macro(pasteAsPlainText) \
macro(pasteAsRichText) \
macro(pasteFont) \
macro(performFindPanelAction) \
macro(scrollLineDown) \
macro(scrollLineUp) \
macro(scrollPageDown) \
macro(scrollPageUp) \
sullivan's avatar
sullivan committed
242
243
macro(scrollToBeginningOfDocument) \
macro(scrollToEndOfDocument) \
244
245
246
macro(selectAll) \
macro(selectLine) \
macro(selectParagraph) \
darin@apple.com's avatar
darin@apple.com committed
247
248
249
250
macro(selectSentence) \
macro(selectToMark) \
macro(selectWord) \
macro(setMark) \
251
252
253
254
255
macro(showGuessPanel) \
macro(startSpeaking) \
macro(stopSpeaking) \
macro(subscript) \
macro(superscript) \
darin@apple.com's avatar
darin@apple.com committed
256
257
258
259
macro(swapWithMark) \
macro(takeFindStringFromSelection) \
macro(toggleBaseWritingDirection) \
macro(transpose) \
260
261
262
263
264
265
macro(underline) \
macro(unscript) \
macro(uppercaseWord) \
macro(yank) \
macro(yankAndSelect) \

sullivan's avatar
sullivan committed
266
267
268
#define WebKitOriginalTopPrintingMarginKey @"WebKitOriginalTopMargin"
#define WebKitOriginalBottomPrintingMarginKey @"WebKitOriginalBottomMargin"

darin@apple.com's avatar
darin@apple.com committed
269
270
271
272
#define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange"
#define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode")
#define UniversalAccessDomain CFSTR("com.apple.universalaccess")

ggaren's avatar
gtk:    
ggaren committed
273
274
275
static BOOL s_didSetCacheModel;
static WebCacheModel s_cacheModel = WebCacheModelDocumentViewer;

kdecker's avatar
   
kdecker committed
276
277
278
static BOOL applicationIsTerminating;
static int pluginDatabaseClientCount = 0;

darin's avatar
darin committed
279
280
281
282
@interface NSSpellChecker (AppKitSecretsIKnow)
- (void)_preflightChosenSpellServer;
@end

283
284
@interface NSView (AppKitSecretsIKnow)
- (NSView *)_hitTest:(NSPoint *)aPoint dragTypes:(NSSet *)types;
285
286
- (void)_autoscrollForDraggingInfo:(id)dragInfo timeDelta:(NSTimeInterval)repeatDelta;
- (BOOL)_shouldAutoscrollForDraggingInfo:(id)dragInfo;
287
288
@end

mjs's avatar
mjs committed
289
290
291
292
@interface NSWindow (AppKitSecretsIKnow) 
- (id)_oldFirstResponderBeforeBecoming;
@end

thatcher's avatar
thatcher committed
293
294
295
296
@interface NSObject (ValidateWithoutDelegate)
- (BOOL)validateUserInterfaceItemWithoutDelegate:(id <NSValidatedUserInterfaceItem>)item;
@end

thatcher's avatar
thatcher committed
297
298
299
300
301
302
303
304
305
@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@apple.com's avatar
darin@apple.com committed
306
@interface WebViewPrivate : NSObject {
mjs's avatar
mjs committed
307
@public
ggaren's avatar
ggaren committed
308
    Page* page;
mjs's avatar
mjs committed
309
310
311
312
313
314
315
316
317
318
319
320
321
322
    
    id UIDelegate;
    id UIDelegateForwarder;
    id resourceProgressDelegate;
    id downloadDelegate;
    id policyDelegate;
    id policyDelegateForwarder;
    id frameLoadDelegate;
    id frameLoadDelegateForwarder;
    id <WebFormDelegate> formDelegate;
    id editingDelegate;
    id editingDelegateForwarder;
    id scriptDebugDelegate;
    id scriptDebugDelegateForwarder;
aroben's avatar
aroben committed
323

timothy@apple.com's avatar
timothy@apple.com committed
324
325
    WebInspector *inspector;

326
    BOOL allowsUndo;
beidson's avatar
beidson committed
327
        
hyatt@apple.com's avatar
hyatt@apple.com committed
328
329
    float zoomMultiplier;
    BOOL zoomMultiplierIsTextOnly;
mjs's avatar
mjs committed
330
331

    NSString *applicationNameForUserAgent;
darin's avatar
darin committed
332
    String* userAgent;
mjs's avatar
mjs committed
333
334
335
    BOOL userAgentOverridden;
    
    WebPreferences *preferences;
sullivan's avatar
sullivan committed
336
    BOOL useSiteSpecificSpoofing;
mjs's avatar
mjs committed
337
338
339
340
341
342

    NSWindow *hostWindow;

    int programmaticFocusCount;
    
    WebResourceDelegateImplementationCache resourceLoadDelegateImplementations;
ggaren's avatar
ggaren committed
343
    WebFrameLoadDelegateImplementationCache frameLoadDelegateImplementations;
mjs's avatar
mjs committed
344
345
346

    void *observationInfo;
    
thatcher's avatar
thatcher committed
347
348
    BOOL closed;
    BOOL shouldCloseWithWindow;
thatcher's avatar
thatcher committed
349
    BOOL mainFrameDocumentReady;
mjs's avatar
mjs committed
350
351
    BOOL drawsBackground;
    BOOL editable;
thatcher's avatar
thatcher committed
352
    BOOL tabKeyCyclesThroughElementsChanged;
sullivan's avatar
sullivan committed
353
    BOOL becomingFirstResponder;
mjs's avatar
mjs committed
354
    BOOL becomingFirstResponderFromOutside;
sullivan's avatar
sullivan committed
355
    BOOL hoverFeedbackSuspended;
ggaren's avatar
ggaren committed
356
    BOOL usesPageCache;
thatcher's avatar
thatcher committed
357
    BOOL catchesDelegateExceptions;
thatcher's avatar
thatcher committed
358

thatcher's avatar
thatcher committed
359
360
    NSColor *backgroundColor;

mjs's avatar
mjs committed
361
362
363
    NSString *mediaStyle;
    
    BOOL hasSpellCheckerDocumentTag;
darin's avatar
darin committed
364
    NSInteger spellCheckerDocumentTag;
mjs's avatar
mjs committed
365
366

    BOOL smartInsertDeleteEnabled;
367
        
ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
368
#if ENABLE(DASHBOARD_SUPPORT)
mjs's avatar
mjs committed
369
370
371
372
    BOOL dashboardBehaviorAlwaysSendMouseEventsToAllWindows;
    BOOL dashboardBehaviorAlwaysSendActiveNullEventsToPlugIns;
    BOOL dashboardBehaviorAlwaysAcceptsFirstMouse;
    BOOL dashboardBehaviorAllowWheelScrolling;
ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
373
#endif
mjs's avatar
mjs committed
374
    
kdecker's avatar
   
kdecker committed
375
    // WebKit has both a global plug-in database and a separate, per WebView plug-in database. Dashboard uses the per WebView database.
tomernic's avatar
tomernic committed
376
    WebPluginDatabase *pluginDatabase;
andersca's avatar
andersca committed
377
378
    
    HashMap<unsigned long, RetainPtr<id> >* identifierMap;
darin@apple.com's avatar
darin@apple.com committed
379
380
381

    BOOL _keyboardUIModeAccessed;
    KeyboardUIMode _keyboardUIMode;
mjs's avatar
mjs committed
382
383
384
}
@end

darin's avatar
darin committed
385
@interface WebView (WebFileInternal)
sullivan's avatar
sullivan committed
386
387
388
- (WebFrame *)_selectedOrMainFrame;
- (BOOL)_isLoading;
- (WebFrameView *)_frameViewAtWindowPoint:(NSPoint)point;
sullivan's avatar
sullivan committed
389
- (WebFrame *)_focusedFrame;
mjs's avatar
mjs committed
390
+ (void)_preflightSpellChecker;
darin's avatar
darin committed
391
- (BOOL)_continuousCheckingAllowed;
392
- (NSResponder *)_responderForResponderOperations;
darin's avatar
darin committed
393
394
@end

thatcher's avatar
thatcher committed
395
396
397
@interface WebView (WebCallDelegateFunctions)
@end

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

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

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

426
#define timedLayoutSize 4096
427
428
429

static NSMutableSet *schemesWithRepresentationsSet;

430
431
432
433
434
435
436
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
437
NSString *_WebMainFrameDocumentKey =    @"mainFrameDocument";
438
439
440
441
442
443
444
445
446
447
448
449

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

@implementation WebProgressItem
@end

450
static BOOL continuousSpellCheckingEnabled;
bdash's avatar
bdash committed
451
#ifndef BUILDING_ON_TIGER
sullivan's avatar
sullivan committed
452
453
static BOOL grammarCheckingEnabled;
#endif
454

455
456
@implementation WebViewPrivate

thatcher's avatar
thatcher committed
457
458
459
460
461
462
463
#ifndef BUILDING_ON_TIGER
+ (void)initialize
{
    WebCoreObjCFinalizeOnMainThread(self);
}
#endif

464
465
- init 
{
darin's avatar
darin committed
466
467
468
    self = [super init];
    if (!self)
        return nil;
ap@webkit.org's avatar
ap@webkit.org committed
469
    KJS::initializeThreading();
470
    allowsUndo = YES;
hyatt@apple.com's avatar
hyatt@apple.com committed
471
472
    zoomMultiplier = 1;
    zoomMultiplierIsTextOnly = YES;
ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
473
#if ENABLE(DASHBOARD_SUPPORT)
474
    dashboardBehaviorAllowWheelScrolling = YES;
ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
475
#endif
thatcher's avatar
thatcher committed
476
    shouldCloseWithWindow = objc_collecting_enabled();
477
    continuousSpellCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebContinuousSpellCheckingEnabled];
kdecker's avatar
   
kdecker committed
478

bdash's avatar
bdash committed
479
#ifndef BUILDING_ON_TIGER
sullivan's avatar
sullivan committed
480
481
    grammarCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebGrammarCheckingEnabled];
#endif
darin's avatar
darin committed
482
    userAgent = new String;
sullivan's avatar
sullivan committed
483
    
ggaren's avatar
ggaren committed
484
485
    usesPageCache = YES;
    
andersca's avatar
andersca committed
486
    identifierMap = new HashMap<unsigned long, RetainPtr<id> >();
kdecker's avatar
   
kdecker committed
487
    pluginDatabaseClientCount++;
andersca's avatar
andersca committed
488

489
490
491
492
493
    return self;
}

- (void)dealloc
{
ggaren's avatar
ggaren committed
494
    ASSERT(!page);
ggaren's avatar
gtk:    
ggaren committed
495
    ASSERT(!preferences);
darin's avatar
darin committed
496
497

    delete userAgent;
andersca's avatar
andersca committed
498
499
    delete identifierMap;
    
500
    [applicationNameForUserAgent release];
thatcher's avatar
thatcher committed
501
    [backgroundColor release];
502
    
timothy@apple.com's avatar
timothy@apple.com committed
503
    [inspector release];
504
    [hostWindow release];
aroben's avatar
aroben committed
505

506
507
508
    [policyDelegateForwarder release];
    [UIDelegateForwarder release];
    [frameLoadDelegateForwarder release];
kocienda's avatar
kocienda committed
509
    [editingDelegateForwarder release];
mjs's avatar
mjs committed
510
    [scriptDebugDelegateForwarder release];
511
    
rjw's avatar
rjw committed
512
513
    [mediaStyle release];
    
514
515
516
    [super dealloc];
}

darin's avatar
darin committed
517
518
- (void)finalize
{
thatcher's avatar
thatcher committed
519
    ASSERT_MAIN_THREAD();
520

darin's avatar
darin committed
521
    delete userAgent;
522
523
    delete identifierMap;

darin's avatar
darin committed
524
525
526
    [super finalize];
}

527
528
@end

mjs's avatar
mjs committed
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
@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
559
        allWebViewsSet = CFSetCreateMutable(NULL, 0, &NonRetainingSetCallbacks);
mjs's avatar
mjs committed
560
561
562
563
564
565

    CFSetSetValue(allWebViewsSet, self);
}

@end

566
567
@implementation WebView (WebPrivate)

rjw's avatar
WebKit:    
rjw committed
568
#ifdef DEBUG_WIDGET_DRAWING
569
static bool debugWidget = true;
rjw's avatar
WebKit:    
rjw committed
570
571
572
573
574
575
576
577
- (void)drawRect:(NSRect)rect
{
    [[NSColor blueColor] set];
    NSRectFill (rect);
    
    NSRect htmlViewRect = [[[[self mainFrame] frameView] documentView] frame];

    if (debugWidget) {
darin's avatar
darin committed
578
579
580
        while (debugWidget) {
            sleep (1);
        }
rjw's avatar
WebKit:    
rjw committed
581
582
583
    }

    NSLog (@"%s:   rect:  (%0.f,%0.f) %0.f %0.f, htmlViewRect:  (%0.f,%0.f) %0.f %0.f\n", 
darin's avatar
darin committed
584
585
586
        __PRETTY_FUNCTION__, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height,
        htmlViewRect.origin.x, htmlViewRect.origin.y, htmlViewRect.size.width, htmlViewRect.size.height
    );
rjw's avatar
WebKit:    
rjw committed
587
588
589
590
591

    [super drawRect:rect];
}
#endif

thatcher's avatar
thatcher committed
592
593
594
595
596
597
598
599
600
+ (BOOL)_scriptDebuggerEnabled
{
#ifdef NDEBUG
    return [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitScriptDebuggerEnabled"];
#else
    return YES; // always enable in debug builds
#endif
}

cblu's avatar
WebKit:    
cblu committed
601
602
603
+ (NSArray *)_supportedMIMETypes
{
    // Load the plug-in DB allowing plug-ins to install types.
ggaren's avatar
ggaren committed
604
    [WebPluginDatabase sharedDatabase];
cblu's avatar
WebKit:    
cblu committed
605
606
607
608
609
610
611
612
613
614
    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
615
        NSArray *extensionsForType = WKGetExtensionsForMIMEType(MIMEType);
darin's avatar
darin committed
616
617
        if (extensionsForType) {
            [extensions addObjectsFromArray:extensionsForType];
cblu's avatar
WebKit:    
cblu committed
618
619
620
621
622
623
624
        }
    }
    NSArray *uniqueExtensions = [extensions allObjects];
    [extensions release];
    return uniqueExtensions;
}

625
626
627
+ (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType;
{
    MIMEType = [MIMEType lowercaseString];
eseidel's avatar
eseidel committed
628
629
    Class viewClass = [[WebFrameView _viewTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
    Class repClass = [[WebDataSource _repTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
630
    
ap's avatar
ap committed
631
    if (!viewClass || !repClass || [[WebPDFView supportedMIMETypes] containsObject:MIMEType]) {
eseidel's avatar
eseidel committed
632
633
        // 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
634
        [WebPluginDatabase sharedDatabase];
eseidel's avatar
eseidel committed
635
636
637
638
            
        // 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];
639
640
641
    }
    
    if (viewClass && repClass) {
andersca's avatar
andersca committed
642
643
644
645
        // Special-case WebHTMLView for text types that shouldn't be shown.
        if (viewClass == [WebHTMLView class] &&
            repClass == [WebHTMLRepresentation class] &&
            [[WebHTMLView unsupportedTextMIMETypes] containsObject:MIMEType]) {
646
647
            return NO;
        }
eseidel's avatar
eseidel committed
648
        if (vClass)
649
            *vClass = viewClass;
eseidel's avatar
eseidel committed
650
        if (rClass)
651
652
653
654
655
656
657
            *rClass = repClass;
        return YES;
    }
    
    return NO;
}

tomernic's avatar
tomernic committed
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
- (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType;
{
    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
677
678
+ (void)_setAlwaysUseATSU:(BOOL)f
{
679
    WebCoreSetAlwaysUseATSU(f);
rjw's avatar
rjw committed
680
681
}

682
683
+ (BOOL)canShowFile:(NSString *)path
{
cblu's avatar
cblu committed
684
    return [[self class] canShowMIMEType:[WebView _MIMETypeForFile:path]];
685
686
}

cblu's avatar
cblu committed
687
+ (NSString *)suggestedFileExtensionForMIMEType:(NSString *)type
688
{
mjs's avatar
mjs committed
689
    return WKGetPreferredExtensionForMIMEType(type);
690
691
}

aroben's avatar
aroben committed
692
693
694
695
696
697
698
- (BOOL)_isClosed
{
    if (!_private || _private->closed)
        return YES;
    return NO;
}

699
700
- (void)_close
{
thatcher's avatar
thatcher committed
701
    if (!_private || _private->closed)
thatcher's avatar
thatcher committed
702
703
        return;

704
705
    if (Frame* mainFrame = core([self mainFrame]))
        mainFrame->loader()->detachFromParent();
thatcher's avatar
thatcher committed
706

ggaren's avatar
ggaren committed
707
    [self _removeFromAllWebViewsSet];
thatcher's avatar
thatcher committed
708
    [self setHostWindow:nil];
ggaren's avatar
ggaren committed
709

thatcher's avatar
thatcher committed
710
711
712
713
714
715
716
    [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
717
718
719

    [_private->inspector webViewClosed];

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

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

beidson's avatar
beidson committed
726
727
728
    // 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
729
730
    delete _private->page;
    _private->page = 0;
thatcher's avatar
thatcher committed
731

trey's avatar
Tests:    
trey committed
732
733
734
735
    if (_private->hasSpellCheckerDocumentTag) {
        [[NSSpellChecker sharedSpellChecker] closeSpellDocumentWithTag:_private->spellCheckerDocumentTag];
        _private->hasSpellCheckerDocumentTag = NO;
    }
kdecker's avatar
   
kdecker committed
736
    
darin@apple.com's avatar
darin@apple.com committed
737
    [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
kdecker's avatar
   
kdecker committed
738
    [[NSNotificationCenter defaultCenter] removeObserver:self];
ggaren's avatar
gtk:    
ggaren committed
739
740
741
742
743
744
745
746

    [WebPreferences _removeReferenceForIdentifier:[self preferencesIdentifier]];

    WebPreferences *preferences = _private->preferences;
    _private->preferences = nil;
    [preferences didRemoveFromWebView];
    [preferences release];

kdecker's avatar
   
kdecker committed
747
748
749
750
751
    pluginDatabaseClientCount--;
    
    // Make sure to close both sets of plug-ins databases because plug-ins need an opportunity to clean up files, etc.
    
    // Unload the WebView local plug-in database. 
tomernic's avatar
tomernic committed
752
753
754
755
756
    if (_private->pluginDatabase) {
        [_private->pluginDatabase close];
        [_private->pluginDatabase release];
        _private->pluginDatabase = nil;
    }
kdecker's avatar
   
kdecker committed
757
758
759
    
    // Keep the global plug-in database active until the app terminates to avoid having to reload plug-in bundles.
    if (!pluginDatabaseClientCount && applicationIsTerminating)
adele's avatar
adele committed
760
        [WebPluginDatabase closeSharedDatabase];
761
762
763
764
765
766
767
768
769
}

+ (NSString *)_MIMETypeForFile:(NSString *)path
{
    NSString *extension = [path pathExtension];
    NSString *MIMEType = nil;

    // Get the MIME type from the extension.
    if ([extension length] != 0) {
mjs's avatar
mjs committed
770
        MIMEType = WKGetMIMETypeForExtension(extension);
771
772
773
774
775
    }

    // If we can't get a known MIME type from the extension, sniff.
    if ([MIMEType length] == 0 || [MIMEType isEqualToString:@"application/octet-stream"]) {
        NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
mjs's avatar
mjs committed
776
        NSData *data = [handle readDataOfLength:WEB_GUESS_MIME_TYPE_PEEK_LENGTH];
777
778
        [handle closeFile];
        if ([data length] != 0) {
mjs's avatar
mjs committed
779
            MIMEType = [data _webkit_guessedMIMEType];
780
        }
cblu's avatar
cblu committed
781
        if ([MIMEType length] == 0) {
782
783
784
785
786
787
788
            MIMEType = @"application/octet-stream";
        }
    }

    return MIMEType;
}

tristan's avatar
tristan committed
789
- (WebDownload *)_downloadURL:(NSURL *)URL
790
791
792
793
{
    ASSERT(URL);
    
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:URL];
tristan's avatar
tristan committed
794
795
796
    WebDownload *download = [WebDownload _downloadWithRequest:request
                                                     delegate:_private->downloadDelegate
                                                    directory:nil];
797
    [request release];
tristan's avatar
tristan committed
798
799
    
    return download;
800
801
802
803
}

- (WebView *)_openNewWindowWithRequest:(NSURLRequest *)request
{
tristan's avatar
qt:    
tristan committed
804
805
806
807
808
    NSDictionary *features = [[NSDictionary alloc] init];
    WebView *newWindowWebView = [[self _UIDelegateForwarder] webView:self
                                            createWebViewWithRequest:nil
                                                      windowFeatures:features];
    [features release];
thatcher's avatar
thatcher committed
809
810
    if (!newWindowWebView)
        return nil;
811

thatcher's avatar
thatcher committed
812
    CallUIDelegate(newWindowWebView, @selector(webViewShow:));
813
814
815
    return newWindowWebView;
}

timothy@apple.com's avatar
timothy@apple.com committed
816
817
818
819
820
821
822
- (WebInspector *)inspector
{
    if (!_private->inspector)
        _private->inspector = [[WebInspector alloc] initWithWebView:self];
    return _private->inspector;
}

ggaren's avatar
ggaren committed
823
824
825
826
827
- (WebCore::Page*)page
{
    return _private->page;
}

sullivan's avatar
sullivan committed
828
- (NSMenu *)_menuForElement:(NSDictionary *)element defaultItems:(NSArray *)items
829
{
thatcher's avatar
thatcher committed
830
    NSArray *defaultMenuItems = [[WebDefaultUIDelegate sharedUIDelegate] webView:self contextMenuItemsForElement:element defaultMenuItems:items];
831

thatcher's avatar
thatcher committed
832
833
834
    NSArray *menuItems = CallUIDelegate(self, @selector(webView:contextMenuItemsForElement:defaultMenuItems:), element, defaultMenuItems);
    if (!menuItems)
        return nil;
835

thatcher's avatar
thatcher committed
836
837
838
    unsigned count = [menuItems count];
    if (!count)
        return nil;
839

thatcher's avatar
thatcher committed
840
841
842
    NSMenu *menu = [[NSMenu alloc] init];
    for (unsigned i = 0; i < count; i++)
        [menu addItem:[menuItems objectAtIndex:i]];
843

thatcher's avatar
thatcher committed
844
    return [menu autorelease];
845
846
}

darin's avatar
darin committed
847
- (void)_mouseDidMoveOverElement:(NSDictionary *)dictionary modifierFlags:(NSUInteger)modifierFlags
848
{
thatcher's avatar
thatcher committed
849
850
851
852
    // We originally intended to call this delegate method sometimes with a nil dictionary, but due to
    // a bug dating back to WebKit 1.0 this delegate was never called with nil! Unfortunately we can't
    // start calling this with nil since it will break Adobe Help Viewer, and possibly other clients.
    if (!dictionary)
thatcher's avatar
thatcher committed
853
854
855
        return;
    CallUIDelegate(self, @selector(webView:mouseDidMoveOverElement:modifierFlags:), dictionary, modifierFlags);
}
856
857
858

- (void)_loadBackForwardListFromOtherView:(WebView *)otherView
{
sullivan's avatar
sullivan committed
859
860
861
    if (!_private->page)
        return;
    
darin's avatar
darin committed
862
863
864
    if (!otherView->_private->page)
        return;
    
865
866
867
868
    // It turns out the right combination of behavior is done with the back/forward load
    // type.  (See behavior matrix at the top of WebFramePrivate.)  So we copy all the items
    // in the back forward list, and go to the current one.

beidson's avatar
beidson committed
869
870
    BackForwardList* backForwardList = _private->page->backForwardList();
    ASSERT(!backForwardList->currentItem()); // destination list should be empty
871

beidson's avatar
beidson committed
872
873
    BackForwardList* otherBackForwardList = otherView->_private->page->backForwardList();
    if (!otherBackForwardList->currentItem())
darin's avatar
darin committed
874
        return; // empty back forward list, bail
beidson's avatar
beidson committed
875
876
    
    HistoryItem* newItemToGoTo = 0;
877

beidson's avatar
beidson committed
878
879
    int lastItemIndex = otherBackForwardList->forwardListCount();
    for (int i = -otherBackForwardList->backListCount(); i <= lastItemIndex; ++i) {
880
881
882
883
        if (i == 0) {
            // If this item is showing , save away its current scroll and form state,
            // since that might have changed since loading and it is normally not saved
            // until we leave that page.
beidson's avatar
beidson committed
884
            otherView->_private->page->mainFrame()->loader()->saveDocumentAndScrollState();
885
        }
beidson's avatar
beidson committed
886
887
888
889
        RefPtr<HistoryItem> newItem = otherBackForwardList->itemAtIndex(i)->copy();
        if (i == 0) 
            newItemToGoTo = newItem.get();
        backForwardList->addItem(newItem.release());
890
891
    }
    
beidson's avatar
beidson committed
892
893
    ASSERT(newItemToGoTo);
    _private->page->goToItem(newItemToGoTo, FrameLoadTypeIndexedBackForward);
894
895
896
897
898
899
900
901
902
903
904
905
}

- (void)_setFormDelegate: (id<WebFormDelegate>)delegate
{
    _private->formDelegate = delegate;
}

- (id<WebFormDelegate>)_formDelegate
{
    return _private->formDelegate;
}

thatcher's avatar
thatcher committed
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
- (BOOL)_needsAdobeFrameReloadingQuirk
{
    static BOOL checked = NO;
    static BOOL needsQuirk = NO;

    if (checked)
        return needsQuirk;

    needsQuirk = WKAppVersionCheckLessThan(@"com.adobe.Acrobat", -1, 9.0)
        || WKAppVersionCheckLessThan(@"com.adobe.Acrobat.Pro", -1, 9.0)
        || WKAppVersionCheckLessThan(@"com.adobe.Reader", -1, 9.0)
        || WKAppVersionCheckLessThan(@"com.adobe.distiller", -1, 9.0)
        || WKAppVersionCheckLessThan(@"com.adobe.Contribute", -1, 4.2)
        || WKAppVersionCheckLessThan(@"com.adobe.dreamweaver-9.0", -1, 9.1)
        || WKAppVersionCheckLessThan(@"com.macromedia.fireworks", -1, 9.1)
        || WKAppVersionCheckLessThan(@"com.adobe.InCopy", -1, 5.1)
        || WKAppVersionCheckLessThan(@"com.adobe.InDesign", -1, 5.1)
        || WKAppVersionCheckLessThan(@"com.adobe.Soundbooth", -1, 2);
ap@webkit.org's avatar
ap@webkit.org committed
924
    checked = YES;
thatcher's avatar
thatcher committed
925
926
927
928

    return needsQuirk;
}

ap@webkit.org's avatar
ap@webkit.org committed
929
930
931
932
933
934
935
936
937
- (BOOL)_needsKeyboardEventDisambiguationQuirks
{
    static BOOL checked = NO;
    static BOOL needsQuirks = NO;

    if (checked)
        return needsQuirks;

    needsQuirks = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_IE_COMPATIBLE_KEYBOARD_EVENT_DISPATCH)
darin@apple.com's avatar
darin@apple.com committed
938
        && ![[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Safari"];
ap@webkit.org's avatar
ap@webkit.org committed
939
940
941
942
943
    checked = YES;

    return needsQuirks;
}

944
- (void)_preferencesChangedNotification:(NSNotification *)notification
945
{
946
947
948
    WebPreferences *preferences = (WebPreferences *)[notification object];
    ASSERT(preferences == [self preferences]);
    
ggaren's avatar
gtk:    
ggaren committed
949
950
951
952
953
954
955
    if (!_private->userAgentOverridden)
        *_private->userAgent = String();

    // Cache this value so we don't have to read NSUserDefaults on each page load
    _private->useSiteSpecificSpoofing = [preferences _useSiteSpecificSpoofing];

    // Update corresponding WebCore Settings object.
sullivan's avatar
sullivan committed
956
957
958
    if (!_private->page)
        return;
    
ggaren's avatar
ggaren committed
959
960
961
962
963
964
965
966
    Settings* settings = _private->page->settings();
    
    settings->setCursiveFontFamily([preferences cursiveFontFamily]);
    settings->setDefaultFixedFontSize([preferences defaultFixedFontSize]);
    settings->setDefaultFontSize([preferences defaultFontSize]);
    settings->setDefaultTextEncodingName([preferences defaultTextEncodingName]);
    settings->setFantasyFontFamily([preferences fantasyFontFamily]);
    settings->setFixedFontFamily([preferences fixedFontFamily]);
beidson's avatar
beidson committed
967
968
    settings->setForceFTPDirectoryListings([preferences _forceFTPDirectoryListings]);
    settings->setFTPDirectoryTemplatePath([preferences _ftpDirectoryTemplatePath]);
beidson@apple.com's avatar
beidson@apple.com committed
969
    settings->setLocalStorageDatabasePath([preferences _localStorageDatabasePath]);
ggaren's avatar
ggaren committed
970
971
972
973
974
975
976
977
978
979
980
981
982
    settings->setJavaEnabled([preferences isJavaEnabled]);
    settings->setJavaScriptEnabled([preferences isJavaScriptEnabled]);
    settings->setJavaScriptCanOpenWindowsAutomatically([preferences javaScriptCanOpenWindowsAutomatically]);
    settings->setMinimumFontSize([preferences minimumFontSize]);
    settings->setMinimumLogicalFontSize([preferences minimumLogicalFontSize]);
    settings->setPluginsEnabled([preferences arePlugInsEnabled]);
    settings->setPrivateBrowsingEnabled([preferences privateBrowsingEnabled]);
    settings->setSansSerifFontFamily([preferences sansSerifFontFamily]);
    settings->setSerifFontFamily([preferences serifFontFamily]);
    settings->setStandardFontFamily([preferences standardFontFamily]);
    settings->setLoadsImagesAutomatically([preferences loadsImagesAutomatically]);
    settings->setShouldPrintBackgrounds([preferences shouldPrintBackgrounds]);
    settings->setTextAreasAreResizable([preferences textAreasAreResizable]);
andersca's avatar
andersca committed
983
    settings->setShrinksStandaloneImagesToFit([preferences shrinksStandaloneImagesToFit]);
ggaren's avatar
ggaren committed
984
    settings->setEditableLinkBehavior(core([preferences editableLinkBehavior]));
ggaren's avatar
ggaren committed
985
    settings->setDOMPasteAllowed([preferences isDOMPasteAllowed]);
ggaren's avatar
ggaren committed
986
    settings->setUsesPageCache([self usesPageCache]);
987
    settings->setShowsURLsInToolTips([preferences showsURLsInToolTips]);
988
    settings->setDeveloperExtrasEnabled([preferences developerExtrasEnabled]);
timothy@apple.com's avatar
timothy@apple.com committed
989
    settings->setAuthorAndUserStylesEnabled([preferences authorAndUserStylesEnabled]);
harrison's avatar
harrison committed
990
991
992
993
994
    if ([preferences userStyleSheetEnabled]) {
        NSString* location = [[preferences userStyleSheetLocation] _web_originalDataAsString];
        settings->setUserStyleSheetLocation([NSURL URLWithString:(location ? location : @"")]);
    } else
        settings->setUserStyleSheetLocation([NSURL URLWithString:@""]);
thatcher's avatar
thatcher committed
995
    settings->setNeedsAdobeFrameReloadingQuirk([self _needsAdobeFrameReloadingQuirk]);
ap@webkit.org's avatar
ap@webkit.org committed
996
    settings->setNeedsKeyboardEventDisambiguationQuirks([self _needsKeyboardEventDisambiguationQuirks]);
weinig@apple.com's avatar
weinig@apple.com committed
997
    settings->setNeedsSiteSpecificQuirks(_private->useSiteSpecificSpoofing);
998
    settings->setWebArchiveDebugModeEnabled([preferences webArchiveDebugModeEnabled]);
justin.garcia@apple.com's avatar
justin.garcia@apple.com committed
999
    settings->disableRangeMutationForOldAppleMail(WKAppVersionCheckLessThan(@"com.apple.mail", -1, 4.0));
andersca@apple.com's avatar
andersca@apple.com committed
1000
    settings->setOfflineWebApplicationCacheEnabled([preferences offlineWebApplicationCacheEnabled]);
1001
1002
}

1003
1004
1005
1006
1007
static inline IMP getMethod(id o, SEL s)
{
    return [o respondsToSelector:s] ? [o methodForSelector:s] : 0;
}

1008
1009
- (void)_cacheResourceLoadDelegateImplementations
{
darin's avatar
darin committed
1010
    WebResourceDelegateImplementationCache *cache = &_private->resourceLoadDelegateImplementations;
thatcher's avatar
thatcher committed
1011
    id delegate = _private->resourceProgressDelegate;
darin's avatar
darin committed
1012

1013
1014
1015
1016
1017
    if (!delegate) {
        bzero(cache, sizeof(WebResourceDelegateImplementationCache));
        return;
    }

1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
    cache->didCancelAuthenticationChallengeFunc = getMethod(delegate, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:));
    cache->didFailLoadingWithErrorFromDataSourceFunc = getMethod(delegate, @selector(webView:resource:didFailLoadingWithError:fromDataSource:));
    cache->didFinishLoadingFromDataSourceFunc = getMethod(delegate, @selector(webView:resource:didFinishLoadingFromDataSource:));
    cache->didLoadResourceFromMemoryCacheFunc = getMethod(delegate, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:));
    cache->didReceiveAuthenticationChallengeFunc = getMethod(delegate, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:));
    cache->didReceiveContentLengthFunc = getMethod(delegate, @selector(webView:resource:didReceiveContentLength:fromDataSource:));
    cache->didReceiveResponseFunc = getMethod(delegate, @selector(webView:resource:didReceiveResponse:fromDataSource:));
    cache->identifierForRequestFunc = getMethod(delegate, @selector(webView:identifierForInitialRequest:fromDataSource:));
    cache->plugInFailedWithErrorFunc = getMethod(delegate, @selector(webView:plugInFailedWithError:dataSource:));
    cache->willCacheResponseFunc = getMethod(delegate, @selector(webView:resource:willCacheResponse:fromDataSource:));
    cache->willSendRequestFunc = getMethod(delegate, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:));
mjs's avatar
mjs committed
1029
1030
}

timothy@apple.com's avatar
timothy@apple.com committed
1031
WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *webView)
mjs's avatar
mjs committed
1032
{
timothy@apple.com's avatar
timothy@apple.com committed
1033
    static WebResourceDelegateImplementationCache empty;
1034
    if (!webView)
timothy@apple.com's avatar
timothy@apple.com committed
1035
1036
        return &empty;
    return &webView->_private->resourceLoadDelegateImplementations;
1037
1038
}

ggaren's avatar
ggaren committed
1039
1040
1041
- (void)_cacheFrameLoadDelegateImplementations
{
    WebFrameLoadDelegateImplementationCache *cache = &_private->frameLoadDelegateImplementations;
thatcher's avatar
thatcher committed
1042
    id delegate = _private->frameLoadDelegate;
1043

1044
1045
1046
1047
1048
    if (!delegate) {
        bzero(cache, sizeof(WebFrameLoadDelegateImplementationCache));
        return;
    }

1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
    cache->didCancelClientRedirectForFrameFunc = getMethod(delegate, @selector(webView:didCancelClientRedirectForFrame:));
    cache->didChangeLocationWithinPageForFrameFunc = getMethod(delegate, @selector(webView:didChangeLocationWithinPageForFrame:));
    cache->didClearWindowObjectForFrameFunc = getMethod(delegate, @selector(webView:didClearWindowObject:forFrame:));
    cache->didCommitLoadForFrameFunc = getMethod(delegate, @selector(webView:didCommitLoadForFrame:));
    cache->didFailLoadWithErrorForFrameFunc = getMethod(delegate, @selector(webView:didFailLoadWithError:forFrame:));
    cache->didFailProvisionalLoadWithErrorForFrameFunc = getMethod(delegate, @selector(webView:didFailProvisionalLoadWithError:forFrame:));
    cache->didFinishDocumentLoadForFrameFunc = getMethod(delegate, @selector(webView:didFinishDocumentLoadForFrame:));
    cache->didFinishLoadForFrameFunc = getMethod(delegate, @selector(webView:didFinishLoadForFrame:));
    cache->didFirstLayoutInFrameFunc = getMethod(delegate, @selector(webView:didFirstLayoutInFrame:));
    cache->didHandleOnloadEventsForFrameFunc = getMethod(delegate, @selector(webView:didHandleOnloadEventsForFrame:));
    cache->didReceiveIconForFrameFunc = getMethod(delegate, @selector(webView:didReceiveIcon:forFrame:));
    cache->didReceiveServerRedirectForProvisionalLoadForFrameFunc = getMethod(delegate, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:));
    cache->didReceiveTitleForFrameFunc = getMethod(delegate, @selector(webView:didReceiveTitle:forFrame:));
    cache->didStartProvisionalLoadForFrameFunc = getMethod(delegate, @selector(webView:didStartProvisionalLoadForFrame:));
    cache->willCloseFrameFunc = getMethod(delegate, @selector(webView:willCloseFrame:));
    cache->willPerformClientRedirectToURLDelayFireDateForFrameFunc = getMethod(delegate, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:));
    cache->windowScriptObjectAvailableFunc = getMethod(delegate, @selector(webView:windowScriptObjectAvailable:));
ggaren's avatar
ggaren committed
1066
1067
}

timothy@apple.com's avatar
timothy@apple.com committed
1068
WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *webView)
ggaren's avatar
ggaren committed
1069
{
timothy@apple.com's avatar
timothy@apple.com committed
1070
    static WebFrameLoadDelegateImplementationCache empty;
1071
    if (!webView)
timothy@apple.com's avatar
timothy@apple.com committed
1072
1073
        return &empty;
    return &webView->_private->frameLoadDelegateImplementations;
ggaren's avatar
ggaren committed
1074
1075
}

thatcher's avatar
thatcher committed
1076
- (id)_policyDelegateForwarder
1077
1078
{
    if (!_private->policyDelegateForwarder)
thatcher's avatar
thatcher committed