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
2016-01-24 22:50:55 -05:00
parent 235228976e
commit 686d56fdab
77 changed files with 1543 additions and 487 deletions

View File

@@ -1,34 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.htmls.core.htmls.utls; import gplx.*; import gplx.xowa.*; import gplx.xowa.htmls.*; import gplx.xowa.htmls.core.*; import gplx.xowa.htmls.core.htmls.*;
import gplx.langs.htmls.*; import gplx.xowa.htmls.hrefs.*; import gplx.xowa.htmls.core.htmls.*;
public class Xoh_lnki_wtr_utl {
private final Xoa_app app; private final Xow_wiki wiki; private final Xoh_href_wtr href_wtr; private final Bry_bfr tmp_bfr = Bry_bfr.new_(255);
public Xoh_lnki_wtr_utl(Xow_wiki wiki, Xoh_href_wtr href_wtr) {
this.app = wiki.App();
this.wiki = wiki; this.href_wtr = href_wtr;
}
public byte[] Bld_href(byte[] page) {return Bld_href(wiki.Domain_bry(), wiki.Ttl_parse(page));}
public byte[] Bld_href(byte[] domain_bry, Xoa_ttl ttl) {
href_wtr.Build_to_bfr(tmp_bfr, app, Xoh_wtr_ctx.Mode_popup, domain_bry, ttl);
return tmp_bfr.To_bry_and_clear();
}
public byte[] Bld_title(byte[] text) {
return gplx.langs.htmls.Gfh_utl.Escape_html_as_bry(tmp_bfr, text, Bool_.N, Bool_.N, Bool_.N, Bool_.Y, Bool_.Y);
}
}

View File

@@ -48,8 +48,8 @@ public class Xoh_hdoc_ctx {
this.fsys__root = fsys_mgr.Root_dir().To_http_file_bry();
this.fsys__file = fsys_mgr.File_dir().To_http_file_bry();
this.fsys__file__comm = Bry_.Add(fsys__file, Xow_domain_itm_.Bry__commons, Byte_ascii.Slash_bry);
Xou_cache_mgr cache_mgr = app.User().User_db_mgr().Cache_mgr();
if (cache_mgr != null) file__mgr = Xou_cache_finder_.New_db(cache_mgr); // NOTE: this effectively only loads the cache db in app mode (and not in test mode)
// Xou_cache_mgr cache_mgr = app.User().User_db_mgr().Cache_mgr();
// if (cache_mgr != null) file__mgr = Xou_cache_finder_.New_db(cache_mgr); // NOTE: this effectively only loads the cache db in app mode (and not in test mode)
pool_mgr__hzip.Init();
}
public void Init_by_page(Xow_wiki wiki, byte[] page_url) {

View File

@@ -42,9 +42,10 @@ public class Xoh_hdr_data implements Xoh_data_itm {
Gfh_atr anch_atr = span_head.Atrs__get_by_or_fail(Gfh_atr_.Bry__id);
this.anch_bgn = anch_atr.Val_bgn(); this.anch_end = anch_atr.Val_end();
this.capt_bgn = span_head.Src_end();
Gfh_tag hdr_tail = tag_rdr.Tag__move_fwd_tail(hdr_level); // find </h2> not </span_head> since <span_head> can be nested, but <h2> cannot
Gfh_tag span_tail = tag_rdr.Tag__peek_bwd_tail(Gfh_tag_.Id__span); // get </span_head> before </h2>
Gfh_tag hdr_tail = tag_rdr.Tag__move_fwd_tail(hdr_level); // find </h2> not </span> since <span> can be nested, but <h2> cannot
Gfh_tag span_tail = tag_rdr.Tag__peek_bwd_tail(Gfh_tag_.Id__span); // get </span> before </h2>
this.capt_end = span_tail.Src_bgn();
if (capt_end < src_bgn) return false; // </span> is before <h#>; occurs b/c TIDY will relocate <span headline> out of <h#> if <h#> has center; PAGE:en.s:On_the_Vital_Principle/Book_2/Prelude_to_Chapter_2; DATE:2016-01-21
if (span_tail.Src_end() != hdr_tail.Src_bgn()) {
capt_rhs_bgn = span_tail.Src_end(); capt_rhs_end = hdr_tail.Src_bgn();
}

View File

@@ -70,4 +70,25 @@ public class Xoh_hdr_hzip_tst {
, "<h6><span class='mw-headline' id='AB'>A</span>B</h6>"
);
}
@Test public void Tidy__no_span() { // PURPOSE.TIDY: tidy will duplicate hdr if content has center; will fail if span/div is nearby; EX: ==<center>A</center>==\n<span><div>; PAGE:en.s:On_the_Vital_Principle/Book_2/Prelude_to_Chapter_2 DATE:2016-01-21
fxt.Test__encode(String_.Concat_lines_nl_skip_last
( "\"+A"
, "<center>"
, "<h2>A</h2>"
, "</center>"
, "<span class=\"mw-headline\" id=\"A\"></span>"
, "<div style=\"color:blue;\">"
, "<p>abc</p>"
, "</div>"
), String_.Concat_lines_nl_skip_last
( "<h2><span class='mw-headline' id='A'></span></h2>"
, "<center>"
, "<h2>A</h2>"
, "</center>"
, "<span class='mw-headline' id='A'></span>"
, "<div style='color:blue;'>"
, "<p>abc</p>"
, "</div>"
));
}
}

