WebKit for Qt analysis (III)

Source: Internet
Author: User

Program life 21:50:28 read 490 comments 0 font size: LargeMediumSmall subscription

Qwebview is analyzed in three phases: initialization (data retrieval), HTML parsing, and page display. You can see from the documents that comes with QT:

Qwebview-> qwebpage => qwebframe (A qwebpage contains multiple qwebframes)

Select open URL on the interface. After the URL is entered, void mainwindow: Openurl () is called ()

Void mainwindow: Openurl ()
{
Bool OK;
Qstring url = qinputdialog: gettext (this, TR ("enter a URL "),
TR ("url:"), qlineedit: normal, "http: //", & OK );

If (OK &&! URL. isempty ()){
Centralwidget-> webview-> seturl (URL );
}
}

Qwebview: seturl ()

Void qwebview: seturl (const qurl & URL)
{
Page ()-> mainframe ()-> seturl (URL );
}

Here, page () is used to obtain the qwebpage pointer, while qwebpage: mainframe () is used to obtain the qwebframe pointer.

Therefore, qwebframe: seturl () is called ()

Void qwebframe: seturl (const qurl & URL)
{
D-> frame-> loader ()-> begin (ensureabsoluteurl (URL ));
D-> frame-> loader ()-> end ();
Load (ensureabsoluteurl (URL ));
}

The ensureabsoluteurl () function is used to ensure that the URL is an absolute URL (complete URL ). A relative URL is a Web address without a prefix such as http: // or https. First, let's look at the call in the first sentence. The conversion from qurl to kurl is implicit.

Void frameloader: Begin (const kurl & URL, bool dispatch, securityorigin * origin)
{
// We need to take a reference to the security origin because | clear |
// Might destroy the document that owns it.
Refptr <securityorigin> forcedsecurityorigin = origin;

Bool resetscripting =! (M_isdisplayinginitialemptydocument & m_frame-> document ()-> securityorigin ()-> issecuretransitionto (URL ));
Clear (resetscripting, resetscripting );// Clear the last data and prepare for this load
If (resetscripting)
M_frame-> script ()-> updateplatformscriptobjects ();// In Windows, this is an empty function.
If (dispatch)
Dispatchwindowobjectavailable ();

M_needsclear = true;
M_iscomplete = false;
M_didcallimplicitclose = false;
M_isloadingmainresource = true;
M_isdisplayinginitialemptydocument = m_creatinginitialemptydocument;

Kurl REF (URL );
Ref. setuser (string ());
Ref. setpass (string ());
Ref. SETREF (string ());
M_outgoingreferrer = ref. String ();
M_url = URL;

Refptr <document> document;

If (! M_isdisplayinginitialemptydocument & m_client-> shoulduseplugindocument (m_responsemimetype ))
Document = plugindocument: Create (m_frame );
Else
Document = domimplementation: createdocument (m_responsemimetype, m_frame, m_frame-> inviewsourcemode ());// Create a DOM file. m_responsemimetype has different entities.

// Create an htmldocument object for "text/html"; create a document object for "application/XHTML + XML"

// If it is "application/X-ftp-directory", it is the ftpdirectorydocument object

// Text/vnd. WAP. WML corresponds to the wmldocument entity (Wireless)

// "Application/pdf"/"text/plain" plugindocument object

// For mediaplayer: supportstype (type), The mediadocument object is created.

// "Image/SVG + XML" corresponds to the svgdocument object
M_frame-> setdocument (document );

Document-> seturl (m_url );
If (m_decoder)
Document-> setdecoder (m_decoder.get ());
If (forcedsecurityorigin)
Document-> setsecurityorigin (forcedsecurityorigin. Get ());

M_frame-> domwindow ()-> seturl (document-> URL ());
M_frame-> domwindow ()-> setsecurityorigin (document-> securityorigin ());

Updatepolicybaseurl ();// Update the basic URL of the layout policy

Settings * settings = Document-> Settings ();
Document-> docloader ()-> setautoloadimages (settings & settings-> loadsimagesautomatically ());

If (m_documentloader ){
String dnsprefetchcontrol = m_documentloader-> response (). httpheaderfield ("X-DNS-prefetch-control ");
If (! Dnsprefetchcontrol. isempty ())
Document-> parsednsprefetchcontrolheader (dnsprefetchcontrol );
}

# If frame_loads_user_stylesheet
Kurl userstylesheet = settings? Settings-> userstylesheetlocation (): kurl ();
If (! Userstylesheet. isempty ())
M_frame-> setuserstylesheetlocation (userstylesheet );
# Endif

Restoredocumentstate ();

Document-> implicitopen ();

If (m_frame-> View ())
M_frame-> View ()-> setcontentssize (intsize ());

# If use (low_bandwidth_display)
// Low bandwidth display is a first pass display without external resources
// Used to give an instant visual feedback. We currently only enable it
// HTML documents in the top frame.
If (document-> ishtmldocument ()&&! M_frame-> tree ()-> parent () & m_uselowbandwidthdisplay ){
M_pendingsourceinlowbandwidthdisplay = string ();
M_finishedparsingduringlowbandwidthdisplay = false;
M_needtoswitchoutlowbandwidthdisplay = false;
Document-> setlowbandwidthdisplay (true );
}
# Endif
}

