7cda62474470c14f373095d8d1672b3a6e04bcc1
[WebKit-https.git] / Source / WebKit / mac / WebView / WebView.mm
1 /*
2  * Copyright (C) 2005-2013 Apple Inc. All rights reserved.
3  * Copyright (C) 2006 David Smith (catfish.man@gmail.com)
4  * Copyright (C) 2010 Igalia S.L
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1.  Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer. 
12  * 2.  Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution. 
15  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
16  *     its contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission. 
18  *
19  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #import "WebViewInternal.h"
32 #import "WebViewData.h"
33
34 #import "DOMCSSStyleDeclarationInternal.h"
35 #import "DOMDocumentInternal.h"
36 #import "DOMNodeInternal.h"
37 #import "DOMRangeInternal.h"
38 #import "WebAlternativeTextClient.h"
39 #import "WebApplicationCache.h"
40 #import "WebBackForwardListInternal.h"
41 #import "WebBaseNetscapePluginView.h"
42 #import "WebCache.h"
43 #import "WebChromeClient.h"
44 #import "WebDOMOperationsPrivate.h"
45 #import "WebDataSourceInternal.h"
46 #import "WebDatabaseManagerPrivate.h"
47 #import "WebDefaultEditingDelegate.h"
48 #import "WebDefaultPolicyDelegate.h"
49 #import "WebDefaultUIDelegate.h"
50 #import "WebDelegateImplementationCaching.h"
51 #import "WebDeviceOrientationClient.h"
52 #import "WebDeviceOrientationProvider.h"
53 #import "WebDocument.h"
54 #import "WebDocumentInternal.h"
55 #import "WebDownload.h"
56 #import "WebDownloadInternal.h"
57 #import "WebDragClient.h"
58 #import "WebDynamicScrollBarsViewInternal.h"
59 #import "WebEditingDelegate.h"
60 #import "WebEditorClient.h"
61 #import "WebFormDelegatePrivate.h"
62 #import "WebFrameInternal.h"
63 #import "WebFrameLoaderClient.h"
64 #import "WebFrameNetworkingContext.h"
65 #import "WebFrameViewInternal.h"
66 #import "WebGeolocationClient.h"
67 #import "WebGeolocationPositionInternal.h"
68 #import "WebHTMLRepresentation.h"
69 #import "WebHTMLViewInternal.h"
70 #import "WebHistoryItemInternal.h"
71 #import "WebIconDatabaseInternal.h"
72 #import "WebInspector.h"
73 #import "WebInspectorClient.h"
74 #import "WebKitErrors.h"
75 #import "WebKitFullScreenListener.h"
76 #import "WebKitLogging.h"
77 #import "WebKitNSStringExtras.h"
78 #import "WebKitStatisticsPrivate.h"
79 #import "WebKitSystemBits.h"
80 #import "WebKitVersionChecks.h"
81 #import "WebLocalizableStrings.h"
82 #import "WebNSDataExtras.h"
83 #import "WebNSDataExtrasPrivate.h"
84 #import "WebNSDictionaryExtras.h"
85 #import "WebNSURLExtras.h"
86 #import "WebNSURLRequestExtras.h"
87 #import "WebNSViewExtras.h"
88 #import "WebNodeHighlight.h"
89 #import "WebNotificationClient.h"
90 #import "WebPDFView.h"
91 #import "WebPanelAuthenticationHandler.h"
92 #import "WebPlatformStrategies.h"
93 #import "WebPluginDatabase.h"
94 #import "WebPolicyDelegate.h"
95 #import "WebPreferenceKeysPrivate.h"
96 #import "WebPreferencesPrivate.h"
97 #import "WebProgressTrackerClient.h"
98 #import "WebScriptDebugDelegate.h"
99 #import "WebScriptWorldInternal.h"
100 #import "WebStorageManagerInternal.h"
101 #import "WebSystemInterface.h"
102 #import "WebTextCompletionController.h"
103 #import "WebTextIterator.h"
104 #import "WebUIDelegate.h"
105 #import "WebUIDelegatePrivate.h"
106 #import "WebUserMediaClient.h"
107 #import "WebViewGroup.h"
108 #import <CoreFoundation/CFSet.h>
109 #import <Foundation/NSURLConnection.h>
110 #import <JavaScriptCore/APICast.h>
111 #import <JavaScriptCore/JSValueRef.h>
112 #import <WebCore/AlternativeTextUIController.h>
113 #import <WebCore/AnimationController.h>
114 #import <WebCore/ApplicationCacheStorage.h>
115 #import <WebCore/BackForwardController.h>
116 #import <WebCore/BackForwardList.h>
117 #import <WebCore/MemoryCache.h>
118 #import <WebCore/Chrome.h>
119 #import <WebCore/ColorMac.h>
120 #import <WebCore/Cursor.h>
121 #import <WebCore/DatabaseManager.h>
122 #import <WebCore/Document.h>
123 #import <WebCore/DocumentLoader.h>
124 #import <WebCore/DragController.h>
125 #import <WebCore/DragData.h>
126 #import <WebCore/Editor.h>
127 #import <WebCore/EventHandler.h>
128 #import <WebCore/ExceptionHandlers.h>
129 #import <WebCore/FocusController.h>
130 #import <WebCore/FrameLoader.h>
131 #import <WebCore/FrameSelection.h>
132 #import <WebCore/FrameTree.h>
133 #import <WebCore/FrameView.h>
134 #import <WebCore/GCController.h>
135 #import <WebCore/GeolocationController.h>
136 #import <WebCore/GeolocationError.h>
137 #import <WebCore/HTMLMediaElement.h>
138 #import <WebCore/HTMLNames.h>
139 #import <WebCore/HistoryController.h>
140 #import <WebCore/HistoryItem.h>
141 #import <WebCore/IconDatabase.h>
142 #import <WebCore/JSCSSStyleDeclaration.h>
143 #import <WebCore/JSDocument.h>
144 #import <WebCore/JSElement.h>
145 #import <WebCore/JSNodeList.h>
146 #import <WebCore/JSNotification.h>
147 #import <WebCore/Logging.h>
148 #import <WebCore/MIMETypeRegistry.h>
149 #import <WebCore/MainFrame.h>
150 #import <WebCore/MemoryPressureHandler.h>
151 #import <WebCore/NodeList.h>
152 #import <WebCore/Notification.h>
153 #import <WebCore/NotificationController.h>
154 #import <WebCore/Page.h>
155 #import <WebCore/PageCache.h>
156 #import <WebCore/PageGroup.h>
157 #import <WebCore/PlatformEventFactoryMac.h>
158 #import <WebCore/ProgressTracker.h>
159 #import <WebCore/RenderView.h>
160 #import <WebCore/RenderWidget.h>
161 #import <WebCore/ResourceHandle.h>
162 #import <WebCore/ResourceLoadScheduler.h>
163 #import <WebCore/ResourceRequest.h>
164 #import <WebCore/RuntimeApplicationChecks.h>
165 #import <WebCore/RuntimeEnabledFeatures.h>
166 #import <WebCore/SchemeRegistry.h>
167 #import <WebCore/ScriptController.h>
168 #import <WebCore/SecurityOrigin.h>
169 #import <WebCore/SecurityPolicy.h>
170 #import <WebCore/Settings.h>
171 #import <WebCore/StyleProperties.h>
172 #import <WebCore/TextResourceDecoder.h>
173 #import <WebCore/ThreadCheck.h>
174 #import <WebCore/UserAgent.h>
175 #import <WebCore/WebCoreObjCExtras.h>
176 #import <WebCore/WebCoreView.h>
177 #import <WebCore/Widget.h>
178 #import <WebKitLegacy/DOM.h>
179 #import <WebKitLegacy/DOMExtensions.h>
180 #import <WebKitLegacy/DOMPrivate.h>
181 #import <WebKitSystemInterface.h>
182 #import <bindings/ScriptValue.h>
183 #import <mach-o/dyld.h>
184 #import <objc/objc-auto.h>
185 #import <objc/runtime.h>
186 #import <runtime/ArrayPrototype.h>
187 #import <runtime/DateInstance.h>
188 #import <runtime/InitializeThreading.h>
189 #import <runtime/JSLock.h>
190 #import <runtime/JSCJSValue.h>
191 #import <wtf/Assertions.h>
192 #import <wtf/HashTraits.h>
193 #import <wtf/MainThread.h>
194 #import <wtf/ObjcRuntimeExtras.h>
195 #import <wtf/RefCountedLeakCounter.h>
196 #import <wtf/RefPtr.h>
197 #import <wtf/RunLoop.h>
198 #import <wtf/StdLibExtras.h>
199
200 #if !PLATFORM(IOS)
201 #import "WebContextMenuClient.h"
202 #import "WebFullScreenController.h"
203 #import "WebNSEventExtras.h"
204 #import "WebNSObjectExtras.h"
205 #import "WebNSPasteboardExtras.h"
206 #import "WebNSPrintOperationExtras.h"
207 #import "WebPDFView.h"
208 #import <WebCore/WebVideoFullscreenController.h>
209 #else
210 #import "MemoryMeasure.h"
211 #import "WebCaretChangeListener.h"
212 #import "WebChromeClientIOS.h"
213 #import "WebDefaultFormDelegate.h"
214 #import "WebDefaultFrameLoadDelegate.h"
215 #import "WebDefaultResourceLoadDelegate.h"
216 #import "WebDefaultUIKitDelegate.h"
217 #import "WebFixedPositionContent.h"
218 #import "WebMailDelegate.h"
219 #import "WebNSUserDefaultsExtras.h"
220 #import "WebPDFViewIOS.h"
221 #import "WebPlainWhiteView.h"
222 #import "WebPluginController.h"
223 #import "WebPolicyDelegatePrivate.h"
224 #import "WebSQLiteDatabaseTrackerClient.h"
225 #import "WebStorageManagerPrivate.h"
226 #import "WebUIKitSupport.h"
227 #import "WebVisiblePosition.h"
228 #import <CFNetwork/CFURLCachePriv.h>
229 #import <MobileGestalt.h>
230 #import <WebCore/EventNames.h>
231 #import <WebCore/FontCache.h>
232 #import <WebCore/GraphicsLayer.h>
233 #import <WebCore/IconController.h>
234 #import <WebCore/LegacyTileCache.h>
235 #import <WebCore/NetworkStateNotifier.h>
236 #import <WebCore/RuntimeApplicationChecksIOS.h>
237 #import <WebCore/SQLiteDatabaseTracker.h>
238 #import <WebCore/SmartReplace.h>
239 #import <WebCore/TextRun.h>
240 #import <WebCore/TileControllerMemoryHandlerIOS.h>
241 #import <WebCore/WAKWindow.h>
242 #import <WebCore/WKView.h>
243 #import <WebCore/WebCoreThread.h>
244 #import <WebCore/WebCoreThreadMessage.h>
245 #import <WebCore/WebCoreThreadRun.h>
246 #import <WebCore/WebEvent.h>
247 #import <WebCore/WebVideoFullscreenControllerAVKit.h>
248 #import <dispatch/private.h>
249 #import <wtf/FastMalloc.h>
250 #endif // !PLATFORM(IOS)
251
252 #if ENABLE(DASHBOARD_SUPPORT)
253 #import <WebKitLegacy/WebDashboardRegion.h>
254 #endif
255
256 #if ENABLE(DISK_IMAGE_CACHE) && PLATFORM(IOS)
257 #import "WebDiskImageCacheClientIOS.h"
258 #import <WebCore/DiskImageCacheIOS.h>
259 #endif
260
261 #if ENABLE(REMOTE_INSPECTOR)
262 #import <JavaScriptCore/RemoteInspector.h>
263 #if PLATFORM(IOS)
264 #import "WebIndicateLayer.h"
265 #endif
266 #endif
267
268 #if USE(GLIB)
269 #import <glib.h>
270 #endif
271
272 #if USE(QUICK_LOOK)
273 #include <WebCore/QuickLook.h>
274 #endif
275
276 #if ENABLE(TOUCH_EVENTS)
277 #import <WebCore/WebEventRegion.h>
278 #endif
279
280 #if ENABLE(DISK_IMAGE_CACHE)
281 #import "WebDiskImageCacheClientIOS.h"
282 #import <WebCore/DiskImageCacheIOS.h>
283 #endif
284
285 #if ENABLE(GAMEPAD)
286 #import <WebCore/HIDGamepadProvider.h>
287 #endif
288
289 #if !PLATFORM(IOS)
290 @interface NSSpellChecker (WebNSSpellCheckerDetails)
291 - (void)_preflightChosenSpellServer;
292 @end
293
294 @interface NSView (WebNSViewDetails)
295 - (NSView *)_hitTest:(NSPoint *)aPoint dragTypes:(NSSet *)types;
296 - (void)_autoscrollForDraggingInfo:(id)dragInfo timeDelta:(NSTimeInterval)repeatDelta;
297 - (BOOL)_shouldAutoscrollForDraggingInfo:(id)dragInfo;
298 @end
299
300 @interface NSWindow (WebNSWindowDetails)
301 - (id)_oldFirstResponderBeforeBecoming;
302 - (void)_enableScreenUpdatesIfNeeded;
303 - (BOOL)_wrapsCarbonWindow;
304 - (BOOL)_hasKeyAppearance;
305 @end
306 #endif
307
308 using namespace JSC;
309 using namespace Inspector;
310 using namespace WebCore;
311
312 #define FOR_EACH_RESPONDER_SELECTOR(macro) \
313 macro(alignCenter) \
314 macro(alignJustified) \
315 macro(alignLeft) \
316 macro(alignRight) \
317 macro(capitalizeWord) \
318 macro(centerSelectionInVisibleArea) \
319 macro(changeAttributes) \
320 macro(changeBaseWritingDirection) \
321 macro(changeBaseWritingDirectionToLTR) \
322 macro(changeBaseWritingDirectionToRTL) \
323 macro(changeColor) \
324 macro(changeDocumentBackgroundColor) \
325 macro(changeFont) \
326 macro(changeSpelling) \
327 macro(checkSpelling) \
328 macro(complete) \
329 macro(copy) \
330 macro(copyFont) \
331 macro(cut) \
332 macro(delete) \
333 macro(deleteBackward) \
334 macro(deleteBackwardByDecomposingPreviousCharacter) \
335 macro(deleteForward) \
336 macro(deleteToBeginningOfLine) \
337 macro(deleteToBeginningOfParagraph) \
338 macro(deleteToEndOfLine) \
339 macro(deleteToEndOfParagraph) \
340 macro(deleteToMark) \
341 macro(deleteWordBackward) \
342 macro(deleteWordForward) \
343 macro(ignoreSpelling) \
344 macro(indent) \
345 macro(insertBacktab) \
346 macro(insertLineBreak) \
347 macro(insertNewline) \
348 macro(insertNewlineIgnoringFieldEditor) \
349 macro(insertParagraphSeparator) \
350 macro(insertTab) \
351 macro(insertTabIgnoringFieldEditor) \
352 macro(lowercaseWord) \
353 macro(makeBaseWritingDirectionLeftToRight) \
354 macro(makeBaseWritingDirectionRightToLeft) \
355 macro(makeTextWritingDirectionLeftToRight) \
356 macro(makeTextWritingDirectionNatural) \
357 macro(makeTextWritingDirectionRightToLeft) \
358 macro(moveBackward) \
359 macro(moveBackwardAndModifySelection) \
360 macro(moveDown) \
361 macro(moveDownAndModifySelection) \
362 macro(moveForward) \
363 macro(moveForwardAndModifySelection) \
364 macro(moveLeft) \
365 macro(moveLeftAndModifySelection) \
366 macro(moveParagraphBackwardAndModifySelection) \
367 macro(moveParagraphForwardAndModifySelection) \
368 macro(moveRight) \
369 macro(moveRightAndModifySelection) \
370 macro(moveToBeginningOfDocument) \
371 macro(moveToBeginningOfDocumentAndModifySelection) \
372 macro(moveToBeginningOfLine) \
373 macro(moveToBeginningOfLineAndModifySelection) \
374 macro(moveToBeginningOfParagraph) \
375 macro(moveToBeginningOfParagraphAndModifySelection) \
376 macro(moveToBeginningOfSentence) \
377 macro(moveToBeginningOfSentenceAndModifySelection) \
378 macro(moveToEndOfDocument) \
379 macro(moveToEndOfDocumentAndModifySelection) \
380 macro(moveToEndOfLine) \
381 macro(moveToEndOfLineAndModifySelection) \
382 macro(moveToEndOfParagraph) \
383 macro(moveToEndOfParagraphAndModifySelection) \
384 macro(moveToEndOfSentence) \
385 macro(moveToEndOfSentenceAndModifySelection) \
386 macro(moveToLeftEndOfLine) \
387 macro(moveToLeftEndOfLineAndModifySelection) \
388 macro(moveToRightEndOfLine) \
389 macro(moveToRightEndOfLineAndModifySelection) \
390 macro(moveUp) \
391 macro(moveUpAndModifySelection) \
392 macro(moveWordBackward) \
393 macro(moveWordBackwardAndModifySelection) \
394 macro(moveWordForward) \
395 macro(moveWordForwardAndModifySelection) \
396 macro(moveWordLeft) \
397 macro(moveWordLeftAndModifySelection) \
398 macro(moveWordRight) \
399 macro(moveWordRightAndModifySelection) \
400 macro(orderFrontSubstitutionsPanel) \
401 macro(outdent) \
402 macro(overWrite) \
403 macro(pageDown) \
404 macro(pageDownAndModifySelection) \
405 macro(pageUp) \
406 macro(pageUpAndModifySelection) \
407 macro(paste) \
408 macro(pasteAsPlainText) \
409 macro(pasteAsRichText) \
410 macro(pasteFont) \
411 macro(performFindPanelAction) \
412 macro(scrollLineDown) \
413 macro(scrollLineUp) \
414 macro(scrollPageDown) \
415 macro(scrollPageUp) \
416 macro(scrollToBeginningOfDocument) \
417 macro(scrollToEndOfDocument) \
418 macro(selectAll) \
419 macro(selectLine) \
420 macro(selectParagraph) \
421 macro(selectSentence) \
422 macro(selectToMark) \
423 macro(selectWord) \
424 macro(setMark) \
425 macro(showGuessPanel) \
426 macro(startSpeaking) \
427 macro(stopSpeaking) \
428 macro(subscript) \
429 macro(superscript) \
430 macro(swapWithMark) \
431 macro(takeFindStringFromSelection) \
432 macro(toggleBaseWritingDirection) \
433 macro(transpose) \
434 macro(underline) \
435 macro(unscript) \
436 macro(uppercaseWord) \
437 macro(yank) \
438 macro(yankAndSelect) \
439
440 #define WebKitOriginalTopPrintingMarginKey @"WebKitOriginalTopMargin"
441 #define WebKitOriginalBottomPrintingMarginKey @"WebKitOriginalBottomMargin"
442
443 #define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange"
444 #define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode")
445
446 static BOOL s_didSetCacheModel;
447 static WebCacheModel s_cacheModel = WebCacheModelDocumentViewer;
448
449 #if PLATFORM(IOS)
450 static Class s_pdfRepresentationClass;
451 static Class s_pdfViewClass;
452 #endif
453
454 #ifndef NDEBUG
455 static const char webViewIsOpen[] = "At least one WebView is still open.";
456 #endif
457
458 #if PLATFORM(IOS)
459 @interface WebView(WebViewPrivate)
460 - (void)_preferencesChanged:(WebPreferences *)preferences;
461 - (void)_updateScreenScaleFromWindow;
462 @end
463
464 @interface NSURLCache (WebPrivate)
465 - (CFURLCacheRef)_CFURLCache;
466 @end
467 #endif
468
469 #if !PLATFORM(IOS)
470 @interface NSObject (WebValidateWithoutDelegate)
471 - (BOOL)validateUserInterfaceItemWithoutDelegate:(id <NSValidatedUserInterfaceItem>)item;
472 @end
473 #endif
474
475 #if PLATFORM(IOS)
476 @class _WebSafeForwarder;
477
478 @interface _WebSafeAsyncForwarder : NSObject {
479     _WebSafeForwarder *_forwarder;
480 }
481 - (id)initWithForwarder:(_WebSafeForwarder *)forwarder;
482 @end
483 #endif
484
485 @interface _WebSafeForwarder : NSObject
486 {
487     id target; // Non-retained. Don't retain delegates.
488     id defaultTarget;
489 #if PLATFORM(IOS)
490     _WebSafeAsyncForwarder *asyncForwarder;
491     dispatch_once_t asyncForwarderPred;
492 #endif
493 }
494 - (instancetype)initWithTarget:(id)target defaultTarget:(id)defaultTarget;
495 #if PLATFORM(IOS)
496 - (void)clearTarget;
497 - (id)asyncForwarder;
498 #endif
499 @end
500
501 FindOptions coreOptions(WebFindOptions options)
502 {
503     return (options & WebFindOptionsCaseInsensitive ? CaseInsensitive : 0)
504         | (options & WebFindOptionsAtWordStarts ? AtWordStarts : 0)
505         | (options & WebFindOptionsTreatMedialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0)
506         | (options & WebFindOptionsBackwards ? Backwards : 0)
507         | (options & WebFindOptionsWrapAround ? WrapAround : 0)
508         | (options & WebFindOptionsStartInSelection ? StartInSelection : 0);
509 }
510
511 LayoutMilestones coreLayoutMilestones(WebLayoutMilestones milestones)
512 {
513     return (milestones & WebDidFirstLayout ? DidFirstLayout : 0)
514         | (milestones & WebDidFirstVisuallyNonEmptyLayout ? DidFirstVisuallyNonEmptyLayout : 0)
515         | (milestones & WebDidHitRelevantRepaintedObjectsAreaThreshold ? DidHitRelevantRepaintedObjectsAreaThreshold : 0);
516 }
517
518 WebLayoutMilestones kitLayoutMilestones(LayoutMilestones milestones)
519 {
520     return (milestones & DidFirstLayout ? WebDidFirstLayout : 0)
521         | (milestones & DidFirstVisuallyNonEmptyLayout ? WebDidFirstVisuallyNonEmptyLayout : 0)
522         | (milestones & DidHitRelevantRepaintedObjectsAreaThreshold ? WebDidHitRelevantRepaintedObjectsAreaThreshold : 0);
523 }
524
525 static WebPageVisibilityState kit(PageVisibilityState visibilityState)
526 {
527     switch (visibilityState) {
528     case PageVisibilityStateVisible:
529         return WebPageVisibilityStateVisible;
530     case PageVisibilityStateHidden:
531         return WebPageVisibilityStateHidden;
532     case PageVisibilityStatePrerender:
533         return WebPageVisibilityStatePrerender;
534     }
535
536     ASSERT_NOT_REACHED();
537     return WebPageVisibilityStateVisible;
538 }
539
540 @interface WebView (WebFileInternal)
541 #if !PLATFORM(IOS)
542 - (float)_deviceScaleFactor;
543 #endif
544 - (BOOL)_isLoading;
545 - (WebFrameView *)_frameViewAtWindowPoint:(NSPoint)point;
546 - (WebFrame *)_focusedFrame;
547 + (void)_preflightSpellChecker;
548 - (BOOL)_continuousCheckingAllowed;
549 - (NSResponder *)_responderForResponderOperations;
550 #if USE(GLIB)
551 - (void)_clearGlibLoopObserver;
552 #endif
553 @end
554
555 NSString *WebElementDOMNodeKey =            @"WebElementDOMNode";
556 NSString *WebElementFrameKey =              @"WebElementFrame";
557 NSString *WebElementImageKey =              @"WebElementImage";
558 NSString *WebElementImageAltStringKey =     @"WebElementImageAltString";
559 NSString *WebElementImageRectKey =          @"WebElementImageRect";
560 NSString *WebElementImageURLKey =           @"WebElementImageURL";
561 NSString *WebElementIsSelectedKey =         @"WebElementIsSelected";
562 NSString *WebElementLinkLabelKey =          @"WebElementLinkLabel";
563 NSString *WebElementLinkTargetFrameKey =    @"WebElementTargetFrame";
564 NSString *WebElementLinkTitleKey =          @"WebElementLinkTitle";
565 NSString *WebElementLinkURLKey =            @"WebElementLinkURL";
566 NSString *WebElementMediaURLKey =           @"WebElementMediaURL";
567 NSString *WebElementSpellingToolTipKey =    @"WebElementSpellingToolTip";
568 NSString *WebElementTitleKey =              @"WebElementTitle";
569 NSString *WebElementLinkIsLiveKey =         @"WebElementLinkIsLive";
570 NSString *WebElementIsInScrollBarKey =      @"WebElementIsInScrollBar";
571 NSString *WebElementIsContentEditableKey =  @"WebElementIsContentEditableKey";
572
573 NSString *WebViewProgressStartedNotification =          @"WebProgressStartedNotification";
574 NSString *WebViewProgressEstimateChangedNotification =  @"WebProgressEstimateChangedNotification";
575 #if !PLATFORM(IOS)
576 NSString *WebViewProgressFinishedNotification =         @"WebProgressFinishedNotification";
577 #else
578 NSString * const WebViewProgressEstimatedProgressKey = @"WebProgressEstimatedProgressKey";
579 NSString * const WebViewProgressBackgroundColorKey =   @"WebProgressBackgroundColorKey";
580 #endif
581
582 NSString * const WebViewDidBeginEditingNotification =         @"WebViewDidBeginEditingNotification";
583 NSString * const WebViewDidChangeNotification =               @"WebViewDidChangeNotification";
584 NSString * const WebViewDidEndEditingNotification =           @"WebViewDidEndEditingNotification";
585 NSString * const WebViewDidChangeTypingStyleNotification =    @"WebViewDidChangeTypingStyleNotification";
586 NSString * const WebViewDidChangeSelectionNotification =      @"WebViewDidChangeSelectionNotification";
587
588 enum { WebViewVersion = 4 };
589
590 #define timedLayoutSize 4096
591
592 static NSMutableSet *schemesWithRepresentationsSet;
593
594 #if !PLATFORM(IOS)
595 NSString *_WebCanGoBackKey =            @"canGoBack";
596 NSString *_WebCanGoForwardKey =         @"canGoForward";
597 NSString *_WebEstimatedProgressKey =    @"estimatedProgress";
598 NSString *_WebIsLoadingKey =            @"isLoading";
599 NSString *_WebMainFrameIconKey =        @"mainFrameIcon";
600 NSString *_WebMainFrameTitleKey =       @"mainFrameTitle";
601 NSString *_WebMainFrameURLKey =         @"mainFrameURL";
602 NSString *_WebMainFrameDocumentKey =    @"mainFrameDocument";
603 #endif
604
605 #if USE(QUICK_LOOK)
606 NSString *WebQuickLookFileNameKey = @"WebQuickLookFileNameKey";
607 NSString *WebQuickLookUTIKey      = @"WebQuickLookUTIKey";
608 #endif
609
610 NSString *_WebViewDidStartAcceleratedCompositingNotification = @"_WebViewDidStartAcceleratedCompositing";
611 NSString * const WebViewWillCloseNotification = @"WebViewWillCloseNotification";
612
613 #if ENABLE(REMOTE_INSPECTOR)
614 // FIXME: Legacy, remove this, switch to something from JavaScriptCore Inspector::RemoteInspectorServer.
615 NSString *_WebViewRemoteInspectorHasSessionChangedNotification = @"_WebViewRemoteInspectorHasSessionChangedNotification";
616 #endif
617
618 NSString *WebKitKerningAndLigaturesEnabledByDefaultDefaultsKey = @"WebKitKerningAndLigaturesEnabledByDefault";
619
620 @interface WebProgressItem : NSObject
621 {
622 @public
623     long long bytesReceived;
624     long long estimatedLength;
625 }
626 @end
627
628 @implementation WebProgressItem
629 @end
630
631 static BOOL continuousSpellCheckingEnabled;
632 #if !PLATFORM(IOS)
633 static BOOL grammarCheckingEnabled;
634 static BOOL automaticQuoteSubstitutionEnabled;
635 static BOOL automaticLinkDetectionEnabled;
636 static BOOL automaticDashSubstitutionEnabled;
637 static BOOL automaticTextReplacementEnabled;
638 static BOOL automaticSpellingCorrectionEnabled;
639 #endif
640
641 @implementation WebView (AllWebViews)
642
643 static CFSetCallBacks NonRetainingSetCallbacks = {
644     0,
645     NULL,
646     NULL,
647     CFCopyDescription,
648     CFEqual,
649     CFHash
650 };
651
652 static CFMutableSetRef allWebViewsSet;
653
654 + (void)_makeAllWebViewsPerformSelector:(SEL)selector
655 {
656     if (!allWebViewsSet)
657         return;
658
659     [(NSMutableSet *)allWebViewsSet makeObjectsPerformSelector:selector];
660 }
661
662 - (void)_removeFromAllWebViewsSet
663 {
664     if (allWebViewsSet)
665         CFSetRemoveValue(allWebViewsSet, self);
666 }
667
668 - (void)_addToAllWebViewsSet
669 {
670     if (!allWebViewsSet)
671         allWebViewsSet = CFSetCreateMutable(NULL, 0, &NonRetainingSetCallbacks);
672
673     CFSetSetValue(allWebViewsSet, self);
674 }
675
676 @end
677
678 @implementation WebView (WebPrivate)
679
680 static String webKitBundleVersionString()
681 {
682     return [[NSBundle bundleForClass:[WebView class]] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
683 }
684
685 + (NSString *)_standardUserAgentWithApplicationName:(NSString *)applicationName
686 {
687     return standardUserAgentWithApplicationName(applicationName, webKitBundleVersionString());
688 }
689
690 #if PLATFORM(IOS)
691 - (void)_setBrowserUserAgentProductVersion:(NSString *)productVersion buildVersion:(NSString *)buildVersion bundleVersion:(NSString *)bundleVersion
692 {
693     [self setApplicationNameForUserAgent:[NSString stringWithFormat:@"Version/%@ Mobile/%@ Safari/%@", productVersion, buildVersion, bundleVersion]];
694 }
695
696 - (void)_setUIWebViewUserAgentWithBuildVersion:(NSString *)buildVersion
697 {
698     [self setApplicationNameForUserAgent:[@"Mobile/" stringByAppendingString:buildVersion]];
699 }
700 #endif // PLATFORM(IOS)
701
702 + (void)_reportException:(JSValueRef)exception inContext:(JSContextRef)context
703 {
704     if (!exception || !context)
705         return;
706
707     JSC::ExecState* execState = toJS(context);
708     JSLockHolder lock(execState);
709
710     // Make sure the context has a DOMWindow global object, otherwise this context didn't originate from a WebView.
711     if (!toJSDOMWindow(execState->lexicalGlobalObject()))
712         return;
713
714     reportException(execState, toJS(execState, exception));
715 }
716
717 static void WebKitInitializeApplicationCachePathIfNecessary()
718 {
719     static BOOL initialized = NO;
720     if (initialized)
721         return;
722
723     NSString *appName = [[NSBundle mainBundle] bundleIdentifier];
724     if (!appName)
725         appName = [[NSProcessInfo processInfo] processName];
726 #if PLATFORM(IOS)
727     if (WebCore::applicationIsMobileSafari() || WebCore::applicationIsWebApp())
728         appName = @"com.apple.WebAppCache";
729 #endif
730
731     ASSERT(appName);
732
733     NSString* cacheDir = [NSString _webkit_localCacheDirectoryWithBundleIdentifier:appName];
734
735     cacheStorage().setCacheDirectory(cacheDir);
736     initialized = YES;
737 }
738
739 static bool shouldEnableLoadDeferring()
740 {
741     return !applicationIsAdobeInstaller();
742 }
743
744 static bool shouldRestrictWindowFocus()
745 {
746 #if PLATFORM(IOS)
747     return true;
748 #else
749     return !applicationIsHRBlock();
750 #endif
751 }
752
753 - (void)_dispatchPendingLoadRequests
754 {
755     resourceLoadScheduler()->servePendingRequests();
756 }
757
758 #if !PLATFORM(IOS)
759 - (void)_registerDraggedTypes
760 {
761     NSArray *editableTypes = [WebHTMLView _insertablePasteboardTypes];
762     NSArray *URLTypes = [NSPasteboard _web_dragTypesForURL];
763     NSMutableSet *types = [[NSMutableSet alloc] initWithArray:editableTypes];
764     [types addObjectsFromArray:URLTypes];
765     [self registerForDraggedTypes:[types allObjects]];
766     [types release];
767 }
768
769 static bool needsOutlookQuirksScript()
770 {
771     static bool isOutlookNeedingQuirksScript = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_HTML5_PARSER)
772         && applicationIsMicrosoftOutlook();
773     return isOutlookNeedingQuirksScript;
774 }
775
776 static NSString *leakOutlookQuirksUserScriptContents()
777 {
778     NSString *scriptPath = [[NSBundle bundleForClass:[WebView class]] pathForResource:@"OutlookQuirksUserScript" ofType:@"js"];
779     NSStringEncoding encoding;
780     return [[NSString alloc] initWithContentsOfFile:scriptPath usedEncoding:&encoding error:0];
781 }
782
783 -(void)_injectOutlookQuirksScript
784 {
785     static NSString *outlookQuirksScriptContents = leakOutlookQuirksUserScriptContents();
786     core(self)->group().addUserScriptToWorld(*core([WebScriptWorld world]),
787         outlookQuirksScriptContents, URL(), Vector<String>(), Vector<String>(), InjectAtDocumentEnd, InjectInAllFrames);
788 }
789 #endif
790
791 static bool shouldRespectPriorityInCSSAttributeSetters()
792 {
793 #if PLATFORM(IOS)
794     static bool isStanzaNeedingAttributeSetterQuirk = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CSS_ATTRIBUTE_SETTERS_IGNORING_PRIORITY)
795         && [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.lexcycle.stanza"];
796     return isStanzaNeedingAttributeSetterQuirk;
797 #else
798     static bool isIAdProducerNeedingAttributeSetterQuirk = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CSS_ATTRIBUTE_SETTERS_IGNORING_PRIORITY)
799         && [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.iAdProducer"];
800     return isIAdProducerNeedingAttributeSetterQuirk;
801 #endif
802 }
803
804 #if PLATFORM(IOS)
805 static bool shouldTransformsAffectOverflow()
806 {
807     static bool shouldTransformsAffectOverflow = !applicationIsOkCupid() || WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CSS_TRANSFORMS_AFFECTING_OVERFLOW);
808     return shouldTransformsAffectOverflow;
809 }
810
811 static bool shouldDispatchJavaScriptWindowOnErrorEvents()
812 {
813     static bool shouldDispatchJavaScriptWindowOnErrorEvents = !applicationIsFacebook() || WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_WINDOW_ON_ERROR);
814     return shouldDispatchJavaScriptWindowOnErrorEvents;
815 }
816
817 static bool isInternalInstall()
818 {
819     static bool isInternal = MGGetBoolAnswer(kMGQAppleInternalInstallCapability);
820     return isInternal;
821 }
822
823 static bool didOneTimeInitialization = false;
824 #endif
825
826 static bool shouldUseLegacyBackgroundSizeShorthandBehavior()
827 {
828 #if PLATFORM(IOS)
829     static bool shouldUseLegacyBackgroundSizeShorthandBehavior = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_LEGACY_BACKGROUNDSIZE_SHORTHAND_BEHAVIOR);
830 #else
831     static bool shouldUseLegacyBackgroundSizeShorthandBehavior = applicationIsVersions()
832         && !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_LEGACY_BACKGROUNDSIZE_SHORTHAND_BEHAVIOR);
833 #endif
834     return shouldUseLegacyBackgroundSizeShorthandBehavior;
835 }
836
837 #if ENABLE(GAMEPAD)
838 static void WebKitInitializeGamepadProviderIfNecessary()
839 {
840     static bool initialized = false;
841     if (initialized)
842         return;
843
844     GamepadProvider::shared().setSharedProvider(HIDGamepadProvider::shared());
845     initialized = true;
846 }
847 #endif
848
849 - (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName
850 {
851     WebCoreThreadViolationCheckRoundTwo();
852
853 #ifndef NDEBUG
854     WTF::RefCountedLeakCounter::suppressMessages(webViewIsOpen);
855 #endif
856     
857     WebPreferences *standardPreferences = [WebPreferences standardPreferences];
858     [standardPreferences willAddToWebView];
859
860     _private->preferences = [standardPreferences retain];
861     _private->mainFrameDocumentReady = NO;
862     _private->drawsBackground = YES;
863 #if !PLATFORM(IOS)
864     _private->backgroundColor = [[NSColor colorWithDeviceWhite:1 alpha:1] retain];
865 #else
866     _private->backgroundColor = CGColorRetain(cachedCGColor(Color::white, ColorSpaceDeviceRGB));
867 #endif
868     _private->includesFlattenedCompositingLayersWhenDrawingToBitmap = YES;
869
870     NSRect f = [self frame];
871     WebFrameView *frameView = [[WebFrameView alloc] initWithFrame: NSMakeRect(0,0,f.size.width,f.size.height)];
872     [frameView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
873     [self addSubview:frameView];
874     [frameView release];
875
876 #if !PLATFORM(IOS)
877     static bool didOneTimeInitialization = false;
878 #endif
879     if (!didOneTimeInitialization) {
880 #if !LOG_DISABLED
881         WebKitInitializeLoggingChannelsIfNecessary();
882         WebCore::initializeLoggingChannelsIfNecessary();
883 #endif // !LOG_DISABLED
884
885         // Initialize our platform strategies first before invoking the rest
886         // of the initialization code which may depend on the strategies.
887         WebPlatformStrategies::initializeIfNecessary();
888
889 #if ENABLE(SQL_DATABASE)
890 #if PLATFORM(IOS)
891         // Set the WebSQLiteDatabaseTrackerClient.
892         SQLiteDatabaseTracker::setClient(WebSQLiteDatabaseTrackerClient::sharedWebSQLiteDatabaseTrackerClient());
893
894         if ([standardPreferences databasesEnabled])
895 #endif
896         [WebDatabaseManager sharedWebDatabaseManager];
897 #endif
898
899 #if PLATFORM(IOS)        
900         if ([standardPreferences storageTrackerEnabled])
901 #endif
902         WebKitInitializeStorageIfNecessary();
903         WebKitInitializeApplicationCachePathIfNecessary();
904 #if ENABLE(DISK_IMAGE_CACHE) && PLATFORM(IOS)
905         WebKitInitializeWebDiskImageCache();
906 #endif
907 #if ENABLE(GAMEPAD)
908         WebKitInitializeGamepadProviderIfNecessary();
909 #endif
910         
911         Settings::setDefaultMinDOMTimerInterval(0.004);
912         
913         Settings::setShouldRespectPriorityInCSSAttributeSetters(shouldRespectPriorityInCSSAttributeSetters());
914
915 #if PLATFORM(IOS)
916         if (applicationIsMobileSafari())
917             Settings::setShouldManageAudioSessionCategory(true);
918 #endif
919
920         didOneTimeInitialization = true;
921     }
922
923     Page::PageClients pageClients;
924 #if !PLATFORM(IOS)
925     pageClients.chromeClient = new WebChromeClient(self);
926     pageClients.contextMenuClient = new WebContextMenuClient(self);
927 #if ENABLE(DRAG_SUPPORT)
928     pageClients.dragClient = new WebDragClient(self);
929 #endif
930     pageClients.inspectorClient = new WebInspectorClient(self);
931 #else
932     pageClients.chromeClient = new WebChromeClientIOS(self);
933     pageClients.inspectorClient = new WebInspectorClient(self);
934 #endif
935     pageClients.editorClient = new WebEditorClient(self);
936     pageClients.alternativeTextClient = new WebAlternativeTextClient(self);
937     pageClients.loaderClientForMainFrame = new WebFrameLoaderClient;
938     pageClients.progressTrackerClient = new WebProgressTrackerClient(self);
939     _private->page = new Page(pageClients);
940 #if ENABLE(GEOLOCATION)
941     WebCore::provideGeolocationTo(_private->page, new WebGeolocationClient(self));
942 #endif
943 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
944     WebCore::provideNotification(_private->page, new WebNotificationClient(self));
945 #endif
946 #if ENABLE(DEVICE_ORIENTATION)
947 #if !PLATFORM(IOS)
948     WebCore::provideDeviceOrientationTo(_private->page, new WebDeviceOrientationClient(self));
949 #endif
950 #endif
951 #if ENABLE(MEDIA_STREAM)
952     WebCore::provideUserMediaTo(_private->page, new WebUserMediaClient(self));
953 #endif
954
955 #if ENABLE(REMOTE_INSPECTOR)
956     _private->page->setRemoteInspectionAllowed(true);
957 #endif
958
959     _private->page->setCanStartMedia([self window]);
960     _private->page->settings().setLocalStorageDatabasePath([[self preferences] _localStorageDatabasePath]);
961     _private->page->settings().setUseLegacyBackgroundSizeShorthandBehavior(shouldUseLegacyBackgroundSizeShorthandBehavior());
962
963 #if !PLATFORM(IOS)
964     if (needsOutlookQuirksScript()) {
965         _private->page->settings().setShouldInjectUserScriptsInInitialEmptyDocument(true);
966         [self _injectOutlookQuirksScript];
967     }
968 #endif
969
970 #if PLATFORM(IOS)
971     // Preserve the behavior we had before <rdar://problem/7580867>
972     // by enforcing a 5MB limit for session storage.
973     _private->page->settings().setSessionStorageQuota(5 * 1024 * 1024);
974
975     [self _updateScreenScaleFromWindow];
976     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_wakWindowScreenScaleChanged:) name:WAKWindowScreenScaleDidChangeNotification object:nil];
977     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_wakWindowVisibilityChanged:) name:WAKWindowVisibilityDidChangeNotification object:nil];
978     _private->_fixedPositionContent = [[WebFixedPositionContent alloc] initWithWebView:self];
979 #endif
980
981     if ([[NSUserDefaults standardUserDefaults] objectForKey:WebSmartInsertDeleteEnabled])
982         [self setSmartInsertDeleteEnabled:[[NSUserDefaults standardUserDefaults] boolForKey:WebSmartInsertDeleteEnabled]];
983
984     [WebFrame _createMainFrameWithPage:_private->page frameName:frameName frameView:frameView];
985
986 #if !PLATFORM(IOS)
987     NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
988
989     if (WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOADING_DURING_COMMON_RUNLOOP_MODES))
990         [self scheduleInRunLoop:runLoop forMode:(NSString *)kCFRunLoopCommonModes];
991     else
992         [self scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];
993 #endif
994
995     [self _addToAllWebViewsSet];
996     [self setGroupName:groupName];
997     
998     // If there's already a next key view (e.g., from a nib), wire it up to our
999     // contained frame view. In any case, wire our next key view up to the our
1000     // contained frame view. This works together with our becomeFirstResponder 
1001     // and setNextKeyView overrides.
1002     NSView *nextKeyView = [self nextKeyView];
1003     if (nextKeyView && nextKeyView != frameView)
1004         [frameView setNextKeyView:nextKeyView];
1005     [super setNextKeyView:frameView];
1006
1007     if ([[self class] shouldIncludeInWebKitStatistics])
1008         ++WebViewCount;
1009
1010 #if !PLATFORM(IOS)
1011     [self _registerDraggedTypes];
1012 #endif
1013
1014     [self _setIsVisible:[self _isViewVisible]];
1015
1016     WebPreferences *prefs = [self preferences];
1017     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_preferencesChangedNotification:)
1018                                                  name:WebPreferencesChangedInternalNotification object:prefs];
1019
1020 #if !PLATFORM(IOS)
1021     [self _preferencesChanged:[self preferences]];
1022     [[self preferences] _postPreferencesChangedAPINotification];
1023 #else
1024     // do this on the current thread on iOS, since the web thread could be blocked on the main thread,
1025     // and prefs need to be changed synchronously <rdar://problem/5841558>
1026     [self _preferencesChanged:prefs];
1027     _private->page->settings().setFontFallbackPrefersPictographs(true);
1028 #endif
1029
1030     memoryPressureHandler().install();
1031
1032     if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOCAL_RESOURCE_SECURITY_RESTRICTION)) {
1033         // Originally, we allowed all local loads.
1034         SecurityPolicy::setLocalLoadPolicy(SecurityPolicy::AllowLocalLoadsForAll);
1035     } else if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_MORE_STRICT_LOCAL_RESOURCE_SECURITY_RESTRICTION)) {
1036         // Later, we allowed local loads for local URLs and documents loaded
1037         // with substitute data.
1038         SecurityPolicy::setLocalLoadPolicy(SecurityPolicy::AllowLocalLoadsForLocalAndSubstituteData);
1039     }
1040
1041 #if !PLATFORM(IOS)
1042     if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_CONTENT_SNIFFING_FOR_FILE_URLS))
1043         ResourceHandle::forceContentSniffing();
1044 #endif
1045
1046 #if USE(GLIB)
1047     [self _scheduleGlibContextIterations];
1048 #endif
1049 }
1050
1051 - (id)_initWithFrame:(NSRect)f frameName:(NSString *)frameName groupName:(NSString *)groupName
1052 {
1053     self = [super initWithFrame:f];
1054     if (!self)
1055         return nil;
1056
1057 #ifdef ENABLE_WEBKIT_UNSET_DYLD_FRAMEWORK_PATH
1058     // DYLD_FRAMEWORK_PATH is used so Safari will load the development version of WebKit, which
1059     // may not work with other WebKit applications.  Unsetting DYLD_FRAMEWORK_PATH removes the
1060     // need for Safari to unset it to prevent it from being passed to applications it launches.
1061     // Unsetting it when a WebView is first created is as good a place as any.
1062     // See <http://bugs.webkit.org/show_bug.cgi?id=4286> for more details.
1063     if (getenv("WEBKIT_UNSET_DYLD_FRAMEWORK_PATH")) {
1064         unsetenv("DYLD_FRAMEWORK_PATH");
1065         unsetenv("WEBKIT_UNSET_DYLD_FRAMEWORK_PATH");
1066     }
1067 #endif
1068
1069     _private = [[WebViewPrivate alloc] init];
1070     [self _commonInitializationWithFrameName:frameName groupName:groupName];
1071     [self setMaintainsBackForwardList: YES];
1072 #if !PLATFORM(IOS)
1073     _private->page->setDeviceScaleFactor([self _deviceScaleFactor]);
1074 #endif
1075     return self;
1076 }
1077
1078 - (void)_viewWillDrawInternal
1079 {
1080     Frame* frame = [self _mainCoreFrame];
1081     if (frame && frame->view())
1082         frame->view()->updateLayoutAndStyleIfNeededRecursive();
1083 }
1084
1085 + (NSArray *)_supportedMIMETypes
1086 {
1087     // Load the plug-in DB allowing plug-ins to install types.
1088     [WebPluginDatabase sharedDatabase];
1089     return [[WebFrameView _viewTypesAllowImageTypeOmission:NO] allKeys];
1090 }
1091
1092 #if !PLATFORM(IOS)
1093 + (NSArray *)_supportedFileExtensions
1094 {
1095     NSMutableSet *extensions = [[NSMutableSet alloc] init];
1096     NSArray *MIMETypes = [self _supportedMIMETypes];
1097     NSEnumerator *enumerator = [MIMETypes objectEnumerator];
1098     NSString *MIMEType;
1099     while ((MIMEType = [enumerator nextObject]) != nil) {
1100         NSArray *extensionsForType = WKGetExtensionsForMIMEType(MIMEType);
1101         if (extensionsForType) {
1102             [extensions addObjectsFromArray:extensionsForType];
1103         }
1104     }
1105     NSArray *uniqueExtensions = [extensions allObjects];
1106     [extensions release];
1107     return uniqueExtensions;
1108 }
1109 #endif
1110
1111 #if PLATFORM(IOS)
1112 + (void)enableWebThread
1113 {
1114     static BOOL isWebThreadEnabled = NO;
1115     if (!isWebThreadEnabled) {
1116         WebCoreObjCDeallocOnWebThread([WebBasePluginPackage class]);
1117         WebCoreObjCDeallocOnWebThread([WebDataSource class]);
1118         WebCoreObjCDeallocOnWebThread([WebFrame class]);
1119         WebCoreObjCDeallocOnWebThread([WebHTMLView class]);
1120         WebCoreObjCDeallocOnWebThread([WebHistoryItem class]);
1121         WebCoreObjCDeallocOnWebThread([WebPlainWhiteView class]);
1122         WebCoreObjCDeallocOnWebThread([WebPolicyDecisionListener class]);
1123         WebCoreObjCDeallocOnWebThread([WebView class]);
1124         WebCoreObjCDeallocOnWebThread([WebVisiblePosition class]);
1125         if (applicationIsTheEconomistOnIPhone() && !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_DELEGATE_CALLS_IN_COMMON_RUNLOOP_MODES))
1126             WebThreadSetDelegateSourceRunLoopMode(kCFRunLoopDefaultMode);
1127         WebThreadEnable();
1128         isWebThreadEnabled = YES;
1129     }
1130 }
1131
1132 - (id)initSimpleHTMLDocumentWithStyle:(NSString *)style frame:(CGRect)frame preferences:(WebPreferences *)preferences groupName:(NSString *)groupName
1133 {
1134     self = [super initWithFrame:frame];
1135     if (!self)
1136         return nil;
1137     
1138     _private = [[WebViewPrivate alloc] init];
1139     
1140 #ifndef NDEBUG
1141     WTF::RefCountedLeakCounter::suppressMessages(webViewIsOpen);
1142 #endif
1143     
1144     if (!preferences)
1145         preferences = [WebPreferences standardPreferences];
1146     [preferences willAddToWebView];
1147     
1148     _private->preferences = [preferences retain];
1149     _private->mainFrameDocumentReady = NO;
1150     _private->drawsBackground = YES;
1151     _private->backgroundColor = CGColorRetain(cachedCGColor(Color::white, ColorSpaceDeviceRGB));
1152     
1153     WebFrameView *frameView = nil;
1154     frameView = [[WebFrameView alloc] initWithFrame: CGRectMake(0,0,frame.size.width,frame.size.height)];
1155     [frameView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
1156     [self addSubview:frameView];
1157     [frameView release];
1158
1159     
1160     Page::PageClients pageClients;
1161     pageClients.chromeClient = new WebChromeClientIOS(self);
1162 #if ENABLE(DRAG_SUPPORT)
1163     pageClients.dragClient = new WebDragClient(self);
1164 #endif
1165     pageClients.editorClient = new WebEditorClient(self);
1166     pageClients.inspectorClient = new WebInspectorClient(self);
1167     pageClients.loaderClientForMainFrame = new WebFrameLoaderClient;
1168     pageClients.progressTrackerClient = new WebProgressTrackerClient(self);
1169     _private->page = new Page(pageClients);
1170     
1171     [self setSmartInsertDeleteEnabled:YES];
1172     
1173     // FIXME: <rdar://problem/6851451> Should respect preferences in fast path WebView initialization
1174     // We are ignoring the preferences object on fast path and just using Settings defaults (everything fancy off).
1175     // This matches how UIKit sets up the preferences. We need to set  default values for fonts though, <rdar://problem/6850611>.
1176     // This should be revisited later. There is some risk involved, _preferencesChanged used to show up badly in Shark.
1177     _private->page->settings().setMinimumLogicalFontSize(9);
1178     _private->page->settings().setDefaultFontSize([_private->preferences defaultFontSize]);
1179     _private->page->settings().setDefaultFixedFontSize(13);
1180     _private->page->settings().setDownloadableBinaryFontsEnabled(false);
1181     _private->page->settings().setAcceleratedDrawingEnabled([preferences acceleratedDrawingEnabled]);
1182     _private->page->settings().setScreenFontSubstitutionEnabled(false);
1183     
1184     // FIXME: <rdar://problem/7394370> Always use primary font baseline in text field base line calculation, ignore fallback fonts.
1185     _private->page->settings().setAlwaysUseBaselineOfPrimaryFont([preferences _alwaysUseBaselineOfPrimaryFont]);
1186
1187     _private->page->settings().setFontFallbackPrefersPictographs(true);
1188     _private->page->settings().setPictographFontFamily("AppleColorEmoji");
1189     
1190     // FIXME: this is a workaround for <rdar://problem/11518688> REGRESSION: Quoted text font changes when replying to certain email
1191     _private->page->settings().setStandardFontFamily([_private->preferences standardFontFamily]);
1192     
1193     // FIXME: this is a workaround for <rdar://problem/11820090> Quoted text changes in size when replying to certain email
1194     _private->page->settings().setMinimumFontSize([_private->preferences minimumFontSize]);
1195
1196     [self setGroupName:groupName];
1197
1198 #if ENABLE(REMOTE_INSPECTOR)
1199     _private->page->setRemoteInspectionAllowed(isInternalInstall());
1200 #endif
1201     
1202     [self _updateScreenScaleFromWindow];
1203     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_wakWindowScreenScaleChanged:) name:WAKWindowScreenScaleDidChangeNotification object:nil];
1204     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_wakWindowVisibilityChanged:) name:WAKWindowVisibilityDidChangeNotification object:nil];
1205
1206     [WebFrame _createMainFrameWithSimpleHTMLDocumentWithPage:_private->page frameView:frameView style:style];
1207     
1208     [self _addToAllWebViewsSet];
1209     
1210     ++WebViewCount;
1211     
1212     SecurityPolicy::setLocalLoadPolicy(SecurityPolicy::AllowLocalLoadsForLocalAndSubstituteData);
1213     
1214     return self;
1215 }
1216
1217 + (void)_handleMemoryWarning
1218 {
1219     ASSERT(WebThreadIsCurrent());
1220     WebKit::MemoryMeasure totalMemory("Memory warning: Overall memory change from [WebView _handleMemoryWarning].");
1221
1222     // Always peform the following.
1223     [WebView purgeInactiveFontData];
1224
1225     // Only perform the remaining if a non-simple document was created.
1226     if (!didOneTimeInitialization)
1227         return;
1228
1229     tileControllerMemoryHandler().trimUnparentedTilesToTarget(0);
1230
1231 #if ENABLE(DISK_IMAGE_CACHE)
1232     {
1233         WebKit::MemoryMeasure measurer("Memory warning: flushing images to disk.");
1234         WebCore::memoryCache()->flushCachedImagesToDisk();
1235     }
1236 #endif
1237
1238     [WebStorageManager closeIdleLocalStorageDatabases];
1239
1240     [WebView _releaseMemoryNow];
1241 }
1242
1243 + (void)registerForMemoryNotifications
1244 {
1245     BOOL shouldAutoClearPressureOnMemoryRelease = !WebCore::applicationIsMobileSafari();
1246
1247     memoryPressureHandler().installMemoryReleaseBlock(^{
1248         [WebView _handleMemoryWarning];
1249     }, shouldAutoClearPressureOnMemoryRelease);
1250
1251 #if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
1252     static dispatch_source_t memoryNotificationEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYSTATUS, 0, DISPATCH_MEMORYSTATUS_PRESSURE_WARN, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
1253 #else
1254     static dispatch_source_t memoryNotificationEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_VM, 0, DISPATCH_VM_PRESSURE, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
1255 #endif
1256     dispatch_source_set_event_handler(memoryNotificationEventSource, ^{
1257         // Set memory pressure flag and schedule releasing memory in web thread runloop exit.
1258         memoryPressureHandler().setReceivedMemoryPressure(WebCore::MemoryPressureReasonVMPressure);
1259     });
1260
1261     dispatch_resume(memoryNotificationEventSource);
1262
1263     if (!shouldAutoClearPressureOnMemoryRelease) {
1264         // Listen to memory status notification to reset the memory pressure flag.
1265         static dispatch_source_t memoryStatusEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYSTATUS,
1266                                                                                     0,
1267                                                                                     DISPATCH_MEMORYSTATUS_PRESSURE_WARN | DISPATCH_MEMORYSTATUS_PRESSURE_NORMAL,
1268                                                                                     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
1269         dispatch_source_set_event_handler(memoryStatusEventSource, ^{
1270             unsigned long currentStatus = dispatch_source_get_data(memoryStatusEventSource);
1271             if (currentStatus == DISPATCH_MEMORYSTATUS_PRESSURE_NORMAL)
1272                 memoryPressureHandler().clearMemoryPressure();
1273             else if (currentStatus == DISPATCH_MEMORYSTATUS_PRESSURE_WARN)
1274                 memoryPressureHandler().setReceivedMemoryPressure(WebCore::MemoryPressureReasonVMStatus);
1275         });
1276
1277         dispatch_resume(memoryStatusEventSource);
1278     }
1279 }
1280
1281 + (void)_releaseMemoryNow
1282 {
1283     ASSERT(WebThreadIsCurrent());
1284     [WebView discardAllCompiledCode];
1285     [WebView garbageCollectNow];
1286     [WebView purgeInactiveFontData];
1287     [WebView drainLayerPool];
1288     [WebCache emptyInMemoryResources];
1289     [WebView releaseFastMallocMemoryOnCurrentThread];
1290
1291     dispatch_async(dispatch_get_main_queue(), ^{
1292         // Clear the main thread's TCMalloc thread cache.
1293         [WebView releaseFastMallocMemoryOnCurrentThread];
1294     });
1295 }
1296
1297 + (void)_clearPrivateBrowsingSessionCookieStorage
1298 {
1299     WebFrameNetworkingContext::clearPrivateBrowsingSessionCookieStorage();
1300 }
1301
1302 - (void)_replaceCurrentHistoryItem:(WebHistoryItem *)item
1303 {
1304     Frame* frame = [self _mainCoreFrame];
1305     if (frame)
1306         frame->loader().history().replaceCurrentItem(core(item));
1307 }
1308
1309 + (void)willEnterBackgroundWithCompletionHandler:(void(^)(void))handler
1310 {
1311     WebThreadRun(^{
1312         [WebView _releaseMemoryNow];
1313         dispatch_async(dispatch_get_main_queue(), handler);
1314     });
1315 }
1316
1317 + (void)releaseFastMallocMemoryOnCurrentThread
1318 {
1319     WebKit::MemoryMeasure measurer("Memory warning: Releasing fast malloc memory to system.");
1320     WTF::releaseFastMallocFreeMemory();
1321 }
1322
1323 + (void)garbageCollectNow
1324 {
1325     ASSERT(WebThreadIsCurrent());
1326     WebKit::MemoryMeasure measurer("Memory warning: Calling JavaScript GC.");
1327     gcController().garbageCollectNow();
1328 }
1329
1330 + (void)purgeInactiveFontData
1331 {
1332     ASSERT(WebThreadIsCurrent());
1333     WebKit::MemoryMeasure measurer("Memory warning: Purging inactive font data.");
1334     fontCache().purgeInactiveFontData();
1335 }
1336
1337 + (void)drainLayerPool
1338 {
1339     ASSERT(WebThreadIsCurrent());
1340     WebKit::MemoryMeasure measurer("Memory warning: Draining layer pool.");
1341     WebCore::LegacyTileCache::drainLayerPool();
1342 }
1343
1344 + (void)discardAllCompiledCode
1345 {
1346     ASSERT(WebThreadIsCurrent());
1347     WebKit::MemoryMeasure measurer("Memory warning: Discarding JIT'ed code.");
1348     gcController().discardAllCompiledCode();
1349 }
1350
1351 + (BOOL)isCharacterSmartReplaceExempt:(unichar)character isPreviousCharacter:(BOOL)b
1352 {
1353     return WebCore::isCharacterSmartReplaceExempt(character, b);
1354 }
1355
1356 - (void)updateLayoutIgnorePendingStyleSheets
1357 {
1358     WebThreadRun(^{
1359         for (Frame* frame = [self _mainCoreFrame]; frame; frame = frame->tree().traverseNext()) {
1360             Document *document = frame->document();
1361             if (document)
1362                 document->updateLayoutIgnorePendingStylesheets();
1363         }
1364     });
1365 }
1366 #endif // PLATFORM(IOS)
1367
1368 static NSMutableSet *knownPluginMIMETypes()
1369 {
1370     static NSMutableSet *mimeTypes = [[NSMutableSet alloc] init];
1371     
1372     return mimeTypes;
1373 }
1374
1375 + (void)_registerPluginMIMEType:(NSString *)MIMEType
1376 {
1377     [WebView registerViewClass:[WebHTMLView class] representationClass:[WebHTMLRepresentation class] forMIMEType:MIMEType];
1378     [knownPluginMIMETypes() addObject:MIMEType];
1379 }
1380
1381 + (void)_unregisterPluginMIMEType:(NSString *)MIMEType
1382 {
1383     [self _unregisterViewClassAndRepresentationClassForMIMEType:MIMEType];
1384     [knownPluginMIMETypes() removeObject:MIMEType];
1385 }
1386
1387 + (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType allowingPlugins:(BOOL)allowPlugins
1388 {
1389     MIMEType = [MIMEType lowercaseString];
1390     Class viewClass = [[WebFrameView _viewTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
1391     Class repClass = [[WebDataSource _repTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType];
1392
1393 #if PLATFORM(IOS)
1394 #define WebPDFView ([WebView _getPDFViewClass])
1395 #endif
1396     if (!viewClass || !repClass || [[WebPDFView supportedMIMETypes] containsObject:MIMEType]) {
1397 #if PLATFORM(IOS)
1398 #undef WebPDFView
1399 #endif
1400         // Our optimization to avoid loading the plug-in DB and image types for the HTML case failed.
1401
1402         if (allowPlugins) {
1403             // Load the plug-in DB allowing plug-ins to install types.
1404             [WebPluginDatabase sharedDatabase];
1405         }
1406
1407         // Load the image types and get the view class and rep class. This should be the fullest picture of all handled types.
1408         viewClass = [[WebFrameView _viewTypesAllowImageTypeOmission:NO] _webkit_objectForMIMEType:MIMEType];
1409         repClass = [[WebDataSource _repTypesAllowImageTypeOmission:NO] _webkit_objectForMIMEType:MIMEType];
1410     }
1411     
1412     if (viewClass && repClass) {
1413         if (viewClass == [WebHTMLView class] && repClass == [WebHTMLRepresentation class]) {
1414             // Special-case WebHTMLView for text types that shouldn't be shown.
1415             if ([[WebHTMLView unsupportedTextMIMETypes] containsObject:MIMEType])
1416                 return NO;
1417
1418             // If the MIME type is a known plug-in we might not want to load it.
1419             if (!allowPlugins && [knownPluginMIMETypes() containsObject:MIMEType]) {
1420                 BOOL isSupportedByWebKit = [[WebHTMLView supportedNonImageMIMETypes] containsObject:MIMEType] ||
1421                     [[WebHTMLView supportedMIMETypes] containsObject:MIMEType];
1422                 
1423                 // If this is a known plug-in MIME type and WebKit can't show it natively, we don't want to show it.
1424                 if (!isSupportedByWebKit)
1425                     return NO;
1426             }
1427         }
1428         if (vClass)
1429             *vClass = viewClass;
1430         if (rClass)
1431             *rClass = repClass;
1432         return YES;
1433     }
1434     
1435     return NO;
1436 }
1437
1438 - (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType
1439 {
1440     if ([[self class] _viewClass:vClass andRepresentationClass:rClass forMIMEType:MIMEType allowingPlugins:[_private->preferences arePlugInsEnabled]])
1441         return YES;
1442 #if !PLATFORM(IOS)
1443     if (_private->pluginDatabase) {
1444         WebBasePluginPackage *pluginPackage = [_private->pluginDatabase pluginForMIMEType:MIMEType];
1445         if (pluginPackage) {
1446             if (vClass)
1447                 *vClass = [WebHTMLView class];
1448             if (rClass)
1449                 *rClass = [WebHTMLRepresentation class];
1450             return YES;
1451         }
1452     }
1453 #endif
1454     return NO;
1455 }
1456
1457 + (void)_setAlwaysUsesComplexTextCodePath:(BOOL)f
1458 {
1459     Font::setCodePath(f ? Font::Complex : Font::Auto);
1460 }
1461
1462 + (void)_setAllowsRoundingHacks:(BOOL)allowsRoundingHacks
1463 {
1464     TextRun::setAllowsRoundingHacks(allowsRoundingHacks);
1465 }
1466
1467 + (BOOL)_allowsRoundingHacks
1468 {
1469     return TextRun::allowsRoundingHacks();
1470 }
1471
1472 + (BOOL)canCloseAllWebViews
1473 {
1474     return DOMWindow::dispatchAllPendingBeforeUnloadEvents();
1475 }
1476
1477 + (void)closeAllWebViews
1478 {
1479     DOMWindow::dispatchAllPendingUnloadEvents();
1480
1481     // This will close the WebViews in a random order. Change this if close order is important.
1482     // Make a new set to avoid mutating the set we are enumerating.
1483     NSSet *webViewsToClose = [NSSet setWithSet:(NSSet *)allWebViewsSet]; 
1484     NSEnumerator *enumerator = [webViewsToClose objectEnumerator];
1485     while (WebView *webView = [enumerator nextObject])
1486         [webView close];
1487 }
1488
1489 + (BOOL)canShowFile:(NSString *)path
1490 {
1491     return [[self class] canShowMIMEType:[WebView _MIMETypeForFile:path]];
1492 }
1493
1494 #if !PLATFORM(IOS)
1495 + (NSString *)suggestedFileExtensionForMIMEType:(NSString *)type
1496 {
1497     return WKGetPreferredExtensionForMIMEType(type);
1498 }
1499 #endif
1500
1501 - (BOOL)_isClosed
1502 {
1503     return !_private || _private->closed;
1504 }
1505
1506 #if PLATFORM(IOS)
1507 - (void)_dispatchUnloadEvent
1508 {
1509     WebThreadRun(^{
1510         WebFrame *mainFrame = [self mainFrame];
1511         Frame *coreMainFrame = core(mainFrame);
1512         if (coreMainFrame) {
1513             Document *document = coreMainFrame->document();
1514             if (document)
1515                 document->dispatchWindowEvent(Event::create(eventNames().unloadEvent, false, false));
1516         }
1517     });
1518 }
1519
1520 - (DOMCSSStyleDeclaration *)styleAtSelectionStart
1521 {
1522     WebFrame *mainFrame = [self mainFrame];
1523     Frame *coreMainFrame = core(mainFrame);
1524     if (!coreMainFrame)
1525         return nil;
1526     return coreMainFrame->styleAtSelectionStart();
1527 }
1528
1529 - (NSUInteger)_renderTreeSize
1530 {
1531     if (!_private->page)
1532         return 0;
1533     return _private->page->renderTreeSize();
1534 }
1535
1536 - (void)_dispatchTileDidDraw:(CALayer*)tile
1537 {
1538     id mailDelegate = [self _webMailDelegate];
1539     if ([mailDelegate respondsToSelector:@selector(_webthread_webView:tileDidDraw:)]) {
1540         [mailDelegate _webthread_webView:self tileDidDraw:tile];
1541         return;
1542     }
1543
1544     if (!OSAtomicCompareAndSwap32(0, 1, &_private->didDrawTiles))
1545         return;
1546
1547     WebThreadLock();
1548
1549     [[[self _UIKitDelegateForwarder] asyncForwarder] webViewDidDrawTiles:self];
1550 }
1551
1552 - (void)_willStartScrollingOrZooming
1553 {
1554     // Pause timers during top level interaction
1555     if (_private->mainViewIsScrollingOrZooming)
1556         return;
1557     _private->mainViewIsScrollingOrZooming = YES;
1558
1559     // This suspends active DOM objects like timers, but not media.
1560     [[self mainFrame] setTimeoutsPaused:YES];
1561
1562     // This defers loading callbacks only.
1563     // WARNING: This behavior could change if Bug 49401 lands in open source WebKit again.
1564     [self setDefersCallbacks:YES];
1565 }
1566
1567 - (void)_didFinishScrollingOrZooming
1568 {
1569     if (!_private->mainViewIsScrollingOrZooming)
1570         return;
1571     _private->mainViewIsScrollingOrZooming = NO;
1572     [self setDefersCallbacks:NO];
1573     [[self mainFrame] setTimeoutsPaused:NO];
1574     FrameView* view = [self _mainCoreFrame]->view();
1575     if (view && view->renderView())
1576         view->renderView()->resumePausedImageAnimationsIfNeeded();
1577 }
1578
1579 - (void)_setResourceLoadSchedulerSuspended:(BOOL)suspend
1580 {
1581     if (suspend)
1582         resourceLoadScheduler()->suspendPendingRequests();
1583     else
1584         resourceLoadScheduler()->resumePendingRequests();
1585 }
1586
1587 + (void)_setAllowCookies:(BOOL)allow
1588 {
1589     ResourceRequestBase::setDefaultAllowCookies(allow);
1590 }
1591
1592 + (BOOL)_allowCookies
1593 {
1594     return ResourceRequestBase::defaultAllowCookies();
1595 }
1596
1597 + (BOOL)_isUnderMemoryPressure
1598 {
1599     return memoryPressureHandler().isUnderMemoryPressure();
1600 }
1601
1602 + (void)_clearMemoryPressure
1603 {
1604     memoryPressureHandler().clearMemoryPressure();
1605 }
1606
1607 + (BOOL)_shouldWaitForMemoryClearMessage
1608 {
1609     return memoryPressureHandler().shouldWaitForMemoryClearMessage();
1610 }
1611 #endif // PLATFORM(IOS)
1612
1613 - (void)_closePluginDatabases
1614 {
1615     pluginDatabaseClientCount--;
1616
1617     // Close both sets of plug-in databases because plug-ins need an opportunity to clean up files, etc.
1618
1619 #if !PLATFORM(IOS)
1620     // Unload the WebView local plug-in database. 
1621     if (_private->pluginDatabase) {
1622         [_private->pluginDatabase destroyAllPluginInstanceViews];
1623         [_private->pluginDatabase close];
1624         [_private->pluginDatabase release];
1625         _private->pluginDatabase = nil;
1626     }
1627 #endif
1628     
1629     // Keep the global plug-in database active until the app terminates to avoid having to reload plug-in bundles.
1630     if (!pluginDatabaseClientCount && applicationIsTerminating)
1631         [WebPluginDatabase closeSharedDatabase];
1632 }
1633
1634 - (void)_closeWithFastTeardown 
1635 {
1636 #ifndef NDEBUG
1637     WTF::RefCountedLeakCounter::suppressMessages("At least one WebView was closed with fast teardown.");
1638 #endif
1639
1640 #if !PLATFORM(IOS)
1641     [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
1642 #endif
1643     [[NSNotificationCenter defaultCenter] removeObserver:self];
1644
1645     [self _closePluginDatabases];
1646 }
1647
1648 static bool fastDocumentTeardownEnabled()
1649 {
1650 #ifdef NDEBUG
1651     static bool enabled = ![[NSUserDefaults standardUserDefaults] boolForKey:WebKitEnableFullDocumentTeardownPreferenceKey];
1652 #else
1653     static bool initialized = false;
1654     static bool enabled = false;
1655     if (!initialized) {
1656         // This allows debug builds to default to not have fast teardown, so leak checking still works.
1657         // But still allow the WebKitEnableFullDocumentTeardown default to override it if present.
1658         NSNumber *setting = [[NSUserDefaults standardUserDefaults] objectForKey:WebKitEnableFullDocumentTeardownPreferenceKey];
1659         if (setting)
1660             enabled = ![setting boolValue];
1661         initialized = true;
1662     }
1663 #endif
1664     return enabled;
1665 }
1666
1667 // _close is here only for backward compatibility; clients and subclasses should use
1668 // public method -close instead.
1669 - (void)_close
1670 {
1671 #if PLATFORM(IOS)
1672     // Always clear delegates on calling thread, becasue caller can deallocate delegates right after calling -close
1673     // (and could in fact already be in delegate's -dealloc method, as seen in <rdar://problem/11540972>).
1674
1675     [self _clearDelegates];
1676
1677     // Fix for problems such as <rdar://problem/5774587> Crash closing tab in WebCore::Frame::page() from -[WebCoreFrameBridge pauseTimeouts]
1678     WebThreadRun(^{
1679 #endif            
1680
1681     if (!_private || _private->closed)
1682         return;
1683
1684     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewWillCloseNotification object:self];
1685
1686     _private->closed = YES;
1687     [self _removeFromAllWebViewsSet];
1688
1689 #ifndef NDEBUG
1690     WTF::RefCountedLeakCounter::cancelMessageSuppression(webViewIsOpen);
1691 #endif
1692
1693     // To quit the apps fast we skip document teardown, except plugins
1694     // need to be destroyed and unloaded.
1695     if (applicationIsTerminating && fastDocumentTeardownEnabled()) {
1696         [self _closeWithFastTeardown];
1697         return;
1698     }
1699
1700 #if ENABLE(VIDEO) && !PLATFORM(IOS)
1701     [self _exitFullscreen];
1702 #endif
1703
1704 #if PLATFORM(IOS)
1705     _private->closing = YES;
1706 #endif
1707
1708     if (Frame* mainFrame = [self _mainCoreFrame])
1709         mainFrame->loader().detachFromParent();
1710
1711     [self setHostWindow:nil];
1712
1713 #if !PLATFORM(IOS)
1714     [self setDownloadDelegate:nil];
1715     [self setEditingDelegate:nil];
1716     [self setFrameLoadDelegate:nil];
1717     [self setPolicyDelegate:nil];
1718     [self setResourceLoadDelegate:nil];
1719     [self setScriptDebugDelegate:nil];
1720     [self setUIDelegate:nil];
1721
1722     [_private->inspector webViewClosed];
1723 #endif
1724
1725 #if !PLATFORM(IOS)
1726     // To avoid leaks, call removeDragCaret in case it wasn't called after moveDragCaretToPoint.
1727     [self removeDragCaret];
1728 #endif
1729
1730     _private->group->removeWebView(self);
1731
1732     // Deleteing the WebCore::Page will clear the page cache so we call destroy on
1733     // all the plug-ins in the page cache to break any retain cycles.
1734     // See comment in HistoryItem::releaseAllPendingPageCaches() for more information.
1735     Page* page = _private->page;
1736     _private->page = 0;
1737     delete page;
1738
1739 #if !PLATFORM(IOS)
1740     if (_private->hasSpellCheckerDocumentTag) {
1741         [[NSSpellChecker sharedSpellChecker] closeSpellDocumentWithTag:_private->spellCheckerDocumentTag];
1742         _private->hasSpellCheckerDocumentTag = NO;
1743     }
1744 #endif
1745
1746     if (_private->layerFlushController) {
1747         _private->layerFlushController->invalidate();
1748         _private->layerFlushController = nullptr;
1749     }
1750     
1751 #if USE(GLIB)
1752     [self _clearGlibLoopObserver];
1753 #endif
1754
1755     [[self _notificationProvider] unregisterWebView:self];
1756
1757 #if !PLATFORM(IOS)
1758     [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
1759 #endif
1760     [[NSNotificationCenter defaultCenter] removeObserver:self];
1761
1762     [WebPreferences _removeReferenceForIdentifier:[self preferencesIdentifier]];
1763
1764     WebPreferences *preferences = _private->preferences;
1765     _private->preferences = nil;
1766     [preferences didRemoveFromWebView];
1767     [preferences release];
1768
1769     [self _closePluginDatabases];
1770
1771 #ifndef NDEBUG
1772     // Need this to make leak messages accurate.
1773     if (applicationIsTerminating) {
1774         gcController().garbageCollectNow();
1775         [WebCache setDisabled:YES];
1776     }
1777 #endif
1778 #if PLATFORM(IOS)
1779     // Fix for problems such as <rdar://problem/5774587> Crash closing tab in WebCore::Frame::page() from -[WebCoreFrameBridge pauseTimeouts]
1780     });
1781 #endif            
1782 }
1783
1784 // Indicates if the WebView is in the midst of a user gesture.
1785 - (BOOL)_isProcessingUserGesture
1786 {
1787     return ScriptController::processingUserGesture();
1788 }
1789
1790 + (NSString *)_MIMETypeForFile:(NSString *)path
1791 {
1792 #if !PLATFORM(IOS)
1793     NSString *extension = [path pathExtension];
1794 #endif
1795     NSString *MIMEType = nil;
1796
1797 #if !PLATFORM(IOS)
1798     // Get the MIME type from the extension.
1799     if ([extension length] != 0) {
1800         MIMEType = WKGetMIMETypeForExtension(extension);
1801     }
1802 #endif
1803
1804     // If we can't get a known MIME type from the extension, sniff.
1805     if ([MIMEType length] == 0 || [MIMEType isEqualToString:@"application/octet-stream"]) {
1806         NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
1807         NSData *data = [handle readDataOfLength:WEB_GUESS_MIME_TYPE_PEEK_LENGTH];
1808         [handle closeFile];
1809         if ([data length] != 0) {
1810             MIMEType = [data _webkit_guessedMIMEType];
1811         }
1812         if ([MIMEType length] == 0) {
1813             MIMEType = @"application/octet-stream";
1814         }
1815     }
1816
1817     return MIMEType;
1818 }
1819
1820 - (WebDownload *)_downloadURL:(NSURL *)URL
1821 {
1822     ASSERT(URL);
1823     
1824     NSURLRequest *request = [[NSURLRequest alloc] initWithURL:URL];
1825     WebDownload *download = [WebDownload _downloadWithRequest:request
1826                                                      delegate:_private->downloadDelegate
1827                                                     directory:nil];
1828     [request release];
1829     
1830     return download;
1831 }
1832
1833 - (WebView *)_openNewWindowWithRequest:(NSURLRequest *)request
1834 {
1835     NSDictionary *features = [[NSDictionary alloc] init];
1836     WebView *newWindowWebView = [[self _UIDelegateForwarder] webView:self
1837                                             createWebViewWithRequest:nil
1838                                                       windowFeatures:features];
1839     [features release];
1840     if (!newWindowWebView)
1841         return nil;
1842
1843     CallUIDelegate(newWindowWebView, @selector(webViewShow:));
1844     return newWindowWebView;
1845 }
1846
1847 - (WebInspector *)inspector
1848 {
1849     if (!_private->inspector)
1850         _private->inspector = [[WebInspector alloc] initWithWebView:self];
1851     return _private->inspector;
1852 }
1853
1854 #if ENABLE(REMOTE_INSPECTOR)
1855 + (void)_enableRemoteInspector
1856 {
1857     RemoteInspector::shared().start();
1858 }
1859
1860 + (void)_disableRemoteInspector
1861 {
1862     RemoteInspector::shared().stop();
1863 }
1864
1865 + (void)_disableAutoStartRemoteInspector
1866 {
1867     RemoteInspector::startDisabled();
1868 }
1869
1870 + (BOOL)_isRemoteInspectorEnabled
1871 {
1872     return RemoteInspector::shared().enabled();
1873 }
1874
1875 + (BOOL)_hasRemoteInspectorSession
1876 {
1877     return RemoteInspector::shared().hasActiveDebugSession();
1878 }
1879
1880 - (BOOL)allowsRemoteInspection
1881 {
1882     return _private->page->remoteInspectionAllowed();
1883 }
1884
1885 - (void)setAllowsRemoteInspection:(BOOL)allow
1886 {
1887     _private->page->setRemoteInspectionAllowed(allow);
1888 }
1889
1890 - (void)setShowingInspectorIndication:(BOOL)showing
1891 {
1892 #if PLATFORM(IOS)
1893     ASSERT(WebThreadIsLocked());
1894
1895     if (showing) {
1896         if (!_private->indicateLayer) {
1897             _private->indicateLayer = [[WebIndicateLayer alloc] initWithWebView:self];
1898             [_private->indicateLayer setNeedsLayout];
1899             [[[self window] hostLayer] addSublayer:_private->indicateLayer];
1900         }
1901     } else {
1902         [_private->indicateLayer removeFromSuperlayer];
1903         [_private->indicateLayer release];
1904         _private->indicateLayer = nil;
1905     }
1906 #else
1907     // Implemented in WebCore::InspectorOverlay.
1908 #endif
1909 }
1910
1911 #if PLATFORM(IOS)
1912 - (void)_setHostApplicationProcessIdentifier:(pid_t)pid auditToken:(audit_token_t)auditToken
1913 {
1914     RetainPtr<CFDataRef> auditData = adoptCF(CFDataCreate(nullptr, (const UInt8*)&auditToken, sizeof(auditToken)));
1915     RemoteInspector::shared().setParentProcessInformation(pid, auditData);
1916 }
1917 #endif // PLATFORM(IOS)
1918 #endif // ENABLE(REMOTE_INSPECTOR)
1919
1920 - (WebCore::Page*)page
1921 {
1922     return _private->page;
1923 }
1924
1925 #if !PLATFORM(IOS)
1926 - (NSMenu *)_menuForElement:(NSDictionary *)element defaultItems:(NSArray *)items
1927 {
1928     NSArray *defaultMenuItems = [[WebDefaultUIDelegate sharedUIDelegate] webView:self contextMenuItemsForElement:element defaultMenuItems:items];
1929     NSArray *menuItems = defaultMenuItems;
1930
1931     // CallUIDelegate returns nil if UIDelegate is nil or doesn't respond to the selector. So we need to check that here
1932     // to distinguish between using defaultMenuItems or the delegate really returning nil to say "no context menu".
1933     SEL selector = @selector(webView:contextMenuItemsForElement:defaultMenuItems:);
1934     if (_private->UIDelegate && [_private->UIDelegate respondsToSelector:selector]) {
1935         menuItems = CallUIDelegate(self, selector, element, defaultMenuItems);
1936         if (!menuItems)
1937             return nil;
1938     }
1939
1940     unsigned count = [menuItems count];
1941     if (!count)
1942         return nil;
1943
1944     NSMenu *menu = [[NSMenu alloc] init];
1945     for (unsigned i = 0; i < count; i++)
1946         [menu addItem:[menuItems objectAtIndex:i]];
1947
1948     return [menu autorelease];
1949 }
1950 #endif
1951
1952 - (void)_mouseDidMoveOverElement:(NSDictionary *)dictionary modifierFlags:(NSUInteger)modifierFlags
1953 {
1954     // We originally intended to call this delegate method sometimes with a nil dictionary, but due to
1955     // a bug dating back to WebKit 1.0 this delegate was never called with nil! Unfortunately we can't
1956     // start calling this with nil since it will break Adobe Help Viewer, and possibly other clients.
1957     if (!dictionary)
1958         return;
1959     CallUIDelegate(self, @selector(webView:mouseDidMoveOverElement:modifierFlags:), dictionary, modifierFlags);
1960 }
1961
1962 - (void)_loadBackForwardListFromOtherView:(WebView *)otherView
1963 {
1964     if (!_private->page)
1965         return;
1966     
1967     if (!otherView->_private->page)
1968         return;
1969     
1970     // It turns out the right combination of behavior is done with the back/forward load
1971     // type.  (See behavior matrix at the top of WebFramePrivate.)  So we copy all the items
1972     // in the back forward list, and go to the current one.
1973
1974     BackForwardClient* backForwardClient = _private->page->backForward().client();
1975     ASSERT(!backForwardClient->currentItem()); // destination list should be empty
1976
1977     BackForwardClient* otherBackForwardClient = otherView->_private->page->backForward().client();
1978     if (!otherBackForwardClient->currentItem())
1979         return; // empty back forward list, bail
1980     
1981     HistoryItem* newItemToGoTo = 0;
1982
1983     int lastItemIndex = otherBackForwardClient->forwardListCount();
1984     for (int i = -otherBackForwardClient->backListCount(); i <= lastItemIndex; ++i) {
1985         if (i == 0) {
1986             // If this item is showing , save away its current scroll and form state,
1987             // since that might have changed since loading and it is normally not saved
1988             // until we leave that page.
1989             otherView->_private->page->mainFrame().loader().history().saveDocumentAndScrollState();
1990         }
1991         RefPtr<HistoryItem> newItem = otherBackForwardClient->itemAtIndex(i)->copy();
1992         if (i == 0) 
1993             newItemToGoTo = newItem.get();
1994         backForwardClient->addItem(newItem.release());
1995     }
1996     
1997     ASSERT(newItemToGoTo);
1998     _private->page->goToItem(newItemToGoTo, FrameLoadType::IndexedBackForward);
1999 }
2000
2001 - (void)_setFormDelegate: (id<WebFormDelegate>)delegate
2002 {
2003     _private->formDelegate = delegate;
2004 #if PLATFORM(IOS)
2005     [_private->formDelegateForwarder clearTarget];
2006     [_private->formDelegateForwarder release];
2007     _private->formDelegateForwarder = nil;
2008 #endif
2009 }
2010
2011 - (id<WebFormDelegate>)_formDelegate
2012 {
2013     return _private->formDelegate;
2014 }
2015
2016 #if PLATFORM(IOS)
2017 - (id)_formDelegateForwarder
2018 {
2019     if (_private->closing)
2020         return nil;
2021
2022     if (!_private->formDelegateForwarder)
2023         _private->formDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:[self _formDelegate] defaultTarget:[WebDefaultFormDelegate sharedFormDelegate]];
2024     return _private->formDelegateForwarder;
2025 }
2026
2027 - (id)_formDelegateForSelector:(SEL)selector
2028 {
2029     id delegate = self->_private->formDelegate;
2030     if ([delegate respondsToSelector:selector])
2031         return delegate;
2032
2033     delegate = [WebDefaultFormDelegate sharedFormDelegate];
2034     if ([delegate respondsToSelector:selector])
2035         return delegate;
2036
2037     return nil;
2038 }
2039 #endif
2040
2041 #if !PLATFORM(IOS)
2042 - (BOOL)_needsAdobeFrameReloadingQuirk
2043 {
2044     static BOOL needsQuirk = WKAppVersionCheckLessThan(@"com.adobe.Acrobat", -1, 9.0)
2045         || WKAppVersionCheckLessThan(@"com.adobe.Acrobat.Pro", -1, 9.0)
2046         || WKAppVersionCheckLessThan(@"com.adobe.Reader", -1, 9.0)
2047         || WKAppVersionCheckLessThan(@"com.adobe.distiller", -1, 9.0)
2048         || WKAppVersionCheckLessThan(@"com.adobe.Contribute", -1, 4.2)
2049         || WKAppVersionCheckLessThan(@"com.adobe.dreamweaver-9.0", -1, 9.1)
2050         || WKAppVersionCheckLessThan(@"com.macromedia.fireworks", -1, 9.1)
2051         || WKAppVersionCheckLessThan(@"com.adobe.InCopy", -1, 5.1)
2052         || WKAppVersionCheckLessThan(@"com.adobe.InDesign", -1, 5.1)
2053         || WKAppVersionCheckLessThan(@"com.adobe.Soundbooth", -1, 2);
2054
2055     return needsQuirk;
2056 }
2057
2058 - (BOOL)_needsLinkElementTextCSSQuirk
2059 {
2060     static BOOL needsQuirk = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_LINK_ELEMENT_TEXT_CSS_QUIRK)
2061         && WKAppVersionCheckLessThan(@"com.e-frontier.shade10", -1, 10.6);
2062     return needsQuirk;
2063 }
2064
2065 - (BOOL)_needsIsLoadingInAPISenseQuirk
2066 {
2067     static BOOL needsQuirk = WKAppVersionCheckLessThan(@"com.apple.iAdProducer", -1, 2.1);
2068     
2069     return needsQuirk;
2070 }
2071
2072 - (BOOL)_needsKeyboardEventDisambiguationQuirks
2073 {
2074     static BOOL needsQuirks = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_IE_COMPATIBLE_KEYBOARD_EVENT_DISPATCH) && !applicationIsSafari();
2075     return needsQuirks;
2076 }
2077
2078 - (BOOL)_needsFrameLoadDelegateRetainQuirk
2079 {
2080     static BOOL needsQuirk = WKAppVersionCheckLessThan(@"com.equinux.iSale5", -1, 5.6);    
2081     return needsQuirk;
2082 }
2083
2084 static bool needsSelfRetainWhileLoadingQuirk()
2085 {
2086     static bool needsQuirk = applicationIsAperture();
2087     return needsQuirk;
2088 }
2089 #endif // !PLATFORM(IOS)
2090
2091 - (BOOL)_needsPreHTML5ParserQuirks
2092 {    
2093 #if !PLATFORM(IOS)
2094     // AOL Instant Messenger and Microsoft My Day contain markup incompatible
2095     // with the new HTML5 parser. If these applications were linked against a
2096     // version of WebKit prior to the introduction of the HTML5 parser, enable
2097     // parser quirks to maintain compatibility. For details, see 
2098     // <https://bugs.webkit.org/show_bug.cgi?id=46134> and
2099     // <https://bugs.webkit.org/show_bug.cgi?id=46334>.
2100     static bool isApplicationNeedingParserQuirks = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_HTML5_PARSER)
2101         && (applicationIsAOLInstantMessenger() || applicationIsMicrosoftMyDay());
2102     
2103     // Mail.app must continue to display HTML email that contains quirky markup.
2104     static bool isAppleMail = applicationIsAppleMail();
2105
2106     return isApplicationNeedingParserQuirks
2107         || isAppleMail
2108 #if ENABLE(DASHBOARD_SUPPORT)
2109         // Pre-HTML5 parser quirks are required to remain compatible with many
2110         // Dashboard widgets. See <rdar://problem/8175982>.
2111         || (_private->page && _private->page->settings().usesDashboardBackwardCompatibilityMode())
2112 #endif
2113         || [[self preferences] usePreHTML5ParserQuirks];
2114 #else
2115     static bool isApplicationNeedingParserQuirks = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_HTML5_PARSER) && applicationIsDaijisenDictionary();
2116     return isApplicationNeedingParserQuirks || [[self preferences] usePreHTML5ParserQuirks];
2117 #endif
2118 }
2119
2120 - (void)_preferencesChangedNotification:(NSNotification *)notification
2121 {
2122 #if PLATFORM(IOS)
2123     // For WebViews that load synchronously, preference changes need to be propagated
2124     // down to WebCore synchronously so that loads in that WebView have the correct
2125     // up-to-date settings.
2126     if (!WebThreadIsLocked())
2127         WebThreadLock();
2128     if ([[self mainFrame] _loadsSynchronously]) {
2129 #endif
2130
2131     WebPreferences *preferences = (WebPreferences *)[notification object];
2132     [self _preferencesChanged:preferences];
2133
2134 #if PLATFORM(IOS)
2135     } else {
2136         WebThreadRun(^{
2137             // It is possible that the prefs object has already changed before the invocation could be called
2138             // on the web thread. This is not possible on TOT which is why they have a simple ASSERT.
2139             WebPreferences *preferences = (WebPreferences *)[notification object];
2140             if (preferences != [self preferences])
2141                 return;
2142             [self _preferencesChanged:preferences];
2143         });
2144     }
2145 #endif
2146 }
2147
2148 - (void)_preferencesChanged:(WebPreferences *)preferences
2149 {    
2150     ASSERT(preferences == [self preferences]);
2151     if (!_private->userAgentOverridden)
2152         _private->userAgent = String();
2153
2154     // Cache this value so we don't have to read NSUserDefaults on each page load
2155     _private->useSiteSpecificSpoofing = [preferences _useSiteSpecificSpoofing];
2156
2157     // Update corresponding WebCore Settings object.
2158     if (!_private->page)
2159         return;
2160
2161 #if PLATFORM(IOS)
2162     // iOS waits to call [WebDatabaseManager sharedWebDatabaseManager] until
2163     // didOneTimeInitialization is true so that we don't initialize databases
2164     // until the first WebView has been created. This is because database
2165     // initialization current requires disk access to populate the origins
2166     // quota map and we want to do this lazily by waiting until WebKit is
2167     // used to display web content in a WebView. The possible cases are:
2168     //   - on one time initialize (the first WebView creation) if databases are enabled (default)
2169     //   - when databases are dynamically enabled later, and they were disabled at startup (this case)
2170     if (didOneTimeInitialization) {
2171         if ([preferences databasesEnabled])
2172             [WebDatabaseManager sharedWebDatabaseManager];
2173         
2174         if ([preferences storageTrackerEnabled])
2175             WebKitInitializeStorageIfNecessary();
2176     }
2177 #endif
2178     
2179     Settings& settings = _private->page->settings();
2180
2181     settings.setCursiveFontFamily([preferences cursiveFontFamily]);
2182     settings.setDefaultFixedFontSize([preferences defaultFixedFontSize]);
2183     settings.setDefaultFontSize([preferences defaultFontSize]);
2184     settings.setDefaultTextEncodingName([preferences defaultTextEncodingName]);
2185     settings.setUsesEncodingDetector([preferences usesEncodingDetector]);
2186     settings.setFantasyFontFamily([preferences fantasyFontFamily]);
2187     settings.setFixedFontFamily([preferences fixedFontFamily]);
2188     settings.setScreenFontSubstitutionEnabled(
2189 #if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
2190         [[NSUserDefaults standardUserDefaults] boolForKey:@"NSFontDefaultScreenFontSubstitutionEnabled"] ||
2191 #endif
2192         [preferences screenFontSubstitutionEnabled]
2193     );
2194     settings.setForceFTPDirectoryListings([preferences _forceFTPDirectoryListings]);
2195     settings.setFTPDirectoryTemplatePath([preferences _ftpDirectoryTemplatePath]);
2196     settings.setLocalStorageDatabasePath([preferences _localStorageDatabasePath]);
2197     settings.setJavaEnabled([preferences isJavaEnabled]);
2198     settings.setScriptEnabled([preferences isJavaScriptEnabled]);
2199     settings.setWebSecurityEnabled([preferences isWebSecurityEnabled]);
2200     settings.setAllowUniversalAccessFromFileURLs([preferences allowUniversalAccessFromFileURLs]);
2201     settings.setAllowFileAccessFromFileURLs([preferences allowFileAccessFromFileURLs]);
2202     settings.setJavaScriptCanOpenWindowsAutomatically([preferences javaScriptCanOpenWindowsAutomatically]);
2203     settings.setMinimumFontSize([preferences minimumFontSize]);
2204     settings.setMinimumLogicalFontSize([preferences minimumLogicalFontSize]);
2205     settings.setPictographFontFamily([preferences pictographFontFamily]);
2206     settings.setPluginsEnabled([preferences arePlugInsEnabled]);
2207     settings.setLocalStorageEnabled([preferences localStorageEnabled]);
2208
2209     _private->page->enableLegacyPrivateBrowsing([preferences privateBrowsingEnabled]);
2210     settings.setSansSerifFontFamily([preferences sansSerifFontFamily]);
2211     settings.setSerifFontFamily([preferences serifFontFamily]);
2212     settings.setStandardFontFamily([preferences standardFontFamily]);
2213     settings.setLoadsImagesAutomatically([preferences loadsImagesAutomatically]);
2214     settings.setLoadsSiteIconsIgnoringImageLoadingSetting([preferences loadsSiteIconsIgnoringImageLoadingPreference]);
2215 #if PLATFORM(IOS)
2216     settings.setShouldPrintBackgrounds(true);
2217 #else
2218     settings.setShouldPrintBackgrounds([preferences shouldPrintBackgrounds]);
2219 #endif
2220     settings.setShrinksStandaloneImagesToFit([preferences shrinksStandaloneImagesToFit]);
2221     settings.setEditableLinkBehavior(core([preferences editableLinkBehavior]));
2222     settings.setTextDirectionSubmenuInclusionBehavior(core([preferences textDirectionSubmenuInclusionBehavior]));
2223     settings.setDOMPasteAllowed([preferences isDOMPasteAllowed]);
2224     settings.setUsesPageCache([self usesPageCache]);
2225     settings.setPageCacheSupportsPlugins([preferences pageCacheSupportsPlugins]);
2226     settings.setBackForwardCacheExpirationInterval([preferences _backForwardCacheExpirationInterval]);
2227
2228     settings.setDeveloperExtrasEnabled([preferences developerExtrasEnabled]);
2229     settings.setJavaScriptExperimentsEnabled([preferences javaScriptExperimentsEnabled]);
2230     settings.setAuthorAndUserStylesEnabled([preferences authorAndUserStylesEnabled]);
2231     settings.setApplicationChromeMode([preferences applicationChromeModeEnabled]);
2232
2233     settings.setNeedsSiteSpecificQuirks(_private->useSiteSpecificSpoofing);
2234     settings.setWebArchiveDebugModeEnabled([preferences webArchiveDebugModeEnabled]);
2235     settings.setLocalFileContentSniffingEnabled([preferences localFileContentSniffingEnabled]);
2236     settings.setOfflineWebApplicationCacheEnabled([preferences offlineWebApplicationCacheEnabled]);
2237     settings.setJavaScriptCanAccessClipboard([preferences javaScriptCanAccessClipboard]);
2238     settings.setXSSAuditorEnabled([preferences isXSSAuditorEnabled]);
2239     settings.setDNSPrefetchingEnabled([preferences isDNSPrefetchingEnabled]);
2240     
2241     // FIXME: Enabling accelerated compositing when WebGL is enabled causes tests to fail on Leopard which expect HW compositing to be disabled.
2242     // Until we fix that, I will comment out the test (CFM)
2243     settings.setAcceleratedCompositingEnabled([preferences acceleratedCompositingEnabled]);
2244     settings.setAcceleratedDrawingEnabled([preferences acceleratedDrawingEnabled]);
2245     settings.setCanvasUsesAcceleratedDrawing([preferences canvasUsesAcceleratedDrawing]);    
2246     settings.setShowDebugBorders([preferences showDebugBorders]);
2247     settings.setShowRepaintCounter([preferences showRepaintCounter]);
2248     settings.setWebGLEnabled([preferences webGLEnabled]);
2249     settings.setSubpixelCSSOMElementMetricsEnabled([preferences subpixelCSSOMElementMetricsEnabled]);
2250
2251     settings.setForceSoftwareWebGLRendering([preferences forceSoftwareWebGLRendering]);
2252     settings.setAccelerated2dCanvasEnabled([preferences accelerated2dCanvasEnabled]);
2253     settings.setLoadDeferringEnabled(shouldEnableLoadDeferring());
2254     settings.setWindowFocusRestricted(shouldRestrictWindowFocus());
2255     settings.setFrameFlatteningEnabled([preferences isFrameFlatteningEnabled]);
2256     settings.setSpatialNavigationEnabled([preferences isSpatialNavigationEnabled]);
2257     settings.setPaginateDuringLayoutEnabled([preferences paginateDuringLayoutEnabled]);
2258     RuntimeEnabledFeatures::sharedFeatures().setCSSRegionsEnabled([preferences cssRegionsEnabled]);
2259     RuntimeEnabledFeatures::sharedFeatures().setCSSCompositingEnabled([preferences cssCompositingEnabled]);
2260
2261     settings.setAsynchronousSpellCheckingEnabled([preferences asynchronousSpellCheckingEnabled]);
2262     settings.setHyperlinkAuditingEnabled([preferences hyperlinkAuditingEnabled]);
2263     settings.setUsePreHTML5ParserQuirks([self _needsPreHTML5ParserQuirks]);
2264     settings.setInteractiveFormValidationEnabled([self interactiveFormValidationEnabled]);
2265     settings.setValidationMessageTimerMagnification([self validationMessageTimerMagnification]);
2266
2267     settings.setMediaPlaybackRequiresUserGesture([preferences mediaPlaybackRequiresUserGesture]);
2268     settings.setMediaPlaybackAllowsInline([preferences mediaPlaybackAllowsInline]);
2269     settings.setSuppressesIncrementalRendering([preferences suppressesIncrementalRendering]);
2270     settings.setBackspaceKeyNavigationEnabled([preferences backspaceKeyNavigationEnabled]);
2271     settings.setWantsBalancedSetDefersLoadingBehavior([preferences wantsBalancedSetDefersLoadingBehavior]);
2272     settings.setMockScrollbarsEnabled([preferences mockScrollbarsEnabled]);
2273
2274     settings.setShouldRespectImageOrientation([preferences shouldRespectImageOrientation]);
2275
2276     settings.setRequestAnimationFrameEnabled([preferences requestAnimationFrameEnabled]);
2277     settings.setDiagnosticLoggingEnabled([preferences diagnosticLoggingEnabled]);
2278     settings.setLowPowerVideoAudioBufferSizeEnabled([preferences lowPowerVideoAudioBufferSizeEnabled]);
2279
2280     settings.setUseLegacyTextAlignPositionedElementBehavior([preferences useLegacyTextAlignPositionedElementBehavior]);
2281
2282     settings.setShouldConvertPositionStyleOnCopy([preferences shouldConvertPositionStyleOnCopy]);
2283     settings.setEnableInheritURIQueryComponent([preferences isInheritURIQueryComponentEnabled]);
2284
2285     switch ([preferences storageBlockingPolicy]) {
2286     case WebAllowAllStorage:
2287         settings.setStorageBlockingPolicy(SecurityOrigin::AllowAllStorage);
2288         break;
2289     case WebBlockThirdPartyStorage:
2290         settings.setStorageBlockingPolicy(SecurityOrigin::BlockThirdPartyStorage);
2291         break;
2292     case WebBlockAllStorage:
2293         settings.setStorageBlockingPolicy(SecurityOrigin::BlockAllStorage);
2294         break;
2295     }
2296
2297     settings.setPlugInSnapshottingEnabled([preferences plugInSnapshottingEnabled]);
2298
2299     settings.setFixedPositionCreatesStackingContext(true);
2300
2301 #if PLATFORM(IOS)
2302     settings.setStandalone([preferences _standalone]);
2303     settings.setTelephoneNumberParsingEnabled([preferences _telephoneNumberParsingEnabled]);
2304     settings.setAlwaysUseBaselineOfPrimaryFont([preferences _alwaysUseBaselineOfPrimaryFont]);
2305     settings.setAllowMultiElementImplicitSubmission([preferences _allowMultiElementImplicitFormSubmission]);
2306     settings.setLayoutInterval(std::chrono::milliseconds([preferences _layoutInterval]));
2307     settings.setMaxParseDuration([preferences _maxParseDuration]);
2308     settings.setAlwaysUseAcceleratedOverflowScroll([preferences _alwaysUseAcceleratedOverflowScroll]);
2309     settings.setMediaPlaybackAllowsAirPlay([preferences mediaPlaybackAllowsAirPlay]);
2310     settings.setAudioSessionCategoryOverride([preferences audioSessionCategoryOverride]);
2311     settings.setNetworkDataUsageTrackingEnabled([preferences networkDataUsageTrackingEnabled]);
2312     settings.setNetworkInterfaceName([preferences networkInterfaceName]);
2313     settings.setAVKitEnabled([preferences avKitEnabled]);
2314     settings.setShouldTransformsAffectOverflow(shouldTransformsAffectOverflow());
2315     settings.setShouldDispatchJavaScriptWindowOnErrorEvents(shouldDispatchJavaScriptWindowOnErrorEvents());
2316
2317     settings.setPasswordEchoEnabled([preferences _allowPasswordEcho]);
2318     settings.setPasswordEchoDurationInSeconds([preferences _passwordEchoDuration]);
2319
2320     ASSERT_WITH_MESSAGE(settings.pageCacheSupportsPlugins(), "PageCacheSupportsPlugins should be enabled on iOS.");
2321     settings.setDelegatesPageScaling(true);
2322
2323 #if ENABLE(IOS_TEXT_AUTOSIZING)
2324     settings.setMinimumZoomFontSize([preferences _minimumZoomFontSize]);
2325 #endif
2326
2327     settings.setAllowNavigationToInvalidURL(!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_NAVIGATION_URL_VALIDATION));
2328 #endif // PLATFORM(IOS)
2329
2330 #if PLATFORM(MAC)
2331     if ([preferences userStyleSheetEnabled]) {
2332         NSString* location = [[preferences userStyleSheetLocation] _web_originalDataAsString];
2333         if ([location isEqualToString:@"apple-dashboard://stylesheet"])
2334             location = @"file:///System/Library/PrivateFrameworks/DashboardClient.framework/Resources/widget.css";
2335         settings.setUserStyleSheetLocation([NSURL URLWithString:(location ? location : @"")]);
2336     } else
2337         settings.setUserStyleSheetLocation([NSURL URLWithString:@""]);
2338
2339     settings.setNeedsAdobeFrameReloadingQuirk([self _needsAdobeFrameReloadingQuirk]);
2340     settings.setTreatsAnyTextCSSLinkAsStylesheet([self _needsLinkElementTextCSSQuirk]);
2341     settings.setNeedsKeyboardEventDisambiguationQuirks([self _needsKeyboardEventDisambiguationQuirks]);
2342     settings.setEnforceCSSMIMETypeInNoQuirksMode(!WKAppVersionCheckLessThan(@"com.apple.iWeb", -1, 2.1));
2343     settings.setNeedsIsLoadingInAPISenseQuirk([self _needsIsLoadingInAPISenseQuirk]);
2344     settings.setTextAreasAreResizable([preferences textAreasAreResizable]);
2345     settings.setExperimentalNotificationsEnabled([preferences experimentalNotificationsEnabled]);
2346     settings.setShowsURLsInToolTips([preferences showsURLsInToolTips]);
2347     settings.setShowsToolTipOverTruncatedText([preferences showsToolTipOverTruncatedText]);
2348     settings.setQTKitEnabled([preferences isQTKitEnabled]);
2349
2350     // FIXME: Should we enable this following <rdar://problem/15290404>?
2351     settings.setMultithreadedWebGLEnabled([preferences multithreadedWebGLEnabled]);
2352 #endif // PLATFORM(MAC)
2353
2354 #if ENABLE(SQL_DATABASE)
2355     DatabaseManager::manager().setIsAvailable([preferences databasesEnabled]);
2356 #endif
2357
2358 #if ENABLE(MEDIA_SOURCE)
2359     settings.setMediaSourceEnabled([preferences mediaSourceEnabled]);
2360 #endif
2361
2362 #if ENABLE(SERVICE_CONTROLS)
2363     settings.setImageControlsEnabled([preferences imageControlsEnabled]);
2364 #endif
2365
2366 #if ENABLE(VIDEO_TRACK)
2367     settings.setShouldDisplaySubtitles([preferences shouldDisplaySubtitles]);
2368     settings.setShouldDisplayCaptions([preferences shouldDisplayCaptions]);
2369     settings.setShouldDisplayTextDescriptions([preferences shouldDisplayTextDescriptions]);
2370 #endif
2371
2372 #if USE(AVFOUNDATION)
2373     settings.setAVFoundationEnabled([preferences isAVFoundationEnabled]);
2374 #endif
2375
2376 #if ENABLE(WEB_AUDIO)
2377     settings.setWebAudioEnabled([preferences webAudioEnabled]);
2378 #endif
2379
2380 #if ENABLE(FULLSCREEN_API)
2381     settings.setFullScreenEnabled([preferences fullScreenEnabled]);
2382 #endif
2383
2384 #if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
2385     settings.setHiddenPageDOMTimerThrottlingEnabled([preferences hiddenPageDOMTimerThrottlingEnabled]);
2386 #endif
2387
2388     settings.setHiddenPageCSSAnimationSuspensionEnabled([preferences hiddenPageCSSAnimationSuspensionEnabled]);
2389
2390 #if ENABLE(GAMEPAD)
2391     RuntimeEnabledFeatures::sharedFeatures().setGamepadsEnabled([preferences gamepadsEnabled]);
2392 #endif
2393
2394     NSTimeInterval timeout = [preferences incrementalRenderingSuppressionTimeoutInSeconds];
2395     if (timeout > 0)
2396         settings.setIncrementalRenderingSuppressionTimeoutInSeconds(timeout);
2397
2398     // Application Cache Preferences are stored on the global cache storage manager, not in Settings.
2399     [WebApplicationCache setDefaultOriginQuota:[preferences applicationCacheDefaultOriginQuota]];
2400
2401     BOOL zoomsTextOnly = [preferences zoomsTextOnly];
2402     if (_private->zoomsTextOnly != zoomsTextOnly)
2403         [self _setZoomMultiplier:_private->zoomMultiplier isTextOnly:zoomsTextOnly];
2404
2405 #if ENABLE(DISK_IMAGE_CACHE) && PLATFORM(IOS)
2406     DiskImageCache& diskImageCache = WebCore::diskImageCache();
2407     diskImageCache.setEnabled([preferences diskImageCacheEnabled]);
2408     diskImageCache.setMinimumImageSize([preferences diskImageCacheMinimumImageSize]);
2409     diskImageCache.setMaximumCacheSize([preferences diskImageCacheMaximumCacheSize]);
2410 #endif
2411
2412 #if PLATFORM(IOS)
2413     [[self window] setTileBordersVisible:[preferences showDebugBorders]];
2414     [[self window] setTilePaintCountsVisible:[preferences showRepaintCounter]];
2415     [[self window] setAcceleratedDrawingEnabled:[preferences acceleratedDrawingEnabled]];
2416     [WAKView _setInterpolationQuality:[preferences _interpolationQuality]];
2417 #endif
2418 }
2419
2420 static inline IMP getMethod(id o, SEL s)
2421 {
2422     return [o respondsToSelector:s] ? [o methodForSelector:s] : 0;
2423 }
2424
2425 #if PLATFORM(IOS)
2426 - (id)_UIKitDelegateForwarder
2427 {
2428     if (_private->closing)
2429         return nil;
2430         
2431     if (!_private->UIKitDelegateForwarder)
2432         _private->UIKitDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:_private->UIKitDelegate defaultTarget:[WebDefaultUIKitDelegate sharedUIKitDelegate]];
2433     return _private->UIKitDelegateForwarder;
2434 }
2435 #endif
2436
2437 - (void)_cacheResourceLoadDelegateImplementations
2438 {
2439     WebResourceDelegateImplementationCache *cache = &_private->resourceLoadDelegateImplementations;
2440     id delegate = _private->resourceProgressDelegate;
2441
2442     if (!delegate) {
2443         bzero(cache, sizeof(WebResourceDelegateImplementationCache));
2444         return;
2445     }
2446
2447     cache->didCancelAuthenticationChallengeFunc = getMethod(delegate, @selector(webView:resource:didCancelAuthenticationChallenge:fromDataSource:));
2448     cache->didFailLoadingWithErrorFromDataSourceFunc = getMethod(delegate, @selector(webView:resource:didFailLoadingWithError:fromDataSource:));
2449     cache->didFinishLoadingFromDataSourceFunc = getMethod(delegate, @selector(webView:resource:didFinishLoadingFromDataSource:));
2450     cache->didLoadResourceFromMemoryCacheFunc = getMethod(delegate, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:));
2451     cache->didReceiveAuthenticationChallengeFunc = getMethod(delegate, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:));
2452 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
2453     cache->canAuthenticateAgainstProtectionSpaceFunc = getMethod(delegate, @selector(webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:));
2454 #endif
2455
2456 #if PLATFORM(IOS)
2457     cache->connectionPropertiesFunc = getMethod(delegate, @selector(webView:connectionPropertiesForResource:dataSource:));
2458     cache->webThreadDidFinishLoadingFromDataSourceFunc = getMethod(delegate, @selector(webThreadWebView:resource:didFinishLoadingFromDataSource:));
2459     cache->webThreadDidFailLoadingWithErrorFromDataSourceFunc = getMethod(delegate, @selector(webThreadWebView:resource:didFailLoadingWithError:fromDataSource:));
2460     cache->webThreadIdentifierForRequestFunc = getMethod(delegate, @selector(webThreadWebView:identifierForInitialRequest:fromDataSource:));
2461     cache->webThreadDidLoadResourceFromMemoryCacheFunc = getMethod(delegate, @selector(webThreadWebView:didLoadResourceFromMemoryCache:response:length:fromDataSource:));
2462     cache->webThreadWillSendRequestFunc = getMethod(delegate, @selector(webThreadWebView:resource:willSendRequest:redirectResponse:fromDataSource:));
2463     cache->webThreadDidReceiveResponseFunc = getMethod(delegate, @selector(webThreadWebView:resource:didReceiveResponse:fromDataSource:));
2464     cache->webThreadDidReceiveContentLengthFunc = getMethod(delegate, @selector(webThreadWebView:resource:didReceiveContentLength:fromDataSource:));
2465     cache->webThreadWillCacheResponseFunc = getMethod(delegate, @selector(webThreadWebView:resource:willCacheResponse:fromDataSource:));
2466 #endif
2467
2468     cache->didReceiveContentLengthFunc = getMethod(delegate, @selector(webView:resource:didReceiveContentLength:fromDataSource:));
2469     cache->didReceiveResponseFunc = getMethod(delegate, @selector(webView:resource:didReceiveResponse:fromDataSource:));
2470     cache->identifierForRequestFunc = getMethod(delegate, @selector(webView:identifierForInitialRequest:fromDataSource:));
2471     cache->plugInFailedWithErrorFunc = getMethod(delegate, @selector(webView:plugInFailedWithError:dataSource:));
2472     cache->willCacheResponseFunc = getMethod(delegate, @selector(webView:resource:willCacheResponse:fromDataSource:));
2473     cache->willSendRequestFunc = getMethod(delegate, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:));
2474     cache->shouldUseCredentialStorageFunc = getMethod(delegate, @selector(webView:resource:shouldUseCredentialStorageForDataSource:));
2475     cache->shouldPaintBrokenImageForURLFunc = getMethod(delegate, @selector(webView:shouldPaintBrokenImageForURL:));
2476 }
2477
2478 - (void)_cacheFrameLoadDelegateImplementations
2479 {
2480     WebFrameLoadDelegateImplementationCache *cache = &_private->frameLoadDelegateImplementations;
2481     id delegate = _private->frameLoadDelegate;
2482
2483     if (!delegate) {
2484         bzero(cache, sizeof(WebFrameLoadDelegateImplementationCache));
2485         return;
2486     }
2487
2488     cache->didCancelClientRedirectForFrameFunc = getMethod(delegate, @selector(webView:didCancelClientRedirectForFrame:));
2489     cache->didChangeLocationWithinPageForFrameFunc = getMethod(delegate, @selector(webView:didChangeLocationWithinPageForFrame:));
2490     cache->didPushStateWithinPageForFrameFunc = getMethod(delegate, @selector(webView:didPushStateWithinPageForFrame:));
2491     cache->didReplaceStateWithinPageForFrameFunc = getMethod(delegate, @selector(webView:didReplaceStateWithinPageForFrame:));
2492     cache->didPopStateWithinPageForFrameFunc = getMethod(delegate, @selector(webView:didPopStateWithinPageForFrame:));
2493 #if JSC_OBJC_API_ENABLED
2494     cache->didCreateJavaScriptContextForFrameFunc = getMethod(delegate, @selector(webView:didCreateJavaScriptContext:forFrame:));
2495 #endif
2496     cache->didClearWindowObjectForFrameFunc = getMethod(delegate, @selector(webView:didClearWindowObject:forFrame:));
2497     cache->didClearWindowObjectForFrameInScriptWorldFunc = getMethod(delegate, @selector(webView:didClearWindowObjectForFrame:inScriptWorld:));
2498     cache->didClearInspectorWindowObjectForFrameFunc = getMethod(delegate, @selector(webView:didClearInspectorWindowObject:forFrame:));
2499     cache->didCommitLoadForFrameFunc = getMethod(delegate, @selector(webView:didCommitLoadForFrame:));
2500     cache->didFailLoadWithErrorForFrameFunc = getMethod(delegate, @selector(webView:didFailLoadWithError:forFrame:));
2501     cache->didFailProvisionalLoadWithErrorForFrameFunc = getMethod(delegate, @selector(webView:didFailProvisionalLoadWithError:forFrame:));
2502     cache->didFinishDocumentLoadForFrameFunc = getMethod(delegate, @selector(webView:didFinishDocumentLoadForFrame:));
2503     cache->didFinishLoadForFrameFunc = getMethod(delegate, @selector(webView:didFinishLoadForFrame:));
2504     cache->didFirstLayoutInFrameFunc = getMethod(delegate, @selector(webView:didFirstLayoutInFrame:));
2505     cache->didFirstVisuallyNonEmptyLayoutInFrameFunc = getMethod(delegate, @selector(webView:didFirstVisuallyNonEmptyLayoutInFrame:));
2506     cache->didLayoutFunc = getMethod(delegate, @selector(webView:didLayout:));
2507     cache->didHandleOnloadEventsForFrameFunc = getMethod(delegate, @selector(webView:didHandleOnloadEventsForFrame:));
2508 #if ENABLE(ICONDATABASE)
2509     cache->didReceiveIconForFrameFunc = getMethod(delegate, @selector(webView:didReceiveIcon:forFrame:));
2510 #endif
2511     cache->didReceiveServerRedirectForProvisionalLoadForFrameFunc = getMethod(delegate, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:));
2512     cache->didReceiveTitleForFrameFunc = getMethod(delegate, @selector(webView:didReceiveTitle:forFrame:));
2513     cache->didStartProvisionalLoadForFrameFunc = getMethod(delegate, @selector(webView:didStartProvisionalLoadForFrame:));
2514     cache->willCloseFrameFunc = getMethod(delegate, @selector(webView:willCloseFrame:));
2515     cache->willPerformClientRedirectToURLDelayFireDateForFrameFunc = getMethod(delegate, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:));
2516     cache->windowScriptObjectAvailableFunc = getMethod(delegate, @selector(webView:windowScriptObjectAvailable:));
2517     cache->didDisplayInsecureContentFunc = getMethod(delegate, @selector(webViewDidDisplayInsecureContent:));
2518     cache->didRunInsecureContentFunc = getMethod(delegate, @selector(webView:didRunInsecureContent:));
2519     cache->didDetectXSSFunc = getMethod(delegate, @selector(webView:didDetectXSS:));
2520     cache->didRemoveFrameFromHierarchyFunc = getMethod(delegate, @selector(webView:didRemoveFrameFromHierarchy:));
2521 #if PLATFORM(IOS)
2522     cache->webThreadDidLayoutFunc = getMethod(delegate, @selector(webThreadWebView:didLayout:));
2523 #endif
2524
2525     // It would be nice to get rid of this code and transition all clients to using didLayout instead of
2526     // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required
2527     // for backwards compatibility.
2528     Page* page = core(self);
2529     if (page) {
2530         unsigned milestones = DidFirstLayout;
2531 #if PLATFORM(IOS)
2532         milestones |= DidFirstVisuallyNonEmptyLayout;
2533 #else
2534         if (cache->didFirstVisuallyNonEmptyLayoutInFrameFunc)
2535             milestones |= DidFirstVisuallyNonEmptyLayout;
2536 #endif
2537         page->addLayoutMilestones(static_cast<LayoutMilestones>(milestones));
2538     }
2539 }
2540
2541 - (void)_cacheScriptDebugDelegateImplementations
2542 {
2543     WebScriptDebugDelegateImplementationCache *cache = &_private->scriptDebugDelegateImplementations;
2544     id delegate = _private->scriptDebugDelegate;
2545
2546     if (!delegate) {
2547         bzero(cache, sizeof(WebScriptDebugDelegateImplementationCache));
2548         return;
2549     }
2550
2551     cache->didParseSourceFunc = getMethod(delegate, @selector(webView:didParseSource:baseLineNumber:fromURL:sourceId:forWebFrame:));
2552     if (cache->didParseSourceFunc)
2553         cache->didParseSourceExpectsBaseLineNumber = YES;
2554     else {
2555         cache->didParseSourceExpectsBaseLineNumber = NO;
2556         cache->didParseSourceFunc = getMethod(delegate, @selector(webView:didParseSource:fromURL:sourceId:forWebFrame:));
2557     }
2558
2559     cache->failedToParseSourceFunc = getMethod(delegate, @selector(webView:failedToParseSource:baseLineNumber:fromURL:withError:forWebFrame:));
2560
2561     cache->exceptionWasRaisedFunc = getMethod(delegate, @selector(webView:exceptionWasRaised:hasHandler:sourceId:line:forWebFrame:));
2562     if (cache->exceptionWasRaisedFunc)
2563         cache->exceptionWasRaisedExpectsHasHandlerFlag = YES;
2564     else {
2565         cache->exceptionWasRaisedExpectsHasHandlerFlag = NO;
2566         cache->exceptionWasRaisedFunc = getMethod(delegate, @selector(webView:exceptionWasRaised:sourceId:line:forWebFrame:));
2567     }
2568 }
2569
2570 - (void)_cacheHistoryDelegateImplementations
2571 {
2572     WebHistoryDelegateImplementationCache *cache = &_private->historyDelegateImplementations;
2573     id delegate = _private->historyDelegate;
2574
2575     if (!delegate) {
2576         bzero(cache, sizeof(WebHistoryDelegateImplementationCache));
2577         return;
2578     }
2579
2580     cache->navigatedFunc = getMethod(delegate, @selector(webView:didNavigateWithNavigationData:inFrame:));
2581     cache->clientRedirectFunc = getMethod(delegate, @selector(webView:didPerformClientRedirectFromURL:toURL:inFrame:));
2582     cache->serverRedirectFunc = getMethod(delegate, @selector(webView:didPerformServerRedirectFromURL:toURL:inFrame:));
2583     cache->deprecatedSetTitleFunc = getMethod(delegate, @selector(webView:updateHistoryTitle:forURL:));
2584     cache->setTitleFunc = getMethod(delegate, @selector(webView:updateHistoryTitle:forURL:inFrame:));
2585     cache->populateVisitedLinksFunc = getMethod(delegate, @selector(populateVisitedLinksForWebView:));
2586 }
2587
2588 - (id)_policyDelegateForwarder
2589 {
2590 #if PLATFORM(IOS)
2591     if (_private->closing)
2592         return nil;
2593 #endif
2594     if (!_private->policyDelegateForwarder)
2595         _private->policyDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:_private->policyDelegate defaultTarget:[WebDefaultPolicyDelegate sharedPolicyDelegate]];
2596     return _private->policyDelegateForwarder;
2597 }
2598
2599 - (id)_UIDelegateForwarder
2600 {
2601 #if PLATFORM(IOS)
2602     if (_private->closing)
2603         return nil;
2604 #endif
2605     if (!_private->UIDelegateForwarder)
2606         _private->UIDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:_private->UIDelegate defaultTarget:[WebDefaultUIDelegate sharedUIDelegate]];
2607     return _private->UIDelegateForwarder;
2608 }
2609
2610 #if PLATFORM(IOS)
2611 - (id)_UIDelegateForSelector:(SEL)selector
2612 {
2613     id delegate = self->_private->UIDelegate;
2614     if ([delegate respondsToSelector:selector])
2615         return delegate;
2616
2617     delegate = [WebDefaultUIDelegate sharedUIDelegate];
2618     if ([delegate respondsToSelector:selector])
2619         return delegate;
2620
2621     return nil;
2622 }
2623 #endif
2624
2625 - (id)_editingDelegateForwarder
2626 {
2627 #if PLATFORM(IOS)
2628     if (_private->closing)
2629         return nil;
2630 #endif    
2631     // This can be called during window deallocation by QTMovieView in the QuickTime Cocoa Plug-in.
2632     // Not sure if that is a bug or not.
2633     if (!_private)
2634         return nil;
2635
2636     if (!_private->editingDelegateForwarder)
2637         _private->editingDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:_private->editingDelegate defaultTarget:[WebDefaultEditingDelegate sharedEditingDelegate]];
2638     return _private->editingDelegateForwarder;
2639 }
2640
2641 - (void)_closeWindow
2642 {
2643     [[self _UIDelegateForwarder] webViewClose:self];
2644 }
2645
2646 + (void)_unregisterViewClassAndRepresentationClassForMIMEType:(NSString *)MIMEType
2647 {
2648     [[WebFrameView _viewTypesAllowImageTypeOmission:NO] removeObjectForKey:MIMEType];
2649     [[WebDataSource _repTypesAllowImageTypeOmission:NO] removeObjectForKey:MIMEType];
2650     
2651     // FIXME: We also need to maintain MIMEType registrations (which can be dynamically changed)
2652     // in the WebCore MIMEType registry.  For now we're doing this in a safe, limited manner
2653     // to fix <rdar://problem/5372989> - a future revamping of the entire system is neccesary for future robustness
2654     MIMETypeRegistry::getSupportedNonImageMIMETypes().remove(MIMEType);
2655 }
2656
2657 + (void)_registerViewClass:(Class)viewClass representationClass:(Class)representationClass forURLScheme:(NSString *)URLScheme
2658 {
2659     NSString *MIMEType = [self _generatedMIMETypeForURLScheme:URLScheme];
2660     [self registerViewClass:viewClass representationClass:representationClass forMIMEType:MIMEType];
2661
2662     // FIXME: We also need to maintain MIMEType registrations (which can be dynamically changed)
2663     // in the WebCore MIMEType registry.  For now we're doing this in a safe, limited manner
2664     // to fix <rdar://problem/5372989> - a future revamping of the entire system is neccesary for future robustness
2665     if ([viewClass class] == [WebHTMLView class])
2666         MIMETypeRegistry::getSupportedNonImageMIMETypes().add(MIMEType);
2667     
2668     // This is used to make _representationExistsForURLScheme faster.
2669     // Without this set, we'd have to create the MIME type each time.
2670     if (schemesWithRepresentationsSet == nil) {
2671         schemesWithRepresentationsSet = [[NSMutableSet alloc] init];
2672     }
2673     [schemesWithRepresentationsSet addObject:[[[URLScheme lowercaseString] copy] autorelease]];
2674 }
2675
2676 + (NSString *)_generatedMIMETypeForURLScheme:(NSString *)URLScheme
2677 {
2678     return [@"x-apple-web-kit/" stringByAppendingString:[URLScheme lowercaseString]];
2679 }
2680
2681 + (BOOL)_representationExistsForURLScheme:(NSString *)URLScheme
2682 {
2683     return [schemesWithRepresentationsSet containsObject:[URLScheme lowercaseString]];
2684 }
2685
2686 + (BOOL)_canHandleRequest:(NSURLRequest *)request forMainFrame:(BOOL)forMainFrame
2687 {
2688     // FIXME: If <rdar://problem/5217309> gets fixed, this check can be removed.
2689     if (!request)
2690         return NO;
2691
2692     if ([NSURLConnection canHandleRequest:request])
2693         return YES;
2694
2695     NSString *scheme = [[request URL] scheme];
2696
2697     // Representations for URL schemes work at the top level.
2698     if (forMainFrame && [self _representationExistsForURLScheme:scheme])
2699         return YES;
2700
2701     if ([scheme _webkit_isCaseInsensitiveEqualToString:@"applewebdata"])
2702         return YES;
2703
2704     if ([scheme _webkit_isCaseInsensitiveEqualToString:@"blob"])
2705         return YES;
2706
2707     return NO;
2708 }
2709
2710 + (BOOL)_canHandleRequest:(NSURLRequest *)request
2711 {
2712     return [self _canHandleRequest:request forMainFrame:YES];
2713 }
2714
2715 + (NSString *)_decodeData:(NSData *)data
2716 {
2717     HTMLNames::init(); // this method is used for importing bookmarks at startup, so HTMLNames are likely to be uninitialized yet
2718     return TextResourceDecoder::create("text/html")->decodeAndFlush(static_cast<const char*>([data bytes]), [data length]); // bookmark files are HTML
2719 }
2720
2721 - (void)_pushPerformingProgrammaticFocus
2722 {
2723     _private->programmaticFocusCount++;
2724 }
2725
2726 - (void)_popPerformingProgrammaticFocus
2727 {
2728     _private->programmaticFocusCount--;
2729 }
2730
2731 - (BOOL)_isPerformingProgrammaticFocus
2732 {
2733     return _private->programmaticFocusCount != 0;
2734 }
2735
2736 #if !PLATFORM(IOS)
2737 - (void)_didChangeValueForKey: (NSString *)key
2738 {
2739     LOG (Bindings, "calling didChangeValueForKey: %@", key);
2740     [self didChangeValueForKey: key];
2741 }
2742
2743 - (void)_willChangeValueForKey: (NSString *)key
2744 {
2745     LOG (Bindings, "calling willChangeValueForKey: %@", key);
2746     [self willChangeValueForKey: key];
2747 }
2748
2749 + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
2750     static NSSet *manualNotifyKeys = nil;
2751     if (!manualNotifyKeys)
2752         manualNotifyKeys = [[NSSet alloc] initWithObjects:_WebMainFrameURLKey, _WebIsLoadingKey, _WebEstimatedProgressKey,
2753             _WebCanGoBackKey, _WebCanGoForwardKey, _WebMainFrameTitleKey, _WebMainFrameIconKey, _WebMainFrameDocumentKey,
2754             nil];
2755     if ([manualNotifyKeys containsObject:key])
2756         return NO;
2757     return YES;
2758 }
2759
2760 - (NSArray *)_declaredKeys {
2761     static NSArray *declaredKeys = nil;
2762     if (!declaredKeys)
2763         declaredKeys = [[NSArray alloc] initWithObjects:_WebMainFrameURLKey, _WebIsLoadingKey, _WebEstimatedProgressKey,
2764             _WebCanGoBackKey, _WebCanGoForwardKey, _WebMainFrameTitleKey, _WebMainFrameIconKey, _WebMainFrameDocumentKey, nil];
2765     return declaredKeys;
2766 }
2767
2768 - (void)setObservationInfo:(void *)info
2769 {
2770     _private->observationInfo = info;
2771 }
2772
2773 - (void *)observationInfo
2774 {
2775     return _private->observationInfo;
2776 }
2777
2778 - (void)_willChangeBackForwardKeys
2779 {
2780     [self _willChangeValueForKey: _WebCanGoBackKey];
2781     [self _willChangeValueForKey: _WebCanGoForwardKey];
2782 }
2783
2784 - (void)_didChangeBackForwardKeys
2785 {
2786     [self _didChangeValueForKey: _WebCanGoBackKey];
2787     [self _didChangeValueForKey: _WebCanGoForwardKey];
2788 }
2789
2790 - (void)_didStartProvisionalLoadForFrame:(WebFrame *)frame
2791 {
2792     if (needsSelfRetainWhileLoadingQuirk())
2793         [self retain];
2794
2795     [self _willChangeBackForwardKeys];
2796     if (frame == [self mainFrame]){
2797         // Force an observer update by sending a will/did.
2798         [self _willChangeValueForKey: _WebIsLoadingKey];
2799         [self _didChangeValueForKey: _WebIsLoadingKey];
2800
2801         [self _willChangeValueForKey: _WebMainFrameURLKey];
2802     }
2803
2804     [NSApp setWindowsNeedUpdate:YES];
2805
2806 #if ENABLE(FULLSCREEN_API)
2807     Document* document = core([frame DOMDocument]);
2808     if (Element* element = document ? document->webkitCurrentFullScreenElement() : 0) {
2809         SEL selector = @selector(webView:closeFullScreenWithListener:);
2810         if (_private->UIDelegate && [_private->UIDelegate respondsToSelector:selector]) {
2811             WebKitFullScreenListener *listener = [[WebKitFullScreenListener alloc] initWithElement:element];
2812             CallUIDelegate(self, selector, listener);
2813             [listener release];
2814         } else if (_private->newFullscreenController && [_private->newFullscreenController isFullScreen]) {
2815             [_private->newFullscreenController close];
2816         }
2817     }
2818 #endif
2819 }
2820
2821 - (void)_checkDidPerformFirstNavigation
2822 {
2823     if (_private->_didPerformFirstNavigation)
2824         return;
2825
2826     Page* page = _private->page;
2827     if (!page)
2828         return;
2829
2830     auto& backForwardController = page->backForward();
2831
2832     if (!backForwardController.backItem())
2833         return;
2834
2835     _private->_didPerformFirstNavigation = YES;
2836
2837     if (_private->preferences.automaticallyDetectsCacheModel && _private->preferences.cacheModel < WebCacheModelDocumentBrowser)
2838         _private->preferences.cacheModel = WebCacheModelDocumentBrowser;
2839 }
2840
2841 - (void)_didCommitLoadForFrame:(WebFrame *)frame
2842 {
2843     if (frame == [self mainFrame])
2844         [self _didChangeValueForKey: _WebMainFrameURLKey];
2845
2846     [self _checkDidPerformFirstNavigation];
2847
2848     [NSApp setWindowsNeedUpdate:YES];
2849 }
2850
2851 - (void)_didFinishLoadForFrame:(WebFrame *)frame
2852 {
2853     if (needsSelfRetainWhileLoadingQuirk())
2854         [self performSelector:@selector(release) withObject:nil afterDelay:0];
2855         
2856     [self _didChangeBackForwardKeys];
2857     if (frame == [self mainFrame]){
2858         // Force an observer update by sending a will/did.
2859         [self _willChangeValueForKey: _WebIsLoadingKey];
2860         [self _didChangeValueForKey: _WebIsLoadingKey];
2861     }
2862     [NSApp setWindowsNeedUpdate:YES];
2863 }
2864
2865 - (void)_didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
2866 {
2867     if (needsSelfRetainWhileLoadingQuirk())
2868         [self performSelector:@selector(release) withObject:nil afterDelay:0];
2869
2870     [self _didChangeBackForwardKeys];
2871     if (frame == [self mainFrame]){
2872         // Force an observer update by sending a will/did.
2873         [self _willChangeValueForKey: _WebIsLoadingKey];
2874         [self _didChangeValueForKey: _WebIsLoadingKey];
2875     }
2876     [NSApp setWindowsNeedUpdate:YES];
2877 }
2878
2879 - (void)_didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
2880 {
2881     if (needsSelfRetainWhileLoadingQuirk())
2882         [self performSelector:@selector(release) withObject:nil afterDelay:0];
2883
2884     [self _didChangeBackForwardKeys];
2885     if (frame == [self mainFrame]){
2886         // Force an observer update by sending a will/did.
2887         [self _willChangeValueForKey: _WebIsLoadingKey];
2888         [self _didChangeValueForKey: _WebIsLoadingKey];
2889         
2890         [self _didChangeValueForKey: _WebMainFrameURLKey];
2891     }
2892     [NSApp setWindowsNeedUpdate:YES];
2893 }
2894
2895 - (NSCachedURLResponse *)_cachedResponseForURL:(NSURL *)URL
2896 {
2897     RetainPtr<NSMutableURLRequest *> request = adoptNS([[NSMutableURLRequest alloc] initWithURL:URL]);
2898     [request _web_setHTTPUserAgent:[self userAgentForURL:URL]];
2899     NSCachedURLResponse *cachedResponse;
2900
2901     if (!_private->page)
2902         return nil;
2903
2904     if (CFURLStorageSessionRef storageSession = _private->page->mainFrame().loader().networkingContext()->storageSession().platformSession())
2905         cachedResponse = WKCachedResponseForRequest(storageSession, request.get());
2906     else
2907         cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request.get()];
2908
2909     return cachedResponse;
2910 }
2911
2912 - (void)_writeImageForElement:(NSDictionary *)element withPasteboardTypes:(NSArray *)types toPasteboard:(NSPasteboard *)pasteboard
2913 {
2914     NSURL *linkURL = [element objectForKey:WebElementLinkURLKey];
2915     DOMElement *domElement = [element objectForKey:WebElementDOMNodeKey];
2916     [pasteboard _web_writeImage:(NSImage *)(domElement ? nil : [element objectForKey:WebElementImageKey])
2917                         element:domElement
2918                             URL:linkURL ? linkURL : (NSURL *)[element objectForKey:WebElementImageURLKey]
2919                           title:[element objectForKey:WebElementImageAltStringKey] 
2920                         archive:[[element objectForKey:WebElementDOMNodeKey] webArchive]
2921                           types:types
2922                          source:nil];
2923 }
2924
2925 - (void)_writeLinkElement:(NSDictionary *)element withPasteboardTypes:(NSArray *)types toPasteboard:(NSPasteboard *)pasteboard
2926 {
2927     [pasteboard _web_writeURL:[element objectForKey:WebElementLinkURLKey]
2928                      andTitle:[element objectForKey:WebElementLinkLabelKey]
2929                         types:types];
2930 }
2931
2932 #if ENABLE(DRAG_SUPPORT)
2933 - (void)_setInitiatedDrag:(BOOL)initiatedDrag
2934 {
2935     if (!_private->page)
2936         return;
2937     _private->page->dragController().setDidInitiateDrag(initiatedDrag);
2938 }
2939 #endif
2940
2941 #else
2942
2943 - (void)_didCommitLoadForFrame:(WebFrame *)frame
2944 {
2945     if (frame == [self mainFrame])
2946         _private->didDrawTiles = 0;
2947 }
2948
2949 #endif // PLATFORM(IOS)
2950
2951 #if ENABLE(DASHBOARD_SUPPORT)
2952
2953 #define DASHBOARD_CONTROL_LABEL @"control"
2954
2955 - (void)_addControlRect:(NSRect)bounds clip:(NSRect)clip fromView:(NSView *)view toDashboardRegions:(NSMutableDictionary *)regions
2956 {
2957     NSRect adjustedBounds = bounds;
2958     adjustedBounds.origin = [self convertPoint:bounds.origin fromView:view];
2959     adjustedBounds.origin.y = [self bounds].size.height - adjustedBounds.origin.y;
2960     adjustedBounds.size = bounds.size;
2961
2962     NSRect adjustedClip;
2963     adjustedClip.origin = [self convertPoint:clip.origin fromView:view];
2964     adjustedClip.origin.y = [self bounds].size.height - adjustedClip.origin.y;
2965     adjustedClip.size = clip.size;
2966
2967     WebDashboardRegion *region = [[WebDashboardRegion alloc] initWithRect:adjustedBounds 
2968         clip:adjustedClip type:WebDashboardRegionTypeScrollerRectangle];
2969     NSMutableArray *scrollerRegions = [regions objectForKey:DASHBOARD_CONTROL_LABEL];
2970     if (!scrollerRegions) {
2971         scrollerRegions = [[NSMutableArray alloc] init];
2972         [regions setObject:scrollerRegions forKey:DASHBOARD_CONTROL_LABEL];
2973         [scrollerRegions release];
2974     }
2975     [scrollerRegions addObject:region];
2976     [region release];
2977 }
2978
2979 - (void)_addScrollerDashboardRegionsForFrameView:(FrameView*)frameView dashboardRegions:(NSMutableDictionary *)regions
2980 {    
2981     NSView *documentView = [[kit(&frameView->frame()) frameView] documentView];
2982
2983     for (const auto& widget: frameView->children()) {
2984         if (widget->isFrameView()) {
2985             [self _addScrollerDashboardRegionsForFrameView:toFrameView(widget.get()) dashboardRegions:regions];
2986             continue;
2987         }
2988
2989         if (!widget->isScrollbar())
2990             continue;
2991
2992         // FIXME: This should really pass an appropriate clip, but our first try got it wrong, and
2993         // it's not common to need this to be correct in Dashboard widgets.
2994         NSRect bounds = widget->frameRect();
2995         [self _addControlRect:bounds clip:bounds fromView:documentView toDashboardRegions:regions];
2996     }
2997 }
2998
2999 - (void)_addScrollerDashboardRegions:(NSMutableDictionary *)regions from:(NSArray *)views
3000 {
3001     // Add scroller regions for NSScroller and WebCore scrollbars
3002     NSUInteger count = [views count];
3003     for (NSUInteger i = 0; i < count; i++) {
3004         NSView *view = [views objectAtIndex:i];
3005         
3006         if ([view isKindOfClass:[WebHTMLView class]]) {
3007             if (Frame* coreFrame = core([(WebHTMLView*)view _frame])) {
3008                 if (FrameView* coreView = coreFrame->view())
3009                     [self _addScrollerDashboardRegionsForFrameView:coreView dashboardRegions:regions];
3010             }
3011         } else if ([view isKindOfClass:[NSScroller class]]) {
3012             // AppKit places absent scrollers at -100,-100
3013             if ([view frame].origin.y < 0)
3014                 continue;
3015             [self _addControlRect:[view bounds] clip:[view visibleRect] fromView:view toDashboardRegions:regions];
3016         }
3017         [self _addScrollerDashboardRegions:regions from:[view subviews]];
3018     }
3019 }
3020
3021 - (void)_addScrollerDashboardRegions:(NSMutableDictionary *)regions
3022 {
3023     [self _addScrollerDashboardRegions:regions from:[self subviews]];
3024 }
3025
3026 - (NSDictionary *)_dashboardRegions
3027 {
3028     // Only return regions from main frame.
3029     Frame* mainFrame = [self _mainCoreFrame];
3030     if (!mainFrame)
3031         return nil;
3032
3033     const Vector<AnnotatedRegionValue>& regions = mainFrame->document()->annotatedRegions();
3034     size_t size = regions.size();
3035
3036     NSMutableDictionary *webRegions = [NSMutableDictionary dictionaryWithCapacity:size];
3037     for (size_t i = 0; i < size; i++) {
3038         const AnnotatedRegionValue& region = regions[i];
3039
3040         if (region.type == StyleDashboardRegion::None)
3041             continue;
3042
3043         NSString *label = region.label;
3044         WebDashboardRegionType type = WebDashboardRegionTypeNone;
3045         if (region.type == StyleDashboardRegion::Circle)
3046             type = WebDashboardRegionTypeCircle;
3047         else if (region.type == StyleDashboardRegion::Rectangle)
3048             type = WebDashboardRegionTypeRectangle;
3049         NSMutableArray *regionValues = [webRegions objectForKey:label];
3050         if (!regionValues) {
3051             regionValues = [[NSMutableArray alloc] initWithCapacity:1];
3052             [webRegions setObject:regionValues forKey:label];
3053             [regionValues release];
3054         }
3055
3056         WebDashboardRegion *webRegion = [[WebDashboardRegion alloc] initWithRect:pixelSnappedIntRect(region.bounds) clip:pixelSnappedIntRect(region.clip) type:type];
3057         [regionValues addObject:webRegion];
3058         [webRegion release];
3059     }
3060
3061     [self _addScrollerDashboardRegions:webRegions];
3062
3063     return webRegions;
3064 }
3065
3066 - (void)_setDashboardBehavior:(WebDashboardBehavior)behavior to:(BOOL)flag
3067 {
3068     // FIXME: Remove this blanket assignment once Dashboard and Dashcode implement 
3069     // specific support for the backward compatibility mode flag.
3070     if (behavior == WebDashboardBehaviorAllowWheelScrolling && flag == NO && _private->page)
3071         _private->page->settings().setUsesDashboardBackwardCompatibilityMode(true);
3072     
3073     switch (behavior) {
3074         case WebDashboardBehaviorAlwaysSendMouseEventsToAllWindows: {
3075             _private->dashboardBehaviorAlwaysSendMouseEventsToAllWindows = flag;
3076             break;
3077         }
3078         case WebDashboardBehaviorAlwaysSendActiveNullEventsToPlugIns: {
3079             _private->dashboardBehaviorAlwaysSendActiveNullEventsToPlugIns = flag;
3080             break;
3081         }
3082         case WebDashboardBehaviorAlwaysAcceptsFirstMouse: {
3083             _private->dashboardBehaviorAlwaysAcceptsFirstMouse = flag;
3084             break;
3085         }
3086         case WebDashboardBehaviorAllowWheelScrolling: {
3087             _private->dashboardBehaviorAllowWheelScrolling = flag;
3088             break;
3089         }
3090         case WebDashboardBehaviorUseBackwardCompatibilityMode: {
3091             if (_private->page)
3092                 _private->page->settings().setUsesDashboardBackwardCompatibilityMode(flag);
3093 #if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
3094             RuntimeEnabledFeatures::sharedFeatures().setLegacyCSSVendorPrefixesEnabled(flag);
3095 #endif
3096             break;
3097         }
3098     }
3099
3100     // Pre-HTML5 parser quirks should be enabled if Dashboard is in backward
3101     // compatibility mode. See <rdar://problem/8175982>.
3102     if (_private->page)
3103         _private->page->settings().setUsePreHTML5ParserQuirks([self _needsPreHTML5ParserQuirks]);
3104 }
3105
3106 - (BOOL)_dashboardBehavior:(WebDashboardBehavior)behavior
3107 {
3108     switch (behavior) {
3109         case WebDashboardBehaviorAlwaysSendMouseEventsToAllWindows: {
3110             return _private->dashboardBehaviorAlwaysSendMouseEventsToAllWindows;
3111         }
3112         case WebDashboardBehaviorAlwaysSendActiveNullEventsToPlugIns: {
3113             return _private->dashboardBehaviorAlwaysSendActiveNullEventsToPlugIns;
3114         }
3115         case WebDashboardBehaviorAlwaysAcceptsFirstMouse: {
3116             return _private->dashboardBehaviorAlwaysAcceptsFirstMouse;
3117         }
3118         case WebDashboardBehaviorAllowWheelScrolling: {
3119             return _private->dashboardBehaviorAllowWheelScrolling;
3120         }
3121         case WebDashboardBehaviorUseBackwardCompatibilityMode: {
3122             return _private->page && _private->page->settings().usesDashboardBackwardCompatibilityMode();
3123         }
3124     }
3125     return NO;
3126 }
3127
3128 #endif /* ENABLE(DASHBOARD_SUPPORT) */
3129
3130 + (void)_setShouldUseFontSmoothing:(BOOL)f
3131 {
3132     Font::setShouldUseSmoothing(f);
3133 }
3134
3135 + (BOOL)_shouldUseFontSmoothing
3136 {
3137     return Font::shouldUseSmoothing();
3138 }
3139
3140 #if !PLATFORM(IOS)
3141 + (void)_setUsesTestModeFocusRingColor:(BOOL)f
3142 {
3143     setUsesTestModeFocusRingColor(f);
3144 }
3145
3146 + (BOOL)_usesTestModeFocusRingColor
3147 {
3148     return usesTestModeFocusRingColor();
3149 }
3150 #endif
3151
3152 #if PLATFORM(IOS)
3153 - (void)_setUIKitDelegate:(id)delegate
3154 {
3155     _private->UIKitDelegate = delegate;
3156     [_private->UIKitDelegateForwarder clearTarget];
3157     [_private->UIKitDelegateForwarder release];
3158     _private->UIKitDelegateForwarder = nil;
3159 }
3160
3161 - (id)_UIKitDelegate
3162 {
3163     return _private->UIKitDelegate;
3164 }
3165
3166 - (void)setWebMailDelegate:(id)delegate
3167 {
3168     _private->WebMailDelegate = delegate;
3169 }
3170
3171 - (id)_webMailDelegate
3172 {
3173     return _private->WebMailDelegate;
3174 }
3175
3176 - (id <WebCaretChangeListener>)caretChangeListener
3177 {
3178     return _private->_caretChangeListener;
3179 }
3180
3181 - (void)setCaretChangeListener:(id <WebCaretChangeListener>)listener
3182 {
3183     _private->_caretChangeListener = listener;
3184 }
3185
3186 - (NSSet *)caretChangeListeners
3187 {
3188     return _private->_caretChangeListeners;
3189 }
3190
3191 - (void)addCaretChangeListener:(id <WebCaretChangeListener>)listener
3192 {
3193     if (_private->_caretChangeListeners == nil) {
3194         _private->_caretChangeListeners = [[NSMutableSet alloc] init];
3195     }
3196     
3197     [_private->_caretChangeListeners addObject:listener];
3198 }
3199
3200 - (void)removeCaretChangeListener:(id <WebCaretChangeListener>)listener
3201 {
3202     [_private->_caretChangeListeners removeObject:listener];
3203 }
3204
3205 - (void)removeAllCaretChangeListeners
3206 {
3207     [_private->_caretChangeListeners removeAllObjects];
3208 }
3209
3210 - (void)caretChanged
3211 {
3212     [_private->_caretChangeListener caretChanged];
3213     NSSet *copy = [_private->_caretChangeListeners copy];
3214     for (id <WebCaretChangeListener> listener in copy) {
3215         [listener caretChanged];
3216     }
3217     [copy release];
3218 }
3219
3220 - (void)_clearDelegates
3221 {
3222     ASSERT(WebThreadIsLocked() || !WebThreadIsEnabled());
3223     
3224     [self _setFormDelegate:nil];
3225     [self _setUIKitDelegate:nil];
3226     [self setCaretChangeListener:nil];
3227     [self removeAllCaretChangeListeners];
3228     [self setWebMailDelegate:nil];
3229     
3230     [self setDownloadDelegate:nil];
3231     [self setEditingDelegate:nil]; 
3232     [self setFrameLoadDelegate:nil];
3233     [self setPolicyDelegate:nil];
3234     [self setResourceLoadDelegate:nil];
3235     [self setScriptDebugDelegate:nil];
3236     [self setUIDelegate:nil];     
3237 }
3238
3239 - (NSURL *)_displayURL
3240 {
3241     WebThreadLock();
3242     WebFrame *frame = [self mainFrame];
3243     // FIXME: <rdar://problem/6362369> We used to get provisionalDataSource here if in provisional state; how do we tell that now? Is this right?
3244     WebDataSource *dataSource = [frame provisionalDataSource];
3245     if (!dataSource)
3246         dataSource = [frame dataSource];
3247     NSURL *unreachableURL = [dataSource unreachableURL];
3248     NSURL *URL = unreachableURL != nil ? unreachableURL : [[dataSource request] URL];
3249     [[URL retain] autorelease];
3250     return URL;
3251 }
3252 #endif // PLATFORM(IOS)
3253
3254 #if !PLATFORM(IOS)
3255 - (void)setAlwaysShowVerticalScroller:(BOOL)flag
3256 {
3257     WebDynamicScrollBarsView *scrollview = [[[self mainFrame] frameView] _scrollView];
3258     if (flag) {
3259         [scrollview setVerticalScrollingMode:ScrollbarAlwaysOn andLock:YES];
3260     } else {
3261         [scrollview setVerticalScrollingModeLocked:NO];
3262         [scrollview setVerticalScrollingMode:ScrollbarAuto andLock:NO];
3263     }
3264 }
3265
3266 - (BOOL)alwaysShowVerticalScroller
3267 {
3268     WebDynamicScrollBarsView *scrollview = [[[self mainFrame] frameView] _scrollView];
3269     return [scrollview verticalScrollingModeLocked] && [scrollview verticalScrollingMode] == ScrollbarAlwaysOn;
3270 }
3271
3272 - (void)setAlwaysShowHorizontalScroller:(BOOL)flag
3273 {
3274     WebDynamicScrollBarsView *scrollview = [[[self mainFrame] frameView] _scrollView];
3275     if (flag) {
3276         [scrollview setHorizontalScrollingMode:ScrollbarAlwaysOn andLock:YES];
3277     } else {
3278         [scrollview setHorizontalScrollingModeLocked:NO];
3279         [scrollview setHorizontalScrollingMode:ScrollbarAuto andLock:NO];
3280     }
3281 }
3282
3283 - (void)setProhibitsMainFrameScrolling:(BOOL)prohibits
3284 {
3285     if (Frame* mainFrame = [self _mainCoreFrame])
3286         mainFrame->view()->setProhibitsScrolling(prohibits);
3287 }
3288
3289 - (BOOL)alwaysShowHorizontalScroller
3290 {
3291     WebDynamicScrollBarsView *scrollview = [[[self mainFrame] frameView] _scrollView];
3292     return [scrollview horizontalScrollingModeLocked] && [scrollview horizontalScrollingMode] == ScrollbarAlwaysOn;
3293 }
3294 #endif // !PLATFORM(IOS)
3295
3296 - (void)_setUseFastImageScalingMode:(BOOL)flag
3297 {
3298     if (_private->page && _private->page->inLowQualityImageInterpolationMode() != flag) {
3299         _private->page->setInLowQualityImageInterpolationMode(flag);
3300         [self setNeedsDisplay:YES];
3301     }
3302 }
3303
3304 - (BOOL)_inFastImageScalingMode
3305 {
3306     if (_private->page)
3307         return _private->page->inLowQualityImageInterpolationMode();
3308     return NO;
3309 }
3310
3311 - (BOOL)_cookieEnabled
3312 {
3313     if (_private->page)
3314         return _private->page->settings().cookieEnabled();
3315     return YES;
3316 }
3317
3318 - (void)_setCookieEnabled:(BOOL)enable
3319 {
3320     if (_private->page)
3321         _private->page->settings().setCookieEnabled(enable);
3322 }
3323
3324 #if !PLATFORM(IOS)
3325 - (void)_setAdditionalWebPlugInPaths:(NSArray *)newPaths
3326 {
3327     if (!_private->pluginDatabase)
3328         _private->pluginDatabase = [[WebPluginDatabase alloc] init];
3329         
3330     [_private->pluginDatabase setPlugInPaths:newPaths];
3331     [_private->pluginDatabase refresh];
3332 }
3333 #endif
3334
3335 #if PLATFORM(IOS)
3336 - (BOOL)_locked_plugInsAreRunningInFrame:(WebFrame *)frame
3337 {
3338     // Ask plug-ins in this frame
3339     id <WebDocumentView> documentView = [[frame frameView] documentView];
3340     if (documentView && [documentView isKindOfClass:[WebHTMLView class]]) {
3341         if ([[(WebHTMLView *)documentView _pluginController] plugInsAreRunning])
3342             return YES;
3343     }
3344
3345     // Ask plug-ins in child frames
3346     NSArray *childFrames = [frame childFrames];
3347     unsigned childCount = [childFrames count];
3348     unsigned childIndex;
3349     for (childIndex = 0; childIndex < childCount; childIndex++) {
3350         if ([self _locked_plugInsAreRunningInFrame:[childFrames objectAtIndex:childIndex]])
3351             return YES;
3352     }
3353     
3354     return NO;
3355 }
3356
3357 - (BOOL)_pluginsAreRunning
3358 {
3359     WebThreadLock();
3360     return [self _locked_plugInsAreRunningInFrame:[self mainFrame]];
3361 }
3362
3363 - (void)_locked_recursivelyPerformPlugInSelector:(SEL)selector inFrame:(WebFrame *)frame
3364 {
3365     // Send the message to plug-ins in this frame
3366     id <WebDocumentView> documentView = [[frame frameView] documentView];
3367     if (documentView && [documentView isKindOfClass:[WebHTMLView class]])
3368         [[(WebHTMLView *)documentView _pluginController] performSelector:selector];
3369
3370     // Send the message to plug-ins in child frames
3371     NSArray *childFrames = [frame childFrames];
3372     unsigned childCount = [childFrames count];
3373     unsigned childIndex;
3374     for (childIndex = 0; childIndex < childCount; childIndex++) {
3375         [self _locked_recursivelyPerformPlugInSelector:selector inFrame:[childFrames objectAtIndex:childIndex]];
3376     }
3377 }
3378
3379 - (void)_destroyAllPlugIns
3380 {
3381     WebThreadLock();
3382     [self _locked_recursivelyPerformPlugInSelector:@selector(destroyAllPlugins) inFrame:[self mainFrame]];
3383 }
3384
3385 - (void)_clearBackForwardCache
3386 {
3387     WebThreadRun(^{
3388         WebKit::MemoryMeasure measurer("[WebView _clearBackForwardCache]");
3389         BackForwardList* bfList = core([self backForwardList]);
3390         if (!bfList)
3391             return;
3392
3393         BOOL didClearBFCache = bfList->clearAllPageCaches();
3394         if (WebKit::MemoryMeasure::isLoggingEnabled())
3395             NSLog(@"[WebView _clearBackForwardCache] %@ empty cache\n", (didClearBFCache ? @"DID" : @"did NOT"));
3396     });
3397 }
3398
3399 - (void)_startAllPlugIns
3400 {
3401     WebThreadLock();
3402     [self _locked_recursivelyPerformPlugInSelector:@selector(startAllPlugins) inFrame:[self mainFrame]];
3403 }
3404
3405 - (void)_stopAllPlugIns
3406 {
3407     WebThreadLock();
3408     [self _locked_recursivelyPerformPlugInSelector:@selector(stopAllPlugins) inFrame:[self mainFrame]];
3409 }
3410
3411 - (void)_stopAllPlugInsForPageCache
3412 {
3413     WebThreadLock();
3414     [self _locked_recursivelyPerformPlugInSelector:@selector(stopPluginsForPageCache) inFrame:[self mainFrame]];
3415 }
3416
3417 - (void)_restorePlugInsFromCache
3418 {
3419     WebThreadLock();
3420     [self _locked_recursivelyPerformPlugInSelector:@selector(restorePluginsFromCache) inFrame:[self mainFrame]];
3421 }
3422
3423 - (BOOL)_setMediaLayer:(CALayer*)layer forPluginView:(NSView*)pluginView
3424 {
3425     WebThreadLock();
3426
3427     Frame* mainCoreFrame = [self _mainCoreFrame];
3428     for (Frame* frame = mainCoreFrame; frame; frame = frame->tree().traverseNext()) {
3429         FrameView* coreView = frame ? frame->view() : 0;
3430         if (!coreView)
3431             continue;
3432
3433         // Get the GraphicsLayer for this widget.
3434         GraphicsLayer* layerForWidget = coreView->graphicsLayerForPlatformWidget(pluginView);
3435         if (!layerForWidget)
3436             continue;
3437         
3438         if (layerForWidget->contentsLayerForMedia() != layer) {
3439             layerForWidget->setContentsToMedia(layer);
3440             // We need to make sure the layer hierachy change is applied immediately.
3441             if (mainCoreFrame->view())
3442                 mainCoreFrame->view()->flushCompositingStateIncludingSubframes();
3443             return YES;
3444         }
3445     }
3446
3447     return NO;
3448 }
3449
3450 - (void)_setNeedsUnrestrictedGetMatchedCSSRules:(BOOL)flag
3451 {
3452     if (_private->page)
3453         _private->page->settings().setCrossOriginCheckInGetMatchedCSSRulesDisabled(flag);
3454 }
3455 #endif // PLATFORM(IOS)
3456
3457 - (void)_attachScriptDebuggerToAllFrames
3458 {
3459     for (Frame* frame = [self _mainCoreFrame]; frame; frame = frame->tree().traverseNext())
3460         [kit(frame) _attachScriptDebugger];
3461 }
3462
3463 - (void)_detachScriptDebuggerFromAllFrames
3464 {
3465     for (Frame* frame = [self _mainCoreFrame]; frame; frame = frame->tree().traverseNext())
3466         [kit(frame) _detachScriptDebugger];
3467 }
3468
3469 #if !PLATFORM(IOS)
3470 - (void)setBackgroundColor:(NSColor *)backgroundColor
3471 {
3472     if ([_private->backgroundColor isEqual:backgroundColor])
3473         return;
3474
3475     id old = _private->backgroundColor;
3476     _private->backgroundColor = [backgroundColor retain];
3477     [old release];
3478
3479     [[self mainFrame] _updateBackgroundAndUpdatesWhileOffscreen];
3480 }
3481
3482 - (NSColor *)backgroundColor
3483 {
3484     return _private->backgroundColor;
3485 }
3486 #else
3487 - (void)setBackgroundColor:(CGColorRef)backgroundColor
3488 {
3489    if (!backgroundColor || CFEqual(_private->backgroundColor, backgroundColor))
3490         return;
3491
3492     CFTypeRef old = _private->backgroundColor;
3493     CFRetain(backgroundColor);
3494     _private->backgroundColor = backgroundColor;
3495     CFRelease(old);
3496
3497     [[self mainFrame] _updateBackgroundAndUpdatesWhileOffscreen];
3498 }
3499
3500 - (CGColorRef)backgroundColor
3501 {
3502     return _private->backgroundColor;
3503 }
3504 #endif
3505
3506 - (BOOL)defersCallbacks
3507 {
3508     if (!_private->page)
3509         return NO;
3510     return _private->page->defersLoading();
3511 }
3512
3513 - (void)setDefersCallbacks:(BOOL)defer
3514 {
3515     if (!_private->page)
3516         return;
3517     return _private->page->setDefersLoading(defer);
3518 }
3519
3520 #if TARGET_OS_IPHONE && USE(QUICK_LOOK)
3521 - (NSDictionary *)quickLookContentForURL:(NSURL *)url
3522 {
3523     NSString *uti = qlPreviewConverterUTIForURL(url);
3524     if (!uti)
3525         return nil;
3526
3527     NSString *fileName = qlPreviewConverterFileNameForURL(url);
3528     if (!fileName)
3529         return nil;
3530
3531     return [NSDictionary dictionaryWithObjectsAndKeys: fileName, WebQuickLookFileNameKey, uti, WebQuickLookUTIKey, nil];
3532 }
3533 #endif
3534
3535 #if PLATFORM(IOS)
3536 - (BOOL)_isStopping
3537 {
3538     return _private->isStopping;
3539 }
3540
3541 - (BOOL)_isClosing
3542 {
3543     return _private->closing;
3544 }
3545
3546 + (NSArray *)_productivityDocumentMIMETypes
3547 {
3548 #if USE(QUICK_LOOK)
3549     return [QLPreviewGetSupportedMIMETypesSet() allObjects];
3550 #else
3551     return nil;
3552 #endif
3553 }
3554
3555 - (void)_setAllowsMessaging:(BOOL)aFlag
3556 {
3557     _private->allowsMessaging = aFlag;
3558 }
3559
3560 - (BOOL)_allowsMessaging
3561 {
3562     return _private->allowsMessaging;
3563 }
3564
3565 - (void)_setFixedLayoutSize:(CGSize)size
3566 {
3567     ASSERT(WebThreadIsLocked());
3568     _private->fixedLayoutSize = size;
3569     if (Frame* mainFrame = core([self mainFrame])) {
3570         IntSize newSize(size);
3571         mainFrame->view()->setFixedLayoutSize(newSize);
3572         mainFrame->view()->setUseFixedLayout(!newSize.isEmpty());
3573         [self setNeedsDisplay:YES];
3574     }
3575 }
3576
3577 - (CGSize)_fixedLayoutSize
3578 {
3579     return _private->fixedLayoutSize;
3580 }
3581
3582 - (void)_synchronizeCustomFixedPositionLayoutRect
3583 {
3584     ASSERT(WebThreadIsLocked());
3585
3586     IntRect newRect;
3587     {
3588         MutexLocker locker(_private->pendingFixedPositionLayoutRectMutex);
3589         if (CGRectIsNull(_private->pendingFixedPositionLayoutRect))
3590             return;
3591         newRect = enclosingIntRect(_private->pendingFixedPositionLayoutRect);
3592         _private->pendingFixedPositionLayoutRect = CGRectNull;
3593     }
3594
3595     if (Frame* mainFrame = core([self mainFrame]))
3596         mainFrame->view()->setCustomFixedPositionLayoutRect(newRect);
3597 }
3598
3599 - (void)_setCustomFixedPositionLayoutRectInWebThread:(CGRect)rect synchronize:(BOOL)synchronize
3600 {
3601     {
3602         MutexLocker locker(_private->pendingFixedPositionLayoutRectMutex);
3603         _private->pendingFixedPositionLayoutRect = rect;
3604     }
3605     if (!synchronize)
3606         return;
3607     WebThreadRun(^{
3608         [self _synchronizeCustomFixedPositionLayoutRect];
3609     });
3610 }
3611
3612 - (void)_setCustomFixedPositionLayoutRect:(CGRect)rect
3613 {
3614     ASSERT(WebThreadIsLocked());
3615     {
3616         MutexLocker locker(_private->pendingFixedPositionLayoutRectMutex);
3617         _private->pendingFixedPositionLayoutRect = rect;
3618     }
3619     [self _synchronizeCustomFixedPositionLayoutRect];
3620 }
3621
3622 - (BOOL)_fetchCustomFixedPositionLayoutRect:(NSRect*)rect
3623 {
3624     MutexLocker locker(_private->pendingFixedPositionLayoutRectMutex);
3625     if (CGRectIsNull(_private->pendingFixedPositionLayoutRect))
3626         return false;
3627
3628     *rect = _private->pendingFixedPositionLayoutRect;
3629     _private->pendingFixedPositionLayoutRect = CGRectNull;
3630     return true;
3631 }
3632
3633 - (void)_viewGeometryDidChange
3634 {
3635     ASSERT(WebThreadIsLocked());
3636     
3637     if (Frame* coreFrame = [self _mainCoreFrame])
3638         coreFrame->viewportOffsetChanged(Frame::IncrementalScrollOffset);
3639 }
3640
3641 - (void)_overflowScrollPositionChangedTo:(CGPoint)offset forNode:(DOMNode *)domNode isUserScroll:(BOOL)userScroll
3642 {
3643     // Find the frame
3644     Node* node = core(domNode);
3645     Frame* frame = node->document().frame();
3646     if (!frame)
3647         return;
3648
3649     frame->overflowScrollPositionChangedForNode(roundedIntPoint(offset), node, userScroll);
3650 }
3651
3652 + (void)_doNotStartObservingNetworkReachability
3653 {
3654     Settings::setShouldOptOutOfNetworkStateObservation(true);
3655 }
3656 #endif // PLATFORM(IOS)
3657
3658 #if ENABLE(TOUCH_EVENTS)
3659 - (NSArray *)_touchEventRegions
3660 {
3661     Frame* frame = [self _mainCoreFrame];
3662     if (!frame)
3663         return nil;
3664     
3665     Document* document = frame->document();
3666     if (!document)
3667         return nil;
3668
3669     Vector<IntRect> rects;
3670     document->getTouchRects(rects);
3671
3672     if (rects.size() == 0)
3673         return nil;
3674
3675     NSMutableArray *eventRegionArray = [[[NSMutableArray alloc] initWithCapacity:rects.size()] autorelease];
3676
3677     Vector<IntRect>::const_iterator end = rects.end();
3678     for (Vector<IntRect>::const_iterator it = rects.begin(); it != end; ++it) {
3679         const IntRect& rect = *it;
3680         if (rect.isEmpty())
3681             continue;
3682
3683         // The event region wants this points in this order:
3684         //  p2------p3
3685         //  |       |
3686         //  p1------p4
3687         //
3688         WebEventRegion *eventRegion = [[WebEventRegion alloc] initWithPoints:FloatPoint(rect.x(), rect.maxY())
3689                                                                             :FloatPoint(rect.x(), rect.y())
3690                                                                             :FloatPoint(rect.maxX(), rect.y())
3691                                                                             :FloatPoint(rect.maxX(), rect.maxY())];
3692         if (eventRegion) {
3693             [eventRegionArray addObject:eventRegion];
3694             [eventRegion release];
3695         }
3696     }
3697
3698     return eventRegionArray;
3699 }
3700 #endif // ENABLE(TOUCH_EVENTS)
3701
3702 // For backwards compatibility with the WebBackForwardList API, we honor both
3703 // a per-WebView and a per-preferences setting for whether to use the page cache.
3704
3705 - (BOOL)usesPageCache
3706 {
3707     return _private->usesPageCache && [[self preferences] usesPageCache];
3708 }
3709
3710 - (void)setUsesPageCache:(BOOL)usesPageCache
3711 {
3712     _private->usesPageCache = usesPageCache;
3713
3714     // Update our own settings and post the public notification only
3715     [self _preferencesChanged:[self preferences]];
3716     [[self preferences] _postPreferencesChangedAPINotification];
3717 }
3718
3719 - (WebHistoryItem *)_globalHistoryItem
3720 {
3721     if (!_private)
3722         return nil;
3723
3724     return kit(_private->_globalHistoryItem.get());
3725 }
3726
3727 - (void)_setGlobalHistoryItem:(HistoryItem*)historyItem
3728 {
3729     _private->_globalHistoryItem = historyItem;
3730 }
3731
3732 - (WebTextIterator *)textIteratorForRect:(NSRect)rect
3733 {
3734     IntPoint rectStart(rect.origin.x, rect.origin.y);
3735     IntPoint rectEnd(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
3736     
3737     Frame* coreFrame = [self _mainCoreFrame];
3738     if (!coreFrame)
3739         return nil;
3740     
3741     VisibleSelection selectionInsideRect(coreFrame->visiblePositionForPoint(rectStart), coreFrame->visiblePositionForPoint(rectEnd));
3742     
3743     return [[[WebTextIterator alloc] initWithRange:kit(selectionInsideRect.toNormalizedRange().get())] autorelease];
3744 }
3745
3746 #if ENABLE(DASHBOARD_SUPPORT)
3747 - (void)handleAuthenticationForResource:(id)identifier challenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource 
3748 {
3749     NSWindow *window = [self hostWindow] ? [self hostWindow] : [self window]; 
3750     [[WebPanelAuthenticationHandler sharedHandler] startAuthentication:challenge window:window]; 
3751
3752 #endif
3753
3754 #if !PLATFORM(IOS)
3755 - (void)_clearUndoRedoOperations
3756 {
3757     if (!_private->page)
3758         return;
3759     _private->page->clearUndoRedoOperations();
3760 }
3761 #endif
3762
3763 - (void)_executeCoreCommandByName:(NSString *)name value:(NSString *)value
3764 {
3765     Frame* coreFrame = [self _mainCoreFrame];
3766     if (!coreFrame)
3767         return;
3768     coreFrame->editor().command(name).execute(value);
3769 }
3770
3771 - (void)_clearMainFrameName
3772 {
3773     _private->page->mainFrame().tree().clearName();
3774 }
3775
3776 - (void)setSelectTrailingWhitespaceEnabled:(BOOL)flag
3777 {
3778     if (_private->page->settings().selectTrailingWhitespaceEnabled() != flag) {
3779         _private->page->settings().setSelectTrailingWhitespaceEnabled(flag);
3780         [self setSmartInsertDeleteEnabled:!flag];
3781     }
3782 }
3783
3784 - (BOOL)isSelectTrailingWhitespaceEnabled
3785 {
3786     return _private->page->settings().selectTrailingWhitespaceEnabled();
3787 }
3788
3789 - (void)setMemoryCacheDelegateCallsEnabled:(BOOL)enabled
3790 {
3791     _private->page->setMemoryCacheClientCallsEnabled(enabled);
3792 }
3793
3794 - (BOOL)areMemoryCacheDelegateCallsEnabled
3795 {
3796     return _private->page->areMemoryCacheClientCallsEnabled();
3797 }
3798
3799 #if !PLATFORM(IOS)
3800 + (NSCursor *)_pointingHandCursor
3801 {
3802     return handCursor().platformCursor();
3803 }
3804 #endif
3805
3806 - (BOOL)_postsAcceleratedCompositingNotifications
3807 {
3808     return _private->postsAcceleratedCompositingNotifications;
3809 }
3810 - (void)_setPostsAcceleratedCompositingNotifications:(BOOL)flag
3811 {
3812     _private->postsAcceleratedCompositingNotifications = flag;
3813 }
3814
3815 - (BOOL)_isUsingAcceleratedCompositing
3816 {
3817     Frame* coreFrame = [self _mainCoreFrame];
3818     for (Frame* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
3819         NSView *documentView = [[kit(frame) frameView] documentView];
3820         if ([documentView isKindOfClass:[WebHTMLView class]] && [(WebHTMLView *)documentView _isUsingAcceleratedCompositing])
3821             return YES;
3822     }
3823
3824     return NO;
3825 }
3826
3827 - (void)_setBaseCTM:(CGAffineTransform)transform forContext:(CGContextRef)context
3828 {
3829     WKSetBaseCTM(context, transform);
3830 }
3831
3832 - (BOOL)interactiveFormValidationEnabled
3833 {
3834     return _private->interactiveFormValidationEnabled;
3835 }
3836
3837 - (void)setInteractiveFormValidationEnabled:(BOOL)enabled
3838 {
3839     _private->interactiveFormValidationEnabled = enabled;
3840 }
3841
3842 - (int)validationMessageTimerMagnification
3843 {
3844     return _private->validationMessageTimerMagnification;
3845 }
3846
3847 - (void)setValidationMessageTimerMagnification:(int)newValue
3848 {
3849     _private->validationMessageTimerMagnification = newValue;
3850 }
3851
3852 - (BOOL)_isSoftwareRenderable
3853 {
3854     Frame* coreFrame = [self _mainCoreFrame];
3855     for (Frame* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
3856         if (FrameView* view = frame->view()) {
3857             if (!view->isSoftwareRenderable())
3858                 return NO;
3859         }
3860     }
3861
3862     return YES;
3863 }
3864
3865 - (void)_setIncludesFlattenedCompositingLayersWhenDrawingToBitmap:(BOOL)flag
3866 {
3867     _private->includesFlattenedCompositingLayersWhenDrawingToBitmap = flag;
3868 }
3869
3870 - (BOOL)_includesFlattenedCompositingLayersWhenDrawingToBitmap
3871 {
3872     return _private->includesFlattenedCompositingLayersWhenDrawingToBitmap;
3873 }
3874
3875 - (void)setTracksRepaints:(BOOL)flag
3876 {
3877     Frame* coreFrame = [self _mainCoreFrame];
3878     if (FrameView* view = coreFrame->view())
3879         view->setTracksRepaints(flag);
3880 }
3881
3882 - (BOOL)isTrackingRepaints
3883 {
3884     Frame* coreFrame = [self _mainCoreFrame];
3885     if (FrameView* view = coreFrame->view())
3886         return view->isTrackingRepaints();
3887     
3888     return NO;
3889 }
3890
3891 - (void)resetTrackedRepaints
3892 {
3893     Frame* coreFrame = [self _mainCoreFrame];
3894     if (FrameView* view = coreFrame->view())
3895         view->resetTrackedRepaints();
3896 }
3897
3898 - (NSArray*)trackedRepaintRects
3899 {
3900     Frame* coreFrame = [self _mainCoreFrame];
3901     FrameView* view = coreFrame->view();
3902     if (!view || !view->isTrackingRepaints())
3903         return nil;
3904
3905     const Vector<FloatRect>& repaintRects = view->trackedRepaintRects();
3906     NSMutableArray* rectsArray = [[NSMutableArray alloc] initWithCapacity:repaintRects.size()];
3907     
3908     for (unsigned i = 0; i < repaintRects.size(); ++i)
3909         [rectsArray addObject:[NSValue valueWithRect:pixelSnappedIntRect(LayoutRect(repaintRects[i]))]];
3910
3911     return [rectsArray autorelease];
3912 }
3913
3914 #if !PLATFORM(IOS)
3915 - (NSPasteboard *)_insertionPasteboard
3916 {
3917     return _private ? _private->insertionPasteboard : nil;
3918 }
3919 #endif
3920
3921 + (void)_addOriginAccessWhitelistEntryWithSourceOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains
3922 {
3923     SecurityPolicy::addOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
3924 }
3925
3926 + (void)_removeOriginAccessWhitelistEntryWithSourceOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains
3927 {
3928     SecurityPolicy::removeOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
3929 }
3930
3931 + (void)_resetOriginAccessWhitelists
3932 {
3933     SecurityPolicy::resetOriginAccessWhitelists();
3934 }
3935
3936 - (BOOL)_isViewVisible
3937 {
3938     if (![self window])
3939         return false;
3940
3941     if (![[self window] isVisible])
3942         return false;
3943
3944     if ([self isHiddenOrHasHiddenAncestor])
3945         return false;
3946
3947     return true;
3948 }
3949
3950 - (void)_updateVisibilityState
3951 {
3952     if (_private && _private->page)
3953         [self _setIsVisible:[self _isViewVisible]];
3954 }
3955
3956 - (void)_updateActiveState
3957 {
3958     if (_private && _private->page)
3959 #if PLATFORM(IOS)
3960         _private->page->focusController().setActive([[self window] isKeyWindow]);
3961 #else
3962         _private->page->focusController().setActive([[self window] _hasKeyAppearance]);
3963 #endif
3964 }
3965
3966 static Vector<String> toStringVector(NSArray* patterns)
3967 {
3968     Vector<String> patternsVector;
3969
3970     NSUInteger count = [patterns count];
3971     if (!count)
3972         return patternsVector;
3973
3974     for (NSUInteger i = 0; i < count; ++i) {
3975         id entry = [patterns objectAtIndex:i];
3976         if ([entry isKindOfClass:[NSString class]])
3977             patternsVector.append(String((NSString *)entry));
3978     }
3979     return patternsVector;
3980 }
3981
3982 + (void)_addUserScriptToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url
3983                     whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist
3984                 injectionTime:(WebUserScriptInjectionTime)injectionTime
3985 {
3986     [WebView _addUserScriptToGroup:groupName world:world source:source url:url whitelist:whitelist blacklist:blacklist injectionTime:injectionTime injectedFrames:WebInjectInAllFrames];
3987 }
3988
3989 + (void)_addUserScriptToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url
3990                     whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist
3991                 injectionTime:(WebUserScriptInjectionTime)injectionTime
3992                injectedFrames:(WebUserContentInjectedFrames)injectedFrames
3993 {
3994     String group(groupName);
3995     if (group.isEmpty())
3996         return;
3997     
3998     PageGroup* pageGroup = PageGroup::pageGroup(group);
3999     if (!pageGroup)
4000         return;
4001
4002     if (!world)
4003         return;
4004
4005     pageGroup->addUserScriptToWorld(*core(world), source, url, toStringVector(whitelist), toStringVector(blacklist),
4006                                     injectionTime == WebInjectAtDocumentStart ? InjectAtDocumentStart : InjectAtDocumentEnd,
4007                                     injectedFrames == WebInjectInAllFrames ? InjectInAllFrames : InjectInTopFrameOnly);
4008 }
4009
4010 + (void)_addUserStyleSheetToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url
4011                         whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist
4012 {
4013     [WebView _addUserStyleSheetToGroup:groupName world:world source:source url:url whitelist:whitelist blacklist:blacklist injectedFrames:WebInjectInAllFrames];
4014 }
4015
4016 + (void)_addUserStyleSheetToGroup:(NSString *)groupName world:(WebScriptWorld *)world source:(NSString *)source url:(NSURL *)url
4017                         whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist
4018                    injectedFrames:(WebUserContentInjectedFrames)injectedFrames
4019 {
4020     String group(groupName);
4021     if (group.isEmpty())
4022         return;
4023     
4024     PageGroup* pageGroup = PageGroup::pageGroup(group);
4025     if (!pageGroup)
4026         return;
4027
4028     if (!world)
4029         return;
4030
4031     pageGroup->addUserStyleSheetToWorld(*core(world), source, url, toStringVector(whitelist), toStringVector(blacklist), injectedFrames == WebInjectInAllFrames ? InjectInAllFrames : InjectInTopFrameOnly);
4032 }
4033
4034 + (void)_removeUserScriptFromGroup:(NSString *)groupName world:(WebScriptWorld *)world url:(NSURL *)url
4035 {
4036     String group(groupName);
4037     if (group.isEmpty())
4038         return;
4039     
4040     PageGroup* pageGroup = PageGroup::pageGroup(group);
4041     if (!pageGroup)
4042         return;
4043
4044     if (!world)
4045         return;
4046
4047     pageGroup->removeUserScriptFromWorld(*core(world), url);
4048 }
4049
4050 + (void)_removeUserStyleSheetFromGroup:(NSString *)groupName world:(WebScriptWorld *)world url:(NSURL *)url
4051 {
4052     String group(groupName);
4053     if (group.isEmpty())
4054         return;
4055     
4056     PageGroup* pageGroup = PageGroup::pageGroup(group);
4057     if (!pageGroup)
4058         return;
4059
4060     if (!world)
4061         return;
4062
4063     pageGroup->removeUserStyleSheetFromWorld(*core(world), url);
4064 }
4065
4066 + (void)_removeUserScriptsFromGroup:(NSString *)groupName world:(WebScriptWorld *)world
4067 {
4068     String group(groupName);
4069     if (group.isEmpty())
4070         return;
4071     
4072     PageGroup* pageGroup = PageGroup::pageGroup(group);
4073     if (!pageGroup)
4074         return;
4075
4076     if (!world)
4077         return;
4078
4079     pageGroup->removeUserScriptsFromWorld(*core(world));
4080 }
4081
4082 + (void)_removeUserStyleSheetsFromGroup:(NSString *)groupName world:(WebScriptWorld *)world
4083 {
4084     String group(groupName);
4085     if (group.isEmpty())
4086         return;
4087     
4088     PageGroup* pageGroup = PageGroup::pageGroup(group);
4089     if (!pageGroup)
4090         return;
4091
4092     if (!world)
4093         return;
4094
4095     pageGroup->removeUserStyleSheetsFromWorld(*core(world));
4096 }
4097
4098 + (void)_removeAllUserContentFromGroup:(NSString *)groupName
4099 {
4100     String group(groupName);
4101     if (group.isEmpty())
4102         return;
4103     
4104     PageGroup* pageGroup = PageGroup::pageGroup(group);
4105     if (!pageGroup)
4106         return;
4107     
4108     pageGroup->removeAllUserContent();
4109 }
4110
4111 - (BOOL)allowsNewCSSAnimationsWhileSuspended
4112 {
4113     Frame* frame = core([self mainFrame]);
4114     if (frame)
4115         return frame->animation().allowsNewAnimationsWhileSuspended();
4116
4117     return false;
4118 }
4119
4120 - (void)setAllowsNewCSSAnimationsWhileSuspended:(BOOL)allowed
4121 {
4122     Frame* frame = core([self mainFrame]);
4123     if (frame)
4124         frame->animation().setAllowsNewAnimationsWhileSuspended(allowed);
4125 }
4126
4127 - (BOOL)cssAnimationsSuspended
4128 {
4129     // should ask the page!
4130     Frame* frame = core([self mainFrame]);
4131     if (frame)
4132         return frame->animation().isSuspended();
4133
4134     return false;
4135 }
4136
4137 - (void)setCSSAnimationsSuspended:(BOOL)suspended
4138 {
4139     Frame* frame = core([self mainFrame]);
4140     if (suspended == frame->animation().isSuspended())
4141         return;
4142         
4143     if (suspended)
4144         frame->animation().suspendAnimations();
4145     else
4146         frame->animation().resumeAnimations();
4147 }
4148
4149 + (void)_setDomainRelaxationForbidden:(BOOL)forbidden forURLScheme:(NSString *)scheme
4150 {
4151     SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(forbidden, scheme);
4152 }
4153
4154 + (void)_registerURLSchemeAsSecure:(NSString *)scheme
4155 {
4156     SchemeRegistry::registerURLSchemeAsSecure(scheme);
4157 }
4158
4159 + (void)_registerURLSchemeAsAllowingLocalStorageAccessInPrivateBrowsing:(NSString *)scheme
4160 {
4161     SchemeRegistry::registerURLSchemeAsAllowingLocalStorageAccessInPrivateBrowsing(scheme);
4162 }
4163
4164 + (void)_registerURLSchemeAsAllowingDatabaseAccessInPrivateBrowsing:(NSString *)scheme
4165 {
4166     SchemeRegistry::registerURLSchemeAsAllowingDatabaseAccessInPrivateBrowsing(scheme);
4167 }
4168
4169 - (void)_scaleWebView:(float)scale atOrigin:(NSPoint)origin
4170 {
4171     _private->page->setPageScaleFactor(scale, IntPoint(origin));
4172 }
4173
4174 - (float)_viewScaleFactor
4175 {
4176     return _private->page->pageScaleFactor();
4177 }
4178
4179 - (void)_setUseFixedLayout:(BOOL)fixed
4180 {
4181     Frame* coreFrame = [self _mainCoreFrame];
4182     if (!coreFrame)
4183         return;
4184
4185     FrameView* view = coreFrame->view();
4186     if (!view)
4187         return;
4188
4189     view->setUseFixedLayout(fixed);
4190     if (!fixed)
4191         view->setFixedLayoutSize(IntSize());
4192 }
4193
4194 #if !PLATFORM(IOS)
4195 - (void)_setFixedLayoutSize:(NSSize)size
4196 {
4197     Frame* coreFrame = [self _mainCoreFrame];
4198     if (!coreFrame)
4199         return;
4200     
4201     FrameView* view = coreFrame->view();
4202     if (!view)
4203         return;
4204     
4205     view->setFixedLayoutSize(IntSize(size));
4206     view->forceLayout();
4207 }
4208 #endif
4209
4210 - (BOOL)_useFixedLayout
4211 {
4212     Frame* coreFrame = [self _mainCoreFrame];
4213     if (!coreFrame)
4214         return NO;
4215     
4216     FrameView* view = coreFrame->view();
4217     if (!view)
4218         return NO;
4219     
4220     return view->useFixedLayout();
4221 }
4222
4223 #if !PLATFORM(IOS)
4224 - (NSSize)_fixedLayoutSize
4225 {
4226     Frame* coreFrame = [self _mainCoreFrame];
4227     if (!coreFrame)
4228         return IntSize();
4229     
4230     FrameView* view = coreFrame->view();
4231     if (!view)
4232         return IntSize();
4233
4234     return view->fixedLayoutSize();
4235 }
4236 #endif
4237
4238 - (void)_setPaginationMode:(WebPaginationMode)paginationMode
4239 {
4240     Page* page = core(self);
4241     if (!page)
4242         return;
4243
4244     Pagination pagination = page->pagination();
4245     switch (paginationMode) {
4246     case WebPaginationModeUnpaginated:
4247         pagination.mode = Pagination::Unpaginated;
4248         break;
4249     case WebPaginationModeLeftToRight:
4250         pagination.mode = Pagination::LeftToRightPaginated;
4251         break;
4252     case WebPaginationModeRightToLeft:
4253         pagination.mode = Pagination::RightToLeftPaginated;
4254         break;
4255     case WebPaginationModeTopToBottom:
4256         pagination.mode = Pagination::TopToBottomPaginated;
4257         break;
4258     case WebPaginationModeBottomToTop:
4259         pagination.mode = Pagination::BottomToTopPaginated;
4260         break;
4261     default:
4262         return;
4263     }
4264
4265     page->setPagination(pagination);
4266 }
4267
4268 - (WebPaginationMode)_paginationMode
4269 {
4270     Page* page = core(self);
4271     if (!page)
4272         return WebPaginationModeUnpaginated;
4273
4274     switch (page->pagination().mode) {
4275     case Pagination::Unpaginated:
4276         return WebPaginationModeUnpaginated;
4277     case Pagination::LeftToRightPaginated:
4278         return WebPaginationModeLeftToRight;
4279     case Pagination::RightToLeftPaginated:
4280         return WebPaginationModeRightToLeft;
4281     case Pagination::TopToBottomPaginated:
4282         return WebPaginationModeTopToBottom;
4283     case Pagination::BottomToTopPaginated:
4284         return WebPaginationModeBottomToTop;
4285     }
4286
4287     ASSERT_NOT_REACHED();
4288     return WebPaginationModeUnpaginated;
4289 }
4290
4291 - (void)_listenForLayoutMilestones:(WebLayoutMilestones)layoutMilestones
4292 {
4293     Page* page = core(self);
4294     if (!page)
4295         return;
4296
4297     page->addLayoutMilestones(coreLayoutMilestones(layoutMilestones));
4298 }
4299
4300 - (WebLayoutMilestones)_layoutMilestones
4301 {
4302     Page* page = core(self);
4303     if (!page)
4304         return 0;
4305
4306     return kitLayoutMilestones(page->requestedLayoutMilestones());
4307 }
<