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,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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.html.*; import gplx.xowa.html.hdumps.abrvs.*;
public interface Gallery_box_w_fmtr_arg extends Bry_fmtr_arg {
Gallery_box_w_fmtr_arg Init(int uid, int width);
}
class Gallery_box_w_fmtr_arg__basic implements Gallery_box_w_fmtr_arg {
private int width;
public Gallery_box_w_fmtr_arg Init(int uid, int width) {this.width = width; return this;}
public void XferAry(Bry_bfr bfr, int idx) {
bfr.Add(Style_bgn);
bfr.Add_int_variable(width);
bfr.Add(Style_end);
}
private static final byte[] Style_bgn = Bry_.new_a7("style=\"width: "), Style_end = Bry_.new_a7("px\"");
}
class Gallery_box_w_fmtr_arg__hdump implements Gallery_box_w_fmtr_arg {
private int uid;
public Gallery_box_w_fmtr_arg Init(int uid, int width) {this.uid = uid; return this;}
public void XferAry(Bry_bfr bfr, int idx) {
bfr.Add(Xohd_abrv_.Key_gallery_box_w);
bfr.Add_int_variable(uid);
bfr.Add_byte_apos();
}
}
interface Gallery_img_pad_fmtr_arg extends Bry_fmtr_arg {
Gallery_img_pad_fmtr_arg Init(int uid, int vpad);
}
class Gallery_img_pad_fmtr_arg__basic implements Gallery_img_pad_fmtr_arg {
private int vpad;
public Gallery_img_pad_fmtr_arg Init(int uid, int vpad) {this.vpad = vpad; return this;}
public void XferAry(Bry_bfr bfr, int idx) {
bfr.Add(Style_bgn);
bfr.Add_int_variable(vpad);
bfr.Add(Style_end);
}
private static final byte[] Style_bgn = Bry_.new_a7("style=\"margin:"), Style_end = Bry_.new_a7("px auto;\"");
}
class Gallery_img_pad_fmtr_arg__hdump implements Gallery_img_pad_fmtr_arg {
private int uid;
public Gallery_img_pad_fmtr_arg Init(int uid, int width) {this.uid = uid; return this;}
public void XferAry(Bry_bfr bfr, int idx) {
bfr.Add(Xohd_abrv_.Key_gallery_img_pad);
bfr.Add_int_variable(uid);
bfr.Add_byte_apos();
}
}

View File

@@ -0,0 +1,173 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.files.*; import gplx.xowa.html.*; import gplx.xowa.html.lnkis.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hdumps.pages.*;
public class Gallery_html_wtr {
private final Xoh_arg_img_core img_core_fmtr_basic = new Xoh_arg_img_core__basic(), img_core_fmtr_hdump = new Xoh_arg_img_core__hdump();
public void Write_html(Bry_bfr bfr, Xoae_app app, Xowe_wiki wiki, Xop_ctx ctx, Xoh_html_wtr wtr, Xoh_wtr_ctx hctx, Xoae_page page, Gallery_xnde mgr, byte[] src) {
int itm_div_w = Gallery_html_wtr_utl.Calc_itm_div_len(mgr.Itm_w_or_default());
int itm_div_h = Gallery_html_wtr_utl.Calc_itm_div_len(mgr.Itm_h_or_default());
int itm_box_w = Gallery_html_wtr_utl.Calc_itm_box_w(itm_div_w);
int itms_len = mgr.Itms_len();
int itms_per_row = mgr.Itms_per_row();
if (itms_per_row == Gallery_xnde.Null) itms_per_row = wiki.Cfg_gallery().Imgs_per_row();
int mgr_box_width_row = Gallery_html_wtr_utl.Calc_itm_pad_w(itm_box_w) * itms_per_row;
int row_multiplier; Bry_fmtr mgr_box_style;
if (itms_per_row == Gallery_xnde.Null) { // no "perrow" defined; default to total # of items;
row_multiplier = itms_len;
mgr_box_style = Gallery_html_wtr_.Mgr_box_style_none;
}
else {
row_multiplier = itms_per_row;
mgr_box_style = Gallery_html_wtr_.Mgr_box_style_max;
}
boolean mode_is_packed = Gallery_mgr_base_.Mode_is_packed(mgr.Mode());
byte[] mgr_box_cls; int mgr_box_width_all;
if (mode_is_packed) {
mgr_box_cls = Gallery_html_wtr_.Cls_packed;
mgr_box_width_all = 0;
}
else {
mgr_box_cls = Bry_.Empty;
mgr_box_width_all = Gallery_html_wtr_utl.Calc_itm_pad_w(itm_box_w) * row_multiplier; // 8=Gallery Box borders; REF.MW:ImageGallery.php|GB_BORDERS;
}
Bry_bfr itm_bfr = wiki.Utl__bfr_mkr().Get_k004(), tmp_bfr = wiki.Utl__bfr_mkr().Get_k004();
int mgr_elem_id = -1; int gallery_w_count = 0;
boolean hctx_is_hdump = hctx.Mode_is_hdump();
Xoh_arg_img_core img_core_fmtr = hctx_is_hdump ? img_core_fmtr_hdump : img_core_fmtr_basic;
Xopg_hdump_data hdump_imgs = page.Hdump_data();
for (int i = 0; i < itms_len; i++) {
Gallery_itm itm = mgr.Itms_get_at(i);
byte[] itm_caption = Gallery_html_wtr_.Bld_caption(wiki, ctx, wtr, hctx, itm);
Xoa_ttl itm_ttl = itm.Ttl();
if ( itm_ttl != null // ttl does not have invalid characters
&& itm_ttl.Ns().Id_file() // ttl is in file ns;
) {
Xop_lnki_tkn lnki = ctx.Tkn_mkr().Lnki(itm.Ttl_bgn(), itm.Ttl_end()).Ttl_(itm_ttl).W_(mgr.Itm_w()).H_(mgr.Itm_h());
Xof_file_itm xfer_itm = wtr.Lnki_wtr().File_wtr().Lnki_eval(Xof_exec_tid.Tid_wiki_page, ctx, page, lnki);
xfer_itm.Html_gallery_mgr_h_(mgr.Itm_h_or_default());
xfer_itm.Html_elem_tid_(Xof_html_elem.Tid_gallery);
if (mode_is_packed) {
if (gallery_w_count < itms_per_row) {
mgr_box_width_all += Gallery_html_wtr_utl.Calc_itm_pad_w(itm_box_w);
++gallery_w_count;
}
if (xfer_itm.Html_w() > 0) {
itm_div_w = Gallery_html_wtr_utl.Calc_itm_div_len(xfer_itm.Html_w());
itm_box_w = Gallery_html_wtr_utl.Calc_itm_box_w(itm_div_w); // NOTE: redefine itm_box_w for rest of loop
}
if (xfer_itm.Html_h() > 0)
itm_div_h = Gallery_html_wtr_utl.Calc_itm_div_len(xfer_itm.Html_h());
}
int itm_elem_id = xfer_itm.Html_uid();
if (mgr_elem_id == -1)
mgr_elem_id = itm_elem_id; // HACK: set mgr_elem_id to first itm_elem_id
int html_w = xfer_itm.Html_w();
int html_h = xfer_itm.Html_h();
byte[] html_src = xfer_itm.Html_view_url().To_http_file_bry();
if (html_src.length == 0) { // itm not found; use gallery defaults
html_w = mgr.Itm_w_or_default();
html_h = mgr.Itm_h_or_default();
}
byte[] lnki_ttl = lnki.Ttl().Page_txt();
Xoa_ttl lnki_link_ttl = itm_ttl; // default href to ttl
if ( itm.Link_bgn() != Bry_.NotFound // link is not -1; EX: "A.png" has no link specified
&& (itm.Link_end() - itm.Link_bgn()) > 0 // and link_end - link_bgn > 0; EX: "A.png|link="; DATE:2014-06-15
)
lnki_link_ttl = Xoa_ttl.parse_(wiki, Bry_.Mid(src, itm.Link_bgn(), itm.Link_end()));
byte[] lnki_href = app.Href_parser().Build_to_bry(wiki, lnki_link_ttl);
byte[] lnki_alt = itm.Alt_bgn() == Bry_.NotFound ? lnki_ttl : Xoh_html_wtr_escaper.Escape(app.Parser_amp_mgr(), tmp_bfr, Bry_.Mid(src, itm.Alt_bgn(), itm.Alt_end()));
img_core_fmtr.Init(itm_elem_id, html_src, html_w, html_h);
int itm_margin = Gallery_html_wtr_utl.Calc_vpad(mgr.Itm_h(), html_h);
Gallery_html_wtr_.Itm_img_fmtr.Bld_bfr_many(itm_bfr
, itm_box_w, itm_div_w, itm_margin
, itm_elem_id
, lnki_ttl
, lnki_href
, img_core_fmtr
, itm_caption
, lnki_alt
);
if (hctx_is_hdump)
hdump_imgs.Imgs_add_img(new Xohd_data_itm__gallery_itm().Data_init_gallery(itm_div_w, itm_box_w, itm_margin), xfer_itm, Xohd_data_itm__gallery_itm.Tid_gallery);
}
else {
Gallery_html_wtr_.Itm_txt_fmtr.Bld_bfr_many(itm_bfr
, itm_box_w, itm_div_h
, Bry_.Mid(src, itm.Ttl_bgn(), itm.Ttl_end())
, itm_caption
);
}
}
itm_bfr.Mkr_rls();
tmp_bfr.Mkr_rls();
int mgr_box_width_max = mgr_box_width_all < mgr_box_width_row ? mgr_box_width_row : mgr_box_width_all;
Gallery_html_wtr_.Mgr_all_fmtr.Bld_bfr_many(bfr, mgr_elem_id, mgr_box_cls, Bry_fmtr_arg_.fmtr_(mgr_box_style, Bry_fmtr_arg_.int_(mgr_box_width_max)), itm_bfr);
}
}
class Gallery_html_wtr_ {
public static final byte[] Cls_packed = Bry_.new_u8(" mw-gallery-packed");
public static final Bry_fmtr
Mgr_all_fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( "<ul id=\"xowa_gallery_ul_~{gallery_id}\" class=\"gallery~{gallery_cls}\" style=\"~{gallery_style}\">~{itm_list}"
, "</ul>"
), "gallery_id", "gallery_cls", "gallery_style", "itm_list"
)
, Mgr_box_style_none = Bry_fmtr.new_()
, Mgr_box_style_max = Bry_fmtr.new_("max-width:~{gallery_width}px; _width:~{gallery_width}px;", "gallery_width")
, Itm_img_fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <li id=\"xowa_gallery_li_~{img_id}\" class=\"gallerybox\" style=\"width:~{itm_box_width}px;\">"
, " <div id=\"xowa_gallery_div1_~{img_id}\" style=\"width:~{itm_box_width}px;\">"
, " <div id=\"xowa_gallery_div2_~{img_id}\" class=\"thumb\" style=\"width:~{itm_div_width}px;\">"
, " <div id=\"xowa_gallery_div3_~{img_id}\" style=\"margin:~{itm_margin}px auto;\">"
, " <a href=\"~{img_href}\" class=\"image\">"
, " <img id=\"xowa_file_img_~{img_id}\" alt=\"~{img_alt}\"~{img_core} />"
, " </a>"
, " </div>"
, " </div>"
, " <div class=\"gallerytext\">~{itm_caption}"
, " </div>"
, " </div>"
, " </li>"
), "itm_box_width", "itm_div_width", "itm_margin", "img_id", "img_ttl", "img_href", "img_core", "itm_caption", "img_alt"
)
, Itm_txt_fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <li id=\"xowa_gallery_li_~{img_id}\" class=\"gallerybox\" style=\"width:~{itm_box_width};\">"
, " <div id=\"xowa_gallery_div1_~{img_id}\" style=\"width:~{itm_box_width};\">"
, " <div id=\"xowa_gallery_div2_~{img_id}\" style=\"~{itm_div_height}\">"
, " ~{itm_text}"
, " </div>"
, " <div class=\"gallerytext\">~{itm_caption}"
, " </div>"
, " </div>"
, " </li>"
), "itm_box_width", "itm_div_height", "itm_text", "itm_caption"
);
public static byte[] Bld_caption(Xowe_wiki wiki, Xop_ctx ctx, Xoh_html_wtr wtr, Xoh_wtr_ctx hctx, Gallery_itm itm) {
byte[] rv = itm.Caption_bry();
if (Bry_.Len_gt_0(rv)) {
Bry_bfr caption_bfr = wiki.Utl__bfr_mkr().Get_k004();
Xop_root_tkn caption_root = itm.Caption_tkn();
wtr.Write_tkn(caption_bfr, ctx, hctx, caption_root.Root_src(), caption_root, Xoh_html_wtr.Sub_idx_null, caption_root);
rv = caption_bfr.To_bry_and_rls();
}
return rv;
}
}

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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
public class Gallery_html_wtr_utl {
public static int Calc_itm_div_len(int v) {return v + 30;} // 30=Thumb padding; REF.MW:ImageGallery.php|THUMB_PADDING
public static int Calc_itm_box_w(int v) {return v + 5;} // 5=Gallery Box padding; REF.MW:ImageGallery.php|GB_PADDING
public static int Calc_itm_pad_w(int v) {return v + 8;} // 8=Gallery Box borders; REF.MW:ImageGallery.php|GB_BORDERS
public static int Calc_vpad(int mgr_itm_height, int html_h) {
int min_thumb_height = html_h > 17 ? html_h : 17; // $minThumbHeight = $thumb->height > 17 ? $thumb->height : 17;
return (int)Math_.Floor((30 + mgr_itm_height - min_thumb_height) / 2); // $vpad = floor(( self::THUMB_PADDING + $this->mHeights - $minThumbHeight ) /2);
}
}

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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.files.*; import gplx.xowa.files.gui.*; import gplx.xowa.gui.views.*; import gplx.xowa.html.*;
public class Gallery_itm implements Js_img_wkr {
private Gallery_xnde xnde; private Xof_file_itm xfer_itm; private Xowe_wiki wiki; private Xop_ctx ctx; private byte[] src; private byte[] gallery_li_id_bry; private int gallery_itm_idx;
public Xoa_ttl Ttl() {return ttl;} public Gallery_itm Ttl_(Xoa_ttl v) {ttl = v; return this;} private Xoa_ttl ttl;
public int Ttl_bgn() {return ttl_bgn;} public Gallery_itm Ttl_bgn_(int v) {ttl_bgn = v; return this;} private int ttl_bgn;
public int Ttl_end() {return ttl_end;} public Gallery_itm Ttl_end_(int v) {ttl_end = v; return this;} private int ttl_end;
public Xof_ext Ext() {return ext;} public Gallery_itm Ext_(Xof_ext v) {ext = v; return this;} private Xof_ext ext;
public byte[] Caption_bry() {return caption_bry;} public Gallery_itm Caption_bry_(byte[] v) {caption_bry = v; return this;} private byte[] caption_bry;
public Xop_root_tkn Caption_tkn() {return caption_tkn;} public Gallery_itm Caption_tkn_(Xop_root_tkn v) {caption_tkn = v; return this;} private Xop_root_tkn caption_tkn;
public int Alt_bgn() {return alt_bgn;} public Gallery_itm Alt_bgn_(int v) {alt_bgn = v; return this;} private int alt_bgn;
public int Alt_end() {return alt_end;} public Gallery_itm Alt_end_(int v) {alt_end = v; return this;} private int alt_end;
public int Link_bgn() {return link_bgn;} public Gallery_itm Link_bgn_(int v) {link_bgn = v; return this;} private int link_bgn;
public int Link_end() {return link_end;} public Gallery_itm Link_end_(int v) {link_end = v; return this;} private int link_end;
public int Page_bgn() {return page_bgn;} public Gallery_itm Page_bgn_(int v) {page_bgn = v; return this;} private int page_bgn;
public int Page_end() {return page_end;} public Gallery_itm Page_end_(int v) {page_end = v; return this;} private int page_end;
public Xop_lnki_tkn Lnki_tkn() {return lnki_tkn;} public Gallery_itm Lnki_tkn_(Xop_lnki_tkn v) {lnki_tkn = v; return this;} private Xop_lnki_tkn lnki_tkn;
public Gallery_itm Reset() {
ttl = null;
ttl_bgn = ttl_end = alt_bgn = alt_end = link_bgn = link_end = page_bgn = page_end = Bry_.NotFound;
caption_bry = null; // NOTE: use null instead of ""; more legible tests
caption_tkn = null;
ext = null;
return this;
}
public void Html_prepare(Xowe_wiki wiki, Xop_ctx ctx, byte[] src, Gallery_xnde xnde, Xof_file_itm xfer_itm, byte[] gallery_li_id_bry, int gallery_itm_idx) {
this.xnde = xnde; this.xfer_itm = xfer_itm;
this.wiki = wiki; this.ctx = ctx; this.src = src; this.gallery_li_id_bry = gallery_li_id_bry; this.gallery_itm_idx = gallery_itm_idx;
}
public void Html_update(Xoa_page page, Xog_js_wkr js_wkr, int html_uid, int html_w, int html_h, Io_url html_view_url, int orig_w, int orig_h, Io_url html_orig_url, byte[] lnki_ttl) {
Gallery_mgr_base gallery_mgr = xnde.Gallery_mgr();
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_k004(), tmp_bfr = wiki.Utl__bfr_mkr().Get_k004();
try {
xfer_itm.Init_at_gallery_end(html_w, html_h, html_view_url, html_orig_url);
gallery_mgr.Write_html_itm(bfr, tmp_bfr, wiki.Appe(), wiki, ctx.Cur_page(), ctx, wiki.Html_mgr().Html_wtr(), Xoh_wtr_ctx.Basic, src, xnde, Bry_.Empty, gallery_itm_idx, xfer_itm, false);
String itm_html = bfr.Xto_str_and_clear();
js_wkr.Html_elem_replace_html(String_.new_u8(gallery_li_id_bry), itm_html);
if (gallery_itm_idx == xnde.Itms_len() - 1 && Gallery_mgr_base_.Mode_is_packed(xnde.Mode()))
page.Xtn_gallery_packed_exists_y_(); // set flag for packed_gallery; don't fire multiple times; PAGE:en.w:National_Sculpture_Museum_(Valladolid); DATE:2014-07-21
}
finally {
bfr.Mkr_rls(); tmp_bfr.Mkr_rls();
}
}
}

