码迷,mamicode.com
首页 > Web开发 > 详细

webkit内核分析之 Frame

时间:2016-04-19 18:53:25      阅读:282      评论:0      收藏:0      [点我收藏+]

标签:

参考地址: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!!!! 完结

webkit内核分析之 Frame

标签:

原文地址:http://www.cnblogs.com/lfsblack/p/5407758.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!