View File

@@ -218,7 +218,7 @@ public class Xoh_img_hzip implements Xoh_hzip_wkr, Gfo_poolable_itm {
tmp_bfr.Add(Xoh_href_.Bry__wiki).Add(page_ttl_bry);
}
else {
byte[] ns_bry = anch__ns_is_custom ? ns_custom_bry : Xow_ns_.Bry__file;
byte[] ns_bry = anch__ns_is_custom ? ns_custom_bry : hctx.Wiki__ttl_parser().Ns_mgr().Ns_file().Name_db();
tmp_bfr.Add(Xoh_href_.Bry__wiki).Add(ns_bry).Add_byte_colon();
tmp_bfr.Add(page_db);
// Gfo_url_encoder_.Href.Encode(tmp_bfr, page_db); // encode needed for ?; PAGE:en.w:Voiceless_alveolar_affricate; DATE:2016-01-04

View File

@@ -16,7 +16,7 @@ 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.htmls.core.wkrs.imgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.htmls.*; import gplx.xowa.htmls.core.*; import gplx.xowa.htmls.core.wkrs.*;
import org.junit.*; import gplx.xowa.htmls.core.hzips.*;
import org.junit.*; import gplx.xowa.htmls.core.hzips.*; import gplx.xowa.wikis.nss.*;
public class Xoh_img_hzip__dump__tst {
private final Xoh_hzip_fxt fxt = new Xoh_hzip_fxt().Init_mode_diff_y_();
@Before public void Clear() {fxt.Clear();}
@@ -60,6 +60,29 @@ public class Xoh_img_hzip__dump__tst {
String html = "<a href=\"/wiki/A%27b_link\" class=\"image\" xowa_title=\"A'b.png\"><img data-xowa-title=\"A'b.png\" data-xoimg=\"0|220|-1|-1|-1|-1\" src=\"\" width=\"0\" height=\"0\" class=\"thumbborder\" alt=\"A'b_capt\"></a>";
fxt.Test__bicode_raw("~%#oA%27b_link~A'b.png~#)#SA'b_capt~", html, html);
}
@Test public void Href__image() { // [[Image:A.png|abc]]
fxt.Test__bicode
( "~%-%A.png~Image~)#Sabc~"
, "<a href='/wiki/Image:A.png' class='image' title='abc' xowa_title='A.png'><img data-xowa-title='A.png' data-xoimg='0|220|-1|-1|-1|-1' src='' width='0' height='0' alt='abc'></a>"
);
}
@Test public void Ns__cs() { // [[image:a.png|abc]]; PAGE:en.d:freedom_of_speech DATE:2016-01-21
fxt.Wiki().Ns_mgr().Ns_file().Case_match_(gplx.xowa.wikis.nss.Xow_ns_case_.Tid__all);
fxt.Test__bicode
( "~%-%a.png~image~)#Sabc~"
, "<a href='/wiki/image:a.png' class='image' title='abc' xowa_title='a.png'><img data-xowa-title='a.png' data-xoimg='0|220|-1|-1|-1|-1' src='' width='0' height='0' alt='abc'></a>"
);
fxt.Wiki().Ns_mgr().Ns_file().Case_match_(gplx.xowa.wikis.nss.Xow_ns_case_.Tid__1st);
}
@Test public void Ns__foreign() { // [[Fichier:a.png|abc]]; PAGE:fr.w: DATE:2016-01-21
Xow_ns_mgr ns_mgr = fxt.Wiki().Ns_mgr();
ns_mgr.Ns_file().Name_bry_(Bry_.new_u8("Fichier")); ns_mgr.Init_w_defaults();
fxt.Test__bicode
( "~%!!a.png~)#Sabc~"
, "<a href='/wiki/Fichier:a.png' class='image' title='abc' xowa_title='a.png'><img data-xowa-title='a.png' data-xoimg='0|220|-1|-1|-1|-1' src='' width='0' height='0' alt='abc'></a>"
);
ns_mgr.Ns_file().Name_bry_(Bry_.new_u8("File")); ns_mgr.Init_w_defaults();
}
@Test public void Link__cs() { // [[File:A.png|link=File:a.ogg|abc]]
fxt.Test__bicode
( "~%!Aa.ogg~A.png~)#Sabc~"
@@ -121,7 +144,7 @@ public class Xoh_img_hzip__dump__tst {
);
}
@Test public void Link__ns_alias() { // [[File:A.png|link=WP:MCB]]; PAGE:en.w:Wikipedia:WikiProject_Molecular_and_Cell_Biology; DATE:2016-01-11
fxt.Init__ns_alias__add("WP", gplx.xowa.wikis.nss.Xow_ns_.Tid__project);
fxt.Init__ns_alias__add("WP", Xow_ns_.Tid__project);
fxt.Test__bicode
( "~%/+MCB~A.png~'WP~)!q"
, "<a href='/wiki/WP:MCB' class='image' xowa_title='A.png'><img data-xowa-title='A.png' data-xoimg='0|80|-1|-1|-1|-1' src='' width='0' height='0' alt=''></a>"
@@ -134,12 +157,6 @@ public class Xoh_img_hzip__dump__tst {
, "<a href='/site/en.wiktionary.org/wiki/Category:en:A' class='image' xowa_title='A.png'><img data-xowa-title='A.png' data-xoimg='0|80|-1|-1|-1|-1' src='' width='0' height='0' alt=''></a>"
);
}
@Test public void Href__image() { // [[Image:A.png|abc]]
fxt.Test__bicode
( "~%-%A.png~Image~)#Sabc~"
, "<a href='/wiki/Image:A.png' class='image' title='abc' xowa_title='A.png'><img data-xowa-title='A.png' data-xoimg='0|220|-1|-1|-1|-1' src='' width='0' height='0' alt='abc'></a>"
);
}
@Test public void Missing() { // PURPOSE: bad dump shouldn't write corrupt data
fxt.Test__bicode
( "%|\"\\QA.png!!!!A"

View File

@@ -128,7 +128,7 @@ public class Xoh_lnki_data {
title_bgn = title_atr.Val_bgn(); title_end = title_atr.Val_end();
if (href_ns_name != null) { // ns_name exists
int title_bgn_wo_ns = title_bgn + href_ns_name_len;
if (Bry_.Match(src, title_bgn, title_bgn_wo_ns, href_ns_name)) // title matches ns_name;
if (Bry_.Match(src, title_bgn, title_bgn_wo_ns, href_ns_name)) // title matches href_ns;
title_bgn = title_bgn_wo_ns; // skip ns; "Help:"
else
title_missing_ns = true;
@@ -136,7 +136,7 @@ public class Xoh_lnki_data {
if (title_end == -1)
title_tid = Title__missing;
else {
if (Bry_.Match(src, title_bgn, title_end, href_src, href_bgn, href_end))
if (Bry_.Match(src, title_bgn, title_end, href_src, href_bgn, href_end) && !title_missing_ns) // NOTE: do not mark title=href if href omitted title; PAGE:en.b:Wikibooks:WikiProject; DATE:2016-01-20
title_tid = Title__href;
else if (Bry_.Match(src, title_bgn, title_end, src, capt_bgn, capt_end))
title_tid = Title__capt;

View File

@@ -76,6 +76,7 @@ public class Xoh_lnki_hzip implements Xoh_hzip_wkr, Gfo_poolable_itm {
byte href_type = flag_bldr.Get_as_byte(Flag__href_type);
int capt_cs0_tid = flag_bldr.Get_as_int(Flag__capt_cs0_tid);
byte text_type = flag_bldr.Get_as_byte(Flag__text_type);
// Tfds.Dbg(cls_tid, title_missing_ns, ttl_is_main_page, ns_custom_exists, title_tid, capt_has_ns, ns_is_not_main, href_type, capt_cs0_tid, text_type);
int site_bgn = -1, site_end = -1; if (href_type == Xoh_anch_href_data.Tid__site) {site_bgn = rdr.Pos(); site_end = rdr.Find_fwd_lr();}
int ns_id = ns_is_not_main ? Xoh_lnki_dict_.Ns_decode(rdr) : Xow_ns_.Tid__main;

View File

@@ -68,7 +68,8 @@ public class Xoh_lnki_hzip__ns__tst {
fxt.Test__bicode("~${3h)Image~A%C3%BC.png~b~Image:Aü.png~", "<a href='/wiki/Image:A%C3%BC.png' title='Image:Aü.png'>b</a>");
}
@Test public void Ctg__main() { // links at bottom of pages in main ns; DATE:2015-12-28
fxt.Test__bicode("~$|$t'1A~", "<a href='/wiki/Category:A' class='inte" + "rnal' title='A'>A</a>");
fxt.Test__bicode("~$|%\"(1A~", "<a href='/wiki/Category:A' class='inte" + "rnal' title='A'>A</a>");
fxt.Test__decode("~$|$t'1A~", "<a href='/wiki/Category:A' class='inte" + "rnal' title='A'>A</a>"); // NOTE:backward compatibility for en.w:2015-12; delete after 2016-01 is uploaded
}
@Test public void Ctg__tree() { // links on Category pages;
fxt.Test__bicode("~$|&3J1A~", "<a href='/wiki/Category:A' class='CategoryTreeLabel CategoryTreeLabelNs14 CategoryTreeLabelCategory'>A</a>");
@@ -79,4 +80,7 @@ public class Xoh_lnki_hzip__ns__tst {
@Test public void Ctg__xnav__under() { // previous / next 200 links on Category pages; PAGE:en.w:Category:Public_transit_articles_with_unsupported_infobox_fields; DATE:2016-01-14
fxt.Test__bicode("~$|&`Z1A B?pageuntil=C,_D#mw-pages~previous 200~Category:A_B~", "<a href='/wiki/Category:A_B?pageuntil=C,_D#mw-pages' class='xowa_nav' title='Category:A_B'>previous 200</a>");
}
@Test public void Outlier__title_wo_ns() {// should not happen, but handle situation wherein title doesnot have ns PAGE:en.b:Wikibooks:WikiProject DATE:2016-01-20
fxt.Test__bicode("~${Tr/A B~", "<a href='/wiki/Help:A_B' title='A B'>A B</a>");
}
}

View File

@@ -302,7 +302,7 @@ public class Xoh_thm_hzip_tst {
, "</div>"
));
}
@Test public void Dump() {
// @Test public void Dump() {
// Xowe_wiki en_d = fxt.Init_wiki_alias("wikt", "en.wiktionary.org");
// gplx.xowa.wikis.nss.Xow_ns_mgr ns_mgr = en_d.Ns_mgr();
// ns_mgr.Ns_main().Case_match_(gplx.xowa.wikis.nss.Xow_ns_case_.Tid__all);
@@ -313,5 +313,5 @@ public class Xoh_thm_hzip_tst {
// fxt.Init_mode_is_b256_(Bool_.N);
// fxt.Exec_write_to_fsys(Io_url_.new_dir_("J:\\xowa\\dev_rls\\html\\"), "debug.html");
// fxt.Init_mode_is_b256_(Bool_.N);
}
// }
}

View File

@@ -27,11 +27,12 @@ public class Xoh_thm_wtr implements gplx.core.brys.Bfr_arg {
private final Bfr_arg__bry_ary div_2_magnify = new Bfr_arg__bry_ary();
private final Bfr_arg__bry capt_2 = Bfr_arg__bry.New(Bry_.Empty);
private final Bfr_arg__bry capt_3 = Bfr_arg__bry.New(Bry_.Empty);
private final Bfr_arg__bry enlarge = Bfr_arg__bry.New(Bry_.Empty);
private final Bry_bfr tmp_bfr = Bry_bfr.new_(255);
private Bfr_arg div_1_img = Bfr_arg_.Noop, capt_1 = Bfr_arg_.Noop;
private byte[] img_is_vid_nl, trailing_space;
public Xoh_thm_wtr Clear() {
Bfr_arg_.Clear(div_0_align, div_1_id, div_2_href, capt_2, capt_3); // , div_1_width, div_2_magnify
Bfr_arg_.Clear(div_0_align, div_1_id, div_2_href, enlarge, capt_2, capt_3); // , div_1_width, div_2_magnify
div_1_img = capt_1 = Bfr_arg_.Noop;
img_is_vid_nl = Bry_.Empty;
return this;
@@ -48,6 +49,11 @@ public class Xoh_thm_wtr implements gplx.core.brys.Bfr_arg {
this.div_1_img = img_wtr;
this.div_2_href.Set_by_bry(div_2_href);
div_2_magnify.Set(hctx.Fsys__root(), bry_div_2_magnify);
Xow_wiki wiki = (Xow_wiki)hctx.Wiki__ttl_parser();
if (wiki.Type_is_edit())
enlarge.Set_by_val(wiki.Lang().Msg_mgr().Itm_by_id_or_null(gplx.xowa.langs.msgs.Xol_msg_itm_.Id_file_enlarge).Val());
else
enlarge.Set_by_val(Bry__enlarge);
this.capt_1 = capt_1;
if (capt_2_exists) {
if (capt_2_is_tidy)
@@ -66,15 +72,16 @@ public class Xoh_thm_wtr implements gplx.core.brys.Bfr_arg {
this.Bfr_arg__add(bfr);
}
public void Bfr_arg__add(Bry_bfr bfr) {
fmtr.Bld_bfr_many(bfr, div_0_align, div_1_id, div_1_width, img_is_vid_nl, div_1_img, trailing_space, div_2_href, div_2_magnify, capt_1, capt_2, capt_3);
fmtr.Bld_bfr_many(bfr, div_0_align, div_1_id, div_1_width, img_is_vid_nl, div_1_img, trailing_space, div_2_href, div_2_magnify, enlarge, capt_1, capt_2, capt_3);
}
private static final byte[] Bry__enlarge = Bry_.new_a7("Enlarge");
private static final Bry_fmtr fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( "<div class=\"thumb t~{div_0_align}\">"
, "<div~{div_1_id} class=\"thumbinner\" style=\"width:~{div_1_width}px;\">~{img_is_vid_nl}~{div_1_img}~{trailing_space}" // NOTE: trailing space is intentional; matches jtidy behavior
, "<div class=\"thumbcaption\">"
, "<div class=\"magnify\"><a~{div_2_href} class=\"internal\" title=\"Enlarge\"></a></div>"
, "<div class=\"magnify\"><a~{div_2_href} class=\"internal\" title=\"~{enlarge}\"></a></div>"
, "~{capt_1}</div>~{capt_2}</div>~{capt_3}</div>"
), "div_0_align", "div_1_id", "div_1_width", "img_is_vid_nl", "div_1_img", "trailing_space", "div_2_href", "div_2_magnify", "capt_1", "capt_2", "capt_3");
), "div_0_align", "div_1_id", "div_1_width", "img_is_vid_nl", "div_1_img", "trailing_space", "div_2_href", "div_2_magnify", "enlarge", "capt_1", "capt_2", "capt_3");
private static final Bry_fmtr alt_fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, "<hr>"

View File

@@ -44,18 +44,27 @@ public class Xowd_css_core_mgr {
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.Instance.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.Instance.SaveFilBry(file_url, file.Data());
}
return true;
String dbg = "enter";
try {
int css_id = core_tbl.Select_id_by_key(key);
dbg += ";css_id";
if (css_id == Xowd_css_core_tbl.Id_null) return false; // unknown key; return false (not found)
dbg += ";select_by_owner";
Xowd_css_file_itm[] file_list = file_tbl.Select_by_owner(css_id);
dbg += ";file_list:" + file_list.length;
// Io_mgr.Instance.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];
dbg += ";file_url:" + file.Path();
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.Instance.SaveFilBry(file_url, file.Data());
dbg += ";file_data:" + file.Data().length;
}
return true;
} catch (Exception e) {throw Err_.new_exc(e, "css", "Xowd_css_core_mgr.Get failed", "dbg", dbg, "err", Err_.Message_gplx_log(e));}
}
public static final String Key_default = "xowa.default", Key_mobile = "xowa.mobile";
}