WebKit的历史项管理
标准定义
关于历史的管理,和HTML页面载入一样,都有其相应的标准。地址例如以下:
	WhatWG: https://html.spec.whatwg.org/multipage/browsers.html#history
当中关于历史项的要点例如以下:
1. 在onload之前。非用户操作引起的导航操作不建立历史项。
非用户操作比方页面中指定的Timer改动location或iframe的src引发的导航操作。而用户点击发起的Timer,则在timer中记录下在发起timer时标记手势来源。但有一个例外是由还有一个Timer发起的Timer或是反复运行的Timer, 则仅针对第一次运行有效(以nesting level标识)。
2. 子Frame载入完毕仍有未载入的上层Frame, 则不创建历史项。
3. 当前Frame仅仅有一个历史项。且为about:blank, 则不创建历史项。
4. 假设页面跳转的间隔小于1s,则不创建历史项。
关于Timer的nesting level能够參考这里:
http://www.w3.org/html/wg/drafts/html/CR/webappapis.html#timer-nesting-level
以上规则相应于以下三个WebKit的函数:
a. LockBackForwardList NavigationScheduler::mustLockBackForwardList(Frame& targetFrame)
LockBackForwardList NavigationScheduler::mustLockBackForwardList(Frame& targetFrame)
{
    // Non-user navigation before the page has finished firing onload should not create a new back/forward item.
    // See https://webkit.org/b/42861 for the original motivation for this.   
    if (!ScriptController::processingUserGesture() && targetFrame.loader().documentLoader() && !targetFrame.loader().documentLoader()->wasOnloadHandled())
        return LockBackForwardList::Yes;
   
    // Navigation of a subframe during loading of an ancestor frame does not create a new back/forward item.
    // The definition of "during load" is any time before all handlers for the load event have been run.
    // See https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation for this.
    for (Frame* ancestor = targetFrame.tree().parent(); ancestor; ancestor = ancestor->tree().parent()) {
        Document* document = ancestor->document();
        if (!ancestor->loader().isComplete() || (document && document->processingLoadEvent()))
            return LockBackForwardList::Yes;
    }
    return LockBackForwardList::No;
}
b. HistoryController::currentItemShouldBeReplaced() const
{
    // From the HTML5 spec for location.assign():
    //  "If the browsing context's session history contains only one Document,
    //   and that was the about:blank Document created when the browsing context
    //   was created, then the navigation must be done with replacement enabled."
    return m_currentItem && !m_previousItem && equalIgnoringCase(m_currentItem->urlString(), blankURL());
}
c. void NavigationScheduler::scheduleRedirect(double delay, const URL& url)
{
    if (!shouldScheduleNavigation(url))
        return;
    if (delay < 0 || delay > INT_MAX / 1000)
        return;
    if (url.isEmpty())
        return;
    // We want a new back/forward list item if the refresh timeout is > 1 second.
    if (!m_redirect || delay <= m_redirect->delay()) {
        LockBackForwardList lockBackForwardList = delay <= 1 ? LockBackForwardList::Yes : LockBackForwardList::No;
        schedule(std::make_unique<ScheduledRedirect>(delay, m_frame.document()->securityOrigin(), url, LockHistory::Yes, lockBackForwardList));
    }
}
页面问题分析
1. Timer问题
最初WebKit建一个全局的变量记录, easy受到不同页面。frame中Timer的影响。
id=137631
。如以下測试页面所看到的。当在一个document中。有一个repeat timer运行后, 且未载入完毕(onload事件没有运行)。其他Timer的跳转仍然无法创建历史项。
<head>
</head>
<body>
<input type="button" value="Goto next page" onclick="gotoNextPage();">
<input type="button" value="Start repeating timer" onclick="startRepeatingTimer();">
<p>
<div id="Timer">Paused</div>
</p>
<script type="text/javascript">
function gotoNextPage(){
    setTimeout(function(){location.href="http://www.webkit.org/";},300);
  }
function startRepeatingTimer(){
    setInterval(function(){document.getElementById("Timer").innerHTML="Running...";},500);
  }
  </script>
<img src="http://therecoveringpolitician.com/wp-content/uploads/2013/01/moderate.jpg" width="640" height="480">
  <img src="http://cullogo.com/full/wallpapers-high-resolution-widescreen-hd-pk.jpg" width="640" height="480">
  <img src="http://www.highresolutionwallpapers.net/wallpapers/autumn-1680x1050.jpg" width="640" height="480">
  </body>
</html>
2. 载入规则导致多余历史项问题
<head>
</head>
<body>
<p>
<div id="info">Loading...</div>
</p>
<script type="text/javascript">
setTimeout(function(){ attr("sub_iframe","http://m.baidu.com/?abc=23&t=20080225");},5000);
function attr(id,url){
        var obj=document.getElementById(id);
        obj.setAttribute("src", url);
    }
    
    window.onload=function(){
        document.getElementById("info").innerHTML="Loaded.";
    }
