1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2015-08-03 00:10:03 -04:00
parent 9d63f03b3d
commit 34c34f227c
514 changed files with 4972 additions and 3910 deletions

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.html; import gplx.*; import gplx.xowa.*;
public class Xoh_consts {
public static final String
Atr_xowa_title_str = "xowa_title"
Atr_xowa_title_str = "xowa_title"
, Img_w_str = "width"
, Img_h_str = "height"
;
@@ -31,14 +31,13 @@ public class Xoh_consts {
, A_bgn = Bry_.new_a7("<a href=\""), A_bgn_lnki_0 = Bry_.new_a7("\" title=\""), A_mid_xowa_title = Bry_.new_a7("\" xowa_title=\"")
, A_mid_id = Bry_.new_a7("\" id=\"xowa_lnki_")
, A_end = Bry_.new_a7("</a>")
, Div_bgn_open = Bry_.new_a7("<div ")
, Div_end = Bry_.new_a7("</div>")
, Img_bgn = Bry_.new_a7("<img src=\"")
, Span_bgn_open = Bry_.new_a7("<span")
, Span_end = Bry_.new_a7("</span>")
, Span_bgn = Bry_.new_a7("<span>")
, Img_bgn = Bry_.new_a7("<img src=\"")
, Span_bgn_open = Bry_.new_a7("<span")
, Span_end = Bry_.new_a7("</span>")
, Span_bgn = Bry_.new_a7("<span>")
, Pre_bgn = Bry_.new_a7("<pre>"), Pre_end = Bry_.new_a7("</pre>")
, Pre_bgn_open = Bry_.new_a7("<pre")
@@ -53,6 +52,5 @@ public class Xoh_consts {
, Style_atr = Bry_.new_a7(" style=\"")
, Atr_xowa_title_bry = Bry_.new_a7(Atr_xowa_title_str)
;
public static final int Nbsp_int = 160;
}

View File

@@ -19,17 +19,16 @@ package gplx.xowa.html; import gplx.*; import gplx.xowa.*;
import gplx.xowa.html.tidy.*; import gplx.xowa.html.utils.*; import gplx.xowa.html.skins.*;
public class Xoh_html_mgr implements GfoInvkAble {
public Xoh_html_mgr(Xoae_app app) {
page_mgr = new Xoh_page_mgr(app);
js_cleaner = new Xoh_js_cleaner(app);
}
public void Init_by_app(Xoae_app app) {
tidy_mgr.Init_by_app(app);
}
public Xop_xatr_whitelist_mgr Whitelist_mgr() {return whitelist_mgr;} private Xop_xatr_whitelist_mgr whitelist_mgr = new Xop_xatr_whitelist_mgr().Ini();
public Xoh_page_mgr Page_mgr() {return page_mgr;} private Xoh_page_mgr page_mgr;
public Xoh_tidy_mgr Tidy_mgr() {return tidy_mgr;} private Xoh_tidy_mgr tidy_mgr = new Xoh_tidy_mgr();
public Xoh_js_cleaner Js_cleaner() {return js_cleaner;} private Xoh_js_cleaner js_cleaner;
public Xoh_skin_mgr Skin_mgr() {return skin_mgr;} private Xoh_skin_mgr skin_mgr = new Xoh_skin_mgr();
public Xop_xatr_whitelist_mgr Whitelist_mgr() {return whitelist_mgr;} private final Xop_xatr_whitelist_mgr whitelist_mgr = new Xop_xatr_whitelist_mgr().Ini();
public Xoh_page_mgr Page_mgr() {return page_mgr;} private final Xoh_page_mgr page_mgr = new Xoh_page_mgr();
public Xoh_tidy_mgr Tidy_mgr() {return tidy_mgr;} private final Xoh_tidy_mgr tidy_mgr = new Xoh_tidy_mgr();
public Xoh_js_cleaner Js_cleaner() {return js_cleaner;} private final Xoh_js_cleaner js_cleaner;
public Xoh_skin_mgr Skin_mgr() {return skin_mgr;} private final Xoh_skin_mgr skin_mgr = new Xoh_skin_mgr();
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_page)) return page_mgr;
else if (ctx.Match(k, Invk_tidy)) return tidy_mgr;

View File

@@ -16,8 +16,8 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html; import gplx.*; import gplx.xowa.*;
import gplx.core.primitives.*;
import gplx.core.btries.*; import gplx.html.*; import gplx.xowa.wikis.*; import gplx.xowa.net.*;
import gplx.core.primitives.*; import gplx.core.net.*;
import gplx.core.btries.*; import gplx.html.*; import gplx.xowa.wikis.*;
import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.hdrs.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.html.lnkis.*; import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.paras.*;
import gplx.xowa.xtns.*; import gplx.xowa.xtns.dynamicPageList.*; import gplx.xowa.xtns.math.*; import gplx.xowa.langs.vnts.*; import gplx.xowa.xtns.cite.*; import gplx.xowa.html.hzips.*;
public class Xoh_html_wtr {
@@ -633,7 +633,7 @@ class Xoh_display_ttl_wtr {
Atr_key_style = Bry_.new_a7("style")
, Msg_style_restricted = Bry_.new_a7(" style='/* attempt to bypass $wgRestrictDisplayTitle */'")
;
private Btrie_slim_mgr style_trie = Btrie_slim_mgr.ci_ascii_()
private Btrie_slim_mgr style_trie = Btrie_slim_mgr.ci_a7()
.Add_str_byte__many(Byte_.By_int(0), "display", "user-select", "visibility"); // if ( preg_match( '/(display|user-select|visibility)\s*:/i', $decoded['style'] ) ) {
public boolean Is_style_restricted(Bry_bfr bfr, Xoh_wtr_ctx hctx, byte[] src, Xop_xatr_itm atr, byte[] atr_key) {
if (atr_key != null

View File

@@ -18,10 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.html; import gplx.*; import gplx.xowa.*;
import gplx.xowa.html.portal.*;
public class Xoh_page_mgr implements GfoInvkAble {
public Xoh_page_mgr(Xoae_app app) {
this.subpages_bldr = new Xoh_subpages_bldr(app);
}
public Xoh_subpages_bldr Subpages_bldr() {return subpages_bldr;} private Xoh_subpages_bldr subpages_bldr;
public Xoh_subpages_bldr Subpages_bldr() {return subpages_bldr;} private final Xoh_subpages_bldr subpages_bldr = new Xoh_subpages_bldr();
public boolean Font_enabled() {return font_enabled;} private boolean font_enabled = false;
public void Font_enabled_(boolean v) {font_enabled = v;}
public String Font_name() {return font_name;} private String font_name = "Arial";

View File

@@ -67,11 +67,17 @@ public class Xoh_page_wtr_wkr implements Bry_fmtr_arg {
byte[] page_content_sub = Xoh_page_wtr_wkr_.Bld_page_content_sub(app, wiki, page, tmp_bfr);
byte[] js_edit_toolbar_bry = view_tid == Xopg_view_mode.Tid_edit ? wiki.Fragment_mgr().Html_js_edit_toolbar() : Bry_.Empty;
Xow_portal_mgr portal_mgr = wiki.Html_mgr().Portal_mgr().Init_assert();
byte[] page_name = Xoh_page_wtr_wkr_.Bld_page_name(tmp_bfr, page_ttl, null); // NOTE: page_name does not show display_title (<i>). always pass in null
byte[] page_display = Xoh_page_wtr_wkr_.Bld_page_name(tmp_bfr, page_ttl, page.Html_data().Display_ttl());
Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr();
if (vnt_mgr.Enabled()) { // VNT
page_name = vnt_mgr.Convert_text(wiki, page_name);
page_display = vnt_mgr.Convert_text(wiki, page_display);
}
fmtr.Bld_bfr_many(html_bfr
, root_dir_bry, Xoa_app_.Version, Xoa_app_.Build_date, app.Tcp_server().Running_str()
, page.Revision_data().Id()
, Xoh_page_wtr_wkr_.Bld_page_name(tmp_bfr, page_ttl, null) // NOTE: page_name does not show display_title (<i>). always pass in null
, Xoh_page_wtr_wkr_.Bld_page_name(tmp_bfr, page_ttl, page.Html_data().Display_ttl())
, page_name, page_display
, page_modified_on_msg
, mgr.Css_common_bry(), mgr.Css_wiki_bry(), page.Html_data().Head_mgr().Init(app, wiki, page).Init_dflts()
, page.Lang().Dir_ltr_bry(), page.Html_data().Indicators(), page_content_sub, wiki.Html_mgr().Portal_mgr().Div_jump_to(), page_body_class, html_content_editable
@@ -123,9 +129,6 @@ public class Xoh_page_wtr_wkr implements Bry_fmtr_arg {
boolean tidy_enabled = tidy_mgr.Enabled();
Bry_bfr hdom_bfr = tidy_enabled ? app.Utl__bfr_mkr().Get_m001() : bfr; // if tidy, then write to tidy_bfr; note that bfr already has <html> and <head> written to it, so this can't be passed to tidy; DATE:2014-06-11
wiki.Html_mgr().Html_wtr().Write_all(hdom_bfr, page.Wikie().Ctx(), hctx, page.Root().Data_mid(), page.Root());
// Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr();
// if (vnt_mgr.Enabled()) // VNT
// hdom_bfr.Add(vnt_mgr.Convert_text(wiki, hdom_bfr.Xto_bry_and_clear()));
if (tidy_enabled) {
tidy_mgr.Run_tidy_html(page, hdom_bfr);
bfr.Add_bfr_and_clear(hdom_bfr);
@@ -145,6 +148,9 @@ public class Xoh_page_wtr_wkr implements Bry_fmtr_arg {
else
wiki.Html_mgr().Ctg_mgr().Bld(bfr, page, ctgs_len);
}
Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr();
if (vnt_mgr.Enabled()) // VNT
bfr.Add(vnt_mgr.Convert_text(wiki, bfr.Xto_bry_and_clear()));
}
private void Write_body_pre(Bry_bfr bfr, Xoae_app app, Xowe_wiki wiki, byte[] data_raw, Bry_bfr tmp_bfr) {
Xoh_html_wtr_escaper.Escape(app.Parser_amp_mgr(), tmp_bfr, data_raw, 0, data_raw.length, false, false);

View File

@@ -53,7 +53,7 @@ class Xoh_ctg_itm_fmtr implements Bry_fmtr_arg {
for (int i = 0; i < ctgs_len; i++) {
byte[] page_name = page.Category_list()[i];
tmp_bfr.Add(ctg_prefix).Add(page_name);
page.Wikie().Appe().Href_parser().Build_to_bfr(tmp_href, app, wiki.Domain_bry(), wiki.Ttl_parse(tmp_bfr.Xto_bry_and_clear()));
page.Wikie().Appe().Html__href_wtr().Build_to_bfr(tmp_href, app, wiki.Domain_bry(), wiki.Ttl_parse(tmp_bfr.Xto_bry_and_clear()));
itm_fmtr.Bld_bfr(bfr, tmp_href.Xto_bry_and_clear(), page_name, page_name);
}
tmp_bfr.Mkr_rls();

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.html.bridges; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.json.*;
public class Bridge_cmd_mgr {
private final Hash_adp_bry cmd_hash = Hash_adp_bry.cs_();
private final Hash_adp_bry cmd_hash = Hash_adp_bry.cs();
public void Add(Bridge_cmd_itm cmd) {cmd_hash.Add_bry_obj(cmd.Key(), cmd);}
public String Exec(GfoMsg m) {
if (m.Args_count() == 0) throw Err_.new_("bridge.cmds", "no json specified for json_exec");

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.html.bridges.dbuis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.bridges.*;
import gplx.core.json.*; import gplx.xowa.html.bridges.dbuis.tbls.*;
public class Dbui_cmd_mgr {
private final Hash_adp_bry hash = Hash_adp_bry.cs_();
private final Hash_adp_bry hash = Hash_adp_bry.cs();
private boolean init;
public void Init_by_bridge(Bridge_cmd_mgr cmd_mgr) {
if (init) return;

View File

@@ -41,7 +41,7 @@ class Dbui_head_cell_fmtr implements Bry_fmtr_arg {
Dbui_col_itm col = cols[i];
fmtr.Bld_bfr_many(bfr, col.Width(), col.Display());
}
bfr.Add_str_a7("\n <div class='xo_head xo_resizable_col' style='width:35px;'>&nbsp;</div>"); // btns headers
bfr.Add_str_a7("\n <div class='xo_head xo_resizable_col' style='width:50px;'>&nbsp;</div>"); // btns headers
}
private static final Bry_fmtr fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""

View File

@@ -51,7 +51,7 @@ public class Xohd_hdump_wtr {
public void Generate_hdump(Bry_bfr tmp_bfr, Xoae_page page) {
page.File_queue().Clear(); // need to reset uid to 0, else xowa_file_# will resume from last
page_wtr_mgr.Wkr(Xopg_view_mode.Tid_read).Write_body(tmp_bfr, Xoh_wtr_ctx.Hdump, page);
if (!Env_.Mode_testing()) page.Wikie().Html_mgr().Hzip_mgr().Write(tmp_bfr, new Xodump_stats_itm(), page.Url().Xto_full_bry(), tmp_bfr.Xto_bry_and_clear()); // hzip data;
if (!Env_.Mode_testing()) page.Wikie().Html_mgr().Hzip_mgr().Write(tmp_bfr, new Xodump_stats_itm(), page.Url().To_bry_full_wo_qargs(), tmp_bfr.Xto_bry_and_clear()); // hzip data;
page.Hdump_data().Body_(tmp_bfr.Xto_bry_and_clear()); // write to body bry
}
}

View File

@@ -48,7 +48,7 @@ public class Xohd_abrv_ {
, Html_redlink_end = Bry_.new_a7("'>")
;
public static Btrie_slim_mgr new_trie() {
Btrie_slim_mgr rv = Btrie_slim_mgr.cs_();
Btrie_slim_mgr rv = Btrie_slim_mgr.cs();
trie_itm(rv, Tid_dir , Byte_ascii.Null , Key_dir);
trie_itm(rv, Tid_img , Byte_ascii.Apos , Key_img);
trie_itm(rv, Tid_img_style , Byte_ascii.Apos , Key_img_style);

View File

@@ -80,8 +80,8 @@ public class Xohd_abrv_mgr {
case Xohd_abrv_.Tid_hdr_end: return wkr__hdr.Write_end(bfr, hpg, uid, rv);
}
if (itm.Elem_is_xnde()) rv += 2; // if xnde, skip "/>"
if (uid == bry_rdr.Or_int()) {usr_dlg.Warn_many("", "", "index is not a valid int; hpg=~{0} text=~{1}", hpg.Url().Xto_full_str_safe(), Bry_.Mid_safe(src, uid_bgn, uid_end)); return uid_end;}
if (!Int_.Between(uid, 0, imgs_len)) {usr_dlg.Warn_many("", "", "index is out of range; hpg=~{0} idx=~{1} len=~{2}", hpg.Url().Xto_full_str_safe(), uid, imgs_len); return uid_end;}
if (uid == bry_rdr.Or_int()) {usr_dlg.Warn_many("", "", "index is not a valid int; hpg=~{0} text=~{1}", hpg.Url().To_str(), Bry_.Mid_safe(src, uid_bgn, uid_end)); return uid_end;}
if (!Int_.Between(uid, 0, imgs_len)) {usr_dlg.Warn_many("", "", "index is out of range; hpg=~{0} idx=~{1} len=~{2}", hpg.Url().To_str(), uid, imgs_len); return uid_end;}
if (uid >= imgs.length) return rv;
Xohd_data_itm__base img = imgs[uid];
int img_view_w = img.Html_w();

View File

@@ -54,10 +54,10 @@ public class Xob_hdump_bldr {
private void Hzip_data(Xoae_page page) {
Xowe_wiki wiki = page.Wikie();
Xow_hzip_mgr hzip_mgr = wiki.Html_mgr().Hzip_mgr();
page.File_queue().Clear(); // need to reset uid to 0, else xowa_file_# will resume from last
wiki.Html_mgr().Page_wtr_mgr().Wkr(Xopg_view_mode.Tid_read).Write_body(tmp_bfr, Xoh_wtr_ctx.Hdump, page); // write to html again, except in hdump mode
if (hzip_enabled) hzip_mgr.Write(tmp_bfr, stats_itm, page.Url().Xto_full_bry(), tmp_bfr.Xto_bry_and_clear()); // hzip data
page.Hdump_data().Body_(tmp_bfr.Xto_bry_and_clear()); // write to body bry
page.File_queue().Clear(); // need to reset uid to 0, else xowa_file_# will resume from last
wiki.Html_mgr().Page_wtr_mgr().Wkr(Xopg_view_mode.Tid_read).Write_body(tmp_bfr, Xoh_wtr_ctx.Hdump, page); // write to html again, except in hdump mode
if (hzip_enabled) hzip_mgr.Write(tmp_bfr, stats_itm, page.Url().To_bry_full_wo_qargs(), tmp_bfr.Xto_bry_and_clear()); // hzip data
page.Hdump_data().Body_(tmp_bfr.Xto_bry_and_clear()); // write to body bry
}
}
class Xob_ns_to_db_wkr__html implements Xob_ns_to_db_wkr {

View File

@@ -25,7 +25,7 @@ public class Xohd_page_html_mgr__load {
public void Load_page(Xow_wiki wiki, Xog_page hpg, Xowd_html_tbl tbl, int page_id, Xoa_ttl page_ttl) {
Xoa_app_.Usr_dlg().Plog_many("", "", "hdump.load.text: ttl=~{0}", page_ttl.Full_db_as_str());
tbl.Select_by_page(rows, page_id);
Parse_rows(wiki, hpg, page_id, Xoa_url.blank_(), page_ttl, rows);
Parse_rows(wiki, hpg, page_id, Xoa_url.blank(), page_ttl, rows);
}
public void Parse_rows(Xow_wiki wiki, Xog_page hpg, int page_id, Xoa_url page_url, Xoa_ttl page_ttl, List_adp rows) { // TEST:
hpg.Init(wiki, page_id, page_url, page_ttl);

View File

@@ -1,75 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.hrefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_href {
public byte[] Raw() {return raw;} public Xoh_href Raw_(byte[] v) {raw = v; return this;} private byte[] raw;
public byte[] Wiki() {return wiki;} public Xoh_href Wiki_(byte[] v) {wiki = v; return this;} private byte[] wiki;
public byte[] Page() {return page;} public Xoh_href Page_(byte[] v) {page = v; return this;} private byte[] page;
public byte[] Anchor() {return anchor;} public Xoh_href Anchor_(byte[] v) {anchor = v; return this;} private byte[] anchor;
public byte Tid() {return tid;} public Xoh_href Tid_(byte v) {tid = v; return this;} private byte tid;
public byte[] Page_and_anchor() {
if (Bry_.Len_eq_0(anchor)) return page;
else if (Bry_.Len_eq_0(page)) return anchor;
else return Bry_.Add_w_dlm(Byte_ascii.Hash, page, anchor);
}
public byte Protocol_tid() {return protocol_tid;} private byte protocol_tid;
public void Init(byte[] raw, byte protocol_tid) {
this.raw = raw; this.protocol_tid = protocol_tid;
wiki = page = anchor = null;
tid = Tid_null;
}
public void Print_to_bfr(Bry_bfr bfr, boolean full) { // currently used for status bar (not embedded in any html)
switch (tid) {
case Xoh_href.Tid_http: case Xoh_href.Tid_file: // full protocol; embed all; EX: "http://en.wikipedia.org/wiki/A"; "file:///C/dir/file.txt"
bfr.Add(raw);
break;
case Xoh_href.Tid_xowa:
bfr.Add(page);
break;
default:
if (full) { // "full" can be copied and pasted into firefox url bar
switch (tid) {
case Xoh_href.Tid_wiki: case Xoh_href.Tid_site: case Xoh_href.Tid_anchor:
bfr.Add(wiki); // add wiki_key; EX: "en.wikipedia.org"
bfr.Add(Xoh_href_parser.Href_wiki_bry); // add wiki_str; EX: "/wiki/"
bfr.Add(page); // add page; EX: "A"
if (anchor != null)
bfr.Add_byte(Byte_ascii.Hash).Add(anchor); // add anchor; EX: "#B"
break;
}
}
else {
switch (tid) {
case Xoh_href.Tid_site:
bfr.Add(wiki).Add_byte(Byte_ascii.Slash); // add wiki_key; EX: "en.wikipedia.org/"
bfr.Add(page); // add page; EX: "A"
break;
case Xoh_href.Tid_wiki:
bfr.Add(page); // add page; EX: "A"
break;
case Xoh_href.Tid_anchor: // anchor to be added below
break;
}
if (anchor != null)
bfr.Add_byte(Byte_ascii.Hash).Add(anchor); // add anchor; EX: "#B"
}
break;
}
}
public static final byte Tid_null = 0, Tid_http = 1, Tid_file = 2, Tid_wiki = 3, Tid_site = 4, Tid_xcmd = 5, Tid_anchor = 6, Tid_xowa = 7;
}

View File

@@ -0,0 +1,40 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.hrefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_href_ {
public static final String
Str__file = "file://"
, Str__site = "/site/"
, Str__wiki = "/wiki/"
, Str__anch = "#"
;
public static final byte[]
Bry__file = Bry_.new_a7(Str__file)
, Bry__site = Bry_.new_a7(Str__site)
, Bry__wiki = Bry_.new_a7(Str__wiki)
, Bry__anch = Bry_.new_a7(Str__anch)
, Bry__https = Bry_.new_a7("https://") // NOTE: must be "https:" or wmf api won't work; DATE:2015-06-17
, Bry__xcmd = Bry_.new_a7("/xcmd/")
;
public static final int
Len__file = Bry__file.length
, Len__site = Bry__site.length
, Len__wiki = Bry__wiki.length
, Len__anch = Bry__anch.length
;
}

View File

@@ -0,0 +1,94 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.hrefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.btries.*; import gplx.core.primitives.*;
public class Xoh_href_gui_utl {
public static String Html_extract_text(String site, String page, String text_str) {
byte[] text_bry = Bry_.new_u8(text_str);
int text_len = text_bry.length;
int text_tid = Byte_ascii.Xto_digit(text_bry[0]);
switch (text_tid) {
case Text_tid_none: return ""; // "0"
case Text_tid_text: return String_.new_u8(text_bry, 2, text_len); // 2 to skip "1|"
case Text_tid_href: break; // fall through to below
default: throw Err_.new_unhandled(text_tid);
}
int href_bgn = 2; // 2 to skip "2|"
if (Bry_.Has_at_bgn(text_bry, Xoh_href_.Bry__file, href_bgn, text_len))
href_bgn += Xoh_href_.Len__file; // skip "file://"
Byte_obj_val href_tid = (Byte_obj_val)href_trie.Match_bgn(text_bry, href_bgn, text_len);
if (href_tid != null) {
switch (href_tid.Val()) {
case Href_tid_wiki: return site + String_.new_u8(text_bry, href_bgn, text_len);
case Href_tid_site: return String_.new_u8(text_bry, href_bgn + 6, text_len); // +6 to skip "site/"
case Href_tid_anch: return site + "/wiki/" + page + String_.new_u8(text_bry, href_bgn, text_len);
}
}
return String_.new_u8(text_bry, 2, text_len); // 2 to skip "2|"; handles "http://" text as well as any fall-thru from above
}
public static String Standardize_xowa_link(String str) {
byte[] bry = Bry_.new_u8(str);
int skip = Skip_start_of_xowa_link(bry, bry.length, 0);
return skip == 0 ? str : String_.Mid(str, skip);
}
private static int Skip_start_of_xowa_link(byte[] src, int src_len, int bgn) {
if (!Bry_.Has_at_bgn(src, Xoh_href_.Bry__file, bgn, src_len)) return bgn; // does not start with "file://"
int pos = bgn + Xoh_href_.Len__file; // skip "file://"
Object tid_obj = href_trie.Match_bgn(src, pos, src_len);
if (tid_obj == null) {
return bgn; // if not a known xowa link, return original bgn;
}
switch (((Byte_obj_val)tid_obj).Val()) {
case Href_tid_site: return pos;
case Href_tid_wiki: return pos;
case Href_tid_anch: return pos;
default: throw Err_.new_unhandled(tid_obj);
}
}
private static final byte Text_tid_none = 0, Text_tid_text = 1, Text_tid_href = 2;
private static final byte Href_tid_wiki = 1, Href_tid_site = 2, Href_tid_anch = 3;
private static final Btrie_slim_mgr href_trie = Btrie_slim_mgr.cs()
.Add_bry_byte(Xoh_href_.Bry__site , Href_tid_site)
.Add_bry_byte(Xoh_href_.Bry__wiki , Href_tid_wiki)
.Add_bry_byte(Xoh_href_.Bry__anch , Href_tid_anch)
;
}
/*
NOTE_1:
. swt/mozilla treats text differently in href="{text}" when content_editable=n; occurs in LocationListener.changing
http://a.org -> http://a.org does nothing
A -> file:///A adds "file:///"
/wiki/A -> file:///wiki/A adds "file://"
Category:A -> Category:A noops; Category is assumed to be protocol?
//en.wiktionary.org/wiki/a -> file:///wiki/a strips out site name and prepends "file://"; no idea why
. so, to handle the above, the code does the following
http://a.org -> http://a.org does nothing; nothing needed
A -> /wiki/A always prepend /wiki/
Category:A -> /wiki/Category:A always prepend /wiki/
//en.wiktionary.org/wiki/A -> /site/en.wiktionary.org/wiki/A always transform relative url to /site/
. the href will still come here as file:///wiki/A or file:///site/en.wiktionary.org/wiki/A.
. however, the file:// can be lopped off and discarded and the rest of the href will fall into one of the following cases
.. /wiki/
.. /site/
.. /xcmd/
.. #
.. anything else -> assume to be really a file:// url; EX: file://C/dir/fil.txt -> C/dir/fil.txt
. the other advantage of this approach is that this proc can be reused outside of swt calls; i.e.: it can parse both "file:///wiki/A" and "/wiki/A"
*/

View File

@@ -0,0 +1,68 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.hrefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*;
import gplx.core.primitives.*; import gplx.xowa.html.hrefs.*; import gplx.xowa.gui.views.*;
public class Xoh_href_gui_utl_tst {
@Before public void init() {fxt.Clear();} private Xoh_href_gui_utl_fxt fxt = new Xoh_href_gui_utl_fxt();
@Test public void Extract_href__text() {
fxt.Test_extract_href("0|" , "");
fxt.Test_extract_href("1|selected_text" , "selected_text");
fxt.Test_extract_href("2|http://a.org" , "http://a.org");
}
@Test public void Extract_href__file() {
fxt.Test_extract_href("2|file:///site/en.wiktionary.org/wiki/Page_1" , "en.wiktionary.org/wiki/Page_1");
fxt.Test_extract_href("2|file:///wiki/Page_2" , "en.wikipedia.org/wiki/Page_2");
fxt.Test_extract_href("2|file://#anchor" , "en.wikipedia.org/wiki/Page_0#anchor");
}
@Test public void Extract_href__internal() {
fxt.Test_extract_href("2|/site/en.wiktionary.org/wiki/Page_1" , "en.wiktionary.org/wiki/Page_1");
fxt.Test_extract_href("2|/wiki/Page_2" , "en.wikipedia.org/wiki/Page_2");
fxt.Test_extract_href("2|#anchor" , "en.wikipedia.org/wiki/Page_0#anchor");
}
@Test public void Html_window_vpos_parse() {
fxt.Test_Html_window_vpos_parse("0|0,1,2", "0", "'0','1','2'");
fxt.Test_Html_window_vpos_parse("org.eclipse.swt.SWTException: Permission denied for <file://> to get property Selection.rangeCount", null, null); // check that invalid path doesn't fail; DATE:2014-04-05
}
@Test public void Standardize_xowa_link() {
fxt.Test_standardize_xowa_link("file:///site/en.wikipedia.org/wiki/A" , "/site/en.wikipedia.org/wiki/A");
fxt.Test_standardize_xowa_link("file:///wiki/A" , "/wiki/A");
fxt.Test_standardize_xowa_link("file://#A" , "#A");
}
}
class Xoh_href_gui_utl_fxt {
public void Clear() {
cur_wiki = "en.wikipedia.org";
cur_page = "Page_0";
}
public String Cur_wiki() {return cur_wiki;} public Xoh_href_gui_utl_fxt Cur_wiki_(String v) {cur_wiki = v; return this;} private String cur_wiki;
public String Cur_page() {return cur_page;} public Xoh_href_gui_utl_fxt Cur_page_(String v) {cur_page = v; return this;} private String cur_page;
public void Test_extract_href(String text_str, String expd) {
Tfds.Eq(expd, Xoh_href_gui_utl.Html_extract_text(cur_wiki, cur_page, text_str));
}
private String_obj_ref scroll_top = String_obj_ref.null_(), node_path = String_obj_ref.null_();
public void Test_Html_window_vpos_parse(String raw, String expd_scroll_top, String expd_node_path) {
scroll_top.Val_null_(); node_path.Val_null_();
Xog_html_itm.Html_window_vpos_parse(raw, scroll_top, node_path);
Tfds.Eq(expd_scroll_top, scroll_top.Val(), expd_scroll_top);
Tfds.Eq(expd_node_path, node_path.Val(), expd_node_path);
}
public void Test_standardize_xowa_link(String raw, String expd) {
Tfds.Eq_str(expd, Xoh_href_gui_utl.Standardize_xowa_link(raw), "standardize");
}
}

View File

@@ -16,228 +16,64 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.hrefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.btries.*; import gplx.xowa.wikis.xwikis.*; import gplx.xowa.net.*; import gplx.xowa.parsers.lnkes.*;
import gplx.xowa.wikis.*;
import gplx.core.primitives.*; import gplx.core.btries.*; import gplx.core.net.*;
import gplx.xowa.langs.vnts.*;
public class Xoh_href_parser {
private Gfo_url_parser url_parser; private Gfo_url tmp_url = new Gfo_url();
private Btrie_slim_mgr segs = Btrie_slim_mgr.ci_ascii_(); // NOTE:ci.ascii:XO_const.en; /wiki/, /site/ etc.
private Bry_bfr bfr_encoder = Bry_bfr.reset_(255), tmp_bfr = Bry_bfr.reset_(255);
public Xoh_href_parser(Url_encoder encoder, Gfo_url_parser url_parser) {
this.encoder = encoder;
this.url_parser = url_parser;
url_parser.Init_protocol(Protocol_xowa_tid, Xop_lnke_wkr.Str_xowa_protocol);
segs.Add_stubs(Seg__ary);
}
public Url_encoder Encoder() {return encoder;} private Url_encoder encoder;
public void Parse(Xoh_href rv, String raw, Xowe_wiki wiki, byte[] cur_page) {Parse(rv, Bry_.new_u8(raw), wiki, cur_page);}
public void Parse(Xoh_href rv, byte[] raw, Xowe_wiki wiki, byte[] cur_page) {
int bgn = 0, raw_len = raw.length; int file_slash_end = 0;
url_parser.Parse(tmp_url, raw, 0, raw_len); // parse as regular tmp_url to get protocol
rv.Init(raw, tmp_url.Protocol_tid());
switch (tmp_url.Protocol_tid()) {
default: // tmp_url is known protocol ("http:", "ftp:", etc); use it and exit; do not do any substitutions EX: http://en.wikipedia.org
rv.Tid_(Xoh_href.Tid_http);
return;
case Xoo_protocol_itm.Tid_null: // unknown protocol ("unknown:A")or protocol-less ("A"); could be wiki-title or file-name; fall through to below
public void Parse_as_url(Xoa_url rv, byte[] raw, Xowe_wiki wiki, byte[] cur_page) {
int bgn = 0;
Object seg_obj = btrie.Match_bgn(raw, bgn, raw.length); // match /wiki/ or /site/ or /xcmd/
if (seg_obj == null) {
Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr();
if (vnt_mgr.Enabled() && raw[0] == Byte_ascii.Slash) {
int slash_end = Bry_finder.Find_fwd(raw, Byte_ascii.Slash, 1);
if (vnt_mgr.Vnt_grp().Has(Bry_.Mid(raw, 1, slash_end))) {
raw = Bry_.Add(wiki.Domain_bry(), raw);
}
}
}
else { // something matched
switch (((Byte_obj_val)seg_obj).Val()) {
case Seg_xcmd_tid: // convert "/xcmd/a" to "xowa-cmd:a"
raw = Bry_.Add(Gfo_protocol_itm.Bry_xcmd, Bry_.Mid(raw, btrie.Match_pos()));
bgn = 0;
break;
case Seg_wiki_tid: // skip "/wiki/" or "/site/"
case Seg_site_tid:
bgn = btrie.Match_pos();
break;
default:
break;
}
}
wiki.Utl__url_parser().Parse(rv, raw, bgn, raw.length);
switch (rv.Tid()) {
case Xoa_url_.Tid_anch:
rv.Wiki_bry_(wiki.Domain_bry());
rv.Page_bry_(cur_page);
break;
case Xoo_protocol_itm.Tid_file: // tmp_url is "file:"; remove it; NOTE: swt/mozilla automatically prepends "file://" to any protocol-less links; see NOTE_1 below
int file_proto_len = tmp_url.Protocol_bry().length;
bgn = file_slash_end = Bry_.While_fwd(raw, Byte_ascii.Slash, file_proto_len, raw_len);
if (file_slash_end - file_proto_len > 0) --bgn; // if at least 1 slash, include slash; this ensures that all strings which have "file://" stripped will start with a "/"; EX: file:///wiki -> "/wiki"; file://C -> "/C"
case Xoa_url_.Tid_page:
Xow_wiki ttl_wiki = wiki.App().Wiki_mgri().Get_by_key_or_make_init_n(rv.Wiki_bry());
byte[] tmp_page = rv.Page_bry();
if (rv.Page_is_main())
tmp_page = ttl_wiki.Props().Main_page();
else {
if (tmp_page != null) {
if (ttl_wiki != null) {
Xoa_ttl ttl = ttl_wiki.Ttl_parse(tmp_page);
if (ttl == null) // invalid ttl; null out page;
tmp_page = Bry_.Empty;
else
tmp_page = ttl.Full_txt();
}
}
}
rv.Page_bry_(tmp_page);
break;
case Xoo_protocol_itm.Tid_xowa:
bgn = file_slash_end = Bry_.While_fwd(raw, Byte_ascii.Slash, tmp_url.Protocol_bry().length, raw_len);
rv.Tid_(Xoh_href.Tid_xowa);
rv.Wiki_(wiki.Domain_bry()); // wiki is always the current wiki
byte[] page = Xoa_app_.Utl__encoder_mgr().Gfs().Decode(Bry_.Mid(raw, bgn, raw_len));
rv.Page_(page); // page is everything after "/xcmd/"; individual cmds will do further parsing; note that it should be decoded; EX: %20 -> " "; also note that anchor (#) or query params (?) are not parsed; the entire String will be reparsed later
return;
}
if (file_slash_end < raw_len && raw[file_slash_end] == Byte_ascii.Hash) { // 1st character is anchor; extract and return
rv.Tid_(Xoh_href.Tid_anchor);
rv.Wiki_(wiki.Domain_bry()); // wiki is always current
rv.Page_(cur_page); // page is always current
rv.Anchor_(Bry_.Mid(raw, file_slash_end + 1, raw_len)); // +1 to skip #; i.e. Anchor should be "A" not "#A"
return;
}
Object seg_obj = segs.Match_bgn(raw, bgn, raw_len); // match /wiki/ or /site/ or /xcmd/
if (seg_obj == null) // nothing matched; assume file; EX: file:///C/dir/fil.txt -> /C/dir/fil.txt
rv.Tid_(Xoh_href.Tid_file);
else { // something matched;
Btrie_itm_stub seg = (Btrie_itm_stub)seg_obj;
bgn += seg.Val().length;
switch (seg.Tid()) {
case Seg_wiki_tid: Parse_wiki(rv, encoder, wiki, raw, bgn, raw_len); break;
case Seg_site_tid: Parse_site(rv, encoder, wiki, raw, bgn, raw_len); break;
case Seg_xcmd_tid: Parse_xcmd(rv, encoder, wiki, raw, bgn, raw_len); break;
}
}
}
public byte[] Build_to_bry(Xow_wiki wiki, Xoa_ttl ttl) {
synchronized (tmp_bfr) {
Build_to_bfr(tmp_bfr, wiki.App(), wiki.Domain_bry(), ttl, Bool_.N);
return tmp_bfr.Xto_bry_and_clear();
}
}
public void Build_to_bfr(Bry_bfr bfr, Xoa_app app, byte[] domain_bry, Xoa_ttl ttl) {Build_to_bfr(bfr, app, domain_bry, ttl, Bool_.N);}
public void Build_to_bfr(Bry_bfr bfr, Xoa_app app, byte[] domain_bry, Xoa_ttl ttl, boolean force_site) {
byte[] page = ttl.Full_txt_raw();
Xow_xwiki_itm xwiki = ttl.Wik_itm();
if (xwiki == null) // not an xwiki; EX: [[wikt:Word]]
Build_to_bfr_page(ttl, page, 0); // write page only; NOTE: changed to remove leaf logic DATE:2014-09-07
else { // xwiki; skip wiki and encode page only;
byte[] wik_txt = ttl.Wik_txt();
Build_to_bfr_page(ttl, page, wik_txt.length + 1);
}
if (xwiki == null) { // not an xwiki
if (ttl.Anch_bgn() != 1) { // not an anchor-only; EX: "#A"
if (force_site) { // popup parser always writes as "/site/"
bfr.Add(Href_site_bry); // add "/site/"; EX: /site/
bfr.Add(domain_bry); // add xwiki; EX: en_dict
bfr.Add(Href_wiki_bry); // add "/wiki/"; EX: /wiki/
}
else
bfr.Add(Href_wiki_bry); // add "/wiki/"; EX: /wiki/Page
}
else {} // anchor: noop
}
else { // xwiki
if (app.Xwiki_mgr__missing(xwiki.Domain_bry())) { // xwiki is not offline; use http:
Bry_fmtr url_fmtr = xwiki.Url_fmtr();
if (url_fmtr == null) {
bfr.Add(Href_https_bry); // add "https://"; EX: https://
bfr.Add(xwiki.Domain_bry()); // add xwiki; EX: en_dict
bfr.Add(Href_wiki_bry); // add "/wiki/"; EX: /wiki/
}
else { // url_fmtr exists; DATE:2015-04-22
url_fmtr.Bld_bfr(bfr, bfr_encoder.Xto_bry_and_clear()); // use it and pass bfr_encoder for page_name;
return;
}
}
else { // xwiki is avaiable; use /site/
bfr.Add(Href_site_bry); // add "/site/"; EX: /site/
bfr.Add(xwiki.Domain_bry()); // add xwiki; EX: en_dict
bfr.Add(Href_wiki_bry); // add "/wiki/"; EX: /wiki/
}
}
bfr.Add_bfr_and_clear(bfr_encoder);
}
private void Build_to_bfr_page(Xoa_ttl ttl, byte[] ttl_full, int page_bgn) {
int anch_bgn = Bry_finder.Find_fwd(ttl_full, Byte_ascii.Hash); // NOTE: cannot use Anch_bgn b/c Anch_bgn has bug with whitespace
if (anch_bgn == Bry_.NotFound) // no anchor; just add page
encoder.Encode(bfr_encoder, ttl_full, page_bgn, ttl_full.length);
else { // anchor exists; check if anchor is preceded by ws; EX: [[A #b]] -> "/wiki/A#b"
int page_end = Bry_finder.Find_bwd_last_ws(ttl_full, anch_bgn); // first 1st ws before #; handles multiple ws
page_end = page_end == Bry_.NotFound ? anch_bgn : page_end; // if ws not found, use # pos; else use 1st ws pos
encoder.Encode(bfr_encoder, ttl_full, page_bgn, page_end); // add page
encoder.Encode(bfr_encoder, ttl_full, anch_bgn, ttl_full.length); // add anchor
}
}
public static final String Href_file_str = "file:///", Href_wiki_str = "/wiki/", Href_site_str = "/site/", Href_xcmd_str = "/xcmd/";
public static final byte[]
Href_https_bry = Bry_.new_a7("https://") // NOTE: must be "https:" or wmf api won't work; DATE:2015-06-17
, Href_file_bry = Bry_.new_a7(Href_file_str), Href_site_bry = Bry_.new_a7(Href_site_str), Href_wiki_bry = Bry_.new_a7(Href_wiki_str);
private static final int Href_wiki_len = Href_wiki_bry.length;
static final byte Seg_null_tid = 0, Seg_wiki_tid = 1, Seg_site_tid = 2, Seg_xcmd_tid = 3;
private static final byte[] Seg_null_bry = Bry_.new_a7("/null/"), Seg_wiki_bry = Bry_.new_a7(Href_wiki_str), Seg_site_bry = Bry_.new_a7(Href_site_str), Seg_xcmd_bry = Bry_.new_a7(Href_xcmd_str);
private static final byte[][] Seg__ary = new byte[][] {Seg_null_bry, Seg_wiki_bry, Seg_site_bry, Seg_xcmd_bry};
private static void Parse_wiki(Xoh_href rv, Url_encoder encoder, Xowe_wiki wiki, byte[] raw, int bgn, int len) {
byte[] ttl_raw = Bry_.Mid(raw, bgn, len);
Xoa_ttl ttl = wiki.Ttl_parse(ttl_raw);
if (ttl == null) {
Xoa_app_.Usr_dlg().Warn_many("xowa.href.parser", "invalid_wiki", "wiki href does not have valid title: ~{0}", String_.new_u8(raw, bgn, len));
return;
}
if (ttl.Wik_itm() == null) { // standard href; EX: "/wiki/A"
rv.Tid_(Xoh_href.Tid_wiki);
rv.Wiki_(wiki.Domain_bry()); // wiki is always the current wiki
}
else { // embedded xwiki prefix; EX: "/wiki/fr:A"
rv.Tid_(Xoh_href.Tid_site);
rv.Wiki_(ttl.Wik_itm().Domain_bry()); // wiki is the xwiki prefix; EX: "en.wikpedia.org//wiki/fr:A" -> "fr.wikpedia.org/wiki/A"
}
byte[] page_bry = encoder.Decode(ttl.Full_txt()); // note that Full is everything except for ns, so it handles "fr:A" ("fr:" being treated as ns, so only "A" will be Full_txt)
if (Bry_.Len_eq_0(page_bry)) // handle xwiki hrefs like "fr:"; EX: "/wiki/wikipedia:" on en.wikisource.org/Main Page
page_bry = Xoa_page_.Main_page_bry_empty;
// if (ttl.Qarg_bgn() != Bry_.NotFound)
// rv.Qarg_(ttl.Qarg_txt());
rv.Page_(page_bry); // add page; note that it should be decoded; EX: %20 -> " "; also note that anchor (#) or query params (?) are not parsed; the entire String will be reparsed later
if (ttl.Anch_bgn() != Bry_.NotFound) rv.Anchor_(ttl.Anch_txt());
}
private static void Parse_site(Xoh_href rv, Url_encoder encoder, Xowe_wiki wiki, byte[] raw, int bgn, int len) { // /site/; EX: /site/fr.wikipedia.org/wiki/A
int slash = Bry_finder.Find_fwd(raw, Byte_ascii.Slash, bgn, len); if (slash == Bry_.NotFound) throw Err_.new_wo_type("site href is missing slash", "snip", String_.new_u8(raw, bgn, len));
rv.Tid_(Xoh_href.Tid_site);
byte[] wiki_bry = Bry_.Mid(raw, bgn, slash); // wiki is text between "/site/" and next "/"
Xow_xwiki_itm xwiki = wiki.Appe().Usere().Wiki().Xwiki_mgr().Get_by_key(wiki_bry); // NOTE: site may refer to alias in user_wiki; ex: /site/wikisource.org which points to en.wikisource.org; this occurs during lnke substitution; EX: [//wikisource.org Wikisource]
if (xwiki != null) {
wiki_bry = xwiki.Domain_bry();
wiki = wiki.Appe().Wiki_mgr().Get_by_key_or_make(wiki_bry); // NOTE: xwiki links should use case_match of xwiki (en.wiktionary.org) not cur_wiki (en.wikipedia.org); EX:w:alphabet
}
rv.Wiki_(wiki_bry);
int page_pos = slash + Href_wiki_len;
byte[] page_bry = page_pos < len
? Bry_.Mid(raw, page_pos, len) // page is text after next "/" + "/wiki/";
: Bry_.Empty;
if (Bry_.Len_eq_0(page_bry)) // handle "/site/fr.wikipedia.org/wiki/"; note that these are generated by [[fr:]]
page_bry = wiki.Props().Main_page(); // default to Main Page
// int qarg_pos = Bry_finder.Find_bwd(page_bry, Byte_ascii.Question);
// byte[] qarg_bry = null;
// if (qarg_pos != Bry_.NotFound) {
// qarg_bry = Bry_.Mid(page_bry, qarg_pos + 1, page_bry.length);
// rv.Qarg_(qarg_bry);
// page_bry = Bry_.Mid(page_bry, 0, qarg_pos);
// }
Parse_ttl_and_resolve_xwiki(rv, wiki, encoder, page_bry, raw, bgn, len);
}
private static void Parse_ttl_and_resolve_xwiki(Xoh_href rv, Xowe_wiki wiki, Url_encoder encoder, byte[] page_bry, byte[] raw, int bgn, int len) {
Xoa_ttl ttl = wiki.Ttl_parse(page_bry);
if (ttl == null) {
Xoa_app_.Usr_dlg().Warn_many("xowa.href.parser", "invalid_wiki", "wiki href does not have valid title: ~{0}", String_.new_u8(raw, bgn, len));
rv.Page_(Bry_.Empty);
return;
}
if (ttl.Wik_itm() != null) { // page_bry has xwiki; EX: "wikt:A"; note that since this is called by "/site/", there may be two xwikis; EX: "w:wikt:"; Note that more than 2 is not being handled
wiki = wiki.Appe().Wiki_mgr().Get_by_key_or_make(ttl.Wik_itm().Domain_bry());
rv.Wiki_(wiki.Domain_bry());
if (Bry_.Len_eq_0(ttl.Page_txt())) // page_bry is just alias; EX: "wikt:"
page_bry = wiki.Props().Main_page();
else
page_bry = ttl.Page_txt();
ttl = Xoa_ttl.parse_(wiki, page_bry); if (ttl == null) throw Err_.new_wo_type("wiki href does not have valid title", "ttl", String_.new_u8(raw, bgn, len));
}
rv.Page_(encoder.Decode(ttl.Full_txt())); // add page; note that it should be decoded; EX: %20 -> " "; also note that anchor (#) or query params (?) are not parsed; the entire String will be reparsed later
if (ttl.Anch_bgn() != Bry_.NotFound) // add anchor if it exists
rv.Anchor_(ttl.Anch_txt());
}
private static void Parse_xcmd(Xoh_href rv, Url_encoder encoder, Xowe_wiki wiki, byte[] raw, int bgn, int len) { // /xcmd/; note encoder is passed, but don't decode for now; most invk commands have an _ which will get changed to a " ";
rv.Tid_(Xoh_href.Tid_xcmd);
rv.Wiki_(wiki.Domain_bry()); // wiki is always the current wiki
rv.Page_(Bry_.Mid(raw, bgn, len)); // page is everything after "/xcmd/"; individual cmds will do further parsing; note that it should be decoded; EX: %20 -> " "; also note that anchor (#) or query params (?) are not parsed; the entire String will be reparsed later
}
private static final byte Protocol_xowa_tid = Xoo_protocol_itm.Tid_xowa;
private static final byte Seg_wiki_tid = 0, Seg_site_tid = 1, Seg_xcmd_tid = 2;
private static final Btrie_slim_mgr btrie = Btrie_slim_mgr.ci_a7() // NOTE:ci.ascii:XO_const.en; /wiki/, /site/ etc.
.Add_bry_tid(Xoh_href_.Bry__wiki, Seg_wiki_tid)
.Add_bry_tid(Xoh_href_.Bry__site, Seg_site_tid)
.Add_bry_tid(Xoh_href_.Bry__xcmd, Seg_xcmd_tid);
}
/*
NOTE_1:
. swt/mozilla treats text differently in href="{text}" when content_editable=n; occurs in LocationListener.changing
http://a.org -> http://a.org does nothing
A -> file:///A adds "file:///"
/wiki/A -> file:///wiki/A adds "file://"
Category:A -> Category:A noops; Category is assumed to be protocol?
//en.wiktionary.org/wiki/a -> file:///wiki/a strips out site name and prepends "file://"; no idea why
. so, to handle the above, the code does the following
http://a.org -> http://a.org does nothing; nothing needed
A -> /wiki/A always prepend /wiki/
Category:A -> /wiki/Category:A always prepend /wiki/
//en.wiktionary.org/wiki/A -> /site/en.wiktionary.org/wiki/A always transform relative url to /site/
. the href will still come here as file:///wiki/A or file:///site/en.wiktionary.org/wiki/A.
. however, the file:// can be lopped off and discarded and the rest of the href will fall into one of the following cases
.. /wiki/
.. /site/
.. /xcmd/
.. #
.. anything else -> assume to be really a file:// url; EX: file://C/dir/fil.txt -> C/dir/fil.txt
. the other advantage of this approach is that this proc can be reused outside of swt calls; i.e.: it can parse both "file:///wiki/A" and "/wiki/A"
*/

View File

@@ -16,234 +16,103 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.hrefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*;
import gplx.xowa.net.*;
public class Xoh_href_parser_tst {
@Before public void init() {fxt.Clear();} private Xoh_href_parser_fxt fxt = new Xoh_href_parser_fxt();
@Test public void Parse_full_wiki() {
fxt .Prep_raw_("file:///wiki/A")
.Expd_tid_(Xoh_href.Tid_wiki)
.Expd_full_("en.wikipedia.org/wiki/A")
.Expd_wiki_("en.wikipedia.org")
.Expd_page_("A")
.Test_parse();
import org.junit.*; import gplx.xowa.urls.*;
public class Xoh_href_parser_tst {
private final Xoh_href_parser_fxt fxt = new Xoh_href_parser_fxt();
@Test public void Wiki__basic() {
fxt.Run_parse_by_href("/wiki/A").Chk_tid(Xoa_url_.Tid_page).Chk_to_str("en.wikipedia.org/wiki/A").Chk_wiki("en.wikipedia.org").Chk_page("A");
}
@Test public void Parse_full_http() {
fxt .Prep_raw_("http://a.org/b")
.Expd_tid_(Xoh_href.Tid_http)
.Expd_full_("http://a.org/b")
.Test_parse();
@Test public void Wiki__page__w_question() {
fxt.Run_parse_by_href("/wiki/%3F").Chk_page("?");
}
@Test public void Parse_full_file() {
fxt .Prep_raw_("file:///C/xowa/file/a.png")
.Expd_tid_(Xoh_href.Tid_file)
.Expd_full_("file:///C/xowa/file/a.png")
.Test_parse();
@Test public void Wiki__qarg() {
fxt.Run_parse_by_href("/wiki/A?action=edit").Chk_page("A").Chk_qargs("?action=edit").Chk_to_str("en.wikipedia.org/wiki/A?action=edit");
}
@Test public void Parse_full_anchor_only() {
fxt .Prep_raw_("#a")
.Expd_tid_(Xoh_href.Tid_anchor)
.Expd_full_("en.wikipedia.org/wiki/Page 1#a")
.Expd_anch_("a")
.Test_parse();
@Test public void Wiki__qarg__w_question() {
fxt.Run_parse_by_href("/wiki/A%3F?action=edit").Chk_page("A?").Chk_qargs("?action=edit");
}
@Test public void Parse_full_anchor_w_page() {
fxt .Prep_raw_("file:///wiki/A#b")
.Expd_tid_(Xoh_href.Tid_wiki)
.Expd_full_("en.wikipedia.org/wiki/A#b")
.Expd_anch_("b")
.Test_parse();
@Test public void Wiki__anchor() {
fxt.Run_parse_by_href("/wiki/A#b").Chk_to_str("en.wikipedia.org/wiki/A#b").Chk_anch("b");
}
@Test public void Parse_full_xwiki() {
fxt .Prep_raw_("file:///site/en.wikt.org/wiki/Page")
.Expd_tid_(Xoh_href.Tid_site)
.Expd_full_("en.wikt.org/wiki/Page")
.Expd_page_("Page")
.Test_parse();
@Test public void Wiki__xwiki__only() {
fxt.Prep_add_xwiki_to_wiki("wikt", "en.wiktionary.org");
fxt.Run_parse_by_href("/wiki/wikt:").Chk_page_is_main_y().Chk_page("Main_Page").Chk_to_str("en.wiktionary.org/wiki/Main_Page");
}
@Test public void Parse_full_xwiki_domain_only() {
fxt .Prep_raw_("/wiki/wikt:")
.Init_xwiki_alias("wikt", "en.wiktionary.org")
.Expd_full_("en.wiktionary.org/wiki/")
.Expd_page_("")
.Test_parse();
@Test public void Wiki__encoded() {
fxt.Run_parse_by_href("/wiki/A%22b%22c").Chk_page("A\"b\"c");
}
@Test public void Parse_full_wiki_page() {
fxt .Prep_raw_("/wiki/A")
.Expd_tid_(Xoh_href.Tid_wiki)
.Expd_full_("en.wikipedia.org/wiki/A")
.Expd_page_("A")
.Test_parse();
@Test public void Site__basic() {
fxt.Run_parse_by_href("/site/en.wikipedia.org/wiki/A").Chk_tid(Xoa_url_.Tid_page).Chk_to_str("en.wikipedia.org/wiki/A").Chk_page("A");
}
@Test public void Parse_empty_is_main_page() { // PURPOSE: w/ slash; "wiki/"
fxt .Prep_raw_("/site/en.wikipedia.org/wiki/")
.Expd_tid_(Xoh_href.Tid_site)
.Expd_full_("en.wikipedia.org/wiki/Main Page")
.Expd_page_("Main Page")
.Test_parse();
@Test public void Site__ns_case() {
fxt.Run_parse_by_href("/site/en.wikipedia.org/wiki/file:A").Chk_page("File:A");
}
@Test public void Parse_empty_is_main_page_2() { // PURPOSE: wo slash; "wiki"
fxt .Prep_raw_("/site/en.wikipedia.org/wiki")
.Expd_tid_(Xoh_href.Tid_site)
.Expd_full_("en.wikipedia.org/wiki/Main Page")
.Expd_page_("Main Page")
.Test_parse();
@Test public void Site__main_page() {
fxt.Run_parse_by_href("/site/en.wikipedia.org/wiki/").Chk_page("Main_Page").Chk_page_is_main_y();
}
@Test public void Parse_site_page() {
fxt .Prep_raw_("/site/en.wikt.org/wiki/A")
.Expd_tid_(Xoh_href.Tid_site)
.Expd_full_("en.wikt.org/wiki/A")
.Expd_page_("A")
.Test_parse();
@Test public void Site__anch() {
fxt.Run_parse_by_href("/site/en.wikipedia.org/wiki/A#b_c").Chk_page("A").Chk_anch("b_c");
}
@Test public void Parse_site_ns_case() {
fxt .Prep_raw_("/site/en.wikt.org/wiki/file:A")
.Expd_tid_(Xoh_href.Tid_site)
.Expd_full_("en.wikt.org/wiki/File:A")
.Expd_page_("File:A")
.Test_parse();
@Test public void Site__qarg() {
fxt.Run_parse_by_href("/site/en.wikipedia.org/wiki/A?action=edit").Chk_page("A").Chk_qargs("?action=edit");
}
@Test public void Parse_site_page__invalid_ttl_shouldnt_fail() { // PURPOSE: invalid title shouldn't fail; EX: A{{B}} is invalid (b/c of braces);
fxt .Prep_raw_("/site/en.wikt.org/wiki/A{{B}}")
.Expd_tid_(Xoh_href.Tid_site)
.Expd_full_("en.wikt.org/wiki/")
.Expd_page_("")
.Test_parse();
@Test public void Site__invalid_ttl_shouldnt_fail() { // PURPOSE: invalid title shouldn't fail; EX: A{{B}} is invalid (b/c of braces);
fxt.Run_parse_by_href("/site/en.wikipedia.org/wiki/A{{B}}").Chk_page("");
}
@Test public void Parse_xcmd_edit() {
fxt .Prep_raw_("/xcmd/page_edit")
.Expd_tid_(Xoh_href.Tid_xcmd)
.Expd_full_("")
.Expd_page_("page_edit")
.Test_parse();
}
@Test public void Parse_xowa() {
fxt .Prep_raw_("xowa-cmd:a%22b*c")
.Expd_tid_(Xoh_href.Tid_xowa)
.Expd_full_("a\"b*c")
.Expd_page_("a\"b*c")
.Test_parse();
}
@Test public void Parse_edit_wiki_quote() {
fxt .Prep_raw_("/wiki/A%22b%22c")
.Expd_tid_(Xoh_href.Tid_wiki)
.Expd_full_("en.wikipedia.org/wiki/A\"b\"c")
.Expd_page_("A\"b\"c")
.Test_parse();
}
@Test public void Hover_string_wiki() {fxt.Init_hover_full_n_().Test_hover_string("file:///wiki/A" , "A");}
@Test public void Hover_string_http() {fxt.Init_hover_full_n_().Test_hover_string("http://a.org/b" , "http://a.org/b");}
@Test public void Hover_string_file() {fxt.Init_hover_full_n_().Test_hover_string("file:///C/xowa/file/a.png" , "file:///C/xowa/file/a.png");}
@Test public void Hover_string_anchor() {fxt.Init_hover_full_n_().Test_hover_string("#a" , "#a");}
@Test public void Hover_string_anchor_file() {fxt.Init_hover_full_n_().Test_hover_string("file:///#a" , "#a");}
@Test public void Hover_string_xwiki() {fxt.Init_hover_full_n_().Test_hover_string("file:///site/en.wikt.org/wiki/Page" , "en.wikt.org/Page");}
@Test public void Hover_string_xwiki_2() {fxt.Init_hover_full_n_().Expd_page_("a").Test_hover_string("/wiki/wikt:a" , "en.wiktionary.org/a");}
@Test public void Hover_string_error() {fxt.Init_hover_full_n_().Test_hover_string("file:///wiki/{{{extlink}}}" , "");} // {{{extlink}}} not a valid title; return empty
// @Test public void Parse_site_qarg() {fxt.Prep_raw_("/site/en.wikt.org/wiki/A?action=edit").Expd_tid_(Xoh_href.Tid_site).Expd_full_("en.wikt.org/wiki/A").Expd_page_("A").Expd_qarg_("action=edit").Test_parse();}
// @Test public void Parse_wiki_qarg() {fxt.Prep_raw_("/wiki/A?action=edit").Expd_tid_(Xoh_href.Tid_wiki).Expd_full_("en.wikipedia.org/wiki/A").Expd_page_("A").Expd_qarg_("action=edit").Test_parse();}
//@Test public void Parse_site_anchor() {fxt.Prep_raw_("/site/en.wikt.org/wiki/A#b_c" ).Expd_tid_(Xoh_href.Tid_site).Expd_full_("en.wikt.org/wiki/A#b_c").Expd_page_("A").Expd_anch_("b_c").Test_parse();}
@Test public void Build_xwiki_enc() {fxt.Test_build("wikt:abc?d" , "/site/en.wiktionary.org/wiki/abc%3Fd");}
@Test public void Build_page_quote() {fxt.Test_build("a\"b\"c" , "/wiki/A%22b%22c");}
@Test public void Build_page() {fxt.Test_build("abc" , "/wiki/Abc");}
@Test public void Build_page_ns() {fxt.Test_build("Image:A.png" , "/wiki/Image:A.png");}
@Test public void Build_anchor() {fxt.Test_build("#abc" , "#abc");}
@Test public void Build_page_anchor() {fxt.Test_build("Abc#def" , "/wiki/Abc#def");}
@Test public void Build_xwiki() {fxt.Test_build("wikt:abc" , "/site/en.wiktionary.org/wiki/abc");} // NOTE: "abc" not capitalized, b/c other wiki's case sensitivity is not known; this emulates WP's behavior
@Test public void Build_xwiki_2() {fxt.Test_build("wikt:Special:Search/a" , "/site/en.wiktionary.org/wiki/Special:Search/a");}
@Test public void Build_category() {fxt.Test_build("Category:abc" , "/wiki/Category:Abc");}
@Test public void Parse_site_user_wiki() {// PURPOSE: outlier for wikisource.org which is alias to en.wikisource.org; alias added in user_wiki; EX: [//wikisource.org a]; in browser, automatically goes to http://wikisource.org; in xowa, should go to /site/en.wikisource.org
fxt .Prep_raw_("/site/en_wiki_alias/wiki/")
.Init_xwiki_alias("en_wiki_alias", "en.wikipedia.org")
.Expd_tid_(Xoh_href.Tid_site)
.Expd_full_("en.wikipedia.org/wiki/Main Page")
.Expd_page_("Main Page")
.Test_parse();
}
@Test public void Parse_xwiki_cases_correctly() { // PURPOSE: xwiki links should use case_match of xwiki (en.wiktionary.org) not cur_wiki (en.wikipedia.org); EX:w:Alphabet
fxt .Prep_raw_("/site/en.wiktionary.org/wiki/alphabet")
.Init_xwiki_alias("en.wiktionary.org", "en.wiktionary.org");
Xowe_wiki en_wiktionary_org = fxt.App().Wiki_mgr().Get_by_key_or_make(Bry_.new_a7("en.wiktionary.org"));
@Test public void Site__xwiki_cases_correctly() { // PURPOSE: xwiki links should use case_match of xwiki (en.wiktionary.org) not cur_wiki (en.wikipedia.org); EX:w:Alphabet
Xowe_wiki en_wiktionary_org = fxt.Prep_create_wiki("en.wiktionary.org");
en_wiktionary_org.Ns_mgr().Ns_main().Case_match_(Xow_ns_case_.Id_all);
fxt .Expd_tid_(Xoh_href.Tid_site)
.Expd_full_("en.wiktionary.org/wiki/alphabet")
.Expd_page_("alphabet")
.Test_parse();
fxt.Prep_add_xwiki_to_user("en.wiktionary.org", "en.wiktionary.org");
fxt.Run_parse_by_href("/site/en.wiktionary.org/wiki/alphabet");
fxt.Chk_to_str("en.wiktionary.org/wiki/alphabet").Chk_page("alphabet");
}
@Test public void Parse_xwiki_compound() { // PURPOSE: [[[w:wikt:]] not handled; DATE:2013-07-25
fxt .Prep_raw_("/site/en.wikipedia.org/wiki/wikt:")
.Init_xwiki_alias("wikt:", "en.wiktionary.org")
.Expd_tid_(Xoh_href.Tid_site)
.Expd_full_("en.wiktionary.org/wiki/Main Page")
.Expd_page_("Main Page")
.Test_parse();
@Test public void Site__xwiki_compound() { // PURPOSE: [[[w:wikt:]] not handled; DATE:2013-07-25
fxt.Prep_add_xwiki_to_wiki("wikt", "en.wiktionary.org");
fxt.Run_parse_by_href("/site/en.wikipedia.org/wiki/wikt:")
.Chk_tid(Xoa_url_.Tid_page)
.Chk_page("Main_Page")
.Chk_to_str("en.wiktionary.org/wiki/Main_Page")
;
}
@Test public void Parse_protocol() { // PURPOSE: check that urls with form of "ftp://" return back Tid_ftp; DATE:2014-04-25
fxt .Test_parse_protocol("ftp://a.org", Xoo_protocol_itm.Tid_ftp);
// @Test public void Vnt() {
// Xowe_wiki wiki = fxt.Wiki();
// fxt.Prep_add_xwiki_to_user("zh.wikipedia.org");
// wiki.Lang().Vnt_mgr().Enabled_(true);
// wiki.Lang().Vnt_mgr().Vnt_grp().Add(new gplx.xowa.langs.vnts.Vnt_mnu_itm(Bry_.new_a7("zh-hans"), Bry_.new_a7("zh-hant")));
// fxt.Run_parse_by_href("/site/zh.wikipedia.org/zh-hant/A").Chk_page("A").Chk_vnt("zh-hant");
// }
@Test public void Http__basic() {
fxt.Run_parse_by_href("http://a.org/b").Chk_tid(Xoa_url_.Tid_inet);
}
@Test public void Build_xwiki_wikimedia_mail() { // PURPOSE: DATE:2015-04-22
fxt .Init_xwiki_by_many("mail|https://lists.wikimedia.org/mailman/listinfo/$1|Wikitech Mailing List");
fxt.Test_build("mail:A" , "https://lists.wikimedia.org/mailman/listinfo/A");
@Test public void Prot__ftp() { // PURPOSE: check that urls with form of "ftp://" return back Tid_ftp; DATE:2014-04-25
fxt.Run_parse_by_href("ftp://a.org").Chk_tid(Xoa_url_.Tid_inet);
}
// @Test public void Parse_question_ttl() {fxt.Prep_raw_("/wiki/%3F").Expd_tid_(Xoh_href.Tid_wiki).Expd_full_("en.wikipedia.org/wiki/?").Expd_page_("?").Test_parse();}
// @Test public void Parse_question_w_arg() {fxt.Prep_raw_("/wiki/A%3F?action=edit").Expd_tid_(Xoh_href.Tid_wiki).Expd_full_("en.wikipedia.org/wiki/A??action=edit").Expd_page_("A??action=edit").Test_parse();}
@Test public void File__basic() {
fxt.Run_parse_by_href("file:///C/xowa/file/a.png").Chk_tid(Xoa_url_.Tid_file);
}
@Test public void Anchor__basic() {
fxt.Run_parse_by_href("#a").Chk_tid(Xoa_url_.Tid_anch).Chk_to_str("en.wikipedia.org/wiki/Page 1#a").Chk_anch("a");
}
@Test public void Xcmd__basic() {
fxt.Run_parse_by_href("/xcmd/page_edit").Chk_tid(Xoa_url_.Tid_xcmd).Chk_page("page_edit");
}
@Test public void Xowa__basic() {
fxt.Run_parse_by_href("xowa-cmd:a%22b*c").Chk_tid(Xoa_url_.Tid_xcmd).Chk_page("a\"b*c");
}
// COMMENTED: this seems wrong; [//wikisource.org] should go to https://wikisource.org not https://en.wikisource.org; both sites are different; DATE:2015-08-02
// @Test public void Site__user_wiki() {// PURPOSE: outlier for wikisource.org which is alias to en.wikisource.org; alias added in user_wiki; EX: [//wikisource.org a]; in browser, automatically goes to http://wikisource.org; in xowa, should go to /site/en.wikisource.org
// fxt.Prep_xwiki(fxt.App().User().Wikii(), "en_wiki_alias", "en.wikipedia.org", null);
// fxt.Run_parse_by_href("/site/en_wiki_alias/wiki/")
// .Chk_tid(Xoa_url_.Tid_page)
// .Chk_page("Main_Page")
// .Chk_to_str("en.wikipedia.org/wiki/Main_Page")
// ;
// }
}
class Xoh_href_parser_fxt {
private Xowe_wiki wiki; private Xoh_href_parser href_parser; private Bry_bfr tmp_bfr = Bry_bfr.reset_(255); private Xoh_href href = new Xoh_href();
private static final byte[] Page_1_ttl = Bry_.new_a7("Page 1");
public void Clear() {
expd_tid = Xoh_href.Tid_null;
prep_raw = expd_full = expd_wiki = expd_page = expd_anch = null;
if (app != null) return;
app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
wiki.Xwiki_mgr().Add_bulk(Bry_.new_a7("wikt|en.wiktionary.org"));
app.Usere().Wiki().Xwiki_mgr().Add_bulk(Bry_.new_a7("en.wiktionary.org|en.wiktionary.org"));
href_parser = new Xoh_href_parser(Xoa_app_.Utl__encoder_mgr().Href(), app.Utl__url_parser().Url_parser());
}
public Xoae_app App() {return app;} private Xoae_app app;
public Xoh_href_parser_fxt Init_xwiki_alias(String alias, String domain) {
app.Usere().Wiki().Xwiki_mgr().Add_full(alias, domain);
class Xoh_href_parser_fxt extends Xoa_url_parser_fxt { private final Xoh_href_parser href_parser = new Xoh_href_parser();
public Xoh_href_parser_fxt Run_parse_by_href(String raw) {
href_parser.Parse_as_url(actl_url, Bry_.new_u8(raw), cur_wiki, Bry__page_1);
return this;
}
public Xoh_href_parser_fxt Init_xwiki_by_many(String raw) {
wiki.Xwiki_mgr().Add_many(Bry_.new_u8(raw)); // need to add to wiki's xwiki_mgr for ttl_parse
return this;
}
public Xoh_href_parser_fxt Init_hover_full_y_() {return Init_hover_full_(Bool_.Y);}
public Xoh_href_parser_fxt Init_hover_full_n_() {return Init_hover_full_(Bool_.N);}
public Xoh_href_parser_fxt Init_hover_full_(boolean v) {show_full_hover_string = v; return this;}
public Xoh_href_parser_fxt Prep_raw_(String v) {this.prep_raw = v; return this;} private String prep_raw;
public Xoh_href_parser_fxt Expd_tid_(byte v) {this.expd_tid = v; return this;} private byte expd_tid;
public Xoh_href_parser_fxt Expd_full_(String v) {this.expd_full = v; return this;} private String expd_full;
public Xoh_href_parser_fxt Expd_wiki_(String v) {this.expd_wiki = v; return this;} private String expd_wiki;
public Xoh_href_parser_fxt Expd_page_(String v) {this.expd_page = v; return this;} private String expd_page;
public Xoh_href_parser_fxt Expd_anch_(String v) {this.expd_anch = v; return this;} private String expd_anch;
public void Test_parse() {
href_parser.Parse(href, prep_raw, wiki, Page_1_ttl);
if (expd_tid != Xoh_href.Tid_null) Tfds.Eq(expd_tid, href.Tid());
if (expd_wiki != null) Tfds.Eq(expd_wiki, String_.new_u8(href.Wiki()));
if (expd_page != null) Tfds.Eq(expd_page, String_.new_u8(href.Page()));
if (expd_anch != null) Tfds.Eq(expd_anch, String_.new_u8(href.Anchor()));
if (expd_full != null) {
href.Print_to_bfr(tmp_bfr, true);
Tfds.Eq(expd_full, tmp_bfr.Xto_str_and_clear());
}
}
private boolean show_full_hover_string = false;
public void Test_hover_string(String raw, String expd) {
href_parser.Parse(href, raw, wiki, Page_1_ttl);
href.Print_to_bfr(tmp_bfr, show_full_hover_string);
Tfds.Eq(expd, tmp_bfr.Xto_str_and_clear());
}
public void Test_build(String raw, String expd) {
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_u8(raw));
href_parser.Build_to_bfr(tmp_bfr, app, wiki.Domain_bry(), ttl);
Tfds.Eq(expd, tmp_bfr.Xto_str_and_clear());
}
public void Test_parse_protocol(String raw, byte expd_tid) {
href_parser.Parse(href, raw, wiki, Page_1_ttl);
Tfds.Eq(expd_tid, href.Protocol_tid());
}
private static final byte[] Bry__page_1 = Bry_.new_a7("Page 1");
}

View File

@@ -0,0 +1,83 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.hrefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.wikis.xwikis.*;
public class Xoh_href_wtr {
private final Bry_bfr encoder_bfr = Bry_bfr.reset_(255), tmp_bfr = Bry_bfr.reset_(255);
private final Url_encoder encoder = Xoa_app_.Utl__encoder_mgr().Href();
public byte[] Build_to_bry(Xow_wiki wiki, Xoa_ttl ttl) {
synchronized (tmp_bfr) {
Build_to_bfr(tmp_bfr, wiki.App(), wiki.Domain_bry(), ttl, Bool_.N);
return tmp_bfr.Xto_bry_and_clear();
}
}
public void Build_to_bfr(Bry_bfr bfr, Xoa_app app, byte[] domain_bry, Xoa_ttl ttl) {Build_to_bfr(bfr, app, domain_bry, ttl, Bool_.N);}
public void Build_to_bfr(Bry_bfr bfr, Xoa_app app, byte[] domain_bry, Xoa_ttl ttl, boolean force_site) {
byte[] page = ttl.Full_txt_raw();
Xow_xwiki_itm xwiki = ttl.Wik_itm();
if (xwiki == null) // not an xwiki; EX: [[wikt:Word]]
Build_to_bfr_page(ttl, page, 0); // write page only; NOTE: changed to remove leaf logic DATE:2014-09-07
else { // xwiki; skip wiki and encode page only;
byte[] wik_txt = ttl.Wik_txt();
Build_to_bfr_page(ttl, page, wik_txt.length + 1);
}
if (xwiki == null) { // not an xwiki
if (ttl.Anch_bgn() != 1) { // not an anchor-only; EX: "#A"
if (force_site) { // popup parser always writes as "/site/"
bfr.Add(Xoh_href_.Bry__site); // add "/site/"; EX: /site/
bfr.Add(domain_bry); // add xwiki; EX: en_dict
bfr.Add(Xoh_href_.Bry__wiki); // add "/wiki/"; EX: /wiki/
}
else
bfr.Add(Xoh_href_.Bry__wiki); // add "/wiki/"; EX: /wiki/Page
}
else {} // anchor: noop
}
else { // xwiki
if (app.Xwiki_mgr__missing(xwiki.Domain_bry())) { // xwiki is not offline; use http:
Bry_fmtr url_fmtr = xwiki.Url_fmtr();
if (url_fmtr == null) {
bfr.Add(Xoh_href_.Bry__https); // add "https://"; EX: https://
bfr.Add(xwiki.Domain_bry()); // add xwiki; EX: en_dict
bfr.Add(Xoh_href_.Bry__wiki); // add "/wiki/"; EX: /wiki/
}
else { // url_fmtr exists; DATE:2015-04-22
url_fmtr.Bld_bfr(bfr, encoder_bfr.Xto_bry_and_clear()); // use it and pass encoder_bfr for page_name;
return;
}
}
else { // xwiki is avaiable; use /site/
bfr.Add(Xoh_href_.Bry__site); // add "/site/"; EX: /site/
bfr.Add(xwiki.Domain_bry()); // add xwiki; EX: en_dict
bfr.Add(Xoh_href_.Bry__wiki); // add "/wiki/"; EX: /wiki/
}
}
bfr.Add_bfr_and_clear(encoder_bfr);
}
private void Build_to_bfr_page(Xoa_ttl ttl, byte[] ttl_full, int page_bgn) {
int anch_bgn = Bry_finder.Find_fwd(ttl_full, Byte_ascii.Hash); // NOTE: cannot use Anch_bgn b/c Anch_bgn has bug with whitespace
if (anch_bgn == Bry_.NotFound) // no anchor; just add page
encoder.Encode(encoder_bfr, ttl_full, page_bgn, ttl_full.length);
else { // anchor exists; check if anchor is preceded by ws; EX: [[A #b]] -> "/wiki/A#b"
int page_end = Bry_finder.Find_bwd_last_ws(ttl_full, anch_bgn); // first 1st ws before #; handles multiple ws
page_end = page_end == Bry_.NotFound ? anch_bgn : page_end; // if ws not found, use # pos; else use 1st ws pos
encoder.Encode(encoder_bfr, ttl_full, page_bgn, page_end); // add page
encoder.Encode(encoder_bfr, ttl_full, anch_bgn, ttl_full.length); // add anchor
}
}
}

View File

@@ -0,0 +1,59 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.hrefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*;
import gplx.core.net.*;
public class Xoh_href_wtr_tst {
private final Xoh_href_wtr_fxt fxt = new Xoh_href_wtr_fxt();
@Test public void Xwiki_enc() {fxt.Test_build("wikt:abc?d" , "/site/en.wiktionary.org/wiki/abc%3Fd");}
@Test public void Page_quote() {fxt.Test_build("a\"b\"c" , "/wiki/A%22b%22c");}
@Test public void Page() {fxt.Test_build("abc" , "/wiki/Abc");}
@Test public void Page_ns() {fxt.Test_build("Image:A.png" , "/wiki/Image:A.png");}
@Test public void Anchor() {fxt.Test_build("#abc" , "#abc");}
@Test public void Page_anchor() {fxt.Test_build("Abc#def" , "/wiki/Abc#def");}
@Test public void Xwiki() {fxt.Test_build("wikt:abc" , "/site/en.wiktionary.org/wiki/abc");} // NOTE: "abc" not capitalized, b/c other wiki's case sensitivity is not known; this emulates WP's behavior
@Test public void Xwiki_2() {fxt.Test_build("wikt:Special:Search/a" , "/site/en.wiktionary.org/wiki/Special:Search/a");}
@Test public void Category() {fxt.Test_build("Category:abc" , "/wiki/Category:Abc");}
@Test public void Xwiki_wikimedia_mail() { // PURPOSE: DATE:2015-04-22
fxt.Prep_xwiki_by_many("mail|https://lists.wikimedia.org/mailman/listinfo/$1|Wikitech Mailing List");
fxt.Test_build("mail:A" , "https://lists.wikimedia.org/mailman/listinfo/A");
}
}
class Xoh_href_wtr_fxt {
private final Xowe_wiki wiki;
private final Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
private final Xoh_href_wtr href_wtr = new Xoh_href_wtr();
public Xoh_href_wtr_fxt() {
this.app = Xoa_app_fxt.app_();
this.wiki = Xoa_app_fxt.wiki_tst_(app);
wiki.Xwiki_mgr().Add_bulk(Bry_.new_a7("wikt|en.wiktionary.org"));
app.Usere().Wiki().Xwiki_mgr().Add_bulk(Bry_.new_a7("en.wiktionary.org|en.wiktionary.org"));
}
public Xoae_app App() {return app;} private final Xoae_app app;
public Xoh_href_wtr_fxt Prep_wiki_cs(String domain) {
Xow_wiki wiki = app.Wiki_mgr().Get_by_key_or_make_init_n(Bry_.new_u8(domain));
wiki.Ns_mgr().Ns_main().Case_match_(Xow_ns_case_.Id_all);
return this;
}
public Xoh_href_wtr_fxt Prep_xwiki_by_many(String raw) {wiki.Xwiki_mgr().Add_many(Bry_.new_u8(raw)); return this;} // need to add to wiki's xwiki_mgr for ttl_parse
public void Test_build(String raw, String expd) {
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_u8(raw));
href_wtr.Build_to_bfr(tmp_bfr, app, wiki.Domain_bry(), ttl);
Tfds.Eq(expd, tmp_bfr.Xto_str_and_clear());
}
}

View File

@@ -80,7 +80,7 @@ public class Xow_hzip_itm__anchor {
if (id_bgn > a_lhs_end) return Xow_hzip_mgr.Unhandled;
id_bgn += Find_id_bry.length + gplx.xowa.parsers.lnkis.redlinks.Xopg_redlink_lnki_list.Lnki_id_prefix_len;
int id_end = Bry_finder.Find_fwd(src, Byte_ascii.Quote, id_bgn, src_len); if (id_end == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled;
int id = Bry_.Xto_int_or(src, id_bgn, id_end, -1); if (id == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled;
int id = Bry_.To_int_or(src, id_bgn, id_end, -1); if (id == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled;
int a_rhs_bgn = Bry_finder.Find_fwd(src, Find_a_rhs_bgn_bry, a_lhs_end, src_len); if (a_rhs_bgn == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.a_rhs_bgn_missing", bgn, ttl_end);
int ttl_len = ttl_end - ttl_bgn;
int html_text_len = a_rhs_bgn - a_lhs_end;
@@ -132,7 +132,7 @@ public class Xow_hzip_itm__anchor {
int a_lhs_end = Bry_finder.Find_fwd(src, Byte_ascii.Gt, href_end, src_len); if (a_lhs_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.a_lhs_end_missing", bgn, href_end);
int num_bgn = a_lhs_end + 2; // skip >[
int num_end = Bry_finder.Find_fwd(src, Byte_ascii.Brack_end, num_bgn, src_len); if (num_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.num_end_missing", bgn, href_end);
int num = Bry_.Xto_int_or(src, num_bgn, num_end, -1); if (num == -1) return hzip_mgr.Warn_by_pos_add_dflt("a.num_invalid", num_bgn, num_end);
int num = Bry_.To_int_or(src, num_bgn, num_end, -1); if (num == -1) return hzip_mgr.Warn_by_pos_add_dflt("a.num_invalid", num_bgn, num_end);
Xow_hzip_int_.Save_bin_int_abrv(bfr, num);
int a_rhs_bgn = num_end + 1;
int a_rhs_end = a_rhs_bgn + Find_a_rhs_bgn_len;

View File

@@ -68,17 +68,17 @@ class Xow_hzip_itm__href {
, Tid_ext_asp = 6
, Tid_ext_aspx = 7
;
// private static final Btrie_slim_mgr proto_trie = Btrie_slim_mgr.ci_ascii_()
// private static final Btrie_slim_mgr proto_trie = Btrie_slim_mgr.ci_a7()
// .Add_str_byte("http", Tid_proto_http)
// .Add_str_byte("https", Tid_proto_http)
// ;
// private static final Btrie_slim_mgr tld_trie = Btrie_slim_mgr.ci_ascii_()
// private static final Btrie_slim_mgr tld_trie = Btrie_slim_mgr.ci_a7()
// .Add_str_byte("com", Tid_tld_com)
// .Add_str_byte("org", Tid_tld_org)
// .Add_str_byte("net", Tid_tld_net)
// .Add_str_byte("gov", Tid_tld_gov)
// ;
// private static final Btrie_slim_mgr ext_trie = Btrie_slim_mgr.ci_ascii_()
// private static final Btrie_slim_mgr ext_trie = Btrie_slim_mgr.ci_a7()
// .Add_str_byte("htm", Tid_ext_htm)
// .Add_str_byte("html", Tid_ext_html)
// .Add_str_byte("php", Tid_ext_php)

View File

@@ -101,7 +101,7 @@ public class Xow_hzip_mgr {
, Tid_a_rhs = 1
, Tid_h_lhs = 2
;
private Btrie_slim_mgr btrie = Btrie_slim_mgr.cs_()
private Btrie_slim_mgr btrie = Btrie_slim_mgr.cs()
.Add_str_byte("<a " , Tid_a_lhs)
.Add_str_byte("</a>" , Tid_a_rhs)
// .Add_str_byte("<h" , Tid_h_lhs)

View File

@@ -40,7 +40,7 @@ class Xow_hzip_xtid {
, Bry_img_full = Bry_.new_a7("a_img_full")
, Bry_hdr = Bry_.new_a7("hdr")
;
private static final Hash_adp_bry Xtids = Hash_adp_bry.cs_()
private static final Hash_adp_bry Xtids = Hash_adp_bry.cs()
.Add_bry_byte(Bry_lnki_text_n , Xow_hzip_dict.Tid_lnki_text_n)
.Add_bry_byte(Bry_lnki_text_y , Xow_hzip_dict.Tid_lnki_text_y)
.Add_bry_byte(Bry_lnke_txt , Xow_hzip_dict.Tid_lnke_txt)

View File

@@ -149,7 +149,7 @@ public class Xoh_js_cbk implements GfoInvkAble {
if (Bry_.Eq(lang_key, Wikidata_get_label_xowa_title))
val_bry = ttl_bry;
else {
val_bry = page.Label_list_get(lang_key);
val_bry = page.Label_list__get(lang_key);
}
if (val_bry == null) continue;
rv[i - 1] = String_.new_u8(val_bry);

View File

@@ -20,7 +20,7 @@ import gplx.html.*; import gplx.xowa.files.*; import gplx.xowa.html.hdumps.core.
public class Xoh_file_wtr__basic {
private final Xowe_wiki wiki; private final Xow_html_mgr html_mgr; private final Xoh_html_wtr html_wtr; private final Bry_bfr_mkr bfr_mkr; private final Bry_bfr scratch_bfr = Bry_bfr.reset_(Io_mgr.Len_kb);
private final Xoh_lnki_text_fmtr media_alt_fmtr, caption_fmtr;
private final Xop_link_parser tmp_link_parser = new Xop_link_parser(); private Xoa_url tmp_url = Xoa_url.blank_(); private final Xoh_lnki_title_fmtr anchor_title_wkr = new Xoh_lnki_title_fmtr();
private final Xop_link_parser tmp_link_parser = new Xop_link_parser(); private Xoa_url tmp_url = Xoa_url.blank(); private final Xoh_lnki_title_fmtr anchor_title_wkr = new Xoh_lnki_title_fmtr();
private Xoh_file_html_fmtr__base html_fmtr = Xoh_file_html_fmtr__base.Base;
private Xoae_page page; private boolean cfg_alt_defaults_to_caption;
public Xoh_file_wtr__basic(Xowe_wiki wiki, Xow_html_mgr html_mgr, Xoh_html_wtr html_wtr) {
@@ -45,7 +45,7 @@ public class Xoh_file_wtr__basic {
if (lnki_halign == Xop_lnki_align_h.Null)
lnki_halign = wiki.Lang().Img_thumb_halign_default(); // if halign is not supplied, then default to align for language
byte[] lnki_halign_bry = Xop_lnki_align_h.Html_names[lnki_halign];
byte[] lnki_href = wiki.Appe().Href_parser().Build_to_bry(wiki, lnki.Ttl());
byte[] lnki_href = wiki.Appe().Html__href_wtr().Build_to_bry(wiki, lnki.Ttl());
byte[] img_view_src = xfer_itm.Html_view_url().To_http_file_bry();
byte[] img_orig_src = xfer_itm.Html_orig_url().To_http_file_bry();
byte[] lnki_ttl = lnki.Ttl().Page_txt();

View File

@@ -42,7 +42,7 @@ public class Xoh_lnki_wtr {
public void Write(Bry_bfr bfr, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki) {
Xoa_ttl lnki_ttl = lnki.Ttl();
if (lnki_ttl == null) {// NOTE: parser failed to properly invalidate lnki; escape tkn now and warn; DATE:2014-06-06
app.Usr_dlg().Warn_many("", "", "invalid lnki evaded parser; page=~{0} ex=~{1}", ctx.Cur_page().Url().Xto_full_str(), String_.new_u8(src, lnki.Src_bgn(), lnki.Src_end()));
app.Usr_dlg().Warn_many("", "", "invalid lnki evaded parser; page=~{0} ex=~{1}", ctx.Cur_page().Url().To_str(), String_.new_u8(src, lnki.Src_bgn(), lnki.Src_end()));
Xoh_html_wtr_escaper.Escape(app.Parser_amp_mgr(), bfr, src, lnki.Src_bgn(), lnki.Src_end(), true, false);
return;
}
@@ -100,7 +100,7 @@ public class Xoh_lnki_wtr {
wiki.Html_mgr().Hzip_mgr().Itm__anchor().Html_plain(bfr, lnki);
else
bfr.Add(Xoh_consts.A_bgn); // '<a href="'
app.Href_parser().Build_to_bfr(bfr, app, wiki.Domain_bry(), lnki_ttl, hctx.Mode_is_popup()); // '/wiki/A'
app.Html__href_wtr().Build_to_bfr(bfr, app, wiki.Domain_bry(), lnki_ttl, hctx.Mode_is_popup()); // '/wiki/A'
if (cfg.Lnki__id()) {
int lnki_html_id = lnki.Html_uid();
if (lnki_html_id > Lnki_id_ignore) // html_id=0 for skipped lnkis; EX:anchors and interwiki

View File

@@ -25,7 +25,7 @@ import gplx.xowa.apis.xowa.html.modules.*;
public class Xow_popup_mgr implements GfoInvkAble, GfoEvObj {
private Xoae_app app; private Xowe_wiki wiki; private Js_wtr js_wtr = new Js_wtr();
private int show_init_word_count = Xoapi_popups.Dflt_show_init_word_count, show_more_word_count = Xoapi_popups.Dflt_show_more_word_count;
private Xoh_href temp_href = new Xoh_href();
private Xoa_url tmp_url = Xoa_url.blank();
private static final Object thread_lock = new Object(); private Xow_popup_itm async_itm; private GfoInvkAble async_cmd_show; private int async_id_next = 1;
public Xow_popup_mgr(Xowe_wiki wiki) {
this.wiki = wiki; this.app = wiki.Appe();
@@ -117,11 +117,11 @@ public class Xow_popup_mgr implements GfoInvkAble, GfoEvObj {
Running_(true);
if (itm.Canceled()) return null;
cur_page.Popup_mgr().Itms().Add_if_dupe_use_nth(itm.Popup_id(), itm);
app.Href_parser().Parse(temp_href, itm.Page_href(), wiki, cur_page.Ttl().Full_url()); // NOTE: use Full_url, not Page_url, else anchors won't work for non-main ns; PAGE:en.w:Project:Sandbox; DATE:2014-08-07
if (temp_href.Protocol_tid() == gplx.xowa.net.Xoo_protocol_itm.Tid_file) return Bry_.Empty; // NOTE: do not get popups for "file:///"; DATE:2015-04-05
Xowe_wiki popup_wiki = app.Wiki_mgr().Get_by_key_or_null(temp_href.Wiki());
app.Html__href_parser().Parse_as_url(tmp_url, itm.Page_href(), wiki, cur_page.Ttl().Full_url()); // NOTE: use Full_url, not Page_url, else anchors won't work for non-main ns; PAGE:en.w:Project:Sandbox; DATE:2014-08-07
if (!Xoa_url_.Tid_is_pagelike(tmp_url.Tid())) return Bry_.Empty; // NOTE: do not get popups for "file:///"; DATE:2015-04-05
Xowe_wiki popup_wiki = app.Wiki_mgr().Get_by_key_or_null(tmp_url.Wiki_bry());
popup_wiki.Init_assert();
Xoa_ttl popup_ttl = Xoa_ttl.parse_(popup_wiki, temp_href.Page_and_anchor());
Xoa_ttl popup_ttl = Xoa_ttl.parse_(popup_wiki, tmp_url.To_bry_page_w_anch());
switch (popup_ttl.Ns().Id()) {
case Xow_ns_.Id_media:
case Xow_ns_.Id_file:
@@ -255,11 +255,11 @@ class Xow_popup_mgr_ {
}
}
class Load_popup_wkr implements Gfo_thread_wkr {
private Xow_popup_itm itm; private Xoae_page cur_page; private Xoh_href temp_href;
private Xow_popup_itm itm; private Xoae_page cur_page; private Xoa_url tmp_url;
private Hash_adp ns_allowed_regy;
private Int_obj_ref ns_allowed_regy_key = Int_obj_ref.zero_();
public Load_popup_wkr(Xowe_wiki wiki, Xoae_page cur_page, Xow_popup_itm itm, Xoh_href temp_href, Hash_adp ns_allowed_regy, Int_obj_ref ns_allowed_regy_key) {
this.wiki = wiki; this.cur_page = cur_page; this.itm = itm; this.temp_href = temp_href; this.ns_allowed_regy = ns_allowed_regy; this.ns_allowed_regy_key = ns_allowed_regy_key;
public Load_popup_wkr(Xowe_wiki wiki, Xoae_page cur_page, Xow_popup_itm itm, Xoa_url tmp_url, Hash_adp ns_allowed_regy, Int_obj_ref ns_allowed_regy_key) {
this.wiki = wiki; this.cur_page = cur_page; this.itm = itm; this.tmp_url = tmp_url; this.ns_allowed_regy = ns_allowed_regy; this.ns_allowed_regy_key = ns_allowed_regy_key;
}
public String Name() {return "xowa.load_popup_wkr";}
public boolean Resume() {return false;}
@@ -272,11 +272,11 @@ class Load_popup_wkr implements Gfo_thread_wkr {
try {
if (itm.Canceled()) return;
cur_page.Popup_mgr().Itms().Add_if_dupe_use_nth(itm.Popup_id(), itm);
app.Href_parser().Parse(temp_href, itm.Page_href(), wiki, cur_page.Ttl().Full_url()); // NOTE: use Full_url, not Page_url, else anchors won't work for non-main ns; PAGE:en.w:Project:Sandbox; DATE:2014-08-07
if (temp_href.Protocol_tid() == gplx.xowa.net.Xoo_protocol_itm.Tid_file) return; // NOTE: do not get popups for "file:///"; DATE:2015-04-05
Xowe_wiki popup_wiki = app.Wiki_mgr().Get_by_key_or_null(temp_href.Wiki());
app.Html__href_parser().Parse_as_url(tmp_url, itm.Page_href(), wiki, cur_page.Ttl().Full_url()); // NOTE: use Full_url, not Page_url, else anchors won't work for non-main ns; PAGE:en.w:Project:Sandbox; DATE:2014-08-07
if (!Xoa_url_.Tid_is_pagelike(tmp_url.Tid())) return; // NOTE: do not get popups for "file:///"; DATE:2015-04-05
Xowe_wiki popup_wiki = app.Wiki_mgr().Get_by_key_or_null(tmp_url.Wiki_bry());
popup_wiki.Init_assert();
Xoa_ttl popup_ttl = Xoa_ttl.parse_(popup_wiki, temp_href.Page_and_anchor());
Xoa_ttl popup_ttl = Xoa_ttl.parse_(popup_wiki, tmp_url.To_bry_page_w_anch());
switch (popup_ttl.Ns().Id()) {
case Xow_ns_.Id_media:
case Xow_ns_.Id_file:

View File

@@ -21,7 +21,7 @@ import gplx.xowa.parsers.lnkes.*;
public class Xow_popup_wrdx_mkr {
private boolean skip_space;
private Xop_tkn_itm prv_tkn_seen, prv_tkn_added;
public Hash_adp_bry Xnde_id_ignore_list() {return xnde_id_ignore_list;} private Hash_adp_bry xnde_id_ignore_list = Hash_adp_bry.ci_ascii_();
public Hash_adp_bry Xnde_id_ignore_list() {return xnde_id_ignore_list;} private Hash_adp_bry xnde_id_ignore_list = Hash_adp_bry.ci_a7();
public void Init() {
skip_space = false;
prv_tkn_seen = prv_tkn_added = null;

View File

@@ -108,7 +108,7 @@ class Xoh_ns_file_page_mgr_fxt {
// file.Orig_ttl_and_redirect_(ttl_bry, Bry_.Empty);
file.Init_at_orig(Byte_.Zero, wiki.Domain_bry(), ttl_bry, Xof_ext_.new_by_ttl_(ttl_bry), 0, 0, Bry_.Empty);
file.Init_at_hdoc(0, Xof_html_elem.Tid_img);
wkr.Bld_html(wiki, bfr, file, ttl, opt, Bry_.XtoStrBytesByInt(html_file_size, 0), play_btn_icon); // TEST: must pass in elem_val b/c test only uses 2nd Bld_html while app uses 1st
wkr.Bld_html(wiki, bfr, file, ttl, opt, Bry_.To_a7_bry(html_file_size, 0), play_btn_icon); // TEST: must pass in elem_val b/c test only uses 2nd Bld_html while app uses 1st
Tfds.Eq_str_lines(expd, bfr.Xto_str_and_clear());
} static final byte[] play_btn_icon = Bry_.new_a7("file:///mem/xowa/user/test_user/app/img/file/play.png");
public static final String Hdr = String_.Concat_lines_nl_skip_last

View File

@@ -18,10 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.html.portal; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.html.hrefs.*;
public class Xoh_subpages_bldr implements Bry_fmtr_arg {
private Xoae_app app;
private Bry_bfr tmp_bfr = Bry_bfr.reset_(255), ttl_bfr = Bry_bfr.reset_(255);
private byte[][] segs;
public Xoh_subpages_bldr(Xoae_app app) {this.app = app;}
public byte[] Bld(Xow_ns_mgr ns_mgr, Xoa_ttl ttl) {
Xow_ns ns = ttl.Ns();
if (! ( ns.Subpages_enabled() // ns has subpages
@@ -47,8 +45,8 @@ public class Xoh_subpages_bldr implements Bry_fmtr_arg {
byte[] seg = segs[i];
ttl_bfr.Add(seg);
byte[] seg_ttl = ttl_bfr.Xto_bry();
byte[] seg_ttl_enc = app.Href_parser().Encoder().Encode(ttl_bfr.Xto_bry());
byte[] href = Bry_.Add(Xoh_href_parser.Href_wiki_bry, seg_ttl_enc); // EX: /wiki/Help:A
byte[] seg_ttl_enc = Xoa_app_.Utl__encoder_mgr().Href().Encode(ttl_bfr.Xto_bry());
byte[] href = Bry_.Add(Xoh_href_.Bry__wiki, seg_ttl_enc); // EX: /wiki/Help:A
fmtr_itm.Bld_bfr(bfr, dlm, href, seg_ttl, seg);
}
ttl_bfr.Clear();

View File

@@ -35,13 +35,12 @@ public class Xoh_subpages_bldr_tst {
}
class Xoh_subpages_bldr_fxt {
private Xoae_app app;
private Xoh_subpages_bldr subpages_bldr;
private Xoh_subpages_bldr subpages_bldr = new Xoh_subpages_bldr();
public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki;
public void Init() {
this.app = Xoa_app_fxt.app_();
this.wiki = Xoa_app_fxt.wiki_tst_(app);
wiki.Ns_mgr().Ids_get_or_null(Xow_ns_.Id_help).Subpages_enabled_(true);
this.subpages_bldr = new Xoh_subpages_bldr(app);
}
public void Test_bld(String ttl_str, String expd) {
byte[] actl = subpages_bldr.Bld(wiki.Ns_mgr(), Xoa_ttl.parse_(wiki, Bry_.new_u8(ttl_str)));

View File

@@ -45,8 +45,8 @@ public class Xow_portal_mgr implements GfoInvkAble {
Init_fmtr(tmp_bfr, eval_mgr, div_view_fmtr);
Init_fmtr(tmp_bfr, eval_mgr, div_ns_fmtr);
byte[] wiki_user_name = wiki.User().Name();
div_personal_bry = Init_fmtr(tmp_bfr, eval_mgr, div_personal_fmtr, Bry_.Add(Xoh_href_parser.Href_wiki_bry, wiki.Ns_mgr().Ids_get_or_null(Xow_ns_.Id_user).Name_db_w_colon(), wiki_user_name), wiki_user_name, Ns_cls_by_id(wiki.Ns_mgr(), Xow_ns_.Id_user), Bry_.Add(Xoh_href_parser.Href_wiki_bry, wiki.Ns_mgr().Ids_get_or_null(Xow_ns_.Id_user_talk).Name_db_w_colon(), wiki_user_name), Ns_cls_by_id(wiki.Ns_mgr(), Xow_ns_.Id_user_talk));
byte[] main_page_href_bry = tmp_bfr.Add(Xoh_href_parser.Href_site_bry).Add(wiki.Domain_bry()).Add(Xoh_href_parser.Href_wiki_bry).Xto_bry_and_clear(); // NOTE: build /site/en.wikipedia.org/wiki/ href; no Main_Page, as that will be inserted by Xoh_href_parser
div_personal_bry = Init_fmtr(tmp_bfr, eval_mgr, div_personal_fmtr, Bry_.Add(Xoh_href_.Bry__wiki, wiki.Ns_mgr().Ids_get_or_null(Xow_ns_.Id_user).Name_db_w_colon(), wiki_user_name), wiki_user_name, Ns_cls_by_id(wiki.Ns_mgr(), Xow_ns_.Id_user), Bry_.Add(Xoh_href_.Bry__wiki, wiki.Ns_mgr().Ids_get_or_null(Xow_ns_.Id_user_talk).Name_db_w_colon(), wiki_user_name), Ns_cls_by_id(wiki.Ns_mgr(), Xow_ns_.Id_user_talk));
byte[] main_page_href_bry = tmp_bfr.Add(Xoh_href_.Bry__site).Add(wiki.Domain_bry()).Add(Xoh_href_.Bry__wiki).Xto_bry_and_clear(); // NOTE: build /site/en.wikipedia.org/wiki/ href; no Main_Page, as that will be inserted by Xoh_href_parser
div_logo_bry = Init_fmtr(tmp_bfr, eval_mgr, div_logo_fmtr, main_page_href_bry, Xoa_app_.Utl__encoder_mgr().Fsys().Encode_http(wiki.Appe().Usere().Fsys_mgr().Wiki_root_dir().GenSubFil_nest(wiki.Domain_str(), "html", "logo.png")));
div_home_bry = Init_fmtr(tmp_bfr, eval_mgr, div_home_fmtr);
div_wikis_fmtr.Eval_mgr_(eval_mgr);
@@ -69,14 +69,14 @@ public class Xow_portal_mgr implements GfoInvkAble {
else
subj_cls = Xow_portal_mgr.Cls_selected_y;
Bry_fmtr_arg vnt_menu = null;
// Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr(); // VNT; DATE:2015-03-03
// if (vnt_mgr.Enabled()) {
// Vnt_mnu_grp_fmtr vnt_menu_fmtr = vnt_mgr.Vnt_mnu_fmtr();
// vnt_menu_fmtr.Init(vnt_mgr.Vnt_grp(), ttl.Full_db(), vnt_mgr.Cur_vnt());
// vnt_menu = wiki.Lang().Vnt_mgr().Enabled() ? vnt_menu_fmtr : null;
// }
Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr(); // VNT; DATE:2015-03-03
if (vnt_mgr.Enabled()) {
Vnt_mnu_grp_fmtr vnt_menu_fmtr = vnt_mgr.Vnt_mnu_fmtr();
vnt_menu_fmtr.Init(vnt_mgr.Vnt_grp(), wiki.Domain_bry(), ttl.Full_db(), vnt_mgr.Cur_vnt());
vnt_menu = wiki.Lang().Vnt_mgr().Enabled() ? vnt_menu_fmtr : null;
}
Bry_bfr tmp_bfr = bfr_mkr.Get_k004();
div_ns_fmtr.Bld_bfr_many(tmp_bfr, Bry_.Add(Xoh_href_parser.Href_wiki_bry, ttl.Subj_txt()), subj_cls, Bry_.Add(Xoh_href_parser.Href_wiki_bry, ttl.Talk_txt()), talk_cls, vnt_menu);
div_ns_fmtr.Bld_bfr_many(tmp_bfr, Bry_.Add(Xoh_href_.Bry__wiki, ttl.Subj_txt()), subj_cls, Bry_.Add(Xoh_href_.Bry__wiki, ttl.Talk_txt()), talk_cls, vnt_menu);
return tmp_bfr.To_bry_and_rls();
}
private byte[] Ns_cls_by_ord(Xow_ns_mgr ns_mgr, int ns_ord) {

View File

@@ -90,7 +90,7 @@ public class Xowh_sidebar_mgr implements GfoInvkAble {
cur_grp.Itms_add(cur_itm);
}
}
} private Xoa_url tmp_url = Xoa_url.blank_();
} private Xoa_url tmp_url = Xoa_url.blank();
public void Bld_html(Bry_bfr bfr) {
int len = grps.Count();
for (int i = 0; i < len; i++) {
@@ -125,7 +125,7 @@ public class Xowh_sidebar_mgr implements GfoInvkAble {
} private static final String Invk_html_grp_fmt_ = "html_grp_fmt_", Invk_html_itm_fmt_ = "html_itm_fmt_";
private static final byte[] CONST_id_prefix = Bry_.new_a7("n-");
private static final byte Ignore_tid_search = 1, Ignore_tid_toolbox = 2, Ignore_tid_toolbox_end = 3, Ignore_tid_languages = 4;
private static final Btrie_slim_mgr ignore_trie = Btrie_slim_mgr.ci_ascii_()
private static final Btrie_slim_mgr ignore_trie = Btrie_slim_mgr.ci_a7()
.Add_str_byte("SEARCH", Ignore_tid_search)
.Add_str_byte("TOOLBOX", Ignore_tid_toolbox)
.Add_str_byte("TOOLBOXEND", Ignore_tid_toolbox_end)

View File

@@ -108,7 +108,7 @@ public class Xow_toc_mgr implements Bry_fmtr_arg {
bfr.Mkr_rls();
return bfr.Xto_bry_and_clear();
} catch (Exception e) {
Gfo_usr_dlg_.I.Warn_many("", "", "failed to write toc: url=~{0} err=~{1}", page.Url().Xto_full_str_safe(), Err_.Message_gplx_full(e));
Gfo_usr_dlg_.I.Warn_many("", "", "failed to write toc: url=~{0} err=~{1}", page.Url().To_str(), Err_.Message_gplx_full(e));
return Bry_.Empty;
}
}

View File

@@ -199,5 +199,5 @@ public class Xoh_js_cleaner {
Reg_itm("seekSegmentTime");
ctor = false;
}
private void Reg_itm(String s) {trie.Add_bry(Bry_.new_a7(s));} Btrie_slim_mgr trie = Btrie_slim_mgr.ci_ascii_(); // NOTE:ci.ascii:javascript event name
private void Reg_itm(String s) {trie.Add_bry(Bry_.new_a7(s));} Btrie_slim_mgr trie = Btrie_slim_mgr.ci_a7(); // NOTE:ci.ascii:javascript event name
}

View File

@@ -18,12 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.html.wtrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.html.*; import gplx.xowa.html.hrefs.*;
public class Xoh_lnki_bldr {
private final Xoa_app app; private final Xoh_href_parser href_parser; private final byte[] img_root_dir;
private final Xoa_app app; private final Xoh_href_wtr href_wtr; private final byte[] img_root_dir;
private final Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
private byte[] href, title, id, caption;
private byte[] img_rel_path; private int img_w, img_h; private boolean img_pos_is_left;
public Xoh_lnki_bldr(Xoa_app app, Xoh_href_parser href_parser) {
this.app = app; this.href_parser = href_parser;
public Xoh_lnki_bldr(Xoa_app app, Xoh_href_wtr href_wtr) {
this.app = app; this.href_wtr = href_wtr;
this.img_root_dir = app.Fsys_mgr().Root_dir().GenSubDir_nest("user", "anonymous", "app", "img").To_http_file_bry();
}
public Xoh_lnki_bldr Clear() {
@@ -35,7 +35,7 @@ public class Xoh_lnki_bldr {
public Xoh_lnki_bldr Id_(byte[] v) {this.id = Html_utl.Escape_for_atr_val_as_bry(tmp_bfr, Byte_ascii.Apos, v); return this;}
public Xoh_lnki_bldr Href_(Xow_wiki wiki, byte[] bry) {return Href_(wiki.Domain_bry(), wiki.Ttl_parse(bry));}
public Xoh_lnki_bldr Href_(byte[] domain_bry, Xoa_ttl ttl) {
href_parser.Build_to_bfr(tmp_bfr, app, domain_bry, ttl, Bool_.Y);
href_wtr.Build_to_bfr(tmp_bfr, app, domain_bry, ttl, Bool_.Y);
this.href = tmp_bfr.Xto_bry_and_clear();
return this;
}

View File

@@ -18,14 +18,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.html.wtrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.html.*; import gplx.xowa.html.hrefs.*;
public class Xoh_lnki_wtr_utl {
private final Xoa_app app; private final Xow_wiki wiki; private final Xoh_href_parser href_parser; private final Bry_bfr tmp_bfr = Bry_bfr.new_(255);
public Xoh_lnki_wtr_utl(Xow_wiki wiki, Xoh_href_parser href_parser) {
private final Xoa_app app; private final Xow_wiki wiki; private final Xoh_href_wtr href_wtr; private final Bry_bfr tmp_bfr = Bry_bfr.new_(255);
public Xoh_lnki_wtr_utl(Xow_wiki wiki, Xoh_href_wtr href_wtr) {
this.app = wiki.App();
this.wiki = wiki; this.href_parser = href_parser;
this.wiki = wiki; this.href_wtr = href_wtr;
}
public byte[] Bld_href(byte[] page) {return Bld_href(wiki.Domain_bry(), wiki.Ttl_parse(page));}
public byte[] Bld_href(byte[] domain_bry, Xoa_ttl ttl) {
href_parser.Build_to_bfr(tmp_bfr, app, domain_bry, ttl, Bool_.Y);
href_wtr.Build_to_bfr(tmp_bfr, app, domain_bry, ttl, Bool_.Y);
return tmp_bfr.Xto_bry_and_clear();
}
public byte[] Bld_title(byte[] text) {