【渲染】webkit内部的WebView,page, WebFrame, Frame, document, frameView, RenderView, RenderFrame,Widget的层级关联关系以及构建过程
更多内容: https://blog.csdn.net/csshell2002/category_5801303.html
一定要参考:Chromium网页加载过程简要介绍和学习计划_老罗的Android之旅-CSDN博客 才能更好理解底下几个模块的关系:
webkit内部的WebView,page, WebFrame, Frame, document, frameView, RenderView, RenderFrame,Widget的层级关联关系以及构建过程
Webcore内部:
Page, Node, Element, Document, Settings
WebKit接口层:
WebView(WebViewImpl), WebNode, WebElement, WebDocument,WebSettings, WebFrame,
Platform层:
Widget.h, WebLayer,
WebViewImpl包含Page,WebSettings, WebLayer tree.
Page包含:Frame(main frame),FrameHost(一个被page内所有frame共享的数据结构),Settings.
Frame(LocalFrame)包含:
FrameLoader, FrameView,
有指向LocalDomWindow的引用,
FrameTree,
指向FrameHost,
指向一个FrameOwner(HTMLFrameOwnerElement)就是包含这个Frame的element.而element间接继承自Node,Node又和renderObject关联,也就是有renderer()函数。
WebLocalFrame指向WebCore::LocalFrame.
Frame.ownerRenderer()拿到一个RenderPart.继承自RenderWidget,实际上继承自RenderObject.
FrameHost,和一个page关联,是一个page内所有frame共享的结构。
FrameOwnerElement.继承自HTMLELement,是element.能够拿到renderer().
LocalDomWindow有Document指针,由于继承自FrameDestructionObserver,所以有Frame指针,这个Frame应该是mainframe.
一个Frame包含一个document么?LocalDomWindow对应整个网页么?
创建LocalDOMWindow:
->DocumentLoader::dataReceived
->DocumentLoader::commitData
->DocumentLoader::ensureWriter
->DocumentLoader::createWriterFor(LocalFrame* frame, constDocument* ownerDocument, const KURL& url,
->LocalDOMWindow::create(*frame),并把创建的dowwindow设置给frame.
可以看出此domwindow和frame一一对应,那么要看该frame是mainframe还是普通frame?
可以自己写一个多个frame的网页,然后加log,看看究竟创建了几个frame,几个domwindow,几个Document,几个Page,几个DocumentLoader,等等。
我写了一个简单的网页:
f.htm:
<body>
<iframe src="1.htm">
</iframe>
<iframe src="2.htm">
</iframe>
</body>
1.htm:
<body>
<p>hello 1</p>
</body>
2.htm:
<body>
<p>hello 2</p>
</body>
打开f.htm显示两个frame.
那么此时构建的上述类的结构关系如何?
当加载f.htm时:
Page (1个)----
Frame (mainFrame, 也是LocalFrame, 1个)
Frame包含:
1. FrameHost (1个,被page的所有frame共享)
2. FrameLoader (1个,于Frame11对应)
3. LocalDomWindow(1个,于Frame
11对应
4. Document
(1个,先创建一个,加载完成后,会destroy然后重新创建,
于frame11对应)
5.
DocumentLoader(会出现2个,应该是provisional,commited状态变换所致,最终会销毁第一个,只剩下一个),每个DocumentLoader会附带创建一个11对应的ResourceFetcher,
DocumentLoader销毁,ResourceFetcher也销毁。
6. FrameView
(1个,加载网页后,会被销毁重建,于frame
11对应)
加载网页过程中,Document会销毁重建,2个DocumentLoader中,有一个会被销毁。FrameView会被销毁重建。
f.htm加载完成,解析,发现有2个子iframe,
会生成两个子frame去加载:
子frame的结构关系:
Frame包含:
1. FrameLoader (于frame
11对应)
2. DocumentLoader
(也会建立两个,最后销毁一个),每个DocumetLoader对应一个resourceFetcher.
3. FrameView (于frame
11对应,会销毁重建)
4. Document (于frame
11对应,会销毁重建)
5. LocalDomWindow (于
frame 11 对应,会销毁重建)
最终结论:
网页中有main
frame, 每个iframe会建立子frame.
每个frame都有自己的FrameLoader,
Document, DoducmentLoader, FrameView 和LocalDomWindow.
但是FrameHost是多个frame共享的,Page也是共享的。
下面看Frame
--- element --- render之间的关联。
WebLocalFrame指向一个LocalFram.
每个LocalFrame关联一个FrameOwner,
其实是一个element:
class
HTMLFrameOwnerElement : public HTMLElement, public FrameOwner .
Element
的父类ContainerNode的父类Node有renderer()函数可以得到RenderObject*。所以Frame也可通过其Owner
Element得到renderer.
实际上Frame的render是RenderPart.
是一个很深的继承自RenderObject的子孙类。所以HTMLFrameOwnerElement有函数renderPart()得到RenderPart*.
Widget:
HTMLFrameOwnerElement拥有一个widget,ownedWidget()可以拿到。这个widget一般情况下就是FrameView.
Widget是scrollView,scrollBar,以及pluginView的基类。
Widget之间有父子关系。
FrameView:
Frame都有一个FrameView,FrameView就继承自ScrollView,继承自Widget.
FrameView是widget系列的东西。
FrameView有m_widgets保存若干子RenderWIdgets.
LocalFrame::createView中会为自己创建一个FrameView,并把它当作widget注册给HTMLFrameOwnerElement,也就是ownerRender.
classHTMLFrameElementBase : public HTMLFrameOwnerElement {
RenderView:
RenderView和Document关联,Document的attach函数创建一个RenderView, RenderView也是继承自RenderObject,他是rendertree的root.
RenderView是RenderObject系列的东西,也是render系列的东西。
RenderWIdget:
RenderWidget也是RenderObject系列的东西。
RenderWidget和一个widget关联。也是和一个HTMLFrameOwnerElement关联。
可以认为RenderWidget把widget包装了一层,是一个adapter,对RenderWIdget调用的一些操作会被其关联的widget处理。所以虽然RenderWidget是render系列的东西,但是他会把逻辑调用转给widget.
LocalDomWindow:
在DocumentLoader收到数据后,会创建LocalDomWindow并注册给Frame.
WebView:
继承自WebWIdget.
WebViewImpl继承自WebView.
WebView.h是接口。被chrome的content模块使用。
Content层的RenderViewImpl::initialize中就创建了WebView,并创建了WebFrame作为mainframe注册给创建的WebView.
下面看看FrameHost,FrameClient.
FrameClient:
FrameLoaderClient继承自FrameClient,所以Frame的FrameClient就是FrameLoaderClient.
classFrameLoaderClientImpl FINAL: public WebCore::FrameLoaderClient
Frame,LocalFrame, WebFrame, WebLocalFrame, WebLocalFrameImpl:
WebLocalFrameImpl继承自WebFrame.LocalFrame继承自Frame.
WebLocalFrameImpl里面会建立并关联一个LocalFrame.并把自己的FrameLoaderClientImpl关联给LocalFrame作为FrameClient.
WebLocalFrame的创建:
1.建立childframe:
在content的RenderFrameImpl中创建一个RenderFrameImpl和一个WebLocalFrameImpl(调用的是WebLocalFrame::create),然后把这两个content模块和WebCore模块的frame相关联。而且content模块的RenderFrameImpl作为WebLocalFrame的WebFrameClient。
Childframe何时建立?
->htmlparser解析处理token:比如处理iframetoken.
->HTMLConstructionSite::insertSelfClosingHTMLElement(AtomicHTMLToken*token)
->HTMLConstructionSite::attachLater(ContainerNode*parent, PassRefPtrWillBeRawPtr<Node> prpChild, boolselfClosing)
建立HTMLConstructionSiteTask,然后queueTask.
---------------下面是执行task----------------
->voidHTMLConstructionSite::executeQueuedTasks()
-》executeInsertTask()
->插入,replace,append节点都会引起一些下面的notify动作。
->voidContainerNode::updateTreeAfterInsertion(Node& child)
void ContainerNode::parserInsertBefore(PassRefPtrWillBeRawPtr<Node>newChild, Node& nextChild)
void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node>newChild)
-》ContainerNode::notifyNodeInserted(Node&root, ChildrenChangeSource source)当一个node被插入到domtree后,会调用这个callback:
->voidHTMLFrameElementBase::didNotifySubtreeInsertionsToDocument()
->voidHTMLFrameElementBase::setNameAndOpenURL()
->HTMLFrameElementBase::openURL(boollockBackForwardList)
->HTMLFrameOwnerElement::loadOrRedirectSubframe
->FrameLoaderClient::createFrame(url,framname,...)创建完后会调用started()
->WebLocalFrameImpl::createChildFrame
->RenderFrameImpl::createChildFrame
建立mainframe
content模块的RenderViewImpl::initialize中,建立一个RenderFrameImpl,和一个WebLocalFrameImpl(通过WebLocalFrame::create),并让他们关联。
并把mainframe注册给webview.
LocalFrame的client是WebLocalFrame的FrameLoaderClientImpl成员.
WebLocalFrame的client是RenderFrameImpl.
WebFrame,WebLocalFrame可以看作是把Frame,LocalFrame的内容包了一下。
WebFrame,WebLocalFrame都是blinknamespace的。
Frame,LocalFrame都是webCorenamespace的。
加载网页时,是调用WebFrame的loadrequest()函数。
进而会触发FrameLoader的一系列操作。
————————————————
版权声明:本文为CSDN博主「csshell2002」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/csshell2002/article/details/48313387
render对象关系:
RenderObject
* RenderText
* RenderBR
* RenderCombineText
* RenderCounter
* RenderQuote
*RenderTextFragment
* RenderWordBreak
* RenderLayerModelObject
*RenderBoxModelObject
*RenderInline
*RenderRubyAsInline
* RenderBox
* RenderListBox
* RenderListItem
* RenderListMarker
* RenderFrameSet
* RenderReplica
*RenderTableSection
*RenderTableRow
*RenderBlock
*RenderFlexibleBox
* RenderButton
* RenderFullScreen
*RenderMenuList(PopupMenuClient)
* RenderSlider
* RenderDeprecatedFlexibleBox
* RenderDetailsMarker
* RenderFieldset
*RenderFileUploadControl
* RenderFlowThread
* RenderGrid
* RenderLazyBlock
* RenderTextTrackContainerElement
* RenderMeter
* RenderProgress
* RenderRubyAsBlock
* RenderRubyBase
* RenderRubyRun
* RenderRubyText
*RenderScrollbarPart
* RenderTable
* RenderTableCaption
* RenderTableCell
* RenderTableCol
* RenderTextTrackCue
* RenderView
* RenderTextControl
*RenderTextControlMultiLine
* RenderTextControlSingleLine
* RenderMultiColumnBlock
* RenderFlowThread
*RenderMultiColumnFlowThread
* RenderNamedFlowThread
* RenderRegion
* RenderRegionSet
*RenderMultiColumnSet
* RenderTextControl
* RenderTextControlSingleLine
*RenderSearchField (PopupMenuClient)
* RenderReplaced
* RenderHTMLCanvas
* RenderImage
* RenderMedia
* RenderVideo
* RenderWidget
*RenderPart
* RenderEmbeddedObject
*RenderApplet
* RenderFrameBase
*RenderFrame
* RenderIFrame
ScrollableArea
* RenderLayer
WebCore::Widget
*WebCore::Scrollbar
*WebCore::RenderScrollbar
ScrollbarTheme
*ScrollbarThemeComposite
*RenderScrollbarTheme
RenderArena
RenderBoxRegionInfo
WebView对应一个window.
WebView有一个Page,一个WebView对应一个page.
RenderView给WebView建立一个WebFrameImpl作为最顶层的rootwebframe.
一个webView的page里面可以有WebFrame构成的树,最顶层就是mainWebFrame. Root WebFrame可以建立孩子WebFrame.
WebFrame的client是RenderFrameImpl,这个RenderFrameImpl是RenderViewImpl::initialize里面建立的。
每个WebFrame会建立自己的Frame.而每个Frame会建立自己的FrameView.
所有这些WebFrame都持有containerView也就是WebView的引用。
一个Page关联一个最顶层的WebFrame,所以关联最顶层的Frame,最顶层的Frame对应整个网页,不被销毁。他的孩子会被销毁替换。
从最顶层的frame可以访问到各孩子frame.
每个frame内部有一个frameloader。
每个frame还会建立DocumentLoader.DocumentLoader也和frame关联。
每个Frame和一个document关联。
每个Frame又会关联一个FrameView.FrameView继承自ScrollView,又继承自Widget.所以他是实际和显示相关的。
Frame的创建点2个:
WebFrameImpl::initializeAsMainFrame
WebFrameImpl::createChildFrame(),会先创建一个WebFrame,然后建立Frame.
都会调用Frame::create().
Frame的构造函数回传进来一个HTMLFrameOwnerElement,对于mainFrame,这个是空,对于childframe这个才有值。
render建立主frame和FrameView的流程:
1, Main frame的创建,即root frame:
RenderView被建立时,会建立mainFrame,从而会建立FrameLoader,并且会加载空文档,所以也会直接建立一个FrameView:
从上往下执行:
->IPC::ChannelProxy::Context::OnDispatchMessage
->content::ChildThread::OnMessageReceived
->content::RenderThreadImpl::OnControlMessageReceived
->content::RenderThreadImpl::OnCreateNewView
->content::RenderViewImpl::Create
->content::RenderViewImpl::Initialize
->WebKit::WebViewImpl::initializeMainFrame
->WebKit::WebFrameImpl::initializeAsMainFrame
->WebCore::FrameLoader::init
->WebCore::DocumentLoader::startLoadingMainResource
->WebCore::DocumentLoader::maybeLoadEmpty
->WebCore::DocumentLoader::finishedLoading
->WebCore::FrameLoader::commitProvisionalLoad
->FrameLoader::transitionToCommitted(PassRefPtr<CachedPage>cachedPage)
->voidFrameLoaderClientImpl::transitionToCommittedForNewPage()
->WebFrameImpl::createFrameView()
->Frame::createView(),创建FrameView.
→ 调用如下:
FrameView::create(),建立FrameView
ownerRenderer()->setWidget(frameView);//相当于告诉该render以后向哪里绘制
ownerRender其实是HTMLFrameOwnerElement->render(),会得到一个RenderPart,然后RenderPart->setWidget()相当于告诉该render以后向哪里绘制。HTMLFrameOwnerElement是WebFrameImpl::initializeAsMainFrame中建立Frame时传进来的。由于此时,建立的是mainframe,此时的HTMLFrameOwnerElement是空的。
2, 子Frame啥时候建立的?
->HTMLFrameElementBase::parseAttribute,当解析到src属性时,把src的值当作location调用下面函数:
->voidHTMLFrameElementBase::setLocation(constString&str) //str就是链接地址
->HTMLFrameElementBase::openURL(boollockBackForwardList)
->HTMLFrameOwnerElement::loadOrRedirectSubframe(constKURL&url, constAtomicString&frameName, boollockBackForwardList)//这个函数会创建childframe,并初始化childFrame,然后启动childframe的loader.
->调用如下:
RefPtr<Frame>parentFrame = document()->frame();拿到本HTMLFrameOwnerElement的document对应的主Frame.
parentFrame->loader()->client()->createFrame(url,frameName, this,..)其实调用了FrameLoaderClientImpl::createFrame,创建childframe,第三个参数this就是传入的HTMLFrameOwnerElement.也是一个HTMLElement.一个page里所有的Frame共用一个FrameLoaderClientImpl.(共用还是每个frame有一个???)
>WebFrameImpl::createChildFrame()
->Frame::create(
->Frame::Init()
->FrameLoader::init(),//启动childframe的FrameLoader.开始加载资源当资源数据到来之后会触发本Frame的FrameView的创建,当然那就是异步的了
->创建ProvisionalDocumentLoader,并调用m_provisionalDocumentLoader->startLoadingMainResource()以及activeDocLoader->startLoadingSpeculativeResource()。
childFrame->loader()->started();
toRenderWidget(renderObject)->setWidget(FrameView);renderObject是和这个HTMLElement关联的RenderObject,把它cast成RenderWidget.然后设置他的Widget为childFrame里面的FrameView.不过一般当Frame刚建立时,这个view可能是空的,所以这个操作可能不会执行。
下面是一个创建childframe的callstack的场景:
这个场景看样子就是加载网页的过程中,收到backgroundhtml parser发来的一些token,处理并增加一个childframe的过程。
#0 WebCore::HTMLFrameOwnerElement::loadOrRedirectSubframe(this=0x33888014, url=..., frameName=..., lockBackForwardList=true)at../../third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp:127 #1 0x6226b91c in openURL (lockBackForwardList=true, this=0x33888014) at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:93 #2 WebCore::HTMLFrameElementBase::openURL(this=0x33888014, lockBackForwardList=<optimized out>) at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:73 #3 0x627cf016 in WebCore::ChildNodeInsertionNotifier::notify(this=0x650899c0, node=<optimized out>) at../../third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h:228 #4 0x627cf19a in WebCore::ContainerNode::parserAppendChild(this=0x3387de44, newChild=...) at../../third_party/WebKit/Source/core/dom/ContainerNode.cpp:676 #5 0x622bd6ee in WebCore::insert (task=..., lazyAttach=<optimizedout>) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:105 #6 0x622bd708 in executeInsertTask (task=...) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:122 #7 WebCore::executeTask (task=...) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:162 #8 0x622be256 in WebCore::HTMLConstructionSite::executeQueuedTasks(this=<optimized out>) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:213 #9 0x622c1396 inWebCore::HTMLDocumentParser::constructTreeFromCompactHTMLToken(this=0x6b477b68, compactToken=...) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:598 #100x622c3186 inWebCore::HTMLDocumentParser::processParsedChunkFromBackgroundParser(this=0x6b477b68, popChunk=...) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:422 #110x622c32d8 in WebCore::HTMLDocumentParser::pumpPendingSpeculations(this=0x6b477b68) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:467 #120x622c3682 inWebCore::HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(this=0x6b477b68, chunk=...) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:317 #130x622bad76 in WTF::FunctionWrapper<void(WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>::operator()(this=0x6b46b810, c=..., p1=...) at../../third_party/WebKit/Source/wtf/Functional.h:210 #140x622badac in WTF::BoundFunctionImpl<WTF::FunctionWrapper<void(WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>,void (WTF::WeakPtr<WebCore::HTMLDocumentParser>, WTF ::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>::operator()()(this=<optimized out>) at../../third_party/WebKit/Source/wtf/Functional.h:420 #150x6222df40 in operator() (this=0x693cea08) at../../third_party/WebKit/Source/wtf/Functional.h:577 #16WTF::callFunctionObject (context=0x693cea08) at../../third_party/WebKit/Source/wtf/MainThread.cpp:62 #170x61f3a922 in Run (this=<synthetic pointer>, a1=<optimizedout>) at ../../base/bind_internal.h:171 #18MakeItSo (runnable=..., a1=<optimized out>) at../../base/bind_internal.h:871 #19base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(*)(void*)>, void (void*), void (void*)>, void(void*)>::Run(base::internal::BindStateBase*) (base=<optimizedout>) at../../base/bind_internal.h:1169 #200x621dbe40 in Run (this=0x65089c38) at ../../base/callback.h:396 #21base::MessageLoop::RunTask (this=0x65089cc0, pending_task=...) at../../base/message_loop/message_loop.cc:482 #220x621dc33a in base::MessageLoop::DeferOrRunPendingTask(this=0x65089cc0, pending_task=...) at../../base/message_loop/message_loop.cc:494 #230x621dc66c in DoWork (this=<optimized out>) at../../base/message_loop/message_loop.cc:608 #24base::MessageLoop::DoWork (this=0x65089cc0) at../../base/message_loop/message_loop.cc:587 #250x621dca86 in base::MessagePumpDefault::Run (this=0x5952d468,delegate=0x65089cc0) at../../base/message_loop/message_pump_default.cc:32 #260x621dc08a in base::MessageLoop::RunInternal (this=0x65089cc0) at../../base/message_loop/message_loop.cc:436 #270x621e4572 in base::RunLoop::Run (this=0x65089ca0) at../../base/run_loop.cc:45 #280x621db8f8 in base::MessageLoop::Run (this=<optimized out>) at../../base/message_loop/message_loop.cc:307 #290x621ed86a in base::Thread::ThreadMain (this=0x1) at../../base/threading/thread.cc:203 #300x621eb4a6 in base::(anonymous namespace)::ThreadFunc(params=<optimized out>) at../../base/threading/platform_thread_posix.cc:80 #310x40104a5c in __thread_entry () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so #320x40104bd8 in pthread_create () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so
下面是另一个创建childframe的callstack场景:
这个场景看样子是资源加载完成后,执行完了script之后继续处理backgroundhtmlparser发来的一些任务,并插入一个子frame.
#0 WebKit::WebFrameImpl::createChildFrame (this=0x661a79c0,request=..., ownerElement=0x33888014) at../../third_party/WebKit/Source/web/WebFrameImpl.cpp:2150 #1 0x6218fea6 in WebKit::FrameLoaderClientImpl::createFrame(this=0x661a79e4, url=..., name=..., ownerElement=0x33888014,referrer=..., allowsScrolling=true, marginWidth=-1, marginHeight=-1) at../../third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp:644 #2 0x6226c03a in WebCore::HTMLFrameOwnerElement::loadOrRedirectSubframe(this=0x33888014, url=..., frameName=...,lockBackForwardList=<optimized out>) at../../third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp:143 #3 0x6226b91c in openURL (lockBackForwardList=true, this=0x33888014) at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:93 #4 WebCore::HTMLFrameElementBase::openURL(this=0x33888014, lockBackForwardList=<optimized out>) at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:73 #5 0x627cf016 in WebCore::ChildNodeInsertionNotifier::notify(this=0x650895e8, node=<optimized out>) at../../third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h:228 #6 0x627cf19a in WebCore::ContainerNode::parserAppendChild(this=0x338582b4, newChild=...) at../../third_party/WebKit/Source/core/dom/ContainerNode.cpp:676 #7 0x622bd6ee in WebCore::insert (task=..., lazyAttach=<optimizedout>) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:105 #8 0x622bd708 in executeInsertTask (task=...) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:122 #9 WebCore::executeTask (task=...) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:162 #100x622be256 in WebCore::HTMLConstructionSite::executeQueuedTasks(this=<optimized out>) at../../third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:213 #110x622c1396 inWebCore::HTMLDocumentParser::constructTreeFromCompactHTMLToken(this=0x694443e8, compactToken=...) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:598 #120x622c3186 inWebCore::HTMLDocumentParser::processParsedChunkFromBackgroundParser(this=0x694443e8, popChunk=...) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:422 #130x622c32d8 in WebCore::HTMLDocumentParser::pumpPendingSpeculations(this=0x694443e8) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:467 #140x622c3462 inWebCore::HTMLDocumentParser::resumeParsingAfterScriptExecution(this=0x694443e8) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:872 #150x622c35c2 in WebCore::HTMLDocumentParser::notifyFinished(this=0x694443e8, cachedResource=0x69234fe8) at../../third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp:917 #160x6275ee66 in checkNotify (this=0x69234fe8) at../../third_party/WebKit/Source/core/loader/cache/Resource.cpp:205 #17WebCore::Resource::checkNotify (this=0x69234fe8) at../../third_party/WebKit/Source/core/loader/cache/Resource.cpp:198 #180x6275d574 in WebCore::Resource::finishOnePart (this=<optimizedout>) at../../third_party/WebKit/Source/core/loader/cache/Resource.cpp:240 #190x6275d6aa in WebCore::Resource::finish(this=0x69234fe8, finishTime=<optimized out>) at../../third_party/WebKit/Source/core/loader/cache/Resource.cpp:248 #200x62754458 in didFinishLoading (finishTime=161969.75042699999,this=0x6ad2eea0) at../../third_party/WebKit/Source/core/loader/ResourceLoader.cpp:363 #21WebCore::ResourceLoader::didFinishLoading(this=0x6ad2eea0, finishTime=<optimized out>) at../../third_party/WebKit/Source/core/loader/ResourceLoader.cpp:351 #220x61f3cf48 inwebkit_glue::WebURLLoaderImpl::Context::OnCompletedRequest(this=0x6ae4aac8, error_code=<optimized out>,was_ignored_by_handler=<optimized out>, security_info=...,completion_time=...) at../../webkit/child/weburlloader_impl.cc:726 #230x62d6bfb4 in content::ResourceDispatcher::OnRequestComplete(this=0x595bc780, request_id=<optimized out>, error_code=0,was_ignored_by_handler=<optimized out>, security_info=...,browser_completion_time=...) at../../content/child/resource_dispatcher.cc:514 #240x62d6b648 in DispatchToMethod<content::ResourceDispatcher, void(content::ResourceDispatcher::*)(int, int, bool, std::string const&,base::TimeTicks const&), int, int, bool, std::string,base::TimeTicks> ( obj=<optimizedout>, method= (void(content::ResourceDispatcher::*)(content::ResourceDispatcher * const,int, int, bool, const std::basic_string<char,std::char_traits<char>, std::allocator<char> > &,const base::TimeTicks &)) 0x62d6bf3d <content::ResourceDispatcher::OnRequestComplete(int,int, bool, std::string const&, base::TimeTicks const&)>,arg=...) at ../../base/tuple.h:579 #250x62d6b694 inResourceMsg_RequestComplete::Dispatch<content::ResourceDispatcher,content::ResourceDispatcher, void(content::ResourceDispatcher::*)(int, int, bool, std::string const&,base::TimeTicks const&)> (msg=0x69656080,obj=0x595bc780, func= (void(content::ResourceDispatcher::*)(content::ResourceDispatcher * const,int, int, bool, const std::basic_string<char,std::char_traits<char>, std::allocator<char> > &,const base::TimeTicks &)) 0x62d6bf3d <content::ResourceDispatcher::OnRequestComplete(int,int, bool, std::string const&, base::TimeTicks const&)>,sender=<optimized out>) at../../content/common/resource_messages.h:268 #260x62d6b8a6 in content::ResourceDispatcher::DispatchMessage(this=0x595bc780, message=...) at../../content/child/resource_dispatcher.cc:615 #270x62d6c758 in OnMessageReceived (message=..., this=0x595bc780) at../../content/child/resource_dispatcher.cc:305 #28content::ResourceDispatcher::OnMessageReceived (this=0x595bc780,message=...) at ../../content/child/resource_dispatcher.cc:268 #290x62d5a2f6 in content::ChildThread::OnMessageReceived(this=0x5952a304, msg=...) at ../../content/child/child_thread.cc:314 #300x6217331a in IPC::ChannelProxy::Context::OnDispatchMessage(this=0x594f6938, message=...) at ../../ipc/ipc_channel_proxy.cc:264 #310x6217277a in Run (a1=..., object=<optimized out>,this=0x65089b60) at ../../base/bind_internal.h:190 #32MakeItSo (a2=..., runnable=..., a1=<optimized out>) at../../base/bind_internal.h:898 #33base::internal::Invoker<2,base::internal::BindState<base::internal::RunnableAdapter<void(IPC::ChannelProxy::Context::*)(IPC::Message const&)>, void(IPC::ChannelProxy::Context*, IPC::Message const&), void (I PC::ChannelProxy::Context*,IPC::Message)>, void (IPC::ChannelProxy::Context*, IPC::Messageconst&)>::Run(base::internal::BindStateBase*)(base=0x69656068) at ../../base/bind_internal.h:1253 #340x621dbe40 in Run (this=0x65089c38) at ../../base/callback.h:396 #35base::MessageLoop::RunTask (this=0x65089cc0, pending_task=...) at../../base/message_loop/message_loop.cc:482 #360x621dc33a in base::MessageLoop::DeferOrRunPendingTask(this=0x65089cc0, pending_task=...) at../../base/message_loop/message_loop.cc:494 #370x621dc66c in DoWork (this=<optimized out>) at../../base/message_loop/message_loop.cc:608 #38base::MessageLoop::DoWork (this=0x65089cc0) at../../base/message_loop/message_loop.cc:587 #390x621dca86 in base::MessagePumpDefault::Run (this=0x5952d468,delegate=0x65089cc0) at../../base/message_loop/message_pump_default.cc:32 #400x621dc08a in base::MessageLoop::RunInternal (this=0x65089cc0) at../../base/message_loop/message_loop.cc:436 #410x621e4572 in base::RunLoop::Run (this=0x65089ca0) at../../base/run_loop.cc:45 #420x621db8f8 in base::MessageLoop::Run (this=<optimized out>) at../../base/message_loop/message_loop.cc:307 #430x621ed86a in base::Thread::ThreadMain (this=0x1) at../../base/threading/thread.cc:203 #440x621eb4a6 in base::(anonymous namespace)::ThreadFunc(params=<optimized out>) at../../base/threading/platform_thread_posix.cc:80 #450x40104a5c in __thread_entry () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so #460x40104bd8 in pthread_create () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so #470x00000000 in ?? ()
下面是第三个建立childframe的callstack场景:
这里看样子是v8脚本引擎执行一个api调用,设置了一个元素的属性,引起了一个IFrame的创建。这里的element节点是HTMLIFrameElement.有classHTMLIFrameElement FINAL : publicHTMLFrameElementBase 。可见脚本执行也会创建childframe。
#0 WebCore::HTMLFrameOwnerElement::loadOrRedirectSubframe(this=0x338880cc, url=..., frameName=..., lockBackForwardList=false)at../../third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp:127 #1 0x6226b91c in openURL (lockBackForwardList=false, this=0x338880cc)at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:93 #2 WebCore::HTMLFrameElementBase::openURL(this=0x338880cc, lockBackForwardList=<optimized out>) at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:73 #3 0x6226b9e2 in WebCore::HTMLFrameElementBase::setLocation(this=0x338880cc, str=...) at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:198 #4 0x6226ba9a in WebCore::HTMLFrameElementBase::parseAttribute(this=0x338880cc, name=..., value=...) at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:105 #5 0x6226d736 in WebCore::HTMLIFrameElement::parseAttribute(this=0x338880cc, name=..., value=...) at../../third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp:97 #6 0x627f150e inWebCore::Element::attributeChanged (this=0x338880cc, name=...,newValue=..., reason=WebCore::Element::ModifiedDirectly) at../../third_party/WebKit/Source/core/dom/Element.cpp:911 #7 0x627edc84 in WebCore::Element::didModifyAttribute (this=0x338880cc,name=..., value=...) at../../third_party/WebKit/Source/core/dom/Element.cpp:2845 #8 0x627f39ba in WebCore::Element::setAttributeInternal(this=0x338880cc, index=0, name=..., newValue=...,inSynchronizationOfLazyAttribute=WebCore::Element::NotInSynchronizationOfLazyAttribute) at../../third_party/WebKit/Source/core/dom/Element.cpp:884 #9 0x627f46b0 in WebCore::Element::setAttribute(this=0x338880cc, localName=..., value=..., es=...) at../../third_party/WebKit/Source/core/dom/Element.cpp:841 #100x62911a50 in setAttributeMethod (args=...) atgen/blink/bindings/V8Element.cpp:4151 #11WebCore::ElementV8Internal::setAttributeMethodCallback(args=...) at gen/blink/bindings/V8Element.cpp:4161 #120x61d1448c in v8::internal::FunctionCallbackArguments::Call(this=0x65089178, f=<optimized out>) at../../v8/src/arguments.cc:103 #130x61d204fc in HandleApiCallHelper<false> (isolate=0x599ea008,args=...) at ../../v8/src/builtins.cc:1272 #14Builtin_implHandleApiCall (isolate=0x599ea008, args=...) at../../v8/src/builtins.cc:1289 #15v8::internal::Builtin_HandleApiCall(args_length=4, args_object=0x650891e8, isolate=0x599ea008) at../../v8/src/builtins.cc:1288 #160x6630ab7c in ?? ()
下面又是一个v8引起的子frame的建立:
#0 WebCore::HTMLFrameOwnerElement::loadOrRedirectSubframe(this=0x33888184, url=..., frameName=..., lockBackForwardList=true)at../../third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp:127 #1 0x6226b91c in openURL (lockBackForwardList=true, this=0x33888184) at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:93 #2 WebCore::HTMLFrameElementBase::openURL (this=0x33888184,lockBackForwardList=<optimized out>) at../../third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp:73 #3 0x627cf016 in WebCore::ChildNodeInsertionNotifier::notify(this=0x650895c0, node=<optimized out>) at../../third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h:228 #4 0x627cf39e in WebCore::updateTreeAfterInsertion (parent=0x3387f654,child=0x338b890c, attachBehavior=WebCore::AttachLazily) at../../third_party/WebKit/Source/core/dom/ContainerNode.cpp:1036 #5 0x627d061e in WebCore::ContainerNode::insertBefore (this=0x3387f654,newChild=..., refChild=<optimized out>, es=...,attachBehavior=WebCore::AttachLazily) at../../third_party/WebKit/Source/core/dom/ContainerNode.cpp:279 #6 0x62264584 in WebCore::HTMLElement::insertAdjacent (this=0x3386f4ac,where=..., newChild=0x3388c014, es=...) at../../third_party/WebKit/Source/core/html/HTMLElement.cpp:502 #7 0x6226470c in WebCore::HTMLElement::insertAdjacentHTML(this=0x3386f4ac, where=..., markup=..., es=...) at../../third_party/WebKit/Source/core/html/HTMLElement.cpp:570 #8 0x629d212c in insertAdjacentHTMLMethod (args=...) atgen/blink/bindings/V8HTMLElement.cpp:627 #9 WebCore::HTMLElementV8Internal::insertAdjacentHTMLMethodCallback(args=...) at gen/blink/bindings/V8HTMLElement.cpp:637 #100x61d1448c in v8::internal::FunctionCallbackArguments::Call(this=0x65089788, f=<optimized out>) at../../v8/src/arguments.cc:103 #110x61d204fc in HandleApiCallHelper<false> (isolate=0x599ea008,args=...) at ../../v8/src/builtins.cc:1272 #12Builtin_implHandleApiCall (isolate=0x599ea008, args=...) at../../v8/src/builtins.cc:1289 #13v8::internal::Builtin_HandleApiCall (args_length=4,args_object=0x650897fc, isolate=0x599ea008) at../../v8/src/builtins.cc:1288 #140x6630ab7c in ?? () #150x6630ab7c in ?? ()
Render在一个frame的数据来了之后,建立该frame的FrameView的流程:
某个frame的数据来了之后,从下层ResourceLoader通知上来,通过DocumentLoader,到达FrameLoader,FrameLoader让DocumentLoader状态切换成commited,表明收到数据确认了,那么此时就建立该Frame的FrameView.看来子frame的frameView应该也是这个流程。
#0 WebCore::Frame::createView (this=0x59467a58, viewportSize=...,backgroundColor=..., transparent=false,fixedLayoutSize=..., useFixedLayout=true, horizontalScrollbarMode=WebCore::ScrollbarAuto,horizontalLock=false, verticalScrollbarMode=WebCore::ScrollbarAuto,verticalLock=false) at../../third_party/WebKit/Source/core/page/Frame.cpp:482 #1 0x61b23af2 in WebKit::WebFrameImpl::createFrameView(this=0x594679b0) at../../third_party/WebKit/Source/web/WebFrameImpl.cpp:2222 这里其实缺少了一行调用stack:FrameLoaderClientImpl::transitionToCommittedForNewPage() #2 0x620cc584 in WebCore::FrameLoader::transitionToCommitted(this=0x59467ab0, cachedPage=...)//这个函数把当前的用于加载的DocumentLoader从Provisional状态改为commited状态,这样这个DocumentLoader成为当前的正式的Documentloader.之前的Frame数据和Doucmentloader被清理。 at../../third_party/WebKit/Source/core/loader/FrameLoader.cpp:1342 #3 0x620cc6d4 in WebCore::FrameLoader::commitProvisionalLoad(this=0x59467ab0) at../../third_party/WebKit/Source/core/loader/FrameLoader.cpp:1230 #4 0x620c4518 in WebCore::DocumentLoader::dataReceived(this=0x60e09068, resource=<optimized out>, data=0x68b60000"<!DOCTYPE html>\r\n<html>\r\n\r\n<head>\r\n<metacharset=\"UTF-8\" />\r\n<metahttp-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"/>\r\n<meta name=\"viewport\" content=\"width=device- width,minimum-scale=1.0,user-"...,length=2802) at../../third_party/WebKit/Source/core/loader/DocumentLoader.cpp:658 #5 0x620ddea4 in WebCore::RawResource::appendData(this=0x658ec3d0, ttp-equiv=\"X-UA-Compatible\"content=\"IE=edge,chrome=1\" />\r\n<metaname=\"viewport\"content=\"width=device-width,minimum-scale=1.0,user-"...,length=2802) at../../third_party/WebKit/Source/core/loader/cache/RawResource.cpp:49 #6 0x620d4d58 in WebCore::ResourceLoader::didReceiveData(this=0x60e0a310, dth=device-width,minimum-scale=1.0,user-"...,length=2802, encodedDataLength=-1) at../../third_party/WebKit/Source/core/loader/ResourceLoader.cpp:348 #7 0x618bdc38 in OnReceivedData (encoded_data_length=<optimizedout>, data_length=2802, data=0x68b60000"<!DOCTYPE html>\r\n<html>\r\n\r\n<head>\r\n<metacharset=\"UTF-8\" />\r\n<metahttp-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"/>\r\n<meta name=\"viewport\" content=\"width=device- width,minimum-scale=1.0,user-"...,this=0x60e0bbc8) at../../webkit/child/weburlloader_impl.cc:693 #8 webkit_glue::WebURLLoaderImpl::Context::OnReceivedData(this=0x60e0bbc8, ttp-equiv=\"X-UA-Compatible\"content=\"IE=edge,chrome=1\" />\r\n<metaname=\"viewport\"content=\"width=device-width,minimum-scale=1.0,user-"...,data_length=2802, encoded_data_length=<optimized out>) at../../webkit/child/weburlloader_impl.cc:678 #9 0x626ed3d4 in content::ResourceDispatcher::OnReceivedData(this=0x59c5b458, message=..., request_id=0,data_offset=<optimized out>, data_length=2802,encoded_data_length=-1) at../../content/child/resource_dispatcher.cc:417 #100x626ec7ce inResourceMsg_DataReceived::Dispatch<content::ResourceDispatcher,content::ResourceDispatcher, int, int, int, int> (msg=0x67906e98,obj=0x59c5b458, sender=<optimized out>, func= int,int, int, int)) 0x626ed2ad<content::ResourceDispatcher::OnReceivedData(IPC::Message const&,int, int, int, int)>) at../../content/common/resource_messages.h:253 #110x626ecae2 in content::ResourceDispatcher::DispatchMessage(this=0x59c5b458, message=...) at../../content/child/resource_dispatcher.cc:613 #120x626eda00 in OnMessageReceived (message=..., this=0x59c5b458) at../../content/child/resource_dispatcher.cc:305 #13content::ResourceDispatcher::OnMessageReceived (this=0x59c5b458,message=...) at../../content/child/resource_dispatcher.cc:268 #140x626db59e in content::ChildThread::OnMessageReceived(this=0x59bc231c, msg=...) at../../content/child/child_thread.cc:314 #150x61af431a in IPC::ChannelProxy::Context::OnDispatchMessage(this=0x59bc2580, message=...) at../../ipc/ipc_channel_proxy.cc:264 #160x61af377a in Run (a1=..., object=<optimized out>,this=0x64e0ab60) at../../base/bind_internal.h:190 #17MakeItSo (a2=..., runnable=..., a1=<optimized out>) at../../base/bind_internal.h:898 #18base::internal::Invoker<2,base::internal::BindState<base::internal::RunnableAdapter<void(IPC::ChannelProxy::Context::*)(IPC::Message const&)>, void(IPC::ChannelProxy::Context*, IPC::Message const&), void (I econst&)>::Run(base::internal::BindStateBase*)(base=0x67906e80) at ../../base/bind_internal.h:1253 #190x61b5ce40 in Run (this=0x64e0ac38) at ../../base/callback.h:396 #20base::MessageLoop::RunTask (this=0x64e0acc0, pending_task=...) at../../base/message_loop/message_loop.cc:482 #210x61b5d33a in base::MessageLoop::DeferOrRunPendingTask(this=0x64e0acc0, pending_task=...) at../../base/message_loop/message_loop.cc:494 #220x61b5d66c in DoWork (this=<optimized out>) at../../base/message_loop/message_loop.cc:608 #23base::MessageLoop::DoWork (this=0x64e0acc0) at../../base/message_loop/message_loop.cc:587 #240x61b5da86 in base::MessagePumpDefault::Run (this=0x59befeb8,delegate=0x64e0acc0) at../../base/message_loop/message_pump_default.cc:32 #250x61b5d08a in base::MessageLoop::RunInternal (this=0x64e0acc0) at../../base/message_loop/message_loop.cc:436 #260x61b65572 in base::RunLoop::Run (this=0x64e0aca0) at../../base/run_loop.cc:45 #270x61b5c8f8 in base::MessageLoop::Run (this=<optimized out>) at../../base/message_loop/message_loop.cc:307 #280x61b6e86a in base::Thread::ThreadMain (this=0x1) at../../base/threading/thread.cc:203 #290x61b6c4a6 in base::(anonymous namespace)::ThreadFunc(params=<optimized out>) at../../base/threading/platform_thread_posix.cc:80 #300x40104a5c in __thread_entry () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so #310x40104bd8 in pthread_create () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so #320x00000000 in ?? ()
那么Frame::createView干了什么:
->Frame::createView(),创建FrameView.
→ 调用如下:
FrameView::create(),建立FrameView
ownerRenderer()->setWidget(frameView);ownerRender其实是HTMLFrameOwnerElement->render(),会得到一个RenderPart,然后RenderPart->setWidget()相当于告诉该render以后向哪里绘制。HTMLFrameOwnerElement是建立childFrame时传进来的,对应本frame的HTMLElement.由于此时.当建立mainframe时,HTMLFrameOwnerElement就是空的。
————————————————
版权声明:本文为CSDN博主「csshell2002」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/csshell2002/article/details/48312337
相关文章
- 解决Android8.0系统应用打开webView报错
- webview相关知识
- webview和js交互
- 关于webview调用js出现has no method 'toString'
- android软件开发之webView.addJavascriptInterface循环渐进【一】
- webview与js交互(转)
- WebView 加载网页 加载资源 总结 MD
- 【Android】带进度条的WebView
- Atitit.android webview h5运行环境总结
- Android问题笔记 - 解决WebView白屏空白的九种方案,AutoSize?
- Webview & Browser & Chrome
- Android 实现WebView
- android webview加载执行本地js,执行js方法undefined
- android 下 利用webview实现浏览器功能
- android WebView总结
- 安卓系统源码编译系列(六)——单独编译内置浏览器WebView教程
- android WebView总结
- Appium基础 — webview操作(重点)