1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2024-10-27 20:34:16 +00:00

HTTP Server: Add search-suggest [#489]

This commit is contained in:
gnosygnu 2019-08-04 21:25:04 -04:00
parent f5abfa11da
commit b350d95206
9 changed files with 146 additions and 49 deletions

View File

@ -76,6 +76,7 @@ public class Xoax_addon_mgr {
// jsons // jsons
, new gplx.xowa.addons.servers.https.utils .Xoa_util_addon() , new gplx.xowa.addons.servers.https.utils .Xoa_util_addon()
, new gplx.xowa.addons.wikis.searchs .Xoax_addon_itm__search_ui()
); );
if (app.Mode().Tid_is_http()) { if (app.Mode().Tid_is_http()) {

View File

@ -0,0 +1,24 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
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.addons.wikis.searchs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*;
import gplx.xowa.htmls.bridges.*;
import gplx.xowa.addons.wikis.searchs.gui.htmlbars.*;
public class Xoax_addon_itm__search_ui implements Xoax_addon_itm, Xoax_addon_itm__json {
public String Addon__key() {return "xowa.search.ui";}
public Bridge_cmd_itm[] Json_cmds() {
return new Bridge_cmd_itm[] {new Bridge_cmd_itm__srch_suggest()};
}
}

View File

@ -0,0 +1,39 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
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.addons.wikis.searchs.gui.htmlbars; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.searchs.*; import gplx.xowa.addons.wikis.searchs.gui.*;
import gplx.langs.jsons.*;
import gplx.xowa.htmls.bridges.*;
public class Bridge_cmd_itm__srch_suggest implements Bridge_cmd_itm {
private Xoa_app app;
public byte[] Key() {return Bry_.new_a7("xowa.search.ui.suggest");}
public void Init_by_app(Xoa_app app) {
this.app = app;
}
public String Exec(Json_nde data) {
// extract vars from json
byte[] wiki_bry = data.Get_as_bry("wiki");
byte[] search_bry = data.Get_as_bry("search");
byte[] cbk_func = data.Get_as_bry("cbk");
// build vars for search
Xowe_wiki wiki = (Xowe_wiki)app.Wiki_mgri().Get_by_or_null(wiki_bry);
Srch_rslt_cbk__js cbk = new Srch_rslt_cbk__js(cbk_func, search_bry);
// do search and return result
app.Addon_mgr().Itms__search__htmlbar().Search(wiki, search_bry, cbk);
return cbk.To_str_and_clear();
}
}

View File

@ -14,35 +14,32 @@ GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.addons.wikis.searchs.gui.htmlbars; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.searchs.*; import gplx.xowa.addons.wikis.searchs.gui.*; package gplx.xowa.addons.wikis.searchs.gui.htmlbars; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.searchs.*; import gplx.xowa.addons.wikis.searchs.gui.*;
import gplx.core.net.*; import gplx.core.net.qargs.*; import gplx.xowa.addons.wikis.searchs.searchers.*; import gplx.xowa.addons.wikis.searchs.searchers.cbks.*; import gplx.xowa.addons.wikis.searchs.searchers.rslts.*;
import gplx.xowa.wikis.nss.*;
import gplx.xowa.addons.wikis.searchs.searchers.cbks.*; import gplx.xowa.addons.wikis.searchs.searchers.*;
public class Srch_htmlbar_mgr implements Gfo_invk { public class Srch_htmlbar_mgr implements Gfo_invk {
private Srch_search_addon addon;
private int results_max = 25; private int results_max = 25;
public void Init_by_kit(Xoae_app app, gplx.gfui.kits.core.Gfui_kit kit) { public void Init_by_kit(Xoae_app app, gplx.gfui.kits.core.Gfui_kit kit) {
app.Cfg().Bind_many_app(this, Cfg__enabled, Cfg__results_max); app.Cfg().Bind_many_app(this, Cfg__enabled, Cfg__results_max);
} }
public boolean Enabled() {return enabled;} private boolean enabled = true; public boolean Enabled() {return enabled;} private boolean enabled = true;
public void Search(Xowe_wiki wiki, byte[] search_bry, byte[] cbk_func) { public void Search_by_swt(Xowe_wiki wiki, byte[] search_bry, byte[] cbk_func) {
if ( !enabled this.Search(wiki, search_bry, new Srch_rslt_cbk__swt(wiki.Appe(), cbk_func, search_bry));
|| search_bry.length == 0
) return;
if (addon == null)
addon = Srch_search_addon.Get(wiki);
else {
if (!Bry_.Eq(wiki.Domain_bry(), addon.Wiki_domain())) // NOTE: suggest-box caches addon at wiki level; need to check if wiki has changed
addon = Srch_search_addon.Get(wiki);
} }
// tab_close_mgr.Add(this); public void Search(Xowe_wiki wiki, byte[] search_bry, Srch_rslt_cbk cbk) {
Srch_search_qry qry = Srch_search_qry.New__suggest_box(wiki, wiki.App().Addon_mgr().Itms__search__special().Ns_mgr(), wiki.App().Addon_mgr().Itms__search__special().Auto_wildcard(), results_max, search_bry); // return if not-enabled or if search is empty
Srch_rslt_cbk__suggest_box cbk = new Srch_rslt_cbk__suggest_box(wiki.Appe(), cbk_func, search_bry); if (!enabled || Bry_.Len_eq_0(search_bry)) return;
// get search_addon associated with wiki
Srch_search_addon addon = Srch_search_addon.Get(wiki);
// build query
Srch_search_qry qry = Srch_search_qry.New__suggest_box
( wiki
, wiki.App().Addon_mgr().Itms__search__special().Ns_mgr()
, wiki.App().Addon_mgr().Itms__search__special().Auto_wildcard()
, results_max, search_bry);
// run it
addon.Search(qry, cbk); addon.Search(qry, cbk);
cbkrslt = cbk.Get_js_str();
}
private String cbkrslt;
public String Get_js_rslt() {
return cbkrslt;
} }
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Cfg__enabled)) enabled = m.ReadYn("v"); if (ctx.Match(k, Cfg__enabled)) enabled = m.ReadYn("v");

View File

@ -13,21 +13,23 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.addons.wikis.searchs.searchers.cbks; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.searchs.*; import gplx.xowa.addons.wikis.searchs.searchers.*; package gplx.xowa.addons.wikis.searchs.gui.htmlbars; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.searchs.*; import gplx.xowa.addons.wikis.searchs.gui.*;
import gplx.core.js.*; import gplx.core.js.*;
import gplx.xowa.addons.wikis.searchs.searchers.*; import gplx.xowa.addons.wikis.searchs.searchers.rslts.*; import gplx.xowa.addons.wikis.searchs.searchers.*; import gplx.xowa.addons.wikis.searchs.searchers.rslts.*;
public class Srch_rslt_cbk__suggest_box implements Srch_rslt_cbk, Gfo_invk { class Srch_rslt_cbk__js implements Srch_rslt_cbk {
private final Js_wtr js_wtr = new Js_wtr(); protected final Js_wtr js_wtr = new Js_wtr();
private final Xoae_app app; private byte[] cbk_func, search_raw;
private final byte[] cbk_func; public Srch_rslt_cbk__js(byte[] cbk_func, byte[] search_raw) {
private final byte[] search_raw; this.cbk_func = cbk_func;
public Srch_rslt_cbk__suggest_box(Xoae_app app, byte[] cbk_func, byte[] search_raw) {
this.app = app; this.cbk_func = cbk_func;
this.search_raw = search_raw; this.search_raw = search_raw;
} }
public String To_str_and_clear() {return js_wtr.To_str_and_clear();}
public void On_cancel() {} public void On_cancel() {}
public void On_rslts_found(Srch_search_qry qry, Srch_rslt_list rslts_list, int rslts_bgn, int rslts_end) { @gplx.Virtual public void On_rslts_found(Srch_search_qry qry, Srch_rslt_list rslts_list, int rslts_bgn, int rslts_end) {
// exit if done
if (!rslts_list.Rslts_are_enough && !rslts_list.Rslts_are_done) return; if (!rslts_list.Rslts_are_enough && !rslts_list.Rslts_are_done) return;
// build js; EX: "receiveSuggestions('search_word', ["a"])"
js_wtr.Func_init(cbk_func); js_wtr.Func_init(cbk_func);
js_wtr.Prm_bry(search_raw); js_wtr.Prm_bry(search_raw);
js_wtr.Prm_spr(); js_wtr.Prm_spr();
@ -41,20 +43,22 @@ public class Srch_rslt_cbk__suggest_box implements Srch_rslt_cbk, Gfo_invk {
} }
js_wtr.Ary_term(); js_wtr.Ary_term();
js_wtr.Func_term(); js_wtr.Func_term();
Gfo_invk_.Invk_by_key(app.Gui_mgr().Kit().New_cmd_sync(this), Srch_rslt_cbk__suggest_box.Invk__notify);
if (!app.Mode().Tid_is_http())
Gfo_invk_.Invk_by_key(app.Gui_mgr().Kit().New_cmd_sync(this), Srch_rslt_cbk__suggest_box.Invk__notify);
} }
public String Get_js_str() {
return js_wtr.To_str_and_clear();
} }
private void Notify() { class Srch_rslt_cbk__swt extends Srch_rslt_cbk__js implements Gfo_invk { private final Xoae_app app;
app.Gui_mgr().Browser_win().Active_html_box().Html_js_eval_script(js_wtr.To_str_and_clear()); public Srch_rslt_cbk__swt(Xoae_app app, byte[] cbk_func, byte[] search_raw) {super(cbk_func, search_raw);
this.app = app;
}
@Override public void On_rslts_found(Srch_search_qry qry, Srch_rslt_list list, int rslts_bgn, int rslts_end) {
super.On_rslts_found(qry, list, rslts_bgn, rslts_end);
Gfo_invk_.Invk_by_val(app.Gui_mgr().Kit().New_cmd_sync(this), Invk__notify, js_wtr.To_str_and_clear());
} }
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk__notify)) Notify(); if (ctx.Match(k, Invk__notify)) {
app.Gui_mgr().Browser_win().Active_html_box().Html_js_eval_script(m.ReadStr("v"));
}
else return Gfo_invk_.Rv_unhandled; else return Gfo_invk_.Rv_unhandled;
return this; return this;
} }
public static final String Invk__notify = "notify"; private static final String Invk__notify = "notify";
} }

