In Page Navigation Issue about HasDocument() introduced in CEF3

Issue #1843 wontfix
yang zhou created an issue

Answers to the questions:

  1. Open a popup window, for example, window.open("https://www.w3.org/WAI/tutorials/page-structure/headings/");, If navigate in page, for example, https://www.w3.org/WAI/tutorials/page-structure/headings/#heading-levels.

  2. If check whether the current window is empty, using bool CefBrowserHostImpl::HasDocument(), the expected output is true. But it returns false instead.

  3. I am using CEF3 2272 in windows 7. The issue also exists in CEF3 2454 in windows. I have not tested all version, but I suspect that the issue is introduced in CEF3. CEF1 works as expected.

  4. Yes. It would be reproducible in CEF3 versions of CEFClient.

  5. No. The logic is in CEF source code.

More details: I met a In-Page-Navigation issue in CEF3, which does not exist in CEF1. I open a popup window, for example, window.open("https://www.w3.org/WAI/tutorials/page-structure/headings/");, If I navigate in page, for example, https://www.w3.org/WAI/tutorials/page-structure/headings/#heading-levels. Then If I check whether the current window is empty, using bool CefBrowserHostImpl::HasDocument(), it will return false. But actually, the current window has document, and should return true. Might be a bug introduced in CEF3? In CEF1, it works as expected. CEF1 does not set has_document_ to false whether we are navigating to a different page or in-page navigation.

I am trying to launch another popup window from the current one, using window.location.href, and close the current one if it is an empty popup window. With CEF1, it all work as expected. But when we update to CEF3, after in page navigation, the previous window is determined as empty, and will be closed when launching the new popup window.

Should I continue to use bool CefBrowserHostImpl::HasDocument() to check whether the window is empty or not. Or if there exists any other variables that I can use to check if the window is empty?

Looking into CEF source code, I found out in void WebContentsImpl::DidNavigateMainFramePostCommit( RenderFrameHostImpl* render_frame_host, const LoadCommittedDetails& details, const FrameHostMsg_DidCommitProvisionalLoad_Params& params)

it will call DidNavigateMainFramePostCommit(this) no matter whether it is navigating to a different page or in page navigation.

void CefBrowserHostImpl::DidNavigateMainFramePostCommit( content::WebContents* web_contents) { base::AutoLock lock_scope(state_lock_); has_document_ = false; }

DidNavigateMainFramePostCommit will set has_document to false.

If navigation to a different page, DocumentAvailableInMainFrame() will be called to set has_document_ to true. While navigating in page, DocumentAvailableInMainFrame() will never be called. And has_document_ will keep being false.

I patched to chromium not to call DidNavigateMainFramePostCommit() if it is in page navigation. This can solve the issue I am running into now. But our team are concerning whether patching to chromium will break anything else now or in the future. We might prefer a CEF level fix or work around.

Thanks, Yang Zhou

Comments (3)

  1. Marshall Greenblatt

    Marking as WontFix due to the age of the reported CEF version. If this problem still reproduces with currently supported CEF versions then we can re-open.

  2. Cristian Amarie

    Yes, it is reproducing even today (branch 3557). https://www.postbank.de/ > Login > Online Banking It can open https://banking.postbank.de/rai/login/?legacy=true If so, click on Demokonto testen, then close it and retry until the popup navigates to https://meine.postbank.de/#/login.

    Once it navigates to https://meine.postbank.de/#/login:

    • click on Demo-Konto testen

    • close the flying Aktuelles DIV (click on Weiter)

    • select first row from the table with operations

    • up to the table, there are 2 buttons, one "Neue Uberweisung" and one with 3 vertical dots; click on latter and choose PDF herunteladen

    Result: HasDocument() is false.

    This is happening because CefBrowserHostImpl::DidNavigateMainFramePostCommit is called (has_document_ becomes false) but CefBrowserHostImpl::DocumentAvailableInMainFrame is not called (so no has_document_ = true called).

  3. Cristian Amarie

    One thing I can't understand is:

    bool CefBrowserImpl::HasDocument() {
      CEF_REQUIRE_RT_RETURN(false);
    
      if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame())
        return !render_view()->GetWebView()->mainFrame()->document().isNull();
      return false;
    } 
    

    but host implements it as

    bool CefBrowserHostImpl::HasDocument() {
      base::AutoLock lock_scope(state_lock_);
      return has_document_;
    }
    

    In this case, it should call the CefBrowserImpl implementation and not the CefBrowserHostImpl one. Or have both CefBrowser and CefBrowserHost implement HasDocument.

  4. Log in to comment