(系列一)webkit 的各个模块

   本文内容很残缺,有精力了再把自己掌握的内容写出来, 并且加上相关流程图.暂时先这样了. 
   Webkit的各个部分,我自己简单的归纳了一下. 
     0.程序界面管理.  
     1.加载网页的总控制器,loader.  
     2.资源内容的获取和管理  
     3.html,css文档的解析.  
     4.html元素,Dom树,CSS样式相关的各个数据结构的创建和维护  
     5.布局和渲染  
     6.事件响应  
     7.javascript部分  
     8.插件的支持.  
     9.其它杂项.  
    
    由于网络已经存在不少分析文章,有一些质量很高,因此我不必再重复别人的内容,徒增对比学习缓慢及错误之羞愧.而且既然写出来就要对内容负责,涉及细节太多,webkit仅是我个人众多业余爱好之一,非工作内容,精力实在不够. 
    网络上的文章欠缺DOM树构建过程的分析,和layout的具体细节分析. 不过前者乏味冗长,后者基本遵循CSS box模型,也没太大意义去深究. 罗列内容,供日后参考. 

一. webkitcore的外壳接口部分.  
   1.Page 
    Page类对应于一个网页的页面.比如它管理页面相关的如下数据结构,界面移植相关的client,RenderTheme,主Frame, 
,Plugins, BackForwardList,settings,进度条,音频音量,查找并高亮字符串等等. 
   该类在外部移植代码中创建, 如Qt版本在QWebPagePrivate的构造函数中创建. 
   网络文章对Page的分析: 
    http://blog.csdn.net/dlmu2001/article/details/6213377  
   2.Frame 
    Frame类对于一个网页内的Frame或iframe;一个网页原生窗口对应一个Page,Page处理页面相关的各种内容,一个Page对应一个主Frame,根据是否有Frame或iframe,主Frame又有子frame, 每个frame对应一个FrameView, 一个Document类. 
    frame管理的数据略混乱.与page相比,主要偏向管理HTML对象.如   FrameView,FrameLoader,DOMWindow,Document,scriptcontroller ,SelectionController,VisibleSelection,EventHandler 
   该类对象在外部移植代码中创建,如Qt版本在QWebFrameData的构造函数中创建. 
   它管理frame相关的数据结构.它与一份html代码对应,同时也对应着一个FrameView. 
   网络文章对Frame的分析: 
    http://blog.csdn.net/dlmu2001/article/details/6164873  
   FrameView 继承于 ScrollView. 拥有一个平台相关的PlatformWidget指针, 
在Qt中是Qwidget, win下是HWND.它主要是用来管理Frame的界面.不过貌似这个PlatformWidget并没有被使用. 
一直是NULL值.即一个Frame不是一个原生的窗口.FrameView是在Frame的CrateView方法中创建的. 
   Chrome继承于HostWindow,它与ChromeClient通信,ChromeClientQt继承ChromeClient主要是用来管理 
整个网页的窗口界面.ChromeClientQt是在QWebPagePrivate中创建,平台Widget指针由其传入. 
   每个移植一般要实现一些外壳类,如webview,webwidget,webpage,webframe之类的来封装相应的内容. 
   网络文章分析: 
    http://blog.csdn.net/dlmu2001/article/details/6208241  
 二. 加载控制器Loader. 
Loader: 
   主要是FrameLoader和Loader.一个加载网页,一个加载资源. 
   webkit主页上的论述. 
   http://www.webkit.org/blog/1188/how-webkit-loads-a-web-page/  
   网络文章的分析. 

http://www.jjos.org/%e8%bd%af%e4%bb%b6%e6%9e%b6%e6%9e%84/webkit-%e8%bd%af%e4%bb%b6%e6%9e%b6%e6%9e%84/2010/04/29/136_webkit.html
http://www.docin.com/p-35821198.html
 
  FrameLoader:
   http://blog.csdn.net/dlmu2001/article/details/6168545
  Loader:
   http://blog.csdn.net/dlmu2001/article/details/6363380
  涉及到的类大致有这些.
  FrameLoader,FrameLoaderClient,FrameLoaderClientQt, DocumentLoader,DocLoader,PolicyChecker,  MainResourceLoader,ResourceHandle, ResourceLoader,ResourceHandlerClient, MainResourceLoader,