View File

@@ -0,0 +1,251 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.primitives.*; import gplx.core.btries.*;
import gplx.xowa.parsers.lnkis.redlinks.*;
import gplx.xowa.files.*;
public class Gallery_itm_parser {
private Xowe_wiki wiki; private Btrie_slim_mgr trie = Btrie_slim_mgr.ci_utf_8_();
private Gallery_itm cur_itm;
private byte[] src; private int end_pos;
private int cur_pos; private byte cur_byte;
private byte cur_fld;
private int itm_bgn;
private Bry_bfr caption_bfr = Bry_bfr.reset_(255); private int caption_bgn;
private Xop_ctx ctx;
public Gallery_itm_parser Init_by_wiki(Xowe_wiki wiki) {
this.wiki = wiki; Xol_lang lang = wiki.Lang();
this.ctx = wiki.Ctx();
trie.Clear();
Byte_obj_ref tmp_bref = Byte_obj_ref.zero_();
Init_keyword(tmp_bref, lang, Xol_kwd_grp_.Id_img_alt, Fld_alt); // NOTE: MW uses "gallery-@gplx.Internal protected-alt" which just maps to "img-alt"
Init_keyword(tmp_bref, lang, Xol_kwd_grp_.Id_img_link, Fld_link); // NOTE: MW uses "gallery-@gplx.Internal protected-link" which just maps to "img-link"
Init_keyword(tmp_bref, lang, Xol_kwd_grp_.Id_img_page, Fld_page);
return this;
}
public boolean Parse_in_progress() {return parse_in_progress;} public void Parse_in_progress_(boolean v) {parse_in_progress = v;} private boolean parse_in_progress;
public void Parse_all(List_adp rv, Gallery_mgr_base mgr, Gallery_xnde xnde, byte[] src, int content_bgn, int content_end) {
synchronized (trie) {parse_in_progress = true;}
this.src = src;
this.cur_pos = content_bgn; this.end_pos = content_end;
cur_itm = new Gallery_itm();
while (cur_pos < end_pos) {
cur_itm.Reset();
caption_bfr.Clear();
byte cur_mode = Parse_itm();
if (cur_itm.Ttl() != null) {
if (caption_bfr.Len() > 0)
cur_itm.Caption_bry_(caption_bfr.Xto_bry_and_clear_and_trim());
Make_lnki_tkn(mgr, xnde, src);
rv.Add(cur_itm);
cur_itm = new Gallery_itm();
}
if (cur_mode == Mode_nl)
++cur_pos;
}
synchronized (trie) {parse_in_progress = false;}
}
private void Make_lnki_tkn(Gallery_mgr_base mgr, Gallery_xnde xnde, byte[] src) {
Xop_lnki_tkn lnki_tkn = ctx.Tkn_mkr().Lnki(cur_itm.Ttl_bgn(), cur_itm.Ttl_end()).Ttl_(cur_itm.Ttl());
if (cur_itm.Link_bgn() != -1)
lnki_tkn.Link_tkn_(new Arg_nde_tkn_mock("link", String_.new_u8(src, cur_itm.Link_bgn(), cur_itm.Link_end()))); // NOTE: hackish, but add the link as arg_nde, since gallery link is not parsed like a regular lnki
cur_itm.Lnki_tkn_(lnki_tkn);
if (cur_itm.Page_bgn() != -1) {
int page_val = Bry_.Xto_int_or(src, cur_itm.Page_bgn(), cur_itm.Page_end(), -1);
if (page_val == -1) Xoa_app_.Usr_dlg().Warn_many("", "", "page is not an int: wiki=~{0} ttl=~{1} page=~{2}", wiki.Domain_str(), ctx.Cur_page().Ttl().Page_db(), String_.new_u8(src, cur_itm.Page_bgn(), cur_itm.Page_end()));
lnki_tkn.Page_(page_val);
}
byte[] lnki_caption = cur_itm.Caption_bry();
if (Bry_.Len_gt_0(lnki_caption)) {
Xop_root_tkn caption_tkn = wiki.Parser().Parse_text_to_wdom_old_ctx(ctx, lnki_caption, true);
cur_itm.Caption_tkn_(caption_tkn);
}
Xopg_redlink_logger file_wkr = ctx.Lnki().File_wkr(); // NOTE: do not set file_wkr ref early (as member var); parse_all sets late
ctx.Cur_page().Lnki_list().Add(lnki_tkn);
mgr.Get_thumb_size(lnki_tkn, cur_itm.Ext()); // NOTE: set thumb size, so that lnki.temp parse picks it up
if (file_wkr != null) file_wkr.Wkr_exec(ctx, src, lnki_tkn, gplx.xowa.bldrs.cmds.files.Xob_lnki_src_tid.Tid_gallery);
lnki_tkn.W_(-1).H_(-1); // NOTE: reset lnki back to defaults, else itm will show as large missing caption
}
private byte Parse_itm() {
int fld_count = 0;
itm_bgn = cur_pos;
while (cur_pos < end_pos) {
byte mode = Fld_bgn(fld_count);
if (mode == Mode_nl || mode == Mode_eos) return mode;
mode = Skip_to_fld_end();
Fld_end();
if (mode != Mode_pipe) return mode;
++cur_pos; // position after pipe
++fld_count;
}
return Mode_eos;
}
private byte Fld_bgn(int fld_count) {
cur_fld = Fld_null;
int bgn_pos = cur_pos;
byte mode = Skip_ws();
switch (mode) {
case Mode_nl:
case Mode_eos:
return mode;
}
Object o = trie.Match_bgn_w_byte(cur_byte, src, cur_pos, end_pos);
if (o != null) { // either "alt" or "link"
int old_pos = cur_pos;
cur_pos = trie.Match_pos();
Skip_ws();
if (cur_byte == Byte_ascii.Eq) { // "="
++cur_pos; // position after eq
Skip_ws();
cur_fld = ((Byte_obj_val)o).Val();
switch (cur_fld) {
case Fld_alt: cur_itm.Alt_bgn_(cur_pos); return Mode_text;
case Fld_link: cur_itm.Link_bgn_(cur_pos); return Mode_text;
case Fld_page:
if (cur_itm.Ext() != null && cur_itm.Ext().Id_supports_page()) { // NOTE: ext can be null with long multi-line captions; EX:<ref\n|page=1 />; DATE:2014-03-21
cur_itm.Page_bgn_(cur_pos);
return Mode_text;
}
else { // not a pdf / djvu; treat "page=" as caption
cur_fld = Fld_caption;
cur_pos = old_pos;
break; // NOTE: do not return Mode_text, so it reaches caption code below
}
}
}
else
cur_pos = old_pos;
}
if (fld_count == 0) {
cur_fld = Fld_ttl;
cur_itm.Ttl_bgn_(cur_pos);
}
else {
cur_fld = Fld_caption;
caption_bgn = caption_bfr.Len() == 0 ? cur_pos : bgn_pos; // if 1st caption, trim bgn; otherwise, enclose rest; EX: "File:A.png| a| b" -> "a| b"
}
return Mode_text;
}
private byte Skip_to_fld_end() {
while (cur_pos < end_pos) {
cur_byte = src[cur_pos];
switch (cur_byte) {
case Byte_ascii.Pipe: return Mode_pipe;
case Byte_ascii.Nl: return Mode_nl;
case Byte_ascii.Cr:
case Byte_ascii.Space:
case Byte_ascii.Tab:
++cur_pos;
continue;
default:
++cur_pos;
continue;
}
}
return Mode_eos;
}
private void Fld_end() {
int fld_end = cur_pos;
if (cur_fld != Fld_caption) {
int non_ws_pos = Bry_finder.Find_bwd_non_ws_or_not_found(src, cur_pos - 1, itm_bgn) + 1; // SEE:non_ws_pos
if (non_ws_pos != Bry_.NotFound + 1)
fld_end = non_ws_pos;
}
switch (cur_fld) {
case Fld_ttl:
cur_itm.Ttl_end_(fld_end);
byte[] ttl_bry = Bry_.Mid(src, cur_itm.Ttl_bgn(), fld_end);
ttl_bry = Xoa_app_.Utl__encoder_mgr().Http_url_ttl().Decode(ttl_bry); // NOTE: must decode url-encoded entries; EX: "A%28b%29.png" -> "A(b).png"; DATE:2014-01-01
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ttl_bry);
if ( ttl == null // invalid ttl; EX: "<invalid>"
|| ttl.Anch_bgn() == 1 // anchor-only ttl; EX: "#invalid"; DATE:2014-03-18
)
cur_itm.Reset();
else {
if (!ttl.Ns().Id_file_or_media()) // ttl does not have "File:"; MW allows non-ns names; EX: "A.png" instead of "File:A.png"; DATE:2013-11-18
ttl = Xoa_ttl.parse_(wiki, Xow_ns_.Id_file, ttl_bry);
cur_itm.Ttl_(ttl);
cur_itm.Ext_(Xof_ext_.new_by_ttl_(ttl_bry));
}
break;
case Fld_caption:
if (caption_bfr.Len() != 0) caption_bfr.Add_byte_pipe(); // prepend | to all other captions; EX: File:A.png|a|b -> "a|b" (pipe not added to 1st, but added to 2nd)
caption_bfr.Add_mid(src, caption_bgn, fld_end);
break;
case Fld_alt:
if (fld_end < cur_itm.Alt_bgn())
cur_itm.Alt_bgn_(-1);
else
cur_itm.Alt_end_(fld_end);
break;
case Fld_link:
if (fld_end < cur_itm.Link_bgn())
cur_itm.Link_bgn_(-1);
else
cur_itm.Link_end_(fld_end);
break;
case Fld_page:
if (fld_end < cur_itm.Page_bgn())
cur_itm.Page_bgn_(-1);
else
cur_itm.Page_end_(fld_end);
break;
default: throw Exc_.new_unhandled(fld_end);
}
}
private byte Skip_ws() {
while (cur_pos < end_pos) {
cur_byte = src[cur_pos];
switch (cur_byte) {
case Byte_ascii.Cr:
case Byte_ascii.Space:
case Byte_ascii.Tab: ++cur_pos; continue; // ignore
case Byte_ascii.Pipe: return Mode_pipe;
case Byte_ascii.Nl: return Mode_nl;
default: return Mode_text;
}
}
return Mode_eos;
}
private static final byte Fld_null = 0, Fld_ttl = 1, Fld_caption = 2, Fld_alt = 3, Fld_link = 4, Fld_page = 5;
private static final byte Mode_eos = 1, Mode_nl = 2, Mode_pipe = 3, Mode_text = 4;
private void Init_keyword(Byte_obj_ref tmp_bref, Xol_lang lang, int kwd_id, byte trie_key) {
Xol_kwd_grp grp = lang.Kwd_mgr().Get_at(kwd_id);
if (grp == null) {Gfo_usr_dlg_.I.Warn_many("", "", "could not find gallery keyword: ~{0}", String_.new_u8(Xol_kwd_grp_.Bry_by_id(kwd_id))); return;}
Xol_kwd_itm[] itms = grp.Itms();
int len = itms.length;
Byte_obj_val trie_ref = Byte_obj_val.new_(trie_key);
for (int i = 0; i < len; i++) {
Xol_kwd_itm itm = itms[i];
byte[] itm_bry = Xol_kwd_parse_data.Strip(caption_bfr, itm.Val(), tmp_bref); // strip off =$1 for "alt=$1"
trie.Add_obj(itm_bry, trie_ref);
}
}
}
/*
SEE:non_ws_pos;
int non_ws_pos = Bry_finder.Find_bwd_non_ws(src, cur_pos - 1, itm_bgn) + 1;
. -1 to start before cur_pos (which is usually pipe);
. +1 to place after non_ws_char
EX: text="b c |"; cur_pos = 4;
. -1 to start at cur_pos = 3
. src[3] = ' '; ws; continue
. src[2] = c; return 2;
. + 1 to place after "c" -> 3
. fld_end = 3
*/

