mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
HTTP Server: Support popups [#264]
This commit is contained in:
@@ -91,7 +91,7 @@ public class Http_server_mgr implements Gfo_invk {
|
||||
String cmd = url_converter.Decode_str(url_encoded_str);
|
||||
app.Gfs_mgr().Run_str(cmd);
|
||||
}
|
||||
public String Parse_page_to_html(Http_data__client data__client, byte[] wiki_domain, byte[] ttl_bry, byte mode) {
|
||||
public String Parse_page_to_html(Http_data__client data__client, byte[] wiki_domain, byte[] ttl_bry, byte mode, boolean popup_enabled, String popup_mode, String popup_id) {
|
||||
synchronized (thread_lock) {
|
||||
// create a shim gui to automatically handle default XOWA gui JS calls
|
||||
if (init_gui_needed) {
|
||||
@@ -102,7 +102,7 @@ public class Http_server_mgr implements Gfo_invk {
|
||||
// get the wiki
|
||||
Xowe_wiki wiki = (Xowe_wiki)app.Wiki_mgr().Get_by_or_make_init_y(wiki_domain); // assert init for Main_Page; EX:click zh.w on wiki sidebar; DATE:2015-07-19
|
||||
if (Runtime_.Memory_total() > Io_mgr.Len_gb) Xowe_wiki_.Rls_mem(wiki, true); // release memory at 1 GB; DATE:2015-09-11
|
||||
|
||||
|
||||
// get the url / ttl
|
||||
if (Bry_.Len_eq_0(ttl_bry)) ttl_bry = wiki.Props().Main_page();
|
||||
Xoa_url url = wiki.Utl__url_parser().Parse(ttl_bry);
|
||||
@@ -119,22 +119,31 @@ public class Http_server_mgr implements Gfo_invk {
|
||||
page.Html_data().Head_mgr().Itm__server().Init_by_http(data__client).Enabled_y_();
|
||||
|
||||
// generate html
|
||||
String rv = String_.new_u8(wiki.Html_mgr().Page_wtr_mgr().Gen(page, mode)); // NOTE: must generate HTML now in order for "wait" and "async_server" to work with text_dbs; DATE:2016-07-10
|
||||
boolean rebuild_html = false;
|
||||
switch (retrieve_mode) {
|
||||
case File_retrieve_mode.Mode_skip: // noop
|
||||
break;
|
||||
case File_retrieve_mode.Mode_async_server:
|
||||
rebuild_html = true;
|
||||
app.Gui_mgr().Browser_win().Page__async__bgn(tab);
|
||||
break;
|
||||
case File_retrieve_mode.Mode_wait:
|
||||
rebuild_html = true;
|
||||
gplx.xowa.guis.views.Xog_async_wkr.Async(page, tab.Html_itm());
|
||||
page = wiki.Page_mgr().Load_page(url, ttl, tab); // HACK: fetch page again so that HTML will now include img data
|
||||
break;
|
||||
String rv = null;
|
||||
if (popup_enabled) {
|
||||
if (String_.Eq(popup_mode, "more"))
|
||||
rv = wiki.Html_mgr().Head_mgr().Popup_mgr().Show_more(popup_id);
|
||||
else
|
||||
rv = wiki.Html_mgr().Head_mgr().Popup_mgr().Show_init(popup_id, ttl_bry, ttl_bry);
|
||||
}
|
||||
else {
|
||||
rv = String_.new_u8(wiki.Html_mgr().Page_wtr_mgr().Gen(page, mode)); // NOTE: must generate HTML now in order for "wait" and "async_server" to work with text_dbs; DATE:2016-07-10
|
||||
boolean rebuild_html = false;
|
||||
switch (retrieve_mode) {
|
||||
case File_retrieve_mode.Mode_skip: // noop
|
||||
break;
|
||||
case File_retrieve_mode.Mode_async_server:
|
||||
rebuild_html = true;
|
||||
app.Gui_mgr().Browser_win().Page__async__bgn(tab);
|
||||
break;
|
||||
case File_retrieve_mode.Mode_wait:
|
||||
rebuild_html = true;
|
||||
gplx.xowa.guis.views.Xog_async_wkr.Async(page, tab.Html_itm());
|
||||
page = wiki.Page_mgr().Load_page(url, ttl, tab); // HACK: fetch page again so that HTML will now include img data
|
||||
break;
|
||||
}
|
||||
if (rebuild_html) rv = String_.new_u8(wiki.Html_mgr().Page_wtr_mgr().Gen(page, mode));
|
||||
}
|
||||
if (rebuild_html) rv = String_.new_u8(wiki.Html_mgr().Page_wtr_mgr().Gen(page, mode));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ class Http_server_wkr implements Gfo_invk {
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr_.New_w_size(64);
|
||||
private Socket_adp socket;
|
||||
private Http_data__client data__client;
|
||||
private final Gfo_url_parser url_parser = new Gfo_url_parser();
|
||||
public Http_server_wkr(Http_server_mgr server_mgr, int uid){
|
||||
this.server_mgr = server_mgr; this.uid = uid;
|
||||
this.app = server_mgr.App(); this.server_wtr = server_mgr.Server_wtr(); this.url_encoder = server_mgr.Encoder();
|
||||
@@ -105,7 +106,7 @@ class Http_server_wkr implements Gfo_invk {
|
||||
page_html = url_parser.Err_msg();
|
||||
}
|
||||
else {
|
||||
page_html = app.Http_server().Parse_page_to_html(data__client, url_parser.Wiki(), url_parser.Page(), url_parser.Action());
|
||||
page_html = app.Http_server().Parse_page_to_html(data__client, url_parser.Wiki(), url_parser.Page(), url_parser.Action(), url_parser.Popup(), url_parser.Popup_mode(), url_parser.Popup_id());
|
||||
page_html = Convert_page(page_html, root_dir_http, String_.new_u8(url_parser.Wiki()));
|
||||
}
|
||||
Xosrv_http_wkr_.Write_response_as_html(client_wtr, Bool_.N, page_html);
|
||||
|
||||
@@ -14,6 +14,7 @@ GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
|
||||
import gplx.core.net.*; import gplx.core.net.qargs.*;
|
||||
import gplx.langs.htmls.encoders.*;
|
||||
import gplx.xowa.htmls.hrefs.*;
|
||||
import gplx.xowa.wikis.pages.*;
|
||||
@@ -25,13 +26,17 @@ class Http_url_parser {
|
||||
public byte[] Wiki() {return wiki;} public Http_url_parser Wiki_(String v) {this.wiki = Bry_.new_u8(v); return this;} private byte[] wiki;
|
||||
public byte[] Page() {return page;} public Http_url_parser Page_(String v) {this.page = Bry_.new_u8(v); return this;} private byte[] page;
|
||||
public byte Action() {return action;} public Http_url_parser Action_(byte v) {this.action = v; return this;} private byte action;
|
||||
public String Popup_mode() {return popup_mode;} public Http_url_parser Popup_mode_(String v) {this.popup_mode = v; return this;} private String popup_mode;
|
||||
public boolean Popup() {return popup;} public Http_url_parser Popup_(boolean v) {this.popup = v; return this;} private boolean popup;
|
||||
public String Popup_id() {return popup_id;} public Http_url_parser Popup_id_(String v) {this.popup_id = v; return this;} private String popup_id;
|
||||
public String Err_msg() {return err_msg;} public Http_url_parser Err_msg_(String v) {this.err_msg = v; return this;} private String err_msg;
|
||||
|
||||
public String To_str() {
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
bfr.Add_str_a7("wiki=").Add_safe(wiki).Add_byte_nl();
|
||||
bfr.Add_str_a7("page=").Add_safe(page).Add_byte_nl();
|
||||
bfr.Add_str_a7("action=").Add_byte(action).Add_byte_nl();
|
||||
bfr.Add_str_a7("action=").Add_byte_variable(action).Add_byte_nl();
|
||||
bfr.Add_str_a7("popup=").Add_yn(popup).Add_byte_nl();
|
||||
bfr.Add_str_a7("err_msg=").Add_str_u8_null(err_msg).Add_byte_nl();
|
||||
return bfr.To_str_and_clear();
|
||||
}
|
||||
@@ -40,11 +45,45 @@ class Http_url_parser {
|
||||
public boolean Parse(byte[] url) {
|
||||
try {
|
||||
// initial validations
|
||||
if (url == null) return Fail(url, "invalid url; url is null");
|
||||
if (url == null) return Fail(null, "invalid url; url is null");
|
||||
int url_len = url.length;
|
||||
if (url_len == 0) return Fail(url, "invalid url; url is empty");
|
||||
if (url_len == 0) return Fail(null, "invalid url; url is empty");
|
||||
if (url[0] != Byte_ascii.Slash) return Fail(url, "invalid url; must start with '/'");
|
||||
|
||||
Gfo_url_parser url_parser = new Gfo_url_parser();
|
||||
Gfo_url url_obj = url_parser.Parse(url);
|
||||
this.wiki = url_obj.Segs()[0];
|
||||
|
||||
int segs_len = url_obj.Segs().length;
|
||||
if (segs_len > 1) {
|
||||
byte[] x = url_obj.Segs()[2];
|
||||
if (segs_len > 2) {
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
for (int i = 2; i < segs_len; i++) {
|
||||
if (i != 2) bfr.Add_byte_slash();
|
||||
bfr.Add(url_obj.Segs()[i]);
|
||||
}
|
||||
x = bfr.To_bry_and_clear();
|
||||
}
|
||||
this.page = x;
|
||||
}
|
||||
|
||||
Gfo_qarg_mgr qarg_mgr = new Gfo_qarg_mgr().Init(url_obj.Qargs());
|
||||
byte[] action_val = qarg_mgr.Read_bry_or("action", Bry_.Empty);
|
||||
if (Bry_.Eq(action_val, Xoa_url_.Qarg__action__read))
|
||||
this.action = Xopg_page_.Tid_read;
|
||||
else if (Bry_.Eq(action_val, Xoa_url_.Qarg__action__edit))
|
||||
this.action = Xopg_page_.Tid_edit;
|
||||
else if (Bry_.Eq(action_val, Xoa_url_.Qarg__action__html))
|
||||
this.action = Xopg_page_.Tid_html;
|
||||
else if (Bry_.Eq(action_val, Qarg__action__popup)) {
|
||||
this.popup = true;
|
||||
this.popup_id = qarg_mgr.Read_str_or_null(Bry_.new_a7("popup_id"));
|
||||
this.popup_mode = qarg_mgr.Read_str_or_null(Bry_.new_a7("popup_mode"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// get wiki
|
||||
int wiki_bgn = 1; // skip initial "/"
|
||||
int wiki_end = Bry_find_.Find_fwd_or(url, Byte_ascii.Slash, wiki_bgn, url_len, url_len);
|
||||
@@ -73,13 +112,16 @@ class Http_url_parser {
|
||||
this.action = Xopg_page_.Tid_edit;
|
||||
else if (Bry_.Eq(url, action_val_bgn, action_val_end, Xoa_url_.Qarg__action__html))
|
||||
this.action = Xopg_page_.Tid_html;
|
||||
else
|
||||
else if (Bry_.Eq(url, action_val_bgn, action_val_end, Qarg__action__popup))
|
||||
this.popup = true;
|
||||
else // no "?action=" found; ignore "?"; EX: "A?action=unknown"
|
||||
trim_page = false;
|
||||
if (trim_page)
|
||||
page_end = action_key_bgn;
|
||||
}
|
||||
|
||||
this.page = url_encoder.Decode(Bry_.Mid(url, page_bgn, page_end));
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -90,10 +132,13 @@ class Http_url_parser {
|
||||
private boolean Fail(byte[] url, String err_msg) {
|
||||
this.wiki = null;
|
||||
this.page = null;
|
||||
this.err_msg = err_msg + "; url=" + String_.new_u8(url);
|
||||
this.err_msg = err_msg;
|
||||
if (url != null)
|
||||
this.err_msg += "; url=" + String_.new_u8(url);
|
||||
return false;
|
||||
}
|
||||
private static final byte[]
|
||||
Qarg__action__frag = Bry_.Add(Byte_ascii.Question_bry, Xoa_url_.Qarg__action, Byte_ascii.Eq_bry) // "?action="
|
||||
, Qarg__action__popup = Bry_.new_a7("popup")
|
||||
;
|
||||
}
|
||||
|
||||
@@ -38,20 +38,24 @@ public class Http_url_parser_tst {
|
||||
// action=html
|
||||
fxt.Test__parse("/en.wikipedia.org/wiki/Page_1?action=html", fxt.Make().Wiki_("en.wikipedia.org").Page_("Page_1").Action_(Xopg_page_.Tid_html));
|
||||
|
||||
// action=popup
|
||||
fxt.Test__parse("/en.wikipedia.org/wiki/Page_1?action=popup", fxt.Make().Wiki_("en.wikipedia.org").Page_("Page_1").Popup_(true));
|
||||
|
||||
// action=N/A
|
||||
fxt.Test__parse("/en.wikipedia.org/wiki/Page_1?action=a", fxt.Make().Wiki_("en.wikipedia.org").Page_("Page_1?action=a"));
|
||||
fxt.Test__parse("/en.wikipedia.org/wiki/Page_1?action=a", fxt.Make().Wiki_("en.wikipedia.org").Page_("Page_1"));
|
||||
|
||||
// fail: null
|
||||
fxt.Test__parse(null, fxt.Make().Err_msg_("invalid url; url is null; url="));
|
||||
fxt.Test__parse(null, fxt.Make().Err_msg_("invalid url; url is null"));
|
||||
|
||||
// fail: empty
|
||||
fxt.Test__parse("", fxt.Make().Err_msg_("invalid url; url is empty; url="));
|
||||
fxt.Test__parse("", fxt.Make().Err_msg_("invalid url; url is empty"));
|
||||
|
||||
// fail: missing '/' at start
|
||||
fxt.Test__parse("en.wikipedia.org", fxt.Make().Err_msg_("invalid url; must start with '/'; url=en.wikipedia.org"));
|
||||
|
||||
/*
|
||||
// fail: missing '/wiki/'
|
||||
fxt.Test__parse("/en.wikipedia.org/Page_1", fxt.Make().Err_msg_("invalid url; must have '/wiki/' after wiki_domain; url=/en.wikipedia.org/Page_1"));
|
||||
*/
|
||||
}
|
||||
}
|
||||
class Http_url_parser_fxt {
|
||||
|
||||
Reference in New Issue
Block a user