WebKit/mac/WebView/WebFrame.mm
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     8  * 1.  Redistributions of source code must retain the above copyright
       
     9  *     notice, this list of conditions and the following disclaimer. 
       
    10  * 2.  Redistributions in binary form must reproduce the above copyright
       
    11  *     notice, this list of conditions and the following disclaimer in the
       
    12  *     documentation and/or other materials provided with the distribution. 
       
    13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
       
    14  *     its contributors may be used to endorse or promote products derived
       
    15  *     from this software without specific prior written permission. 
       
    16  *
       
    17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
       
    18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    27  */
       
    28 
       
    29 #import "WebFrameInternal.h"
       
    30 
       
    31 #import "DOMCSSStyleDeclarationInternal.h"
       
    32 #import "DOMDocumentFragmentInternal.h"
       
    33 #import "DOMDocumentInternal.h"
       
    34 #import "DOMElementInternal.h"
       
    35 #import "DOMHTMLElementInternal.h"
       
    36 #import "DOMNodeInternal.h"
       
    37 #import "DOMRangeInternal.h"
       
    38 #import "WebArchiveInternal.h"
       
    39 #import "WebChromeClient.h"
       
    40 #import "WebDataSourceInternal.h"
       
    41 #import "WebDocumentLoaderMac.h"
       
    42 #import "WebDynamicScrollBarsView.h"
       
    43 #import "WebFrameLoaderClient.h"
       
    44 #import "WebFrameViewInternal.h"
       
    45 #import "WebHTMLView.h"
       
    46 #import "WebHTMLViewInternal.h"
       
    47 #import "WebIconFetcherInternal.h"
       
    48 #import "WebKitStatisticsPrivate.h"
       
    49 #import "WebKitVersionChecks.h"
       
    50 #import "WebNSObjectExtras.h"
       
    51 #import "WebNSURLExtras.h"
       
    52 #import "WebScriptDebugger.h"
       
    53 #import "WebScriptWorldInternal.h"
       
    54 #import "WebViewInternal.h"
       
    55 #import <JavaScriptCore/APICast.h>
       
    56 #import <WebCore/AXObjectCache.h>
       
    57 #import <WebCore/AccessibilityObject.h>
       
    58 #import <WebCore/AnimationController.h>
       
    59 #import <WebCore/CSSMutableStyleDeclaration.h>
       
    60 #import <WebCore/Chrome.h>
       
    61 #import <WebCore/ColorMac.h>
       
    62 #import <WebCore/DOMImplementation.h>
       
    63 #import <WebCore/DocLoader.h>
       
    64 #import <WebCore/DocumentFragment.h>
       
    65 #import <WebCore/EventHandler.h>
       
    66 #import <WebCore/EventNames.h>
       
    67 #import <WebCore/Frame.h>
       
    68 #import <WebCore/FrameLoader.h>
       
    69 #import <WebCore/FrameLoaderStateMachine.h>
       
    70 #import <WebCore/FrameTree.h>
       
    71 #import <WebCore/GraphicsContext.h>
       
    72 #import <WebCore/HTMLFrameOwnerElement.h>
       
    73 #import <WebCore/HistoryItem.h>
       
    74 #import <WebCore/HitTestResult.h>
       
    75 #import <WebCore/LegacyWebArchive.h>
       
    76 #import <WebCore/Page.h>
       
    77 #import <WebCore/PluginData.h>
       
    78 #import <WebCore/PrintContext.h>
       
    79 #import <WebCore/RenderLayer.h>
       
    80 #import <WebCore/RenderPart.h>
       
    81 #import <WebCore/RenderView.h>
       
    82 #import <WebCore/ReplaceSelectionCommand.h>
       
    83 #import <WebCore/RuntimeApplicationChecks.h>
       
    84 #import <WebCore/ScriptValue.h>
       
    85 #import <WebCore/SmartReplace.h>
       
    86 #import <WebCore/SVGSMILElement.h>
       
    87 #import <WebCore/TextIterator.h>
       
    88 #import <WebCore/ThreadCheck.h>
       
    89 #import <WebCore/TypingCommand.h>
       
    90 #import <WebCore/htmlediting.h>
       
    91 #import <WebCore/markup.h>
       
    92 #import <WebCore/visible_units.h>
       
    93 #import <WebKitSystemInterface.h>
       
    94 #import <runtime/JSLock.h>
       
    95 #import <runtime/JSObject.h>
       
    96 #import <runtime/JSValue.h>
       
    97 #import <wtf/CurrentTime.h>
       
    98 
       
    99 using namespace std;
       
   100 using namespace WebCore;
       
   101 using namespace HTMLNames;
       
   102 
       
   103 using JSC::JSGlobalObject;
       
   104 using JSC::JSLock;
       
   105 using JSC::JSValue;
       
   106 using JSC::SilenceAssertionsOnly;
       
   107 
       
   108 /*
       
   109 Here is the current behavior matrix for four types of navigations:
       
   110 
       
   111 Standard Nav:
       
   112 
       
   113  Restore form state:   YES
       
   114  Restore scroll and focus state:  YES
       
   115  Cache policy: NSURLRequestUseProtocolCachePolicy
       
   116  Add to back/forward list: YES
       
   117  
       
   118 Back/Forward:
       
   119 
       
   120  Restore form state:   YES
       
   121  Restore scroll and focus state:  YES
       
   122  Cache policy: NSURLRequestReturnCacheDataElseLoad
       
   123  Add to back/forward list: NO
       
   124 
       
   125 Reload (meaning only the reload button):
       
   126 
       
   127  Restore form state:   NO
       
   128  Restore scroll and focus state:  YES
       
   129  Cache policy: NSURLRequestReloadIgnoringCacheData
       
   130  Add to back/forward list: NO
       
   131 
       
   132 Repeat load of the same URL (by any other means of navigation other than the reload button, including hitting return in the location field):
       
   133 
       
   134  Restore form state:   NO
       
   135  Restore scroll and focus state:  NO, reset to initial conditions
       
   136  Cache policy: NSURLRequestReloadIgnoringCacheData
       
   137  Add to back/forward list: NO
       
   138 */
       
   139 
       
   140 NSString *WebPageCacheEntryDateKey = @"WebPageCacheEntryDateKey";
       
   141 NSString *WebPageCacheDataSourceKey = @"WebPageCacheDataSourceKey";
       
   142 NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
       
   143 
       
   144 NSString *WebFrameMainDocumentError = @"WebFrameMainDocumentErrorKey";
       
   145 NSString *WebFrameHasPlugins = @"WebFrameHasPluginsKey";
       
   146 NSString *WebFrameHasUnloadListener = @"WebFrameHasUnloadListenerKey";
       
   147 NSString *WebFrameUsesDatabases = @"WebFrameUsesDatabasesKey";
       
   148 NSString *WebFrameUsesGeolocation = @"WebFrameUsesGeolocationKey";
       
   149 NSString *WebFrameUsesApplicationCache = @"WebFrameUsesApplicationCacheKey";
       
   150 NSString *WebFrameCanSuspendActiveDOMObjects = @"WebFrameCanSuspendActiveDOMObjectsKey";
       
   151 
       
   152 // FIXME: Remove when this key becomes publicly defined
       
   153 NSString *NSAccessibilityEnhancedUserInterfaceAttribute = @"AXEnhancedUserInterface";
       
   154 
       
   155 @implementation WebFramePrivate
       
   156 
       
   157 - (void)dealloc
       
   158 {
       
   159     [webFrameView release];
       
   160 
       
   161     delete scriptDebugger;
       
   162 
       
   163     [super dealloc];
       
   164 }
       
   165 
       
   166 - (void)finalize
       
   167 {
       
   168     delete scriptDebugger;
       
   169 
       
   170     [super finalize];
       
   171 }
       
   172 
       
   173 - (void)setWebFrameView:(WebFrameView *)v 
       
   174 { 
       
   175     [v retain];
       
   176     [webFrameView release];
       
   177     webFrameView = v;
       
   178 }
       
   179 
       
   180 @end
       
   181 
       
   182 EditableLinkBehavior core(WebKitEditableLinkBehavior editableLinkBehavior)
       
   183 {
       
   184     switch (editableLinkBehavior) {
       
   185         case WebKitEditableLinkDefaultBehavior:
       
   186             return EditableLinkDefaultBehavior;
       
   187         case WebKitEditableLinkAlwaysLive:
       
   188             return EditableLinkAlwaysLive;
       
   189         case WebKitEditableLinkOnlyLiveWithShiftKey:
       
   190             return EditableLinkOnlyLiveWithShiftKey;
       
   191         case WebKitEditableLinkLiveWhenNotFocused:
       
   192             return EditableLinkLiveWhenNotFocused;
       
   193         case WebKitEditableLinkNeverLive:
       
   194             return EditableLinkNeverLive;
       
   195     }
       
   196     ASSERT_NOT_REACHED();
       
   197     return EditableLinkDefaultBehavior;
       
   198 }
       
   199 
       
   200 WebCore::EditingBehaviorType core(WebKitEditingBehavior behavior)
       
   201 {
       
   202     switch (behavior) {
       
   203         case WebKitEditingMacBehavior:
       
   204             return WebCore::EditingMacBehavior;
       
   205         case WebKitEditingWinBehavior:
       
   206             return WebCore::EditingWindowsBehavior;
       
   207     }
       
   208     ASSERT_NOT_REACHED();
       
   209     return WebCore::EditingMacBehavior;
       
   210 }
       
   211 
       
   212 TextDirectionSubmenuInclusionBehavior core(WebTextDirectionSubmenuInclusionBehavior behavior)
       
   213 {
       
   214     switch (behavior) {
       
   215         case WebTextDirectionSubmenuNeverIncluded:
       
   216             return TextDirectionSubmenuNeverIncluded;
       
   217         case WebTextDirectionSubmenuAutomaticallyIncluded:
       
   218             return TextDirectionSubmenuAutomaticallyIncluded;
       
   219         case WebTextDirectionSubmenuAlwaysIncluded:
       
   220             return TextDirectionSubmenuAlwaysIncluded;
       
   221     }
       
   222     ASSERT_NOT_REACHED();
       
   223     return TextDirectionSubmenuNeverIncluded;
       
   224 }
       
   225 
       
   226 @implementation WebFrame (WebInternal)
       
   227 
       
   228 Frame* core(WebFrame *frame)
       
   229 {
       
   230     return frame ? frame->_private->coreFrame : 0;
       
   231 }
       
   232 
       
   233 WebFrame *kit(Frame* frame)
       
   234 {
       
   235     return frame ? static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame() : nil;
       
   236 }
       
   237 
       
   238 Page* core(WebView *webView)
       
   239 {
       
   240     return [webView page];
       
   241 }
       
   242 
       
   243 WebView *kit(Page* page)
       
   244 {
       
   245     return page ? static_cast<WebChromeClient*>(page->chrome()->client())->webView() : nil;
       
   246 }
       
   247 
       
   248 WebView *getWebView(WebFrame *webFrame)
       
   249 {
       
   250     Frame* coreFrame = core(webFrame);
       
   251     if (!coreFrame)
       
   252         return nil;
       
   253     return kit(coreFrame->page());
       
   254 }
       
   255 
       
   256 + (PassRefPtr<Frame>)_createFrameWithPage:(Page*)page frameName:(const String&)name frameView:(WebFrameView *)frameView ownerElement:(HTMLFrameOwnerElement*)ownerElement
       
   257 {
       
   258     WebView *webView = kit(page);
       
   259 
       
   260     WebFrame *frame = [[self alloc] _initWithWebFrameView:frameView webView:webView];
       
   261     RefPtr<Frame> coreFrame = Frame::create(page, ownerElement, new WebFrameLoaderClient(frame));
       
   262     [frame release];
       
   263     frame->_private->coreFrame = coreFrame.get();
       
   264 
       
   265     coreFrame->tree()->setName(name);
       
   266     if (ownerElement) {
       
   267         ASSERT(ownerElement->document()->frame());
       
   268         ownerElement->document()->frame()->tree()->appendChild(coreFrame.get());
       
   269     }
       
   270 
       
   271     coreFrame->init();
       
   272 
       
   273     [webView _setZoomMultiplier:[webView _realZoomMultiplier] isTextOnly:[webView _realZoomMultiplierIsTextOnly]];
       
   274 
       
   275     return coreFrame.release();
       
   276 }
       
   277 
       
   278 + (void)_createMainFrameWithPage:(Page*)page frameName:(const String&)name frameView:(WebFrameView *)frameView
       
   279 {
       
   280     [self _createFrameWithPage:page frameName:name frameView:frameView ownerElement:0];
       
   281 }
       
   282 
       
   283 + (PassRefPtr<WebCore::Frame>)_createSubframeWithOwnerElement:(HTMLFrameOwnerElement*)ownerElement frameName:(const String&)name frameView:(WebFrameView *)frameView
       
   284 {
       
   285     return [self _createFrameWithPage:ownerElement->document()->frame()->page() frameName:name frameView:frameView ownerElement:ownerElement];
       
   286 }
       
   287 
       
   288 - (BOOL)_isIncludedInWebKitStatistics
       
   289 {
       
   290     return _private && _private->includedInWebKitStatistics;
       
   291 }
       
   292 
       
   293 - (void)_attachScriptDebugger
       
   294 {
       
   295     ScriptController* scriptController = _private->coreFrame->script();
       
   296 
       
   297     // Calling ScriptController::globalObject() would create a window shell, and dispatch corresponding callbacks, which may be premature
       
   298     // if the script debugger is attached before a document is created.  These calls use the debuggerWorld(), we will need to pass a world
       
   299     // to be able to debug isolated worlds.
       
   300     if (!scriptController->existingWindowShell(debuggerWorld()))
       
   301         return;
       
   302 
       
   303     JSGlobalObject* globalObject = scriptController->globalObject(debuggerWorld());
       
   304     if (!globalObject)
       
   305         return;
       
   306 
       
   307     if (_private->scriptDebugger) {
       
   308         ASSERT(_private->scriptDebugger == globalObject->debugger());
       
   309         return;
       
   310     }
       
   311 
       
   312     _private->scriptDebugger = new WebScriptDebugger(globalObject);
       
   313 }
       
   314 
       
   315 - (void)_detachScriptDebugger
       
   316 {
       
   317     if (!_private->scriptDebugger)
       
   318         return;
       
   319 
       
   320     delete _private->scriptDebugger;
       
   321     _private->scriptDebugger = 0;
       
   322 }
       
   323 
       
   324 - (id)_initWithWebFrameView:(WebFrameView *)fv webView:(WebView *)v
       
   325 {
       
   326     self = [super init];
       
   327     if (!self)
       
   328         return nil;
       
   329 
       
   330     _private = [[WebFramePrivate alloc] init];
       
   331 
       
   332     // Set includedInWebKitStatistics before calling WebFrameView _setWebFrame, since
       
   333     // it calls WebFrame _isIncludedInWebKitStatistics.
       
   334     if ((_private->includedInWebKitStatistics = [[v class] shouldIncludeInWebKitStatistics]))
       
   335         ++WebFrameCount;
       
   336 
       
   337     if (fv) {
       
   338         [_private setWebFrameView:fv];
       
   339         [fv _setWebFrame:self];
       
   340     }
       
   341 
       
   342     _private->shouldCreateRenderers = YES;
       
   343 
       
   344     return self;
       
   345 }
       
   346 
       
   347 - (void)_clearCoreFrame
       
   348 {
       
   349     _private->coreFrame = 0;
       
   350 }
       
   351 
       
   352 - (void)_updateBackgroundAndUpdatesWhileOffscreen
       
   353 {
       
   354     WebView *webView = getWebView(self);
       
   355     BOOL drawsBackground = [webView drawsBackground];
       
   356     NSColor *backgroundColor = [webView backgroundColor];
       
   357 
       
   358     Frame* coreFrame = _private->coreFrame;
       
   359     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   360         if ([webView _usesDocumentViews]) {
       
   361             // Don't call setDrawsBackground:YES here because it may be NO because of a load
       
   362             // in progress; WebFrameLoaderClient keeps it set to NO during the load process.
       
   363             WebFrame *webFrame = kit(frame);
       
   364             if (!drawsBackground)
       
   365                 [[[webFrame frameView] _scrollView] setDrawsBackground:NO];
       
   366             [[[webFrame frameView] _scrollView] setBackgroundColor:backgroundColor];
       
   367             id documentView = [[webFrame frameView] documentView];
       
   368             if ([documentView respondsToSelector:@selector(setDrawsBackground:)])
       
   369                 [documentView setDrawsBackground:drawsBackground];
       
   370             if ([documentView respondsToSelector:@selector(setBackgroundColor:)])
       
   371                 [documentView setBackgroundColor:backgroundColor];
       
   372         }
       
   373 
       
   374         if (FrameView* view = frame->view()) {
       
   375             view->setTransparent(!drawsBackground);
       
   376             view->setBaseBackgroundColor(colorFromNSColor([backgroundColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]));
       
   377             view->setShouldUpdateWhileOffscreen([webView shouldUpdateWhileOffscreen]);
       
   378         }
       
   379     }
       
   380 }
       
   381 
       
   382 - (void)_setInternalLoadDelegate:(id)internalLoadDelegate
       
   383 {
       
   384     _private->internalLoadDelegate = internalLoadDelegate;
       
   385 }
       
   386 
       
   387 - (id)_internalLoadDelegate
       
   388 {
       
   389     return _private->internalLoadDelegate;
       
   390 }
       
   391 
       
   392 #ifndef BUILDING_ON_TIGER
       
   393 - (void)_unmarkAllBadGrammar
       
   394 {
       
   395     Frame* coreFrame = _private->coreFrame;
       
   396     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   397         if (Document* document = frame->document())
       
   398             document->removeMarkers(DocumentMarker::Grammar);
       
   399     }
       
   400 }
       
   401 #endif
       
   402 
       
   403 - (void)_unmarkAllMisspellings
       
   404 {
       
   405     Frame* coreFrame = _private->coreFrame;
       
   406     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   407         if (Document* document = frame->document())
       
   408             document->removeMarkers(DocumentMarker::Spelling);
       
   409     }
       
   410 }
       
   411 
       
   412 - (BOOL)_hasSelection
       
   413 {
       
   414     if ([getWebView(self) _usesDocumentViews]) {
       
   415         id documentView = [_private->webFrameView documentView];    
       
   416 
       
   417         // optimization for common case to avoid creating potentially large selection string
       
   418         if ([documentView isKindOfClass:[WebHTMLView class]])
       
   419             if (Frame* coreFrame = _private->coreFrame)
       
   420                 return coreFrame->selection()->isRange();
       
   421 
       
   422         if ([documentView conformsToProtocol:@protocol(WebDocumentText)])
       
   423             return [[documentView selectedString] length] > 0;
       
   424         
       
   425         return NO;
       
   426     }
       
   427 
       
   428     Frame* coreFrame = _private->coreFrame;
       
   429     return coreFrame && coreFrame->selection()->isRange();
       
   430 }
       
   431 
       
   432 - (void)_clearSelection
       
   433 {
       
   434     ASSERT([getWebView(self) _usesDocumentViews]);
       
   435     id documentView = [_private->webFrameView documentView];    
       
   436     if ([documentView conformsToProtocol:@protocol(WebDocumentText)])
       
   437         [documentView deselectAll];
       
   438 }
       
   439 
       
   440 #if !ASSERT_DISABLED
       
   441 - (BOOL)_atMostOneFrameHasSelection
       
   442 {
       
   443     // FIXME: 4186050 is one known case that makes this debug check fail.
       
   444     BOOL found = NO;
       
   445     Frame* coreFrame = _private->coreFrame;
       
   446     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame))
       
   447         if ([kit(frame) _hasSelection]) {
       
   448             if (found)
       
   449                 return NO;
       
   450             found = YES;
       
   451         }
       
   452     return YES;
       
   453 }
       
   454 #endif
       
   455 
       
   456 - (WebFrame *)_findFrameWithSelection
       
   457 {
       
   458     Frame* coreFrame = _private->coreFrame;
       
   459     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   460         WebFrame *webFrame = kit(frame);
       
   461         if ([webFrame _hasSelection])
       
   462             return webFrame;
       
   463     }
       
   464     return nil;
       
   465 }
       
   466 
       
   467 - (void)_clearSelectionInOtherFrames
       
   468 {
       
   469     // We rely on WebDocumentSelection protocol implementors to call this method when they become first 
       
   470     // responder. It would be nicer to just notice first responder changes here instead, but there's no 
       
   471     // notification sent when the first responder changes in general (Radar 2573089).
       
   472     WebFrame *frameWithSelection = [[getWebView(self) mainFrame] _findFrameWithSelection];
       
   473     if (frameWithSelection != self)
       
   474         [frameWithSelection _clearSelection];
       
   475 
       
   476     // While we're in the general area of selection and frames, check that there is only one now.
       
   477     ASSERT([[getWebView(self) mainFrame] _atMostOneFrameHasSelection]);
       
   478 }
       
   479 
       
   480 static inline WebDataSource *dataSource(DocumentLoader* loader)
       
   481 {
       
   482     return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;
       
   483 }
       
   484 
       
   485 - (WebDataSource *)_dataSource
       
   486 {
       
   487     return dataSource(_private->coreFrame->loader()->documentLoader());
       
   488 }
       
   489 
       
   490 - (void)_addData:(NSData *)data
       
   491 {
       
   492     Document* document = _private->coreFrame->document();
       
   493     
       
   494     // Document may be nil if the part is about to redirect
       
   495     // as a result of JS executing during load, i.e. one frame
       
   496     // changing another's location before the frame's document
       
   497     // has been created. 
       
   498     if (!document)
       
   499         return;
       
   500 
       
   501     document->setShouldCreateRenderers(_private->shouldCreateRenderers);
       
   502     _private->coreFrame->loader()->addData((const char *)[data bytes], [data length]);
       
   503 }
       
   504 
       
   505 - (NSString *)_stringWithDocumentTypeStringAndMarkupString:(NSString *)markupString
       
   506 {
       
   507     return _private->coreFrame->documentTypeString() + markupString;
       
   508 }
       
   509 
       
   510 - (NSArray *)_nodesFromList:(Vector<Node*> *)nodesVector
       
   511 {
       
   512     size_t size = nodesVector->size();
       
   513     NSMutableArray *nodes = [NSMutableArray arrayWithCapacity:size];
       
   514     for (size_t i = 0; i < size; ++i)
       
   515         [nodes addObject:kit((*nodesVector)[i])];
       
   516     return nodes;
       
   517 }
       
   518 
       
   519 - (NSString *)_markupStringFromRange:(DOMRange *)range nodes:(NSArray **)nodes
       
   520 {
       
   521     // FIXME: This is always "for interchange". Is that right? See the previous method.
       
   522     Vector<Node*> nodeList;
       
   523     NSString *markupString = createMarkup(core(range), nodes ? &nodeList : 0, AnnotateForInterchange);
       
   524     if (nodes)
       
   525         *nodes = [self _nodesFromList:&nodeList];
       
   526 
       
   527     return [self _stringWithDocumentTypeStringAndMarkupString:markupString];
       
   528 }
       
   529 
       
   530 - (NSString *)_selectedString
       
   531 {
       
   532     return _private->coreFrame->displayStringModifiedByEncoding(_private->coreFrame->selectedText());
       
   533 }
       
   534 
       
   535 - (NSString *)_stringForRange:(DOMRange *)range
       
   536 {
       
   537     // This will give a system malloc'd buffer that can be turned directly into an NSString
       
   538     unsigned length;
       
   539     UChar* buf = plainTextToMallocAllocatedBuffer(core(range), length, true);
       
   540     
       
   541     if (!buf)
       
   542         return [NSString string];
       
   543 
       
   544     // Transfer buffer ownership to NSString
       
   545     return [[[NSString alloc] initWithCharactersNoCopy:buf length:length freeWhenDone:YES] autorelease];
       
   546 }
       
   547 
       
   548 - (void)_drawRect:(NSRect)rect contentsOnly:(BOOL)contentsOnly
       
   549 {
       
   550     ASSERT([[NSGraphicsContext currentContext] isFlipped]);
       
   551 
       
   552     CGContextRef ctx = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
       
   553     GraphicsContext context(ctx);
       
   554 
       
   555     FrameView* view = _private->coreFrame->view();
       
   556     
       
   557     bool shouldFlatten = false;
       
   558     if (Frame* parentFrame = _private->coreFrame->tree()->parent()) {
       
   559         // For subframes, we need to inherit the paint behavior from our parent
       
   560         FrameView* parentView = parentFrame ? parentFrame->view() : 0;
       
   561         if (parentView)
       
   562             shouldFlatten = parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers;
       
   563     } else
       
   564         shouldFlatten = WKCGContextIsBitmapContext(ctx) && [getWebView(self) _includesFlattenedCompositingLayersWhenDrawingToBitmap];
       
   565 
       
   566     PaintBehavior oldBehavior = PaintBehaviorNormal;
       
   567     if (shouldFlatten) {
       
   568         oldBehavior = view->paintBehavior();
       
   569         view->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
       
   570     }
       
   571     
       
   572     if (contentsOnly)
       
   573         _private->coreFrame->view()->paintContents(&context, enclosingIntRect(rect));
       
   574     else
       
   575         _private->coreFrame->view()->paint(&context, enclosingIntRect(rect));
       
   576 
       
   577     if (shouldFlatten)
       
   578         view->setPaintBehavior(oldBehavior);
       
   579 }
       
   580 
       
   581 // Used by pagination code called from AppKit when a standalone web page is printed.
       
   582 - (NSArray*)_computePageRectsWithPrintWidthScaleFactor:(float)printWidthScaleFactor printHeight:(float)printHeight
       
   583 {
       
   584     NSMutableArray* pages = [NSMutableArray arrayWithCapacity:5];
       
   585     if (printWidthScaleFactor <= 0) {
       
   586         LOG_ERROR("printWidthScaleFactor has bad value %.2f", printWidthScaleFactor);
       
   587         return pages;
       
   588     }
       
   589     
       
   590     if (printHeight <= 0) {
       
   591         LOG_ERROR("printHeight has bad value %.2f", printHeight);
       
   592         return pages;
       
   593     }
       
   594 
       
   595     if (!_private->coreFrame || !_private->coreFrame->document() || !_private->coreFrame->view()) return pages;
       
   596     RenderView* root = toRenderView(_private->coreFrame->document()->renderer());
       
   597     if (!root) return pages;
       
   598     
       
   599     FrameView* view = _private->coreFrame->view();
       
   600     if (!view)
       
   601         return pages;
       
   602 
       
   603     NSView* documentView = view->documentView();
       
   604     if (!documentView)
       
   605         return pages;
       
   606 
       
   607     float docWidth = root->layer()->width();
       
   608     float printWidth = docWidth / printWidthScaleFactor;
       
   609 
       
   610     PrintContext printContext(_private->coreFrame);
       
   611     printContext.computePageRectsWithPageSize(FloatSize(printWidth, printHeight), true);
       
   612 
       
   613     const Vector<IntRect>& pageRects = printContext.pageRects();
       
   614     const size_t pageCount = pageRects.size();
       
   615     for (size_t pageNumber = 0; pageNumber < pageCount; ++pageNumber)
       
   616         [pages addObject: [NSValue valueWithRect: NSRect(pageRects[pageNumber])]];
       
   617     return pages;
       
   618 }
       
   619 
       
   620 - (BOOL)_getVisibleRect:(NSRect*)rect
       
   621 {
       
   622     ASSERT_ARG(rect, rect);
       
   623     if (RenderPart* ownerRenderer = _private->coreFrame->ownerRenderer()) {
       
   624         if (ownerRenderer->needsLayout())
       
   625             return NO;
       
   626         *rect = ownerRenderer->absoluteClippedOverflowRect();
       
   627         return YES;
       
   628     }
       
   629 
       
   630     return NO;
       
   631 }
       
   632 
       
   633 - (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string
       
   634 {
       
   635     return [self _stringByEvaluatingJavaScriptFromString:string forceUserGesture:true];
       
   636 }
       
   637 
       
   638 - (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture
       
   639 {
       
   640     ASSERT(_private->coreFrame->document());
       
   641     
       
   642     JSValue result = _private->coreFrame->script()->executeScript(string, forceUserGesture).jsValue();
       
   643 
       
   644     if (!_private->coreFrame) // In case the script removed our frame from the page.
       
   645         return @"";
       
   646 
       
   647     // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
       
   648     // If you don't like it, use -[WebScriptObject evaluateWebScript:] or 
       
   649     // JSEvaluateScript instead, since they have less surprising semantics.
       
   650     if (!result || !result.isBoolean() && !result.isString() && !result.isNumber())
       
   651         return @"";
       
   652 
       
   653     JSLock lock(SilenceAssertionsOnly);
       
   654     return ustringToString(result.toString(_private->coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec()));
       
   655 }
       
   656 
       
   657 - (NSRect)_caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity
       
   658 {
       
   659     VisiblePosition visiblePosition(core(node), offset, static_cast<EAffinity>(affinity));
       
   660     return visiblePosition.absoluteCaretBounds();
       
   661 }
       
   662 
       
   663 - (NSRect)_firstRectForDOMRange:(DOMRange *)range
       
   664 {
       
   665    return _private->coreFrame->firstRectForRange(core(range));
       
   666 }
       
   667 
       
   668 - (void)_scrollDOMRangeToVisible:(DOMRange *)range
       
   669 {
       
   670     NSRect rangeRect = [self _firstRectForDOMRange:range];    
       
   671     Node *startNode = core([range startContainer]);
       
   672         
       
   673     if (startNode && startNode->renderer()) {
       
   674         RenderLayer *layer = startNode->renderer()->enclosingLayer();
       
   675         if (layer)
       
   676             layer->scrollRectToVisible(enclosingIntRect(rangeRect), false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
       
   677     }
       
   678 }
       
   679 
       
   680 - (BOOL)_needsLayout
       
   681 {
       
   682     return _private->coreFrame->view() ? _private->coreFrame->view()->needsLayout() : false;
       
   683 }
       
   684 
       
   685 - (id)_accessibilityTree
       
   686 {
       
   687 #if HAVE(ACCESSIBILITY)
       
   688     if (!AXObjectCache::accessibilityEnabled()) {
       
   689         AXObjectCache::enableAccessibility();
       
   690         if ([[NSApp accessibilityAttributeValue:NSAccessibilityEnhancedUserInterfaceAttribute] boolValue])
       
   691             AXObjectCache::enableEnhancedUserInterfaceAccessibility();
       
   692     }
       
   693 
       
   694     if (!_private->coreFrame || !_private->coreFrame->document())
       
   695         return nil;
       
   696     RenderView* root = toRenderView(_private->coreFrame->document()->renderer());
       
   697     if (!root)
       
   698         return nil;
       
   699     return _private->coreFrame->document()->axObjectCache()->getOrCreate(root)->wrapper();
       
   700 #else
       
   701     return nil;
       
   702 #endif
       
   703 }
       
   704 
       
   705 - (DOMRange *)_rangeByAlteringCurrentSelection:(SelectionController::EAlteration)alteration direction:(SelectionController::EDirection)direction granularity:(TextGranularity)granularity
       
   706 {
       
   707     if (_private->coreFrame->selection()->isNone())
       
   708         return nil;
       
   709 
       
   710     SelectionController selection;
       
   711     selection.setSelection(_private->coreFrame->selection()->selection());
       
   712     selection.modify(alteration, direction, granularity);
       
   713     return kit(selection.toNormalizedRange().get());
       
   714 }
       
   715 
       
   716 - (TextGranularity)_selectionGranularity
       
   717 {
       
   718     return _private->coreFrame->selectionGranularity();
       
   719 }
       
   720 
       
   721 - (NSRange)_convertToNSRange:(Range *)range
       
   722 {
       
   723     if (!range || !range->startContainer())
       
   724         return NSMakeRange(NSNotFound, 0);
       
   725 
       
   726     Element* selectionRoot = _private->coreFrame->selection()->rootEditableElement();
       
   727     Element* scope = selectionRoot ? selectionRoot : _private->coreFrame->document()->documentElement();
       
   728     
       
   729     // Mouse events may cause TSM to attempt to create an NSRange for a portion of the view
       
   730     // that is not inside the current editable region.  These checks ensure we don't produce
       
   731     // potentially invalid data when responding to such requests.
       
   732     if (range->startContainer() != scope && !range->startContainer()->isDescendantOf(scope))
       
   733         return NSMakeRange(NSNotFound, 0);
       
   734     if (range->endContainer() != scope && !range->endContainer()->isDescendantOf(scope))
       
   735         return NSMakeRange(NSNotFound, 0);
       
   736     
       
   737     RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset());
       
   738     ASSERT(testRange->startContainer() == scope);
       
   739     int startPosition = TextIterator::rangeLength(testRange.get());
       
   740 
       
   741     ExceptionCode ec;
       
   742     testRange->setEnd(range->endContainer(), range->endOffset(), ec);
       
   743     ASSERT(testRange->startContainer() == scope);
       
   744     int endPosition = TextIterator::rangeLength(testRange.get());
       
   745 
       
   746     return NSMakeRange(startPosition, endPosition - startPosition);
       
   747 }
       
   748 
       
   749 - (PassRefPtr<Range>)_convertToDOMRange:(NSRange)nsrange
       
   750 {
       
   751     if (nsrange.location > INT_MAX)
       
   752         return 0;
       
   753     if (nsrange.length > INT_MAX || nsrange.location + nsrange.length > INT_MAX)
       
   754         nsrange.length = INT_MAX - nsrange.location;
       
   755 
       
   756     // our critical assumption is that we are only called by input methods that
       
   757     // concentrate on a given area containing the selection
       
   758     // We have to do this because of text fields and textareas. The DOM for those is not
       
   759     // directly in the document DOM, so serialization is problematic. Our solution is
       
   760     // to use the root editable element of the selection start as the positional base.
       
   761     // That fits with AppKit's idea of an input context.
       
   762     Element* selectionRoot = _private->coreFrame->selection()->rootEditableElement();
       
   763     Element* scope = selectionRoot ? selectionRoot : _private->coreFrame->document()->documentElement();
       
   764     return TextIterator::rangeFromLocationAndLength(scope, nsrange.location, nsrange.length);
       
   765 }
       
   766 
       
   767 - (DOMRange *)convertNSRangeToDOMRange:(NSRange)nsrange
       
   768 {
       
   769     // This method exists to maintain compatibility with Leopard's Dictionary.app. <rdar://problem/6002160>
       
   770     return [self _convertNSRangeToDOMRange:nsrange];
       
   771 }
       
   772 
       
   773 - (DOMRange *)_convertNSRangeToDOMRange:(NSRange)nsrange
       
   774 {
       
   775     return kit([self _convertToDOMRange:nsrange].get());
       
   776 }
       
   777 
       
   778 - (NSRange)convertDOMRangeToNSRange:(DOMRange *)range
       
   779 {
       
   780     // This method exists to maintain compatibility with Leopard's Dictionary.app. <rdar://problem/6002160>
       
   781     return [self _convertDOMRangeToNSRange:range];
       
   782 }
       
   783 
       
   784 - (NSRange)_convertDOMRangeToNSRange:(DOMRange *)range
       
   785 {
       
   786     return [self _convertToNSRange:core(range)];
       
   787 }
       
   788 
       
   789 - (DOMRange *)_markDOMRange
       
   790 {
       
   791     return kit(_private->coreFrame->mark().toNormalizedRange().get());
       
   792 }
       
   793 
       
   794 // Given proposedRange, returns an extended range that includes adjacent whitespace that should
       
   795 // be deleted along with the proposed range in order to preserve proper spacing and punctuation of
       
   796 // the text surrounding the deletion.
       
   797 - (DOMRange *)_smartDeleteRangeForProposedRange:(DOMRange *)proposedRange
       
   798 {
       
   799     Node* startContainer = core([proposedRange startContainer]);
       
   800     Node* endContainer = core([proposedRange endContainer]);
       
   801     if (startContainer == nil || endContainer == nil)
       
   802         return nil;
       
   803 
       
   804     ASSERT(startContainer->document() == endContainer->document());
       
   805     
       
   806     _private->coreFrame->document()->updateLayoutIgnorePendingStylesheets();
       
   807 
       
   808     Position start(startContainer, [proposedRange startOffset]);
       
   809     Position end(endContainer, [proposedRange endOffset]);
       
   810     Position newStart = start.upstream().leadingWhitespacePosition(DOWNSTREAM, true);
       
   811     if (newStart.isNull())
       
   812         newStart = start;
       
   813     Position newEnd = end.downstream().trailingWhitespacePosition(DOWNSTREAM, true);
       
   814     if (newEnd.isNull())
       
   815         newEnd = end;
       
   816 
       
   817     newStart = rangeCompliantEquivalent(newStart);
       
   818     newEnd = rangeCompliantEquivalent(newEnd);
       
   819 
       
   820     RefPtr<Range> range = _private->coreFrame->document()->createRange();
       
   821     int exception = 0;
       
   822     range->setStart(newStart.node(), newStart.deprecatedEditingOffset(), exception);
       
   823     range->setEnd(newStart.node(), newStart.deprecatedEditingOffset(), exception);
       
   824     return kit(range.get());
       
   825 }
       
   826 
       
   827 // Determines whether whitespace needs to be added around aString to preserve proper spacing and
       
   828 // punctuation when it’s inserted into the receiver’s text over charRange. Returns by reference
       
   829 // in beforeString and afterString any whitespace that should be added, unless either or both are
       
   830 // nil. Both are returned as nil if aString is nil or if smart insertion and deletion are disabled.
       
   831 - (void)_smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)rangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString
       
   832 {
       
   833     // give back nil pointers in case of early returns
       
   834     if (beforeString)
       
   835         *beforeString = nil;
       
   836     if (afterString)
       
   837         *afterString = nil;
       
   838         
       
   839     // inspect destination
       
   840     Node *startContainer = core([rangeToReplace startContainer]);
       
   841     Node *endContainer = core([rangeToReplace endContainer]);
       
   842 
       
   843     Position startPos(startContainer, [rangeToReplace startOffset]);
       
   844     Position endPos(endContainer, [rangeToReplace endOffset]);
       
   845 
       
   846     VisiblePosition startVisiblePos = VisiblePosition(startPos, VP_DEFAULT_AFFINITY);
       
   847     VisiblePosition endVisiblePos = VisiblePosition(endPos, VP_DEFAULT_AFFINITY);
       
   848     
       
   849     // this check also ensures startContainer, startPos, endContainer, and endPos are non-null
       
   850     if (startVisiblePos.isNull() || endVisiblePos.isNull())
       
   851         return;
       
   852 
       
   853     bool addLeadingSpace = startPos.leadingWhitespacePosition(VP_DEFAULT_AFFINITY, true).isNull() && !isStartOfParagraph(startVisiblePos);
       
   854     if (addLeadingSpace)
       
   855         if (UChar previousChar = startVisiblePos.previous().characterAfter())
       
   856             addLeadingSpace = !isCharacterSmartReplaceExempt(previousChar, true);
       
   857     
       
   858     bool addTrailingSpace = endPos.trailingWhitespacePosition(VP_DEFAULT_AFFINITY, true).isNull() && !isEndOfParagraph(endVisiblePos);
       
   859     if (addTrailingSpace)
       
   860         if (UChar thisChar = endVisiblePos.characterAfter())
       
   861             addTrailingSpace = !isCharacterSmartReplaceExempt(thisChar, false);
       
   862     
       
   863     // inspect source
       
   864     bool hasWhitespaceAtStart = false;
       
   865     bool hasWhitespaceAtEnd = false;
       
   866     unsigned pasteLength = [pasteString length];
       
   867     if (pasteLength > 0) {
       
   868         NSCharacterSet *whiteSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
       
   869         
       
   870         if ([whiteSet characterIsMember:[pasteString characterAtIndex:0]]) {
       
   871             hasWhitespaceAtStart = YES;
       
   872         }
       
   873         if ([whiteSet characterIsMember:[pasteString characterAtIndex:(pasteLength - 1)]]) {
       
   874             hasWhitespaceAtEnd = YES;
       
   875         }
       
   876     }
       
   877     
       
   878     // issue the verdict
       
   879     if (beforeString && addLeadingSpace && !hasWhitespaceAtStart)
       
   880         *beforeString = @" ";
       
   881     if (afterString && addTrailingSpace && !hasWhitespaceAtEnd)
       
   882         *afterString = @" ";
       
   883 }
       
   884 
       
   885 - (DOMDocumentFragment *)_documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString 
       
   886 {
       
   887     if (!_private->coreFrame || !_private->coreFrame->document())
       
   888         return nil;
       
   889 
       
   890     return kit(createFragmentFromMarkup(_private->coreFrame->document(), markupString, baseURLString, FragmentScriptingNotAllowed).get());
       
   891 }
       
   892 
       
   893 - (DOMDocumentFragment *)_documentFragmentWithNodesAsParagraphs:(NSArray *)nodes
       
   894 {
       
   895     if (!_private->coreFrame || !_private->coreFrame->document())
       
   896         return nil;
       
   897     
       
   898     NSEnumerator *nodeEnum = [nodes objectEnumerator];
       
   899     Vector<Node*> nodesVector;
       
   900     DOMNode *node;
       
   901     while ((node = [nodeEnum nextObject]))
       
   902         nodesVector.append(core(node));
       
   903     
       
   904     return kit(createFragmentFromNodes(_private->coreFrame->document(), nodesVector).get());
       
   905 }
       
   906 
       
   907 - (void)_replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle
       
   908 {
       
   909     DOMDocumentFragment *fragment = kit(_private->coreFrame->document()->createDocumentFragment().get());
       
   910     [fragment appendChild:node];
       
   911     [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:matchStyle];
       
   912 }
       
   913 
       
   914 - (void)_insertParagraphSeparatorInQuotedContent
       
   915 {
       
   916     if (_private->coreFrame->selection()->isNone())
       
   917         return;
       
   918     
       
   919     TypingCommand::insertParagraphSeparatorInQuotedContent(_private->coreFrame->document());
       
   920     _private->coreFrame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
       
   921 }
       
   922 
       
   923 - (VisiblePosition)_visiblePositionForPoint:(NSPoint)point
       
   924 {
       
   925     // FIXME: Someone with access to Apple's sources could remove this needless wrapper call.
       
   926     return _private->coreFrame->visiblePositionForPoint(IntPoint(point));
       
   927 }
       
   928 
       
   929 - (DOMRange *)_characterRangeAtPoint:(NSPoint)point
       
   930 {
       
   931     VisiblePosition position = [self _visiblePositionForPoint:point];
       
   932     if (position.isNull())
       
   933         return nil;
       
   934     
       
   935     VisiblePosition previous = position.previous();
       
   936     if (previous.isNotNull()) {
       
   937         DOMRange *previousCharacterRange = kit(makeRange(previous, position).get());
       
   938         NSRect rect = [self _firstRectForDOMRange:previousCharacterRange];
       
   939         if (NSPointInRect(point, rect))
       
   940             return previousCharacterRange;
       
   941     }
       
   942 
       
   943     VisiblePosition next = position.next();
       
   944     if (next.isNotNull()) {
       
   945         DOMRange *nextCharacterRange = kit(makeRange(position, next).get());
       
   946         NSRect rect = [self _firstRectForDOMRange:nextCharacterRange];
       
   947         if (NSPointInRect(point, rect))
       
   948             return nextCharacterRange;
       
   949     }
       
   950     
       
   951     return nil;
       
   952 }
       
   953 
       
   954 - (DOMCSSStyleDeclaration *)_typingStyle
       
   955 {
       
   956     if (!_private->coreFrame || !_private->coreFrame->typingStyle())
       
   957         return nil;
       
   958     return kit(_private->coreFrame->typingStyle()->copy().get());
       
   959 }
       
   960 
       
   961 - (void)_setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(EditAction)undoAction
       
   962 {
       
   963     if (!_private->coreFrame)
       
   964         return;
       
   965     _private->coreFrame->computeAndSetTypingStyle(core(style), undoAction);
       
   966 }
       
   967 
       
   968 - (void)_dragSourceEndedAt:(NSPoint)windowLoc operation:(NSDragOperation)operation
       
   969 {
       
   970     if (!_private->coreFrame)
       
   971         return;
       
   972     FrameView* view = _private->coreFrame->view();
       
   973     if (!view)
       
   974         return;
       
   975     ASSERT([getWebView(self) _usesDocumentViews]);
       
   976     // FIXME: These are fake modifier keys here, but they should be real ones instead.
       
   977     PlatformMouseEvent event(IntPoint(windowLoc), globalPoint(windowLoc, [view->platformWidget() window]),
       
   978         LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime());
       
   979     _private->coreFrame->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation);
       
   980 }
       
   981 
       
   982 - (BOOL)_canProvideDocumentSource
       
   983 {
       
   984     Frame* frame = _private->coreFrame;
       
   985     String mimeType = frame->loader()->writer()->mimeType();
       
   986     PluginData* pluginData = frame->page() ? frame->page()->pluginData() : 0;
       
   987 
       
   988     if (WebCore::DOMImplementation::isTextMIMEType(mimeType) ||
       
   989         Image::supportsType(mimeType) ||
       
   990         (pluginData && pluginData->supportsMimeType(mimeType)))
       
   991         return NO;
       
   992 
       
   993     return YES;
       
   994 }
       
   995 
       
   996 - (BOOL)_canSaveAsWebArchive
       
   997 {
       
   998     // Currently, all documents that we can view source for
       
   999     // (HTML and XML documents) can also be saved as web archives
       
  1000     return [self _canProvideDocumentSource];
       
  1001 }
       
  1002 
       
  1003 - (void)_receivedData:(NSData *)data textEncodingName:(NSString *)textEncodingName
       
  1004 {
       
  1005     // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
       
  1006     String encoding = _private->coreFrame->loader()->documentLoader()->overrideEncoding();
       
  1007     bool userChosen = !encoding.isNull();
       
  1008     if (encoding.isNull())
       
  1009         encoding = textEncodingName;
       
  1010     _private->coreFrame->loader()->writer()->setEncoding(encoding, userChosen);
       
  1011     [self _addData:data];
       
  1012 }
       
  1013 
       
  1014 @end
       
  1015 
       
  1016 @implementation WebFrame (WebPrivate)
       
  1017 
       
  1018 // FIXME: This exists only as a convenience for Safari, consider moving there.
       
  1019 - (BOOL)_isDescendantOfFrame:(WebFrame *)ancestor
       
  1020 {
       
  1021     Frame* coreFrame = _private->coreFrame;
       
  1022     return coreFrame && coreFrame->tree()->isDescendantOf(core(ancestor));
       
  1023 }
       
  1024 
       
  1025 - (void)_setShouldCreateRenderers:(BOOL)shouldCreateRenderers
       
  1026 {
       
  1027     _private->shouldCreateRenderers = shouldCreateRenderers;
       
  1028 }
       
  1029 
       
  1030 - (NSColor *)_bodyBackgroundColor
       
  1031 {
       
  1032     Document* document = _private->coreFrame->document();
       
  1033     if (!document)
       
  1034         return nil;
       
  1035     HTMLElement* body = document->body();
       
  1036     if (!body)
       
  1037         return nil;
       
  1038     RenderObject* bodyRenderer = body->renderer();
       
  1039     if (!bodyRenderer)
       
  1040         return nil;
       
  1041     Color color = bodyRenderer->style()->visitedDependentColor(CSSPropertyBackgroundColor);
       
  1042     if (!color.isValid())
       
  1043         return nil;
       
  1044     return nsColor(color);
       
  1045 }
       
  1046 
       
  1047 - (BOOL)_isFrameSet
       
  1048 {
       
  1049     Document* document = _private->coreFrame->document();
       
  1050     return document && document->isFrameSet();
       
  1051 }
       
  1052 
       
  1053 - (BOOL)_firstLayoutDone
       
  1054 {
       
  1055     return _private->coreFrame->loader()->stateMachine()->firstLayoutDone();
       
  1056 }
       
  1057 
       
  1058 - (WebFrameLoadType)_loadType
       
  1059 {
       
  1060     return (WebFrameLoadType)_private->coreFrame->loader()->loadType();
       
  1061 }
       
  1062 
       
  1063 - (NSRange)_selectedNSRange
       
  1064 {
       
  1065     return [self _convertToNSRange:_private->coreFrame->selection()->toNormalizedRange().get()];
       
  1066 }
       
  1067 
       
  1068 - (void)_selectNSRange:(NSRange)range
       
  1069 {
       
  1070     RefPtr<Range> domRange = [self _convertToDOMRange:range];
       
  1071     if (domRange)
       
  1072         _private->coreFrame->selection()->setSelection(VisibleSelection(domRange.get(), SEL_DEFAULT_AFFINITY));
       
  1073 }
       
  1074 
       
  1075 - (BOOL)_isDisplayingStandaloneImage
       
  1076 {
       
  1077     Document* document = _private->coreFrame->document();
       
  1078     return document && document->isImageDocument();
       
  1079 }
       
  1080 
       
  1081 - (unsigned)_pendingFrameUnloadEventCount
       
  1082 {
       
  1083     return _private->coreFrame->domWindow()->pendingUnloadEventListeners();
       
  1084 }
       
  1085 
       
  1086 - (WebIconFetcher *)fetchApplicationIcon:(id)target
       
  1087                                 selector:(SEL)selector
       
  1088 {
       
  1089     return [WebIconFetcher _fetchApplicationIconForFrame:self
       
  1090                                                   target:target
       
  1091                                                 selector:selector];
       
  1092 }
       
  1093 
       
  1094 - (void)_setIsDisconnected:(bool)isDisconnected
       
  1095 {
       
  1096     _private->coreFrame->setIsDisconnected(isDisconnected);
       
  1097 }
       
  1098 
       
  1099 - (void)_setExcludeFromTextSearch:(bool)exclude
       
  1100 {
       
  1101     _private->coreFrame->setExcludeFromTextSearch(exclude);
       
  1102 }
       
  1103 
       
  1104 #if ENABLE(NETSCAPE_PLUGIN_API)
       
  1105 - (void)_recursive_resumeNullEventsForAllNetscapePlugins
       
  1106 {
       
  1107     Frame* coreFrame = core(self);
       
  1108     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
  1109         NSView <WebDocumentView> *documentView = [[kit(frame) frameView] documentView];
       
  1110         if ([documentView isKindOfClass:[WebHTMLView class]])
       
  1111             [(WebHTMLView *)documentView _resumeNullEventsForAllNetscapePlugins];
       
  1112     }
       
  1113 }
       
  1114 
       
  1115 - (void)_recursive_pauseNullEventsForAllNetscapePlugins
       
  1116 {
       
  1117     Frame* coreFrame = core(self);
       
  1118     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
  1119         NSView <WebDocumentView> *documentView = [[kit(frame) frameView] documentView];
       
  1120         if ([documentView isKindOfClass:[WebHTMLView class]])
       
  1121             [(WebHTMLView *)documentView _pauseNullEventsForAllNetscapePlugins];
       
  1122     }
       
  1123 }
       
  1124 #endif
       
  1125 
       
  1126 - (BOOL)_pauseAnimation:(NSString*)name onNode:(DOMNode *)node atTime:(NSTimeInterval)time
       
  1127 {
       
  1128     Frame* frame = core(self);
       
  1129     if (!frame)
       
  1130         return false;
       
  1131 
       
  1132     AnimationController* controller = frame->animation();
       
  1133     if (!controller)
       
  1134         return false;
       
  1135 
       
  1136     Node* coreNode = core(node);
       
  1137     if (!coreNode || !coreNode->renderer())
       
  1138         return false;
       
  1139 
       
  1140     return controller->pauseAnimationAtTime(coreNode->renderer(), name, time);
       
  1141 }
       
  1142 
       
  1143 - (BOOL)_pauseTransitionOfProperty:(NSString*)name onNode:(DOMNode*)node atTime:(NSTimeInterval)time
       
  1144 {
       
  1145     Frame* frame = core(self);
       
  1146     if (!frame)
       
  1147         return false;
       
  1148 
       
  1149     AnimationController* controller = frame->animation();
       
  1150     if (!controller)
       
  1151         return false;
       
  1152 
       
  1153     Node* coreNode = core(node);
       
  1154     if (!coreNode || !coreNode->renderer())
       
  1155         return false;
       
  1156 
       
  1157     return controller->pauseTransitionAtTime(coreNode->renderer(), name, time);
       
  1158 }
       
  1159 
       
  1160 // Pause a given SVG animation on the target node at a specific time.
       
  1161 // This method is only intended to be used for testing the SVG animation system.
       
  1162 - (BOOL)_pauseSVGAnimation:(NSString*)elementId onSMILNode:(DOMNode *)node atTime:(NSTimeInterval)time
       
  1163 {
       
  1164     Frame* frame = core(self);
       
  1165     if (!frame)
       
  1166         return false;
       
  1167  
       
  1168     Document* document = frame->document();
       
  1169     if (!document || !document->svgExtensions())
       
  1170         return false;
       
  1171 
       
  1172     Node* coreNode = core(node);
       
  1173     if (!coreNode || !SVGSMILElement::isSMILElement(coreNode))
       
  1174         return false;
       
  1175 
       
  1176 #if ENABLE(SVG)
       
  1177     return document->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreNode), time);
       
  1178 #else
       
  1179     return false;
       
  1180 #endif
       
  1181 }
       
  1182 
       
  1183 - (unsigned) _numberOfActiveAnimations
       
  1184 {
       
  1185     Frame* frame = core(self);
       
  1186     if (!frame)
       
  1187         return false;
       
  1188 
       
  1189     AnimationController* controller = frame->animation();
       
  1190     if (!controller)
       
  1191         return false;
       
  1192 
       
  1193     return controller->numberOfActiveAnimations();
       
  1194 }
       
  1195 
       
  1196 - (void)_replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle
       
  1197 {
       
  1198     if (_private->coreFrame->selection()->isNone() || !fragment)
       
  1199         return;
       
  1200     
       
  1201     applyCommand(ReplaceSelectionCommand::create(_private->coreFrame->document(), core(fragment), selectReplacement, smartReplace, matchStyle));
       
  1202     _private->coreFrame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
       
  1203 }
       
  1204 
       
  1205 - (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
       
  1206 {   
       
  1207     DOMDocumentFragment* fragment = kit(createFragmentFromText(_private->coreFrame->selection()->toNormalizedRange().get(), text).get());
       
  1208     [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:YES];
       
  1209 }
       
  1210 
       
  1211 - (void)_replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
       
  1212 {
       
  1213     DOMDocumentFragment *fragment = [self _documentFragmentWithMarkupString:markupString baseURLString:baseURLString];
       
  1214     [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:NO];
       
  1215 }
       
  1216 
       
  1217 - (NSMutableDictionary *)_cacheabilityDictionary
       
  1218 {
       
  1219     NSMutableDictionary *result = [NSMutableDictionary dictionary];
       
  1220     
       
  1221     FrameLoader* frameLoader = _private->coreFrame->loader();
       
  1222     DocumentLoader* documentLoader = frameLoader->documentLoader();
       
  1223     if (documentLoader && !documentLoader->mainDocumentError().isNull())
       
  1224         [result setObject:(NSError *)documentLoader->mainDocumentError() forKey:WebFrameMainDocumentError];
       
  1225         
       
  1226     if (frameLoader->subframeLoader()->containsPlugins())
       
  1227         [result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameHasPlugins];
       
  1228     
       
  1229     if (DOMWindow* domWindow = _private->coreFrame->domWindow()) {
       
  1230         if (domWindow->hasEventListeners(eventNames().unloadEvent))
       
  1231             [result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameHasUnloadListener];
       
  1232             
       
  1233 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
       
  1234         if (domWindow->optionalApplicationCache())
       
  1235             [result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameUsesApplicationCache];
       
  1236 #endif
       
  1237     }
       
  1238     
       
  1239     if (Document* document = _private->coreFrame->document()) {
       
  1240 #if ENABLE(DATABASE)
       
  1241         if (document->hasOpenDatabases())
       
  1242             [result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameUsesDatabases];
       
  1243 #endif
       
  1244             
       
  1245         if (document->usingGeolocation())
       
  1246             [result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameUsesGeolocation];
       
  1247             
       
  1248         if (!document->canSuspendActiveDOMObjects())
       
  1249             [result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameCanSuspendActiveDOMObjects];
       
  1250     }
       
  1251     
       
  1252     return result;
       
  1253 }
       
  1254 
       
  1255 - (BOOL)_allowsFollowingLink:(NSURL *)URL
       
  1256 {
       
  1257     if (!_private->coreFrame)
       
  1258         return YES;
       
  1259     return SecurityOrigin::canLoad(URL, String(), _private->coreFrame->document());
       
  1260 }
       
  1261 
       
  1262 - (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string withGlobalObject:(JSObjectRef)globalObjectRef inScriptWorld:(WebScriptWorld *)world
       
  1263 {
       
  1264     // Start off with some guess at a frame and a global object, we'll try to do better...!
       
  1265     JSDOMWindow* anyWorldGlobalObject = _private->coreFrame->script()->globalObject(mainThreadNormalWorld());
       
  1266 
       
  1267     // The global object is probably a shell object? - if so, we know how to use this!
       
  1268     JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
       
  1269     if (!strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell"))
       
  1270         anyWorldGlobalObject = static_cast<JSDOMWindowShell*>(globalObjectObj)->window();
       
  1271 
       
  1272     // Get the frame frome the global object we've settled on.
       
  1273     Frame* frame = anyWorldGlobalObject->impl()->frame();
       
  1274     ASSERT(frame->document());
       
  1275     JSValue result = frame->script()->executeScriptInWorld(core(world), string, true).jsValue();
       
  1276 
       
  1277     if (!frame) // In case the script removed our frame from the page.
       
  1278         return @"";
       
  1279 
       
  1280     // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
       
  1281     // If you don't like it, use -[WebScriptObject evaluateWebScript:] or 
       
  1282     // JSEvaluateScript instead, since they have less surprising semantics.
       
  1283     if (!result || !result.isBoolean() && !result.isString() && !result.isNumber())
       
  1284         return @"";
       
  1285 
       
  1286     JSLock lock(SilenceAssertionsOnly);
       
  1287     return ustringToString(result.toString(anyWorldGlobalObject->globalExec()));
       
  1288 }
       
  1289 
       
  1290 - (JSGlobalContextRef)_globalContextForScriptWorld:(WebScriptWorld *)world
       
  1291 {
       
  1292     Frame* coreFrame = _private->coreFrame;
       
  1293     if (!coreFrame)
       
  1294         return 0;
       
  1295     DOMWrapperWorld* coreWorld = core(world);
       
  1296     if (!coreWorld)
       
  1297         return 0;
       
  1298     return toGlobalRef(coreFrame->script()->globalObject(coreWorld)->globalExec());
       
  1299 }
       
  1300 
       
  1301 - (void)setAllowsScrollersToOverlapContent:(BOOL)flag
       
  1302 {
       
  1303     ASSERT([[[self frameView] _scrollView] isKindOfClass:[WebDynamicScrollBarsView class]]);
       
  1304     [(WebDynamicScrollBarsView *)[[self frameView] _scrollView] setAllowsScrollersToOverlapContent:flag];
       
  1305 }
       
  1306 
       
  1307 - (void)setAlwaysHideHorizontalScroller:(BOOL)flag
       
  1308 {
       
  1309     ASSERT([[[self frameView] _scrollView] isKindOfClass:[WebDynamicScrollBarsView class]]);
       
  1310     [(WebDynamicScrollBarsView *)[[self frameView] _scrollView] setAlwaysHideHorizontalScroller:flag];
       
  1311 }
       
  1312 - (void)setAlwaysHideVerticalScroller:(BOOL)flag
       
  1313 {
       
  1314     ASSERT([[[self frameView] _scrollView] isKindOfClass:[WebDynamicScrollBarsView class]]);
       
  1315     [(WebDynamicScrollBarsView *)[[self frameView] _scrollView] setAlwaysHideVerticalScroller:flag];
       
  1316 }
       
  1317 
       
  1318 - (void)setAccessibleName:(NSString *)name
       
  1319 {
       
  1320 #if HAVE(ACCESSIBILITY)
       
  1321     if (!AXObjectCache::accessibilityEnabled())
       
  1322         return;
       
  1323     
       
  1324     RenderView* root = toRenderView(_private->coreFrame->document()->renderer());
       
  1325     if (!root)
       
  1326         return;
       
  1327     
       
  1328     AccessibilityObject* rootObject = _private->coreFrame->document()->axObjectCache()->getOrCreate(root);
       
  1329     String strName(name);
       
  1330     rootObject->setAccessibleName(strName);
       
  1331 #endif
       
  1332 }
       
  1333 
       
  1334 - (NSString*)_layerTreeAsText
       
  1335 {
       
  1336     Frame* coreFrame = _private->coreFrame;
       
  1337     if (!coreFrame)
       
  1338         return @"";
       
  1339 
       
  1340     return coreFrame->layerTreeAsText();
       
  1341 }
       
  1342 
       
  1343 @end
       
  1344 
       
  1345 @implementation WebFrame
       
  1346 
       
  1347 - (id)init
       
  1348 {
       
  1349     return nil;
       
  1350 }
       
  1351 
       
  1352 // Should be deprecated.
       
  1353 - (id)initWithName:(NSString *)name webFrameView:(WebFrameView *)view webView:(WebView *)webView
       
  1354 {
       
  1355     return nil;
       
  1356 }
       
  1357 
       
  1358 - (void)dealloc
       
  1359 {
       
  1360     if (_private && _private->includedInWebKitStatistics)
       
  1361         --WebFrameCount;
       
  1362 
       
  1363     [_private release];
       
  1364 
       
  1365     [super dealloc];
       
  1366 }
       
  1367 
       
  1368 - (void)finalize
       
  1369 {
       
  1370     if (_private && _private->includedInWebKitStatistics)
       
  1371         --WebFrameCount;
       
  1372 
       
  1373     [super finalize];
       
  1374 }
       
  1375 
       
  1376 - (NSString *)name
       
  1377 {
       
  1378     Frame* coreFrame = _private->coreFrame;
       
  1379     if (!coreFrame)
       
  1380         return nil;
       
  1381     return coreFrame->tree()->name();
       
  1382 }
       
  1383 
       
  1384 - (WebFrameView *)frameView
       
  1385 {
       
  1386     ASSERT(!getWebView(self) || [getWebView(self) _usesDocumentViews]);
       
  1387     return _private->webFrameView;
       
  1388 }
       
  1389 
       
  1390 - (WebView *)webView
       
  1391 {
       
  1392     return getWebView(self);
       
  1393 }
       
  1394 
       
  1395 static bool needsMicrosoftMessengerDOMDocumentWorkaround()
       
  1396 {
       
  1397     static bool needsWorkaround = applicationIsMicrosoftMessenger() && [[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey] compare:@"7.1" options:NSNumericSearch] == NSOrderedAscending;
       
  1398     return needsWorkaround;
       
  1399 }
       
  1400 
       
  1401 - (DOMDocument *)DOMDocument
       
  1402 {
       
  1403     if (needsMicrosoftMessengerDOMDocumentWorkaround() && !pthread_main_np())
       
  1404         return nil;
       
  1405 
       
  1406     Frame* coreFrame = _private->coreFrame;
       
  1407     if (!coreFrame)
       
  1408         return nil;
       
  1409     
       
  1410     // FIXME: <rdar://problem/5145841> When loading a custom view/representation 
       
  1411     // into a web frame, the old document can still be around. This makes sure that
       
  1412     // we'll return nil in those cases.
       
  1413     if (![[self _dataSource] _isDocumentHTML]) 
       
  1414         return nil; 
       
  1415 
       
  1416     Document* document = coreFrame->document();
       
  1417     
       
  1418     // According to the documentation, we should return nil if the frame doesn't have a document.
       
  1419     // While full-frame images and plugins do have an underlying HTML document, we return nil here to be
       
  1420     // backwards compatible.
       
  1421     if (document && (document->isPluginDocument() || document->isImageDocument()))
       
  1422         return nil;
       
  1423     
       
  1424     return kit(coreFrame->document());
       
  1425 }
       
  1426 
       
  1427 - (DOMHTMLElement *)frameElement
       
  1428 {
       
  1429     Frame* coreFrame = _private->coreFrame;
       
  1430     if (!coreFrame)
       
  1431         return nil;
       
  1432     return kit(coreFrame->ownerElement());
       
  1433 }
       
  1434 
       
  1435 - (WebDataSource *)provisionalDataSource
       
  1436 {
       
  1437     Frame* coreFrame = _private->coreFrame;
       
  1438     return coreFrame ? dataSource(coreFrame->loader()->provisionalDocumentLoader()) : nil;
       
  1439 }
       
  1440 
       
  1441 - (WebDataSource *)dataSource
       
  1442 {
       
  1443     Frame* coreFrame = _private->coreFrame;
       
  1444     return coreFrame && coreFrame->loader()->frameHasLoaded() ? [self _dataSource] : nil;
       
  1445 }
       
  1446 
       
  1447 - (void)loadRequest:(NSURLRequest *)request
       
  1448 {
       
  1449     Frame* coreFrame = _private->coreFrame;
       
  1450     if (!coreFrame)
       
  1451         return;
       
  1452     coreFrame->loader()->load(request, false);
       
  1453 }
       
  1454 
       
  1455 static NSURL *createUniqueWebDataURL()
       
  1456 {
       
  1457     CFUUIDRef UUIDRef = CFUUIDCreate(kCFAllocatorDefault);
       
  1458     NSString *UUIDString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, UUIDRef);
       
  1459     CFRelease(UUIDRef);
       
  1460     NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"applewebdata://%@", UUIDString]];
       
  1461     CFRelease(UUIDString);
       
  1462     return URL;
       
  1463 }
       
  1464 
       
  1465 - (void)_loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL unreachableURL:(NSURL *)unreachableURL
       
  1466 {
       
  1467     if (!pthread_main_np())
       
  1468         return [[self _webkit_invokeOnMainThread] _loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:baseURL unreachableURL:unreachableURL];
       
  1469     
       
  1470     KURL responseURL;
       
  1471     if (!baseURL) {
       
  1472         baseURL = blankURL();
       
  1473         responseURL = createUniqueWebDataURL();
       
  1474     }
       
  1475     
       
  1476     ResourceRequest request([baseURL absoluteURL]);
       
  1477 
       
  1478     // hack because Mail checks for this property to detect data / archive loads
       
  1479     [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)request.nsURLRequest()];
       
  1480 
       
  1481     SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData(data), MIMEType, encodingName, [unreachableURL absoluteURL], responseURL);
       
  1482 
       
  1483     _private->coreFrame->loader()->load(request, substituteData, false);
       
  1484 }
       
  1485 
       
  1486 
       
  1487 - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL
       
  1488 {
       
  1489     WebCoreThreadViolationCheckRoundTwo();
       
  1490     
       
  1491     if (!MIMEType)
       
  1492         MIMEType = @"text/html";
       
  1493     [self _loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:baseURL unreachableURL:nil];
       
  1494 }
       
  1495 
       
  1496 - (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL unreachableURL:(NSURL *)unreachableURL
       
  1497 {
       
  1498     NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
       
  1499     [self _loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:baseURL unreachableURL:unreachableURL];
       
  1500 }
       
  1501 
       
  1502 - (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL
       
  1503 {
       
  1504     WebCoreThreadViolationCheckRoundTwo();
       
  1505 
       
  1506     [self _loadHTMLString:string baseURL:baseURL unreachableURL:nil];
       
  1507 }
       
  1508 
       
  1509 - (void)loadAlternateHTMLString:(NSString *)string baseURL:(NSURL *)baseURL forUnreachableURL:(NSURL *)unreachableURL
       
  1510 {
       
  1511     WebCoreThreadViolationCheckRoundTwo();
       
  1512 
       
  1513     [self _loadHTMLString:string baseURL:baseURL unreachableURL:unreachableURL];
       
  1514 }
       
  1515 
       
  1516 - (void)loadArchive:(WebArchive *)archive
       
  1517 {
       
  1518     if (LegacyWebArchive* coreArchive = [archive _coreLegacyWebArchive])
       
  1519         _private->coreFrame->loader()->loadArchive(coreArchive);
       
  1520 }
       
  1521 
       
  1522 - (void)stopLoading
       
  1523 {
       
  1524     if (!_private->coreFrame)
       
  1525         return;
       
  1526     _private->coreFrame->loader()->stopForUserCancel();
       
  1527 }
       
  1528 
       
  1529 - (void)reload
       
  1530 {
       
  1531     if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_RELOAD_FROM_ORIGIN) && applicationIsSafari())
       
  1532         _private->coreFrame->loader()->reload(GetCurrentKeyModifiers() & shiftKey);
       
  1533     else
       
  1534         _private->coreFrame->loader()->reload(false);
       
  1535 }
       
  1536 
       
  1537 - (void)reloadFromOrigin
       
  1538 {
       
  1539     _private->coreFrame->loader()->reload(true);
       
  1540 }
       
  1541 
       
  1542 - (WebFrame *)findFrameNamed:(NSString *)name
       
  1543 {
       
  1544     Frame* coreFrame = _private->coreFrame;
       
  1545     if (!coreFrame)
       
  1546         return nil;
       
  1547     return kit(coreFrame->tree()->find(name));
       
  1548 }
       
  1549 
       
  1550 - (WebFrame *)parentFrame
       
  1551 {
       
  1552     Frame* coreFrame = _private->coreFrame;
       
  1553     if (!coreFrame)
       
  1554         return nil;
       
  1555     return [[kit(coreFrame->tree()->parent()) retain] autorelease];
       
  1556 }
       
  1557 
       
  1558 - (NSArray *)childFrames
       
  1559 {
       
  1560     Frame* coreFrame = _private->coreFrame;
       
  1561     if (!coreFrame)
       
  1562         return [NSArray array];
       
  1563     NSMutableArray *children = [NSMutableArray arrayWithCapacity:coreFrame->tree()->childCount()];
       
  1564     for (Frame* child = coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling())
       
  1565         [children addObject:kit(child)];
       
  1566     return children;
       
  1567 }
       
  1568 
       
  1569 - (WebScriptObject *)windowObject
       
  1570 {
       
  1571     Frame* coreFrame = _private->coreFrame;
       
  1572     if (!coreFrame)
       
  1573         return 0;
       
  1574     return coreFrame->script()->windowScriptObject();
       
  1575 }
       
  1576 
       
  1577 - (JSGlobalContextRef)globalContext
       
  1578 {
       
  1579     Frame* coreFrame = _private->coreFrame;
       
  1580     if (!coreFrame)
       
  1581         return 0;
       
  1582     return toGlobalRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
       
  1583 }
       
  1584 
       
  1585 @end