WebKit Introduction and summary (2)

Source: Internet
Author: User
Tags drawtext

WebKit Introduction and summary (2)
5. Call Process

Now that we know the general structure of WebKit, we can go further and see how the browser engine works. First, we will introduce several basic and important classes:

Page: Open page. h header file, we don't seem to see the "page" related things in our concept. Yes, the page here is not a simple webpage we are impressed with. In the header file, we found a lot of things about history, goback (), goforward (), and so on, as well as topic settings and frame descriptions. Therefore, the page here is more like the browser we see, abstracted, it should be a browsing session when we visit the website;
In the page. cpp file, there is an important global pointer variable: static hashset <page *> * allpages; this variable contains all the page instances. That's right! Like Firefox, we can start several browsers in a process;
Allpages adds the newly generated Page Object to the page constructor. Each time a new window is started, a new page object is created and pagegroup: addpage () is triggered ();

Frame: Compared with page, frame is more like a webpage in our impression. It focuses on page display (frameview) and page data loading (frameloader) and various controllers on the page (Editor, eventhandler, scriptcontroller, etc .) etc. It can be said that this structure indicates that the browser begins to shift from external control to a specific description of a page;

Document: the grandfather class of this class is node, which is the base class of each element of the DOM tree; document has a subclass of htmldocument, which is the root node of the entire DOM tree of the document, in this way, we can understand that the document is the code used to describe a specific document. After looking at its header file, we can better understand that its attributes and methods are centered around various nodes: text, comment, cdatasection, element ......
Of course, document not only describes HTML-related nodes, but also other types of pages such as XHTML, SVG, and WML;
In addition, one of the parent classes of node is eventtarget, that is, all elements have the ability to respond to events. Because the document class acts as the location of the DOM root node, when a window event occurs, it receives the event first, finds the target element of the event, and processes the event in sequence from the tree path starting from the target element.

Renderobject: When the DOM tree node is formed, the node will call the renderobject method as needed to generate the render node and finally form the render tree. Therefore, this class is the base class of various node classes of the render tree, renderview, a Child class of renderview, is the root node of the entire render tree.

For the call process, here is a specific scenario:
"A typical browser application scenario is that users provide a URL (such as directly entering or clicking a link or parsing JavaScript ). Then, the browser shell calls frameloader to load the page. Frameloader first checks some conditions (policycheck (), such as whether the URL is not empty, whether the URL is reachable, and whether the user is canceled. Start a mainresourceloader through documentloader to load the page. Mainresourceloader calls the interface in the network module to download the page content (resourcehandle). In fact, resourcehandle is already platform-related content. For example, in QT, resourcehandleqt is used to control the content, call qtnetworkreplyhandler to process HTTP requests (such as get and post ). After receiving the data, a callback function is provided to notify mainresourceloader that the data has been received. Then, all the way back to frameloader to start calling htmltokenizer to parse HTML text. During the parsing process, if JavaScript scripts are encountered, the JavaScript engine (javascriptcore in WebKit, V8 in chrome) will also be called for parsing. After the data is parsed, it becomes a node to generate the DOM tree and the render tree, and then the content is displayed by calling the external shell through frameloaderclient ."
Let's take the QT platform as an example to see the specific function call relationship in this scenario:

First, sort out and send customer requests to the server:

WebCore: frameloader: load ()

→ WebCore: frameloader: loadwithdocumentloader () → WebCore: frameloader: continueloadafternavigationpolicy () → WebCore: frameloader: Connector () → WebCore: documentloader: startloadingmainresource ()

→ WebCore: mainresourceloader: load ()

→ WebCore: mainresourceloader: loadnow ()

It is noted that when resourcehandle: Create () is called by this function, mainresourceloader passes in as the second parameter of create (). This parameter is the grandparent class resourcehandleclient of mainresourceloader, in this way, the didreceivedata () method of mainresourceloader is called when the didreceivedata () function of the grandparent class is called.

