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 );
}