See the code for document-> implicitopen:

Void document: implicitopen ()
{
Cancelparsing ();

Clear ();
M_tokenizer = createtokenizer ();
Setparsing (true );
}

Tokenizer * htmldocument: createtokenizer ()
{
Bool reporterrors = false;
If (frame ())
If (page * page = frame ()-> page ())
Reporterrors = page-> inspectorcontroller ()-> windowvisible ();

Return new htmltokenizer (this, reporterrors );
}

The newly created htmltokenizer object is the HTML Parser.

Return to the second sentence of qwebframe: seturl (): D-> frame-> loader ()-> end ();

Just stop the last unfinished Resolution:

Void frameloader: endifnotloadingmainresource ()
{
If (m_isloadingmainresource |! M_frame-> page ())
Return;

// Http://bugs.webkit.org/show_bug.cgi? Id = 10854
// The frame's last ref may be removed and it can be deleted by checkcompleted (),
// So we'll add a protective refcount
Refptr <frame> protector (m_frame );

// Make sure nothing's left in there
If (m_frame-> document ()){
Write (0, 0, true );
M_frame-> document ()-> finishparsing ();
} Else
// WebKit partially uses WebCore when loading non-HTML docs. In these cases Doc = nil,
// WebCore is enough involved that we need to checkcompleted () in order for m_bcomplete
// Become true. An example is when a subframe is a pure text doc, and that subframe is
// Last one to complete.
Checkcompleted ();
}

Let's take a look at the third sentence of qwebframe: seturl (): load (ensureabsoluteurl (URL ));

Void qwebframe: load (const qurl & URL)
{
Load (qnetworkrequest (ensureabsoluteurl (URL )));
}

Create a qnetworkrequest object and call

Void load (const qnetworkrequest & request,
Qnetworkaccessmanager: Operation operation = qnetworkaccessmanager: getoperation,
Const qbytearray & Body = qbytearray ());
View its code:

Void qwebframe: load (const qnetworkrequest & req,
Qnetworkaccessmanager: Operation operation,
Const qbytearray & Body)
{
If (D-> parentframe ())
D-> page-> D-> insideopencall = true;

Qurl url = ensureabsoluteurl (req. URL ());

WebCore: resourcerequest request (URL );

Switch (operation ){
Case qnetworkaccessmanager: headoperation:
Request. sethttpmethod ("head ");
Break;
Case qnetworkaccessmanager: getoperation:
Request. sethttpmethod ("get ");
Break;
Case qnetworkaccessmanager: putoperation:
Request. sethttpmethod ("put ");
Break;
Case qnetworkaccessmanager: Postoperation:
Request. sethttpmethod ("Post ");
Break;
Case qnetworkaccessmanager: unknownoperation:
// Eh?
Break;
}

Qlist <qbytearray> httpheaders = Req. rawheaderlist ();
For (INT I = 0; I Const qbytearray & headername = httpheaders. at (I );
Request. addhttpheaderfield (qstring: fromlatin1 (headername), qstring: fromlatin1 (req. rawheader (headername )));
}

If (! Body. isempty ())
Request. sethttpbody (WebCore: formdata: Create (body. constdata (), body. Size ()));

D-> frame-> loader ()-> load (request );

If (D-> parentframe ())
D-> page-> D-> insideopencall = false;
}

See the key frameloader: load ()

Void frameloader: load (const resourcerequest & request)
{
Load (request, substitutedata ());
}

Void frameloader: load (const resourcerequest & request, const substitutedata & substitutedata)
{
If (m_instopallloaders)
Return;

// Fixme: Is this the right place to reset loadtype? Perhaps this shoshould be done after loading is finished or aborted.
M_loadtype = frameloadtypestandard;
Load (m_client-> createdocumentloader (request, substitutedata). Get ());
}

M_client corresponds to the frameloaderclientqt object. m_client-> createdocumentloader () creates a documentloader object. For more information, see the code of frameloader: load (documentloader:

Void frameloader: load (documentloader * newdocumentloader)
{
Resourcerequest & R = newdocumentloader-> request ();
Addextrafieldstomainresourcerequest (R );
Frameloadtype type;

If (shouldtreaturlassameascurrent (newdocumentloader-> originalrequest (). URL ())){
R. setcachepolicy (reloadignoringcachedata );
Type = frameloadtypesame;
} Else
Type = frameloadtypestandard;

If (m_documentloader)
Newdocumentloader-> setoverrideencoding (m_documentloader-> overrideencoding ());

// When we loading alternate content for an unreachable URL that we're re
// Visiting in the History list, we treat it as a reload so the history list
// Is appropriately maintained.
//
// Fixme: this seems like a dangerous overloading of the meaning of "frameloadtypereload "...
// Shouldn't a more explicit type of reload be defined, that means roughly
// "Load without affecting history "?
If (shouldreloadtohandleunreachableurl (newdocumentloader )){
Assert (type = frameloadtypestandard );
Type = frameloadtypereload;
}

Loadwithdocumentloader (newdocumentloader, type, 0 );
}

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.