SubResourceLoader,SubResourceLoaderClient,CacheResourceRequest,CachedResourceLoader,MemoryCached,CachedResource,CachedResourceLoader,
CachedImage,CachedFont,CachedScript,CachedCSSStyleSheet,ReouceLoaderSchedule,CacheResourceShedule,  
一个网页访问和加载的流程由FrameLoader 控制.
load过程的状态变迁:
   policy ->(审查)-> provisional -> (主html获取完毕)-> Committed
外壳会调用FrameLoader::load( ResourceRequest ),中途会交给FrameLoaderClient::createDocumentLoader来创建DocumentLoader,然后FrameLoader::loadWithDocumentLoader(),PolicyChecker::checkNavigationPolicy,检查完毕后 ,继续continueLoadAfterNavigationPolicy  ,进入provisional状态 ,执行provisionalLoadStarted() ,然后是根据是否要发送form 回调client的函数, 然后继续continueLoadAfterWillSubmitForm, 依次执行:
DocumentLoader::startLoadingMainResource 
m_mainResourceLoader = MainResourceLoader::create(m_frame);
MainResourceLoader::loadNow(ResourceRequest& r) ;
m_handle = ResourceHandle::create(r, this, m_frame.get(), false, true);
  再后续就进入了网络请求部分,大家可以自己查看调用堆栈.

   从网络模块收到数据后 : 

会回调到ResourceLoader的didReceiveData再到FrameLoader的receiveData ,再到FrameLoader::commitProvisionalLoad再到FrameLoader::transitionToCommitted ,在此回调Client的transitionToCommittedForNewPage , 在Client中调用了frame::createView(); 之后还会再回调一些Client的函数,执行渲染显示.最后到此结束一次load.

其它资源的load
  图片,在解析图片元素的时候 如果遇到src属性时,执行newImage=document->docLoader()->requestImage(sourceURI(attr));
当下载完毕的时候会回调到RenderImage的ImageChanged完成图片更新.
  css,解析到css元素的时候,StyleElement::process函数调用CSSParser::parseSheet()

三. html和css的解析  
MainResourceLoader会回调FrameLoader的ReceivedData() 
然后调用HTMLTokenizer::write() 
HTMLTokenizer完成了HTML文件的解析过程, 解析的同时创建了DOM/CSS等等数据结构. 
解析的过程并不有趣,代码繁杂,也没太多高深技术. 
可以参看下网络上的文章. 
 http://blog.csdn.net/dlmu2001/article/details/5998130  

html 解析部分:  
获取html数据后,传递给HTMLTokenizer::write();然后基本上就是这个类完成解析工作, 
解析过程就是一个个的读取字符,进行状态变迁.HTMLTokenizer继承于Tokenizer, Tokenizer只是个接口. 
HTMLTokenizer的write函数在解析到一个完整的token后会调用processToken,该函数调用 
HtmlParserr::parseToken() 再调用GetNode通过HTMLElementFactory::createHTMLElement产生Node对象 
然后调用insertNodeAfterLimitBlockDepth,该函数会调用insertNode(),insertNode函数中 : 
Node* newNode = m_current->addChild(n); 
    也即ContainerNode的addChild方法;等等等方法,以及 Element::attach()方法,在这个方法中又创建了RenderObject.通过createRendererIfNeeded(); 可见是边解析边创建,解析了足够创建结点 就创建结点Element.能够创建RenderObject就创建. 
解析没太特别的地方,倒是Node,Element,ContainerNode等类值得关注. 
 CSS的解析
使用了 lex和yyac ,Tokenizer.cpp被包含在CSSParser.cpp的最后. 
CSSGrammar.cpp 
  具体的yacc语法定义在 CSSGrammar.y文件中,该文件包含在CSSGrammar.cpp中 
而CSSParser负责相关的回调函数.CSSStyleRule代表一条css规则. 
最后的内容都在m_parsedStyleObjects,m_parsedRuleLists中. 

