历史项管理依据标准定义,由Page管理一个Joint Session History, 包括了各个子Frame的历史项。逻辑上相应例如以下的关系:

从上面看三个层次:Page,Frame,以及JS Binding的接口。页面载入的核心是由Frame通过FrameLoader来完毕的,HistoryController及BackForwardController能够视为页面载入进行历史项操作的接口。 Frame层次中通过HistoryController, Page层次中通过BackForwardController进行历史项操作。
BackForwardClient及HistoryItem则存储着历史项的详细内容。历史项的变化消息则由FrameLoaderClient负责发送(适配到WebKit层)。

Page层次中的主要类关系例如以下:

一个HistoryItem能够理解为标准中定义的state。HistoryItem存储和Joint Session History的关系表如今其存储的成员变量上:
  m_target, m_parent存储的都是Frame名称,能够从FrameTree获取到Frame, 分别代表着此HistoryItem相应的Frame, 以及其父Frame。
  m_scrollPoint则是当前显示的位置。假设是通过Anchor跳转,这个值就会有所区分。
  m_stateObject则是通过HTML5 History API的pushState及replaceState所操作的内容。

JSBinding层则是由History通过Frame向JS提供服务。在Frame的层次上,Frame主要通过FrameLoader进行历史项操作。页面跳转操作则由Frame的NavigatorScheduler来完毕。在HTML5 Spec中关于Session History的操作集中在HistoryController里,一部分逻辑分散在NavigationScheduler里,比方NavigationScheduler::mustLockBackForwardList()函数,以及1秒内跳转的处理逻辑。

当页面前进后退时,详细的载入操作还是以FrameLoader为核心的,HistoryController和BackForwardController充其量还主要是存储操作。历史项的变化也还须要由FrameLoaderClient及其在各个平台的实现来派发到WebKit及UI层(上图中WebHistoryDelegate即为Mac OS下WebView接收历史项相关信息的Delegate)。

当页面通过JS运行pushState,在WebCore就会在HistoryController中生成一个含有此State的HistoryItem,然后加入到BackForwardList(BackForwardClient)中。下面是其时序图:

当中在HistoryContrller::pushState()中会通过主Fame的HistoryContoller::createItemTree()来创建新的历史项,保存当前文档的状态。假设本身就是主Frame则不须要指定历史项间的从属关系。
下面是页面跳转时,向JS发送popState消息的时序图:

详细的行为逻辑,通读标准定义是最合适的。附链接例如以下:
     https://html.spec.whatwg.org/multipage/browsers.html

从WebKit对外的适配,详细的实现差异比較大,但都会以历史项变化的消息通知来相应UI上的前进后退操作及状态显示,这样能够保持一致性。
比方在Mac OS下,一个历史项变化时,WebFrameLoaderClient::updateGlobalHistory()会使用例如以下的方式通知到WebView上:
     

if ([view historyDelegate]) {
WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
if (implementations->navigatedFunc) {
WebNavigationData *data = [[WebNavigationData alloc] initWithURLString:loader->url()
title:nilOrNSString(loader->title().string())
originalRequest:loader->originalRequestCopy().nsURLRequest(UpdateHTTPBody)
response:loader->response().nsURLResponse()
hasSubstituteData:loader->substituteData().isValid()
clientRedirectSource:loader->clientRedirectSourceForHistory()]; CallHistoryDelegate(implementations->navigatedFunc, view, @selector(webView:didNavigateWithNavigationData:inFrame:), data, m_webFrame.get());
[data release];
} return;
}

历史项的创建及通知流程例如以下:

转载请注明出处: http://blog.csdn.net/horkychen