View File

@@ -0,0 +1,112 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Gallery_itm_parser_tst {
@Before public void init() {fxt.Init();} private Gallery_itm_parser_fxt fxt = new Gallery_itm_parser_fxt();
@Test public void All() {fxt.Test_parse("File:A.png|a|alt=b|link=c" , fxt.Expd("File:A.png", "a" , "b" , "c"));}
@Test public void Ttl_only() {fxt.Test_parse("File:A.png" , fxt.Expd("File:A.png", null, null, null));}
@Test public void Ttl_url_encoded() {fxt.Test_parse("File:A%28b%29.png" , fxt.Expd("File:A(b).png"));} // PURPOSE: handle url-encoded sequences; DATE:2014-01-01
@Test public void Caption_only() {fxt.Test_parse("File:A.png|a" , fxt.Expd("File:A.png", "a" , null, null));}
@Test public void Caption_many() {fxt.Test_parse("File:A.png|a|b" , fxt.Expd("File:A.png", "a|b"));} // NOTE: pipe becomes part of caption (i.e.: doesn't separate into caption / alt)
@Test public void Alt_only() {fxt.Test_parse("File:A.png|alt=a" , fxt.Expd("File:A.png", null, "a" , null));}
@Test public void Link_only() {fxt.Test_parse("File:A.png|link=a" , fxt.Expd("File:A.png", null, null, "a"));}
@Test public void Caption_alt() {fxt.Test_parse("File:A.png|a|alt=b" , fxt.Expd("File:A.png", "a" , "b"));}
@Test public void Alt_caption() {fxt.Test_parse("File:A.png|alt=a|b" , fxt.Expd("File:A.png", "b" , "a"));}
@Test public void Alt_blank() {fxt.Test_parse("File:A.png|alt=|b" , fxt.Expd("File:A.png", "b" , ""));}
@Test public void Alt_invalid() {fxt.Test_parse("File:A.png|alta=b" , fxt.Expd("File:A.png", "alta=b"));} // NOTE: invalid alt becomes caption
@Test public void Ws() {fxt.Test_parse("File:A.png| alt = b | c" , fxt.Expd("File:A.png", "c" , "b"));}
@Test public void Ws_caption_many() {fxt.Test_parse("File:A.png| a | b | c " , fxt.Expd("File:A.png", "a | b | c"));}
@Test public void Page_pdf() {fxt.Test_parse("File:A.pdf|page=1 " , fxt.Expd("File:A.pdf", null, null, null, 1));} // pdf parses page=1
@Test public void Page_png() {fxt.Test_parse("File:A.png|page=1 " , fxt.Expd("File:A.png", "page=1", null, null));} // non-pdf treats page=1 as caption
@Test public void Page_invalid() {fxt.Test_parse("|page=1");} // check that null title doesn't fail; DATE:2014-03-21
@Test public void Skip_blank() {fxt.Test_parse("");}
@Test public void Skip_empty() {fxt.Test_parse("|File:A.png");}
@Test public void Skip_ws() {fxt.Test_parse(" |File:A.png");}
@Test public void Skip_anchor() {fxt.Test_parse("#a");} // PURPOSE: anchor-like ttl should not render; ar.d:جَبَّارَة; DATE:2014-03-18
@Test public void Many() {
fxt.Test_parse("File:A.png\nFile:B.png" , fxt.Expd("File:A.png"), fxt.Expd("File:B.png"));
}
@Test public void Many_nl() {
fxt.Test_parse("File:A.png\n\n\nFile:B.png" , fxt.Expd("File:A.png"), fxt.Expd("File:B.png"));
}
@Test public void Many_nl_w_tab() {
fxt.Test_parse("File:A.png\n \t \nFile:B.png" , fxt.Expd("File:A.png"), fxt.Expd("File:B.png"));
}
@Test public void Many_invalid() {
fxt.Test_parse("File:A.png\n<invalid>\nFile:B.png" , fxt.Expd("File:A.png"), fxt.Expd("File:B.png"));
}
@Test public void Caption_complicated() {
fxt.Test_parse("File:A.png|alt=a|b[[c|d]]e ", fxt.Expd("File:A.png", "b[[c|d]]e", "a"));
}
@Test public void Alt_magic_word_has_arg() { // PURPOSE: img_alt magic_word is of form "alt=$1"; make sure =$1 is stripped for purpose of parser; DATE:2013-09-12
fxt.Init_kwd_set(Xol_kwd_grp_.Id_img_alt, "alt=$1");
fxt.Test_parse("File:A.png|alt=a|b", fxt.Expd("File:A.png", "b", "a"));
}
@Test public void Link_null() { // PURPOSE: null link causes page to fail; EX: ru.w:Гянджа; <gallery>Datei:A.png|link= |</gallery>; DATE:2014-04-11
fxt.Test_parse("File:A.png|link = |b", fxt.Expd("File:A.png", "b", null, null));
}
@Test public void Caption_empty() { // PURPOSE: check that empty ws doesn't break caption (based on Link_null); DATE:2014-04-11
fxt.Test_parse("File:A.png| | | ", fxt.Expd("File:A.png", null, null, null));
}
}
class Gallery_itm_parser_fxt {
private Xoae_app app; private Xowe_wiki wiki;
private Gallery_itm_parser parser;
public Gallery_itm_parser_fxt Init() {
this.app = Xoa_app_fxt.app_();
this.wiki = Xoa_app_fxt.wiki_tst_(app);
parser = new Gallery_itm_parser();
parser.Init_by_wiki(wiki);
return this;
}
public String[] Expd(String ttl) {return new String[] {ttl, null, null, null, null};}
public String[] Expd(String ttl, String caption) {return new String[] {ttl, caption, null, null, null};}
public String[] Expd(String ttl, String caption, String alt) {return new String[] {ttl, caption, alt, null, null};}
public String[] Expd(String ttl, String caption, String alt, String link) {return new String[] {ttl, caption, alt, link, null};}
public String[] Expd(String ttl, String caption, String alt, String link, int page) {return new String[] {ttl, caption, alt, link, Int_.Xto_str(page)};}
public void Init_kwd_set(int kwd_id, String kwd_val) {
wiki.Lang().Kwd_mgr().Get_or_new(kwd_id).Itms()[0].Val_(Bry_.new_a7(kwd_val));
parser.Init_by_wiki(wiki);
}
public void Test_parse(String raw, String[]... expd) {
List_adp actl = List_adp_.new_();
byte[] src = Bry_.new_a7(raw);
parser.Parse_all(actl, Gallery_mgr_base_.New_by_mode(Gallery_mgr_base_.Traditional_tid), new Gallery_xnde(), src, 0, src.length);
Tfds.Eq_ary(String_.Ary_flatten(expd), String_.Ary_flatten(Xto_str_ary(src, actl)));
}
private String[][] Xto_str_ary(byte[] src, List_adp list) {
int len = list.Count();
String[][] rv = new String[len][];
for (int i = 0; i < len; i++) {
Gallery_itm itm = (Gallery_itm)list.Get_at(i);
String[] ary = new String[5];
rv[i] = ary;
ary[0] = String_.new_u8(itm.Ttl().Full_txt());
ary[2] = Xto_str_ary_itm(src, itm.Alt_bgn(), itm.Alt_end());
ary[3] = Xto_str_ary_itm(src, itm.Link_bgn(), itm.Link_end());
ary[4] = Xto_str_ary_itm(src, itm.Page_bgn(), itm.Page_end());
byte[] caption = itm.Caption_bry();
ary[1] = caption == null ? null : String_.new_u8(caption);
}
return rv;
}
private String Xto_str_ary_itm(byte[] src, int bgn, int end) {
return bgn == Bry_.NotFound && end == Bry_.NotFound ? null : String_.new_u8(src, bgn, end);
}
}

