Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-113109

[REG 6.4 -> 6.5] WebEngineScripts don't always run on pages containing iframes

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P2: Important
    • 6.5.1, 6.6.0
    • 6.5.0
    • WebEngine
    • None
    • 17c64fd5d (dev), 4b185cd29 (6.5)

    Description

      On 6.5 QWebEngineScripts don't appear to run on pages with embedded iframes when getting to them via certain types of navigation. In particular:

      Injection point: DocumentCreation

      Scripts run when the page is first loaded. But upon either reloading the page or navigating to it by going backwards in history the scripts no longer runs. (Actually it seems like they never run on the same domain in the same tab afterwards, no matter how you get there, but I didn't go to the effort of confirming that.)

      Injection point: DocumentReady

      Scripts run when the page is first loaded. But when navigating back to the page using history navigation the script doesn't run.

      Downstream bug report here: https://github.com/qutebrowser/qutebrowser/issues/7662

      It's pretty widespread there because qutebrowser injects some utility JS methods into the page at DocumentCreation and later scripts (eg triggered by key presses) rely on them.

      Here's a test script:

      #include <sstream>
      #include <iostream>
      #include <QUrl>
      #include <QApplication>
      #include <QtHttpServer>
      #include <QWebEngineScript>
      #include <QWebEngineScriptCollection>
      #include <QWebEngineView>
      #include <QWebEngineSettings>
      
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
      
          // Test page with:
          // * an iframe
          // * a div for the script to color in to show it is running
          // * a link to enable testing with navigation
          QHttpServer httpServer;
          httpServer.route("/", []() {
              return ""
      "<body>"
      "  <h1>Test userscript running on 6.5</h1>"
      "  <p>The square below should go green after a short delay if the script is running.</br>"
      "     Two cases</br>"
      "     1) DocumentCreation: script runs on page load but stops after reload</br>"
      "     2) DocumentReady: script runs on page load but stops after navigating to the 'other' page then back to the main page"
      "  </p>"
      "  <div id='colorme' style='background-color:red;width:100;height:100;'></div>"
      "  </br>"
      "  <a href='other'>other page</a>"
      "  </br>"
      "  <a href='/?a'>this page on a different URL</a>"
      "  </br>"
      "  <iframe src='https://example.com/'>"
      "  </iframe>"
      "</body>";
          });
          httpServer.route("/other", []() {
              return ""
      "<body>"
      "  <h1>other page</h1>"
      "  <a href='/'>index</a>"
      "</body>"
      ;
          });
          const auto port = httpServer.listen(QHostAddress::Any);
      
          QWebEngineView view;
          QWebEngineScript s;
      
          /* ===
           * Enable/disable these two lines for two different failure cases
           * outlined above.
           * ===
           */
          s.setInjectionPoint(QWebEngineScript::DocumentCreation);
          //s.setInjectionPoint(QWebEngineScript::DocumentReady);
      
          // These two setting don't seem to effect the results.
          //s.setWorldId(QWebEngineScript::ApplicationWorld);
          //s.setRunsOnSubFrames(true);
      
          // Test script to color the div.
          // In a timeout because DocumentCreation is too early to access the DOM.
          // Conditional for the RunsOnSubFrames case (for the child frame)
          s.setSourceCode(QStringLiteral(
      "window.setTimeout(() => {"
      "  var el = document.querySelector('#colorme');"
      "  if (el) {el.style='background-color:green;width:100;height:100;'}"
      "}, 250)"
          ));
          view.page()->scripts().insert(s);
      
          std::ostringstream url;
          url << "http://localhost:" << port << "/";
          std::cout << "Running on: " <<  url.str() << "\n";
          view.load(QUrl(url.str().c_str()));
          view.show();
      
          return app.exec();
      }
      

       

      Attachments

        For Gerrit Dashboard: QTBUG-113109
        # Subject Branch Project Status CR V

        Activity

          People

            allan.jensen Allan Sandfeld Jensen
            toofar toofar
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes