繼續上一次來分æž
LoadRequest
的代碼,在分æžé€™å€‹å‡½æ•¸ä»£ç¢¼ä¹‹å‰ï¼Œå…ˆçœ‹çœ‹
WebFrame
類的繼承層次關系,如下:
class WebFrame : public base::RefCounted<WebFrame> {
WebFrame
是一個接å£é¡žï¼Œä½†å®ƒå…ˆç¹¼æ‰¿å¼•ç”¨è¨ˆæ•¸é¡ž
RefCounted
,這樣å°äºŽé€™å€‹å°è±¡å¤šæ¬¡è¨ªå•ï¼Œå°±å¯ä»¥ä½¿ç”¨å¼•ç”¨è¨ˆæ•¸ä¾†åˆ¤æ–·å°è±¡çš„生命周期了。å°äºŽ
base::RefCounted<WebFrame>
的語法,其實它是一種模æ¿å¯¦ç¾çš„多態特性,這種方案是最高效的實ç¾æ–¹å¼ï¼Œæ¯”使用虛函數更少å å…§å˜ï¼Œå¹¶ä¸”é‹è¡Œçš„速度也更快。它就是解決如下的å•é¡Œï¼š
?
void Release() {
???
if (subtle::RefCountedBase::Release()) {
?????
delete static_cast<T*>(this);
???
}
?
}
上é¢çš„函數里
static_cast<T*>(this)
,它就是一種多態的實ç¾æ–¹æ³•ï¼Œç”±äºŽ
base::RefCounted
類并沒有è²æ˜Žç‚ºè™›æžæ§‹å‡½æ•¸ï¼Œå¦‚下:
template <class T>
class RefCounted : public subtle::RefCountedBase {
?
public:
?
RefCounted() { }
?
~RefCounted() { }
既然沒有把類
RefCounted
è²æ˜Žç‚ºè™›æžæ§‹å‡½æ•¸ï¼Œåˆæƒ³åœ¨åŸºé¡žé‡Œèª¿ç”¨æ´¾ç”Ÿé¡žçš„æžæ§‹å‡½æ•¸ï¼Œåªå¥½ä½¿ç”¨
static_cast
和類型轉æ›äº†ï¼Œé€™æ˜¯ä¸€ç¨®æ¯”較好的模æ¿ä½¿ç”¨æ–¹æ³•ï¼Œåœ¨
WTL
里就大é‡ä½¿ç”¨é€™ç¨®æŠ€è¡“。
接著å¯ä»¥çœ‹åˆ°ï¼š
class WebFrameImpl : public WebFrame {
?
public:
?
WebFrameImpl();
?
~WebFrameImpl();
é¡ž
WebFrameImpl
是繼承接å£é¡ž
WebFrame
,這里是使用接å£èˆ‡å¯¦ç¾åˆ†æžçš„è¨è¨ˆæ¨¡å¼ï¼Œé€™æ¨£æ›´æ–¹ä¾¿ä»£ç¢¼éˆæ´»åœ°å¾©ç”¨ã€‚å¯è¦‹è¨è¨ˆ
Chrome
çš„è¨è¨ˆå¸«å’Œå¯«ä»£ç¢¼çš„程åºå“¡ï¼Œéƒ½æ˜¯é ‚尖的模æ¿é«˜æ‰‹ï¼Œå¤§éƒ¨çš„æ€æƒ³èˆ‡
WTL
庫的è¨è¨ˆæ˜¯ä¸€è„ˆç›¸æ‰¿ã€‚也難怪
Chrome
çš„ç€è¦½å™¨ä½¿ç”¨
WTL
庫來è¨è¨ˆç•Œé¢ã€‚
#001
?
void WebFrameImpl::LoadRequest(WebRequest* request) {
#002
???
SubstituteData data;
#003
???
InternalLoadRequest(request, data, false);
#004
?
}
在
WebFrame
里調用函數
LoadRequest
,實際上是調用實ç¾é¡ž
WebFrameImpl
函數
LoadRequest
,而在這個函數åˆæ˜¯èª¿ç”¨
InternalLoadRequest
來實ç¾çš„,它的代碼如下:
#001
?
void WebFrameImpl::InternalLoadRequest(const WebRequest* request,
#002
????????????????????????????????????????
const SubstituteData& data,
#003
????????????????????????????????????????
bool replace) {
//
轉æ›è«‹æ±‚åƒæ•¸ã€‚
#004
???
const WebRequestImpl* request_impl =
#005
???????
static_cast<const WebRequestImpl*>(request);
#006
?
ç²å–請求的資æºã€‚
#007
???
const ResourceRequest& resource_request =
#008
???????
request_impl->frame_load_request().resourceRequest();
#009
?
#010
???
// Special-case javascript URLs.
?
Do not interrupt the existing load when
#011
???
// asked to load a javascript URL unless the script generates a result.
#012
???
// We can't just use FrameLoader::executeIfJavaScriptURL because it doesn't
#013
???
// handle redirects properly.
ç²å–需è¦ä¸‹è¼‰ç¶²é 的地å€ã€‚
#014
???
const KURL& kurl = resource_request.url();
處ç†åŠ 載
javascript
的連接情æ³ã€‚
#015
???
if (!data.isValid() && kurl.protocol() == "javascript") {
#016
?????
// Don't attempt to reload javascript URLs.
#017
?????
if (resource_request.cachePolicy() == ReloadIgnoringCacheData)
#018
???????
return;
#019
?
#020
?????
// We can't load a javascript: URL if there is no Document!
#021
?????
if (!frame_->document())
#022
???????
return;
#023
?
#024
?????
// TODO(darin): Is this the best API to use here?
?
It works and seems good,
#025
?????
// but will it change out from under us?
#026
?????
DeprecatedString script =
#027
?????????
KURL::decode_string(kurl.deprecatedString().mid(sizeof("javascript:")-1));
#028
?????
bool succ = false;
åŠ è¼‰åŸ·è¡Œè…³æœ¬ã€‚
#029
?????
WebCore::String value =
#030
?????????
frame_->loader()->executeScript(script, &succ, true);
#031
?????
if (succ && !frame_->loader()->isScheduledLocationChangePending()) {
#032
???????
// TODO(darin): We need to figure out how to represent this in session
#033
???????
// history.
?
Hint: don't re-eval script when the user or script navigates
#034
???????
// back-n-forth (instead store the script result somewhere).
#035
???????
LoadDocumentData(kurl, value, String("text/html"), String());
#036
?????
}
#037
?????
return;
#038
???
}
#039
?
åœæ¢ä¸Šä¸€æ¬¡æ²’有完æˆçš„åŠ è¼‰æƒ…æ³ã€‚
#040
???
StopLoading();
?
// make sure existing activity stops
#041
?
#042
???
// Keep track of the request temporarily.
?
This is effectively a way of
#043
???
// passing the request to callbacks that may need it.
?
See
#044
???
// WebFrameLoaderClient::createDocumentLoader.
ä¿å˜ç•¶å‰çš„請求連接。
#045
???
currently_loading_request_ = request;
#046
?
#047
???
// If we have a current datasource, save the request info on it immediately.
#048
???
// This is because WebCore may not actually initiate a load on the toplevel
#049
???
// frame for some subframe navigations, so we want to update its request.
ç²å–當å‰æ•¸æ“šæºï¼Œå¦‚果已經å˜åœ¨å°±å¯ä»¥ä¿å˜å®ƒã€‚
#050
???
WebDataSourceImpl* datasource = GetDataSourceImpl();
#051
???
if (datasource)
#052
?????
CacheCurrentRequestInfo(datasource);
#053
?
如果數據有效就å¯ä»¥ç›´æŽ¥æ›¿æ›å°±è¡Œäº†ã€‚
#054
???
if (data.isValid()) {
#055
?????
frame_->loader()->load(resource_request, data);
#056
?????
if (replace) {
#057
???????
// Do this to force WebKit to treat the load as replacing the currently
#058
???????
// loaded page.
#059
???????
frame_->loader()->setReplacing();
#060
?????
}
如果是æ·å²ç¶²é é¸æ“‡ï¼Œå°±åˆ¤æ–·æ˜¯å¦å‡ºéŒ¯çš„åŠ è¼‰è™•ç†ã€‚
#061
???
} else if (request_impl->history_item()) {
#062
?????
// Use the history item if we have one, otherwise fall back to standard
#063
?????
// load.
#064
?????
RefPtr<HistoryItem> current_item = frame_->loader()->currentHistoryItem();
#065
?
#066
?????
// If there is no current_item, which happens when we are navigating in
#067
?????
// session history after a crash, we need to manufacture one otherwise
#068
?????
// WebKit hoarks. This is probably the wrong thing to do, but it seems to
#069
???
??
// work.
#070
?????
if (!current_item) {
#071
???????
current_item = new HistoryItem(KURL("about:blank"), "");
#072
???????
frame_->loader()->setCurrentHistoryItem(current_item);
#073
???????
frame_->page()->backForwardList()->setCurrentItem(current_item.get());
#074
?
#075
???????
// Mark the item as fake, so that we don't attempt to save its state and
#076
???????
// end up with about:blank in the navigation history.
#077
???????
frame_->page()->backForwardList()->setCurrentItemFake(true);
#078
?????
}
#079
?
#080
?????
frame_->loader()->goToItem(request_impl->history_item().get(),
#081
????????????????????????????????
WebCore::FrameLoadTypeIndexedBackForward);
é‡æ–°åŠ 載網é 。
#082
???
} else if (resource_request.cachePolicy() == ReloadIgnoringCacheData) {
#083
?????
frame_->loader()->reload();
下é¢é–‹å§‹èª¿ç”¨
load
ä¾†åŠ è¼‰æ–°ä¸‹è¼‰çš„ç¶²é 資æºã€‚
#084
???
} else {
#085
?????
frame_->loader()->load(resource_request);
#086
???
}
#087
?
#088
???
currently_loading_request_ = NULL;
#089
?
}
上é¢é€šéŽå¹¾ç¨®æƒ…æ³ä¾†åˆ†åˆ¥å¯¦ç¾äº†åŠ 載
javascript
網é 的處ç†ï¼Œé‚„有æ·å²é¸é …處ç†ï¼Œé‚„有é‡æ–°åŠ 載網é å’ŒåŠ è¼‰æ–°ç¶²é 的處ç†ã€‚下一次å†ä¾†åˆ†æžåŠ 載新網é 的函數
frame_->loader()->load
的實ç¾ã€‚
æ›´å¤šæ–‡ç« ã€æŠ€è¡“交æµã€å•†å‹™åˆä½œã€è¯ç³»åšä¸»
微信掃碼或æœç´¢ï¼šz360901061

å¾®ä¿¡æŽƒä¸€æŽƒåŠ æˆ‘ç‚ºå¥½å‹
QQ號è¯ç³»ï¼š 360901061
您的支æŒæ˜¯åšä¸»å¯«ä½œæœ€å¤§çš„動力,如果您喜æ¡æˆ‘çš„æ–‡ç« ï¼Œæ„Ÿè¦ºæˆ‘çš„æ–‡ç« å°æ‚¨æœ‰å¹«åŠ©ï¼Œè«‹ç”¨å¾®ä¿¡æŽƒæ下é¢äºŒç¶ç¢¼æ”¯æŒåšä¸»2å…ƒã€5å…ƒã€10å…ƒã€20å…ƒç‰æ‚¨æƒ³æ的金é¡å§ï¼Œç‹ ç‹ é»žæ“Šä¸‹é¢çµ¦é»žæ”¯æŒå§ï¼Œç«™é•·éžå¸¸æ„Ÿæ¿€æ‚¨ï¼æ‰‹æ©Ÿå¾®ä¿¡é•·æŒ‰ä¸èƒ½æ”¯ä»˜è§£æ±ºè¾¦æ³•ï¼šè«‹å°‡å¾®ä¿¡æ”¯ä»˜äºŒç¶ç¢¼ä¿å˜åˆ°ç›¸å†Šï¼Œåˆ‡æ›åˆ°å¾®ä¿¡ï¼Œç„¶åŽé»žæ“Šå¾®ä¿¡å³ä¸Šè§’掃一掃功能,é¸æ“‡æ”¯ä»˜äºŒç¶ç¢¼å®Œæˆæ”¯ä»˜ã€‚
ã€æœ¬æ–‡å°æ‚¨æœ‰å¹«åŠ©å°±å¥½ã€‘å…ƒ
