webengine/osswebengine/WebKit/WebView/WebFrame.mm
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  * Copyright (C) 2005, 2006 Apple Computer, 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 "DOMDocumentInternal.h"
       
    33 #import "DOMElementInternal.h"
       
    34 #import "DOMHTMLElementInternal.h"
       
    35 #import "DOMNodeInternal.h"
       
    36 #import "DOMRangeInternal.h"
       
    37 #import "WebBackForwardList.h"
       
    38 #import "WebChromeClient.h"
       
    39 #import "WebDataSourceInternal.h"
       
    40 #import "WebDocumentInternal.h"
       
    41 #import "WebDocumentLoaderMac.h"
       
    42 #import "WebFrameBridge.h"
       
    43 #import "WebFrameLoadDelegate.h"
       
    44 #import "WebFrameLoaderClient.h"
       
    45 #import "WebFrameViewInternal.h"
       
    46 #import "WebHTMLViewInternal.h"
       
    47 #import "WebHistoryItem.h"
       
    48 #import "WebHistoryItemInternal.h"
       
    49 #import "WebHistoryItemPrivate.h"
       
    50 #import "WebKitLogging.h"
       
    51 #import "WebKitStatisticsPrivate.h"
       
    52 #import "WebNSURLExtras.h"
       
    53 #import "WebNSURLRequestExtras.h"
       
    54 #import "WebNetscapePluginEmbeddedView.h"
       
    55 #import "WebNullPluginView.h"
       
    56 #import "WebPlugin.h"
       
    57 #import "WebPluginController.h"
       
    58 #import "WebPreferencesPrivate.h"
       
    59 #import "WebScriptDebugDelegatePrivate.h"
       
    60 #import "WebViewInternal.h"
       
    61 #import <WebCore/Chrome.h>
       
    62 #import <WebCore/ColorMac.h>
       
    63 #import <WebCore/Document.h>
       
    64 #import <WebCore/Event.h>
       
    65 #import <WebCore/FrameLoader.h>
       
    66 #import <WebCore/Frame.h>
       
    67 #import <WebCore/FrameTree.h>
       
    68 #import <WebCore/HistoryItem.h>
       
    69 #import <WebCore/HTMLFormElement.h>
       
    70 #import <WebCore/HTMLFrameOwnerElement.h>
       
    71 #import <WebCore/Page.h>
       
    72 #import <WebCore/SelectionController.h>
       
    73 #import <WebCore/SharedBuffer.h>
       
    74 #import <WebCore/FormState.h>
       
    75 #import <WebCore/ResourceRequest.h>
       
    76 #import <WebCore/kjs_binding.h>
       
    77 #import <WebCore/kjs_proxy.h>
       
    78 #import <WebKit/DOMDocument.h>
       
    79 #import <WebKit/DOMElement.h>
       
    80 #import <WebKit/DOMHTMLElement.h>
       
    81 #import <WebKit/DOMNode.h>
       
    82 #import <WebKit/DOMRange.h>
       
    83 
       
    84 using namespace WebCore;
       
    85 
       
    86 /*
       
    87 Here is the current behavior matrix for four types of navigations:
       
    88 
       
    89 Standard Nav:
       
    90 
       
    91  Restore form state:   YES
       
    92  Restore scroll and focus state:  YES
       
    93  Cache policy: NSURLRequestUseProtocolCachePolicy
       
    94  Add to back/forward list: YES
       
    95  
       
    96 Back/Forward:
       
    97 
       
    98  Restore form state:   YES
       
    99  Restore scroll and focus state:  YES
       
   100  Cache policy: NSURLRequestReturnCacheDataElseLoad
       
   101  Add to back/forward list: NO
       
   102 
       
   103 Reload (meaning only the reload button):
       
   104 
       
   105  Restore form state:   NO
       
   106  Restore scroll and focus state:  YES
       
   107  Cache policy: NSURLRequestReloadIgnoringCacheData
       
   108  Add to back/forward list: NO
       
   109 
       
   110 Repeat load of the same URL (by any other means of navigation other than the reload button, including hitting return in the location field):
       
   111 
       
   112  Restore form state:   NO
       
   113  Restore scroll and focus state:  NO, reset to initial conditions
       
   114  Cache policy: NSURLRequestReloadIgnoringCacheData
       
   115  Add to back/forward list: NO
       
   116 */
       
   117 
       
   118 using namespace WebCore;
       
   119 
       
   120 NSString *WebPageCacheEntryDateKey = @"WebPageCacheEntryDateKey";
       
   121 NSString *WebPageCacheDataSourceKey = @"WebPageCacheDataSourceKey";
       
   122 NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
       
   123 
       
   124 @interface WebFrame (ForwardDecls)
       
   125 - (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL;
       
   126 - (WebHistoryItem *)_createItem:(BOOL)useOriginal;
       
   127 - (WebHistoryItem *)_createItemTreeWithTargetFrame:(WebFrame *)targetFrame clippedAtTarget:(BOOL)doClip;
       
   128 @end
       
   129 
       
   130 @interface NSView (WebFramePluginHosting)
       
   131 - (void)setWebFrame:(WebFrame *)webFrame;
       
   132 @end
       
   133 
       
   134 @implementation WebFramePrivate
       
   135 
       
   136 - (void)dealloc
       
   137 {
       
   138     [webFrameView release];
       
   139     
       
   140     [scriptDebugger release];
       
   141 
       
   142     [super dealloc];
       
   143 }
       
   144 
       
   145 - (void)setWebFrameView:(WebFrameView *)v 
       
   146 { 
       
   147     [v retain];
       
   148     [webFrameView release];
       
   149     webFrameView = v;
       
   150 }
       
   151 
       
   152 @end
       
   153 
       
   154 CSSStyleDeclaration* core(DOMCSSStyleDeclaration *declaration)
       
   155 {
       
   156     return [declaration _CSSStyleDeclaration];
       
   157 }
       
   158 
       
   159 DOMCSSStyleDeclaration *kit(WebCore::CSSStyleDeclaration* declaration)
       
   160 {
       
   161     return [DOMCSSStyleDeclaration _wrapCSSStyleDeclaration:declaration];
       
   162 }
       
   163 
       
   164 Element* core(DOMElement *element)
       
   165 {
       
   166     return [element _element];
       
   167 }
       
   168 
       
   169 DOMElement *kit(Element* element)
       
   170 {
       
   171     return [DOMElement _wrapElement:element];
       
   172 }
       
   173 
       
   174 Node* core(DOMNode *node)
       
   175 {
       
   176     return [node _node];
       
   177 }
       
   178 
       
   179 DOMNode *kit(Node* node)
       
   180 {
       
   181     return [DOMNode _wrapNode:node];
       
   182 }
       
   183 
       
   184 DOMNode *kit(PassRefPtr<Node> node)
       
   185 {
       
   186     return [DOMNode _wrapNode:node.get()];
       
   187 }
       
   188 
       
   189 Document* core(DOMDocument *document)
       
   190 {
       
   191     return [document _document];
       
   192 }
       
   193 
       
   194 DOMDocument *kit(Document* document)
       
   195 {
       
   196     return [DOMDocument _wrapDocument:document];
       
   197 }
       
   198 
       
   199 HTMLElement* core(DOMHTMLElement *element)
       
   200 {
       
   201     return [element _HTMLElement];
       
   202 }
       
   203 
       
   204 DOMHTMLElement *kit(HTMLElement *element)
       
   205 {
       
   206     return [DOMHTMLElement _wrapHTMLElement:element];
       
   207 }
       
   208 
       
   209 Range* core(DOMRange *range)
       
   210 {
       
   211     return [range _range];
       
   212 }
       
   213 
       
   214 DOMRange *kit(Range* range)
       
   215 {
       
   216     return [DOMRange _wrapRange:range];
       
   217 }
       
   218 
       
   219 WebCore::EditableLinkBehavior core(WebKitEditableLinkBehavior editableLinkBehavior)
       
   220 {
       
   221     return static_cast<WebCore::EditableLinkBehavior>(editableLinkBehavior);
       
   222 }
       
   223 
       
   224 WebKitEditableLinkBehavior kit(WebCore::EditableLinkBehavior editableLinkBehavior)
       
   225 {
       
   226     return static_cast<WebKitEditableLinkBehavior>(editableLinkBehavior);
       
   227 }
       
   228 
       
   229 @implementation WebFrame (WebInternal)
       
   230 
       
   231 
       
   232 static inline WebFrame *frame(WebCoreFrameBridge *bridge)
       
   233 {
       
   234     return ((WebFrameBridge *)bridge)->_frame;
       
   235 }
       
   236 
       
   237 Frame* core(WebFrame *frame)
       
   238 {
       
   239     if (!frame)
       
   240         return 0;
       
   241     
       
   242     if (!frame->_private->bridge)
       
   243         return 0;
       
   244 
       
   245     return frame->_private->bridge->m_frame;
       
   246 }
       
   247 
       
   248 WebFrame *kit(Frame* frame)
       
   249 {
       
   250     return frame ? ((WebFrameBridge *)frame->bridge())->_frame : nil;
       
   251 }
       
   252 
       
   253 Page* core(WebView *webView)
       
   254 {
       
   255     return [webView page];
       
   256 }
       
   257 
       
   258 WebView *kit(Page* page)
       
   259 {
       
   260     return page ? static_cast<WebChromeClient*>(page->chrome()->client())->webView() : nil;
       
   261 }
       
   262 
       
   263 WebView *getWebView(WebFrame *webFrame)
       
   264 {
       
   265     Frame* coreFrame = core(webFrame);
       
   266     if (!coreFrame)
       
   267         return nil;
       
   268     return kit(coreFrame->page());
       
   269 }
       
   270 
       
   271 /*
       
   272     In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree.  
       
   273     The item that was the target of the user's navigation is designated as the "targetItem".  
       
   274     When this method is called with doClip=YES we're able to create the whole tree except for the target's children, 
       
   275     which will be loaded in the future.  That part of the tree will be filled out as the child loads are committed.
       
   276 */
       
   277 
       
   278 + (CFAbsoluteTime)_timeOfLastCompletedLoad
       
   279 {
       
   280     return FrameLoader::timeOfLastCompletedLoad() - kCFAbsoluteTimeIntervalSince1970;
       
   281 }
       
   282 
       
   283 - (WebFrameBridge *)_bridge
       
   284 {
       
   285     return _private->bridge;
       
   286 }
       
   287 
       
   288 - (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer intoChild:(WebFrame *)childFrame
       
   289 {
       
   290     ASSERT(childFrame);
       
   291     HistoryItem* parentItem = core(self)->loader()->currentHistoryItem();
       
   292     FrameLoadType loadType = [self _frameLoader]->loadType();
       
   293     FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
       
   294 
       
   295     // If we're moving in the backforward list, we might want to replace the content
       
   296     // of this child frame with whatever was there at that point.
       
   297     // Reload will maintain the frame contents, LoadSame will not.
       
   298     if (parentItem && parentItem->children().size() &&
       
   299         (isBackForwardLoadType(loadType)
       
   300          || loadType == FrameLoadTypeReload
       
   301          || loadType == FrameLoadTypeReloadAllowingStaleData))
       
   302     {
       
   303         HistoryItem* childItem = parentItem->childItemWithName([childFrame name]);
       
   304         if (childItem) {
       
   305             // Use the original URL to ensure we get all the side-effects, such as
       
   306             // onLoad handlers, of any redirects that happened. An example of where
       
   307             // this is needed is Radar 3213556.
       
   308             URL = [NSURL _web_URLWithDataAsString:childItem->originalURLString()];
       
   309             // These behaviors implied by these loadTypes should apply to the child frames
       
   310             childLoadType = loadType;
       
   311 
       
   312             if (isBackForwardLoadType(loadType))
       
   313                 // For back/forward, remember this item so we can traverse any child items as child frames load
       
   314                 core(childFrame)->loader()->setProvisionalHistoryItem(childItem);
       
   315             else
       
   316                 // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item
       
   317                 core(childFrame)->loader()->setCurrentHistoryItem(childItem);
       
   318         }
       
   319     }
       
   320 
       
   321     WebArchive *archive = [[self _dataSource] _popSubframeArchiveWithName:[childFrame name]];
       
   322     if (archive)
       
   323         [childFrame loadArchive:archive];
       
   324     else
       
   325         [childFrame _frameLoader]->load([URL absoluteURL], referrer, childLoadType,
       
   326                                         String(), 0, 0);
       
   327 }
       
   328 
       
   329 
       
   330 - (void)_viewWillMoveToHostWindow:(NSWindow *)hostWindow
       
   331 {
       
   332     Frame* coreFrame = core(self);
       
   333     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame))
       
   334         [[[kit(frame) frameView] documentView] viewWillMoveToHostWindow:hostWindow];
       
   335 }
       
   336 
       
   337 - (void)_viewDidMoveToHostWindow
       
   338 {
       
   339     Frame* coreFrame = core(self);
       
   340     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame))
       
   341         [[[kit(frame) frameView] documentView] viewDidMoveToHostWindow];
       
   342 }
       
   343 
       
   344 - (void)_addChild:(WebFrame *)child
       
   345 {
       
   346     core(self)->tree()->appendChild(adoptRef(core(child)));
       
   347     if ([child _dataSource])
       
   348         [[child _dataSource] _documentLoader]->setOverrideEncoding([[self _dataSource] _documentLoader]->overrideEncoding());  
       
   349 }
       
   350 
       
   351 - (int)_numPendingOrLoadingRequests:(BOOL)recurse
       
   352 {
       
   353     return core(self)->loader()->numPendingOrLoadingRequests(recurse);
       
   354 }
       
   355 
       
   356 - (void)_reloadForPluginChanges
       
   357 {
       
   358     Frame* coreFrame = core(self);
       
   359     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   360         NSView <WebDocumentView> *documentView = [[kit(frame) frameView] documentView];
       
   361         if (([documentView isKindOfClass:[WebHTMLView class]] && coreFrame->loader()->containsPlugins()))
       
   362             [kit(frame) reload];
       
   363     }
       
   364 }
       
   365 
       
   366 - (void)_attachScriptDebugger
       
   367 {
       
   368     if (!_private->scriptDebugger && core(self)->scriptProxy()->haveInterpreter())
       
   369         _private->scriptDebugger = [[WebScriptDebugger alloc] initWithWebFrame:self];
       
   370 }
       
   371 
       
   372 - (void)_detachScriptDebugger
       
   373 {
       
   374     if (_private->scriptDebugger) {
       
   375         id old = _private->scriptDebugger;
       
   376         _private->scriptDebugger = nil;
       
   377         [old release];
       
   378     }
       
   379 }
       
   380 
       
   381 - (id)_initWithWebFrameView:(WebFrameView *)fv webView:(WebView *)v bridge:(WebFrameBridge *)bridge
       
   382 {
       
   383     self = [super init];
       
   384     if (!self)
       
   385         return nil;
       
   386 
       
   387     _private = [[WebFramePrivate alloc] init];
       
   388     _private->bridge = bridge;
       
   389 
       
   390     if (fv) {
       
   391         [_private setWebFrameView:fv];
       
   392         [fv _setWebFrame:self];
       
   393     }
       
   394 
       
   395     ++WebFrameCount;
       
   396 
       
   397     return self;
       
   398 }
       
   399 
       
   400 - (NSArray *)_documentViews
       
   401 {
       
   402     NSMutableArray *result = [NSMutableArray array];
       
   403     Frame* coreFrame = core(self);
       
   404     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   405         id docView = [[kit(frame) frameView] documentView];
       
   406         if (docView)
       
   407             [result addObject:docView];
       
   408     }
       
   409     return result;
       
   410 }
       
   411 
       
   412 - (void)_updateBackground
       
   413 {
       
   414     BOOL drawsBackground = [getWebView(self) drawsBackground];
       
   415     NSColor *backgroundColor = [getWebView(self) backgroundColor];
       
   416 
       
   417     Frame* coreFrame = core(self);
       
   418     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   419         WebFrameBridge *bridge = (WebFrameBridge *)frame->bridge();
       
   420         WebFrame *webFrame = [bridge webFrame];
       
   421         // Never call setDrawsBackground:YES here on the scroll view or the background color will
       
   422         // flash between pages loads. setDrawsBackground:YES will be called in _frameLoadCompleted.
       
   423         if (!drawsBackground)
       
   424             [[[webFrame frameView] _scrollView] setDrawsBackground:NO];
       
   425         [[[webFrame frameView] _scrollView] setBackgroundColor:backgroundColor];
       
   426         id documentView = [[webFrame frameView] documentView];
       
   427         if ([documentView respondsToSelector:@selector(setDrawsBackground:)])
       
   428             [documentView setDrawsBackground:drawsBackground];
       
   429         if ([documentView respondsToSelector:@selector(setBackgroundColor:)])
       
   430             [documentView setBackgroundColor:backgroundColor];
       
   431         [bridge setDrawsBackground:drawsBackground];
       
   432         [bridge setBaseBackgroundColor:backgroundColor];
       
   433     }
       
   434 }
       
   435 
       
   436 - (void)_setInternalLoadDelegate:(id)internalLoadDelegate
       
   437 {
       
   438     _private->internalLoadDelegate = internalLoadDelegate;
       
   439 }
       
   440 
       
   441 - (id)_internalLoadDelegate
       
   442 {
       
   443     return _private->internalLoadDelegate;
       
   444 }
       
   445 
       
   446 #ifndef BUILDING_ON_TIGER
       
   447 - (void)_unmarkAllBadGrammar
       
   448 {
       
   449     Frame* coreFrame = core(self);
       
   450     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   451         Document *doc = frame->document();
       
   452         if (!doc)
       
   453             return;
       
   454 
       
   455         doc->removeMarkers(DocumentMarker::Grammar);
       
   456     }
       
   457 }
       
   458 #endif
       
   459 
       
   460 - (void)_unmarkAllMisspellings
       
   461 {
       
   462     Frame* coreFrame = core(self);
       
   463     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   464         Document *doc = frame->document();
       
   465         if (!doc)
       
   466             return;
       
   467 
       
   468         doc->removeMarkers(DocumentMarker::Spelling);
       
   469     }
       
   470 }
       
   471 
       
   472 - (BOOL)_hasSelection
       
   473 {
       
   474     id documentView = [_private->webFrameView documentView];    
       
   475 
       
   476     // optimization for common case to avoid creating potentially large selection string
       
   477     if ([documentView isKindOfClass:[WebHTMLView class]])
       
   478         if (Frame* coreFrame = core(self))
       
   479             return coreFrame->selectionController()->isRange();
       
   480 
       
   481     if ([documentView conformsToProtocol:@protocol(WebDocumentText)])
       
   482         return [[documentView selectedString] length] > 0;
       
   483     
       
   484     return NO;
       
   485 }
       
   486 
       
   487 - (void)_clearSelection
       
   488 {
       
   489     id documentView = [_private->webFrameView documentView];    
       
   490     if ([documentView conformsToProtocol:@protocol(WebDocumentText)])
       
   491         [documentView deselectAll];
       
   492 }
       
   493 
       
   494 #if !ASSERT_DISABLED
       
   495 - (BOOL)_atMostOneFrameHasSelection
       
   496 {
       
   497     // FIXME: 4186050 is one known case that makes this debug check fail.
       
   498     BOOL found = NO;
       
   499     Frame* coreFrame = core(self);
       
   500     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame))
       
   501         if ([kit(frame) _hasSelection]) {
       
   502             if (found)
       
   503                 return NO;
       
   504             found = YES;
       
   505         }
       
   506     return YES;
       
   507 }
       
   508 #endif
       
   509 
       
   510 - (WebFrame *)_findFrameWithSelection
       
   511 {
       
   512     Frame* coreFrame = core(self);
       
   513     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame))
       
   514         if ([kit(frame) _hasSelection])
       
   515             return kit(frame);
       
   516     return nil;
       
   517 }
       
   518 
       
   519 - (void)_clearSelectionInOtherFrames
       
   520 {
       
   521     // We rely on WebDocumentSelection protocol implementors to call this method when they become first 
       
   522     // responder. It would be nicer to just notice first responder changes here instead, but there's no 
       
   523     // notification sent when the first responder changes in general (Radar 2573089).
       
   524     WebFrame *frameWithSelection = [[getWebView(self) mainFrame] _findFrameWithSelection];
       
   525     if (frameWithSelection != self)
       
   526         [frameWithSelection _clearSelection];
       
   527 
       
   528     // While we're in the general area of selection and frames, check that there is only one now.
       
   529     ASSERT([[getWebView(self) mainFrame] _atMostOneFrameHasSelection]);
       
   530 }
       
   531 
       
   532 - (BOOL)_isMainFrame
       
   533 {
       
   534    Frame* coreFrame = core(self);
       
   535    if (!coreFrame)
       
   536        return NO;
       
   537    return coreFrame == coreFrame->page()->mainFrame() ;
       
   538 }
       
   539 
       
   540 - (FrameLoader*)_frameLoader
       
   541 {
       
   542     Frame* frame = core(self);
       
   543     return frame ? frame->loader() : 0;
       
   544 }
       
   545 
       
   546 static inline WebDataSource *dataSource(DocumentLoader* loader)
       
   547 {
       
   548     return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;
       
   549 }
       
   550 
       
   551 - (WebDataSource *)_dataSourceForDocumentLoader:(DocumentLoader*)loader
       
   552 {
       
   553     return dataSource(loader);
       
   554 }
       
   555 
       
   556 - (void)_addDocumentLoader:(DocumentLoader*)loader toUnarchiveState:(WebArchive *)archive
       
   557 {
       
   558     [dataSource(loader) _addToUnarchiveState:archive];
       
   559 }
       
   560 
       
   561 - (WebDataSource *)_dataSource
       
   562 {
       
   563     FrameLoader* frameLoader = [self _frameLoader];
       
   564 
       
   565     if (!frameLoader)
       
   566         return nil;
       
   567 
       
   568     return dataSource(frameLoader->documentLoader());
       
   569 }
       
   570 
       
   571 @end
       
   572 
       
   573 @implementation WebFrame (WebPrivate)
       
   574 
       
   575 // FIXME: Yhis exists only as a convenience for Safari, consider moving there.
       
   576 - (BOOL)_isDescendantOfFrame:(WebFrame *)ancestor
       
   577 {
       
   578     Frame* coreFrame = core(self);
       
   579     return coreFrame && coreFrame->tree()->isDescendantOf(core(ancestor));
       
   580 }
       
   581 
       
   582 - (void)_setShouldCreateRenderers:(BOOL)frame
       
   583 {
       
   584     [_private->bridge setShouldCreateRenderers:frame];
       
   585 }
       
   586 
       
   587 - (NSColor *)_bodyBackgroundColor
       
   588 {
       
   589     Document* document = core(self)->document();
       
   590     if (!document)
       
   591         return nil;
       
   592     HTMLElement* body = document->body();
       
   593     if (!body)
       
   594         return nil;
       
   595     RenderObject* bodyRenderer = body->renderer();
       
   596     if (!bodyRenderer)
       
   597         return nil;
       
   598     Color color = bodyRenderer->style()->backgroundColor();
       
   599     if (!color.isValid())
       
   600         return nil;
       
   601     return nsColor(color);
       
   602 }
       
   603 
       
   604 - (BOOL)_isFrameSet
       
   605 {
       
   606     return core(self)->isFrameSet();
       
   607 }
       
   608 
       
   609 - (BOOL)_firstLayoutDone
       
   610 {
       
   611     return [self _frameLoader]->firstLayoutDone();
       
   612 }
       
   613 
       
   614 - (WebFrameLoadType)_loadType
       
   615 {
       
   616     return (WebFrameLoadType)[self _frameLoader]->loadType();
       
   617 }
       
   618 
       
   619 #ifndef __LP64__
       
   620 - (void)_recursive_resumeNullEventsForAllNetscapePlugins
       
   621 {
       
   622     Frame* coreFrame = core(self);
       
   623     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   624         NSView <WebDocumentView> *documentView = [[kit(frame) frameView] documentView];
       
   625         if ([documentView isKindOfClass:[WebHTMLView class]])
       
   626             [(WebHTMLView *)documentView _resumeNullEventsForAllNetscapePlugins];
       
   627     }
       
   628 }
       
   629 #endif
       
   630 
       
   631 #ifndef __LP64__
       
   632 - (void)_recursive_pauseNullEventsForAllNetscapePlugins
       
   633 {
       
   634     Frame* coreFrame = core(self);
       
   635     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
   636         NSView <WebDocumentView> *documentView = [[kit(frame) frameView] documentView];
       
   637         if ([documentView isKindOfClass:[WebHTMLView class]])
       
   638             [(WebHTMLView *)documentView _pauseNullEventsForAllNetscapePlugins];
       
   639     }
       
   640 }
       
   641 #endif
       
   642 
       
   643 - (NSRange)_selectedNSRange
       
   644 {
       
   645     return [_private->bridge selectedNSRange];
       
   646 }
       
   647 
       
   648 - (void)_selectNSRange:(NSRange)range
       
   649 {
       
   650     [_private->bridge selectNSRange:range];
       
   651 }
       
   652 
       
   653 - (BOOL)_isDisplayingStandaloneImage
       
   654 {
       
   655     Document* document = core(self)->document();
       
   656     return document && document->isImageDocument();
       
   657 }
       
   658 
       
   659 @end
       
   660 
       
   661 @implementation WebFrame
       
   662 
       
   663 - (id)init
       
   664 {
       
   665     return nil;
       
   666 }
       
   667 
       
   668 // Should be deprecated.
       
   669 - (id)initWithName:(NSString *)name webFrameView:(WebFrameView *)view webView:(WebView *)webView
       
   670 {
       
   671     return nil;
       
   672 }
       
   673 
       
   674 - (void)dealloc
       
   675 {
       
   676     ASSERT(_private->bridge == nil);
       
   677     [_private release];
       
   678     --WebFrameCount;
       
   679     [super dealloc];
       
   680 }
       
   681 
       
   682 - (void)finalize
       
   683 {
       
   684     ASSERT(_private->bridge == nil);
       
   685     --WebFrameCount;
       
   686     [super finalize];
       
   687 }
       
   688 
       
   689 - (NSString *)name
       
   690 {
       
   691     Frame* coreFrame = core(self);
       
   692     if (!coreFrame)
       
   693         return nil;
       
   694     return coreFrame->tree()->name();
       
   695 }
       
   696 
       
   697 - (WebFrameView *)frameView
       
   698 {
       
   699     return _private->webFrameView;
       
   700 }
       
   701 
       
   702 - (WebView *)webView
       
   703 {
       
   704     return getWebView(self);
       
   705 }
       
   706 
       
   707 - (DOMDocument *)DOMDocument
       
   708 {
       
   709     Frame* coreFrame = core(self);
       
   710     if (!coreFrame)
       
   711         return nil;
       
   712     
       
   713     // FIXME: <rdar://problem/5145841> When loading a custom view/representation 
       
   714     // into a web frame, the old document can still be around. This makes sure that
       
   715     // we'll return nil in those cases.
       
   716     if (![[self _dataSource] _isDocumentHTML]) 
       
   717         return nil; 
       
   718 
       
   719     Document* document = coreFrame->document();
       
   720     
       
   721     // According to the documentation, we should return nil if the frame doesn't have a document.
       
   722     // While full-frame images and plugins do have an underlying HTML document, we return nil here to be
       
   723     // backwards compatible.
       
   724     if (document && (document->isPluginDocument() || document->isImageDocument()))
       
   725         return nil;
       
   726     
       
   727     return kit(coreFrame->document());
       
   728 }
       
   729 
       
   730 - (DOMHTMLElement *)frameElement
       
   731 {
       
   732     Frame* coreFrame = core(self);
       
   733     if (!coreFrame)
       
   734         return nil;
       
   735     return kit(coreFrame->ownerElement());
       
   736 }
       
   737 
       
   738 - (WebDataSource *)provisionalDataSource
       
   739 {
       
   740     FrameLoader* frameLoader = [self _frameLoader];
       
   741     return frameLoader ? dataSource(frameLoader->provisionalDocumentLoader()) : nil;
       
   742 }
       
   743 
       
   744 - (WebDataSource *)dataSource
       
   745 {
       
   746     FrameLoader* loader = [self _frameLoader];
       
   747     if (!loader || !loader->frameHasLoaded())
       
   748         return nil;
       
   749 
       
   750     return [self _dataSource];
       
   751 }
       
   752 
       
   753 - (void)loadRequest:(NSURLRequest *)request
       
   754 {
       
   755     [self _frameLoader]->load(request);
       
   756 }
       
   757 
       
   758 static NSURL *createUniqueWebDataURL()
       
   759 {
       
   760     CFUUIDRef UUIDRef = CFUUIDCreate(kCFAllocatorDefault);
       
   761     NSString *UUIDString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, UUIDRef);
       
   762     CFRelease(UUIDRef);
       
   763     NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"applewebdata://%@", UUIDString]];
       
   764     CFRelease(UUIDString);
       
   765     return URL;
       
   766 }
       
   767 
       
   768 - (void)_loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL
       
   769 {
       
   770     KURL responseURL;
       
   771     if (!URL) {
       
   772         URL = [NSURL URLWithString:@"about:blank"];
       
   773         responseURL = createUniqueWebDataURL();
       
   774     }
       
   775     
       
   776     ResourceRequest request([URL absoluteURL]);
       
   777 
       
   778     // hack because Mail checks for this property to detect data / archive loads
       
   779     [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)request.nsURLRequest()];
       
   780 
       
   781     SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData(data), MIMEType, encodingName, [unreachableURL absoluteURL], responseURL);
       
   782 
       
   783     [self _frameLoader]->load(request, substituteData);
       
   784 }
       
   785 
       
   786 
       
   787 - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL
       
   788 {
       
   789     if (!MIMEType)
       
   790         MIMEType = @"text/html";
       
   791     [self _loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:URL unreachableURL:nil];
       
   792 }
       
   793 
       
   794 - (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL
       
   795 {
       
   796     NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
       
   797     [self _loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:URL unreachableURL:unreachableURL];
       
   798 }
       
   799 
       
   800 - (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)URL
       
   801 {
       
   802     [self _loadHTMLString:string baseURL:URL unreachableURL:nil];
       
   803 }
       
   804 
       
   805 - (void)loadAlternateHTMLString:(NSString *)string baseURL:(NSURL *)URL forUnreachableURL:(NSURL *)unreachableURL
       
   806 {
       
   807     [self _loadHTMLString:string baseURL:URL unreachableURL:unreachableURL];
       
   808 }
       
   809 
       
   810 - (void)loadArchive:(WebArchive *)archive
       
   811 {
       
   812     WebResource *mainResource = [archive mainResource];
       
   813     if (mainResource) {
       
   814         SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData([mainResource data]), [mainResource MIMEType], [mainResource textEncodingName], KURL());
       
   815         ResourceRequest request([mainResource URL]);
       
   816 
       
   817         // hack because Mail checks for this property to detect data / archive loads
       
   818         [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)request.nsURLRequest()];
       
   819 
       
   820         RefPtr<DocumentLoader> documentLoader = core(self)->loader()->client()->createDocumentLoader(request, substituteData);
       
   821 
       
   822         [dataSource(documentLoader.get()) _addToUnarchiveState:archive];
       
   823 
       
   824         [self _frameLoader]->load(documentLoader.get());
       
   825     }
       
   826 }
       
   827 
       
   828 - (void)stopLoading
       
   829 {
       
   830     if (FrameLoader* frameLoader = [self _frameLoader])
       
   831         frameLoader->stopForUserCancel();
       
   832 }
       
   833 
       
   834 - (void)reload
       
   835 {
       
   836     [self _frameLoader]->reload();
       
   837 }
       
   838 
       
   839 - (WebFrame *)findFrameNamed:(NSString *)name
       
   840 {
       
   841     Frame* coreFrame = core(self);
       
   842     if (!coreFrame)
       
   843         return nil;
       
   844     return kit(coreFrame->tree()->find(name));
       
   845 }
       
   846 
       
   847 - (WebFrame *)parentFrame
       
   848 {
       
   849     Frame* coreFrame = core(self);
       
   850     if (!coreFrame)
       
   851         return nil;
       
   852     return [[kit(coreFrame->tree()->parent()) retain] autorelease];
       
   853 }
       
   854 
       
   855 - (NSArray *)childFrames
       
   856 {
       
   857     Frame* coreFrame = core(self);
       
   858     if (!coreFrame)
       
   859         return [NSArray array];
       
   860     NSMutableArray *children = [NSMutableArray arrayWithCapacity:coreFrame->tree()->childCount()];
       
   861     for (Frame* child = coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling())
       
   862         [children addObject:kit(child)];
       
   863     return children;
       
   864 }
       
   865 
       
   866 - (WebScriptObject *)windowObject
       
   867 {
       
   868     Frame* coreFrame = core(self);
       
   869     if (!coreFrame)
       
   870         return 0;
       
   871     return coreFrame->windowScriptObject();
       
   872 }
       
   873 
       
   874 - (JSGlobalContextRef)globalContext
       
   875 {
       
   876     Frame* coreFrame = core(self);
       
   877     if (!coreFrame)
       
   878         return 0;
       
   879     return reinterpret_cast<JSGlobalContextRef>(coreFrame->scriptProxy()->interpreter()->globalExec());
       
   880 }
       
   881 
       
   882 @end