</script>
  <iframe src="http://m.baidu.com/?abc=23&t=20080225" id="sub_iframe" width="320" height="480"></iframe><br/>
  </body>
</html>
WebKit的历史项管理的更多相关文章
- WebKit历史项管理的实现
		历史项管理依据标准定义,由Page管理一个Joint Session History, 包括了各个子Frame的历史项.逻辑上相应例如以下的关系: 从上面看三个层次:Page,Frame,以及JS B ... 
- ASP.NET Core 1.0 中的依赖项管理
		var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ... 
- RDIFramework.NET ━ 9.7 操作权限项管理 ━ Web部分
		RDIFramework.NET ━ .NET快速信息化系统开发框架 9.7 操作权限项管理 -Web部分 随着经济全球化趋势的发展和企业间竞争的加剧,企业对管理要求不断变化.提高,越来越多的信息都表 ... 
- History API与浏览器历史堆栈管理
		移动端开发在某些场景中有着特殊需求,如为了提高用户体验和加快响应速度,常常在部分工程采用SPA架构.传统的单页应用基于url的hash值进行路由,这种实现不存在兼容性问题,但是缺点也有--针对不支持o ... 
- windows启动项管理
		在运行框中输入 msconfig 选择启动栏 会跳转到任务管理器,可以管理启动项,可以看到我的启动项里有nc病毒 ,点击禁用即可. 
- 什么是Maven? 使用Apache Maven构建和依赖项管理
		通过优锐课java架构学习中,学到了不少干货,整理分享给大家学习. 开始使用最流行的Java构建和依赖管理工具Maven Apache Maven是Java开发的基石,也是Java使用最广泛的构建管理 ... 
- Linux命令:history命令历史的管理及用法
		bash可以保存的过去曾经执行过的命令.当某个用户登录到shell中,会读取该用户家目录中的~/.bash_history文件,并将历史命令列表保存到内存中.当用户退出当前shell时,会将内存中的历 ... 
- Linux历史命令管理以及用法
		history [-c] [-d offset] [n] history -anrw [filename] history -ps arg [arg...] -c: 清空命令历史 -d offset: ... 
- ubuntu mint 开机启动项管理
		使用工具 sysv-rc-conf,需要安装. 点击打开链接http://blog.chinaunix.net/uid-21516619-id-1825027.html 
随机推荐
- linux文件名乱码解决办法
			1.linux解压压缩文件乱码 unzip -O CP936 xxx.zip 2.一般文件用convmv sudo convmv -f gbk -t utf-8 -r --notest /your_d ... 
- Prepare Python environment and install selenium.
			1, Install python and selenium. I use python 3.5, the following is the example 1.) Python downloa ... 
- [C#]Stream.Write Extension Method
			在处理Stream型态时常会使用到Stream.Write这个方法,每次都会有种疑问就是,大多数的处理都是要将Buffer整个写入,為何偏偏每次都要将索引带0,长度带為Buffer的大小呢?另外在处理 ... 
- 强烈推荐visual c++ 2012入门经典适合初学者入门
			强烈推荐visual c++ 2012入门经典适合初学者入门 此书循序渐进,用其独特.易于理解的教程风格来介绍各个主题,无论是编程新手,还是经验丰富的编程人员,都很容易理解. 此书的目录基本覆盖了Wi ... 
- nodejs的url模块中的resolve()的用法总结
			var url = require('url'); var a = url.resolve('/one/two/three', 'four') , b = url.resolve('http://ex ... 
- Android 4.2启动代码分析(一)
			Android系统启动过程分析 Android系统的框架架构图如下(来自网上): Linux内核启动之后----->就到Android的Init进程 ----->进而启动Android ... 
- Android开发学习之TypedArray类
			在学习Android的开发中,学习Gallery视图显示图片的过程中,在设置图片适配器的时候,用到了此TypedArray类型,这次根据android SDK,一块把此类型弄清楚! android.c ... 
- http 双向通信之port映射
			新产品开发了近2-3个月,给到客户做试用的时候,发现一个开发这么久从未考虑到的一个通信问题,mark下,下次开发同类产品的时候长点记性了. 产品由client与服务端两部分组成,client与服务端须 ... 
- xcode UIImage图片拉伸
			图片拉伸 +(UIImage*)wlisWithImage:(NSString *)name{ //获取图片 UIImage * img=[UIImage imageNamed:name]; //获取 ... 
- 今年暑假不AC1
			Description "今年暑假不AC?" "是的." "那你干什么呢?" "看世界杯呀,笨蛋!" " ... 
