WebKit曆史項管理的實現

來源:互聯網
上載者:User

標籤:webkit

曆史項管理根據標準定義,由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)中。以下是其時序圖:


以下是頁面跳轉時,向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曆史項管理的實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.