View File

@@ -0,0 +1,226 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.html.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*; import gplx.xowa.files.*; import gplx.xowa.html.hdumps.abrvs.*; import gplx.xowa.html.hdumps.core.*;
public abstract class Gallery_mgr_base {
private Gallery_box_w_fmtr_arg__basic box_w_fmtr__basic = new Gallery_box_w_fmtr_arg__basic(); private Gallery_box_w_fmtr_arg__hdump box_w_fmtr__hdump = new Gallery_box_w_fmtr_arg__hdump();
private Gallery_img_pad_fmtr_arg__basic img_pad_fmtr__basic = new Gallery_img_pad_fmtr_arg__basic(); private Gallery_img_pad_fmtr_arg__hdump img_pad_fmtr__hdump = new Gallery_img_pad_fmtr_arg__hdump();
public abstract byte Tid();
public abstract byte[] Tid_bry();
@gplx.Virtual public boolean Tid_is_packed() {return false;}
public int Itm_default_w() {return itm_default_w;} protected int itm_default_w;
public int Itm_default_h() {return itm_default_h;} protected int itm_default_h;
public int Itms_per_row() {return itms_per_row;} @gplx.Virtual public void Itms_per_row_(int v) {this.itms_per_row = v;} protected int itms_per_row;
@gplx.Virtual public int Get_thumb_padding() {return 30;} // REF.MW: getThumbPadding; How much padding such the thumb have between image and inner div that that contains the border. This is both for verical and horizontal padding. (However, it is cut in half in the vertical direction).
@gplx.Virtual public int Get_gb_padding() {return 5;} // REF.MW: getGBPadding; GB stands for gallerybox (as in the <li class="gallerybox"> element)
@gplx.Virtual public int Get_gb_borders() {return 8;} // REF.MW: getGBBorders; Get how much extra space the borders around the image takes up. For this mode, it is 2px borders on each side + 2px implied padding on each side from the stylesheet, giving us 2*2+2*2 = 8.
@gplx.Virtual public int Get_all_padding() {return this.Get_thumb_padding() + this.Get_gb_padding() + this.Get_gb_borders();} // REF.MW: getAllPadding; How many pixels of whitespace surround the thumbnail.
@gplx.Virtual public int Get_vpad(int itm_h, int thm_h) { // REF.MW: getVPad; Get vertical padding for a thumbnail; Generally this is the total height minus how high the thumb is.
return (this.Get_thumb_padding() + itm_h - thm_h) / 2;
}
@gplx.Virtual public int Get_thumb_div_width(int thm_w) { // REF.MW: getThumbDivWidth; Get the width of the inner div that contains the thumbnail in question. This is the div with the class of "thumb".
return itm_default_w + this.Get_thumb_padding();
}
@gplx.Virtual public int Get_gb_width(int thm_w, int thm_h) {// REF.MW: getGBWidth; Width of gallerybox <li>. Generally is the width of the image, plus padding on image plus padding on gallerybox.s
return itm_default_w + this.Get_thumb_padding() + this.Get_gb_padding();
}
@gplx.Virtual public void Get_modules(Xoae_page page) {} // REF.MW: getModules; Get a list of modules to include in the page.
@gplx.Virtual public void Init(int itms_per_row, int itm_default_w, int itm_default_h) {
this.itms_per_row = itms_per_row;
this.itm_default_w = itm_default_w;
this.itm_default_h = itm_default_h;
}
@gplx.Virtual public void Wrap_gallery_text(Bry_bfr bfr, byte[] gallery_text, int thm_w, int thm_h) {
bfr .Add(Wrap_gallery_text_bgn)
.Add(gallery_text)
.Add(Wrap_gallery_text_end)
;
}
public void Write_html(Bry_bfr bfr, Xowe_wiki wiki, Xoae_page page, Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Gallery_xnde xnde) {
boolean hctx_is_hdump = hctx.Mode_is_hdump();
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512();
byte[] box_style = xnde.Atr_style();
int gallery_uid = page.Html_data().Xtn_gallery_next_id();
if (itms_per_row > 0) {
int max_width = itms_per_row * (itm_default_w + this.Get_all_padding());
box_style = Fmt_and_add(tmp_bfr, box_style_max_width_fmtr, box_style, max_width);
page.Hdump_data().Imgs_add(new Xohd_data_itm__gallery_mgr(gallery_uid, max_width));
}
byte[] box_cls = Fmt_and_add(tmp_bfr, box_cls_fmtr, xnde.Atr_cls(), this.Tid_bry());
byte[] gallery_ul_id = tmp_bfr.Add(box_id_prefix_bry).Add_int_variable(gallery_uid).Xto_bry_and_clear();
Box_hdr_write(bfr, wiki.Appe().Html_mgr().Whitelist_mgr(), src, gallery_ul_id, box_cls, box_style, xnde.Atrs_other(), hctx_is_hdump, gallery_uid);
byte[] box_caption = xnde.Atr_caption();
if (Bry_.Len_gt_0(box_caption)) box_caption_fmtr.Bld_bfr_many(bfr, box_caption);
Xoae_app app = wiki.Appe(); Xoh_html_wtr html_wtr = wiki.Html_mgr().Html_wtr();
int itm_len = xnde.Itms_len();
for (int i = 0; i < itm_len; i++) {
Write_html_itm(bfr, tmp_bfr, app, wiki, page, ctx, html_wtr, hctx, src, xnde, gallery_ul_id, i, null, hctx_is_hdump);
}
bfr.Add(box_html_end_bry);
tmp_bfr.Mkr_rls();
} private static final byte[] box_id_prefix_bry = Bry_.new_a7("xowa_gallery_ul_"), itm_id_prefix_bry = Bry_.new_a7("xowa_gallery_li_");
public static byte File_found_mode = Bool_.__byte;
public void Write_html_itm(Bry_bfr bfr, Bry_bfr tmp_bfr, Xoae_app app, Xowe_wiki wiki, Xoae_page page, Xop_ctx ctx, Xoh_html_wtr html_wtr, Xoh_wtr_ctx hctx, byte[] src, Gallery_xnde xnde, byte[] gallery_ul_id, int i, Xof_file_itm xfer_itm, boolean hctx_is_hdump) {
Gallery_itm itm = (Gallery_itm)xnde.Itms_get_at(i);
Xoa_ttl ttl = itm.Ttl();
byte[] itm_caption = itm.Caption_bry(); if (itm_caption == null) itm_caption = Bry_.Empty;
Xop_lnki_tkn lnki = itm.Lnki_tkn();
int lnki_w_orig = lnki.W(), lnki_h_orig = lnki.H(); // store orig lnki_w / lnki_w
this.Get_thumb_size(lnki, itm.Ext()); // packed=expand by 1.5;
if (xfer_itm == null) { // will be null on 1st pass
xfer_itm = html_wtr.Lnki_wtr().File_wtr().Lnki_eval(Xof_exec_tid.Tid_wiki_page, ctx, page, lnki);
xfer_itm.Html_gallery_mgr_h_(xnde.Itm_h_or_default());
xfer_itm.Html_elem_tid_(Xof_html_elem.Tid_gallery_v2);
}
int img_uid = xfer_itm.Html_uid();
byte[] gallery_li_id = tmp_bfr.Add(itm_id_prefix_bry).Add_int_variable(img_uid).Xto_bry_and_clear();
byte[] itm_html = Bry_.Empty;
int html_w_expand = xfer_itm.Html_w();
int html_h_expand = xfer_itm.Html_h();
boolean file_found = xfer_itm.File_exists();
if (File_found_mode != Bool_.__byte)
file_found = File_found_mode == Bool_.Y_byte;
int vpad = -1, img_div_w = -1;
if ( !hctx_is_hdump // always write img if hdump; DATE:2015-04-27
&& ( !ttl.Ns().Id_file()
|| !file_found
)
) { // itm is not a file, or is not found; write text
itm_html = itm_missing_fmtr.Bld_bry_many(tmp_bfr, this.Get_thumb_padding() + itm_default_h, ttl.Page_txt());
itm.Html_prepare(wiki, ctx, src, xnde, xfer_itm, gallery_li_id, i);
xfer_itm.Html_img_wkr_(itm);
lnki.W_(lnki_w_orig).H_(lnki_h_orig);
html_w_expand = lnki_w_orig; html_h_expand = lnki_h_orig; // reset lnki_w_orig / lnki_h_orig else large captions
}
else {
byte[] alt = itm.Alt_bgn() == Bry_.NotFound && Bry_.Len_eq_0(itm_caption) // if ( $alt == '' && $text == '' ) $imageParameters['alt'] = $nt->getText();
? itm.Ttl().Page_txt()
: Xoh_html_wtr_escaper.Escape(app.Parser_amp_mgr(), tmp_bfr, Bry_.Mid(src, itm.Alt_bgn(), itm.Alt_end()))
;
Xoa_ttl href_ttl = itm.Link_bgn() == Bry_.NotFound
? ttl
: Xoa_ttl.parse_(wiki, Bry_.Mid(src, itm.Link_bgn(), itm.Link_end()))
;
if (href_ttl == null) href_ttl = ttl; // occurs when link is invalid; EX: A.png|link=<invalid>
this.Adjust_image_parameters(xfer_itm); // trad=noop; packed=reduce by 1.5
int html_w_normal = xfer_itm.Html_w();
int html_h_normal = xfer_itm.Html_h();
xfer_itm.Init_at_gallery_bgn(html_w_normal, html_h_normal, html_w_expand);// NOTE: file_w should be set to expanded width so js can resize if gallery
img_div_w = this.Get_thumb_div_width(html_w_expand);
itm_div0_fmtr.Bld_bfr_many(tmp_bfr, img_div_w);
Gallery_img_pad_fmtr_arg vpad_fmtr = hctx_is_hdump ? (Gallery_img_pad_fmtr_arg)img_pad_fmtr__hdump : (Gallery_img_pad_fmtr_arg)img_pad_fmtr__basic;
vpad = this.Get_vpad(itm_default_h, html_h_expand);
itm_div1_fmtr.Bld_bfr_many(tmp_bfr, vpad_fmtr.Init(img_uid, vpad)); // <div style="margin:~{vpad}px auto;">
wiki.Html_mgr().Html_wtr().Lnki_wtr().Write_file(tmp_bfr, ctx, hctx, src, lnki, xfer_itm, alt);
tmp_bfr.Add(itm_divs_end_bry);
itm_html = tmp_bfr.Xto_bry_and_clear();
}
byte[] show_filenames_link = Bry_.Empty;
if (xnde.Show_filename()) {
wiki.Html_mgr().Html_wtr().Lnki_wtr().Write_plain_by_bry
( tmp_bfr, src, lnki
, Bry_.Limit(ttl.Page_txt(), 25) // 25 is defined by captionLength in DefaultSettings.php
); // MW:passes know,noclasses which isn't relevant to XO
}
int itm_div_width = this.Get_gb_width(html_w_expand, html_h_expand);
Gallery_box_w_fmtr_arg box_w_fmtr_arg = hctx_is_hdump ? (Gallery_box_w_fmtr_arg)box_w_fmtr__hdump : (Gallery_box_w_fmtr_arg)box_w_fmtr__basic;
itm_li_bgn_fmtr.Bld_bfr_many(bfr, gallery_li_id, box_w_fmtr_arg.Init(img_uid, itm_div_width));
bfr.Add(itm_html);
wiki.Parser().Parse_text_to_html(tmp_bfr, page, true, itm_caption);
itm_caption = tmp_bfr.Xto_bry_and_clear();
itm_caption = tmp_bfr.Add(show_filenames_link).Add(itm_caption).Xto_bry_and_clear();
Wrap_gallery_text(bfr, itm_caption, html_w_expand, html_h_expand);
bfr.Add(itm_li_end_bry);
if (hctx_is_hdump)
page.Hdump_data().Imgs_add_img(new Xohd_data_itm__gallery_itm().Data_init_gallery(itm_div_width, img_div_w, vpad), xfer_itm, Xohd_data_itm__gallery_itm.Tid_gallery);
}
private static final byte[]
Wrap_gallery_text_bgn = Bry_.new_a7("\n <div class=\"gallerytext\">") // NOTE: The newline after <div class="gallerytext"> is needed to accommodate htmltidy
, Wrap_gallery_text_end = Bry_.new_a7("\n </div>") // NOTE: prepend "\n"; will cause extra \n when caption exists, but needed when caption doesn't exists; EX: "<div class='caption'> </div>"; \n puts
;
@gplx.Virtual public void Get_thumb_size(Xop_lnki_tkn lnki, Xof_ext ext) { // REF.MW: getThumbParams; Get the transform parameters for a thumbnail.
lnki.W_(itm_default_w);
lnki.H_(itm_default_h);
}
@gplx.Virtual public void Adjust_image_parameters(Xof_file_itm xfer_itm) {} // REF.MW: Adjust the image parameters for a thumbnail. Used by a subclass to insert extra high resolution images.
public static final Bry_fmtr
box_style_max_width_fmtr = Bry_fmtr.new_( "max-width:~{max_width}px;_width:~{max_width}px;", "max_width") // id=xowa_gallery_ul_1
, box_cls_fmtr = Bry_fmtr.new_( "gallery mw-gallery-~{mode}", "mode")
, box_caption_fmtr = Bry_fmtr.new_( "\n <li class='gallerycaption'>~{caption}</li>", "caption")
, itm_li_bgn_fmtr = Bry_fmtr.new_( "\n <li id=\"~{id}\" class=\"gallerybox\" ~{itm_box_w}>" // id=xowa_gallery_li_1
+ "\n <div ~{itm_box_w}>", "id", "itm_box_w")
, itm_div0_fmtr = Bry_fmtr.new_( "\n <div class=\"thumb\" style=\"width: ~{width}px;\">", "width")
, itm_missing_fmtr = Bry_fmtr.new_( "\n <div class=\"thumb\" style=\"height: ~{height}px;\">~{ttl_text}</div>", "height", "ttl_text")
, itm_div1_fmtr = Bry_fmtr.new_( "\n <div ~{vpad}>\n ", "vpad")
, hdump_box_w_fmtr = Bry_fmtr.new_( "width:~{width}px;", "width")
, hdump_img_pad_fmtr = Bry_fmtr.new_( "margin:~{width}px auto;", "width")
;
private static final byte[]
itm_li_end_bry = Bry_.new_a7 ( "\n </div>"
+ "\n </li>")
, box_html_end_bry = Bry_.new_a7 ( "\n</ul>")
, itm_divs_end_bry = Bry_.new_a7 ( "\n </div>\n </div>")
;
private static byte[] Fmt_and_add(Bry_bfr tmp_bfr, Bry_fmtr fmtr, byte[] trailer, Object... fmtr_args) {
fmtr.Bld_bfr_many(tmp_bfr, fmtr_args);
if (Bry_.Len_gt_0(trailer)) {
tmp_bfr.Add_byte_space();
tmp_bfr.Add(trailer);
}
return tmp_bfr.Xto_bry_and_clear();
}
private static void Box_hdr_write(Bry_bfr bfr, Xop_xatr_whitelist_mgr whitelist_mgr, byte[] src, byte[] gallery_ul_uid, byte[] cls, byte[] style, List_adp xatr_list, boolean hctx_is_hdump, int uid) {
bfr.Add_byte(Byte_ascii.Lt).Add(Html_tag_.Ul_name_bry);
Html_wtr.Write_atr_bry(bfr, Html_atr_.Id_bry, gallery_ul_uid);
Html_wtr.Write_atr_bry(bfr, Html_atr_.Cls_bry, cls);
if (hctx_is_hdump) {
bfr.Add_byte_space();
bfr.Add(Xohd_abrv_.Key_gallery_box_max);
bfr.Add_int_variable(uid);
bfr.Add_byte_apos();
}
else
Html_wtr.Write_atr_bry(bfr, Html_atr_.Style_bry, style);
if (xatr_list != null) {
int len = xatr_list.Count();
for (int i = 0; i < len; i++) {
Xop_xatr_itm xatr = (Xop_xatr_itm)xatr_list.Get_at(i);
if (!whitelist_mgr.Chk(Xop_xnde_tag_.Tid_ul, src, xatr)) continue;
byte[] key = xatr.Key_bry();
byte[] val = xatr.Val_as_bry(src);
Html_wtr.Write_atr_bry(bfr, key, val);
}
}
bfr.Add_byte(Byte_ascii.Gt);
}
}
class Gallery_mgr_traditional extends Gallery_mgr_base {
@Override public byte Tid() {return Gallery_mgr_base_.Traditional_tid;}
@Override public byte[] Tid_bry() {return Gallery_mgr_base_.Traditional_bry;}
}
class Gallery_mgr_nolines extends Gallery_mgr_base {
@Override public byte Tid() {return Gallery_mgr_base_.Nolines_tid;}
@Override public byte[] Tid_bry() {return Gallery_mgr_base_.Nolines_bry;}
@Override public int Get_thumb_padding() {return 0;}
@Override public int Get_gb_padding() {return 4;} // This accounts for extra space between <li> elements.
@Override public int Get_vpad(int itm_h, int thm_h) {return 0;}
}

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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.primitives.*;
class Gallery_mgr_base_ {
public static byte Get_or_traditional(byte[] bry) {
Byte_obj_val rv = (Byte_obj_val)Hash.Get_by(bry);
return rv == null ? Traditional_tid : rv.Val();
}
public static Gallery_mgr_base New_by_mode(byte mode) {
switch (mode) {
default:
case Traditional_tid: return new Gallery_mgr_traditional();
case Nolines_tid: return new Gallery_mgr_nolines();
case Packed_tid: return new Gallery_mgr_packed_base();
case Packed_hover_tid: return new Gallery_mgr_packed_hover();
case Packed_overlay_tid: return new Gallery_mgr_packed_overlay();
}
}
public static boolean Mode_is_packed(byte v) {
switch (v) {
case Packed_tid:
case Packed_hover_tid:
case Packed_overlay_tid: return true;
default: return false;
}
}
public static final byte
Traditional_tid = 0
, Nolines_tid = 1
, Packed_tid = 2
, Packed_hover_tid = 3
, Packed_overlay_tid = 4
;
public static final byte[]
Traditional_bry = Bry_.new_a7("traditional")
, Nolines_bry = Bry_.new_a7("nolines")
, Packed_bry = Bry_.new_a7("packed")
, Packed_hover_bry = Bry_.new_a7("packed-hover")
, Packed_overlay_bry = Bry_.new_a7("packed-overlay")
;
private static final Hash_adp_bry Hash = Hash_adp_bry.ci_ascii_()
.Add_bry_byte(Traditional_bry , Traditional_tid)
.Add_bry_byte(Nolines_bry , Nolines_tid)
.Add_bry_byte(Packed_bry , Packed_tid)
.Add_bry_byte(Packed_hover_bry , Packed_hover_tid)
.Add_bry_byte(Packed_overlay_bry , Packed_overlay_tid)
;
}

