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-07-12 21:10:02 -04:00
commit 794b5a232f
3099 changed files with 238212 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
/*
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; import gplx.*; import gplx.xowa.*;
public class Xoh_cfg_file {
public Xoh_cfg_file(Url_encoder url_encoder, Io_url xowa_dir) {
Io_url mw_file_dir = xowa_dir.GenSubDir_nest("file", "mw.file");
img_media_play_btn = url_encoder.Encode_http(mw_file_dir.GenSubFil("play.png"));
img_media_info_btn = url_encoder.Encode_http(mw_file_dir.GenSubFil("info.png"));
img_thumb_magnify = url_encoder.Encode_http(mw_file_dir.GenSubFil("magnify-clip.png"));
}
public byte[] Img_media_play_btn() {return img_media_play_btn;} private final byte[] img_media_play_btn;
public byte[] Img_media_info_btn() {return img_media_info_btn;} private final byte[] img_media_info_btn;
public byte[] Img_thumb_magnify() {return img_thumb_magnify;} private final byte[] img_thumb_magnify;
}

View File

@@ -0,0 +1,23 @@
/*
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; import gplx.*; import gplx.xowa.*;
public interface Xoh_cmd_itm {
String Hcmd_id();
void Hcmd_exec(Xoae_app app, Gfo_usr_dlg usr_dlg, Xoae_page page);
void Hcmd_write(Xoae_app app, Gfo_usr_dlg usr_dlg, Xoae_page page);
}

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; import gplx.*; import gplx.xowa.*;
public class Xoh_cmd_mgr {
public int Count() {return cmds.Count();}
public void Clear() {cmds.Clear();}
public void Add(Xoh_cmd_itm itm) {cmds.Add(itm);} List_adp cmds = List_adp_.new_();
public void Exec(Xoae_app app, Xoae_page page) {
int len = cmds.Count();
if (len == 0) return;
Gfo_usr_dlg usr_dlg = app.Usr_dlg();
usr_dlg.Prog_one(GRP_KEY, "bgn", "cmds bgn: ~{0}", len); // NOTE: this message will not show, but is needed for other messages to show; SWT swallowing 1st msg before showing others?; DATE:2013-04-25
for (int i = 0; i < len; i++) {
if (usr_dlg.Canceled()) {usr_dlg.Prog_none(GRP_KEY, "cmds.done", ""); app.Log_wtr().Queue_enabled_(false); return;}
Xoh_cmd_itm itm = null;
try {
itm = (Xoh_cmd_itm)cmds.Get_at(i);
itm.Hcmd_exec(app, usr_dlg, page);
itm.Hcmd_write(app, usr_dlg, page);
} catch (Exception e) {throw Exc_.new_exc(e, "xo", "failed to execute html cmd", "name", itm == null ? "unknown" : itm.Hcmd_id());}
}
this.Clear();
}
static final String GRP_KEY = "xowa.html.cmd_mgr";
}

View File

@@ -0,0 +1,58 @@
/*
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; import gplx.*; import gplx.xowa.*;
public class Xoh_consts {
public static final String
Atr_xowa_title_str = "xowa_title"
, Img_w_str = "width"
, Img_h_str = "height"
;
public static final byte[]
__end = Bry_.new_a7(">")
, __end_quote = Bry_.new_a7("\">")
, __inline_quote = Bry_.new_a7("\"/>")
, Space_2 = Bry_.new_a7(" ")
, 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>")
, Pre_bgn = Bry_.new_a7("<pre>"), Pre_end = Bry_.new_a7("</pre>")
, Pre_bgn_open = Bry_.new_a7("<pre")
, Pre_style_overflow_auto = Bry_.new_a7("overflow:auto;")
, Pre_bgn_overflow = Bry_.new_a7("<pre style=\"overflow:auto\">")
, Code_bgn_closed = Bry_.new_a7("<code>")
, Code_bgn_open = Bry_.new_a7("<code")
, Code_end = Bry_.new_a7("</code>")
, Title_atr = Bry_.new_a7("\" title=\"")
, Id_atr = Bry_.new_a7(" id=\"")
, 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

@@ -0,0 +1,39 @@
/*
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; 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 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;
else if (ctx.Match(k, Invk_skins)) return skin_mgr;
else return GfoInvkAble_.Rv_unhandled;
} private static final String Invk_page = "page", Invk_tidy = "tidy", Invk_skins = "skins";
}

View File

@@ -0,0 +1,666 @@
/*
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; 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.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 {
private Xowe_wiki wiki; private Xoae_app app; private Xoae_page page; private Xop_xatr_whitelist_mgr whitelist_mgr;
public Xoh_html_wtr(Xowe_wiki wiki, Xow_html_mgr html_mgr) {
this.wiki = wiki; this.app = wiki.Appe(); this.whitelist_mgr = app.Html_mgr().Whitelist_mgr();
this.html_mgr = html_mgr;
lnki_wtr = new Xoh_lnki_wtr(this, wiki, html_mgr, cfg);
ref_wtr = new Ref_html_wtr(wiki);
lnke_wtr = new Xoh_lnke_wtr(wiki);
}
public void Init_by_wiki(Xowe_wiki wiki) {
cfg.Toc__show_(Bool_.Y).Lnki__title_(true).Lnki_visited_y_().Lnki__id_y_(); // NOTE: set during Init_by_wiki, b/c all tests assume these are false
ref_wtr.Init_by_wiki(wiki);
}
public Xow_html_mgr Html_mgr() {return html_mgr;} private Xow_html_mgr html_mgr;
public Xoh_html_wtr_cfg Cfg() {return cfg;} private Xoh_html_wtr_cfg cfg = new Xoh_html_wtr_cfg();
public Xoh_lnki_wtr Lnki_wtr() {return lnki_wtr;} private Xoh_lnki_wtr lnki_wtr;
public Xoh_lnke_wtr Lnke_wtr() {return lnke_wtr;} private Xoh_lnke_wtr lnke_wtr;
public Ref_html_wtr Ref_wtr() {return ref_wtr;} private Ref_html_wtr ref_wtr;
public void Init_by_page(Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xoae_page page) {this.page = page; lnki_wtr.Init_by_page(ctx, hctx, src, page);}
public void Write_all(Bry_bfr bfr, Xop_ctx ctx, byte[] src, Xop_root_tkn root) {Write_all(bfr, ctx, Xoh_wtr_ctx.Basic, src, root);}
public void Write_all(Bry_bfr bfr, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_root_tkn root) {
try {
indent_level = 0; this.page = ctx.Cur_page();
page.Slink_list().Clear(); // HACK: always clear langs; necessary for reload
lnki_wtr.Init_by_page(ctx, hctx, src, ctx.Cur_page());
Write_tkn(bfr, ctx, hctx, src, null, -1, root);
if (cfg.Hdr__div_wrapper())
bfr.Add(Tag_hdr__div_wrapper_end);
}
finally {
page.Category_list_(page.Html_data().Ctgs_to_ary());
}
}
public void Write_tkn_ary(Bry_bfr bfr, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_tkn_itm[] ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
Xop_tkn_itm itm = ary[i];
Write_tkn(bfr, ctx, hctx, src, itm, i, itm);
}
}
public void Write_tkn(Bry_bfr bfr, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_tkn_grp grp, int sub_idx, Xop_tkn_itm tkn) {
if (tkn.Ignore()) return;
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_arg_itm:
case Xop_tkn_itm_.Tid_root:
int subs_len = tkn.Subs_len();
for (int i = 0; i < subs_len; i++)
Write_tkn(bfr, ctx, hctx, src, tkn, i, tkn.Subs_get(i));
break;
case Xop_tkn_itm_.Tid_ignore: break;
case Xop_tkn_itm_.Tid_html_ncr: Html_ncr(ctx, hctx, bfr, src, (Xop_amp_tkn_num)tkn); break;
case Xop_tkn_itm_.Tid_html_ref: Html_ref(ctx, hctx, bfr, src, (Xop_amp_tkn_txt)tkn); break;
case Xop_tkn_itm_.Tid_hr: Hr(ctx, hctx, bfr, src, (Xop_hr_tkn)tkn); break;
case Xop_tkn_itm_.Tid_hdr: Hdr(ctx, hctx, bfr, src, (Xop_hdr_tkn)tkn); break;
case Xop_tkn_itm_.Tid_apos: Apos(ctx, hctx, bfr, src, (Xop_apos_tkn)tkn); break;
case Xop_tkn_itm_.Tid_lnke: lnke_wtr.Write_all(bfr, this, hctx, ctx, src, (Xop_lnke_tkn)tkn); break;
case Xop_tkn_itm_.Tid_lnki: lnki_wtr.Write(bfr, hctx, src, (Xop_lnki_tkn)tkn); break;
case Xop_tkn_itm_.Tid_list: List(ctx, hctx, bfr, src, (Xop_list_tkn)tkn); break;
case Xop_tkn_itm_.Tid_xnde: Xnde(ctx, hctx, bfr, src, (Xop_xnde_tkn)tkn); break;
case Xop_tkn_itm_.Tid_under: Under(ctx, hctx, bfr, src, (Xop_under_tkn)tkn); break;
case Xop_tkn_itm_.Tid_tblw_tb: Tblw(ctx, hctx, bfr, src, (Xop_tblw_tkn)tkn, Tag_tblw_tb_bgn_atr, Tag_tblw_tb_end, true); break;
case Xop_tkn_itm_.Tid_tblw_tr: Tblw(ctx, hctx, bfr, src, (Xop_tblw_tkn)tkn, Tag_tblw_tr_bgn_atr, Tag_tblw_tr_end, false); break;
case Xop_tkn_itm_.Tid_tblw_td: Tblw(ctx, hctx, bfr, src, (Xop_tblw_tkn)tkn, Tag_tblw_td_bgn_atr, Tag_tblw_td_end, false); break;
case Xop_tkn_itm_.Tid_tblw_th: Tblw(ctx, hctx, bfr, src, (Xop_tblw_tkn)tkn, Tag_tblw_th_bgn_atr, Tag_tblw_th_end, false); break;
case Xop_tkn_itm_.Tid_tblw_tc: Tblw(ctx, hctx, bfr, src, (Xop_tblw_tkn)tkn, Tag_tblw_tc_bgn_atr, Tag_tblw_tc_end, false); break;
case Xop_tkn_itm_.Tid_para: Para(ctx, hctx, bfr, src, (Xop_para_tkn)tkn); break;
case Xop_tkn_itm_.Tid_space: Space(ctx, hctx, bfr, src, grp, sub_idx, (Xop_space_tkn)tkn); break;
case Xop_tkn_itm_.Tid_pre: Pre(ctx, hctx, bfr, src, (Xop_pre_tkn)tkn); break;
case Xop_tkn_itm_.Tid_newLine: NewLine(ctx, hctx, bfr, src, (Xop_nl_tkn)tkn); break;
case Xop_tkn_itm_.Tid_bry: Bry(ctx, hctx, bfr, src, (Xop_bry_tkn)tkn); break;
case Xop_tkn_itm_.Tid_vnt: Vnt(ctx, hctx, bfr, src, (Xop_vnt_tkn)tkn); break;
// case Xop_tkn_itm_.Tid_tab: bfr.Add_byte_repeat(Byte_ascii.Tab, tkn.Src_end() - tkn.Src_bgn()); break;
default:
Xoh_html_wtr_escaper.Escape(app.Parser_amp_mgr(), bfr, src, tkn.Src_bgn(), tkn.Src_end(), true, false); // NOTE: always escape text including (a) lnki_alt text; and (b) any other text, especially failed xndes; DATE:2013-06-18
break;
}
}
@gplx.Virtual public void Html_ncr(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_amp_tkn_num tkn) {
bfr.Add_byte(Byte_ascii.Amp).Add_byte(Byte_ascii.Hash).Add_int_variable(tkn.Val()).Add_byte(Byte_ascii.Semic); // NOTE: do not literalize, else browser may not display multi-char bytes properly; EX: &#160; gets added as &#160; not as {192,160}; DATE:2013-12-09
}
@gplx.Virtual public void Html_ref(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_amp_tkn_txt tkn) {
if (tkn.Itm_is_custom()) // used by <nowiki>; EX:<nowiki>&#60;</nowiki> -> &xowa_lt; DATE:2014-11-07
tkn.Print_literal(bfr);
else
tkn.Print_ncr(bfr);
}
private static final byte[] Bry_hdr_bgn = Bry_.new_a7("<span class='mw-headline' id='"), Bry_hdr_end = Bry_.new_a7("</span>");
@gplx.Virtual public void Hr(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_hr_tkn tkn) {bfr.Add(Tag_hr);}
@gplx.Virtual public void Hdr(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_hdr_tkn hdr) {
boolean hdr_is_1st = hdr.Hdr_html_first();
if (hdr_is_1st && cfg.Toc__show() && !page.Hdr_mgr().Toc_manual()) { // __TOC__ not specified; place at top; NOTE: if __TOC__ was specified, then it would be placed wherever __TOC__ appears
wiki.Html_mgr().Toc_mgr().Html(ctx.Cur_page(), hctx, src, bfr);
}
int hdr_len = hdr.Hdr_len();
if (hdr_len > 0) { // NOTE: need to check hdr_len b/c it could be dangling
Para_assert_tag_starts_on_nl(bfr, hdr.Src_bgn());
if ( cfg.Hdr__div_wrapper() // div_wrapper enabled
&& !hdr_is_1st // not 1st <h#>; 2nd and up will close previous <#>
)
bfr.Add(Tag_hdr__div_wrapper_end); // add </div>
bfr.Add(Tag_hdr_bgn).Add_int(hdr_len, 1, 1);
if (cfg.Toc__show()) {
bfr.Add_byte(Tag__end);
bfr.Add(Bry_hdr_bgn);
bfr.Add(hdr.Hdr_html_id());
bfr.Add_byte(Byte_ascii.Apos);
}
bfr.Add_byte(Tag__end);
}
if (hdr.Hdr_bgn_manual() > 0) bfr.Add_byte_repeat(Byte_ascii.Eq, hdr.Hdr_bgn_manual());
int subs_len = hdr.Subs_len();
for (int i = 0; i < subs_len; i++)
Write_tkn(bfr, ctx, hctx, src, hdr, i, hdr.Subs_get(i));
if (hdr_len > 0) { // NOTE: need to check hdr_len b/c it could be dangling
if (hdr.Hdr_end_manual() > 0) bfr.Add_byte_repeat(Byte_ascii.Eq, hdr.Hdr_end_manual());
if (cfg.Toc__show()) {
if (hctx.Mode_is_hdump())
bfr.Add(Xow_hzip_itm__header.Hdr_end);
bfr.Add(Bry_hdr_end);
}
bfr.Add(Tag_hdr_end).Add_int(hdr_len, 1, 1).Add_byte(Tag__end).Add_byte_nl();// NOTE: do not need to check hdr_len b/c it is impossible for end to occur without bgn
if ( cfg.Hdr__div_wrapper()) // div_wrapper enabled
bfr.Add(Tag_hdr__div_wrapper_bgn); // add <div>
}
}
public void Apos(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_apos_tkn apos) {
if (hctx.Mode_is_alt()) return; // ignore apos if alt; EX: [[File:A.png|''A'']] should have alt of A; DATE:2013-10-25
int literal_apos = apos.Apos_lit();
if (literal_apos > 0)
bfr.Add_byte_repeat(Byte_ascii.Apos, literal_apos);
switch (apos.Apos_cmd()) {
case Xop_apos_tkn_.Cmd_b_bgn: bfr.Add(Html_tag_.B_lhs); break;
case Xop_apos_tkn_.Cmd_b_end: bfr.Add(Html_tag_.B_rhs); break;
case Xop_apos_tkn_.Cmd_i_bgn: bfr.Add(Html_tag_.I_lhs); break;
case Xop_apos_tkn_.Cmd_i_end: bfr.Add(Html_tag_.I_rhs); break;
case Xop_apos_tkn_.Cmd_bi_bgn: bfr.Add(Html_tag_.B_lhs).Add(Html_tag_.I_lhs); break;
case Xop_apos_tkn_.Cmd_ib_end: bfr.Add(Html_tag_.I_rhs).Add(Html_tag_.B_rhs); break;
case Xop_apos_tkn_.Cmd_ib_bgn: bfr.Add(Html_tag_.I_lhs).Add(Html_tag_.B_lhs); break;
case Xop_apos_tkn_.Cmd_bi_end: bfr.Add(Html_tag_.B_rhs).Add(Html_tag_.I_rhs);; break;
case Xop_apos_tkn_.Cmd_bi_end__b_bgn: bfr.Add(Html_tag_.B_rhs).Add(Html_tag_.I_rhs).Add(Html_tag_.B_lhs); break;
case Xop_apos_tkn_.Cmd_ib_end__i_bgn: bfr.Add(Html_tag_.I_rhs).Add(Html_tag_.B_rhs).Add(Html_tag_.I_lhs); break;
case Xop_apos_tkn_.Cmd_b_end__i_bgn: bfr.Add(Html_tag_.B_rhs).Add(Html_tag_.I_lhs); break;
case Xop_apos_tkn_.Cmd_i_end__b_bgn: bfr.Add(Html_tag_.I_rhs).Add(Html_tag_.B_lhs); break;
case Xop_apos_tkn_.Cmd_nil: break;
default: throw Exc_.new_unhandled(apos.Apos_cmd());
}
}
public static byte[] Ttl_to_title(byte[] ttl) {return ttl;} // FUTURE: swap html chars?
public void List(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_list_tkn list) {
if (hctx.Mode_is_alt()) { // alt; add literally; EX: "*" for "\n*"; note that \n is added in NewLine()
if (list.List_bgn() == Bool_.Y_byte) { // bgn tag
bfr.Add_byte(list.List_itmTyp()); // add literal byte
}
else {} // end tag; ignore
}
else {
byte list_itm_type = list.List_itmTyp();
if (list.List_bgn() == Bool_.Y_byte) {
if (list.List_sub_first()) List_grp_bgn(ctx, hctx, bfr, src, list_itm_type);
List_itm_bgn(ctx, hctx, bfr, src, list_itm_type);
}
else {
List_itm_end(ctx, hctx, bfr, src, list_itm_type);
if (list.List_sub_last() == Bool_.Y_byte) List_grp_end(ctx, hctx, bfr, src, list_itm_type);
}
}
}
@gplx.Virtual public void List_grp_bgn(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, byte type) {
byte[] tag = null;
switch (type) {
case Xop_list_tkn_.List_itmTyp_ol: tag = Tag_list_grp_ol_bgn; break;
case Xop_list_tkn_.List_itmTyp_ul: tag = Tag_list_grp_ul_bgn; break;
case Xop_list_tkn_.List_itmTyp_dd:
case Xop_list_tkn_.List_itmTyp_dt: tag = Tag_list_grp_dl_bgn; break;
default: throw Exc_.new_unhandled(type);
}
if (bfr.Len() > 0) bfr.Add_byte_nl(); // NOTE: do not add newLine if start
if (indent_level > 0) bfr.Add_byte_repeat(Byte_ascii.Space, indent_level * 2);
bfr.Add(tag);
++indent_level;
}
@gplx.Virtual public void List_itm_bgn(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, byte type) {
byte[] tag = null;
switch (type) {
case Xop_list_tkn_.List_itmTyp_ol:
case Xop_list_tkn_.List_itmTyp_ul: tag = Tag_list_itm_li_bgn; break;
case Xop_list_tkn_.List_itmTyp_dt: tag = Tag_list_itm_dt_bgn; break;
case Xop_list_tkn_.List_itmTyp_dd: tag = Tag_list_itm_dd_bgn; break;
default: throw Exc_.new_unhandled(type);
}
bfr.Add_byte_nl();
if (indent_level > 0) bfr.Add_byte_repeat(Byte_ascii.Space, indent_level * 2);
bfr.Add(tag);
++indent_level;
}
@gplx.Virtual public void List_grp_end(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, byte type) {
--indent_level;
byte[] tag = null;
switch (type) {
case Xop_list_tkn_.List_itmTyp_ol: tag = Tag_list_grp_ol_end; break;
case Xop_list_tkn_.List_itmTyp_ul: tag = Tag_list_grp_ul_end; break;
case Xop_list_tkn_.List_itmTyp_dd:
case Xop_list_tkn_.List_itmTyp_dt: tag = Tag_list_grp_dl_end; break;
default: throw Exc_.new_unhandled(type);
}
bfr.Add_byte_nl();
if (indent_level > 0) bfr.Add_byte_repeat(Byte_ascii.Space, indent_level * 2);
bfr.Add(tag);
}
@gplx.Virtual public void List_itm_end(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, byte type) {
--indent_level;
byte[] tag = null;
switch (type) {
case Xop_list_tkn_.List_itmTyp_ol:
case Xop_list_tkn_.List_itmTyp_ul: tag = Tag_list_itm_li_end; break;
case Xop_list_tkn_.List_itmTyp_dt: tag = Tag_list_itm_dt_end; break;
case Xop_list_tkn_.List_itmTyp_dd: tag = Tag_list_itm_dd_end; break;
default: throw Exc_.new_unhandled(type);
}
bfr.Add_byte_if_not_last(Byte_ascii.Nl);
if (indent_level > 0) bfr.Add_byte_repeat(Byte_ascii.Space, indent_level * 2);
bfr.Add(tag);
}
@gplx.Virtual public void NewLine(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_nl_tkn tkn) {
if (hctx.Mode_is_alt())
bfr.Add_byte_space();
else {
if (tkn.Nl_tid() == Xop_nl_tkn.Tid_char) {
bfr.Add_byte_if_not_last(Byte_ascii.Nl);
}
}
}
public void Space(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_tkn_grp grp, int sub_idx, Xop_space_tkn space) {
bfr.Add_byte_repeat(Byte_ascii.Space, space.Src_end_grp(grp, sub_idx) - space.Src_bgn_grp(grp, sub_idx)); // NOTE: lnki.caption will convert \n to \s; see Xop_nl_lxr; PAGE:en.w:Schwarzschild radius
}
@gplx.Virtual public void Para(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_para_tkn para) {
if (para.Nl_bgn() && bfr.Len() > 0) {
if (hctx.Mode_is_alt())
bfr.Add_byte_space();
else
bfr.Add_byte_if_not_last(Byte_ascii.Nl);
}
switch (para.Para_end()) {
case Xop_para_tkn.Tid_none: break;
case Xop_para_tkn.Tid_para: bfr.Add(Tag_para_end).Add_byte_nl(); break;
case Xop_para_tkn.Tid_pre: bfr.Add(Tag_pre_end).Add_byte_nl(); break;
default: throw Exc_.new_unhandled(para.Para_end());
}
switch (para.Para_bgn()) {
case Xop_para_tkn.Tid_none: break;
case Xop_para_tkn.Tid_para: Para_assert_tag_starts_on_nl(bfr, para.Src_bgn()); bfr.Add(Tag_para_bgn); break;
case Xop_para_tkn.Tid_pre: Para_assert_tag_starts_on_nl(bfr, para.Src_bgn()); bfr.Add(Tag_pre_bgn); break;
default: throw Exc_.new_unhandled(para.Para_bgn());
}
if (para.Space_bgn() > 0)
bfr.Add_byte_repeat(Byte_ascii.Space, para.Space_bgn());
}
private void Para_assert_tag_starts_on_nl(Bry_bfr bfr, int src_bgn) {
if (!bfr.Match_end_byt_nl_or_bos()) bfr.Add_byte_nl();
if (src_bgn != 0) bfr.Add_byte_nl();
}
@gplx.Virtual public void Pre(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_pre_tkn pre) {
switch (pre.Pre_tid()) {
case Xop_pre_tkn.Pre_tid_bgn:
bfr.Add(Tag_pre_bgn);
break;
case Xop_pre_tkn.Pre_tid_end:
bfr.Add_byte_nl().Add(Tag_pre_end).Add_byte_nl().Add_byte_nl();
break;
}
}
@gplx.Virtual public void Bry(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_bry_tkn bry) {
bfr.Add(bry.Val());
}
@gplx.Virtual public void Vnt(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_vnt_tkn vnt) {
Xop_vnt_html_wtr.Write(bfr, this, ctx, hctx, page, src, vnt); // NOTE: using wiki, b/c getting nullPointer with ctx during mass parse
}
@gplx.Virtual public void Under(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_under_tkn under) {
if (hctx.Mode_is_alt()) return;
switch (under.Under_tid()) {
case Xol_kwd_grp_.Id_toc:
wiki.Html_mgr().Toc_mgr().Html(page, hctx, src, bfr);
break;
case Xol_kwd_grp_.Id_notoc: case Xol_kwd_grp_.Id_forcetoc: // NOTE: skip output; changes flag on page only
break;
}
}
@gplx.Virtual public void Xnde(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde) {
if (hctx.Mode_is_alt()) {
if (xnde.Tag_close_bgn() > 0) // NOTE: some tags are not closed; WP.EX: France; <p>
Xoh_html_wtr_escaper.Escape(app.Parser_amp_mgr(), bfr, src, xnde.Tag_open_end(), xnde.Tag_close_bgn(), true, false);
else
Xnde_subs(ctx, hctx, bfr, src, xnde);
return;
}
Xop_xnde_tag tag = xnde.Tag();
int tag_id = tag.Id();
switch (tag_id) {
case Xop_xnde_tag_.Tid_br:
if (xnde.Src_end() - xnde.Src_bgn() < 4
|| xnde.Src_bgn() == -1)
bfr.Add(Tag_br); else bfr.Add_mid(src, xnde.Src_bgn(), xnde.Src_end()); break;
case Xop_xnde_tag_.Tid_hr: bfr.Add(Tag_hr); break;
case Xop_xnde_tag_.Tid_includeonly: // NOTE: do not write tags or content
break;
case Xop_xnde_tag_.Tid_noinclude: // NOTE: do not write tags
case Xop_xnde_tag_.Tid_onlyinclude:
Xnde_subs_escape(ctx, hctx, bfr, src, xnde, false, false);
break;
case Xop_xnde_tag_.Tid_nowiki:
Xnde_subs_escape(ctx, hctx, bfr, src, xnde, false, false);
break;
case Xop_xnde_tag_.Tid_b: case Xop_xnde_tag_.Tid_strong:
case Xop_xnde_tag_.Tid_i: case Xop_xnde_tag_.Tid_em: case Xop_xnde_tag_.Tid_cite: case Xop_xnde_tag_.Tid_dfn: case Xop_xnde_tag_.Tid_var:
case Xop_xnde_tag_.Tid_u: case Xop_xnde_tag_.Tid_ins: case Xop_xnde_tag_.Tid_abbr:
case Xop_xnde_tag_.Tid_strike: case Xop_xnde_tag_.Tid_s: case Xop_xnde_tag_.Tid_del:
case Xop_xnde_tag_.Tid_sub: case Xop_xnde_tag_.Tid_sup: case Xop_xnde_tag_.Tid_big: case Xop_xnde_tag_.Tid_small:
case Xop_xnde_tag_.Tid_code: case Xop_xnde_tag_.Tid_tt: case Xop_xnde_tag_.Tid_kbd: case Xop_xnde_tag_.Tid_samp: case Xop_xnde_tag_.Tid_blockquote:
case Xop_xnde_tag_.Tid_font: case Xop_xnde_tag_.Tid_center:
case Xop_xnde_tag_.Tid_p: case Xop_xnde_tag_.Tid_span: case Xop_xnde_tag_.Tid_div:
case Xop_xnde_tag_.Tid_h1: case Xop_xnde_tag_.Tid_h2: case Xop_xnde_tag_.Tid_h3: case Xop_xnde_tag_.Tid_h4: case Xop_xnde_tag_.Tid_h5: case Xop_xnde_tag_.Tid_h6:
case Xop_xnde_tag_.Tid_dt: case Xop_xnde_tag_.Tid_dd: case Xop_xnde_tag_.Tid_ol: case Xop_xnde_tag_.Tid_ul: case Xop_xnde_tag_.Tid_dl:
case Xop_xnde_tag_.Tid_table: case Xop_xnde_tag_.Tid_tr: case Xop_xnde_tag_.Tid_td: case Xop_xnde_tag_.Tid_th: case Xop_xnde_tag_.Tid_caption: case Xop_xnde_tag_.Tid_tbody:
case Xop_xnde_tag_.Tid_ruby: case Xop_xnde_tag_.Tid_rt: case Xop_xnde_tag_.Tid_rb: case Xop_xnde_tag_.Tid_rp:
case Xop_xnde_tag_.Tid_time: case Xop_xnde_tag_.Tid_bdi: case Xop_xnde_tag_.Tid_data: case Xop_xnde_tag_.Tid_mark: case Xop_xnde_tag_.Tid_wbr: case Xop_xnde_tag_.Tid_bdo: // HTML 5: write literally and let browser handle them
case Xop_xnde_tag_.Tid_q:
Write_xnde(bfr, ctx, hctx, xnde, tag, tag_id, src);
break;
case Xop_xnde_tag_.Tid_pre: {
if (xnde.Tag_open_end() == xnde.Tag_close_bgn()) return; // ignore empty tags, else blank pre line will be printed; DATE:2014-03-12
byte[] name = tag.Name_bry();
bfr.Add_byte(Tag__bgn).Add(name);
if (xnde.Atrs_bgn() > Xop_tblw_wkr.Atrs_ignore_check) Xnde_atrs(tag_id, hctx, src, xnde.Atrs_bgn(), xnde.Atrs_end(), xnde.Atrs_ary(), bfr);
bfr.Add_byte(Tag__end);
Xnde_subs_escape(ctx, hctx, bfr, src, xnde, false, true);
bfr.Add(Tag__end_bgn).Add(name).Add_byte(Tag__end);
break;
}
case Xop_xnde_tag_.Tid_li: {
byte[] name = tag.Name_bry();
int bfr_len = bfr.Len();
if (bfr_len > 0 && bfr.Bfr()[bfr_len - 1] != Byte_ascii.Nl) bfr.Add_byte_nl(); // NOTE: always add nl before li else some lists will merge and force long horizontal bar; EX:w:Music
if (xnde.Tag_visible()) {
bfr.Add_byte(Tag__bgn).Add(name);
if (xnde.Atrs_bgn() > Xop_tblw_wkr.Atrs_ignore_check) Xnde_atrs(tag_id, hctx, src, xnde.Atrs_bgn(), xnde.Atrs_end(), xnde.Atrs_ary(), bfr);
bfr.Add_byte(Tag__end);
}
Xnde_subs(ctx, hctx, bfr, src, xnde);
if (xnde.Tag_visible())
bfr.Add(Tag__end_bgn).Add(name).Add_byte(Tag__end); // NOTE: inline is never written as <b/>; will be written as <b></b>; SEE: NOTE_1
break;
}
case Xop_xnde_tag_.Tid_timeline: {
bfr.Add_str_a7("<pre class='xowa-timeline'>");
Xox_mgr_base.Xtn_write_escape(app, bfr, src, xnde.Tag_open_end(), xnde.Tag_close_bgn()); // NOTE: do not embed <timeline> tag inside pre, else timeline will render in black; EX:<pre><timeline>a</timeline></pre> will fail; DATE:2014-05-22
bfr.Add_str_a7("</pre>");
break;
}
case Xop_xnde_tag_.Tid_source: { // convert <source> to <pre>;
byte[] name = Xop_xnde_tag_.Tag_pre.Name_bry();
bfr.Add_byte(Tag__bgn).Add(name);
if (xnde.Atrs_bgn() > Xop_tblw_wkr.Atrs_ignore_check) Xnde_atrs(tag_id, hctx, src, xnde.Atrs_bgn(), xnde.Atrs_end(), xnde.Atrs_ary(), bfr);
bfr.Add_byte(Tag__end);
int tag_close_bgn = Bry_finder.Find_bwd_while(src, xnde.Tag_close_bgn(), -1, Byte_ascii.Space) + 1; // trim space from end; PAGE:en.w:Comment_(computer_programming) DATE:2014-06-23
Xoh_html_wtr_escaper.Escape(app.Parser_amp_mgr(), bfr, src, xnde.Tag_open_end(), tag_close_bgn, false, false); // <source> is a .Xtn(); render literally everything between > and <; DATE:2014-03-11
bfr.Add(Tag__end_bgn).Add(name).Add_byte(Tag__end);
break;
}
case Xop_xnde_tag_.Tid_gallery:
case Xop_xnde_tag_.Tid_poem:
case Xop_xnde_tag_.Tid_hiero:
case Xop_xnde_tag_.Tid_score:
case Xop_xnde_tag_.Tid_ref:
case Xop_xnde_tag_.Tid_references:
case Xop_xnde_tag_.Tid_inputBox:
case Xop_xnde_tag_.Tid_imageMap:
case Xop_xnde_tag_.Tid_pages:
case Xop_xnde_tag_.Tid_pagequality:
case Xop_xnde_tag_.Tid_pagelist:
case Xop_xnde_tag_.Tid_section:
case Xop_xnde_tag_.Tid_translate:
case Xop_xnde_tag_.Tid_dynamicPageList:
case Xop_xnde_tag_.Tid_languages:
case Xop_xnde_tag_.Tid_templateData:
case Xop_xnde_tag_.Tid_syntaxHighlight:
case Xop_xnde_tag_.Tid_listing_buy:
case Xop_xnde_tag_.Tid_listing_do:
case Xop_xnde_tag_.Tid_listing_drink:
case Xop_xnde_tag_.Tid_listing_eat:
case Xop_xnde_tag_.Tid_listing_listing:
case Xop_xnde_tag_.Tid_listing_see:
case Xop_xnde_tag_.Tid_listing_sleep:
case Xop_xnde_tag_.Tid_xowa_cmd:
case Xop_xnde_tag_.Tid_rss:
case Xop_xnde_tag_.Tid_quiz:
case Xop_xnde_tag_.Tid_math:
case Xop_xnde_tag_.Tid_indicator:
case Xop_xnde_tag_.Tid_xowa_html:
Xox_xnde xtn = xnde.Xnde_xtn();
xtn.Xtn_write(bfr, app, ctx, this, hctx, xnde, src);
break;
case Xop_xnde_tag_.Tid_xowa_tag_bgn:
case Xop_xnde_tag_.Tid_xowa_tag_end:
break;
default: // unknown tag
if (tag.Restricted()) { // a; img; script; etc..
if ( !page.Html_data().Html_restricted() // page is not marked restricted (only [[Special:]])
|| page.Wiki().Domain_tid() == Xow_domain_type_.Tid_home) { // page is in home wiki
bfr.Add_mid(src, xnde.Src_bgn(), xnde.Src_end());
return;
}
}
bfr.Add(Ary_escape_bgn).Add(tag.Name_bry()); // escape bgn
if (xnde.Atrs_bgn() > Xop_tblw_wkr.Atrs_ignore_check) Xnde_atrs(tag_id, hctx, src, xnde.Atrs_bgn(), xnde.Atrs_end(), xnde.Atrs_ary(), bfr);
switch (xnde.CloseMode()) {
case Xop_xnde_tkn.CloseMode_inline:
bfr.Add_byte(Byte_ascii.Slash).Add(Ary_escape_end);
break;
default: // NOTE: close tag, even if dangling; EX: <center>a -> <center>a</center>
bfr.Add_byte(Byte_ascii.Gt);
Xnde_subs(ctx, hctx, bfr, src, xnde);
bfr.Add(Ary_escape_bgn).Add_byte(Byte_ascii.Slash).Add(tag.Name_bry()).Add(Ary_escape_end);
break;
}
break;
}
}
private void Write_xnde(Bry_bfr bfr, Xop_ctx ctx, Xoh_wtr_ctx hctx, Xop_xnde_tkn xnde, Xop_xnde_tag tag, int tag_id, byte[] src) {
byte[] name = tag.Name_bry();
boolean at_bgn = true;
Bry_bfr ws_bfr = wiki.Utl__bfr_mkr().Get_b512(); // create separate ws_bfr to handle "a<b> c </b>d" -> "a <b>c</b> d"
int subs_len = xnde.Subs_len();
for (int i = 0; i < subs_len; i++) {
Xop_tkn_itm sub = xnde.Subs_get(i);
byte tkn_tid = sub.Tkn_tid();
switch (tkn_tid) {
case Xop_tkn_itm_.Tid_space: // space; add to ws_bfr;
ws_bfr.Add_mid(src, sub.Src_bgn(), sub.Src_end());
break;
default:
if (tkn_tid == Xop_tkn_itm_.Tid_html_ncr) { // html_entity &#32; needed for fr.wikipedia.org and many spans with <span>&#32;</span>; DATE:2013-06-18
Xop_amp_tkn_num ncr_tkn = (Xop_amp_tkn_num)sub;
if (ncr_tkn.Val() == Byte_ascii.Space
|| ncr_tkn.Val() == 160
) {
ws_bfr.Add_mid(src, ncr_tkn.Src_bgn(), ncr_tkn.Src_end());
continue; // just add entity; don't process rest;
}
}
if (ws_bfr.Len() > 0) bfr.Add_bfr_and_clear(ws_bfr); // dump ws_bfr to real bfr
if (at_bgn) { // 1st non-ws tkn; add open tag; <b>
at_bgn = false;
bfr.Add_byte(Tag__bgn).Add(name);
if (xnde.Atrs_bgn() > Xop_tblw_wkr.Atrs_ignore_check) Xnde_atrs(tag_id, hctx, src, xnde.Atrs_bgn(), xnde.Atrs_end(), xnde.Atrs_ary(), bfr);
bfr.Add_byte(Tag__end);
}
Write_tkn(bfr, ctx, hctx, src, xnde, i, sub); // NOTE: never escape; <p>, <table>, <center> etc may have nested nodes
break;
}
}
if (at_bgn) { // occurs when xnde is empty; EX: <b></b>
bfr.Add_byte(Tag__bgn).Add(name);
if (xnde.Atrs_bgn() > Xop_tblw_wkr.Atrs_ignore_check) Xnde_atrs(tag_id, hctx, src, xnde.Atrs_bgn(), xnde.Atrs_end(), xnde.Atrs_ary(), bfr);
bfr.Add_byte(Tag__end);
}
bfr.Add(Tag__end_bgn).Add(name).Add_byte(Tag__end); // NOTE: inline is never written as <b/>; will be written as <b></b>; SEE: NOTE_1
if (ws_bfr.Len() > 0) bfr.Add_bfr_and_clear(ws_bfr); // dump any leftover ws to bfr; handles "<b>c </b>" -> "<b>c</b> "
ws_bfr.Mkr_rls();
}
public void Xnde_atrs(int tag_id, Xoh_wtr_ctx hctx, byte[] src, int bgn, int end, Xop_xatr_itm[] ary, Bry_bfr bfr) {
if (ary == null) return; // NOTE: some nodes will have null xatrs b/c of whitelist; EX: <pre style="overflow:auto">a</pre>; style is not on whitelist so not xatr generated, but xatr_bgn will != -1
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
Xop_xatr_itm atr = ary[i];
if (atr.Invalid()) continue;
if (!whitelist_mgr.Chk(tag_id, src, atr)) continue;
Xnde_atr_write(bfr, app, hctx, src, atr);
}
}
public static void Xnde_atr_write(Bry_bfr bfr, Xoae_app app, Xoh_wtr_ctx hctx, byte[] src, Xop_xatr_itm atr) {
byte[] atr_key = atr.Key_bry();
if ( hctx.Mode_is_display_title()
&& Xoh_display_ttl_wtr._.Is_style_restricted(bfr, hctx, src, atr, atr_key))
return;
bfr.Add_byte(Byte_ascii.Space); // add space before every attribute
if (atr_key != null) {
bfr.Add(atr_key);
bfr.Add_byte(Byte_ascii.Eq);
}
byte quote_byte = atr.Quote_byte(); if (quote_byte == Byte_ascii.Nil) quote_byte = Byte_ascii.Quote;
bfr.Add_byte(quote_byte);
if (atr.Key_tid() == Xop_xatr_itm.Key_tid_id) { // ids should not have spaces; DATE:2013-04-01
if (atr.Val_bry() == null)
Xnde_atr_write_id(bfr, app, src, atr.Val_bgn(), atr.Val_end());
else {
byte[] atr_val = atr.Val_bry();
Xnde_atr_write_id(bfr, app, atr_val, 0, atr_val.length);
}
}
else {
if (atr.Val_bry() == null)
bfr.Add_mid(src, atr.Val_bgn(), atr.Val_end());
else
bfr.Add(atr.Val_bry());
}
bfr.Add_byte(quote_byte);
}
private static void Xnde_atr_write_id(Bry_bfr bfr, Xoae_app app, byte[] bry, int bgn, int end) {
Xoa_app_.Utl__encoder_mgr().Id().Encode(bfr, bry, bgn, end);
}
private void Xnde_subs(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde) {
int subs_len = xnde.Subs_len();
for (int i = 0; i < subs_len; i++)
Write_tkn(bfr, ctx, hctx, src, xnde, i, xnde.Subs_get(i));
}
private void Xnde_subs_escape(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde, boolean amp_enable, boolean nowiki) {
int xndesubs_len = xnde.Subs_len();
for (int i = 0; i < xndesubs_len; i++) {
Xop_tkn_itm sub = xnde.Subs_get(i);
switch (sub.Tkn_tid()) {
case Xop_tkn_itm_.Tid_xnde:
Xop_xnde_tkn sub_xnde = (Xop_xnde_tkn)sub;
switch (sub_xnde.Tag().Id()) {
case Xop_xnde_tag_.Tid_noinclude:
case Xop_xnde_tag_.Tid_onlyinclude:
case Xop_xnde_tag_.Tid_includeonly:
break;
default:
byte[] tag_name = sub_xnde.Tag().Name_bry();
bfr.Add(Html_entity_.Lt_bry).Add(tag_name);
if (xnde.Atrs_bgn() > Xop_tblw_wkr.Atrs_ignore_check) Xnde_atrs(sub_xnde.Tag().Id(), hctx, src, sub_xnde.Atrs_bgn(), sub_xnde.Atrs_end(), xnde.Atrs_ary(), bfr);
bfr.Add(Html_entity_.Gt_bry);
break;
}
Xnde_subs_escape(ctx, hctx, bfr, src, sub_xnde, amp_enable, false);
break;
case Xop_tkn_itm_.Tid_txt:
if (amp_enable)
bfr.Add_mid(src, sub.Src_bgn(), sub.Src_end());
else
Xoh_html_wtr_escaper.Escape(app.Parser_amp_mgr(), bfr, src, sub.Src_bgn(), sub.Src_end(), true, nowiki);
break;
default:
Write_tkn(bfr, ctx, hctx, src, xnde, i, sub);
break;
}
}
}
public void Tblw(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_tblw_tkn tkn, byte[] bgn, byte[] end, boolean tblw_bgn) {
if (hctx.Mode_is_alt()) // add \s for each \n
bfr.Add_byte_space();
else {
bfr.Add_byte_if_not_last(Byte_ascii.Nl);
if (indent_level > 0) bfr.Add_byte_repeat(Byte_ascii.Space, indent_level * 2);
// boolean para_mode = tblw_bgn && tbl_para && depth == 1; // DELETE: old code; adding <p> to handle strange mozilla key down behavior on linux; DATE:2013-03-30
// if (para_mode) {bfr.Add(Xoh_consts.P_bgn);}
bfr.Add(bgn);
int atrs_bgn = tkn.Atrs_bgn();
if (atrs_bgn != -1) Xnde_atrs(tkn.Tblw_tid(), hctx, src, atrs_bgn, tkn.Atrs_end(), tkn.Atrs_ary(), bfr); //bfr.Add_byte(Byte_ascii.Space).Add_mid(src, atrs_bgn, tkn.Atrs_end());
bfr.Add_byte(Tag__end);
++indent_level;
}
int subs_len = tkn.Subs_len();
for (int i = 0; i < subs_len; i++)
Write_tkn(bfr, ctx, hctx, src, tkn, i, tkn.Subs_get(i));
if (hctx.Mode_is_alt()) {
if (tblw_bgn) // only add \s for closing table; |} -> "\s"
bfr.Add_byte_space();
}
else {
--indent_level;
bfr.Add_byte_if_not_last(Byte_ascii.Nl);
if (indent_level > 0) bfr.Add_byte_repeat(Byte_ascii.Space, indent_level * 2);
bfr.Add(end);
// if (para_mode) {bfr.Add(Xoh_consts.P_end);} // DELETE: old code; adding <p> to handle strange mozilla key down behavior on linux; DATE:2013-03-30
bfr.Add_byte_if_not_last(Byte_ascii.Nl);
// bfr.Add_byte_nl();
}
}
public static final byte[] Tag__end_quote = Bry_.new_a7("\">"), Tag__end_bgn = Bry_.new_a7("</")
, Tag_hdr_bgn = Bry_.new_a7("<h"), Tag_hdr_end = Bry_.new_a7("</h"), Tag_hr = Bry_.new_a7("<hr/>"), Tag_br = Bry_.new_a7("<br/>")
, Tag_list_grp_ul_bgn = Bry_.new_a7("<ul>"), Tag_list_grp_ul_end = Bry_.new_a7("</ul>")
, Tag_list_grp_ol_bgn = Bry_.new_a7("<ol>"), Tag_list_grp_ol_end = Bry_.new_a7("</ol>")
, Tag_list_itm_li_bgn = Bry_.new_a7("<li>"), Tag_list_itm_li_end = Bry_.new_a7("</li>")
, Tag_list_itm_dt_bgn = Bry_.new_a7("<dt>"), Tag_list_itm_dt_end = Bry_.new_a7("</dt>")
, Tag_list_itm_dd_bgn = Bry_.new_a7("<dd>"), Tag_list_itm_dd_end = Bry_.new_a7("</dd>")
, Tag_list_grp_dl_bgn = Bry_.new_a7("<dl>"), Tag_list_grp_dl_end = Bry_.new_a7("</dl>")
, File_divider = Bry_.new_a7("---------------------------------")
, Tag_tblw_tb_bgn = Bry_.new_a7("<table>"), Tag_tblw_tb_bgn_atr = Bry_.new_a7("<table"), Tag_tblw_tb_end = Bry_.new_a7("</table>")
, Tag_tblw_tr_bgn = Bry_.new_a7("<tr>"), Tag_tblw_tr_bgn_atr = Bry_.new_a7("<tr"), Tag_tblw_tr_end = Bry_.new_a7("</tr>")
, Tag_tblw_td_bgn = Bry_.new_a7("<td>"), Tag_tblw_td_bgn_atr = Bry_.new_a7("<td"), Tag_tblw_td_end = Bry_.new_a7("</td>")
, Tag_tblw_th_bgn = Bry_.new_a7("<th>"), Tag_tblw_th_bgn_atr = Bry_.new_a7("<th"), Tag_tblw_th_end = Bry_.new_a7("</th>")
, Tag_tblw_tc_bgn = Bry_.new_a7("<caption>"), Tag_tblw_tc_bgn_atr = Bry_.new_a7("<caption"), Tag_tblw_tc_end = Bry_.new_a7("</caption>")
, Ary_escape_bgn = Bry_.new_a7("&lt;"), Ary_escape_end = Bry_.new_a7("&gt;"), Ary_escape_end_bgn = Bry_.new_a7("&lt;/")
, Tag_para_bgn = Bry_.new_a7("<p>"), Tag_para_end = Bry_.new_a7("</p>"), Tag_para_mid = Bry_.new_a7("</p>\n\n<p>")
, Tag_pre_bgn = Bry_.new_a7("<pre>"), Tag_pre_end = Bry_.new_a7("</pre>")
;
private static final byte[] Tag_hdr__div_wrapper_bgn = Bry_.new_a7("<div>\n"), Tag_hdr__div_wrapper_end = Bry_.new_a7("</div>\n");
public static final byte Tag__bgn = Byte_ascii.Lt, Tag__end = Byte_ascii.Gt;
public static final byte Dir_spr_http = Byte_ascii.Slash;
private int indent_level = 0;
public static final int Sub_idx_null = -1; // nonsense placeholder
}
class Xoh_display_ttl_wtr {
private static final byte[]
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_()
.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
&& Bry_.Eq(atr_key, Atr_key_style)
) {
byte[] atr_val = atr.Val_as_bry(src); if (atr_val == null) return false; // bounds_chk
int atr_val_len = atr_val.length;
int atr_pos = 0;
while (atr_pos < atr_val_len) {
byte b = atr_val[atr_pos];
Object o = style_trie.Match_bgn_w_byte(b, atr_val, atr_pos, atr_val_len);
if (o != null) {
bfr.Add(Msg_style_restricted);
return true;
}
++atr_pos;
}
}
return false;
}
public static final Xoh_display_ttl_wtr _ = new Xoh_display_ttl_wtr(); Xoh_display_ttl_wtr() {}
}
/*
NOTE_1:inline always written as <tag></tag>, not <tag/>
see WP:Permian<61>Triassic extinction event
this will cause firefox to swallow up rest of text
<div id="ScaleBar" style="width:1px; float:left; height:38em; padding:0; background-color:#242020" />
this will not
<div id="ScaleBar" style="width:1px; float:left; height:38em; padding:0; background-color:#242020" ></div>
*/

View File

@@ -0,0 +1,25 @@
/*
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; import gplx.*; import gplx.xowa.*;
public class Xoh_html_wtr_cfg {
public boolean Toc__show() {return toc__show;} public Xoh_html_wtr_cfg Toc__show_(boolean v) {toc__show = v; return this;} private boolean toc__show;
public boolean Lnki__id() {return lnki__id;} public Xoh_html_wtr_cfg Lnki__id_y_() {lnki__id = Bool_.Y; return this;} private boolean lnki__id;
public boolean Lnki__title() {return lnki__title;} public Xoh_html_wtr_cfg Lnki__title_(boolean v) {lnki__title = v; return this;} private boolean lnki__title;
public boolean Lnki__visited() {return lnki__visited;} public Xoh_html_wtr_cfg Lnki_visited_y_() {lnki__visited = true; return this;} private boolean lnki__visited;
public boolean Hdr__div_wrapper() {return hdr__div_wrapper;} public Xoh_html_wtr_cfg Hdr__div_wrapper_(boolean v) {hdr__div_wrapper = v; return this;} private boolean hdr__div_wrapper;
}

View File

@@ -0,0 +1,123 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.core.btries.*; import gplx.html.*; import gplx.xowa.parsers.amps.*;
public class Xoh_html_wtr_escaper {
public static byte[] Escape(Xop_amp_mgr amp_mgr, Bry_bfr tmp_bfr, byte[] src) {
Escape(amp_mgr, tmp_bfr, src, 0, src.length, true, false);
return tmp_bfr.Xto_bry_and_clear();
}
public static void Escape(Xop_amp_mgr amp_mgr, Bry_bfr bfr, byte[] src, int bgn, int end, boolean interpret_amp, boolean nowiki_skip) {
Btrie_slim_mgr amp_trie = amp_mgr.Amp_trie();
for (int i = bgn; i < end; i++) {
byte b = src[i];
switch (b) {
case Byte_ascii.Lt:
if (nowiki_skip) {
byte[] nowiki_name = Xop_xnde_tag_.Tag_nowiki.Name_bry();
int nowiki_name_len = nowiki_name.length;
if (Bry_.Eq(nowiki_name, src, i + 1, i + 1 + nowiki_name_len)) { // <nowiki found;
int end_gt = Escape_nowiki_skip(bfr, src, i, end, nowiki_name, nowiki_name_len);
if (end_gt != Bry_.NotFound) {
i = end_gt;
continue;
}
}
}
bfr.Add(Html_entity_.Lt_bry);
break;
case Byte_ascii.Gt:
bfr.Add(Html_entity_.Gt_bry);
break;
case Byte_ascii.Amp:
if (interpret_amp) {
int text_bgn = i + 1; // i is &; i + 1 is first char after amp
Object o = (text_bgn < end) ? amp_trie.Match_bgn(src, text_bgn, end) : null; // check if this is a valid &; note must check that text_bgn < end or else arrayIndex error; occurs when src is just "&"; DATE:2013-12-19
if (o == null) // invalid; EX: "a&b"; "&bad;"; "&#letters;";
bfr.Add(Html_entity_.Amp_bry); // escape & and continue
else { // is either (1) a name or (2) an ncr (hex/dec)
Xop_amp_trie_itm itm = (Xop_amp_trie_itm)o;
int match_pos = amp_trie.Match_pos();
int itm_tid = itm.Tid();
switch (itm_tid) {
case Xop_amp_trie_itm.Tid_name_std:
case Xop_amp_trie_itm.Tid_name_xowa: // name
bfr.Add_mid(src, i, match_pos); // embed entire name
i = match_pos - 1;
break;
case Xop_amp_trie_itm.Tid_num_dec:
case Xop_amp_trie_itm.Tid_num_hex: // ncr: dec/hex
boolean pass = amp_mgr.Parse_as_int(itm_tid == Xop_amp_trie_itm.Tid_num_hex, src, end, i, match_pos);
int end_pos = amp_mgr.Rslt_pos();
if (pass) { // parse worked; embed entire ncr
bfr.Add_mid(src, i, end_pos);
i = end_pos - 1;
}
else // parse failed; escape and continue
bfr.Add(Html_entity_.Amp_bry);
break;
default: throw Exc_.new_unhandled(itm_tid);
}
}
}
else
bfr.Add(Html_entity_.Amp_bry);
break;
case Byte_ascii.Quote:
bfr.Add(Html_entity_.Quote_bry);
break;
default:
bfr.Add_byte(b);
break;
}
}
}
private static int Escape_nowiki_skip(Bry_bfr bfr, byte[] src, int bgn, int end, byte[] nowiki_name, int nowiki_name_len) {
try {
boolean tag_is_bgn = true;
int bgn_gt = -1, end_lt = -1, end_gt = -1;
for (int i = bgn + nowiki_name_len; i < end; i++) {
byte b = src[i];
switch (b) {
case Byte_ascii.Gt:
if (tag_is_bgn) {bgn_gt = i; tag_is_bgn = false;}
else return Bry_.NotFound; // <nowiki>> found
break;
case Byte_ascii.Lt:
if ( tag_is_bgn // <nowiki < found
|| (i + nowiki_name_len + 2 > end) // not enough chars for "/nowiki>"
|| src[i + 1] != Byte_ascii.Slash // /
|| !Bry_.Eq(nowiki_name, src, i + 2, i + 2 + nowiki_name_len) // nowiki
|| src[i + 2 + nowiki_name_len] != Byte_ascii.Gt // >
) return Bry_.NotFound;
end_lt = i;
end_gt = i + 2 + nowiki_name_len;
i = end;
break;
}
}
if (end_gt == -1) return Bry_.NotFound; // ">" of </nowiki> not found
bfr.Add_mid(src, bgn_gt + 1, end_lt);
return end_gt;
}
catch (Exception e) {
Xoa_app_.Usr_dlg().Warn_many("", "", "unknown error in escape.nowiki: ~{0} ~{1}", Err_.Message_gplx_brief(e), String_.new_u8(src, bgn, end));
return Bry_.NotFound;
}
}
}

View File

@@ -0,0 +1,357 @@
/*
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; import gplx.*; import gplx.xowa.*;
import org.junit.*;
public class Xoh_html_wtr_tst {
private Xop_fxt fxt = new Xop_fxt();
@After public void term() {fxt.Init_para_n_(); fxt.Reset();}
@Test public void Hr_basic() {fxt.Test_parse_page_wiki_str("----" , "<hr/>");}
@Test public void Hr_extended() {fxt.Test_parse_page_wiki_str("--------" , "<hr/>");}
@Test public void Lnki_basic() {fxt.Test_parse_page_wiki_str("[[a]]" , "<a href=\"/wiki/A\">a</a>");}
@Test public void Lnki_caption() {fxt.Test_parse_page_wiki_str("[[a|b]]" , "<a href=\"/wiki/A\">b</a>");}
@Test public void Lnki_caption_fmt() {fxt.Test_parse_page_wiki_str("[[a|''b'']]" , "<a href=\"/wiki/A\"><i>b</i></a>");}
@Test public void Lnki_tail_trg() {fxt.Test_parse_page_wiki_str("[[a]]b" , "<a href=\"/wiki/A\">ab</a>");}
@Test public void Lnki_tail_caption() {fxt.Test_parse_page_wiki_str("[[a|b]]c" , "<a href=\"/wiki/A\">bc</a>");}
@Test public void Lnki_title() {
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_wiki_str("[[a|b]]", "<a href=\"/wiki/A\" title=\"A\">b</a>");
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Lnki_title_page_text() {
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_wiki_str("[[a_b]]", "<a href=\"/wiki/A_b\" title=\"A b\">a_b</a>");
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Lnki_category() {fxt.Test_parse_page_wiki_str("[[Category:A]]" , "");} // NOTE: Category does not get written in main page bfr
@Test public void Lnki_category_force() {fxt.Test_parse_page_wiki_str("[[:Category:A]]" , "<a href=\"/wiki/Category:A\">Category:A</a>");}
@Test public void Lnki_matches_page() {fxt.Test_parse_page_wiki_str("[[test page|t1]]", "<b>t1</b>");} // NOTE: "Test page" is hardcoded to be the test page name
@Test public void Lnki_matches_page_but_has_anchor() {fxt.Test_parse_page_wiki_str("[[Test page#a|test 1]]", "<a href=\"/wiki/Test_page#a\">test 1</a>");} // NOTE: "Test page" is hardcoded to be the test page name
@Test public void Lnki_anchor() {fxt.Test_parse_page_wiki_str("[[A#b]]" , "<a href=\"/wiki/A#b\">A#b</a>");}
// @Test public void Img_invalid_wnt_char() {
// fxt.Test_parse_page_wiki_str
// ( "[[File:A*b.png]]"
// , "<div class=\"floatnone\"><a href=\"File:A.png\" class=\"image\"><img alt=\"\" src=\"\" width=\"20\" height=\"30\" /></a></div>"
// );
// }
// @Test public void Img_alt() { // FUTURE: enable; WHEN: after fixing xnde to handle bad xnde; EX: France
// fxt.Test_parse_page_wiki_str("[[File:A.png|none|9x8px|alt=a<b>b</b>\"c\"d]]", Xop_fxt.html_img_none("File:A.png", "ab&quot;c&quot;d"));
// }
@Test public void Url_encode() {fxt.Test_parse_page_wiki_str("[[a;@$!*(),/ _^b|z]]" , "<a href=\"/wiki/A;@$!*(),/_%5Eb\">z</a>");} // NOTE: was "a" instead of "A"; "__" instead of "_" DATE:2014-09-07
@Test public void Url_encode_space() {fxt.Test_parse_page_wiki_str("[[a _b|z]]" , "<a href=\"/wiki/A_b\">z</a>");}
@Test public void Apos_i() {fxt.Test_parse_page_wiki_str("''a''" , "<i>a</i>");}
@Test public void Apos_b() {fxt.Test_parse_page_wiki_str("'''a'''" , "<b>a</b>");}
@Test public void Apos_ib() {fxt.Test_parse_page_wiki_str("'''''a'''''" , "<i><b>a</b></i>");}
@Test public void Html_ent() {fxt.Test_parse_page_wiki_str("&#33;" , "&#33;");} // PURPOSE:ncrs should be literal, not decoded (!); DATE:2014-11-06
@Test public void Html_ref() {fxt.Test_parse_page_wiki_str("&gt;" , "&gt;");}
@Test public void List_1_itm() {
fxt.Test_parse_page_wiki_str("*a", String_.Concat_lines_nl_skip_last
( "<ul>"
, " <li>a"
, " </li>"
, "</ul>"
));
}
@Test public void List_2_itms() {
fxt.Test_parse_page_wiki_str("*a\n*b", String_.Concat_lines_nl_skip_last
( "<ul>"
, " <li>a"
, " </li>"
, " <li>b"
, " </li>"
, "</ul>"
));
}
@Test public void List_nest_ul() {
fxt.Test_parse_page_wiki_str("*a\n**b", String_.Concat_lines_nl_skip_last
( "<ul>"
, " <li>a"
, " <ul>"
, " <li>b"
, " </li>"
, " </ul>"
, " </li>"
, "</ul>"
));
}
@Test public void List_dt_dd() {
fxt.Test_parse_page_wiki_str(";a:b", String_.Concat_lines_nl_skip_last
( "<dl>"
, " <dt>a"
, " </dt>"
, " <dd>b"
, " </dd>"
, "</dl>"
));
}
@Test public void List_dd_nest2() {
fxt.Test_parse_page_wiki_str("::a", String_.Concat_lines_nl_skip_last
( "<dl>"
, " <dd>"
, " <dl>"
, " <dd>a"
, " </dd>"
, " </dl>"
, " </dd>"
, "</dl>"
));
}
@Test public void Tblw_basic() {
fxt.Test_parse_page_wiki_str("{|\n|+a\n!b||c\n|-\n|d||e\n|}", String_.Concat_lines_nl
( "<table>"
, " <caption>a"
, " </caption>"
, " <tr>"
, " <th>b"
, " </th>"
, " <th>c"
, " </th>"
, " </tr>"
, " <tr>"
, " <td>d"
, " </td>"
, " <td>e"
, " </td>"
, " </tr>"
, "</table>"
));
}
@Test public void Tblw_atrs() {
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "{|style='z'"
, "|+a"
, "!style='y'|b||style='x'|c"
, "|-style='w'"
, "|style='v'|d||style='u'|e"
, "|}"
), String_.Concat_lines_nl
( "<table style='z'>"
, " <caption>a"
, " </caption>"
, " <tr>"
, " <th style='y'>b"
, " </th>"
, " <th style='x'>c"
, " </th>"
, " </tr>"
, " <tr style='w'>"
, " <td style='v'>d"
, " </td>"
, " <td style='u'>e"
, " </td>"
, " </tr>"
, "</table>"
));
}
@Test public void Para_hdr_list() {
fxt.Init_para_y_();
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "==a=="
, ""
, "*b"
, "*c"
), String_.Concat_lines_nl_skip_last
( "<h2>a</h2>"
, ""
, "<ul>"
, " <li>b"
, " </li>"
, " <li>c"
, " </li>"
, "</ul>"
));
fxt.Init_para_n_();
}
@Test public void Para_nl_is_space() {
fxt.Init_para_y_();
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "a"
, "b"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "b"
, "</p>"
, ""
));
fxt.Init_para_n_();
}
@Test public void Para_nl_2_2() {
fxt.Init_para_y_();
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "a"
, ""
, "b"
, ""
, "c"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, ""
, "<p>b"
, "</p>"
, ""
, "<p>c"
, "</p>"
, ""
));
fxt.Init_para_n_();
}
@Test public void Div_2() { // WP:[[Air]]#Density of air
fxt.Init_para_y_();
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "<div>a</div>"
, ""
, "<div>b</div>"
), String_.Concat_lines_nl_skip_last
( "<div>a</div>"
, "<div>b</div>"
));
fxt.Init_para_n_();
}
@Test public void Tblw() {
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
( "{|"
, "|-"
, "|a"
, "|b"
, "|-"
, "|c"
, "|d"
, "|}"
)
, String_.Concat_lines_nl
( "<table>"
, " <tr>"
, " <td>a"
, " </td>"
, " <td>b"
, " </td>"
, " </tr>"
, " <tr>"
, " <td>c"
, " </td>"
, " <td>d"
, " </td>"
, " </tr>"
, "</table>"
, ""
));
}
@Test public void Tblw_lnki_bang() {
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
( "{|"
, "|-"
, "|[[a|!]]"
, "|}"
)
, String_.Concat_lines_nl
( "<table>"
, " <tr>"
, " <td><a href=\"/wiki/A\">!</a>"
, " </td>"
, " </tr>"
, "</table>"
, ""
));
}
@Test public void Tr_inside_tblw_td() { // WP:[[Earth]]
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
( "{|"
, "|-"
, "<tr><td>a</td></tr>"
, "|}"
)
, String_.Concat_lines_nl
( "<table>"
, " <tr>"
, " <td>a"
, " </td>"
, " </tr>"
, "</table>"
, ""
));
}
@Test public void Tblw_tr_with_newlines() {// WP:[[John Adams]] Infobox Officeholder
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
( "{|"
, "|-"
, ""
, ""
, ""
, "|a"
, "|}"
)
, String_.Concat_lines_nl
( "<table>"
, " <tr>"
, " <td>a"
, " </td>"
, " </tr>"
, "</table>"
, ""
));
}
@Test public void Bang_doesnt_force_tbl() {
fxt.Init_para_y_();
fxt.Test_parse_page_wiki_str("a! b! c", "<p>a! b! c\n</p>\n");
fxt.Init_para_n_();
}
@Test public void Err_nlOnly() {
fxt.Test_parse_page_wiki_str("{{\n}}", "{{\n}}"); // NOTE: was {{}}
}
@Test public void Xnde_inline() {
fxt.Test_parse_page_wiki_str("<div/>", "<div></div>");
}
@Test public void Xnde_id_encode() { // PURPOSE: id should be url-encoded; DATE: 2013-11-13;
fxt.Test_parse_page_wiki_str("<div id='a*'></div>", "<div id='a.2A'></div>");
fxt.Test_parse_page_wiki_str("<div id='a b'></div>", "<div id='a_b'></div>");
}
@Test public void Math() {
fxt.App().File_mgr().Math_mgr().Renderer_is_mathjax_(false);
fxt.Test_parse_page_all_str("<math>x + y</math>", "<img id='xowa_math_img_0' src='' width='' height=''/><span id='xowa_math_txt_0'>x + y</span>"); // latex has img
fxt.App().File_mgr().Math_mgr().Renderer_is_mathjax_(true);
fxt.Test_parse_page_all_str("<math>x + y</math>", "<span id='xowa_math_txt_0'>x + y</span>"); // mathjax has no img
fxt.App().File_mgr().Math_mgr().Renderer_is_mathjax_(false);
}
@Test public void Timeline() {// PURPOSE: embed timeline contents in pre; DATE:2014-05-22
fxt.Test_parse_page_wiki_str("<timeline>a</timeline>", "<pre class='xowa-timeline'>a</pre>");
}
@Test public void Amp_ncr_should_not_be_rendered_as_bytes() { // PURPOSE: &#160; should be rendered as &#160; not as literal bytes {192,160}; DATE:2013-12-09
fxt.Test_parse_page_wiki_str("a&#160;b", "a&#160;b");
}
// @Test public void Fix_PositionAbsolute_stripped() {
// fxt.Test_parse_page_wiki_str("<span style=\"position:absolute;\"></span>", "<span style=\";\"></span>");
// }
// @Test public void Xnde_nl() {
// fxt.Test_parse_page_wiki_str("<div id='a'\nclass='b'>c</div>", String_.Concat_lines_nl_skip_last
// ( "<div id='a' class='b'>c</div>"
// ));
// }
// @Test public void Tblw() {
// fxt.Test_parse_page_wiki_str("{|\n|}", String_.Concat_lines_nl
// ( "<table>"
// , " <tr>"
// , " <td>a"
// , " </td>"
// , " <td>b"
// , " </td>"
// , " </tr>"
// , "</table>"
// ));
// }
}

View File

@@ -0,0 +1,36 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.core.primitives.*;
import gplx.xowa.wikis.*;
public class Xoh_imgs_mgr implements GfoInvkAble {
public Xoh_imgs_mgr(Xow_html_mgr html_mgr) {wiki_is_default = html_mgr.Wiki().Domain_tid() == Xow_domain_type_.Tid_home;} private boolean wiki_is_default;
public Bool_obj_ref Alt_in_caption() {return alt_in_caption;} Bool_obj_ref alt_in_caption = Bool_obj_ref.y_();
public Bool_obj_ref Alt_defaults_to_caption() {return alt_defaults_to_caption;} Bool_obj_ref alt_defaults_to_caption = Bool_obj_ref.y_();
public void Copy_cfg(Xoh_imgs_mgr copy) {this.alt_in_caption = copy.alt_in_caption;}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_alt_in_caption)) return Yn.Xto_str(alt_in_caption.Val());
else if (ctx.Match(k, Invk_alt_in_caption_)) alt_in_caption = Modify(wiki_is_default, alt_in_caption, m.ReadYn("v"));
else if (ctx.Match(k, Invk_alt_defaults_to_caption)) return Yn.Xto_str(alt_defaults_to_caption.Val());
else if (ctx.Match(k, Invk_alt_defaults_to_caption_)) alt_defaults_to_caption = Modify(wiki_is_default, alt_defaults_to_caption, m.ReadYn("v"));
else return GfoInvkAble_.Rv_unhandled;
return this;
}
public static final String Invk_alt_in_caption = "alt_in_caption", Invk_alt_in_caption_ = "alt_in_caption_", Invk_alt_defaults_to_caption = "alt_defaults_to_caption", Invk_alt_defaults_to_caption_ = "alt_defaults_to_caption_";
private static Bool_obj_ref Modify(boolean orig, Bool_obj_ref cur, boolean v) {return orig ? cur.Val_(v) : Bool_obj_ref.new_(v);}
}

View File

@@ -0,0 +1,62 @@
/*
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; 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 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";
public float Font_size() {return font_size;} private float font_size = Font_size_default;
public void Font_size_(float v) {
font_size = v;
this.Font_css_bry_update();
}
public Bry_fmtr Font_css_fmtr() {return font_css_fmtr;} private Bry_fmtr font_css_fmtr = Bry_fmtr.new_("body {font-family: ~{font_name}; font-size: ~{font_size}px;}", "font_name", "font_size");
public Bry_fmtr Content_code_fmtr() {return content_code_fmtr;} private Bry_fmtr content_code_fmtr = Bry_fmtr.new_("<pre>~{page_text}</pre>", "page_text");
private void Font_css_fmtr_(byte[] bry) {
font_css_fmtr.Fmt_(bry);
Font_css_bry_update();
}
public byte[] Font_css_bry() {return font_css_bry;}
public void Font_css_bry_update() {
font_css_bry = font_css_fmtr.Bld_bry_many(Bry_bfr.new_(), font_name, font_size);
} private byte[] font_css_bry = Bry_.Empty;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_font_name)) return font_name;
else if (ctx.Match(k, Invk_font_name_)) {font_name = m.ReadStr("v"); this.Font_css_bry_update();}
else if (ctx.Match(k, Invk_font_size)) return font_size;
else if (ctx.Match(k, Invk_font_size_)) {font_size = m.ReadFloat("v"); this.Font_css_bry_update();}
else if (ctx.Match(k, Invk_font_css_fmt)) return String_.new_u8(font_css_fmtr.Fmt());
else if (ctx.Match(k, Invk_font_css_fmt_)) Font_css_fmtr_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_font_enabled)) return Yn.Xto_str(font_enabled);
else if (ctx.Match(k, Invk_font_enabled_)) font_enabled = m.ReadYn("v");
else if (ctx.Match(k, Invk_content_code_fmt)) return String_.new_u8(content_code_fmtr.Fmt());
else if (ctx.Match(k, Invk_content_code_fmt_)) content_code_fmtr.Fmt_(m.ReadBry("v"));
else return GfoInvkAble_.Rv_unhandled;
return this;
}
private static final String Invk_font_name = "font_name", Invk_font_name_ = "font_name_", Invk_font_size = "font_size", Invk_font_size_ = "font_size_"
, Invk_font_css_fmt = "font_css_fmt", Invk_font_css_fmt_ = "font_css_fmt_", Invk_font_enabled = "font_enabled", Invk_font_enabled_ = "font_enabled_"
, Invk_content_code_fmt = "content_code_fmt", Invk_content_code_fmt_ = "content_code_fmt_"
;
public static final float Font_size_default = 16;
}

View File

@@ -0,0 +1,26 @@
/*
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; import gplx.*; import gplx.xowa.*;
public abstract class Xoh_page_wtr_mgr_base {
public byte[] Css_common_bry() {return css_common_bry;} private byte[] css_common_bry;
public byte[] Css_wiki_bry() {return css_wiki_bry;} private byte[] css_wiki_bry;
public void Init_css_urls(Io_url css_common_url, Io_url css_wiki_url) {
this.css_common_bry = css_common_url.To_http_file_bry();
this.css_wiki_bry = css_wiki_url.To_http_file_bry();
}
}

View File

@@ -0,0 +1,33 @@
/*
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; import gplx.*; import gplx.xowa.*;
import org.junit.*;
import gplx.xowa.gui.*; import gplx.xowa.html.*; import gplx.xowa.html.portal.*; import gplx.xowa.pages.*;
public class Xoh_page_wtr_mgr_tst {
@Before public void init() {}
@Test public void Logo_has_correct_main_page() { // PURPOSE: Logo href should be "/site/en.wikipedia.org/wiki/", not "/wiki/Main_Page"
Xoae_app app = Xoa_app_fxt.app_();
Xowe_wiki wiki = Xoa_app_fxt.wiki_tst_(app);
Xow_portal_mgr portal_mgr = wiki.Html_mgr().Portal_mgr();
GfoInvkAble_.InvkCmd_val(portal_mgr, Xow_portal_mgr.Invk_div_logo_, Bry_.new_a7("~{portal_nav_main_href}"));
portal_mgr.Init_assert();
Xohe_page_wtr_mgr page_wtr_mgr = new Xohe_page_wtr_mgr(true);
page_wtr_mgr.Gen(wiki.Ctx().Cur_page(), Xopg_view_mode.Tid_read);
Tfds.Eq(String_.new_a7(portal_mgr.Div_logo_bry()), "/site/en.wikipedia.org/wiki/");
}
}

View File

@@ -0,0 +1,169 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.html.*; import gplx.xowa.html.portal.*; import gplx.xowa.pages.skins.*; import gplx.xowa.pages.*;
import gplx.xowa.wikis.*; import gplx.xowa.gui.*; import gplx.xowa.xtns.wdatas.*; import gplx.xowa.langs.vnts.*;
public class Xoh_page_wtr_wkr implements Bry_fmtr_arg {
private Xop_ctx ctx; private Xoae_page page; private Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
private byte[] root_dir_bry;
public Xoh_page_wtr_wkr(byte page_mode) {this.page_mode = page_mode;} private byte page_mode;
public Wdata_xwiki_link_wtr Wdata_lang_wtr() {return wtr_page_lang;} private Wdata_xwiki_link_wtr wtr_page_lang = new Wdata_xwiki_link_wtr();
public Xoh_page_wtr_wkr Page_(Xoae_page v) {this.page = v; return this;}
public Xoh_page_wtr_wkr Mgr_(Xohe_page_wtr_mgr v) {this.mgr = v; return this;} private Xohe_page_wtr_mgr mgr;
public boolean Ctgs_enabled() {return ctgs_enabled;} public Xoh_page_wtr_wkr Ctgs_enabled_(boolean v) {ctgs_enabled = v; return this;} private boolean ctgs_enabled = true;
public byte[] Write(Xohe_page_wtr_mgr mgr, Xoae_page page, Xop_ctx ctx, Bry_bfr html_bfr) {
this.mgr = mgr; this.page = page; this.ctx = ctx;
Xowe_wiki wiki = page.Wikie(); Xoae_app app = wiki.Appe();
ctx.Cur_page_(page); // HACK: must update page for toc_mgr; WHEN: Xoae_page rewrite
Bry_fmtr fmtr = null;
if (mgr.Html_capable()) {
wtr_page_lang.Page_(page);
byte view_mode = page_mode;
switch (page_mode) {
case Xopg_view_mode.Tid_edit: fmtr = mgr.Page_edit_fmtr(); break;
case Xopg_view_mode.Tid_html: fmtr = mgr.Page_read_fmtr(); view_mode = Xopg_view_mode.Tid_read; break; // set view_mode to read, so that "read" is highlighted in HTML
case Xopg_view_mode.Tid_read: fmtr = mgr.Page_read_fmtr();
ctx.Cur_page().Redlink_lnki_list().Clear(); // not sure if this is the best place to put it, but redlinks (a) must only fire once; (b) must fire before html generation; (c) cannot fire during edit (preview will handle separately)
break;
}
Write_page(html_bfr, app, wiki, mgr, page, view_mode, fmtr, this);
if (page_mode == Xopg_view_mode.Tid_html) // if html, write page again, but wrap it in html skin this time
Write_page(html_bfr, app, wiki, mgr, page, page_mode, mgr.Page_html_fmtr(), Html_utl.Escape_html_as_str(html_bfr.Xto_str_and_clear()));
wtr_page_lang.Page_(null);
}
else
XferAry(html_bfr, 0);
this.page = null;
return html_bfr.Xto_bry_and_clear();
}
private void Write_page(Bry_bfr html_bfr, Xoae_app app, Xowe_wiki wiki, Xohe_page_wtr_mgr mgr, Xoae_page page, byte view_tid, Bry_fmtr fmtr, Object page_data) {
byte[] custom_html = page.Html_data().Custom_html();
if (custom_html != null) {
html_bfr.Add(custom_html);
return;
}
if (root_dir_bry == null) this.root_dir_bry = app.Fsys_mgr().Root_dir().To_http_file_bry();
DateAdp page_modified_on_dte = page.Revision_data().Modified_on();
Xoa_ttl page_ttl = page.Ttl(); int page_ns_id = page_ttl.Ns().Id();
byte page_tid = Xow_page_tid.Identify(wiki.Domain_tid(), page_ns_id, page_ttl.Page_db());
byte[] page_modified_on_msg = wiki.Msg_mgr().Val_by_id_args(Xol_msg_itm_.Id_portal_lastmodified, page_modified_on_dte.XtoStr_fmt_yyyy_MM_dd(), page_modified_on_dte.XtoStr_fmt_HHmm());
byte[] page_body_class = Xoh_page_body_cls.Calc(tmp_bfr, page_ttl, page_tid);
byte[] html_content_editable = wiki.Gui_mgr().Cfg_browser().Content_editable() ? Content_editable_bry : Bry_.Empty;
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();
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_modified_on_msg
, mgr.Css_common_bry(), mgr.Css_wiki_bry(), page.Html_data().Module_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
, page_data, wtr_page_lang
, portal_mgr.Div_personal_bry(), portal_mgr.Div_ns_bry(app.Utl__bfr_mkr(), page_ttl, wiki.Ns_mgr()), portal_mgr.Div_view_bry(app.Utl__bfr_mkr(), view_tid, page.Html_data().Xtn_search_text())
, portal_mgr.Div_logo_bry(), portal_mgr.Div_home_bry(), new Xopg_xtn_skin_fmtr_arg(page, Xopg_xtn_skin_itm_tid.Tid_sidebar), portal_mgr.Div_wikis_bry(app.Utl__bfr_mkr()), portal_mgr.Sidebar_mgr().Html_bry()
, mgr.Edit_rename_div_bry(page_ttl), page.Html_data().Edit_preview_w_dbg(), js_edit_toolbar_bry
);
Xoh_page_wtr_wkr_.Bld_head_end(html_bfr, page);
Xoh_page_wtr_wkr_.Bld_html_end(html_bfr, page);
}
public void XferAry(Bry_bfr bfr, int idx) {Write_body(bfr, Xoh_wtr_ctx.Basic, page);}
public void Write_body(Bry_bfr bfr, Xoh_wtr_ctx hctx, Xoae_page page) {
Xowe_wiki wiki = page.Wikie(); Xoae_app app = wiki.Appe();
Xoa_ttl page_ttl = page.Ttl(); int page_ns_id = page_ttl.Ns().Id();
byte page_tid = Xow_page_tid.Identify(wiki.Domain_tid(), page_ns_id, page_ttl.Page_db()); // NOTE: can't cache page_tid b/c Write_body is called directly; DATE:2014-10-02
byte[] data_raw = page.Data_raw();
boolean page_tid_uses_pre = false;
int bfr_page_bgn = bfr.Len();
if (page_mode == Xopg_view_mode.Tid_edit)
Write_body_edit(bfr, data_raw, page_ns_id, page_tid);
else {
switch (page_tid) {
case Xow_page_tid.Tid_js:
case Xow_page_tid.Tid_css:
case Xow_page_tid.Tid_lua: Write_body_pre (bfr, app, wiki, data_raw, tmp_bfr); page_tid_uses_pre = true; break;
case Xow_page_tid.Tid_wikitext: Write_body_wikitext (bfr, app, wiki, data_raw, hctx, page, page_tid, page_ns_id); break;
case Xow_page_tid.Tid_json: app.Wiki_mgr().Wdata_mgr().Write_json_as_html(bfr, page_ttl.Page_db(), data_raw); break;
}
}
if ( wiki.Domain_tid() != Xow_domain_type_.Tid_home // allow home wiki to use javascript
&& !page_tid_uses_pre) { // if .js, .css or .lua, skip test; may have js fragments, but entire text is escaped and put in pre; don't show spurious warning; DATE:2013-11-21
app.Html_mgr().Js_cleaner().Clean_bfr(wiki, page_ttl, bfr, bfr_page_bgn);
}
}
private void Write_body_wikitext(Bry_bfr bfr, Xoae_app app, Xowe_wiki wiki, byte[] data_raw, Xoh_wtr_ctx hctx, Xoae_page page, byte page_tid, int ns_id) {
byte[] hdump_data = page.Hdump_data().Body();
if (Bry_.Len_gt_0(hdump_data)) {
bfr.Add(hdump_data);
return;
}
if (ns_id == Xow_ns_.Id_mediawiki) { // if MediaWiki and wikitext, must be a message; convert args back to php; DATE:2014-06-13
bfr.Add(gplx.xowa.apps.Xoa_gfs_php_mgr.Xto_php(tmp_bfr, Bool_.N, data_raw));
return;
}
Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr();
if (vnt_mgr.Enabled()) { // VNT
// vnt_mgr.Convert_ttl(
}
if (ns_id == Xow_ns_.Id_file) // if [[File]], add boilerplate header
app.Ns_file_page_mgr().Bld_html(wiki, ctx, page, bfr, page.Ttl(), wiki.Cfg_file_page(), page.File_queue());
gplx.xowa.html.tidy.Xoh_tidy_mgr tidy_mgr = app.Html_mgr().Tidy_mgr();
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());
if (tidy_enabled) {
tidy_mgr.Run_tidy_html(page, hdom_bfr);
bfr.Add_bfr_and_clear(hdom_bfr);
hdom_bfr.Mkr_rls();
}
if (ns_id == Xow_ns_.Id_category) // if Category, render rest of html (Subcategories; Pages; Files); note that a category may have other html which requires wikitext processing
wiki.Html_mgr().Ns_ctg().Bld_html(wiki, page, bfr);
int ctgs_len = page.Category_list().length; // add Categories
if ( ctgs_enabled
&& ctgs_len > 0
&& !wiki.Html_mgr().Importing_ctgs() // do not show categories if importing categories, page will wait for category import to be done; DATE:2014-10-15
) {
app.Usr_dlg().Prog_many("", "", "loading categories: count=~{0}", ctgs_len);
if (app.Ctg_mgr().Pagecats_grouping_enabled())
app.Ctg_mgr().Pagectgs_wtr().Write(bfr, wiki, page);
else
wiki.Html_mgr().Ctg_mgr().Bld(bfr, page, ctgs_len);
}
}
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);
app.Html_mgr().Page_mgr().Content_code_fmtr().Bld_bfr_many(bfr, tmp_bfr);
tmp_bfr.Clear();
}
private void Write_body_edit(Bry_bfr bfr, byte[] data_raw, int ns_id, byte page_tid) {
if ( ns_id == Xow_ns_.Id_mediawiki // if MediaWiki and wikitext, must be a message; convert args back to php; DATE:2014-06-13
&& page_tid == Xow_page_tid.Tid_wikitext
)
data_raw = gplx.xowa.apps.Xoa_gfs_php_mgr.Xto_php(tmp_bfr, Bool_.N, data_raw);
int data_raw_len = data_raw.length;
if (mgr.Html_capable())
Xoh_html_wtr_escaper.Escape(page.Wikie().Appe().Parser_amp_mgr(), bfr, data_raw, 0, data_raw_len, false, false); // NOTE: must escape; assume that browser will automatically escape (&lt;) (which Mozilla does)
else
bfr.Add(data_raw);
if (data_raw_len > 0) // do not add nl if empty String
bfr.Add_byte_nl(); // per MW:EditPage.php: "Ensure there's a newline at the end, otherwise adding lines is awkward."
}
private static final byte[] Content_editable_bry = Bry_.new_a7(" contenteditable=\"true\"");
}

View File

@@ -0,0 +1,56 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.html.*; import gplx.xowa.xtns.relatedSites.*;
public class Xoh_page_wtr_wkr_ {
public static byte[] Bld_page_content_sub(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Bry_bfr tmp_bfr) {
byte[] subpages = app.Html_mgr().Page_mgr().Subpages_bldr().Bld(wiki.Ns_mgr(), page.Ttl());
byte[] page_content_sub = page.Html_data().Content_sub(); // contentSub exists; SEE: {{#isin}}
byte[] redirect_msg = Xop_redirect_mgr.Bld_redirect_msg(app, wiki, page);
return Bry_.Add(subpages, page_content_sub, redirect_msg);
}
public static byte[] Bld_page_name(Bry_bfr tmp_bfr, Xoa_ttl ttl, byte[] display_ttl) {
if (display_ttl != null) return display_ttl; // display_ttl explicitly set; use it
if (ttl.Ns().Id() == Xow_ns_.Id_special) { // special: omit query args, else excessively long titles: EX:"Special:Search/earth?fulltext=y&xowa page index=1"
tmp_bfr.Add(ttl.Ns().Name_txt_w_colon()).Add(ttl.Page_txt_wo_qargs());
return tmp_bfr.Xto_bry_and_clear();
}
else
return ttl.Full_txt(); // NOTE: include ns with ttl as per defect d88a87b3
}
public static void Bld_head_end(Bry_bfr html_bfr, Xoae_page page) {
byte[] head_end = page.Html_data().Custom_head_end();
if (head_end == null) return;
int insert_pos = Bry_finder.Find_fwd(html_bfr.Bfr(), Html_tag_.Head_rhs);
if (insert_pos == Bry_finder.Not_found) {
Gfo_usr_dlg_.I.Warn_many("", "", "could not find </head>");
return;
}
html_bfr.Insert_at(insert_pos, head_end);
}
public static void Bld_html_end(Bry_bfr html_bfr, Xoae_page page) {
byte[] html_end = page.Html_data().Custom_html_end();
if (html_end == null) return;
int insert_pos = Bry_finder.Find_bwd(html_bfr.Bfr(), Html_tag_.Html_rhs, html_bfr.Len());
if (insert_pos == Bry_finder.Not_found) {
Gfo_usr_dlg_.I.Warn_many("", "", "could not find </html>");
return;
}
html_bfr.Insert_at(insert_pos, html_end);
}
}

View File

@@ -0,0 +1,75 @@
/*
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; import gplx.*; import gplx.xowa.*;
import org.junit.*;
import gplx.xowa.gui.*; import gplx.xowa.pages.*;
public class Xoh_page_wtr_wkr_tst {
@Before public void init() {fxt.Clear();} private Xoh_page_wtr_wkr_fxt fxt = new Xoh_page_wtr_wkr_fxt();
@Test public void Page_name() {
fxt.Test_page_name_by_ttl("Earth", "Earth");
fxt.Test_page_name_by_ttl("File:A.png", "File:A.png");
fxt.Test_page_name_by_ttl("Special:Search/earth?fulltext=y", "Special:Search/earth");
fxt.Test_page_name_by_ttl("Special:Search/earth", "Special:Search/earth");
fxt.Test_page_name_by_display("Special:Allpages", "All pages", "All pages");
}
@Test public void Edit() {
fxt.Test_edit("&#9;", "&amp;#9;\n"); // NOTE: cannot by &#9; or will show up in edit box as "\t" and save as "\t" instead of &#9;
}
@Test public void Css() {
fxt.App().Html_mgr().Page_mgr().Content_code_fmtr().Fmt_("<pre style='overflow:auto'>~{page_text}</pre>");
fxt.Test_read("MediaWiki:Common.css", ".xowa {}", "<pre style='overflow:auto'>.xowa {}</pre>");
fxt.App().Html_mgr().Page_mgr().Content_code_fmtr().Fmt_("<pre>~{page_text}</pre>");
}
@Test public void Amp_disable() { // PURPOSE: in js documents; &quot; should be rendered as &quot;, not as "; DATE:2013-11-07
fxt.Test_read("MediaWiki:Gadget.js", "&quot;", "<pre>&amp;quot;</pre>");
}
}
class Xoh_page_wtr_wkr_fxt {
public void Clear() {
if (app == null) {
app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
}
} private Bry_bfr tmp_bfr = Bry_bfr.reset_(255); private Xowe_wiki wiki;
public Xoae_app App() {return app;} private Xoae_app app;
public void Test_page_name_by_display(String ttl, String display, String expd) {
Tfds.Eq(expd, String_.new_a7(Xoh_page_wtr_wkr_.Bld_page_name(tmp_bfr, Xoa_ttl.parse_(wiki, Bry_.new_a7(ttl)), Bry_.new_a7(display))));
}
public void Test_page_name_by_ttl(String raw, String expd) {
Tfds.Eq(expd, String_.new_a7(Xoh_page_wtr_wkr_.Bld_page_name(tmp_bfr, Xoa_ttl.parse_(wiki, Bry_.new_a7(raw)), null)));
}
public void Test_edit(String raw, String expd) {
wiki.Html_mgr().Page_wtr_mgr().Html_capable_(true);
Xoae_page page = wiki.Ctx().Cur_page();
page.Data_raw_(Bry_.new_u8(raw));
Xohe_page_wtr_mgr mgr = wiki.Html_mgr().Page_wtr_mgr();
Xoh_page_wtr_wkr wkr = mgr.Wkr(Xopg_view_mode.Tid_edit).Page_(page).Mgr_(mgr);
wkr.XferAry(tmp_bfr, 0);
Tfds.Eq(expd, tmp_bfr.Xto_str_and_clear());
}
public void Test_read(String page_name, String page_text, String expd) {
wiki.Html_mgr().Page_wtr_mgr().Html_capable_(true);
Xoae_page page = wiki.Ctx().Cur_page();
page.Ttl_(Xoa_ttl.parse_(wiki, Bry_.new_a7(page_name)));
page.Data_raw_(Bry_.new_u8(page_text));
Xohe_page_wtr_mgr mgr = wiki.Html_mgr().Page_wtr_mgr();
Xoh_page_wtr_wkr wkr = mgr.Wkr(Xopg_view_mode.Tid_read).Page_(page).Mgr_(mgr);
wkr.XferAry(tmp_bfr, 0);
Tfds.Eq(expd, tmp_bfr.Xto_str_and_clear());
}
}

View File

@@ -0,0 +1,33 @@
/*
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; import gplx.*; import gplx.xowa.*;
public class Xoh_wtr_ctx {
Xoh_wtr_ctx(byte mode) {this.mode = mode;} private byte mode;
public boolean Mode_is_alt() {return mode == Mode_alt;}
public boolean Mode_is_display_title() {return mode == Mode_display_title;}
public boolean Mode_is_popup() {return mode == Mode_popup;}
public boolean Mode_is_hdump() {return mode == Mode_hdump;}
public static final byte Mode_basic = 0, Mode_alt = 1, Mode_display_title = 2, Mode_popup = 3, Mode_hdump = 4;
public static final Xoh_wtr_ctx
Basic = new Xoh_wtr_ctx(Mode_basic)
, Alt = new Xoh_wtr_ctx(Mode_alt)
, Display_title = new Xoh_wtr_ctx(Mode_display_title)
, Popup = new Xoh_wtr_ctx(Mode_popup)
, Hdump = new Xoh_wtr_ctx(Mode_hdump)
;
}

View File

@@ -0,0 +1,114 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.xowa.gui.*; import gplx.xowa.pages.*;
public class Xohe_page_wtr_mgr extends Xoh_page_wtr_mgr_base implements GfoInvkAble {
private Xoh_page_wtr_wkr edit_wtr, html_wtr, read_wtr;
private final Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
public Xohe_page_wtr_mgr(boolean html_capable) {
// page_edit_fmtr.Fmt_(String_.Concat_lines_nl_skip_last
// ( "<html>"
// , "<head>"
// , " <meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\" />"
// , " <script language='javascript'>"
// , " window.onload = function() {"
// , " var elem = document.getElementById('wikiText');"
// , " elem.selectionStart = 0;"
// , " elem.selectionEnd = 0;"
// , " window.setTimeout(function(){elem.focus();}, 100);"
// , " }"
// , " </script>"
// , "</head>"
// , "<body spellcheck='false'>"
// , " <textarea id='wikiText' style='width:99%;height:99%;border:0;'>"
// , "~{page_data}</textarea>"
// , "</body>"
// , "</html>"
// ));
this.html_capable = html_capable;
read_wtr = new Xoh_page_wtr_wkr(Xopg_view_mode.Tid_read);
edit_wtr = new Xoh_page_wtr_wkr(Xopg_view_mode.Tid_edit);
html_wtr = new Xoh_page_wtr_wkr(Xopg_view_mode.Tid_html);
}
public boolean Html_capable() {return html_capable;} public Xohe_page_wtr_mgr Html_capable_(boolean v) {html_capable = v; return this;} private boolean html_capable;
public Bry_fmtr Page_read_fmtr() {return page_read_fmtr;} private Bry_fmtr page_read_fmtr = Bry_fmtr.new_("", Fmtr_keys);
public Bry_fmtr Page_edit_fmtr() {return page_edit_fmtr;} private Bry_fmtr page_edit_fmtr = Bry_fmtr.new_("", Fmtr_keys);
public Bry_fmtr Page_html_fmtr() {return page_html_fmtr;} private Bry_fmtr page_html_fmtr = Bry_fmtr.new_("", Fmtr_keys);
public byte[] Edit_rename_div_bry(Xoa_ttl ttl) {return div_edit_rename_fmtr.Bld_bry_many(tmp_bfr, ttl.Full_db());}
public void Init_(boolean v) {init = v;} private boolean init = true;
public byte[] Gen(Xoae_page page, byte output_tid) {
Xoh_page_wtr_wkr wtr = Wkr(output_tid);
Xowe_wiki wiki = page.Wikie();
if (init) {
init = false;
page_read_fmtr.Eval_mgr_(wiki.Eval_mgr());
page_edit_fmtr.Eval_mgr_(wiki.Eval_mgr());
page_html_fmtr.Eval_mgr_(wiki.Eval_mgr());
}
Bry_bfr tmp_bfr = Xoa_app_.Utl__bfr_mkr().Get_m001();
byte[] bry = wtr.Write(this, page, wiki.Ctx(), tmp_bfr);
tmp_bfr.Mkr_rls();
return bry;
}
public Xoh_page_wtr_wkr Wkr(byte output_tid) {
switch (output_tid) {
case Xopg_view_mode.Tid_edit: return edit_wtr;
case Xopg_view_mode.Tid_html: return html_wtr;
case Xopg_view_mode.Tid_read: return read_wtr;
default: throw Exc_.new_unhandled(output_tid);
}
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_page_read_)) page_read_fmtr.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_page_edit_)) page_edit_fmtr.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_page_html_)) page_html_fmtr.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_xowa_div_edit_rename_)) div_edit_rename_fmtr.Fmt_(m.ReadBry("v"));
else return GfoInvkAble_.Rv_unhandled;
return this;
}
private Bry_fmtr div_edit_rename_fmtr = Bry_fmtr.new_(String_.Concat_lines_nl
( " <input id='xowa_edit_rename_box' width='120' height='20' />"
, " <a href='xowa-cmd:app.gui.main_win.page_edit_rename;' class='xowa_anchor_button' style='width:100px;max-width:1024px;'>"
, " Rename page"
, " </a>"
, " <a href='/wiki/Special:MovePage?wpOldTitle=~{src_full_db}' class='xowa_anchor_button' style='width:100px;max-width:1024px;'>"
, " Special:MovePage"
, " </a>"
), "src_full_db");
public static final String Invk_page_read_ = "page_read_", Invk_page_edit_ = "page_edit_", Invk_page_html_ = "page_html_", Invk_xowa_div_edit_rename_ = "xowa_div_edit_rename_";
private static final String[] Fmtr_keys = new String[]
{ "app_root_dir", "app_version", "app_build_date", "xowa_mode_is_server"
, "page_id", "page_name", "page_title", "page_modified_on_msg"
, "html_css_common_path", "html_css_wiki_path", "xowa_head"
, "page_lang_ltr", "page_indicators", "page_content_sub", "page_jumpto", "page_body_cls", "html_content_editable"
, "page_data", "page_langs"
, "portal_div_personal", "portal_div_ns", "portal_div_view"
, "portal_div_logo", "portal_div_home", "portal_div_xtn"
, "portal_div_wikis", "portal_sidebar"
, "edit_div_rename", "edit_div_preview", "js_edit_toolbar"
};
}
/*
NOTE_1:xowa_anchor_button
. used for media (WP forces javascript with oggplayer. wanted "simpler" model)
. display:inline-block; must be set for centering to work; see USSR and anthem; (display:block; must be enabled in order for padding to work)
. text-align:center; forces img to be in center
General notes:
. contentSub div is needed; PAGE:en.w:Battle of Spotsylvania Court House
*/

View File

@@ -0,0 +1,62 @@
/*
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; import gplx.*; import gplx.xowa.*;
public class Xohp_ctg_grp_mgr {
final Bry_fmtr grp_fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( "<div id=\"catlinks\" class=\"catlinks\">"
, " <div id=\"mw-normal-catlinks\" class=\"mw-normal-catlinks\">"
, " ~{grp_lbl}"
, " <ul>~{grp_itms}"
, " </ul>"
, " </div>"
, "</div>"
), "grp_lbl", "grp_itms")
;
final Bry_fmtr itm_fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <li>"
, " <a href=\"~{itm_href}\" class=\"internal\" title=\"~{itm_title}\">~{itm_text}</a>"
, " </li>"
), "itm_href", "itm_title", "itm_text"
);
Xoh_ctg_itm_fmtr itm_mgr = new Xoh_ctg_itm_fmtr();
public void Bld(Bry_bfr bfr, Xoae_page page, int ctgs_len) {
byte[] categories_lbl = page.Wikie().Msg_mgr().Val_by_id(Xol_msg_itm_.Id_ctg_tbl_hdr);
itm_mgr.Set(page, itm_fmtr);
grp_fmtr.Bld_bfr_many(bfr, categories_lbl, itm_mgr);
}
}
class Xoh_ctg_itm_fmtr implements Bry_fmtr_arg {
public void Set(Xoae_page page, Bry_fmtr itm_fmtr) {this.page = page; this.itm_fmtr = itm_fmtr;} private Xoae_page page; Bry_fmtr itm_fmtr;
public void XferAry(Bry_bfr bfr, int idx) {
int ctgs_len = page.Category_list().length;
Bry_bfr tmp_bfr = Xoa_app_.Utl__bfr_mkr().Get_b128();
Bry_bfr tmp_href = Xoa_app_.Utl__bfr_mkr().Get_b128();
Xowe_wiki wiki = page.Wikie();
Xoae_app app = wiki.Appe();
byte[] ctg_prefix = wiki.Ns_mgr().Ns_category().Name_db_w_colon();
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()));
itm_fmtr.Bld_bfr(bfr, tmp_href.Xto_bry_and_clear(), page_name, page_name);
}
tmp_bfr.Mkr_rls();
tmp_href.Mkr_rls();
}
}

View File

@@ -0,0 +1,56 @@
/*
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; import gplx.*; import gplx.xowa.*;
import org.junit.*;
public class Xohp_ctg_grp_mgr_tst {
Xoh_ctg_mgr_fxt fxt = new Xoh_ctg_mgr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Basic() {
fxt.Init_ctgs("A", "B").Test_html(String_.Concat_lines_nl
( "<div id=\"catlinks\" class=\"catlinks\">"
, " <div id=\"mw-normal-catlinks\" class=\"mw-normal-catlinks\">"
, " Categories"
, " <ul>"
, " <li>"
, " <a href=\"/wiki/Category:A\" class=\"internal\" title=\"A\">A</a>"
, " </li>"
, " <li>"
, " <a href=\"/wiki/Category:B\" class=\"internal\" title=\"B\">B</a>"
, " </li>"
, " </ul>"
, " </div>"
, "</div>"
));
}
}
class Xoh_ctg_mgr_fxt {
public Xoh_ctg_mgr_fxt Clear() {
app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
ctg_grp_mgr = new Xohp_ctg_grp_mgr();
return this;
} private Xohp_ctg_grp_mgr ctg_grp_mgr; Xoae_app app; Xowe_wiki wiki; Bry_bfr tmp_bfr = Bry_bfr.new_();
public Xoh_ctg_mgr_fxt Init_ctgs(String... v) {init_ctgs = v; return this;} private String[] init_ctgs;
public void Test_html(String expd) {
byte[][] ctgs_bry_ary = Bry_.Ary(init_ctgs);
Xoae_page page = wiki.Ctx().Cur_page();
page.Category_list_(ctgs_bry_ary);
ctg_grp_mgr.Bld(tmp_bfr, page, ctgs_bry_ary.length);
Tfds.Eq_str_lines(expd, tmp_bfr.Xto_str_and_clear());
}
}

View File

@@ -0,0 +1,20 @@
/*
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; import gplx.*; import gplx.xowa.*;
public class Xohv_page_wtr_mgr extends Xoh_page_wtr_mgr_base {
}

View File

@@ -0,0 +1,75 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.xowa.ctgs.*; import gplx.xowa.xtns.gallery.*;
import gplx.xowa.html.portal.*; import gplx.xowa.html.tocs.*; import gplx.xowa.wikis.modules.*; import gplx.xowa.html.hzips.*;
public class Xow_html_mgr implements GfoInvkAble {
public Xow_html_mgr(Xowe_wiki wiki) {
this.wiki = wiki;
html_wtr = new Xoh_html_wtr(wiki, this);
Xoae_app app = wiki.Appe();
page_wtr_mgr = new Xohe_page_wtr_mgr(app.Gui_mgr().Kit().Tid() != gplx.gfui.Gfui_kit_.Swing_tid); // reverse logic to handle swt,drd but not mem
Io_url file_dir = app.Usere().Fsys_mgr().App_img_dir().GenSubDir_nest("file");
img_media_play_btn = Xoa_app_.Utl__encoder_mgr().Fsys().Encode_http(file_dir.GenSubFil("play.png"));
img_media_info_btn = Xoa_app_.Utl__encoder_mgr().Fsys().Encode_http(file_dir.GenSubFil("info.png"));
img_thumb_magnify = Xoa_app_.Utl__encoder_mgr().Fsys().Encode_http(file_dir.GenSubFil("magnify-clip.png"));
img_xowa_protocol = Xoa_app_.Utl__encoder_mgr().Fsys().Encode_http(app.Usere().Fsys_mgr().App_img_dir().GenSubFil_nest("xowa", "protocol.png"));
portal_mgr = new Xow_portal_mgr(wiki);
imgs_mgr = new Xoh_imgs_mgr(this);
module_mgr = new Xow_module_mgr(wiki);
hzip_mgr = new Xow_hzip_mgr(app.Usr_dlg(), wiki);
}
public void Init_by_wiki(Xowe_wiki wiki) {
html_wtr.Init_by_wiki(wiki);
module_mgr.Init_by_wiki(wiki);
}
public void Init_by_lang(Xol_lang lang) {
portal_mgr.Init_by_lang(lang);
}
public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki;
public Xoh_html_wtr Html_wtr() {return html_wtr;} private Xoh_html_wtr html_wtr;
public Xohe_page_wtr_mgr Page_wtr_mgr() {return page_wtr_mgr;} private Xohe_page_wtr_mgr page_wtr_mgr;
public Xow_portal_mgr Portal_mgr() {return portal_mgr;} private Xow_portal_mgr portal_mgr;
public Xow_toc_mgr Toc_mgr() {return toc_mgr;} private Xow_toc_mgr toc_mgr = new Xow_toc_mgr();
public Xow_module_mgr Module_mgr() {return module_mgr;} private Xow_module_mgr module_mgr;
public Xow_hzip_mgr Hzip_mgr() {return hzip_mgr;} private Xow_hzip_mgr hzip_mgr;
public boolean Importing_ctgs() {return importing_ctgs;} public void Importing_ctgs_(boolean v) {importing_ctgs = v;} private boolean importing_ctgs;
public int Img_thumb_width() {return img_thumb_width;} private int img_thumb_width = 220;
public byte[] Img_media_play_btn() {return img_media_play_btn;} private byte[] img_media_play_btn;
public byte[] Img_media_info_btn() {return img_media_info_btn;} private byte[] img_media_info_btn;
public byte[] Img_thumb_magnify() {return img_thumb_magnify;} private byte[] img_thumb_magnify;
public byte[] Img_xowa_protocol() {return img_xowa_protocol;} private byte[] img_xowa_protocol;
public boolean Img_suppress_missing_src() {return img_suppress_missing_src;} public Xow_html_mgr Img_suppress_missing_src_(boolean v) {img_suppress_missing_src = v; return this;} private boolean img_suppress_missing_src = true;
public Xohp_ctg_grp_mgr Ctg_mgr() {return ctg_mgr;} private Xohp_ctg_grp_mgr ctg_mgr = new Xohp_ctg_grp_mgr();
public Xoctg_html_mgr Ns_ctg() {return ns_ctg;} private Xoctg_html_mgr ns_ctg = new Xoctg_html_mgr();
public Xoh_imgs_mgr Imgs_mgr() {return imgs_mgr;} private Xoh_imgs_mgr imgs_mgr;
public void Copy_cfg(Xow_html_mgr html_mgr) {imgs_mgr.Copy_cfg(html_mgr.Imgs_mgr());}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_article)) return page_wtr_mgr;
else if (ctx.Match(k, Invk_portal)) return portal_mgr;
else if (ctx.Match(k, Invk_imgs)) return imgs_mgr;
else if (ctx.Match(k, Invk_ns_ctg)) return ns_ctg;
else if (ctx.Match(k, Invk_modules)) return module_mgr;
else return GfoInvkAble_.Rv_unhandled;
}
public static final String
Invk_article = "article"
, Invk_portal = "portal", Invk_imgs = "imgs", Invk_ns_ctg = "ns_ctg"
, Invk_modules = "modules"
;
}

View File

@@ -0,0 +1,79 @@
/*
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.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.wikis.*; import gplx.xowa.wikis.data.*;
import gplx.xowa.bldrs.css.*;
public class Xob_css_status {
public int Update_tid() {return update_tid;} private int update_tid;
public boolean Fs_exists() {return fs_exists;} private boolean fs_exists;
public Io_url Fs_dir() {return fs_dir;} private Io_url fs_dir;
public boolean Db_exists() {return db_exists;} private boolean db_exists;
public void Fs_exists_(boolean fs_exists, Io_url fs_dir) {
this.fs_exists = fs_exists;
this.fs_dir = fs_dir;
}
public void Db_exists_(boolean db_exists) {
this.db_exists = db_exists;
}
public void Update_tid_none_y_() {this.update_tid = Update_tid_none;}
public void Update_tid_wmf_y_() {this.update_tid = Update_tid_wmf;}
public void Update_tid_db_y_() {this.update_tid = Update_tid_db;}
public static final int Update_tid_none = 0, Update_tid_db = 1, Update_tid_wmf = 2;
public static Xob_css_status Chk(Xow_wiki wiki, Io_url css_dir, String key) {
Xob_css_status rv = new Xob_css_status();
Chk_fs(rv, wiki);
Chk_db(rv, wiki, css_dir);
return rv;
}
private static void Chk_fs(Xob_css_status rv, Xow_wiki wiki) {
Io_url css_dir = wiki.App().Fsys_mgr().Wiki_css_dir(wiki.Domain_str()); // EX: /xowa/user/anonymous/wiki/en.wikipedia.org/html/
Io_url css_fil_wiki = css_dir.GenSubFil(Xoa_css_extractor.Css_wiki_name); // EX: /xowa/user/anonymous/wiki/en.wikipedia.org/html/xowa_wiki.css
boolean exists = Io_mgr.I.ExistsFil(css_fil_wiki);
rv.Fs_exists_(exists, css_dir);
}
private static void Chk_db(Xob_css_status rv, Xow_wiki wiki, Io_url css_dir) {
Xowd_db_mgr core_db_mgr = wiki.Data__core_mgr();
if ( core_db_mgr == null
|| core_db_mgr.Props() != null
|| !core_db_mgr.Props().Schema_is_1()
|| core_db_mgr.Tbl__cfg().Select_yn_or(Xow_cfg_consts.Grp__wiki_schema, Xowd_db_file_schema_props.Key__tbl_css_core, Bool_.N)
) {
rv.Db_exists_(false);
if (rv.Fs_exists())
rv.Update_tid_none_y_(); // v1_db and fs_exists; don't do update; legacy behavior
else
rv.Update_tid_wmf_y_(); // v1_db and fs_missing; update from wmf; legacy behavior
}
if (rv.Fs_exists()) {
DateAdp fs_timestamp = Timestamp_load(css_dir);
DateAdp db_timestamp = DateAdp_.Now();
if (db_timestamp.compareTo(fs_timestamp) == CompareAble_.More)
rv.Update_tid_db_y_(); // v2_db and later_version; update from db
else
rv.Update_tid_none_y_(); // v2_db and current version; noop
}
}
public static void Timestamp_save(Io_url css_dir, DateAdp time) {
Io_mgr.I.SaveFilStr(css_dir.GenSubFil(Timestamp_filename), time.XtoStr_fmt_yyyyMMdd_HHmmss());
}
public static DateAdp Timestamp_load(Io_url css_dir) {
String rv = Io_mgr.I.LoadFilStr(css_dir.GenSubFil(Timestamp_filename));
return rv == null ? DateAdp_.MinValue : DateAdp_.parse_iso8561_or(rv, DateAdp_.MinValue);
}
private static final String Timestamp_filename = "xowa.css.timestamp.txt";
}

View File

@@ -0,0 +1,53 @@
/*
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.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.wikis.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*;
public class Xow_css_mgr {
private final Xow_wiki wiki;
private boolean db_css_exists;
private Xowd_css_core_tbl css_core_tbl; private Xowd_css_file_tbl css_file_tbl;
public Xow_css_mgr(Xow_wiki wiki) {this.wiki = wiki;}
public void Init_by_wiki() {
Gfo_usr_dlg usr_dlg = Xoa_app_.Usr_dlg();
Xowd_db_mgr core_db_mgr = wiki.Data__core_mgr();
if (core_db_mgr == null) {
usr_dlg.Log_many("", "", "db.css.exists; css_missing b/c tdb; wiki=~{0}", wiki.Domain_str());
return;
}
if ( core_db_mgr.Props() == null
|| core_db_mgr.Props().Schema_is_1()) {
usr_dlg.Log_many("", "", "db.css.exists; css_missing b/c v1; wiki=~{0}", wiki.Domain_str());
return;
}
Xowd_db_file core_db = core_db_mgr.Db__core();
this.css_core_tbl = core_db.Tbl__css_core();
this.css_file_tbl = core_db.Tbl__css_file();
if ( core_db == null
|| !core_db.Conn().Meta_tbl_exists(css_core_tbl.Tbl_name())
) {
usr_dlg.Log_many("", "", "db.css.exists; css_missing b/c v2 w/o css; wiki=~{0}", wiki.Domain_str());
return;
}
this.db_css_exists = true;
}
public void Db_del_all() {
if (!db_css_exists) {Xoa_app_.Usr_dlg().Log_many("", "", "db.css.del_all; del_all skipped; wiki=~{0}", wiki.Domain_str()); return;}
css_core_tbl.Delete_all();
css_file_tbl.Delete_all();
}
}

View File

@@ -0,0 +1,60 @@
/*
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.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.dbs.*;
import gplx.xowa.wikis.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*;
import gplx.xowa.bldrs.css.*;
public class Xowd_css_core_mgr {
public static void Set(Xowd_css_core_tbl core_tbl, Xowd_css_file_tbl file_tbl, Io_url css_dir, String key) {
Db_conn conn = core_tbl.Conn();
Io_url[] file_list = Io_mgr.I.QueryDir_args(css_dir).Recur_().ExecAsUrlAry();
try {
conn.Txn_bgn();
int css_id = core_tbl.Select_id_by_key(key);
DateAdp updated_on = DateAdp_.Now().XtoUtc();
if (css_id == -1)
css_id = core_tbl.Insert(key, updated_on);
else {
core_tbl.Update(css_id, key, updated_on);
file_tbl.Delete(css_id);
}
for (Io_url file : file_list) {
String path = Op_sys.Fsys_path_to_lnx(file.GenRelUrl_orEmpty(css_dir));
byte[] data = Io_mgr.I.LoadFilBry(file);
file_tbl.Insert(css_id, path, data);
}
conn.Txn_end();
}
catch (Exception e) {conn.Txn_cxl(); throw e;}
}
public static boolean Get(Xowd_css_core_tbl core_tbl, Xowd_css_file_tbl file_tbl, Io_url css_dir, String key) {
int css_id = core_tbl.Select_id_by_key(key); if (css_id == Xowd_css_core_tbl.Id_null) return false; // unknown key; return false (not found)
Xowd_css_file_itm[] file_list = file_tbl.Select_by_owner(css_id);
// Io_mgr.I.DeleteDirDeep(css_dir); // NOTE: do not delete existing files; just overwrite;
int len = file_list.length;
if (len == 0) return false; // no css files in db
for (int i = 0; i < len; ++i) {
Xowd_css_file_itm file = file_list[i];
Io_url file_url = Io_url_.new_fil_(css_dir.Gen_sub_path_for_os(file.Path()));
if (file.Data() == null) continue; // NOTE: sqlite will return 0 length fields as NULL; if no data, just ignore, else error below
Io_mgr.I.SaveFilBry(file_url, file.Data());
}
return true;
}
public static final String Key_default = "xowa.default", Key_mobile = "xowa.mobile";
}

View File

@@ -0,0 +1,120 @@
/*
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.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*; import gplx.ios.*; import gplx.dbs.*; import gplx.xowa.wikis.data.tbls.*;
public class Xowd_css_core_mgr_tst {
@Before public void init() {fxt.Clear();} private Xowd_css_core_mgr_fxt fxt = new Xowd_css_core_mgr_fxt();
@Test public void Basic() {
Xowd_css_core_itm[] skin_ary = fxt.Make_skin_ary
( fxt.Make_skin_itm(1, "desktop", "20010101_050200")
);
Xowd_css_file_itm[] file_ary = fxt.Make_file_ary
( fxt.Make_file_itm(1, "a.css", "a_data")
, fxt.Make_file_itm(1, "b/b.png", "b/b_data")
);
Io_url src_dir = Io_url_.mem_dir_("mem/src/");
fxt.Init_fs(src_dir, file_ary);
fxt.Exec_set(src_dir, "desktop");
fxt.Test_skin_tbl(skin_ary);
fxt.Test_file_tbl(file_ary);
Io_url trg_dir = Io_url_.mem_dir_("mem/trg/");
fxt.Exec_get(trg_dir, "desktop");
fxt.Test_fs(trg_dir, file_ary);
}
@Test public void Update() { // update css files; keep same skin_id; insert new files
Xowd_css_core_itm[] skin_ary = fxt.Make_skin_ary
( fxt.Make_skin_itm(1, "desktop", "20010101_050500")
);
Xowd_css_file_itm[] file_ary = fxt.Make_file_ary
( fxt.Make_file_itm(1, "a.css", "a_data")
, fxt.Make_file_itm(1, "b/b.png", "b/b_data")
);
Io_url src_dir = Io_url_.mem_dir_("mem/src/");
fxt.Init_fs(src_dir, file_ary);
fxt.Exec_set(src_dir, "desktop");
file_ary = fxt.Make_file_ary
( fxt.Make_file_itm(1, "a1.css", "a1_data")
, fxt.Make_file_itm(1, "b/b1.png", "b/b1_data")
);
Io_mgr.I.DeleteDirDeep(src_dir);
fxt.Init_fs(src_dir, file_ary);
fxt.Exec_set(src_dir, "desktop");
fxt.Test_skin_tbl(skin_ary);
fxt.Test_file_tbl(file_ary);
}
}
class Xowd_css_core_mgr_fxt {
private final Bry_bfr bfr = Bry_bfr.reset_(32);
private Xowd_css_core_tbl core_tbl; private Xowd_css_file_tbl file_tbl;
public void Clear() {
Tfds.Now_enabled_y_();
Io_mgr.I.InitEngine_mem();
Db_conn_bldr.I.Reg_default_mem();
Db_conn conn = Db_conn_bldr.I.New(Io_url_.mem_fil_("mem/db/css.sqlite3"));
this.core_tbl = new Xowd_css_core_tbl(conn);
this.file_tbl = new Xowd_css_file_tbl(conn);
core_tbl.Create_tbl();
file_tbl.Create_tbl();
}
public Xowd_css_core_itm Make_skin_itm(int id, String key, String updated_on) {return new Xowd_css_core_itm(id, key, DateAdp_.parse_gplx(updated_on));}
public Xowd_css_file_itm Make_file_itm(int skin_id, String path, String data) {return new Xowd_css_file_itm(skin_id, path, Bry_.new_u8(data));}
public Xowd_css_file_itm[] Make_file_ary(Xowd_css_file_itm... ary) {return ary;}
public Xowd_css_core_itm[] Make_skin_ary(Xowd_css_core_itm... ary) {return ary;}
public void Init_fs(Io_url css_dir, Xowd_css_file_itm[] file_ary) {
for (Xowd_css_file_itm itm : file_ary)
Io_mgr.I.SaveFilBry(css_dir.GenSubFil(itm.Path()), itm.Data());
}
public void Exec_set(Io_url css_dir, String key) {Xowd_css_core_mgr.Set(core_tbl, file_tbl, css_dir, key);}
public void Exec_get(Io_url css_dir, String key) {Xowd_css_core_mgr.Get(core_tbl, file_tbl, css_dir, key);}
public void Test_skin_tbl(Xowd_css_core_itm[] expd) {
Xowd_css_core_itm[] actl = core_tbl.Select_all();
Tfds.Eq_str_lines(To_str(expd), To_str(actl));
}
public void Test_file_tbl(Xowd_css_file_itm[] expd) {
Xowd_css_file_itm[] actl = file_tbl.Select_all();
Tfds.Eq_str_lines(To_str(expd), To_str(actl));
}
public void Test_fs(Io_url css_dir, Xowd_css_file_itm[] expd) {
Io_url[] actl = Io_mgr.I.QueryDir_args(css_dir).Recur_().ExecAsUrlAry();
int len = expd.length;
Tfds.Eq(len, actl.length);
for (int i = 0; i < len; ++i) {
Xowd_css_file_itm expd_itm = expd[i];
Tfds.Eq_bry(expd_itm.Data(), Io_mgr.I.LoadFilBry(actl[i]));
}
}
private String To_str(Xowd_css_file_itm[] ary) {
int len = ary.length;
for (int i = 0; i < len; ++i) {
Xowd_css_file_itm itm = ary[i];
bfr.Add_int_variable(itm.Css_id()).Add_byte_pipe().Add_str_u8(itm.Path()).Add_byte_pipe().Add(itm.Data()).Add_byte_nl();
}
return bfr.Xto_str_and_clear();
}
private String To_str(Xowd_css_core_itm[] ary) {
Bry_bfr bfr = Bry_bfr.new_();
int len = ary.length;
for (int i = 0; i < len; ++i) {
Xowd_css_core_itm itm = ary[i];
bfr.Add_int_variable(itm.Id()).Add_byte_pipe().Add_str_u8(itm.Key()).Add_byte_pipe().Add_str_u8(itm.Updated_on().XtoStr_fmt_yyyyMMdd_HHmmss()).Add_byte_nl();
}
return bfr.Xto_str_and_clear();
}
}

View File

@@ -0,0 +1,88 @@
/*
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.hdumps; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.html.hdumps.data.*; import gplx.xowa.html.hzips.*; import gplx.xowa.html.hdumps.abrvs.*; import gplx.xowa.html.hdumps.pages.*;
import gplx.xowa.pages.*; import gplx.xowa.pages.skins.*; import gplx.xowa.html.modules.*;
import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa2.gui.*;
public class Xohd_hdump_rdr {
private final Bry_bfr_mkr bfr_mkr; private final Xow_hzip_mgr hzip_mgr;
private final Xohd_abrv_mgr abrv_mgr; private final Xohd_page_html_mgr__load load_mgr;
private Xowd_db_mgr core_data_mgr; private final Xowd_page_itm dbpg = new Xowd_page_itm();
private final Xow_wiki wiki;
public Xohd_hdump_rdr(Xoa_app app, Xow_wiki wiki) {
this.bfr_mkr = app.Utl__bfr_mkr(); this.hzip_mgr = wiki.Html__hzip_mgr(); this.wiki = wiki;
abrv_mgr = new Xohd_abrv_mgr(app.Usr_dlg(), app.Fsys_mgr(), app.Utl__encoder_mgr().Fsys(), wiki.Domain_bry());
load_mgr = new Xohd_page_html_mgr__load(); // TODO: get db_id
}
public void Init_by_db(Xowd_db_mgr core_data_mgr) {this.core_data_mgr = core_data_mgr;}
public void Get_by_ttl(Xoae_page page) {
Xog_page hpg = new Xog_page();
Get_by_ttl(hpg, page.Ttl());
page.Hdump_data().Body_(hpg.Page_body());
page.Root_(new Xop_root_tkn());
Xopg_html_data html_data = page.Html_data();
html_data.Display_ttl_(hpg.Display_ttl());
html_data.Content_sub_(hpg.Content_sub());
html_data.Xtn_skin_mgr().Add(new Xopg_xtn_skin_itm_stub(hpg.Sidebar_div()));
Load_module_mgr(html_data.Module_mgr(), hpg);
for (gplx.xowa.html.hdumps.core.Xohd_data_itm__base itm : hpg.Img_itms())
page.Hdump_data().Imgs_add(itm);
}
public void Get_by_ttl(Xog_page rv, Xoa_ttl ttl) {
synchronized (dbpg) {
dbpg.Clear();
if ( !Get_by_ttl__fill_hpg(rv, ttl)
|| rv.Page_body() == null) { // occurs when row exists in page, but not in html
rv.Exists_n_();
return;
}
Bry_bfr bfr = bfr_mkr.Get_m001();
Xoa_app_.Usr_dlg().Plog_many("", "", "hdump.load.abrv: ttl=~{0}", ttl.Full_db_as_str());
byte[] body_bry = abrv_mgr.Parse(bfr, rv);
Xoa_app_.Usr_dlg().Plog_many("", "", "hdump.load.hzip: ttl=~{0}", ttl.Full_db_as_str());
body_bry = hzip_mgr.Parse(bfr, ttl.Page_db(), body_bry, rv.Redlink_uids());
bfr.Mkr_rls();
rv.Page_body_(body_bry);
}
}
private boolean Get_by_ttl__fill_hpg(Xog_page rv, Xoa_ttl ttl) {
Xoa_app_.Usr_dlg().Plog_many("", "", "hdump.load.meta: ttl=~{0}", ttl.Full_db_as_str());
core_data_mgr.Tbl__page().Select_by_ttl(dbpg, ttl.Ns(), ttl.Page_db()); // get rows from db
if (dbpg.Redirect_id() != -1) Get_by_ttl__resolve_redirect(dbpg, rv);
if (dbpg.Html_db_id() == -1) return false; // dbpg does not hdump; exit;
rv.Init(wiki, dbpg.Id(), null, ttl); // FIXME
Xowd_db_file html_db = core_data_mgr.Dbs__get_at(dbpg.Html_db_id());
load_mgr.Load_page(wiki, rv, html_db.Tbl__html(), dbpg.Id(), ttl);
return true;
}
private void Get_by_ttl__resolve_redirect(Xowd_page_itm dbpg, Xog_page hpg) {
int redirect_count = 0;
while (redirect_count < 5) {
int redirect_id = dbpg.Redirect_id();
core_data_mgr.Tbl__page().Select_by_id(dbpg, redirect_id);
if (redirect_id == -1) break;
}
}
public static void Load_module_mgr(Xoh_module_mgr page_module_mgr, Xog_page hpg) {
Xopg_module_mgr dump_module_mgr = hpg.Module_mgr();
page_module_mgr.Itm__mathjax().Enabled_ (dump_module_mgr.Math_exists());
page_module_mgr.Itm__popups().Bind_hover_area_ (dump_module_mgr.Imap_exists());
page_module_mgr.Itm__gallery().Enabled_ (dump_module_mgr.Gallery_packed_exists());
page_module_mgr.Itm__hiero().Enabled_ (dump_module_mgr.Hiero_exists());
}
}

View File

@@ -0,0 +1,57 @@
/*
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.hdumps; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.html.hdumps.data.*; import gplx.xowa.html.hzips.*; import gplx.xowa.html.hdumps.abrvs.*; import gplx.xowa.html.hdumps.pages.*;
import gplx.xowa.pages.*; import gplx.xowa.pages.skins.*; import gplx.xowa.dbs.*;
import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa2.gui.*;
public class Xohd_hdump_wtr {
private final Bry_bfr_mkr bfr_mkr; private final Xohe_page_wtr_mgr page_wtr_mgr;
private final Xohd_page_html_mgr__save save_mgr; private Xowd_db_mgr core_data_mgr;
public Xohd_hdump_wtr(Xoa_app app, Xowe_wiki wiki) {
this.bfr_mkr = app.Utl__bfr_mkr(); this.page_wtr_mgr = wiki.Html_mgr().Page_wtr_mgr();
save_mgr = new Xohd_page_html_mgr__save();
}
public void Init_by_db(Xowd_db_mgr core_data_mgr) {
this.core_data_mgr = core_data_mgr;
}
public void Save(Xoae_page page) {
Bry_bfr tmp_bfr = bfr_mkr.Get_m001();
Generate_hdump(tmp_bfr, page);
int html_db_id = page.Revision_data().Html_db_id();
Xowd_db_file hdump_db = Xowd_db_file.Null;
if (html_db_id == -1) {
hdump_db = core_data_mgr.Db__html();
html_db_id = hdump_db.Id();
page.Revision_data().Html_db_id_(html_db_id);
core_data_mgr.Tbl__page().Update__html_db_id(page.Revision_data().Id(), html_db_id);
}
else {
hdump_db = core_data_mgr.Dbs__get_at(html_db_id);
html_db_id = hdump_db.Id();
// return; // DELETE: don't remember why return was here; DATE:2015-06-06
}
save_mgr.Update(tmp_bfr, hdump_db.Tbl__html(), page);
tmp_bfr.Mkr_rls();
}
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;
page.Hdump_data().Body_(tmp_bfr.Xto_bry_and_clear()); // write to body bry
}
}

View File

@@ -0,0 +1,158 @@
/*
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.hdumps; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*; import gplx.xowa.files.*;
import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hdumps.data.*; import gplx.xowa.html.hdumps.pages.*; import gplx.xowa.xtns.hieros.*; import gplx.xowa.xtns.gallery.*;
public class Xohd_hdump_wtr_tst {
@Before public void init() {fxt.Clear();} private Xohd_hdump_wtr_fxt fxt = new Xohd_hdump_wtr_fxt();
// @Test public void Image_full() {
// fxt.Expd_itms_xfers(fxt.Make_xfer("A.png", 0, 0, 0, Bool_.Y, Xof_ext_.Id_png));
// fxt.Test_write_all
// ( "[[File:A.png|test_caption]]"
// , "<a xtid='a_img_full' xatrs='1|0|0||0|test_caption'/>"
// );
// }
@Test public void Image_thumb() {
// fxt.Expd_itms_xfers(fxt.Make_xfer("A.png", 0, 0, 0, Bool_.N, Xof_ext_.Id_png));
// fxt.Test_write_all
// ( "[[File:A.png|thumb|test_caption]]", String_.Concat_lines_nl_skip_last
// ( "<div class=\"thumb tright\">"
// , " <div id=\"xowa_file_div_0\" class=\"thumbinner\" xowa_img_style='0'>"
// , " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" xowa_img='0' /></a>"
// , " <div class=\"thumbcaption\"><xowa_mgnf id='0'/>"
// , " test_caption"
// , " </div>"
// , " </div>"
// , "</div>"
// ));
}
@Test public void Audio_thumb() {
fxt.Expd_itms_xfers(fxt.Make_xfer("A.oga", 0, 220, -1, Bool_.N, Xof_ext_.Id_oga));
fxt.Test_write_all
( "[[File:A.oga|thumb|test_caption]]", String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" xowa_img_style='0'>"
, " <div id=\"xowa_media_div\"><xowa_play id='0'/><xowa_info id='0'/>"
, " </div>"
, " <div class=\"thumbcaption\"><xowa_mgnf id='0'/>"
, " test_caption"
, " </div>"
, " </div>"
, "</div>"
));
}
@Test public void Video_thumb() {
fxt.Expd_itms_xfers(fxt.Make_xfer("A.ogv", 0, 0, 0, Bool_.N, Xof_ext_.Id_ogv));
fxt.Test_write_all
( "[[File:A.ogv|thumb|test_caption]]", String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" xowa_img_style='0'>"
, " <div id=\"xowa_media_div\">"
, " <div>"
, " <a href=\"/wiki/File:A.ogv\" class=\"image\" title=\"A.ogv\">"
, " <img id=\"xowa_file_img_0\" xowa_img='0' alt=\"\" />"
, " </a>"
, " </div><xowa_play id='0'/>"
, " </div>"
, " <div class=\"thumbcaption\"><xowa_mgnf id='0'/>"
, " test_caption"
, " </div>"
, " </div>"
, "</div>"
));
}
@Test public void Hiero() {
Hiero_html_mgr_fxt hiero_fxt = new Hiero_html_mgr_fxt(fxt.Fxt());
hiero_fxt.Reset();
hiero_fxt.Init_hiero_A1_B1();
fxt.Test_write_frag("<hiero>A1</hiero>", "src='~{xowa_hiero_dir}hiero_A1.png'");
}
@Test public void Gallery() {
Gallery_mgr_base.File_found_mode = Bool_.__byte;
fxt.Test_write_all
( "<gallery>File:A.png|A1</gallery>", String_.Concat_lines_nl_skip_last
( "<ul id=\"xowa_gallery_ul_0\" class=\"gallery mw-gallery-traditional\" xowa_gly_box_max='0'>"
, " <li id=\"xowa_gallery_li_0\" class=\"gallerybox\" xowa_gly_box_w='0'>"
, " <div xowa_gly_box_w='0'>"
, " <div class=\"thumb\" style=\"width: 150px;\">"
, " <div xowa_gly_img_pad='0'>"
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" xowa_img='0' /></a>"
, " </div>"
, " </div>"
, " <div class=\"gallerytext\"><p>A1"
, "</p>"
, ""
, " </div>"
, " </div>"
, " </li>"
, "</ul>"
));
}
}
class Xodb_hdump_mgr__base_fxt {
protected Bry_bfr bfr = Bry_bfr.reset_(255);
protected Xowe_wiki wiki; protected Xoae_page page;
private Xohd_hdump_wtr hdump_wtr;
public Xop_fxt Fxt() {return fxt;} protected Xop_fxt fxt;
public void Clear() {
if (fxt == null) {
fxt = new Xop_fxt();
wiki = fxt.Wiki();
page = wiki.Ctx().Cur_page();
hdump_wtr = new Xohd_hdump_wtr(fxt.App(), fxt.Wiki());
}
fxt.Reset();
page.Revision_data().Id_(0);
this.Clear_end();
}
@gplx.Virtual public void Clear_end() {}
@gplx.Virtual public void Exec_write(String raw) {
Xop_root_tkn root = fxt.Exec_parse_page_all_as_root(Bry_.new_u8(raw));
page.Root_(root);
hdump_wtr.Generate_hdump(bfr, page);
}
public Xohd_data_itm__base Make_xfer(String lnki_ttl, int html_uid, int html_w, int html_h, boolean file_is_orig, int file_ext_id) {
return new Xohd_data_itm__img().Data_init_base
(Bry_.new_u8(lnki_ttl), Byte_.Zero, Xof_img_size.Upright_null, 0, 0, Xof_lnki_time.Null, Xof_lnki_page.Null, Xohd_data_itm__base.File_repo_id_null, file_ext_id, file_is_orig, html_w, html_uid, html_w, html_h);
}
}
class Xohd_hdump_wtr_fxt extends Xodb_hdump_mgr__base_fxt {
private List_adp expd_itms_xfers = List_adp_.new_();
@Override public void Clear_end() {expd_itms_xfers.Clear();}
public void Expd_itms_xfers(Xohd_data_itm__base... itms) {expd_itms_xfers.Add_many((Object[])itms);}
public void Test_write_all (String raw, String expd_html) {Test_write(Bool_.N, raw, expd_html);}
public void Test_write_frag(String raw, String expd_frag) {Test_write(Bool_.Y, raw, expd_frag);}
public void Test_write(boolean frag, String raw, String expd_html) {
this.Exec_write(raw);
String actl_html = String_.new_u8(page.Hdump_data().Body());
if (frag)
Tfds.Eq_true(String_.Has(actl_html, expd_html), actl_html);
else
Tfds.Eq_str_lines(expd_html, actl_html);
if (expd_itms_xfers.Count() > 0) Tfds.Eq_ary_str(Xfer_to_str_ary(expd_itms_xfers), Xfer_to_str_ary(page.Hdump_data().Imgs()));
}
private static String[] Xfer_to_str_ary(List_adp list) {
int len = list.Count();
String[] rv = new String[len];
for (int i = 0; i < len; ++i) {
Xohd_data_itm__base itm = (Xohd_data_itm__base)list.Get_at(i);
rv[i] = itm.Data_print();
}
return rv;
}
}

View File

@@ -0,0 +1,74 @@
/*
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.hdumps.abrvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.core.btries.*;
public class Xohd_abrv_ {
public static final byte
Tid_dir = 1, Tid_img = 2, Tid_img_style = 3, Tid_file_play = 4, Tid_file_info = 5, Tid_file_mgnf = 6
, Tid_hiero_dir = 7, Tid_gallery_box_max = 8, Tid_gallery_box_w = 9, Tid_gallery_img_w = 10, Tid_gallery_img_pad = 11
, Tid_redlink = 12, Tid_toc = 13, Tid_hdr_bgn = 14, Tid_hdr_end = 15
;
public static final byte[]
Key_dir = Bry_.new_a7("~{xowa_dir}")
, Key_img = Bry_.new_a7("xowa_img='")
, Key_img_style = Bry_.new_a7("xowa_img_style='")
, Key_file_play = Bry_.new_a7("<xowa_play id='")
, Key_file_info = Bry_.new_a7("<xowa_info id='")
, Key_file_mgnf = Bry_.new_a7("<xowa_mgnf id='")
, Key_hiero_dir = Bry_.new_a7("~{xowa_hiero_dir}")
, Key_gallery_box_max = Bry_.new_a7("xowa_gly_box_max='")
, Key_gallery_box_w = Bry_.new_a7("xowa_gly_box_w='")
, Key_gallery_img_w = Bry_.new_a7("xowa_gly_img_w='")
, Key_gallery_img_pad = Bry_.new_a7("xowa_gly_img_pad='")
, Key_redlink = Bry_.new_a7("xowa_redlink='")
, Key_toc = Bry_.new_a7("~{xowa_toc}")
, Key_hdr_bgn = Bry_.new_a7("<h")
, Key_hdr_end = Bry_.new_a7("</h")
;
public static final byte[]
A_href_bgn = Bry_.new_a7("/wiki/File:")
, Bry_img_style_bgn = Bry_.new_a7("style='width:")
, Bry_img_style_end = Bry_.new_a7("px;'")
, Html_redlink_bgn = Bry_.Add(Bry_.new_a7("\" "), Key_redlink)
, Html_redlink_end = Bry_.new_a7("'>")
;
public static Btrie_slim_mgr new_trie() {
Btrie_slim_mgr rv = Btrie_slim_mgr.cs_();
trie_itm(rv, Tid_dir , Byte_ascii.Nil , Key_dir);
trie_itm(rv, Tid_img , Byte_ascii.Apos , Key_img);
trie_itm(rv, Tid_img_style , Byte_ascii.Apos , Key_img_style);
trie_itm(rv, Tid_file_play , Byte_ascii.Apos , Key_file_play);
trie_itm(rv, Tid_file_info , Byte_ascii.Apos , Key_file_info);
trie_itm(rv, Tid_file_mgnf , Byte_ascii.Apos , Key_file_mgnf);
trie_itm(rv, Tid_hiero_dir , Byte_ascii.Nil , Key_hiero_dir);
trie_itm(rv, Tid_gallery_box_max , Byte_ascii.Apos , Key_gallery_box_max);
trie_itm(rv, Tid_gallery_box_w , Byte_ascii.Apos , Key_gallery_box_w);
trie_itm(rv, Tid_gallery_img_w , Byte_ascii.Apos , Key_gallery_img_w);
trie_itm(rv, Tid_gallery_img_pad , Byte_ascii.Apos , Key_gallery_img_pad);
trie_itm(rv, Tid_redlink , Byte_ascii.Apos , Key_redlink);
trie_itm(rv, Tid_toc , Byte_ascii.Nil , Key_toc);
// trie_itm(rv, Tid_hdr_bgn , Byte_ascii.Nil , Key_hdr_bgn);
// trie_itm(rv, Tid_hdr_end , Byte_ascii.Nil , Key_hdr_end);
return rv;
}
private static void trie_itm(Btrie_slim_mgr trie, byte tid, byte subst_end_byte, byte[] key_bry) {
boolean elem_is_xnde = key_bry[0] == Byte_ascii.Lt;
Hdump_html_fmtr_itm itm = new Hdump_html_fmtr_itm(tid, elem_is_xnde, subst_end_byte, key_bry);
trie.Add_obj(key_bry, itm);
}
}

View File

@@ -0,0 +1,162 @@
/*
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.hdumps.abrvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.core.primitives.*; import gplx.core.brys.*; import gplx.core.btries.*;
import gplx.html.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.lnkis.*;
import gplx.xowa.files.*; import gplx.xowa.files.repos.*; import gplx.xowa.xtns.gallery.*;
import gplx.xowa.wikis.*; import gplx.xowa.apps.fsys.*;
import gplx.xowa2.gui.*;
public class Xohd_abrv_mgr {
private Bry_bfr tmp_bfr = Bry_bfr.reset_(255); private Bry_rdr bry_rdr = new Bry_rdr(); private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.I;
private Xoh_cfg_file cfg_file; private Xof_url_bldr url_bldr = Xof_url_bldr.new_v2(); private Xoh_file_html_fmtr__base html_fmtr;
private byte[] root_dir, file_dir, file_dir_comm, file_dir_wiki, hiero_img_dir;
private byte[] wiki_domain;
private final Xohd_abrv_wkr__hdr wkr__hdr = new Xohd_abrv_wkr__hdr();
public Xohd_abrv_mgr(Gfo_usr_dlg usr_dlg, Xoa_fsys_mgr fsys_mgr, Url_encoder fsys_encoder, byte[] wiki_domain) {
this.usr_dlg = usr_dlg;
this.root_dir = fsys_mgr.Root_dir().To_http_file_bry();
this.file_dir = fsys_mgr.File_dir().To_http_file_bry();
this.hiero_img_dir = gplx.xowa.xtns.hieros.Hiero_xtn_mgr.Hiero_root_dir(fsys_mgr).GenSubDir("img").To_http_file_bry();
this.cfg_file = new Xoh_cfg_file(fsys_encoder, fsys_mgr.Bin_xowa_dir());
this.html_fmtr = Xoh_file_html_fmtr__hdump.Base;
this.wiki_domain = wiki_domain;
}
private void Init() {
file_dir_comm = tmp_bfr.Add(file_dir).Add(Xow_domain_.Domain_bry_commons).Add_byte_slash().Xto_bry_and_clear();
file_dir_wiki = tmp_bfr.Add(file_dir).Add(wiki_domain).Add_byte_slash().Xto_bry_and_clear();
}
public byte[] Parse(Bry_bfr rv, Xog_page hpg) {
this.Init();
byte[] src = hpg.Page_body(); int len = src.length;
Xohd_data_itm__base[] imgs = hpg.Img_itms(); int imgs_len = hpg.Img_itms().length;
bry_rdr.Init(src);
int pos = 0; int rng_bgn = -1;
while (pos < len) {
byte b = src[pos];
Object o = trie.Match_bgn_w_byte(b, src, pos, len);
if (o == null) { // regular char; set bgn and move to next char
if (rng_bgn == -1) rng_bgn = pos;
++pos;
}
else { // special tkn
if (rng_bgn != -1) { // pending rng exists; add it
rv.Add_mid(src, rng_bgn, pos);
rng_bgn = -1;
}
pos = trie.Match_pos(); // position after match; EX: "xowa_img='" positions after "'"
Hdump_html_fmtr_itm itm = (Hdump_html_fmtr_itm)o;
pos = Write_data(rv, html_fmtr, hpg, src, imgs, imgs_len, pos, itm); // note no +1; Write_data return pos after }
}
}
if (rng_bgn != -1) rv.Add_mid(src, rng_bgn, len);
return rv.Xto_bry_and_clear();
}
private int Write_data(Bry_bfr bfr, Xoh_file_html_fmtr__base fmtr, Xog_page hpg, byte[] src, Xohd_data_itm__base[] imgs, int imgs_len, int uid_bgn, Hdump_html_fmtr_itm itm) {
bry_rdr.Pos_(uid_bgn);
int uid = itm.Subst_end_byte() == Byte_ascii.Nil ? -1 : bry_rdr.Read_int_to(itm.Subst_end_byte());
int uid_end = bry_rdr.Pos(); // set uid_end after subst_end
int rv = uid_end;
byte tid = itm.Tid();
switch (tid) {
case Xohd_abrv_.Tid_dir: bfr.Add(root_dir); return rv;
case Xohd_abrv_.Tid_hiero_dir: bfr.Add(hiero_img_dir); return rv;
case Xohd_abrv_.Tid_redlink: return Write_redlink(bfr, hpg, uid, rv);
case Xohd_abrv_.Tid_hdr_bgn: return wkr__hdr.Write_bgn(bfr, hpg, uid, rv);
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 >= imgs.length) return rv;
Xohd_data_itm__base img = imgs[uid];
int img_view_w = img.Html_w();
switch (tid) {
case Xohd_abrv_.Tid_img_style:
bfr.Add(Xohd_abrv_.Bry_img_style_bgn);
bfr.Add_int_variable(img_view_w);
bfr.Add(Xohd_abrv_.Bry_img_style_end);
return rv;
}
byte[] a_title = img.Lnki_ttl();
byte[] a_href = Bry_.Add(Xohd_abrv_.A_href_bgn, a_title);
try {
switch (tid) {
case Xohd_abrv_.Tid_file_info: fmtr.Html_thumb_part_info (bfr, uid, a_href, cfg_file.Img_media_info_btn()); return rv;
case Xohd_abrv_.Tid_file_mgnf: fmtr.Html_thumb_part_magnify (bfr, uid, a_href, a_title, cfg_file.Img_thumb_magnify()); return rv;
case Xohd_abrv_.Tid_file_play: fmtr.Html_thumb_part_play (bfr, uid, img_view_w, Xoh_file_wtr__basic.Play_btn_max_width, a_href, a_title, cfg_file.Img_media_play_btn()); return rv;
case Xohd_abrv_.Tid_gallery_box_max: {
Xohd_data_itm__gallery_mgr gly = (Xohd_data_itm__gallery_mgr)hpg.Gallery_itms().Get_by(uid);
if (gly != null) { // -1 means no box_max
byte[] style = Gallery_mgr_base.box_style_max_width_fmtr.Bld_bry_many(tmp_bfr, gly.Box_max());
Html_wtr.Write_atr_bry(bfr, Bool_.N, Byte_ascii.Quote, Html_atr_.Style_bry, style);
}
return rv;
}
case Xohd_abrv_.Tid_gallery_box_w: {
Xohd_data_itm__gallery_itm gly = (Xohd_data_itm__gallery_itm)img;
byte[] style = Gallery_mgr_base.hdump_box_w_fmtr.Bld_bry_many(tmp_bfr, gly.Box_w());
Html_wtr.Write_atr_bry(bfr, Bool_.N, Byte_ascii.Quote, Html_atr_.Style_bry, style);
return rv;
}
case Xohd_abrv_.Tid_gallery_img_w: {
Xohd_data_itm__gallery_itm gly = (Xohd_data_itm__gallery_itm)img;
byte[] style = Gallery_mgr_base.hdump_box_w_fmtr.Bld_bry_many(tmp_bfr, gly.Img_w());
Html_wtr.Write_atr_bry(bfr, Bool_.N, Byte_ascii.Quote, Html_atr_.Style_bry, style);
return rv;
}
case Xohd_abrv_.Tid_gallery_img_pad: {
Xohd_data_itm__gallery_itm gly = (Xohd_data_itm__gallery_itm)img;
byte[] style = Gallery_mgr_base.hdump_img_pad_fmtr.Bld_bry_many(tmp_bfr, gly.Img_pad());
Html_wtr.Write_atr_bry(bfr, Bool_.N, Byte_ascii.Quote, Html_atr_.Style_bry, style);
return rv;
}
}
url_bldr.Init_by_root(img.Orig_repo_id() == Xof_repo_itm_.Repo_remote ? file_dir_comm : file_dir_wiki, Byte_ascii.Slash, false, false, 2);
url_bldr.Init_by_itm(img.File_is_orig() ? Xof_repo_itm_.Mode_orig : Xof_repo_itm_.Mode_thumb, img.Lnki_ttl(), Xof_file_wkr_.Md5_(img.Lnki_ttl()), Xof_ext_.new_by_id_(img.Orig_ext()), img.File_w(), img.Lnki_time(), img.Lnki_page());
byte[] img_src = url_bldr.Xto_bry();
if (tid == Xohd_abrv_.Tid_img) {
fmtr_img.Bld_bfr_many(bfr, img_src, img_view_w, img.Html_h());
}
} catch (Exception e) {Xoa_app_.Usr_dlg().Warn_many("", "", "abrv.read: page=~{0} itm=~{1} err=~{2}", hpg.Url_bry_safe(), img == null ? "<NULL>" : img.Data_print(), Err_.Message_gplx(e));}
return rv;
}
private int Write_redlink(Bry_bfr bfr, Xog_page hpg, int uid, int rv) {
if (hpg.Redlink_uids().Has(redlink_key.Val_(uid)))
bfr.Add(Xoh_redlink_utl.Cls_bry);
else
bfr.Del_by_1();
return rv;
} private final Int_obj_ref redlink_key = Int_obj_ref.neg1_();
public static final Bry_fmtr fmtr_img = Bry_fmtr.new_("src='~{src}' width='~{w}' height='~{h}'", "src", "w", "h");
private static final Btrie_slim_mgr trie = Xohd_abrv_.new_trie();
}
class Hdump_html_fmtr_itm {
public Hdump_html_fmtr_itm(byte tid, boolean elem_is_xnde, byte subst_end_byte, byte[] key) {this.tid = tid; this.key = key; this.elem_is_xnde = elem_is_xnde; this.subst_end_byte = subst_end_byte;}
public byte Tid() {return tid;} private final byte tid;
public byte[] Key() {return key;} private final byte[] key;
public boolean Elem_is_xnde() {return elem_is_xnde;} private final boolean elem_is_xnde;
public byte Subst_end_byte() {return subst_end_byte;} private final byte subst_end_byte;
}
class Xohd_abrv_wkr__hdr {
public int Write_bgn(Bry_bfr bfr, Xog_page hpg, int uid, int rv) {
return rv;
}
public int Write_end(Bry_bfr bfr, Xog_page hpg, int uid, int rv) {
return rv;
}
}

View File

@@ -0,0 +1,153 @@
/*
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.hdumps.abrvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import org.junit.*; import gplx.core.primitives.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hdumps.data.*; import gplx.xowa.files.*;
import gplx.xowa2.gui.*;
public class Xohd_abrv_mgr_tst {
@Before public void init() {
fxt.Clear();
fxt.Init_data_img_basic("A.png", 0, 220, 110);
} private final Xohd_abrv_mgr_fxt fxt = new Xohd_abrv_mgr_fxt();
@Test public void Img() {
fxt .Init_body("<img xowa_img='0' />")
.Test_html("<img src='file:///mem/xowa/file/commons.wikimedia.org/thumb/7/0/A.png/220px.png' width='220' height='110' />");
}
@Test public void Img_style() {
fxt .Init_body("<div xowa_img_style='0'>")
.Test_html("<div style='width:220px;'>");
}
@Test public void File_info() {
fxt .Init_body("<xowa_info id='0'/>")
.Test_html(String_.Concat_lines_nl_skip_last
( ""
, " <div>"
, " <a href=\"/wiki/File:A.png\" class=\"image\" title=\"About this file\">"
, " <img src=\"file:///mem/xowa/bin/any/xowa/file/mw.file/info.png\" width=\"22\" height=\"22\" />"
, " </a>"
, " </div>"
));
}
@Test public void File_mgnf() {
fxt .Init_body("<xowa_mgnf id='0'/>")
.Test_html(String_.Concat_lines_nl_skip_last
( ""
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"A.png\">"
, " <img src=\"file:///mem/xowa/bin/any/xowa/file/mw.file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
));
}
@Test public void File_play() {
fxt .Init_body("<xowa_play id='0'/>")
.Test_html(String_.Concat_lines_nl_skip_last
( ""
, " <div>"
, " <a id=\"xowa_file_play_0\" href=\"/wiki/File:A.png\" xowa_title=\"A.png\" class=\"xowa_anchor_button\" style=\"width:220px;max-width:1024px;\">"
, " <img src=\"file:///mem/xowa/bin/any/xowa/file/mw.file/play.png\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
));
}
@Test public void Hiero_dir() {
fxt .Init_body("<img src='~{xowa_hiero_dir}hiero_a&A1.png' />")
.Test_html("<img src='file:///mem/xowa/bin/any/xowa/xtns/Wikihiero/img/hiero_a&A1.png' />");
}
@Test public void Gallery() {
fxt.Clear_imgs();
fxt .Init_data_gly(0, 800);
fxt .Init_data_img_gly("A.png", 0, 220, 110, 155, 150, 15);
fxt .Init_body(String_.Concat_lines_nl_skip_last
( "<ul xowa_gly_box_max='0'>"
, " <li class='gallerybox' xowa_gly_box_w='0'>"
, " <div xowa_gly_box_w='0'>"
, " <div class='thumb' xowa_gly_img_w='0'>"
, " <div xowa_gly_img_pad='0'>"
))
.Test_html(String_.Concat_lines_nl_skip_last
( "<ul style=\"max-width:800px;_width:800px;\">"
, " <li class='gallerybox' style=\"width:155px;\">"
, " <div style=\"width:155px;\">"
, " <div class='thumb' style=\"width:150px;\">"
, " <div style=\"margin:15px auto;\">"
));
}
@Test public void Redlink() {
fxt .Init_data_redlink(1, 2);
fxt .Init_body(String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/A\" xowa_redlink='1'>A</a>"
, "<a href=\"/wiki/B\" xowa_redlink='2'>B</a>"
, "<a href=\"/wiki/C\" xowa_redlink='3'>C</a>"
))
.Test_html(String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/A\" class='new'>A</a>"
, "<a href=\"/wiki/B\" class='new'>B</a>"
, "<a href=\"/wiki/C\">C</a>"
));
}
}
class Xohd_abrv_mgr_fxt {
private Xohd_abrv_mgr abrv_mgr;
private Bry_bfr bfr = Bry_bfr.reset_(255);
private List_adp img_list = List_adp_.new_();
private Xowe_wiki wiki;
public Xog_page Hpg() {return hpg;} private Xog_page hpg = new Xog_page();
public void Clear() {
Xoae_app app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
abrv_mgr = new Xohd_abrv_mgr(Gfo_usr_dlg_.I, app.Fsys_mgr(), app.Utl__encoder_mgr().Fsys(), wiki.Domain_bry());
}
public void Clear_imgs() {img_list.Clear();}
public Xohd_abrv_mgr_fxt Init_body(String body) {hpg.Page_body_(Bry_.new_u8(body)); return this;}
public Xohd_abrv_mgr_fxt Init_data_gly(int uid, int box_max) {hpg.Gallery_itms().Add(uid, new Xohd_data_itm__gallery_mgr(uid, box_max)); return this;}
public Xohd_abrv_mgr_fxt Init_data_img_basic(String ttl, int html_uid, int html_w, int html_h) {
Xohd_data_itm__img img = new Xohd_data_itm__img();
img.Data_init_base(Bry_.new_u8(ttl), Xop_lnki_type.Id_none, Xof_img_size.Upright_null, Xof_img_size.Null, Xof_img_size.Null
, Xof_lnki_time.Null, Xof_lnki_page.Null
, Xohd_data_itm__base.File_repo_id_commons, Xof_ext_.Id_png, Bool_.N, html_w
, html_uid, html_w, html_h
);
img_list.Add(img);
return this;
}
public Xohd_abrv_mgr_fxt Init_data_img_gly(String ttl, int html_uid, int html_w, int html_h, int box_w, int img_w, int img_pad) {
Xohd_data_itm__gallery_itm img = new Xohd_data_itm__gallery_itm();
img.Data_init_gallery(box_w, img_w, img_pad);
img.Data_init_base(Bry_.new_u8(ttl), Xop_lnki_type.Id_none, Xof_img_size.Upright_null, Xof_img_size.Null, Xof_img_size.Null
, Xof_lnki_time.Null, Xof_lnki_page.Null
, Xohd_data_itm__base.File_repo_id_commons, Xof_ext_.Id_png, Bool_.N, html_w
, html_uid, html_w, html_h
);
img_list.Add(img);
return this;
}
public Xohd_abrv_mgr_fxt Init_data_redlink(int... uids) {
int uids_len = uids.length;
for (int i = 0; i < uids_len; ++i) {
Int_obj_ref redlink_uid = Int_obj_ref.new_(uids[i]);
hpg.Redlink_uids().Add(redlink_uid, redlink_uid);
}
return this;
}
public Xohd_abrv_mgr_fxt Test_html(String expd) {
if (img_list.Count() > 0) hpg.Img_itms_((Xohd_data_itm__base[])img_list.To_ary_and_clear(Xohd_data_itm__base.class));
byte[] actl = abrv_mgr.Parse(bfr, hpg);
Tfds.Eq_str_lines(expd, String_.new_u8(actl));
return this;
}
}

View File

@@ -0,0 +1,96 @@
/*
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.hdumps.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.dbs.*; import gplx.xowa.wikis.data.*; import gplx.dbs.engines.sqlite.*; import gplx.xowa.dbs.*; import gplx.xowa.wikis.data.tbls.*;
import gplx.xowa.html.hdumps.data.*; import gplx.xowa.html.hzips.*;
import gplx.xowa.pages.*; import gplx.xowa2.gui.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.cmds.*;
public class Xob_hdump_bldr {
private final Xowd_db_mgr wiki_db_mgr; private final Xob_ns_to_db_mgr ns_to_db_mgr; int prv_row_len = 0;
private final Xodump_stats_itm stats_itm = new Xodump_stats_itm(); private final Xodump_stats_tbl stats_tbl;
private final Xog_page tmp_hpg = new Xog_page(); private final Bry_bfr tmp_bfr = Bry_bfr.reset_(Io_mgr.Len_mb);
private final Xohd_page_html_mgr__save hdump_save_mgr = new Xohd_page_html_mgr__save();
private final boolean hzip_enabled;
public Xob_hdump_bldr(Xow_ns_mgr ns_mgr, Xodb_mgr_sql db_mgr, Db_conn make_conn, long hdump_db_max, boolean hzip_enabled) {
this.wiki_db_mgr = db_mgr.Core_data_mgr();
this.ns_to_db_mgr = new Xob_ns_to_db_mgr(new Xob_ns_to_db_wkr__html(wiki_db_mgr.Db__core()), wiki_db_mgr, hdump_db_max);
this.stats_tbl = new Xodump_stats_tbl(make_conn);
Xob_ns_file_itm.Init_ns_bldr_data(Xowd_db_file_.Tid_html_data, ns_mgr, gplx.xowa.apis.xowa.bldrs.imports.Xoapi_import.Ns_file_map__each);
this.hzip_enabled = hzip_enabled;
}
public void Bld_term() {
this.Commit();
Db_term();
}
public void Insert_page(Xoae_page page) {
Hzip_data(page);
tmp_hpg.Ctor_from_page(tmp_bfr, page);
Xowd_db_file db_file = ns_to_db_mgr.Get_by_ns(page.Ttl().Ns().Bldr_data(), prv_row_len);
this.prv_row_len = hdump_save_mgr.Insert(tmp_bfr, db_file.Tbl__html(), tmp_hpg, page.Hdump_data());
stats_tbl.Insert(tmp_hpg, stats_itm, page.Root().Root_src().length, tmp_hpg.Page_body().length, prv_row_len);
}
public void Commit() {
ns_to_db_mgr.Commit();
// wiki_db_mgr.Tbl__cfg().Update_long(Cfg_grp_hdump_make, Cfg_itm_hdump_size, hdump_db_size); // update cfg; should happen after commit entries
}
private void Db_term() {
ns_to_db_mgr.Rls_all();
}
// private static final String Cfg_grp_hdump_make = "hdump.make", Cfg_itm_hdump_size = "hdump.size";
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
}
}
class Xob_ns_to_db_wkr__html implements Xob_ns_to_db_wkr {
private final Xowd_db_file page_db;
public Xob_ns_to_db_wkr__html(Xowd_db_file page_db) {this.page_db = page_db;}
public byte Db_tid() {return Xowd_db_file_.Tid_html_data;}
public void Tbl_init(Xowd_db_file db) {
Xowd_html_tbl tbl = db.Tbl__html();
tbl.Create_tbl();
tbl.Insert_bgn();
}
public void Tbl_term(Xowd_db_file db) {
db.Tbl__text().Insert_end();
Db_conn db_conn = db.Conn();
db.Tbl__html().Create_idx();
Db_attach_cmd.new_(page_db.Conn(), "html_db", db.Url())
.Add_fmt("hdump.update page.html_db_id", Sql_update_page_html_db_id, db.Id())
.Exec();
db_conn.Rls_conn();
}
private static final String Sql_update_page_html_db_id = String_.Concat_lines_nl_skip_last
( "REPLACE INTO page (page_id, page_namespace, page_title, page_is_redirect, page_touched, page_len, page_random_int, page_text_db_id, page_html_db_id, page_redirect_id)"
, "SELECT p.page_id"
, ", p.page_namespace"
, ", p.page_title"
, ", p.page_is_redirect"
, ", p.page_touched"
, ", p.page_len"
, ", p.page_random_int"
, ", p.page_text_db_id"
, ", {0}"
, ", p.page_redirect_id"
, "FROM page p"
, " JOIN <attach_db>html h ON p.page_id = h.page_id"
);
}

View File

@@ -0,0 +1,116 @@
/*
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.hdumps.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.dbs.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa.bldrs.*; import gplx.xowa.html.hdumps.core.*;
import gplx.xowa.files.*;
import gplx.xowa2.gui.*;
class Xob_hdump_img_cmd extends Xob_itm_basic_base implements Xob_cmd {
private Xowd_html_tbl html_tbl;
public Xob_hdump_img_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki);}
public String Cmd_key() {return Key_const;} public static final String Key_const = "hdump.make.imgs";
public void Cmd_init(Xob_bldr bldr) {}
public void Cmd_bgn(Xob_bldr bldr) {}
public void Cmd_run() {Exec_main();}
public void Cmd_end() {}
public void Cmd_term() {}
private void Exec_main() {
Bry_bfr bfr = Bry_bfr.reset_(Io_mgr.Len_mb);
Db_conn conn = Xob_db_file.new__file_make(wiki.Fsys_mgr().Root_dir()).Conn();
Db_rdr rdr = conn.Stmt_new(gplx.dbs.qrys.Db_qry_sql.rdr_(Sql_select)).Exec_select__rls_auto();
html_tbl = new Xowd_html_tbl(conn, wiki.Db_mgr_as_sql().Core_data_mgr().Props().Zip_tid_text());
int cur_page_id = -1;
while (rdr.Move_next()) {
int lnki_page_id = rdr.Read_int("lnki_page_id");
if (lnki_page_id != cur_page_id) {
Save(cur_page_id, bfr.Xto_bry_and_clear());
cur_page_id = lnki_page_id;
}
// int html_uid = rdr.Read_int(1);
// byte[] lnki_ttl = rdr.Read_bry(2);
// int html_w = rdr.Read_int(3);
// int html_h = rdr.Read_int(4);
// int file_repo_id = rdr.Read_int(5);
// int file_ext_id = rdr.Read_int(6);
// boolean file_is_orig = rdr.Read_int(7) == 1;
// double file_time = rdr.Read_double(8);
// int file_page = rdr.Read_int(9);
// Xohd_data_itm__base.Data_write_static(bfr, 0, lnki_ttl, Byte_.Zero, 0, 0, Xof_img_size.Upright_null, html_uid, html_w, html_h, file_repo_id, file_ext_id, file_is_orig, html_w, file_time, file_page);
}
Save(cur_page_id, bfr.Xto_bry_and_clear());;
}
private void Save(int page_id, byte[] data) {
if (page_id == -1 || data.length == 0) return;
html_tbl.Insert(page_id, Xohd_data_tid.Tid_img, data);
}
private static final String Sql_select = String_.Concat_lines_nl_skip_last
( "SELECT lt.lnki_page_id"
, ", lt.html_uid"
, ", lt.lnki_ttl"
, ", xr.file_w"
, ", xr.file_h"
, ", xr.orig_repo"
, ", xr.lnki_ext"
, ", xr.file_is_orig"
, ", xr.lnki_time"
, ", xr.lnki_page"
, "FROM xfer_regy xr"
, " JOIN lnki_temp lt ON xr.file_ttl = lt.lnki_ttl"
// , " LEFT JOIN xtn_gallery lt ON xr.file_ttl = lt.lnki_ttl"
// , " LEFT JOIN xtn_imap lt ON xr.file_ttl = lt.lnki_ttl"
, "ORDER BY "
, " lt.lnki_page_id"
, ", lt.lnki_uid"
);
}
interface Page_async_cmd {
void Prep();
void Exec();
}
class Page_async_cmd__img implements Page_async_cmd {
private Xog_page hpg;
private List_adp missing = List_adp_.new_();
public Page_async_cmd__img(Xog_page hpg) {this.hpg = hpg;}
public void Prep() {
int len = hpg.Img_count();
Xohd_data_itm__base[] ary = hpg.Img_itms();
missing.Clear();
for (int i = 0; i < len; ++i) {
Xohd_data_itm__base itm = ary[i];
boolean exists = Io_mgr.I.ExistsFil(itm.Html_view_url());
if (!exists) missing.Add(itm);
}
}
public void Exec() {
int len = missing.Count();
for (int i = 0; i < len; ++i) {
// Xohd_data_itm__base itm = (Xohd_data_itm__base)missing.Get_at(i);
// byte[] bytes = null; //fsdb.Db_get()ttl, file_w,....):
// Write file(bytes);
}
}
}
/*
CREATE TABLE xtn_gallery
( src_page_id integer NOT NULL
, html_uid integer NOT NULL
, box_max integer NOT NULL
, box_w integer NOT NULL
, img_w integer NOT NULL
, img_pad integer NOT NULL
);
*/

View File

@@ -0,0 +1,56 @@
/*
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.hdumps.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.core.brys.*; import gplx.dbs.*;
public class Xob_link_dump_cmd {
private Xob_link_dump_tbl tbl; private int src_page_id; private Io_url page_db_url;
public void Init_by_wiki(Xowe_wiki wiki) {
this.page_db_url = wiki.Data__core_mgr().Db__core().Url();
this.tbl = Xob_link_dump_tbl.Get_or_new(wiki);
tbl.Insert_bgn();
}
public void Page_bgn(int src_page_id) {this.src_page_id = src_page_id;}
public void Add(int src_html_uid, int trg_ns_id, byte[] trg_ttl) {tbl.Insert_cmd_by_batch(src_page_id, src_html_uid, trg_ns_id, trg_ttl);}
public void Wkr_commit() {tbl.Conn().Txn_sav();}
public void Wkr_end() {
try {
tbl.Insert_end();
tbl.Create_idx_1();
Db_conn conn = tbl.Conn();
Db_attach_cmd.new_(conn, "page_db", page_db_url)
.Add_fmt("update trg_page_id", String_.Concat_lines_nl_skip_last
( "REPLACE INTO link_dump"
, "SELECT r.uid"
, ", r.src_page_id"
, ", r.src_html_uid"
, ", Coalesce(p.page_id, -1)"
, ", r.trg_ns"
, ", r.trg_ttl"
, "FROM link_dump r"
, " LEFT JOIN page_db.page p ON r.trg_ns = p.page_namespace AND r.trg_ttl = p.page_title"
, ";"
))
.Exec();
conn.Exec_sql("UPDATE link_dump SET trg_ns = -1 AND trg_ttl = '' WHERE trg_page_id != -1;");
tbl.Create_idx_2();
conn.Env_vacuum();
} catch (Exception e) {
Tfds.Write(Err_.Message_gplx(e));
}
}
}

View File

@@ -0,0 +1,69 @@
/*
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.hdumps.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.dbs.*;
class Xob_link_dump_tbl implements RlsAble {
public static final String Tbl_name = "link_dump"; private static final Db_meta_fld_list flds = Db_meta_fld_list.new_();
public static final String
Fld_uid = flds.Add_int_pkey_autonum("uid")
, Fld_src_page_id = flds.Add_int("src_page_id")
, Fld_src_html_uid = flds.Add_int("src_html_uid")
, Fld_trg_page_id = flds.Add_int_dflt("trg_page_id", -1)
, Fld_trg_ns = flds.Add_int("trg_ns")
, Fld_trg_ttl = flds.Add_str("trg_ttl", 255)
;
private Db_stmt stmt_insert;
public Xob_link_dump_tbl(Db_conn conn) {
this.conn = conn;
conn.Rls_reg(this);
}
public Db_conn Conn() {return conn;} private final Db_conn conn;
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(Tbl_name, flds));}
public void Create_idx_1() {
conn.Ddl_create_idx
( Db_meta_idx.new_normal_by_tbl(Tbl_name, "src", Fld_src_page_id, Fld_src_html_uid)
, Db_meta_idx.new_normal_by_tbl(Tbl_name, "trg_temp", Fld_trg_ns, Fld_trg_ttl)
);
}
public void Create_idx_2() {
conn.Ddl_create_idx
( Db_meta_idx.new_normal_by_tbl(Tbl_name, "trg", Fld_trg_page_id, Fld_src_page_id, Fld_src_html_uid)
);
}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
}
public void Insert_bgn() {conn.Txn_bgn();}
public void Insert_end() {conn.Txn_end(); stmt_insert = Db_stmt_.Rls(stmt_insert);}
public void Insert_cmd_by_batch(int src_page_id, int src_html_uid, int trg_ns, byte[] trg_ttl) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(Tbl_name, flds.To_str_ary_wo_autonum());
stmt_insert.Clear().Val_int(Fld_src_page_id, src_page_id)
.Val_int(Fld_src_html_uid, src_html_uid).Val_int(Fld_trg_page_id, -1).Val_int(Fld_trg_ns, trg_ns).Val_bry_as_str(Fld_trg_ttl, trg_ttl)
.Exec_insert();
}
public Db_rdr Select_missing() {
return conn.Stmt_select_order(Tbl_name, flds, String_.Ary(Fld_trg_page_id), Fld_src_page_id, Fld_src_html_uid)
.Crt_int(Fld_trg_page_id, -1).Exec_select__rls_auto();
}
public static Xob_link_dump_tbl Get_or_new(Xow_wiki wiki) {
Db_conn_bldr_data conn_data = Db_conn_bldr.I.Get_or_new(wiki.Fsys_mgr().Root_dir().GenSubFil("xowa.temp.redlink.sqlite3"));
Xob_link_dump_tbl rv = new Xob_link_dump_tbl(conn_data.Conn());
if (conn_data.Created()) rv.Create_tbl();
return rv;
}
}

View File

@@ -0,0 +1,88 @@
/*
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.hdumps.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.dbs.*; import gplx.xowa.bldrs.*; import gplx.xowa.html.hdumps.data.*;
import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*;
public class Xob_redlink_mkr_cmd extends Xob_itm_basic_base implements Xob_cmd {
private int commit_interval = 10000, commit_count = 0;
public Xob_redlink_mkr_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki);}
public String Cmd_key() {return Xob_cmd_keys.Key_html_redlinks;}
public void Cmd_run() {Read_data();}
private void Read_data() {
Bry_bfr bfr = Bry_bfr.reset_(255);
wiki.Init_assert();
Xowd_db_file core_db = wiki.Data__core_mgr().Db__core();
Xob_db_file link_dump_db = Xob_db_file.new__redlink(wiki.Fsys_mgr().Root_dir());
Db_attach_rdr attach_rdr = new Db_attach_rdr(link_dump_db.Conn(), "page_db", core_db.Url());
attach_rdr.Attach();
Xowd_page_tbl page_tbl = core_db.Tbl__page();
int cur_html_db_id = -1, cur_page_id = -1; Xowd_html_tbl html_dump_tbl = null;
Db_rdr rdr = attach_rdr.Exec_as_rdr(Sql_select);
try {
while (rdr.Move_next()) {
// switch html_db if needed
int html_db_id = rdr.Read_int(page_tbl.Fld_html_db_id());
if (html_db_id != cur_html_db_id) {
if (html_dump_tbl != null) html_dump_tbl.Conn().Txn_end();
html_dump_tbl = wiki.Data__core_mgr().Dbs__get_at(html_db_id).Tbl__html();
html_dump_tbl.Conn().Txn_bgn();
cur_html_db_id = html_db_id;
}
// commit page_id if needed
int page_id = rdr.Read_int(page_tbl.Fld_page_id());
if (cur_page_id != page_id) {
if (cur_page_id != -1) Commit(html_dump_tbl, cur_page_id, bfr);
bfr.Add_int_variable(gplx.xowa.html.hdumps.core.Xohd_data_tid.Tid_redlink).Add_byte_pipe();
cur_page_id = page_id;
}
// add html_uid to cur_page's bfr
int html_uid = rdr.Read_int(Xob_link_dump_tbl.Fld_src_html_uid);
bfr.Add_int_variable(html_uid).Add_byte_pipe();
}
}
finally {rdr.Rls();}
Commit(html_dump_tbl, cur_page_id, bfr); // commit cur page
html_dump_tbl.Conn().Txn_end(); // close cur tbl
attach_rdr.Detach();
}
private void Commit(Xowd_html_tbl html_dump_tbl, int cur_page_id, Bry_bfr bfr) {
html_dump_tbl.Insert(cur_page_id, Xowd_html_row.Tid_redlink, bfr.Xto_bry_and_clear());
++commit_count;
if ((commit_count % commit_interval ) == 0)
html_dump_tbl.Conn().Txn_sav();
}
private static final String Sql_select = String_.Concat_lines_nl_skip_last
( "SELECT p.page_html_db_id"
, ", p.page_id"
, ", ld.src_html_uid"
, "FROM link_dump ld"
, " JOIN <attach_db>page p ON p.page_id = ld.src_page_id "
, "WHERE ld.trg_page_id = -1"
, "ORDER BY p.page_html_db_id, p.page_id"
, ";"
);
public void Cmd_init(Xob_bldr bldr) {}
public void Cmd_bgn(Xob_bldr bldr) {}
public void Cmd_end() {}
public void Cmd_term() {}
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_commit_interval_)) commit_interval = m.ReadInt("v");
else return GfoInvkAble_.Rv_unhandled;
return this;
} private static final String Invk_commit_interval_ = "commit_interval_";
}

View File

@@ -0,0 +1,23 @@
/*
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.hdumps.core; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
public interface Xohd_data_itm {
int Data_tid();
void Data_write(Bry_bfr bfr);
String Data_print();
}

View File

@@ -0,0 +1,101 @@
/*
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.hdumps.core; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.core.brys.*; import gplx.xowa.html.hdumps.data.*; import gplx.xowa.files.repos.*;
public abstract class Xohd_data_itm__base implements Xohd_data_itm {
public abstract int Img_tid();
public int Data_tid() {return Xohd_data_tid.Tid_img;}
public byte[] Lnki_ttl() {return lnki_ttl;} private byte[] lnki_ttl;
public byte Lnki_type() {return lnki_type;} private byte lnki_type;
public double Lnki_upright() {return lnki_upright;} private double lnki_upright;
public int Lnki_w() {return lnki_w;} private int lnki_w;
public int Lnki_h() {return lnki_h;} private int lnki_h;
public double Lnki_time() {return lnki_time;} private double lnki_time;
public int Lnki_page() {return lnki_page;} private int lnki_page;
public int Orig_repo_id() {return orig_repo_id;} private int orig_repo_id;
public int Orig_ext() {return orig_ext;} private int orig_ext;
public boolean File_is_orig() {return file_is_orig;} private boolean file_is_orig;
public int File_w() {return file_w;} private int file_w;
public int Html_uid() {return html_uid;} private int html_uid;
public int Html_w() {return html_w;} private int html_w;
public int Html_h() {return html_h;} private int html_h;
public Io_url Html_view_url() {return html_view_url;} public void File_url_(Io_url v) {html_view_url = v;} private Io_url html_view_url;
public abstract byte Html_elem_tid();
public Xohd_data_itm__base Data_init_base
( byte[] lnki_ttl, byte lnki_type, double lnki_upright, int lnki_w, int lnki_h, double lnki_time, int lnki_page
, int orig_repo_id, int orig_ext, boolean file_is_orig, int file_w
, int html_uid, int html_w, int html_h
) {
this.lnki_ttl = lnki_ttl; this.orig_ext = orig_ext; this.lnki_type = lnki_type;
this.lnki_w = lnki_w; this.lnki_h = lnki_h; this.lnki_upright = lnki_upright; this.lnki_time = lnki_time; this.lnki_page = lnki_page;
this.orig_repo_id = orig_repo_id; this.file_is_orig = file_is_orig; this.file_w = file_w;
this.html_uid = html_uid; this.html_w = html_w; this.html_h = html_h;
return this;
}
public void Data_write(Bry_bfr bfr) {
bfr .Add_int_variable(Xohd_data_tid.Tid_img).Add_byte_pipe()
.Add_int_variable(this.Img_tid()).Add_byte_pipe()
.Add(lnki_ttl).Add_byte_pipe()
.Add_int_variable(orig_ext).Add_byte_pipe()
.Add_byte(lnki_type).Add_byte_pipe()
.Add_int_variable(lnki_w).Add_byte_pipe()
.Add_int_variable(lnki_h).Add_byte_pipe()
.Add_double(lnki_upright).Add_byte_pipe()
.Add_double(lnki_time).Add_byte_pipe()
.Add_int_variable(lnki_page).Add_byte_pipe()
.Add_int_variable(orig_repo_id).Add_byte_pipe()
.Add_yn(file_is_orig).Add_byte_pipe()
.Add_int_variable(file_w).Add_byte_pipe()
.Add_int_variable(html_uid).Add_byte_pipe()
.Add_int_variable(html_w).Add_byte_pipe()
.Add_int_variable(html_h).Add_byte_pipe()
;
Data_write_hook(bfr);
bfr.Add_byte_nl();
}
public String Data_print() {
return String_.Concat_with_str("|", Int_.Xto_str(this.Img_tid()), String_.new_u8(lnki_ttl), Int_.Xto_str(html_uid), Int_.Xto_str(html_w), Int_.Xto_str(html_h)
, Int_.Xto_str(orig_repo_id), Int_.Xto_str(orig_ext), Yn.Xto_str(file_is_orig), Int_.Xto_str(file_w), Double_.Xto_str(lnki_time), Int_.Xto_str(lnki_page)
);
}
@gplx.Virtual public void Data_parse(Bry_rdr rdr) {
this.lnki_ttl = Xoa_app_.Utl__encoder_mgr().Http_url().Decode(rdr.Read_bry_to_pipe());
this.orig_ext = rdr.Read_int_to_pipe();
this.lnki_type = rdr.Read_byte_to_pipe();
this.lnki_w = rdr.Read_int_to_pipe();
this.lnki_h = rdr.Read_int_to_pipe();
this.lnki_upright = rdr.Read_double_to_pipe();
this.lnki_time = rdr.Read_double_to_pipe();
this.lnki_page = rdr.Read_int_to_pipe();
this.orig_repo_id = rdr.Read_int_to_pipe();
this.file_is_orig = rdr.Read_yn_to_pipe();
this.file_w = rdr.Read_int_to_pipe();
this.html_uid = rdr.Read_int_to_pipe();
this.html_w = rdr.Read_int_to_pipe();
this.html_h = rdr.Read_int_to_pipe();
}
@gplx.Virtual public void Data_write_hook(Bry_bfr bfr) {}
@Override public String toString() {return this.Data_print();} // TEST
public static final int Tid_basic = 0, Tid_gallery = 1;
public static final int
File_repo_id_commons = Xof_repo_itm_.Repo_remote
, File_repo_id_local = Xof_repo_itm_.Repo_local
, File_repo_id_null = Xof_repo_itm_.Repo_null
;
public static final Xohd_data_itm__base[] Ary_empty = new Xohd_data_itm__base[0];
}

View File

@@ -0,0 +1,44 @@
/*
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.hdumps.core; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.core.brys.*; import gplx.xowa.files.*;
public class Xohd_data_itm__gallery_itm extends Xohd_data_itm__base {
@Override public int Img_tid() {return Xohd_data_itm__base.Tid_gallery;}
@Override public byte Html_elem_tid() {return Xof_html_elem.Tid_img;}
public int Box_w() {return box_w;} private int box_w;
public int Img_w() {return img_w;} private int img_w;
public int Img_pad() {return img_pad;} private int img_pad;
public Xohd_data_itm__gallery_itm Data_init_gallery(int box_w, int img_w, int img_pad) {
this.box_w = box_w;
this.img_w = img_w;
this.img_pad = img_pad;
return this;
}
@Override public void Data_write_hook(Bry_bfr bfr) {
bfr .Add_int_variable(box_w).Add_byte_pipe()
.Add_int_variable(img_w).Add_byte_pipe()
.Add_int_variable(img_pad).Add_byte_pipe()
;
}
@Override public void Data_parse(Bry_rdr rdr) {
super.Data_parse(rdr);
this.box_w = rdr.Read_int_to_pipe();
this.img_w = rdr.Read_int_to_pipe();
this.img_pad = rdr.Read_int_to_pipe();
}
}

View File

@@ -0,0 +1,35 @@
/*
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.hdumps.core; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
public class Xohd_data_itm__gallery_mgr implements Xohd_data_itm {
public Xohd_data_itm__gallery_mgr(int uid, int box_max) {
this.uid = uid;
this.box_max = box_max;
}
public int Data_tid() {return Xohd_data_tid.Tid_gallery;}
public void Data_write(Bry_bfr bfr) {
bfr .Add_int_variable(Xohd_data_tid.Tid_gallery).Add_byte_pipe()
.Add_int_variable(uid).Add_byte_pipe()
.Add_int_variable(box_max).Add_byte_pipe()
;
bfr.Add_byte_nl();
}
public String Data_print() {return Int_.Xto_str(box_max);}
public int Uid() {return uid;} private int uid;
public int Box_max() {return box_max;} private int box_max;
}

View File

@@ -0,0 +1,23 @@
/*
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.hdumps.core; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.xowa.files.*;
public class Xohd_data_itm__img extends Xohd_data_itm__base {
@Override public int Img_tid() {return Xohd_data_itm__base.Tid_basic;}
@Override public byte Html_elem_tid() {return Xof_html_elem.Tid_img;}
}

View File

@@ -0,0 +1,26 @@
/*
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.hdumps.core; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
public class Xohd_data_tid { // SERIALIZED
public static final int
Tid_img = 1
, Tid_redlink = 2
, Tid_gallery = 3
, Tid_imap = 4
;
}

View File

@@ -0,0 +1,87 @@
/*
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.hdumps.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.core.primitives.*; import gplx.core.brys.*; import gplx.core.btries.*; import gplx.dbs.*; import gplx.ios.*;
import gplx.xowa.dbs.*; import gplx.xowa.pages.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hdumps.data.*; import gplx.xowa.html.hdumps.pages.*; import gplx.xowa.pages.skins.*; import gplx.xowa.html.hdumps.data.srl.*;
import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa2.gui.*;
public class Xohd_page_html_mgr__load {
private final Xohd_page_srl_mgr srl_mgr = Xohd_page_srl_mgr.I;
private final Bry_rdr rdr = new Bry_rdr(); private final List_adp rows = List_adp_.new_(), imgs = List_adp_.new_();
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);
}
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);
imgs.Clear();
int len = rows.Count();
for (int i = 0; i < len; ++i) {
Xowd_html_row row = (Xowd_html_row)rows.Get_at(i);
switch (row.Tid()) {
case Xowd_html_row.Tid_html: srl_mgr.Load(hpg, row.Data()); break;
case Xowd_html_row.Tid_img:
case Xowd_html_row.Tid_redlink:
Parse_data(hpg, row); break;
}
}
rows.Clear();
}
private void Parse_data(Xog_page hpg, Xowd_html_row row) {
rdr.Init(row.Data());
while (!rdr.Pos_is_eos()) {
int tid = rdr.Read_int_to_pipe();
switch (tid) {
case Xohd_data_tid.Tid_img : Load_data_img(); break; // 1|0|A.png|0|220|110|...
case Xohd_data_tid.Tid_gallery : Load_data_gallery(hpg); break; // 3|0|800
case Xohd_data_tid.Tid_redlink : Load_data_redlink(hpg); break; // 2|2|0|1
}
}
if (imgs.Count() > 0) hpg.Img_itms_((Xohd_data_itm__base[])imgs.To_ary_and_clear(Xohd_data_itm__base.class));
}
public static Xohd_data_itm__base Load_img(Bry_rdr rdr) {
int tid = rdr.Read_int_to_pipe();
Xohd_data_itm__base img_itm = null;
switch (tid) {
case Xohd_data_itm__base.Tid_basic : img_itm = new Xohd_data_itm__img(); break;
case Xohd_data_itm__base.Tid_gallery : img_itm = new Xohd_data_itm__gallery_itm(); break;
default : throw Exc_.new_unhandled(tid);
}
img_itm.Data_parse(rdr);
// Xoa_app_.Usr_dlg().Log_many("", "", "itm: ~{0}", img_itm.Data_print());
rdr.Pos_add_one();
return img_itm;
}
private void Load_data_img() {
Xohd_data_itm__base img = Load_img(rdr);
if (img == null) return;
imgs.Add(img);
}
private void Load_data_redlink(Xog_page hpg) {
Ordered_hash redlink_hash = hpg.Redlink_uids();
while (!rdr.Pos_is_eos()) {
Int_obj_ref redlink_uid = Int_obj_ref.new_(rdr.Read_int_to_pipe());
redlink_hash.Add(redlink_uid, redlink_uid);
}
}
private void Load_data_gallery(Xog_page hpg) {
int uid = rdr.Read_int_to_pipe();
int box_max = rdr.Read_int_to_pipe();
hpg.Gallery_itms().Add_if_dupe_use_nth(uid, new Xohd_data_itm__gallery_mgr(uid, box_max)); // TODO: temporarily added b/c last build did not add gallery uid correctly
}
}

View File

@@ -0,0 +1,52 @@
/*
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.hdumps.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hdumps.data.srl.*;
import gplx.xowa2.gui.*; import gplx.xowa.html.hdumps.pages.*; import gplx.xowa.parsers.lnkis.redlinks.*;
public class Xohd_page_html_mgr__save {
private Xohd_page_srl_mgr srl_mgr = Xohd_page_srl_mgr.I;
public void Update(Bry_bfr tmp_bfr, Xowd_html_tbl tbl, Xoae_page page) {
Xog_page hpg = new Xog_page();
hpg.Ctor_from_page(tmp_bfr, page);
tbl.Delete(page.Revision_data().Id());
this.Insert(tmp_bfr, tbl, hpg, page.Hdump_data());
}
public int Insert(Bry_bfr tmp_bfr, Xowd_html_tbl tbl, Xog_page hpg, Xopg_hdump_data hdump_data) {
int rv = 0;
int page_id = hpg.Page_id();
rv += Insert_row(tbl, page_id, Xowd_html_row.Tid_html , srl_mgr.Save(hpg, tmp_bfr));
rv += Insert_row(tbl, page_id, Xowd_html_row.Tid_img , Write_imgs(tmp_bfr, hdump_data.Imgs()));
rv += Insert_row(tbl, page_id, Xowd_html_row.Tid_redlink , Write_redlinks(tmp_bfr, hdump_data.Redlink_mgr()));
return rv;
}
private int Insert_row(Xowd_html_tbl tbl, int page_id, int row_tid, byte[] bry) {return bry == null ? 0 : tbl.Insert(page_id, row_tid, bry);}
public static byte[] Write_redlinks(Bry_bfr bfr, Xopg_redlink_idx_list redlink_mgr) {
int len = redlink_mgr.Len(); if (len == 0) return null;
for (int i = 0; i < len; ++i)
bfr.Add_int_variable(redlink_mgr.Get_at(i)).Add_byte_pipe();
return bfr.Xto_bry_and_clear();
}
public static byte[] Write_imgs(Bry_bfr bfr, List_adp imgs) {
int len = imgs.Count(); if (len == 0) return null; // no images; exit early, else will write blank String
for (int i = 0; i < len; ++i) {
Xohd_data_itm itm = (Xohd_data_itm)imgs.Get_at(i);
itm.Data_write(bfr);
}
return bfr.Xto_bry_and_clear();
}
}

View File

@@ -0,0 +1,46 @@
/*
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.hdumps.data.srl; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*; import gplx.xowa.html.hdumps.data.*;
import gplx.core.primitives.*; import gplx.xowa.html.hzips.*; import gplx.xowa2.gui.*;
public interface Xohd_page_srl_itm { // INFO: serializes Xog_page to a byte[] before storing in the wiki_page_html table
byte Tid();
void Save(Xog_page hpg, Bry_bfr bfr);
int Load(Xog_page hpg, byte[] bry, int bry_len, int itm_bgn, Int_obj_ref count_ref);
}
abstract class Xohd_page_srl_itm__base implements Xohd_page_srl_itm {
public abstract byte Tid();
protected void Save_tid_n_() {save_tid = false;} private boolean save_tid = true;
public void Save(Xog_page hpg, Bry_bfr bfr) {
byte[] bry = Save_itm(hpg); if (bry == null) return; // subclasses return null if nothing to save
int len = bry.length; if (len == 0) return; // don't bother saving 0-len
if (save_tid) // body doesn't save tid
bfr.Add_byte(this.Tid());
Xow_hzip_int_.Save_bin_int_abrv(bfr, len);
bfr.Add(bry);
}
public abstract byte[] Save_itm(Xog_page hpg);
public int Load(Xog_page hpg, byte[] bry, int bry_len, int itm_bgn, Int_obj_ref count_ref) {
int itm_len = Xow_hzip_int_.Load_bin_int_abrv(bry, bry_len, itm_bgn, count_ref); if (itm_len == -1) throw Exc_.new_("bry_itm has invalid len", "page", hpg.Page_id(), "tid", this.Tid());
int data_bgn = itm_bgn + count_ref.Val(); if (itm_len == 0) return data_bgn;
int data_end = data_bgn + itm_len;
byte[] itm_data = Bry_.Mid(bry, data_bgn, data_end);
this.Load_itm(hpg, itm_data);
return data_end - itm_bgn;
}
public abstract void Load_itm(Xog_page hpg, byte[] data);
}

View File

@@ -0,0 +1,34 @@
/*
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.hdumps.data.srl; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*; import gplx.xowa.html.hdumps.data.*;
public class Xohd_page_srl_itm_ {
public static final byte // SERIALIZED
Tid_body = 0
, Tid_html_module = 1
, Tid_display_ttl = 2
, Tid_content_sub = 3
, Tid_sidebar_div = 4
;
public static final Xohd_page_srl_itm[] Itms = new Xohd_page_srl_itm[] // NOTE: ary_idx must match tid above
{ new Xohd_page_srl_itm__body()
, new Xohd_page_srl_itm__html_module()
, new Xohd_page_srl_itm__display_ttl()
, new Xohd_page_srl_itm__content_sub()
, new Xohd_page_srl_itm__sidebar_div()
};
}

View File

@@ -0,0 +1,98 @@
/*
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.hdumps.data.srl; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*; import gplx.xowa.html.hdumps.data.*;
import org.junit.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hzips.*; import gplx.xowa.html.hdumps.pages.*;
import gplx.xowa2.gui.*;
public class Xohd_page_srl_itm_tst {
@Before public void init() {fxt.Clear();} private Xohd_page_srl_itm_fxt fxt = new Xohd_page_srl_itm_fxt();
@Test public void Body() {
fxt.Test_page(fxt.Make_page().Body_("A"), fxt.Make_srl_body("A"));
}
@Test public void Html_modules() {
fxt.Test_page(fxt.Make_page().Body_("A").Html_modules_(Bool_.Y, Bool_.N, Bool_.Y, Bool_.N), fxt.Make_srl_body("A"), fxt.Make_srl_html_modules(Bool_.Y, Bool_.N, Bool_.Y, Bool_.N));
}
@Test public void Body_all() {
fxt.Test_page(fxt.Make_page().Body_("A").Html_modules_(Bool_.Y, Bool_.N, Bool_.Y, Bool_.N).Display_ttl_("B").Content_sub_("C").Sidebar_div_("D")
, fxt.Make_srl_body("A")
, fxt.Make_srl_html_modules(Bool_.Y, Bool_.N, Bool_.Y, Bool_.N)
, fxt.Make_srl_display_ttl("B")
, fxt.Make_srl_content_sub("C")
, fxt.Make_srl_sidebar_div("D")
);
}
}
class Xohd_page_srl_itm_fxt {
private final Bry_bfr bfr = Bry_bfr.reset_(8);
public void Clear() {bfr.Clear();}
public Xog_page_bldr Make_page() {return new Xog_page_bldr();}
public Xohd_page_srl_itm_mok Make_srl_body(String s) {return Make_srl(Xohd_page_srl_itm_.Tid_body, s);}
public Xohd_page_srl_itm_mok Make_srl_display_ttl(String s) {return Make_srl(Xohd_page_srl_itm_.Tid_display_ttl, s);}
public Xohd_page_srl_itm_mok Make_srl_content_sub(String s) {return Make_srl(Xohd_page_srl_itm_.Tid_content_sub, s);}
public Xohd_page_srl_itm_mok Make_srl_sidebar_div(String s) {return Make_srl(Xohd_page_srl_itm_.Tid_sidebar_div, s);}
public Xohd_page_srl_itm_mok Make_srl(byte tid, String s) {return new Xohd_page_srl_itm_mok(tid, Bry_.new_u8(s));}
public Xohd_page_srl_itm_mok Make_srl_html_modules(boolean... v) {
return new Xohd_page_srl_itm_mok(Xohd_page_srl_itm_.Tid_html_module, new byte[] {Xohd_page_srl_itm__html_module.Calc_flag(v[0], v[1], v[2], v[3])});
}
public void Test_page(Xog_page_bldr hpg_bldr, Xohd_page_srl_itm_mok... expd_itms) {
Xog_page hpg = hpg_bldr.Bld();
byte[] actl = Xohd_page_srl_mgr.I.Save(hpg, bfr);
Tfds.Eq_ary(Xohd_page_srl_itm_mok.Xto_bry(bfr, expd_itms), actl);
Xog_page actl_hpg = new Xog_page();
Xohd_page_srl_mgr.I.Load(actl_hpg, actl);
Tfds.Eq_ary(actl, Xohd_page_srl_mgr.I.Save(hpg, bfr));
}
}
class Xog_page_bldr {
public byte[] Body() {return body;} public Xog_page_bldr Body_(String v) {body = Bry_.new_u8(v); return this;} private byte[] body;
public boolean[] Html_modules() {return html_modules;} public Xog_page_bldr Html_modules_(boolean... v) {html_modules = v; return this;} private boolean[] html_modules;
public byte[] Display_ttl() {return display_ttl;} public Xog_page_bldr Display_ttl_(String v) {display_ttl = Bry_.new_u8(v); return this;} private byte[] display_ttl;
public byte[] Content_sub() {return content_sub;} public Xog_page_bldr Content_sub_(String v) {content_sub = Bry_.new_u8(v); return this;} private byte[] content_sub;
public byte[] Sidebar_div() {return sidebar_div;} public Xog_page_bldr Sidebar_div_(String v) {sidebar_div = Bry_.new_u8(v); return this;} private byte[] sidebar_div;
public Xog_page Bld() {
Xog_page rv = new Xog_page();
rv.Page_body_(body);
Xopg_module_mgr mod_mgr = rv.Module_mgr();
if (html_modules != null) {
mod_mgr.Math_exists_(html_modules[0]);
mod_mgr.Imap_exists_(html_modules[1]);
mod_mgr.Gallery_packed_exists_(html_modules[2]);
mod_mgr.Hiero_exists_(html_modules[3]);
}
rv.Display_ttl_(display_ttl);
rv.Content_sub_(content_sub);
rv.Sidebar_div_(sidebar_div);
return rv;
}
}
class Xohd_page_srl_itm_mok {
public Xohd_page_srl_itm_mok(byte tid, byte[] data) {this.tid = tid; this.data = data;}
public byte Tid() {return tid;} private final byte tid;
public int Len() {return data.length;}
public byte[] Data() {return data;} private final byte[] data;
public static byte[] Xto_bry(Bry_bfr bfr, Xohd_page_srl_itm_mok[] ary) {
int len = ary.length;
for (int i = 0; i < len; ++i) {
Xohd_page_srl_itm_mok itm = ary[i];
if (itm.Tid() != Xohd_page_srl_itm_.Tid_body)
bfr.Add_byte(itm.Tid());
Xow_hzip_int_.Save_bin_int_abrv(bfr, itm.Len());
bfr.Add(itm.Data());
}
return bfr.Xto_bry_and_clear();
}
}

View File

@@ -0,0 +1,75 @@
/*
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.hdumps.data.srl; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*; import gplx.xowa.html.hdumps.data.*;
import gplx.core.primitives.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hzips.*; import gplx.xowa.html.hdumps.pages.*;
import gplx.xowa2.gui.*;
class Xohd_page_srl_itm__body extends Xohd_page_srl_itm__base {
public Xohd_page_srl_itm__body() {this.Save_tid_n_();}
@Override public byte Tid() {return Xohd_page_srl_itm_.Tid_body;}
@Override public byte[] Save_itm(Xog_page hpg) {return hpg.Page_body();}
@Override public void Load_itm(Xog_page hpg, byte[] data) {hpg.Page_body_(data);}
}
class Xohd_page_srl_itm__display_ttl extends Xohd_page_srl_itm__base {
@Override public byte Tid() {return Xohd_page_srl_itm_.Tid_display_ttl;}
@Override public byte[] Save_itm(Xog_page hpg) {return hpg.Display_ttl();}
@Override public void Load_itm(Xog_page hpg, byte[] data) {hpg.Display_ttl_(data);}
}
class Xohd_page_srl_itm__content_sub extends Xohd_page_srl_itm__base {
@Override public byte Tid() {return Xohd_page_srl_itm_.Tid_content_sub;}
@Override public byte[] Save_itm(Xog_page hpg) {return hpg.Content_sub();}
@Override public void Load_itm(Xog_page hpg, byte[] data) {hpg.Content_sub_(data);}
}
class Xohd_page_srl_itm__sidebar_div extends Xohd_page_srl_itm__base {
@Override public byte Tid() {return Xohd_page_srl_itm_.Tid_sidebar_div;}
@Override public byte[] Save_itm(Xog_page hpg) {return hpg.Sidebar_div();}
@Override public void Load_itm(Xog_page hpg, byte[] data) {hpg.Sidebar_div_(data);}
}
class Xohd_page_srl_itm__html_module implements Xohd_page_srl_itm {
public byte Tid() {return Xohd_page_srl_itm_.Tid_html_module;}
public int Load(Xog_page hpg, byte[] bry, int bry_len, int itm_bgn, Int_obj_ref count_ref) {
itm_bgn += 2; // skip bin_int_abrv of [1, 0]
byte flag = bry[itm_bgn];
hpg.Module_mgr().Init(Enm_.Has_byte(flag, Tid_math), Enm_.Has_byte(flag, Tid_imap), Enm_.Has_byte(flag, Tid_packed), Enm_.Has_byte(flag, Tid_hiero));
return 3;
}
public void Save(Xog_page hpg, Bry_bfr bfr) {
byte flag = Calc_flag(hpg);
if (flag == 0) return;
bfr.Add_byte(this.Tid());
Xow_hzip_int_.Save_bin_int_abrv(bfr, 1);
bfr.Add_byte(flag);
}
private static byte Calc_flag(Xog_page hpg) {
Xopg_module_mgr module_mgr = hpg.Module_mgr();
return Calc_flag(module_mgr.Math_exists(), module_mgr.Imap_exists(), module_mgr.Gallery_packed_exists(), module_mgr.Hiero_exists());
}
public static byte Calc_flag(boolean math, boolean imap, boolean packed, boolean hiero) {
byte rv = 0;
if (math) rv = Enm_.Add_byte(rv, Tid_math);
if (imap) rv = Enm_.Add_byte(rv, Tid_imap);
if (packed) rv = Enm_.Add_byte(rv, Tid_packed);
if (hiero) rv = Enm_.Add_byte(rv, Tid_hiero);
return rv;
}
private static final byte // SERIALIZED; only supports 8 different types
Tid_math = 1
, Tid_imap = 2
, Tid_packed = 4
, Tid_hiero = 8
;
}

View File

@@ -0,0 +1,44 @@
/*
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.hdumps.data.srl; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*; import gplx.xowa.html.hdumps.data.*;
import gplx.core.primitives.*; import gplx.xowa.html.hdumps.core.*;
import gplx.xowa2.gui.*;
public class Xohd_page_srl_mgr {
private final Xohd_page_srl_itm[] itm_ary; private final Xohd_page_srl_itm itm_body;
private final Int_obj_ref count_ref = Int_obj_ref.zero_();
public Xohd_page_srl_mgr(Xohd_page_srl_itm[] itm_ary) {
this.itm_ary = itm_ary;
this.itm_body = itm_ary[0];
}
public byte[] Save(Xog_page hpg, Bry_bfr bfr) {
for (Xohd_page_srl_itm itm : itm_ary)
itm.Save(hpg, bfr);
return bfr.Xto_bry_and_clear();
}
public void Load(Xog_page hpg, byte[] bry) {
if (bry == null) return;
int bry_len = bry.length; if (bry_len == 0) return;
int pos = itm_body.Load(hpg, bry, bry_len, 0, count_ref); // assume every page has a body; saves 1 byte by not specifying tid for body
while (pos < bry_len) {
byte itm_tid = bry[pos]; // itm_tid is always 1-byte
Xohd_page_srl_itm itm = itm_ary[itm_tid]; // itm_tid always matches itm_ary's idx
pos += itm.Load(hpg, bry, bry_len, pos + 1, count_ref) + 1; // +1 to skip tid
}
}
public static final Xohd_page_srl_mgr I = new Xohd_page_srl_mgr(Xohd_page_srl_itm_.Itms);
}

View File

@@ -0,0 +1,39 @@
/*
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.hdumps.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.xowa.html.hdumps.core.*; import gplx.xowa.files.*;
import gplx.xowa.parsers.lnkis.redlinks.*;
public class Xopg_hdump_data {
public byte[] Body() {return body;} public void Body_(byte[] v) {body = v;} private byte[] body;
public Xopg_redlink_idx_list Redlink_mgr() {return redlink_mgr;} private final Xopg_redlink_idx_list redlink_mgr = new Xopg_redlink_idx_list();
public List_adp Imgs() {return imgs;} private final List_adp imgs = List_adp_.new_();
public void Imgs_add(Xohd_data_itm itm) {imgs.Add(itm);}
public void Imgs_add_img(Xohd_data_itm__base img, Xof_file_itm xfer, int tid) {
img.Data_init_base
( xfer.Lnki_ttl(), xfer.Lnki_type(), xfer.Lnki_upright(), xfer.Lnki_w(), xfer.Lnki_h(), xfer.Lnki_time(), xfer.Lnki_page()
, xfer.Orig_repo_id(), xfer.Orig_ext().Id(), xfer.File_is_orig(), xfer.File_w()
, xfer.Html_uid(), xfer.Html_w(), xfer.Html_h()
);
imgs.Add(img);
}
public void Clear() {
body = null;
imgs.Clear();
redlink_mgr.Clear();
}
}

View File

@@ -0,0 +1,33 @@
/*
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.hdumps.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
public class Xopg_module_mgr {
public boolean Math_exists() {return math_exists;} public void Math_exists_(boolean v) {math_exists = v;} private boolean math_exists;
public boolean Imap_exists() {return imap_exists;} public void Imap_exists_(boolean v) {imap_exists = v;} private boolean imap_exists;
public boolean Gallery_packed_exists() {return gallery_packed_exists;} public void Gallery_packed_exists_(boolean v) {gallery_packed_exists = v;} private boolean gallery_packed_exists;
public boolean Hiero_exists() {return hiero_exists;} public void Hiero_exists_(boolean v) {hiero_exists = v;} private boolean hiero_exists;
public void Init(boolean math, boolean imap, boolean packed, boolean hiero) {
this.math_exists = math;
this.imap_exists = imap;
this.gallery_packed_exists = packed;
this.hiero_exists = hiero;
}
public void Clear() {
math_exists = imap_exists = gallery_packed_exists = hiero_exists = false;
}
}

View File

@@ -0,0 +1,75 @@
/*
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,243 @@
/*
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.xowa.wikis.xwikis.*; import gplx.xowa.net.*; import gplx.xowa.parsers.lnkes.*;
import gplx.xowa.wikis.*;
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
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"
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_u8("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 Exc_.new_("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 Exc_.new_("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;
}
/*
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,249 @@
/*
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.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();
}
@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 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 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 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 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 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 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 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 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 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 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 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 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"));
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();
}
@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 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 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 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();}
}
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);
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());
}
}

View File

@@ -0,0 +1,54 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
class Hzip_bfr_mgr {
private Gfo_usr_dlg usr_dlg; private Bry_bfr_mkr bfr_mkr;
private List_adp stack = List_adp_.new_();
public Hzip_bfr_mgr(Gfo_usr_dlg usr_dlg, Bry_bfr_mkr bfr_mkr) {this.usr_dlg = usr_dlg; this.bfr_mkr = bfr_mkr;}
public Bry_bfr Add(Hzip_bfr_itm__base itm) {
stack.Add(itm);
return bfr_mkr.Get_k004();
}
public Bry_bfr Pop(int expd_tid, Bry_bfr cur, byte[] src, int src_len, int pos) {
Hzip_bfr_itm__base itm = (Hzip_bfr_itm__base)List_adp_.Pop(stack);
if (expd_tid != itm.Tid()) {usr_dlg.Warn_many("", "", "bfr_mgr tid does not match; expd=~{0} actl=~{1}", expd_tid, itm.Tid());}
itm.Pop_exec(cur, src, src_len, pos);
cur.Mkr_rls();
return itm.Bfr();
}
}
abstract class Hzip_bfr_itm__base {
public Hzip_bfr_itm__base Init(Bry_bfr bfr) {this.bfr = bfr; return this;}
public Bry_bfr Bfr() {return bfr;} protected Bry_bfr bfr;
public abstract int Tid();
public abstract void Pop_exec(Bry_bfr cur, byte[] src, int src_len, int pos);
}
class Hzip_bfr_itm__anchor extends Hzip_bfr_itm__base { // <a href="/wiki/File:Earth_Eastern_Hemisphere.jpg" class="image" title="Photograph of Earth, taken by NASA" xowa_title="Earth Eastern Hemisphere.jpg">
@Override public int Tid() {return Tid_file;} public static final int Tid_file = 1;
@Override public void Pop_exec(Bry_bfr cur, byte[] src, int src_len, int pos) {
byte[] caption_bry = cur.Xto_bry(); // Calc_title(cur.Xto_bry())
bfr.Add(caption_bry).Add_str("'>");
bfr.Add_bfr_and_clear(cur);
bfr.Add_str_a7("</a>");
}
public static Hzip_bfr_itm__base new_(Bry_bfr cur, byte[] src, int src_len, int pos) {
Hzip_bfr_itm__anchor rv = new Hzip_bfr_itm__anchor();
rv.Init(cur);
return rv;
}
}

View File

@@ -0,0 +1,49 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xodump_stats_itm {
public void Clear() {
a_rhs = lnki_text_n = lnki_text_y = lnke_txt = lnke_brk_text_n = lnke_brk_text_y = 0;
hdr_1 = hdr_2 = hdr_3 = hdr_4 = hdr_5 = hdr_6 = 0;
img_full = 0;
}
public int A_rhs() {return a_rhs;} public void A_rhs_add() {++a_rhs;} private int a_rhs;
public int Lnki_text_n() {return lnki_text_n;} public void Lnki_text_n_add() {++lnki_text_n;} private int lnki_text_n;
public int Lnki_text_y() {return lnki_text_y;} public void Lnki_text_y_add() {++lnki_text_y;} private int lnki_text_y;
public int Lnke_txt() {return lnke_txt;} public void Lnke_txt_add() {++lnke_txt;} private int lnke_txt;
public int Lnke_brk_text_n() {return lnke_brk_text_n;} public void Lnke_brk_text_n_add() {++lnke_brk_text_n;} private int lnke_brk_text_n;
public int Lnke_brk_text_y() {return lnke_brk_text_y;} public void Lnke_brk_text_y_add() {++lnke_brk_text_y;} private int lnke_brk_text_y;
public int Img_full() {return img_full;} public void Img_full_add() {++img_full;} private int img_full;
public int Hdr_1() {return hdr_1;} private int hdr_1;
public int Hdr_2() {return hdr_2;} private int hdr_2;
public int Hdr_3() {return hdr_3;} private int hdr_3;
public int Hdr_4() {return hdr_4;} private int hdr_4;
public int Hdr_5() {return hdr_5;} private int hdr_5;
public int Hdr_6() {return hdr_6;} private int hdr_6;
public void Hdr_add(byte hdr_num) {
switch (hdr_num) {
case 1: ++hdr_1; break;
case 2: ++hdr_2; break;
case 3: ++hdr_3; break;
case 4: ++hdr_4; break;
case 5: ++hdr_5; break;
case 6: ++hdr_6; break;
default: throw Exc_.new_unhandled(hdr_num);
}
}
}

View File

@@ -0,0 +1,75 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.dbs.*; import gplx.dbs.engines.sqlite.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hzips.*; import gplx.xowa.html.hdumps.pages.*;
import gplx.xowa2.gui.*;
public class Xodump_stats_tbl implements RlsAble {
private static final String tbl_name = "hdump_stats"; private static final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private static final String
fld_page_id = flds.Add_int_pkey("page_id"), fld_wtxt_len = flds.Add_int("wtxt_len"), fld_row_orig_len = flds.Add_int("row_orig_len"), fld_row_zip_len = flds.Add_int("row_zip_len")
, fld_body_len = flds.Add_int("body_len"), fld_display_ttl_len = flds.Add_int("display_ttl_len"), fld_content_sub_len = flds.Add_int("content_sub_len"), fld_sidebar_div_len = flds.Add_int("sidebar_div_len")
, fld_js_math = flds.Add_int("js_math"), fld_js_imap = flds.Add_int("js_imap"), fld_js_packed = flds.Add_int("js_packed"), fld_js_hiero = flds.Add_int("js_hiero")
, fld_a_rhs = flds.Add_int("a_rhs"), fld_lnki_text_n = flds.Add_int("lnki_text_n"), fld_lnki_text_y = flds.Add_int("lnki_text_y")
, fld_lnke_txt = flds.Add_int("lnke_txt"), fld_lnke_brk_text_n = flds.Add_int("lnke_brk_text_n"), fld_lnke_brk_text_y = flds.Add_int("lnke_brk_text_y")
, fld_hdr_1 = flds.Add_int("hdr_1"), fld_hdr_2 = flds.Add_int("hdr_2"), fld_hdr_3 = flds.Add_int("hdr_3"), fld_hdr_4 = flds.Add_int("hdr_4"), fld_hdr_5 = flds.Add_int("hdr_5"), fld_hdr_6 = flds.Add_int("hdr_6")
, fld_img_full = flds.Add_int("img_full")
;
private final Db_conn conn; private Db_stmt stmt_insert;
public Xodump_stats_tbl(Db_conn conn) {
this.conn = conn;
this.Create_tbl();
conn.Stmt_delete(tbl_name).Exec_delete(); // always zap table
conn.Rls_reg(this);
}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds, Db_meta_idx.new_unique_by_tbl(tbl_name, "pkey", fld_page_id)));}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
}
public void Insert(Xog_page hpg, Xodump_stats_itm hzip, int wtxt_len, int row_orig_len, int row_zip_len) {
Xopg_module_mgr js_mgr = hpg.Module_mgr();
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_page_id , hpg.Page_id())
.Val_int(fld_wtxt_len , wtxt_len)
.Val_int(fld_row_orig_len , row_orig_len)
.Val_int(fld_row_zip_len , row_zip_len)
.Val_int(fld_body_len , Len_or_0(hpg.Page_body()))
.Val_int(fld_display_ttl_len , Len_or_0(hpg.Display_ttl()))
.Val_int(fld_content_sub_len , Len_or_0(hpg.Content_sub()))
.Val_int(fld_sidebar_div_len , Len_or_0(hpg.Sidebar_div()))
.Val_bool_as_byte(fld_js_math , js_mgr.Math_exists())
.Val_bool_as_byte(fld_js_imap , js_mgr.Imap_exists())
.Val_bool_as_byte(fld_js_packed , js_mgr.Gallery_packed_exists())
.Val_bool_as_byte(fld_js_hiero , js_mgr.Hiero_exists())
.Val_int(fld_a_rhs , hzip.A_rhs())
.Val_int(fld_lnki_text_n , hzip.Lnki_text_n())
.Val_int(fld_lnki_text_y , hzip.Lnki_text_y())
.Val_int(fld_lnke_txt , hzip.Lnke_txt())
.Val_int(fld_lnke_brk_text_n , hzip.Lnke_brk_text_n())
.Val_int(fld_lnke_brk_text_y , hzip.Lnke_brk_text_y())
.Val_int(fld_hdr_1 , hzip.Hdr_1())
.Val_int(fld_hdr_2 , hzip.Hdr_2())
.Val_int(fld_hdr_3 , hzip.Hdr_3())
.Val_int(fld_hdr_4 , hzip.Hdr_4())
.Val_int(fld_hdr_5 , hzip.Hdr_5())
.Val_int(fld_hdr_6 , hzip.Hdr_6())
.Val_int(fld_img_full , hzip.Img_full())
.Exec_insert();
}
private int Len_or_0(byte[] bry) {return bry == null ? 0 : bry.length;}
}

View File

@@ -0,0 +1,44 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
class Xow_hzip_dict {// SERIALIZED
public static final byte Escape = Byte_.By_int(255);
public static final byte[] Escape_bry = Bry_.ints_(255);
public static final byte
Tid_a_rhs = 0
, Tid_lnki_text_n = 1
, Tid_lnki_text_y = 2
, Tid_lnke_txt = 3
, Tid_lnke_brk_text_n = 4
, Tid_lnke_brk_text_y = 5
, Tid_img_full = 6
, Tid_hdr_lhs = 7
, Tid_hdr_rhs = 8
;
public static final byte[]
Bry_a_rhs = Bry_.ints_(Escape, Tid_a_rhs)
, Bry_lnki_text_n = Bry_.ints_(Escape, Tid_lnki_text_n)
, Bry_lnki_text_y = Bry_.ints_(Escape, Tid_lnki_text_y)
, Bry_lnke_txt = Bry_.ints_(Escape, Tid_lnke_txt)
, Bry_lnke_brk_text_n = Bry_.ints_(Escape, Tid_lnke_brk_text_n)
, Bry_lnke_brk_text_y = Bry_.ints_(Escape, Tid_lnke_brk_text_y)
, Bry_img_full = Bry_.ints_(Escape, Tid_img_full)
, Bry_hdr_lhs = Bry_.ints_(Escape, Tid_hdr_lhs)
, Bry_hdr_rhs = Bry_.ints_(Escape, Tid_hdr_rhs)
;
}

View File

@@ -0,0 +1,64 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.primitives.*;
public class Xow_hzip_int_ {
private static final int Base_255_int = 255;
private static final byte Base_255_byte = (byte)255;
public static byte[] Save_bin_int_abrv(int val_int) {
Bry_bfr bfr = Bry_bfr.reset_(10);
Save_bin_int_abrv(bfr, val_int);
return bfr.Xto_bry_and_clear();
}
public static void Save_bin_int_abrv(Bry_bfr bfr, int val_int) { // save int in binary little endian form; range from -2,080,766,977 to 2,147,483,648; 255^4 or 4,228,250,625
if (val_int == 0) {bfr.Add_byte(Byte_ascii.Nil); return;}
long val = val_int;
if (val < 0) val = Int_.MaxValue + -val;
int count = 0;
while (val > 0) {
byte mod = (byte)(val % Base_255_int);
int adj = 0;
if (mod == 0) {mod = Base_255_byte; adj = 1;} // if 0, then set byte to 255; also set adj to 1 to properly decrement value
bfr.Add_byte(mod);
++count;
val = (val - adj) / Base_255_int;
}
if (count < 4) bfr.Add_byte(Byte_ascii.Nil);
}
public static int Load_bin_int_abrv(byte[] bry, int bry_len, int bgn, Int_obj_ref count_ref) {
int end = bgn + 4; // read no more than 4 bytes
int count = 0;
long rv = 0; int mult = 1;
for (int i = bgn; i < end; ++i) {
if (i == bry_len) break;
else {
++count;
int b = bry[i] & 0xFF; // PATCH.JAVA:need to convert to unsigned byte
if (b == 0) break;
rv += (b * mult);
mult *= Base_255_int;
}
}
if (rv > Int_.MaxValue) {
rv -= Int_.MaxValue;
rv *= -1;
}
count_ref.Val_(count);
return (int)rv;
}
}

View File

@@ -0,0 +1,52 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*; import gplx.core.primitives.*;
public class Xow_hzip_int__tst {
@Before public void init() {fxt.Clear();} private Xow_hzip_int__fxt fxt = new Xow_hzip_int__fxt();
@Test public void Srl() {
fxt.Test_srl( 0, 0);
fxt.Test_srl( 1, 1, 0);
fxt.Test_srl( 255, 255, 0);
fxt.Test_srl( 256, 1, 1, 0);
fxt.Test_srl( 257, 2, 1, 0);
fxt.Test_srl( 510, 255, 1, 0);
fxt.Test_srl( 511, 1, 2, 0);
fxt.Test_srl( 512, 2, 2, 0);
fxt.Test_srl( 65280, 255, 255, 0);
fxt.Test_srl( 65281, 1, 1, 1, 0);
fxt.Test_srl( 16646655, 255, 255, 255, 0);
fxt.Test_srl( 16646656, 1, 1, 1, 1);
fxt.Test_srl( 16646657, 2, 1, 1, 1);
fxt.Test_srl(Int_.MaxValue, 127, 129, 130, 129);
fxt.Test_srl( -1, 128, 129, 130, 129);
fxt.Test_srl( -2, 129, 129, 130, 129);
}
}
class Xow_hzip_int__fxt {
private final Bry_bfr bfr = Bry_bfr.reset_(8); private final Int_obj_ref read = Int_obj_ref.zero_();
public void Clear() {bfr.Clear();}
public void Test_srl(int val, int... bytes) {
Xow_hzip_int_.Save_bin_int_abrv(bfr, val);
byte[] save = bfr.Xto_bry_and_clear();
Tfds.Eq_ary(Bry_.ints_(bytes), save, "save");
int load = Xow_hzip_int_.Load_bin_int_abrv(save, save.length, 0, read);
Tfds.Eq(val, load, "load");
Tfds.Eq(bytes.length, read.Val(), "load_read");
}
}

View File

@@ -0,0 +1,236 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.primitives.*; import gplx.core.brys.*; import gplx.core.btries.*;
import gplx.html.*; import gplx.xowa.wikis.ttls.*;
public class Xow_hzip_itm__anchor {
private Xow_hzip_mgr hzip_mgr; private Xow_ttl_parser ttl_parser; private Byte_obj_ref xtid_ref = Byte_obj_ref.zero_();
private Bry_rdr bry_rdr = new Bry_rdr();
public Xow_hzip_itm__anchor(Xow_hzip_mgr hzip_mgr, Xow_ttl_parser ttl_parser) {this.hzip_mgr = hzip_mgr; this.ttl_parser = ttl_parser;}
public int Save_a_rhs(Bry_bfr bfr, Xodump_stats_itm stats, byte[] src, int src_len, int bgn, int pos) {
bfr.Add(Xow_hzip_dict.Bry_a_rhs);
stats.A_rhs_add();
return pos;
}
public int Save(Bry_bfr bfr, Xodump_stats_itm stats, byte[] src, int src_len, int bgn, int pos) {
int xtid_end = Xow_hzip_xtid.Find_xtid(hzip_mgr, src, src_len, bgn, pos, xtid_ref); if (xtid_end == Xow_hzip_mgr.Unhandled) return Xow_hzip_mgr.Unhandled;
byte xtid_val = xtid_ref.Val();
switch (xtid_val) {
case Xow_hzip_dict.Tid_lnki_text_n:
case Xow_hzip_dict.Tid_lnki_text_y: return Save_lnki(bfr, stats, src, src_len, bgn, xtid_end, xtid_val == Xow_hzip_dict.Tid_lnki_text_y);
case Xow_hzip_dict.Tid_lnke_txt:
case Xow_hzip_dict.Tid_lnke_brk_text_n:
case Xow_hzip_dict.Tid_lnke_brk_text_y: return Save_lnke(bfr, stats, src, src_len, bgn, xtid_end, xtid_val);
case Xow_hzip_dict.Tid_img_full: return Save_img_full(bfr, stats, src, src_len, bgn, xtid_end);
default: return hzip_mgr.Warn_by_pos("a.xtid_unknown", bgn, pos);
}
}
private static int[] Save_img_full_pow = new int[] {0, 1, 2};
private int Save_img_full(Bry_bfr bfr, Xodump_stats_itm stats, byte[] src, int src_len, int bgn, int pos) {
bfr.Add(Xow_hzip_dict.Bry_img_full);
int xatrs_bgn = Bry_finder.Move_fwd(src, Find_img_xatrs, pos, src_len); if (xatrs_bgn == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.img_xatrs_missing", bgn, pos);
bry_rdr.Init(src, xatrs_bgn);
int a_cls = bry_rdr.Read_int_to_pipe();
int a_rel = bry_rdr.Read_int_to_pipe();
int img_rel = bry_rdr.Read_int_to_pipe();
byte meta = (byte)Bit_.Shift_lhs_to_int(Save_img_full_pow, a_cls, a_rel, img_rel);
bfr.Add_byte(meta); // meta
Xow_hzip_int_.Save_bin_int_abrv(bfr, bry_rdr.Read_int_to_pipe()); // uid
bfr.Add(bry_rdr.Read_bry_to_pipe()).Add_byte_pipe(); // img_cls_other
bfr.Add(bry_rdr.Read_bry_to_apos()); // alt
bfr.Add_byte(Xow_hzip_dict.Escape);
return bry_rdr.Pos() + 2; // +2=/>
}
public int Save_lnki(Bry_bfr bfr, Xodump_stats_itm stats, byte[] src, int src_len, int bgn, int pos, boolean caption) {
// href
int ttl_bgn = Bry_finder.Find_fwd(src, Find_href_bry, pos, src_len); if (ttl_bgn == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled;//hzip_mgr.Warn_by_pos_add_dflt("a.ttl_bgn_missing", bgn, pos);
ttl_bgn += Find_href_bry.length;
// site or wiki; EX: "/site/" or "/wiki/"
byte[] site = null;
Object href_tid_obj = btrie_href.Match_bgn(src, ttl_bgn, src_len);
if (href_tid_obj == null) return Xow_hzip_mgr.Unhandled; // not "/wiki/" or "/site/"
if (((Byte_obj_val)href_tid_obj).Val() == Href_tid_site) { // site; EX:"/site/en.wiktionary.org/"
int site_bgn = ttl_bgn + Href_bry_len; int site_end = Bry_finder.Find_fwd(src, Byte_ascii.Slash, site_bgn);
byte[] site_domain = Bry_.Mid(src, site_bgn, site_end);
site = site_domain;
}
else // page; EX: "/wiki/Page"
ttl_bgn += Href_bry_len;
int ttl_end = Bry_finder.Find_fwd(src, Byte_ascii.Quote, ttl_bgn , src_len); if (ttl_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.ttl_end_missing", bgn, ttl_bgn);
Xoa_ttl ttl = ttl_parser.Ttl_parse(Bry_.Mid(src, ttl_bgn, ttl_end)); if (ttl == null) return hzip_mgr.Warn_by_pos("a.ttl_invalid", ttl_bgn, ttl_end);
int a_lhs_end = Bry_finder.Find_fwd(src, Byte_ascii.Gt, ttl_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, ttl_end);
++a_lhs_end; // skip >
// id
int id_bgn = Bry_finder.Find_fwd(src, Find_id_bry, ttl_end, src_len); if (id_bgn == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled;
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 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;
if ( !caption // lnki_text_n; EX: [[A]] not [[A|A1]]
&& site == null // not xwiki; EX: [[wikt:A]]
&& html_text_len != ttl_len) { // note that in 99% of lnki_text_n cases, html_text_len == text_len; however, tidy sometimes relocates html inside html_text; PAGE:en.w:Abyssal_plain; EX:<font color='green'>[[A]]</font>; DATE:2015-06-02
caption = true; // change to lnki_text_y
}
// caption
if (caption)
bfr.Add(Xow_hzip_dict.Bry_lnki_text_y);
else
bfr.Add(Xow_hzip_dict.Bry_lnki_text_n);
bfr.Add_byte((byte)ttl.Ns().Ord()); // ASSUME:NS_MAX_255; no more than 255 ns in wiki; note that ids > 255 still supported
Xow_hzip_int_.Save_bin_int_abrv(bfr, id);
if (site != null) {
bfr.Add_byte_pipe().Add(site).Add_byte_pipe();
}
if (caption) {
bfr.Add(ttl.Page_db());
bfr.Add_byte(Xow_hzip_dict.Escape);
stats.Lnki_text_y_add();
return a_lhs_end;
}
else {
if (!ttl.Ns().Id_main()) // non-main ns should write page_db only; EX: "Template:A" should write "A" since "Template" will be inferred by ns_id
bfr.Add(ttl.Page_db());
else // main ns should write html_text; handles [[a]] which has <a href="A">a</a>
bfr.Add_mid(src, a_lhs_end, a_rhs_bgn);
bfr.Add_byte(Xow_hzip_dict.Escape);
stats.Lnki_text_n_add();
return a_rhs_bgn + Find_a_rhs_bgn_len;
}
}
public int Save_lnke(Bry_bfr bfr, Xodump_stats_itm stats, byte[] src, int src_len, int bgn, int pos, byte xtid) {// <a rel="nofollow" class="external free" href="http://a.org">http://a.org</a>
int href_bgn = Bry_finder.Find_fwd(src, Find_href_bry, pos, src_len); if (href_bgn == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.href_missing", bgn, pos);
href_bgn += Find_href_len;
int href_end = Bry_finder.Find_fwd(src, Byte_ascii.Quote, href_bgn, src_len); if (href_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.href_missing", bgn, href_bgn);
bfr.Add_byte(Xow_hzip_dict.Escape).Add_byte(xtid);
bfr.Add_mid(src, href_bgn, href_end);
bfr.Add_byte(Xow_hzip_dict.Escape);
switch (xtid) {
case Xow_hzip_dict.Tid_lnke_txt: {
int a_rhs_bgn = Bry_finder.Find_fwd(src, Find_a_rhs_bgn_bry, href_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, href_end);
stats.Lnke_txt_add();
return a_rhs_bgn + Find_a_rhs_bgn_len;
}
case Xow_hzip_dict.Tid_lnke_brk_text_n: {
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);
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;
if (!Bry_.Match(src, a_rhs_bgn, a_rhs_end, Find_a_rhs_bgn_bry)) return hzip_mgr.Warn_by_pos_add_dflt("a.rhs_missing", bgn, href_end);
stats.Lnke_brk_text_n_add();
return a_rhs_end;
}
case Xow_hzip_dict.Tid_lnke_brk_text_y: {
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);
stats.Lnke_brk_text_y_add();
return a_lhs_end + 1;
}
default:
return hzip_mgr.Warn_by_pos("a.xtid_unknown", bgn, href_end);
}
}
private Int_obj_ref count_ref = Int_obj_ref.zero_();
public int Load_lnke(Bry_bfr bfr, byte[] src, int src_len, int href_bgn, byte xtid) {
int href_end = Bry_finder.Find_fwd(src, Xow_hzip_dict.Escape, href_bgn, src_len); if (href_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.href_missing", href_bgn, href_bgn);
switch (xtid) {
case Xow_hzip_dict.Tid_lnke_txt:
bfr.Add_str_a7("<a rel=\"nofollow\" class=\"external free\" href=\"").Add_mid(src, href_bgn, href_end).Add_str_a7("\">").Add_mid(src, href_bgn, href_end).Add_str_a7("</a>");
return href_end + 1; // +1 to skip escape
case Xow_hzip_dict.Tid_lnke_brk_text_n:
int num = Xow_hzip_int_.Load_bin_int_abrv(src, src_len, href_end + 1, count_ref);
bfr.Add_str_a7("<a rel=\"nofollow\" class=\"external autonumber\" href=\"").Add_mid(src, href_bgn, href_end).Add_str_a7("\">[").Add_int_variable(num).Add_str_a7("]</a>");
return href_end + 1 + count_ref.Val(); // +1 to skip escape
case Xow_hzip_dict.Tid_lnke_brk_text_y:
bfr.Add_str_a7("<a rel=\"nofollow\" class=\"external text\" href=\"").Add_mid(src, href_bgn, href_end).Add_str_a7("\">");
return href_end + 1; // +1 to skip escape
default:
return hzip_mgr.Warn_by_pos("a.xtid_unknown", href_bgn, href_end);
}
}
private final Int_obj_ref id_count_ref = Int_obj_ref.neg1_();
public int Load_lnki(Bry_bfr bfr, byte[] src, int src_len, int bgn, byte tid, Ordered_hash redlink_uids) {
// ns; 255 max
byte ns_ord = src[bgn];
Xow_ns ns = ttl_parser.Ns_mgr().Ords_get_at(ns_ord);
// id
int id = Xow_hzip_int_.Load_bin_int_abrv(src, src_len, bgn + 1, id_count_ref);
// site
byte[] site_bry = null;
int ttl_bgn = bgn + 1 + id_count_ref.Val();
if (src[ttl_bgn] == Byte_ascii.Pipe) { // if "|" after ns, then site is present; EX: "0|enwiki" vs. "0page"
int site_bgn = ttl_bgn + 1;
int site_end = Bry_finder.Find_fwd(src, Byte_ascii.Pipe, site_bgn, src_len);
site_bry = Bry_.Mid(src, site_bgn, site_end);
ttl_bgn = site_end + 1;
}
// page
int ttl_end = Bry_finder.Find_fwd(src, Xow_hzip_dict.Escape, ttl_bgn, src_len); if (ttl_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.ttl_end_missing", bgn, ttl_bgn);
byte[] ttl_bry = Bry_.Mid(src, ttl_bgn, ttl_end);
Xoa_ttl ttl = ttl_parser.Ttl_parse(ns.Id(), ttl_bry); if (ttl == null) return hzip_mgr.Warn_by_pos_add_dflt("a.ttl_is_invalid", bgn, ttl_bgn);
byte[] ttl_full = ttl.Full_db();
bfr.Add_str_a7("<a href='");
if (site_bry != null) {
bfr.Add_str_a7("/site/");
bfr.Add(site_bry);
}
bfr.Add_str_a7("/wiki/");
bfr.Add(Html_utl.Escape_html_as_bry(ttl_full));
if (redlink_uids.Has(id_count_ref.Val_(id)))
bfr.Add_str_a7("' class='xowa_disabled");
bfr.Add_str_a7("' id='").Add_str_a7(gplx.xowa.parsers.lnkis.redlinks.Xopg_redlink_lnki_list.Lnki_id_prefix).Add_int_variable(id);
bfr.Add_str_a7("' title='");
int rv = ttl_end + 1;
if (tid == Xow_hzip_dict.Tid_lnki_text_n) {
if (ns.Id() != 0) ttl_bry = ttl_full;
bfr.Add(Html_utl.Escape_html_as_bry(ttl_bry)).Add_str_a7("'>").Add(ttl_bry);
bfr.Add_str_a7("</a>");
}
else {
bfr.Add(ttl.Page_txt()).Add_str_a7("'>");
}
return rv;
}
public void Html_plain(Bry_bfr bfr, Xop_lnki_tkn lnki) {
bfr.Add_str_a7
( lnki.Caption_exists() // caption exists; EX: [[A|b]]
|| lnki.Tail_bgn() != -1 // trailing chars; EX: [[A]]b
? "<a xtid='a_lnki_text_y' href=\"" // embed caption
: "<a xtid='a_lnki_text_n' href=\"" // use link only
);
}
private static final byte[]
Find_href_bry = Bry_.new_a7(" href=\"")
, Find_id_bry = Bry_.new_a7(" id=\"")
, Find_a_rhs_bgn_bry = Bry_.new_a7("</a>")
, Find_img_xatrs = Bry_.new_a7("xatrs='")
;
private static final byte Href_tid_wiki = 1, Href_tid_site = 2;
private static final int Href_bry_len = 6; // "/wiki/".length
private static final Btrie_fast_mgr btrie_href = Btrie_fast_mgr.cs_()
.Add_str_byte("/wiki/", Href_tid_wiki)
.Add_str_byte("/site/", Href_tid_site);
private static final int
Find_href_len = Find_href_bry.length
, Find_a_rhs_bgn_len = Find_a_rhs_bgn_bry.length
;
}

View File

@@ -0,0 +1,120 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*; import gplx.xowa.html.*;
public class Xow_hzip_itm__anchor_tst {
@Before public void init() {fxt.Clear();} private Xow_hzip_mgr_fxt fxt = new Xow_hzip_mgr_fxt();
@Test public void Srl_lnki_text_n() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_a7("A"), Xow_hzip_dict.Escape_bry); // 2=ns_ord for Main
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/A\" id=\"xowa_lnki_3\" title='A'>A</a>");
fxt.Test_load(brys, "<a href='/wiki/A' id='xowa_lnki_3' title='A'>A</a>");
}
@Test public void Srl_lnki_text_n_alt_case() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_a7("a"), Xow_hzip_dict.Escape_bry);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/A\" id=\"xowa_lnki_3\" title='A'>a</a>");
fxt.Test_load(brys, "<a href='/wiki/A' id='xowa_lnki_3' title='a'>a</a>");
}
@Test public void Srl_lnki_text_n_ns() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(12), fxt.Make_int(3), Bry_.new_a7("A"), Xow_hzip_dict.Escape_bry);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/Template:A\" id=\"xowa_lnki_3\" title='Template:A'>Template:A</a>");
fxt.Test_load(brys, "<a href='/wiki/Template:A' id='xowa_lnki_3' title='Template:A'>Template:A</a>");
}
@Test public void Srl_lnki_text_n_apos() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(12), fxt.Make_int(3), Bry_.new_a7("A'b"), Xow_hzip_dict.Escape_bry);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/Template:A'b\" id=\"xowa_lnki_3\" title='Template:A'b'>Template:A'b</a>");
fxt.Test_load(brys, "<a href='/wiki/Template:A&#39;b' id='xowa_lnki_3' title='Template:A&#39;b'>Template:A'b</a>");
}
@Test public void Srl_lnki_text_n_xwiki() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Byte_ascii.Pipe_bry, Bry_.new_a7("en.wiktionary.org"), Byte_ascii.Pipe_bry, Bry_.new_a7("A"), Xow_hzip_dict.Escape_bry);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/site/en.wiktionary.org/wiki/A\" id=\"xowa_lnki_3\" title='A'>A</a>");
fxt.Test_load(brys, "<a href='/site/en.wiktionary.org/wiki/A' id='xowa_lnki_3' title='A'>A</a>");
}
@Test public void Srl_lnki_text_n_smoke() {
byte[][] brys = Bry_.Ary(Bry_.new_a7("a_1"), Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_a7("A"), Xow_hzip_dict.Escape_bry, Bry_.new_a7("a_2"));
fxt.Test_save(brys, "a_1<a xtid='a_lnki_text_n' href=\"/wiki/A\" id=\"xowa_lnki_3\" title='A'>A</a>a_2");
fxt.Test_load(brys, "a_1<a href='/wiki/A' id='xowa_lnki_3' title='A'>A</a>a_2");
}
@Test public void Srl_lnki_text_y() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_a7("A"), Xow_hzip_dict.Escape_bry, Bry_.new_a7("A1"), Xow_hzip_dict.Bry_a_rhs);
fxt.Test_save(brys, "<a xtid='a_lnki_text_y' href=\"/wiki/A\" id=\"xowa_lnki_3\" title='A'>A1</a>");
fxt.Test_load(brys, "<a href='/wiki/A' id='xowa_lnki_3' title='A'>A1</a>");
}
@Test public void Srl_lnki_text_y_nest() {
byte[][] brys = Bry_.Ary
( Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_a7("A"), Xow_hzip_dict.Escape_bry
, Bry_.new_a7("B"), Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_a7("C"), Xow_hzip_dict.Escape_bry, Bry_.new_a7("C1"), Xow_hzip_dict.Bry_a_rhs, Bry_.new_a7("D")
, Xow_hzip_dict.Bry_a_rhs
);
fxt.Test_save(brys, "<a xtid='a_lnki_text_y' href=\"/wiki/A\" id=\"xowa_lnki_3\">B<a xtid='a_lnki_text_y' href=\"/wiki/C\" id=\"xowa_lnki_3\">C1</a>D</a>");
fxt.Test_load(brys, "<a href='/wiki/A' id='xowa_lnki_3' title='A'>B<a href='/wiki/C' id='xowa_lnki_3' title='C'>C1</a>D</a>");
}
@Test public void Srl_noop() {
byte[][] brys = Bry_.Ary(Bry_.new_u8("<a href='/wiki/A'>A"), Xow_hzip_dict.Bry_a_rhs); // NOTE: still converts "</a>" to hzip
fxt.Test_save(brys, "<a href='/wiki/A'>A</a>");
fxt.Test_load(brys, "<a href='/wiki/A'>A</a>");
}
@Test public void Srl_lnki_text_y__multiple() { // PURPOSE: if id is missing from 1st anchor, do not get from second
byte[][] brys = Bry_.Ary(Bry_.new_u8("<a xtid='a_lnki_text_n' href=\"/wiki/A\" title=\"A\">A")
, Xow_hzip_dict.Bry_a_rhs
, Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_a7("B"), Xow_hzip_dict.Escape_bry
);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/A\" title=\"A\">A</a><a xtid='a_lnki_text_n' href=\"/wiki/B\" id=\"xowa_lnki_3\" title=\"B\">B</a>");
fxt.Test_load(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/A\" title=\"A\">A</a><a href='/wiki/B' id='xowa_lnki_3' title='B'>B</a>");
}
@Test public void Srl_lnki_text_y__html() { // PURPOSE: PAGE:en.w:Abyssal_plain; DATE:2015-06-02
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_a7("A"), Xow_hzip_dict.Escape_bry, Bry_.new_a7("<font color='white'>A1</font>"), Xow_hzip_dict.Bry_a_rhs);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/A\" id=\"xowa_lnki_3\" title='A'><font color='white'>A1</font></a>");
}
@Test public void Srl_lnke_txt() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnke_txt, Bry_.new_a7("http://a.org"), Xow_hzip_dict.Escape_bry);
fxt.Test_save(brys, "<a xtid='a_lnke_txt' rel=\"nofollow\" class=\"external free\" href=\"http://a.org\">http://a.org</a>");
fxt.Test_load(brys, "<a rel=\"nofollow\" class=\"external free\" href=\"http://a.org\">http://a.org</a>");
}
@Test public void Srl_lnke_brk_y() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnke_brk_text_y, Bry_.new_a7("http://a.org"), Xow_hzip_dict.Escape_bry, Bry_.new_a7("A1"), Xow_hzip_dict.Bry_a_rhs);
fxt.Test_save(brys, "<a xtid='a_lnke_brk_y' class=\"external text\" rel=\"nofollow\" href=\"http://a.org\">A1</a>");
fxt.Test_load(brys, "<a rel=\"nofollow\" class=\"external text\" href=\"http://a.org\">A1</a>");
}
@Test public void Srl_lnke_brk_n() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnke_brk_text_n, Bry_.new_a7("http://a.org"), Xow_hzip_dict.Escape_bry, Xow_hzip_int_.Save_bin_int_abrv(123));
fxt.Test_save(brys, "<a xtid='a_lnke_brk_n' class=\"external autonumber\" rel=\"nofollow\" href=\"http://a.org\">[123]</a>");
fxt.Test_load(brys, "<a rel=\"nofollow\" class=\"external autonumber\" href=\"http://a.org\">[123]</a>");
}
@Test public void Html_lnki_ttl() {
fxt.Test_html("[[A]]", "<a xtid='a_lnki_text_n' href=\"/wiki/A\" xowa_redlink='1'>A</a>");
}
@Test public void Html_lnki_capt() {
fxt.Test_html("[[A|a]]", "<a xtid='a_lnki_text_y' href=\"/wiki/A\" xowa_redlink='1'>a</a>");
}
@Test public void Html_lnki_trail() {
fxt.Test_html("[[A]]b", "<a xtid='a_lnki_text_y' href=\"/wiki/A\" xowa_redlink='1'>Ab</a>");
}
@Test public void Html_lnki_xwiki() {
fxt.Init_xwiki("wikt", "en.wiktionary.org");
fxt.Test_html("[[wikt:A]]", "<a xtid='a_lnki_text_n' href=\"/site/en.wiktionary.org/wiki/A\" xowa_redlink='1'>wikt:A</a>");
}
@Test public void Html_lnke_txt() {
fxt.Test_html("http://a.org", "<a xtid='a_lnke_txt' href=\"http://a.org\" class=\"external text\" rel=\"nofollow\">http://a.org</a>");
}
@Test public void Html_lnke_brk_n() {
fxt.Test_html("[http://a.org]", "<a xtid='a_lnke_brk_n' href=\"http://a.org\" class=\"external text\" rel=\"nofollow\">[1]</a>");
}
@Test public void Html_lnke_brk_y() {
fxt.Test_html("[http://a.org A]", "<a xtid='a_lnke_brk_y' href=\"http://a.org\" class=\"external text\" rel=\"nofollow\">A</a>");
}
}

View File

@@ -0,0 +1,27 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*; import gplx.xowa.html.*;
public class Xow_hzip_itm__file_tst {
@Before public void init() {fxt.Clear();} private Xow_hzip_mgr_fxt fxt = new Xow_hzip_mgr_fxt();
@Test public void Srl_lnki_img_full() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_img_full, Bry_.ints_(7), Bry_.ints_(12, 0), Bry_.new_a7("cls_other"), Bry_.new_a7("|caption_other"), Xow_hzip_dict.Escape_bry);
fxt.Test_save(brys, "<a xtid='a_img_full' xatrs='1|1|1|12|cls_other|caption_other'/>");
// fxt.Test_load(brys, "a_1<a href='/wiki/A' title='A'>A</a>a_2");
}
}

View File

@@ -0,0 +1,55 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.html.*; import gplx.xowa.wikis.ttls.*;
public class Xow_hzip_itm__header {
private Xow_hzip_mgr hzip_mgr;
public Xow_hzip_itm__header(Xow_hzip_mgr hzip_mgr) {this.hzip_mgr = hzip_mgr;}
public int Save(Bry_bfr bfr, Xodump_stats_itm stats, byte[] src, int src_len, int bgn, int pos) {// <h2><span class='mw-headline' id='A'>A<xo_hdr_end/></span></h2>
if (pos >= src_len) return Xow_hzip_mgr.Unhandled;
byte hdr_num_byte = src[pos];
switch (hdr_num_byte) {
case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3:
case Byte_ascii.Num_4: case Byte_ascii.Num_5: case Byte_ascii.Num_6:
break;
default:
return Xow_hzip_mgr.Unhandled;
}
int span_lhs_bgn = pos + 2; // +2 to skip # and >; EX: "<h2>"
int span_lhs_end = Bry_finder.Find_fwd(src, Byte_ascii.Gt, span_lhs_bgn, src_len); if (span_lhs_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("h.span_end_missing", bgn, pos);
++span_lhs_end; // +1 to skip >
bfr.Add(Xow_hzip_dict.Bry_hdr_lhs);
byte hdr_num = (byte)(hdr_num_byte - Byte_ascii.Num_0);
bfr.Add_byte(hdr_num);
int hdr_end = Bry_finder.Find_fwd(src, Hdr_end, span_lhs_end, src_len); if (hdr_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("h.capt_end_missing", bgn, span_lhs_end);
bfr.Add_mid(src, span_lhs_end, hdr_end);
hdr_end += Hdr_end.length;
bfr.Add(Xow_hzip_dict.Escape_bry);
stats.Hdr_add(hdr_num);
return hdr_end + 12; // +12 = "</span></h2>"
}
public int Load(Bry_bfr bfr, byte[] src, int src_len, int bgn) {
byte hdr_num = (byte)(src[bgn] + Byte_ascii.Num_0);
int capt_bgn = bgn + 1;
int capt_end = Bry_finder.Find_fwd(src, Xow_hzip_dict.Escape, capt_bgn, src_len); if (capt_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("hdr.capt_end_missing", bgn, capt_bgn);
bfr.Add_str_a7("<h").Add_byte(hdr_num).Add_str("><span class='mw-headline' id='").Add_mid(src, capt_bgn, capt_end).Add_str("'>").Add_mid(src, capt_bgn, capt_end).Add_str("</span></h").Add_byte(hdr_num).Add_str(">");
return capt_end + 1;
}
public void Html(Bry_bfr bfr, boolean caption) {}
public static final byte[] Hdr_end = Bry_.new_a7("<!--xo_hdr_end-->");
}

View File

@@ -0,0 +1,38 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*; import gplx.xowa.html.*;
public class Xow_hzip_itm__header_tst {
@Before public void init() {fxt.Clear();} private Xow_hzip_mgr_fxt fxt = new Xow_hzip_mgr_fxt();
@Test public void Srl_basic() {
// byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_hdr_lhs, Bry_.ints_(2), Bry_.new_a7("A"), Xow_hzip_dict.Escape_bry);
// fxt.Test_save(brys, "<h2><span class='mw-headline' id='A'>A<!--xo_hdr_end--></span></h2>");
// fxt.Test_load(brys, "<h2><span class='mw-headline' id='A'>A</span></h2>");
}
// @Test public void Html_basic() {
// fxt.Test_html("==A==", "<h2><span class='mw-headline' id='A'>A<!--xo_hdr_end--></span></h2>\n");
// }
// @Test public void Srl_anchor() {
// byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_hdr_lhs, Bry_.ints_(2), Bry_.new_a7("A <a xtid='a_lnki_text_n' href=\"/wiki/B\" xowa_redlink='1'>b</a> c"), Xow_hzip_dict.Escape_bry);
// fxt.Test_save(brys, "<h2><span class='mw-headline' id='A_b_c'>A <a xtid='a_lnki_text_n' href=\"/wiki/B\" xowa_redlink='1'>b</a> c<!--xo_hdr_end--></span></h2>");
//// fxt.Test_load(brys, "<h2><span class='mw-headline' id='A_b_c'>A <a xtid='a_lnki_text_n' href=\"/wiki/B\" xowa_redlink='1'>b</a> c<!--xo_hdr_end--></span></h2>");
// }
// @Test public void Html_anchor() {
// fxt.Test_html("==A [[b]] c==", "<h2><span class='mw-headline' id='A_b_c'>A <a xtid='a_lnki_text_n' href=\"/wiki/B\" xowa_redlink='1'>b</a> c<!--xo_hdr_end--></span></h2>\n");
// }
}

View File

@@ -0,0 +1,98 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.btries.*;
class Xow_hzip_itm__href {
public void Save(Bry_bfr bfr, Xodump_stats_itm stats, byte[] src, int src_len, int bgn, int pos, byte bgn_quote) {
// // ignore anchors; EX: "#a"
// int proto_bgn = pos;
// int proto_end = Bry_finder.Find_fwd(src, Byte_ascii.Colon, proto_bgn, src_len);
// byte proto_tid = Tid_proto_other;
// if (proto_end != Bry_finder.Not_found) {
// Object proto_obj = proto_trie.Match_exact(src, pos, proto_bgn);
// if (proto_obj != null)
// proto_tid = ((Byte_obj_val)proto_obj).Val();
// pos = Bry_finder.Find_fwd_while(src, proto_bgn + 1, src_len, Byte_ascii.Slash); // eat /; EX: http:// should position after /
// }
// // stats.Lnke_proto_reg(proto_tid, src, proto_bgn, proto_end);
//
// int domain_bgn = pos;
// int domain_end = Bry_finder.Find_fwd(src, Byte_ascii.Slash, domain_bgn, src_len);
// if (domain_end == Bry_finder.Not_found) // href has no slash; assume entire String is domain EX: "www.a.org"
// domain_end = Bry_finder.Find_fwd(src, bgn_quote, pos, src_len);
//
// int tld_pos = Bry_finder.Find_bwd(src, Byte_ascii.Dot, domain_bgn, src_len);
// byte tld_tid = Tid_tld_other;
// if (tld_pos != Bry_.NotFound) {
// Object tld_obj = tld_trie.Match_exact(src, domain_bgn, domain_end);
// if (tld_obj != null)
// tld_tid = ((Byte_obj_val)tld_obj).Val();
// pos = Bry_finder.Find_fwd_while(src, domain_bgn + 1, src_len, Byte_ascii.Slash); // eat /; EX: http:// should position after /
// }
// // stats.Lnke_tld_reg(tld_tid, src, domain_bgn, domain_end);
}
public static final byte // 2
Tid_proto_other = 0
, Tid_proto_http = 1
, Tid_proto_https = 2
;
public static final byte // 3
Tid_tld_other = 0
, Tid_tld_com = 1
, Tid_tld_org = 2
, Tid_tld_net = 3
, Tid_tld_gov = 4
;
public static final byte // 3
Tid_ext_other = 0
, Tid_ext_none = 1
, Tid_ext_htm = 2
, Tid_ext_html = 3
, Tid_ext_php = 4
, Tid_ext_jsp = 5
, Tid_ext_asp = 6
, Tid_ext_aspx = 7
;
// private static final Btrie_slim_mgr proto_trie = Btrie_slim_mgr.ci_ascii_()
// .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_()
// .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_()
// .Add_str_byte("htm", Tid_ext_htm)
// .Add_str_byte("html", Tid_ext_html)
// .Add_str_byte("php", Tid_ext_php)
// .Add_str_byte("jsp", Tid_ext_jsp)
// .Add_str_byte("asp", Tid_ext_asp)
// .Add_str_byte("aspx", Tid_ext_aspx)
// ;
// <a href="/site/simple.wikipedia.org/wiki/Template:Solar_System?action=edit"><span title="Edit this template" style="">e</span></a> // xwiki [[simple:xx
// <a href="http://planetarynames.wr.usgs.gov/jsp/append5.jsp" class="external text" rel="nofollow">"Descriptor Terms (Feature Types)"</a>
/*
0: proto,tld,ext
1-n: domain
n: 0: domain_end
n: url remainder
n: 0: url_end
*/
}

View File

@@ -0,0 +1,109 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.primitives.*; import gplx.core.btries.*; import gplx.xowa.wikis.ttls.*;
public class Xow_hzip_mgr {
private final Gfo_usr_dlg usr_dlg;
private byte[] page_url; private byte[] src; private int src_len;
public Xow_hzip_mgr(Gfo_usr_dlg usr_dlg, Xow_ttl_parser ttl_parser) {
this.usr_dlg = usr_dlg;
itm__anchor = new Xow_hzip_itm__anchor(this, ttl_parser);
itm__header = new Xow_hzip_itm__header(this);
}
public Xow_hzip_itm__anchor Itm__anchor() {return itm__anchor;} private Xow_hzip_itm__anchor itm__anchor;
public Xow_hzip_itm__header Itm__header() {return itm__header;} private Xow_hzip_itm__header itm__header;
public void Write(Bry_bfr bfr, Xodump_stats_itm stats, byte[] page_url, byte[] src) {
this.page_url = page_url; this.src = src; this.src_len = src.length;
bfr.Clear(); stats.Clear();
int pos = 0, add_bgn = -1;
while (pos < src_len) {
byte b = src[pos];
Object o = btrie.Match_bgn_w_byte(b, src, pos, src_len);
if (o == null) {
if (add_bgn == -1) add_bgn = pos;
++pos;
}
else {
if (add_bgn != -1) {bfr.Add_mid(src, add_bgn, pos); add_bgn = -1;}
byte tid = ((Byte_obj_val)o).Val();
int match_bgn = pos;
int match_end = btrie.Match_pos();
switch (tid) {
case Tid_a_lhs: pos = itm__anchor.Save(bfr, stats, src, src_len, match_bgn, match_end); break;
case Tid_a_rhs: pos = itm__anchor.Save_a_rhs(bfr, stats, src, src_len, match_bgn, match_end); break;
case Tid_h_lhs: pos = itm__header.Save(bfr, stats, src, src_len, match_bgn, match_end); break;
default: Warn_by_pos("save.tid.unknown", match_bgn, match_end); pos = match_end; continue;
}
if (pos == Unhandled) {
bfr.Add_mid(src, match_bgn, match_end);
pos = match_end;
}
}
}
if (add_bgn != -1) bfr.Add_mid(src, add_bgn, src_len);
}
public byte[] Parse(Bry_bfr rv, byte[] page_url, byte[] src, Ordered_hash redlink_uids) {
this.page_url = page_url; this.src = src;
this.src_len = src.length;
int pos = 0, add_bgn = -1;
rv.Clear();
while (pos < src_len) {
byte b = src[pos];
if (b == Xow_hzip_dict.Escape) {
if (add_bgn != -1) {rv.Add_mid(src, add_bgn, pos); add_bgn = -1;}
int itm_pos = pos + 2;
int tid_pos = pos + 1; if (tid_pos >= src_len) {Warn_by_pos("load.eos", pos, itm_pos); break;}
byte tid = src[tid_pos];
switch (tid) {
case Xow_hzip_dict.Tid_lnki_text_n:
case Xow_hzip_dict.Tid_lnki_text_y: pos = itm__anchor.Load_lnki(rv, src, src_len, itm_pos, tid, redlink_uids); break;
case Xow_hzip_dict.Tid_lnke_txt:
case Xow_hzip_dict.Tid_lnke_brk_text_n:
case Xow_hzip_dict.Tid_lnke_brk_text_y: pos = itm__anchor.Load_lnke(rv, src, src_len, itm_pos, tid); break;
case Xow_hzip_dict.Tid_a_rhs: pos = itm_pos; rv.Add_str("</a>"); break;
case Xow_hzip_dict.Tid_hdr_lhs: pos = itm__header.Load(rv, src, src_len, itm_pos); break;
default: pos = itm_pos; Warn_by_pos("hzip.load.unknown", pos, itm_pos); break; // NOTE: should not happen, but handle else infinite loop; DATE:2015-06-08
}
}
else {
if (add_bgn == -1) add_bgn = pos;
++pos;
}
}
if (add_bgn != -1) rv.Add_mid(src, add_bgn, src_len);
return rv.Xto_bry_and_clear();
}
public int Warn_by_pos_add_dflt(String err, int bgn, int end) {return Warn_by_pos(err, bgn, end, 32);}
public int Warn_by_pos(String err, int bgn, int end) {return Warn_by_pos(err, bgn, end, 0);}
private int Warn_by_pos(String err, int bgn, int end, int end_adj) {
end += end_adj; if (end > src_len) end = src_len;
usr_dlg.Warn_many("", "", "hzip failed: page=~{0} err=~{1} mid=~{2}", String_.new_u8(page_url), err, String_.new_u8(src, bgn, end));
return end + 1;
}
public static final int Unhandled = -1;
private static final byte
Tid_a_lhs = 0
, Tid_a_rhs = 1
, Tid_h_lhs = 2
;
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

@@ -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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
class Xow_hzip_mgr_fxt {
private Bry_bfr bfr = Bry_bfr.reset_(Io_mgr.Len_mb); private Xow_hzip_mgr hzip_mgr; private Xowe_wiki wiki;
private Xodump_stats_itm stats = new Xodump_stats_itm(); private final Ordered_hash redlink_uids = Ordered_hash_.new_();
public void Clear() {
if (hzip_mgr == null) {
Xoae_app app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
hzip_mgr = new Xow_hzip_mgr(Gfo_usr_dlg_.I, wiki);
}
}
public void Init_xwiki(String alias, String domain) {
wiki.Appe().Wiki_mgr().Get_by_key_or_make(Bry_.new_u8(domain));
wiki.Xwiki_mgr().Add_full(alias, domain);
wiki.Appe().Usere().Wiki().Xwiki_mgr().Add_full(domain, domain);
}
public byte[] Make_int(int v) {return Xow_hzip_int_.Save_bin_int_abrv(v);}
public void Test_save(byte[][] expd_brys, String html) {Test_save(html, expd_brys);}
public void Test_save(String html, byte[]... expd_brys) {
byte[] expd = Bry_.Add(expd_brys);
hzip_mgr.Write(bfr, stats, Bry_.Empty, Bry_.new_u8(html));
Tfds.Eq_ary(expd, bfr.Xto_bry_and_clear());
}
public void Test_load(byte[][] src_brys, String expd) {
byte[] src = Bry_.Add(src_brys);
src = hzip_mgr.Parse(bfr, Bry_.Empty, src, redlink_uids);
Tfds.Eq(expd, String_.new_u8(src));
}
public void Test_html(String html, String expd) {
Xop_ctx ctx = wiki.Ctx(); Xop_parser parser = wiki.Parser(); Xop_tkn_mkr tkn_mkr = ctx.Tkn_mkr();
ctx.Para().Enabled_n_();
ctx.Cur_page().Redlink_lnki_list().Clear();
byte[] html_bry = Bry_.new_u8(html);
Xop_root_tkn root = ctx.Tkn_mkr().Root(html_bry);
parser.Parse_page_all_clear(root, ctx, tkn_mkr, html_bry);
Xoh_wtr_ctx hctx = Xoh_wtr_ctx.Hdump;
Xoh_html_wtr html_wtr = wiki.Html_mgr().Html_wtr();
html_wtr.Cfg().Toc__show_(Bool_.Y); // needed for hdr to show <span class='mw-headline' id='A'>
html_wtr.Write_all(bfr, ctx, hctx, html_bry, root);
Tfds.Eq(expd, bfr.Xto_str_and_clear());
}
}

View File

@@ -0,0 +1,52 @@
/*
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.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.primitives.*;
class Xow_hzip_xtid {
public static int Find_xtid(Xow_hzip_mgr hzip_mgr, byte[] src, int src_len, int bgn, int pos, Byte_obj_ref xtid_ref) {
int xtid_bgn = pos + Len_xtid; if (!Bry_.Match(src, pos, xtid_bgn, Bry_xtid)) return Xow_hzip_mgr.Unhandled; // next atr should be "xtid='"
int xtid_end = Bry_finder.Find_fwd(src, Byte_ascii.Apos, xtid_bgn); if (xtid_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("xtid_end_missing", bgn, xtid_bgn);
Object xtid_obj = Xtids.Get_by_mid(src, xtid_bgn, xtid_end); if (xtid_obj == null) return hzip_mgr.Warn_by_pos("a.xtid_invalid", xtid_bgn, xtid_end);
xtid_ref.Val_(xtid_obj == null ? Byte_.Min_value : ((Byte_obj_val)xtid_obj).Val());
return xtid_end;
}
private static final byte[]
Bry_xtid = Bry_.new_a7("xtid='")
;
private static final int
Len_xtid = Bry_xtid.length
;
public static final byte[]
Bry_lnki_text_n = Bry_.new_a7("a_lnki_text_n")
, Bry_lnki_text_y = Bry_.new_a7("a_lnki_text_y")
, Bry_lnke_txt = Bry_.new_a7("a_lnke_txt")
, Bry_lnke_brk_n = Bry_.new_a7("a_lnke_brk_n")
, Bry_lnke_brk_y = Bry_.new_a7("a_lnke_brk_y")
, 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_()
.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)
.Add_bry_byte(Bry_lnke_brk_n , Xow_hzip_dict.Tid_lnke_brk_text_n)
.Add_bry_byte(Bry_lnke_brk_y , Xow_hzip_dict.Tid_lnke_brk_text_y)
.Add_bry_byte(Bry_img_full , Xow_hzip_dict.Tid_img_full)
.Add_bry_byte(Bry_hdr , Xow_hzip_dict.Tid_hdr_lhs)
;
}

View File

@@ -0,0 +1,197 @@
/*
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.js; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.threads.*; import gplx.xowa.xtns.pfuncs.ifs.*; import gplx.xowa.wikis.data.tbls.*;
import gplx.json.*;
import gplx.xowa.html.js.*;
import gplx.xowa.gui.views.*;
public class Xoh_js_cbk implements GfoInvkAble {
private Xoae_app app;
private Xog_html_itm html_itm;
private Xop_root_tkn root = new Xop_root_tkn();
private final Bry_bfr bfr = Bry_bfr.reset_(255);
public Xoh_js_cbk(Xog_html_itm html_itm) {this.html_itm = html_itm; this.app = html_itm.Owner_tab().Tab_mgr().Win().App();}
private String Xowa_exec_test(GfoMsg m) { // concat args with pipe; EX: xowa_exec('proc', 'arg0', 'arg1'); -> proc|arg0|arg1
bfr.Clear();
bfr.Add_str(m.Key());
int len = m.Args_count();
for (int i = 0; i < len; i++)
bfr.Add_str_a7("|").Add_str(m.Args_getAt(i).Val_to_str_or_empty());
return bfr.Xto_str_and_clear();
}
private String[] Xowa_exec_test_as_array(GfoMsg m) {// return args as array; EX: xowa_exec('proc', 'arg0', 'arg1'); -> proc,arg0,arg1
bfr.Clear();
int len = m.Args_count();
String[] rv = new String[len + 1];
rv[0] = Invk_xowa_exec_test_as_array;
for (int i = 0; i < len; i++)
rv[i + 1] = Object_.Xto_str_strict_or_empty(m.ReadValAt(i));
return rv;
}
private String Parse_to_html(GfoMsg m) {
Xowe_wiki wiki = html_itm.Owner_tab().Wiki();
Xop_ctx ctx = wiki.Ctx();
boolean old_para_enabled = ctx.Para().Enabled();
byte[] raw = Bry_.new_u8(m.Args_getAt(0).Val_to_str_or_empty());
boolean para_enabled = m.Args_count() < 2 ? false : Bool_.parse_(m.Args_getAt(1).Val_to_str_or_empty());
try {
wiki.Ctx().Para().Enabled_(para_enabled);
wiki.Parser().Parse_text_to_wdom(root, wiki.Ctx(), wiki.Ctx().Tkn_mkr(), raw, 0);
byte[] data = root.Data_mid();
wiki.Html_mgr().Html_wtr().Write_all(bfr, wiki.Ctx(), data, root);
return bfr.Xto_str_and_clear();
}
finally {
wiki.Ctx().Para().Enabled_(old_para_enabled);
}
}
private String Get_page(GfoMsg m) {
Xowe_wiki wiki = html_itm.Owner_tab().Wiki();
try {
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, m.Args_getAt(0).Val_to_bry());
Xoae_page page = wiki.Data_mgr().Get_page(ttl, false);
return String_.new_u8(page.Data_raw());
} catch (Exception e) {Exc_.Noop(e); return null;}
}
private String Popups_get_async_bgn(GfoMsg m) {
try {
byte[] js_cbk = m.Args_getAt(0).Val_to_bry();
byte[] href_bry = m.Args_getAt(1).Val_to_bry();
return html_itm.Owner_tab().Wiki().Html_mgr().Module_mgr().Popup_mgr().Get_async_bgn(js_cbk, href_bry);
} catch (Exception e) {Exc_.Noop(e); return null;}
}
private String Popups_get_html(GfoMsg m) {
try {
int popups_id = Int_.Xby_double_(Double_.cast_(m.Args_getAt(0).Val()));
byte[] href_bry = m.Args_getAt(1).Val_to_bry();
byte[] tooltip_bry = m.Args_getAt(2).Val_to_bry();
return html_itm.Owner_tab().Wiki().Html_mgr().Module_mgr().Popup_mgr().Show_init(popups_id, href_bry, tooltip_bry);
} catch (Exception e) {Exc_.Noop(e); return null;}
}
private String[] Get_title_meta(Xowe_wiki wiki, byte[] ttl_bry) {
synchronized (tmp_page) {
tmp_page.Clear();
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ttl_bry);
wiki.Db_mgr().Load_mgr().Load_by_ttl(tmp_page, ttl.Ns(), ttl.Page_db());
}
return String_.Ary(tmp_page.Exists() ? "1" : "0", Int_.Xto_str(tmp_page.Id()), Int_.Xto_str(tmp_page.Ns_id()), String_.new_u8(tmp_page.Ttl_page_db()), Bool_.Xto_str_lower(tmp_page.Redirected()), tmp_page.Modified_on().XtoStr_fmt("yyyy-MM-dd HH:mm:ss"), Int_.Xto_str(tmp_page.Text_len()));
} private static final Xowd_page_itm tmp_page = Xowd_page_itm.new_tmp();
private String[][] Get_titles_meta(GfoMsg m) {
Xowe_wiki wiki = html_itm.Owner_tab().Wiki();
try {
byte[][] ttls = Bry_.Split(Bry_.new_u8((String)m.ReadValAt(0)), Byte_ascii.Nl);
int ttls_len = ttls.length;
String[][] rv = new String[ttls_len][];
for (int i = 0; i < ttls_len; i++) {
byte[] ttl = ttls[i];
rv[i] = Get_title_meta(wiki, ttl);
}
return rv;
} catch (Exception e) {Exc_.Noop(e); return null;}
}
private boolean Get_title_exists(Xowe_wiki wiki, byte[] ttl) {
return Pfunc_ifexist.Exists(wiki, ttl);
}
private String[] Get_titles_exists(GfoMsg m) {
Xowe_wiki wiki = html_itm.Owner_tab().Wiki();
try {
byte[][] ttls = Bry_.Ary_obj((Object[])m.ReadValAt(0));
int ttls_len = ttls.length;
String[] rv = new String[ttls_len];
for (int i = 0; i < ttls_len; i++) {
byte[] ttl = ttls[i];
rv[i] = Get_title_exists(wiki, ttl) ? "1" : "0";
}
return rv;
} catch (Exception e) {Exc_.Noop(e); return null;}
}
private String Get_search_suggestions(GfoMsg m) {
Xowe_wiki wiki = html_itm.Owner_tab().Wiki();
byte[] search_str = Bry_.new_u8((String)m.ReadValAt(0));
byte[] cbk_func = Bry_.new_u8((String)m.ReadValAt(1));
app.Gui_mgr().Search_suggest_mgr().Search(wiki, search_str, cbk_func);
return "";
}
private String[] Wikidata_get_label(GfoMsg m) {
try {
Thread_adp_.Sleep(10); // slow down calls to prevent random crashing in XulRunner; DATE:2014-04-23
gplx.xowa.xtns.wdatas.Wdata_wiki_mgr wdata_mgr = app.Wiki_mgr().Wdata_mgr();
wdata_mgr.Wdata_wiki().Init_assert(); // NOTE: must assert else ns_mgr won't load Property
int len = m.Args_count();
if (len < 1) return null;
byte[][] langs = Bry_.Split(m.Args_getAt(0).Val_to_bry(), Byte_ascii.Semic);
int langs_len = langs.length;
String[] rv = new String[len - 1];
for (int i = 1; i < len; i++) {
try {
byte[] ttl_bry = m.Args_getAt(i).Val_to_bry();
gplx.xowa.xtns.wdatas.Wdata_doc page = wdata_mgr.Pages_get(ttl_bry); if (page == null) continue;
for (int j = 0; j < langs_len; j++) {
byte[] lang_key = langs[j];
if (Bry_.Eq(lang_key, Wikidata_get_label_xowa_ui_lang))
lang_key = app.Sys_cfg().Lang();
byte[] val_bry = null;
if (Bry_.Eq(lang_key, Wikidata_get_label_xowa_title))
val_bry = ttl_bry;
else {
val_bry = page.Label_list_get(lang_key);
}
if (val_bry == null) continue;
rv[i - 1] = String_.new_u8(val_bry);
break;
}
} catch (Exception e) {Exc_.Noop(e); rv[i] = null;}
finally {}
}
return rv;
} catch (Exception e) {Exc_.Noop(e); return null;}
}
private String Scripts_exec(GfoMsg m) {
Object rv = null;
try {
rv = app.Gfs_mgr().Run_str(m.Args_getAt(0).Val_to_str_or_empty());
}
catch (Exception e) {Exc_.Noop(e); return null;}
return Object_.Xto_str_strict_or_empty(rv);
}
private static final byte[] Wikidata_get_label_xowa_ui_lang = Bry_.new_a7("xowa_ui_lang"), Wikidata_get_label_xowa_title = Bry_.new_a7("xowa_title");
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_parse_to_html)) return Parse_to_html(m);
else if (ctx.Match(k, Invk_wikidata_get_label)) return Wikidata_get_label(m);
else if (ctx.Match(k, Invk_get_page)) return Get_page(m);
else if (ctx.MatchIn(k, Invk_cmd, Invk_scripts_exec)) return Scripts_exec(m);
else if (ctx.Match(k, Invk_scripts_exec)) return Scripts_exec(m);
else if (ctx.Match(k, Invk_popups_get_async_bgn)) return Popups_get_async_bgn(m);
else if (ctx.Match(k, Invk_popups_get_html)) return Popups_get_html(m);
else if (ctx.Match(k, Invk_get_search_suggestions)) return Get_search_suggestions(m);
else if (ctx.Match(k, Invk_get_titles_meta)) return Get_titles_meta(m);
else if (ctx.Match(k, Invk_get_titles_exists)) return Get_titles_exists(m);
else if (ctx.Match(k, Invk_get_current_url)) return String_.new_u8(html_itm.Owner_tab().Page().Url().Raw());
else if (ctx.Match(k, Invk_xowa_exec_test)) return Xowa_exec_test(m);
else if (ctx.Match(k, Invk_xowa_exec_test_as_array)) return Xowa_exec_test_as_array(m);
else if (ctx.Match(k, Invk_exec_json)) return app.Html__json_exec().Exec_json(m);
else return GfoInvkAble_.Rv_unhandled;
}
public static final String Invk_parse_to_html = "parse_to_html", Invk_wikidata_get_label = "wikidata_get_label", Invk_get_page = "get_page", Invk_cmd = "cmd", Invk_scripts_exec = "scripts_exec"
, Invk_get_search_suggestions = "get_search_suggestions", Invk_get_titles_meta = "get_titles_meta", Invk_get_titles_exists = "get_titles_exists", Invk_get_current_url = "get_current_url"
, Invk_xowa_exec_test = "xowa_exec_test", Invk_xowa_exec_test_as_array = "xowa_exec_test_as_array"
, Invk_popups_get_async_bgn = "popups_get_async_bgn"
, Invk_popups_get_html = "popups_get_html"
, Invk_exec_json = "exec_json"
;
}

View File

@@ -0,0 +1,46 @@
/*
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.js; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*; import gplx.xowa.xtns.wdatas.*;
import gplx.xowa.gui.views.*;
public class Xoh_js_cbk_tst {
@Before public void init() {fxt.Clear();} private Xoh_js_cbk_fxt fxt = new Xoh_js_cbk_fxt();
@Test public void Get_title() {
fxt.Fxt().Init_page_create("exists");
fxt.Test_get_title("exists", "1" , "0" , Int_.Xto_str(Int_.MinValue), "Exists", "false", "0001-01-01 00:00:00", "0");
fxt.Test_get_title("absent", "0", "-1", Int_.Xto_str(Int_.MinValue), null , "false", "0001-01-01 00:00:00", "0");
}
}
class Xoh_js_cbk_fxt {
public void Clear() {
fxt = new Xop_fxt();
Xoa_app_fxt.Init_gui(fxt.App(), fxt.Wiki());
} private Xop_fxt fxt;
public Xop_fxt Fxt() {return fxt;}
public void Test_get_title(String ttl, Object... expd) {
Xoae_app app = fxt.App();
Xowe_wiki wiki = fxt.Wiki();
Xoae_page page = Xoae_page.test_(wiki, Xoa_ttl.parse_(wiki, Bry_.new_a7("mock_page")));
Xog_tab_itm tab = app.Gui_mgr().Browser_win().Active_tab();
tab.Page_(page);
Xoh_js_cbk exec = tab.Html_itm().Js_cbk();
GfoMsg msg = GfoMsg_.new_cast_(Xoh_js_cbk.Invk_get_titles_meta).Add("ttl", ttl);
String[][] actl = (String[][])GfoInvkAble_.InvkCmd_msg(exec, Xoh_js_cbk.Invk_get_titles_meta, msg);
Tfds.Eq_ary_str(expd, actl[0]);
}
}

View File

@@ -0,0 +1,63 @@
/*
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.js; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*; import gplx.xowa.xtns.wdatas.*;
public class Xoh_js_cbk_wdata_labels_tst {
@Before public void init() {fxt.Init();} Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt();
@Test public void Basic() {
fxt.Init_pages_add(fxt.Wdoc_bldr("q1").Add_label("en", "en_q1").Xto_wdoc());
fxt.Init_pages_add(fxt.Wdoc_bldr("q2").Add_label("en", "en_q2").Xto_wdoc());
fxt.Init_pages_add(fxt.Wdoc_bldr("Property:P1").Add_label("en", "en_property_p1").Xto_wdoc());
Tst_wikidata_label_get(String_.Ary("en", "q1", "q2", "Property:P1"), String_.Ary("en_q1", "en_q2", "en_property_p1"));
}
@Test public void Outliers() {
fxt.Init_pages_add(fxt.Wdoc_bldr("q1").Add_label("en", "en_q1").Add_label("de", "de_q1").Xto_wdoc());
Tst_wikidata_label_get(String_.Ary("fr", "q1"), String_.Ary((String)null));
Tst_wikidata_label_get(String_.Ary("de", "q1"), String_.Ary("de_q1"));
Tst_wikidata_label_get(String_.Ary("xowa_title", "q1"), String_.Ary("q1"));
Tst_wikidata_label_get(String_.Ary("xowa_ui_lang", "q1"), String_.Ary("en_q1"));
Tst_wikidata_label_get(String_.Ary("fr;de", "q1"), String_.Ary("de_q1"));
}
@Test public void Escaped() { // PURPOSE: \t should be escaped; EX:wd.q:2; DATE:2014-04-23
Wdata_doc d = doc_("q1", String_.Concat_lines_nl
( "{ 'entity':['item',1]"
, ", 'label':"
, " { 'en':'\\ta'" // NOTE: json literally has "\t", not (char)8
, " }"
, "}"
));
fxt.Init_pages_add(d);
Tst_wikidata_label_get(String_.Ary("en", "q1"), String_.Ary("\ta"));
}
private Wdata_doc doc_(String qid, String src) {
gplx.json.Json_doc doc = gplx.json.Json_doc.new_apos_(src);
Xoae_app app = Xoa_app_fxt.app_();
Wdata_doc rv = new Wdata_doc(Bry_.new_a7(qid), app.Wiki_mgr().Wdata_mgr(), doc);
return rv;
}
private void Tst_wikidata_label_get(String[] args, String[] expd) {
Xoa_app_fxt.Init_gui(fxt.App(), fxt.Wiki());
Xoh_js_cbk exec = fxt.App().Gui_mgr().Browser_win().Active_html_itm().Js_cbk();
GfoMsg msg = GfoMsg_.new_cast_(Xoh_js_cbk.Invk_wikidata_get_label);
int args_len = args.length;
for (int i = 0; i < args_len; i++)
msg.Add("v", args[i]);
String[] actl = (String[])GfoInvkAble_.InvkCmd_msg(exec, Xoh_js_cbk.Invk_wikidata_get_label, msg);
Tfds.Eq_ary_str(expd, actl);
}
}

View File

@@ -0,0 +1,53 @@
/*
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.js; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.primitives.*;
import gplx.json.*;
public class Xoh_json_exec {
private final Xoa_app app;
public Xoh_json_exec(Xoa_app app) {this.app = app;}
public String Exec_json(GfoMsg m) {
if (m.Args_count() == 0) throw Exc_.new_("xowa_exec.json; no json specified for json_exec");
return Exec_json(m.Args_getAt(0).Val_to_bry());
}
public String Exec_json(byte[] jdoc_bry) {
Json_doc jdoc = null;
try {jdoc = Json_doc.new_(jdoc_bry);}
catch (Exception e) {throw Exc_.new_exc(e, "js", "xowa_exec.json; invalid json", "json", jdoc_bry);}
return Xoui_exec(jdoc, jdoc.Root());
}
private String Xoui_exec(Json_doc jdoc, Json_itm_nde nde) {
byte[] wiki_bry = nde.Subs_get_val_by_key_as_bry(Key_wiki, null); if (wiki_bry == null) throw Exc_.new_("xoui_exec.json; no wiki specified", "json", jdoc.Src());
byte[] proc_bry = nde.Subs_get_val_by_key_as_bry(Key_proc, null); if (proc_bry == null) throw Exc_.new_("xoui_exec.json; no proc specified", "json", jdoc.Src());
Xow_wiki wiki = app.Wiki_mgri().Get_by_key_or_make_init_y(wiki_bry);
Object tid_obj = proc_hash.Get_by(proc_bry); if (tid_obj == null) throw Exc_.new_("xoui_exec.json; invalid tid", "json", jdoc.Src());
switch (((Byte_obj_val)tid_obj).Val()) {
case Tid_edit : return wiki.Html__xoui_tbl_mgr().Edit(jdoc);
case Tid_save : return wiki.Html__xoui_tbl_mgr().Save(wiki, jdoc);
case Tid_delete : return wiki.Html__xoui_tbl_mgr().Del(jdoc);
}
throw Exc_.new_("xoui_exec.json; cmd not handled", "json", jdoc.Src());
}
private static final byte[] Key_wiki = Bry_.new_a7("wiki"), Key_proc = Bry_.new_a7("proc");
private static final byte Tid_edit = 1, Tid_save = 2, Tid_delete = 3;
private static final Hash_adp_bry proc_hash = Hash_adp_bry.cs_()
.Add_str_byte("xowa.xoui.grid.edit" , Tid_edit)
.Add_str_byte("xowa.xoui.grid.save" , Tid_save)
.Add_str_byte("xowa.xoui.grid.delete" , Tid_delete)
;
}

View File

@@ -0,0 +1,21 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public interface Xoh_arg_img_core extends Bry_fmtr_arg {
Xoh_arg_img_core Init(int uid, byte[] src, int w, int h);
}

View File

@@ -0,0 +1,26 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_arg_img_core__basic implements Xoh_arg_img_core {
private byte[] src; private int w, h;
public Xoh_arg_img_core Init(int uid, byte[] src, int w, int h) {this.src = src; this.w = w; this.h = h; return this;}
public void XferAry(Bry_bfr bfr, int idx) {
fmtr_img_atrs.Bld_bfr_many(bfr, src, w, h);
}
private Bry_fmtr fmtr_img_atrs = Bry_fmtr.new_(" src=\"~{img_src}\" width=\"~{img_w}\" height=\"~{img_h}\"", "img_src", "img_w", "img_h");
}

View File

@@ -0,0 +1,31 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_arg_img_core__hdump implements Xoh_arg_img_core {
private int uid;
public Xoh_arg_img_core Init(int uid, byte[] img_src, int img_w, int img_h) {
this.uid = uid;
return this;
}
public void XferAry(Bry_bfr bfr, int idx) {
bfr.Add_byte_space();
bfr.Add(gplx.xowa.html.hdumps.abrvs.Xohd_abrv_.Key_img);
bfr.Add_int_variable(uid);
bfr.Add_byte_apos();
}
}

View File

@@ -0,0 +1,146 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.files.*; import gplx.xowa.html.hdumps.abrvs.*;
public class Xoh_file_html_fmtr__base implements Xoh_file_img_wkr {
private final Xoh_arg_img_core arg_img_core;
private Bry_bfr scratch_bfr = Bry_bfr.reset_(128);
public Xoh_file_html_fmtr__base() {
arg_img_core = New_arg_img_core();
}
@gplx.Internal @gplx.Virtual protected Xoh_arg_img_core New_arg_img_core() {return new Xoh_arg_img_core__basic();}
@gplx.Virtual public void Html_full_media(Bry_bfr tmp_bfr, byte[] a_href, byte[] a_title, Bry_fmtr_arg html) {fmtr_full_media.Bld_bfr_many(tmp_bfr, a_href, a_title, html);}
private final Bry_fmtr fmtr_full_media = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( "<a href=\"~{a_href}\" xowa_title=\"~{a_xowa_title}\">~{html}"
, "</a>"
), "a_href", "a_xowa_title", "html"
);
@gplx.Virtual public void Html_full_img(Bry_bfr tmp_bfr, Xoh_wtr_ctx hctx, Xoae_page page, Xof_file_itm xfer_itm, int uid
, byte[] a_href, byte a_cls, byte a_rel, byte[] a_title, byte[] a_xowa_title
, int img_w, int img_h, byte[] img_src, byte[] img_alt, byte img_cls, byte[] img_cls_other
) {
fmtr_full_img.Bld_bfr_many(tmp_bfr, uid
, a_href, Xoh_lnki_consts.A_cls_to_bry(a_cls), Xoh_lnki_consts.A_rel_to_bry(a_rel), a_title, a_xowa_title
, arg_img_core.Init(uid, img_src, img_w, img_h), img_alt, Xoh_lnki_consts.Img_cls_to_bry(img_cls, img_cls_other));
}
private Bry_fmtr fmtr_full_img = Bry_fmtr.new_
( "<a href=\"~{a_href}\"~{a_class}~{a_rel}~{a_title} xowa_title=\"~{a_xowa_title}\">"
+ "<img id=\"xowa_file_img_~{uid}\" alt=\"~{img_alt}\"~{img_core}~{img_class} /></a>"
, "uid", "a_href", "a_class", "a_rel", "a_title", "a_xowa_title", "img_core", "img_alt", "img_class"
);
@gplx.Virtual public void Html_thumb_core(Bry_bfr tmp_bfr, int uid, byte[] div1_halign, int div2_width, byte[] div2_content) {
scratch_bfr.Add(Bry_style_bgn);
scratch_bfr.Add_int_variable(div2_width);
scratch_bfr.Add(Bry_style_end);
fmtr_thumb_core.Bld_bfr_many(tmp_bfr, uid, div1_halign, scratch_bfr.Xto_bry_and_clear(), div2_content);
} private static final byte[] Bry_style_bgn = Bry_.new_a7("style=\"width:"), Bry_style_end = Bry_.new_a7("px;\"");
protected Bry_fmtr fmtr_thumb_core = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last // REF.MW: Linker.php|makeImageLink2
( "<div class=\"thumb t~{div1_halign}\">"
, " <div id=\"xowa_file_div_~{uid}\" class=\"thumbinner\" ~{style}>"
, "~{div2_content}"
, " </div>"
, "</div>"
, ""
), "uid", "div1_halign", "style", "div2_content"
);
public byte[] Html_thumb_part_img(Bry_bfr tmp_bfr, Xoae_page page, Xof_file_itm xfer_itm, Xop_lnki_tkn lnki, int uid, byte[] a_href, byte[] img_src, byte[] img_alt) {
Html_thumb_part_img(tmp_bfr, page, xfer_itm, uid, a_href, lnki.Ttl().Page_txt(), xfer_itm.Html_w(), xfer_itm.Html_h(), img_src, img_alt);
return tmp_bfr.Xto_bry_and_clear();
}
public void Html_thumb_part_img(Bry_bfr tmp_bfr, Xoae_page page, Xof_file_itm xfer_itm, int uid, byte[] a_href, byte[] a_title, int img_w, int img_h, byte[] img_src, byte[] img_alt) {
fmtr_thumb_part_img.Bld_bfr_many(tmp_bfr, uid, a_href, a_title, arg_img_core.Init(uid, img_src, img_w, img_h), img_alt);
}
private Bry_fmtr fmtr_thumb_part_img = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <div>"
, " <a href=\"~{a_href}\" class=\"image\" title=\"~{a_title}\">"
, " <img id=\"xowa_file_img_~{uid}\"~{img_core} alt=\"~{img_alt}\" />"
, " </a>"
, " </div>"
), "uid", "a_href", "a_title", "img_core", "img_alt");
public void Html_thumb_part_caption(Bry_bfr tmp_bfr, byte[] magnify_btn, Bry_fmtr_arg caption) {fmtr_thumb_part_caption.Bld_bfr_many(tmp_bfr, magnify_btn, caption);}
private Bry_fmtr fmtr_thumb_part_caption = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <div class=\"thumbcaption\">~{magnify_btn}"
, " ~{caption}"
, " </div>"
), "magnify_btn", "caption");
public void Html_thumb_file_image(Bry_bfr tmp_bfr, byte[] thumb_image, byte[] caption, byte[] alt) {fmtr_thumb_file_image.Bld_bfr_many(tmp_bfr, thumb_image, caption, alt);}
private Bry_fmtr fmtr_thumb_file_image = Bry_fmtr.new_(" ~{thumb_image}~{caption}~{alt}", "thumb_image", "caption", "alt");
public void Html_thumb_file_audio(Bry_bfr tmp_bfr, byte[] caption, byte[] alt, byte[] play_btn, byte[] audio_info) {fmtr_thumb_file_audio.Bld_bfr_many(tmp_bfr, caption, alt, play_btn, audio_info);}
private Bry_fmtr fmtr_thumb_file_audio = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( " <div id=\"xowa_media_div\">~{play_btn}~{audio_info}"
, " </div>~{caption}~{alt}"
), "caption", "alt", "play_btn", "audio_info");
public void Html_thumb_file_video(Bry_bfr tmp_bfr, byte[] play_btn, byte[] video_thumb, byte[] caption, byte[] alt) {fmtr_thumb_file_video.Bld_bfr_many(tmp_bfr, caption, alt, play_btn, video_thumb);}
private Bry_fmtr fmtr_thumb_file_video = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( " <div id=\"xowa_media_div\">~{video_thumb}~{play_btn}"
, " </div>~{caption}~{alt}"
), "caption", "alt", "play_btn", "video_thumb");
public void Html_thumb_part_alt(Bry_bfr tmp_bfr, byte[] alt_html) {fmtr_thumb_part_alt.Bld_bfr_many(tmp_bfr, alt_html);}
public Bry_fmtr Html_thumb_part_alt_fmtr() {return fmtr_thumb_part_alt;} private Bry_fmtr fmtr_thumb_part_alt = Bry_fmtr.new_
(String_.Concat_lines_nl_skip_last
( ""
, " <hr/>"
, " <div class=\"thumbcaption\">"
, "~{html}"
, " </div>"
), "html");
@gplx.Virtual public void Html_thumb_part_magnify(Bry_bfr tmp_bfr, int uid, byte[] a_href, byte[] a_title, byte[] img_src) {
fmtr_thumb_part_magnify.Bld_bfr_many(tmp_bfr, a_href, a_title, img_src);
}
private Bry_fmtr fmtr_thumb_part_magnify = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <div class=\"magnify\">"
, " <a href=\"~{a_href}\" class=\"internal\" title=\"~{a_title}\">"
, " <img src=\"~{img_src}\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
), "a_href", "a_title", "img_src");
@gplx.Virtual public void Html_thumb_part_info(Bry_bfr tmp_bfr, int uid, byte[] a_href, byte[] img_src) {fmtr_thumb_part_info.Bld_bfr_many(tmp_bfr, a_href, img_src);}
private Bry_fmtr fmtr_thumb_part_info = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <div>"
, " <a href=\"~{a_href}\" class=\"image\" title=\"About this file\">"
, " <img src=\"~{img_src}\" width=\"22\" height=\"22\" />"
, " </a>"
, " </div>"
), "a_href", "img_src");
@gplx.Virtual public void Html_thumb_part_play(Bry_bfr tmp_bfr, int uid, int a_width, int a_max_width, byte[] a_href, byte[] a_xowa_title, byte[] img_src) {
fmtr_thumb_part_play.Bld_bfr_many(tmp_bfr, uid, a_width, a_max_width, a_href, a_xowa_title, img_src);
}
private Bry_fmtr fmtr_thumb_part_play = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <div>"
, " <a id=\"xowa_file_play_~{uid}\" href=\"~{a_href}\" xowa_title=\"~{a_xowa_title}\" class=\"xowa_anchor_button\" style=\"width:~{a_width}px;max-width:~{a_max_width}px;\">"
, " <img src=\"~{img_src}\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
), "uid", "a_width", "a_max_width", "a_href", "a_xowa_title", "img_src");
public static final Xoh_file_html_fmtr__base Base = new Xoh_file_html_fmtr__base();
}

View File

@@ -0,0 +1,55 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.html.*;
import gplx.xowa.files.*; import gplx.xowa.html.hdumps.abrvs.*;
public class Xoh_file_html_fmtr__hdump extends Xoh_file_html_fmtr__base {
private Bry_bfr tmp_bfr = Bry_bfr.reset_(128);
@gplx.Internal @Override protected Xoh_arg_img_core New_arg_img_core() {return new Xoh_arg_img_core__hdump();}
// public override void Html_full_media(Bry_bfr tmp_bfr, byte[] a_href, byte[] a_title, Bry_fmtr_arg html) {
// fmtr_full_media.Bld_bfr_many(tmp_bfr, a_href, a_title, html);
// }
// public override void Html_full_img(Bry_bfr tmp_bfr, Xoh_wtr_ctx hctx, Xoae_page page, Xof_file_itm xfer_itm, int uid
// , byte[] a_href, byte a_cls, byte a_rel, byte[] a_title, byte[] a_xowa_title
// , int img_w, int img_h, byte[] img_src, byte[] img_alt, byte img_cls, byte[] img_cls_other) {
// tmp_bfr.Add_str_a7("<a xtid='a_img_full' xatrs='");
// tmp_bfr.Add_str_a7(a_cls == Xoh_lnki_consts.Tid_a_cls_none ? "0|" : "1|"); // a_cls : "" || image
// tmp_bfr.Add_str_a7(a_rel == Xoh_lnki_consts.Tid_a_rel_none ? "0|" : "1|"); // a_rel : "" || nofollow
// tmp_bfr.Add_int_fixed(img_cls, 1).Add_byte_pipe(); // img_cls : "" || thumbborder || thumbimage || other
// tmp_bfr.Add_int_variable(uid).Add_byte_pipe(); // uid
// tmp_bfr.Add_safe(img_cls_other).Add_byte_pipe(); // img_cls_other : "" || {other}
// Html_utl.Escape_html_to_bfr(tmp_bfr, img_alt, 0, img_alt.length, Bool_.N, Bool_.N, Bool_.N, Bool_.N, Bool_.Y);
// tmp_bfr.Add_str_a7("'/>");
// }
@Override public void Html_thumb_core(Bry_bfr bfr, int uid, byte[] div1_halign, int div2_width, byte[] div2_content) {
tmp_bfr.Add(Xohd_abrv_.Key_img_style);
tmp_bfr.Add_int_variable(uid);
tmp_bfr.Add_byte_apos();
byte[] div2_width_repl = tmp_bfr.Xto_bry_and_clear();
fmtr_thumb_core.Bld_bfr_many(bfr, uid, div1_halign, div2_width_repl, div2_content);
}
@Override public void Html_thumb_part_magnify(Bry_bfr bfr, int uid, byte[] a_href, byte[] a_title, byte[] img_src) {Write_xnde(bfr, Xohd_abrv_.Key_file_mgnf, uid);}
@Override public void Html_thumb_part_info(Bry_bfr bfr, int uid, byte[] a_href, byte[] img_src) {Write_xnde(bfr, Xohd_abrv_.Key_file_info, uid);}
@Override public void Html_thumb_part_play(Bry_bfr bfr, int uid, int a_width, int a_max_width, byte[] a_href, byte[] a_xowa_title, byte[] img_src) {Write_xnde(bfr, Xohd_abrv_.Key_file_play, uid);}
public static void Write_xnde(Bry_bfr bfr, byte[] key, int uid) {
bfr.Add(key);
bfr.Add_int_variable(uid);
bfr.Add(Bry_xnde_end);
} private static final byte[] Bry_xnde_end = Bry_.new_a7("'/>");
public static final Xoh_file_html_fmtr__hdump Hdump = new Xoh_file_html_fmtr__hdump(); Xoh_file_html_fmtr__hdump() {}
}

View File

@@ -0,0 +1,25 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.files.*;
public interface Xoh_file_img_wkr {
void Html_full_img(Bry_bfr tmp_bfr, Xoh_wtr_ctx hctx, Xoae_page page, Xof_file_itm xfer_itm, int uid
, byte[] a_href, byte a_cls, byte a_rel, byte[] a_title, byte[] a_xowa_title
, int img_w, int img_h, byte[] img_src, byte[] img_alt, byte img_cls, byte[] img_cls_other
);
}

View File

@@ -0,0 +1,76 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.core.primitives.*;
import gplx.xowa.files.*; import gplx.xowa.files.xfers.*; import gplx.xowa.parsers.lnkis.*;
public class Xoh_file_mgr {
private final Xowe_wiki wiki;
public Xoh_file_mgr(Xowe_wiki wiki, Xow_html_mgr html_mgr, Xoh_html_wtr html_wtr) {
this.wiki = wiki; this.file_wtr = new Xoh_file_wtr__basic(wiki, html_mgr, html_wtr);
}
public Xoh_file_wtr__basic File_wtr() {return file_wtr;} private final Xoh_file_wtr__basic file_wtr;
public void Init_by_page(Xoh_wtr_ctx hctx, Xoae_page page) {file_wtr.Init_by_page(hctx, page);}
public void Write_or_queue(Bry_bfr bfr, Xoae_page page, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki) {Write_or_queue(bfr, page, ctx, hctx, src, lnki, file_wtr.Arg_alt_text(ctx, src, lnki));}
public void Write_or_queue(Bry_bfr bfr, Xoae_page page, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, byte[] alt_text) {
file_wtr.Write_file(bfr, ctx, hctx, src, lnki, this.Lnki_eval(Xof_exec_tid.Tid_wiki_page, ctx, page, lnki), alt_text);
}
public Xof_file_itm Lnki_eval(int exec_tid, Xop_ctx ctx, Xoae_page page, Xop_lnki_tkn lnki) {return Lnki_eval(exec_tid, ctx, page, page.File_queue(), lnki.Ttl().Page_url(), lnki.Lnki_type(), lnki.Upright(), lnki.W(), lnki.H(), lnki.Time(), lnki.Page(), lnki.Ns_id() == Xow_ns_.Id_media);}
public Xof_file_itm Lnki_eval(int exec_tid, Xop_ctx ctx, Xoae_page page, Xof_xfer_queue queue, byte[] lnki_ttl, byte lnki_type, double lnki_upright, int lnki_w, int lnki_h, double lnki_time, int lnki_page, boolean lnki_is_media_ns) {
int uid = queue.Html_uid().Val_add();
Xof_xfer_itm xfer = new Xof_xfer_itm();
xfer.Init_at_lnki(exec_tid, page.Wiki().Domain_itm().Abrv_xo(), lnki_ttl, lnki_type, lnki_upright, lnki_w, lnki_h, lnki_time, lnki_page, Xof_patch_upright_tid_.Tid_all);
xfer.Init_at_hdoc(uid, Xof_html_elem.Tid_img);
Xowe_wiki source_wiki = (Xowe_wiki)page.Commons_mgr().Source_wiki_or(wiki);
boolean found = Find_file(ctx, source_wiki, xfer);
boolean file_queue_add = File_queue_add(source_wiki, xfer, lnki_is_media_ns, found);
if (file_queue_add)
queue.Add(xfer);
else
xfer.File_exists_(found);
return xfer;
}
private boolean Find_file(Xop_ctx ctx, Xowe_wiki source_wiki, Xof_xfer_itm xfer) {
if ( source_wiki.File__fsdb_mode() == null // ignore if null; occurs during some tests; also null-ref check for next
|| source_wiki.File__fsdb_mode().Tid_v2_bld() // ignore builds
)
return false;
if (source_wiki.File_mgr().Version() == Xow_file_mgr.Version_2)
return ctx.App().User().User_db_mgr().File__xfer_itm_finder().Find(source_wiki, xfer.Lnki_exec_tid(), xfer, ctx.Cur_page().Url_bry_safe());
else
return source_wiki.File_mgr().Find_meta(xfer);
}
private static boolean File_queue_add(Xowe_wiki wiki, Xof_xfer_itm xfer, boolean lnki_is_media_ns, boolean found) {
if (!wiki.File_mgr().Cfg_download().Enabled()) return false;
if (lnki_is_media_ns) return false;
switch (wiki.File_mgr().Cfg_download().Redownload()) {
case Xof_cfg_download.Redownload_none:
if (found) return false;
if (!found
&& xfer.Meta_itm() != null // null check; fsdb_call does not set meta
&& xfer.Meta_itm().Orig_exists() == Xof_meta_itm.Exists_n)
return false; // not found, and orig_exists is n; do not download again (NOTE: even if current lnki is thumb, don't bother looking for thumb if orig is missing)
break;
case Xof_cfg_download.Redownload_missing:
if (found) return false;
break;
case Xof_cfg_download.Redownload_all:
break;
}
return true;
}
}

View File

@@ -0,0 +1,235 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
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 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) {
this.wiki = wiki; this.html_mgr = html_mgr; this.html_wtr = html_wtr; this.bfr_mkr = wiki.Utl__bfr_mkr();
this.media_alt_fmtr = new Xoh_lnki_text_fmtr(bfr_mkr, html_wtr);
this.caption_fmtr = new Xoh_lnki_text_fmtr(bfr_mkr, html_wtr);
}
public Xoh_file_html_fmtr__base Html_fmtr() {return html_fmtr;}
public void Init_by_page(Xoh_wtr_ctx hctx, Xoae_page page) {
this.page = page;
this.cfg_alt_defaults_to_caption = wiki.Appe().Usere().Wiki().Html_mgr().Imgs_mgr().Alt_defaults_to_caption().Val();
html_fmtr = hctx.Mode_is_hdump() ? Xoh_file_html_fmtr__hdump.Hdump : Xoh_file_html_fmtr__hdump.Base;
}
public void Write_file(Bry_bfr bfr, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, Xof_file_itm xfer_itm, byte[] img_alt) {
int uid = xfer_itm.Html_uid();
int div_width = xfer_itm.Html_w();
if (div_width < 1 && wiki.File_mgr().Version_2_y()) // NOTE: html_w is -1 for v2 and missing files; use lnki_w if available; primarily affects audio files with specified width; [[File:A.oga|30px]]; DATE:2014-05-03
div_width = xfer_itm.Lnki_w();
if (div_width < 1)
div_width = wiki.Html_mgr().Img_thumb_width();
int lnki_halign = lnki.Align_h();
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[] 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();
Xof_ext orig_ext = xfer_itm.Orig_ext();
boolean lnki_is_thumbable = Xop_lnki_type.Id_is_thumbable(lnki.Lnki_type());
if (lnki_is_thumbable && !xfer_itm.File_exists()) // "non-found" thumbs should default to 220; otherwise large "non-found" thumbs will create large boxes; PAGE:en.w:Wikipedia:Featured_picture_candidates/September_Morn "|1000000x260px"; DATE:2014-09-24
div_width = Xof_img_size.Thumb_width_img;
if ( html_mgr.Img_suppress_missing_src() // option to suppress src when file is missing
&& !xfer_itm.File_exists() // file is missing; wipe values and wait for "correct" info before regenerating; mostly to handle unknown redirects
&& !orig_ext.Id_is_media() // file is media; never suppress; src needs to be available for "click" on play; note that most media will be missing (not downloaded)
&& lnki.Ns_id() != Xow_ns_.Id_media // ns is media; never suppress; "src" will use only orig_src; DATE:2014-01-30
) {
img_orig_src = img_view_src = Bry_.Empty; // null out src
}
if (lnki.Ns_id() == Xow_ns_.Id_media) // NOTE: regardless of ext (ogg vs jpeg) and literal status (Media vs :Media), [[Media]] links are always rendered the same way; REF.MW:Linker.php|makeMediaLinkObj; PAGE:en.w:Beethoven; EX: [[:Media:De-Ludwig_van_Beethoven.ogg|listen]]); [[File:Beethoven 3.jpg|The [[Media:BeethovenWithLyreGuitar( W. J. Mahler - 1804).jpg|complete painting]]...]]
this.Write_file_ns_media(bfr, ctx, src, lnki, img_orig_src);
else {
if ( Xof_ext_.Id_is_video_strict(orig_ext.Id()) // id is .ogv or .webm
|| ( orig_ext.Id_is_ogg() // id is ogg
&& wiki.File_mgr().Version_1_y() // version is v1 (v2 always marks ogg as aud); DATE:2014-02-01
&& ( xfer_itm.File_exists() // NOTE: xfer_itm.Html_pass() checks for video .ogg files (ext = .ogg and thumb is available); EX: WWI;
|| xfer_itm.Meta_is_new() // NOTE: State_new() will always assume that ogg is video; needed for 1st load and dynamic updates
)
)
) {
xfer_itm.Html_elem_tid_(Xof_html_elem.Tid_vid);
this.Write_file_video(bfr, ctx, src, lnki, uid, div_width, lnki_halign_bry, lnki_href, img_view_src, img_orig_src, img_alt, xfer_itm);
}
else if (orig_ext.Id_is_audio()) // audio
this.Write_file_audio(bfr, ctx, src, lnki, uid, div_width, lnki_halign_bry, lnki_href, img_orig_src, img_alt);
else // image
this.Write_file_image(bfr, ctx, hctx, src, lnki, xfer_itm, uid, lnki_is_thumbable, div_width, lnki_halign, lnki_halign_bry, lnki_ttl, orig_ext, lnki_href, img_view_src, img_orig_src, img_alt);
}
if (hctx.Mode_is_hdump() && Xof_html_elem.Tid_is_file(xfer_itm.Html_elem_tid())) {
page.Hdump_data().Imgs_add_img(new Xohd_data_itm__img(), xfer_itm, Xohd_data_itm__gallery_itm.Tid_basic);
}
}
private void Write_file_ns_media(Bry_bfr bfr, Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, byte[] img_orig_src) {
html_fmtr.Html_full_media(bfr, img_orig_src, lnki.Ttl().Page_txt(), Arg_caption(ctx, src, Xoh_wtr_ctx.Basic, lnki)); // NOTE: use orig_src not view_src; DATE:2014-01-19
}
private void Write_file_audio(Bry_bfr bfr, Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, int uid, int div_width, byte[] lnki_halign_bry, byte[] lnki_href, byte[] img_orig_src, byte[] alt) {
byte[] content = Arg_content_audio(lnki, ctx, src, uid, lnki_href, img_orig_src, alt);
if (lnki.Media_icon())
html_fmtr.Html_thumb_core(bfr, uid, lnki_halign_bry, div_width, content);
else
bfr.Add(content);
}
private void Write_file_video(Bry_bfr bfr, Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, int uid, int div_width, byte[] lnki_halign_bry, byte[] lnki_href, byte[] img_view_src, byte[] img_orig_src, byte[] alt, Xof_file_itm xfer_itm) {
xfer_itm.Html_elem_tid_(Xof_html_elem.Tid_vid);
boolean video_is_thumb = Xop_lnki_type.Id_defaults_to_thumb(lnki.Lnki_type());
byte[] content = Arg_content_video(ctx, src, lnki, xfer_itm, uid, video_is_thumb, lnki_href, img_view_src, img_orig_src, alt);
if (video_is_thumb)
html_fmtr.Html_thumb_core(bfr, uid, lnki_halign_bry, div_width, content);
else
bfr.Add(content);
}
private void Write_file_image(Bry_bfr bfr, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, Xof_file_itm xfer_itm, int uid, boolean lnki_is_thumbable, int div_width, int lnki_halign, byte[] lnki_halign_bry
, byte[] lnki_ttl, Xof_ext orig_ext, byte[] lnki_href, byte[] img_view_src, byte[] img_orig_src, byte[] alt) {
if (lnki_halign == Xop_lnki_align_h.Center) bfr.Add(Div_center_bgn);
Bry_bfr tmp_bfr = bfr_mkr.Get_k004();
byte[] anchor_title = html_wtr.Cfg().Lnki__title()
? Arg_anchor_title(tmp_bfr, src, lnki, lnki_ttl, anchor_title_wkr) // NOTE: Arg_anchor_title should only be called if there is no caption, else refs may not show; DATE:2014-03-05
: Bry_.Empty;
Xoh_file_img_wkr lnki_file_wkr = lnki.Lnki_file_wkr(); if (lnki_file_wkr == null) lnki_file_wkr = html_fmtr;
if (lnki_is_thumbable) { // is "thumb"
if (bfr.Len() > 0) bfr.Add_byte_nl();
byte[] content = Arg_content_thumb(lnki_file_wkr, ctx, hctx, src, lnki, xfer_itm, uid, lnki_href, img_view_src, img_orig_src, alt, lnki_ttl, anchor_title);
html_fmtr.Html_thumb_core(bfr, uid, lnki_halign_bry, div_width, content);
}
else {
if ( cfg_alt_defaults_to_caption
&& Bry_.Len_eq_0(alt) // NOTE: if no alt, always use caption; DATE:2013-07-22
&& !lnki.Alt_exists() // unless blank alt exists; EX: [[File:A.png|a|alt=]] should have alt of "", not "a"
) {
Arg_caption(ctx, src, Xoh_wtr_ctx.Alt, lnki).XferAry(tmp_bfr, 0);
alt = tmp_bfr.Xto_bry_and_clear();
}
boolean div_align_exists = false;
switch (lnki.Align_h()) {
case Xop_lnki_align_h.Left: bfr.Add(Div_float_left) .Add_byte_nl(); div_align_exists = true; break;
case Xop_lnki_align_h.Right: bfr.Add(Div_float_right).Add_byte_nl(); div_align_exists = true; break;
case Xop_lnki_align_h.None: bfr.Add(Div_float_none) .Add_byte_nl(); div_align_exists = true; break;
}
Arg_nde_tkn lnki_link_tkn = lnki.Link_tkn();
byte img_cls_tid = lnki.Border() == Bool_.Y_byte ? Xoh_lnki_consts.Tid_img_cls_thumbborder : Xoh_lnki_consts.Tid_img_cls_none;
byte[] img_cls_other = lnki.Lnki_cls(); // PAGE:en.s:Page:Notes_on_Osteology_of_Baptanodon._With_a_Description_of_a_New_Species.pdf/3; DATE:2014-09-06
if (lnki_link_tkn == Arg_nde_tkn.Null) // full
lnki_file_wkr.Html_full_img(bfr, hctx, page, xfer_itm, uid, lnki_href, Xoh_lnki_consts.Tid_a_cls_image, Xoh_lnki_consts.Tid_a_rel_none, anchor_title, lnki_ttl, xfer_itm.Html_w(), xfer_itm.Html_h(), img_view_src, alt, img_cls_tid, img_cls_other);
else { // thumb
Arg_itm_tkn link_tkn = lnki_link_tkn.Val_tkn();
byte[] link_ref = link_tkn.Dat_to_bry(src);
byte[] link_ref_new = tmp_link_parser.Parse(tmp_bfr, tmp_url, wiki, link_ref, lnki_href);
link_ref = link_ref_new == null ? lnki_href: link_ref_new; // if parse fails, then assign to lnki_href; EX:link={{{1}}}
link_ref = Xoa_app_.Utl__encoder_mgr().Href_quotes().Encode(link_ref); // must encode quotes; PAGE:en.w:List_of_cultural_heritage_sites_in_Punjab,_Pakistan; DATE:2014-07-16
if (Bry_.Len_gt_0(tmp_link_parser.Html_xowa_ttl())) lnki_ttl = tmp_link_parser.Html_xowa_ttl();
lnki_file_wkr.Html_full_img(bfr, hctx, page, xfer_itm, uid, link_ref, tmp_link_parser.Html_anchor_cls(), tmp_link_parser.Html_anchor_rel(), anchor_title, lnki_ttl, xfer_itm.Html_w(), xfer_itm.Html_h(), img_view_src, alt, img_cls_tid, img_cls_other);
}
if (div_align_exists) bfr.Add(Html_tag_.Div_rhs); // close div from above
}
if (lnki_halign == Xop_lnki_align_h.Center) bfr.Add(Html_tag_.Div_rhs);
tmp_bfr.Mkr_rls();
}
private byte[] Arg_content_thumb(Xoh_file_img_wkr lnki_file_wkr, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, Xof_file_itm xfer_itm, int uid, byte[] lnki_href, byte[] view_src, byte[] img_orig_src, byte[] lnki_alt_text, byte[] lnki_ttl, byte[] anchor_title) {
byte[] lnki_alt_html = wiki.Html_mgr().Imgs_mgr().Alt_in_caption().Val() ? Arg_alt_html(ctx, src, lnki) : Bry_.Empty;
byte img_cls_tid = xfer_itm.File_exists() ? Xoh_lnki_consts.Tid_img_cls_thumbimage : Xoh_lnki_consts.Tid_img_cls_none;
Bry_bfr tmp_bfr = bfr_mkr.Get_k004();
lnki_file_wkr.Html_full_img(tmp_bfr, hctx, page, xfer_itm, uid, lnki_href, Xoh_lnki_consts.Tid_a_cls_image, Xoh_lnki_consts.Tid_a_rel_none, anchor_title, lnki_ttl, xfer_itm.Html_w(), xfer_itm.Html_h(), view_src, lnki_alt_text, img_cls_tid, Xoh_lnki_consts.Bry_none);
byte[] thumb = tmp_bfr.Xto_bry_and_clear();
html_fmtr.Html_thumb_file_image(tmp_bfr, thumb, Arg_caption_div(ctx, src, lnki, uid, img_orig_src, lnki_href), lnki_alt_html);
return tmp_bfr.To_bry_and_rls();
}
private byte[] Arg_content_audio(Xop_lnki_tkn lnki, Xop_ctx ctx, byte[] src, int uid, byte[] lnki_href, byte[] img_orig_src, byte[] alt) {
byte[] info_btn = Bry_.Empty;
if (lnki.Media_icon()) {
html_fmtr.Html_thumb_part_info(scratch_bfr, uid, lnki_href, html_mgr.Img_media_info_btn());
info_btn = scratch_bfr.Xto_bry_and_clear();
}
int play_btn_width = lnki.W(); if (play_btn_width < 1) play_btn_width = html_mgr.Img_thumb_width(); // if no width set width to default img width
html_fmtr.Html_thumb_file_audio(scratch_bfr, Arg_caption_div(ctx, src, lnki, uid, img_orig_src, lnki_href), Arg_alt_html(ctx, src, lnki), Arg_play_btn(uid, play_btn_width, Play_btn_max_width, img_orig_src, lnki.Ttl().Page_txt()), info_btn);
return scratch_bfr.Xto_bry_and_clear();
}
private byte[] Arg_content_video(Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, Xof_file_itm xfer_itm, int uid, boolean lnki_thumb, byte[] a_href, byte[] view_src, byte[] orig_src, byte[] img_alt) {
int thumb_w = xfer_itm.Html_w();
int play_btn_width = thumb_w; if (play_btn_width < 1) play_btn_width = wiki.Html_mgr().Img_thumb_width();
byte[] caption_html = Bry_.Empty, alt_html = Bry_.Empty;
if (lnki_thumb) {
caption_html = Arg_caption_div(ctx, src, lnki, uid, orig_src, a_href);
alt_html = Arg_alt_html(ctx, src, lnki);
}
html_fmtr.Html_thumb_file_video(scratch_bfr, Arg_play_btn(uid, play_btn_width, play_btn_width, orig_src, lnki.Ttl().Page_txt()), html_fmtr.Html_thumb_part_img(scratch_bfr, page, xfer_itm, lnki, uid, a_href, view_src, img_alt), caption_html, alt_html);
return scratch_bfr.Xto_bry_and_clear();
}
private byte[] Arg_caption_div(Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, int uid, byte[] img_orig_src, byte[] lnki_href) {
Bry_fmtr_arg caption = Arg_caption(ctx, src, Xoh_wtr_ctx.Basic, lnki);
byte[] magnify_btn = Bry_.Empty;
if (lnki.Media_icon()) {
if (msg_file_enlarge == null) msg_file_enlarge = wiki.Msg_mgr().Val_by_id(Xol_msg_itm_.Id_file_enlarge);
html_fmtr.Html_thumb_part_magnify(scratch_bfr, uid, lnki_href, msg_file_enlarge, html_mgr.Img_thumb_magnify());
magnify_btn = scratch_bfr.Xto_bry_and_clear();
}
html_fmtr.Html_thumb_part_caption(scratch_bfr, magnify_btn, caption);
return scratch_bfr.Xto_bry_and_clear();
} private byte[] msg_file_enlarge;
private Bry_fmtr_arg Arg_caption(Xop_ctx ctx, byte[] src, Xoh_wtr_ctx hctx_for_caption, Xop_lnki_tkn lnki) {
return lnki.Caption_exists() ? caption_fmtr.Set(ctx, hctx_for_caption, src, lnki.Caption_val_tkn(), Xoh_lnki_text_fmtr.Null_fmtr) : Bry_fmtr_arg_.Noop;
}
public byte[] Arg_alt_text(Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki) {
if (!lnki.Alt_exists()) return Bry_.Empty;
media_alt_fmtr.Set(ctx, Xoh_wtr_ctx.Alt, src, lnki.Alt_tkn().Val_tkn(), Xoh_lnki_text_fmtr.Null_fmtr);
Bry_bfr tmp_bfr = bfr_mkr.Get_k004();
media_alt_fmtr.XferAry(tmp_bfr, 0);
return tmp_bfr.To_bry_and_rls();
}
private byte[] Arg_alt_html(Xop_ctx ctx, byte[] alt_src, Xop_lnki_tkn lnki) {
if (!lnki.Alt_exists()) return Bry_.Empty;
media_alt_fmtr.Set(ctx, Xoh_wtr_ctx.Basic, alt_src, lnki.Alt_tkn().Val_tkn(), html_fmtr.Html_thumb_part_alt_fmtr());
Bry_bfr tmp_bfr = bfr_mkr.Get_k004();
media_alt_fmtr.XferAry(tmp_bfr, 0);
return tmp_bfr.To_bry_and_rls();
}
private byte[] Arg_play_btn(int uid, int width, int max_width, byte[] a_href, byte[] a_xowa_title) {
html_fmtr.Html_thumb_part_play(scratch_bfr, uid, width - 2, max_width, a_href, a_xowa_title, html_mgr.Img_media_play_btn()); // NOTE: -2 is fudge factor else play btn will jut out over video thumb; see Earth and ISS video
return scratch_bfr.Xto_bry_and_clear();
}
private static byte[] Arg_anchor_title(Bry_bfr tmp_bfr, byte[] src, Xop_lnki_tkn lnki, byte[] lnki_ttl, Xoh_lnki_title_fmtr anchor_title_wkr) {
if ( Enm_.HasInt(lnki.Lnki_type(), Xop_lnki_type.Id_thumb)
|| Enm_.HasInt(lnki.Lnki_type(), Xop_lnki_type.Id_frame) // If the image is a thumb, do not add a title / alt, even if a caption is available
)
return Bry_.Empty;
else if ( Enm_.HasInt(lnki.Lnki_type(), Xop_lnki_type.Id_frameless)) { // If the image is frameless, add the caption as a title / alt. If no caption is available, do not add a title / alt
}
Xop_tkn_itm anchor_title_tkn = lnki.Caption_tkn();
if (anchor_title_tkn == Xop_tkn_null.Null_tkn) return Bry_.Empty; // no caption; return empty; (do not use lnki); DATE:2013-12-31
tmp_bfr.Add(Atr_title);
anchor_title_wkr.Set(src, anchor_title_tkn).XferAry(tmp_bfr, 0);
tmp_bfr.Add_byte(Byte_ascii.Quote);
return tmp_bfr.Xto_bry_and_clear();
}
public static final int Play_btn_max_width = 1024;
private static final byte[]
Div_center_bgn = Bry_.new_a7("<div class=\"center\">")
, Div_float_none = Bry_.new_a7("<div class=\"floatnone\">")
, Div_float_left = Bry_.new_a7("<div class=\"floatleft\">")
, Div_float_right = Bry_.new_a7("<div class=\"floatright\">")
, Atr_title = Bry_.new_a7(" title=\"")
;
}

View File

@@ -0,0 +1,249 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*; import gplx.xowa.files.*;
public class Xoh_file_wtr_audio_video_tst {
@Before public void init() {fxt.Reset();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Audio_full() {
fxt.Test_parse_page_wiki_str
( "[[File:A.oga|noicon]]", String_.Concat_lines_nl_skip_last
( " <div id=\"xowa_media_div\">"
, " <div>"
, " <a id=\"xowa_file_play_0\" href=\"file:///mem/wiki/repo/trg/orig/4/f/A.oga\" xowa_title=\"A.oga\" class=\"xowa_anchor_button\" style=\"width:218px;max-width:1024px;\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/play.png\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
, " </div>"
, " <div class=\"thumbcaption\">"
, " "
, " </div>"
));
}
@Test public void Audio_full_ogg() {// PURPOSE: ogg should show src on first load
fxt.Wiki().Html_mgr().Img_suppress_missing_src_(true); // simulate release-mode wherein missing images will not have src
fxt.Test_parse_page_all_str
( "[[File:A.ogg]]", String_.Concat_lines_nl_skip_last
( " <div id=\"xowa_media_div\">"
, " <div>"
, " <a href=\"/wiki/File:A.ogg\" class=\"image\" title=\"A.ogg\">"
, " <img id=\"xowa_file_img_0\" src=\"file:///mem/wiki/repo/trg/orig/4/2/A.ogg\" width=\"220\" height=\"-1\" alt=\"\" />" // note that src still exists (needed for clicking)
, " </a>"
, " </div>"
, " <div>"
, " <a id=\"xowa_file_play_0\" href=\"file:///mem/wiki/repo/trg/orig/4/2/A.ogg\" xowa_title=\"A.ogg\" class=\"xowa_anchor_button\" style=\"width:218px;max-width:220px;\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/play.png\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
, " </div>"
));
fxt.Wiki().Html_mgr().Img_suppress_missing_src_(false);
}
@Test public void Audio_thumb() {
fxt.Test_parse_page_wiki_str
( "[[File:A.oga|thumb|a|alt=b]]", String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
, " <div id=\"xowa_media_div\">"
, " <div>"
, " <a id=\"xowa_file_play_0\" href=\"file:///mem/wiki/repo/trg/orig/4/f/A.oga\" xowa_title=\"A.oga\" class=\"xowa_anchor_button\" style=\"width:218px;max-width:1024px;\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/play.png\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
, " <div>"
, " <a href=\"/wiki/File:A.oga\" class=\"image\" title=\"About this file\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/info.png\" width=\"22\" height=\"22\" />"
, " </a>"
, " </div>"
, " </div>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.oga\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " a"
, " </div>"
, " <hr/>"
, " <div class=\"thumbcaption\">"
, "b"
, " </div>"
, " </div>"
, "</div>"
, ""
));
}
@Test public void Audio_full_width() { // ISSUE: width arg ignored for v2; zh.b:小学数学/自然数; DATE:2014-05-03
fxt.Wiki().File_mgr().Version_2_y_();
fxt.App().Usere().Init_by_app(fxt.App()); // TEST: init cache else null reference
fxt.Test_html_wiki_frag("[[File:A.oga|30px|a]]", "<div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:30px;\">");
fxt.Wiki().File_mgr().Version_1_y_();
}
@Test public void Audio_noicon() {
fxt.Test_parse_page_wiki_str
( "[[File:A.oga|thumb|noicon|a|alt=b]]", String_.Concat_lines_nl_skip_last
( " <div id=\"xowa_media_div\">"
, " <div>"
, " <a id=\"xowa_file_play_0\" href=\"file:///mem/wiki/repo/trg/orig/4/f/A.oga\" xowa_title=\"A.oga\" class=\"xowa_anchor_button\" style=\"width:218px;max-width:1024px;\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/play.png\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
, " </div>"
, " <div class=\"thumbcaption\">"
, " a"
, " </div>"
, " <hr/>"
, " <div class=\"thumbcaption\">"
, "b"
, " </div>"
));
}
@Test public void Video_full() {
fxt.Test_parse_page_wiki_str
( "[[File:A.ogv|400px|a|alt=b]]", String_.Concat_lines_nl_skip_last
( " <div id=\"xowa_media_div\">"
, " <div>"
, " <a href=\"/wiki/File:A.ogv\" class=\"image\" title=\"A.ogv\">"
, " <img id=\"xowa_file_img_0\" src=\"file:///\" width=\"400\" height=\"0\" alt=\"b\" />"
, " </a>"
, " </div>"
, " <div>"
, " <a id=\"xowa_file_play_0\" href=\"file:///mem/wiki/repo/trg/orig/d/0/A.ogv\" xowa_title=\"A.ogv\" class=\"xowa_anchor_button\" style=\"width:398px;max-width:400px;\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/play.png\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
, " </div>"
));
}
@Test public void Video_full_ogg() {// PURPOSE: ogg should default to video on first load; otherwise dynamic-update won't be able to put in thumb; DATE:2015-05-21
Xof_file_fxt file_fxt = Xof_file_fxt.new_all(fxt.Wiki());
file_fxt.Exec_orig_add(Bool_.Y, "A.ogg", Xof_ext_.Id_ogv, 400, 400, "");
fxt.Test_parse_page_wiki_str
( "[[File:A.ogg|400px|a|alt=b]]", String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:400px;\">"
, " <div id=\"xowa_media_div\">"
, " <div>"
, " <a id=\"xowa_file_play_0\" href=\"file:///\" xowa_title=\"A.ogg\" class=\"xowa_anchor_button\" style=\"width:398px;max-width:1024px;\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/play.png\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
, " <div>"
, " <a href=\"/wiki/File:A.ogg\" class=\"image\" title=\"About this file\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/info.png\" width=\"22\" height=\"22\" />"
, " </a>"
, " </div>"
, " </div>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.ogg\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " a"
, " </div>"
, " <hr/>"
, " <div class=\"thumbcaption\">"
, "b"
, " </div>"
, " </div>"
, "</div>"
));
}
@Test public void Video_thumb() {
fxt.Test_parse_page_wiki_str
( "[[File:A.ogv|thumb|400px|a|alt=b]]", String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">" // NOTE:220px is default w for "non-found" thumb; DATE:2014-09-24
, " <div id=\"xowa_media_div\">"
, " <div>"
, " <a href=\"/wiki/File:A.ogv\" class=\"image\" title=\"A.ogv\">"
, " <img id=\"xowa_file_img_0\" src=\"file:///\" width=\"400\" height=\"0\" alt=\"b\" />"
, " </a>"
, " </div>"
, " <div>"
, " <a id=\"xowa_file_play_0\" href=\"file:///mem/wiki/repo/trg/orig/d/0/A.ogv\" xowa_title=\"A.ogv\" class=\"xowa_anchor_button\" style=\"width:398px;max-width:400px;\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/play.png\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
, " </div>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.ogv\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " a"
, " </div>"
, " <hr/>"
, " <div class=\"thumbcaption\">"
, "b"
, " </div>"
, " </div>"
, "</div>"
, ""
));
}
@Test public void Video_thumb_webm() { // PURPOSE: webm thumb wasn't being shown; DATE:2014-01-25
fxt.Test_parse_page_wiki_str
( "[[File:A.webm|thumb|400px|a|alt=b]]", String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">" // NOTE:220px is default w for "non-found" thumb; DATE:2014-09-24
, " <div id=\"xowa_media_div\">"
, " <div>"
, " <a href=\"/wiki/File:A.webm\" class=\"image\" title=\"A.webm\">"
, " <img id=\"xowa_file_img_0\" src=\"file:///\" width=\"400\" height=\"0\" alt=\"b\" />"
, " </a>"
, " </div>"
, " <div>"
, " <a id=\"xowa_file_play_0\" href=\"file:///mem/wiki/repo/trg/orig/3/4/A.webm\" xowa_title=\"A.webm\" class=\"xowa_anchor_button\" style=\"width:398px;max-width:400px;\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/play.png\" width=\"22\" height=\"22\" alt=\"Play sound\" />"
, " </a>"
, " </div>"
, " </div>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.webm\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " a"
, " </div>"
, " <hr/>"
, " <div class=\"thumbcaption\">"
, "b"
, " </div>"
, " </div>"
, "</div>"
, ""
));
}
}
// @Test public void Ogg() {
// fxt.Src_en_wiki_repo().Ext_rules().Get_or_new(Xof_ext_.Bry_ogg).View_max_(0);
// fxt .ini_page_api("commons", "A.ogg", "", 0, 0);
// fxt .Lnki_orig_("A.ogg")
// .Src( )
// .Trg(
// fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/4/42.csv", "A.ogg|z||2?0,0|0?0,0")
// )
// .tst();
// fxt .Lnki_orig_("A.ogg")
// .Html_orig_src_("file:///mem/trg/en.wikipedia.org/raw/4/2/A.ogg")
// .tst();
// fxt.Src_en_wiki_repo().Ext_rules().Get_or_new(Xof_ext_.Bry_ogg).View_max_(-1);
// }

View File

@@ -0,0 +1,297 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*;
public class Xoh_file_wtr_basic_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@Test public void Img_full() { // PURPOSE: full with title was outputting invalid html; DATE:2013-12-31
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_wiki_str
( "[[File:A.png]]"
, String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>" // NOTE: used to output class=\"image\"A.png
));
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Img_embed() {
fxt.Test_parse_page_wiki_str("[[File:A.png|9x8px|alt=abc]]", Xop_fxt.html_img_none("File:A.png", "abc", "file:///mem/wiki/repo/trg/thumb/7/0/A.png/9px.png", "A.png"));
}
@Test public void Img_none() { // NOTE: floatnone is WP behavior; MW omits div tag
fxt.Test_parse_page_wiki_str
( "[[File:A.png|none|20x30px|b]]"
, String_.Concat_lines_nl_skip_last
( "<div class=\"floatnone\">"
, "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"b\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/20px.png\" width=\"20\" height=\"30\" /></a></div>"
));
}
@Test public void Img_thumb_none() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|thumb|none|b]]"
, Img_thumb_str("none")
);
}
@Test public void Img_thumb_ltr() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|thumb|b]]"
, Img_thumb_str("right")
);
}
@Test public void Img_thumb_rtl() {
fxt.Wiki().Lang().Dir_ltr_(false);
fxt.Test_parse_page_wiki_str
( "[[File:A.png|thumb|b]]"
, Img_thumb_str("left")
);
fxt.Wiki().Lang().Dir_ltr_(true);
}
private String Img_thumb_str(String align) {
return String_.Concat_lines_nl_skip_last
( "<div class=\"thumb t" + align + "\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"0\" height=\"0\" /></a>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " b"
, " </div>"
, " </div>"
, "</div>"
, ""
);
}
@Test public void Img_frame() { // PURPOSE: lnki with "frame" is same as thumb; DATE:2013-12-23
fxt.Test_parse_page_wiki_str
( "[[File:A.png|frame|220x110px|b]]"
, String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"220\" height=\"110\" /></a>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " b"
, " </div>"
, " </div>"
, "</div>"
, ""
));
}
@Test public void Img_frame_and_thumb() { // PURPOSE: lnki with "frame and thumb" was not showing box due to bit-adding; PAGE:en.w:History_of_Western_Civilization DATE:2015-04-16
fxt.Test_parse_page_wiki_str
( "[[File:A.png|frame|thumb|220x110px|b]]" // NOTE: frame AND thumb
, String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"220\" height=\"110\" /></a>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " b"
, " </div>"
, " </div>"
, "</div>"
, ""
));
}
@Test public void Cls_border() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|border]]"
, "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" class=\"thumbborder\" /></a>");
}
@Test public void Cls_custom() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|class=abc]]"
, "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" class=\"abc\" /></a>");
}
@Test public void Cls_border_custom() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|border|class=abc]]"
, "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" class=\"thumbborder abc\" /></a>");
}
@Test public void Lnki_full_svg() {
fxt.Test_parse_page_wiki_str
( "[[File:A.svg|a|alt=b]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:A.svg\" class=\"image\" xowa_title=\"A.svg\"><img id=\"xowa_file_img_0\" alt=\"b\" src=\"file:///mem/wiki/repo/trg/thumb/7/5/A.svg/-1px.png\" width=\"0\" height=\"0\" /></a>" // HACK: tries to get orig_w which is not available
));
}
@Test public void Lnki_file_alt_link() { // PURPOSE: lnki in caption should not create alt="b<a href="c">cd</a>"
fxt.Test_parse_page_wiki_str("[[File:A.png|thumb|alt=b [[c]] d]]", String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"b c d\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"0\" height=\"0\" /></a>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " "
, " </div>"
, " <hr/>"
, " <div class=\"thumbcaption\">"
, "b <a href=\"/wiki/C\">c</a> d"
, " </div>"
, " </div>"
, "</div>"
, ""
));
}
@Test public void Pre_in_caption() { // PURPOSE: ignore pre if in caption; PAGE:s.w:Virus; DATE:2015-03-31
fxt.Init_para_y_();
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "[[File:A.png|thumb|a\n b]]" // "\n " is pre
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"0\" height=\"0\" /></a>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " a" // no pre
, " b"
, " </div>"
, " </div>"
, "</div>"
, ""
));
fxt.Init_para_n_();
}
@Test public void Img_title() {
fxt.Wtr_cfg().Lnki__title_(true);
Tst_img_title("[[File:A.png|frameless|a b]]", "a b");
Tst_img_title("[[File:A.png|thumb|a b]]", "Enlarge"); // caption should not replace text
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Title_escape() { // PURPOSE: escape quotes in title; PAGE:none; DATE:2014-10-27
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_wiki_str("[[A\"B]]", "<a href=\"/wiki/A%22B\" title=\"A&quot;B\">A\"B</a>");
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Img_title__caption_has_lnki() { // PURPOSE: caption with lnki should show in title; PAGE:en.w:Earth; DATE:2014-08-06
fxt.Wtr_cfg().Lnki__title_(true);
Tst_img_title("[[File:A.png|frameless|[[A]]]]" , "A"); // ttl only
Tst_img_title("[[File:A.png|frameless|[[A|B]]]]" , "B"); // caption
Tst_img_title("[[File:A.png|frameless|[[A]]b]]" , "Ab"); // tail
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Lnki_alt_is_text() { // PURPOSE: (a) alt should default to caption; (b) alt should not show html chars (like <a src=")
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_all_str
( "[[File:A.png|a[[b]]c]]"
, "<a href=\"/wiki/File:A.png\" class=\"image\" title=\"aBc\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"abc\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Alt_ignore_apos() {// PURPOSE: alt should ignore apos; EX: [[File:A.png|''A'']] should have alt of A; DATE:2013-10-25
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_all_str
( "[[File:A.png|''b'']]"
, "<a href=\"/wiki/File:A.png\" class=\"image\" title=\"b\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"b\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Alt_ignore_lnke() {// PURPOSE: alt should ignore lnke
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_all_str
( "[[File:A.png|b[http://c.org d] e]]"
, "<a href=\"/wiki/File:A.png\" class=\"image\" title=\"bd e\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"bd e\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Alt_ignore_list() {// PURPOSE: alt should ignore list
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_all_str
( "[[File:A.png|b\n*c]]"
, "<a href=\"/wiki/File:A.png\" class=\"image\" title=\"bc\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"b*c\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Alt_ignore_tblw() {// PURPOSE: alt should ignore tblw
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_all_str
( "[[File:A.png|\n{|\n|-\n|b\n|}\n]]"
, "<a href=\"/wiki/File:A.png\" class=\"image\" title=\"b&#10;\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\" b \" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Alt_ignore_para() {// PURPOSE: alt should ignore para
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Init_para_y_();
fxt.Test_parse_page_all_str
( "[[File:A.png|b\nc]]"
, String_.Concat_lines_nl
( "<p><a href=\"/wiki/File:A.png\" class=\"image\" title=\"b&#10;c\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"b c\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
, "</p>"
));
fxt.Init_para_n_();
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Lnki_empty_alt_is_omitted() {// PURPOSE: empty alt should be ignored; DATE:2013-07-30
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_all_str
( "[[File:A.png|a|alt=]]"
, "<a href=\"/wiki/File:A.png\" class=\"image\" title=\"a\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
fxt.Wtr_cfg().Lnki__title_(false);
}
@Test public void Href_anchor_leading_space() { // PURPOSE: space before anchor should be preserved, not " " -> "#"
fxt.Test_parse_page_all_str("[[A #b]]", "<a href=\"/wiki/A#b\">A #b</a>");
}
@Test public void Href_anchor_leading_space_ns() { // PURPOSE: same as above, but with ns; DATE:2013-08-29
fxt.Test_parse_page_all_str("[[Help:A #b]]", "<a href=\"/wiki/Help:A#b\">Help:A #b</a>");
}
@Test public void Href_anchor_leading_ns_lc() { // PURPOSE: same as above but with lc title
fxt.Test_parse_page_all_str("[[Help:a#b]]", "<a href=\"/wiki/Help:A#b\">Help:A#b</a>");
}
@Test public void Href_anchor_leading_space_ns_lc() { // PURPOSE: same as above but with lc title
fxt.Test_parse_page_all_str("[[Help:a #b]]", "<a href=\"/wiki/Help:A#b\">Help:A #b</a>");
}
@Test public void Lnki_caption_nested_file() { // PURPOSE: nested lnki in caption breaks alt with html chars; EX:de.w:Wien; DATE:2013-12-16
fxt.Wtr_cfg().Lnki__title_(true);
fxt.Test_parse_page_wiki_str("[[File:A.png|none|[[File:B.png|20px|d]] c]]", String_.Concat_lines_nl_skip_last
( "<div class=\"floatnone\">"
, "<a href=\"/wiki/File:A.png\" class=\"image\" title=\"d c\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"d c\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a></div>"
, ""
));
fxt.Wtr_cfg().Lnki__title_(false);
}
private void Tst_img_title(String raw, String expd_ttl) {
String actl = fxt.Exec_parse_page_wiki_as_str(raw);
String actl_ttl = null;
int title_bgn = String_.FindFwd(actl, " title=\"");
if (title_bgn != String_.Find_none) {
title_bgn += String_.Len(" title=\"");
int title_end = String_.FindFwd(actl, "\"", title_bgn);
if (title_end != String_.Find_none) actl_ttl = String_.Mid(actl, title_bgn, title_end);
}
Tfds.Eq(expd_ttl, actl_ttl, actl);
}
}

View File

@@ -0,0 +1,63 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*;
public class Xoh_file_wtr_media_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@Test public void Lnki_caption_nested_media() { // PAGE:en.w:Beethoven;
fxt.Test_parse_page_wiki_str("[[File:A.png|thumb|b [[Media:A.ogg]] c]]", String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"0\" height=\"0\" /></a>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " b <a href=\"file:///mem/wiki/repo/trg/orig/4/2/A.ogg\" xowa_title=\"A.ogg\">"
, "</a> c"
, " </div>"
, " </div>"
, "</div>"
, ""
));
}
@Test public void Lnki_media_normal() {
fxt.Test_parse_page_wiki_str("[[Media:A.png|b]]", String_.Concat_lines_nl_skip_last
( "<a href=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" xowa_title=\"A.png\">b"
, "</a>"
));
}
@Test public void Lnki_media_literal() {
fxt.Test_parse_page_wiki_str("[[:Media:A.ogg|b]]", String_.Concat_lines_nl_skip_last
( "<a href=\"file:///mem/wiki/repo/trg/orig/4/2/A.ogg\" xowa_title=\"A.ogg\">b"
, "</a>"
));
}
@Test public void Lnki_media_literal_pdf() {
fxt.Wiki().Html_mgr().Img_suppress_missing_src_(true); // simulate missing file; DATE:2014-01-30
fxt.Test_parse_page_wiki_str("[[Media:A.pdf|b]]", String_.Concat_lines_nl_skip_last
( "<a href=\"file:///mem/wiki/repo/trg/orig/e/f/A.pdf\" xowa_title=\"A.pdf\">b"
, "</a>"
));
Tfds.Eq(0, fxt.Page().File_queue().Count()); // make sure media does not add to queue
fxt.Wiki().Html_mgr().Img_suppress_missing_src_(false);
}
}

View File

@@ -0,0 +1,50 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_lnki_consts {
public static final byte
Tid_a_cls_none = 0 , Tid_a_cls_image = 1
, Tid_a_rel_none = 0 , Tid_a_rel_nofollow = 1
, Tid_img_cls_none = 0 , Tid_img_cls_thumbimage = 2, Tid_img_cls_thumbborder = 3
;
public static final String Str_img_cls_thumbimage = "thumbimage";
private static final byte[]
Bry_anchor_class_image = Bry_.new_a7(" class=\"image\"")
, Bry_anchor_rel_nofollow = Bry_.new_a7(" rel=\"nofollow\"")
, Bry_img_cls_thumbborder = Bry_.new_a7(" class=\"thumbborder\"")
, Bry_img_cls_prefix = Bry_.new_a7(" class=\"")
;
public static final byte[] Bry_img_cls_thumbimage = Bry_.new_a7(" class=\"thumbimage\"");
public static final byte[] Bry_none = Bry_.Empty;
public static byte[] A_cls_to_bry(byte tid) {return tid == Tid_a_cls_none ? Bry_.Empty : Bry_anchor_class_image;}
public static byte[] A_rel_to_bry(byte tid) {return tid == Tid_a_rel_none ? Bry_.Empty : Bry_anchor_rel_nofollow;}
public static byte[] Img_cls_to_bry(byte tid, byte[] other) {
boolean other_is_empty = Bry_.Len_eq_0(other);
byte[] rv = null;
switch (tid) {
case Tid_img_cls_none: return other_is_empty ? Bry_.Empty : Bry_.Add(Bry_img_cls_prefix, other, Byte_ascii.Quote_bry);
case Tid_img_cls_thumbimage: rv = Bry_img_cls_thumbimage; break;
case Tid_img_cls_thumbborder: rv = Bry_img_cls_thumbborder; break;
default: throw Exc_.new_unhandled(tid);
}
if (other_is_empty) return rv;
rv = Bry_.Copy(rv); // copy for replace below
rv[rv.length - 1] = Byte_ascii.Space; // replace " with space
return Bry_.Add(rv, other, Byte_ascii.Quote_bry); // add custom cls
}
}

View File

@@ -0,0 +1,34 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*;
public class Xoh_lnki_consts_tst {
private Xoh_lnki_consts_fxt fxt = new Xoh_lnki_consts_fxt();
@Test public void Img_cls_to_bry() {
fxt.Test_img_cls_to_bry(Xoh_lnki_consts.Tid_img_cls_none , null , "");
fxt.Test_img_cls_to_bry(Xoh_lnki_consts.Tid_img_cls_none , "a" , " class=\"a\"");
fxt.Test_img_cls_to_bry(Xoh_lnki_consts.Tid_img_cls_thumbimage , null , " class=\"thumbimage\"");
fxt.Test_img_cls_to_bry(Xoh_lnki_consts.Tid_img_cls_thumbborder , null , " class=\"thumbborder\"");
fxt.Test_img_cls_to_bry(Xoh_lnki_consts.Tid_img_cls_thumbborder , "a" , " class=\"thumbborder a\"");
}
}
class Xoh_lnki_consts_fxt {
public void Test_img_cls_to_bry(byte tid, String other, String expd) {
Tfds.Eq(expd, String_.new_u8(Xoh_lnki_consts.Img_cls_to_bry(tid, Bry_.new_u8_safe(other))));
}
}

View File

@@ -0,0 +1,39 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_lnki_text_fmtr implements Bry_fmtr_arg { // formats alt or caption
private final Bry_bfr_mkr bfr_mkr; private final Xoh_html_wtr html_wtr;
private Xop_ctx ctx; private Xoh_wtr_ctx hctx; private byte[] src; private Xop_tkn_itm text_tkn; private Bry_fmtr fmtr;
public Xoh_lnki_text_fmtr(Bry_bfr_mkr bfr_mkr, Xoh_html_wtr html_wtr) {this.bfr_mkr = bfr_mkr; this.html_wtr = html_wtr;}
public Xoh_lnki_text_fmtr Set(Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_tkn_itm text_tkn, Bry_fmtr fmtr) {
this.ctx = ctx; this.hctx = hctx; this.src = src; this.text_tkn = text_tkn; this.fmtr = fmtr;
return this;
}
public void XferAry(Bry_bfr trg, int idx) {
Bry_bfr tmp_bfr = bfr_mkr.Get_k004();
html_wtr.Write_tkn(tmp_bfr, ctx, hctx, src, null, Xoh_html_wtr.Sub_idx_null, text_tkn);
tmp_bfr.Mkr_rls();
if (tmp_bfr.Len() == 0) return;
byte[] bry = tmp_bfr.Xto_bry_and_clear();
if (fmtr == Null_fmtr)
trg.Add(bry);
else
fmtr.Bld_bfr_many(trg, bry);
}
public static final Bry_fmtr Null_fmtr = null;
}

View File

@@ -0,0 +1,76 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_lnki_title_fmtr implements Bry_fmtr_arg {
public Xoh_lnki_title_fmtr Set(byte[] src, Xop_tkn_itm tkn) {this.src = src; this.tkn = tkn; return this;}
public void XferAry(Bry_bfr bfr, int idx) {
Bld_recurse(bfr, tkn);
}
public void Bld_recurse(Bry_bfr bfr, Xop_tkn_itm tkn) {
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_newLine: case Xop_tkn_itm_.Tid_space: case Xop_tkn_itm_.Tid_txt: // leaf tkns which will have no subs
Write_atr_text(bfr, src, tkn.Src_bgn(), tkn.Src_end());
break;
case Xop_tkn_itm_.Tid_arg_nde: // caption tkns have no subs; just a key and a val; recurse val
Arg_nde_tkn arg_nde = (Arg_nde_tkn)tkn;
Bld_recurse(bfr, arg_nde.Val_tkn());
break;
case Xop_tkn_itm_.Tid_lnki:
Xop_lnki_tkn tkn_as_lnki = (Xop_lnki_tkn)tkn;
if (tkn_as_lnki.Caption_exists())
Bld_recurse(bfr, tkn_as_lnki.Caption_tkn());
else {
if (tkn_as_lnki.Ttl() != null) // guard against invalid ttls
bfr.Add(tkn_as_lnki.Ttl().Page_txt());
}
if (tkn_as_lnki.Tail_bgn() != -1)
bfr.Add_mid(src, tkn_as_lnki.Tail_bgn(), tkn_as_lnki.Tail_end());
break;
default: // all other tkns, just iterate over subs for txt tkns
if (tkn.Tkn_tid() == Xop_tkn_itm_.Tid_xnde) {
Xop_xnde_tkn xnde = (Xop_xnde_tkn)tkn;
if (xnde.Tag().Id() == Xop_xnde_tag_.Tid_ref) { // if ref, disable tkn
gplx.xowa.xtns.cite.Ref_nde ref_xnde = (gplx.xowa.xtns.cite.Ref_nde)xnde.Xnde_xtn();
ref_xnde.Exists_in_lnki_title_(true); // ref found during html_title_wkr's generation; mark ref; will be ignored by references_html_wtr later; DATE:2014-03-05
}
}
int len = tkn.Subs_len();
for (int i = 0; i < len; i++) {
Xop_tkn_itm sub = tkn.Subs_get(i);
Bld_recurse(bfr, sub);
}
break;
}
}
public static void Write_atr_text(Bry_bfr bfr, byte[] src, int bgn, int end) {
for (int i = bgn; i < end; i++) {
byte b = src[i];
switch (b) {
case Byte_ascii.Nl: case Byte_ascii.Cr: case Byte_ascii.Tab: // NOTE: escape ws so that it renders correctly in tool tips
case Byte_ascii.Quote: case Byte_ascii.Lt: case Byte_ascii.Gt: case Byte_ascii.Amp: // NOTE: escape possible javascript injection characters
bfr.Add(Escape_bgn);
bfr.Add_int_variable(b);
bfr.Add_byte(Byte_ascii.Semic);
break;
default: bfr.Add_byte(b); break;
}
}
}
byte[] src; Xop_tkn_itm tkn;
public static final byte[] Escape_bgn = Bry_.new_a7("&#");
}

View File

@@ -0,0 +1,42 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import org.junit.*;
public class Xoh_lnki_title_fmtr_tst {
@Before public void init() {fxt.Clear();} private Xoh_lnki_title_fmtr_fxt fxt = new Xoh_lnki_title_fmtr_fxt();
@Test public void Basic() {
fxt.Test_parse("a b c", "a b c");
fxt.Test_parse("a ''b'' c", "a b c");
fxt.Test_parse("a <i>b</i> c", "a b c");
fxt.Test_parse("a\nb", "a&#10;b");
fxt.Test_parse("a\"b", "a&#34;b");
}
}
class Xoh_lnki_title_fmtr_fxt {
private Xop_fxt fxt = new Xop_fxt();
Bry_bfr bfr = Bry_bfr.new_();
Xoh_lnki_title_fmtr title_wkr = new Xoh_lnki_title_fmtr();
public Xoh_lnki_title_fmtr_fxt Clear() {return this;}
public void Test_parse(String raw, String expd) {
byte[] raw_bry = Bry_.new_u8(raw);
Xop_root_tkn root = fxt.Ctx().Tkn_mkr().Root(raw_bry);
fxt.Parser().Parse_page_all_clear(root, fxt.Ctx(), fxt.Ctx().Tkn_mkr(), raw_bry);
title_wkr.Set(raw_bry, root).Bld_recurse(bfr, root);
Tfds.Eq(expd, bfr.Xto_str_and_clear());
}
}

View File

@@ -0,0 +1,201 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.html.*; import gplx.xowa.files.*; import gplx.xowa.parsers.lnkis.redlinks.*; import gplx.xowa.users.history.*; import gplx.xowa.xtns.pfuncs.ttls.*; import gplx.xowa.xtns.relatedSites.*;
import gplx.xowa.wikis.xwikis.*; import gplx.xowa.xtns.wdatas.core.*; import gplx.xowa.html.hzips.*;
public class Xoh_lnki_wtr {
private Xoae_app app; private Xowe_wiki wiki; private Xoae_page page; private Xop_ctx ctx;
private Xoh_html_wtr_cfg cfg;
private Xou_history_mgr history_mgr;
private Xop_lnki_caption_wtr_tkn caption_tkn_wtr;
private Xop_lnki_caption_wtr_bry caption_bry_wtr;
private Xopg_redlink_lnki_list redlinks_mgr;
public Xoh_lnki_wtr(Xoh_html_wtr html_wtr, Xowe_wiki wiki, Xow_html_mgr html_mgr, Xoh_html_wtr_cfg cfg) {
caption_tkn_wtr = new Xop_lnki_caption_wtr_tkn(html_wtr);
caption_bry_wtr = new Xop_lnki_caption_wtr_bry();
this.wiki = wiki; this.app = wiki.Appe(); this.cfg = cfg;
file_wtr = new Xoh_file_mgr(wiki, html_mgr, html_wtr);
}
public Xoh_file_mgr File_wtr() {return file_wtr;} private Xoh_file_mgr file_wtr;
public void Init_by_page(Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xoae_page page) {
this.ctx = ctx; this.page = page; // NOTE: must set ctx for file.v2; DATE:2014-06-22
this.wiki = ctx.Wiki();
redlinks_mgr = page.Redlink_lnki_list(); // NOTE: need to set redlinks_mgr, else toc parse may fail; EX:pl.d:head_sth_off;DATE:2014-05-07
file_wtr.Init_by_page(hctx, page);
this.history_mgr = app.Usere().History_mgr();
}
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()));
Xoh_html_wtr_escaper.Escape(app.Parser_amp_mgr(), bfr, src, lnki.Src_bgn(), lnki.Src_end(), true, false);
return;
}
Xow_xwiki_itm xwiki_lang = lnki_ttl.Wik_itm();
if ( xwiki_lang != null // lnki is xwiki; EX: [[commons:]] [[en:]] [[wikt:]]
&& xwiki_lang.Domain_tid() == wiki.Xwiki_domain_tid() // xwiki is same type as cur wiki; EX: cur=w xwiki=w -> add to xwiki_langs; cur=w xwikid=d -> don't add to xwiki_langs; DATE:2014-09-14
&& xwiki_lang.Type_is_xwiki_lang(wiki.Domain_itm().Lang_orig_uid())// NOTE: use Lang_orig_id to handle xwikis between s.w and en.w; PAGE:s.q:Anonymous DATE:2014-09-10
&& !lnki_ttl.ForceLiteralLink() // not literal; [[:en:A]]
) {
Wdata_sitelink_itm slink = new Wdata_sitelink_itm(null, null, null).Page_ttl_(lnki_ttl);
page.Slink_list().Add(slink);
return;
}
boolean literal_link = lnki_ttl.ForceLiteralLink(); // NOTE: if literal link, then override ns behavior; for File, do not show image; for Ctg, do not display at bottom of page
redlinks_mgr.Lnki_add(lnki);
boolean stage_is_alt = hctx.Mode_is_alt();
switch (lnki.Ns_id()) {
case Xow_ns_.Id_media: if (!stage_is_alt) file_wtr.Write_or_queue(bfr, page, ctx, hctx, src, lnki); return; // NOTE: literal ":" has no effect; PAGE:en.w:Beethoven and [[:Media:De-Ludwig_van_Beethoven.ogg|listen]]
case Xow_ns_.Id_file: if (!literal_link && !stage_is_alt) {file_wtr.Write_or_queue(bfr, page, ctx, hctx, src, lnki); return;} break;
case Xow_ns_.Id_category: if (!literal_link) {page.Html_data().Ctgs_add(lnki.Ttl()); return;} break;
}
Write_plain_by_tkn(bfr, hctx, src, lnki, lnki_ttl);
}
public void Write_file(Bry_bfr bfr, Xoae_page page, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, byte[] alt) {
file_wtr.Write_or_queue(bfr, page, ctx, hctx, src, lnki, alt);
}
public void Write_file(Bry_bfr bfr, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, Xof_file_itm xfer, byte[] alt) {
file_wtr.File_wtr().Write_file(bfr, ctx, hctx, src, lnki, xfer, alt);
}
public void Write_plain_by_bry(Bry_bfr bfr, byte[] src, Xop_lnki_tkn lnki, byte[] caption) {
Write_plain(bfr, Xoh_wtr_ctx.Basic, src, lnki, lnki.Ttl(), caption_bry_wtr.Caption_bry_(caption));
}
public void Write_plain_by_tkn(Bry_bfr bfr, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, Xoa_ttl lnki_ttl) {
Write_plain(bfr, hctx, src, lnki, lnki_ttl, caption_tkn_wtr);
}
public void Write_caption(Bry_bfr bfr, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, Xoa_ttl lnki_ttl) {
Write_caption(bfr, ctx, hctx, src, lnki, lnki.Ttl_ary(), true, caption_tkn_wtr);
}
private void Write_plain(Bry_bfr bfr, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, Xoa_ttl lnki_ttl, Xop_lnki_caption_wtr caption_wkr) {
byte[] ttl_bry = lnki.Ttl_ary();
if (Bry_.Len_eq_0(ttl_bry)) ttl_bry = lnki_ttl.Full_txt_raw(); // NOTE: handles ttls like [[fr:]] and [[:fr;]] which have an empty Page_txt, but a valued Full_txt_raw
if (Bry_.Eq(lnki_ttl.Full_txt(), page.Ttl().Full_txt())) { // lnki is same as pagename; bold; SEE: Month widget on day pages will bold current day; PAGE:en.w:January 1
if (lnki_ttl.Anch_bgn() == -1 && Bry_.Eq(lnki_ttl.Wik_txt(), page.Ttl().Wik_txt())) { // only bold if lnki is not pointing to anchor on same page; PAGE:en.w:Comet; [[Comet#Physical characteristics|ion tail]]
bfr.Add(Html_tag_.B_lhs);
Write_caption(bfr, ctx, hctx, src, lnki, ttl_bry, true, caption_wkr);
bfr.Add(Html_tag_.B_rhs);
return;
}
}
if (lnki.Xtn_sites_link()) return; // lnki marked for relatedSites; don't write to page
if (hctx.Mode_is_alt())
Write_caption(bfr, ctx, hctx, src, lnki, ttl_bry, true, caption_wkr);
else {
if (hctx.Mode_is_hdump())
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'
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
bfr .Add(Xoh_consts.A_mid_id) // '" id=\"xowa_lnki_'
.Add_int_variable(lnki_html_id); // '1234'
}
if (cfg.Lnki__title()) {
bfr .Add(Xoh_consts.A_bgn_lnki_0); // '" title=\"'
byte[] lnki_title_bry = lnki_ttl.Page_txt(); // 'Abcd' NOTE: use Page_txt to (a) replace underscores with spaces; (b) get title casing; EX:[[roman_empire]] -> Roman empire
Html_utl.Escape_html_to_bfr(bfr, lnki_title_bry, 0, lnki_title_bry.length, Bool_.N, Bool_.N, Bool_.N, Bool_.Y, Bool_.N); // escape title; DATE:2014-10-27
}
if (hctx.Mode_is_hdump()) {
bfr.Add(gplx.xowa.html.hdumps.abrvs.Xohd_abrv_.Html_redlink_bgn);
bfr.Add_int_variable(lnki.Html_uid());
bfr.Add(gplx.xowa.html.hdumps.abrvs.Xohd_abrv_.Html_redlink_end);
}
else {
if (cfg.Lnki__visited()
&& history_mgr.Has(wiki.Domain_bry(), ttl_bry))
bfr.Add(Bry_xowa_visited); // '" class="xowa-visited'
bfr.Add(Xoh_consts.__end_quote); // '">'
}
if (lnki_ttl.Anch_bgn() != -1 && !lnki_ttl.Ns().Id_main()) { // anchor exists and not main_ns; anchor must be manually added b/c Xoa_ttl does not handle # for non main-ns
byte[] anch_txt = lnki_ttl.Anch_txt();
byte anch_spr
= (anch_txt.length > 0 && anch_txt[0] == Byte_ascii.Hash) // 1st char is #; occurs when page_txt has trailing space; causes 1st letter of anch_txt to start at # instead of 1st letter
? Byte_ascii.Space // ASSUME: 1 space ("Help:A #b"); does not handle multiple spaces like ("Help:A #b"); needs change to Xoa_ttl
: Byte_ascii.Hash; // Anch_txt bgns at 1st letter, so add # for caption;
ttl_bry = Bry_.Add_w_dlm(anch_spr, ttl_bry, anch_txt); // manually add anchor; else "Help:A#b" becomes "Help:A". note that lnki.Ttl_ary() uses .Full_txt (wiki + page but no anchor) to captialize 1st letter of page otherwise "Help:A#b" shows as "Help:A" (so Help:a -> Help:A); DATE:2013-06-21
}
Write_caption(bfr, ctx, hctx, src, lnki, ttl_bry, true, caption_wkr);
bfr.Add(Xoh_consts.A_end); // </a>
}
}
private void Write_caption(Bry_bfr bfr, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xop_lnki_tkn lnki, byte[] ttl_bry, boolean tail_enabled, Xop_lnki_caption_wtr caption_wkr) {
if (lnki.Caption_exists()) { // lnki has a caption seg; EX: [[A|caption]]
if (lnki.Caption_tkn_pipe_trick()) // "pipe trick"; [[A|]] is same as [[A|A]]; also, [[Help:A|]] -> [[Help:A|A]]
bfr.Add(lnki.Ttl().Page_txt());
else
caption_wkr.Write_tkn(ctx, hctx, bfr, src, lnki, Xoh_html_wtr.Sub_idx_null, lnki.Caption_val_tkn());
}
else { // lnki only has ttl
if (!Write_caption_for_rel2abs(bfr, lnki)) // write caption if rel2abs ttls
bfr.Add(ttl_bry); // write ttl_bry as caption;
}
if (tail_enabled) { // write tail if enabled; EX: [[A]]b -> Ab
int tail_bgn = lnki.Tail_bgn();
if (tail_bgn != -1) bfr.Add_mid(src, tail_bgn, lnki.Tail_end());
}
}
private static boolean Write_caption_for_rel2abs(Bry_bfr bfr, Xop_lnki_tkn lnki) {
int subpage_tid = lnki.Subpage_tid(); if (subpage_tid == Pfunc_rel2abs.Id_null) return false; // not a subpage
boolean subpage_slash_at_end = lnki.Subpage_slash_at_end();
byte[] leaf_txt = lnki.Ttl().Leaf_txt_wo_qarg();
switch (subpage_tid) {
case Pfunc_rel2abs.Id_slash:
if (subpage_slash_at_end) // "/" at end; only add text; EX: [[/A/]] -> A
bfr.Add(leaf_txt);
else // "/" absent; add slash to bgn; EX: [[/A]] -> /A
bfr.Add_byte(Byte_ascii.Slash).Add(leaf_txt);
return true;
case Pfunc_rel2abs.Id_dot_dot_slash:
if (subpage_slash_at_end) // "/" at end; only add text; EX: [[../A/]] -> A
bfr.Add(leaf_txt);
else // "/" absent; add page; EX: [[../A]] -> Page/A
bfr.Add(lnki.Ttl().Page_txt());
return true;
}
return false;
}
public static byte[] Lnki_cls_visited(gplx.xowa.users.history.Xou_history_mgr history_mgr, byte[] wiki_key, byte[] page_ttl) {
return history_mgr.Has(wiki_key, page_ttl) ? Lnki_cls_visited_bry : Bry_.Empty;
} private static final byte[] Lnki_cls_visited_bry = Bry_.new_a7(" class=\"xowa-visited\"");
private static final byte[] Bry_xowa_visited = Bry_.new_a7("\" class=\"xowa-visited");
public static final int Lnki_id_ignore = 0, Lnki_id_min = 1;
}
interface Xop_lnki_caption_wtr {
void Write_tkn(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_tkn_grp grp, int sub_idx, Xop_tkn_itm tkn);
}
class Xop_lnki_caption_wtr_bry implements Xop_lnki_caption_wtr {
private byte[] caption_bry;
public Xop_lnki_caption_wtr_bry Caption_bry_(byte[] caption_bry) {
this.caption_bry = caption_bry;
return this;
}
public void Write_tkn(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_tkn_grp grp, int sub_idx, Xop_tkn_itm tkn) {
bfr.Add(caption_bry);
}
}
class Xop_lnki_caption_wtr_tkn implements Xop_lnki_caption_wtr {
private Xoh_html_wtr html_wtr;
public Xop_lnki_caption_wtr_tkn(Xoh_html_wtr html_wtr) {
this.html_wtr = html_wtr;
}
public void Write_tkn(Xop_ctx ctx, Xoh_wtr_ctx hctx, Bry_bfr bfr, byte[] src, Xop_tkn_grp grp, int sub_idx, Xop_tkn_itm tkn) {
html_wtr.Write_tkn(bfr, ctx, hctx, src, grp, sub_idx, tkn);
}
}

View File

@@ -0,0 +1,22 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_redlink_utl {
public static final byte[] Cls_bry = Bry_.new_a7("class='new'");
public static final String New_str = "new";
}

View File

@@ -0,0 +1,34 @@
/*
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.modules; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public interface Xoh_module_itm {
byte[] Key();
void Write_css_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr);
void Write_css_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr);
void Write_js_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr);
void Write_js_head_global(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr);
void Write_js_head_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr);
void Write_js_tail_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr);
void Clear();
}
/*
Position // top, bottom
Targets // mobile, desktop
Dependencies
Messages
*/

View File

@@ -0,0 +1,36 @@
/*
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.modules; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_module_itm_ {
public static final byte[] // SRL: navframe, toc, title_rewrite are in wiki.cfg
Key_collapsible = Bry_.new_a7("collapsible")
, Key_css = Bry_.new_a7("css")
, Key_gallery = Bry_.new_a7("gallery")
, Key_globals = Bry_.new_a7("globals")
, Key_hiero = Bry_.new_a7("hiero")
, Key_mathjax = Bry_.new_a7("mathjax")
, Key_navframe = Bry_.new_a7("navframe")
, Key_popups = Bry_.new_a7("popups")
, Key_search_suggest = Bry_.new_a7("xowa.search_suggest")
, Key_timeline = Bry_.new_a7("xowa.timeline")
, Key_title_rewrite = Bry_.new_a7("title_rewrite")
, Key_toc = Bry_.new_a7("toc")
, Key_top_icon = Bry_.new_a7("top_icon")
, Key_xoui = Bry_.new_a7("xoui")
;
}

View File

@@ -0,0 +1,41 @@
/*
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.modules; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
public class Xoh_module_itm__collapsible implements Xoh_module_itm {
public byte[] Key() {return Xoh_module_itm_.Key_collapsible;}
public boolean Enabled() {return enabled;} public void Enabled_y_() {enabled = true;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public void Clear() {enabled = false;}
public void Write_css_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_css_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_tail_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_global(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {
if (!enabled) return;
wtr.Write_js_global_ini_atr_val(Key_enabled , true);
wtr.Write_js_global_ini_atr_val(Key_collapsed , app.Api_root().Html().Modules().Collapsible().Collapsed());
wtr.Write_js_global_ini_atr_msg(wiki , Key_collapse);
wtr.Write_js_global_ini_atr_msg(wiki , Key_expand);
}
private static final byte[]
Key_enabled = Bry_.new_a7("collapsible-enabled")
, Key_collapsed = Bry_.new_a7("collapsible-collapsed")
, Key_collapse = Bry_.new_a7("collapsible-collapse")
, Key_expand = Bry_.new_a7("collapsible-expand")
;
}

View File

@@ -0,0 +1,38 @@
/*
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.modules; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.gui.*;
public class Xoh_module_itm__css implements Xoh_module_itm {
public byte[] Key() {return Xoh_module_itm_.Key_css;}
public boolean Enabled() {return enabled;} public void Enabled_y_() {enabled = true;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public void Clear() {enabled = false;}
public void Write_css_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_css_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {
if (!enabled) return;
wtr.Write_css_style_itm(app.Ctg_mgr().Missing_ctg_cls_css());
if (app.Html_mgr().Page_mgr().Font_enabled())
wtr.Write_css_style_itm(app.Html_mgr().Page_mgr().Font_css_bry());
byte[] css_xtn = app.Gui_mgr().Html_mgr().Css_xtn();
if (Bry_.Len_gt_0(css_xtn))
wtr.Write_css_style_itm(css_xtn);
}
public void Write_js_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_tail_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_global(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
}

View File

@@ -0,0 +1,36 @@
/*
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.modules; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.gui.*;
public class Xoh_module_itm__gallery implements Xoh_module_itm {
public byte[] Key() {return Xoh_module_itm_.Key_gallery;}
public boolean Enabled() {return enabled;} public void Enabled_y_() {enabled = true;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public void Clear() {enabled = false;}
public void Write_css_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_css_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_tail_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_global(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {
if (!enabled) return;
wtr.Write_js_global_ini_atr_val(Key_enabled , true);
}
private static final byte[]
Key_enabled = Bry_.new_a7("gallery-packed-enabled")
;
}

View File

@@ -0,0 +1,105 @@
/*
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.modules; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.langs.numbers.*;
public class Xoh_module_itm__globals implements Xoh_module_itm {
private final Xoh_module_wtr tmp_wtr = new Xoh_module_wtr();
public byte[] Key() {return Xoh_module_itm_.Key_globals;}
public boolean Enabled() {return enabled;} public void Enabled_n_() {enabled = false;} public void Enabled_y_() {enabled = true;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public void Clear() {enabled = false;}
public void Write_css_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {
if (!enabled) return;
if (Url_core_css == null) Url_core_css = app.Fsys_mgr().Bin_any_dir().GenSubFil_nest("xowa", "html", "res", "src", "xowa", "core", "core.css").To_http_file_bry();
wtr.Write_css_include(Url_core_css);
}
public void Write_css_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {
if (!enabled) return;
if (Url_core_js == null) {
Io_url core_dir = app.Fsys_mgr().Bin_any_dir().GenSubDir_nest("xowa", "html", "res", "src", "xowa", "core");
Url_core_js = core_dir.GenSubFil("core.js").To_http_file_bry();
Url_DOMContentLoaded_js = core_dir.GenSubFil("DOMContentLoaded.js").To_http_file_bry();
}
wtr.Write_js_include(Url_core_js);
wtr.Write_js_include(Url_DOMContentLoaded_js);
}
public void Write_js_head_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {
if (!enabled) return;
wtr.Write_js_var(Var_xowa_root_dir , Bool_.Y, app.Fsys_mgr().Root_dir().To_http_file_bry());
wtr.Write_js_var(Var_xowa_mode_is_server , Bool_.N, app.Tcp_server().Running() ? Bool_.True_bry : Bool_.False_bry);
}
public void Write_js_tail_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_global(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {
if (!enabled) return;
wtr.Write_js_global_ini_atr_val(Key_mode_is_gui , app.App_type().Uid_is_gui());
wtr.Write_js_global_ini_atr_val(Key_mode_is_http , app.App_type().Uid_is_http());
wtr.Write_js_global_ini_atr_val(Key_http_port , app.Http_server().Port());
wtr.Write_js_global_ini_atr_msg(wiki, Key_sort_ascending);
wtr.Write_js_global_ini_atr_msg(wiki, Key_sort_descending);
Xol_lang lang = wiki.Lang(); Xow_msg_mgr msg_mgr = wiki.Msg_mgr();
Bry_bfr tmp_bfr = app.Utl__bfr_mkr().Get_b512();
tmp_wtr.Init(tmp_bfr);
byte[] months_long = Html_js_table_months(tmp_wtr, msg_mgr, Xol_msg_itm_.Id_dte_month_name_january, Xol_msg_itm_.Id_dte_month_name_december);
byte[] months_short = Html_js_table_months(tmp_wtr, msg_mgr, Xol_msg_itm_.Id_dte_month_abrv_jan, Xol_msg_itm_.Id_dte_month_abrv_dec);
byte[] num_format_separators = Html_js_table_num_format_separators(tmp_wtr, lang.Num_mgr().Separators_mgr());
tmp_bfr.Mkr_rls();
wtr.Write_js_global_ini_atr_val(Key_wgContentLanguage , lang.Key_bry());
wtr.Write_js_global_ini_atr_obj(Key_wgSeparatorTransformTable , num_format_separators);
wtr.Write_js_global_ini_atr_obj(Key_wgDigitTransformTable , Num_format_digits);
wtr.Write_js_global_ini_atr_val(Key_wgDefaultDateFormat , Date_format_default);
wtr.Write_js_global_ini_atr_obj(Key_wgMonthNames , months_long);
wtr.Write_js_global_ini_atr_obj(Key_wgMonthNamesShort , months_short);
}
public static final byte[] // NOTE: most of these are for the table-sorter
Key_mode_is_gui = Bry_.new_a7("mode_is_gui")
, Key_mode_is_http = Bry_.new_a7("mode_is_http")
, Key_http_port = Bry_.new_a7("http-port")
, Key_sort_descending = Bry_.new_a7("sort-descending")
, Key_sort_ascending = Bry_.new_a7("sort-ascending")
, Key_wgContentLanguage = Bry_.new_a7("wgContentLanguage")
, Key_wgSeparatorTransformTable = Bry_.new_a7("wgSeparatorTransformTable")
, Key_wgDigitTransformTable = Bry_.new_a7("wgDigitTransformTable")
, Key_wgDefaultDateFormat = Bry_.new_a7("wgDefaultDateFormat")
, Key_wgMonthNames = Bry_.new_a7("wgMonthNames")
, Key_wgMonthNamesShort = Bry_.new_a7("wgMonthNamesShort")
;
private static byte[] Html_js_table_months(Xoh_module_wtr tmp_wtr, Xow_msg_mgr msg_mgr, int january_id, int december_id) {
tmp_wtr.Write_js_ary_bgn();
tmp_wtr.Write_js_ary_itm(Bry_.Empty); // 1st month is always empty
for (int i = january_id; i <= december_id; i++)
tmp_wtr.Write_js_ary_itm(msg_mgr.Val_by_id(i));
tmp_wtr.Write_js_ary_end();
return tmp_wtr.Bfr().Xto_bry_and_clear();
}
private static byte[] Html_js_table_num_format_separators(Xoh_module_wtr tmp_wtr, Xol_transform_mgr separator_mgr) {
byte[] dec_spr = separator_mgr.Get_val_or_self(Xol_num_mgr.Separators_key__dec);
byte[] grp_spr = separator_mgr.Get_val_or_self(Xol_num_mgr.Separators_key__grp);
tmp_wtr.Write_js_ary_bgn();
tmp_wtr.Write_js_ary_itm(Bry_.Add(dec_spr, Byte_ascii.Tab_bry, Byte_ascii.Dot_bry));
tmp_wtr.Write_js_ary_itm(Bry_.Add(grp_spr, Byte_ascii.Tab_bry, Byte_ascii.Comma_bry));
tmp_wtr.Write_js_ary_end();
return tmp_wtr.Bfr().Xto_bry_and_clear();
}
private static final byte[]
Date_format_default = Bry_.new_a7("dmy")
, Num_format_digits = Bry_.new_a7("['', '']")
, Var_xowa_root_dir = Bry_.new_a7("xowa_root_dir")
, Var_xowa_mode_is_server = Bry_.new_a7("xowa_mode_is_server")
;
private static byte[] Url_core_css, Url_core_js, Url_DOMContentLoaded_js;
}

View File

@@ -0,0 +1,35 @@
/*
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.modules; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.gui.*;
public class Xoh_module_itm__hiero implements Xoh_module_itm {
public byte[] Key() {return Xoh_module_itm_.Key_hiero;}
public boolean Enabled() {return enabled;} public void Enabled_y_() {enabled = true;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public void Clear() {enabled = false;}
public void Write_css_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {
if (!enabled) return;
if (Url_css == null) Url_css = app.Fsys_mgr().Bin_any_dir().GenSubFil_nest("xowa", "xtns", "Wikihiero", "modules", "ext.wikihiero.css").To_http_file_bry();
wtr.Write_css_include(Url_css);
}
public void Write_css_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_tail_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_global(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
private static byte[] Url_css;
}

View File

@@ -0,0 +1,35 @@
/*
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.modules; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*;
import gplx.xowa.gui.*;
public class Xoh_module_itm__mathjax implements Xoh_module_itm {
public byte[] Key() {return Xoh_module_itm_.Key_mathjax;}
public boolean Enabled() {return enabled;} public void Enabled_y_() {enabled = true;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public void Clear() {enabled = false;}
public void Write_css_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_css_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_include(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {
if (!enabled) return;
if (Url_mathjax == null) Url_mathjax = app.Fsys_mgr().Bin_any_dir().GenSubFil_nest("xowa", "xtns", "Math", "modules", "mathjax", "xowa_mathjax.js").To_http_file_bry();
wtr.Write_js_include(Url_mathjax);
}
public void Write_js_head_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_tail_script(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
public void Write_js_head_global(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xoh_module_wtr wtr) {}
private static byte[] Url_mathjax;
}

Some files were not shown because too many files have changed in this diff Show More