View File

@ -127,7 +127,7 @@ public class Xoh_js_cbk implements Gfo_invk {
Xowe_wiki wiki = html_itm.Owner_tab().Wiki(); Xowe_wiki wiki = html_itm.Owner_tab().Wiki();
byte[] search_str = Bry_.new_u8((String)m.ReadValAt(0)); byte[] search_str = Bry_.new_u8((String)m.ReadValAt(0));
byte[] cbk_func = Bry_.new_u8((String)m.ReadValAt(1)); byte[] cbk_func = Bry_.new_u8((String)m.ReadValAt(1));
app.Addon_mgr().Itms__search__htmlbar().Search(wiki, search_str, cbk_func); app.Addon_mgr().Itms__search__htmlbar().Search_by_swt(wiki, search_str, cbk_func);
return ""; return "";
} }
private String[] Wikidata_get_label(GfoMsg m) { private String[] Wikidata_get_label(GfoMsg m) {

View File

@ -5,6 +5,7 @@
width: 100%; width: 100%;
list-style: none; list-style: none;
background: transparent; /*2013-08-20:else blue vertical bar will be visible directly underneath right-edge of search box*/ background: transparent; /*2013-08-20:else blue vertical bar will be visible directly underneath right-edge of search box*/
z-index: 128; /*else indicators page-indicator icons will show; EX:en.w:Earth; DATE:2019-08-04*/
} }
#xowa-search-suggestions li { #xowa-search-suggestions li {

