Merge lp:~rpadovani/oxide/http-status-code into lp:~oxide-developers/oxide/oxide.trunk

Proposed by Riccardo Padovani
Status: Merged
Merged at revision: 1078
Proposed branch: lp:~rpadovani/oxide/http-status-code
Merge into: lp:~oxide-developers/oxide/oxide.trunk
Diff against target: 1034 lines (+612/-65)
10 files modified
qt/core/api/oxideqloadevent.cc (+17/-3)
qt/core/api/oxideqloadevent.h (+16/-3)
qt/core/browser/oxide_qt_web_view.cc (+17/-9)
qt/core/browser/oxide_qt_web_view.h (+8/-4)
qt/qmlplugin/oxide_qml_plugin.cc (+2/-0)
qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.py (+21/-0)
qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml (+462/-0)
qt/tests/qmltests/api/tst_WebView_loading.qml (+33/-27)
shared/browser/oxide_web_view.cc (+25/-13)
shared/browser/oxide_web_view.h (+11/-6)
To merge this branch: bzr merge lp:~rpadovani/oxide/http-status-code
Reviewer Review Type Date Requested Status
Olivier Tilloy (community) Approve
Chris Coulson Approve
Review via email: mp+256606@code.launchpad.net

Commit message

Implement HttpStatusCode in OxideQLoadEvent

Description of the change

My first patch for Oxide :-)

So, atm it doesn't work (and test fails) because it returns always Code 200. I submitted the code just to have some feedbacks.

I inserted in the Enum HttpStatusCode all codes listed here: https://tools.ietf.org/html/rfc2616#section-6.1.1

To post a comment you must log in.
Revision history for this message
Olivier Tilloy (osomon) wrote :

You’re setting the HTTP status code on load events emitted from a LoadCommitted event. That’s not enough, the HTTP status code is also relevant for load events emitted from LoadRedirected, LoadFailed and LoadSucceeded events.

Also, I’m not sure it’s super useful to define an enum for the codes. I’m thinking an int property would be enough. But if we go for an enum, you might be able to get rid of HttpStatusCodeFromInt by doing a static cast from the int value to the enum.

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

> You’re setting the HTTP status code on load events emitted from a
> LoadCommitted event. That’s not enough, the HTTP status code is also relevant
> for load events emitted from LoadRedirected, LoadFailed and LoadSucceeded
> events.
>
> Also, I’m not sure it’s super useful to define an enum for the codes. I’m
> thinking an int property would be enough. But if we go for an enum, you might
> be able to get rid of HttpStatusCodeFromInt by doing a static cast from the
> int value to the enum.

Yeah, I'd be tempted to just use an int for this too (and setting it to -1 for events which don't have a status code). Other API's seem to just use an int (eg, https://developer.gnome.org/libsoup/stable/SoupMessage.html#SoupMessage--status-code, although they use an unsigned int here).

Note that LoadFailed can be generated before a commit - this means the connection failed for the main resource and there will be no valid status code. (If it's generated after a commit, then it means that the main resource loaded but a subresource failed. In this case, the status code will be the one for the successful main resource load).

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

To expose the status code for load succeeded events, you can use the same mechanism as used for committed events (NavigationEntry::GetHttpStatusCode). For redirect events, it's slightly different as the status code on NavigationEntry is only set when a load commits - in this case, you can use content::ResourceRedirectDetails::http_response_code (see |details| in WebView::DidGetRedirectForResourceRequest).

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Ok, I've added a few minor comments inline as well.

In addition to additional tests with a few different response codes, it would be worthwhile adding this property to the tests in tst_WebView_loading.qml where we test the sequence of LoadEvents (I guess it should always be "200" in these tests for events where the status code is valid).

And thanks for working on this :)

review: Needs Fixing
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Thanks for your feedbacks :-)

So, I dropped Enum and I implemented http_status_code also for Redirect and Success.

The code should be ok, but I didn't understand what I should add to oxide_qml_plugin.cc. I read the documentation, but I don't understand how qmlRegisterUncreatableType uri works, sorry.

I'm also a bit confused by tests: I thougth (let me know if I'm wrong) to write a test for every 'collection' of status code (2xx, 3xx, 4xx, 5xx) instead a test for each status code, so they verify also if on an url change the code status is updated.

But this approach has something wrong, because every LoadEvent.TypeSucceeded returns -1, and it's not a code fail, because I updated also tst_WebView_loading.qml and there LoadEvent.TypeSucceeded returns the right status code.

In exports.onBeforeSendHeaders = function(event){} (file qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.js) I wasn't able to use functions to manipulate strings, like substring, because they stop execution of the function. There is a way to don't have all these if, but simply extract the argument and pass it to the python script?

Or maybe there is a better way at all to create these tests?

Last thing: when the page returns 407 http_status_code becomes 406.
This maybe due the response, because 407 should also indicates the proxy that the requestor should use, so since the python script doesn't indicate anything, it fails on 406?

Thanks for your time!

Revision history for this message
Olivier Tilloy (osomon) wrote :

You will need to add the following line at the end of OxideQmlPlugin::registerTypes(…):

    qmlRegisterUncreatableType<OxideQLoadEvent, 2>(uri, 1, 8, "LoadEvent",
        "LoadEvent is delivered by WebView.loadEvent");

This means that revision 2 of OxideQLoadEvent is registered under oxide 1.8, and as a consequence the new property won’t be accessible when importing previous versions.
As a consequence you will need to update tst_LoadEvent_httpStatusCode.qml and tst_WebView_loading.qml to import oxide 1.8.

Revision history for this message
Olivier Tilloy (osomon) wrote :

As for the unit tests, no need for a javascript file that inserts a custom header for the server to parse. In the python handler function, request.path contains e.g. "/tst_LoadEvent_httpStatusCode.py?404", so you can just parse this to get the expected status code.

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Hi Olivier,
thanks for your feedback.

Sorry for the delay, it has been a busy week!

I followed your suggestions, so I think now it's ok, but it still has problems with test, because every LoadEvent.TypeSucceeded returns -1 in tst_LoadEvent_httpStatusCode.qml, and it's not a code fail, because I updated also tst_WebView_loading.qml and there LoadEvent.TypeSucceeded returns the right status code.

Revision history for this message
Olivier Tilloy (osomon) wrote :

Try the following patch, this should fix the issue you’re seeing with httpStatusCode not properly set:

