summaryrefslogtreecommitdiff
path: root/src/ui/documentwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r--src/ui/documentwidget.c119
1 files changed, 108 insertions, 11 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 2a3a2509..9fdadc4c 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -38,6 +38,7 @@ struct Impl_DocumentWidget {
38 iClick click; 38 iClick click;
39 iScrollWidget *scroll; 39 iScrollWidget *scroll;
40 iWidget *menu; 40 iWidget *menu;
41// iWidget *userInput;
41}; 42};
42 43
43iDefineObjectConstruction(DocumentWidget) 44iDefineObjectConstruction(DocumentWidget)
@@ -64,6 +65,7 @@ void init_DocumentWidget(iDocumentWidget *d) {
64 { "---", 0, 0, NULL }, 65 { "---", 0, 0, NULL },
65 { "Reload", 'r', KMOD_PRIMARY, "navigate.reload" } }, 66 { "Reload", 'r', KMOD_PRIMARY, "navigate.reload" } },
66 4); 67 4);
68// setFlags_Widget(d->userInput, hidden_WidgetFlag | disabled_WidgetFlag, iTrue);
67} 69}
68 70
69void deinit_DocumentWidget(iDocumentWidget *d) { 71void deinit_DocumentWidget(iDocumentWidget *d) {
@@ -139,20 +141,27 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) {
139 render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d); 141 render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d);
140} 142}
141 143
142static void updateSource_DocumentWidget_(iDocumentWidget *d) { 144static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) {
143 /* TODO: Do this in the background. However, that requires a text metrics calculator
144 that does not try to cache the glyph bitmaps. */
145 iString str;
146 initBlock_String(&str, body_GmRequest(d->request));
147 setSource_GmDocument(d->doc, &str, documentWidth_DocumentWidget_(d));
148 deinit_String(&str);
149 updateVisible_DocumentWidget_(d);
150 refresh_Widget(as_Widget(d));
151 setTitle_Window(get_Window(), 145 setTitle_Window(get_Window(),
152 !isEmpty_String(title_GmDocument(d->doc)) ? title_GmDocument(d->doc) 146 !isEmpty_String(title_GmDocument(d->doc)) ? title_GmDocument(d->doc)
153 : collectNewCStr_String("Lagrange")); 147 : collectNewCStr_String("Lagrange"));
154} 148}
155 149
150static void updateSource_DocumentWidget_(iDocumentWidget *d) {
151 /* TODO: Do this in the background. However, that requires a text metrics calculator
152 that does not try to cache the glyph bitmaps. */
153 if (status_GmRequest(d->request) != input_GmStatusCode &&
154 status_GmRequest(d->request) != sensitiveInput_GmStatusCode) {
155 iString str;
156 initBlock_String(&str, body_GmRequest(d->request));
157 setSource_GmDocument(d->doc, &str, documentWidth_DocumentWidget_(d));
158 updateWindowTitle_DocumentWidget_(d);
159 updateVisible_DocumentWidget_(d);
160 refresh_Widget(as_Widget(d));
161 deinit_String(&str);
162 }
163}
164
156static void fetch_DocumentWidget_(iDocumentWidget *d) { 165static void fetch_DocumentWidget_(iDocumentWidget *d) {
157 /* Forget the previous request. */ 166 /* Forget the previous request. */
158 if (d->request) { 167 if (d->request) {
@@ -256,22 +265,80 @@ static const iString *absoluteUrl_DocumentWidget_(const iDocumentWidget *d, cons
256 return collect_String(absolute); 265 return collect_String(absolute);
257} 266}
258 267
268static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode code) {
269 iWidget *w = as_Widget(d);
270 iString *src = collectNew_String();
271 const iGmError *msg = get_GmError(code);
272 format_String(src,
273 "# %lc %s\n%s",
274 msg->icon ? msg->icon : 0x2327, /* X in a box */
275 msg->title,
276 msg->info);
277 switch (code) {
278 case failedToOpenFile_GmStatusCode:
279 case certificateNotValid_GmStatusCode:
280 appendFormat_String(src, "\n\n%s", cstr_String(meta_GmRequest(d->request)));
281 break;
282 case slowDown_GmStatusCode:
283 appendFormat_String(src, "\n\nWait %s seconds before your next request.",
284 cstr_String(meta_GmRequest(d->request)));
285 break;
286 default:
287 break;
288 }
289 setSource_GmDocument(d->doc, src, documentWidth_DocumentWidget_(d));
290 updateWindowTitle_DocumentWidget_(d);
291 updateVisible_DocumentWidget_(d);
292 refresh_Widget(w);
293}
294
259static void checkResponseCode_DocumentWidget_(iDocumentWidget *d) { 295static void checkResponseCode_DocumentWidget_(iDocumentWidget *d) {
260 if (d->state == fetching_DocumentState) { 296 if (d->state == fetching_DocumentState) {
261 d->state = receivedPartialResponse_DocumentState; 297 d->state = receivedPartialResponse_DocumentState;
262 d->scrollY = 0; 298 d->scrollY = 0;
263 switch (status_GmRequest(d->request)) { 299 switch (status_GmRequest(d->request)) {
300 case none_GmStatusCode:
301 case success_GmStatusCode:
302 break;
303 case input_GmStatusCode:
304 case sensitiveInput_GmStatusCode: {
305 iUrl parts;
306 init_Url(&parts, d->url);
307 makeValueInput_Widget(
308 as_Widget(d),
309 NULL,
310 cstrFormat_String(cyan_ColorEscape "%s",
311 cstr_String(collect_String(newRange_String(parts.host)))),
312 isEmpty_String(meta_GmRequest(d->request))
313 ? cstrFormat_String(
314 "Please enter input for %s:",
315 cstr_String(collect_String(newRange_String(parts.path))))
316 : cstr_String(meta_GmRequest(d->request)),
317 orange_ColorEscape "Send \u21d2",
318 "document.input.submit");
319 break;
320 }
264 case redirectTemporary_GmStatusCode: 321 case redirectTemporary_GmStatusCode:
265 case redirectPermanent_GmStatusCode: 322 case redirectPermanent_GmStatusCode:
266 postCommandf_App("open redirect:1 url:%s", cstr_String(meta_GmRequest(d->request))); 323 if (isEmpty_String(meta_GmRequest(d->request))) {
267 iReleasePtr(&d->request); 324 showErrorPage_DocumentWidget_(d, invalidRedirect_GmStatusCode);
325 }
326 else {
327 postCommandf_App("open redirect:1 url:%s", cstr_String(meta_GmRequest(d->request)));
328 iReleasePtr(&d->request);
329 }
268 break; 330 break;
269 default: 331 default:
332 showErrorPage_DocumentWidget_(d, status_GmRequest(d->request));
270 break; 333 break;
271 } 334 }
272 } 335 }
273} 336}
274 337
338const iString *valueString_Command(const char *cmd, const char *label) {
339 return collect_String(newCStr_String(suffixPtr_Command(cmd, label)));
340}
341
275static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *ev) { 342static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *ev) {
276 iWidget *w = as_Widget(d); 343 iWidget *w = as_Widget(d);
277 if (isResize_UserEvent(ev)) { 344 if (isResize_UserEvent(ev)) {
@@ -279,6 +346,25 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
279 updateVisible_DocumentWidget_(d); 346 updateVisible_DocumentWidget_(d);
280 refresh_Widget(w); 347 refresh_Widget(w);
281 } 348 }
349 else if (isCommand_UserEvent(ev, "document.input.submit")) {
350 iString *value = collect_String(suffix_Command(command_UserEvent(ev), "value"));
351 urlEncode_String(value);
352 iString *url = collect_String(copy_String(d->url));
353 const size_t qPos = indexOfCStr_String(url, "?");
354 if (qPos != iInvalidPos) {
355 remove_Block(&url->chars, qPos, iInvalidSize);
356 }
357 appendCStr_String(url, "?");
358 append_String(url, value);
359 postCommandf_App("open url:%s", cstr_String(url));
360 return iTrue;
361 }
362 else if (isCommand_UserEvent(ev, "valueinput.cancelled") &&
363 cmp_String(string_Command(command_UserEvent(ev), "id"), "document.input.submit") ==
364 0) {
365 postCommand_App("navigate.back");
366 return iTrue;
367 }
282 else if (isCommand_Widget(w, ev, "document.request.updated") && 368 else if (isCommand_Widget(w, ev, "document.request.updated") &&
283 pointerLabel_Command(command_UserEvent(ev), "request") == d->request) { 369 pointerLabel_Command(command_UserEvent(ev), "request") == d->request) {
284 updateSource_DocumentWidget_(d); 370 updateSource_DocumentWidget_(d);
@@ -325,6 +411,17 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
325 updateVisible_DocumentWidget_(d); 411 updateVisible_DocumentWidget_(d);
326 refresh_Widget(w); 412 refresh_Widget(w);
327 return iTrue; 413 return iTrue;
414#if 0
415 case 't':
416 if (mods == KMOD_PRIMARY) {
417 makeValueInput_Widget(get_Window()->root,
418 NULL,
419 cyan_ColorEscape "Input Needed",
420 "Give it!",
421 "document.input.submit");
422 }
423 return iTrue;
424#endif
328 case SDLK_END: 425 case SDLK_END:
329 d->scrollY = scrollMax_DocumentWidget_(d); 426 d->scrollY = scrollMax_DocumentWidget_(d);
330 updateVisible_DocumentWidget_(d); 427 updateVisible_DocumentWidget_(d);