WebKit历史项管理的实现的更多相关文章

  1. WebKit的历史项管理

    标准定义 关于历史的管理,和HTML页面载入一样,都有其相应的标准.地址例如以下: WhatWG: https://html.spec.whatwg.org/multipage/browsers.ht ...

  2. ASP.NET Core 1.0 中的依赖项管理

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  3. RDIFramework.NET ━ 9.7 操作权限项管理 ━ Web部分

    RDIFramework.NET ━ .NET快速信息化系统开发框架 9.7 操作权限项管理 -Web部分 随着经济全球化趋势的发展和企业间竞争的加剧,企业对管理要求不断变化.提高,越来越多的信息都表 ...

  4. History API与浏览器历史堆栈管理

    移动端开发在某些场景中有着特殊需求,如为了提高用户体验和加快响应速度,常常在部分工程采用SPA架构.传统的单页应用基于url的hash值进行路由,这种实现不存在兼容性问题,但是缺点也有--针对不支持o ...

  5. windows启动项管理

    在运行框中输入 msconfig 选择启动栏 会跳转到任务管理器,可以管理启动项,可以看到我的启动项里有nc病毒 ,点击禁用即可.

  6. 什么是Maven? 使用Apache Maven构建和依赖项管理

    通过优锐课java架构学习中,学到了不少干货,整理分享给大家学习. 开始使用最流行的Java构建和依赖管理工具Maven Apache Maven是Java开发的基石,也是Java使用最广泛的构建管理 ...

  7. Linux命令:history命令历史的管理及用法

    bash可以保存的过去曾经执行过的命令.当某个用户登录到shell中,会读取该用户家目录中的~/.bash_history文件,并将历史命令列表保存到内存中.当用户退出当前shell时,会将内存中的历 ...

  8. Linux历史命令管理以及用法

    history [-c] [-d offset] [n] history -anrw [filename] history -ps arg [arg...] -c: 清空命令历史 -d offset: ...

  9. ubuntu mint 开机启动项管理

    使用工具 sysv-rc-conf,需要安装. 点击打开链接http://blog.chinaunix.net/uid-21516619-id-1825027.html

随机推荐

  1. HttpRequest 和HttpWebRequest的区别

    [1]问题: asp.NET C#  中HttpRequest 和HttpWebRequest的区别 HttpRequest 与HttpWebRequest 有什么区别? 网上中文的帖子很多,但是答案 ...

  2. smarty模板引擎原理解析

    //php 控制器文件 <?php//引入模板引擎文件include("20130304.php");$smarty =newTinySmarty();$qq_numbers ...

  3. #Leet Code# Same Tree

    语言:Python 描述:使用递归实现 # Definition for a binary tree node # class TreeNode: # def __init__(self, x): # ...

  4. start_amboot()函数分析

    一.整体流程 start_amboot()函数是执行完start.S汇编文件后第一个C语言函数,完成的功能自然还是初始化的工作 . 1.全局变量指针r8设定,以及全局变量区清零 2.执行一些类初始化函 ...

  5. 《深入剖析Tomcat》阅读(二)

    Tomcat是基于Sun公司标准的开源Servlet容器. Servlet是什么? Servlet(Server Applet),全称Java Servlet,未有中文译文.是用Java编写的服务器端 ...

  6. iOS MD5加密算法

    考虑到用户账户安全,对用户的登录密码进行MD5加密 什么是MD5加密呢...懒了就不在这搬砖了,大家可以自己搜索查查,在此记录下代码,以供以后学习查询! 下面,直接上代码... // 需要倒入这个头文 ...

  7. 关于Java(常用数据类型)

    工作中,除非特殊需要,一般使用的数据类型较为单一. int int 是最常用的类型之一,一般能满足判断或循环的需求 float 或 double 两个浮点类型,可以在一定程度上确保数据的精度 BigD ...

  8. bzoj 1486: [HNOI2009]最小圈 dfs求负环

    1486: [HNOI2009]最小圈 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1022  Solved: 487[Submit][Status] ...

  9. 【Ireport】利用Ireport5.2的table组件迅速制作表格导出pdf

    转载请注明网址.Ireport table dataset Ireport在半年前还是4.7,今天无意发现,居然出到了5.2就搞一把. 首先,去下载Ireport,并进行安装.这个我就不演示了.下载完 ...

  10. jquery deferred

    http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html http:// ...