四. DOM树与Render树.  
网络文章的论述. 
http://www.jjos.org/%e4%ba%92%e8%81%94%e7%bd%91/%e6%b5%8f%e8%a7%88%e5%99%a8/2010/05/10/308_webkit-webkit-major-objects.html  (其中最后那张图片非常直观和经典) 
webkit主页上文章的翻译 
 http://www.webkit.org/blog/114/webcore-rendering-i-the-basics/  
 http://mogoweb.net/archives/45  
webkit研究报告(该文章Dom部分不多,但RenderObject数据结构的描述非常的详尽) 
 http://www.docin.com/p-35821198.html  
Document类 
  继承与ContainerNode 和 ScriptExecutionContext 
  在DOMImplementation::createDocument中创建 
  而此函数在 
   void FrameLoader::begin(const KURL& url, bool dispatch, SecurityOrigin* origin) 
  或  PassRefPtr<Document> DOMParser::parseFromString(const String& str, const String& contentType) 
  中调用. 
     1.Tokenizer 
     2.DocLoader 
     3.各类URL 
     4.CSSStyleSheet 
     5.HistoryItem 
     等等一个网页的方方面面数据都在这里. 
DOMWindow 
   供js调用的DOM接口. 
 五. 布局和渲染  
    layout和paint 
    webkit主页上的文章: 
     http://www.webkit.org/blog/114/webcore-rendering-i-the-basics/  
    layout的网络文章分析: 
     http://hi.baidu.com/liangyj/blog/item/edecdd333e57afff1a4cffcc.html  
     http://blog.chinaunix.net/space.php?uid=580722&do=blog&id=2090487  
    layout完成之后,RenderBox的渲染相关的成员就填写了正确的值: 
    比如: 
    IntRect m_frameRect; 
    int m_marginLeft; 
    int m_marginRight; 
    int m_marginTop; 
    int m_marginBottom; 
    paint: 
    根据css的要求设置相应的坐标,画刷,到最后提交给平台底层的绘图函数. 
 六. DOM事件处理.  
    网络文章分析: 
     http://www.starwd.com/?p=340  
     http://blogt.chinaunix.net/space.php?uid=20412483&do=blog&id=2994789  
     http://mobile.51cto.com/symbian-287629.htm  
 七. javascript  
    网络文章的分析: 
     http://www.osseye.com/?p=417  
     http://mogoweb.net/archives/194  
     http://ishare.iask.sina.com.cn/f/22019184.html  
     http://wenku.baidu.com/view/b7207e1fff00bed5b8f31d05.html  
     http://blog.csdn.net/bertzhang/article/details/6759055  
     http://wingolog.org/archives/2011/10/28/javascriptcore-the-webkit-js-implementation  
     http://wuhuizhong.iteye.com/blog/1107633  
    0. 外围和DOM绑定 
       scriptController,JSDOMWindowShell,Completion. 
       绑定webkitcore的方法和DOM对象到JSC见bindings目录以及脚本产生的generated目录中的文件 
    1. JSC的内部 
       (1) 解析和执行流程. 
        a. 解析. 
          jsc使用yacc来完成parse功能,利用yacc回调的函数,创建SourceElements结构.相关的数据结构参见Nodes.cpp, 然后SourceElements转化成ProgramNode,感觉2者意义上差别不大.然后创建一个ByteCodeGenerator对象,该对象调用大量emitcode函数,逻辑实现在 byteCodeGenerator.h,byteCodeGenerator.cpp, NodesCodegen.cpp中.最后产生的东西在CodeBlock的instruction中. 
        b. 执行. 
         入口:interpreter::execute(),根据是否启用JIT分别调用 jitcode()或 privateExecute. 
          如果启用JIT, jitcode调用JIT::compile->privatecompile(),调用了很多七七八八的函数,产生X86的机器代码,具体见Assembler相关类.最后的execute调用了JITStubs.cpp中的ctiTrampoline(),该函数为汇编代码,调整堆栈,然后开始执行. 
          如果不启用JIT, privateExecute()是长达3000行的巨大函数,重复及繁杂的完成了一个js解释器的完整逻辑,很强悍.哈哈. 
       (2) 内存管理. 

         jsc使用的是标记-清除式的GC.底层相关类,JSObject,JSCell和structure.

