Changeset 115191 in webkit


Ignore:
Timestamp:
Apr 25, 2012 6:29:00 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.

A slight change in the activeUrl() implementation is also done,
where we now favour the url of an pending API request, even when
we don't have a mainframe yet.

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
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r115145 r115191  
     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        A slight change in the activeUrl() implementation is also done,
     22        where we now favour the url of an pending API request, even when
     23        we don't have a mainframe yet.
     24
     25        Finally, the location bar in the minibrowser is updated to behave
     26        a bit more like normal browsers in terms of when the url will change
     27        and how active focus is handled.
     28
     29        Reviewed by Simon Hausmann.
     30
     31        * UIProcess/API/qt/qquickwebview.cpp:
     32        (QQuickWebViewPrivate::onComponentComplete):
     33        (QQuickWebView::reload):
     34        (QQuickWebView::url):
     35        (QQuickWebView::setUrl):
     36        (QQuickWebView::loadHtml):
     37        * UIProcess/API/qt/qquickwebview_p.h:
     38        * UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro:
     39        * UIProcess/API/qt/tests/qmltests/WebView.pro:
     40        * UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml:
     41        * UIProcess/API/qt/tests/qmltests/common/link.html: Added.
     42        * UIProcess/API/qt/tests/qmltests/common/redirect.html: Added.
     43        * UIProcess/WebPageProxy.cpp:
     44        (WebKit::WebPageProxy::activeURL):
     45        * UIProcess/qt/QtWebPageLoadClient.cpp:
     46        (QtWebPageLoadClient::QtWebPageLoadClient):
     47        (QtWebPageLoadClient::didStartProvisionalLoadForFrame):
     48        (QtWebPageLoadClient::didReceiveServerRedirectForProvisionalLoadForFrame):
     49        (QtWebPageLoadClient::didCommitLoadForFrame):
     50        (QtWebPageLoadClient::dispatchLoadFailed):
     51        (QtWebPageLoadClient::didFailProvisionalLoadWithErrorForFrame):
     52        (QtWebPageLoadClient::didFailLoadWithErrorForFrame):
     53        * UIProcess/qt/QtWebPageLoadClient.h:
     54        (QtWebPageLoadClient):
     55
    1562012-04-24  Enrica Casucci  <enrica@apple.com>
    257
  • trunk/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp

    r115082 r115191  
    5151#include <JavaScriptCore/InitializeThreading.h>
    5252#include <QDateTime>
     53#include <QtQml/QQmlEngine>
     54#include <QtQuick/QQuickCanvas>
     55#include <WKOpenPanelResultListener.h>
    5356#include <WebCore/IntPoint.h>
    5457#include <WebCore/IntRect.h>
    55 #include <WKOpenPanelResultListener.h>
     58#include <WebCore/KURL.h>
    5659#include <wtf/Assertions.h>
    5760#include <wtf/MainThread.h>
     
    232235void QQuickWebViewPrivate::onComponentComplete()
    233236{
    234     if (m_deferedUrlToLoad.isEmpty())
    235         return;
    236 
    237     q_ptr->setUrl(m_deferedUrlToLoad);
     237    if (m_deferredUrlToLoad.isEmpty())
     238        return;
     239
     240    q_ptr->setUrl(m_deferredUrlToLoad);
     241    m_deferredUrlToLoad.clear();
    238242}
    239243
     
    11981202{
    11991203    Q_D(QQuickWebView);
     1204
     1205    WebFrameProxy* mainFrame = d->webPageProxy->mainFrame();
     1206    if (mainFrame && !mainFrame->unreachableURL().isEmpty() && mainFrame->url() != blankURL()) {
     1207        // We have an unreachable url, but haven't loaded alternative content
     1208        // for it (an error page eg.), so WebCore doesn't know about the unreachable
     1209        // url, and will try to reload the currently committed url instead. We don't
     1210        // want that, so we override the reload here by doing a manual load.
     1211        d->webPageProxy->loadURL(mainFrame->unreachableURL());
     1212        return;
     1213    }
     1214
    12001215    const bool reloadFromOrigin = true;
    12011216    d->webPageProxy->reload(reloadFromOrigin);
     
    12051220{
    12061221    Q_D(const QQuickWebView);
    1207     RefPtr<WebFrameProxy> mainFrame = d->webPageProxy->mainFrame();
    1208     if (!mainFrame)
    1209         return QUrl();
    1210     return QUrl(QString(mainFrame->url()));
     1222
     1223    if (!isComponentComplete())
     1224        return d->m_deferredUrlToLoad;
     1225
     1226    Q_ASSERT(d->m_currentUrl == d->webPageProxy->activeURL());
     1227    return QUrl(d->m_currentUrl);
    12111228}
    12121229
     
    12181235        return;
    12191236
    1220     if (!isComponentComplete()) {
    1221         d->m_deferedUrlToLoad = url;
    1222         return;
     1237    if (!isComponentComplete())
     1238        d->m_deferredUrlToLoad = url;
     1239    else
     1240        d->webPageProxy->loadURL(url.toString());
     1241
     1242    emitUrlChangeIfNeeded();
     1243}
     1244
     1245// Make sure we don't emit urlChanged unless it actually changed
     1246void QQuickWebView::emitUrlChangeIfNeeded()
     1247{
     1248    Q_D(QQuickWebView);
     1249
     1250    WTF::String activeUrl = d->webPageProxy->activeURL();
     1251    if (activeUrl != d->m_currentUrl) {
     1252        d->m_currentUrl = activeUrl;
     1253        emit urlChanged();
    12231254    }
    1224 
    1225     d->webPageProxy->loadURL(url.toString());
    12261255}
    12271256
     
    15321561    document are located relative to \a baseUrl.
    15331562
     1563    If an \a unreachableUrl is passed it is used as the url for the loaded
     1564    content. This is typically used to display error pages for a failed
     1565    load.
     1566
    15341567    \sa load()
    15351568*/
    1536 void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl)
    1537 {
    1538     Q_D(QQuickWebView);
    1539     d->webPageProxy->loadHTMLString(html, baseUrl.toString());
     1569void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl, const QUrl& unreachableUrl)
     1570{
     1571    Q_D(QQuickWebView);
     1572    if (unreachableUrl.isValid())
     1573        d->webPageProxy->loadAlternateHTMLString(html, baseUrl.toString(), unreachableUrl.toString());
     1574    else
     1575        d->webPageProxy->loadHTMLString(html, baseUrl.toString());
    15401576}
    15411577
  • trunk/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h

    r114900 r115191  
    150150
    151151public Q_SLOTS:
    152     void loadHtml(const QString& html, const QUrl& baseUrl = QUrl());
     152    void loadHtml(const QString& html, const QUrl& baseUrl = QUrl(), const QUrl& unreachableUrl = QUrl());
    153153
    154154    void goBack();
     
    203203    WKPageRef pageRef() const;
    204204
     205    void emitUrlChangeIfNeeded();
     206
    205207    Q_PRIVATE_SLOT(d_func(), void _q_suspend());
    206208    Q_PRIVATE_SLOT(d_func(), void _q_resume());
  • trunk/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h

    r115082 r115191  
    195195    bool m_dialogActive;
    196196    QUrl m_iconURL;
    197     QUrl m_deferedUrlToLoad;
     197    QUrl m_deferredUrlToLoad;
     198    WTF::String m_currentUrl;
    198199};
    199200
  • trunk/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp

    r110272 r115191  
    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/DesktopBehavior.pro

    r112195 r115191  
    1616
    1717OTHER_FILES += \
    18     DesktopBehavior/DesktopWebView.qml \
    19     DesktopBehavior/tst_linkHovered.qml \
    20     DesktopBehavior/tst_loadHtml.qml \
    21     DesktopBehavior/tst_messaging.qml \
    22     DesktopBehavior/tst_navigationRequested.qml \
    23     DesktopBehavior/tst_singleFileupload.qml \
    24     DesktopBehavior/tst_multiFileupload.qml
     18    DesktopBehavior/*.qml \
     19    common/*
  • trunk/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro

    r110272 r115191  
    1515
    1616OTHER_FILES += \
    17     WebView/tst_favIconLoad.qml \
    18     WebView/tst_download.qml \
    19     WebView/tst_geopermission.qml \
    20     WebView/tst_itemSelector.qml \
    21     WebView/tst_javaScriptDialogs.qml \
    22     WebView/tst_loadFail.qml \
    23     WebView/tst_loadIgnore.qml \
    24     WebView/tst_loadHtml.qml \
    25     WebView/tst_loadProgress.qml \
    26     WebView/tst_loadProgressSignal.qml \
    27     WebView/tst_preferences.qml \
    28     WebView/tst_properties.qml \
    29     WebView/tst_titleChanged.qml \
    30     WebView/tst_applicationScheme.qml \
    31     WebView/tst_origin.qml
     17    WebView/tst_*.qml \
     18    common/*
  • trunk/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml

    r112376 r115191  
    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/WebPageProxy.cpp

    r114451 r115191  
    658658String WebPageProxy::activeURL() const
    659659{
    660     if (!m_mainFrame)
    661         return String();
    662 
    663660    // If there is a currently pending url, it is the active URL.
    664661    if (!m_pendingAPIRequestURL.isNull())
    665662        return m_pendingAPIRequestURL;
     663
     664    if (!m_mainFrame)
     665        return String();
    666666
    667667    if (!m_mainFrame->unreachableURL().isEmpty())
  • trunk/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp

    r114897 r115191  
    4040    loadClient.clientInfo = this;
    4141    loadClient.didStartProvisionalLoadForFrame = didStartProvisionalLoadForFrame;
     42    loadClient.didReceiveServerRedirectForProvisionalLoadForFrame = didReceiveServerRedirectForProvisionalLoadForFrame;
    4243    loadClient.didFailProvisionalLoadWithErrorForFrame = didFailProvisionalLoadWithErrorForFrame;
    4344    loadClient.didCommitLoadForFrame = didCommitLoadForFrame;
     
    5758{
    5859    QWebLoadRequest loadRequest(url, QQuickWebView::LoadStartedStatus);
     60    m_webView->emitUrlChangeIfNeeded();
    5961    m_webView->d_func()->didChangeLoadingState(&loadRequest);
    6062}
    6163
     64void QtWebPageLoadClient::didReceiveServerRedirectForProvisionalLoadForFrame(const QUrl& url)
     65{
     66    m_webView->emitUrlChangeIfNeeded();
     67}
     68
    6269void QtWebPageLoadClient::didCommitLoadForFrame()
    6370{
    6471    emit m_webView->navigationHistoryChanged();
    65     emit m_webView->urlChanged();
    6672    emit m_webView->titleChanged();
    6773    m_webView->d_func()->loadDidCommit();
     
    7076void QtWebPageLoadClient::didSameDocumentNavigationForFrame()
    7177{
     78    m_webView->emitUrlChangeIfNeeded();
    7279    emit m_webView->navigationHistoryChanged();
    73     emit m_webView->urlChanged();
    7480}
    7581
     
    94100}
    95101
    96 void QtWebPageLoadClient::dispatchLoadFailed(WKErrorRef error)
     102void QtWebPageLoadClient::dispatchLoadFailed(WKFrameRef frame, WKErrorRef error)
    97103{
    98104    int errorCode = WKErrorGetErrorCode(error);
    99105    if (toImpl(error)->platformError().isCancellation() || errorCode == kWKErrorCodeFrameLoadInterruptedByPolicyChange || errorCode == kWKErrorCodePlugInWillHandleLoad) {
     106        // The active url might have changed
     107        m_webView->emitUrlChangeIfNeeded();
     108
    100109        // Make sure that LoadStartedStatus has a counterpart when e.g. requesting a download.
    101110        dispatchLoadSucceeded();
     111
    102112        return;
    103113    }
    104114
    105115    QtWebError qtError(error);
     116
     117    // We set the unreachable url unconditionally so that the current
     118    // active url of the webview when the loadingChanged signal is
     119    // emitted reflects the failed url, not the previously committed
     120    // url. This also ensures that if the user does not do a loadHtml
     121    // with an error page and and unreachable url, as a reponse to the
     122    // failed load, we can still detect the failed url for reloads.
     123    WebFrameProxy* wkframe = toImpl(frame);
     124    wkframe->setUnreachableURL(toImpl(error)->failingURL());
     125    m_webView->emitUrlChangeIfNeeded();
     126
    106127    QWebLoadRequest loadRequest(qtError.url(), QQuickWebView::LoadFailedStatus, qtError.description(), static_cast<QQuickWebView::ErrorDomain>(qtError.type()), qtError.errorCode());
    107128    emit m_webView->loadingChanged(&loadRequest);
     
    130151}
    131152
     153void QtWebPageLoadClient::didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
     154{
     155    if (!WKFrameIsMainFrame(frame))
     156        return;
     157    WebFrameProxy* wkframe = toImpl(frame);
     158    QString urlStr(wkframe->provisionalURL());
     159    QUrl qUrl = urlStr;
     160    toQtWebPageLoadClient(clientInfo)->didReceiveServerRedirectForProvisionalLoadForFrame(qUrl);
     161}
     162
    132163void QtWebPageLoadClient::didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef frame, WKErrorRef error, WKTypeRef, const void* clientInfo)
    133164{
    134165    if (!WKFrameIsMainFrame(frame))
    135166        return;
    136     toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(error);
     167
     168    toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(frame, error);
    137169}
    138170
     
    155187    if (!WKFrameIsMainFrame(frame))
    156188        return;
    157     toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(error);
     189    toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(frame, error);
    158190}
    159191
  • trunk/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h

    r114897 r115191  
    4141private:
    4242    void didStartProvisionalLoadForFrame(const QUrl&);
     43    void didReceiveServerRedirectForProvisionalLoadForFrame(const QUrl&);
    4344    void didCommitLoadForFrame();
    4445    void didSameDocumentNavigationForFrame();
     
    4849
    4950    void dispatchLoadSucceeded();
    50     void dispatchLoadFailed(WKErrorRef);
     51    void dispatchLoadFailed(WKFrameRef, WKErrorRef);
    5152    void setLoadProgress(int);
    5253
    5354    // WKPageLoadClient callbacks.
    5455    static void didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
     56    static void didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
    5557    static void didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef, WKErrorRef, WKTypeRef userData, const void* clientInfo);
    5658    static void didCommitLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
  • trunk/Tools/ChangeLog

    r115184 r115191  
     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-04-25  Philippe Normand  <pnormand@igalia.com>
    216
  • trunk/Tools/MiniBrowser/qt/qml/BrowserWindow.qml

    r113172 r115191  
    4242    function load(address) {
    4343        webView.url = address
     44        webView.forceActiveFocus()
    4445    }
    4546
    4647    function reload() {
    4748        webView.reload()
     49        webView.forceActiveFocus()
    4850    }
    4951
     
    252254                }
    253255                radius: 3
    254                 width: parent.width / 100 * webView.loadProgress
     256                width: parent.width / 100 * Math.max(5, webView.loadProgress)
    255257                color: "blue"
    256258                opacity: 0.3
    257                 visible: webView.loadProgress != 100
     259                visible: webView.loading
    258260            }
    259261            Image {
     
    272274                clip: true
    273275                selectByMouse: true
     276                horizontalAlignment: TextInput.AlignLeft
    274277                font {
    275278                    pointSize: 11
     
    284287
    285288                Keys.onReturnPressed:{
    286                     console.log("going to: ", addressLine.text)
    287                     webView.url = utils.urlFromUserInput(addressLine.text)
    288                 }
     289                    console.log("Navigating to: ", addressLine.text)
     290                    load(utils.urlFromUserInput(addressLine.text))
     291                }
     292
     293                property url url
     294
     295                onUrlChanged: {
     296                    if (activeFocus)
     297                        return;
     298
     299                    text = url
     300                    cursorPosition = 0
     301                }
     302
     303                onActiveFocusChanged: url = webView.url
    289304            }
    290305        }
     
    302317        onTitleChanged: pageTitleChanged(title)
    303318        onUrlChanged: {
    304             addressLine.text = url
     319            addressLine.url = webView.url
     320
    305321            if (options.printLoadedUrls)
    306                 console.log("Loaded:", webView.url.toString());
    307             forceActiveFocus();
     322                console.log("WebView url changed:", webView.url.toString());
     323        }
     324
     325        onLoadingChanged: {
     326            if (!loading && loadRequest.status == WebView.LoadFailedStatus)
     327                webView.loadHtml("Failed to load " + loadRequest.url, "", loadRequest.url)
    308328        }
    309329
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp

    r108106 r115191  
    139139    WKPageLoadURL(webView.page(), url.get());
    140140
     141    WKRetainPtr<WKURLRef> activeUrl = adoptWK(WKPageCopyActiveURL(webView.page()));
     142    ASSERT_NOT_NULL(activeUrl.get());
     143    EXPECT_TRUE(WKURLIsEqual(activeUrl.get(), url.get()));
     144
    141145    Util::run(&test1Done);
    142146}
Note: See TracChangeset for help on using the changeset viewer.