View File

@@ -0,0 +1,170 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
import gplx.xowa.html.*; import gplx.xowa.files.fsdb.*;
public class Gallery_mgr_base_basic_tst {
private Gallery_mgr_base_fxt fxt = new Gallery_mgr_base_fxt();
@Before public void init() {fxt.Reset();}
@Test public void Basic() {
fxt.Test_html_str(String_.Concat_lines_nl_skip_last
( "<gallery widths=200px heights=300px>"
, "A.png|''a1''"
, "B.png|''b1''"
, "</gallery>"
), String_.Concat_lines_nl_skip_last
( "<ul id=\"xowa_gallery_ul_0\" class=\"gallery mw-gallery-traditional\">"
, " <li id=\"xowa_gallery_li_0\" class=\"gallerybox\" style=\"width: 235px\">"
, " <div style=\"width: 235px\">"
, " <div class=\"thumb\" style=\"width: 230px;\">"
, " <div style=\"margin:15px auto;\">"
, " <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/200px.png\" width=\"200\" height=\"300\" /></a>"
, " </div>"
, " </div>"
, " <div class=\"gallerytext\"><p><i>a1</i>"
, "</p>"
, ""
, " </div>"
, " </div>"
, " </li>"
, " <li id=\"xowa_gallery_li_1\" class=\"gallerybox\" style=\"width: 235px\">"
, " <div style=\"width: 235px\">"
, " <div class=\"thumb\" style=\"width: 230px;\">"
, " <div style=\"margin:15px auto;\">"
, " <a href=\"/wiki/File:B.png\" class=\"image\" xowa_title=\"B.png\"><img id=\"xowa_file_img_1\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/5/7/B.png/200px.png\" width=\"200\" height=\"300\" /></a>"
, " </div>"
, " </div>"
, " <div class=\"gallerytext\"><p><i>b1</i>"
, "</p>"
, ""
, " </div>"
, " </div>"
, " </li>"
, "</ul>"
));
fxt.Test_html_modules_js("");
}
@Test public void Tmpl() {
fxt.Fxt().Init_defn_add("test_tmpl", "b");
fxt.Test_html_frag("<gallery>File:A.png|a{{test_tmpl}}c</gallery>", "<div class=\"gallerytext\"><p>abc\n</p>");
}
@Test public void Itm_defaults_to_120() {
fxt.Test_html_frag("<gallery>File:A.png|a</gallery>", "<img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/120px.png\" width=\"120\" height=\"120\" />");
}
@Test public void Height_fix() {
fxt.Fxt().Wiki().File_mgr().Cfg_set(Xof_fsdb_mgr_cfg.Grp_xowa, Xof_fsdb_mgr_cfg.Key_gallery_fix_defaults, "y");
fxt.Test_html_frag("<gallery heights=250>File:A.png|a<br/>c</gallery>", " width=\"120\" height=\"250\"");
fxt.Fxt().Wiki().File_mgr().Cfg_set(Xof_fsdb_mgr_cfg.Grp_xowa, Xof_fsdb_mgr_cfg.Key_gallery_fix_defaults, "n");
}
@Test public void Alt() {
fxt.Test_html_frag("<gallery>File:A.png|b|alt=c</gallery>"
, "<img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/120px.png\" width=\"120\" height=\"120\" />"
, "<div class=\"gallerytext\"><p>b\n</p>"
);
}
@Test public void Link() {
fxt.Test_html_frag("<gallery>File:A.png|b|link=c</gallery>", "<a href=\"/wiki/C\" class=\"image\"");
}
@Test public void Page() { // PURPOSE: page was not being set; PAGE:pt.s:Portal:Diccionario_geographico_do_Brazil; DATE:2015-04-16
fxt.Test_html_frag
( "<gallery>File:A.pdf|b|page=8</gallery>"
, "A.pdf/120px-8.jpg" // make sure page 8 shows up
);
}
@Test public void Alt_caption_multiple() {
fxt.Test_html_frag("<gallery>File:A.png|alt=b|c[[d|e]]f</gallery>", "<div class=\"gallerytext\"><p>c<a href=\"/wiki/D\">ef</a>\n</p>");
}
@Test public void Alt_escape_quote() {
fxt.Test_html_frag("<gallery>File:A.png|b|alt=c\"d'e</gallery>", "alt=\"c&quot;d'e\"");
}
@Test public void Caption_null() { // PURPOSE: null caption causes page to fail; EX: de.w:Lewis Caroll; <gallery>Datei:A.png</gallery>; DATE:2013-10-09
fxt.Test_html_frag("<gallery>File:A.png</gallery>", "<div class=\"gallerytext\">\n");
}
@Test public void Ttl_has_no_ns() { // PURPOSE: MW allows ttl to not have ns; DATE: 2013-11-18
fxt.Test_html_frag("<gallery>A.png|b</gallery>", "<img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/120px.png\" width=\"120\" height=\"120\" />"); // make sure image is generated
}
@Test public void Ref() { // PURPOSE: <ref> inside <gallery> was not showing up in <references>; DATE:2013-10-09
fxt.Test_html_frag("<gallery>File:A.png|<ref name='a'>b</ref></gallery><references/>"
, "<div class=\"gallerytext\"><p><sup id=\"cite_ref-a_0-0\" class=\"reference\"><a href=\"#cite_note-a-0\">[1]</a></sup>\n</p>"
, String_.Concat_lines_nl
( "</ul><ol class=\"references\">"
, "<li id=\"cite_note-a-0\"><span class=\"mw-cite-backlink\"><a href=\"#cite_ref-a_0-0\">^</a></span> <span class=\"reference-text\">b</span></li>"
, "</ol>"
)
);
}
@Test public void Packed() {
fxt.Test_html_frag("<gallery mode=packed heights=300px>File:A.png|a</gallery>", "<ul id=\"xowa_gallery_ul_0\" class=\"gallery mw-gallery-packed\">");
fxt.Test_html_modules_js(String_.Concat_lines_nl_skip_last
( ""
, " <script type='text/javascript'>"
, " var xowa_global_values = {"
, " 'gallery-packed-enabled' : true,"
, " }"
, " </script>"
));
}
@Test public void Missing() {
fxt.Init_files_missing_y_();
fxt.Test_html_frag("<gallery>File:A.png|b</gallery>", "<div class=\"thumb\" style=\"height: 150px;\">A.png</div>");
}
@Test public void Multiple() { // PURPOSE.bug: multiple galleries should not use same gallery super; DATE:2014-04-13
fxt.Test_html_frag("<gallery>File:A.png|a</gallery><gallery widths=180px>File:B.png|b</gallery>"
, "src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/120px.png\" width=\"120\" height=\"120\" />" // should not be 180px from gallery #2
);
}
@Test public void Link_is_empty() { // PURPOSE: "link=" causes null pointer exception; DATE:2014-06-15
fxt.Test_html_frag("<gallery>File:A.png|link=</gallery>", "href=\"/wiki/File:A.png\"");
}
@Test public void Dangling_autcloses() { // PURPOSE: dangling gallery should auto-close, not escape; PAGE:en.w:Wikipedia:Featured_pictures_thumbs_43 DATE:2014-08-23
fxt.Test_html_frag("<gallery>File:A.png|b", "<ul id=\"xowa_gallery_ul_0\"");
}
@Test public void Nested() { // PURPOSE: handle gallery nested inside ref; PAGE: es.w:Arquitectura_medieval DATE:2015-07-10
fxt.Test_html_frag(String_.Concat_lines_nl_skip_last
( "<gallery>"
, "File:A.jpg|A1"
, "File:B.jpg|B1 <ref>B2 <gallery>File:B11.jpg|B123./gallery></ref>" // NOTE: nested gallery
, "File:C.jpg|C1"
, "</gallery>"
), "C1" // make sure that image after nested gallery appears
);
}
// @Test public void Ttl_caption() { // TODO: category entries get rendered with name only (no ns)
// fxt.Test_html_frag
// ( "<gallery>Category:A</gallery>"
// , "<li class='gallerycaption'>B</li>"
// );
// }
}
class Gallery_mgr_base_fxt {
public void Reset() {
fxt.Wiki().Xtn_mgr().Init_by_wiki(fxt.Wiki());
Gallery_mgr_base.File_found_mode = Bool_.Y_byte;
}
public Xop_fxt Fxt() {return fxt;} private Xop_fxt fxt = new Xop_fxt();
public void Init_files_missing_y_() {
Gallery_mgr_base.File_found_mode = Bool_.N_byte;
}
public void Test_html_str(String raw, String expd) {fxt.Test_html_full_str(raw, expd);}
public void Test_html_frag(String raw, String... expd_frags) {fxt.Test_html_full_frag(raw, expd_frags);} // TODO: change to wiki_str; currently uids do not get reset if wiki
public void Test_html_frag_n(String raw, String... expd_frags) {fxt.Test_html_full_frag_n(raw, expd_frags);}
public void Test_html_modules_js(String expd) {
fxt.Page().Html_data().Module_mgr().Itm__globals().Enabled_n_();
fxt.Test_html_modules_js(expd);
}
}

