Add isLoadingMainFrame method to WebContents.

Also switch `webContents.executeJavaScript` to check it instead of `isLoading`.
There doesn’t seem to be a reasonable public way to get this information out of Chromium, so it’s synthesized here based on WebContentsObserver callbacks.
Fixes #5183.
This commit is contained in:
Rob Brackett 2016-04-18 10:37:08 -07:00
parent 3a9bbe30ac
commit 64a84dee3b
4 changed files with 44 additions and 3 deletions

View file

@ -220,7 +220,8 @@ WebContents::WebContents(content::WebContents* web_contents)
embedder_(nullptr), embedder_(nullptr),
type_(REMOTE), type_(REMOTE),
request_id_(0), request_id_(0),
background_throttling_(true) { background_throttling_(true),
is_loading_main_frame_(false) {
AttachAsUserData(web_contents); AttachAsUserData(web_contents);
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
} }
@ -229,7 +230,8 @@ WebContents::WebContents(v8::Isolate* isolate,
const mate::Dictionary& options) const mate::Dictionary& options)
: embedder_(nullptr), : embedder_(nullptr),
request_id_(0), request_id_(0),
background_throttling_(true) { background_throttling_(true),
is_loading_main_frame_(false) {
// Read options. // Read options.
options.Get("backgroundThrottling", &background_throttling_); options.Get("backgroundThrottling", &background_throttling_);
@ -543,12 +545,32 @@ void WebContents::DocumentLoadedInFrame(
void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host, void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) { const GURL& validated_url) {
bool is_main_frame = !render_frame_host->GetParent(); bool is_main_frame = !render_frame_host->GetParent();
if (is_main_frame)
is_loading_main_frame_ = false;
Emit("did-frame-finish-load", is_main_frame); Emit("did-frame-finish-load", is_main_frame);
if (is_main_frame) if (is_main_frame)
Emit("did-finish-load"); Emit("did-finish-load");
} }
void WebContents::DidStartProvisionalLoadForFrame(
content::RenderFrameHost* render_frame_host,
const GURL& url,
bool is_error_page,
bool is_iframe_srcdoc) {
if (!render_frame_host->GetParent())
is_loading_main_frame_ = true;
}
void WebContents::DidCommitProvisionalLoadForFrame(
content::RenderFrameHost* render_frame_host,
const GURL& url,
ui::PageTransition transition_type) {
if (!render_frame_host->GetParent())
is_loading_main_frame_ = true;
}
void WebContents::DidFailProvisionalLoad( void WebContents::DidFailProvisionalLoad(
content::RenderFrameHost* render_frame_host, content::RenderFrameHost* render_frame_host,
const GURL& url, const GURL& url,
@ -556,6 +578,8 @@ void WebContents::DidFailProvisionalLoad(
const base::string16& description, const base::string16& description,
bool was_ignored_by_handler) { bool was_ignored_by_handler) {
bool is_main_frame = !render_frame_host->GetParent(); bool is_main_frame = !render_frame_host->GetParent();
if (is_main_frame)
is_loading_main_frame_ = false;
Emit("did-fail-provisional-load", code, description, url, is_main_frame); Emit("did-fail-provisional-load", code, description, url, is_main_frame);
Emit("did-fail-load", code, description, url, is_main_frame); Emit("did-fail-load", code, description, url, is_main_frame);
} }
@ -793,6 +817,10 @@ bool WebContents::IsLoading() const {
return web_contents()->IsLoading(); return web_contents()->IsLoading();
} }
bool WebContents::IsLoadingMainFrame() const {
return is_loading_main_frame_;
}
bool WebContents::IsWaitingForResponse() const { bool WebContents::IsWaitingForResponse() const {
return web_contents()->IsWaitingForResponse(); return web_contents()->IsWaitingForResponse();
} }
@ -1189,6 +1217,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("_getURL", &WebContents::GetURL) .SetMethod("_getURL", &WebContents::GetURL)
.SetMethod("getTitle", &WebContents::GetTitle) .SetMethod("getTitle", &WebContents::GetTitle)
.SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isLoading", &WebContents::IsLoading)
.SetMethod("isLoadingMainFrame", &WebContents::IsLoadingMainFrame)
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
.SetMethod("_stop", &WebContents::Stop) .SetMethod("_stop", &WebContents::Stop)
.SetMethod("_goBack", &WebContents::GoBack) .SetMethod("_goBack", &WebContents::GoBack)

View file

@ -62,6 +62,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
GURL GetURL() const; GURL GetURL() const;
base::string16 GetTitle() const; base::string16 GetTitle() const;
bool IsLoading() const; bool IsLoading() const;
bool IsLoadingMainFrame() const;
bool IsWaitingForResponse() const; bool IsWaitingForResponse() const;
void Stop(); void Stop();
void ReloadIgnoringCache(); void ReloadIgnoringCache();
@ -228,6 +229,13 @@ class WebContents : public mate::TrackableObject<WebContents>,
int error_code, int error_code,
const base::string16& error_description, const base::string16& error_description,
bool was_ignored_by_handler) override; bool was_ignored_by_handler) override;
void DidStartProvisionalLoadForFrame(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
bool is_error_page,
bool is_iframe_srcdoc) override;
void DidCommitProvisionalLoadForFrame(content::RenderFrameHost* render_frame_host,
const GURL& url,
ui::PageTransition transition_type) override;
void DidStartLoading() override; void DidStartLoading() override;
void DidStopLoading() override; void DidStopLoading() override;
void DidGetResourceResponseStart( void DidGetResourceResponseStart(
@ -302,6 +310,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Whether background throttling is disabled. // Whether background throttling is disabled.
bool background_throttling_; bool background_throttling_;
// Whether the main frame (not just a sub-frame) is currently loading.
bool is_loading_main_frame_;
DISALLOW_COPY_AND_ASSIGN(WebContents); DISALLOW_COPY_AND_ASSIGN(WebContents);
}; };

View file

@ -116,7 +116,7 @@ let wrapWebContents = function (webContents) {
callback = hasUserGesture callback = hasUserGesture
hasUserGesture = false hasUserGesture = false
} }
if (this.getURL() && !this.isLoading()) { if (this.getURL() && !this.isLoadingMainFrame()) {
return asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture) return asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture)
} else { } else {
return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, 'executeJavaScript', callback, code, hasUserGesture)) return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, 'executeJavaScript', callback, code, hasUserGesture))

View file

@ -335,6 +335,7 @@ var registerWebViewElement = function () {
'loadURL', 'loadURL',
'getTitle', 'getTitle',
'isLoading', 'isLoading',
'isLoadingMainFrame',
'isWaitingForResponse', 'isWaitingForResponse',
'stop', 'stop',
'reload', 'reload',