• webkit内核分析之 Frame


    参考地址:http://blog.csdn.net/dlmu2001/article/details/6164873

    1.    描述

    Frame类是WebCore内核同应用之间联系的一个重要的类。它有点像设计模式中的Façade,将内核的各个不同的零配件组装在了一起,但又不是Façade,因为用户很多时候还是要直接去操作里面的组件。除了设计上的考虑,Frame还有语法上的意义,它对应于Page里面的帧。

    看一下类定义:

      1  class Frame : public RefCounted<Frame>, public TiledBackingStoreClient {
      2     public:
      3         static PassRefPtr<Frame> create(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
      4 
      5         void init();
      6         void setView(PassRefPtr<FrameView>);
      7         void createView(const IntSize&, const Color&, bool, const IntSize&, bool,
      8             ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
      9             ScrollbarMode = ScrollbarAuto, bool verticalLock = false);
     10 
     11         ~Frame();
     12 
     13         void addDestructionObserver(FrameDestructionObserver*);
     14         void removeDestructionObserver(FrameDestructionObserver*);
     15 
     16         void detachFromPage();
     17         void pageDestroyed();
     18         void disconnectOwnerElement();
     19 
     20         Page* page() const;
     21         HTMLFrameOwnerElement* ownerElement() const;
     22 
     23         Document* document() const;
     24         FrameView* view() const;
     25 
     26         Editor* editor() const;
     27         EventHandler* eventHandler() const;
     28         FrameLoader* loader() const;
     29         NavigationScheduler* navigationScheduler() const;
     30         SelectionController* selection() const;
     31         FrameTree* tree() const;
     32         AnimationController* animation() const;
     33         ScriptController* script();
     34         
     35         RenderView* contentRenderer() const; // Root of the render tree for the document contained in this frame.
     36         RenderPart* ownerRenderer() const; // Renderer for the element that contains this frame.
     37 
     38         void transferChildFrameToNewDocument();
     39 
     40     // ======== All public functions below this point are candidates to move out of Frame into another class. ========
     41 
     42         bool isDisconnected() const;
     43         void setIsDisconnected(bool);
     44         bool excludeFromTextSearch() const;
     45         void setExcludeFromTextSearch(bool);
     46 
     47         void injectUserScripts(UserScriptInjectionTime);
     48         
     49         String layerTreeAsText(bool showDebugInfo = false) const;
     50 
     51         // Unlike most accessors in this class, domWindow() always creates a new DOMWindow if m_domWindow is null.
     52         // Callers that don't need a new DOMWindow to be created should use existingDOMWindow().
     53         DOMWindow* domWindow() const;
     54         DOMWindow* existingDOMWindow() { return m_domWindow.get(); }
     55         void setDOMWindow(DOMWindow*);
     56         void clearFormerDOMWindow(DOMWindow*);
     57         void clearDOMWindow();
     58 
     59         static Frame* frameForWidget(const Widget*);
     60 
     61         Settings* settings() const; // can be NULL
     62 
     63         enum AdjustViewSizeOrNot { DoNotAdjustViewSize, AdjustViewSize };
     64         void setPrinting(bool printing, const FloatSize& pageSize, float maximumShrinkRatio, AdjustViewSizeOrNot);
     65 
     66         bool inViewSourceMode() const;
     67         void setInViewSourceMode(bool = true);
     68 
     69         void keepAlive(); // Used to keep the frame alive when running a script that might destroy it.
     70         static void cancelAllKeepAlive();
     71 
     72         void setDocument(PassRefPtr<Document>);
     73 
     74         void setPageZoomFactor(float factor);
     75         float pageZoomFactor() const { return m_pageZoomFactor; }
     76         void setTextZoomFactor(float factor);
     77         float textZoomFactor() const { return m_textZoomFactor; }
     78         void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor);
     79 
     80         void scalePage(float scale, const IntPoint& origin);
     81         float pageScaleFactor() const { return m_pageScaleFactor; }
     82 
     83 #if ENABLE(ORIENTATION_EVENTS)
     84         // Orientation is the interface orientation in degrees. Some examples are:
     85         //  0 is straight up; -90 is when the device is rotated 90 clockwise;
     86         //  90 is when rotated counter clockwise.
     87         void sendOrientationChangeEvent(int orientation);
     88         int orientation() const { return m_orientation; }
     89 #endif
     90 
     91         void clearTimers();
     92         static void clearTimers(FrameView*, Document*);
     93 
     94         String documentTypeString() const;
     95 
     96         String displayStringModifiedByEncoding(const String&) const;
     97 
     98         DragImageRef nodeImage(Node*);
     99         DragImageRef dragImageForSelection();
    100 
    101         VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
    102         Document* documentAtPoint(const IntPoint& windowPoint);
    103         PassRefPtr<Range> rangeForPoint(const IntPoint& framePoint);
    104 
    105         String searchForLabelsAboveCell(RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell);
    106         String searchForLabelsBeforeElement(const Vector<String>& labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove);
    107         String matchLabelsAgainstElement(const Vector<String>& labels, Element*);
    108 
    109         Color getDocumentBackgroundColor() const;
    110         
    111 #if PLATFORM(MAC)
    112         NSString* searchForLabelsBeforeElement(NSArray* labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove);
    113         NSString* matchLabelsAgainstElement(NSArray* labels, Element*);
    114 
    115         NSImage* selectionImage(bool forceBlackText = false) const;
    116         NSImage* snapshotDragImage(Node*, NSRect* imageRect, NSRect* elementRect) const;
    117         NSImage* imageFromRect(NSRect) const;
    118 #endif
    119 
    120 #if ENABLE(MEDIA_STREAM)
    121         MediaStreamFrameController* mediaStreamFrameController() const { return m_mediaStreamFrameController.get(); }
    122 #endif
    123 
    124     // ========
    125 
    126     private:
    127         Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
    128 
    129         void injectUserScriptsForWorld(DOMWrapperWorld*, const UserScriptVector&, UserScriptInjectionTime);
    130         void lifeSupportTimerFired(Timer<Frame>*);
    131 
    132 #if USE(ACCELERATED_COMPOSITING)
    133         void updateContentsScale(float);
    134 #endif
    135 
    136         HashSet<FrameDestructionObserver*> m_destructionObservers;
    137 
    138         Page* m_page;
    139         mutable FrameTree m_treeNode;
    140         mutable FrameLoader m_loader;
    141         mutable NavigationScheduler m_navigationScheduler;
    142 
    143         mutable RefPtr<DOMWindow> m_domWindow;
    144         HashSet<DOMWindow*> m_liveFormerWindows;
    145 
    146         HTMLFrameOwnerElement* m_ownerElement;
    147         RefPtr<FrameView> m_view;
    148         RefPtr<Document> m_doc;
    149 
    150         ScriptController m_script;
    151 
    152         mutable Editor m_editor;
    153         mutable SelectionController m_selectionController;
    154         mutable EventHandler m_eventHandler;
    155         mutable AnimationController m_animationController;
    156 
    157         Timer<Frame> m_lifeSupportTimer;
    158 
    159         float m_pageZoomFactor;
    160         float m_textZoomFactor;
    161 
    162         float m_pageScaleFactor;
    163 
    164 #if ENABLE(ORIENTATION_EVENTS)
    165         int m_orientation;
    166 #endif
    167 
    168         bool m_inViewSourceMode;
    169         bool m_isDisconnected;
    170         bool m_excludeFromTextSearch;
    171 
    172 #if ENABLE(TILED_BACKING_STORE)
    173     // FIXME: The tiled backing store belongs in FrameView, not Frame.
    174 
    175     public:
    176         TiledBackingStore* tiledBackingStore() const { return m_tiledBackingStore.get(); }
    177         void setTiledBackingStoreEnabled(bool);
    178 
    179     private:
    180         // TiledBackingStoreClient interface
    181         virtual void tiledBackingStorePaintBegin();
    182         virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&);
    183         virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea);
    184         virtual IntRect tiledBackingStoreContentsRect();
    185         virtual IntRect tiledBackingStoreVisibleRect();
    186         virtual Color tiledBackingStoreBackgroundColor() const;
    187 
    188         OwnPtr<TiledBackingStore> m_tiledBackingStore;
    189 #endif
    190 
    191 #if ENABLE(MEDIA_STREAM)
    192         OwnPtr<MediaStreamFrameController> m_mediaStreamFrameController;
    193 #endif
    194     }

    2.    类结构

    1,FrameTree对象用来协助管理父帧和子帧的关系,常见的比如 main frame之中有 iframe元素,就会调用 FrameLoaderClientQt::createFrame来产生子帧,产生的子帧会通过appendChild添加到主帧的树状结构中。Frame通过FrameTree对象,可以方便的访问它的父帧,子帧,兄弟帧。

     1 Frame* SubframeLoader::loadSubframe(HTMLFrameOwnerElement* ownerElement, const KURL& url, const String& name, const String& referrer)
     2 {
     3     bool allowsScrolling = true;
     4     int marginWidth = -1;
     5     int marginHeight = -1;
     6     if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag)) {
     7         HTMLFrameElementBase* o = static_cast<HTMLFrameElementBase*>(ownerElement);
     8         allowsScrolling = o->scrollingMode() != ScrollbarAlwaysOff;
     9         marginWidth = o->marginWidth();
    10         marginHeight = o->marginHeight();
    11     }
    12 
    13     if (!ownerElement->document()->securityOrigin()->canDisplay(url)) {
    14         FrameLoader::reportLocalLoadFailed(m_frame, url.string());
    15         return 0;
    16     }
    17 
    18     if (!ownerElement->document()->contentSecurityPolicy()->allowChildFrameFromSource(url))
    19         return 0;
    20 
    21     bool hideReferrer = SecurityOrigin::shouldHideReferrer(url, referrer);
    22     RefPtr<Frame> frame = m_frame->loader()->client()->createFrame(url, name, ownerElement, hideReferrer ? String() : referrer, allowsScrolling, marginWidth, marginHeight);
    23 
    24     if (!frame)  {
    25         m_frame->loader()->checkCallImplicitClose();
    26         return 0;
    27     }
    28     
    29     // All new frames will have m_isComplete set to true at this point due to synchronously loading
    30     // an empty document in FrameLoader::init(). But many frames will now be starting an
    31     // asynchronous load of url, so we set m_isComplete to false and then check if the load is
    32     // actually completed below. (Note that we set m_isComplete to false even for synchronous
    33     // loads, so that checkCompleted() below won't bail early.)
    34     // FIXME: Can we remove this entirely? m_isComplete normally gets set to false when a load is committed.
    35     frame->loader()->started();
    36    
    37     RenderObject* renderer = ownerElement->renderer();
    38     FrameView* view = frame->view();
    39     if (renderer && renderer->isWidget() && view)
    40         toRenderWidget(renderer)->setWidget(view);
    41     
    42     m_frame->loader()->checkCallImplicitClose();
    43     
    44     // Some loads are performed synchronously (e.g., about:blank and loads
    45     // cancelled by returning a null ResourceRequest from requestFromDelegate).
    46     // In these cases, the synchronous load would have finished
    47     // before we could connect the signals, so make sure to send the 
    48     // completed() signal for the child by hand and mark the load as being
    49     // complete.
    50     // FIXME: In this case the Frame will have finished loading before 
    51     // it's being added to the child list. It would be a good idea to
    52     // create the child first, then invoke the loader separately.
    53     if (frame->loader()->state() == FrameStateComplete && !frame->loader()->policyDocumentLoader())
    54         frame->loader()->checkCompleted();
    55 
    56     return frame.get();
    57 }

    然后就是创建看createFrame函数

     1 PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
     2                                         const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
     3 {
     4     if (!m_webFrame)
     5         return 0;
     6 
     7     QWebFrameData frameData(m_frame->page(), m_frame, ownerElement, name);
     8 
     9     if (url.isEmpty())
    10         frameData.url = blankURL();
    11     else
    12         frameData.url = url;
    13 
    14     frameData.referrer = referrer;
    15     frameData.allowsScrolling = allowsScrolling;
    16     frameData.marginWidth = marginWidth;
    17     frameData.marginHeight = marginHeight;
    18 
    19     QPointer<QWebFrame> webFrame = new QWebFrame(m_webFrame, &frameData);
    20     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
    21     if (!webFrame->d->frame->page()) {
    22         frameData.frame.release();
    23         ASSERT(webFrame.isNull());
    24         return 0;
    25     }
    26 
    27     emit m_webFrame->page()->frameCreated(webFrame);
    28 
    29     // FIXME: Set override encoding if we have one.
    30 
    31     m_frame->loader()->loadURLIntoChildFrame(frameData.url, frameData.referrer, frameData.frame.get());
    32 
    33     // The frame's onload handler may have removed it from the document.
    34     if (!frameData.frame->tree()->parent())
    35         return 0;
    36 
    37     return frameData.frame.release();
    38 }
    1 void FrameTree::appendChild(PassRefPtr<Frame> child)
    2 {
    3     ASSERT(child->page() == m_thisFrame->page());
    4     child->tree()->m_parent = m_thisFrame;
    5     actuallyAppendChild(child); // Note, on return |child| is null.
    6 }


    2,维护FrameLoader对象用来完成frame的加载,FrameLoader是一个非常重要的类,后续进行进一步的分析。

    3,维护NavigationScheduler对象用来管理页面跳转调度(比如重定向,meta refresh等)。

    4,DOMWindow用来管理同 DOM 相关的事件、属性和消息。

    5,FrameView类用于Frame的排版

    6,Frame文档解析后,对于每一个tag或者attr,会有对应的dom节点关联,Document类用来管理这些dom节点。不同的文档类型继承出不同的子类,比如HTML文档对应子类 HTMLDocument,XML文档对应于XMLDocument。

    7,ScriptController对象。脚本控制器,用来管理脚本的执行和操作

    8,Editor对象用来处理页面的编辑相关工作,比如拷贝,粘贴,输入等,Editor对象,它同Page类的 EditorClient对象紧密合作。 和EditorClient关系就如同 Page和 Frame的关系

    9,SelectionController 用来管理 Frame中的选取操作

    10,AnimationController 动画控制,控制动画的播放、暂停、继续(同 HTML video标签是否有关系?)

    11,EventHandler 事件处理对象,这里的对象主要是同上层应用也即是用户参与的事件, 比如鼠标事件、按键事件(快捷键等)、滚动事件、resize事件等。这是一个浏览器外壳经常需要打交道的类

    3.    主要接口

    3.1   Create

     1 static PassRefPtr<Frame> create(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
     2 
     3 
     4 
     5 PassRefPtr<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
     6 {
     7     RefPtr<Frame> frame = adoptRef(new Frame(page, ownerElement, client));
     8     if (!ownerElement)
     9         page->setMainFrame(frame);
    10     return frame.release();
    11 }

    描述:
          调用Frame构造函数,创建出 Frame 对象。 有两个地方会创建 Frame对象: 一个是要加载一个新的页面请求,这时候会创建一个 main frame。 一个是 在加载子帧的时候,通过 FrameLoaderClientQt 的

    createFrame接口,创建子帧对应的Frame对象,在第一种情况下 HTMLFrameOwnerElement的参数为NULL, 第二种情况传子帧的父元素。在一个tab页内,main frame会重用

    调用系列:

     1 QwebPage::setView
     2 QwebPage::setViewportSize
     3 QwebPage::mainFrame
     4 QwebPagePrivate::createMainFrame
     5 QwebFrameData::QwebFrameData
     6 Frame::create
     7 
     8 FrameLoader::finishedLoading
     9 ......
    10 HTMLDocumentParser::append
    11 ......
    12 HTMLTreeBuilder::processToken
    13 ......
    14 HTMLElementBase::openURL
    15 SubFrameLoader::requestFrame
    16 ......
    17 FrameLoaderClientQt::creatFrame
    18 QwebFrameData::QwebFrameData
    19 Frame::create

    源码追踪一下(只跟踪源码和颜色标识,不解释):

    第一种情况下:

    1,

     1 void QWebPage::setView(QWidget* view)
     2 {
     3     if (this->view() == view)
     4         return;
     5 
     6     d->view = view;
     7     setViewportSize(view ? view->size() : QSize(0, 0));
     8 
     9     // If we have no client, we install a special client delegating
    10     // the responsibility to the QWidget. This is the code path
    11     // handling a.o. the "legacy" QWebView.
    12     //
    13     // If such a special delegate already exist, we substitute the view.
    14 
    15     if (d->client) {
    16         if (d->client->isQWidgetClient())
    17             static_cast<PageClientQWidget*>(d->client.get())->view = view;
    18         return;
    19     }
    20 
    21     if (view)
    22         d->client = new PageClientQWidget(view, this);
    23 }

    2,

     1 void QWebPage::setViewportSize(const QSize &size) const
     2 {
     3     d->viewportSize = size;
     4 
     5     QWebFrame *frame = mainFrame();
     6     if (frame->d->frame && frame->d->frame->view()) {
     7         WebCore::FrameView* view = frame->d->frame->view();
     8         view->resize(size);
     9         view->adjustViewSize();
    10     }
    11 }

    3,

    1 QWebFrame *QWebPage::mainFrame() const
    2 {
    3     d->createMainFrame();
    4     return d->mainFrame;
    5 }

    4,

    1 void QWebPagePrivate::createMainFrame()
    2 {
    3     if (!mainFrame) {
    4         QWebFrameData frameData(page);
    5         mainFrame = new QWebFrame(q, &frameData);
    6 
    7         emit q->frameCreated(mainFrame);
    8     }
    9 }

    5,

    1     QWebFrameData(WebCore::Page*, WebCore::Frame* parentFrame = 0,
    2                   WebCore::HTMLFrameOwnerElement* = 0,
    3                   const WTF::String& frameName = WTF::String());

    6,

     1 QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame,
     2                              WebCore::HTMLFrameOwnerElement* ownerFrameElement,
     3                              const WTF::String& frameName)
     4     : name(frameName)
     5     , ownerElement(ownerFrameElement)
     6     , page(parentPage)
     7     , allowsScrolling(true)
     8     , marginWidth(0)
     9     , marginHeight(0)
    10 {
    11     frameLoaderClient = new FrameLoaderClientQt();
    12     frame = Frame::create(page, ownerElement, frameLoaderClient);
    13 
    14     // FIXME: All of the below should probably be moved over into WebCore
    15     frame->tree()->setName(name);
    16     if (parentFrame)
    17         parentFrame->tree()->appendChild(frame);
    18 }


     

    第二种情况下:

    1,FrameLoader::finishedLoading()

     1 void FrameLoader::finishedLoading()
     2 {
     3     // Retain because the stop may release the last reference to it.
     4     RefPtr<Frame> protect(m_frame);
     5 
     6     RefPtr<DocumentLoader> dl = activeDocumentLoader();
     7     dl->finishedLoading();
     8     if (!dl->mainDocumentError().isNull() || !dl->frameLoader())
     9         return;
    10     dl->setPrimaryLoadComplete(true);
    11     m_client->dispatchDidLoadMainResource(dl.get());
    12     checkLoadComplete();
    13 }

    2,DocumentLoader::finishedLoading()

    1 void DocumentLoader::finishedLoading()
    2 {
    3     m_gotFirstByte = true;   
    4     commitIfReady();
    5     if (FrameLoader* loader = frameLoader()) {
    6         loader->finishedLoadingDocument(this);
    7         m_writer.end();
    8     }
    9 }

    3,DocumentWriter::end()

    1 void DocumentWriter::end()
    2 {
    3     m_frame->loader()->didEndDocument();
    4     endIfNotLoadingMainResource();
    5 }

    4, DocumentWriter::endIfNotLoadingMainResource()

     1 void DocumentWriter::endIfNotLoadingMainResource()
     2 {
     3     if (m_frame->loader()->isLoadingMainResource() || !m_frame->page() || !m_frame->document())
     4         return;
     5 
     6     // http://bugs.webkit.org/show_bug.cgi?id=10854
     7     // The frame's last ref may be removed and it can be deleted by checkCompleted(), 
     8     // so we'll add a protective refcount
     9     RefPtr<Frame> protector(m_frame);
    10 
    11     // make sure nothing's left in there
    12     addData(0, 0, true);
    13     m_frame->document()->finishParsing();
    14 }

    5,DocumentWriter::addData(const char* str, int len, bool flush)

    1 void DocumentWriter::addData(const char* str, int len, bool flush)
    2 {
    3     if (len == -1)
    4         len = strlen(str);
    5 
    6     DocumentParser* parser = m_frame->document()->parser();
    7     if (parser)
    8         parser->appendBytes(this, str, len, flush);
    9 }

    6,DecodedDataDocumentParser::appendBytes(DocumentWriter* writer , const char* data, int length, bool shouldFlush)

     1 void DecodedDataDocumentParser::appendBytes(DocumentWriter* writer , const char* data, int length, bool shouldFlush)
     2 {
     3     if (!length && !shouldFlush)
     4         return;
     5 
     6     TextResourceDecoder* decoder = writer->createDecoderIfNeeded();
     7     String decoded = decoder->decode(data, length);
     8     if (shouldFlush)
     9         decoded += decoder->flush();
    10     if (decoded.isEmpty())
    11         return;
    12 
    13     writer->reportDataReceived();
    14 
    15     append(decoded);
    16 }

    7,HTMLDocumentParser::append(const SegmentedString& source)

     1 void HTMLDocumentParser::append(const SegmentedString& source)
     2 {
     3     if (isStopped())
     4         return;
     5 
     6     // pumpTokenizer can cause this parser to be detached from the Document,
     7     // but we need to ensure it isn't deleted yet.
     8     RefPtr<HTMLDocumentParser> protect(this);
     9 
    10     if (m_preloadScanner) {
    11         if (m_input.current().isEmpty() && !isWaitingForScripts()) {
    12             // We have parsed until the end of the current input and so are now moving ahead of the preload scanner.
    13             // Clear the scanner so we know to scan starting from the current input point if we block again.
    14             m_preloadScanner.clear();
    15         } else {
    16             m_preloadScanner->appendToEnd(source);
    17             if (isWaitingForScripts())
    18                 m_preloadScanner->scan();
    19         }
    20     }
    21 
    22     m_input.appendToEnd(source);
    23 
    24     if (inPumpSession()) {
    25         // We've gotten data off the network in a nested write.
    26         // We don't want to consume any more of the input stream now.  Do
    27         // not worry.  We'll consume this data in a less-nested write().
    28         return;
    29     }
    30 
    31     pumpTokenizerIfPossible(AllowYield);
    32 
    33     endIfDelayed();
    34 }

    8,HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode)

     1 void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode)
     2 {
     3     if (isStopped() || m_treeBuilder->isPaused())
     4         return;
     5 
     6     // Once a resume is scheduled, HTMLParserScheduler controls when we next pump.
     7     if (isScheduledForResume()) {
     8         ASSERT(mode == AllowYield);
     9         return;
    10     }
    11 
    12     pumpTokenizer(mode);
    13 }

    9,HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)

     1 void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
     2 {
     3     ASSERT(!isStopped());
     4     ASSERT(!isScheduledForResume());
     5     // ASSERT that this object is both attached to the Document and protected.
     6     ASSERT(refCount() >= 2);
     7 
     8     PumpSession session(m_pumpSessionNestingLevel);
     9 
    10     // We tell the InspectorInstrumentation about every pump, even if we
    11     // end up pumping nothing.  It can filter out empty pumps itself.
    12     // FIXME: m_input.current().length() is only accurate if we
    13     // end up parsing the whole buffer in this pump.  We should pass how
    14     // much we parsed as part of didWriteHTML instead of willWriteHTML.
    15     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteHTML(document(), m_input.current().length(), m_tokenizer->lineNumber());
    16 
    17     while (canTakeNextToken(mode, session) && !session.needsYield) {
    18         if (!isParsingFragment())
    19             m_sourceTracker.start(m_input, m_token);
    20 
    21         if (!m_tokenizer->nextToken(m_input.current(), m_token))
    22             break;
    23 
    24         if (!isParsingFragment()) {
    25             m_sourceTracker.end(m_input, m_token);
    26 
    27             // We do not XSS filter innerHTML, which means we (intentionally) fail
    28             // http/tests/security/xssAuditor/dom-write-innerHTML.html
    29             m_xssFilter.filterToken(m_token);
    30         }
    31 
    32         m_treeBuilder->constructTreeFromToken(m_token);
    33         ASSERT(m_token.isUninitialized());
    34     }
    35 
    36     // Ensure we haven't been totally deref'ed after pumping. Any caller of this
    37     // function should be holding a RefPtr to this to ensure we weren't deleted.
    38     ASSERT(refCount() >= 1);
    39 
    40     if (isStopped())
    41         return;
    42 
    43     if (session.needsYield)
    44         m_parserScheduler->scheduleForResume();
    45 
    46     if (isWaitingForScripts()) {
    47         ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
    48         if (!m_preloadScanner) {
    49             m_preloadScanner = adoptPtr(new HTMLPreloadScanner(document()));
    50             m_preloadScanner->appendToEnd(m_input.current());
    51         }
    52         m_preloadScanner->scan();
    53     }
    54 
    55     InspectorInstrumentation::didWriteHTML(cookie, m_tokenizer->lineNumber());
    56 }

    10,HTMLTreeBuilder::constructTreeFromToken(HTMLToken& rawToken)

     1 void HTMLTreeBuilder::constructTreeFromToken(HTMLToken& rawToken)
     2 {
     3     AtomicHTMLToken token(rawToken);
     4 
     5     // We clear the rawToken in case constructTreeFromAtomicToken
     6     // synchronously re-enters the parser. We don't clear the token immedately
     7     // for Character tokens because the AtomicHTMLToken avoids copying the
     8     // characters by keeping a pointer to the underlying buffer in the
     9     // HTMLToken. Fortuantely, Character tokens can't cause use to re-enter
    10     // the parser.
    11     //
    12     // FIXME: Top clearing the rawToken once we start running the parser off
    13     // the main thread or once we stop allowing synchronous JavaScript
    14     // execution from parseMappedAttribute.
    15     if (rawToken.type() != HTMLToken::Character)
    16         rawToken.clear();
    17 
    18     constructTreeFromAtomicToken(token);
    19 
    20     if (!rawToken.isUninitialized()) {
    21         ASSERT(rawToken.type() == HTMLToken::Character);
    22         rawToken.clear();
    23     }
    24 }

    11,HTMLTreeBuilder::constructTreeFromAtomicToken(AtomicHTMLToken& token)

     1 void HTMLTreeBuilder::constructTreeFromAtomicToken(AtomicHTMLToken& token)
     2 {
     3     processToken(token);
     4 
     5     // Swallowing U+0000 characters isn't in the HTML5 spec, but turning all
     6     // the U+0000 characters into replacement characters has compatibility
     7     // problems.
     8     m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode == TextMode || m_insertionMode == InForeignContentMode);
     9     m_parser->tokenizer()->setShouldAllowCDATA(m_insertionMode == InForeignContentMode && !isInHTMLNamespace(m_tree.currentNode()));
    10 }

    12,HTMLTreeBuilder::processToken(AtomicHTMLToken& token)

     1 void HTMLTreeBuilder::processToken(AtomicHTMLToken& token)
     2 {
     3     switch (token.type()) {
     4     case HTMLToken::Uninitialized:
     5         ASSERT_NOT_REACHED();
     6         break;
     7     case HTMLToken::DOCTYPE:
     8         processDoctypeToken(token);
     9         break;
    10     case HTMLToken::StartTag:
    11         processStartTag(token);
    12         break;
    13     case HTMLToken::EndTag:
    14         processEndTag(token);
    15         break;
    16     case HTMLToken::Comment:
    17         processComment(token);
    18         return;
    19     case HTMLToken::Character:
    20         processCharacter(token);
    21         break;
    22     case HTMLToken::EndOfFile:
    23         processEndOfFile(token);
    24         break;
    25     }
    26 }

    13,HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)

      1 void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
      2 {
      3     ASSERT(token.type() == HTMLToken::StartTag);
      4     switch (insertionMode()) {
      5     case InitialMode:
      6         ASSERT(insertionMode() == InitialMode);
      7         defaultForInitial();
      8         // Fall through.
      9     case BeforeHTMLMode:
     10         ASSERT(insertionMode() == BeforeHTMLMode);
     11         if (token.name() == htmlTag) {
     12             m_tree.insertHTMLHtmlStartTagBeforeHTML(token);
     13             setInsertionMode(BeforeHeadMode);
     14             return;
     15         }
     16         defaultForBeforeHTML();
     17         // Fall through.
     18     case BeforeHeadMode:
     19         ASSERT(insertionMode() == BeforeHeadMode);
     20         if (token.name() == htmlTag) {
     21             m_tree.insertHTMLHtmlStartTagInBody(token);
     22             return;
     23         }
     24         if (token.name() == headTag) {
     25             m_tree.insertHTMLHeadElement(token);
     26             setInsertionMode(InHeadMode);
     27             return;
     28         }
     29         defaultForBeforeHead();
     30         // Fall through.
     31     case InHeadMode:
     32         ASSERT(insertionMode() == InHeadMode);
     33         if (processStartTagForInHead(token))
     34             return;
     35         defaultForInHead();
     36         // Fall through.
     37     case AfterHeadMode:
     38         ASSERT(insertionMode() == AfterHeadMode);
     39         if (token.name() == htmlTag) {
     40             m_tree.insertHTMLHtmlStartTagInBody(token);
     41             return;
     42         }
     43         if (token.name() == bodyTag) {
     44             m_framesetOk = false;
     45             m_tree.insertHTMLBodyElement(token);
     46             setInsertionMode(InBodyMode);
     47             return;
     48         }
     49         if (token.name() == framesetTag) {
     50             m_tree.insertHTMLElement(token);
     51             setInsertionMode(InFramesetMode);
     52             return;
     53         }
     54         if (token.name() == baseTag
     55             || token.name() == basefontTag
     56             || token.name() == bgsoundTag
     57             || token.name() == linkTag
     58             || token.name() == metaTag
     59             || token.name() == noframesTag
     60             || token.name() == scriptTag
     61             || token.name() == styleTag
     62             || token.name() == titleTag) {
     63             parseError(token);
     64             ASSERT(m_tree.head());
     65             m_tree.openElements()->pushHTMLHeadElement(m_tree.head());
     66             processStartTagForInHead(token);
     67             m_tree.openElements()->removeHTMLHeadElement(m_tree.head());
     68             return;
     69         }
     70         if (token.name() == headTag) {
     71             parseError(token);
     72             return;
     73         }
     74         defaultForAfterHead();
     75         // Fall through
     76     case InBodyMode:
     77         ASSERT(insertionMode() == InBodyMode);
     78         processStartTagForInBody(token);
     79         break;
     80     case InTableMode:
     81         ASSERT(insertionMode() == InTableMode);
     82         processStartTagForInTable(token);
     83         break;
     84     case InCaptionMode:
     85         ASSERT(insertionMode() == InCaptionMode);
     86         if (isCaptionColOrColgroupTag(token.name())
     87             || isTableBodyContextTag(token.name())
     88             || isTableCellContextTag(token.name())
     89             || token.name() == trTag) {
     90             parseError(token);
     91             if (!processCaptionEndTagForInCaption()) {
     92                 ASSERT(isParsingFragment());
     93                 return;
     94             }
     95             reprocessStartTag(token);
     96             return;
     97         }
     98         processStartTagForInBody(token);
     99         break;
    100     case InColumnGroupMode:
    101         ASSERT(insertionMode() == InColumnGroupMode);
    102         if (token.name() == htmlTag) {
    103             m_tree.insertHTMLHtmlStartTagInBody(token);
    104             return;
    105         }
    106         if (token.name() == colTag) {
    107             m_tree.insertSelfClosingHTMLElement(token);
    108             return;
    109         }
    110         if (!processColgroupEndTagForInColumnGroup()) {
    111             ASSERT(isParsingFragment());
    112             return;
    113         }
    114         reprocessStartTag(token);
    115         break;
    116     case InTableBodyMode:
    117         ASSERT(insertionMode() == InTableBodyMode);
    118         if (token.name() == trTag) {
    119             m_tree.openElements()->popUntilTableBodyScopeMarker(); // How is there ever anything to pop?
    120             m_tree.insertHTMLElement(token);
    121             setInsertionMode(InRowMode);
    122             return;
    123         }
    124         if (isTableCellContextTag(token.name())) {
    125             parseError(token);
    126             processFakeStartTag(trTag);
    127             ASSERT(insertionMode() == InRowMode);
    128             reprocessStartTag(token);
    129             return;
    130         }
    131         if (isCaptionColOrColgroupTag(token.name()) || isTableBodyContextTag(token.name())) {
    132             // FIXME: This is slow.
    133             if (!m_tree.openElements()->inTableScope(tbodyTag.localName()) && !m_tree.openElements()->inTableScope(theadTag.localName()) && !m_tree.openElements()->inTableScope(tfootTag.localName())) {
    134                 ASSERT(isParsingFragment());
    135                 parseError(token);
    136                 return;
    137             }
    138             m_tree.openElements()->popUntilTableBodyScopeMarker();
    139             ASSERT(isTableBodyContextTag(m_tree.currentElement()->localName()));
    140             processFakeEndTag(m_tree.currentElement()->tagQName());
    141             reprocessStartTag(token);
    142             return;
    143         }
    144         processStartTagForInTable(token);
    145         break;
    146     case InRowMode:
    147         ASSERT(insertionMode() == InRowMode);
    148         if (isTableCellContextTag(token.name())) {
    149             m_tree.openElements()->popUntilTableRowScopeMarker();
    150             m_tree.insertHTMLElement(token);
    151             setInsertionMode(InCellMode);
    152             m_tree.activeFormattingElements()->appendMarker();
    153             return;
    154         }
    155         if (token.name() == trTag
    156             || isCaptionColOrColgroupTag(token.name())
    157             || isTableBodyContextTag(token.name())) {
    158             if (!processTrEndTagForInRow()) {
    159                 ASSERT(isParsingFragment());
    160                 return;
    161             }
    162             ASSERT(insertionMode() == InTableBodyMode);
    163             reprocessStartTag(token);
    164             return;
    165         }
    166         processStartTagForInTable(token);
    167         break;
    168     case InCellMode:
    169         ASSERT(insertionMode() == InCellMode);
    170         if (isCaptionColOrColgroupTag(token.name())
    171             || isTableCellContextTag(token.name())
    172             || token.name() == trTag
    173             || isTableBodyContextTag(token.name())) {
    174             // FIXME: This could be more efficient.
    175             if (!m_tree.openElements()->inTableScope(tdTag) && !m_tree.openElements()->inTableScope(thTag)) {
    176                 ASSERT(isParsingFragment());
    177                 parseError(token);
    178                 return;
    179             }
    180             closeTheCell();
    181             reprocessStartTag(token);
    182             return;
    183         }
    184         processStartTagForInBody(token);
    185         break;
    186     case AfterBodyMode:
    187     case AfterAfterBodyMode:
    188         ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
    189         if (token.name() == htmlTag) {
    190             m_tree.insertHTMLHtmlStartTagInBody(token);
    191             return;
    192         }
    193         setInsertionMode(InBodyMode);
    194         reprocessStartTag(token);
    195         break;
    196     case InHeadNoscriptMode:
    197         ASSERT(insertionMode() == InHeadNoscriptMode);
    198         if (token.name() == htmlTag) {
    199             m_tree.insertHTMLHtmlStartTagInBody(token);
    200             return;
    201         }
    202         if (token.name() == basefontTag
    203             || token.name() == bgsoundTag
    204             || token.name() == linkTag
    205             || token.name() == metaTag
    206             || token.name() == noframesTag
    207             || token.name() == styleTag) {
    208             bool didProcess = processStartTagForInHead(token);
    209             ASSERT_UNUSED(didProcess, didProcess);
    210             return;
    211         }
    212         if (token.name() == htmlTag || token.name() == noscriptTag) {
    213             parseError(token);
    214             return;
    215         }
    216         defaultForInHeadNoscript();
    217         processToken(token);
    218         break;
    219     case InFramesetMode:
    220         ASSERT(insertionMode() == InFramesetMode);
    221         if (token.name() == htmlTag) {
    222             m_tree.insertHTMLHtmlStartTagInBody(token);
    223             return;
    224         }
    225         if (token.name() == framesetTag) {
    226             m_tree.insertHTMLElement(token);
    227             return;
    228         }
    229         if (token.name() == frameTag) {
    230             m_tree.insertSelfClosingHTMLElement(token);
    231             return;
    232         }
    233         if (token.name() == noframesTag) {
    234             processStartTagForInHead(token);
    235             return;
    236         }
    237         parseError(token);
    238         break;
    239     case AfterFramesetMode:
    240     case AfterAfterFramesetMode:
    241         ASSERT(insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
    242         if (token.name() == htmlTag) {
    243             m_tree.insertHTMLHtmlStartTagInBody(token);
    244             return;
    245         }
    246         if (token.name() == noframesTag) {
    247             processStartTagForInHead(token);
    248             return;
    249         }
    250         parseError(token);
    251         break;
    252     case InSelectInTableMode:
    253         ASSERT(insertionMode() == InSelectInTableMode);
    254         if (token.name() == captionTag
    255             || token.name() == tableTag
    256             || isTableBodyContextTag(token.name())
    257             || token.name() == trTag
    258             || isTableCellContextTag(token.name())) {
    259             parseError(token);
    260             AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
    261             processEndTag(endSelect);
    262             reprocessStartTag(token);
    263             return;
    264         }
    265         // Fall through
    266     case InSelectMode:
    267         ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
    268         if (token.name() == htmlTag) {
    269             m_tree.insertHTMLHtmlStartTagInBody(token);
    270             return;
    271         }
    272         if (token.name() == optionTag) {
    273             if (m_tree.currentNode()->hasTagName(optionTag)) {
    274                 AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
    275                 processEndTag(endOption);
    276             }
    277             m_tree.insertHTMLElement(token);
    278             return;
    279         }
    280         if (token.name() == optgroupTag) {
    281             if (m_tree.currentNode()->hasTagName(optionTag)) {
    282                 AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
    283                 processEndTag(endOption);
    284             }
    285             if (m_tree.currentNode()->hasTagName(optgroupTag)) {
    286                 AtomicHTMLToken endOptgroup(HTMLToken::EndTag, optgroupTag.localName());
    287                 processEndTag(endOptgroup);
    288             }
    289             m_tree.insertHTMLElement(token);
    290             return;
    291         }
    292         if (token.name() == selectTag) {
    293             parseError(token);
    294             AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
    295             processEndTag(endSelect);
    296             return;
    297         }
    298         if (token.name() == inputTag
    299             || token.name() == keygenTag
    300             || token.name() == textareaTag) {
    301             parseError(token);
    302             if (!m_tree.openElements()->inSelectScope(selectTag)) {
    303                 ASSERT(isParsingFragment());
    304                 return;
    305             }
    306             AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
    307             processEndTag(endSelect);
    308             reprocessStartTag(token);
    309             return;
    310         }
    311         if (token.name() == scriptTag) {
    312             bool didProcess = processStartTagForInHead(token);
    313             ASSERT_UNUSED(didProcess, didProcess);
    314             return;
    315         }
    316         break;
    317     case InTableTextMode:
    318         defaultForInTableText();
    319         processStartTag(token);
    320         break;
    321     case InForeignContentMode: {
    322         if (shouldProcessForeignContentUsingInBodyInsertionMode(token, m_tree.currentNode())) {
    323             processForeignContentUsingInBodyModeAndResetMode(token);
    324             return;
    325         }
    326         if (token.name() == bTag
    327             || token.name() == bigTag
    328             || token.name() == blockquoteTag
    329             || token.name() == bodyTag
    330             || token.name() == brTag
    331             || token.name() == centerTag
    332             || token.name() == codeTag
    333             || token.name() == ddTag
    334             || token.name() == divTag
    335             || token.name() == dlTag
    336             || token.name() == dtTag
    337             || token.name() == emTag
    338             || token.name() == embedTag
    339             || isNumberedHeaderTag(token.name())
    340             || token.name() == headTag
    341             || token.name() == hrTag
    342             || token.name() == iTag
    343             || token.name() == imgTag
    344             || token.name() == liTag
    345             || token.name() == listingTag
    346             || token.name() == menuTag
    347             || token.name() == metaTag
    348             || token.name() == nobrTag
    349             || token.name() == olTag
    350             || token.name() == pTag
    351             || token.name() == preTag
    352             || token.name() == rubyTag
    353             || token.name() == sTag
    354             || token.name() == smallTag
    355             || token.name() == spanTag
    356             || token.name() == strongTag
    357             || token.name() == strikeTag
    358             || token.name() == subTag
    359             || token.name() == supTag
    360             || token.name() == tableTag
    361             || token.name() == ttTag
    362             || token.name() == uTag
    363             || token.name() == ulTag
    364             || token.name() == varTag
    365             || (token.name() == fontTag && (token.getAttributeItem(colorAttr) || token.getAttributeItem(faceAttr) || token.getAttributeItem(sizeAttr)))) {
    366             parseError(token);
    367             m_tree.openElements()->popUntilForeignContentScopeMarker();
    368             resetInsertionModeAppropriately();
    369             reprocessStartTag(token);
    370             return;
    371         }
    372         const AtomicString& currentNamespace = m_tree.currentElement()->namespaceURI();
    373         if (currentNamespace == MathMLNames::mathmlNamespaceURI)
    374             adjustMathMLAttributes(token);
    375         if (currentNamespace == SVGNames::svgNamespaceURI) {
    376             adjustSVGTagNameCase(token);
    377             adjustSVGAttributes(token);
    378         }
    379         adjustForeignAttributes(token);
    380         m_tree.insertForeignElement(token, currentNamespace);
    381         break;
    382     }
    383     case TextMode:
    384         ASSERT_NOT_REACHED();
    385         break;
    386     }
    387 }

    14,HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken& token)

    1 void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken& token)
    2 {
    3     m_openElements.push(attachToCurrent(createHTMLElement(token)));
    4 }

    15,HTMLConstructionSite::attachToCurrent(PassRefPtr<Element> child)

    1 PassRefPtr<Element> HTMLConstructionSite::attachToCurrent(PassRefPtr<Element> child)
    2 {
    3     return attach(currentNode(), child);
    4 }

    16,HTMLConstructionSite::attach(ContainerNode* rawParent, PassRefPtr<ChildType> prpChild)

     1 template<typename ChildType>
     2 PassRefPtr<ChildType> HTMLConstructionSite::attach(ContainerNode* rawParent, PassRefPtr<ChildType> prpChild)
     3 {
     4     RefPtr<ChildType> child = prpChild;
     5     RefPtr<ContainerNode> parent = rawParent;
     6 
     7     // FIXME: It's confusing that HTMLConstructionSite::attach does the magic
     8     // redirection to the foster parent but HTMLConstructionSite::attachAtSite
     9     // doesn't. It feels like we're missing a concept somehow.
    10     if (shouldFosterParent()) {
    11         fosterParent(child.get());
    12         ASSERT(child->attached() || !child->parentNode() || !child->parentNode()->attached());
    13         return child.release();
    14     }
    15 
    16     parent->parserAddChild(child);
    17 
    18     // An event handler (DOM Mutation, beforeload, et al.) could have removed
    19     // the child, in which case we shouldn't try attaching it.
    20     if (!child->parentNode())
    21         return child.release();
    22 
    23     if (parent->attached() && !child->attached())
    24         child->attach();
    25     return child.release();
    26 }

    17,ContainerNode::parserAddChild(PassRefPtr<Node> newChild)

     1 void ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
     2 {
     3     ASSERT(newChild);
     4     ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
     5 
     6 #if ENABLE(INSPECTOR)
     7     InspectorInstrumentation::willInsertDOMNode(document(), newChild.get(), this);
     8 #endif
     9 
    10     forbidEventDispatch();
    11     Node* last = m_lastChild;
    12     // FIXME: This method should take a PassRefPtr.
    13     appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
    14     newChild->setTreeScopeRecursively(treeScope());
    15     
    16     allowEventDispatch();
    17 
    18     // FIXME: Why doesn't this use notifyChildInserted(newChild) instead?
    19     document()->incDOMTreeVersion();
    20     if (inDocument())
    21         newChild->insertedIntoDocument();
    22     childrenChanged(true, last, 0, 1);
    23 }

    18,ContainerNode::insertedIntoDocument()

     1 void ContainerNode::insertedIntoDocument()
     2 {
     3     RefPtr<Node> protect(this);
     4 
     5     Node::insertedIntoDocument();
     6     insertedIntoTree(false);
     7 
     8     for (RefPtr<Node> child = m_firstChild; child; child = child->nextSibling()) {
     9         // Guard against mutation during re-parenting.
    10         if (!inDocument()) // Check for self being removed from document while reparenting.
    11             break;
    12         if (child->parentNode() != this) // Check for child being removed from subtree while reparenting.
    13             break;
    14         child->insertedIntoDocument();
    15     }
    16 }

    19,HTMLFrameElementBase::insertedIntoDocument()

     1 void HTMLFrameElementBase::insertedIntoDocument()
     2 {
     3     HTMLFrameOwnerElement::insertedIntoDocument();
     4 
     5     if (m_remainsAliveOnRemovalFromTree) {
     6         updateOnReparenting();
     7         setRemainsAliveOnRemovalFromTree(false);
     8         return;
     9     }
    10     // DocumentFragments don't kick of any loads.
    11     if (!document()->frame())
    12         return;
    13 
    14     // Loads may cause synchronous javascript execution (e.g. beforeload or
    15     // src=javascript), which could try to access the renderer before the normal
    16     // parser machinery would call lazyAttach() and set us as needing style
    17     // resolve.  Any code which expects this to be attached will resolve style
    18     // before using renderer(), so this will make sure we attach in time.
    19     // FIXME: Normally lazyAttach marks the renderer as attached(), but we don't
    20     // want to do that here, as as callers expect to call attach() right after
    21     // this and attach() will ASSERT(!attached())
    22     ASSERT(!renderer()); // This recalc is unecessary if we already have a renderer.
    23     lazyAttach(DoNotSetAttached);
    24     setNameAndOpenURL();
    25 }

    20,HTMLFrameElementBase::setNameAndOpenURL()

    1 void HTMLFrameElementBase::setNameAndOpenURL()
    2 {
    3     m_frameName = getAttribute(nameAttr);
    4     if (m_frameName.isNull())
    5         m_frameName = getIdAttribute();
    6     openURL();
    7 }

    21,HTMLFrameElementBase::openURL(bool lockHistory, bool lockBackForwardList)

     1 void HTMLFrameElementBase::openURL(bool lockHistory, bool lockBackForwardList)
     2 {
     3     if (!isURLAllowed())
     4         return;
     5 
     6     if (m_URL.isEmpty())
     7         m_URL = blankURL().string();
     8 
     9     Frame* parentFrame = document()->frame();
    10     if (!parentFrame)
    11         return;
    12 
    13     parentFrame->loader()->subframeLoader()->requestFrame(this, m_URL, m_frameName, lockHistory, lockBackForwardList);
    14     if (contentFrame())
    15         contentFrame()->setInViewSourceMode(viewSourceMode());
    16 }

    22,SubframeLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const String& urlString, const AtomicString& frameName, bool lockHistory, bool lockBackForwardList)

     1 bool SubframeLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const String& urlString, const AtomicString& frameName, bool lockHistory, bool lockBackForwardList)
     2 {
     3     // Support for <frame src="javascript:string">
     4     KURL scriptURL;
     5     KURL url;
     6     if (protocolIsJavaScript(urlString)) {
     7         scriptURL = completeURL(urlString); // completeURL() encodes the URL.
     8         url = blankURL();
     9     } else
    10         url = completeURL(urlString);
    11 
    12     Frame* frame = loadOrRedirectSubframe(ownerElement, url, frameName, lockHistory, lockBackForwardList);
    13     if (!frame)
    14         return false;
    15 
    16     if (!scriptURL.isEmpty())
    17         frame->script()->executeIfJavaScriptURL(scriptURL);
    18 
    19     return true;
    20 }

    23,SubframeLoader::loadOrRedirectSubframe(HTMLFrameOwnerElement* ownerElement, const KURL& url, const AtomicString& frameName, bool lockHistory, bool lockBackForwardList)

    1 Frame* SubframeLoader::loadOrRedirectSubframe(HTMLFrameOwnerElement* ownerElement, const KURL& url, const AtomicString& frameName, bool lockHistory, bool lockBackForwardList)
    2 {
    3     Frame* frame = ownerElement->contentFrame();
    4     if (frame)
    5         frame->navigationScheduler()->scheduleLocationChange(m_frame->document()->securityOrigin(), url.string(), m_frame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList);
    6     else
    7         frame = loadSubframe(ownerElement, url, frameName, m_frame->loader()->outgoingReferrer());
    8     return frame;
    9 }

    24,SubframeLoader::loadSubframe(HTMLFrameOwnerElement* ownerElement, const KURL& url, const String& name, const String& referrer)

     1 Frame* SubframeLoader::loadSubframe(HTMLFrameOwnerElement* ownerElement, const KURL& url, const String& name, const String& referrer)
     2 {
     3     bool allowsScrolling = true;
     4     int marginWidth = -1;
     5     int marginHeight = -1;
     6     if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag)) {
     7         HTMLFrameElementBase* o = static_cast<HTMLFrameElementBase*>(ownerElement);
     8         allowsScrolling = o->scrollingMode() != ScrollbarAlwaysOff;
     9         marginWidth = o->marginWidth();
    10         marginHeight = o->marginHeight();
    11     }
    12 
    13     if (!ownerElement->document()->securityOrigin()->canDisplay(url)) {
    14         FrameLoader::reportLocalLoadFailed(m_frame, url.string());
    15         return 0;
    16     }
    17 
    18     if (!ownerElement->document()->contentSecurityPolicy()->allowChildFrameFromSource(url))
    19         return 0;
    20 
    21     bool hideReferrer = SecurityOrigin::shouldHideReferrer(url, referrer);
    22     RefPtr<Frame> frame = m_frame->loader()->client()->createFrame(url, name, ownerElement, hideReferrer ? String() : referrer, allowsScrolling, marginWidth, marginHeight);
    23 
    24     if (!frame)  {
    25         m_frame->loader()->checkCallImplicitClose();
    26         return 0;
    27     }
    28     
    29     // All new frames will have m_isComplete set to true at this point due to synchronously loading
    30     // an empty document in FrameLoader::init(). But many frames will now be starting an
    31     // asynchronous load of url, so we set m_isComplete to false and then check if the load is
    32     // actually completed below. (Note that we set m_isComplete to false even for synchronous
    33     // loads, so that checkCompleted() below won't bail early.)
    34     // FIXME: Can we remove this entirely? m_isComplete normally gets set to false when a load is committed.
    35     frame->loader()->started();
    36    
    37     RenderObject* renderer = ownerElement->renderer();
    38     FrameView* view = frame->view();
    39     if (renderer && renderer->isWidget() && view)
    40         toRenderWidget(renderer)->setWidget(view);
    41     
    42     m_frame->loader()->checkCallImplicitClose();
    43     
    44     // Some loads are performed synchronously (e.g., about:blank and loads
    45     // cancelled by returning a null ResourceRequest from requestFromDelegate).
    46     // In these cases, the synchronous load would have finished
    47     // before we could connect the signals, so make sure to send the 
    48     // completed() signal for the child by hand and mark the load as being
    49     // complete.
    50     // FIXME: In this case the Frame will have finished loading before 
    51     // it's being added to the child list. It would be a good idea to
    52     // create the child first, then invoke the loader separately.
    53     if (frame->loader()->state() == FrameStateComplete && !frame->loader()->policyDocumentLoader())
    54         frame->loader()->checkCompleted();
    55 
    56     return frame.get();
    57 }

    25,FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)

     1 PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
     2                                         const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
     3 {
     4     if (!m_webFrame)
     5         return 0;
     6 
     7     QWebFrameData frameData(m_frame->page(), m_frame, ownerElement, name);
     8 
     9     if (url.isEmpty())
    10         frameData.url = blankURL();
    11     else
    12         frameData.url = url;
    13 
    14     frameData.referrer = referrer;
    15     frameData.allowsScrolling = allowsScrolling;
    16     frameData.marginWidth = marginWidth;
    17     frameData.marginHeight = marginHeight;
    18 
    19     QPointer<QWebFrame> webFrame = new QWebFrame(m_webFrame, &frameData);
    20     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
    21     if (!webFrame->d->frame->page()) {
    22         frameData.frame.release();
    23         ASSERT(webFrame.isNull());
    24         return 0;
    25     }
    26 
    27     emit m_webFrame->page()->frameCreated(webFrame);
    28 
    29     // FIXME: Set override encoding if we have one.
    30 
    31     m_frame->loader()->loadURLIntoChildFrame(frameData.url, frameData.referrer, frameData.frame.get());
    32 
    33     // The frame's onload handler may have removed it from the document.
    34     if (!frameData.frame->tree()->parent())
    35         return 0;
    36 
    37     return frameData.frame.release();
    38 }

    26,QWebFrameData::QWebFrameData(... )

     1 QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame,
     2                              WebCore::HTMLFrameOwnerElement* ownerFrameElement,
     3                              const WTF::String& frameName)
     4     : name(frameName)
     5     , ownerElement(ownerFrameElement)
     6     , page(parentPage)
     7     , allowsScrolling(true)
     8     , marginWidth(0)
     9     , marginHeight(0)
    10 {
    11     frameLoaderClient = new FrameLoaderClientQt();
    12     frame = Frame::create(page, ownerElement, frameLoaderClient);
    13 
    14     // FIXME: All of the below should probably be moved over into WebCore
    15     frame->tree()->setName(name);
    16     if (parentFrame)
    17         parentFrame->tree()->appendChild(frame);
    18 }


    OK,代码量太庞大了,至此,代码跟踪完成!!!

    3.2  createView

    1         void createView(const IntSize&, const Color&, bool, const IntSize&, bool,
    2             ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
    3             ScrollbarMode = ScrollbarAuto, bool verticalLock = false);

    描述:
          创建出FrameView对象,以用于之后的排版。应用调用这个函数的时候需要传入同排版有关的一些信息,如初始 视窗大小、背景色、滚动条模式等。创建出FrameView以后,即调用Frame::setView设置成当前的FrameView。

    实现:

     1 void Frame::setView(PassRefPtr<FrameView> view)
     2 {
     3     // We the custom scroll bars as early as possible to prevent m_doc->detach()
     4     // from messing with the view such that its scroll bars won't be torn down.
     5     // FIXME: We should revisit this.
     6     if (m_view)
     7         m_view->detachCustomScrollbars();
     8 
     9     // Detach the document now, so any onUnload handlers get run - if
    10     // we wait until the view is destroyed, then things won't be
    11     // hooked up enough for some JavaScript calls to work.
    12     if (!view && m_doc && m_doc->attached() && !m_doc->inPageCache()) {
    13         // FIXME: We don't call willRemove here. Why is that OK?
    14         m_doc->detach();
    15     }
    16     
    17     if (m_view)
    18         m_view->unscheduleRelayout();
    19     
    20     eventHandler()->clear();
    21 
    22     m_view = view;
    23 
    24     // Only one form submission is allowed per view of a part.
    25     // Since this part may be getting reused as a result of being
    26     // pulled from the back/forward cache, reset this flag.
    27     loader()->resetMultipleFormSubmissionProtection();
    28     
    29 #if ENABLE(TILED_BACKING_STORE)
    30     if (m_view && tiledBackingStore())
    31         m_view->setPaintsEntireContents(true);
    32 #endif
    33 }

    函数调用系列:

    1 FrameLoader::commitProvisionalLoad
    2 FrameLoader::transitionToCommitted
    3 FrameLoaderClientQt::transitionToCommittedForNewPage
    4 Frame::createView

    跟踪一下代码(同上)
    1,QWebView::load(const QUrl &url)

    1 void QWebView::load(const QUrl &url)
    2 {
    3     page()->mainFrame()->load(url);
    4 }

    2,QWebFrame::load(const QNetworkRequest &req,QNetworkAccessManager::Operation operation,const QByteArray &body)

     1 void QWebFrame::load(const QNetworkRequest &req,
     2                      QNetworkAccessManager::Operation operation,
     3                      const QByteArray &body)
     4 {
     5     if (d->parentFrame())
     6         d->page->d->insideOpenCall = true;
     7 
     8     QUrl url = ensureAbsoluteUrl(req.url());
     9 
    10     WebCore::ResourceRequest request(url);
    11 
    12     switch (operation) {
    13         case QNetworkAccessManager::HeadOperation:
    14             request.setHTTPMethod("HEAD");
    15             break;
    16         case QNetworkAccessManager::GetOperation:
    17             request.setHTTPMethod("GET");
    18             break;
    19         case QNetworkAccessManager::PutOperation:
    20             request.setHTTPMethod("PUT");
    21             break;
    22         case QNetworkAccessManager::PostOperation:
    23             request.setHTTPMethod("POST");
    24             break;
    25         case QNetworkAccessManager::DeleteOperation:
    26             request.setHTTPMethod("DELETE");
    27             break;
    28         case QNetworkAccessManager::CustomOperation:
    29             request.setHTTPMethod(req.attribute(QNetworkRequest::CustomVerbAttribute).toByteArray().constData());
    30             break;
    31         case QNetworkAccessManager::UnknownOperation:
    32             // eh?
    33             break;
    34     }
    35 
    36     QVariant cacheLoad = req.attribute(QNetworkRequest::CacheLoadControlAttribute);
    37     if (cacheLoad.isValid()) {
    38         bool ok;
    39         uint cacheLoadValue = cacheLoad.toUInt(&ok);
    40         if (ok)
    41             request.setCachePolicy(cacheLoadControlToCachePolicy(cacheLoadValue));
    42     }
    43 
    44     QList<QByteArray> httpHeaders = req.rawHeaderList();
    45     for (int i = 0; i < httpHeaders.size(); ++i) {
    46         const QByteArray &headerName = httpHeaders.at(i);
    47         request.addHTTPHeaderField(QString::fromLatin1(headerName), QString::fromLatin1(req.rawHeader(headerName)));
    48     }
    49 
    50     if (!body.isEmpty())
    51         request.setHTTPBody(WebCore::FormData::create(body.constData(), body.size()));
    52 
    53     d->frame->loader()->load(request, false);
    54 
    55     if (d->parentFrame())
    56         d->page->d->insideOpenCall = false;
    57 }

    3, FrameLoader::load(const ResourceRequest& request, bool lockHistory)

    1 void FrameLoader::load(const ResourceRequest& request, bool lockHistory)
    2 {
    3     load(request, SubstituteData(), lockHistory);
    4 }

    4,FrameLoader::load(const ResourceRequest& request, const SubstituteData& substituteData, bool lockHistory)

     1 void FrameLoader::load(const ResourceRequest& request, const SubstituteData& substituteData, bool lockHistory)
     2 {
     3     if (m_inStopAllLoaders)
     4         return;
     5         
     6     // FIXME: is this the right place to reset loadType? Perhaps this should be done after loading is finished or aborted.
     7     m_loadType = FrameLoadTypeStandard;
     8     RefPtr<DocumentLoader> loader = m_client->createDocumentLoader(request, substituteData);
     9     if (lockHistory && m_documentLoader)
    10         loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
    11     load(loader.get());
    12 }

    5,FrameLoader::load(DocumentLoader* newDocumentLoader)

     1 void FrameLoader::load(DocumentLoader* newDocumentLoader)
     2 {
     3     ResourceRequest& r = newDocumentLoader->request();
     4     addExtraFieldsToMainResourceRequest(r);
     5     FrameLoadType type;
     6 
     7     if (shouldTreatURLAsSameAsCurrent(newDocumentLoader->originalRequest().url())) {
     8         r.setCachePolicy(ReloadIgnoringCacheData);
     9         type = FrameLoadTypeSame;
    10     } else
    11         type = FrameLoadTypeStandard;
    12 
    13     if (m_documentLoader)
    14         newDocumentLoader->setOverrideEncoding(m_documentLoader->overrideEncoding());
    15     
    16     // When we loading alternate content for an unreachable URL that we're
    17     // visiting in the history list, we treat it as a reload so the history list 
    18     // is appropriately maintained.
    19     //
    20     // FIXME: This seems like a dangerous overloading of the meaning of "FrameLoadTypeReload" ...
    21     // shouldn't a more explicit type of reload be defined, that means roughly 
    22     // "load without affecting history" ? 
    23     if (shouldReloadToHandleUnreachableURL(newDocumentLoader)) {
    24         // shouldReloadToHandleUnreachableURL() returns true only when the original load type is back-forward.
    25         // In this case we should save the document state now. Otherwise the state can be lost because load type is
    26         // changed and updateForBackForwardNavigation() will not be called when loading is committed.
    27         history()->saveDocumentAndScrollState();
    28 
    29         ASSERT(type == FrameLoadTypeStandard);
    30         type = FrameLoadTypeReload;
    31     }
    32 
    33     loadWithDocumentLoader(newDocumentLoader, type, 0);
    34 }

    6,FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType type, PassRefPtr<FormState> prpFormState)

     1 void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType type, PassRefPtr<FormState> prpFormState)
     2 {
     3     // Retain because dispatchBeforeLoadEvent may release the last reference to it.
     4     RefPtr<Frame> protect(m_frame);
     5 
     6     ASSERT(m_client->hasWebView());
     7 
     8     // Unfortunately the view must be non-nil, this is ultimately due
     9     // to parser requiring a FrameView.  We should fix this dependency.
    10 
    11     ASSERT(m_frame->view());
    12 
    13     if (m_pageDismissalEventBeingDispatched)
    14         return;
    15 
    16     if (m_frame->document())
    17         m_previousUrl = m_frame->document()->url();
    18 
    19     policyChecker()->setLoadType(type);
    20     RefPtr<FormState> formState = prpFormState;
    21     bool isFormSubmission = formState;
    22 
    23     const KURL& newURL = loader->request().url();
    24     const String& httpMethod = loader->request().httpMethod();
    25 
    26     if (shouldScrollToAnchor(isFormSubmission,  httpMethod, policyChecker()->loadType(), newURL)) {
    27         RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
    28         NavigationAction action(newURL, policyChecker()->loadType(), isFormSubmission);
    29 
    30         oldDocumentLoader->setTriggeringAction(action);
    31         policyChecker()->stopCheck();
    32         policyChecker()->checkNavigationPolicy(loader->request(), oldDocumentLoader.get(), formState,
    33             callContinueFragmentScrollAfterNavigationPolicy, this);
    34     } else {
    35         if (Frame* parent = m_frame->tree()->parent())
    36             loader->setOverrideEncoding(parent->loader()->documentLoader()->overrideEncoding());
    37 
    38         policyChecker()->stopCheck();
    39         setPolicyDocumentLoader(loader);
    40         if (loader->triggeringAction().isEmpty())
    41             loader->setTriggeringAction(NavigationAction(newURL, policyChecker()->loadType(), isFormSubmission));
    42 
    43         if (Element* ownerElement = m_frame->ownerElement()) {
    44             // We skip dispatching the beforeload event if we've already
    45             // committed a real document load because the event would leak
    46             // subsequent activity by the frame which the parent frame isn't
    47             // supposed to learn. For example, if the child frame navigated to
    48             // a new URL, the parent frame shouldn't learn the URL.
    49             if (!m_stateMachine.committedFirstRealDocumentLoad()
    50                 && !ownerElement->dispatchBeforeLoadEvent(loader->request().url().string())) {
    51                 continueLoadAfterNavigationPolicy(loader->request(), formState, false);
    52                 return;
    53             }
    54         }
    55 
    56         policyChecker()->checkNavigationPolicy(loader->request(), loader, formState,
    57             callContinueLoadAfterNavigationPolicy, this);
    58     }
    59 }

    7,FrameLoader::callContinueLoadAfterNavigationPolicy( ... )

    1 void FrameLoader::callContinueLoadAfterNavigationPolicy(void* argument,
    2     const ResourceRequest& request, PassRefPtr<FormState> formState, bool shouldContinue)
    3 {
    4     FrameLoader* loader = static_cast<FrameLoader*>(argument);
    5     loader->continueLoadAfterNavigationPolicy(request, formState, shouldContinue);
    6 }

    8,FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState> formState, bool shouldContinue)

     1 void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState> formState, bool shouldContinue)
     2 {
     3     // If we loaded an alternate page to replace an unreachableURL, we'll get in here with a
     4     // nil policyDataSource because loading the alternate page will have passed
     5     // through this method already, nested; otherwise, policyDataSource should still be set.
     6     ASSERT(m_policyDocumentLoader || !m_provisionalDocumentLoader->unreachableURL().isEmpty());
     7 
     8     bool isTargetItem = history()->provisionalItem() ? history()->provisionalItem()->isTargetItem() : false;
     9 
    10     // Two reasons we can't continue:
    11     //    1) Navigation policy delegate said we can't so request is nil. A primary case of this 
    12     //       is the user responding Cancel to the form repost nag sheet.
    13     //    2) User responded Cancel to an alert popped up by the before unload event handler.
    14     bool canContinue = shouldContinue && shouldClose();
    15 
    16     if (!canContinue) {
    17         // If we were waiting for a quick redirect, but the policy delegate decided to ignore it, then we 
    18         // need to report that the client redirect was cancelled.
    19         if (m_quickRedirectComing)
    20             clientRedirectCancelledOrFinished(false);
    21 
    22         setPolicyDocumentLoader(0);
    23 
    24         // If the navigation request came from the back/forward menu, and we punt on it, we have the 
    25         // problem that we have optimistically moved the b/f cursor already, so move it back.  For sanity, 
    26         // we only do this when punting a navigation for the target frame or top-level frame.  
    27         if ((isTargetItem || isLoadingMainFrame()) && isBackForwardLoadType(policyChecker()->loadType())) {
    28             if (Page* page = m_frame->page()) {
    29                 Frame* mainFrame = page->mainFrame();
    30                 if (HistoryItem* resetItem = mainFrame->loader()->history()->currentItem()) {
    31                     page->backForward()->setCurrentItem(resetItem);
    32                     m_frame->loader()->client()->updateGlobalHistoryItemForPage();
    33                 }
    34             }
    35         }
    36         return;
    37     }
    38 
    39     FrameLoadType type = policyChecker()->loadType();
    40     // A new navigation is in progress, so don't clear the history's provisional item.
    41     stopAllLoaders(ShouldNotClearProvisionalItem);
    42     
    43     // <rdar://problem/6250856> - In certain circumstances on pages with multiple frames, stopAllLoaders()
    44     // might detach the current FrameLoader, in which case we should bail on this newly defunct load. 
    45     if (!m_frame->page())
    46         return;
    47 
    48 #if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) && ENABLE(INSPECTOR)
    49     if (Page* page = m_frame->page()) {
    50         if (page->mainFrame() == m_frame)
    51             m_frame->page()->inspectorController()->resume();
    52     }
    53 #endif
    54 
    55     setProvisionalDocumentLoader(m_policyDocumentLoader.get());
    56     m_loadType = type;
    57     setState(FrameStateProvisional);
    58 
    59     setPolicyDocumentLoader(0);
    60 
    61     if (isBackForwardLoadType(type) && history()->provisionalItem()->isInPageCache()) {
    62         loadProvisionalItemFromCachedPage();
    63         return;
    64     }
    65 
    66     if (formState)
    67         m_client->dispatchWillSubmitForm(&PolicyChecker::continueLoadAfterWillSubmitForm, formState);
    68     else
    69         continueLoadAfterWillSubmitForm();
    70 }

    9,FrameLoader::loadProvisionalItemFromCachedPage()

     1 void FrameLoader::loadProvisionalItemFromCachedPage()
     2 {
     3     DocumentLoader* provisionalLoader = provisionalDocumentLoader();
     4     LOG(PageCache, "WebCorePageCache: Loading provisional DocumentLoader %p with URL '%s' from CachedPage", provisionalDocumentLoader(), provisionalDocumentLoader()->url().string().utf8().data());
     5 
     6     provisionalLoader->prepareForLoadStart();
     7 
     8     m_loadingFromCachedPage = true;
     9     
    10     // Should have timing data from previous time(s) the page was shown.
    11     ASSERT(provisionalLoader->timing()->navigationStart);
    12     provisionalLoader->resetTiming();
    13     provisionalLoader->timing()->navigationStart = currentTime();    
    14 
    15     provisionalLoader->setCommitted(true);
    16     commitProvisionalLoad();
    17 }

    10,FrameLoader::commitProvisionalLoad()

     1 void FrameLoader::commitProvisionalLoad()
     2 {
     3     RefPtr<CachedPage> cachedPage = m_loadingFromCachedPage ? pageCache()->get(history()->provisionalItem()) : 0;
     4     RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
     5 
     6     LOG(PageCache, "WebCoreLoading %s: About to commit provisional load from previous URL '%s' to new URL '%s'", m_frame->tree()->uniqueName().string().utf8().data(),
     7         m_frame->document() ? m_frame->document()->url().string().utf8().data() : "", 
     8         pdl ? pdl->url().string().utf8().data() : "<no provisional DocumentLoader>");
     9 
    10     // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
    11     // We are doing this here because we know for sure that a new page is about to be loaded.
    12     HistoryItem* item = history()->currentItem();
    13     if (!m_frame->tree()->parent() && PageCache::canCache(m_frame->page()) && !item->isInPageCache())
    14         pageCache()->add(item, m_frame->page());
    15 
    16     if (m_loadType != FrameLoadTypeReplace)
    17         closeOldDataSources();
    18 
    19     if (!cachedPage && !m_stateMachine.creatingInitialEmptyDocument())
    20         m_client->makeRepresentation(pdl.get());
    21 
    22     transitionToCommitted(cachedPage);
    23 
    24     if (pdl) {
    25         // Check if the destination page is allowed to access the previous page's timing information.
    26         RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::create(pdl->request().url());
    27         m_documentLoader->timing()->hasSameOriginAsPreviousDocument = securityOrigin->canRequest(m_previousUrl);
    28     }
    29 
    30     // Call clientRedirectCancelledOrFinished() here so that the frame load delegate is notified that the redirect's
    31     // status has changed, if there was a redirect.  The frame load delegate may have saved some state about
    32     // the redirect in its -webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:.  Since we are
    33     // just about to commit a new page, there cannot possibly be a pending redirect at this point.
    34     if (m_sentRedirectNotification)
    35         clientRedirectCancelledOrFinished(false);
    36     
    37     if (cachedPage && cachedPage->document()) {
    38         prepareForCachedPageRestore();
    39         cachedPage->restore(m_frame->page());
    40 
    41         dispatchDidCommitLoad();
    42 
    43         // If we have a title let the WebView know about it. 
    44         StringWithDirection title = m_documentLoader->title();
    45         if (!title.isNull())
    46             m_client->dispatchDidReceiveTitle(title);
    47 
    48         checkCompleted();
    49     } else {        
    50         KURL url = pdl->substituteData().responseURL();
    51         if (url.isEmpty())
    52             url = pdl->url();
    53         if (url.isEmpty())
    54             url = pdl->responseURL();
    55         if (url.isEmpty())
    56             url = blankURL();
    57 
    58         didOpenURL(url);
    59     }
    60 
    61     LOG(Loading, "WebCoreLoading %s: Finished committing provisional load to URL %s", m_frame->tree()->uniqueName().string().utf8().data(),
    62         m_frame->document() ? m_frame->document()->url().string().utf8().data() : "");
    63 
    64     if (m_loadType == FrameLoadTypeStandard && m_documentLoader->isClientRedirect())
    65         history()->updateForClientRedirect();
    66 
    67     if (m_loadingFromCachedPage) {
    68         m_frame->document()->documentDidBecomeActive();
    69         
    70         // Force a layout to update view size and thereby update scrollbars.
    71         m_frame->view()->forceLayout();
    72 
    73         const ResponseVector& responses = m_documentLoader->responses();
    74         size_t count = responses.size();
    75         for (size_t i = 0; i < count; i++) {
    76             const ResourceResponse& response = responses[i];
    77             // FIXME: If the WebKit client changes or cancels the request, this is not respected.
    78             ResourceError error;
    79             unsigned long identifier;
    80             ResourceRequest request(response.url());
    81             requestFromDelegate(request, identifier, error);
    82             // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
    83             // However, with today's computers and networking speeds, this won't happen in practice.
    84             // Could be an issue with a giant local file.
    85             notifier()->sendRemainingDelegateMessages(m_documentLoader.get(), identifier, response, static_cast<int>(response.expectedContentLength()), 0, error);
    86         }
    87         
    88         pageCache()->remove(history()->currentItem());
    89 
    90         m_documentLoader->setPrimaryLoadComplete(true);
    91 
    92         // FIXME: Why only this frame and not parent frames?
    93         checkLoadCompleteForThisFrame();
    94     }
    95 }

    11,FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage)

      1 void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage)
      2 {
      3     ASSERT(m_client->hasWebView());
      4     ASSERT(m_state == FrameStateProvisional);
      5 
      6     if (m_state != FrameStateProvisional)
      7         return;
      8 
      9     if (m_frame->view())
     10         m_frame->view()->scrollAnimator()->cancelAnimations();
     11 
     12     m_client->setCopiesOnScroll();
     13     history()->updateForCommit();
     14 
     15     // The call to closeURL() invokes the unload event handler, which can execute arbitrary
     16     // JavaScript. If the script initiates a new load, we need to abandon the current load,
     17     // or the two will stomp each other.
     18     DocumentLoader* pdl = m_provisionalDocumentLoader.get();
     19     if (m_documentLoader)
     20         closeURL();
     21     if (pdl != m_provisionalDocumentLoader)
     22         return;
     23 
     24     // Nothing else can interupt this commit - set the Provisional->Committed transition in stone
     25     if (m_documentLoader)
     26         m_documentLoader->stopLoadingSubresources();
     27     if (m_documentLoader)
     28         m_documentLoader->stopLoadingPlugIns();
     29 
     30     setDocumentLoader(m_provisionalDocumentLoader.get());
     31     setProvisionalDocumentLoader(0);
     32     setState(FrameStateCommittedPage);
     33 
     34     // Handle adding the URL to the back/forward list.
     35     DocumentLoader* dl = m_documentLoader.get();
     36 
     37     switch (m_loadType) {
     38         case FrameLoadTypeForward:
     39         case FrameLoadTypeBack:
     40         case FrameLoadTypeIndexedBackForward:
     41             if (m_frame->page()) {
     42                 // If the first load within a frame is a navigation within a back/forward list that was attached
     43                 // without any of the items being loaded then we need to update the history in a similar manner as
     44                 // for a standard load with the exception of updating the back/forward list (<rdar://problem/8091103>).
     45                 if (!m_stateMachine.committedFirstRealDocumentLoad())
     46                     history()->updateForStandardLoad(HistoryController::UpdateAllExceptBackForwardList);
     47 
     48                 history()->updateForBackForwardNavigation();
     49 
     50                 // For cached pages, CachedFrame::restore will take care of firing the popstate event with the history item's state object
     51                 if (history()->currentItem() && !cachedPage)
     52                     m_pendingStateObject = history()->currentItem()->stateObject();
     53 
     54                 // Create a document view for this document, or used the cached view.
     55                 if (cachedPage) {
     56                     DocumentLoader* cachedDocumentLoader = cachedPage->documentLoader();
     57                     ASSERT(cachedDocumentLoader);
     58                     cachedDocumentLoader->setFrame(m_frame);
     59                     m_client->transitionToCommittedFromCachedFrame(cachedPage->cachedMainFrame());
     60 
     61                 } else
     62                     m_client->transitionToCommittedForNewPage();
     63             }
     64             break;
     65 
     66         case FrameLoadTypeReload:
     67         case FrameLoadTypeReloadFromOrigin:
     68         case FrameLoadTypeSame:
     69         case FrameLoadTypeReplace:
     70             history()->updateForReload();
     71             m_client->transitionToCommittedForNewPage();
     72             break;
     73 
     74         case FrameLoadTypeStandard:
     75             history()->updateForStandardLoad();
     76             if (m_frame->view())
     77                 m_frame->view()->setScrollbarsSuppressed(true);
     78             m_client->transitionToCommittedForNewPage();
     79             break;
     80 
     81         case FrameLoadTypeRedirectWithLockedBackForwardList:
     82             history()->updateForRedirectWithLockedBackForwardList();
     83             m_client->transitionToCommittedForNewPage();
     84             break;
     85 
     86         // FIXME Remove this check when dummy ds is removed (whatever "dummy ds" is).
     87         // An exception should be thrown if we're in the FrameLoadTypeUninitialized state.
     88         default:
     89             ASSERT_NOT_REACHED();
     90     }
     91 
     92     m_documentLoader->writer()->setMIMEType(dl->responseMIMEType());
     93 
     94     // Tell the client we've committed this URL.
     95     ASSERT(m_frame->view());
     96 
     97     if (m_stateMachine.creatingInitialEmptyDocument())
     98         return;
     99 
    100     if (!m_stateMachine.committedFirstRealDocumentLoad())
    101         m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
    102 
    103     if (!m_client->hasHTMLView())
    104         receivedFirstData();
    105 }

    12,FrameLoaderClientQt::transitionToCommittedForNewPage()

     1 void FrameLoaderClientQt::transitionToCommittedForNewPage()
     2 {
     3     ASSERT(m_frame);
     4     ASSERT(m_webFrame);
     5 
     6     QBrush brush = m_webFrame->page()->palette().brush(QPalette::Base);
     7     QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
     8 
     9     QWebPage* page = m_webFrame->page();
    10     const QSize preferredLayoutSize = page->preferredContentsSize();
    11 
    12     ScrollbarMode hScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Horizontal);
    13     ScrollbarMode vScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Vertical);
    14     bool hLock = hScrollbar != ScrollbarAuto;
    15     bool vLock = vScrollbar != ScrollbarAuto;
    16 
    17     IntSize currentVisibleContentSize = m_frame->view() ? m_frame->view()->actualVisibleContentRect().size() : IntSize();
    18 
    19     m_frame->createView(m_webFrame->page()->viewportSize(),
    20                         backgroundColor, !backgroundColor.alpha(),
    21                         preferredLayoutSize.isValid() ? IntSize(preferredLayoutSize) : IntSize(),
    22                         preferredLayoutSize.isValid(),
    23                         hScrollbar, hLock,
    24                         vScrollbar, vLock);
    25 
    26     bool isMainFrame = m_frame == m_frame->page()->mainFrame();
    27     if (isMainFrame && page->d->client) {
    28         m_frame->view()->setPaintsEntireContents(page->d->client->viewResizesToContentsEnabled());
    29         m_frame->view()->setDelegatesScrolling(page->d->client->viewResizesToContentsEnabled());
    30     }
    31 
    32     // The HistoryController will update the scroll position later if needed.
    33     m_frame->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize));
    34 }

    13,Frame::createView( ... )

    14,Frame::setView(PassRefPtr<FrameView> view)

     1 void Frame::setView(PassRefPtr<FrameView> view)
     2 {
     3     // We the custom scroll bars as early as possible to prevent m_doc->detach()
     4     // from messing with the view such that its scroll bars won't be torn down.
     5     // FIXME: We should revisit this.
     6     if (m_view)
     7         m_view->detachCustomScrollbars();
     8 
     9     // Detach the document now, so any onUnload handlers get run - if
    10     // we wait until the view is destroyed, then things won't be
    11     // hooked up enough for some JavaScript calls to work.
    12     if (!view && m_doc && m_doc->attached() && !m_doc->inPageCache()) {
    13         // FIXME: We don't call willRemove here. Why is that OK?
    14         m_doc->detach();
    15     }
    16     
    17     if (m_view)
    18         m_view->unscheduleRelayout();
    19     
    20     eventHandler()->clear();
    21 
    22     m_view = view;
    23 
    24     // Only one form submission is allowed per view of a part.
    25     // Since this part may be getting reused as a result of being
    26     // pulled from the back/forward cache, reset this flag.
    27     loader()->resetMultipleFormSubmissionProtection();
    28     
    29 #if ENABLE(TILED_BACKING_STORE)
    30     if (m_view && tiledBackingStore())
    31         m_view->setPaintsEntireContents(true);
    32 #endif
    33 }

    OK!!! CreateView代码跟踪到此为止!!

    3.3 setDocument

    1 void setDocument(PassRefPtr<Document>);

    描述:

        置同Frame关联的Document对象(一般是DocumentWriter创建的)。还是两种情况

    实现:

     1 void Frame::setDocument(PassRefPtr<Document> newDoc)
     2 {
     3     ASSERT(!newDoc || newDoc->frame());
     4     if (m_doc && m_doc->attached() && !m_doc->inPageCache()) {
     5         // FIXME: We don't call willRemove here. Why is that OK?
     6         m_doc->detach();
     7     }
     8 
     9     m_doc = newDoc;
    10     selection()->updateSecureKeyboardEntryIfActive();
    11 
    12     if (m_doc && !m_doc->attached())
    13         m_doc->attach();
    14 
    15     // Update the cached 'document' property, which is now stale.
    16     m_script.updateDocument();
    17 
    18     if (m_page)
    19         m_page->updateViewportArguments();
    20 }

    函数调用系列:

     1 QWebFrame::QwebFrame
     2 QwebFramePrivate::init
     3 Frame::init
     4 FrameLoader::init
     5 DocumentWriter::begin
     6 Frame::setDocument
     7 
     8 
     9 DocumentLoader::receivedData
    10 DocumentLoader::commitLoad
    11 FrameLoaderClientQt::committedLoad
    12 DocumentLoader::commitData
    13 DocumentWriter::setEncoding
    14 DocumentWriter::willSetEncoding
    15 FrameLoader::receivedFirstData
    16 DocumentWriter::begin
    17 FrameLoader::clear
    18 Frame::setDocument

    代码跟踪(分两种)
    情况一:

    1,QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData)

     1 QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData)
     2     : QObject(parent)
     3     , d(new QWebFramePrivate)
     4 {
     5     d->page = parent->d->page;
     6     d->init(this, frameData);
     7 #if ENABLE(ORIENTATION_EVENTS) && ENABLE(DEVICE_ORIENTATION)
     8     connect(&d->m_orientation, SIGNAL(readingChanged()), this, SLOT(_q_orientationChanged()));
     9     d->m_orientation.start();
    10 #endif
    11 }

    2,QWebFramePrivate::init(QWebFrame *qframe, QWebFrameData *frameData)

     1 void QWebFramePrivate::init(QWebFrame *qframe, QWebFrameData *frameData)
     2 {
     3     q = qframe;
     4 
     5     allowsScrolling = frameData->allowsScrolling;
     6     marginWidth = frameData->marginWidth;
     7     marginHeight = frameData->marginHeight;
     8     frame = frameData->frame.get();
     9     frameLoaderClient = frameData->frameLoaderClient;
    10     frameLoaderClient->setFrame(qframe, frame);
    11 
    12     frame->init();
    13 }

    3,Frame::init()

    1  inline void Frame::init()
    2 {
    3     m_loader.init();
    4 }

    4,FrameLoader::init()

     1 void FrameLoader::init()
     2 {
     3     // Propagate sandbox attributes to this Frameloader and its descendants.
     4     // This needs to be done early, so that an initial document gets correct sandbox flags in its SecurityOrigin.
     5     updateSandboxFlags();
     6 
     7     // this somewhat odd set of steps is needed to give the frame an initial empty document
     8     m_stateMachine.advanceTo(FrameLoaderStateMachine::CreatingInitialEmptyDocument);
     9     setPolicyDocumentLoader(m_client->createDocumentLoader(ResourceRequest(KURL(ParsedURLString, "")), SubstituteData()).get());
    10     setProvisionalDocumentLoader(m_policyDocumentLoader.get());
    11     setState(FrameStateProvisional);
    12     m_provisionalDocumentLoader->setResponse(ResourceResponse(KURL(), "text/html", 0, String(), String()));
    13     m_provisionalDocumentLoader->finishedLoading();
    14     m_documentLoader->writer()->begin(KURL(), false);
    15     m_documentLoader->writer()->end();
    16     m_frame->document()->cancelParsing();
    17     m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);
    18     m_didCallImplicitClose = true;
    19 
    20     m_networkingContext = m_client->createNetworkingContext();
    21 }

    5,DocumentWriter::begin(const KURL& urlReference, bool dispatch, SecurityOrigin* origin)

     1 void DocumentWriter::begin(const KURL& urlReference, bool dispatch, SecurityOrigin* origin)
     2 {
     3     // We need to take a reference to the security origin because |clear|
     4     // might destroy the document that owns it.
     5     RefPtr<SecurityOrigin> forcedSecurityOrigin = origin;
     6 
     7     // We grab a local copy of the URL because it's easy for callers to supply
     8     // a URL that will be deallocated during the execution of this function.
     9     // For example, see <https://bugs.webkit.org/show_bug.cgi?id=66360>.
    10     KURL url = urlReference;
    11 
    12     // Create a new document before clearing the frame, because it may need to
    13     // inherit an aliased security context.
    14     RefPtr<Document> document = createDocument(url);
    15     
    16     // If the new document is for a Plugin but we're supposed to be sandboxed from Plugins,
    17     // then replace the document with one whose parser will ignore the incoming data (bug 39323)
    18     if (document->isPluginDocument() && m_frame->loader()->isSandboxed(SandboxPlugins))
    19         document = SinkDocument::create(m_frame, url);
    20 
    21     // FIXME: Do we need to consult the content security policy here about blocked plug-ins?
    22 
    23     bool resetScripting = !(m_frame->loader()->stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->document()->securityOrigin()->isSecureTransitionTo(url));
    24     m_frame->loader()->clear(resetScripting, resetScripting);
    25     clear();
    26     if (resetScripting)
    27         m_frame->script()->updatePlatformScriptObjects();
    28 
    29     m_frame->loader()->setOutgoingReferrer(url);
    30     m_frame->setDocument(document);
    31 
    32     if (m_decoder)
    33         document->setDecoder(m_decoder.get());
    34     if (forcedSecurityOrigin)
    35         document->setSecurityOrigin(forcedSecurityOrigin.get());
    36 
    37     m_frame->domWindow()->setURL(document->url());
    38     m_frame->domWindow()->setSecurityOrigin(document->securityOrigin());
    39 
    40     m_frame->loader()->didBeginDocument(dispatch);
    41 
    42     document->implicitOpen();
    43 
    44     if (m_frame->view() && m_frame->loader()->client()->hasHTMLView())
    45         m_frame->view()->setContentsSize(IntSize());
    46 }

    6,Frame::setDocument(PassRefPtr<Document> newDoc)

    情况二:

    1,MainResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, bool allAtOnce)

     1 void MainResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, bool allAtOnce)
     2 {
     3     ASSERT(data);
     4     ASSERT(length != 0);
     5 
     6     ASSERT(!m_response.isNull());
     7 
     8 #if USE(CFNETWORK) || PLATFORM(MAC)
     9     // Workaround for <rdar://problem/6060782>
    10     if (m_response.isNull()) {
    11         m_response = ResourceResponse(KURL(), "text/html", 0, String(), String());
    12         if (DocumentLoader* documentLoader = frameLoader()->activeDocumentLoader())
    13             documentLoader->setResponse(m_response);
    14     }
    15 #endif
    16 
    17     // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
    18     // See <rdar://problem/6304600> for more details.
    19 #if !USE(CF)
    20     ASSERT(!defersLoading());
    21 #endif
    22  
    23  #if ENABLE(OFFLINE_WEB_APPLICATIONS)
    24     documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, encodedDataLength, allAtOnce);
    25 #endif
    26 
    27     // The additional processing can do anything including possibly removing the last
    28     // reference to this object; one example of this is 3266216.
    29     RefPtr<MainResourceLoader> protect(this);
    30 
    31     m_timeOfLastDataReceived = currentTime();
    32 
    33     ResourceLoader::didReceiveData(data, length, encodedDataLength, allAtOnce);
    34 }

    2,ResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, bool allAtOnce)

     1 void ResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, bool allAtOnce)
     2 {
     3     // The following assertions are not quite valid here, since a subclass
     4     // might override didReceiveData in a way that invalidates them. This
     5     // happens with the steps listed in 3266216
     6     // ASSERT(con == connection);
     7     // ASSERT(!m_reachedTerminalState);
     8 
     9     // Protect this in this delegate method since the additional processing can do
    10     // anything including possibly derefing this; one example of this is Radar 3266216.
    11     RefPtr<ResourceLoader> protector(this);
    12 
    13     addData(data, length, allAtOnce);
    14     // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
    15     // However, with today's computers and networking speeds, this won't happen in practice.
    16     // Could be an issue with a giant local file.
    17     if (m_sendResourceLoadCallbacks && m_frame)
    18         frameLoader()->notifier()->didReceiveData(this, data, length, static_cast<int>(encodedDataLength));
    19 }

    3,MainResourceLoader::addData(const char* data, int length, bool allAtOnce)

    1 void MainResourceLoader::addData(const char* data, int length, bool allAtOnce)
    2 {
    3     ResourceLoader::addData(data, length, allAtOnce);
    4     documentLoader()->receivedData(data, length);
    5 }

    4,DocumentLoader::receivedData(const char* data, int length)

    1 void DocumentLoader::receivedData(const char* data, int length)
    2 {    
    3     m_gotFirstByte = true;
    4     if (doesProgressiveLoad(m_response.mimeType()))
    5         commitLoad(data, length);
    6 }

    5,DocumentLoader::commitLoad(const char* data, int length)

     1 void DocumentLoader::commitLoad(const char* data, int length)
     2 {
     3     // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource
     4     // by starting a new load, so retain temporarily.
     5     RefPtr<Frame> protectFrame(m_frame);
     6     RefPtr<DocumentLoader> protectLoader(this);
     7 
     8     commitIfReady();
     9     FrameLoader* frameLoader = DocumentLoader::frameLoader();
    10     if (!frameLoader)
    11         return;
    12 #if ENABLE(WEB_ARCHIVE)
    13     if (ArchiveFactory::isArchiveMimeType(response().mimeType()))
    14         return;
    15 #endif
    16     frameLoader->client()->committedLoad(this, data, length);
    17 }

    6,FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length)

     1 void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length)
     2 {
     3     if (!m_pluginView)
     4         loader->commitData(data, length);
     5     
     6     // We re-check here as the plugin can have been created.
     7     if (m_pluginView && m_pluginView->isPluginView()) {
     8         if (!m_hasSentResponseToPlugin) {
     9             m_pluginView->didReceiveResponse(loader->response());
    10             // The function didReceiveResponse sets up a new stream to the plug-in.
    11             // On a full-page plug-in, a failure in setting up this stream can cause the
    12             // main document load to be cancelled, setting m_pluginView to null.
    13             if (!m_pluginView)
    14                 return;
    15             m_hasSentResponseToPlugin = true;
    16         }
    17         m_pluginView->didReceiveData(data, length);
    18     }
    19 }

    7,DocumentLoader::commitData(const char* bytes, int length)

     1 void DocumentLoader::commitData(const char* bytes, int length)
     2 {
     3     // Set the text encoding.  This is safe to call multiple times.
     4     bool userChosen = true;
     5     String encoding = overrideEncoding();
     6     if (encoding.isNull()) {
     7         userChosen = false;
     8         encoding = response().textEncodingName();
     9     }
    10     m_writer.setEncoding(encoding, userChosen);
    11     ASSERT(m_frame->document()->parsing());
    12     m_writer.addData(bytes, length);
    13 }

    8,DocumentWriter::setEncoding(const String& name, bool userChosen)

    1 void DocumentWriter::setEncoding(const String& name, bool userChosen)
    2 {
    3     m_frame->loader()->willSetEncoding();
    4     m_encoding = name;
    5     m_encodingWasChosenByUser = userChosen;
    6 }

    9,FrameLoader::willSetEncoding()

    1 void FrameLoader::willSetEncoding()
    2 {
    3     if (!m_workingURL.isEmpty())
    4         receivedFirstData();
    5 }

    10,FrameLoader::receivedFirstData()

     1 void FrameLoader::receivedFirstData()
     2 {
     3     activeDocumentLoader()->writer()->begin(m_workingURL, false);
     4     activeDocumentLoader()->writer()->setDocumentWasLoadedAsPartOfNavigation();
     5 
     6     dispatchDidCommitLoad();
     7     dispatchDidClearWindowObjectsInAllWorlds();
     8     
     9     if (m_documentLoader) {
    10         StringWithDirection ptitle = m_documentLoader->title();
    11         // If we have a title let the WebView know about it.
    12         if (!ptitle.isNull())
    13             m_client->dispatchDidReceiveTitle(ptitle);
    14     }
    15 
    16     m_workingURL = KURL();
    17 
    18     double delay;
    19     String url;
    20     if (!m_documentLoader)
    21         return;
    22     if (m_frame->inViewSourceMode())
    23         return;
    24     if (!parseHTTPRefresh(m_documentLoader->response().httpHeaderField("Refresh"), false, delay, url))
    25         return;
    26 
    27     if (url.isEmpty())
    28         url = m_frame->document()->url().string();
    29     else
    30         url = m_frame->document()->completeURL(url).string();
    31 
    32     m_frame->navigationScheduler()->scheduleRedirect(delay, url);
    33 }

    11,DocumentWriter::begin(const KURL& urlReference, bool dispatch, SecurityOrigin* origin)

     1 void DocumentWriter::begin(const KURL& urlReference, bool dispatch, SecurityOrigin* origin)
     2 {
     3     // We need to take a reference to the security origin because |clear|
     4     // might destroy the document that owns it.
     5     RefPtr<SecurityOrigin> forcedSecurityOrigin = origin;
     6 
     7     // We grab a local copy of the URL because it's easy for callers to supply
     8     // a URL that will be deallocated during the execution of this function.
     9     // For example, see <https://bugs.webkit.org/show_bug.cgi?id=66360>.
    10     KURL url = urlReference;
    11 
    12     // Create a new document before clearing the frame, because it may need to
    13     // inherit an aliased security context.
    14     RefPtr<Document> document = createDocument(url);
    15     
    16     // If the new document is for a Plugin but we're supposed to be sandboxed from Plugins,
    17     // then replace the document with one whose parser will ignore the incoming data (bug 39323)
    18     if (document->isPluginDocument() && m_frame->loader()->isSandboxed(SandboxPlugins))
    19         document = SinkDocument::create(m_frame, url);
    20 
    21     // FIXME: Do we need to consult the content security policy here about blocked plug-ins?
    22 
    23     bool resetScripting = !(m_frame->loader()->stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->document()->securityOrigin()->isSecureTransitionTo(url));
    24     m_frame->loader()->clear(resetScripting, resetScripting);
    25     clear();
    26     if (resetScripting)
    27         m_frame->script()->updatePlatformScriptObjects();
    28 
    29     m_frame->loader()->setOutgoingReferrer(url);
    30     m_frame->setDocument(document);
    31 
    32     if (m_decoder)
    33         document->setDecoder(m_decoder.get());
    34     if (forcedSecurityOrigin)
    35         document->setSecurityOrigin(forcedSecurityOrigin.get());
    36 
    37     m_frame->domWindow()->setURL(document->url());
    38     m_frame->domWindow()->setSecurityOrigin(document->securityOrigin());
    39 
    40     m_frame->loader()->didBeginDocument(dispatch);
    41 
    42     document->implicitOpen();
    43 
    44     if (m_frame->view() && m_frame->loader()->client()->hasHTMLView())
    45         m_frame->view()->setContentsSize(IntSize());
    46 }

    12,FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects, bool clearFrameView)

     1 void FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects, bool clearFrameView)
     2 {
     3     m_frame->editor()->clear();
     4 
     5     if (!m_needsClear)
     6         return;
     7     m_needsClear = false;
     8     
     9     if (!m_frame->document()->inPageCache()) {
    10         m_frame->document()->cancelParsing();
    11         m_frame->document()->stopActiveDOMObjects();
    12         if (m_frame->document()->attached()) {
    13             m_frame->document()->willRemove();
    14             m_frame->document()->detach();
    15             
    16             m_frame->document()->removeFocusedNodeOfSubtree(m_frame->document());
    17         }
    18     }
    19 
    20     // Do this after detaching the document so that the unload event works.
    21     if (clearWindowProperties) {
    22         m_frame->clearDOMWindow();
    23         m_frame->script()->clearWindowShell(m_frame->document()->inPageCache());
    24     }
    25 
    26     m_frame->selection()->clear();
    27     m_frame->eventHandler()->clear();
    28     if (clearFrameView && m_frame->view())
    29         m_frame->view()->clear();
    30 
    31     // Do not drop the document before the ScriptController and view are cleared
    32     // as some destructors might still try to access the document.
    33     m_frame->setDocument(0);
    34 
    35     m_subframeLoader.clear();
    36 
    37     if (clearScriptObjects)
    38         m_frame->script()->clearScriptObjects();
    39 
    40     m_frame->navigationScheduler()->clear();
    41 
    42     m_checkTimer.stop();
    43     m_shouldCallCheckCompleted = false;
    44     m_shouldCallCheckLoadComplete = false;
    45 
    46     if (m_stateMachine.isDisplayingInitialEmptyDocument() && m_stateMachine.committedFirstRealDocumentLoad())
    47         m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
    48 }

    13,Frame::setDocument(PassRefPtr<Document> newDoc)

    OK! setDocuemnt源码跟踪到此为止!

    3.4 init

    1 void init();

    描述:

         Frame对象初始化,会调用 FrameLoader::init 初始化FrameLoader对象

    实现:

    1     inline void Frame::init()
    2     {
    3         m_loader.init();
    4     }

    调用系列:

    1 QWebFrame::QWebFrame
    2 QwebFramePrivate::init
    3 Frame::init

    代码已经跟踪过,见上面

    3.5 setPageAndTextZoomFactors

    1 void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor);

     描述:

         设置页面放大因子和文字放大因子。在网页缩放或者改变网页字体大小的时候调用

    实现:

     1 void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor)
     2 {
     3     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
     4         return;
     5 
     6     Page* page = this->page();
     7     if (!page)
     8         return;
     9 
    10     Document* document = this->document();
    11     if (!document)
    12         return;
    13 
    14     m_editor.dismissCorrectionPanelAsIgnored();
    15 
    16 #if ENABLE(SVG)
    17     // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
    18     // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
    19     if (document->isSVGDocument()) {
    20         if (!static_cast<SVGDocument*>(document)->zoomAndPanEnabled())
    21             return;
    22         if (document->renderer())
    23             document->renderer()->setNeedsLayout(true);
    24     }
    25 #endif
    26 
    27     if (m_pageZoomFactor != pageZoomFactor) {
    28         if (FrameView* view = this->view()) {
    29             // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
    30             IntPoint scrollPosition = view->scrollPosition();
    31             float percentDifference = (pageZoomFactor / m_pageZoomFactor);
    32             view->setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference));
    33         }
    34     }
    35 
    36     m_pageZoomFactor = pageZoomFactor;
    37     m_textZoomFactor = textZoomFactor;
    38 
    39     document->recalcStyle(Node::Force);
    40 
    41     for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
    42         child->setPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor);
    43 
    44     if (FrameView* view = this->view()) {
    45         if (document->renderer() && document->renderer()->needsLayout() && view->didFirstLayout())
    46             view->layout();
    47     }
    48 }

    OK!!!! 完结

  • 相关阅读:
    【移动自动化】【三】控件定位
    【移动自动化】【二】Appium
    【自动化测试:笔记一】adb命令
    mysql api
    计算经纬度的正方形边界
    转 高效的多维空间点索引算法 — Geohash 和 Google S2
    转 为什么geometry+GIST 比 geohash+BTREE更适合空间搜索
    转 HBase GC日志
    转 HBase最佳实践-CMS GC调优
    转:HBase最佳实践-内存规划
  • 原文地址:https://www.cnblogs.com/lfsblack/p/5407758.html
Copyright © 2020-2023  润新知