View File

@@ -0,0 +1,66 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
import gplx.xowa.html.*;
public class Gallery_mgr_base_xnde_atrs_tst {
private Gallery_mgr_base_fxt fxt = new Gallery_mgr_base_fxt();
@Before public void init() {fxt.Reset();}
@Test public void Atr_misc() {// PURPOSE: add other atrs to end of ul
fxt.Test_html_frag
( "<gallery id=a>File:A.png</gallery>"
, "<ul id=\"xowa_gallery_ul_0\" class=\"gallery mw-gallery-traditional\" id=\"a\">"
);
}
@Test public void Atr_style() { // PURPOSE: combine style with itms_per_row
fxt.Test_html_frag
( "<gallery perrow=2 style='color:blue;'>File:A.png</gallery>"
, "<ul id=\"xowa_gallery_ul_0\" class=\"gallery mw-gallery-traditional\" style=\"max-width:326px;_width:326px; color:blue;\">"
);
}
@Test public void Atr_caption() { // PURPOSE: caption atr adds new element
fxt.Test_html_frag
( "<gallery caption=B>File:A.png</gallery>"
, "<li class='gallerycaption'>B</li>"
);
}
@Test public void Atr_caption_ignore() { // PURPOSE: blank caption should not create caption element; PAGE:fr.w:Chronologie_du_si<73>ge_de_Paris_(1870) DATE:2014-08-15
fxt.Test_html_frag_n
( "<gallery caption=>File:A.png</gallery>"
, "<li class='gallerycaption'>"
);
}
@Test public void Atr_show_filename() { // PURPOSE: show filename
fxt.Test_html_frag
( "<gallery showfilename=true>A.png</gallery>"
, "<div class=\"gallerytext\"><a href=\"/wiki/File:A.png\">File:A.png</a>"
);
}
@Test public void Atr_whitelist() { // PURPOSE: ignore atrs not in whitelist
fxt.Test_html_frag
( "<gallery onmouseover='alert();'>A.png</gallery>"
, "<ul id=\"xowa_gallery_ul_0\" class=\"gallery mw-gallery-traditional\">"
);
}
// @Test public void Ttl_caption() { // TODO: PURPOSE: category entries get rendered with name only (no ns)
// fxt.Test_html_frag
// ( "<gallery>Category:A</gallery>"
// , "<li class='gallerycaption'>B</li>"
// );
// }
}