View File

@ -37,11 +37,37 @@ function receiveSuggestions (search, suggestions) {
} }
window.receiveSuggestions = receiveSuggestions; window.receiveSuggestions = receiveSuggestions;
function fetchSuggestions () { function fetchSuggestions () {
if (xowa_mode_is_server) if (xowa_global_values.mode_is_http) {
xowa_exec_async(function(){}, 'get_search_suggestions', currentSearch, 'receiveSuggestions'); var wiki = xowa.page.wiki;
var search = document.getElementById("searchInput").value;
sendByAjaxWithCallback
( 'xowa.search.ui.suggest'
, { wiki: wiki
, search: search
, cbk: "receiveSuggestions"
}
, function(xreq)
{
eval(xreq.responseText);
}
);
}
else else
xowa_exec('get_search_suggestions', currentSearch, 'receiveSuggestions'); xowa_exec('get_search_suggestions', currentSearch, 'receiveSuggestions');
} }
function sendByAjaxWithCallback(cmd, data, cbk) {
var xreq = new XMLHttpRequest();
xreq.onreadystatechange = function() {
if (xreq.readyState == 4 && xreq.status == 200) {
cbk(xreq)
}
};
var form_data = new FormData();
form_data.append('msg', JSON.stringify({cmd:cmd, data:data}));
form_data.append('app_mode', 'http_server');
xreq.open("POST", '/exec/json', true);
xreq.send(form_data);
}
function renderSuggestion (page_db, page_display) { function renderSuggestion (page_db, page_display) {
var textNode = document.createElement('span'), var textNode = document.createElement('span'),
@ -49,7 +75,11 @@ function renderSuggestion (page_db, page_display) {
liNode = document.createElement('li'); liNode = document.createElement('li');
textNode.innerHTML = page_display; textNode.innerHTML = page_display;
textNode.setAttribute('xowa_page_db', page_db); textNode.setAttribute('xowa_page_db', page_db);
linkNode.href = '/wiki/' + page_db; var href = '/wiki/' + page_db;
if (xowa_global_values.mode_is_http) {
href = '/' + xowa.page.wiki + href;
}
linkNode.href = href;
linkNode.appendChild(textNode); linkNode.appendChild(textNode);
liNode.appendChild(linkNode); liNode.appendChild(linkNode);
return liNode; return liNode;

View File

@ -5,6 +5,7 @@
width: 100%; width: 100%;
list-style: none; list-style: none;
background: transparent; /*2013-08-20:else blue vertical bar will be visible directly underneath right-edge of search box*/ background: transparent; /*2013-08-20:else blue vertical bar will be visible directly underneath right-edge of search box*/
z-index: 128; /*else indicators page-indicator icons will show; EX:en.w:Earth; DATE:2019-08-04*/
} }
#xowa-search-suggestions li { #xowa-search-suggestions li {