=== modified file 'qt/core/browser/oxide_qt_web_view.cc'
--- qt/core/browser/oxide_qt_web_view.cc 2015-04-30 21:25:36 +0000
+++ qt/core/browser/oxide_qt_web_view.cc 2015-04-30 21:56:58 +0000
@@ -621,6 +621,7 @@
   OxideQLoadEvent event(
       QUrl(QString::fromStdString(validated_url.spec())),
       OxideQLoadEvent::TypeSucceeded,
+ false,
       http_status_code);
   client_->LoadEvent(&event);
 }

review: Needs Fixing
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

You rock, thanks :-)

Could you please help me understandig what was wrong?

So, as far as I can say, I called the wrong constructor - instead of

OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
                                 Type type,
                                 bool is_error,
                                 int http_status_code)

I called

OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
                                 const QUrl& original_url,
                                 int http_status_code)

so, why the compiler didn't warning me about the conversion from Type type to const QUrl& original_url?

Revision history for this message
Olivier Tilloy (osomon) wrote :

In fact the right constructor was being called, but the status code was being converted to a boolean (is_error), and http_status_code was initialized with its default value, -1.

Revision history for this message
Olivier Tilloy (osomon) wrote :

There is now a minor conflict in qt/qmlplugin/oxide_qml_plugin.cc when merging this branch into trunk, would you mind addressing it? Both conflicting lines need to stay.

lp:~rpadovani/oxide/http-status-code updated
1040. By Riccardo Padovani

Merge from trunk and resolve conflict

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Fixed

Revision history for this message
Olivier Tilloy (osomon) wrote :