View File

@@ -0,0 +1,84 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.files.*; import gplx.xowa.html.modules.*;
public class Gallery_mgr_packed_base extends Gallery_mgr_base {
@Override public byte Tid() {return Gallery_mgr_base_.Packed_tid;}
@Override public byte[] Tid_bry() {return Gallery_mgr_base_.Packed_bry;}
@Override public void Init(int itms_per_row, int itm_default_w, int itm_default_h) {
this.itms_per_row = 0; // Does not support per row option.
this.itm_default_w = itm_default_w;
this.itm_default_h = itm_default_h;
}
@Override public void Itms_per_row_(int v) {}
@Override public void Get_modules(Xoae_page page) {
page.Html_data().Module_mgr().Itm__gallery().Enabled_y_();
}
@Override public int Get_thumb_padding() {return 0;}
@Override public int Get_gb_padding() {return 2;}
@Override public int Get_vpad(int itm_h, int thm_h) {
return (int)((this.Get_thumb_padding() + itm_h - thm_h / Scale_factor) / 2);
}
@Override public int Get_thumb_div_width(int thm_w) {
if (thm_w < Scale_factor_x_60)
thm_w = Scale_factor_x_60; // Require at least 60px wide, so caption is wide enough to work.
return (int)(thm_w / Scale_factor) + this.Get_thumb_padding();
}
@Override public int Get_gb_width(int thm_w, int thm_h) {
int val = thm_w == -1 ? (int)(itm_default_w * Scale_factor) : thm_w;
return Get_thumb_div_width(val) + this.Get_gb_padding();
}
@Override public void Get_thumb_size(Xop_lnki_tkn lnki, Xof_ext ext) {
Get_thumb_size_static(lnki, ext, itm_default_w, itm_default_h);
}
@Override public void Adjust_image_parameters(Xof_file_itm xfer_itm) {
int w = (int)(xfer_itm.Html_w() / Scale_factor);
int h = (int)(xfer_itm.Html_h() / Scale_factor);
xfer_itm.Html_size_(w, h);
}
public static final double Scale_factor = 1.5d; // We artificially have 1.5 the resolution neccessary so that we can scale it up by that much on the client side, without worrying about requesting a new image.
private static final int Scale_factor_x_60 = (int)(Scale_factor * 60);
public static void Get_thumb_size_static(Xop_lnki_tkn lnki, Xof_ext ext, int itm_default_w, int itm_default_h) {
int w;
if (ext.Id_is_audio())
w = itm_default_w;
else
w = (itm_default_h) * 10 + 100; // We want the width not to be the constraining factor, so use random big number.
lnki.W_((int)(Scale_factor * w));
lnki.H_((int)(Scale_factor * itm_default_h));
}
}
class Gallery_mgr_packed_overlay extends Gallery_mgr_packed_base {
@Override public byte[] Tid_bry() {return Gallery_mgr_base_.Packed_overlay_bry;}
@Override public void Wrap_gallery_text(Bry_bfr bfr, byte[] gallery_text, int thm_w, int thm_h) {
if (gallery_text.length == 0) return; // If we have no text, do not output anything to avoid ugly white overlay.
int img_w = this.Get_gb_width(thm_w, thm_h) - this.Get_thumb_padding() - this.Get_gb_padding();
int caption_w = (img_w - 20);
bfr .Add(Wrap_gallery_text_0).Add_int_variable(caption_w)
.Add(Wrap_gallery_text_1).Add(gallery_text)
.Add(Wrap_gallery_text_2)
;
}
private static final byte[]
Wrap_gallery_text_0 = Bry_.new_a7("\n <div class=\"gallerytextwrapper\" style=\"width: ")
, Wrap_gallery_text_1 = Bry_.new_a7("px\"><div class=\"gallerytext\">\n") // NOTE: The newline after <div class="gallerytext"> is needed to accommodate htmltidy
, Wrap_gallery_text_2 = Bry_.new_a7("\n </div></div>") // NOTE: 2nd </div> is not part of MW, but needed to close div
;
}
class Gallery_mgr_packed_hover extends Gallery_mgr_packed_overlay { @Override public byte[] Tid_bry() {return Gallery_mgr_base_.Packed_hover_bry;}
}

View File