Continue:

→ WebCore: resourcehandle: Create ()

→ WebCore: resourcehandleqt: Start ()

→ WebCore: qnetworkreplyhandler: Start ()

As of this function, user requests will be finally sent out, and then several signal callback functions are mounted using the connect () method, such as the finish () function for finished () signal, for the forwarddata () function of readyread () signal, for the sendqueueditems () function of processqueueditems () signal, the most important of which is the forwarddata () function, this function is used to receive and process the data returned by the server.

Let's take a look at the processing process of the returned data:

WebCore: qnetworkreplyhandler: forwarddata ()

→ WebCore: (qnetworkreply) qiodevice: Read (), resourcehandleclient: didreceivedata ()

It can be seen that the forwarddata () function will first use the read () method of qiodevice to read the received data from the network data buffer, and then call the didreceivedata () method. In the resourcehandleclient class, this method is actually a virtual function, so it actually calls the function with the same name as its sub-class resourceloader:

→ WebCore: resourceloader: didreceivedata (resourcehandle *, const char * data, int length, int lengthreceived)

→ WebCore: mainresourceloader: didreceivedata ()

→ WebCore: resourceloader: didreceivedata (const char * data, int length, long lengthreceived, bool allatonce)

In this function, one directly calls adddata (data, length, allatonce). Although this statement is in resourceloader, actually it calls not resourceloader: adddata (), but mainresourceloader:: adddata (), another example of virtual function coverage:

→ WebCore: mainresourceloader: adddata ()

→ WebCore: resourceloader: adddata (), frameloader: receiveddata () → WebCore: documentloader: receiveddata ()

→ WebCore: documentloader: commitload ()

→ WebCore: frameloader: committedload ()

→ WebCore: frameloaderclient: committedload ()

→ WebCore: frameloaderclientqt: committedload ()

→ WebCore: frameloader: adddata ()

→ WebCore: documentwriter: adddata ()

At this point, the initialization settings, request sending, and data reception of a URL request are completed. The next step is HTML/JS analysis.

→ WebCore: tokenizer: Write ()

→ WebCore: htmltokenizer: Write ()

There is a loop in this function to analyze each tag. The following is the analysis process for a tag:

→ WebCore: htmltokenizer: Advance ()

→ WebCore: htmltokenizer: parsetag (), htmltokenizer: processtoken ()

→ WebCore: htmlparser: parsetoken ()

→ WebCore: htmlparser: insertnodeafterlimitdepth ()

→ WebCore: htmlparser: insertnode ()

→ WebCore: element: attach ()

When a tag is analyzed, if it is not an HTML Tag, the related parse function (such as parsenonhtmltext) is called; if it is an HTML tag, add it to a node in the DOM tree, and then generate a render Tree node based on the node:

→ WebCore: node: createrendererifneeded ()

→ WebCore: Text: createrenderer ()

→ WebCore: rendertext ()

In addition, htmltokenizer: parsetag () also calls htmltokenizer: parsenonhtmltext, and then calls:

→ WebCore: htmltokenizer: scripthandler ()

→ WebCore: htmltokenizer: scriptexecution ()

→ WebCore: scriptcontroller: executescript ()

→ WebCore: scriptcontroller: Evaluate ()

→ WebCore: scriptcontroller: evaluateinworld ()

→ WebCore: jsmainthreadexecstate: Evaluate ()

→ JSC: Evaluate ()

→ JSC: Interpreter: Execute ()

→ JSC: jitcode: Execute ()

→ JSC: jitthunks: trycachegetbyid ()

→ Cti_op_put_by_id ()

→ JSC: jsvalue: Put ()

→ WebCore: jshtmlinputelement: Put ()

→ JSC: lookupput <WebCore: jshtmlinputelement, WebCore: jshtmlelement> ()

→ JSC: lookupput <WebCore: jshtmlinputelement> ()

