WebView.mm 128 KB
Newer Older
ddkilzer's avatar
WebKit:  
ddkilzer committed
1
/*
darin's avatar
darin committed
2
 * Copyright (C) 2005, 2006 Apple Computer, 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"
darin's avatar
darin committed
33 34
#import "WebBackForwardList.h"
#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 38
#import "WebDOMOperationsPrivate.h"
#import "WebDashboardRegion.h"
mjs's avatar
mjs committed
39
#import "WebDataSourceInternal.h"
darin's avatar
darin committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#import "WebDefaultEditingDelegate.h"
#import "WebDefaultFrameLoadDelegate.h"
#import "WebDefaultPolicyDelegate.h"
#import "WebDefaultResourceLoadDelegate.h"
#import "WebDefaultScriptDebugDelegate.h"
#import "WebDefaultUIDelegate.h"
#import "WebDocument.h"
#import "WebDocumentInternal.h"
#import "WebDownload.h"
#import "WebDownloadInternal.h"
#import "WebDynamicScrollBarsView.h"
#import "WebEditingDelegate.h"
#import "WebFormDelegatePrivate.h"
#import "WebFrameBridge.h"
#import "WebFrameInternal.h"
#import "WebFrameViewInternal.h"
#import "WebHTMLRepresentation.h"
#import "WebHTMLViewInternal.h"
beidson's avatar
beidson committed
58
#import "WebHistoryItemInternal.h"
darin's avatar
darin committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
#import "WebIconDatabase.h"
#import "WebInspector.h"
#import "WebKitErrors.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
#import "WebKitStatisticsPrivate.h"
#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"
ap's avatar
ap committed
77
#import "WebPDFView.h"
darin's avatar
darin committed
78 79
#import "WebPluginDatabase.h"
#import "WebPolicyDelegate.h"
80
#import "WebPreferenceKeysPrivate.h"
darin's avatar
darin committed
81
#import "WebPreferencesPrivate.h"
darin's avatar
darin committed
82 83
#import "WebResourceLoadDelegate.h"
#import "WebScriptDebugDelegatePrivate.h"
thatcher's avatar
thatcher committed
84
#import "WebScriptDebugServerPrivate.h"
darin's avatar
darin committed
85 86 87 88
#import "WebUIDelegate.h"
#import "WebUIDelegatePrivate.h"
#import <CoreFoundation/CFSet.h>
#import <Foundation/NSURLConnection.h>
darin's avatar
darin committed
89
#import <JavaScriptCore/Assertions.h>
ggaren's avatar
ggaren committed
90
#import <WebCore/Document.h>
ggaren's avatar
ggaren committed
91
#import <WebCore/DocumentLoader.h>
ggaren's avatar
ggaren committed
92 93
#import <WebCore/Editor.h>
#import <WebCore/ExceptionHandlers.h>
ggaren's avatar
ggaren committed
94
#import <WebCore/FrameLoader.h>
darin's avatar
darin committed
95
#import <WebCore/FrameMac.h>
darin's avatar
darin committed
96
#import <WebCore/FrameTree.h>
ggaren's avatar
ggaren committed
97
#import <WebCore/Logging.h>
darin's avatar
darin committed
98
#import <WebCore/Page.h>
ggaren's avatar
ggaren committed
99
#import <WebCore/SelectionController.h>
100
#import <WebCore/WebCoreEncodings.h>
ggaren's avatar
ggaren committed
101
#import <WebCore/WebCoreFrameBridge.h>
102
#import <WebCore/WebCoreSettings.h>
darin's avatar
darin committed
103
#import <WebCore/WebCoreTextRenderer.h>
kocienda's avatar
kocienda committed
104
#import <WebCore/WebCoreView.h>
darin's avatar
darin committed
105 106
#import <WebKit/DOM.h>
#import <WebKit/DOMExtensions.h>
darin's avatar
darin committed
107
#import <WebKit/DOMPrivate.h>
darin's avatar
darin committed
108
#import <WebKitSystemInterface.h>
109
#import <objc/objc-runtime.h>
ggaren's avatar
ggaren committed
110
#import <wtf/RefPtr.h>
111

darin's avatar
darin committed
112
using namespace WebCore;
113

114
#if defined(__ppc__) || defined(__ppc64__)
vicki's avatar
vicki committed
115
#define PROCESSOR "PPC"
116
#elif defined(__i386__) || defined(__x86_64__)
vicki's avatar
vicki committed
117 118 119 120 121
#define PROCESSOR "Intel"
#else
#error Unknown architecture
#endif

122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
#define FOR_EACH_RESPONDER_SELECTOR(macro) \
macro(alignCenter) \
macro(alignJustified) \
macro(alignLeft) \
macro(alignRight) \
macro(capitalizeWord) \
macro(centerSelectionInVisibleArea) \
macro(changeAttributes) \
macro(changeColor) \
macro(changeDocumentBackgroundColor) \
macro(changeFont) \
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) \
macro(deleteWordBackward) \
macro(deleteWordForward) \
macro(ignoreSpelling) \
macro(indent) \
macro(insertBacktab) \
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) \
macro(moveRight) \
macro(moveRightAndModifySelection) \
macro(moveToBeginningOfDocument) \
macro(moveToBeginningOfDocumentAndModifySelection) \
harrison's avatar
harrison committed
169 170
macro(moveToBeginningOfSentence) \
macro(moveToBeginningOfSentenceAndModifySelection) \
171 172 173 174 175 176 177 178 179 180
macro(moveToBeginningOfLine) \
macro(moveToBeginningOfLineAndModifySelection) \
macro(moveToBeginningOfParagraph) \
macro(moveToBeginningOfParagraphAndModifySelection) \
macro(moveToEndOfDocument) \
macro(moveToEndOfDocumentAndModifySelection) \
macro(moveToEndOfLine) \
macro(moveToEndOfLineAndModifySelection) \
macro(moveToEndOfParagraph) \
macro(moveToEndOfParagraphAndModifySelection) \
harrison's avatar
harrison committed
181 182
macro(moveToEndOfSentence) \
macro(moveToEndOfSentenceAndModifySelection) \
183 184 185 186 187 188 189 190 191 192
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
193
macro(outdent) \
194 195 196 197 198 199 200 201 202 203 204
macro(pageDown) \
macro(pageUp) \
macro(paste) \
macro(pasteAsPlainText) \
macro(pasteAsRichText) \
macro(pasteFont) \
macro(performFindPanelAction) \
macro(scrollLineDown) \
macro(scrollLineUp) \
macro(scrollPageDown) \
macro(scrollPageUp) \
sullivan's avatar
sullivan committed
205 206
macro(scrollToBeginningOfDocument) \
macro(scrollToEndOfDocument) \
207
macro(selectAll) \
harrison's avatar
harrison committed
208 209
macro(selectWord) \
macro(selectSentence) \
210 211 212 213 214 215 216 217 218 219 220 221 222
macro(selectLine) \
macro(selectParagraph) \
macro(showGuessPanel) \
macro(startSpeaking) \
macro(stopSpeaking) \
macro(subscript) \
macro(superscript) \
macro(underline) \
macro(unscript) \
macro(uppercaseWord) \
macro(yank) \
macro(yankAndSelect) \

darin's avatar
darin committed
223 224 225 226
@interface NSSpellChecker (AppKitSecretsIKnow)
- (void)_preflightChosenSpellServer;
@end

227 228
@interface NSView (AppKitSecretsIKnow)
- (NSView *)_hitTest:(NSPoint *)aPoint dragTypes:(NSSet *)types;
229 230
- (void)_autoscrollForDraggingInfo:(id)dragInfo timeDelta:(NSTimeInterval)repeatDelta;
- (BOOL)_shouldAutoscrollForDraggingInfo:(id)dragInfo;
231 232
@end

mjs's avatar
mjs committed
233 234 235
@interface WebViewPrivate : NSObject
{
@public
ggaren's avatar
ggaren committed
236
    Page* page;
mjs's avatar
mjs committed
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
    
    id UIDelegate;
    id UIDelegateForwarder;
    id resourceProgressDelegate;
    id resourceProgressDelegateForwarder;
    id downloadDelegate;
    id policyDelegate;
    id policyDelegateForwarder;
    id frameLoadDelegate;
    id frameLoadDelegateForwarder;
    id <WebFormDelegate> formDelegate;
    id editingDelegate;
    id editingDelegateForwarder;
    id scriptDebugDelegate;
    id scriptDebugDelegateForwarder;
    
    WebBackForwardList *backForwardList;
    BOOL useBackForwardList;
    
    float textSizeMultiplier;

    NSString *applicationNameForUserAgent;
darin's avatar
darin committed
259
    String* userAgent;
mjs's avatar
mjs committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
    BOOL userAgentOverridden;
    
    WebPreferences *preferences;
    WebCoreSettings *settings;
        
    BOOL lastElementWasNonNil;

    NSWindow *hostWindow;

    int programmaticFocusCount;
    
    WebResourceDelegateImplementationCache resourceLoadDelegateImplementations;

    long long totalPageAndResourceBytesToLoad;
    long long totalBytesReceived;
    double progressValue;
    double lastNotifiedProgressValue;
    double lastNotifiedProgressTime;
    double progressNotificationInterval;
    double progressNotificationTimeInterval;
    BOOL finalProgressChangedSent;
ggaren's avatar
ggaren committed
281
    WebFrame *originatingProgressFrame;
mjs's avatar
mjs committed
282 283 284 285 286 287
    
    int numProgressTrackedFrames;
    NSMutableDictionary *progressItems;
    
    void *observationInfo;
    
thatcher's avatar
thatcher committed
288 289
    BOOL closed;
    BOOL shouldCloseWithWindow;
thatcher's avatar
thatcher committed
290
    BOOL mainFrameDocumentReady;
mjs's avatar
mjs committed
291 292 293
    BOOL drawsBackground;
    BOOL editable;
    BOOL initiatedDrag;
thatcher's avatar
thatcher committed
294
    BOOL tabKeyCyclesThroughElements;
thatcher's avatar
thatcher committed
295
    BOOL tabKeyCyclesThroughElementsChanged;
thatcher's avatar
thatcher committed
296

thatcher's avatar
thatcher committed
297 298
    NSColor *backgroundColor;

mjs's avatar
mjs committed
299 300 301 302 303 304
    NSString *mediaStyle;
    
    NSView <WebDocumentDragging> *draggingDocumentView;
    unsigned int dragDestinationActionMask;
    
    BOOL hasSpellCheckerDocumentTag;
thatcher's avatar
thatcher committed
305
    WebNSInteger spellCheckerDocumentTag;
mjs's avatar
mjs committed
306 307

    BOOL smartInsertDeleteEnabled;
308
        
mjs's avatar
mjs committed
309 310 311 312 313 314
    BOOL dashboardBehaviorAlwaysSendMouseEventsToAllWindows;
    BOOL dashboardBehaviorAlwaysSendActiveNullEventsToPlugIns;
    BOOL dashboardBehaviorAlwaysAcceptsFirstMouse;
    BOOL dashboardBehaviorAllowWheelScrolling;
    
    BOOL selectWordBeforeMenuEvent;
tomernic's avatar
tomernic committed
315 316
    
    WebPluginDatabase *pluginDatabase;
mjs's avatar
mjs committed
317 318 319
}
@end

darin's avatar
darin committed
320
@interface WebView (WebFileInternal)
sullivan's avatar
sullivan committed
321
- (WebFrame *)_selectedOrMainFrame;
mjs's avatar
mjs committed
322
- (WebFrameBridge *)_bridgeForSelectedOrMainFrame;
sullivan's avatar
sullivan committed
323 324
- (BOOL)_isLoading;
- (WebFrameView *)_frameViewAtWindowPoint:(NSPoint)point;
mjs's avatar
mjs committed
325
- (WebFrameBridge *)_bridgeAtPoint:(NSPoint)point;
sullivan's avatar
sullivan committed
326
- (WebFrame *)_focusedFrame;
mjs's avatar
mjs committed
327
+ (void)_preflightSpellChecker;
darin's avatar
darin committed
328
- (BOOL)_continuousCheckingAllowed;
329
- (NSResponder *)_responderForResponderOperations;
330
- (BOOL)_performTextSizingSelector:(SEL)sel withObject:(id)arg onTrackingDocs:(BOOL)doTrackingViews selForNonTrackingDocs:(SEL)testSel newScaleFactor:(float)newScaleFactor;
harrison's avatar
harrison committed
331
- (void)_notifyTextSizeMultiplierChanged;
darin's avatar
darin committed
332 333
@end

cblu's avatar
cblu committed
334
NSString *WebElementDOMNodeKey =            @"WebElementDOMNode";
cblu's avatar
cblu committed
335 336 337 338 339 340 341
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
342
NSString *WebElementLinkTargetFrameKey =    @"WebElementTargetFrame";
cblu's avatar
cblu committed
343
NSString *WebElementLinkTitleKey =          @"WebElementLinkTitle";
sullivan's avatar
sullivan committed
344 345 346
NSString *WebElementLinkURLKey =            @"WebElementLinkURL";
NSString *WebElementSpellingToolTipKey =    @"WebElementSpellingToolTip";
NSString *WebElementTitleKey =              @"WebElementTitle";
gdennis's avatar
gdennis committed
347
NSString *WebElementLinkIsLiveKey =         @"WebElementLinkIsLive";
bdakin's avatar
bdakin committed
348
NSString *WebElementIsContentEditableKey =  @"WebElementIsContentEditableKey";
cblu's avatar
cblu committed
349

350 351 352
NSString *WebViewProgressStartedNotification =          @"WebProgressStartedNotification";
NSString *WebViewProgressEstimateChangedNotification =  @"WebProgressEstimateChangedNotification";
NSString *WebViewProgressFinishedNotification =         @"WebProgressFinishedNotification";
rjw's avatar
WebKit:  
rjw committed
353

kocienda's avatar
kocienda committed
354 355 356 357 358 359
NSString * const WebViewDidBeginEditingNotification =         @"WebViewDidBeginEditingNotification";
NSString * const WebViewDidChangeNotification =               @"WebViewDidChangeNotification";
NSString * const WebViewDidEndEditingNotification =           @"WebViewDidEndEditingNotification";
NSString * const WebViewDidChangeTypingStyleNotification =    @"WebViewDidChangeTypingStyleNotification";
NSString * const WebViewDidChangeSelectionNotification =      @"WebViewDidChangeSelectionNotification";

360
enum { WebViewVersion = 2 };
rjw's avatar
WebKit:  
rjw committed
361

362
#define timedLayoutSize 4096
363 364 365

static NSMutableSet *schemesWithRepresentationsSet;

366 367 368 369 370 371 372
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
373
NSString *_WebMainFrameDocumentKey =    @"mainFrameDocument";
374 375 376 377 378 379 380 381 382 383 384 385

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

@implementation WebProgressItem
@end

386
static BOOL continuousSpellCheckingEnabled;
sullivan's avatar
sullivan committed
387 388 389
#if !BUILDING_ON_TIGER
static BOOL grammarCheckingEnabled;
#endif
390

391 392 393 394
@implementation WebViewPrivate

- init 
{
darin's avatar
darin committed
395 396 397 398
    self = [super init];
    if (!self)
        return nil;
    
399 400 401
    backForwardList = [[WebBackForwardList alloc] init];
    textSizeMultiplier = 1;
    progressNotificationInterval = 0.02;
rjw's avatar
rjw committed
402
    progressNotificationTimeInterval = 0.1;
403
    settings = [[WebCoreSettings alloc] init];
404
    dashboardBehaviorAllowWheelScrolling = YES;
thatcher's avatar
thatcher committed
405
    tabKeyCyclesThroughElements = YES;
thatcher's avatar
thatcher committed
406
    shouldCloseWithWindow = objc_collecting_enabled();
407
    continuousSpellCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebContinuousSpellCheckingEnabled];
sullivan's avatar
sullivan committed
408 409 410
#if !BUILDING_ON_TIGER
    grammarCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebGrammarCheckingEnabled];
#endif
darin's avatar
darin committed
411
    userAgent = new String;
sullivan's avatar
sullivan committed
412
    
413 414 415 416 417
    return self;
}

- (void)dealloc
{
ggaren's avatar
ggaren committed
418
    ASSERT(!page);
cblu's avatar
cblu committed
419
    ASSERT(draggingDocumentView == nil);
darin's avatar
darin committed
420 421 422

    delete userAgent;

423 424
    [backForwardList release];
    [applicationNameForUserAgent release];
thatcher's avatar
thatcher committed
425
    [backgroundColor release];
426 427 428 429 430 431 432 433 434
    
    [preferences release];
    [settings release];
    [hostWindow release];
    
    [policyDelegateForwarder release];
    [resourceProgressDelegateForwarder release];
    [UIDelegateForwarder release];
    [frameLoadDelegateForwarder release];
kocienda's avatar
kocienda committed
435
    [editingDelegateForwarder release];
mjs's avatar
mjs committed
436
    [scriptDebugDelegateForwarder release];
437 438
    
    [progressItems release];
cblu's avatar
cblu committed
439
        
rjw's avatar
rjw committed
440 441
    [mediaStyle release];
    
442 443 444
    [super dealloc];
}

darin's avatar
darin committed
445 446 447 448 449 450
- (void)finalize
{
    delete userAgent;
    [super finalize];
}

451 452
@end

mjs's avatar
mjs committed
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
@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
483
        allWebViewsSet = CFSetCreateMutable(NULL, 0, &NonRetainingSetCallbacks);
mjs's avatar
mjs committed
484 485 486 487 488 489

    CFSetSetValue(allWebViewsSet, self);
}

@end

490 491
@implementation WebView (WebPrivate)

rjw's avatar
WebKit:  
rjw committed
492
#ifdef DEBUG_WIDGET_DRAWING
493
static bool debugWidget = true;
rjw's avatar
WebKit:  
rjw committed
494 495 496 497 498 499 500 501
- (void)drawRect:(NSRect)rect
{
    [[NSColor blueColor] set];
    NSRectFill (rect);
    
    NSRect htmlViewRect = [[[[self mainFrame] frameView] documentView] frame];

    if (debugWidget) {
darin's avatar
darin committed
502 503 504
        while (debugWidget) {
            sleep (1);
        }
rjw's avatar
WebKit:  
rjw committed
505 506 507
    }

    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
508 509 510
        __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
511 512 513 514 515

    [super drawRect:rect];
}
#endif

thatcher's avatar
thatcher committed
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
+ (BOOL)_developerExtrasEnabled
{
#ifdef NDEBUG
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    BOOL enableDebugger = [defaults boolForKey:@"WebKitDeveloperExtras"];
    if (!enableDebugger)
        enableDebugger = [defaults boolForKey:@"IncludeDebugMenu"];
    return enableDebugger;
#else
    return YES; // always enable in debug builds
#endif
}

+ (BOOL)_scriptDebuggerEnabled
{
#ifdef NDEBUG
    return [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitScriptDebuggerEnabled"];
#else
    return YES; // always enable in debug builds
#endif
}

cblu's avatar
WebKit:  
cblu committed
538 539 540 541 542 543 544 545 546 547 548 549 550 551
+ (NSArray *)_supportedMIMETypes
{
    // Load the plug-in DB allowing plug-ins to install types.
    [WebPluginDatabase installedPlugins];
    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
552
        NSArray *extensionsForType = WKGetExtensionsForMIMEType(MIMEType);
darin's avatar
darin committed
553 554
        if (extensionsForType) {
            [extensions addObjectsFromArray:extensionsForType];
cblu's avatar
WebKit:  
cblu committed
555 556 557 558 559 560 561
        }
    }
    NSArray *uniqueExtensions = [extensions allObjects];
    [extensions release];
    return uniqueExtensions;
}

562 563 564
+ (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType;
{
    MIMEType = [MIMEType lowercaseString];
eseidel's avatar
eseidel committed
565 566
    Class viewClass = [[WebFrameView _viewTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
    Class repClass = [[WebDataSource _repTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
567
    
ap's avatar
ap committed
568
    if (!viewClass || !repClass || [[WebPDFView supportedMIMETypes] containsObject:MIMEType]) {
eseidel's avatar
eseidel committed
569 570 571 572 573 574 575
        // 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.
        [WebPluginDatabase installedPlugins];
            
        // 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];
576 577 578
    }
    
    if (viewClass && repClass) {
andersca's avatar
andersca committed
579 580 581 582
        // Special-case WebHTMLView for text types that shouldn't be shown.
        if (viewClass == [WebHTMLView class] &&
            repClass == [WebHTMLRepresentation class] &&
            [[WebHTMLView unsupportedTextMIMETypes] containsObject:MIMEType]) {
583 584
            return NO;
        }
eseidel's avatar
eseidel committed
585
        if (vClass)
586
            *vClass = viewClass;
eseidel's avatar
eseidel committed
587
        if (rClass)
588 589 590 591 592 593 594
            *rClass = repClass;
        return YES;
    }
    
    return NO;
}

tomernic's avatar
tomernic committed
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
- (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
614 615
+ (void)_setAlwaysUseATSU:(BOOL)f
{
616
    WebCoreSetAlwaysUseATSU(f);
rjw's avatar
rjw committed
617 618
}

619 620
+ (BOOL)canShowFile:(NSString *)path
{
cblu's avatar
cblu committed
621
    return [[self class] canShowMIMEType:[WebView _MIMETypeForFile:path]];
622 623
}

cblu's avatar
cblu committed
624
+ (NSString *)suggestedFileExtensionForMIMEType:(NSString *)type
625
{
mjs's avatar
mjs committed
626
    return WKGetPreferredExtensionForMIMEType(type);
627 628 629 630
}

- (void)_close
{
thatcher's avatar
thatcher committed
631
    if (!_private || _private->closed)
thatcher's avatar
thatcher committed
632
        return;
thatcher's avatar
thatcher committed
633
    _private->closed = YES;
thatcher's avatar
thatcher committed
634

mjs's avatar
mjs committed
635
    [self _removeFromAllWebViewsSet];
thatcher's avatar
thatcher committed
636

mjs's avatar
mjs committed
637
    [self setGroupName:nil];
thatcher's avatar
thatcher committed
638 639 640 641 642 643 644 645
    [self setHostWindow:nil];
    [self setDownloadDelegate:nil];
    [self setEditingDelegate:nil];
    [self setFrameLoadDelegate:nil];
    [self setPolicyDelegate:nil];
    [self setResourceLoadDelegate:nil];
    [self setScriptDebugDelegate:nil];
    [self setUIDelegate:nil];
646

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

darin's avatar
darin committed
650 651 652
    FrameLoader* mainFrameLoader = [[self mainFrame] _frameLoader];
    if (mainFrameLoader)
        mainFrameLoader->detachFromParent();
ggaren's avatar
ggaren committed
653 654 655
    
    delete _private->page;
    _private->page = 0;
thatcher's avatar
thatcher committed
656

657 658
    // 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 [WebHistoryItem _releaseAllPendingPageCaches] for more information.
thatcher's avatar
thatcher committed
659 660 661 662 663 664
    if (_private->backForwardList) {
        [_private->backForwardList _close];
        [_private->backForwardList release];
        _private->backForwardList = nil;
    }

trey's avatar
Tests:  
trey committed
665 666 667 668
    if (_private->hasSpellCheckerDocumentTag) {
        [[NSSpellChecker sharedSpellChecker] closeSpellDocumentWithTag:_private->spellCheckerDocumentTag];
        _private->hasSpellCheckerDocumentTag = NO;
    }
thatcher's avatar
thatcher committed
669

tomernic's avatar
tomernic committed
670 671 672 673 674
    if (_private->pluginDatabase) {
        [_private->pluginDatabase close];
        [_private->pluginDatabase release];
        _private->pluginDatabase = nil;
    }
thatcher's avatar
thatcher committed
675 676 677 678

    [[NSNotificationCenter defaultCenter] removeObserver:self];

    [WebPreferences _removeReferenceForIdentifier: [self preferencesIdentifier]];
679 680 681 682 683 684 685 686 687
}

+ (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
688
        MIMEType = WKGetMIMETypeForExtension(extension);
689 690 691 692 693
    }

    // 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
694
        NSData *data = [handle readDataOfLength:WEB_GUESS_MIME_TYPE_PEEK_LENGTH];
695 696
        [handle closeFile];
        if ([data length] != 0) {
mjs's avatar
mjs committed
697
            MIMEType = [data _webkit_guessedMIMEType];
698
        }
cblu's avatar
cblu committed
699
        if ([MIMEType length] == 0) {
700 701 702 703 704 705 706 707 708 709 710 711 712 713
            MIMEType = @"application/octet-stream";
        }
    }

    return MIMEType;
}

- (void)_downloadURL:(NSURL *)URL
{
    ASSERT(URL);
    
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:URL];
    [WebDownload _downloadWithRequest:request
                             delegate:_private->downloadDelegate
mjs's avatar
mjs committed
714
                            directory:nil];
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
    [request release];
}

- (WebView *)_openNewWindowWithRequest:(NSURLRequest *)request
{
    id wd = [self UIDelegate];
    WebView *newWindowWebView = nil;
    if ([wd respondsToSelector:@selector(webView:createWebViewWithRequest:)])
        newWindowWebView = [wd webView:self createWebViewWithRequest:request];
    else {
        newWindowWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:self createWebViewWithRequest: request];
    }

    [[newWindowWebView _UIDelegateForwarder] webViewShow: newWindowWebView];

    return newWindowWebView;
}

ggaren's avatar
ggaren committed
733 734 735 736 737
- (WebCore::Page*)page
{
    return _private->page;
}

sullivan's avatar
sullivan committed
738
- (NSMenu *)_menuForElement:(NSDictionary *)element defaultItems:(NSArray *)items
739 740
{
    NSArray *defaultMenuItems = [[WebDefaultUIDelegate sharedUIDelegate]
sullivan's avatar
sullivan committed
741
          webView:self contextMenuItemsForElement:element defaultMenuItems:items];
742 743 744 745
    NSArray *menuItems = defaultMenuItems;
    NSMenu *menu = nil;
    unsigned i;

adele's avatar
adele committed
746 747
    DOMNode* node = [element objectForKey:WebElementDOMNodeKey];
    BOOL elementIsTextField = [node isKindOfClass:[DOMHTMLInputElement class]] && [(DOMHTMLInputElement*)node _isTextField];
adele's avatar
adele committed
748 749
    BOOL elementIsTextArea = [node isKindOfClass:[DOMHTMLTextAreaElement class]];
    if (_private->UIDelegate && !elementIsTextField && !elementIsTextArea) {
750 751
        id cd = _private->UIDelegate;
        
sullivan's avatar
sullivan committed
752
        if ([cd respondsToSelector:@selector(webView:contextMenuItemsForElement:defaultMenuItems:)]) {
753
            menuItems = [cd webView:self contextMenuItemsForElement:element defaultMenuItems:defaultMenuItems];
sullivan's avatar
sullivan committed
754 755 756 757 758 759

            // Versions of Mail compiled with older WebKits will end up without three context menu items, though
            // with the separators between them. Here we check for that problem and reinsert the three missing
            // items. This shouldn't affect any clients other than Mail since the tags for the three items
            // were not public API. We can remove this code when we no longer support previously-built versions
            // of Mail on Tiger. See 4498606 for more details.
thatcher's avatar
thatcher committed
760
            if ([menuItems count] && ([[defaultMenuItems objectAtIndex:0] tag] == WebMenuItemTagSearchInSpotlight) && ([[menuItems objectAtIndex:0] isSeparatorItem])) {
sullivan's avatar
sullivan committed
761 762 763 764 765 766 767 768 769 770 771 772
                ASSERT([[menuItems objectAtIndex:1] isSeparatorItem]);
                ASSERT([[defaultMenuItems objectAtIndex:1] tag] == WebMenuItemTagSearchWeb);
                ASSERT([[defaultMenuItems objectAtIndex:2] isSeparatorItem]);
                ASSERT([[defaultMenuItems objectAtIndex:3] tag] == WebMenuItemTagLookUpInDictionary);
                ASSERT([[defaultMenuItems objectAtIndex:4] isSeparatorItem]);
                NSMutableArray *mutableMenuItems = [NSMutableArray arrayWithArray:menuItems];
                [mutableMenuItems insertObject:[defaultMenuItems objectAtIndex:0] atIndex:0];
                [mutableMenuItems insertObject:[defaultMenuItems objectAtIndex:1] atIndex:1];
                [mutableMenuItems insertObject:[defaultMenuItems objectAtIndex:3] atIndex:3];
                menuItems = mutableMenuItems;
            }
        }
773 774 775 776 777 778 779 780 781 782
    } 

    if (menuItems && [menuItems count] > 0) {
        menu = [[[NSMenu alloc] init] autorelease];

        for (i=0; i<[menuItems count]; i++) {
            [menu addItem:[menuItems objectAtIndex:i]];
        }
    }

thatcher's avatar
thatcher committed
783 784 785
    // optionally add the Inspect Element menu item it if preference is set or in debug builds
    // and only showing the menu item if we are working with a WebHTMLView
    WebFrame *webFrame = [element objectForKey:WebElementFrameKey];
thatcher's avatar
thatcher committed
786
    if ([WebView _developerExtrasEnabled] && [[[webFrame frameView] documentView] isKindOfClass:[WebHTMLView class]]) {
thatcher's avatar
thatcher committed
787 788 789 790 791 792 793 794 795 796 797
        if (!menu)
            menu = [[[NSMenu alloc] init] autorelease];
        else if ([menu numberOfItems])
            [menu addItem:[NSMenuItem separatorItem]];
        NSMenuItem *menuItem = [[[NSMenuItem alloc] init] autorelease];
        [menuItem setAction:@selector(_inspectElement:)];
        [menuItem setTitle:UI_STRING("Inspect Element", "Inspect Element context menu item")];
        [menuItem setRepresentedObject:element];
        [menu addItem:menuItem];
    }

798 799 800
    return menu;
}

thatcher's avatar
thatcher committed
801
- (void)_mouseDidMoveOverElement:(NSDictionary *)dictionary modifierFlags:(WebNSUInteger)modifierFlags
802 803 804 805 806 807 808 809 810 811 812 813 814 815
{
    // When the mouse isn't over this view at all, we'll get called with a dictionary of nil over
    // and over again. So it's a good idea to catch that here and not send multiple calls to the delegate
    // for that case.
    
    if (dictionary && _private->lastElementWasNonNil) {
        [[self _UIDelegateForwarder] webView:self mouseDidMoveOverElement:dictionary modifierFlags:modifierFlags];
    }
    _private->lastElementWasNonNil = dictionary != nil;
}

- (void)_goToItem:(WebHistoryItem *)item withLoadType:(WebFrameLoadType)type
{
    // We never go back/forward on a per-frame basis, so the target must be the main frame
rjw's avatar
WebKit:  
rjw committed
816
    //ASSERT([item target] == nil || [self _findFrameNamed:[item target]] == [self mainFrame]);
817 818 819

    // abort any current load if we're going back/forward
    [[self mainFrame] stopLoading];
darin's avatar
darin committed
820
    [[self mainFrame] _goToItem:item withLoadType:(FrameLoadType)type];
821 822 823 824 825 826 827 828 829
}

- (void)_loadBackForwardListFromOtherView:(WebView *)otherView
{
    // 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.

    WebBackForwardList *bfList = [self backForwardList];
darin's avatar
darin committed
830
    ASSERT(![bfList currentItem]); // destination list should be empty
831 832 833

    WebBackForwardList *otherBFList = [otherView backForwardList];
    if (![otherBFList currentItem]) {
darin's avatar
darin committed
834
        return; // empty back forward list, bail
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871
    }

    WebHistoryItem *newItemToGoTo = nil;
    int lastItemIndex = [otherBFList forwardListCount];
    int i;
    for (i = -[otherBFList backListCount]; i <= lastItemIndex; i++) {
        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.
            [[otherView mainFrame] _saveDocumentAndScrollState];
        }
        WebHistoryItem *newItem = [[otherBFList itemAtIndex:i] copy];
        [bfList addItem:newItem];
        if (i == 0) {
            newItemToGoTo = newItem;
        }
    }
    
    [self _goToItem:newItemToGoTo withLoadType:WebFrameLoadTypeIndexedBackForward];
}

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

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

- (WebCoreSettings *)_settings
{
    return _private->settings;
}

mjs's avatar
mjs committed
872
- (void)_updateWebCoreSettingsFromPreferences:(WebPreferences *)preferences
873 874 875 876 877 878 879 880 881 882 883
{
    [_private->settings setCursiveFontFamily:[preferences cursiveFontFamily]];
    [_private->settings setDefaultFixedFontSize:[preferences defaultFixedFontSize]];
    [_private->settings setDefaultFontSize:[preferences defaultFontSize]];
    [_private->settings setDefaultTextEncoding:[preferences defaultTextEncodingName]];
    [_private->settings setFantasyFontFamily:[preferences fantasyFontFamily]];
    [_private->settings setFixedFontFamily:[preferences fixedFontFamily]];
    [_private->settings setJavaEnabled:[preferences isJavaEnabled]];
    [_private->settings setJavaScriptEnabled:[preferences isJavaScriptEnabled]];
    [_private->settings setJavaScriptCanOpenWindowsAutomatically:[preferences javaScriptCanOpenWindowsAutomatically]];
    [_private->settings setMinimumFontSize:[preferences minimumFontSize]];
884
    [_private->settings setMinimumLogicalFontSize:[preferences minimumLogicalFontSize]];
885
    [_private->settings setPluginsEnabled:[preferences arePlugInsEnabled]];
sullivan's avatar
sullivan committed
886
    [_private->settings setPrivateBrowsingEnabled:[preferences privateBrowsingEnabled]];
887 888 889 890 891 892 893 894 895 896 897
    [_private->settings setSansSerifFontFamily:[preferences sansSerifFontFamily]];
    [_private->settings setSerifFontFamily:[preferences serifFontFamily]];
    [_private->settings setStandardFontFamily:[preferences standardFontFamily]];
    [_private->settings setWillLoadImagesAutomatically:[preferences loadsImagesAutomatically]];

    if ([preferences userStyleSheetEnabled]) {
        [_private->settings setUserStyleSheetLocation:[[preferences userStyleSheetLocation] _web_originalDataAsString]];
    } else {
        [_private->settings setUserStyleSheetLocation:@""];
    }
    [_private->settings setShouldPrintBackgrounds:[preferences shouldPrintBackgrounds]];
sullivan's avatar
sullivan committed
898
    [_private->settings setTextAreasAreResizable:[preferences textAreasAreResizable]];
899
    [_private->settings setEditableLinkBehavior:[preferences editableLinkBehavior]];
900 901 902 903 904 905 906
}

- (void)_preferencesChangedNotification: (NSNotification *)notification
{
    WebPreferences *preferences = (WebPreferences *)[notification object];
    
    ASSERT(preferences == [self preferences]);
darin's avatar
darin committed
907 908
    if (!_private->userAgentOverridden)
        *_private->userAgent = String();
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927
    [self _updateWebCoreSettingsFromPreferences: preferences];
}

- _frameLoadDelegateForwarder
{
    if (!_private->frameLoadDelegateForwarder)
        _private->frameLoadDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self frameLoadDelegate]  defaultTarget: [WebDefaultFrameLoadDelegate sharedFrameLoadDelegate] templateClass: [WebDefaultFrameLoadDelegate class]];
    return _private->frameLoadDelegateForwarder;
}

- _resourceLoadDelegateForwarder
{
    if (!_private->resourceProgressDelegateForwarder)
        _private->resourceProgressDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self resourceLoadDelegate] defaultTarget: [WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] templateClass: [WebDefaultResourceLoadDelegate class]];
    return _private->resourceProgressDelegateForwarder;
}

- (void)_cacheResourceLoadDelegateImplementations
{
darin's avatar
darin committed
928 929
    WebResourceDelegateImplementationCache *cache = &_private->resourceLoadDelegateImplementations;
    id delegate = [self resourceLoadDelegate];
mjs's avatar
mjs committed
930
    Class delegateClass = [delegate class];
darin's avatar
darin committed
931 932 933 934 935 936 937 938

    cache->delegateImplementsDidCancelAuthenticationChallenge = [delegate respondsToSelector:@selector(webView:resource:didCancelAuthenticationChallenge:fromDataSource:)];
    cache->delegateImplementsDidReceiveAuthenticationChallenge = [delegate respondsToSelector:@selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:)];
    cache->delegateImplementsDidFinishLoadingFromDataSource = [delegate respondsToSelector:@selector(webView:resource:didFinishLoadingFromDataSource:)];
    cache->delegateImplementsDidReceiveContentLength = [delegate respondsToSelector:@selector(webView:resource:didReceiveContentLength:fromDataSource:)];
    cache->delegateImplementsDidReceiveResponse = [delegate respondsToSelector:@selector(webView:resource:didReceiveResponse:fromDataSource:)];
    cache->delegateImplementsWillSendRequest = [delegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)];
    cache->delegateImplementsIdentifierForRequest = [delegate respondsToSelector:@selector(webView:identifierForInitialRequest:fromDataSource:)];
mjs's avatar
mjs committed
939 940
    cache->delegateImplementsDidLoadResourceFromMemoryCache = [delegate respondsToSelector:@selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:)];

thatcher's avatar
thatcher committed
941 942 943 944 945 946
#if defined(OBJC_API_VERSION) && OBJC_API_VERSION > 0
#define GET_OBJC_METHOD_IMP(class,selector) class_getMethodImplementation(class, selector)
#else
#define GET_OBJC_METHOD_IMP(class,selector) class_getInstanceMethod(class, selector)->method_imp
#endif

mjs's avatar
mjs committed
947
    if (cache->delegateImplementsDidCancelAuthenticationChallenge)
thatcher's avatar
thatcher committed
948
        cache->didCancelAuthenticationChallengeFunc = (WebDidCancelAuthenticationChallengeFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:));
mjs's avatar
mjs committed
949
    if (cache->delegateImplementsDidReceiveAuthenticationChallenge)
thatcher's avatar
thatcher committed
950
        cache->didReceiveAuthenticationChallengeFunc = (WebDidReceiveAuthenticationChallengeFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:));
mjs's avatar
mjs committed
951
    if (cache->delegateImplementsDidFinishLoadingFromDataSource)
thatcher's avatar
thatcher committed
952
        cache->didFinishLoadingFromDataSourceFunc = (WebDidFinishLoadingFromDataSourceFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didFinishLoadingFromDataSource:));
mjs's avatar
mjs committed
953
    if (cache->delegateImplementsDidReceiveContentLength)
thatcher's avatar
thatcher committed
954
        cache->didReceiveContentLengthFunc = (WebDidReceiveContentLengthFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveContentLength:fromDataSource:));
mjs's avatar
mjs committed
955
    if (cache->delegateImplementsDidReceiveResponse)
thatcher's avatar
thatcher committed
956
        cache->didReceiveResponseFunc = (WebDidReceiveResponseFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveResponse:fromDataSource:));
mjs's avatar
mjs committed
957
    if (cache->delegateImplementsWillSendRequest)
thatcher's avatar
thatcher committed
958
        cache->willSendRequestFunc = (WebWillSendRequestFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:));
mjs's avatar
mjs committed
959
    if (cache->delegateImplementsIdentifierForRequest)
thatcher's avatar
thatcher committed
960
        cache->identifierForRequestFunc = (WebIdentifierForRequestFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:identifierForInitialRequest:fromDataSource:));
mjs's avatar
mjs committed
961
    if (cache->delegateImplementsDidLoadResourceFromMemoryCache)
thatcher's avatar
thatcher committed
962 963 964
        cache->didLoadResourceFromMemoryCacheFunc = (WebDidLoadResourceFromMemoryCacheFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:));

#undef GET_OBJC_METHOD_IMP
965 966
}

mjs's avatar
mjs committed
967
id WebViewGetResourceLoadDelegate(WebView *webView)
968
{
mjs's avatar
mjs committed
969 970 971 972 973 974
    return webView->_private->resourceProgressDelegate;
}

WebResourceDelegateImplementationCache WebViewGetResourceLoadDelegateImplementations(WebView *webView)
{
    return webView->_private->resourceLoadDelegateImplementations;
975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
}

- _policyDelegateForwarder
{
    if (!_private->policyDelegateForwarder)
        _private->policyDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self policyDelegate] defaultTarget: [WebDefaultPolicyDelegate sharedPolicyDelegate] templateClass: [WebDefaultPolicyDelegate class]];
    return _private->policyDelegateForwarder;
}

- _UIDelegateForwarder
{
    if (!_private->UIDelegateForwarder)
        _private->UIDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self UIDelegate] defaultTarget: [WebDefaultUIDelegate sharedUIDelegate] templateClass: [WebDefaultUIDelegate class]];
    return _private->UIDelegateForwarder;
}

kocienda's avatar
kocienda committed
991 992
- _editingDelegateForwarder
{
darin's avatar
darin committed
993 994 995 996
    // This can be called during window deallocation by QTMovieView in the QuickTime Cocoa Plug-in.
    // Not sure if that is a bug or not.
    if (!_private)
        return nil;
kocienda's avatar
kocienda committed
997 998 999 1000 1001
    if (!_private->editingDelegateForwarder)
        _private->editingDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self editingDelegate] defaultTarget: [WebDefaultEditingDelegate sharedEditingDelegate] templateClass: [WebDefaultEditingDelegate class]];
    return _private->editingDelegateForwarder;
}

mjs's avatar
mjs committed
1002 1003 1004 1005 1006 1007 1008
- _scriptDebugDelegateForwarder
{
    if (!_private->scriptDebugDelegateForwarder)
        _private->scriptDebugDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self scriptDebugDelegate] defaultTarget: [WebDefaultScriptDebugDelegate sharedScriptDebugDelegate] templateClass: [WebDefaultScriptDebugDelegate class]];
    return _private->scriptDebugDelegateForwarder;
}

1009 1010 1011 1012 1013
- (void)_closeWindow
{
    [[self _UIDelegateForwarder] webViewClose:self];
}

cblu's avatar
cblu committed
1014 1015 1016 1017 1018 1019
+ (void)_unregisterViewClassAndRepresentationClassForMIMEType:(NSString *)MIMEType;
{
    [[WebFrameView _viewTypesAllowImageTypeOmission:NO] removeObjectForKey:MIMEType];
    [[WebDataSource _repTypesAllowImageTypeOmission:NO] removeObjectForKey:MIMEType];
}

1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
+ (void)_registerViewClass:(Class)viewClass representationClass:(Class)representationClass forURLScheme:(NSString *)URLScheme;
{
    NSString *MIMEType = [self _generatedMIMETypeForURLScheme:URLScheme];
    [self registerViewClass:viewClass representationClass:representationClass forMIMEType:MIMEType];

    // This is used to make _representationExistsForURLScheme faster.
    // Without this set, we'd have to create the MIME type each time.
    if (schemesWithRepresentationsSet == nil) {
        schemesWithRepresentationsSet = [[NSMutableSet alloc] init];
    }
    [schemesWithRepresentationsSet addObject:[[[URLScheme lowercaseString] copy] autorelease]];
}

mjs's avatar
mjs committed
1033 1034 1035 1036 1037
+ (NSString *)_generatedMIMETypeForURLScheme:(NSString *)URLScheme
{
    return [@"x-apple-web-kit/" stringByAppendingString:[URLScheme lowercaseString]];
}

1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
+ (BOOL)_representationExistsForURLScheme:(NSString *)URLScheme
{
    return [schemesWithRepresentationsSet containsObject:[URLScheme lowercaseString]];
}

+ (BOOL)_canHandleRequest:(NSURLRequest *)request
{
    if ([NSURLConnection canHandleRequest:request]) {
        return YES;
    }

    return [self _representationExistsForURLScheme:[[request URL] scheme]];
}

+ (NSString *)_decodeData:(NSData *)data
{
    return [WebCoreEncodings decodeData:data];
}

- (void)_pushPerformingProgrammaticFocus
{
    _private->programmaticFocusCount++;
}

- (void)_popPerformingProgrammaticFocus
{
    _private->programmaticFocusCount--;
}

- (BOOL)_isPerformingProgrammaticFocus
{
    return _private->programmaticFocusCount != 0;
}

#define UnknownTotalBytes -1
#define WebProgressItemDefaultEstimatedLength 1024*16

- (void)_didChangeValueForKey: (NSString *)key
{
    LOG (Bindings, "calling didChangeValueForKey: %@", key);
    [self didChangeValueForKey: key];
}

- (void)_willChangeValueForKey: (NSString *)key
{
    LOG (Bindings, "calling willChangeValueForKey: %@", key);
    [self willChangeValueForKey: key];
}

ggaren's avatar
ggaren committed
1087 1088
// Always start progress at INITIAL_PROGRESS_VALUE. This helps provide feedback as 
// soon as a load starts.
rjw's avatar
rjw committed
1089
#define INITIAL_PROGRESS_VALUE 0.1
ggaren's avatar
ggaren committed
1090 1091 1092
// Similarly, always leave space at the end. This helps show the user that we're not done
// until we're done.
#define FINAL_PROGRESS_VALUE 1.0 - INITIAL_PROGRESS_VALUE
1093

rjw's avatar
rjw committed
1094 1095 1096 1097 1098 1099
- (void)_resetProgress
{
    [_private->progressItems release];
    _private->progressItems = nil;
    _private->totalPageAndResourceBytesToLoad = 0;
    _private->totalBytesReceived = 0;
rjw's avatar
rjw committed
1100
    _private->progressValue = 0;
rjw's avatar
rjw committed
1101 1102 1103 1104
    _private->lastNotifiedProgressValue = 0;
    _private->lastNotifiedProgressTime = 0;
    _private->finalProgressChangedSent = NO;
    _private->numProgressTrackedFrames = 0;
ggaren's avatar
ggaren committed
1105 1106
    [_private->originatingProgressFrame release];
    _private->originatingProgressFrame = nil;
rjw's avatar
rjw committed
1107 1108 1109
}
- (void)_progressStarted:(WebFrame *)frame
{
ggaren's avatar
ggaren committed
1110
    LOG (Progress, "frame %p(%@), _private->numProgressTrackedFrames %d, _private->originatingProgressFrame %p", frame, [frame name], _private->numProgressTrackedFrames, _private->originatingProgressFrame);
1111
    [self _willChangeValueForKey: @"estimatedProgress"];
ggaren's avatar
ggaren committed
1112
    if (_private->numProgressTrackedFrames == 0 || _private->originatingProgressFrame == frame){
rjw's avatar
rjw committed
1113
        [self _resetProgress];
rjw's avatar
rjw committed
1114
        _private->progressValue = INITIAL_PROGRESS_VALUE;
ggaren's avatar
ggaren committed
1115
        _private->originatingProgressFrame = [frame retain];
1116 1117 1118 1119 1120 1121
        [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressStartedNotification object:self];
    }
    _private->numProgressTrackedFrames++;
    [self _didChangeValueForKey: @"estimatedProgress"];
}

rjw's avatar
rjw committed
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
- (void)_finalProgressComplete
{
    LOG (Progress, "");

    // Before resetting progress value be sure to send client a least one notification
    // with final progress value.
    if (!_private->finalProgressChangedSent) {
        _private->progressValue = 1;
        [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressEstimateChangedNotification object:self];
    }
    
    [self _resetProgress];
    
thatcher's avatar
thatcher committed
1135
    [self setMainFrameDocumentReady:YES];   // make sure this is turned on at this point
rjw's avatar
rjw committed
1136 1137 1138 1139
    [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressFinishedNotification object:self];
}

- (void)_progressCompleted:(WebFrame *)frame
rjw's avatar
rjw committed
1140
{    
ggaren's avatar
ggaren committed
1141
    LOG (Progress, "frame %p(%@), _private->numProgressTrackedFrames %d, _private->originatingProgressFrame %p", frame, [frame name], _private->numProgressTrackedFrames, _private->originatingProgressFrame);
rjw's avatar
rjw committed
1142 1143 1144 1145

    if (_private->numProgressTrackedFrames <= 0)
        return;

1146
    [self _willChangeValueForKey: @"estimatedProgress"];
rjw's avatar
rjw committed
1147 1148

    _private->numProgressTrackedFrames--;
rjw's avatar
rjw committed
1149
    if (_private->numProgressTrackedFrames == 0 ||
ggaren's avatar
ggaren committed
1150
        (frame == _private->originatingProgressFrame && _private->numProgressTrackedFrames != 0)){
rjw's avatar
rjw committed
1151
        [self _finalProgressComplete];
1152 1153 1154 1155
    }
    [self _didChangeValueForKey: @"estimatedProgress"];
}

mjs's avatar
mjs committed
1156
- (void)_incrementProgressForIdentifier:(id)identifier response:(NSURLResponse *)response;
1157
{
mjs's avatar
mjs committed
1158
    if (!identifier)
1159 1160
        return;

ggaren's avatar
ggaren committed
1161
    LOG (Progress, "_private->numProgressTrackedFrames %d, _private->originatingProgressFrame %p", _private->numProgressTrackedFrames, _private->originatingProgressFrame);
rjw's avatar
rjw committed
1162 1163 1164 1165
    
    if (_private->numProgressTrackedFrames <= 0)
        return;
        
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
    WebProgressItem *item = [[WebProgressItem alloc] init];

    if (!item)
        return;

    long long length = [response expectedContentLength];
    if (length < 0){
        length = WebProgressItemDefaultEstimatedLength;
    }
    item->estimatedLength = length;
    _private->totalPageAndResourceBytesToLoad += length;
    
    if (!_private->progressItems)
        _private->progressItems = [[NSMutableDictionary alloc] init];
        
mjs's avatar
mjs committed
1181
    [_private->progressItems _webkit_setObject:item forUncopiedKey:identifier];
1182 1183 1184
    [item release];
}

mjs's avatar
mjs committed
1185
- (void)_incrementProgressForIdentifier:(id)identifier data:(NSData *)data
1186
{
mjs's avatar
mjs committed
1187
    if (!identifier)