@@ -0,0 +1,129 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.primitives.*; import gplx.dbs.cfgs.*;
import gplx.fsdb.meta.*;
import gplx.xowa.parsers.logs.*;
import gplx.xowa.html.*; import gplx.xowa.files.*; import gplx.xowa.files.fsdb.*;
public class Gallery_xnde implements Xox_xnde, Xop_xnde_atr_parser {
private Gallery_xtn_mgr xtn_mgr;
public byte Mode() {return mode;} private byte mode;
public int Itm_w() {return itm_w;} private int itm_w = Null;
public int Itm_h() {return itm_h;} private int itm_h = Null;
public int Itms_per_row() {return itms_per_row;} private int itms_per_row = Null;
public boolean Show_filename() {return show_filename;} private boolean show_filename = false;
public byte[] Atr_caption() {return atr_caption;} private byte[] atr_caption = Bry_.Empty;
public byte[] Atr_style() {return atr_style;} private byte[] atr_style = Bry_.Empty;
public byte[] Atr_cls() {return atr_cls;} private byte[] atr_cls = Bry_.Empty;
public List_adp Atrs_other() {return atrs_other;} private List_adp atrs_other;
public int Itm_w_or_default() {return itm_w == Null ? Default : itm_w;}
public int Itm_h_or_default() {return itm_h == Null ? Default : itm_h;}
public int Itms_len() {return itms.Count();} private List_adp itms = List_adp_.new_();
public Gallery_itm Itms_get_at(int i) {return (Gallery_itm)itms.Get_at(i);}
public Gallery_mgr_base Gallery_mgr() {return gallery_mgr;} private Gallery_mgr_base gallery_mgr;
private boolean html_wtr_v1 = false;
public void Xatr_parse(Xowe_wiki wiki, byte[] src, Xop_xatr_itm xatr, Object xatr_key_obj) {
if (xatr_key_obj != null) {
Byte_obj_val xatr_key = (Byte_obj_val)xatr_key_obj;
switch (xatr_key.Val()) {
case Gallery_xnde_atrs.Mode_tid: mode = Gallery_mgr_base_.Get_or_traditional(xatr.Val_as_bry(src)); break;
case Gallery_xnde_atrs.Perrow_tid: itms_per_row = xatr.Val_as_int_or(src, Null); break;
case Gallery_xnde_atrs.Widths_tid: itm_w = xatr.Val_as_int_or(src, Null); break;
case Gallery_xnde_atrs.Heights_tid: itm_h = xatr.Val_as_int_or(src, Null); break;
case Gallery_xnde_atrs.Showfilename_tid: show_filename = xatr.Val_as_bool(src); break;
case Gallery_xnde_atrs.Caption_tid: if (!xatr.Tid_is_key_only()) atr_caption = xatr.Val_as_bry(src); break; // NOTE: do not create caption for key only; EX:<gallery caption=> PAGE:fr.w:Chronologie_du_si<73>ge_de_Paris_(1870); DATE:2014-08-15
case Gallery_xnde_atrs.Style_tid: atr_style = xatr.Val_as_bry(src); break;
case Gallery_xnde_atrs.Class_tid: atr_cls = xatr.Val_as_bry(src); break;
}
}
else {
if (atrs_other == null) atrs_other = List_adp_.new_();
atrs_other.Add(xatr);
}
}
public void Xtn_parse(Xowe_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {
try {
ctx.Para().Process_block__xnde(xnde.Tag(), Xop_xnde_tag.Block_bgn); // cancel pre for <gallery>; DATE:2014-03-11
Xop_xatr_itm.Xatr_parse(wiki.Appe(), this, Gallery_xnde_atrs.Key_hash, wiki, src, xnde);
xtn_mgr = (Gallery_xtn_mgr)wiki.Xtn_mgr().Get_or_fail(Gallery_xtn_mgr.XTN_KEY);
Init_atrs(wiki);
gallery_mgr.Get_modules(ctx.Cur_page());
Gallery_itm_parser parser = xtn_mgr.Parser();
if (parser.Parse_in_progress()) parser = new Gallery_itm_parser().Init_by_wiki(wiki); // handle nested galleries; EX: <gallery><ref><gallery>; PAGE:es.w:Arquitectura_medieval DATE:2015-07-10
parser.Parse_all(itms, gallery_mgr, this, src, xnde.Tag_open_end(), xnde.Tag_close_bgn());
boolean log_wkr_enabled = Log_wkr != Xop_log_basic_wkr.Null; if (log_wkr_enabled) Log_wkr.Log_end_xnde(ctx.Cur_page(), Xop_log_basic_wkr.Tid_gallery, src, xnde);
ctx.Para().Process_block__xnde(xnde.Tag(), Xop_xnde_tag.Block_end); // cancel pre for <gallery>; DATE:2014-03-11
} catch (Exception exc) {
wiki.Appe().Usr_dlg().Warn_many("", "", "failed to write gallery; src=~{0} err=~{1}", String_.new_u8(src, xnde.Src_bgn(), xnde.Src_end()), Err_.Message_gplx(exc));
}
} public static Xop_log_basic_wkr Log_wkr = Xop_log_basic_wkr.Null;
public void Xtn_write(Bry_bfr bfr, Xoae_app app, Xop_ctx ctx, Xoh_html_wtr html_wtr, Xoh_wtr_ctx hctx, Xop_xnde_tkn xnde, byte[] src) {
Xowe_wiki wiki = ctx.Wiki();
try {
if (html_wtr_v1)
xtn_mgr.Html_wtr().Write_html(bfr, app, wiki, ctx, html_wtr, hctx, ctx.Cur_page(), this, src);
else {
gallery_mgr.Write_html(bfr, wiki, ctx.Cur_page(), ctx, hctx, src, this);
}
} catch (Exception exc) {
wiki.Appe().Usr_dlg().Warn_many("", "", "failed to write gallery; src=~{0} err=~{1}", String_.new_u8(src, xnde.Src_bgn(), xnde.Src_end()), Err_.Message_gplx(exc));
}
}
private void Init_atrs(Xowe_wiki wiki) {
Db_cfg_hash cfg_grp = wiki.File_mgr().Cfg_get(Xof_fsdb_mgr_cfg.Grp_xowa);
if (cfg_grp.Get(Xof_fsdb_mgr_cfg.Key_gallery_fix_defaults).To_yn_or_n()) {
if (itm_w == Gallery_xnde.Null && itm_h == Gallery_xnde.Null) // if no w/h specified, set both to default (just like v1)
itm_w = itm_h = Gallery_xnde.Default;
}
else {
if (itm_w == Gallery_xnde.Null) itm_w = Gallery_xnde.Default;
if (itm_h == Gallery_xnde.Null) itm_h = Gallery_xnde.Default;
}
gallery_mgr = Gallery_mgr_base_.New_by_mode(mode);
if ( !wiki.File_mgr().Version_1_y() // v2: fsdb
&& !cfg_grp.Get(Xof_fsdb_mgr_cfg.Key_gallery_packed).To_yn_or_n() // packed not supported
) {
gallery_mgr = Gallery_mgr_base_.New_by_mode(Gallery_mgr_base_.Traditional_tid); // always go to traditional
html_wtr_v1 = true;
}
gallery_mgr.Init(itms_per_row, this.Itm_w_or_default(), this.Itm_h_or_default());
}
public static final int Default = 120, Null = -1;
}
class Gallery_xnde_atrs {
public static final byte
Mode_tid = 0
, Perrow_tid = 1
, Widths_tid = 2
, Heights_tid = 3
, Caption_tid = 4
, Showfilename_tid = 5
, Style_tid = 6
, Class_tid = 7
;
public static Hash_adp_bry Key_hash = Hash_adp_bry.ci_ascii_()
.Add_str_byte("mode" , Mode_tid)
.Add_str_byte("perrow" , Perrow_tid)
.Add_str_byte("widths" , Widths_tid)
.Add_str_byte("heights" , Heights_tid)
.Add_str_byte("caption" , Caption_tid)
.Add_str_byte("showfilename" , Showfilename_tid)
.Add_str_byte("style" , Style_tid)
.Add_str_byte("class" , Class_tid)
;
}

View File

@@ -0,0 +1,182 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Gallery_xnde_tst {
private Xop_fxt fxt = new Xop_fxt(); String raw_src;
@Before public void init() {fxt.Reset(); fxt.Wiki().Xtn_mgr().Init_by_wiki(fxt.Wiki());}
@Test public void Lnki_no_caption() {
fxt.Test_parse_page_wiki("<gallery>File:A.png</gallery>"
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png")
)
));
}
@Test public void Lnki_1() {
fxt.Test_parse_page_wiki("<gallery>File:A.png|b</gallery>"
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png")
)
));
}
@Test public void Lnki_3() {
fxt.Test_parse_page_wiki("<gallery>File:A.png|a\nFile:B.png|b\nFile:C.png|c</gallery>"
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png")
, new_chkr_gallery_itm().Expd_lnki_("File:B.png")
, new_chkr_gallery_itm().Expd_lnki_("File:C.png")
)
));
}
@Test public void Ignore_newLines() {
fxt.Test_parse_page_wiki("<gallery>\n\n\nFile:A.png|a\n\n\nFile:B.png|b\n\n\n</gallery>"
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png")
, new_chkr_gallery_itm().Expd_lnki_("File:B.png")
)
));
}
@Test public void Only_first_pipe() {
fxt.Test_parse_page_wiki("<gallery>File:A.png|File:B.png|cc</gallery>"
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png")
)
));
}
@Test public void Invalid_lnki() {
fxt.Test_parse_page_wiki("<gallery>A.png|cc</gallery>"
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png") // NOTE: MW converts "A.png" to "File:A.png"
)
));
}
@Test public void File_only_trailing_nl() {
fxt.Test_parse_page_wiki("<gallery>File:A.png\n</gallery>"
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png").Expd_caption_(null)
)
));
}
@Test public void Invalid_curly() {
raw_src = "a\n";
fxt.Init_log_(Xop_ttl_log.Invalid_char).Test_parse_page_wiki("<gallery>File:A.png|" + raw_src + "}}</gallery>" // NOTE: }} is ignored since it is not a valid title
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png").Expd_caption_("a")
)
));
}
@Test public void Caption() {
raw_src = "a<br/>c";
fxt.Test_parse_page_wiki("<gallery>File:A.png|" + raw_src + "</gallery>"
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png").Expd_caption_(raw_src)
)
));
}
@Test public void Xnde_atr() {
raw_src = "<center>a<br/>b</center>";
fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
( "<gallery perrow=3>"
, "File:A.jpg|" + raw_src
, "</gallery>"
) , fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.jpg").Expd_caption_(raw_src)
)
));
}
@Test public void Err_pre() { // PURPOSE: leading ws was failing; PAGE:en.w:Vlaardingen; "\nA.jpg| <center>Visbank</center>\n"
raw_src = " <center>a</center>";
fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
( "<gallery>"
, "File:A.jpg|" + raw_src
, "</gallery>"
) , fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.jpg").Expd_caption_("<center>a</center>")
)
));
}
@Test public void Err_comment() { // PURPOSE: comment was being rendered; PAGE:en.w:Perpetual motion; <!-- removed A.jpg|bcde -->
raw_src = "b";
fxt.Init_log_(Xop_ttl_log.Comment_eos).Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
( "<gallery>"
, "<!-- deleted A.jpg|" + raw_src
, "</gallery>"
) , fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_()
)
);
}
@Test public void Misc_atr() { // make sure misc attribute doesn't fail
raw_src = "b";
fxt.Test_parse_page_wiki("<gallery id=a>File:A.png|" + raw_src + "</gallery>"
, fxt.tkn_xnde_().Xnde_tagId_(Xop_xnde_tag_.Tid_gallery).Xnde_xtn_
( new_chkr_gallery_mgr().Expd_subs_
( new_chkr_gallery_itm().Expd_lnki_("File:A.png").Expd_caption_(raw_src)
)
));
}
private Gallery_mgr_data_chkr new_chkr_gallery_mgr() {return new Gallery_mgr_data_chkr();}
private Gallery_itm_chkr new_chkr_gallery_itm() {return new Gallery_itm_chkr();}
}
class Gallery_mgr_data_chkr implements Tst_chkr {
public Class<?> TypeOf() {return Gallery_xnde.class;}
public Gallery_itm_chkr[] Expd_subs() {return expd_subs;} public Gallery_mgr_data_chkr Expd_subs_(Gallery_itm_chkr... v) {expd_subs = v; return this;} Gallery_itm_chkr[] expd_subs = null;
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
Gallery_xnde actl = (Gallery_xnde)actl_obj;
int rv = 0;
rv += Chk_basic(mgr, path, actl, rv);
rv += Chk_subs(mgr, path, actl, rv);
return rv;
}
public int Chk_basic(Tst_mgr mgr, String path, Gallery_xnde actl, int err) {
return err;
}
public int Chk_subs(Tst_mgr mgr, String path, Gallery_xnde actl, int err) {
if (expd_subs != null) {
int actl_subs_len = actl.Itms_len();
Gallery_itm[] actl_subs = new Gallery_itm[actl_subs_len];
for (int i = 0; i < actl_subs_len; i++)
actl_subs[i] = actl.Itms_get_at(i);
return mgr.Tst_sub_ary(expd_subs, actl_subs, path, err);
}
return err;
}
}
class Gallery_itm_chkr implements Tst_chkr {
public Class<?> TypeOf() {return Gallery_itm.class;}
public Gallery_itm_chkr Expd_lnki_(String v) {expd_lnki = Xoa_ttl_chkr.new_(v); return this;} private Xoa_ttl_chkr expd_lnki;
public Gallery_itm_chkr Expd_caption_(String v) {expd_caption = v; return this;} private String expd_caption;
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
Gallery_itm actl = (Gallery_itm)actl_obj;
int err = 0;
err += mgr.Tst_sub_obj(expd_lnki, actl.Ttl(), path, err);
err += mgr.Tst_val(expd_caption == null, "", "caption", expd_caption, String_.new_u8(actl.Caption_bry()));
return err;
}
}

View File

@@ -0,0 +1,30 @@
/*
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.xtns.gallery; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.html.modules.*;
public class Gallery_xtn_mgr extends Xox_mgr_base {
@Override public byte[] Xtn_key() {return XTN_KEY;} public static final byte[] XTN_KEY = Bry_.new_a7("gallery");
@Override public Xox_mgr Clone_new() {return new Gallery_xtn_mgr();}
public Gallery_itm_parser Parser() {return parser;} private Gallery_itm_parser parser;
public Gallery_html_wtr Html_wtr() {return html_wtr;} private Gallery_html_wtr html_wtr;
@Override public void Xtn_init_by_wiki(Xowe_wiki wiki) {
parser = new Gallery_itm_parser();
parser.Init_by_wiki(wiki);
html_wtr = new Gallery_html_wtr();
}
}