Changeset 118158 in webkit


Ignore:
Timestamp:
May 23, 2012 4:03:11 AM (12 years ago)
Author:
vestbo@webkit.org
Message:

[Qt] Make the web view's url property follow the active url

https://bugs.webkit.org/show_bug.cgi?id=77554

The url property of the webview now reflects the 'active' url of the
page, which maps to either the currently loading url, in the case of
an ongoing load, or the result of a load, even when the load failed.

In practice this means that setting the url though QML, or navigating
to a new url in the page by e.g clicking, will both instantly change
the url-property of the webview to the target url. This differs from
earlier behavior, where we would update the url when the load
committed.

An optional argument is added to loadHtml(), to allow setting
the unreachable url when providing replacement content for failed
loads.

Finally, the location bar in the minibrowser is updated to behave
a bit more like normal browsers in terms of when the url will change
and how active focus is handled.

Reviewed by Simon Hausmann.

Location:
trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r118156 r118158  
     12012-04-18  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
     2
     3        [Qt] Make the web view's url property follow the active url
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=77554
     6
     7        The url property of the webview now reflects the 'active' url of the
     8        page, which maps to either the currently loading url, in the case of
     9        an ongoing load, or the result of a load, even when the load failed.
     10
     11        In practice this means that setting the url though QML, or navigating
     12        to a new url in the page by e.g clicking, will both instantly change
     13        the url-property of the webview to the target url. This differs from
     14        earlier behavior, where we would update the url when the load
     15        committed.
     16
     17        An optional argument is added to loadHtml(), to allow setting
     18        the unreachable url when providing replacement content for failed
     19        loads.
     20
     21        Finally, the location bar in the minibrowser is updated to behave
     22        a bit more like normal browsers in terms of when the url will change
     23        and how active focus is handled.
     24
     25        Reviewed by Simon Hausmann.
     26
     27        * UIProcess/API/qt/qquickwebview.cpp:
     28        (QQuickWebViewPrivate::onComponentComplete):
     29        (QQuickWebView::reload):
     30        (QQuickWebView::url):
     31        (QQuickWebView::setUrl):
     32        (QQuickWebView::loadHtml):
     33        * UIProcess/API/qt/qquickwebview_p.h:
     34        * UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro:
     35        * UIProcess/API/qt/tests/qmltests/WebView.pro:
     36        * UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml:
     37        * UIProcess/API/qt/tests/qmltests/common/link.html: Added.
     38        * UIProcess/API/qt/tests/qmltests/common/redirect.html: Added.
     39        * UIProcess/qt/QtWebPageLoadClient.cpp:
     40        (QtWebPageLoadClient::QtWebPageLoadClient):
     41        (QtWebPageLoadClient::didStartProvisionalLoadForFrame):
     42        (QtWebPageLoadClient::didReceiveServerRedirectForProvisionalLoadForFrame):
     43        (QtWebPageLoadClient::didCommitLoadForFrame):
     44        (QtWebPageLoadClient::dispatchLoadFailed):
     45        (QtWebPageLoadClient::didFailProvisionalLoadWithErrorForFrame):
     46        (QtWebPageLoadClient::didFailLoadWithErrorForFrame):
     47        * UIProcess/qt/QtWebPageLoadClient.h:
     48        (QtWebPageLoadClient):
     49
    1502012-05-23  Simon Hausmann  <simon.hausmann@nokia.com>
    251
  • trunk/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp

    r117968 r118158  
    329329*/
    330330
    331 void QQuickWebViewPrivate::provisionalLoadDidStart(const QUrl& url)
    332 {
    333     Q_Q(QQuickWebView);
    334 
    335     QWebLoadRequest loadRequest(url, QQuickWebView::LoadStartedStatus);
     331void QQuickWebViewPrivate::provisionalLoadDidStart(const WTF::String& url)
     332{
     333    Q_Q(QQuickWebView);
     334
     335    q->emitUrlChangeIfNeeded();
     336
     337    QWebLoadRequest loadRequest(QString(url), QQuickWebView::LoadStartedStatus);
    336338    emit q->loadingChanged(&loadRequest);
    337339}
    338340
     341void QQuickWebViewPrivate::didReceiveServerRedirectForProvisionalLoad(const WTF::String&)
     342{
     343    Q_Q(QQuickWebView);
     344
     345    q->emitUrlChangeIfNeeded();
     346}
     347
    339348void QQuickWebViewPrivate::loadDidCommit()
    340349{
     
    343352
    344353    emit q->navigationHistoryChanged();
    345     emit q->urlChanged();
    346354    emit q->titleChanged();
    347355}
     
    351359    Q_Q(QQuickWebView);
    352360
     361    q->emitUrlChangeIfNeeded();
    353362    emit q->navigationHistoryChanged();
    354     emit q->urlChanged();
    355363}
    356364
     
    414422{
    415423    Q_Q(QQuickWebView);
     424
    416425    if (q->url() != pageURL)
    417426        return;
     
    637646    Q_Q(QQuickWebView);
    638647    if (m_iconURL == iconURL)
     648        return;
     649
     650    if (!webPageProxy->mainFrame())
    639651        return;
    640652
     
    14301442{
    14311443    Q_D(QQuickWebView);
     1444
     1445    WebFrameProxy* mainFrame = d->webPageProxy->mainFrame();
     1446    if (mainFrame && !mainFrame->unreachableURL().isEmpty() && mainFrame->url() != blankURL()) {
     1447        // We are aware of the unreachable url on the UI process side, but since we haven't
     1448        // loaded alternative/subsitute data for it (an error page eg.) WebCore doesn't know
     1449        // about the unreachable url yet. If we just do a reload at this point WebCore will try to
     1450        // reload the currently committed url instead of the unrachable url. To work around this
     1451        // we override the reload here by doing a manual load.
     1452        d->webPageProxy->loadURL(mainFrame->unreachableURL());
     1453        // FIXME: We should make WebCore aware of the unreachable url regardless of substitute-loads
     1454        return;
     1455    }
     1456
    14321457    const bool reloadFromOrigin = true;
    14331458    d->webPageProxy->reload(reloadFromOrigin);
     
    14371462{
    14381463    Q_D(const QQuickWebView);
    1439     RefPtr<WebFrameProxy> mainFrame = d->webPageProxy->mainFrame();
    1440     if (!mainFrame)
    1441         return QUrl();
    1442     return QUrl(QString(mainFrame->url()));
     1464
     1465    // FIXME: Enable once we are sure this should not trigger
     1466    // Q_ASSERT(d->m_currentUrl == d->webPageProxy->activeURL());
     1467
     1468    return QUrl(d->m_currentUrl);
    14431469}
    14441470
     
    14511477
    14521478    d->webPageProxy->loadURL(url.toString());
     1479    emitUrlChangeIfNeeded();
     1480}
     1481
     1482// Make sure we don't emit urlChanged unless it actually changed
     1483void QQuickWebView::emitUrlChangeIfNeeded()
     1484{
     1485    Q_D(QQuickWebView);
     1486
     1487    WTF::String activeUrl = d->webPageProxy->activeURL();
     1488    if (activeUrl != d->m_currentUrl) {
     1489        d->m_currentUrl = activeUrl;
     1490        emit urlChanged();
     1491    }
    14531492}
    14541493
     
    17981837    document are located relative to \a baseUrl.
    17991838
     1839    If an \a unreachableUrl is passed it is used as the url for the loaded
     1840    content. This is typically used to display error pages for a failed
     1841    load.
     1842
    18001843    \sa WebView::url
    18011844*/
    1802 void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl)
    1803 {
    1804     Q_D(QQuickWebView);
    1805     d->webPageProxy->loadHTMLString(html, baseUrl.toString());
     1845void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl, const QUrl& unreachableUrl)
     1846{
     1847    Q_D(QQuickWebView);
     1848    if (unreachableUrl.isValid())
     1849        d->webPageProxy->loadAlternateHTMLString(html, baseUrl.toString(), unreachableUrl.toString());
     1850    else
     1851        d->webPageProxy->loadHTMLString(html, baseUrl.toString());
    18061852}
    18071853
  • trunk/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h

    r117943 r118158  
    151151
    152152public Q_SLOTS:
    153     void loadHtml(const QString& html, const QUrl& baseUrl = QUrl());
     153    void loadHtml(const QString& html, const QUrl& baseUrl = QUrl(), const QUrl& unreachableUrl = QUrl());
    154154
    155155    void goBack();
     
    204204    WKPageRef pageRef() const;
    205205
     206    void emitUrlChangeIfNeeded();
     207
    206208    Q_PRIVATE_SLOT(d_func(), void _q_suspend());
    207209    Q_PRIVATE_SLOT(d_func(), void _q_resume());
  • trunk/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h

    r117943 r118158  
    7575    virtual void disableMouseEvents() { }
    7676
    77     virtual void provisionalLoadDidStart(const QUrl& url);
     77    virtual void provisionalLoadDidStart(const WTF::String& url);
     78    virtual void didReceiveServerRedirectForProvisionalLoad(const WTF::String& url);
    7879    virtual void loadDidCommit();
    7980    virtual void didSameDocumentNavigation();
     
    199200    QUrl m_iconURL;
    200201    int m_loadProgress;
     202    WTF::String m_currentUrl;
    201203};
    202204
  • trunk/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp

    r116102 r118158  
    7171    << "QQuickWebView.linkHovered(QUrl,QString) --> void"
    7272    << "QQuickWebView.navigationRequested(QWebNavigationRequest*) --> void"
     73    << "QQuickWebView.loadHtml(QString,QUrl,QUrl) --> void"
    7374    << "QQuickWebView.loadHtml(QString,QUrl) --> void"
    7475    << "QQuickWebView.loadHtml(QString) --> void"
  • trunk/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml

    r109136 r118158  
    3636            var url = Qt.resolvedUrl("../common/favicon.html")
    3737            webView.url = url
    38             spy.wait()
     38            verify(webView.waitForLoadSucceeded())
     39            expectFail("", "https://bugs.webkit.org/show_bug.cgi?id=87133")
    3940            compare(spy.count, 1)
    4041            compare(favicon.width, 48)
     
    4647            var url = Qt.resolvedUrl("../common/favicon2.html?favicon=load should work with#whitespace!")
    4748            webView.url = url
    48             spy.wait()
     49            verify(webView.waitForLoadSucceeded())
     50            expectFail("", "https://bugs.webkit.org/show_bug.cgi?id=87133")
    4951            compare(spy.count, 1)
    5052            compare(favicon.width, 16)
    5153            compare(favicon.height, 16)
     54
    5255        }
    5356    }
  • trunk/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml

    r115862 r118158  
    1010    property int numLoadStarted: 0
    1111    property int numLoadSucceeded: 0
     12
     13    focus: true
    1214
    1315    onLoadProgressChanged: {
     
    2830        id: test
    2931        name: "WebViewLoadUrl"
     32        when: windowShown
     33
    3034        function test_loadIgnoreEmptyUrl() {
    3135            var url = Qt.resolvedUrl("../common/test1.html")
     
    5963            compare(webView.url, url)
    6064        }
     65
     66        function test_urlProperty() {
     67            var url = Qt.resolvedUrl("../common/test1.html")
     68
     69            webView.url = url
     70            compare(webView.url, url)
     71            verify(webView.waitForLoadSucceeded())
     72            compare(webView.url, url)
     73
     74            var bogusSite = "http://www.somesitethatdoesnotexist.abc/"
     75            webView.url = bogusSite
     76            compare(webView.url, bogusSite)
     77            verify(webView.waitForLoadFailed())
     78            compare(webView.url, bogusSite)
     79
     80            webView.url = "about:blank" // Reset from previous test
     81            verify(webView.waitForLoadSucceeded())
     82
     83            var handleLoadFailed = function(loadRequest) {
     84                if (loadRequest.status == WebView.LoadFailedStatus) {
     85                    compare(webView.url, bogusSite)
     86                    compare(loadRequest.url, bogusSite)
     87                    webView.loadHtml("load failed", bogusSite, bogusSite)
     88                }
     89            }
     90            webView.loadingChanged.connect(handleLoadFailed)
     91            webView.url = bogusSite
     92            compare(webView.url, bogusSite)
     93            verify(webView.waitForLoadSucceeded())
     94            compare(webView.url, bogusSite)
     95            webView.loadingChanged.disconnect(handleLoadFailed)
     96
     97            var dataUrl = "data:text/html,foo"
     98            webView.url = dataUrl
     99            compare(webView.url, dataUrl)
     100
     101            var redirectUrl = Qt.resolvedUrl("../common/redirect.html")
     102            webView.url = redirectUrl
     103            compare(webView.url, redirectUrl)
     104            verify(webView.waitForLoadSucceeded())
     105            compare(webView.url, redirectUrl)
     106            verify(webView.waitForLoadSucceeded())
     107            compare(webView.url, url)
     108
     109            var linkUrl = Qt.resolvedUrl("../common/link.html")
     110            webView.url = linkUrl
     111            compare(webView.url, linkUrl)
     112            verify(webView.waitForLoadSucceeded())
     113            compare(webView.url, linkUrl)
     114            webView.loadingChanged.connect(function(loadRequest) {
     115                compare(webView.url, loadRequest.url)
     116                compare(webView.url, url)
     117            })
     118            webView.forceActiveFocus()
     119            keyPress(Qt.Key_Return) // Link is focused
     120            verify(webView.waitForLoadSucceeded())
     121            compare(webView.url, url)
     122        }
    61123    }
    62124}
  • trunk/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp

    r116516 r118158  
    3737    loadClient.clientInfo = this;
    3838    loadClient.didStartProvisionalLoadForFrame = didStartProvisionalLoadForFrame;
     39    loadClient.didReceiveServerRedirectForProvisionalLoadForFrame = didReceiveServerRedirectForProvisionalLoadForFrame;
    3940    loadClient.didFailProvisionalLoadWithErrorForFrame = didFailProvisionalLoadWithErrorForFrame;
    4041    loadClient.didCommitLoadForFrame = didCommitLoadForFrame;
     
    5051}
    5152
    52 void QtWebPageLoadClient::didStartProvisionalLoad(const QUrl& url)
     53void QtWebPageLoadClient::didStartProvisionalLoad(const WTF::String& url)
    5354{
    5455    m_webView->d_func()->provisionalLoadDidStart(url);
    5556}
    5657
     58void QtWebPageLoadClient::didReceiveServerRedirectForProvisionalLoad(const WTF::String& url)
     59{
     60    m_webView->d_func()->didReceiveServerRedirectForProvisionalLoad(url);
     61}
     62
    5763void QtWebPageLoadClient::didCommitLoad()
    5864{
     
    8591}
    8692
    87 void QtWebPageLoadClient::dispatchLoadFailed(const QtWebError& error)
     93void QtWebPageLoadClient::dispatchLoadFailed(WebFrameProxy* frame, const QtWebError& error)
    8894{
    8995    int errorCode = error.errorCode();
    9096
    9197    if (error.isCancellation() || errorCode == kWKErrorCodeFrameLoadInterruptedByPolicyChange || errorCode == kWKErrorCodePlugInWillHandleLoad) {
     98        // The active url might have changed
     99        m_webView->emitUrlChangeIfNeeded();
     100
    92101        // Make sure that LoadStartedStatus has a counterpart when e.g. requesting a download.
    93102        dispatchLoadSucceeded();
     103
    94104        return;
    95105    }
     106
     107    // We set the unreachable url unconditionally so that the current
     108    // active url of the webview when the loadingChanged signal is
     109    // emitted reflects the failed url, not the previously committed
     110    // url. This also ensures that if the user does not do a loadHtml
     111    // with an error page and and unreachable url as a reponse to the
     112    // failed load, we can still detect the failed url for reloads.
     113    frame->setUnreachableURL(error.url());
     114    m_webView->emitUrlChangeIfNeeded();
    96115
    97116    m_webView->d_func()->loadDidFail(error);
     
    108127    if (!WKFrameIsMainFrame(frame))
    109128        return;
    110     QString urlStr(toImpl(frame)->provisionalURL());
    111     QUrl qUrl = urlStr;
    112     toQtWebPageLoadClient(clientInfo)->didStartProvisionalLoad(qUrl);
     129    toQtWebPageLoadClient(clientInfo)->didStartProvisionalLoad(toImpl(frame)->provisionalURL());
     130}
     131
     132void QtWebPageLoadClient::didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
     133{
     134    if (!WKFrameIsMainFrame(frame))
     135        return;
     136
     137    WebFrameProxy* wkframe = toImpl(frame);
     138    toQtWebPageLoadClient(clientInfo)->didReceiveServerRedirectForProvisionalLoad(wkframe->provisionalURL());
    113139}
    114140
     
    117143    if (!WKFrameIsMainFrame(frame))
    118144        return;
    119     toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(error);
     145    toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(toImpl(frame), error);
    120146}
    121147
     
    138164    if (!WKFrameIsMainFrame(frame))
    139165        return;
    140     toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(error);
     166    toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(toImpl(frame), error);
    141167}
    142168
  • trunk/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h

    r116516 r118158  
    2323
    2424#include <QtGlobal>
     25#include <WebFrameProxy.h>
    2526#include <WKPage.h>
     27#include <wtf/text/WTFString.h>
    2628
    2729QT_BEGIN_NAMESPACE
     
    4042
    4143private:
    42     void didStartProvisionalLoad(const QUrl&);
     44    void didStartProvisionalLoad(const WTF::String&);
     45    void didReceiveServerRedirectForProvisionalLoad(const WTF::String&);
    4346    void didCommitLoad();
    4447    void didSameDocumentNavigation();
     
    4851
    4952    void dispatchLoadSucceeded();
    50     void dispatchLoadFailed(const QtWebError&);
     53    void dispatchLoadFailed(WebFrameProxy*, const QtWebError&);
    5154
    5255
    5356    // WKPageLoadClient callbacks.
    5457    static void didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
     58    static void didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
    5559    static void didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef, WKErrorRef, WKTypeRef userData, const void* clientInfo);
    5660    static void didCommitLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
  • trunk/Tools/ChangeLog

    r118155 r118158  
     12012-04-18  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
     2
     3        [Qt] Make the web view's url property follow the active url
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=77554
     6
     7        Update  the location bar in the minibrowser to behave
     8        a bit more like normal browsers in terms of when the url will change
     9        and how active focus is handled.
     10
     11        Reviewed by Simon Hausmann.
     12
     13        * MiniBrowser/qt/qml/BrowserWindow.qml:
     14
    1152012-05-23  Oswald Buddenhagen  <oswald.buddenhagen@nokia.com>
    216
  • trunk/Tools/MiniBrowser/qt/qml/BrowserWindow.qml

    r117061 r118158  
    4343    function load(address) {
    4444        webView.url = address
     45        webView.forceActiveFocus()
    4546    }
    4647
    4748    function reload() {
    4849        webView.reload()
     50        webView.forceActiveFocus()
    4951    }
    5052
     
    254256                }
    255257                radius: 3
    256                 width: parent.width / 100 * webView.loadProgress
     258                width: parent.width / 100 * Math.max(5, webView.loadProgress)
    257259                color: "blue"
    258260                opacity: 0.3
    259                 visible: webView.loadProgress != 100
     261                visible: webView.loading
    260262            }
    261263            Image {
     
    274276                clip: true
    275277                selectByMouse: true
     278                horizontalAlignment: TextInput.AlignLeft
    276279                font {
    277280                    pointSize: 11
     
    286289
    287290                Keys.onReturnPressed:{
    288                     console.log("going to: ", addressLine.text)
    289                     webView.url = utils.urlFromUserInput(addressLine.text)
    290                 }
     291                    console.log("Navigating to: ", addressLine.text)
     292                    load(utils.urlFromUserInput(addressLine.text))
     293                }
     294
     295                property url url
     296
     297                onUrlChanged: {
     298                    if (activeFocus)
     299                        return;
     300
     301                    text = url
     302                    cursorPosition = 0
     303                }
     304
     305                onActiveFocusChanged: url = webView.url
    291306            }
    292307        }
     
    306321        onTitleChanged: pageTitleChanged(title)
    307322        onUrlChanged: {
    308             addressLine.text = url
     323            addressLine.url = webView.url
     324
    309325            if (options.printLoadedUrls)
    310                 console.log("Loaded:", webView.url.toString());
    311             forceActiveFocus();
     326                console.log("WebView url changed:", webView.url.toString());
     327        }
     328
     329        onLoadingChanged: {
     330            if (!loading && loadRequest.status == WebView.LoadFailedStatus)
     331                webView.loadHtml("Failed to load " + loadRequest.url, "", loadRequest.url)
    312332        }
    313333
Note: See TracChangeset for help on using the changeset viewer.