八. 插件的支持.     
    网上文章: 
    (plugin部分的代码分析) 
     http://wenku.baidu.com/view/9dfee12b3169a4517723a3a7.html  
     http://blog.csdn.net/myaccella/article/details/7009086  

九. 杂项.  
    安全(XSSAuditor). 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
源码介绍: 1、HTML是目前在用户体验、界面舒适度最先进的语言 2、HTML所有标签都是容器,CSS调试效果方便 3、最重要的一点,让做界面的去界面,写程序的去写程序吧,界面与程序分享得更彻底 4、支持js、jq和易语言交互! 5、窗口尺寸自适应; 6、支持FLASH; 7、网页文件可以放在服务器上(如果你有虚拟机或者云主机的话),也可以加密打包后,内存加载;还可以放在资源表里;防止界面代码泄露; 例子中,做了简单的交互示例。并无实际功能! 本例程仅演示界面功能,实际开发需添加更多功能代码; (调用了开源的wke模块) 什么是wke? WebKit 是一个开源的浏览器引擎,同时WebKit 也是苹果Mac OS X 系统引擎框架版本的名称,主要用于Safari,Dashboard,Mail 和其他一些Mac OS X 程序。WebKit 前身是 KDE 小组的 KHTML,WebKit 所包含的 WebCore 排版引擎和 JSCore 引擎来自于 KDE 的 KHTML 和 KJS,当年苹果比较了 Gecko 和 KHTML 后,仍然选择了后者,就因为它拥有清晰的源码结构、极快的渲染速度。apple将 KHTML 发扬光大,推出了装备 KHTML 改进型 WebKit 引擎的浏览器 Safari。Safari, Google Chrome,傲游3,猎豹浏览器,百度浏览器 opera浏览器 等都是基于 Webkit 开发。,Webkit作为一款优秀的浏览器内核,它众多优秀的特性引起业内的的广泛关注。尤其是近来,google的加入更是让Webkit有所升温,从 Goole Chrome浏览器, Goole Anroid手机操作系统内置浏览器均采用Webkit作为内核。
前言:奇易模块是一款基于FiddlerCoreApi二次封装便于易语言调用的开源模块,相信用过Fiddler的都知道他的作用,但我们将它发挥到了更大的作用,通过fiddler实现了对非IE浏览器的填表操作; 该模块的首个版本与2017年7月23号上线,至今已有近2年之久,也非常的感谢在使用中给奇易模块提供的思路和提供BUG的修复方案的那些无私奉献用户; 该版本5.0以后与以前的版本变动相对较大,很多使用方法更简化更开放化了,所以该模块与《高速网页填表与数据监听》教程中存在许多差异的地方,所以请尽请期待我们的最新一期教程; 由于该模块是由诺离一个人所开发,但是由于该模块并无正规的商业化性质,随着年龄的增长,肩上的压力越来越大,所以更新如果存在怠慢,还希望理解;再次感谢对模块提供帮助的那些用户! ------升级说明 本次版本的升级,由于抓去HTTPS数据需要安装证书,5.2.6版本后不在弹出证书安装提示,完全静默安装,但也存在一定弊端,即该模块每次都会重新安装证书,所以如果是抓取手机数据的,每次调试模块都需要重新安装一次证书;当然了,这个问题在今后的版本也会得到一定的优化并解决目前模块所产生的BUG问题。 ------开源声明 本次开源仅仅是对易语言模块的开源,具体核心开源已经开源至码云仓库项目,由VS2017 C++开发工具所编译 核心开源仓库地址:https://gitee.com/cih1996/odd_module FAQ  针对一些用户可能产生的问题: 1.部分电脑运行后出现模块加载失败报错; 该问题是由于系统比较纯净,缺少了相关VC运行库,只需要在百度把VC++运行库安装即可解决 2.运行目录下生成的过多文件; 生成的文件属于Fiddler的一些内核文件,如证书生成工具、Fiddler内核插件等,如果担心影响美观,只能做隐藏处理。 3.部分网页无法填表或无法填表; 填表原来是通过注入JS代码进行实现,注入JS代码的原理是通过文本替换的方式,有可能是该网页没有该文本可替换,可以观看以往的教程进行特定的绑定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值