→ WebCore: setjshtmlinputelementselectionstart ()

→ WebCore: jshtmlinputelement: setselectionstart ()

→ WebCore: htmltextformcontrolelement: setselectionstart ()

→ WebCore: htmltextformcontrolelement: textrendererafterupdatelayout ()

→ WebCore: Document: updatelayoutignorependingstylesheets ()

→ WebCore: Document: updatelayout ()

→ WebCore: frameview: Layout ()

You may call frameview: adjustviewsize (), frameview: setcontentssize (), scrollview: updatescrollbars (), frameview: sums (), frameview: enddeferredrepaints (), frameview: dodeferredrepaints () and other functions, and then call:

→ WebCore: scrollview: repaintcontentrectangle ()

→ WebCore: chrome: invalidatecontentsandwindow ()

In this function, there is a key sentence: emit m_webpage-> repaintrequested (windowrect), which means that the paint signal is finally sent out.

In QT, The qeventloop: exec () function detects events. When an event (signal) is detected, the following function is called for processing:

→ Qeventloop: processevents ()

→?

→ Qeventdispatcherglib: processevents

→ G_main_context_iteration ()

→?

→ G_main_context_dispatch ()

→?

→ Qcoreapplication: sendpostedevents ()

→ Qcoreapplicationprivate: sendpostedevents ()

→ Qcoreapplication: policyinternal ()

→ Qapplication: Policy ()

→ Qapplicationprivate: notify_helper ()

→ Qmainwindow: event (qevent *)

→ Qwidget: event (qevent *)

→ Qwidgetprivate: syncbackingstore ()

→?

→ Qwidgetprivate: drawwidget ()

→ Qcoreapplication: policyinternal ()

→ Qapplication: Policy ()

→ Qapplicationprivate: notify_helper ()

→ Qwebview: event ()

→ Qwidget: event ()

The above is a general process of QT event processing. Starting from the following function, QT recognizes that this signal is a paint signal:

→ Qwebview: paintevent ()

→ Qwebframe: render ()

→ Qwebframeprivate: renderrelativecoords ()

→ WebCore: frameview: paintcontents ()

→ WebCore: renderlayer: paint ()

→ WebCore: renderlayer: paintlayer ()

→ WebCore: renderlayer: paintlist ()

→ WebCore: renderlayer: paintlayer ()

→ WebCore: renderlayer: paintlist ()

→ WebCore: renderlayer: paintlayer ()

→ WebCore: renderblock: paint ()

→ WebCore: renderblock: paw.bject ()

→ WebCore: renderblock: paintcontents ()

→ WebCore: renderblock: paintchildren ()

→ WebCore: renderblock: paint ()

→ WebCore: renderblock: paw.bject ()

→ WebCore: renderblock: paintcontents ()

→ WebCore: renderblock: paintchildren ()

→ WebCore: renderblock: paint ()

→ WebCore: renderblock: paw.bject ()

→ WebCore: renderblock: paintcontents ()

→ WebCore: renderlineboxlist: paint ()

→ WebCore: rootinlinebox: paint ()

→ WebCore: inlineflowbox: paint ()

→ WebCore: inlineflowbox: paint ()

→ WebCore: inlinetextbox: paint ()

→ Painttextwithshadows ()

→ WebCore: graphicscontext: drawtext ()

→ WebCore: Font: drawtext ()

→ WebCore: Font: drawcomplextext ()

→ Qpainter: drawtext ()

As you can see, some of the above functions will be called repeatedly, because the present shows only an execution flow, and WebKit is only the tip of the iceberg. At this point, WebKit finally calls qt's qpainter to draw the text.

In this way, the process from loading the initial data to drawing a text is basically complete, and the process of other films is similar.

After that, WebKit will continue to relayout and repaint with the drive of events such as Resize and mouse-click.

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/spacetiller/archive/2010/08/03/5784475.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.