qt5 webkit,qtwebkit4
夸脱分析之网络工具包(三)分三个阶段对QWebView进行分析:初始化(获取数据)、HTML解析、页面显示。从夸脱自带的文档中可以知道:
QWebView - QWebPage=QWebFrame(一个q网页含多个QWebFrame)
在界面中选择了打开URL,输入统一资源定位器之后,调用的是:void MainWindow:openUrl()
void MainWindow:openUrl()
{
布尔ok
QString URL=QInputDialog:getText(this,tr(输入一个网址’),
tr(URL:),QLineEdit:Normal, http://,ok);
如果(好!url.isEmpty()) {
centralWidget-webView-setUrl(URL);
}
}
调用的是QWebView:setUrl()
void q webview:setUrl(const QUrl URL)
{
page()-mainFrame()-setUrl(URL);
}
其中第页()是获取q网页指针,问网页:大型机()获取的是QWebFrame指针。
所以调用的是:QWebFrame:setUrl()
void qweb frame:setUrl(const QUrl URL)
{
d-frame-loader()-begin(ensureAbsoluteUrl(URL));
d-帧加载器()-end();
load(ensureAbsoluteUrl(URL));
}
ensureAbsoluteUrl()函数作用是,确保统一资源定位器是绝对网址(完整网址).所谓相对统一资源定位器是指没有输入http://或者https://等前缀的网地址。先看第一句的调用。其中隐含了从古尔到库尔的变换。
void frame loader:begin(const KURL URL,bool dispatch,SecurityOrigin* origin)
{
//我们需要引用安全源,因为清晰
//可能会销毁拥有它的文档。
ref ptr security origin forcedSecurityOrigin=origin;
bool resetScripting=!(m _ isDisplayingInitialEmptyDocument m _ frame-document()m _ frame-document()-security origin()-isSecureTransitionTo(URL));
clear(resetScripting,resetScripting);//清除上一次的数据,为本次装载准备
如果(重置脚本)
m _ frame-script()-updatePlatformScriptObjects();//在Windows操作系统操作系统平台下,这是空函数
如果(调度)
dispatchWindowObjectAvailable();
m _ needsClear=true
m _ isComplete=false
m _ didCallImplicitClose=false
m _ isLoadingMainResource=true
m _ isDisplayingInitialEmptyDocument=m _ creating initialemptydocument;
库尔引用(网址);
参考文献。setuser(String());
参考文献。set pass(String());
参考文献。setref(String());
m _ outgoing referrer=ref。string();
m _ URL=url
具体类文档文档;
如果(!m _ isDisplayingInitialEmptyDocument m _ client-shouldUsePluginDocument(m _ responseMIMEType))
document=plugin文档:create(m _ frame);
其他
document=do实现:create document(m _ responseMIMEType,m_frame,m _ frame-inViewSourceMode());//创建数字正射影像图文件,m _ responseMIMEType不同实体不同。
//如果是文本/html 创建超文本标记语言文档实体;应用程序/xhtml xml 创建文件实体
//如果是应用程序/x-FTP-目录则是文件传送协议目录文档实体
//text/vnd.wap.wml对应脑白质病变文档实体(无线)
//应用程序/pdf /文本/普通对应插件文件实体
//如果是MediaPlayer:supportsType(类型),创建的是媒体文档实体
//图像/svg xml 对应挽救(saving的简写)文档实体
m_frame- setDocument(文档);
document-setURL(m _ URL);
中频(m _解码器)
文档集解码器(m _ decoder。get());
if (forcedSecurityOrigin)
document-setSecurityOrigin(forcedsecurityorigin。get());
m _ frame-DOM window()-setURL(document-URL());
m _ frame-DOM window()-setSecurityOrigin(document-security origin());
updatePolicyBaseURL();//更新排布策略的基础统一资源定位器
设置*设置=文档-设置();
document-doc loader()-setAutoLoadImages(设置设置-自动加载图像());
if (m_documentLoader) {
string dnsPrefetchControl=m _ document loader-response().http头字段(“X-DNS-Prefetch-Control”);
如果(!dnsPrefetchControl.isEmpty())
document-parseDNSPrefetchControlHeader(dnsPrefetchControl);
}
# if FRAME _ LOADS _ USER _样式表
库尔用户样式表=设置?settings-userstylesheelocation():KURL();
如果(!userStyleSheet.isEmpty())
m _ frame-setuserstyleshetlocation(用户样式表);
#endif
restoreDocumentState();
文档-隐式open();
if (m_frame- view())
m _ frame-view()-setContentsSize(IntSize());
#如果使用(低带宽显示)
//低带宽显示是没有外部资源的第一遍显示
//用于给出即时的视觉反馈。我们目前仅在以下情况下启用它
//顶部框架中的超文本标记语言文档。
if (document- isHTMLDocument()!m _ frame-tree()-parent()m _ useLowBandwidthDisplay){
m _ pendingSourceInLowBandwidthDisplay=String();
m _ finishedparsingduringlowbandwidth display=false;
m _ needToSwitchOutLowBandwidthDisplay=false;
document-setLowBandwidthDisplay(true);
}
#endif
}
看其中文档-隐式打开()的代码:
空的文档* implicit open()
{
取消解析();
clear();
m _ token izer=createTokenizer();
setParsing(true);
}
tokenizer * html文档:createTokenizer()
{
布尔报告错误=假
if (frame())
if (Page* page=frame()- page())
报告错误=页面-检查器控制器()-窗口可见();
返回新的HTMLTokenizer(this,报告错误);
}
新创建的超文本标记语言标记器对象,就是超文本标记语言的解析器。
回到QWebFrame:setUrl()的第二句:d-frame-loader()-end();
只是把上次未完的解析停止:
void frame loader:endIfNotLoadingMainResource()
{
if (m_isLoadingMainResource !m_frame- page())
返回;
//http://个bug。WebKit。org/show _ bug。CGI?id=10854
//可以移除帧的最后一个裁判,并且可以通过检查完成()删除它,
//所以我们将添加一个保护性的引用计数
具体类帧保护器(m _ Frame);
//确保里面没有留下任何东西
if (m_frame- document()) {
写(0,0,真);
m _ frame-document()-完成解析();
}否则
//WebKit在加载非超文本标记语言文档时部分使用网络核心.在这些情况下,doc==nil,但是
//WebCore非常复杂,我们需要检查已完成(),以便m _完成
//变为真。一个例子是当一个子帧是一个纯文本停靠,且该子帧是
//最后一个完成。
检查完成();
}
再来看QWebFrame:setUrl()的第三句:load(ensureAbsoluteUrl(URL));
void qweb frame:load(const QUrl URL)
{
load(QNetworkRequest(ensureAbsoluteUrl(URL)));
}
新建一个QNetworkRequest对象,然后调用
无效负载(const QNetworkRequest请求,
QNetworkAccessManager:Operation Operation=QNetworkAccessManager:get操作,
const QByteArray body=QByteArray());
看其代码:
void qweb frame:load(const QNetworkRequest请求,
QNetworkAccessManager:操作操作,
const QByteArray体)
{
if (d- parentFrame())
d-page-d-insideOpenCall=true;
QUrl URL=ensureAbsoluteUrl(req。URL());
WebCore:资源请求请求(网址);
开关(操作){
案例QNetworkAccessManager:head操作:
请求。sethttp方法(“HEAD”);
打破;
案例QNetworkAccessManager:get操作:
请求。sethttp方法(“GET”);
打破;
案例QNetworkAccessManager:put操作:
请求。sethttp方法(“PUT”);
打破;
病例QNetworkAccessManager:术后:
请求。sethttp方法(“POST”);
打破;
案例QNetworkAccessManager:未知操作:
//呃?
打破;
}
QList QByteArray http headers=req。rawheaderlist();
for(int I=0;我http头。size();i) {
const QByteArray头名称=http头。在;
请求。addhttpheaderfield(QString:from latin1(头名称),QString:from latin1(req。raw头(头名)));
}
如果(!body.isEmpty())
请求。set http body(WebCore:FormData:create(body。const data()、body。size());
d-帧加载器()-加载(请求);
if (d- parentFrame())
d-page-d-insideOpenCall=false;
}
看关键的FrameLoader:load()
void FrameLoader:load(常量资源请求请求)
{
load(请求,替代数据());
}
void frame loader:load(常量资源请求请求常数替代数据替代数据)
{
if (m_inStopAllLoaders)
返回;
//FIXME:这是重置负载类型的正确位置吗?也许这应该在加载完成或中止后进行。
m _ loadType=FrameLoadTypeStandard;
load(m _ client-createDocumentLoader(request,substituteData).get());
}
上面m _客户端对应的是FrameLoaderClientQt实体,m_client- createDocumentLoader()创建的是文档加载器对象。进一步看帧加载器*加载(DocumentLoader *)的代码:
void frame loader:load(document loader * newDocumentLoader)
{
资源请求r=newDocumentLoader-request();
addextrafieldstominresourcerequest(r);
FrameLoadType类型;
if(shouldtreaturlassamcurrent(新文档加载器-原始请求().url())) {
r。setcachepolicy(reloadingoringcachedata);
type=FrameLoadTypeSame
}否则
type=FrameLoadTypeStandard
if (m_documentLoader)
newDocumentLoader-setOverrideEncoding(m _ document loader-override encoding());
//当我们为一个无法到达的统一资源定位器加载替代内容时
//在访问历史列表时,我们把它当作一个重载所以历史列表
//得到适当的维护。
//
//FIXME:这似乎是" FrameLoadTypeReload "含义的危险重载.
//难道不应该定义一个更明确的重载类型吗,也就是说大概
//加载而不影响历史?
if(shouldReloadToHandleUnreachableURL(newDocumentLoader)){
ASSERT(type==FrameLoadTypeStandard);
type=FrameLoadTypeReload
}
loadWithDocumentLoader(新文档加载器,类型,0);
}
来自:http://嗨。百度一下。com/jakmax/blog/item/e 43 f 56 b 11 ff 40958082302 b 1。超文本标记语言
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。