Implementation of WebKit history item management and webkit history items
According to the standard definition, Page manages a Joint Session History, which contains the historical items of each sub-Frame. The logical relationship is as follows:
From the above, we can see three layers: Page, Frame, and JS Binding interfaces. The core of page loading is Frame through FrameLoader. HistoryController and BackForwardController can be regarded as interfaces for page loading to perform historical operations. The HistoryController is used in the Frame hierarchy, and the BackForwardController is used in the Page hierarchy to perform operations on historical items.
BackForwardClient and HistoryItem store the specific content of historical items. The change message of history items is sent by FrameLoaderClient (adapted to the WebKit Layer ).
The main class relationships in the Page hierarchy are as follows:
A HistoryItem can be understood as the state defined in the standard. The relationship between HistoryItem storage and Joint Session History is manifested in its stored member variables:
M_target and m_parent store all the Frame names. They can be obtained from FrameTree, representing the Frame corresponding to this HistoryItem and its parent Frame respectively.
M_scrollPoint indicates the current position. This value is differentiated if it is redirected through Anchor.
M_stateObject is the content operated through the pushState and replaceState of the HTML5 History API.
The JSBinding layer is provided by History to JS through Frame. At the Frame level, Frame mainly performs operations on historical items through FrameLoader. The page Jump operation is completed by NavigatorScheduler of the Frame. In HTML5 Spec, Session History operations are concentrated in HistoryController, and some logics are scattered in NavigationScheduler, such as the navigationschedist: mustLockBackForwardList () function and the processing logic for jump within 1 second.
When the page moves forward and backward, the specific loading operations are still centered on FrameLoader. HistoryController and BackForwardController are mainly storage operations at best. The change of history items also needs to be distributed to the WebKit and UI Layer by FrameLoaderClient and its implementation on various platforms (in which WebHistoryDelegate is the Delegate in which the WebView under Mac OS receives historical item-related information ).
When the page executes pushState through JS, A HistoryItem containing the State is generated in HistoryController in WebCore, and then added to BackForwardList (BackForwardClient. The timing diagram is as follows:
The following is the sequence diagram of the popState message sent to JS during page Jump:
For specific behavior logic, the standard definition of read-through is appropriate. The link is as follows:
Https://html.spec.whatwg.org/multipage/browsers.html
From WebKit external adaptation, the specific implementation differences are relatively large, but will be based on the historical item change Message notification corresponding to the UI forward and backward operations and Status display, so as to maintain consistency.
For example, in Mac OS, when a historical item changes, WebFrameLoaderClient: updateGlobalHistory () notifies WebView in the following way:
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; }
The process for creating and notifying history items is as follows:
Reprinted please indicate the source: http://blog.csdn.net/horkychen