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