Thanks Riccardo for working on this! The logic looks good and seems to work well. I have a few comments, mostly on the unit tests:

 - In tst_LoadEvent_httpStatusCode.py, the body of the response (html) should be written regardless of the status code (it’s currently written only if http_status_code < 400. Actually, reading the spec more closely, for status codes 204 and 304 there musn’t be a message body, so those need to be special-cased. All others should be fine with a body.

 - In shared/browser/oxide_web_view.cc, the new line after OnLoadRedirected( needs to be indented by 4 whitespaces, for consistency with the rest of the codebase.

 - It should be possible to rewrite the tests in tst_LoadEvent_httpStatusCode.qml to be data-driven (see http://doc.qt.io/qt-5/qml-qttest-testcase.html#data-driven-tests): each row of data would contain a status code, together with a list of expected load events and their respective status codes.

 - Would it be possible to add tests for 3xx and 5xx status codes?

 - What exactly are the issues with the tests for status codes 205 and 407?

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Thanks for working on this - I've added one comment inline.

Also, I don't really understand the difference between -1 and 0. There is a comment saying that -1 is unknown, and that 0 is a list of cases where the status code isn't available - but aren't these just the same?

lp:~rpadovani/oxide/http-status-code updated
1041. By Riccardo Padovani

Improve tests for http status code

- Always write body of the response in tst_LoadEvent_httpStatusCode.py
- Tests now are data-driven
- Add tests for 3xx and 5xx status code

1042. By Riccardo Padovani

Add is_provisional_load to DispatchLoadFailed to be sure we have an http status code

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

I think I addressed all your comments.

@Chris: it returns -1 as default - comment was wrong, now it's only the default value. At first implementation I added Enum for status codes, so when a status code wasn't in the enum it used -1.

I think it's importat the difference between 0 and -1: 0 is returned by Chromium for cases listed in the comment, -1 is returned by Oxide. If you don't want this difference, I change -1 with 0 as default.

@Olivier, now fails only test for 407.
This is the output:

1: 127.0.0.1 - - [15/May/2015 12:30:32] code 407, message Proxy Authentication Required
1: 127.0.0.1 - - [15/May/2015 12:30:32] "GET /tst_LoadEvent_httpStatusCode.py?407 HTTP/1.1" 407 -
1: FAIL! : qml-api-test::LoadEvent_httpStatusCode::test_HttpStatusCode4xx(407) Unexpected value of httpStatusCode
1: Actual (): 406
1: Expected (): 407
1: Loc: [/home/rpadovani/Ubuntu/touch/oxide/branches/firstTime/qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml(22)]

Maybe is because 407 is Proxy Authentication Required and for specs:
   The proxy MUST
   return a Proxy-Authenticate header field (section 14.33) containing a
   challenge applicable to the proxy for the requested resource.

but our http server doesn't return anything?

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

> I think I addressed all your comments.
>
> @Chris: it returns -1 as default - comment was wrong, now it's only the
> default value. At first implementation I added Enum for status codes, so when
> a status code wasn't in the enum it used -1.
>
> I think it's importat the difference between 0 and -1: 0 is returned by
> Chromium for cases listed in the comment, -1 is returned by Oxide. If you
> don't want this difference, I change -1 with 0 as default.
>

I'm not convinced it's important to convey this distinction in the API - either there's a valid status code with this event, or there isn't. I think I'd prefer just sticking with -1 or 0 (I don't mind which).

> @Olivier, now fails only test for 407.
> This is the output:
>
> 1: 127.0.0.1 - - [15/May/2015 12:30:32] code 407, message Proxy Authentication
> Required
> 1: 127.0.0.1 - - [15/May/2015 12:30:32] "GET
> /tst_LoadEvent_httpStatusCode.py?407 HTTP/1.1" 407 -
> 1: FAIL! : qml-api-
> test::LoadEvent_httpStatusCode::test_HttpStatusCode4xx(407) Unexpected value
> of httpStatusCode
> 1: Actual (): 406
> 1: Expected (): 407
> 1: Loc: [/home/rpadovani/Ubuntu/touch/oxide/branches/firstTime/qt/tests/qml
> tests/api/tst_LoadEvent_httpStatusCode.qml(22)]
>
> Maybe is because 407 is Proxy Authentication Required and for specs:
> The proxy MUST
> return a Proxy-Authenticate header field (section 14.33) containing a
> challenge applicable to the proxy for the requested resource.
>
> but our http server doesn't return anything?

You can modify tst_LoadEvent_httpStatusCode.py to return whatever headers you like, but in this case, I don't think this would fix the test (it's missing some other bits in Oxide, notably bug 1422339 I believe). I'd just remove the test for this status code for now.

lp:~rpadovani/oxide/http-status-code updated
1043. By Riccardo Padovani

Return 0 as default for http status code

1044. By Riccardo Padovani

Remove test for http status code 407

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

I removed test 407 and set 0 as default http status code, thanks for your feedback :-)

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Thanks! I think this is good to merge (although I'll wait to see if Olivier has any other comments)

review: Approve
Revision history for this message
Olivier Tilloy (osomon) wrote :

That looks good to me too. I think all the test_HttpStatusCode*xx functions could be factored out into only one test function (and the special-casing on whether to test for load committed, succeeded or stopped should be part of the data driving the test), but at this stage that’s just picking nits (and we can still refactor that later on).

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qt/core/api/oxideqloadevent.cc'
2--- qt/core/api/oxideqloadevent.cc 2014-12-08 14:09:25 +0000
3+++ qt/core/api/oxideqloadevent.cc 2015-05-15 12:21:58 +0000
4@@ -26,6 +26,7 @@
5 : type(OxideQLoadEvent::TypeStarted),
6 error_domain(OxideQLoadEvent::ErrorDomainNone),
7 error_code(0),
8+ http_status_code(0),
9 is_error(false) {}
10
11 QUrl url;
12@@ -33,13 +34,15 @@
13 OxideQLoadEvent::ErrorDomain error_domain;
14 QString error_string;
15 int error_code;
16+ int http_status_code;
17 QUrl original_url;
18 bool is_error;
19 };
20
21 OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
22 Type type,
23- bool is_error)
24+ bool is_error,
25+ int http_status_code)
26 : d_ptr(new OxideQLoadEventPrivate()) {
27 Q_D(OxideQLoadEvent);
28
29@@ -50,12 +53,14 @@
30 d->url = url;
31 d->type = type;
32 d->is_error = is_error;
33+ d->http_status_code = http_status_code;
34 }
35
36 OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
37 ErrorDomain error_domain,
38 const QString& error_string,
39- int error_code)
40+ int error_code,
41+ int http_status_code)
42 : d_ptr(new OxideQLoadEventPrivate()) {
43 Q_D(OxideQLoadEvent);
44
45@@ -64,16 +69,19 @@
46 d->error_domain = error_domain;
47 d->error_string = error_string;
48 d->error_code = error_code;
49+ d->http_status_code = http_status_code;
50 }
51
52 OxideQLoadEvent::OxideQLoadEvent(const QUrl& url,
53- const QUrl& original_url)
54+ const QUrl& original_url,
55+ int http_status_code)
56 : d_ptr(new OxideQLoadEventPrivate()) {
57 Q_D(OxideQLoadEvent);
58
59 d->url = url;
60 d->type = OxideQLoadEvent::TypeRedirected;
61 d->original_url = original_url;
62+ d->http_status_code = http_status_code;
63 }
64
65 OxideQLoadEvent::~OxideQLoadEvent() {}
66@@ -108,6 +116,12 @@
67 return d->error_code;
68 }
69
70+int OxideQLoadEvent::httpStatusCode() const {
71+ Q_D(const OxideQLoadEvent);
72+
73+ return d->http_status_code;
74+}
75+
76 QUrl OxideQLoadEvent::originalUrl() const {
77 Q_D(const OxideQLoadEvent);
78
79
80=== modified file 'qt/core/api/oxideqloadevent.h'
81--- qt/core/api/oxideqloadevent.h 2014-12-09 17:18:01 +0000
82+++ qt/core/api/oxideqloadevent.h 2015-05-15 12:21:58 +0000
83@@ -34,6 +34,15 @@
84 Q_PROPERTY(ErrorDomain errorDomain READ errorDomain CONSTANT)
85 Q_PROPERTY(QString errorString READ errorString CONSTANT)
86 Q_PROPERTY(int errorCode READ errorCode CONSTANT)
87+ // The status code of the last known successful navigation. If
88+ // returns 0 that means that either:
89+ //
90+ // - this navigation hasn't completed yet;
91+ // - a response wasn't received;
92+ // - or this navigation was restored and for some reason the
93+ // status code wasn't available.
94+ //
95+ Q_PROPERTY(int httpStatusCode READ httpStatusCode CONSTANT REVISION 2)
96
97 Q_PROPERTY(QUrl originalUrl READ originalUrl CONSTANT)
98
99@@ -69,13 +78,16 @@
100
101 Q_DECL_HIDDEN OxideQLoadEvent(const QUrl& url,
102 Type type,
103- bool is_error = false);
104+ bool is_error = false,
105+ int http_status_code = -1);
106 Q_DECL_HIDDEN OxideQLoadEvent(const QUrl& url,
107 ErrorDomain error_domain,
108 const QString& error_string,
109- int error_code);
110+ int error_code,
111+ int http_status_code);
112 Q_DECL_HIDDEN OxideQLoadEvent(const QUrl& url,
113- const QUrl& original_url);
114+ const QUrl& original_url,
115+ int http_status_code);
116 virtual ~OxideQLoadEvent();
117
118 QUrl url() const;
119@@ -83,6 +95,7 @@
120 ErrorDomain errorDomain() const;
121 QString errorString() const;
122 int errorCode() const;
123+ int httpStatusCode() const;
124 QUrl originalUrl() const;
125 bool isError() const;
126
127
128=== modified file 'qt/core/browser/oxide_qt_web_view.cc'
129--- qt/core/browser/oxide_qt_web_view.cc 2015-05-11 15:32:11 +0000
130+++ qt/core/browser/oxide_qt_web_view.cc 2015-05-15 12:21:58 +0000
131@@ -581,19 +581,23 @@
132 }
133
134 void WebView::OnLoadRedirected(const GURL& url,
135- const GURL& original_url) {
136+ const GURL& original_url,
137+ int http_status_code) {
138 OxideQLoadEvent event(
139 QUrl(QString::fromStdString(url.spec())),
140- QUrl(QString::fromStdString(original_url.spec())));
141+ QUrl(QString::fromStdString(original_url.spec())),
142+ http_status_code);
143 client_->LoadEvent(&event);
144 }
145
146 void WebView::OnLoadCommitted(const GURL& url,
147- bool is_error_page) {
148+ bool is_error_page,
149+ int http_status_code) {
150 OxideQLoadEvent event(
151 QUrl(QString::fromStdString(url.spec())),
152 OxideQLoadEvent::TypeCommitted,
153- is_error_page);
154+ is_error_page,
155+ http_status_code);
156 client_->LoadEvent(&event);
157 }
158
159@@ -606,19 +610,23 @@
160
161 void WebView::OnLoadFailed(const GURL& validated_url,
162 int error_code,
163- const std::string& error_description) {
164+ const std::string& error_description,
165+ int http_status_code) {
166 OxideQLoadEvent event(
167 QUrl(QString::fromStdString(validated_url.spec())),
168 ErrorDomainFromErrorCode(error_code),
169 QString::fromStdString(error_description),
170- error_code);
171+ error_code,
172+ http_status_code);
173 client_->LoadEvent(&event);
174 }
175
176-void WebView::OnLoadSucceeded(const GURL& validated_url) {
177+void WebView::OnLoadSucceeded(const GURL& validated_url, int http_status_code) {
178 OxideQLoadEvent event(
179 QUrl(QString::fromStdString(validated_url.spec())),
180- OxideQLoadEvent::TypeSucceeded);
181+ OxideQLoadEvent::TypeSucceeded,
182+ false,
183+ http_status_code);
184 client_->LoadEvent(&event);
185 }
186
187@@ -1061,7 +1069,7 @@
188 }
189
190 bool WebView::incognito() const {
191- return IsIncognito();
192+ return IsIncognito();
193 }
194
195 bool WebView::loading() const {
196
197=== modified file 'qt/core/browser/oxide_qt_web_view.h'
198--- qt/core/browser/oxide_qt_web_view.h 2015-05-11 15:32:11 +0000
199+++ qt/core/browser/oxide_qt_web_view.h 2015-05-15 12:21:58 +0000
200@@ -113,14 +113,18 @@
201
202 void OnLoadStarted(const GURL& validated_url) override;
203 void OnLoadRedirected(const GURL& url,
204- const GURL& original_url) override;
205+ const GURL& original_url,
206+ int http_status_code) override;
207 void OnLoadCommitted(const GURL& url,
208- bool is_error_page) override;
209+ bool is_error_page,
210+ int http_status_code) override;
211 void OnLoadStopped(const GURL& validated_url) override;
212 void OnLoadFailed(const GURL& validated_url,
213 int error_code,
214- const std::string& error_description) override;
215- void OnLoadSucceeded(const GURL& validated_url) override;
216+ const std::string& error_description,
217+ int http_status_code) override;
218+ void OnLoadSucceeded(const GURL& validated_url,
219+ int http_status_code) override;
220
221 void OnNavigationEntryCommitted() override;
222 void OnNavigationListPruned(bool from_front, int count) override;
223
224=== modified file 'qt/qmlplugin/oxide_qml_plugin.cc'
225--- qt/qmlplugin/oxide_qml_plugin.cc 2015-05-11 15:32:11 +0000
226+++ qt/qmlplugin/oxide_qml_plugin.cc 2015-05-15 12:21:58 +0000
227@@ -128,6 +128,8 @@
228 qmlRegisterUncreatableType<OxideQQuickLocationBarController, 1>(uri, 1, 7, "LocationBarController",
229 "LocationBarController is accessed via WebView.locationBarController");
230
231+ qmlRegisterUncreatableType<OxideQLoadEvent, 2>(uri, 1, 8, "LoadEvent",
232+ "LoadEvent is delivered by WebView.loadEvent");
233 qmlRegisterType<OxideQQuickWebView, 4>(uri, 1, 8, "WebView");
234 }
235 };
236
237=== added file 'qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.py'
238--- qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.py 1970-01-01 00:00:00 +0000
239+++ qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.py 2015-05-15 12:21:58 +0000
240@@ -0,0 +1,21 @@
241+from cStringIO import StringIO
242+
243+def handler(request):
244+ html = StringIO()
245+
246+ http_status_code = int(request.path[-3:])
247+
248+ html.write("Request for http status code: " + str(http_status_code))
249+
250+ if http_status_code >= 400:
251+ request.send_error(http_status_code)
252+ else:
253+ request.send_response(http_status_code)
254+
255+ if http_status_code != 204 and http_status_code != 304:
256+ request.send_header("Content-type", "application/json")
257+ request.send_header("Content-Length", html.tell())
258+ request.send_header("Cache-Control", "no-cache")
259+ request.end_headers()
260+
261+ request.wfile.write(html.getvalue())
262
263=== added file 'qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml'
264--- qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml 1970-01-01 00:00:00 +0000
265+++ qt/tests/qmltests/api/tst_LoadEvent_httpStatusCode.qml 2015-05-15 12:21:58 +0000
266@@ -0,0 +1,462 @@
267+import QtQuick 2.0
268+import QtTest 1.0
269+import com.canonical.Oxide 1.8
270+import com.canonical.Oxide.Testing 1.0
271+
272+TestWebView {
273+ id: webView
274+ width: 200
275+ height: 200
276+
277+ property var expectedLoadEvents: []
278+ property int expectedHttpStatusCode
279+
280+ onLoadEvent: {
281+ test.verify(expectedLoadEvents.length > 0);
282+ var expected = expectedLoadEvents[0];
283+ expectedLoadEvents.shift();
284+
285+ test.compare(event.type, expected, "Unexpected type")
286+
287+ test.compare(event.httpStatusCode,
288+ event.type != LoadEvent.TypeStarted && event.type != LoadEvent.TypeStopped ? expectedHttpStatusCode : -1,
289+ "Unexpected value of httpStatusCode");
290+ }
291+
292+ TestCase {
293+ id: test
294+ name: "LoadEvent_httpStatusCode"
295+ when: windowShown
296+
297+ function init() {
298+ webView.clearLoadEventCounters();
299+ expectedLoadEvents = [];
300+ }
301+
302+ function test_HttpStatusCode2xx_data() {
303+ return [
304+ {
305+ tag: "200",
306+ httpStatusCode: 200,
307+ events: [
308+ LoadEvent.TypeStarted,
309+ LoadEvent.TypeCommitted,
310+ LoadEvent.TypeSucceeded
311+ ]
312+ },
313+ {
314+ tag: "201",
315+ httpStatusCode: 201,
316+ events: [
317+ LoadEvent.TypeStarted,
318+ LoadEvent.TypeCommitted,
319+ LoadEvent.TypeSucceeded
320+ ]
321+ },
322+ {
323+ tag: "202",
324+ httpStatusCode: 202,
325+ events: [
326+ LoadEvent.TypeStarted,
327+ LoadEvent.TypeCommitted,
328+ LoadEvent.TypeSucceeded
329+ ]
330+ },
331+ {
332+ tag: "203",
333+ httpStatusCode: 203,
334+ events: [
335+ LoadEvent.TypeStarted,
336+ LoadEvent.TypeCommitted,
337+ LoadEvent.TypeSucceeded
338+ ]
339+ },
340+ {
341+ tag: "204",
342+ httpStatusCode: 204,
343+ events: [
344+ LoadEvent.TypeStarted,
345+ LoadEvent.TypeStopped
346+ ]
347+ },
348+ {
349+ tag: "205",
350+ httpStatusCode: 205,
351+ events: [
352+ LoadEvent.TypeStarted,
353+ LoadEvent.TypeStopped
354+ ]
355+ },
356+ {
357+ tag: "206",
358+ httpStatusCode: 206,
359+ events: [
360+ LoadEvent.TypeStarted,
361+ LoadEvent.TypeCommitted,
362+ LoadEvent.TypeSucceeded
363+ ]
364+ },
365+ ]
366+ }
367+
368+ function test_HttpStatusCode2xx(data) {
369+ expectedHttpStatusCode = data.httpStatusCode;
370+ expectedLoadEvents = data.events;
371+
372+ webView.url = "http://testsuite/tst_LoadEvent_httpStatusCode.py?" +
373+ data.httpStatusCode;
374+
375+ if (data.httpStatusCode === 204 || data.httpStatusCode === 205) {
376+ verify(webView.waitForLoadStopped());
377+ } else {
378+ verify(webView.waitForLoadSucceeded());
379+ }
380+ }
381+
382+ function test_HttpStatusCode3xx_data() {
383+ return [
384+ {
385+ tag: "300",
386+ httpStatusCode: 300,
387+ events: [
388+ LoadEvent.TypeStarted,
389+ LoadEvent.TypeCommitted,
390+ LoadEvent.TypeSucceeded
391+ ]
392+ },
393+ {
394+ tag: "301",
395+ httpStatusCode: 301,
396+ events: [
397+ LoadEvent.TypeStarted,
398+ LoadEvent.TypeCommitted,
399+ LoadEvent.TypeSucceeded
400+ ]
401+ },
402+ {
403+ tag: "302",
404+ httpStatusCode: 302,
405+ events: [
406+ LoadEvent.TypeStarted,
407+ LoadEvent.TypeCommitted,
408+ LoadEvent.TypeSucceeded
409+ ]
410+ },
411+ {
412+ tag: "303",
413+ httpStatusCode: 303,
414+ events: [
415+ LoadEvent.TypeStarted,
416+ LoadEvent.TypeCommitted,
417+ LoadEvent.TypeSucceeded
418+ ]
419+ },
420+ {
421+ tag: "304",
422+ httpStatusCode: 304,
423+ events: [
424+ LoadEvent.TypeStarted,
425+ LoadEvent.TypeStopped
426+ ]
427+ },
428+ {
429+ tag: "305",
430+ httpStatusCode: 305,
431+ events: [
432+ LoadEvent.TypeStarted,
433+ LoadEvent.TypeCommitted,
434+ LoadEvent.TypeSucceeded
435+ ]
436+ },
437+ {
438+ tag: "306",
439+ httpStatusCode: 306,
440+ events: [
441+ LoadEvent.TypeStarted,
442+ LoadEvent.TypeCommitted,
443+ LoadEvent.TypeSucceeded
444+ ]
445+ },
446+ {
447+ tag: "307",
448+ httpStatusCode: 307,
449+ events: [
450+ LoadEvent.TypeStarted,
451+ LoadEvent.TypeCommitted,
452+ LoadEvent.TypeSucceeded
453+ ]
454+ },
455+ {
456+ tag: "308",
457+ httpStatusCode: 308,
458+ events: [
459+ LoadEvent.TypeStarted,
460+ LoadEvent.TypeCommitted,
461+ LoadEvent.TypeSucceeded
462+ ]
463+ }
464+ ]
465+ }
466+
467+ function test_HttpStatusCode3xx(data) {
468+ expectedHttpStatusCode = data.httpStatusCode;
469+ expectedLoadEvents = data.events;
470+
471+ webView.url = "http://testsuite/tst_LoadEvent_httpStatusCode.py?" +
472+ data.httpStatusCode;
473+
474+ if (data.httpStatusCode === 304) {
475+ verify(webView.waitForLoadStopped());
476+ } else {
477+ verify(webView.waitForLoadSucceeded());
478+ }
479+ }
480+
481+ function test_HttpStatusCode4xx_data() {
482+ return [
483+ {
484+ tag: "400",
485+ httpStatusCode: 400,
486+ events: [
487+ LoadEvent.TypeStarted,
488+ LoadEvent.TypeCommitted,
489+ LoadEvent.TypeSucceeded
490+ ]
491+ },
492+ {
493+ tag: "401",
494+ httpStatusCode: 401,
495+ events: [
496+ LoadEvent.TypeStarted,
497+ LoadEvent.TypeCommitted,
498+ LoadEvent.TypeSucceeded
499+ ]
500+ },
501+ {
502+ tag: "403",
503+ httpStatusCode: 403,
504+ events: [
505+ LoadEvent.TypeStarted,
506+ LoadEvent.TypeCommitted,
507+ LoadEvent.TypeSucceeded
508+ ]
509+ },
510+ {
511+ tag: "404",
512+ httpStatusCode: 404,
513+ events: [
514+ LoadEvent.TypeStarted,
515+ LoadEvent.TypeCommitted,
516+ LoadEvent.TypeSucceeded
517+ ]
518+ },
519+ {
520+ tag: "405",
521+ httpStatusCode: 405,
522+ events: [
523+ LoadEvent.TypeStarted,
524+ LoadEvent.TypeCommitted,
525+ LoadEvent.TypeSucceeded
526+ ]
527+ },
528+ {
529+ tag: "406",
530+ httpStatusCode: 406,
531+ events: [
532+ LoadEvent.TypeStarted,
533+ LoadEvent.TypeCommitted,
534+ LoadEvent.TypeSucceeded
535+ ]
536+ },
537+ // XXX: investigate on failure of this test.
538+ // See https://code.launchpad.net/~rpadovani/oxide/http-status-code/+merge/256606/comments/647631
539+ // {
540+ // tag: "407",
541+ // httpStatusCode: 407,
542+ // events: [
543+ // LoadEvent.TypeStarted,
544+ // LoadEvent.TypeFailed,
545+ // LoadEvent.TypeCommitted
546+ // ]
547+ // },
548+ {
549+ tag: "408",
550+ httpStatusCode: 408,
551+ events: [
552+ LoadEvent.TypeStarted,
553+ LoadEvent.TypeCommitted,
554+ LoadEvent.TypeSucceeded
555+ ]
556+ },
557+ {
558+ tag: "409",
559+ httpStatusCode: 409,
560+ events: [
561+ LoadEvent.TypeStarted,
562+ LoadEvent.TypeCommitted,
563+ LoadEvent.TypeSucceeded
564+ ]
565+ },
566+ {
567+ tag: "410",
568+ httpStatusCode: 410,
569+ events: [
570+ LoadEvent.TypeStarted,
571+ LoadEvent.TypeCommitted,
572+ LoadEvent.TypeSucceeded
573+ ]
574+ },
575+ {
576+ tag: "411",
577+ httpStatusCode: 411,
578+ events: [
579+ LoadEvent.TypeStarted,
580+ LoadEvent.TypeCommitted,
581+ LoadEvent.TypeSucceeded
582+ ]
583+ },
584+ {
585+ tag: "412",
586+ httpStatusCode: 412,
587+ events: [
588+ LoadEvent.TypeStarted,
589+ LoadEvent.TypeCommitted,
590+ LoadEvent.TypeSucceeded
591+ ]
592+ },
593+ {
594+ tag: "413",
595+ httpStatusCode: 413,
596+ events: [
597+ LoadEvent.TypeStarted,
598+ LoadEvent.TypeCommitted,
599+ LoadEvent.TypeSucceeded
600+ ]
601+ },
602+ {
603+ tag: "414",
604+ httpStatusCode: 414,
605+ events: [
606+ LoadEvent.TypeStarted,
607+ LoadEvent.TypeCommitted,
608+ LoadEvent.TypeSucceeded
609+ ]
610+ },
611+ {
612+ tag: "415",
613+ httpStatusCode: 415,
614+ events: [
615+ LoadEvent.TypeStarted,
616+ LoadEvent.TypeCommitted,
617+ LoadEvent.TypeSucceeded
618+ ]
619+ },
620+ {
621+ tag: "416",
622+ httpStatusCode: 416,
623+ events: [
624+ LoadEvent.TypeStarted,
625+ LoadEvent.TypeCommitted,
626+ LoadEvent.TypeSucceeded
627+ ]
628+ },
629+ {
630+ tag: "417",
631+ httpStatusCode: 417,
632+ events: [
633+ LoadEvent.TypeStarted,
634+ LoadEvent.TypeCommitted,
635+ LoadEvent.TypeSucceeded
636+ ]
637+ }
638+ ]
639+ }
640+
641+ function test_HttpStatusCode4xx(data) {
642+ expectedHttpStatusCode = data.httpStatusCode;
643+ expectedLoadEvents = data.events;
644+
645+ webView.url = "http://testsuite/tst_LoadEvent_httpStatusCode.py?" +
646+ data.httpStatusCode;
647+
648+ if (data.httpStatusCode === 407) {
649+ verify(webView.waitForLoadCommitted());
650+ } else {
651+ verify(webView.waitForLoadSucceeded());
652+ }
653+ }
654+
655+ function test_HttpStatusCode5xx_data() {
656+ return [
657+ {
658+ tag: "500",
659+ httpStatusCode: 500,
660+ events: [
661+ LoadEvent.TypeStarted,
662+ LoadEvent.TypeCommitted,
663+ LoadEvent.TypeSucceeded
664+ ]
665+ },
666+ {
667+ tag: "501",
668+ httpStatusCode: 501,
669+ events: [
670+ LoadEvent.TypeStarted,
671+ LoadEvent.TypeCommitted,
672+ LoadEvent.TypeSucceeded
673+ ]
674+ },
675+ {
676+ tag: "502",
677+ httpStatusCode: 502,
678+ events: [
679+ LoadEvent.TypeStarted,
680+ LoadEvent.TypeCommitted,
681+ LoadEvent.TypeSucceeded
682+ ]
683+ },
684+ {
685+ tag: "503",
686+ httpStatusCode: 503,
687+ events: [
688+ LoadEvent.TypeStarted,
689+ LoadEvent.TypeCommitted,
690+ LoadEvent.TypeSucceeded
691+ ]
692+ },
693+ {
694+ tag: "504",
695+ httpStatusCode: 504,
696+ events: [
697+ LoadEvent.TypeStarted,
698+ LoadEvent.TypeCommitted,
699+ LoadEvent.TypeSucceeded
700+ ]
701+ },
702+ {
703+ tag: "505",
704+ httpStatusCode: 505,
705+ events: [
706+ LoadEvent.TypeStarted,
707+ LoadEvent.TypeCommitted,
708+ LoadEvent.TypeSucceeded
709+ ]
710+ }
711+ ]
712+ }
713+
714+ function test_HttpStatusCode5xx(data) {
715+ expectedHttpStatusCode = data.httpStatusCode;
716+ expectedLoadEvents = data.events;
717+
718+ webView.url = "http://testsuite/tst_LoadEvent_httpStatusCode.py?" +
719+ data.httpStatusCode;
720+
721+ // if (data.httpStatusCode === 304) {
722+ // verify(webView.waitForLoadStopped());
723+ // } else {
724+ verify(webView.waitForLoadSucceeded());
725+ //}
726+ }
727+ }
728+}
729
730=== modified file 'qt/tests/qmltests/api/tst_WebView_loading.qml'
731--- qt/tests/qmltests/api/tst_WebView_loading.qml 2015-04-15 14:49:03 +0000
732+++ qt/tests/qmltests/api/tst_WebView_loading.qml 2015-05-15 12:21:58 +0000
733@@ -1,6 +1,6 @@
734 import QtQuick 2.0
735 import QtTest 1.0
736-import com.canonical.Oxide 1.0
737+import com.canonical.Oxide 1.8
738 import com.canonical.Oxide.Testing 1.0
739
740 TestWebView {
741@@ -35,6 +35,10 @@
742 test.compare(event.originalUrl,
743 event.type == LoadEvent.TypeRedirected ? expected.originalUrl : "",
744 "Unexpected originalUrl");
745+ test.compare(event.httpStatusCode,
746+ event.type != LoadEvent.TypeStarted && event.type != LoadEvent.TypeStopped ?
747+ expected.httpStatusCode : -1,
748+ "Unexpected value of httpStatusCode");
749 test.compare(loading, expected.loading,
750 "Unexpected state of WebView.loading");
751 }
752@@ -63,8 +67,8 @@
753 var url = "http://testsuite/empty.html";
754 expectedLoadEvents = [
755 { type: LoadEvent.TypeStarted, url: url, loading: true },
756- { type: LoadEvent.TypeCommitted, url: url, error: false, loading: true },
757- { type: LoadEvent.TypeSucceeded, url: url, loading: false }
758+ { type: LoadEvent.TypeCommitted, url: url, error: false, httpStatusCode: 200, loading: true },
759+ { type: LoadEvent.TypeSucceeded, url: url, httpStatusCode: 200, loading: false }
760 ];
761
762 webView.url = url;
763@@ -88,11 +92,11 @@
764 var new_url = "http://foo.testsuite/empty.html";
765 expectedLoadEvents = [
766 { type: LoadEvent.TypeStarted, url: initial_url, loading: true },
767- { type: LoadEvent.TypeCommitted, url: initial_url, error: false, loading: true },
768- { type: LoadEvent.TypeSucceeded, url: initial_url, loading: false },
769- { type: LoadEvent.TypeStarted, url: new_url, loading: true },
770- { type: LoadEvent.TypeCommitted, url: new_url, error: false, loading: true },
771- { type: LoadEvent.TypeSucceeded, url: new_url, loading: false }
772+ { type: LoadEvent.TypeCommitted, url: initial_url, httpStatusCode: 200, error: false, loading: true },
773+ { type: LoadEvent.TypeSucceeded, url: initial_url, httpStatusCode: 200, loading: false },
774+ { type: LoadEvent.TypeStarted, url: new_url, loading: true },
775+ { type: LoadEvent.TypeCommitted, url: new_url, error: false, httpStatusCode: 200, loading: true },
776+ { type: LoadEvent.TypeSucceeded, url: new_url, httpStatusCode: 200, loading: false }
777 ];
778
779 webView.url = initial_url;
780@@ -100,7 +104,7 @@
781
782 verify(!webView.loading);
783 spy.clear();
784-
785+
786 webView.getTestApi().evaluateCode("window.location = \"" + new_url + "\";", false);
787 webView.waitFor(function() { return spy.count == 2; });
788
789@@ -146,8 +150,8 @@
790 var url = "http://invalid/";
791 expectedLoadEvents = [
792 { type: LoadEvent.TypeStarted, url: url, loading: true },
793- { type: LoadEvent.TypeFailed, url: url, loading: true },
794- { type: LoadEvent.TypeCommitted, url: url, error: true, loading: true }
795+ { type: LoadEvent.TypeFailed, url: url, httpStatusCode: 0, loading: true },
796+ { type: LoadEvent.TypeCommitted, url: url, error: true, httpStatusCode: 0, loading: true }
797 ];
798
799 webView.url = url;
800@@ -168,8 +172,8 @@
801 spy.clear();
802 expectedLoadEvents = [
803 { type: LoadEvent.TypeStarted, url: url, loading: true },
804- { type: LoadEvent.TypeFailed, url: url, loading: true },
805- { type: LoadEvent.TypeCommitted, url: url, error: true, loading: true }
806+ { type: LoadEvent.TypeFailed, url: url, httpStatusCode: 0, loading: true },
807+ { type: LoadEvent.TypeCommitted, url: url, error: true, httpStatusCode: 0, loading: true }
808 ];
809 webView.reload();
810
811@@ -191,9 +195,11 @@
812 var url = "http://testsuite/tst_WebView_loading_redirect.py";
813 expectedLoadEvents = [
814 { type: LoadEvent.TypeStarted, url: url, loading: true },
815- { type: LoadEvent.TypeRedirected, url: "http://testsuite/empty.html", originalUrl: url, loading: true },
816- { type: LoadEvent.TypeCommitted, url: "http://testsuite/empty.html", error: false, loading: true },
817- { type: LoadEvent.TypeSucceeded, url: "http://testsuite/empty.html", loading: false }
818+ { type: LoadEvent.TypeRedirected, url: "http://testsuite/empty.html",
819+ originalUrl: url, httpStatusCode: 302, loading: true },
820+ { type: LoadEvent.TypeCommitted, url: "http://testsuite/empty.html",
821+ error: false, httpStatusCode: 200, loading: true },
822+ { type: LoadEvent.TypeSucceeded, url: "http://testsuite/empty.html", httpStatusCode: 200, loading: false }
823 ];
824
825 webView.url = url;
826@@ -216,10 +222,10 @@
827 var initial_url = "http://testsuite/empty.html";
828 var new_url = "http://testsuite/empty.html#foo";
829 expectedLoadEvents = [
830- { type: LoadEvent.TypeStarted, url: initial_url, loading: true },
831- { type: LoadEvent.TypeCommitted, url: initial_url, error: false, loading: true },
832- { type: LoadEvent.TypeSucceeded, url: initial_url, loading: false },
833- { type: LoadEvent.TypeCommitted, url: new_url, error: false, loading: true }
834+ { type: LoadEvent.TypeStarted, url: initial_url, httpStatusCode: 200, loading: true },
835+ { type: LoadEvent.TypeCommitted, url: initial_url, error: false, httpStatusCode: 200, loading: true },
836+ { type: LoadEvent.TypeSucceeded, url: initial_url, httpStatusCode: 200, loading: false },
837+ { type: LoadEvent.TypeCommitted, url: new_url, error: false, httpStatusCode: 200, loading: true }
838 ];
839
840 webView.url = initial_url;
841@@ -227,7 +233,7 @@
842
843 verify(!webView.loading);
844 spy.clear();
845-
846+
847 webView.getTestApi().evaluateCode("window.location = \"" + new_url + "\";", false);
848 webView.waitFor(function() { return spy.count == 2; });
849
850@@ -241,10 +247,10 @@
851 var initial_url = "http://testsuite/empty.html";
852 var new_url = "http://testsuite/empty.html#foo";
853 expectedLoadEvents = [
854- { type: LoadEvent.TypeStarted, url: initial_url, loading: true },
855- { type: LoadEvent.TypeCommitted, url: initial_url, error: false, loading: true },
856- { type: LoadEvent.TypeSucceeded, url: initial_url, loading: false },
857- { type: LoadEvent.TypeCommitted, url: new_url, error: false, loading: true }
858+ { type: LoadEvent.TypeStarted, url: initial_url, httpStatusCode: 200, loading: true },
859+ { type: LoadEvent.TypeCommitted, url: initial_url, error: false, httpStatusCode: 200, loading: true },
860+ { type: LoadEvent.TypeSucceeded, url: initial_url, httpStatusCode: 200, loading: false },
861+ { type: LoadEvent.TypeCommitted, url: new_url, error: false, httpStatusCode: 200, loading: true }
862 ];
863
864 webView.url = initial_url;
865@@ -288,8 +294,8 @@
866 var url = "http://testsuite/tst_WebView_loading_subframe.html";
867 expectedLoadEvents = [
868 { type: LoadEvent.TypeStarted, url: url, loading: true },
869- { type: LoadEvent.TypeCommitted, url: url, error: false, loading: true },
870- { type: LoadEvent.TypeSucceeded, url: url, loading: false }
871+ { type: LoadEvent.TypeCommitted, url: url, error: false, httpStatusCode: 200, loading: true },
872+ { type: LoadEvent.TypeSucceeded, url: url, httpStatusCode: 200, loading: false }
873 ];
874
875 webView.url = url;
876
877=== modified file 'shared/browser/oxide_web_view.cc'
878--- shared/browser/oxide_web_view.cc 2015-05-14 15:37:57 +0000
879+++ shared/browser/oxide_web_view.cc 2015-05-15 12:21:58 +0000
880@@ -253,12 +253,16 @@
881
882 void WebView::DispatchLoadFailed(const GURL& validated_url,
883 int error_code,
884- const base::string16& error_description) {
885+ const base::string16& error_description,
886+ bool is_provisional_load) {
887 if (error_code == net::ERR_ABORTED) {
888 OnLoadStopped(validated_url);
889 } else {
890+ content::NavigationEntry* entry =
891+ web_contents_->GetController().GetLastCommittedEntry();
892 OnLoadFailed(validated_url, error_code,
893- base::UTF16ToUTF8(error_description));
894+ base::UTF16ToUTF8(error_description),
895+ is_provisional_load ? 0 : entry->GetHttpStatusCode());
896 }
897 }
898
899@@ -943,7 +947,8 @@
900
901 content::NavigationEntry* entry =
902 web_contents_->GetController().GetLastCommittedEntry();
903- OnLoadCommitted(url, entry->GetPageType() == content::PAGE_TYPE_ERROR);
904+ OnLoadCommitted(url, entry->GetPageType() == content::PAGE_TYPE_ERROR,
905+ entry->GetHttpStatusCode());
906 }
907
908 void WebView::DidFailProvisionalLoad(
909@@ -958,7 +963,7 @@
910
911 if (!frame->parent() &&
912 validated_url.spec() != content::kUnreachableWebDataURL) {
913- DispatchLoadFailed(validated_url, error_code, error_description);
914+ DispatchLoadFailed(validated_url, error_code, error_description, true);
915 }
916
917 if (error_code != net::ERR_ABORTED) {
918@@ -1011,7 +1016,9 @@
919 return;
920 }
921
922- OnLoadSucceeded(validated_url);
923+ content::NavigationEntry* entry =
924+ web_contents_->GetController().GetLastCommittedEntry();
925+ OnLoadSucceeded(validated_url, entry->GetHttpStatusCode());
926 }
927
928 void WebView::DidFailLoad(content::RenderFrameHost* render_frame_host,
929@@ -1032,7 +1039,8 @@
930 return;
931 }
932
933- OnLoadRedirected(details.new_url, details.original_url);
934+ OnLoadRedirected(details.new_url, details.original_url,
935+ details.http_response_code);
936 }
937
938 void WebView::NavigationEntryCommitted(
939@@ -1126,14 +1134,18 @@
940
941 void WebView::OnLoadStarted(const GURL& validated_url) {}
942 void WebView::OnLoadRedirected(const GURL& url,
943- const GURL& original_url) {}
944+ const GURL& original_url,
945+ int http_status_code) {}
946 void WebView::OnLoadCommitted(const GURL& url,
947- bool is_error_page) {}
948+ bool is_error_page,
949+ int http_status_code) {}
950 void WebView::OnLoadStopped(const GURL& validated_url) {}
951 void WebView::OnLoadFailed(const GURL& validated_url,
952 int error_code,
953- const std::string& error_description) {}
954-void WebView::OnLoadSucceeded(const GURL& validated_url) {}
955+ const std::string& error_description,
956+ int http_status_code) {}
957+void WebView::OnLoadSucceeded(const GURL& validated_url,
958+ int http_status_code) {}
959
960 void WebView::OnNavigationEntryCommitted() {}
961 void WebView::OnNavigationListPruned(bool from_front, int count) {}
962@@ -1470,7 +1482,7 @@
963 params.base_url_for_data_url = baseUrl;
964 params.virtual_url_for_data_url = baseUrl.is_empty() ? GURL(url::kAboutBlankURL) : baseUrl;
965 params.can_load_local_resources = true;
966-
967+
968 if (web_contents_) {
969 web_contents_->GetController().LoadURLWithParams(params);
970 } else {
971@@ -2082,7 +2094,7 @@
972 return;
973 }
974
975- SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown);
976+ SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown);
977 host->ImeConfirmComposition(text, replacement_range, false);
978 SendFakeCompositionKeyEvent(host, blink::WebInputEvent::KeyUp);
979 }
980@@ -2096,7 +2108,7 @@
981 return;
982 }
983
984- SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown);
985+ SendFakeCompositionKeyEvent(host, blink::WebInputEvent::RawKeyDown);
986 host->ImeSetComposition(text, underlines,
987 selection_range.start(),
988 selection_range.end());
989
990=== modified file 'shared/browser/oxide_web_view.h'
991--- shared/browser/oxide_web_view.h 2015-05-14 15:37:57 +0000
992+++ shared/browser/oxide_web_view.h 2015-05-15 12:21:58 +0000
993@@ -282,7 +282,7 @@
994 bool strict_enforcement,
995 const base::Callback<void(bool)>& callback,
996 content::CertificateRequestResultType* result);
997-
998+
999 void HandleKeyEvent(const content::NativeWebKeyboardEvent& event);
1000 void HandleMouseEvent(const blink::WebMouseEvent& event);
1001 void HandleTouchEvent(const ui::TouchEvent& event);
1002@@ -341,7 +341,8 @@
1003
1004 void DispatchLoadFailed(const GURL& validated_url,
1005 int error_code,
1006- const base::string16& error_description);
1007+ const base::string16& error_description,
1008+ bool is_provisional_load = false);
1009
1010 void OnDidBlockDisplayingInsecureContent();
1011 void OnDidBlockRunningInsecureContent();
1012@@ -501,14 +502,18 @@
1013
1014 virtual void OnLoadStarted(const GURL& validated_url);
1015 virtual void OnLoadRedirected(const GURL& url,
1016- const GURL& original_url);
1017+ const GURL& original_url,
1018+ int http_status_code);
1019 virtual void OnLoadCommitted(const GURL& url,
1020- bool is_error_page);
1021+ bool is_error_page,
1022+ int http_status_code);
1023 virtual void OnLoadStopped(const GURL& validated_url);
1024 virtual void OnLoadFailed(const GURL& validated_url,
1025 int error_code,
1026- const std::string& error_description);
1027- virtual void OnLoadSucceeded(const GURL& validated_url);
1028+ const std::string& error_description,
1029+ int http_status_code);
1030+ virtual void OnLoadSucceeded(const GURL& validated_url,
1031+ int http_status_code);
1032
1033 virtual void OnNavigationEntryCommitted();
1034 virtual void OnNavigationListPruned(bool from_front, int count);

Subscribers

People subscribed via source and target branches