diff --git a/100_core/src_110_primitive/gplx/Bry_.java b/100_core/src_110_primitive/gplx/Bry_.java index da0f6302f..4e29ab898 100644 --- a/100_core/src_110_primitive/gplx/Bry_.java +++ b/100_core/src_110_primitive/gplx/Bry_.java @@ -111,6 +111,12 @@ public class Bry_ { catch (Exception e) {throw Err_.err_(e, "unsupported encoding");} } public static byte[] Coalesce(byte[] orig, byte[] val_if_not_blank) {return Bry_.Len_eq_0(val_if_not_blank) ? orig : val_if_not_blank;} + public static byte Get_at_end_or_fail(byte[] bry) { + if (bry == null) throw Err_.new_("bry is null"); + int bry_len = bry.length; + if (bry_len == 0) throw Err_.new_("bry has 0 len"); + return bry[bry_len - 1]; + } public static int While_fwd(byte[] src, byte while_byte, int bgn, int end) { for (int i = bgn; i < end; i++) if (src[i] != while_byte) return i; @@ -427,11 +433,14 @@ public class Bry_ { } return true; } + public static boolean HasAtBgn(byte[] src, byte lkp, int src_bgn) { + return src_bgn < src.length ? src[src_bgn] == lkp : false; + } public static boolean HasAtBgn(byte[] src, byte[] lkp) {return HasAtBgn(src, lkp, 0, src.length);} - public static boolean HasAtBgn(byte[] src, byte[] lkp, int src_bgn, int srcEnd) { - int lkpLen = lkp.length; - if (lkpLen + src_bgn > srcEnd) return false; // lkp is longer than src - for (int i = 0; i < lkpLen; i++) { + public static boolean HasAtBgn(byte[] src, byte[] lkp, int src_bgn, int src_end) { + int lkp_len = lkp.length; + if (lkp_len + src_bgn > src_end) return false; // lkp is longer than src + for (int i = 0; i < lkp_len; i++) { if (lkp[i] != src[i + src_bgn]) return false; } return true; diff --git a/100_core/src_110_primitive/gplx/Bry_finder.java b/100_core/src_110_primitive/gplx/Bry_finder.java index c59de5f5b..656af4fa7 100644 --- a/100_core/src_110_primitive/gplx/Bry_finder.java +++ b/100_core/src_110_primitive/gplx/Bry_finder.java @@ -34,6 +34,10 @@ public class Bry_finder { if (src[i] == lkp) return i; return Bry_finder.Not_found; } + public static int Move_fwd(byte[] src, byte lkp, int cur, int end) { + int rv = Find_fwd(src, lkp, cur, src.length); + return rv == Bry_finder.Not_found ? rv : rv + 1; + } public static int Move_fwd(byte[] src, byte[] lkp, int cur, int end) { int rv = Find_fwd(src, lkp, cur, src.length); return rv == Bry_finder.Not_found ? rv : rv + lkp.length; @@ -191,6 +195,18 @@ public class Bry_finder { } } } + public static int Find_fwd_until_ws(byte[] src, int cur, int end) { + while (true) { + if (cur == end) return Bry_finder.Not_found; + switch (src[cur]) { + case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.NewLine: case Byte_ascii.CarriageReturn: + return cur; + default: + ++cur; + break; + } + } + } public static int Find_fwd_while_space_or_tab(byte[] src, int cur, int end) { while (true) { if (cur == end) return cur; @@ -222,11 +238,13 @@ public class Bry_finder { public static int Find_fwd_while_ws(byte[] src, int cur, int end) { while (true) { if (cur == end) return cur; - switch (src[cur]) { - case Byte_ascii.NewLine: case Byte_ascii.CarriageReturn: - case Byte_ascii.Space: case Byte_ascii.Tab: ++cur; break; - default: return cur; - } + try { + switch (src[cur]) { + case Byte_ascii.NewLine: case Byte_ascii.CarriageReturn: + case Byte_ascii.Space: case Byte_ascii.Tab: ++cur; break; + default: return cur; + } + } catch (Exception e) {throw Err_.new_("idx is invalid; cur={0} src={1} err={2}", cur, src, Err_.Message_gplx(e));} } } public static int Find_fwd_while_letter(byte[] src, int cur, int end) { diff --git a/100_core/src_120_basicDataType/gplx/EnmMgr.java b/100_core/src_120_basicDataType/gplx/EnmMgr.java index ca705427a..e3ae2e21f 100644 --- a/100_core/src_120_basicDataType/gplx/EnmMgr.java +++ b/100_core/src_120_basicDataType/gplx/EnmMgr.java @@ -34,7 +34,11 @@ public class EnmMgr { for (int i = 0; i < ary.length; i++) { String term = String_.Trim(ary[i]); // ex: key.ctrl + key.a if (prefix != null) term = String_.Replace(term, prefix, ""); - int cur = Int_.cast_(rawRegy.FetchOrFail(term)); + int cur = -1; + if (String_.HasAtBgn(term, "#")) + cur = Int_.parse_(String_.Mid(term, 1)); + else + cur = Int_.cast_(rawRegy.Fetch(term)); rv |= cur; } return rv; diff --git a/100_core/src_140_list/gplx/OrderedHash.java b/100_core/src_140_list/gplx/OrderedHash.java index 8d8883dd7..a1484db7b 100644 --- a/100_core/src_140_list/gplx/OrderedHash.java +++ b/100_core/src_140_list/gplx/OrderedHash.java @@ -26,6 +26,7 @@ public interface OrderedHash extends HashAdp { void SortBy(ComparerAble comparer); void ResizeBounds(int i); Object Xto_ary(Class t); + Object Xto_ary_and_clear(Class t); String XtoStr_ui(); void MoveTo(int src, int trg); void Lock(); diff --git a/100_core/src_140_list/gplx/OrderedHash_base.java b/100_core/src_140_list/gplx/OrderedHash_base.java index 08a85c83d..6b317e04c 100644 --- a/100_core/src_140_list/gplx/OrderedHash_base.java +++ b/100_core/src_140_list/gplx/OrderedHash_base.java @@ -39,6 +39,11 @@ public class OrderedHash_base extends HashAdp_base implements OrderedHash, GfoIn ordered.Clear(); } public Object Xto_ary(Class type) {return ordered.Xto_ary(type);} + public Object Xto_ary_and_clear(Class t) { + Object rv = Xto_ary(t); + this.Clear(); + return rv; + } @gplx.Virtual public void Sort() {if (locked) Lock_fail(); ordered.Sort();} // NOTE: uses item's .compareTo public void SortBy(ComparerAble comparer) {if (locked) Lock_fail(); ordered.SortBy(comparer);} @Override public java.util.Iterator iterator() {return ordered.iterator();} diff --git a/100_core/src_200_io/gplx/ios/IoEngine_system.java b/100_core/src_200_io/gplx/ios/IoEngine_system.java index 674509b45..ea8c490f5 100644 --- a/100_core/src_200_io/gplx/ios/IoEngine_system.java +++ b/100_core/src_200_io/gplx/ios/IoEngine_system.java @@ -401,8 +401,8 @@ public class IoEngine_system extends IoEngine_base { prog_dlg = xfer_fmt.usr_dlg; if (!Web_access_enabled) { if (prog_dlg != null) { - if (session_fil == null) session_fil = prog_dlg.Log_wtr().Session_dir().GenSubFil("internet.txt"); - prog_dlg.Log_wtr().Log_msg_to_url_fmt(session_fil, "download disabled: src='~{0}' trg='~{1}'", xrg.Src(), xrg.Trg().Raw()); + if (session_fil == null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt"); + prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download disabled: src='~{0}' trg='~{1}'", xrg.Src(), xrg.Trg().Raw()); } return false; } @@ -435,8 +435,8 @@ public class IoEngine_system extends IoEngine_base { } if (prog_dlg != null) { xfer_fmt.Term(); - if (session_fil == null) session_fil = prog_dlg.Log_wtr().Session_dir().GenSubFil("internet.txt"); - prog_dlg.Log_wtr().Log_msg_to_url_fmt(session_fil, "download pass: src='~{0}' trg='~{1}'", src_str, xrg.Trg().Raw()); + if (session_fil == null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt"); + prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download pass: src='~{0}' trg='~{1}'", src_str, xrg.Trg().Raw()); } return true; } @@ -446,8 +446,8 @@ public class IoEngine_system extends IoEngine_base { else if (ClassAdp_.Eq_typeSafe(exc, java.io.FileNotFoundException.class)) xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_file_not_found); else xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_unknown); if (prog_dlg != null && !xrg.Prog_cancel()) { - if (session_fil == null) session_fil = prog_dlg.Log_wtr().Session_dir().GenSubFil("internet.txt"); - prog_dlg.Log_wtr().Log_msg_to_url_fmt(session_fil, "download fail: src='~{0}' trg='~{1}' error='~{2}'", src_str, xrg.Trg().Raw(), Err_.Message_lang(exc)); + if (session_fil == null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt"); + prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download fail: src='~{0}' trg='~{1}' error='~{2}'", src_str, xrg.Trg().Raw(), Err_.Message_lang(exc)); } if (trg_stream != null) { try { @@ -552,7 +552,7 @@ class Io_stream_rdr_http implements Io_stream_rdr { if (!IoEngine_system.Web_access_enabled) { read_done = read_failed = true; if (prog_dlg != null) - prog_dlg.Log_wtr().Log_msg_to_url_fmt(session_fil, "download disabled: src='~{0}' trg='~{1}'", xrg.Src(), xrg.Trg().Raw()); + prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download disabled: src='~{0}' trg='~{1}'", xrg.Src(), xrg.Trg().Raw()); return this; } src_str = xrg.Src(); @@ -604,12 +604,12 @@ class Io_stream_rdr_http implements Io_stream_rdr { if (prog_dlg != null) { xfer_fmt.Term(); } - if (session_fil == null && prog_dlg != null) session_fil = prog_dlg.Log_wtr().Session_dir().GenSubFil("internet.txt"); + if (session_fil == null && prog_dlg != null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt"); if (read_failed) { } else { if (prog_dlg != null) - prog_dlg.Log_wtr().Log_msg_to_url_fmt(session_fil, "download pass: src='~{0}' trg='~{1}'", src_str, xrg.Trg().Raw()); + prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download pass: src='~{0}' trg='~{1}'", src_str, xrg.Trg().Raw()); xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_pass); } xrg.Prog_running_(false); @@ -632,8 +632,8 @@ class Io_stream_rdr_http implements Io_stream_rdr { else if (ClassAdp_.Eq_typeSafe(exc, java.io.FileNotFoundException.class)) xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_file_not_found); else xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_unknown); if (prog_dlg != null && !xrg.Prog_cancel()) { - if (session_fil == null) session_fil = prog_dlg.Log_wtr().Session_dir().GenSubFil("internet.txt"); - prog_dlg.Log_wtr().Log_msg_to_url_fmt(session_fil, "download fail: src='~{0}' trg='~{1}' error='~{2}'", src_str, xrg.Trg().Raw(), Err_.Message_lang(exc)); + if (session_fil == null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt"); + prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download fail: src='~{0}' trg='~{1}' error='~{2}'", src_str, xrg.Trg().Raw(), Err_.Message_lang(exc)); } this.Rls(); } diff --git a/100_core/src_210_env/gplx/ProcessAdp.java b/100_core/src_210_env/gplx/ProcessAdp.java index d011d0745..e017219d4 100644 --- a/100_core/src_210_env/gplx/ProcessAdp.java +++ b/100_core/src_210_env/gplx/ProcessAdp.java @@ -217,9 +217,14 @@ public class ProcessAdp implements GfoInvkAble, RlsAble { else if (!exe_url.OwnerDir().EqNull()) // only set workingDir if ownerDir is not null; NOTE: workingDir necessary for AdvMame; probably not a bad thing to do pb.directory(new File(exe_url.OwnerDir().Xto_api())); } ProcessBuilder pb; - Process Process_start() { + protected Process Process_start() { try {process = pb.start();} - catch (IOException e) {throw Err_.err_key_(e, "gplx.ProcessAdp", "thread start failed");} + catch (IOException e) { + java.util.List command_list = pb.command(); + String[] command_ary = new String[command_list.size()]; + command_ary = command_list.toArray(command_ary); + throw Err_.err_(e, "process:start failed; args={0}", String_.Concat_with_str(" ", command_ary)); + } return process; } void Process_run_and_end() { @@ -290,50 +295,54 @@ class Thread_ProcessAdp_async extends Thread { } } class Thread_ProcessAdp_sync extends Thread { - public Thread_ProcessAdp_sync(ProcessAdp process_adp) {this.process_adp = process_adp;} ProcessAdp process_adp; - public boolean Done() {return done;} boolean done = false; + public Thread_ProcessAdp_sync(ProcessAdp process_adp) {this.process_adp = process_adp;} private final ProcessAdp process_adp; + public boolean Done() {return done;} private boolean done = false; public void Cancel() { process_adp.UnderProcess().destroy(); } public synchronized void run() { done = false; - Process process = process_adp.Process_start(); - StreamGobbler input_gobbler = new StreamGobbler("input", process.getInputStream()); - StreamGobbler error_gobbler = new StreamGobbler("error", process.getErrorStream()); - input_gobbler.start(); - error_gobbler.start(); - try {process.waitFor();} - catch (InterruptedException e) { - this.Cancel(); - String kill_rslt = process_adp.Kill(); - process_adp.Process_post(kill_rslt); - done = false; - return; - } - while (input_gobbler.isAlive()) { - try {input_gobbler.join(50);} - catch (InterruptedException e) {throw Err_.err_key_(e, "gplx.ProcessAdp", "thread interrupted at input gobbler");} - } - while (error_gobbler.isAlive()) { - try {error_gobbler.join(50);} - catch (InterruptedException e) {throw Err_.err_key_(e, "gplx.ProcessAdp", "thread interrupted at error gobbler");} - } - String result = input_gobbler.Rslt() + "\n" + error_gobbler.Rslt(); - process_adp.Process_post(result); - done = true; + try { + Process process = process_adp.Process_start(); + StreamGobbler input_gobbler = new StreamGobbler("input", process.getInputStream()); + StreamGobbler error_gobbler = new StreamGobbler("error", process.getErrorStream()); + input_gobbler.start(); + error_gobbler.start(); + try {process.waitFor();} + catch (InterruptedException e) { + this.Cancel(); + String kill_rslt = process_adp.Kill(); + process_adp.Process_post(kill_rslt); + done = false; + return; + } + while (input_gobbler.isAlive()) { + try {input_gobbler.join(50);} + catch (InterruptedException e) {throw Err_.err_key_(e, "gplx.ProcessAdp", "thread interrupted at input gobbler");} + } + while (error_gobbler.isAlive()) { + try {error_gobbler.join(50);} + catch (InterruptedException e) {throw Err_.err_key_(e, "gplx.ProcessAdp", "thread interrupted at error gobbler");} + } + String result = input_gobbler.Rslt() + "\n" + error_gobbler.Rslt(); + process_adp.Process_post(result); + } catch (Exception e) { // NOTE: warn; do not throw, else multiple errors if timidity not available; PAGE:fr.u:Pentatoniques_altérées/Gammes_avec_deux_notes_altérées DATE:2015-05-08 + Gfo_usr_dlg_.I.Warn_many("", "", "process.sync failed; cmd=~{0} args=~{1}", process_adp.Exe_url().Raw(), process_adp.Args_str()); + } + finally {done = true;} } } class StreamGobbler extends Thread { - String name; InputStream stream; + private final String name; private final InputStream stream; public StreamGobbler (String name, InputStream stream) {this.name = name; this.stream = stream;} - public String Rslt() {return rslt;} String rslt; + public String Rslt() {return rslt;} private String rslt; public void run () { try { String_bldr sb = String_bldr_.new_(); InputStreamReader isr = new InputStreamReader(stream); BufferedReader br = new BufferedReader(isr); while (true) { - String s = br.readLine (); + String s = br.readLine(); if (s == null) break; sb.Add(s); } diff --git a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg.java b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg.java index f3913c2e3..59d0ddf3c 100644 --- a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg.java +++ b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg.java @@ -16,21 +16,20 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx; -public interface Gfo_usr_dlg extends GfoInvkAble, Cancelable { - void Canceled_y_(); void Canceled_n_(); - void Clear(); - Gfo_usr_dlg_ui Ui_wkr(); void Ui_wkr_(Gfo_usr_dlg_ui v); - Gfo_log_wtr Log_wtr(); void Log_wtr_(Gfo_log_wtr v); - String Log_many(String grp_key, String msg_key, String fmt, Object... args); - String Warn_many(String grp_key, String msg_key, String fmt, Object... args); - Err Fail_many(String grp_key, String msg_key, String fmt, Object... args); - String Prog_many(String grp_key, String msg_key, String fmt, Object... args); - String Prog_none(String grp_key, String msg_key, String fmt); - String Note_many(String grp_key, String msg_key, String fmt, Object... args); - String Note_none(String grp_key, String msg_key, String fmt); - String Note_gui_none(String grp_key, String msg_key, String fmt); - String Prog_one(String grp_key, String msg_key, String fmt, Object arg); - String Prog_direct(String msg); - String Log_direct(String msg); - String Plog_many(String grp_key, String msg_key, String fmt, Object... args); +public interface Gfo_usr_dlg extends Cancelable { + void Canceled_y_(); void Canceled_n_(); + Gfo_usr_dlg__log Log_wkr(); void Log_wkr_(Gfo_usr_dlg__log v); + Gfo_usr_dlg__gui Gui_wkr(); void Gui_wkr_(Gfo_usr_dlg__gui v); + String Log_many(String grp_key, String msg_key, String fmt, Object... args); + String Warn_many(String grp_key, String msg_key, String fmt, Object... args); + Err Fail_many(String grp_key, String msg_key, String fmt, Object... args); + String Prog_many(String grp_key, String msg_key, String fmt, Object... args); + String Prog_none(String grp_key, String msg_key, String fmt); + String Note_many(String grp_key, String msg_key, String fmt, Object... args); + String Note_none(String grp_key, String msg_key, String fmt); + String Note_gui_none(String grp_key, String msg_key, String fmt); + String Prog_one(String grp_key, String msg_key, String fmt, Object arg); + String Prog_direct(String msg); + String Log_direct(String msg); + String Plog_many(String grp_key, String msg_key, String fmt, Object... args); } diff --git a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_.java b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_.java index 8b5bcdee6..951d3aaca 100644 --- a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_.java +++ b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_.java @@ -17,15 +17,20 @@ along with this program. If not, see . */ package gplx; public class Gfo_usr_dlg_ { - public static Gfo_usr_dlg I = Gfo_usr_dlg_null._; - public static final Gfo_usr_dlg Null = Gfo_usr_dlg_null._; + public static Gfo_usr_dlg I = Gfo_usr_dlg_noop._; // NOTE: global instance which can be reassigned + public static final Gfo_usr_dlg Noop = Gfo_usr_dlg_noop._; + public static Gfo_usr_dlg Test() { + if (test == null) + test = new Gfo_usr_dlg_base(Gfo_usr_dlg__log_.Noop, Gfo_usr_dlg__gui_.Test); + return test; + } private static Gfo_usr_dlg_base test; } -class Gfo_usr_dlg_null implements Gfo_usr_dlg { +class Gfo_usr_dlg_noop implements Gfo_usr_dlg { public boolean Canceled() {return false;} public void Canceled_y_() {} public void Canceled_n_() {} public void Cancel() {} public void Cancel_reset() {} public void Clear() {} - public Gfo_usr_dlg_ui Ui_wkr() {throw Err_.not_implemented_();} public void Ui_wkr_(Gfo_usr_dlg_ui v) {} - public Gfo_log_wtr Log_wtr() {throw Err_.not_implemented_();} public void Log_wtr_(Gfo_log_wtr v) {} + public Gfo_usr_dlg__log Log_wkr() {return Gfo_usr_dlg__log_.Noop;} public void Log_wkr_(Gfo_usr_dlg__log v) {} + public Gfo_usr_dlg__gui Gui_wkr() {return Gfo_usr_dlg__gui_.Noop;} public void Gui_wkr_(Gfo_usr_dlg__gui v) {} public String Log_many(String grp_key, String msg_key, String fmt, Object... args) {return "";} public String Warn_many(String grp_key, String msg_key, String fmt, Object... args) {return "";} public Err Fail_many(String grp_key, String msg_key, String fmt, Object... args) {return Err_.new_(fmt);} @@ -39,5 +44,5 @@ class Gfo_usr_dlg_null implements Gfo_usr_dlg { public String Log_direct(String msg) {return "";} public String Plog_many(String grp_key, String msg_key, String fmt, Object... args) {return "";} public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return this;} - public static final Gfo_usr_dlg_null _ = new Gfo_usr_dlg_null(); Gfo_usr_dlg_null() {} + public static final Gfo_usr_dlg_noop _ = new Gfo_usr_dlg_noop(); Gfo_usr_dlg_noop() {} } diff --git a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_ui.java b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__gui.java similarity index 95% rename from 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_ui.java rename to 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__gui.java index a063b3ae1..5a688eed3 100644 --- a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_ui.java +++ b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__gui.java @@ -17,7 +17,7 @@ along with this program. If not, see . */ package gplx; import gplx.core.strings.*; -public interface Gfo_usr_dlg_ui { +public interface Gfo_usr_dlg__gui { void Clear(); String_ring Prog_msgs(); void Write_prog(String text); diff --git a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_ui_.java b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__gui_.java similarity index 78% rename from 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_ui_.java rename to 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__gui_.java index c8f81b286..8d54f6543 100644 --- a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_ui_.java +++ b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__gui_.java @@ -17,12 +17,12 @@ along with this program. If not, see . */ package gplx; import gplx.core.strings.*; -public class Gfo_usr_dlg_ui_ { - public static final Gfo_usr_dlg_ui Null = new Gfo_usr_dlg_ui_null(); - public static final Gfo_usr_dlg_ui Console = new Gfo_usr_dlg_ui_console(); - public static final Gfo_usr_dlg_ui Test = new Gfo_usr_dlg_ui_test(); +public class Gfo_usr_dlg__gui_ { + public static final Gfo_usr_dlg__gui Noop = new Gfo_usr_dlg__gui_noop(); + public static final Gfo_usr_dlg__gui Console = new Gfo_usr_dlg__gui_console(); + public static final Gfo_usr_dlg__gui Test = new Gfo_usr_dlg__gui_test(); } -class Gfo_usr_dlg_ui_null implements Gfo_usr_dlg_ui { +class Gfo_usr_dlg__gui_noop implements Gfo_usr_dlg__gui { public void Clear() {} public String_ring Prog_msgs() {return ring;} String_ring ring = new String_ring().Max_(0); public void Write_prog(String text) {} @@ -30,7 +30,7 @@ class Gfo_usr_dlg_ui_null implements Gfo_usr_dlg_ui { public void Write_warn(String text) {} public void Write_stop(String text) {} } -class Gfo_usr_dlg_ui_console implements Gfo_usr_dlg_ui { +class Gfo_usr_dlg__gui_console implements Gfo_usr_dlg__gui { public void Clear() {} public String_ring Prog_msgs() {return ring;} String_ring ring = new String_ring().Max_(0); public void Write_prog(String text) {console.WriteTempText(text);} diff --git a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_ui_test.java b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__gui_test.java similarity index 94% rename from 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_ui_test.java rename to 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__gui_test.java index a8bfc39f9..3284956bd 100644 --- a/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_ui_test.java +++ b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__gui_test.java @@ -17,7 +17,7 @@ along with this program. If not, see . */ package gplx; import gplx.core.strings.*; -public class Gfo_usr_dlg_ui_test implements Gfo_usr_dlg_ui { +public class Gfo_usr_dlg__gui_test implements Gfo_usr_dlg__gui { public String[] Xto_str_ary() {return msgs.XtoStrAry();} public ListAdp Warns() {return warns;} public String_ring Prog_msgs() {return ring;} String_ring ring = new String_ring().Max_(0); diff --git a/100_core/src_420_usrMsg/gplx/Gfo_log_wtr.java b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__log.java similarity index 79% rename from 100_core/src_420_usrMsg/gplx/Gfo_log_wtr.java rename to 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__log.java index 946a283e5..665965b22 100644 --- a/100_core/src_420_usrMsg/gplx/Gfo_log_wtr.java +++ b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__log.java @@ -16,17 +16,16 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx; -public interface Gfo_log_wtr extends GfoInvkAble { - Io_url Session_dir(); - Io_url Log_dir(); void Log_dir_(Io_url v); - Io_url Session_fil(); +public interface Gfo_usr_dlg__log extends GfoInvkAble { boolean Enabled(); void Enabled_(boolean v); boolean Queue_enabled(); void Queue_enabled_(boolean v); + Io_url Log_dir(); void Log_dir_(Io_url v); + Io_url Session_dir(); + Io_url Session_fil(); void Log_msg_to_url_fmt(Io_url url, String fmt, Object... args); - void Log_msg_to_session(String txt); - void Log_msg_to_session_fmt(String fmt, Object... args); - void Log_msg_to_session_direct(String txt); - void Log_err(String txt); - void Init(); - void Term(); + void Log_to_session(String txt); + void Log_to_session_fmt(String fmt, Object... args); + void Log_to_session_direct(String txt); + void Log_to_err(String txt); + void Log_term(); } diff --git a/100_core/src_420_usrMsg/gplx/Gfo_log_wtr_.java b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__log_.java similarity index 76% rename from 100_core/src_420_usrMsg/gplx/Gfo_log_wtr_.java rename to 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__log_.java index 65892cf1b..63bcee8b9 100644 --- a/100_core/src_420_usrMsg/gplx/Gfo_log_wtr_.java +++ b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__log_.java @@ -16,21 +16,20 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx; -public class Gfo_log_wtr_ { - public static final Gfo_log_wtr Null = new Gfo_log_wtr_null(); +public class Gfo_usr_dlg__log_ { + public static final Gfo_usr_dlg__log Noop = new Gfo_usr_dlg__log_noop(); } -class Gfo_log_wtr_null implements Gfo_log_wtr { +class Gfo_usr_dlg__log_noop implements Gfo_usr_dlg__log { public Io_url Session_fil() {return Io_url_.Null;} public Io_url Session_dir() {return Io_url_.Null;} public Io_url Log_dir() {return Io_url_.Null;} public void Log_dir_(Io_url v) {} public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled; public boolean Queue_enabled() {return queue_enabled;} public void Queue_enabled_(boolean v) {queue_enabled = v;} private boolean queue_enabled; public void Log_msg_to_url_fmt(Io_url url, String fmt, Object... args) {} - public void Log_msg_to_session_fmt(String fmt, Object... args) {} - public void Log_msg_to_session(String txt) {} - public void Log_msg_to_session_direct(String txt) {} - public void Log_err(String txt) {} - public void Init() {} - public void Term() {} + public void Log_to_session_fmt(String fmt, Object... args) {} + public void Log_to_session(String txt) {} + public void Log_to_session_direct(String txt) {} + public void Log_to_err(String txt) {} + public void Log_term() {} public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return this;} } diff --git a/400_xowa/src_060_utl/gplx/Gfo_log_wtr_base.java b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__log_base.java similarity index 82% rename from 400_xowa/src_060_utl/gplx/Gfo_log_wtr_base.java rename to 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__log_base.java index 14792316c..e70c54a6d 100644 --- a/400_xowa/src_060_utl/gplx/Gfo_log_wtr_base.java +++ b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg__log_base.java @@ -17,7 +17,11 @@ along with this program. If not, see . */ package gplx; import gplx.core.strings.*; -public class Gfo_log_wtr_base implements Gfo_log_wtr { +public class Gfo_usr_dlg__log_base implements Gfo_usr_dlg__log { + private int archive_dirs_max = 8; + private Io_url log_dir, err_fil; + private OrderedHash queued_list = OrderedHash_.new_(); + private Bry_fmtr fmtr = Bry_fmtr.tmp_(); private Bry_bfr tmp_bfr = Bry_bfr.reset_(255); public boolean Queue_enabled() {return queue_enabled;} public void Queue_enabled_(boolean v) {queue_enabled = v; if (!v) this.Flush();} private boolean queue_enabled; public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled = true; public Io_url Session_dir() {return session_dir;} private Io_url session_dir; @@ -31,17 +35,15 @@ public class Gfo_log_wtr_base implements Gfo_log_wtr { } fil.Flush(); } - } private OrderedHash queued_list = OrderedHash_.new_(); + } public Io_url Log_dir() {return log_dir;} public void Log_dir_(Io_url log_dir) { this.log_dir = log_dir; session_dir = log_dir.GenSubDir(Dir_name_current); session_fil = session_dir.GenSubFil("session.txt"); err_fil = session_dir.GenSubFil("err.txt"); - } private Io_url log_dir, err_fil; - public void Init() { } - public void Term() { + public void Log_term() { if (!enabled) return; Io_url[] archive_dirs = Io_mgr._.QueryDir_args(log_dir).DirInclude_().DirOnly_().ExecAsUrlAry(); int archive_dirs_len = archive_dirs.length; @@ -49,30 +51,30 @@ public class Gfo_log_wtr_base implements Gfo_log_wtr { for (int i = 0; i < session_cutoff; i++) { Io_url archive_dir = archive_dirs[i]; Io_mgr._.DeleteDirDeep(archive_dir); - this.Log_msg_to_session("archive dir del: " + session_dir.Raw()); + this.Log_to_session("archive dir del: " + session_dir.Raw()); } - this.Log_msg_to_session("app term"); + this.Log_to_session("app term"); MoveCurrentToArchive(session_dir); - } int archive_dirs_max = 8; + } private void MoveCurrentToArchive(Io_url dir) {Io_mgr._.MoveDirDeep(dir, dir.OwnerDir().GenSubDir(DateAdp_.Now().XtoStr_fmt_yyyyMMdd_HHmmss_fff()));} + public void Log_info(boolean warn, String s) {if (warn) Log_to_err(s); else Log_to_session(s);} public void Log_msg_to_url_fmt(Io_url url, String fmt, Object... args) { if (!enabled) return; String msg = Bld_msg(String_.new_utf8_(fmtr.Fmt_(fmt).Bld_bry_many(tmp_bfr, args))); Log_msg(url, msg); Log_msg(session_fil, msg); - } private Bry_fmtr fmtr = Bry_fmtr.tmp_(); Bry_bfr tmp_bfr = Bry_bfr.reset_(255); - public void Log_info(boolean warn, String s) {if (warn) Log_err(s); else Log_msg_to_session(s);} - public void Log_msg_to_session_fmt(String fmt, Object... args) {Log_msg_to_session(String_.new_utf8_(fmtr.Fmt_(fmt).Bld_bry_many(tmp_bfr, args)));} - public void Log_msg_to_session(String s) { + } + public void Log_to_session_fmt(String fmt, Object... args) {Log_to_session(String_.new_utf8_(fmtr.Fmt_(fmt).Bld_bry_many(tmp_bfr, args)));} + public void Log_to_session(String s) { if (!enabled) return; String line = Bld_msg(s); Log_msg(session_fil, line); } - public void Log_msg_to_session_direct(String s) { + public void Log_to_session_direct(String s) { if (!enabled) return; Log_msg(session_fil, s); } - public void Log_err(String s) { + public void Log_to_err(String s) { if (!enabled) return; try { String line = Bld_msg(s); @@ -103,7 +105,7 @@ public class Gfo_log_wtr_base implements Gfo_log_wtr { return this; } public static final String Invk_enabled_ = "enabled_", Invk_archive_dirs_max_ = "archive_dirs_max_", Invk_log_dir_ = "log_dir_"; static final String Dir_name_log = "log", Dir_name_current = "current"; - public static final Gfo_log_wtr_base _ = new Gfo_log_wtr_base(); + public static final Gfo_usr_dlg__log_base _ = new Gfo_usr_dlg__log_base(); } class Usr_log_fil { public Usr_log_fil(Io_url url) {this.url = url;} diff --git a/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_base.java b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_base.java similarity index 61% rename from 400_xowa/src_060_utl/gplx/Gfo_usr_dlg_base.java rename to 100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_base.java index b5b97c5dd..70ee321b8 100644 --- a/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_base.java +++ b/100_core/src_420_usrMsg/gplx/Gfo_usr_dlg_base.java @@ -17,30 +17,30 @@ along with this program. If not, see . */ package gplx; public class Gfo_usr_dlg_base implements Gfo_usr_dlg { - private Bry_fmtr tmp_fmtr = Bry_fmtr.tmp_().Fail_when_invalid_escapes_(false); // do not fail b/c msgs may contain excerpt of random text; EX:[[User:A|~A~]] DATE:2014-11-28 - private Bry_bfr tmp_bfr = Bry_bfr.new_(); - public Gfo_usr_dlg_ui Ui_wkr() {return ui_wkr;} public void Ui_wkr_(Gfo_usr_dlg_ui v) {ui_wkr = v;} Gfo_usr_dlg_ui ui_wkr = Gfo_usr_dlg_ui_.Null; - public Gfo_log_wtr Log_wtr() {return log_wtr;} public void Log_wtr_(Gfo_log_wtr v) {log_wtr = v;} Gfo_log_wtr log_wtr; - @gplx.Virtual public void Clear() {ui_wkr.Clear();} + private final Bry_bfr tmp_bfr = Bry_bfr.reset_(255); + private final Bry_fmtr tmp_fmtr = Bry_fmtr.tmp_().Fail_when_invalid_escapes_(false); // do not fail b/c msgs may contain excerpt of random text; EX:[[User:A|~A~]] DATE:2014-11-28 + public Gfo_usr_dlg_base(Gfo_usr_dlg__log log_wkr, Gfo_usr_dlg__gui gui_wkr) {this.log_wkr = log_wkr; this.gui_wkr = gui_wkr;} + public Gfo_usr_dlg__log Log_wkr() {return log_wkr;} public void Log_wkr_(Gfo_usr_dlg__log v) {log_wkr = v;} private Gfo_usr_dlg__log log_wkr; + public Gfo_usr_dlg__gui Gui_wkr() {return gui_wkr;} public void Gui_wkr_(Gfo_usr_dlg__gui v) {gui_wkr = v;} private Gfo_usr_dlg__gui gui_wkr; public boolean Canceled() {return canceled;} public void Canceled_y_() {canceled = true;} public void Canceled_n_() {canceled = false;} private boolean canceled; public void Cancel() {canceled = true;} public void Cancel_reset() {canceled = false;} - public String Log_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); log_wtr.Log_msg_to_session(rv); return rv;} - public String Warn_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); log_wtr.Log_err(rv); ui_wkr.Write_warn(rv); return rv;} - public String Prog_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); ui_wkr.Write_prog(rv); return rv;} - public String Prog_one(String grp_key, String msg_key, String fmt, Object arg) {String rv = Bld_msg_one (grp_key, msg_key, fmt, arg ); ui_wkr.Write_prog(rv); return rv;} - public String Prog_none(String grp_key, String msg_key, String fmt) {String rv = Bld_msg_none(grp_key, msg_key, fmt ); ui_wkr.Write_prog(rv); return rv;} - public String Prog_direct(String msg) { ui_wkr.Write_prog(msg); return msg;} - public String Log_direct(String msg) { log_wtr.Log_msg_to_session(msg); return msg;} - public String Note_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); log_wtr.Log_msg_to_session(rv); ui_wkr.Write_note(rv); return rv;} - public String Note_none(String grp_key, String msg_key, String fmt) {String rv = Bld_msg_none(grp_key, msg_key, fmt ); log_wtr.Log_msg_to_session(rv); ui_wkr.Write_note(rv); return rv;} - public String Note_gui_none(String grp_key, String msg_key, String fmt) {String rv = Bld_msg_none(grp_key, msg_key, fmt ); ui_wkr.Write_note(rv); return rv;} + public String Log_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); log_wkr.Log_to_session(rv); return rv;} + public String Warn_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); log_wkr.Log_to_err(rv); gui_wkr.Write_warn(rv); return rv;} + public String Prog_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); gui_wkr.Write_prog(rv); return rv;} + public String Prog_one(String grp_key, String msg_key, String fmt, Object arg) {String rv = Bld_msg_one (grp_key, msg_key, fmt, arg ); gui_wkr.Write_prog(rv); return rv;} + public String Prog_none(String grp_key, String msg_key, String fmt) {String rv = Bld_msg_none(grp_key, msg_key, fmt ); gui_wkr.Write_prog(rv); return rv;} + public String Prog_direct(String msg) { gui_wkr.Write_prog(msg); return msg;} + public String Log_direct(String msg) { log_wkr.Log_to_session(msg); return msg;} + public String Note_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); log_wkr.Log_to_session(rv); gui_wkr.Write_note(rv); return rv;} + public String Note_none(String grp_key, String msg_key, String fmt) {String rv = Bld_msg_none(grp_key, msg_key, fmt ); log_wkr.Log_to_session(rv); gui_wkr.Write_note(rv); return rv;} + public String Note_gui_none(String grp_key, String msg_key, String fmt) {String rv = Bld_msg_none(grp_key, msg_key, fmt ); gui_wkr.Write_note(rv); return rv;} public String Plog_many(String grp_key, String msg_key, String fmt, Object... args) { String rv = Log_many(grp_key, msg_key, fmt, args); return Prog_direct(rv); } public Err Fail_many(String grp_key, String msg_key, String fmt, Object... args) { Err rv = Err_.new_(Bld_msg_many(grp_key, msg_key, fmt, args)); - log_wtr.Log_err(Err_.Message_gplx(rv)); + log_wkr.Log_to_err(Err_.Message_gplx(rv)); return rv; } private String Bld_msg_many(String grp_key, String msg_key, String fmt, Object[] args) { @@ -51,24 +51,5 @@ public class Gfo_usr_dlg_base implements Gfo_usr_dlg { tmp_fmtr.Fmt_(fmt).Bld_bfr_one(tmp_bfr, val); return tmp_bfr.Xto_str_and_clear(); } - private String Bld_msg_none(String grp_key, String msg_key, String fmt) { - return fmt; - } - private void Ui_wkr_parse(String s) { - if (String_.Eq(s, "null")) ui_wkr = Gfo_usr_dlg_ui_.Null; - else throw Err_.unhandled(s); - } - @gplx.Virtual public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { - if (ctx.Match(k, Invk_ui_wkr_)) Ui_wkr_parse(m.ReadStr("v")); - else return GfoInvkAble_.Rv_unhandled; - return this; - } private static final String Invk_ui_wkr_ = "ui_wkr_"; - public static Gfo_usr_dlg_base test_() { - if (Test == null) { - Test = new Gfo_usr_dlg_base(); - Test.Ui_wkr_(Gfo_usr_dlg_ui_.Test); - Test.Log_wtr_(Gfo_log_wtr_.Null); - } - return Test; - } private static Gfo_usr_dlg_base Test; + private String Bld_msg_none(String grp_key, String msg_key, String fmt) {return fmt;} } diff --git a/140_dbs/src/gplx/dbs/Db_conn.java b/140_dbs/src/gplx/dbs/Db_conn.java index a534f1319..e052e6f12 100644 --- a/140_dbs/src/gplx/dbs/Db_conn.java +++ b/140_dbs/src/gplx/dbs/Db_conn.java @@ -39,7 +39,7 @@ public class Db_conn { public void Env_db_attach(String alias, Io_url db_url) {engine.Env_db_attach(alias, db_url);} public void Env_db_detach(String alias) {engine.Env_db_detach(alias);} public void Env_vacuum() {Exec_sql_plog_ntx("vacuuming: url=" + this.Conn_info().Xto_api(), "VACUUM;");} - public void Ddl_create_tbl(Db_meta_tbl meta) {engine.Ddl_create_tbl(meta); engine.Ddl_create_idx(Gfo_usr_dlg_.Null, meta.Idxs());} + public void Ddl_create_tbl(Db_meta_tbl meta) {engine.Ddl_create_tbl(meta); engine.Ddl_create_idx(Gfo_usr_dlg_.Noop, meta.Idxs());} public void Ddl_create_idx(Db_meta_idx... idxs) {engine.Ddl_create_idx(Gfo_usr_dlg_.I, idxs);} public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... idxs) {engine.Ddl_create_idx(usr_dlg, idxs);} public void Ddl_append_fld(String tbl, Db_meta_fld fld) {engine.Ddl_append_fld(tbl, fld);} diff --git a/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine_.java b/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine_.java index 0b5195ca7..e8a738e21 100644 --- a/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine_.java +++ b/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine_.java @@ -64,7 +64,7 @@ public class Sqlite_engine_ { usr_dlg.Log_many("", "", "index created: ~{0} ~{1}", tbl, idx_sql); } } - public static void Idx_create(Db_conn p, Db_idx_itm... idxs) {Idx_create(Gfo_usr_dlg_.Null, p, "", idxs);} + public static void Idx_create(Db_conn p, Db_idx_itm... idxs) {Idx_create(Gfo_usr_dlg_.Noop, p, "", idxs);} public static void Idx_create(Gfo_usr_dlg usr_dlg, Db_conn p, String file_id, Db_idx_itm... idxs) { int len = idxs.length; for (int i = 0; i < len; i++) { diff --git a/150_gfui/src_200_ipt/gplx/gfui/IptKey_.java b/150_gfui/src_200_ipt/gplx/gfui/IptKey_.java index 9ccb1dc19..f679f2fed 100644 --- a/150_gfui/src_200_ipt/gplx/gfui/IptKey_.java +++ b/150_gfui/src_200_ipt/gplx/gfui/IptKey_.java @@ -19,7 +19,7 @@ package gplx.gfui; import gplx.*; import java.awt.event.KeyEvent; import gplx.core.primitives.*; public class IptKey_ { - private static EnmMgr enmMgr = EnmMgr.new_().BitRngBgn_(65536).BitRngEnd_(262144).Prefix_("key."); + private static EnmMgr enm_mgr = EnmMgr.new_().BitRngBgn_(65536).BitRngEnd_(262144).Prefix_("key."); public static IptKey[] Ary(IptKey... ary) {return ary;} public static final IptKey[] Ary_empty = new IptKey[0]; public static IptKey as_(Object obj) {return obj instanceof IptKey ? (IptKey)obj : null;} @@ -29,13 +29,13 @@ public class IptKey_ { int newVal = ary[0].Val(); for (int i = 1; i < ary.length; i++) newVal = Enm_.FlipInt(true, newVal, ary[i].Val()); - return getOrNew_(newVal); + return get_or_new_(newVal); } public static IptKey api_(int val) { - IptKey rv = (IptKey)enmMgr.Get(val); + IptKey rv = (IptKey)enm_mgr.Get(val); return (rv == null) ? new_(val, "key_" + Int_.Xto_str(val)) : rv; } - public static IptKey parse_(String raw) {return getOrNew_(enmMgr.GetVal(raw));} + public static IptKey parse_(String raw) {return get_or_new_(enm_mgr.GetVal(raw));} public static IptKey rdr_or_(DataRdr rdr, String key, IptKey or) { String val = rdr.ReadStrOr(key, ""); // NOTE: "" cannot be null, b/c nullRdr returns String.empty return (String_.Eq(val, "")) ? or : parse_(val); @@ -58,13 +58,13 @@ public class IptKey_ { list.Del(key); return (IptKey[])list.Xto_ary(IptKey.class); } - static IptKey getOrNew_(int val) { - IptKey rv = (IptKey)enmMgr.Get(val); - return (rv == null) ? new_(val, enmMgr.GetStr(val)) : rv; + private static IptKey get_or_new_(int val) { + IptKey rv = (IptKey)enm_mgr.Get(val); + return (rv == null) ? new_(val, enm_mgr.GetStr(val)) : rv; } static IptKey new_(int val, String name) { IptKey rv = new IptKey(val, String_.HasAtBgn(name, "key.") ? name : "key." + name); - enmMgr.RegObj(val, name, rv); + enm_mgr.RegObj(val, name, rv); return rv; } public static final int KeyCode_Shift = 65536, KeyCode_Ctrl = 131072, KeyCode_Alt = 262144; @@ -100,6 +100,7 @@ public class IptKey_ { , CloseBracket = new_(221, "closeBracket") , Quote = new_(222, "quote") , Shift = new_(KeyCode_Shift, "shift"), Ctrl = new_(KeyCode_Ctrl, "ctrl"), Alt = new_(KeyCode_Alt, "alt") + , Keypad_enter = new_(16777296, "keypad_enter") ; private static OrderedHash ui_str_hash; public static OrderedHash Ui_str_hash() { @@ -140,10 +141,13 @@ public class IptKey_ { boolean mod_c = Enm_.HasInt(val, IptKey_.Ctrl.Val()); if (mod_c) {mod_str += "c"; val = Enm_.FlipInt(Bool_.N, val, IptKey_.Ctrl.Val());} boolean mod_a = Enm_.HasInt(val, IptKey_.Alt.Val()); if (mod_a) {mod_str += "a"; val = Enm_.FlipInt(Bool_.N, val, IptKey_.Alt.Val());} boolean mod_s = Enm_.HasInt(val, IptKey_.Shift.Val()); if (mod_s) {mod_str += "s"; val = Enm_.FlipInt(Bool_.N, val, IptKey_.Shift.Val());} - if (String_.Len_gt_0(mod_str)) - rv = "mod." + mod_str + "+"; + if (String_.Len_gt_0(mod_str)) { + rv = "mod." + mod_str; + if (val == 0) return rv; // handle modifiers only, like "mod.cs"; else will be "mod.cs+key.#0" + rv += "+"; + } IptKey key = (IptKey)IptKey_.Ui_str_hash().Fetch(Int_obj_ref.new_(val)); - String key_str = key == null ? "key." + Int_.Xto_str(val) : key.Key(); + String key_str = key == null ? "key.#" + Int_.Xto_str(val) : key.Key(); return rv + key_str; } } diff --git a/150_gfui/src_200_ipt/gplx/gfui/IptKey__tst.java b/150_gfui/src_200_ipt/gplx/gfui/IptKey__tst.java index ed9d66883..76d51cc57 100644 --- a/150_gfui/src_200_ipt/gplx/gfui/IptKey__tst.java +++ b/150_gfui/src_200_ipt/gplx/gfui/IptKey__tst.java @@ -20,11 +20,20 @@ import org.junit.*; public class IptKey__tst { private final IptKey__fxt fxt = new IptKey__fxt(); @Test public void To_str() { - fxt.Test_to_str(196608, "mod.cs+key.0"); + fxt.Test_to_str(196608, "mod.cs"); + } + @Test public void To_str__numeric() { + fxt.Test_to_str(16777296, "key.#16777296"); + } + @Test public void parse_() { + fxt.Test_parse("key.#10", 10); } } class IptKey__fxt { public void Test_to_str(int keycode, String expd) { Tfds.Eq(expd, IptKey_.To_str(keycode)); } + public void Test_parse(String raw, int keycode) { + Tfds.Eq(keycode, IptKey_.parse_(raw).Val()); + } } diff --git a/150_gfui/src_300_gxw/gplx/gfui/Gxw_html.java b/150_gfui/src_300_gxw/gplx/gfui/Gxw_html.java index 585e8f73e..e29d33063 100644 --- a/150_gfui/src_300_gxw/gplx/gfui/Gxw_html.java +++ b/150_gfui/src_300_gxw/gplx/gfui/Gxw_html.java @@ -28,6 +28,7 @@ public interface Gxw_html extends GxwElem { boolean Html_doc_find(String id, String find, boolean dir_fwd, boolean case_match, boolean wrap_find); void Html_doc_body_focus(); void Html_doc_selection_focus_toggle(); + boolean Html_doc_loaded(); String Html_elem_atr_get_str (String id, String atr_key); boolean Html_elem_atr_get_bool (String id, String atr_key); boolean Html_elem_atr_set (String id, String atr_key, String val); diff --git a/150_gfui/src_420_box_basic/gplx/gfui/Gfui_html.java b/150_gfui/src_420_box_basic/gplx/gfui/Gfui_html.java index a94db326e..96227ea3b 100644 --- a/150_gfui/src_420_box_basic/gplx/gfui/Gfui_html.java +++ b/150_gfui/src_420_box_basic/gplx/gfui/Gfui_html.java @@ -47,6 +47,7 @@ public class Gfui_html extends GfuiElemBase { public String Html_active_atr_get_str(String atrKey, String or) {return under.Html_active_atr_get_str(atrKey, or);} public void Html_js_enabled_(boolean v) {under.Html_js_enabled_(v);} public void Html_js_eval_proc(String name, String... args) {under.Html_js_eval_proc(name, args);} + public boolean Html_doc_loaded() {return under.Html_doc_loaded();} public String Html_js_eval_script(String script) {return under.Html_js_eval_script(script);} public void Html_js_cbks_add(String js_func_name, GfoInvkAble invk) {under.Html_js_cbks_add(js_func_name, invk);} public void Html_invk_src_(GfoEvObj v) {under.Html_invk_src_(v);} diff --git a/150_gfui/src_420_box_basic/gplx/gfui/Gfui_html_cfg.java b/150_gfui/src_420_box_basic/gplx/gfui/Gfui_html_cfg.java index 5e8f5ff61..c7d2c3abd 100644 --- a/150_gfui/src_420_box_basic/gplx/gfui/Gfui_html_cfg.java +++ b/150_gfui/src_420_box_basic/gplx/gfui/Gfui_html_cfg.java @@ -25,6 +25,7 @@ public class Gfui_html_cfg implements GfoInvkAble { public String Doc_selected_get_href_or_text() {return Exec_fmt(fmtr_doc_selected_get_href_or_text);} private Bry_fmtr fmtr_doc_selected_get_href_or_text = Bry_fmtr.keys_(); public String Doc_selected_get_src_or_empty() {return Exec_fmt(fmtr_doc_selected_get_src_or_empty);} private Bry_fmtr fmtr_doc_selected_get_src_or_empty = Bry_fmtr.keys_(); public String Doc_selected_get_active_or_selection() {return Exec_fmt(fmtr_doc_selected_get_active_or_selection);} private Bry_fmtr fmtr_doc_selected_get_active_or_selection = Bry_fmtr.keys_(); + public String Doc_loaded() {return Exec_fmt(fmtr_doc_loaded);} private Bry_fmtr fmtr_doc_loaded = Bry_fmtr.keys_(); public String Doc_find_html(String find, boolean dir_fwd, boolean case_match, boolean wrap_find, boolean search_text_is_diff, int prv_find_bgn) { return Exec_fmt(fmtr_doc_find_html, find, Bool_.Xto_str_lower(dir_fwd), Bool_.Xto_str_lower(case_match), Bool_.Xto_str_lower(wrap_find), Bool_.Xto_str_lower(search_text_is_diff), Int_.Xto_str(prv_find_bgn)); } private Bry_fmtr fmtr_doc_find_html = Bry_fmtr.keys_("find_text", "dir_fwd", "case_match", "wrap_find", "find_text_is_diff", "prv_find_bgn"); @@ -74,6 +75,7 @@ public class Gfui_html_cfg implements GfoInvkAble { else if (ctx.Match(k, Invk_doc_selected_get_active_or_selection_)) fmtr_doc_selected_get_active_or_selection.Fmt_(m.ReadBry("v")); else if (ctx.Match(k, Invk_doc_find_html_)) fmtr_doc_find_html.Fmt_(m.ReadBry("v")); else if (ctx.Match(k, Invk_doc_find_edit_)) fmtr_doc_find_edit.Fmt_(m.ReadBry("v")); + else if (ctx.Match(k, Invk_doc_loaded_)) fmtr_doc_loaded.Fmt_(m.ReadBry("v")); else if (ctx.Match(k, Invk_elem_atr_get_)) fmtr_elem_atr_get.Fmt_(m.ReadBry("v")); else if (ctx.Match(k, Invk_elem_atr_get_toString_)) fmtr_elem_atr_get_toString.Fmt_(m.ReadBry("v")); else if (ctx.Match(k, Invk_elem_atr_set_)) fmtr_elem_atr_set.Fmt_(m.ReadBry("v")); @@ -102,7 +104,7 @@ public class Gfui_html_cfg implements GfoInvkAble { node_path.Val_(node_path_val); } public static final String Invk_debug_file_ = "debug_file_" - , Invk_doc_html_ = "doc_html_", Invk_doc_body_focus_ = "doc_body_focus_", Invk_doc_selection_focus_toggle_ = "doc_selection_focus_toggle_" + , Invk_doc_html_ = "doc_html_", Invk_doc_body_focus_ = "doc_body_focus_", Invk_doc_selection_focus_toggle_ = "doc_selection_focus_toggle_", Invk_doc_loaded_ = "doc_loaded" , Invk_doc_active_atr_get_ = "doc_active_atr_get_", Invk_doc_find_html_ = "doc_find_html_", Invk_doc_find_edit_ = "doc_find_edit_" , Invk_doc_selected_get_text_or_href_ = "doc_selected_get_text_or_href_", Invk_doc_selected_get_href_or_text_ = "doc_selected_get_href_or_text_", Invk_doc_selected_get_src_or_empty_ = "doc_selected_get_src_or_empty_", Invk_doc_selected_get_active_or_selection_ = "doc_selected_get_active_or_selection_" , Invk_win_print_preview_ = "win_print_preview_" diff --git a/150_gfui/src_700_env/gplx/gfui/Mem_html.java b/150_gfui/src_700_env/gplx/gfui/Mem_html.java index 8ee1ce4e1..d9b80e143 100644 --- a/150_gfui/src_700_env/gplx/gfui/Mem_html.java +++ b/150_gfui/src_700_env/gplx/gfui/Mem_html.java @@ -25,6 +25,7 @@ class Mem_html extends GxwTextMemo_lang implements Gxw_html { public String Htm public String Html_doc_selected_get_href_or_text() {return "";} public String Html_doc_selected_get_src_or_empty() {return "";} public String Html_doc_selected_get_active_or_selection() {return "";} + public boolean Html_doc_loaded() {return true;} public boolean Html_window_print_preview() {return false;} public void Html_invk_src_(GfoEvObj v) {} public String Html_elem_atr_get_str(String elem_id, String atr_key) { diff --git a/150_gfui/xtn/gplx/gfui/Swt_html.java b/150_gfui/xtn/gplx/gfui/Swt_html.java index 05c0b4cd4..47a3ee074 100644 --- a/150_gfui/xtn/gplx/gfui/Swt_html.java +++ b/150_gfui/xtn/gplx/gfui/Swt_html.java @@ -75,6 +75,7 @@ class Swt_html implements Gxw_html, Swt_control, FocusListener { public String Html_doc_selected_get_src_or_empty() {return Eval_script_as_str(kit.Html_cfg().Doc_selected_get_src_or_empty());} public String Html_doc_selected_get_active_or_selection() {return Eval_script_as_str(kit.Html_cfg().Doc_selected_get_active_or_selection());} public void Html_doc_body_focus() {Eval_script_as_exec(kit.Html_cfg().Doc_body_focus());} + public boolean Html_doc_loaded() {return Bool_.parse_((String)Eval_script(kit.Html_cfg().Doc_loaded()));} public void Html_doc_selection_focus_toggle() {Eval_script_as_exec(kit.Html_cfg().Doc_selection_focus_toggle());} public String Html_elem_atr_get_str(String elem_id, String atr_key) {return Eval_script_as_str(kit.Html_cfg().Elem_atr_get(elem_id, atr_key));} public boolean Html_elem_atr_get_bool(String elem_id, String atr_key) {return Bool_.parse_((String)Eval_script(kit.Html_cfg().Elem_atr_get_toString(elem_id, atr_key)));} diff --git a/400_xowa/src/gplx/core/html/parsers/Gfo_html_node.java b/400_xowa/src/gplx/core/html/parsers/Gfo_html_node.java new file mode 100644 index 000000000..7a0df0ba2 --- /dev/null +++ b/400_xowa/src/gplx/core/html/parsers/Gfo_html_node.java @@ -0,0 +1,24 @@ +/* +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 . +*/ +package gplx.core.html.parsers; import gplx.*; import gplx.core.*; import gplx.core.html.*; +class Gfo_html_node { + public Gfo_html_node(byte[] src, int bgn, int end) {this.src = src; this.bgn = bgn; this.end = end;} + public byte[] Src() {return src;} private final byte[] src; + public int Bgn() {return bgn;} private final int bgn; + public int End() {return end;} private final int end; +} diff --git a/400_xowa/src/gplx/core/html/parsers/Gfo_html_parser.java b/400_xowa/src/gplx/core/html/parsers/Gfo_html_parser.java new file mode 100644 index 000000000..740bc83a3 --- /dev/null +++ b/400_xowa/src/gplx/core/html/parsers/Gfo_html_parser.java @@ -0,0 +1,68 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.core.html.parsers; import gplx.*; import gplx.core.*; import gplx.core.html.*; +import gplx.core.btries.*; import gplx.core.primitives.*; +import gplx.xowa.*; +class Gfo_html_parser { + private final Gfo_msg_log msg_log = Gfo_msg_log.Test(); + private final Xop_xatr_parser xatr_parser = new Xop_xatr_parser(); + public void Parse(Gfo_html_wkr handler, byte[] src, int bgn, int end) { +// int src_len = src.length; +// int prv_pos = 0; +// int css_find_bgn_len = Css_find_bgn.length; +// byte[] protocol_prefix_bry = Bry_.new_utf8_(protocol_prefix); +// while (true) { +// int url_bgn = Bry_finder.Find_fwd(src, Css_find_bgn, prv_pos); if (url_bgn == Bry_.NotFound) break; // nothing left; stop +// url_bgn += css_find_bgn_len; +// int url_end = Bry_finder.Find_fwd(src, Byte_ascii.Quote, url_bgn, src_len); if (url_end == Bry_.NotFound) {usr_dlg.Warn_many("", "main_page.css_parse", "could not find css; pos='~{0}' text='~{1}'", url_bgn, String_.new_utf8_len_safe_(src, url_bgn, url_bgn + 32)); break;} +// byte[] css_url_bry = Bry_.Mid(src, url_bgn, url_end); +// css_url_bry = Bry_.Replace(css_url_bry, Css_amp_find, Css_amp_repl); // & -> & +// css_url_bry = url_encoder.Decode(css_url_bry); // %2C -> %7C -> | +// css_url_bry = Bry_.Add(protocol_prefix_bry, css_url_bry); +// rv.Add(String_.new_utf8_(css_url_bry)); +// prv_pos = url_end; +// } +// return rv.XtoStrAry(); + int src_len = src.length; int pos = 0; + while (pos < src_len) { + byte b = src[pos]; + switch (b) { + case Byte_ascii.Angle_bgn: + pos = Parse_node(handler, src, end, pos, pos + 1); + break; + default: + ++pos; + break; + } + } + } + private int Parse_node(Gfo_html_wkr handler, byte[] src, int end, int tkn_bgn, int tkn_end) { + int name_bgn = tkn_end; + int name_end = Bry_finder.Find_fwd_until_ws(src, name_bgn, end); + if (name_end == Bry_finder.Not_found) return end; // EOS; EX: "" + int node_end = Bry_finder.Find_fwd(src, Byte_ascii.Angle_end, name_end, end); + if (node_end == Bry_finder.Not_found) return end; // EOS; EX: ". +*/ +package gplx.core.html.parsers; import gplx.*; import gplx.core.*; import gplx.core.html.*; +interface Gfo_html_wkr { + Gfo_html_tkn Get_or_null(byte[] src, int bgn, int end); + void Process(Gfo_html_node node); +} diff --git a/400_xowa/src/gplx/core/html/parsers/Xob_html_tkn.java b/400_xowa/src/gplx/core/html/parsers/Xob_html_tkn.java new file mode 100644 index 000000000..8db3ee9a8 --- /dev/null +++ b/400_xowa/src/gplx/core/html/parsers/Xob_html_tkn.java @@ -0,0 +1,33 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.core.html.parsers; import gplx.*; import gplx.core.*; import gplx.core.html.*; +import gplx.xowa.*; +interface Gfo_html_tkn { + int Tid(); + byte[] Key(); + void Process(byte[] src, Xop_xatr_hash hash); +} +class Gfo_html_tkn_ { + public static final int Tid_link = 1; + public static final byte[] Key_link = Bry_.new_ascii_("link"); +} +class Gfo_html_tkn__link implements Gfo_html_tkn { + public int Tid() {return Gfo_html_tkn_.Tid_link;} + public byte[] Key() {return Gfo_html_tkn_.Key_link;} + @gplx.Virtual public void Process(byte[] src, Xop_xatr_hash hash) {} +} diff --git a/400_xowa/src/gplx/core/threads/Gfo_thread_pool.java b/400_xowa/src/gplx/core/threads/Gfo_thread_pool.java index dd20de9b6..f237f8753 100644 --- a/400_xowa/src/gplx/core/threads/Gfo_thread_pool.java +++ b/400_xowa/src/gplx/core/threads/Gfo_thread_pool.java @@ -21,7 +21,7 @@ public class Gfo_thread_pool implements GfoInvkAble { private ListAdp queue = ListAdp_.new_(); private GfoMsg run_msg = GfoMsg_.new_cast_(Invk_run_wkr); private boolean running = false; - public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} public Gfo_thread_pool Usr_dlg_(Gfo_usr_dlg v) {usr_dlg = v; return this;} private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Null; + public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} public Gfo_thread_pool Usr_dlg_(Gfo_usr_dlg v) {usr_dlg = v; return this;} private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Noop; public void Clear() {synchronized (thread_lock) {queue.Clear(); running = false;}} public Gfo_thread_pool Add_at_end(Gfo_thread_wkr wkr) { synchronized (thread_lock) {queue.Add(wkr);} diff --git a/400_xowa/src/gplx/fsdb/meta/Fsm_cfg_mgr.java b/400_xowa/src/gplx/fsdb/meta/Fsm_cfg_mgr.java index f2b847990..e7c6d6f28 100644 --- a/400_xowa/src/gplx/fsdb/meta/Fsm_cfg_mgr.java +++ b/400_xowa/src/gplx/fsdb/meta/Fsm_cfg_mgr.java @@ -24,7 +24,7 @@ public class Fsm_cfg_mgr { } public void Ctor_by_load() { Db_cfg_hash hash = Grps_get_or_load(Grp_core); - this.next_id = hash.Get(Key_next_id).To_int_or(-1); if (next_id == -1) throw Err_.new_("next_id not found in cfg"); + this.next_id = hash.Get(Key_next_id).To_int_or(-1); if (next_id == -1) throw Err_.new_("next_id not found in cfg; url={0}", tbl.Conn().Conn_info().Xto_api()); this.schema_thm_page = hash.Get(Key_schema_thm_page).To_yn_or_n(); this.patch__next_id = hash.Get(Key_patch__next_id).To_yn_or_n(); this.patch__page_gt_1 = hash.Get(Key_patch__page_gt_1).To_yn_or_n(); diff --git a/400_xowa/src/gplx/gfui/Gfui_bnd_parser.java b/400_xowa/src/gplx/gfui/Gfui_bnd_parser.java index 28eada9eb..011a758f2 100644 --- a/400_xowa/src/gplx/gfui/Gfui_bnd_parser.java +++ b/400_xowa/src/gplx/gfui/Gfui_bnd_parser.java @@ -46,8 +46,8 @@ public class Gfui_bnd_parser { private String Convert(boolean src_is_gfui, String src_str) { this.src = Bry_.new_utf8_(src_str); this.src_len = src.length; tkns.Clear(); mod_val = Mod_val_null; - int pos = 0; int itm_bgn = -1, itm_end = -1; - while (pos <= src_len) { // loop over bytes and break up tkns by symbols + int pos = 0; int itm_bgn = -1, itm_end = -1; boolean is_numeric = false; + while (pos <= src_len) { // loop over bytes and break up tkns by symbols byte b = pos == src_len ? Byte_ascii.NewLine: src[pos]; // treat eos as "\n" for purpose of separating tokens Gfui_bnd_tkn sym_tkn = null; switch (b) { @@ -68,6 +68,11 @@ public class Gfui_bnd_parser { itm_end = pos; ++pos; continue; + case Byte_ascii.Hash: + if (is_numeric) throw Err_.new_("multiple numeric symbols in keycode"); + is_numeric = true; + ++pos; + continue; default: // letter / number; continue if (itm_bgn == -1) // no word started; start it itm_bgn = pos; @@ -76,7 +81,8 @@ public class Gfui_bnd_parser { } if (itm_end == -1) // end not set by space; char before symbol is end itm_end = pos; - Process_sym(src_is_gfui, sym_tkn, itm_bgn, itm_end); + Process_sym(src_is_gfui, is_numeric, sym_tkn, itm_bgn, itm_end); + is_numeric = false; if (sym_tkn.Tid() == Gfui_bnd_tkn.Tid_sym_eos) break; else @@ -90,9 +96,21 @@ public class Gfui_bnd_parser { } return tmp_bfr.Xto_str_and_clear(); } - private void Process_sym(boolean src_is_gfui, Gfui_bnd_tkn sym_tkn, int itm_bgn, int itm_end) { + private void Process_sym(boolean src_is_gfui, boolean is_numeric, Gfui_bnd_tkn sym_tkn, int itm_bgn, int itm_end) { Hash_adp_bry regy = src_is_gfui ? gfui_regy : norm_regy; - Gfui_bnd_tkn tkn = (Gfui_bnd_tkn)regy.Get_by_mid(src, itm_bgn, itm_end); + Gfui_bnd_tkn tkn = null; + if (is_numeric) { // EX: "key.#10" or "#10" + int tkn_bgn = itm_bgn; + if (src_is_gfui) { // remove "key." in "key.#10" + tkn_bgn = Bry_finder.Move_fwd(src, Byte_ascii.Dot, itm_bgn, itm_end); + if (tkn_bgn == -1) throw Err_.new_("invalid keycode.dot: keycode={0}", Bry_.Mid(src, tkn_bgn, itm_end)); + ++tkn_bgn; // skip # + } + int keycode = Bry_.Xto_int_or(src, tkn_bgn, itm_end, -1); if (keycode == -1) throw Err_.new_("invalid keycode: keycode={0}", Bry_.Mid(src, tkn_bgn, itm_end)); + tkn = new Gfui_bnd_tkn(Gfui_bnd_tkn.Tid_key, keycode, Bry_.Empty, Bry_.Empty); + } + else + tkn = (Gfui_bnd_tkn)regy.Get_by_mid(src, itm_bgn, itm_end); if (tkn == null) return; int mod_adj = Mod_val_null; switch (tkn.Tid()) { @@ -103,7 +121,7 @@ public class Gfui_bnd_parser { case Gfui_bnd_tkn.Tid_mod_as: mod_adj = Gfui_bnd_tkn.Tid_mod_as; break; case Gfui_bnd_tkn.Tid_mod_ca: mod_adj = Gfui_bnd_tkn.Tid_mod_ca; break; case Gfui_bnd_tkn.Tid_mod_cas: mod_adj = Gfui_bnd_tkn.Tid_mod_cas; break; - case Gfui_bnd_tkn.Tid_key: break; + case Gfui_bnd_tkn.Tid_key: break; default: throw Err_.unhandled(tkn.Tid()); } switch (sym_tkn.Tid()) { @@ -187,6 +205,7 @@ public class Gfui_bnd_parser { Init_itm("key.tab", "Tab"); Init_itm("key.clear", "Clear"); Init_itm("key.enter", "Enter"); + Init_itm("key.keypad_enter", "Keypad Enter"); Init_itm("key.shiftKey", "ShiftKey"); Init_itm("key.ctrlKey", "CtrlKey"); Init_itm("key.altKey", "AltKey"); @@ -232,21 +251,30 @@ public class Gfui_bnd_parser { private void Init_itm(byte tid, String gfui, String norm) { byte[] gfui_bry = Bry_.new_utf8_(gfui); byte[] norm_bry = Bry_.new_utf8_(norm); - Gfui_bnd_tkn itm = new Gfui_bnd_tkn(tid, gfui_bry, norm_bry); + Gfui_bnd_tkn itm = new Gfui_bnd_tkn(tid, Gfui_bnd_tkn.Keycode_null, gfui_bry, norm_bry); gfui_regy.Add(gfui_bry, itm); norm_regy.Add_if_new(norm_bry, itm); } private static final int Mod_val_null = 0; public static Gfui_bnd_parser new_en_() {return new Gfui_bnd_parser().Init_en();} Gfui_bnd_parser() {} - private static Gfui_bnd_tkn new_sym_(byte tid, byte[] bry) {return new Gfui_bnd_tkn(tid, bry, bry);} - private static Gfui_bnd_tkn new_mod_(byte tid, String gfui, String norm) {return new Gfui_bnd_tkn(tid, Bry_.new_ascii_(gfui), Bry_.new_ascii_(norm));} + private static Gfui_bnd_tkn new_sym_(byte tid, byte[] bry) {return new Gfui_bnd_tkn(tid, Gfui_bnd_tkn.Keycode_null, bry, bry);} + private static Gfui_bnd_tkn new_mod_(byte tid, String gfui, String norm) {return new Gfui_bnd_tkn(tid, Gfui_bnd_tkn.Keycode_null, Bry_.new_ascii_(gfui), Bry_.new_ascii_(norm));} } class Gfui_bnd_tkn { - public Gfui_bnd_tkn(byte tid, byte[] gfui, byte[] norm) {this.tid = tid; this.bry_gfui = gfui; this.bry_norm = norm;} - public byte Tid() {return tid;} private byte tid; - public byte[] Bry_gfui() {return bry_gfui;} private byte[] bry_gfui; - public byte[] Bry_norm() {return bry_norm;} private byte[] bry_norm; + public Gfui_bnd_tkn(byte tid, int keycode, byte[] gfui, byte[] norm) { + this.tid = tid; this.keycode = keycode; ; this.bry_gfui = gfui; this.bry_norm = norm; + } + public byte Tid() {return tid;} private final byte tid; + public int Keycode() {return keycode;} private final int keycode; + public byte[] Bry_gfui() {return bry_gfui;} private final byte[] bry_gfui; + public byte[] Bry_norm() {return bry_norm;} private final byte[] bry_norm; public void Write(Bry_bfr bfr, boolean src_is_gfui) { + if (keycode != Gfui_bnd_tkn.Keycode_null) { + if (src_is_gfui) + bfr.Add(Bry_key_prefix); + bfr.Add_byte(Byte_ascii.Hash).Add_int_variable(keycode); + return; + } byte[] bry = src_is_gfui ? bry_gfui : bry_norm; switch (tid) { case Tid_mod_c: case Tid_mod_a: case Tid_mod_s: @@ -283,4 +311,6 @@ class Gfui_bnd_tkn { , Tid_sym_plus = 8 , Tid_sym_pipe = 9 , Tid_sym_comma = 10, Tid_sym_eos = 11 , Tid_key = 12 ; + public static final int Keycode_null = 0; + private static final byte[] Bry_key_prefix = Bry_.new_ascii_("key."); } diff --git a/400_xowa/src/gplx/gfui/Gfui_bnd_parser_tst.java b/400_xowa/src/gplx/gfui/Gfui_bnd_parser_tst.java index 9aca1417a..c89411cac 100644 --- a/400_xowa/src/gplx/gfui/Gfui_bnd_parser_tst.java +++ b/400_xowa/src/gplx/gfui/Gfui_bnd_parser_tst.java @@ -41,6 +41,10 @@ public class Gfui_bnd_parser_tst { fxt.Test_x_to_gfui("Ctrl + Shift + A" , "mod.cs+key.a"); fxt.Test_x_to_gfui("Ctrl + Alt + Shift + A" , "mod.cas+key.a"); } + @Test public void Keypad_enter() { + fxt.Test_x_to_norm("key.keypad_enter" , "Keypad Enter"); + fxt.Test_x_to_norm("mod.c+key.keypad_enter" , "Ctrl + Keypad Enter"); + } } class Gfui_bnd_parser_fxt { private Gfui_bnd_parser parser; diff --git a/400_xowa/src/gplx/xowa/Xoa_app.java b/400_xowa/src/gplx/xowa/Xoa_app.java index 2c2fcd63f..150fd7713 100644 --- a/400_xowa/src/gplx/xowa/Xoa_app.java +++ b/400_xowa/src/gplx/xowa/Xoa_app.java @@ -17,6 +17,7 @@ along with this program. If not, see . */ package gplx.xowa; import gplx.*; import gplx.xowa.apps.*; import gplx.xowa.apps.fsys.*; +import gplx.xowa.bldrs.css.*; import gplx.xowa.files.caches.*; import gplx.xowa.files.imgs.*; import gplx.xowa.urls.encoders.*; import gplx.xowa.wmfs.*; diff --git a/400_xowa/src/gplx/xowa/Xoa_app_.java b/400_xowa/src/gplx/xowa/Xoa_app_.java index 76ebccca6..814b29e7c 100644 --- a/400_xowa/src/gplx/xowa/Xoa_app_.java +++ b/400_xowa/src/gplx/xowa/Xoa_app_.java @@ -26,16 +26,14 @@ public class Xoa_app_ { boot_mgr.Run(args); } public static final String Name = "xowa"; - public static final String Version = "2.5.1.1"; + public static final String Version = "2.5.2.1"; public static String Build_date = "2012-12-30 00:00:00"; public static String Op_sys; public static String User_agent = ""; public static final Gfo_msg_grp Nde = Gfo_msg_grp_.prj_(Name); public static Gfo_usr_dlg usr_dlg_console_() { - Gfo_usr_dlg rv = new Gfo_usr_dlg_base(); - rv.Ui_wkr_(Gfo_usr_dlg_ui_.Console); - rv.Log_wtr_(new Gfo_log_wtr_base()); - rv.Log_wtr().Queue_enabled_(true); + Gfo_usr_dlg rv = new Gfo_usr_dlg_base(new Gfo_usr_dlg__log_base(), Gfo_usr_dlg__gui_.Console); + rv.Log_wkr().Queue_enabled_(true); return rv; } public static Gfo_usr_dlg Usr_dlg() {return usr_dlg;} public static void Usr_dlg_(Gfo_usr_dlg v) {usr_dlg = v;} private static Gfo_usr_dlg usr_dlg; @@ -45,7 +43,7 @@ public class Xoa_app_ { public static Xoa_gfs_mgr Gfs_mgr() {return gfs_mgr;} public static void Gfs_mgr_(Xoa_gfs_mgr v) {gfs_mgr = v;} private static Xoa_gfs_mgr gfs_mgr; } class Xoa_app_boot_mgr { - private Gfo_usr_dlg usr_dlg; private Gfo_log_wtr log_wtr; private String chkpoint = "null"; + private Gfo_usr_dlg usr_dlg; private Gfo_usr_dlg__log log_wtr; private String chkpoint = "null"; public void Run(String[] args) { try { if (!Init_env(args)) return; @@ -54,7 +52,7 @@ class Xoa_app_boot_mgr { } catch (Exception e) { String err_str = Err_.Message_gplx(e); - log_wtr.Log_err(err_str); + log_wtr.Log_to_err(err_str); ConsoleAdp._.WriteLine(err_str); if (log_wtr.Log_dir() == null) log_wtr.Log_dir_(Env_.AppUrl().OwnerDir().GenSubFil("xowa.log")); log_wtr.Queue_enabled_(false); @@ -62,12 +60,12 @@ class Xoa_app_boot_mgr { } private boolean Init_env(String[] args) { Gfo_usr_dlg_.I = usr_dlg = Xoa_app_.usr_dlg_console_(); - log_wtr = usr_dlg.Log_wtr(); log_wtr.Log_msg_to_session_fmt("env.init: version=~{0}", Xoa_app_.Version); + log_wtr = usr_dlg.Log_wkr(); log_wtr.Log_to_session_fmt("env.init: version=~{0}", Xoa_app_.Version); GfuiEnv_.Init_swt(args, Xoa_app_.class); Io_url jar_url = Env_.AppUrl(); Xoa_app_.Build_date = Io_mgr._.QueryFil(jar_url).ModifiedTime().XtoUtc().XtoStr_fmt("yyyy-MM-dd HH:mm"); - log_wtr.Log_msg_to_session_fmt("env.init: jar_url=~{0}; build_date=~{1}", jar_url.NameAndExt(), Xoa_app_.Build_date); - log_wtr.Log_msg_to_session_fmt("env.init: op_sys=~{0}", Op_sys.Cur().Xto_str()); + log_wtr.Log_to_session_fmt("env.init: jar_url=~{0}; build_date=~{1}", jar_url.NameAndExt(), Xoa_app_.Build_date); + log_wtr.Log_to_session_fmt("env.init: op_sys=~{0}", Op_sys.Cur().Xto_str()); chkpoint = "init_env"; return true; } @@ -142,7 +140,7 @@ class Xoa_app_boot_mgr { // init app Db_conn_bldr.I.Reg_default_sqlite(); app = new Xoae_app(usr_dlg, app_type, root_dir, wiki_dir, root_dir.GenSubDir("file"), user_dir, root_dir.GenSubDir_nest("user", "anonymous", "wiki"), Xoa_app_.Op_sys); - usr_dlg.Log_wtr().Queue_enabled_(false); log_wtr.Log_msg_to_session_fmt("app.init"); + usr_dlg.Log_wkr().Queue_enabled_(false); log_wtr.Log_to_session_fmt("app.init"); try { app.Sys_cfg().Lang_(System_lang()); if (launch_url != null) @@ -153,7 +151,7 @@ class Xoa_app_boot_mgr { app.Init_by_app(); chkpoint = "init_gfs"; } catch (Exception e) {usr_dlg.Warn_many("", "", "app init failed: ~{0} ~{1}", chkpoint, Err_.Message_gplx(e));} - app.Usr_dlg().Log_wtr_(app.Log_wtr()); // NOTE: log_wtr must be set for cmd-line (else process will fail); + app.Usr_dlg().Log_wkr_(app.Log_wtr()); // NOTE: log_wtr must be set for cmd-line (else process will fail); // run gfs gplx.xowa.users.prefs.Prefs_rename_mgr._.Check(app.User().Fsys_mgr().App_data_cfg_user_fil()); diff --git a/400_xowa/src/gplx/xowa/Xoa_app_fxt.java b/400_xowa/src/gplx/xowa/Xoa_app_fxt.java index 69277b5e6..52b0c22a3 100644 --- a/400_xowa/src/gplx/xowa/Xoa_app_fxt.java +++ b/400_xowa/src/gplx/xowa/Xoa_app_fxt.java @@ -25,8 +25,8 @@ public class Xoa_app_fxt { } public static Xoae_app app_(String op_sys, Io_url root_dir) { Io_url user_dir = root_dir.GenSubDir_nest("user", "test_user"); - Gfo_log_wtr_base._.Log_dir_(user_dir.GenSubDir_nest("tmp", "current")); - Xoae_app app = new Xoae_app(Gfo_usr_dlg_base.test_(), Xoa_app_type.Itm_cmd, root_dir, root_dir.GenSubDir("wiki"), root_dir.GenSubDir("file"), user_dir, root_dir.GenSubDir_nest("user", "anonymous", "wiki"), op_sys); + Gfo_usr_dlg__log_base._.Log_dir_(user_dir.GenSubDir_nest("tmp", "current")); + Xoae_app app = new Xoae_app(Gfo_usr_dlg_.Test(), Xoa_app_type.Itm_cmd, root_dir, root_dir.GenSubDir("wiki"), root_dir.GenSubDir("file"), user_dir, root_dir.GenSubDir_nest("user", "anonymous", "wiki"), op_sys); app.Setup_mgr().Dump_mgr().Data_storage_format_(gplx.ios.Io_stream_.Tid_raw); // TEST: set data_storage_format to file, else bldr tests will fails (expects plain text) GfsCore._.Clear(); // NOTE: must clear GfsCore._.AddCmd(app, Xoae_app.Invk_app); // NOTE: must add app to GfsCore; app.Gfs_mgr() always adds current app to GfsCore; note this causes old test to leave behind GfsCore for new test diff --git a/400_xowa/src/gplx/xowa/Xoae_app.java b/400_xowa/src/gplx/xowa/Xoae_app.java index b334c641b..2c3525e63 100644 --- a/400_xowa/src/gplx/xowa/Xoae_app.java +++ b/400_xowa/src/gplx/xowa/Xoae_app.java @@ -19,6 +19,7 @@ package gplx.xowa; import gplx.*; import gplx.core.btries.*; import gplx.core.flds.*; import gplx.ios.*; import gplx.core.threads.*; import gplx.xowa.apps.*; import gplx.xowa.apps.caches.*; import gplx.xowa.apps.fsys.*; import gplx.xowa.apis.*; import gplx.xowa.urls.encoders.*; import gplx.xowa.apps.progs.*; import gplx.xowa.langs.*; import gplx.xowa.specials.*; import gplx.xowa.cfgs2.*; +import gplx.xowa.bldrs.css.*; import gplx.xowa.files.caches.*; import gplx.xowa.files.imgs.*; import gplx.xowa.wikis.*; import gplx.xowa.users.*; import gplx.xowa.gui.*; import gplx.xowa.cfgs.*; import gplx.xowa.ctgs.*; import gplx.xowa.html.tocs.*; import gplx.xowa.fmtrs.*; import gplx.xowa.html.*; import gplx.xowa.html.wtrs.*; @@ -32,7 +33,7 @@ public class Xoae_app implements Xoa_app, GfoInvkAble { this.app_type = app_type; Io_url.Http_file_str_encoder = Xoa_app_.Utl__encoder_mgr().Fsys(); fsys_mgr = new Xoa_fsys_mgr(bin_dir_name, root_dir, wiki_dir, file_dir, css_dir); - log_wtr = usr_dlg.Log_wtr(); + log_wtr = usr_dlg.Log_wkr(); cfg_mgr = new Xoa_cfg_mgr(this); api_root = new Xoapi_root(this); user = new Xou_user(this, user_dir); @@ -84,7 +85,7 @@ public class Xoae_app implements Xoa_app, GfoInvkAble { public Xoapi_root Api_root() {return api_root;} private Xoapi_root api_root; public Xop_tkn_mkr Tkn_mkr() {return tkn_mkr;} private Xop_tkn_mkr tkn_mkr = new Xop_tkn_mkr(); public Gfo_usr_dlg Usr_dlg() {return Xoa_app_.Usr_dlg();} - public Gfo_log_wtr Log_wtr() {return log_wtr;} private Gfo_log_wtr log_wtr; + public Gfo_usr_dlg__log Log_wtr() {return log_wtr;} private Gfo_usr_dlg__log log_wtr; public Xoa_gfs_mgr Gfs_mgr() {return Xoa_app_.Gfs_mgr();} public Xoa_special_mgr Special_mgr() {return special_mgr;} private Xoa_special_mgr special_mgr = new gplx.xowa.specials.Xoa_special_mgr(); public Xoh_html_mgr Html_mgr() {return html_mgr;} private Xoh_html_mgr html_mgr; @@ -131,7 +132,6 @@ public class Xoae_app implements Xoa_app, GfoInvkAble { stage = Xoa_stage_.Tid_init; prog_mgr.Init_by_app(url_cmd_eval); xtn_mgr.Init_by_app(this); - log_wtr.Init(); gui_mgr.Init_by_app(); user.Init_by_app(this); file_mgr.Init_by_app(this); @@ -162,7 +162,7 @@ public class Xoae_app implements Xoa_app, GfoInvkAble { if (!gui_mgr.Browser_win().Tab_mgr().Tabs__pub_close_all()) return false; gui_mgr.Browser_win().Usr_dlg().Canceled_y_(); user.App_term(); usr_dlg.Log_many("", "", "term:app_term"); - log_wtr.Term(); usr_dlg.Log_many("", "", "term:log_wtr"); + log_wtr.Log_term(); usr_dlg.Log_many("", "", "term:log_wtr"); log_mgr.Rls(); usr_dlg.Log_many("", "", "term:log_mgr"); if (Scrib_core.Core() != null) {Scrib_core.Core().Term(); usr_dlg.Log_many("", "", "term:scrib");} wiki_mgr.Rls(); usr_dlg.Log_many("", "", "term:wiki_mgr"); diff --git a/400_xowa/src/gplx/xowa/apis/xowa/gui/browsers/Xoapi_info.java b/400_xowa/src/gplx/xowa/apis/xowa/gui/browsers/Xoapi_info.java index f7026567b..aa6d6f2cd 100644 --- a/400_xowa/src/gplx/xowa/apis/xowa/gui/browsers/Xoapi_info.java +++ b/400_xowa/src/gplx/xowa/apis/xowa/gui/browsers/Xoapi_info.java @@ -17,11 +17,11 @@ along with this program. If not, see . */ package gplx.xowa.apis.xowa.gui.browsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.apis.*; import gplx.xowa.apis.xowa.*; import gplx.xowa.apis.xowa.gui.*; import gplx.gfui.*; import gplx.xowa.gui.views.*; -public class Xoapi_info implements Gfo_usr_dlg_ui_opt, GfoInvkAble { +public class Xoapi_info implements Gfo_usr_dlg__gui__opt, GfoInvkAble { public void Init_by_kit(Xoae_app app) {this.app = app;} private Xoae_app app; private Xog_win_itm Win() {return app.Gui_mgr().Browser_win();} public void Focus() {this.Win().Info_box().Focus();} - public void Clear() {app.Usr_dlg().Ui_wkr().Clear();} + public void Clear() {app.Usr_dlg().Gui_wkr().Clear();} public void Launch() { Io_url session_fil = app.Log_wtr().Session_fil(); app.Prog_mgr().App_view_text().Run(session_fil); diff --git a/400_xowa/src/gplx/xowa/apps/Xoa_gfs_mgr.java b/400_xowa/src/gplx/xowa/apps/Xoa_gfs_mgr.java index d5161db0a..fdcc2097b 100644 --- a/400_xowa/src/gplx/xowa/apps/Xoa_gfs_mgr.java +++ b/400_xowa/src/gplx/xowa/apps/Xoa_gfs_mgr.java @@ -48,7 +48,7 @@ public class Xoa_gfs_mgr implements GfoInvkAble, GfoInvkRootWkr { public Gfs_wtr Wtr() {return wtr;} private Gfs_wtr wtr = new Gfs_wtr(); public void Run_url(Io_url url) { Run_url_for(GfsCore._.Root(), url); - Gfo_usr_dlg_.I.Log_wtr().Log_msg_to_session_fmt("gfs.done: ~{0}", url.Raw()); + Gfo_usr_dlg_.I.Log_wkr().Log_to_session_fmt("gfs.done: ~{0}", url.Raw()); } public void Run_url_for(GfoInvkAble invk, Io_url url) { String raw = Io_mgr._.LoadFilStr_args(url).MissingIgnored_().Exec(); if (String_.Len_eq_0(raw)) return; diff --git a/400_xowa/src/gplx/xowa/apps/setups/Xoa_setup_mgr_tst.java b/400_xowa/src/gplx/xowa/apps/setups/Xoa_setup_mgr_tst.java index e9d4a2ffc..3b42692bf 100644 --- a/400_xowa/src/gplx/xowa/apps/setups/Xoa_setup_mgr_tst.java +++ b/400_xowa/src/gplx/xowa/apps/setups/Xoa_setup_mgr_tst.java @@ -30,7 +30,7 @@ class Xoa_setup_mgr_fxt { public void Test_delete_old_dir(String dir_str, String version_prv, String version_del, boolean expd) { Io_url dir = Io_url_.new_fil_(dir_str); Io_mgr._.CreateDirIfAbsent(dir); - Xoa_setup_mgr.Delete_old_dir(Gfo_usr_dlg_.Null, version_prv, version_del, dir); + Xoa_setup_mgr.Delete_old_dir(Gfo_usr_dlg_.Noop, version_prv, version_del, dir); Tfds.Eq(expd, !Io_mgr._.ExistsDir(dir), version_prv + "|" + version_del); } } diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_init_base.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_init_base.java index b0df293bf..2e8213e86 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_init_base.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_init_base.java @@ -17,6 +17,7 @@ along with this program. If not, see . */ package gplx.xowa.bldrs.cmds.texts; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.cmds.*; import gplx.xowa.wikis.*; import gplx.xowa.xtns.wdatas.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.xmls.*; +import gplx.xowa.bldrs.css.*; public abstract class Xob_init_base implements Xob_cmd, GfoInvkAble { private Xob_bldr bldr; private Xowe_wiki wiki; private Gfo_usr_dlg usr_dlg; private byte wbase_enabled = Bool_.__byte; diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_search_base.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_search_base.java index f17495dfd..c34de6dc6 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_search_base.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_search_base.java @@ -35,22 +35,22 @@ public abstract class Xob_search_base extends Xob_itm_dump_base implements Xobd_ public void Wkr_run(Xowd_page_itm page) { // if (page.Ns_id() != Xow_ns_.Id_main) return; // limit to main ns for now try { - byte[] ttl = page.Ttl_page_db(); - byte[][] words = Split_ttl_into_words(lang, list, dump_bfr, ttl); - Xob_tmp_wtr wtr = tmp_wtr_mgr.Get_or_new(ns_main == null ? page.Ns() : ns_main); - int words_len = words.length; - int row_len = 0; - for (int i = 0; i < words_len; i++) { - byte[] word = words[i]; - row_len += word.length + 13; // 13=5(id) + 5(page_len) + 3(dlms) - } - if (wtr.FlushNeeded(row_len)) wtr.Flush(bldr.Usr_dlg()); - for (int i = 0; i < words_len; i++) { - byte[] word = words[i]; - wtr.Bfr() .Add(word) .Add_byte(Byte_ascii.Pipe) - .Add_base85_len_5(page.Id()) .Add_byte(Byte_ascii.Semic) - .Add_base85_len_5(page.Text().length) .Add_byte(Byte_ascii.NewLine); - } + byte[] ttl = page.Ttl_page_db(); + byte[][] words = Split_ttl_into_words(lang, list, dump_bfr, ttl); + Xob_tmp_wtr wtr = tmp_wtr_mgr.Get_or_new(ns_main == null ? page.Ns() : ns_main); + int words_len = words.length; + int row_len = 0; + for (int i = 0; i < words_len; i++) { + byte[] word = words[i]; + row_len += word.length + 13; // 13=5(id) + 5(page_len) + 3(dlms) + } + if (wtr.FlushNeeded(row_len)) wtr.Flush(bldr.Usr_dlg()); + for (int i = 0; i < words_len; i++) { + byte[] word = words[i]; + wtr.Bfr() .Add(word) .Add_byte(Byte_ascii.Pipe) + .Add_base85_len_5(page.Id()) .Add_byte(Byte_ascii.Semic) + .Add_base85_len_5(page.Text().length) .Add_byte(Byte_ascii.NewLine); + } } catch (Exception e) {bldr.Usr_dlg().Warn_many("", "", "search_index:fatal error: err=~{0}", Err_.Message_gplx_brief(e));} // never let single page crash entire import } public void Wkr_end() { diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_word_parser.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_word_parser.java deleted file mode 100644 index 2bc11001d..000000000 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_word_parser.java +++ /dev/null @@ -1,118 +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 . -*/ -package gplx.xowa.bldrs.cmds.texts; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.cmds.*; -import gplx.core.btries.*; import gplx.xowa.langs.cases.*; -class Xob_word_parser { - private final Btrie_slim_mgr trie = Btrie_slim_mgr.cs_(); - private final Bry_bfr bfr = Bry_bfr.new_(32); - private Xob_word_mgr word_mgr; private Xol_case_mgr case_mgr; - private byte[] src; // private int bgn, end, src_len; - private boolean dirty; private int word_bgn; - public void Init_for_ttl(Xob_word_mgr word_mgr, Xol_case_mgr case_mgr) { - this.word_mgr = word_mgr; this.case_mgr = case_mgr; - trie.Clear(); - Init_tkn(Xob_word_tkn.new_(" ").Split_y_()); - Init_tkn(Xob_word_tkn.new_("_").Split_y_()); - Init_tkn(Xob_word_tkn.new_("..").Split_y_().Extend_y_()); - } - private void Init_tkn(Xob_word_tkn tkn) {trie.Add_obj(tkn.Key(), tkn);} - private void Mgr__add(int word_end) { - byte[] word = dirty ? bfr.Xto_bry_and_clear() : Bry_.Mid(src, word_bgn, word_end); - word_mgr.Add(word); - word_bgn = -1; - } - public void Parse(byte[] src, int bgn, int end, int src_len) { - this.src = src; // this.bgn = bgn; this.end = end; this.src_len = src_len; - this.dirty = false; this.word_bgn = -1; - this.src = case_mgr.Case_build_lower(src); - int pos = bgn; - while (true) { - boolean add_to_word = false; - boolean is_last = pos == end; - if (is_last) { // do split - Mgr__add(end); - break; - } - byte b = src[pos]; - Object o = trie.Match_bgn_w_byte(b, src, pos, end); - int new_pos = -1; - if (o == null) { // unknown sequence; word-char - add_to_word = true; - new_pos = pos + 1; - } - else { - int tkn_end = trie.Match_pos(); - Xob_word_tkn tkn = (Xob_word_tkn)o; - if (tkn.Split()) { // "A b" -> "A", "b" - add_to_word = false; - if (word_bgn != -1) // handle sequences like "... " where "..." sets word_bgn to -1 - Mgr__add(pos); - tkn_end = Bry_finder.Find_fwd_while(src, tkn_end, end, tkn.Key_last_byte()); - if (tkn.Extend()) { - word_bgn = pos; - Mgr__add(tkn_end); - } - pos = tkn_end; - continue; - } - add_to_word = true; - new_pos = tkn_end; - } - if (add_to_word) { - if (dirty) - bfr.Add_byte(src[pos]); - else { - if (word_bgn == -1) - word_bgn = pos; - } - } - pos = new_pos; - } - } -} -class Xob_word_tkn { - public Xob_word_tkn(byte[] key) {this.key = key; this.key_last_byte = key[key.length - 1];} - public byte[] Key() {return key;} private final byte[] key; - public byte Key_last_byte() {return key_last_byte;} private final byte key_last_byte; - public boolean Split() {return split;} public Xob_word_tkn Split_y_() {split = true; return this;} private boolean split; - public boolean Extend() {return extend;} public Xob_word_tkn Extend_y_() {extend = true; return this;} private boolean extend; - public static Xob_word_tkn new_(String v) {return new Xob_word_tkn(Bry_.new_utf8_(v));} -} -class Xob_word_mgr { - private final OrderedHash hash = OrderedHash_.new_bry_(); - public void Clear() {hash.Clear();} - public int Len() {return hash.Count();} - public Xob_word_itm Get_at(int i) {return (Xob_word_itm)hash.FetchAt(i);} - public void Add(byte[] word) { - Xob_word_itm itm = (Xob_word_itm)hash.Fetch(word); - if (itm == null) { - itm = new Xob_word_itm(word); - hash.Add(word, itm); - } - itm.Count_add_1_(); - } -} -class Xob_word_itm { - public Xob_word_itm(byte[] word) { - this.word = word; - this.count = 0; - } - public byte[] Word() {return word;} private final byte[] word; - public int Count() {return count;} private int count; public void Count_add_1_() {++count;} - @gplx.Internal protected Xob_word_itm Count_(int v) {this.count = v; return this;} -} diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_word_parser_tst.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_word_parser_tst.java deleted file mode 100644 index 2c3291616..000000000 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/Xob_word_parser_tst.java +++ /dev/null @@ -1,102 +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 . -*/ -package gplx.xowa.bldrs.cmds.texts; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.cmds.*; -import org.junit.*; import gplx.xowa.langs.cases.*; -public class Xob_word_parser_tst { - private final Xob_word_parser_fxt fxt = new Xob_word_parser_fxt(); - @Before public void init() {fxt.Init();} - @Test public void Basic_1() { - fxt.Clear().Test_split("abcd", "abcd"); - } - @Test public void Basic_many() { - fxt.Clear().Test_split("abc d ef", "abc", "d", "ef"); - } - @Test public void Split_many() { - fxt.Clear().Test_split("a b", "a", "b"); - } - @Test public void Lowercase() { - fxt.Clear().Test_split("A B C", "a", "b", "c"); - } - @Test public void Dupe() { - fxt.Clear().Test_split("a a a", fxt.Make_word("a", 3)); - } - @Test public void Dupe_lowercase() { - fxt.Clear().Test_split("a A", fxt.Make_word("a", 2)); - } - @Test public void Dot_acronym() { // EX: "History of U.S.A. Science " - fxt.Clear().Test_split("abc D.E.F. ghi", "abc", "d.e.f.", "ghi"); - } - @Test public void Dot_name() { // EX: "H. G. Wells" - fxt.Clear().Test_split("a. b. last", "a.", "b.", "last"); - } - @Test public void Dot_internet() { // EX: "en.wikipedia.org" - fxt.Clear().Test_split("a.com", "a.com"); - } - @Test public void Dot_ellipsis() { // EX: "Nights into Dreams..." - fxt.Clear().Test_split("a... bc d", "a", "...", "bc", "d"); - } -// tst_Split("a-b.c", "a", "b", "c"); -// tst_Split("a A", "a"); -// tst_Split("a_b", "a", "b"); -// tst_Split("a (b)", "a", "b"); -} -class Xob_word_parser_fxt { - private final Xob_word_parser word_parser = new Xob_word_parser(); - private final Xob_word_mgr word_mgr = new Xob_word_mgr(); - private final Bry_bfr tmp_bfr = Bry_bfr.new_(32); - private Xol_case_mgr case_mgr; - public void Init() { - case_mgr = Xol_case_mgr_.Ascii(); - word_parser.Init_for_ttl(word_mgr, case_mgr); - } - public Xob_word_parser_fxt Clear() { - word_mgr.Clear(); - return this; - } - public Xob_word_itm Make_word(String raw, int count) {return new Xob_word_itm(Bry_.new_utf8_(raw)).Count_(count);} - public void Test_split(String src, String... expd_words) { - int len = expd_words.length; - Xob_word_itm[] ary = new Xob_word_itm[len]; - for (int i = 0; i < len; ++i) { - ary[i] = Make_word(expd_words[i], 1); - } - Test_split(src, ary); - } - public void Test_split(String src, Xob_word_itm... expd_words) { - byte[] src_bry = Bry_.new_utf8_(src); - word_parser.Parse(src_bry, 0, src_bry.length, src_bry.length); - Tfds.Eq_str_lines(To_str(expd_words), To_str(word_mgr)); - } - private String To_str(Xob_word_itm[] word_ary) { - int len = word_ary.length; - for (int i = 0; i < len; ++i) { - if (i != 0) tmp_bfr.Add_byte_nl(); - Xob_word_itm word = word_ary[i]; - tmp_bfr.Add(word.Word()).Add_byte_pipe(); - tmp_bfr.Add_int_variable(word.Count()); - } - return tmp_bfr.Xto_str_and_clear(); - } - private String To_str(Xob_word_mgr word_mgr) { - int len = word_mgr.Len(); - Xob_word_itm[] ary = new Xob_word_itm[len]; - for (int i = 0; i < len; ++i) - ary[i] = word_mgr.Get_at(i); - return To_str(ary); - } -} diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_css_cmd.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_css_cmd.java index dd9cdb35b..ff5151929 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_css_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_css_cmd.java @@ -36,7 +36,7 @@ public class Xob_css_cmd implements Xob_cmd { core_db.Tbl__css_core().Create_tbl(); core_db.Tbl__css_file().Create_tbl(); gplx.xowa.html.css.Xowd_css_core_mgr.Set(core_db.Tbl__css_core(), core_db.Tbl__css_file(), css_dir, css_key); - core_db.Tbl__cfg().Update_yn(Xow_cfg_consts.Grp__wiki_schema, Xowd_db_file_schema_props.Key__tbl_css_core, Bool_.Y); + core_db.Tbl__cfg().Upsert_yn(Xow_cfg_consts.Grp__wiki_schema, Xowd_db_file_schema_props.Key__tbl_css_core, Bool_.Y); core_db.Conn().Txn_end(); usr_dlg.Plog_many("", "", Cmd_key() + ":end;"); } diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_cmd.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_cmd.java index be5b833fb..aa50845ba 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_cmd.java @@ -25,7 +25,7 @@ public class Xob_search_sql_cmd extends Xob_itm_basic_base implements Xob_cmd { public void Cmd_bgn(Xob_bldr bldr) {} public void Cmd_run() {this.Exec(wiki);} public void Cmd_end() {} - public void Cmd_term() {} + public void Cmd_term() {} public void Exec(Xowe_wiki wiki) { if (!Env_.Mode_testing()) wiki.Init_assert(); Xowd_db_mgr db_mgr = wiki.Db_mgr_as_sql().Core_data_mgr(); diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr.java index 6fababcc8..d12302e7c 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr.java @@ -54,3 +54,40 @@ public class Xob_search_sql_wkr extends Xob_search_base implements Io_make_cmd { search_word_tbl.Ddl__page_count__cfg(search_db.Tbl__cfg()); } } +class Xob_search_wkr extends Xob_itm_basic_base implements Xobd_wkr { + private Xowd_db_file search_db; private Xowd_search_temp_tbl search_temp_tbl; + private Xol_lang lang; private final Bry_bfr tmp_bfr = Bry_bfr.new_(255); private final OrderedHash list = OrderedHash_.new_bry_(); + public String Wkr_key() {return Xob_cmd_keys.Key_text_search_wkr;} + public void Wkr_ini(Xob_bldr bldr) {} + public void Wkr_bgn(Xob_bldr bldr) { + if (!Env_.Mode_testing()) wiki.Init_assert(); + this.lang = wiki.Lang(); + Xowd_db_mgr db_mgr = wiki.Db_mgr_as_sql().Core_data_mgr(); + this.search_db = Xob_search_sql_cmd.Dbs__get_or_make(db_mgr); + this.search_temp_tbl = new Xowd_search_temp_tbl(search_db.Conn(), db_mgr.Props().Schema_is_1()); + search_temp_tbl.Create_tbl(); + search_temp_tbl.Insert_bgn(); + } + public void Wkr_run(Xowd_page_itm page) { + try { + int page_id = page.Id(); + byte[] ttl = page.Ttl_page_db(); + byte[][] words = Xob_search_base.Split_ttl_into_words(lang, list, tmp_bfr, ttl); + int len = words.length; + for (int i = 0; i < len; ++i) { + byte[] word = words[i]; + search_temp_tbl.Insert_cmd_by_batch(page_id, word); + } + } catch (Exception e) {bldr.Usr_dlg().Warn_many("", "", "search_index:fatal error: err=~{0}", Err_.Message_gplx_brief(e));} // never let single page crash entire import + } + public void Wkr_end() { + search_temp_tbl.Make_data(usr_dlg, search_db.Tbl__search_link(), search_db.Tbl__search_word()); + search_temp_tbl.Insert_end(); + } + public void Wkr_print() {} + @Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { + if (ctx.Match(k, Invk_set)) {} + else return GfoInvkAble_.Rv_unhandled; + return this; + } private static final String Invk_set = "set"; +} diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/tdbs/Xob_tst.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/tdbs/Xob_tst.java index ae1b8d431..505ce3d09 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/tdbs/Xob_tst.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/tdbs/Xob_tst.java @@ -174,7 +174,7 @@ public class Xob_tst { Io_mgr._.SaveFilStr(url, raw); Xotdb_page_raw_parser parser = new Xotdb_page_raw_parser(); Xowe_wiki wiki = Xoa_app_fxt.wiki_tst_(app); - parser.Load(Gfo_usr_dlg_base.test_(), wiki, new Xow_ns(Xow_ns_.Id_template, Xow_ns_case_.Id_1st, Bry_.new_utf8_("Template"), false), new Io_url[] {url}, 1 * Io_mgr.Len_kb); + parser.Load(Gfo_usr_dlg_.Test(), wiki, new Xow_ns(Xow_ns_.Id_template, Xow_ns_case_.Id_1st, Bry_.new_utf8_("Template"), false), new Io_url[] {url}, 1 * Io_mgr.Len_kb); ListAdp actl = ListAdp_.new_(); Xowd_page_itm page = new Xowd_page_itm(); while (parser.Read(page)) { diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_image_cmd.java b/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_image_cmd.java index 0c95d7a92..1873fbf5b 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_image_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_image_cmd.java @@ -57,7 +57,7 @@ public class Xob_image_cmd extends Xob_itm_dump_base implements Xob_cmd, GfoInvk case Fld_img_media_type: cur_media_type = Bry_.Mid(src, fld_bgn, fld_end); break; case Fld_img_minor_mime: cur_minor_mime = Bry_.Mid(src, fld_bgn, fld_end); break; case Fld_img_timestamp: cur_timestamp = Bry_.Mid(src, fld_bgn, fld_end); - cur_ext_id = Calc_ext_id(show_issues ? app.Usr_dlg() : Gfo_usr_dlg_.Null, cur_ttl, cur_media_type, cur_minor_mime, cur_width, cur_height); + cur_ext_id = Calc_ext_id(show_issues ? app.Usr_dlg() : Gfo_usr_dlg_.Noop, cur_ttl, cur_media_type, cur_minor_mime, cur_width, cur_height); tbl_image.Insert(stmt, cur_ttl, cur_media_type, cur_minor_mime, cur_size, cur_width, cur_height, cur_bits, cur_ext_id, cur_timestamp); ++commit_count; if ((commit_count % 10000) == 0) { diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_image_cmd_tst.java b/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_image_cmd_tst.java index 4b24acb7d..f3738d152 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_image_cmd_tst.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_image_cmd_tst.java @@ -45,7 +45,7 @@ class Xob_image_cmd_fxt { public Xob_image_cmd_fxt W_(int v) {w = v; return this;} public Xob_image_cmd_fxt H_(int v) {h = v; return this;} public Xob_image_cmd_fxt Test(int expd) { - Tfds.Eq(expd, Xob_image_cmd.Calc_ext_id(Gfo_usr_dlg_.Null, name, media_type, minor_mime, w, h)); + Tfds.Eq(expd, Xob_image_cmd.Calc_ext_id(Gfo_usr_dlg_.Noop, name, media_type, minor_mime, w, h)); return this; } } diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Gfo_html_tkn__link_css.java b/400_xowa/src/gplx/xowa/bldrs/css/Gfo_html_tkn__link_css.java new file mode 100644 index 000000000..b54e4139d --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Gfo_html_tkn__link_css.java @@ -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 . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import gplx.core.html.parsers.*; +// class Gfo_html_tkn__link_css : Gfo_html_tkn__link { // private final Xob_mirror_mgr mgr; +// public Gfo_html_tkn__link_css(Xob_mirror_mgr mgr) {this.mgr = mgr;} +// public override void Process(byte[] src, Xop_xatr_hash xatr_hash) { +// if (!xatr_hash.Match("rel", "stylesheet")) return; +// byte[] href = xatr_hash.Get_as_bry_or("href", null); if (href == null) return; +// mgr.Code_add(href); +// } +// } diff --git a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor.java b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_extractor.java similarity index 95% rename from 400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor.java rename to 400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_extractor.java index 52fc9ae3b..941aa0a94 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor.java +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_extractor.java @@ -15,9 +15,10 @@ 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 . */ -package gplx.xowa; import gplx.*; +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.ios.*; import gplx.xowa.html.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.data.*; +import gplx.xowa.files.downloads.*; public class Xoa_css_extractor { public IoEngine_xrg_downloadFil Download_xrg() {return download_xrg;} private IoEngine_xrg_downloadFil download_xrg = Io_mgr._.DownloadFil_args("", Io_url_.Null); public Xoa_css_extractor Wiki_domain_(byte[] v) {wiki_domain = v; return this;} private byte[] wiki_domain; @@ -81,7 +82,10 @@ public class Xoa_css_extractor { || core_db_mgr.Props() == null || core_db_mgr.Props().Schema_is_1() || !core_db_mgr.Tbl__cfg().Select_yn_or(Xow_cfg_consts.Grp__wiki_schema, Xowd_db_file_schema_props.Key__tbl_css_core, Bool_.N) - ) return false; + ) { + Xoa_app_.Usr_dlg().Warn_many("", "", "css.db not found; wiki=~{0} css_dir=~{1}", wiki.Domain_str(), wiki_html_dir.Raw()); + return false; + } Xowd_db_file core_db = core_db_mgr.Db__core(); gplx.xowa.html.css.Xowd_css_core_mgr.Get(core_db.Tbl__css_core(), core_db.Tbl__css_file(), wiki_html_dir, css_key); return true; @@ -166,7 +170,8 @@ public class Xoa_css_extractor { bgn_pos += Bry_mw_wiki_logo.length; int end_pos = Bry_finder.Find_fwd(commons_src, Byte_ascii.Quote, bgn_pos + 1); if (end_pos == Bry_finder.Not_found) return false; byte[] src_bry = Bry_.Mid(commons_src, bgn_pos, end_pos); - if (Op_sys.Cur().Tid_is_wnt()) + src_bry = Xob_url_fixer.Fix(wiki_domain, src_bry, src_bry.length); + if (wiki_html_dir.Info().DirSpr_byte() == Byte_ascii.Backslash) src_bry = Bry_.Replace(src_bry, Byte_ascii.Slash, Byte_ascii.Backslash); Io_url src_fil = wiki_html_dir.GenSubFil(String_.new_utf8_(src_bry)); Io_mgr._.CopyFil(src_fil, trg_fil, true); @@ -231,7 +236,7 @@ public class Xoa_css_extractor { url_bgn += css_find_bgn_len; int url_end = Bry_finder.Find_fwd(raw, Byte_ascii.Quote, url_bgn, raw_len); if (url_end == Bry_.NotFound) {usr_dlg.Warn_many("", "main_page.css_parse", "could not find css; pos='~{0}' text='~{1}'", url_bgn, String_.new_utf8_len_safe_(raw, url_bgn, url_bgn + 32)); break;} byte[] css_url_bry = Bry_.Mid(raw, url_bgn, url_end); - css_url_bry = Bry_.Replace(css_url_bry, Css_amp_find, Css_amp_repl); // & -> & + css_url_bry = Bry_.Replace(css_url_bry, Css_amp_find, Css_amp_repl); // & -> & css_url_bry = url_encoder.Decode(css_url_bry); // %2C -> %7C -> | css_url_bry = Bry_.Add(protocol_prefix_bry, css_url_bry); rv.Add(String_.new_utf8_(css_url_bry)); diff --git a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_basic_tst.java b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_extractor_basic_tst.java similarity index 91% rename from 400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_basic_tst.java rename to 400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_extractor_basic_tst.java index d68af5cf3..6cb8c5aa1 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_basic_tst.java +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_extractor_basic_tst.java @@ -15,8 +15,8 @@ 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 . */ -package gplx.xowa; import gplx.*; -import org.junit.*; import gplx.ios.*; +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import org.junit.*; import gplx.ios.*; import gplx.xowa.wikis.data.*; import gplx.xowa.files.downloads.*; public class Xoa_css_extractor_basic_tst { @Before public void init() {fxt.Clear();} private Xoa_css_extractor_fxt fxt = new Xoa_css_extractor_fxt(); @Test public void Logo_download() { @@ -27,8 +27,8 @@ public class Xoa_css_extractor_basic_tst { } @Test public void Logo_download_mw_wiki_logo() { fxt.Init_fil("mem/http/en.wikipedia.org" , ""); - fxt.Init_fil("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/wiki.png" , "download"); - fxt.Init_fil("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/xowa_common.css" , ".mw-wiki-logo{background-image:url(\"wiki.png\");"); + fxt.Init_fil("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/a/wiki.png" , "download"); + fxt.Init_fil("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/xowa_common.css" , ".mw-wiki-logo{background-image:url(\"//a/wiki.png\");"); fxt.Exec_logo_setup(); fxt.Test_fil("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/logo.png" , "download"); } @@ -79,7 +79,7 @@ public class Xoa_css_extractor_basic_tst { class Xoa_css_extractor_fxt { public void Clear() { Io_mgr._.InitEngine_mem(); - Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_base.test_(); + Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Test(); css_installer = new Xoa_css_extractor(); css_installer.Download_xrg().Trg_engine_key_(IoEngine_.MemKey); css_installer @@ -90,12 +90,12 @@ class Xoa_css_extractor_fxt { .Failover_dir_(Io_url_.new_any_("mem/xowa/bin/any/html/xowa/import/")) // "mem/xowa/user/anonymous/wiki/home/html/" .Wiki_html_dir_(Io_url_.new_any_("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/")) ; - page_fetcher = new Xow_page_fetcher_mok(); + page_fetcher = new Xow_page_fetcher_test(); css_installer.Page_fetcher_(page_fetcher); Xoa_css_img_downloader css_img_downloader = new Xoa_css_img_downloader(); css_img_downloader.Ctor(usr_dlg, new Xof_download_wkr_test(), Bry_.new_ascii_("mem/http/")); css_installer.Css_img_downloader_(css_img_downloader); - } private Xow_page_fetcher_mok page_fetcher; + } private Xow_page_fetcher_test page_fetcher; public Xoa_css_extractor Css_installer() {return css_installer;} private Xoa_css_extractor css_installer; public void Init_page(int ns_id, String ttl, String text) { page_fetcher.Add(ns_id, Bry_.new_ascii_(ttl), Bry_.new_ascii_(text)); diff --git a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_wiki_tst.java b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_extractor_wiki_tst.java similarity index 93% rename from 400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_wiki_tst.java rename to 400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_extractor_wiki_tst.java index f4773a638..47be0d006 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_wiki_tst.java +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_extractor_wiki_tst.java @@ -15,7 +15,7 @@ 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 . */ -package gplx.xowa; import gplx.*; +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import org.junit.*; import gplx.ios.*; public class Xoa_css_extractor_wiki_tst { @Before public void init() {fxt.Clear();} private Xoa_css_extractor_fxt fxt = new Xoa_css_extractor_fxt(); diff --git a/400_xowa/src_240_install/gplx/xowa/Xoa_css_img_downloader.java b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_img_downloader.java similarity index 95% rename from 400_xowa/src_240_install/gplx/xowa/Xoa_css_img_downloader.java rename to 400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_img_downloader.java index 44560ca1c..72f2ad2a1 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xoa_css_img_downloader.java +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_img_downloader.java @@ -15,14 +15,17 @@ 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 . */ -package gplx.xowa; import gplx.*; +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import gplx.xowa.files.downloads.*; public class Xoa_css_img_downloader { + private byte[] wiki_domain; public Xoa_css_img_downloader Ctor(Gfo_usr_dlg usr_dlg, Xof_download_wkr download_wkr, byte[] stylesheet_prefix) { this.usr_dlg = usr_dlg; this.download_wkr = download_wkr; this.stylesheet_prefix = stylesheet_prefix; return this; } private Gfo_usr_dlg usr_dlg; private Xof_download_wkr download_wkr; public Xoa_css_img_downloader Stylesheet_prefix_(byte[] v) {stylesheet_prefix = v; return this;} private byte[] stylesheet_prefix; // TEST: setter exposed b/c tests can handle "mem/" but not "//mem" public void Chk(byte[] wiki_domain, Io_url css_fil) { + this.wiki_domain = wiki_domain; ListAdp img_list = ListAdp_.new_(); byte[] old_bry = Io_mgr._.LoadFilBry(css_fil); byte[] rel_url_prefix = Bry_.Add(Bry_fwd_slashes, wiki_domain); @@ -77,7 +80,7 @@ public class Xoa_css_img_downloader { prv_pos = import_url_end; continue; } - byte[] img_cleaned = Clean_img_url(img_raw, img_raw_len); + byte[] img_cleaned = Xob_url_fixer.Fix(wiki_domain, img_raw, img_raw_len); if (img_cleaned == null) { // could not clean img usr_dlg.Warn_many(GRP_KEY, "parse.invalid_url.clean_failed", "could not extract valid http src: bgn='~{0}' end='~{1}'", prv_pos, String_.new_utf8_(img_raw)); bfr.Add_mid(src, prv_pos, bgn_pos); prv_pos = bgn_pos; continue; diff --git a/400_xowa/src_240_install/gplx/xowa/Xoa_css_img_downloader_tst.java b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_img_downloader_tst.java similarity index 91% rename from 400_xowa/src_240_install/gplx/xowa/Xoa_css_img_downloader_tst.java rename to 400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_img_downloader_tst.java index 758271416..504c21c30 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xoa_css_img_downloader_tst.java +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xoa_css_img_downloader_tst.java @@ -15,8 +15,8 @@ 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 . */ -package gplx.xowa; import gplx.*; -import org.junit.*; +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import org.junit.*; import gplx.xowa.files.downloads.*; public class Xoa_css_img_downloader_tst { @Before public void init() {fxt.Clear();} private Xoa_css_img_downloader_fxt fxt = new Xoa_css_img_downloader_fxt(); @Test public void Basic() { @@ -62,13 +62,13 @@ public class Xoa_css_img_downloader_tst { , "site/a.jpg" ); } - @Test public void Exc_name_only() { - fxt.Test_css_convert - ( "x {url(\"//site/a.jpg\")} y {url(\"b.jpg\"} z {}" - , "x {url(\"site/a.jpg\")} y {url(\"b.jpg\"} z {}" - , "site/a.jpg" - ); - } +// @Test public void Exc_name_only() { // COMMENTED: not sure how to handle "b.jpg" (automatically add "current" path?); RESTORE: when example found +// fxt.Test_css_convert +// ( "x {url(\"//site/a.jpg\")} y {url(\"b.jpg\"} z {}" +// , "x {url(\"site/a.jpg\")} y {url(\"b.jpg\"} z {}" +// , "site/a.jpg" +// ); +// } @Test public void Repeat() {// PURPOSE.fix: exact same item was being added literally fxt.Test_css_convert ( "x {url(\"//site/a.jpg?a=b\")} y {url(\"//site/a.jpg?a=b\"}" @@ -163,7 +163,7 @@ class Xoa_css_img_downloader_fxt { public Xoa_css_img_downloader Downloader() {return downloader;} private Xoa_css_img_downloader downloader; public void Clear() { downloader = new Xoa_css_img_downloader(); - downloader.Ctor(Gfo_usr_dlg_base.test_(), new Xof_download_wkr_test(), Bry_.Empty); + downloader.Ctor(Gfo_usr_dlg_.Test(), new Xof_download_wkr_test(), Bry_.Empty); } public void Test_css_convert(String raw, String expd, String... expd_img_ary) { ListAdp actl_img_list = ListAdp_.new_(); diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser.java new file mode 100644 index 000000000..4785cde51 --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser.java @@ -0,0 +1,56 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import gplx.core.btries.*; import gplx.core.primitives.*; +class Xob_css_parser { + private final Bry_bfr bfr = Bry_bfr.new_(255); + private final Xob_mirror_mgr mgr; + private final Xob_css_parser__url url_parser; private final Xob_css_parser__import import_parser; + public Xob_css_parser(Xob_mirror_mgr mgr) { + this.mgr = mgr; + this.url_parser = new Xob_css_parser__url(mgr.Site_url()); + this.import_parser = new Xob_css_parser__import(url_parser); + } + public void Parse(byte[] src) { + int src_len = src.length; int pos = 0; + while (pos < src_len) { + byte b = src[pos]; + Object o = tkns_trie.Match_bgn_w_byte(b, src, pos, src_len); + if (o == null) { + bfr.Add_byte(b); + ++pos; + } + else { + byte tkn_tid = ((Byte_obj_val)o).Val(); + int match_pos = tkns_trie.Match_pos(); + Xob_css_tkn__base tkn = null; + switch (tkn_tid) { + case Tkn_url: tkn = url_parser.Parse(src, src_len, pos, match_pos); break; + case Tkn_import: tkn = import_parser.Parse(src, src_len, pos, match_pos); break; + } + tkn.Process(mgr); + pos = tkn.Write(bfr, src); + } + } + } + private static final byte Tkn_import = 1, Tkn_url = 2; + private static final Btrie_slim_mgr tkns_trie = Btrie_slim_mgr.ci_ascii_() + .Add_str_byte("@import" , Tkn_import) + .Add_str_byte(" url(" , Tkn_url) + ; +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__import.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__import.java new file mode 100644 index 000000000..585f3f737 --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__import.java @@ -0,0 +1,43 @@ +/* +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 . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import gplx.xowa.files.downloads.*; +class Xob_css_parser__import { +// // "//id.wikibooks.org/w/index.php?title=MediaWiki:Common.css&oldid=43393&action=raw&ctype=text/css"; + private final Xob_css_parser__url url_parser; + public Xob_css_parser__import(Xob_css_parser__url url_parser) {this.url_parser = url_parser;} + public Xob_css_tkn__base Parse(byte[] src, int src_len, int tkn_bgn, int tkn_end) { // " @import" + int bgn_pos = Bry_finder.Find_fwd_while_ws(src, tkn_end, src_len); // skip any ws after " @import" + if (bgn_pos == src_len) return Xob_css_tkn__warn.new_(tkn_bgn, tkn_end, "mirror.parser.import:EOS after import; bgn=~{0}", tkn_bgn); + if (!Bry_.HasAtBgn(src, Tkn_url_bry, bgn_pos, src_len)) return Xob_css_tkn__warn.new_(tkn_bgn, tkn_end, "mirror.parser.import:url missing; bgn=~{0}", tkn_bgn); + tkn_end = bgn_pos + Tkn_url_bry.length; + Xob_css_tkn__base frag = url_parser.Parse(src, src_len, bgn_pos, tkn_end); + if (frag.Tid() != Xob_css_tkn__url.Tid_url) return Xob_css_tkn__warn.new_(tkn_bgn, frag.Pos_end(), "mirror.parser.import:url invalid; bgn=~{0}", tkn_bgn); + Xob_css_tkn__url url_frag = (Xob_css_tkn__url)frag; + byte[] src_url = url_frag.Src_url(); + src_url = Bry_.Replace(src_url, Byte_ascii.Space, Byte_ascii.Underline); // NOTE: must replace spaces with underlines else download will fail; EX:https://it.wikivoyage.org/w/index.php?title=MediaWiki:Container e Infobox.css&action=raw&ctype=text/css; DATE:2015-03-08 + int semic_pos = Bry_finder.Find_fwd(src, Byte_ascii.Semic, frag.Pos_end(), src_len); + return Xob_css_tkn__import.new_(tkn_bgn, semic_pos + 1, src_url, url_frag.Trg_url(), url_frag.Quote_byte()); + } + private static final byte[] Tkn_url_bry = Bry_.new_ascii_("url("); + public static final byte[] + Wikisource_dynimg_ttl = Bry_.new_ascii_("en.wikisource.org/w/index.php?title=MediaWiki:Dynimg.css") + , Wikisource_dynimg_find = Bry_.new_ascii_(".freedImg img[src*=\"wikipedia\"], .freedImg img[src*=\"wikisource\"], .freedImg img[src*=\"score\"], .freedImg img[src*=\"math\"] {") + , Wikisource_dynimg_repl = Bry_.new_ascii_(".freedImg img[src*=\"wikipedia\"], .freedImg img[src*=\"wikisource\"], /*XOWA:handle file:// paths which will have /commons.wikimedia.org/ but not /wikipedia/ */ .freedImg img[src*=\"wikimedia\"], .freedImg img[src*=\"score\"], .freedImg img[src*=\"math\"] {") + ; +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__import_tst.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__import_tst.java new file mode 100644 index 000000000..3d58675ac --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__import_tst.java @@ -0,0 +1,38 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import org.junit.*; +public class Xob_css_parser__import_tst { + @Before public void init() {fxt.Clear();} private Xob_css_parser__import_fxt fxt = new Xob_css_parser__import_fxt(); + @Test public void Basic() {fxt.Test_parse_import (" @import url(//site/a.png)" , " @import url('site/a.png')");} + @Test public void Warn_eos() {fxt.Test_parse_warn (" @import" , " @import" , "EOS");} + @Test public void Warn_missing() {fxt.Test_parse_warn (" @import ('//site/a.png')" , " @import" , "missing");} // no "url(" + @Test public void Warn_invalid() {fxt.Test_parse_warn (" @import url('//site')" , " @import url('//site')" , "invalid");} // invalid +} +class Xob_css_parser__import_fxt extends Xob_css_parser__url_fxt { private Xob_css_parser__import import_parser; + @Override public void Clear() { + super.Clear(); + this.import_parser = new Xob_css_parser__import(url_parser); + } + @Override protected void Exec_parse_hook() { + this.cur_frag = import_parser.Parse(src_bry, src_bry.length, 0, 8); // 8=" @import".length + } + public void Test_parse_import(String src_str, String expd) { + Exec_parse(src_str, Xob_css_tkn__base.Tid_import, expd); + } +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__url.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__url.java new file mode 100644 index 000000000..f3cabcdbb --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__url.java @@ -0,0 +1,58 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +class Xob_css_parser__url { + private final byte[] site; + public Xob_css_parser__url(byte[] site) {this.site = site;} + public Xob_css_tkn__base Parse(byte[] src, int src_len, int tkn_bgn, int tkn_end) { // " url" + int bgn_pos = Bry_finder.Find_fwd_while_ws(src, tkn_end, src_len); // skip any ws after " url(" + if (bgn_pos == src_len) return Xob_css_tkn__warn.new_(tkn_bgn, tkn_end, "mirror.parser.url:EOS; bgn=~{0}", tkn_bgn); + byte end_byte = src[bgn_pos]; // note that first non-ws byte should determine end_byte + byte quote_byte = end_byte; + switch (end_byte) { + case Byte_ascii.Quote: case Byte_ascii.Apos: // quoted; increment position; EX: ' url("a.png")' + ++bgn_pos; + break; + default: // not quoted; end byte is ")"; EX: ' url(a.png)' + end_byte = Byte_ascii.Paren_end; + quote_byte = Byte_ascii.Nil; + break; + } + int end_pos = Bry_finder.Find_fwd(src, end_byte, bgn_pos, src_len); + if (end_pos == Bry_.NotFound) // unclosed "url("; exit since nothing else will be found + return Xob_css_tkn__warn.new_(tkn_bgn, tkn_end, "mirror.parser.url:dangling; bgn=~{0} excerpt=~{1}", bgn_pos, String_.new_utf8_len_safe_(src, tkn_bgn, tkn_bgn + 128)); + if (end_pos - bgn_pos == 0) // empty; "url()"; ignore + return Xob_css_tkn__warn.new_(tkn_bgn, tkn_end, "mirror.parser.url:empty; bgn=~{0} excerpt=~{1}", bgn_pos, String_.new_utf8_len_safe_(src, tkn_bgn, tkn_bgn + 128)); + byte[] url_orig = Bry_.Mid(src, bgn_pos, end_pos); int url_orig_len = url_orig.length; + ++end_pos; // increment end_pos so rv will be after it; + if ( end_byte != Byte_ascii.Paren_end) { // end_byte is apos / quote + if ( end_pos < src_len + && src[end_pos] == Byte_ascii.Paren_end) + ++end_pos; + else + return Xob_css_tkn__warn.new_(tkn_bgn, end_pos, "mirror.parser.url:base64 dangling; bgn=~{0} excerpt=~{1}", bgn_pos, String_.new_utf8_(url_orig)); + } + if (Bry_.HasAtBgn(url_orig, Bry_data_image)) // base64 + return Xob_css_tkn__base64.new_(tkn_bgn, end_pos); + byte[] src_url = Xob_url_fixer.Fix(site, url_orig, url_orig_len); + if (src_url == null) // could not convert + return Xob_css_tkn__warn.new_(tkn_bgn, end_pos, "mirror.parser.url:invalid url; bgn=~{0} excerpt=~{1}", tkn_bgn, String_.new_utf8_(url_orig)); + return Xob_css_tkn__url.new_(tkn_bgn, end_pos, src_url, quote_byte); + } + private static final byte[] Bry_data_image = Bry_.new_ascii_("data:image/"); +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__url_tst.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__url_tst.java new file mode 100644 index 000000000..f5449bc32 --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_parser__url_tst.java @@ -0,0 +1,60 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import org.junit.*; +public class Xob_css_parser__url_tst { + @Before public void init() {fxt.Clear();} private Xob_css_parser__url_fxt fxt = new Xob_css_parser__url_fxt(); + @Test public void Quote_none() {fxt.Test_parse_url(" url(//site/A.png) b" , " url('site/A.png')");} + @Test public void Quote_apos() {fxt.Test_parse_url(" url('//site/A.png') b" , " url('site/A.png')");} + @Test public void Quote_quote() {fxt.Test_parse_url(" url(\"//site/A.png\") b" , " url(\"site/A.png\")");} + @Test public void Base64() {fxt.Test_parse_base64(" url('data:image/png;base64,BASE64DATA;ABC=') b", " url('data:image/png;base64,BASE64DATA;ABC=')");} + @Test public void Base64_dangling() {fxt.Test_parse_warn(" url('data:image/png;base64,BASE64DATA;ABC=' ", " url('data:image/png;base64,BASE64DATA;ABC='", "base64 dangling");} + @Test public void Warn_eos() {fxt.Test_parse_warn(" url(" , " url(" , "EOS");} + @Test public void Warn_dangling() {fxt.Test_parse_warn(" url(a" , " url(" , "dangling");} + @Test public void Warn_empty() {fxt.Test_parse_warn(" url()" , " url(" , "empty");} + @Test public void Warn_site() {fxt.Test_parse_warn(" url('//site')" , " url('//site')" , "invalid");} +} +class Xob_css_parser__url_fxt { + protected Xob_css_parser__url url_parser; private final Bry_bfr bfr = Bry_bfr.new_(32); + protected Xob_css_tkn__base cur_frag; protected byte[] src_bry; + @gplx.Virtual public void Clear() { + url_parser = new Xob_css_parser__url(Bry_.new_ascii_("site")); + } + protected void Exec_parse(String src_str, int expd_tid, String expd_str) { + this.src_bry = Bry_.new_utf8_(src_str); + this.Exec_parse_hook(); + cur_frag.Write(bfr, src_bry); + String actl_str = bfr.Xto_str_and_clear(); + Tfds.Eq(expd_tid, cur_frag.Tid(), "wrong tid; expd={0}, actl={1}", expd_tid, cur_frag.Tid()); + Tfds.Eq(expd_str, actl_str); + } + @gplx.Virtual protected void Exec_parse_hook() { + this.cur_frag = url_parser.Parse(src_bry, src_bry.length, 0, 5); // 5=" url(".length + } + public void Test_parse_url(String src_str, String expd) { + Exec_parse(src_str, Xob_css_tkn__base.Tid_url, expd); + } + public void Test_parse_base64(String src_str, String expd) { + Exec_parse(src_str, Xob_css_tkn__base.Tid_base64, expd); + } + public void Test_parse_warn(String src_str, String expd, String warn) { + Exec_parse(src_str, Xob_css_tkn__base.Tid_warn, expd); + Xob_css_tkn__warn sub_frag = (Xob_css_tkn__warn)cur_frag; + Tfds.Eq(true, String_.Has(sub_frag.Fail_msg(), warn)); + } +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_tkn__base.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_tkn__base.java new file mode 100644 index 000000000..ae4cc3def --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_css_tkn__base.java @@ -0,0 +1,117 @@ +/* +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 . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +abstract class Xob_css_tkn__base { + public void Init(int tid, int pos_bgn, int pos_end) { + this.tid = tid; this.pos_bgn = pos_bgn; this.pos_end = pos_end; + } + public int Tid() {return tid;} protected int tid; + public int Pos_bgn() {return pos_bgn;} protected int pos_bgn; + public int Pos_end() {return pos_end;} protected int pos_end; + @gplx.Virtual public void Process(Xob_mirror_mgr mgr) {} + public abstract int Write(Bry_bfr bfr, byte[] src); + public static final int Tid_warn = 1, Tid_base64 = 2, Tid_url = 3, Tid_import = 4; +} +class Xob_css_tkn__warn extends Xob_css_tkn__base { + public String Fail_msg() {return fail_msg;} private String fail_msg; + @Override public void Process(Xob_mirror_mgr mgr) { + mgr.Usr_dlg().Warn_many("", "", fail_msg); + } + @Override public int Write(Bry_bfr bfr, byte[] src) { + bfr.Add_mid(src, pos_bgn, pos_end); + return pos_end; + } + public static Xob_css_tkn__warn new_(int pos_bgn, int pos_end, String fmt, Object... fmt_args) { + Xob_css_tkn__warn rv = new Xob_css_tkn__warn(); + rv.Init(Tid_warn, pos_bgn, pos_end); + rv.fail_msg = String_.Format(fmt, fmt_args); + return rv; + } +} +class Xob_css_tkn__base64 extends Xob_css_tkn__base { + @Override public int Write(Bry_bfr bfr, byte[] src) { + bfr.Add_mid(src, pos_bgn, pos_end); + return pos_end; + } + public static Xob_css_tkn__base64 new_(int pos_bgn, int pos_end) { + Xob_css_tkn__base64 rv = new Xob_css_tkn__base64(); + rv.Init(Tid_base64, pos_bgn, pos_end); + return rv; + } +} +class Xob_css_tkn__url extends Xob_css_tkn__base { + public byte Quote_byte() {return quote_byte;} private byte quote_byte; + public byte[] Src_url() {return src_url;} private byte[] src_url; + public byte[] Trg_url() {return trg_url;} private byte[] trg_url; + @Override public void Process(Xob_mirror_mgr mgr) { + mgr.File_hash().Add_if_new(src_url, new Xobc_download_itm(Xobc_download_itm.Tid_file, String_.new_utf8_(src_url), trg_url)); + } + @Override public int Write(Bry_bfr bfr, byte[] src) { + byte quote = quote_byte; if (quote == Byte_ascii.Nil) quote = Byte_ascii.Apos; + bfr.Add_str_ascii(" url("); // EX: ' url(' + bfr.Add_byte(quote).Add(trg_url).Add_byte(quote); // EX: '"a.png"' + bfr.Add_byte(Byte_ascii.Paren_end); // EX: ')' + return pos_end; + } + public static Xob_css_tkn__url new_(int pos_bgn, int pos_end, byte[] src_url, byte quote_byte) { + Xob_css_tkn__url rv = new Xob_css_tkn__url(); + rv.Init(Tid_url, pos_bgn, pos_end); + rv.src_url = src_url; rv.trg_url = To_fsys(src_url); rv.quote_byte = quote_byte; + return rv; + } + public static byte[] To_fsys(byte[] src) { + if (!Op_sys.Cur().Tid_is_wnt()) return src; + src = Bry_.Copy(src); // NOTE: must call ByteAry.Copy else url_actl will change *inside* bry + int len = src.length; + for (int i = 0; i < len; ++i) { + byte b = src[i]; + switch (b) { + case Byte_ascii.Slash: + case Byte_ascii.Backslash: + break; + case Byte_ascii.Lt: case Byte_ascii.Gt: case Byte_ascii.Colon: case Byte_ascii.Pipe: case Byte_ascii.Question: case Byte_ascii.Asterisk: case Byte_ascii.Quote: + src[i] = Byte_ascii.Underline; + break; + default: + break; + } + } + return src; + } +} +class Xob_css_tkn__import extends Xob_css_tkn__base { + public byte Quote_byte() {return quote_byte;} private byte quote_byte; + public byte[] Src_url() {return src_url;} private byte[] src_url; + public byte[] Trg_url() {return trg_url;} private byte[] trg_url; + @Override public void Process(Xob_mirror_mgr mgr) { + mgr.Code_add(src_url); + } + @Override public int Write(Bry_bfr bfr, byte[] src) { + byte quote = quote_byte; if (quote == Byte_ascii.Nil) quote = Byte_ascii.Apos; + bfr.Add_str_ascii(" @import url("); // EX: ' @import url(' + bfr.Add_byte(quote).Add(trg_url).Add_byte(quote); // EX: '"a.png"' + bfr.Add_byte(Byte_ascii.Paren_end); // EX: ')' + return pos_end; + } + public static Xob_css_tkn__import new_(int pos_bgn, int pos_end, byte[] src_url, byte[] trg_url, byte quote_byte) { + Xob_css_tkn__import rv = new Xob_css_tkn__import(); + rv.Init(Tid_import, pos_bgn, pos_end); + rv.src_url = src_url; rv.trg_url = trg_url; rv.quote_byte = quote_byte; + return rv; + } +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_mirror_mgr.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_mirror_mgr.java new file mode 100644 index 000000000..9f04baa98 --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_mirror_mgr.java @@ -0,0 +1,59 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import gplx.ios.*; import gplx.xowa.files.downloads.*; +public class Xob_mirror_mgr { + private final Xof_download_wkr download_wkr; private final Xob_css_parser css_parser; + private final byte[] page_url; private final Io_url fsys_root; + public Xob_mirror_mgr(Gfo_usr_dlg usr_dlg, Xof_download_wkr download_wkr, byte[] site_url, byte[] page_url, Io_url fsys_root) { + this.usr_dlg = usr_dlg; this.download_wkr = download_wkr; + this.site_url = site_url; this.page_url = page_url; this.fsys_root = fsys_root; + this.css_parser = new Xob_css_parser(this); + } + public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} private final Gfo_usr_dlg usr_dlg; + public byte[] Site_url() {return site_url;} private final byte[] site_url; + public void Code_add(byte[] src_url) { + byte[] trg_url = Xob_css_tkn__url.To_fsys(src_url); + code_hash.Add_if_new(src_url, new Xobc_download_itm(Xobc_download_itm.Tid_css, String_.new_utf8_(src_url), trg_url)); + } + public OrderedHash Code_hash() {return code_hash;} private final OrderedHash code_hash = OrderedHash_.new_(); + public OrderedHash File_hash() {return file_hash;} private final OrderedHash file_hash = OrderedHash_.new_(); + public void Exec() { + usr_dlg.Plog_many("", "", "html_mirror:download.root_page; url=~{0}", page_url); + IoEngine_xrg_downloadFil download_xrg = download_wkr.Download_xrg(); + css_parser.Parse(download_xrg.Exec_as_bry(String_.new_utf8_(page_url))); + while (true) { + Xobc_download_itm[] code_ary = (Xobc_download_itm[])code_hash.Xto_ary_and_clear(Xobc_download_itm.class); + int code_ary_len = code_ary.length; + if (code_ary_len == 0) break; + for (int i = 0; i < code_ary_len; ++i) { + Xobc_download_itm code = code_ary[i]; + byte[] code_src = download_xrg.Exec_as_bry(code.Http_str()); + Io_mgr._.SaveFilBry(fsys_root.Gen_sub_path_for_os(String_.new_utf8_(code.Fsys_url())), code_src); + css_parser.Parse(code_src); + } + } + Xobc_download_itm[] file_ary = (Xobc_download_itm[])file_hash.Xto_ary_and_clear(Xobc_download_itm.class); + int file_ary_len = file_ary.length; + for (int i = 0; i < file_ary_len; ++i) { + Xobc_download_itm file = file_ary[i]; + download_xrg.Init(file.Http_str(), Io_url_.new_fil_(fsys_root.Gen_sub_path_for_os(String_.new_utf8_(file.Fsys_url())))); + download_xrg.Exec(); + } + } +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_mirror_mgr_tst.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_mirror_mgr_tst.java new file mode 100644 index 000000000..89c35923b --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_mirror_mgr_tst.java @@ -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 . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import org.junit.*; +import gplx.xowa.files.downloads.*; +public class Xob_mirror_mgr_tst { + @Before public void init() {fxt.Clear();} private Xob_mirror_mgr_fxt fxt = new Xob_mirror_mgr_fxt(); + @Test public void Download_1() { + fxt.Fsys().Init_fil("mem/http/enwiki/file/a.png"); + fxt.Fsys().Init_fil("mem/http/enwiki/wiki/Main_Page", "url('//enwiki/wiki/a.png')"); +// fxt.Test_css(); +// fxt.Fsys().Test_fil("url('//enwiki/wiki/a.png')", "url('enwiki/wiki/a.png')"); // remove "//" +// fxt.Fsys().Test_fil("mem/fsys/enwiki/file/a.png"); + } +} +class Xob_mirror_mgr_fxt { +// private Xob_mirror_mgr mirror_mgr; + public Io_fsys_fxt Fsys() {return fsys;} private final Io_fsys_fxt fsys = new Io_fsys_fxt(); + public void Clear() { + fsys.Clear(); +// mirror_mgr = new Xob_mirror_mgr(Gfo_usr_dlg_.Noop, new Xof_download_wkr_test(), Bry_.new_ascii_("mem/http/enwiki"), Bry_.new_ascii_("mem/http/enwiki/wiki/Main_Page"), Io_url_.new_dir_("mem/fsys")); + } + public void Test_css(String raw, String expd) { +// byte[] raw_bry = Bry_.new_utf8_(raw); +// mirror_mgr.Exec(); + } +} +class Io_fsys_fxt { + public void Clear() { + Io_mgr._.InitEngine_mem(); + } + public void Init_fil(String url_str) { + Io_url url = Io_url_.new_fil_(url_str); + Init_fil(url, url.NameAndExt()); + } + public void Init_fil(String url_str, String text) {Init_fil(Io_url_.new_fil_(url_str), text);} + public void Init_fil(Io_url url, String text) { + Io_mgr._.SaveFilStr(url, text); + } + public void Test_fil(String url_str) { + Io_url url = Io_url_.new_fil_(url_str); + Test_fil(url, url.NameAndExt()); + } + public void Test_fil(String url, String expd) {Test_fil(Io_url_.new_fil_(url), expd);} + public void Test_fil(Io_url url, String expd) { + Tfds.Eq_str_lines(expd, Io_mgr._.LoadFilStr(url)); + } +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_url_fixer.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_url_fixer.java new file mode 100644 index 000000000..88b889cec --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_url_fixer.java @@ -0,0 +1,99 @@ +/* +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 . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import gplx.core.primitives.*; import gplx.core.btries.*; +class Xob_url_fixer { + public static byte[] Fix(byte[] site, byte[] src, int src_len) { // return "site/img.png" if "//site/img.png" or "http://site/img.png"; also, handle "img.png?key=val" + int bgn = 0; int bgn_tkn_tid = 0; + Object o = Xob_url_fixer_tkn.Bgn_trie().Match_bgn(src, bgn, src_len); + if (o != null) { + Xob_url_fixer_tkn tkn = (Xob_url_fixer_tkn)o; + bgn_tkn_tid = tkn.Tid(); + switch (bgn_tkn_tid) { + case Xob_url_fixer_tkn.Tid_bgn_slash_2: + case Xob_url_fixer_tkn.Tid_bgn_http: + case Xob_url_fixer_tkn.Tid_bgn_https: + bgn = tkn.Raw_len(); // remove "//", "http://", "https://" + break; + case Xob_url_fixer_tkn.Tid_bgn_slash_1: // convert "/a" to "site/a" + src = Bry_.Add(site, src); + src_len = src.length; + break; + } + } + int pos = bgn, end = src_len; boolean no_slashes = true; + Btrie_slim_mgr mid_trie = Xob_url_fixer_tkn.Mid_trie(); + while (pos < src_len) { + byte b = src[pos]; + o = mid_trie.Match_bgn_w_byte(b, src, pos, src_len); + if (o != null) { + Xob_url_fixer_tkn tkn = (Xob_url_fixer_tkn)o; + switch (tkn.Tid()) { + case Xob_url_fixer_tkn.Tid_mid_slash: if (no_slashes) no_slashes = false; break; + case Xob_url_fixer_tkn.Tid_mid_question: end = pos; pos = src_len; break; + case Xob_url_fixer_tkn.Tid_mid_rel_1: + case Xob_url_fixer_tkn.Tid_mid_rel_2: + Bry_bfr tmp_bfr = Bry_bfr.new_(src_len); + byte[] to_rel_root = Bry_.Mid(src, bgn, pos); + byte[] to_rel_qry = Bry_.Mid(src, pos, src_len); + src = gplx.xowa.xtns.pfuncs.ttls.Pfunc_rel2abs.Rel2abs(tmp_bfr, to_rel_qry, to_rel_root, Int_obj_ref.neg1_()); + bgn = pos = 0; + end = src_len = src.length; + no_slashes = true; + break; + } + } + ++pos; + } + if (no_slashes) return null; // invalid; EX: "//site" + return Bry_.Mid(src, bgn, end); + } +} +class Xob_url_fixer_tkn { + public Xob_url_fixer_tkn(int tid, byte[] raw) {this.tid = tid; this.raw = raw; this.raw_len = raw.length;} + public int Tid() {return tid;} private int tid; + public byte[] Raw() {return raw;} private byte[] raw; + public int Raw_len() {return raw_len;} private int raw_len; + public static Xob_url_fixer_tkn new_(int tid, String raw) {return new Xob_url_fixer_tkn(tid, Bry_.new_utf8_(raw));} + + private static void trie_add(Btrie_slim_mgr trie, int tid, String s) {trie.Add_obj(s, new_(tid, s));} + public static final int Tid_bgn_slash_1 = 1, Tid_bgn_slash_2 = 2, Tid_bgn_http = 3, Tid_bgn_https = 4; + private static Btrie_slim_mgr bgn_trie; + public static Btrie_slim_mgr Bgn_trie() { + if (bgn_trie == null) { + bgn_trie = Btrie_slim_mgr.ci_ascii_(); + trie_add(bgn_trie, Tid_bgn_slash_1 , "/"); + trie_add(bgn_trie, Tid_bgn_slash_2 , "//"); + trie_add(bgn_trie, Tid_bgn_http , "http://"); + trie_add(bgn_trie, Tid_bgn_https , "https://"); + } + return bgn_trie; + } + public static final int Tid_mid_rel_1 = 1, Tid_mid_rel_2 = 2, Tid_mid_slash = 3, Tid_mid_question = 4; + private static Btrie_slim_mgr mid_trie; + public static Btrie_slim_mgr Mid_trie() { + if (mid_trie == null) { + mid_trie = Btrie_slim_mgr.ci_ascii_(); + trie_add(mid_trie, Tid_mid_rel_1 , "/../"); + trie_add(mid_trie, Tid_mid_rel_2 , "/./"); + trie_add(mid_trie, Tid_mid_slash , "/"); + trie_add(mid_trie, Tid_mid_question , "?"); + } + return mid_trie; + } +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xob_url_fixer_tst.java b/400_xowa/src/gplx/xowa/bldrs/css/Xob_url_fixer_tst.java new file mode 100644 index 000000000..711133bde --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xob_url_fixer_tst.java @@ -0,0 +1,42 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +import org.junit.*; +public class Xob_url_fixer_tst { + @Before public void init() {fxt.Clear();} private Xob_url_fixer_fxt fxt = new Xob_url_fixer_fxt(); + @Test public void Slash2() {fxt.Test_fix("//site/a.png" , "site/a.png");} + @Test public void Http() {fxt.Test_fix("http://site/a.png" , "site/a.png");} + @Test public void Https() {fxt.Test_fix("https://site/a.png" , "site/a.png");} + @Test public void Qarg() {fxt.Test_fix("//site/a.png?key=val" , "site/a.png");} + @Test public void Qarg_dir() {fxt.Test_fix("//site/a/b/c.png?key=val" , "site/a/b/c.png");} + @Test public void Root() {fxt.Test_fix("/a/b.png" , "site/a/b.png");} // EX:/static/images/project-logos/wikivoyage.png; DATE:2015-05-09 + @Test public void Rel_dot2() {fxt.Test_fix("//site/a/../b/c.png" , "site/b/c.png");} // DATE:2015-05-09 + @Test public void Rel_dot2_mult() {fxt.Test_fix("//site/a/../b/../c/d.png" , "site/c/d.png");} // DATE:2015-05-09 + @Test public void Rel_dot1() {fxt.Test_fix("//site/a/./b/c.png" , "site/a/b/c.png");} // DATE:2015-05-09 + @Test public void Site_only() {fxt.Test_fix("//site" , null);} +} +class Xob_url_fixer_fxt { + public void Site_(String v) {site_bry = Bry_.new_utf8_(v);} private byte[] site_bry; + public void Clear() { + this.Site_("site"); + } + public void Test_fix(String raw, String expd) { + byte[] raw_bry = Bry_.new_utf8_(raw); + Tfds.Eq(expd, String_.new_utf8_(Xob_url_fixer.Fix(site_bry, raw_bry, raw_bry.length))); + } +} diff --git a/400_xowa/src/gplx/xowa/bldrs/css/Xobc_download_itm.java b/400_xowa/src/gplx/xowa/bldrs/css/Xobc_download_itm.java new file mode 100644 index 000000000..4d5e3fc14 --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/css/Xobc_download_itm.java @@ -0,0 +1,25 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.css; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; +class Xobc_download_itm { + public Xobc_download_itm(int tid, String http_str, byte[] fsys_url) {this.tid = tid; this.http_str = http_str; this.fsys_url = fsys_url;} + public int Tid() {return tid;} private final int tid; + public String Http_str() {return http_str;} private final String http_str; + public byte[] Fsys_url() {return fsys_url;} private final byte[] fsys_url; + public static final int Tid_file = 1, Tid_html = 2, Tid_css = 3; +} diff --git a/400_xowa/src/gplx/xowa/bldrs/xmls/Xob_xml_parser_tst.java b/400_xowa/src/gplx/xowa/bldrs/xmls/Xob_xml_parser_tst.java index 8165cac5c..2708d323d 100644 --- a/400_xowa/src/gplx/xowa/bldrs/xmls/Xob_xml_parser_tst.java +++ b/400_xowa/src/gplx/xowa/bldrs/xmls/Xob_xml_parser_tst.java @@ -116,7 +116,7 @@ public class Xob_xml_parser_tst { private static final String Date_1 = "2012-01-01T01:01:01Z", Date_2 = "2012-02-02T02:02:02Z"; DateAdp_parser dateParser = DateAdp_parser.new_(); Bry_bfr bfr = Bry_bfr.new_(); Xob_xml_page_bldr page_bldr = new Xob_xml_page_bldr(); Io_buffer_rdr fil; Xob_xml_parser page_parser = new Xob_xml_parser(); Xob_bldr bldr; - Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_base.test_(); + Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Test(); int tst_parse(Io_buffer_rdr fil, Xowd_page_itm expd, int cur_pos) { Xowd_page_itm actl = new Xowd_page_itm(); int rv = page_parser.Parse_page(actl, usr_dlg, fil, fil.Bfr(), cur_pos, ns_mgr); diff --git a/400_xowa/src/gplx/xowa/ctgs/Xoctg_idx_mgr_tst.java b/400_xowa/src/gplx/xowa/ctgs/Xoctg_idx_mgr_tst.java index 9a8d0b1a9..d34c2abee 100644 --- a/400_xowa/src/gplx/xowa/ctgs/Xoctg_idx_mgr_tst.java +++ b/400_xowa/src/gplx/xowa/ctgs/Xoctg_idx_mgr_tst.java @@ -87,11 +87,11 @@ class Xoctg_idx_mgr_fxt { } return bfr.Xto_bry_and_clear(); } - public Xoctg_idx_mgr_fxt Init_itms(int block_len, byte[] src) {idx_mgr.Block_len_(block_len); idx_mgr.Index(Gfo_usr_dlg_base.test_(), Ctg_name, src); return this;} + public Xoctg_idx_mgr_fxt Init_itms(int block_len, byte[] src) {idx_mgr.Block_len_(block_len); idx_mgr.Index(Gfo_usr_dlg_.Test(), Ctg_name, src); return this;} public Xoctg_idx_mgr_fxt Init_block_len(int block_len) {idx_mgr.Block_len_(block_len); return this;} public Xoctg_idx_mgr_fxt Init_src(byte[] v) {src = v; src_len = v.length; return this;} private byte[] src; int src_len; public Xoctg_idx_mgr_fxt Test_index(byte[] src, String... expd) { - idx_mgr.Index(Gfo_usr_dlg_base.test_(), Ctg_name, src); + idx_mgr.Index(Gfo_usr_dlg_.Test(), Ctg_name, src); Tfds.Eq_ary_str(expd, Idx_mgr_itms(idx_mgr)); return this; } @@ -118,7 +118,7 @@ class Xoctg_idx_mgr_fxt { } public Xoctg_idx_mgr_fxt Test_find(String find, boolean fill_at_bgn, String[] expd_ary, String last_plus_one) { if (tmp_list == null) tmp_list = ListAdp_.new_(); - idx_mgr.Index(Gfo_usr_dlg_base.test_(), Bry_.Empty, src); + idx_mgr.Index(Gfo_usr_dlg_.Test(), Bry_.Empty, src); tmp_list.Clear(); idx_mgr.Find(tmp_list, src, fill_at_bgn, Bry_.new_ascii_(find), 3, tmp_last_plus_one); Tfds.Eq_ary(expd_ary, To_str_ary(tmp_list)); diff --git a/400_xowa/src/gplx/xowa/ctgs/Xoctg_url_tst.java b/400_xowa/src/gplx/xowa/ctgs/Xoctg_url_tst.java index 27b34a5f8..3998f76f8 100644 --- a/400_xowa/src/gplx/xowa/ctgs/Xoctg_url_tst.java +++ b/400_xowa/src/gplx/xowa/ctgs/Xoctg_url_tst.java @@ -38,7 +38,7 @@ class Xoctg_url_fxt { } private Xoa_url_parser parser; Xoa_url page_url; Xoctg_url ctg_url; public void Test_parse(String url_str, Xoctg_url_chkr expd) { parser.Parse(page_url, Bry_.new_utf8_(url_str)); - ctg_url.Parse(Gfo_usr_dlg_base.test_(), page_url); + ctg_url.Parse(Gfo_usr_dlg_.Test(), page_url); expd.Chk(ctg_url); expd.Clear(); } diff --git a/400_xowa/src/gplx/xowa/dbs/Xodb_save_mgr_sql.java b/400_xowa/src/gplx/xowa/dbs/Xodb_save_mgr_sql.java index 2eced0928..f1d717b39 100644 --- a/400_xowa/src/gplx/xowa/dbs/Xodb_save_mgr_sql.java +++ b/400_xowa/src/gplx/xowa/dbs/Xodb_save_mgr_sql.java @@ -29,7 +29,7 @@ public class Xodb_save_mgr_sql implements Xodb_save_mgr { int ns_id = ttl.Ns().Id(); Xowd_db_file db_file = db_mgr.Core_data_mgr().Db__core(); int ns_count = db_file.Tbl__ns().Select_ns_count(ns_id) + 1; - int page_id = db_file.Tbl__cfg().Select_int_or("db", "page.id_nxt", -1); + int page_id = db_file.Tbl__cfg().Select_int_or("db", "page.id_next", -1); if (page_id == -1) { // HACK: changed for tests; was dbs.qrys.Db_qry_sql.rdr_("SELECT (Max(page_id) + 1) AS max_page_id FROM page;") // Db_rdr rdr = db_mgr.Core_data_mgr().Tbl__page().Conn().Stmt_new(Db_qry_sql.rdr_("SELECT (Max(page_id) + 1) AS max_page_id FROM page;")).Exec_select__rls_manual(); Db_rdr rdr = db_mgr.Core_data_mgr().Tbl__page().Conn().Stmt_select(db_file.Tbl__page().Tbl_name(), String_.Ary(db_file.Tbl__page().Fld_page_id()), Db_meta_fld.Ary_empy).Exec_select__rls_auto(); @@ -64,11 +64,15 @@ public class Xodb_save_mgr_sql implements Xodb_save_mgr { public void Data_update(Xoae_page page, byte[] text_raw) { boolean redirect = db_mgr.Wiki().Redirect_mgr().Is_redirect(text_raw, text_raw.length); DateAdp modified = update_modified_on_enabled ? DateAdp_.Now() : page.Revision_data().Modified_on(); - db_mgr.Core_data_mgr().Tbl__page().Update__redirect__modified(page.Revision_data().Id(), redirect, modified); + int page_id = page.Revision_data().Id(); + db_mgr.Core_data_mgr().Tbl__page().Update__redirect__modified(page_id, redirect, modified); Xowd_page_itm db_page = new Xowd_page_itm(); db_mgr.Load_mgr().Load_by_id(db_page, page.Revision_data().Id()); Xowd_text_tbl text_tbl = db_mgr.Core_data_mgr().Dbs__get_at(db_page.Text_db_id()).Tbl__text(); text_tbl.Update(page.Revision_data().Id(), text_raw); + int html_db_id = db_page.Html_db_id(); + if (html_db_id != -1) + db_mgr.Core_data_mgr().Tbl__page().Update__html_db_id(page_id, -1); // zap html_db_id so that next load will repopulate it } public void Data_rename(Xoae_page page, int trg_ns, byte[] trg_ttl) { db_mgr.Core_data_mgr().Tbl__page().Update__ns__ttl(page.Revision_data().Id(), trg_ns, trg_ttl); diff --git a/400_xowa/src/gplx/xowa/files/downloads/Xof_download_wkr.java b/400_xowa/src/gplx/xowa/files/downloads/Xof_download_wkr.java new file mode 100644 index 000000000..c5193af30 --- /dev/null +++ b/400_xowa/src/gplx/xowa/files/downloads/Xof_download_wkr.java @@ -0,0 +1,23 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.files.downloads; import gplx.*; import gplx.xowa.*; import gplx.xowa.files.*; +import gplx.ios.*; +public interface Xof_download_wkr { + byte Download(boolean src_is_web, String src, Io_url trg, String prog_fmt_hdr); + IoEngine_xrg_downloadFil Download_xrg(); +} diff --git a/400_xowa/src_160_file/gplx/xowa/Xof_download_wkr_io.java b/400_xowa/src/gplx/xowa/files/downloads/Xof_download_wkr_io.java similarity index 93% rename from 400_xowa/src_160_file/gplx/xowa/Xof_download_wkr_io.java rename to 400_xowa/src/gplx/xowa/files/downloads/Xof_download_wkr_io.java index c34f44eb3..ed83191fb 100644 --- a/400_xowa/src_160_file/gplx/xowa/Xof_download_wkr_io.java +++ b/400_xowa/src/gplx/xowa/files/downloads/Xof_download_wkr_io.java @@ -15,7 +15,7 @@ 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 . */ -package gplx.xowa; import gplx.*; +package gplx.xowa.files.downloads; import gplx.*; import gplx.xowa.*; import gplx.xowa.files.*; import gplx.ios.*; public class Xof_download_wkr_io implements Xof_download_wkr { IoEngine_xrg_downloadFil xrg = Io_mgr._.DownloadFil_args("", Io_url_.Null); diff --git a/400_xowa/src_160_file/gplx/xowa/Xof_download_wkr.java b/400_xowa/src/gplx/xowa/files/downloads/Xof_download_wkr_test.java similarity index 82% rename from 400_xowa/src_160_file/gplx/xowa/Xof_download_wkr.java rename to 400_xowa/src/gplx/xowa/files/downloads/Xof_download_wkr_test.java index 5af0a8c95..d19cfa534 100644 --- a/400_xowa/src_160_file/gplx/xowa/Xof_download_wkr.java +++ b/400_xowa/src/gplx/xowa/files/downloads/Xof_download_wkr_test.java @@ -15,14 +15,9 @@ 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 . */ -package gplx.xowa; import gplx.*; +package gplx.xowa.files.downloads; import gplx.*; import gplx.xowa.*; import gplx.xowa.files.*; import gplx.ios.*; -import gplx.gfui.*; -public interface Xof_download_wkr { - byte Download(boolean src_is_web, String src, Io_url trg, String prog_fmt_hdr); - IoEngine_xrg_downloadFil Download_xrg(); -} -class Xof_download_wkr_test implements Xof_download_wkr { +public class Xof_download_wkr_test implements Xof_download_wkr { public IoEngine_xrg_downloadFil Download_xrg() {return IoEngine_xrg_downloadFil.new_("", Io_url_.Null).Trg_engine_key_(IoEngine_.MemKey);} public byte Download(boolean src_is_web, String src_str, Io_url trg_url, String prog_fmt_hdr) { Io_mgr._.CreateDirIfAbsent(trg_url.OwnerDir()); diff --git a/400_xowa/src/gplx/xowa/files/fsdb/fs_roots/Fs_root_dir_tst.java b/400_xowa/src/gplx/xowa/files/fsdb/fs_roots/Fs_root_dir_tst.java index 5cea68b67..a5ebc1e43 100644 --- a/400_xowa/src/gplx/xowa/files/fsdb/fs_roots/Fs_root_dir_tst.java +++ b/400_xowa/src/gplx/xowa/files/fsdb/fs_roots/Fs_root_dir_tst.java @@ -47,7 +47,7 @@ class Fs_root_dir_fxt { root_dir = new Fs_root_dir(); orig_fil_tbl = new Orig_fil_tbl(); Xof_img_wkr_query_img_size img_size_wkr = new Xof_img_wkr_query_img_size_test(); - root_dir.Init(url, orig_fil_tbl, Gfo_usr_dlg_.Null, img_size_wkr); + root_dir.Init(url, orig_fil_tbl, Gfo_usr_dlg_.Noop, img_size_wkr); } public Orig_fil_mok itm_() {return new Orig_fil_mok();} public void Init_fs(String url, int w, int h) {Save_img(url, w, h);} diff --git a/400_xowa/src/gplx/xowa/files/gui/Js_img_mgr.java b/400_xowa/src/gplx/xowa/files/gui/Js_img_mgr.java index 390ec7c0e..9bfac61b6 100644 --- a/400_xowa/src/gplx/xowa/files/gui/Js_img_mgr.java +++ b/400_xowa/src/gplx/xowa/files/gui/Js_img_mgr.java @@ -27,7 +27,7 @@ public class Js_img_mgr { Js_img_mgr.Update_img(page, js_wkr, itm.Html_img_wkr(), itm.Html_uid(), itm.Lnki_type(), itm.Html_elem_tid(), itm.Html_w(), itm.Html_h(), itm.Html_view_url().To_http_file_str(), itm.Orig_w(), itm.Orig_h(), itm.Html_orig_url().To_http_file_str(), itm.Lnki_ttl(), itm.Gallery_mgr_h()); } public static void Update_link_missing(Xog_html_itm html_itm, String html_id) { - html_itm.Html_elem_atr_set_append(html_id, "class", " new"); + html_itm.Html_redlink(html_id); } private static void Update_img(Xoa_page page, Xog_js_wkr js_wkr, Js_img_wkr img_wkr, int uid, byte lnki_type, byte elem_tid, int html_w, int html_h, String html_src, int orig_w, int orig_h, String orig_src, byte[] lnki_ttl, int gallery_mgr_h) { if (!page.Wiki().App().App_type().Uid_is_gui()) return; // do not update html widget unless app is gui; null ref on http server; DATE:2014-09-17 diff --git a/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr.java b/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr.java index 12c9e0f8e..7ec97f929 100644 --- a/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr.java +++ b/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr.java @@ -19,6 +19,7 @@ package gplx.xowa.files.gui; import gplx.*; import gplx.xowa.*; import gplx.xowa public interface Xog_js_wkr { void Html_img_update (String uid, String src, int w, int h); void Html_redlink (String html_uid); + boolean Html_doc_loaded (); void Html_atr_set (String uid, String key, String val); void Html_elem_replace_html (String uid, String html); diff --git a/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr_.java b/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr_.java index 6c16c679c..f81e5637d 100644 --- a/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr_.java +++ b/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr_.java @@ -25,4 +25,5 @@ class Xog_js_wkr__noop implements Xog_js_wkr { public void Html_elem_replace_html (String uid, String html) {} public void Html_elem_append_above (String uid, String html) {} public void Html_redlink (String html_uid) {} + public boolean Html_doc_loaded () {return true;} } diff --git a/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr__log.java b/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr__log.java index c8744333e..b37b5ccda 100644 --- a/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr__log.java +++ b/400_xowa/src/gplx/xowa/files/gui/Xog_js_wkr__log.java @@ -23,10 +23,11 @@ public class Xog_js_wkr__log implements Xog_js_wkr { public void Html_redlink (String uid) {log_list.Add(Object_.Ary(Proc_redlink, uid));} public void Html_elem_replace_html (String uid, String html) {log_list.Add(Object_.Ary(Proc_replace_html, uid, html));} public void Html_elem_append_above (String uid, String html) {log_list.Add(Object_.Ary(Proc_append_above, uid, html));} + public boolean Html_doc_loaded () {log_list.Add(Object_.Ary(Proc_doc_loaded)); return true;} public void Log__clear() {log_list.Clear();} public int Log__len() {return log_list.Count();} public Object[] Log__get_at(int i) {return (Object[])log_list.FetchAt(i);} - public static final String Proc_img_update = "img_update", Proc_atr_set = "atr_set", Proc_redlink = "redlink", Proc_replace_html = "replace_html", Proc_append_above = "append_above"; + public static final String Proc_img_update = "img_update", Proc_atr_set = "atr_set", Proc_redlink = "redlink", Proc_replace_html = "replace_html", Proc_append_above = "append_above", Proc_doc_loaded = "doc_loaded"; } diff --git a/400_xowa/src/gplx/xowa/files/origs/Xof_orig_mgr.java b/400_xowa/src/gplx/xowa/files/origs/Xof_orig_mgr.java index c564b358d..43b6096d3 100644 --- a/400_xowa/src/gplx/xowa/files/origs/Xof_orig_mgr.java +++ b/400_xowa/src/gplx/xowa/files/origs/Xof_orig_mgr.java @@ -17,7 +17,7 @@ along with this program. If not, see . */ package gplx.xowa.files.origs; import gplx.*; import gplx.xowa.*; import gplx.xowa.files.*; import gplx.core.primitives.*; import gplx.dbs.*; -import gplx.xowa.files.repos.*; import gplx.xowa.files.fsdb.*; import gplx.xowa.wmfs.apis.*; +import gplx.xowa.files.repos.*; import gplx.xowa.files.fsdb.*; import gplx.xowa.wmfs.apis.*; import gplx.xowa.files.downloads.*; public class Xof_orig_mgr { private Xof_orig_wkr[] wkrs; private int wkrs_len; private Xof_url_bldr url_bldr; private Xow_repo_mgr repo_mgr; private final Xof_img_size img_size = new Xof_img_size(); diff --git a/400_xowa/src/gplx/xowa/files/origs/Xof_orig_wkr__wmf_api.java b/400_xowa/src/gplx/xowa/files/origs/Xof_orig_wkr__wmf_api.java index 6bf5f276a..74d70954c 100644 --- a/400_xowa/src/gplx/xowa/files/origs/Xof_orig_wkr__wmf_api.java +++ b/400_xowa/src/gplx/xowa/files/origs/Xof_orig_wkr__wmf_api.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.files.origs; import gplx.*; import gplx.xowa.*; import gplx.xowa.files.*; -import gplx.xowa.files.repos.*; import gplx.xowa.files.fsdb.*; import gplx.xowa.wmfs.apis.*; +import gplx.xowa.files.repos.*; import gplx.xowa.files.fsdb.*; import gplx.xowa.wmfs.apis.*; import gplx.xowa.files.downloads.*; public class Xof_orig_wkr__wmf_api implements Xof_orig_wkr { private final Xoapi_orig_base orig_api; private final Xof_download_wkr download_wkr; private final Xow_repo_mgr repo_mgr; private final byte[] wiki_domain; private final Xoapi_orig_rslts api_rv = new Xoapi_orig_rslts(); diff --git a/400_xowa/src/gplx/xowa/gui/Xoa_gui_mgr.java b/400_xowa/src/gplx/xowa/gui/Xoa_gui_mgr.java index afcb90394..36e16f48c 100644 --- a/400_xowa/src/gplx/xowa/gui/Xoa_gui_mgr.java +++ b/400_xowa/src/gplx/xowa/gui/Xoa_gui_mgr.java @@ -48,7 +48,7 @@ public class Xoa_gui_mgr implements GfoEvObj, GfoInvkAble { RectAdp prog_box_rect = browser_win.Prog_box().Rect(); memo_win.Rect_set(RectAdp_.new_(prog_box_rect.X(), prog_box_rect.Y() - 75, prog_box_rect.Width(), 100)); memo_txt.Size_(memo_win.Size().Op_add(-8, -30)); - memo_txt.Text_(String_.Concat_lines_nl(browser_win.Usr_dlg().Ui_wkr().Prog_msgs().Xto_str_ary())); + memo_txt.Text_(String_.Concat_lines_nl(browser_win.Usr_dlg().Gui_wkr().Prog_msgs().Xto_str_ary())); memo_win.Show(); memo_win.Focus(); } @@ -109,7 +109,7 @@ public class Xoa_gui_mgr implements GfoEvObj, GfoInvkAble { Xog_win_itm main_win = ui_mgr.Browser_win(); Xog_win_itm_.Show_win(main_win); log_bfr.Add("app.gui.win_load.done"); Xog_tab_itm_read_mgr.Launch(main_win); - app.Log_wtr().Log_msg_to_session_direct(log_bfr.Xto_str()); + app.Log_wtr().Log_to_session_direct(log_bfr.Xto_str()); kit.Kit_run(); // NOTE: enters thread-loop } catch (Exception e) { app.Usr_dlg().Warn_many("", "", "run_failed: ~{0} ~{1}", log_bfr.Xto_str(), Err_.Message_gplx(e)); diff --git a/400_xowa/src/gplx/xowa/gui/bnds/Xog_bnd_mgr.java b/400_xowa/src/gplx/xowa/gui/bnds/Xog_bnd_mgr.java index 3cecc7caf..dc4a50b26 100644 --- a/400_xowa/src/gplx/xowa/gui/bnds/Xog_bnd_mgr.java +++ b/400_xowa/src/gplx/xowa/gui/bnds/Xog_bnd_mgr.java @@ -142,12 +142,12 @@ public class Xog_bnd_mgr { Init_itm(Xog_cmd_itm_.Key_gui_edit_exec , Xog_bnd_box_.Tid_browser , "mod.c+key.e,mod.c+key.g"); Init_itm(Xog_cmd_itm_.Key_gui_browser_url_focus , Xog_bnd_box_.Tid_browser , "mod.a+key.d", "mod.c+key.l"); - Init_itm(Xog_cmd_itm_.Key_gui_browser_url_exec , Xog_bnd_box_.Tid_browser_url , "key.enter"); - Init_itm(Xog_cmd_itm_.Key_gui_browser_url_exec_new_tab_by_paste , Xog_bnd_box_.Tid_browser_url , "mod.c+key.enter"); - Init_itm(Xog_cmd_itm_.Key_gui_browser_url_exec_by_paste , Xog_bnd_box_.Tid_browser_url , "mouse.middle", "mod.a+key.enter"); + Init_itm(Xog_cmd_itm_.Key_gui_browser_url_exec , Xog_bnd_box_.Tid_browser_url , "key.enter", "key.keypad_enter"); + Init_itm(Xog_cmd_itm_.Key_gui_browser_url_exec_new_tab_by_paste , Xog_bnd_box_.Tid_browser_url , "mod.c+key.enter", "mod.c+key.keypad_enter"); + Init_itm(Xog_cmd_itm_.Key_gui_browser_url_exec_by_paste , Xog_bnd_box_.Tid_browser_url , "mouse.middle", "mod.a+key.enter", "mod.a+key.keypad_enter"); Init_itm(Xog_cmd_itm_.Key_gui_browser_url_restore , Xog_bnd_box_.Tid_browser_url , "mod.c+key.u"); Init_itm(Xog_cmd_itm_.Key_gui_browser_search_focus , Xog_bnd_box_.Tid_browser , "mod.ca+key.s"); - Init_itm(Xog_cmd_itm_.Key_gui_browser_search_exec , Xog_bnd_box_.Tid_browser_search , "key.enter"); + Init_itm(Xog_cmd_itm_.Key_gui_browser_search_exec , Xog_bnd_box_.Tid_browser_search , "key.enter", "key.keypad_enter"); Init_itm(Xog_cmd_itm_.Key_gui_browser_tabs_new_dflt__at_dflt__focus_y , Xog_bnd_box_.Tid_browser , "mod.c+key.t"); Init_itm(Xog_cmd_itm_.Key_gui_browser_tabs_new_link__at_dflt__focus_n , Xog_bnd_box_.Tid_browser_html , "mouse.middle"); Init_itm(Xog_cmd_itm_.Key_gui_browser_tabs_new_href__at_dflt__focus_y , Xog_bnd_box_.Tid_browser , "mod.c+key.g,mod.c+key.f"); @@ -178,7 +178,7 @@ public class Xog_bnd_mgr { Init_itm(Xog_cmd_itm_.Key_gui_browser_find_show , Xog_bnd_box_.Tid_browser , "mod.c+key.f"); Init_itm(Xog_cmd_itm_.Key_gui_browser_find_show_by_paste , Xog_bnd_box_.Tid_browser , ""); Init_itm(Xog_cmd_itm_.Key_gui_browser_find_hide , Xog_bnd_box_.Tid_browser_find , "key.escape"); - Init_itm(Xog_cmd_itm_.Key_gui_browser_find_exec , Xog_bnd_box_.Tid_browser_find , "key.enter"); + Init_itm(Xog_cmd_itm_.Key_gui_browser_find_exec , Xog_bnd_box_.Tid_browser_find , "key.enter", "key.keypad_enter"); Init_itm(Xog_cmd_itm_.Key_gui_browser_find_find_fwd , Xog_bnd_box_.Tid_browser_find , "mod.a+key.n"); Init_itm(Xog_cmd_itm_.Key_gui_browser_find_find_bwd , Xog_bnd_box_.Tid_browser_find , "mod.a+key.p"); Init_itm(Xog_cmd_itm_.Key_gui_browser_find_case_toggle , Xog_bnd_box_.Tid_browser_find , "mod.a+key.c"); diff --git a/400_xowa/src/gplx/xowa/gui/views/Load_page_wkr.java b/400_xowa/src/gplx/xowa/gui/views/Load_page_wkr.java index 3675d3777..614051e39 100644 --- a/400_xowa/src/gplx/xowa/gui/views/Load_page_wkr.java +++ b/400_xowa/src/gplx/xowa/gui/views/Load_page_wkr.java @@ -63,8 +63,8 @@ public class Load_page_wkr implements Gfo_thread_wkr { Thread_adp_.Sleep(10); } if (wiki.Html__hdump_enabled() && html_db_id != -1) { - wiki.ParsePage(page, false); -// wiki.Html__hdump_rdr().Get_by_ttl(page); + // wiki.ParsePage(page, false); + wiki.Html__hdump_rdr().Get_by_ttl(page); } else wiki.ParsePage(page, false); diff --git a/400_xowa/src/gplx/xowa/gui/views/Xog_html_itm.java b/400_xowa/src/gplx/xowa/gui/views/Xog_html_itm.java index ea7728cf9..31162b91d 100644 --- a/400_xowa/src/gplx/xowa/gui/views/Xog_html_itm.java +++ b/400_xowa/src/gplx/xowa/gui/views/Xog_html_itm.java @@ -105,7 +105,7 @@ public class Xog_html_itm implements Xog_js_wkr, GfoInvkAble, GfoEvObj { GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_atr_set, m); } } - public void Html_redlink(String html_uid) {Html_elem_atr_set_append(html_uid, "class", "new");} + public void Html_redlink(String html_uid) {Html_elem_atr_set_append(html_uid, "class", gplx.xowa.html.lnkis.Xoh_redlink_utl.New_str);} public void Html_elem_atr_set_append(String elem_id, String atr_key, String atr_val) { GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_atr_set_append).Add("elem_id", elem_id).Add("atr_key", atr_key).Add("atr_val", atr_val); GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_atr_set_append, m); @@ -122,6 +122,10 @@ public class Xog_html_itm implements Xog_js_wkr, GfoInvkAble, GfoEvObj { GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_append_above, m); } } + public boolean Html_doc_loaded() { + GfoMsg m = GfoMsg_.new_cast_(Invk_html_doc_loaded); + return Bool_.cast_(GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_doc_loaded, m)); + } public void Html_gallery_packed_exec() { if (!String_.Eq(owner_tab.Tab_key(), owner_tab.Tab_mgr().Active_tab().Tab_key())) return; // do not exec unless active; GfoMsg m = GfoMsg_.new_cast_(Invk_html_gallery_packed_exec); @@ -187,6 +191,7 @@ public class Xog_html_itm implements Xog_js_wkr, GfoInvkAble, GfoEvObj { else if (ctx.Match(k, Invk_html_elem_append_above)) html_box.Html_elem_append_above(m.ReadStr("id"), m.ReadStr("html")); else if (ctx.Match(k, Invk_html_gallery_packed_exec)) html_box.Html_gallery_packed_exec(); else if (ctx.Match(k, Invk_html_popups_bind_hover_to_doc)) html_box.Html_js_eval_script("xowa_popups_bind_doc();"); + else if (ctx.Match(k, Invk_html_doc_loaded)) return html_box.Html_doc_loaded(); else if (ctx.Match(k, Invk_scroll_page_by_bmk)) Scroll_page_by_bmk(); else if (ctx.Match(k, Invk_scroll_page_by_id)) Scroll_page_by_id(m.ReadStr("v")); else if (ctx.Match(k, Invk_html_elem_focus)) html_box.Html_elem_focus(m.ReadStr("v")); @@ -198,7 +203,7 @@ public class Xog_html_itm implements Xog_js_wkr, GfoInvkAble, GfoEvObj { Invk_html_gallery_packed_exec = "html_gallery_packed_exec", Invk_html_popups_bind_hover_to_doc = "html_popups_bind_hover_to_doc" , Invk_html_img_update = "html_img_update", Invk_html_elem_atr_set = "html_elem_atr_set" , Invk_html_elem_atr_set_append = "html_elem_atr_set_append", Invk_html_elem_delete = "html_elem_delete", Invk_html_elem_replace_html = "html_elem_replace_html", Invk_html_elem_append_above = "html_elem_append_above" - , Invk_scroll_page_by_bmk = "scroll_page_by_bmk", Invk_scroll_page_by_id = "scroll_page_by_id" + , Invk_scroll_page_by_bmk = "scroll_page_by_bmk", Invk_scroll_page_by_id = "scroll_page_by_id", Invk_html_doc_loaded = "html_doc_loaded" ; public static final String Elem_id__xowa_edit_data_box = "xowa_edit_data_box" diff --git a/400_xowa/src/gplx/xowa/gui/views/Xog_launcher_tabs.java b/400_xowa/src/gplx/xowa/gui/views/Xog_launcher_tabs.java index 67a237732..37f5ed0d3 100644 --- a/400_xowa/src/gplx/xowa/gui/views/Xog_launcher_tabs.java +++ b/400_xowa/src/gplx/xowa/gui/views/Xog_launcher_tabs.java @@ -30,7 +30,7 @@ class Xog_launcher_tabs { // tab.Html_itm().Html_box().Focus(); // focus the html_box so wheel scroll works; DATE:2013-02-08 app.Usr_dlg().Prog_none("", "", ""); log_bfr.Add("app.launch.page.end"); - app.Usr_dlg().Log_wtr().Log_msg_to_session_direct(log_bfr.Xto_str()); + app.Usr_dlg().Log_wkr().Log_to_session_direct(log_bfr.Xto_str()); } private boolean Restore_tabs(Xoae_app app, Xowe_wiki home_wiki, Xog_win_itm win, Io_fil_marker fil_marker) { String[] launch_urls = app.Api_root().App().Startup().Tabs().Calc_startup_strs(app); diff --git a/400_xowa/src/gplx/xowa/gui/views/Xog_tab_itm.java b/400_xowa/src/gplx/xowa/gui/views/Xog_tab_itm.java index 26fddf0fb..eab6064eb 100644 --- a/400_xowa/src/gplx/xowa/gui/views/Xog_tab_itm.java +++ b/400_xowa/src/gplx/xowa/gui/views/Xog_tab_itm.java @@ -113,7 +113,7 @@ public class Xog_tab_itm implements GfoInvkAble { app.Gui_mgr().Search_suggest_mgr().Cancel(); // cancel pending search_suggest calls if (page != null) page.Tab_data().Close_mgr().When_close(this, url); // cancel any current search cmds app.Log_wtr().Queue_enabled_(true); - usr_dlg.Clear(); + usr_dlg.Gui_wkr().Clear(); this.wiki = app.Wiki_mgr().Get_by_key_or_null(url.Wiki_bry()); // NOTE: must update wiki wiki.Init_assert(); // NOTE: assert wiki.Init before parsing; needed b/c lang (with lang-specific ns) is only loaded on init, and parse Xoa_ttl.parse_ will fail below; EX:pt.wikipedia.org/wiki/Wikipedia:P�gina principal Xoa_ttl ttl = Xoa_ttl.parse_(wiki, url.Page_bry()); @@ -160,14 +160,14 @@ public class Xog_tab_itm implements GfoInvkAble { app.User().Data_mgr().History_mgr().Update_async(app.Async_mgr(), ttl, url); } usr_dlg.Prog_none("", "", "rendering html"); - html_itm.Html_box().Size_(tab_mgr.Tab_mgr().Size()); // NOTE: must resize tab here, else scrolling to anchor in background tab doesn't work (html_box has size of 0, 0) DATE:2015-05-03 + // html_itm.Html_box().Size_(tab_mgr.Tab_mgr().Size()); // COMMENTED: causes clicks on macosx to be off by 4 px; NOTE: must resize tab here, else scrolling to anchor in background tab doesn't work (html_box has size of 0, 0) DATE:2015-05-03 // win.Page__async__bgn(this); - Gfo_thread_wkr async_wkr = null; + Gfo_thread_wkr async_wkr = null; if (wkr.Hdump_enabled()) { wiki.File_mgr().Init_file_mgr_by_load(wiki); Xof_fsdb_mgr fsdb_mgr = wiki.File_mgr().Fsdb_mgr(); async_wkr = new Xof_file_wkr(wiki.File__orig_mgr(), fsdb_mgr.Bin_mgr(), fsdb_mgr.Mnt_mgr(), app.File__cache_mgr(), wiki.File__repo_mgr(), html_itm, page, page.Hdump_data().Imgs(), gplx.xowa.files.Xof_exec_tid.Tid_wiki_page); - if (wiki.Html__hdump_enabled()) { + if (wiki.Html__hdump_enabled() && page.Revision_data().Html_db_id() == -1) { wiki.Html__hdump_wtr().Save(page); } } diff --git a/400_xowa/src/gplx/xowa/gui/views/Xog_win_itm.java b/400_xowa/src/gplx/xowa/gui/views/Xog_win_itm.java index 7f1df6812..a9559cdc7 100644 --- a/400_xowa/src/gplx/xowa/gui/views/Xog_win_itm.java +++ b/400_xowa/src/gplx/xowa/gui/views/Xog_win_itm.java @@ -303,6 +303,6 @@ public class Xog_win_itm implements GfoInvkAble, GfoEvObj { if ( !Env_.Mode_testing() && app.App_type().Uid_is_gui()) // only run for gui; do not run for tcp/http server; DATE:2014-05-03 - app.Usr_dlg().Ui_wkr_(new Gfo_usr_dlg_ui_swt(kit, prog_box, info_box, info_box, app.Api_root().Gui().Browser().Info())); + app.Usr_dlg().Gui_wkr_(new Gfo_usr_dlg__gui__swt(kit, prog_box, info_box, info_box, app.Api_root().Gui().Browser().Info())); } } diff --git a/400_xowa/src/gplx/xowa/html/hdumps/Xohd_hdump_rdr.java b/400_xowa/src/gplx/xowa/html/hdumps/Xohd_hdump_rdr.java index e6d2a86bc..77535d220 100644 --- a/400_xowa/src/gplx/xowa/html/hdumps/Xohd_hdump_rdr.java +++ b/400_xowa/src/gplx/xowa/html/hdumps/Xohd_hdump_rdr.java @@ -52,7 +52,7 @@ public class Xohd_hdump_rdr { } Bry_bfr bfr = bfr_mkr.Get_m001(); byte[] body_bry = abrv_mgr.Parse(bfr, rv); - body_bry = hzip_mgr.Parse(bfr, ttl.Page_db(), body_bry); + body_bry = hzip_mgr.Parse(bfr, ttl.Page_db(), body_bry, rv.Redlink_uids()); bfr.Mkr_rls(); rv.Page_body_(body_bry); } diff --git a/400_xowa/src/gplx/xowa/html/hdumps/Xohd_hdump_wtr.java b/400_xowa/src/gplx/xowa/html/hdumps/Xohd_hdump_wtr.java index a652c0ec5..66adc938a 100644 --- a/400_xowa/src/gplx/xowa/html/hdumps/Xohd_hdump_wtr.java +++ b/400_xowa/src/gplx/xowa/html/hdumps/Xohd_hdump_wtr.java @@ -43,7 +43,7 @@ public class Xohd_hdump_wtr { else { hdump_db = core_data_mgr.Dbs__get_at(html_db_id); html_db_id = hdump_db.Id(); - // return; + return; } save_mgr.Update(tmp_bfr, hdump_db.Tbl__html(), page); tmp_bfr.Mkr_rls(); @@ -51,7 +51,7 @@ public class Xohd_hdump_wtr { public void Generate_hdump(Bry_bfr tmp_bfr, Xoae_page page) { page.File_queue().Clear(); // need to reset uid to 0, else xowa_file_# will resume from last page_wtr_mgr.Wkr(Xopg_view_mode.Tid_read).Write_body(tmp_bfr, Xoh_wtr_ctx.Hdump, page); - // page.Wikie().Html_mgr().Hzip_mgr().Write(tmp_bfr, new Xodump_stats_itm(), page.Url().Xto_full_bry(), tmp_bfr.Xto_bry_and_clear()); // hzip data + if (!Env_.Mode_testing()) page.Wikie().Html_mgr().Hzip_mgr().Write(tmp_bfr, new Xodump_stats_itm(), page.Url().Xto_full_bry(), tmp_bfr.Xto_bry_and_clear()); // hzip data; page.Hdump_data().Body_(tmp_bfr.Xto_bry_and_clear()); // write to body bry } } diff --git a/400_xowa/src/gplx/xowa/html/hdumps/abrvs/Xohd_abrv_mgr.java b/400_xowa/src/gplx/xowa/html/hdumps/abrvs/Xohd_abrv_mgr.java index bf727a476..dcc5a8745 100644 --- a/400_xowa/src/gplx/xowa/html/hdumps/abrvs/Xohd_abrv_mgr.java +++ b/400_xowa/src/gplx/xowa/html/hdumps/abrvs/Xohd_abrv_mgr.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.html.hdumps.abrvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*; -import gplx.core.brys.*; import gplx.core.btries.*; +import gplx.core.primitives.*; import gplx.core.brys.*; import gplx.core.btries.*; import gplx.html.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.lnkis.*; import gplx.xowa.files.*; import gplx.xowa.files.repos.*; import gplx.xowa.xtns.gallery.*; import gplx.xowa.wikis.*; import gplx.xowa.apps.fsys.*; @@ -73,7 +73,7 @@ public class Xohd_abrv_mgr { byte tid = itm.Tid(); switch (tid) { case Xohd_abrv_.Tid_dir: bfr.Add(root_dir); return rv; - case Xohd_abrv_.Tid_hiero_dir: bfr.Add(hiero_img_dir); return rv; + case Xohd_abrv_.Tid_hiero_dir: bfr.Add(hiero_img_dir); return rv; case Xohd_abrv_.Tid_redlink: return Write_redlink(bfr, hpg, uid, rv); } if (itm.Elem_is_xnde()) rv += 2; // if xnde, skip "/>" @@ -131,14 +131,12 @@ public class Xohd_abrv_mgr { return rv; } private int Write_redlink(Bry_bfr bfr, Xog_page hpg, int uid, int rv) { - int[] redlink_uids = hpg.Redlink_uids(); if (redlink_uids == null) return rv; - int redlink_uid_max = redlink_uids.length; - if (uid < redlink_uid_max && redlink_uids[uid] == 1) - bfr.Add(Redlink_cls_new); + if (hpg.Redlink_uids().Has(redlink_key.Val_(uid))) + bfr.Add(Xoh_redlink_utl.Cls_bry); else bfr.Del_by_1(); return rv; - } private static final byte[] Redlink_cls_new = Bry_.new_ascii_("class='new'"); + } private final Int_obj_ref redlink_key = Int_obj_ref.neg1_(); public static final Bry_fmtr fmtr_img = Bry_fmtr.new_("src='~{src}' width='~{w}' height='~{h}'", "src", "w", "h"); private static final Btrie_slim_mgr trie = Xohd_abrv_.new_trie(); } diff --git a/400_xowa/src/gplx/xowa/html/hdumps/abrvs/Xohd_abrv_mgr_tst.java b/400_xowa/src/gplx/xowa/html/hdumps/abrvs/Xohd_abrv_mgr_tst.java index 539900215..fad945857 100644 --- a/400_xowa/src/gplx/xowa/html/hdumps/abrvs/Xohd_abrv_mgr_tst.java +++ b/400_xowa/src/gplx/xowa/html/hdumps/abrvs/Xohd_abrv_mgr_tst.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.html.hdumps.abrvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*; -import org.junit.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hdumps.data.*; import gplx.xowa.files.*; +import org.junit.*; import gplx.core.primitives.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hdumps.data.*; import gplx.xowa.files.*; import gplx.xowa2.gui.*; public class Xohd_abrv_mgr_tst { @Before public void init() { @@ -88,7 +88,7 @@ public class Xohd_abrv_mgr_tst { )); } @Test public void Redlink() { - fxt .Init_data_redlink(2, 1, 2); + fxt .Init_data_redlink(1, 2); fxt .Init_body(String_.Concat_lines_nl_skip_last ( "A" , "B" @@ -136,14 +136,12 @@ class Xohd_abrv_mgr_fxt { img_list.Add(img); return this; } - public Xohd_abrv_mgr_fxt Init_data_redlink(int max, int... uids) { - int[] ary = new int[max + ListAdp_.Base1]; + public Xohd_abrv_mgr_fxt Init_data_redlink(int... uids) { int uids_len = uids.length; for (int i = 0; i < uids_len; ++i) { - int uid = uids[i]; - ary[uid] = 1; + Int_obj_ref redlink_uid = Int_obj_ref.new_(uids[i]); + hpg.Redlink_uids().Add(redlink_uid, redlink_uid); } - hpg.Redlink_uids_(ary); return this; } public Xohd_abrv_mgr_fxt Test_html(String expd) { diff --git a/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_link_dump_cmd.java b/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_link_dump_cmd.java index b3b280f7f..900ec85ba 100644 --- a/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_link_dump_cmd.java +++ b/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_link_dump_cmd.java @@ -35,7 +35,8 @@ public class Xob_link_dump_cmd { Db_attach_cmd.new_(conn, "page_db", page_db_url) .Add_fmt("update trg_page_id", String_.Concat_lines_nl_skip_last ( "REPLACE INTO link_dump" - , "SELECT r.src_page_id" + , "SELECT r.uid" + , ", r.src_page_id" , ", r.src_html_uid" , ", Coalesce(p.page_id, -1)" , ", r.trg_ns" diff --git a/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_link_dump_tbl.java b/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_link_dump_tbl.java index e185bced7..5248dc62b 100644 --- a/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_link_dump_tbl.java +++ b/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_link_dump_tbl.java @@ -20,7 +20,8 @@ import gplx.dbs.*; class Xob_link_dump_tbl implements RlsAble { public static final String Tbl_name = "link_dump"; private static final Db_meta_fld_list flds = Db_meta_fld_list.new_(); public static final String - Fld_src_page_id = flds.Add_int("src_page_id") + Fld_uid = flds.Add_int_pkey_autonum("uid") + , Fld_src_page_id = flds.Add_int("src_page_id") , Fld_src_html_uid = flds.Add_int("src_html_uid") , Fld_trg_page_id = flds.Add_int_dflt("trg_page_id", -1) , Fld_trg_ns = flds.Add_int("trg_ns") @@ -47,9 +48,10 @@ class Xob_link_dump_tbl implements RlsAble { public void Rls() { stmt_insert = Db_stmt_.Rls(stmt_insert); } - public void Insert_bgn() {conn.Txn_bgn(); stmt_insert = conn.Stmt_insert(Tbl_name, flds);} + public void Insert_bgn() {conn.Txn_bgn();} public void Insert_end() {conn.Txn_end(); stmt_insert = Db_stmt_.Rls(stmt_insert);} public void Insert_cmd_by_batch(int src_page_id, int src_html_uid, int trg_ns, byte[] trg_ttl) { + if (stmt_insert == null) stmt_insert = conn.Stmt_insert(Tbl_name, flds.To_str_ary_wo_autonum()); stmt_insert.Clear().Val_int(Fld_src_page_id, src_page_id) .Val_int(Fld_src_html_uid, src_html_uid).Val_int(Fld_trg_page_id, -1).Val_int(Fld_trg_ns, trg_ns).Val_bry_as_str(Fld_trg_ttl, trg_ttl) .Exec_insert(); diff --git a/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_redlink_mkr_cmd.java b/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_redlink_mkr_cmd.java index 2ade84a9e..f9994930a 100644 --- a/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_redlink_mkr_cmd.java +++ b/400_xowa/src/gplx/xowa/html/hdumps/bldrs/Xob_redlink_mkr_cmd.java @@ -47,6 +47,7 @@ public class Xob_redlink_mkr_cmd extends Xob_itm_basic_base implements Xob_cmd { int page_id = rdr.Read_int(page_tbl.Fld_page_id()); if (cur_page_id != page_id) { if (cur_page_id != -1) Commit(html_dump_tbl, cur_page_id, bfr); + bfr.Add_int_variable(gplx.xowa.html.hdumps.core.Xohd_data_tid.Tid_redlink).Add_byte_pipe(); cur_page_id = page_id; } // add html_uid to cur_page's bfr diff --git a/400_xowa/src/gplx/xowa/html/hdumps/data/Xohd_page_html_mgr__load.java b/400_xowa/src/gplx/xowa/html/hdumps/data/Xohd_page_html_mgr__load.java index 125432f00..d7c9a7575 100644 --- a/400_xowa/src/gplx/xowa/html/hdumps/data/Xohd_page_html_mgr__load.java +++ b/400_xowa/src/gplx/xowa/html/hdumps/data/Xohd_page_html_mgr__load.java @@ -16,14 +16,12 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.html.hdumps.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*; -import gplx.core.brys.*; import gplx.core.btries.*; import gplx.dbs.*; import gplx.ios.*; +import gplx.core.primitives.*; import gplx.core.brys.*; import gplx.core.btries.*; import gplx.dbs.*; import gplx.ios.*; import gplx.xowa.dbs.*; import gplx.xowa.pages.*; import gplx.xowa.html.hdumps.core.*; import gplx.xowa.html.hdumps.data.*; import gplx.xowa.html.hdumps.pages.*; import gplx.xowa.pages.skins.*; import gplx.xowa.html.hdumps.data.srl.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa2.gui.*; public class Xohd_page_html_mgr__load { private final Xohd_page_srl_mgr srl_mgr = Xohd_page_srl_mgr.I; - private final Bry_rdr rdr = new Bry_rdr(); private final ListAdp rows = ListAdp_.new_(), imgs = ListAdp_.new_(); - private static final int redlink_list_max = 1024; - private final int[] redlink_list = new int[redlink_list_max]; + private final Bry_rdr rdr = new Bry_rdr(); private final ListAdp rows = ListAdp_.new_(), imgs = ListAdp_.new_(); public void Load_page(Xow_wiki wiki, Xog_page hpg, Xowd_html_tbl tbl, int page_id, Xoa_ttl page_ttl) { tbl.Select_by_page(rows, page_id); Parse_rows(wiki, hpg, page_id, Xoa_url.blank_(), page_ttl, rows); @@ -61,7 +59,7 @@ public class Xohd_page_html_mgr__load { switch (tid) { case Xohd_data_itm__base.Tid_basic : img_itm = new Xohd_data_itm__img(); break; case Xohd_data_itm__base.Tid_gallery : img_itm = new Xohd_data_itm__gallery_itm(); break; - default: return null; // TODO: remove; needed for redlink + default : throw Err_.unhandled(tid); } img_itm.Data_parse(rdr); rdr.Pos_add_one(); @@ -73,10 +71,11 @@ public class Xohd_page_html_mgr__load { imgs.Add(img); } private void Load_data_redlink(Xog_page hpg) { - int len = 0; - while (!rdr.Pos_is_eos() && len < redlink_list_max) - redlink_list[len++] = rdr.Read_int_to_pipe(); - hpg.Redlink_uids_(Int_.Ary_copy(redlink_list, len)); + OrderedHash redlink_hash = hpg.Redlink_uids(); + while (!rdr.Pos_is_eos()) { + Int_obj_ref redlink_uid = Int_obj_ref.new_(rdr.Read_int_to_pipe()); + redlink_hash.Add(redlink_uid, redlink_uid); + } } private void Load_data_gallery(Xog_page hpg) { int uid = rdr.Read_int_to_pipe(); diff --git a/400_xowa/src/gplx/xowa/html/hzips/Xodump_stats_tbl.java b/400_xowa/src/gplx/xowa/html/hzips/Xodump_stats_tbl.java index c1084f0d1..2113f2462 100644 --- a/400_xowa/src/gplx/xowa/html/hzips/Xodump_stats_tbl.java +++ b/400_xowa/src/gplx/xowa/html/hzips/Xodump_stats_tbl.java @@ -33,7 +33,7 @@ public class Xodump_stats_tbl implements RlsAble { public Xodump_stats_tbl(Db_conn conn) { this.conn = conn; this.Create_tbl(); - conn.Stmt_delete(tbl_name); // always zap table + conn.Stmt_delete(tbl_name).Exec_delete(); // always zap table conn.Rls_reg(this); } public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds, Db_meta_idx.new_unique_by_tbl(tbl_name, "pkey", fld_page_id)));} diff --git a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor.java b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor.java index 851d10f25..9a33204a4 100644 --- a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor.java +++ b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor.java @@ -57,34 +57,38 @@ public class Xow_hzip_itm__anchor { return bry_rdr.Pos() + 2; // +2=/> } public int Save_lnki(Bry_bfr bfr, Xodump_stats_itm stats, byte[] src, int src_len, int bgn, int pos, boolean caption) { + // href int ttl_bgn = Bry_finder.Find_fwd(src, Find_href_bry, pos, src_len); if (ttl_bgn == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled;//hzip_mgr.Warn_by_pos_add_dflt("a.ttl_bgn_missing", bgn, pos); ttl_bgn += Find_href_bry.length; - // get site + // site or wiki; EX: "/site/" or "/wiki/" byte[] site = null; Object href_tid_obj = btrie_href.Match_bgn(src, ttl_bgn, src_len); if (href_tid_obj == null) return Xow_hzip_mgr.Unhandled; // not "/wiki/" or "/site/" - if (((Byte_obj_val)href_tid_obj).Val() == Href_tid_site) { - // /site/en.wiktionary.org/ + if (((Byte_obj_val)href_tid_obj).Val() == Href_tid_site) { // site; EX:"/site/en.wiktionary.org/" int site_bgn = ttl_bgn + Href_bry_len; int site_end = Bry_finder.Find_fwd(src, Byte_ascii.Slash, site_bgn); byte[] site_domain = Bry_.Mid(src, site_bgn, site_end); site = site_domain; } - else + else // page; EX: "/wiki/Page" ttl_bgn += Href_bry_len; int ttl_end = Bry_finder.Find_fwd(src, Byte_ascii.Quote, ttl_bgn , src_len); if (ttl_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.ttl_end_missing", bgn, ttl_bgn); Xoa_ttl ttl = ttl_parser.Ttl_parse(Bry_.Mid(src, ttl_bgn, ttl_end)); if (ttl == null) return hzip_mgr.Warn_by_pos("a.ttl_invalid", ttl_bgn, ttl_end); -// int id_bgn = Bry_finder.Find_fwd(src, Find_id_bry, ttl_end, src_len); if (id_bgn == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled; -// id_bgn += Find_id_bry.length; -// int id_end = Bry_finder.Find_fwd(src, Byte_ascii.Quote, id_bgn, src_len); if (id_end == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled; -// int id = Bry_.Xto_int_or(src, id_bgn, id_end, -1); if (id == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled; int a_lhs_end = Bry_finder.Find_fwd(src, Byte_ascii.Gt, ttl_end, src_len); if (a_lhs_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.a_lhs_end_missing", bgn, ttl_end); ++a_lhs_end; // skip > + // id + int id_bgn = Bry_finder.Find_fwd(src, Find_id_bry, ttl_end, src_len); if (id_bgn == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled; + if (id_bgn > a_lhs_end) return Xow_hzip_mgr.Unhandled; + id_bgn += Find_id_bry.length + gplx.xowa.parsers.lnkis.redlinks.Xopg_redlink_lnki_list.Lnki_id_prefix_len; + int id_end = Bry_finder.Find_fwd(src, Byte_ascii.Quote, id_bgn, src_len); if (id_end == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled; + int id = Bry_.Xto_int_or(src, id_bgn, id_end, -1); if (id == Bry_finder.Not_found) return Xow_hzip_mgr.Unhandled; int a_rhs_bgn = Bry_finder.Find_fwd(src, Find_a_rhs_bgn_bry, a_lhs_end, src_len); if (a_rhs_bgn == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.a_rhs_bgn_missing", bgn, ttl_end); + // caption if (caption) bfr.Add(Xow_hzip_dict.Bry_lnki_text_y); else bfr.Add(Xow_hzip_dict.Bry_lnki_text_n); bfr.Add_byte((byte)ttl.Ns().Ord()); // ASSUME:NS_MAX_255; no more than 255 ns in wiki; note that ids > 255 still supported + Xow_hzip_int_.Save_bin_int_abrv(bfr, id); if (site != null) { bfr.Add_byte_pipe().Add(site).Add_byte_pipe(); } @@ -158,17 +162,23 @@ public class Xow_hzip_itm__anchor { return hzip_mgr.Warn_by_pos("a.xtid_unknown", href_bgn, href_end); } } - public int Load_lnki(Bry_bfr bfr, byte[] src, int src_len, int bgn, byte tid) { + private final Int_obj_ref id_count_ref = Int_obj_ref.neg1_(); + public int Load_lnki(Bry_bfr bfr, byte[] src, int src_len, int bgn, byte tid, OrderedHash redlink_uids) { + // ns; 255 max byte ns_ord = src[bgn]; Xow_ns ns = ttl_parser.Ns_mgr().Ords_get_at(ns_ord); + // id + int id = Xow_hzip_int_.Load_bin_int_abrv(src, src_len, bgn + 1, id_count_ref); + // site byte[] site_bry = null; - int ttl_bgn = bgn + 1; - if (src[ttl_bgn] == Byte_ascii.Pipe) { // site + int ttl_bgn = bgn + 1 + id_count_ref.Val(); + if (src[ttl_bgn] == Byte_ascii.Pipe) { // if "|" after ns, then site is present; EX: "0|enwiki" vs. "0page" int site_bgn = ttl_bgn + 1; int site_end = Bry_finder.Find_fwd(src, Byte_ascii.Pipe, site_bgn, src_len); site_bry = Bry_.Mid(src, site_bgn, site_end); ttl_bgn = site_end + 1; } + // page int ttl_end = Bry_finder.Find_fwd(src, Xow_hzip_dict.Escape, ttl_bgn, src_len); if (ttl_end == Bry_finder.Not_found) return hzip_mgr.Warn_by_pos_add_dflt("a.ttl_end_missing", bgn, ttl_bgn); byte[] ttl_bry = Bry_.Mid(src, ttl_bgn, ttl_end); Xoa_ttl ttl = ttl_parser.Ttl_parse(ns.Id(), ttl_bry); @@ -179,7 +189,11 @@ public class Xow_hzip_itm__anchor { bfr.Add(site_bry); } bfr.Add_str_ascii("/wiki/"); - bfr.Add(Html_utl.Escape_html_as_bry(ttl_full)).Add_str("' title='"); + bfr.Add(Html_utl.Escape_html_as_bry(ttl_full)); + if (redlink_uids.Has(id_count_ref.Val_(id))) + bfr.Add_str_ascii("' class='xowa_disabled"); + bfr.Add_str_ascii("' id='").Add_str_ascii(gplx.xowa.parsers.lnkis.redlinks.Xopg_redlink_lnki_list.Lnki_id_prefix).Add_int_variable(id); + bfr.Add_str_ascii("' title='"); int rv = ttl_end + 1; if (tid == Xow_hzip_dict.Tid_lnki_text_n) { if (ns.Id() != 0) ttl_bry = ttl_full; @@ -201,7 +215,7 @@ public class Xow_hzip_itm__anchor { } private static final byte[] Find_href_bry = Bry_.new_ascii_(" href=\"") -// , Find_id_bry = Bry_.new_ascii_(" id=\"") + , Find_id_bry = Bry_.new_ascii_(" id=\"") , Find_a_rhs_bgn_bry = Bry_.new_ascii_("") , Find_img_xatrs = Bry_.new_ascii_("xatrs='") ; diff --git a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor_tst.java b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor_tst.java index 45037a9f9..89c55faf3 100644 --- a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor_tst.java +++ b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor_tst.java @@ -20,52 +20,61 @@ import org.junit.*; import gplx.xowa.html.*; public class Xow_hzip_itm__anchor_tst { @Before public void init() {fxt.Clear();} private Xow_hzip_mgr_fxt fxt = new Xow_hzip_mgr_fxt(); @Test public void Srl_lnki_text_n() { - byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry); // 2=ns_ord for Main - fxt.Test_save(brys, "A"); - fxt.Test_load(brys, "A"); + byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry); // 2=ns_ord for Main + fxt.Test_save(brys, "A"); + fxt.Test_load(brys, "A"); } @Test public void Srl_lnki_text_n_alt_case() { - byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), Bry_.new_ascii_("a"), Xow_hzip_dict.Escape_bry); - fxt.Test_save(brys, "a"); - fxt.Test_load(brys, "a"); + byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_ascii_("a"), Xow_hzip_dict.Escape_bry); + fxt.Test_save(brys, "a"); + fxt.Test_load(brys, "a"); } @Test public void Srl_lnki_text_n_ns() { - byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(12), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry); - fxt.Test_save(brys, "Template:A"); - fxt.Test_load(brys, "Template:A"); + byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(12), fxt.Make_int(3), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry); + fxt.Test_save(brys, "Template:A"); + fxt.Test_load(brys, "Template:A"); } @Test public void Srl_lnki_text_n_apos() { - byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(12), Bry_.new_ascii_("A'b"), Xow_hzip_dict.Escape_bry); - fxt.Test_save(brys, "Template:A'b"); - fxt.Test_load(brys, "Template:A'b"); + byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(12), fxt.Make_int(3), Bry_.new_ascii_("A'b"), Xow_hzip_dict.Escape_bry); + fxt.Test_save(brys, "Template:A'b"); + fxt.Test_load(brys, "Template:A'b"); } @Test public void Srl_lnki_text_n_xwiki() { - byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), Byte_ascii.Pipe_bry, Bry_.new_ascii_("en.wiktionary.org"), Byte_ascii.Pipe_bry, Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry); - fxt.Test_save(brys, "A"); - fxt.Test_load(brys, "A"); + byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Byte_ascii.Pipe_bry, Bry_.new_ascii_("en.wiktionary.org"), Byte_ascii.Pipe_bry, Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry); + fxt.Test_save(brys, "A"); + fxt.Test_load(brys, "A"); } @Test public void Srl_lnki_text_n_smoke() { - byte[][] brys = Bry_.Ary(Bry_.new_ascii_("a_1"), Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry, Bry_.new_ascii_("a_2")); - fxt.Test_save(brys, "a_1Aa_2"); - fxt.Test_load(brys, "a_1Aa_2"); + byte[][] brys = Bry_.Ary(Bry_.new_ascii_("a_1"), Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry, Bry_.new_ascii_("a_2")); + fxt.Test_save(brys, "a_1Aa_2"); + fxt.Test_load(brys, "a_1Aa_2"); } @Test public void Srl_lnki_text_y() { - byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry, Bry_.new_ascii_("A1"), Xow_hzip_dict.Bry_a_rhs); - fxt.Test_save(brys, "A1"); - fxt.Test_load(brys, "A1"); + byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry, Bry_.new_ascii_("A1"), Xow_hzip_dict.Bry_a_rhs); + fxt.Test_save(brys, "A1"); + fxt.Test_load(brys, "A1"); } @Test public void Srl_lnki_text_y_nest() { byte[][] brys = Bry_.Ary - ( Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry - , Bry_.new_ascii_("B"), Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), Bry_.new_ascii_("C"), Xow_hzip_dict.Escape_bry, Bry_.new_ascii_("C1"), Xow_hzip_dict.Bry_a_rhs, Bry_.new_ascii_("D") + ( Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry + , Bry_.new_ascii_("B"), Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_ascii_("C"), Xow_hzip_dict.Escape_bry, Bry_.new_ascii_("C1"), Xow_hzip_dict.Bry_a_rhs, Bry_.new_ascii_("D") , Xow_hzip_dict.Bry_a_rhs ); - fxt.Test_save(brys, "BC1D"); - fxt.Test_load(brys, "BC1D"); + fxt.Test_save(brys, "BC1D"); + fxt.Test_load(brys, "BC1D"); } @Test public void Srl_noop() { - byte[][] brys = Bry_.Ary(Bry_.new_utf8_("A"), Xow_hzip_dict.Bry_a_rhs); + byte[][] brys = Bry_.Ary(Bry_.new_utf8_("A"), Xow_hzip_dict.Bry_a_rhs); // NOTE: still converts "" to hzip fxt.Test_save(brys, "A"); + fxt.Test_load(brys, "A"); + } + @Test public void Srl_lnki_text_y__multiple() { // PURPOSE: if id is missing from 1st anchor, do not get from second + byte[][] brys = Bry_.Ary(Bry_.new_utf8_("A") + , Xow_hzip_dict.Bry_a_rhs + , Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_ascii_("B"), Xow_hzip_dict.Escape_bry + ); + fxt.Test_save(brys, "AB"); + fxt.Test_load(brys, "AB"); } @Test public void Srl_lnke_txt() { byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnke_txt, Bry_.new_ascii_("http://a.org"), Xow_hzip_dict.Escape_bry); @@ -93,7 +102,7 @@ public class Xow_hzip_itm__anchor_tst { } @Test public void Html_lnki_xwiki() { fxt.Init_xwiki("wikt", "en.wiktionary.org"); - fxt.Test_html("[[wikt:A]]", "wikt:A"); + fxt.Test_html("[[wikt:A]]", "wikt:A"); } @Test public void Html_lnke_txt() { fxt.Test_html("http://a.org", "http://a.org"); diff --git a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_mgr.java b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_mgr.java index 9dad9fdf7..0bc188f3d 100644 --- a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_mgr.java +++ b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_mgr.java @@ -57,7 +57,7 @@ public class Xow_hzip_mgr { } if (add_bgn != -1) bfr.Add_mid(src, add_bgn, src_len); } - public byte[] Parse(Bry_bfr rv, byte[] page_url, byte[] src) { + public byte[] Parse(Bry_bfr rv, byte[] page_url, byte[] src, OrderedHash redlink_uids) { this.page_url = page_url; this.src = src; this.src_len = src.length; int pos = 0, add_bgn = -1; @@ -71,7 +71,7 @@ public class Xow_hzip_mgr { byte tid = src[tid_pos]; switch (tid) { case Xow_hzip_dict.Tid_lnki_text_n: - case Xow_hzip_dict.Tid_lnki_text_y: pos = itm__anchor.Load_lnki(rv, src, src_len, itm_pos, tid); break; + case Xow_hzip_dict.Tid_lnki_text_y: pos = itm__anchor.Load_lnki(rv, src, src_len, itm_pos, tid, redlink_uids); break; case Xow_hzip_dict.Tid_lnke_txt: case Xow_hzip_dict.Tid_lnke_brk_text_n: case Xow_hzip_dict.Tid_lnke_brk_text_y: pos = itm__anchor.Load_lnke(rv, src, src_len, itm_pos, tid); break; diff --git a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_mgr_fxt.java b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_mgr_fxt.java index 1a505dbcd..041fce0bd 100644 --- a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_mgr_fxt.java +++ b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_mgr_fxt.java @@ -18,7 +18,7 @@ along with this program. If not, see . package gplx.xowa.html.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; class Xow_hzip_mgr_fxt { private Bry_bfr bfr = Bry_bfr.reset_(Io_mgr.Len_mb); private Xow_hzip_mgr hzip_mgr; private Xowe_wiki wiki; - private Xodump_stats_itm stats = new Xodump_stats_itm(); + private Xodump_stats_itm stats = new Xodump_stats_itm(); private final OrderedHash redlink_uids = OrderedHash_.new_(); public void Clear() { if (hzip_mgr == null) { Xoae_app app = Xoa_app_fxt.app_(); @@ -31,6 +31,7 @@ class Xow_hzip_mgr_fxt { wiki.Xwiki_mgr().Add_full(alias, domain); wiki.Appe().User().Wiki().Xwiki_mgr().Add_full(domain, domain); } + public byte[] Make_int(int v) {return Xow_hzip_int_.Save_bin_int_abrv(v);} public void Test_save(byte[][] expd_brys, String html) {Test_save(html, expd_brys);} public void Test_save(String html, byte[]... expd_brys) { byte[] expd = Bry_.Add(expd_brys); @@ -39,7 +40,7 @@ class Xow_hzip_mgr_fxt { } public void Test_load(byte[][] src_brys, String expd) { byte[] src = Bry_.Add(src_brys); - src = hzip_mgr.Parse(bfr, Bry_.Empty, src); + src = hzip_mgr.Parse(bfr, Bry_.Empty, src, redlink_uids); Tfds.Eq(expd, String_.new_utf8_(src)); } public void Test_html(String html, String expd) { diff --git a/400_xowa/src/gplx/xowa/html/lnkis/Xoh_redlink_utl.java b/400_xowa/src/gplx/xowa/html/lnkis/Xoh_redlink_utl.java new file mode 100644 index 000000000..1463594dc --- /dev/null +++ b/400_xowa/src/gplx/xowa/html/lnkis/Xoh_redlink_utl.java @@ -0,0 +1,22 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.html.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; +public class Xoh_redlink_utl { + public static final byte[] Cls_bry = Bry_.new_ascii_("class='new'"); + public static final String New_str = "new"; +} diff --git a/400_xowa/src/gplx/xowa/parsers/lnkis/redlinks/Xog_redlink_mgr.java b/400_xowa/src/gplx/xowa/parsers/lnkis/redlinks/Xog_redlink_mgr.java index e10bd63fa..417cb89a2 100644 --- a/400_xowa/src/gplx/xowa/parsers/lnkis/redlinks/Xog_redlink_mgr.java +++ b/400_xowa/src/gplx/xowa/parsers/lnkis/redlinks/Xog_redlink_mgr.java @@ -27,7 +27,7 @@ public class Xog_redlink_mgr implements GfoInvkAble { this.redlink_lnki_list = page.Redlink_lnki_list(); this.lnki_list = redlink_lnki_list.Lnki_list(); this.thread_id = redlink_lnki_list.Thread_id(); - this.log_enabled = log_enabled; this.usr_dlg = log_enabled ? Gfo_usr_dlg_.I : Gfo_usr_dlg_.Null; + this.log_enabled = log_enabled; this.usr_dlg = log_enabled ? Gfo_usr_dlg_.I : Gfo_usr_dlg_.Noop; } public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_run)) Redlink(); diff --git a/400_xowa/src/gplx/xowa/parsers/lnkis/redlinks/Xopg_redlink_lnki_list.java b/400_xowa/src/gplx/xowa/parsers/lnkis/redlinks/Xopg_redlink_lnki_list.java index 25ae668c9..539048d53 100644 --- a/400_xowa/src/gplx/xowa/parsers/lnkis/redlinks/Xopg_redlink_lnki_list.java +++ b/400_xowa/src/gplx/xowa/parsers/lnkis/redlinks/Xopg_redlink_lnki_list.java @@ -35,6 +35,7 @@ public class Xopg_redlink_lnki_list { if (disabled) return; Xoa_ttl ttl = lnki.Ttl(); if (ttl == null) return; // occurs for invalid links Xow_ns ns = ttl.Ns(); + lnki.Html_id_(lnki_idx); // NOTE: set html_id in order html to print out "id='xowa_lnki_1'; want to print out id for consistency's sake, even if these links won't be check for redlinks; DATE:2015-05-07 if ( ns.Id_file_or_media() // ignore files which will usually not be in local wiki (most are in commons), and whose html is built up separately || (ns.Id_ctg() && !ttl.ForceLiteralLink()) // ignore ctgs which have their own html builder, unless it is literal; EX: [[:Category:A]]; DATE:2014-02-24 || ns.Id_special() // ignore special, especially Search; EX: Special:Search/Earth @@ -42,9 +43,9 @@ public class Xopg_redlink_lnki_list { || ttl.Wik_itm() != null // xwiki lnki; EX: simplewiki links in homewiki; [[simplewiki:Earth]] ) return; - lnki.Html_id_(lnki_idx); lnki_list.Add(lnki); ++lnki_idx; } public static final String Lnki_id_prefix = "xowa_lnki_"; + public static final int Lnki_id_prefix_len = String_.Len(Lnki_id_prefix); } diff --git a/400_xowa/src/gplx/xowa/servers/Gxw_html_server.java b/400_xowa/src/gplx/xowa/servers/Gxw_html_server.java index f5be0beb2..dec03cbbd 100644 --- a/400_xowa/src/gplx/xowa/servers/Gxw_html_server.java +++ b/400_xowa/src/gplx/xowa/servers/Gxw_html_server.java @@ -39,6 +39,7 @@ public class Gxw_html_server implements Gxw_html { public boolean Html_doc_find(String id, String find, boolean dir_fwd, boolean case_match, boolean wrap_find) {throw Err_.not_implemented_();} public void Html_doc_body_focus() {Exec(cfg.Doc_body_focus());} public void Html_doc_selection_focus_toggle() {Exec(cfg.Doc_selection_focus_toggle());} + public boolean Html_doc_loaded() {return Bool_.cast_(Exec(cfg.Doc_loaded()));} public String Html_elem_atr_get_str (String id, String atr_key) {return Exec(cfg.Elem_atr_get(id, atr_key));} public boolean Html_elem_atr_get_bool (String id, String atr_key) {return Bool_.parse_(Exec(cfg.Elem_atr_get(id, atr_key)));} public boolean Html_elem_atr_set (String id, String atr_key, String val) {return Exec_as_bool(cfg.Elem_atr_set(id, atr_key, val));} diff --git a/400_xowa/src/gplx/xowa/setup/maints/Xoa_maint_mgr.java b/400_xowa/src/gplx/xowa/setup/maints/Xoa_maint_mgr.java index 58f71f42c..f1f5c1cf3 100644 --- a/400_xowa/src/gplx/xowa/setup/maints/Xoa_maint_mgr.java +++ b/400_xowa/src/gplx/xowa/setup/maints/Xoa_maint_mgr.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.setup.maints; import gplx.*; import gplx.xowa.*; import gplx.xowa.setup.*; -import gplx.ios.*; import gplx.xowa.wikis.*; +import gplx.ios.*; import gplx.xowa.wikis.*; import gplx.xowa.files.downloads.*; public class Xoa_maint_mgr implements GfoInvkAble { public Xoa_maint_mgr(Xoae_app app) { this.app = app; diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java b/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java index a93987001..e860bb8ec 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -import gplx.xowa.specials.search.parsers.*; +import gplx.xowa.specials.search.parsers_old.*; class Xows_db_cache { // one cache per search term; EX: "Earth* AND (History OR Future) AND -"middle earth"" is one cache private final OrderedHash hash = OrderedHash_.new_bry_(); public Xows_db_word[] Words() {return words;} private Xows_db_word[] words; // words in cache; EX: earth, history, future but not "middle earth" (since not'ed) diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_parser__v1.java b/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_parser__v1.java new file mode 100644 index 000000000..749336d42 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_parser__v1.java @@ -0,0 +1,68 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.specials.search.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +import gplx.core.primitives.*; +class Xows_text_parser__v1 { + private Xol_lang lang; private Bry_bfr bfr = Bry_bfr.new_(255); + private final OrderedHash list = OrderedHash_.new_bry_(); + public void Init(Xol_lang lang) {this.lang = lang;} + public void Parse(byte[] src, int src_len, int bgn, int end) { + if (lang != null) { // null lang passed in by searcher + src = lang.Case_mgr().Case_build_lower(src); + src_len = src.length; + } + int i = 0; boolean word_done = false; + while (true) { + if (word_done || i == src_len) { + if (bfr.Len() > 0) { + byte[] word = bfr.Xto_bry_and_clear(); + if (!list.Has(word)) list.Add(word, word); // don't add same word twice; EX: Title of "Can Can" should only have "Can" in index + } + if (i == src_len) break; + word_done = false; + } + byte b = src[i]; + switch (b) { + case Byte_ascii.Underline: // underline is word-breaking; EX: A_B -> A, B + case Byte_ascii.Space: // should not occur, but just in case (only underscores) + case Byte_ascii.Tab: case Byte_ascii.NewLine: case Byte_ascii.CarriageReturn: // should not occur in titles, but just in case + + case Byte_ascii.Dash: // treat hypenated words separately + case Byte_ascii.Dot: // treat abbreviations as separate words; EX: A.B.C. + case Byte_ascii.Bang: case Byte_ascii.Hash: case Byte_ascii.Dollar: case Byte_ascii.Percent: + case Byte_ascii.Amp: case Byte_ascii.Paren_bgn: case Byte_ascii.Paren_end: case Byte_ascii.Asterisk: + case Byte_ascii.Comma: case Byte_ascii.Slash: + case Byte_ascii.Colon: case Byte_ascii.Semic: case Byte_ascii.Gt: + case Byte_ascii.Question: case Byte_ascii.At: case Byte_ascii.Brack_bgn: case Byte_ascii.Brack_end: + case Byte_ascii.Pow: case Byte_ascii.Tick: + case Byte_ascii.Curly_bgn: case Byte_ascii.Pipe: case Byte_ascii.Curly_end: case Byte_ascii.Tilde: + case Byte_ascii.Quote: case Byte_ascii.Apos: // FUTURE: apos will split "Earth's" to Earth and s; should remove latter + ++i; + word_done = true; + break; + default: + bfr.Add_byte(b); + ++i; + break; + } + } +// byte[][] rv = (byte[][])list.Xto_ary(typeof(byte[])); +// list.Clear(); list.ResizeBounds(16); +// return rv; + } +} diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_parser__v2.java b/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_parser__v2.java new file mode 100644 index 000000000..1efeaf978 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_parser__v2.java @@ -0,0 +1,107 @@ +/* +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 . +*/ +package gplx.xowa.specials.search.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +import gplx.core.btries.*; import gplx.xowa.langs.cases.*; +class Xows_text_parser__v2 { + private final Btrie_slim_mgr trie = Btrie_slim_mgr.cs_(); + private final Bry_bfr bfr = Bry_bfr.new_(32); + private Xob_word_mgr word_mgr; private Xol_case_mgr case_mgr; + private byte[] src; private int end; // bgn, + private boolean dirty; private Xows_text_tkn__split parser__ws; + public void Init_for_ttl(Xob_word_mgr word_mgr, Xol_case_mgr case_mgr) { + this.word_mgr = word_mgr; this.case_mgr = case_mgr; + trie.Clear(); + this.parser__ws = Xows_text_tkn__split.new_(trie, Bool_.N, " ", "\t", "\n", "\r", "_"); + Xows_text_tkn__split.new_(trie, Bool_.N, "!", "?"); + Xows_text_tkn__split.new_(trie, Bool_.N, "(", ")"); + Xows_text_tkn__split.new_(trie, Bool_.N, "/"); + Xows_text_tkn__ellipsis.new_(trie, ".."); + Xows_text_tkn__apos.new_(trie, "'", Byte_ascii.Ltr_s); + } + public void Parse(byte[] src, int src_len, int bgn, int end) { + this.src = src; this.end = end; // this.bgn = bgn; + this.dirty = false; this.bgn__ws = bgn__dash = bgn__slash = -1; + this.src = case_mgr.Case_build_lower(src); src_len = this.src.length; + int pos = bgn; + while (true) { + boolean is_last = pos == end; + if (is_last) { // do split + Word__add(bgn__ws, end); + break; + } + byte b = src[pos]; + Object o = trie.Match_bgn_w_byte(b, src, pos, end); + if (o == null) { // unknown sequence; word-char + Char__add(b, pos); + ++pos; + } + else { + Xows_text_tkn parser = (Xows_text_tkn)o; + pos = parser.Parse(this, src, end, pos, trie.Match_pos()); + } + } + } + public int Bgn__ws() {return bgn__ws;} private int bgn__ws; + public int Bgn__dash() {return bgn__dash;} private int bgn__dash; + public int Bgn__slash() {return bgn__slash;} private int bgn__slash; + public void Bgn__ws_clear() {this.bgn__ws = -1;} + public void Bgn__dash_(int v) {this.bgn__dash = v;} + public void Bgn__slash_(int v) {this.bgn__slash= v;} + public void Word__add(int bgn__ws, int word_end) { + if (bgn__ws == word_end) return; // handle situations like "A!" where sym is at eos + if (bgn__ws == -1) return; // handle situations like "A... " where " " is different than "..." + byte[] word = dirty ? bfr.Xto_bry_and_clear() : Bry_.Mid(src, bgn__ws, word_end); + word_mgr.Add(word); + if (bgn__dash != -1) { + word_mgr.Add(Bry_.Mid(src, bgn__dash, word_end)); + bgn__dash = -1; + } + } + public void Char__add(byte b, int pos) { + if (dirty) + bfr.Add_byte(b); + else { + if (bgn__ws == -1) + bgn__ws = pos; + } + } + public boolean Ws__is_word_end(int pos) {return parser__ws.Is_word_end(src, end, pos);} +} +class Xob_word_mgr { + private final OrderedHash hash = OrderedHash_.new_bry_(); + public void Clear() {hash.Clear();} + public int Len() {return hash.Count();} + public Xob_word_itm Get_at(int i) {return (Xob_word_itm)hash.FetchAt(i);} + public void Add(byte[] word) { + Xob_word_itm itm = (Xob_word_itm)hash.Fetch(word); + if (itm == null) { + itm = new Xob_word_itm(word); + hash.Add(word, itm); + } + itm.Count_add_1_(); + } +} +class Xob_word_itm { + public Xob_word_itm(byte[] word) { + this.word = word; + this.count = 0; + } + public byte[] Word() {return word;} private final byte[] word; + public int Count() {return count;} private int count; public void Count_add_1_() {++count;} + @gplx.Internal protected Xob_word_itm Count_(int v) {this.count = v; return this;} +} diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_parser__v2_tst.java b/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_parser__v2_tst.java new file mode 100644 index 000000000..59cc7d551 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_parser__v2_tst.java @@ -0,0 +1,156 @@ +/* +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 . +*/ +package gplx.xowa.specials.search.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +import org.junit.*; import gplx.xowa.langs.cases.*; +public class Xows_text_parser__v2_tst { + private final Xows_text_parser__v2_fxt fxt = new Xows_text_parser__v2_fxt(); + @Before public void init() {fxt.Init();} + @Test public void Word__one() { + fxt.Clear().Test_split("abcd", "abcd"); + } + @Test public void Word__many() { + fxt.Clear().Test_split("abc d ef", "abc", "d", "ef"); + } + @Test public void Ws__many() { + fxt.Clear().Test_split("a b", "a", "b"); + } + @Test public void Ws__bgn() { + fxt.Clear().Test_split(" a", "a"); + } + @Test public void Ws__end() { + fxt.Clear().Test_split(" a", "a"); + } + @Test public void Under() { + fxt.Clear().Test_split("a_b", "a", "b"); + } + @Test public void Lowercase() { + fxt.Clear().Test_split("A B C", "a", "b", "c"); + } + @Test public void Dupe() { + fxt.Clear().Test_split("a a a", fxt.Make_word("a", 3)); + } + @Test public void Dupe__lowercase() { + fxt.Clear().Test_split("a A", fxt.Make_word("a", 2)); + } + @Test public void Dot__acronym() { // EX: "History of U.S.A. Science " + fxt.Clear().Test_split("abc D.E.F. ghi", "abc", "d.e.f.", "ghi"); + } + @Test public void Dot__initials() { // EX: "H. G. Wells" + fxt.Clear().Test_split("a. b. cde", "a.", "b.", "cde"); + } + @Test public void Dot__abrv() { // EX: "vs.", "no." + fxt.Clear().Test_split("a vs. b", "a", "vs.", "b"); + } + @Test public void Dot__internet() { // EX: "en.wikipedia.org" + fxt.Clear().Test_split("a.com", "a.com"); + } + @Test public void Ellipsis__basic() { // EX: "Nights into Dreams..." + fxt.Clear().Test_split("a... bc d", "a", "...", "bc", "d"); + } + @Test public void Ellipsis__bgn() { + fxt.Clear().Test_split("...a", "...", "a"); + } + @Test public void Ellipsis__end() { + fxt.Clear().Test_split("a...", "a", "..."); + } + @Test public void Ellipsis__no_ws() { + fxt.Clear().Test_split("a...b", "a", "...", "b"); + } + @Test public void Apos__contraction() { // EX: "I'm" + fxt.Clear().Test_split("i'm", "i'm"); + } + @Test public void Apos__multiple() { + fxt.Clear().Test_split("a''b", "a''b"); + } + @Test public void Apos__possessive_singular_eos() {// EX: "wiki's" + fxt.Clear().Test_split("a's", "a", "a's"); + } + @Test public void Apos__possessive_singular_word() { + fxt.Clear().Test_split("a's b", "a", "a's", "b"); + } + @Test public void Apos__possessive_plural_eos() {// EX: "wiki'" + fxt.Clear().Test_split("a'", "a", "a'"); + } + @Test public void Apos__possessive_plural_word() { + fxt.Clear().Test_split("a' b", "a", "a'", "b"); + } + @Test public void Bang__lone() { + fxt.Clear().Test_split("! a", "a"); + } + @Test public void Bang__word() { + fxt.Clear().Test_split("a!", "a"); + } + @Test public void Bang__sentence() {// EX: "A!" + fxt.Clear().Test_split("a b!", "a", "b"); + } + @Test public void Question__sentence() {// EX: "A?" + fxt.Clear().Test_split("a?", "a"); + } + @Test public void Parens_both() {// EX: "A (letter)" + fxt.Clear().Test_split("a (b)", "a", "b"); + } + @Test public void Slash__word() {// EX: "Good_cop/bad_cop" + fxt.Clear().Test_split("a/b", "a", "b"); + } + // apos: 'Some apostrophe sentence' ? +} +class Xows_text_parser__v2_fxt { + private final Xows_text_parser__v2 word_parser = new Xows_text_parser__v2(); + private final Xob_word_mgr word_mgr = new Xob_word_mgr(); + private final Bry_bfr tmp_bfr = Bry_bfr.new_(32); + private Xol_case_mgr case_mgr; + public void Init() { + case_mgr = Xol_case_mgr_.Ascii(); + word_parser.Init_for_ttl(word_mgr, case_mgr); + } + public Xows_text_parser__v2_fxt Clear() { + word_mgr.Clear(); + return this; + } + public Xob_word_itm Make_word(String raw, int count) {return new Xob_word_itm(Bry_.new_utf8_(raw)).Count_(count);} + public void Test_split(String src, String... expd_words) { + int len = expd_words.length; + Xob_word_itm[] ary = new Xob_word_itm[len]; + for (int i = 0; i < len; ++i) { + ary[i] = Make_word(expd_words[i], 1); + } + Test_split(src, ary); + } + public void Test_split(String src, Xob_word_itm... expd_words) { + byte[] src_bry = Bry_.new_utf8_(src); + word_parser.Parse(src_bry, src_bry.length, 0, src_bry.length); + Tfds.Eq_str_lines(To_str(expd_words), To_str(word_mgr)); + } + private String To_str(Xob_word_itm[] word_ary) { + int len = word_ary.length; + for (int i = 0; i < len; ++i) { + if (i != 0) tmp_bfr.Add_byte_nl(); + Xob_word_itm word = word_ary[i]; + tmp_bfr.Add(word.Word()).Add_byte_pipe(); + tmp_bfr.Add_int_variable(word.Count()); + } + return tmp_bfr.Xto_str_and_clear(); + } + private String To_str(Xob_word_mgr word_mgr) { + int len = word_mgr.Len(); + Xob_word_itm[] ary = new Xob_word_itm[len]; + for (int i = 0; i < len; ++i) + ary[i] = word_mgr.Get_at(i); + return To_str(ary); + } +} diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_tkn.java b/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_tkn.java new file mode 100644 index 000000000..b0e07fea1 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/parsers/Xows_text_tkn.java @@ -0,0 +1,146 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.specials.search.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +import gplx.core.btries.*; import gplx.core.primitives.*; +interface Xows_text_tkn { + int Parse(Xows_text_parser__v2 mgr, byte[] src, int src_end, int tkn_bgn, int tkn_end); +} +class Xows_text_tkn__split implements Xows_text_tkn { + private final boolean add_sym_as_word; + private final Btrie_slim_mgr trie = Btrie_slim_mgr.cs_(); + public Xows_text_tkn__split(boolean add_sym_as_word, byte[][] ary) { + this.add_sym_as_word = add_sym_as_word; + int len = ary.length; + for (int i = 0; i < len; ++i) { + byte[] itm = ary[i]; + trie.Add_obj(itm, Int_obj_val.new_(itm.length)); + } + } + public int Parse(Xows_text_parser__v2 mgr, byte[] src, int src_end, int tkn_bgn, int tkn_end) { + if (mgr.Bgn__ws() != -1) // pending word + mgr.Word__add(mgr.Bgn__ws(), tkn_bgn); // make word; EX: "B" in "A B C" + mgr.Bgn__ws_clear(); + if (add_sym_as_word) + mgr.Word__add(tkn_bgn, tkn_end); + int rv = tkn_end; + while (rv < src_end) { // skip ws; EX: "a b" + byte b = src[rv]; + Object o = trie.Match_bgn_w_byte(b, src, rv, src_end); + if (o == null) break; + Int_obj_val itm_len = (Int_obj_val)o; + rv += itm_len.Val(); + } + return rv; + } + public boolean Is_word_end(byte[] src, int end, int pos) { + if (pos >= end) return true; + byte b = src[pos]; + Object o = trie.Match_bgn_w_byte(b, src, pos, end); + return o != null; + } + public static Xows_text_tkn__split new_(Btrie_slim_mgr trie, boolean add_sym_as_word, String... str_ary) { + byte[][] bry_ary = Bry_.Ary(str_ary); + Xows_text_tkn__split rv = new Xows_text_tkn__split(add_sym_as_word, bry_ary); + int len = bry_ary.length; + for (int i = 0; i < len; ++i) + trie.Add_obj(bry_ary[i], rv); + return rv; + } +} +class Xows_text_tkn__ellipsis implements Xows_text_tkn { + private final byte ellipsis_byte; + public Xows_text_tkn__ellipsis(byte ellipsis_byte) { + this.ellipsis_byte = ellipsis_byte; + } + public int Parse(Xows_text_parser__v2 mgr, byte[] src, int src_end, int tkn_bgn, int tkn_end) { + int bgn__ws = mgr.Bgn__ws(); + if (bgn__ws != -1) { + mgr.Word__add(bgn__ws, tkn_bgn); // add word; EX: "Dreams" in "Dreams..." + mgr.Bgn__ws_clear(); // clear ws flag, else space will create word; EX: "A... B" + } + int rv = Bry_finder.Find_fwd_while(src, tkn_end, src_end, ellipsis_byte); + mgr.Word__add(tkn_bgn, rv); // add ellipssis + return rv; + } + public static Xows_text_tkn new_(Btrie_slim_mgr trie, String ellipsis) { + byte[] bry = Bry_.new_utf8_(ellipsis); + Xows_text_tkn rv = new Xows_text_tkn__ellipsis(Bry_.Get_at_end_or_fail(bry)); + trie.Add_obj(bry, rv); + return rv; + } +} +class Xows_text_tkn__apos implements Xows_text_tkn { + private final byte possessive_byte; + public Xows_text_tkn__apos(byte possessive_byte) {this.possessive_byte = possessive_byte;} + public int Parse(Xows_text_parser__v2 mgr, byte[] src, int src_end, int tkn_bgn, int tkn_end) { + int rv = tkn_end; + byte apos_mode = Apos_contraction; + if (tkn_end == src_end) { // EX: "A'" + apos_mode = Apos_possessive_plural; + rv = src_end; + } + else if (mgr.Ws__is_word_end(tkn_end)) { // EX: "A' " + apos_mode = Apos_possessive_plural; + rv = tkn_end; + } + else if ( src[tkn_end] == possessive_byte // EX: "A's " + && mgr.Ws__is_word_end(tkn_end + 1)) + { + apos_mode = Apos_possessive_singular; + rv = tkn_end + 1; + } + switch (apos_mode) { + case Apos_possessive_plural: + case Apos_possessive_singular: + int word_bgn = mgr.Bgn__ws(); + mgr.Word__add(word_bgn, tkn_bgn); // add noun; EX: "wiki"; + mgr.Word__add(word_bgn, rv); // add full; EX: "wiki's" + mgr.Bgn__ws_clear(); + return rv; + case Apos_contraction: + break; + } + return rv; + } + private static final byte Apos_contraction = 1, Apos_possessive_plural = 2, Apos_possessive_singular = 3; + public static Xows_text_tkn new_(Btrie_slim_mgr trie, String apos, byte possessive_byte) { + byte[] bry = Bry_.new_utf8_(apos); + Xows_text_tkn rv = new Xows_text_tkn__apos(possessive_byte); + trie.Add_obj(bry, rv); + return rv; + } +} +// class Xows_text_tkn__slash : Xows_text_tkn { +// public int Parse(Xows_text_parser__v2 mgr, byte[] src, int src_end, int tkn_bgn, int tkn_end) { +// int bgn__dash = mgr.Bgn__dash(); +// // add part; +// int part_bgn = mgr.Bgn__dash(); +// if (part_bgn == -1) // no dash +// part_bgn = mgr.Bgn__ws(); +// if (part_bgn != -1) +// mgr.Word__add(part_bgn, tkn_bgn); // add word; EX: "a" in "a-b" +// mgr.Bgn__dash_(tkn_end); +// return tkn_end; +// } +// public static Xows_text_tkn new_(Btrie_slim_mgr trie, String dash) { +// byte[] bry = Bry_.new_utf8_(dash); +// Xows_text_tkn rv = new Xows_text_tkn__slash(); +// trie.Add_obj(bry, rv); +// return rv; +// } +// } diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_parser.java b/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_parser.java similarity index 94% rename from 400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_parser.java rename to 400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_parser.java index 02b6c47db..232d972e8 100644 --- a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_parser.java +++ b/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_parser.java @@ -15,7 +15,7 @@ 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 . */ -package gplx.xowa.specials.search.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +package gplx.xowa.specials.search.parsers_old; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; public class Xow_search_parser { private Xow_search_parser_ctx parse_ctx = new Xow_search_parser_ctx(); private byte[] src; public Xows_db_matcher Parse(byte[] src) { diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_scanner.java b/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_scanner.java similarity index 96% rename from 400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_scanner.java rename to 400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_scanner.java index 36edc913d..da646867f 100644 --- a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_scanner.java +++ b/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_scanner.java @@ -15,7 +15,7 @@ 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 . */ -package gplx.xowa.specials.search.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +package gplx.xowa.specials.search.parsers_old; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; import gplx.core.primitives.*; import gplx.core.btries.*; class Xow_search_scanner { private final ListAdp tkns = ListAdp_.new_(); private byte[] src; private int src_len, pos, txt_bgn; diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_tkn.java b/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_tkn.java similarity index 90% rename from 400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_tkn.java rename to 400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_tkn.java index 25d06809f..7f78f56f8 100644 --- a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_tkn.java +++ b/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_tkn.java @@ -15,7 +15,7 @@ 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 . */ -package gplx.xowa.specials.search.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +package gplx.xowa.specials.search.parsers_old; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; class Xow_search_tkn { private final int val_bgn, val_end; private final byte[] val_bry; diff --git a/400_xowa/src/gplx/xowa/users/prefs/Prefs_converter.java b/400_xowa/src/gplx/xowa/users/prefs/Prefs_converter.java index 0f92858e4..fee0b9330 100644 --- a/400_xowa/src/gplx/xowa/users/prefs/Prefs_converter.java +++ b/400_xowa/src/gplx/xowa/users/prefs/Prefs_converter.java @@ -32,7 +32,7 @@ public class Prefs_converter { Io_mgr._.SaveFilStr(trg_fil, new_str); app.Cfg_mgr().Db_load_txt(); app.Cfg_mgr().Set_by_app("app.setup.dumps.wiki_storage_type", "sqlite"); - app.Log_wtr().Log_msg_to_session_fmt("converted options to v2"); + app.Log_wtr().Log_to_session_fmt("converted options to v2"); } } } diff --git a/400_xowa/src/gplx/xowa/wikis/data/Xow_page_fetcher.java b/400_xowa/src/gplx/xowa/wikis/data/Xow_page_fetcher.java new file mode 100644 index 000000000..d4a7966c7 --- /dev/null +++ b/400_xowa/src/gplx/xowa/wikis/data/Xow_page_fetcher.java @@ -0,0 +1,24 @@ +/* +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 . +*/ +package gplx.xowa.wikis.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; +import gplx.xowa.wikis.data.tbls.*; +public interface Xow_page_fetcher { + Xow_page_fetcher Wiki_(Xowe_wiki v); + byte[] Fetch(int ns_id, byte[] ttl); + void Clear(); +} diff --git a/400_xowa/src_240_install/gplx/xowa/Xow_page_fetcher.java b/400_xowa/src/gplx/xowa/wikis/data/Xow_page_fetcher_test.java similarity index 67% rename from 400_xowa/src_240_install/gplx/xowa/Xow_page_fetcher.java rename to 400_xowa/src/gplx/xowa/wikis/data/Xow_page_fetcher_test.java index d7324fe40..2af511b44 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xow_page_fetcher.java +++ b/400_xowa/src/gplx/xowa/wikis/data/Xow_page_fetcher_test.java @@ -15,21 +15,9 @@ 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 . */ -package gplx.xowa; import gplx.*; +package gplx.xowa.wikis.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.data.tbls.*; -public interface Xow_page_fetcher { - Xow_page_fetcher Wiki_(Xowe_wiki v); - byte[] Fetch(int ns_id, byte[] ttl); -} -class Xow_page_fetcher_wiki implements Xow_page_fetcher { - public Xow_page_fetcher Wiki_(Xowe_wiki v) {this.wiki = v; return this;} private Xowe_wiki wiki; - public byte[] Fetch(int ns_id, byte[] ttl_bry) { - Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ns_id, ttl_bry); - Xoae_page page = wiki.Data_mgr().Get_page(ttl, false); // go through data_mgr in case of redirects - return page.Missing() ? null : page.Data_raw(); - } -} -class Xow_page_fetcher_mok implements Xow_page_fetcher { +public class Xow_page_fetcher_test implements Xow_page_fetcher { public Xow_page_fetcher Wiki_(Xowe_wiki v) {return this;} public void Clear() {pages.Clear();} private HashAdp pages = HashAdp_.new_(); public void Add(int ns_id, byte[] ttl, byte[] text) { diff --git a/400_xowa/src/gplx/xowa/wikis/data/Xow_page_fetcher_wiki.java b/400_xowa/src/gplx/xowa/wikis/data/Xow_page_fetcher_wiki.java new file mode 100644 index 000000000..698a9510b --- /dev/null +++ b/400_xowa/src/gplx/xowa/wikis/data/Xow_page_fetcher_wiki.java @@ -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 . +*/ +package gplx.xowa.wikis.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; +public class Xow_page_fetcher_wiki implements Xow_page_fetcher { + public Xow_page_fetcher Wiki_(Xowe_wiki v) {this.wiki = v; return this;} private Xowe_wiki wiki; + public void Clear() {} + public byte[] Fetch(int ns_id, byte[] ttl_bry) { + Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ns_id, ttl_bry); + Xoae_page page = wiki.Data_mgr().Get_page(ttl, false); // go through data_mgr in case of redirects + return page.Missing() ? null : page.Data_raw(); + } +} diff --git a/400_xowa/src/gplx/xowa/wmfs/Xowmf_mgr.java b/400_xowa/src/gplx/xowa/wmfs/Xowmf_mgr.java index 24fb512e9..785b36faf 100644 --- a/400_xowa/src/gplx/xowa/wmfs/Xowmf_mgr.java +++ b/400_xowa/src/gplx/xowa/wmfs/Xowmf_mgr.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.wmfs; import gplx.*; import gplx.xowa.*; -import gplx.xowa.wmfs.apis.*; +import gplx.xowa.wmfs.apis.*; import gplx.xowa.files.downloads.*; public class Xowmf_mgr { public Xowmf_mgr() { Gfo_usr_dlg usr_dlg = Xoa_app_.Usr_dlg(); diff --git a/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_base.java b/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_base.java index 685004015..ccddba2ba 100644 --- a/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_base.java +++ b/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_base.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.wmfs.apis; import gplx.*; import gplx.xowa.*; import gplx.xowa.wmfs.*; -import gplx.ios.*; import gplx.xowa.files.repos.*; +import gplx.ios.*; import gplx.xowa.files.repos.*; import gplx.xowa.files.downloads.*; public abstract class Xoapi_orig_base { public boolean Api_query_size(Xoapi_orig_rslts rv, Xof_download_wkr download_wkr, Xow_repo_mgr repo_mgr, byte[] ttl, int width, int height) { if (!gplx.ios.IoEngine_system.Web_access_enabled) return false; // don't check api if download disabled else "download_failed" messages in log (particularly during pkg_make) DATE:2015-02-12 diff --git a/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_mok.java b/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_mok.java index 930b9b269..c6a542c5f 100644 --- a/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_mok.java +++ b/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_mok.java @@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.wmfs.apis; import gplx.*; import gplx.xowa.*; import gplx.xowa.wmfs.*; +import gplx.xowa.files.downloads.*; public class Xoapi_orig_mok extends Xoapi_orig_base { private String wiki_str = "", ttl_str = "", redirect_str = ""; private int orig_w, orig_h; private boolean fail = false; public Xoapi_orig_mok Ini(String wiki_str, String ttl_str, String redirect_str, int orig_w, int orig_h, boolean pass) { diff --git a/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_wmf.java b/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_wmf.java index b3e31ea99..ccc7803ee 100644 --- a/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_wmf.java +++ b/400_xowa/src/gplx/xowa/wmfs/apis/Xoapi_orig_wmf.java @@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.wmfs.apis; import gplx.*; import gplx.xowa.*; import gplx.xowa.wmfs.*; +import gplx.xowa.files.downloads.*; public class Xoapi_orig_wmf extends Xoapi_orig_base { @Override public boolean Api_query_size_exec(Xoapi_orig_rslts rv, Xof_download_wkr download_wkr, byte[] ttl, int width, int height, Gfo_usr_dlg usr_dlg, byte[] repo_wiki_key) { if (Env_.Mode_testing()) return false; // TEST: disable during tests else scrib_lib_title will try to call WMF API; DATE:2015-03-20 diff --git a/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_xnde_tst.java b/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_xnde_tst.java index a4d70441e..95e858f6b 100644 --- a/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_xnde_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_xnde_tst.java @@ -188,7 +188,7 @@ class Dpl_xnde_fxt { next_id = 100; fxt.Reset(); warns = String_.Ary_empty; - fxt.App().Usr_dlg().Ui_wkr().Clear(); + fxt.App().Usr_dlg().Gui_wkr().Clear(); fxt.Wiki().Hive_mgr().Clear(); fxt.Wiki().Db_mgr().Save_mgr().Clear(); // NOTE: must clear to reset next_id to 0; Ctg_create assumes clean slate from 0 fxt.Wiki().Xtn_mgr().Xtn_proofread().Enabled_y_(); diff --git a/400_xowa/src/gplx/xowa/xtns/imaps/Imap_parser_tst.java b/400_xowa/src/gplx/xowa/xtns/imaps/Imap_parser_tst.java index 53562b084..052ce5f25 100644 --- a/400_xowa/src/gplx/xowa/xtns/imaps/Imap_parser_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/imaps/Imap_parser_tst.java @@ -69,7 +69,7 @@ class Imap_parser_fxt extends Imap_fxt_base { Xoa_url url = Xoa_url.new_(wiki.Domain_bry(), Bry_.new_ascii_("Test_1")); Imap_xtn_mgr xtn_mgr = new Imap_xtn_mgr(); parser = new Imap_parser(xtn_mgr); - parser.Init(wiki, url, Gfo_usr_dlg_.Null); + parser.Init(wiki, url, Gfo_usr_dlg_.Noop); parser.Clear(); imap = new Imap_map(1); } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java index 8228c41d4..b498da602 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java @@ -176,7 +176,7 @@ given qry = "../C/./D" and src = "A/B" . iterate over every slash to create "segs_ary" A -> [A] add B -> [A, B] add -.. -> [A] pop +.. -> [A] pop C -> [A, C] add . -> [A, C] noop D -> [A, C, D] add diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs_tst.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs_tst.java index 2ce45cdfd..1639ef898 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs_tst.java @@ -22,19 +22,19 @@ public class Pfunc_rel2abs_tst { @Before public void init() {fxt.Reset();} @Test public void Slash_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d|a/b/c}}" , "{{test}}" , "a/b/c/d");} @Test public void Cur_lvl1() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:./d|a}}" , "{{test}}" , "a/d");} - @Test public void Cur_lvl2() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:./d|a/b}}" , "{{test}}" , "a/b/d");} + @Test public void Cur_lvl2() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:./d|a/b}}" , "{{test}}" , "a/b/d");} @Test public void Cur_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:./d|a/b/c}}" , "{{test}}" , "a/b/c/d");} @Test public void Owner_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:../d|a/b/c}}" , "{{test}}" , "a/b/d");} @Test public void Owner_cur_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:../.|a/b/c}}" , "{{test}}" , "a/b");} - @Test public void Text_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:d|a/b/c}}" , "{{test}}" , "d");} - @Test public void Slash_mult() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d//e|a/b/c}}" , "{{test}}" , "a/b/c/d/e");} + @Test public void Text_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:d|a/b/c}}" , "{{test}}" , "d");} + @Test public void Slash_mult() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d//e|a/b/c}}" , "{{test}}" , "a/b/c/d/e");} @Test public void Slash_cur_mult() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d/./e|a/b/c}}" , "{{test}}" , "a/b/c/d/e");} @Test public void Qry_ends_w_slash() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d/|a/b/c}}" , "{{test}}" , "a/b/c/d");} @Test public void Qry_is_empty() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:|a/b/c}}" , "{{test}}" , "a/b/c");} - @Test public void Qry_is_dot() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:.|a/b/c}}" , "{{test}}" , "a/b/c");} + @Test public void Qry_is_dot() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:.|a/b/c}}" , "{{test}}" , "a/b/c");} @Test public void DotDot_mult2() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/../..|a/b/c}}" , "{{test}}" , "a");} - @Test public void DotDot_mult3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/../../..|a/b/c}}" , "{{test}}" , "");} - @Test public void Src_is_empty() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d|}}" , "{{test}}" , "Test page/d");} + @Test public void DotDot_mult3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/../../..|a/b/c}}" , "{{test}}" , "");} + @Test public void Src_is_empty() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d|}}" , "{{test}}" , "Test page/d");} @Test public void Err_owner() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:..}}" , "{{test}}" , "");} // PURPOSE.fix: should not fail @Test public void Err_owner_2() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/../../b|a}}" , "{{test}}" , "");} // PURPOSE.fix: should not fail @Test public void Ns_should_be_included_for_cur_page() {// PURPOSE.fix: current title was not returning ns; EX: de.wikipedia.org/wiki/Hilfe:Vorlagenprogrammierung#Funktion_rel2abs diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/engines/process/Process_send_wtr_tst.java b/400_xowa/src/gplx/xowa/xtns/scribunto/engines/process/Process_send_wtr_tst.java index 35c2c61cd..6e303b9bc 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/engines/process/Process_send_wtr_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/engines/process/Process_send_wtr_tst.java @@ -32,7 +32,7 @@ public class Process_send_wtr_tst { class Scrib_lua_srl_fxt { public void Clear() { if (srl == null) { - usr_dlg = Gfo_usr_dlg_base.test_(); + usr_dlg = Gfo_usr_dlg_.Test(); srl = new Process_send_wtr(usr_dlg); } } Process_send_wtr srl; Gfo_usr_dlg usr_dlg; diff --git a/400_xowa/src/gplx/xowa2/apps/Xoav_app.java b/400_xowa/src/gplx/xowa2/apps/Xoav_app.java index 3e6f41251..daf6373c6 100644 --- a/400_xowa/src/gplx/xowa2/apps/Xoav_app.java +++ b/400_xowa/src/gplx/xowa2/apps/Xoav_app.java @@ -19,7 +19,7 @@ package gplx.xowa2.apps; import gplx.*; import gplx.xowa2.*; import gplx.dbs.*; import gplx.xowa.apps.fsys.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.langs.cases.*; import gplx.intl.*; import gplx.xowa.users.data.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa2.apps.urls.*; import gplx.xowa.files.caches.*; import gplx.xowa.files.imgs.*; -import gplx.xowa.html.wtrs.*; +import gplx.xowa.bldrs.css.*; import gplx.xowa.html.wtrs.*; import gplx.xowa.wmfs.*; import gplx.xowa.urls.encoders.*; public class Xoav_app implements Xoa_app { @@ -49,7 +49,7 @@ public class Xoav_app implements Xoa_app { public Xoav_wiki_mgr Wiki_mgr() {return wiki_mgr;} private final Xoav_wiki_mgr wiki_mgr; public Xoud_db_mgr User_data_mgr() {return user_data_mgr;} private Xoud_db_mgr user_data_mgr = new Xoud_db_mgr(); - public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} public void Usr_dlg_(Gfo_usr_dlg v) {usr_dlg = v;} private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Null; + public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} public void Usr_dlg_(Gfo_usr_dlg v) {usr_dlg = v;} private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Noop; public Xop_amp_mgr Utl_amp_mgr() {return utl_amp_mgr;} private Xop_amp_mgr utl_amp_mgr = new Xop_amp_mgr(); public Xol_case_mgr Utl_case_mgr() {return utl_case_mgr;} private Xol_case_mgr utl_case_mgr = Xol_case_mgr_.Utf8(); public Url_encoder Utl_encoder_fsys() {return utl_encoder_fsys;} private Url_encoder utl_encoder_fsys = Url_encoder.new_fsys_lnx_(); diff --git a/400_xowa/src/gplx/xowa2/files/Xofv_file_mgr_tst.java b/400_xowa/src/gplx/xowa2/files/Xofv_file_mgr_tst.java index 5503eeb1f..81bb2dfe1 100644 --- a/400_xowa/src/gplx/xowa2/files/Xofv_file_mgr_tst.java +++ b/400_xowa/src/gplx/xowa2/files/Xofv_file_mgr_tst.java @@ -21,7 +21,7 @@ import gplx.xowa.*; import gplx.xowa.files.*; import gplx.xowa.files.fsdb.*; imp import gplx.xowa2.apps.*; import gplx.xowa2.wikis.*; import gplx.xowa.files.origs.*; public class Xofv_file_mgr_tst { @Before public void init() {fxt.Clear();} private final Xofv_file_mgr_fxt fxt = new Xofv_file_mgr_fxt(); - @After public void term() {Gfo_usr_dlg_.I = Gfo_usr_dlg_.Null;} + @After public void term() {Gfo_usr_dlg_.I = Gfo_usr_dlg_.Noop;} @Test public void Stub() {} // @Test public void Thumb() { // fxt .Init_orig_add(fxt.Mkr_orig().Init_comm("A.png", 440, 400)) diff --git a/400_xowa/src/gplx/xowa2/gui/Xog_page.java b/400_xowa/src/gplx/xowa2/gui/Xog_page.java index aa5d13f05..d211a8ac2 100644 --- a/400_xowa/src/gplx/xowa2/gui/Xog_page.java +++ b/400_xowa/src/gplx/xowa2/gui/Xog_page.java @@ -35,7 +35,7 @@ public class Xog_page implements Xoa_page { public byte[] Display_ttl() {return display_ttl;} public void Display_ttl_(byte[] v) {this.display_ttl = v;} private byte[] display_ttl; public byte[] Content_sub() {return content_sub;} public void Content_sub_(byte[] v) {this.content_sub = v;} private byte[] content_sub; public byte[] Sidebar_div() {return sidebar_div;} public void Sidebar_div_(byte[] v) {this.sidebar_div = v;} private byte[] sidebar_div; - public int[] Redlink_uids() {return redlink_uids;} public void Redlink_uids_(int[] v) {redlink_uids = v;} private int[] redlink_uids; + public OrderedHash Redlink_uids() {return redlink_uids;} private final OrderedHash redlink_uids = OrderedHash_.new_(); public Xohd_data_itm__base[] Img_itms() {return img_itms;} public void Img_itms_(Xohd_data_itm__base[] v) {this.img_itms = v;} private Xohd_data_itm__base[] img_itms; public OrderedHash Gallery_itms() {return gallery_itms;} private OrderedHash gallery_itms = OrderedHash_.new_(); public Xog_page Init(Xow_wiki wiki, int page_id, Xoa_url page_url, Xoa_ttl page_ttl) { @@ -46,6 +46,7 @@ public class Xog_page implements Xoa_page { img_itms = Xohd_data_itm__base.Ary_empty; module_mgr.Clear(); gallery_itms.Clear(); + redlink_uids.Clear(); return this; } public void Ctor_from_page(Bry_bfr tmp_bfr, Xoae_page page) { diff --git a/400_xowa/src/gplx/xowa2/users/Xouv_cfg_keys.java b/400_xowa/src/gplx/xowa2/users/Xouv_cfg_keys.java new file mode 100644 index 000000000..57fb9c068 --- /dev/null +++ b/400_xowa/src/gplx/xowa2/users/Xouv_cfg_keys.java @@ -0,0 +1,23 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa2.users; import gplx.*; import gplx.xowa2.*; +public class Xouv_cfg_keys { + public static final String + Key_history_stack = "xowa.gui.history_stack" + ; +} diff --git a/400_xowa/src/gplx/xowa2/wikis/Xowv_wiki.java b/400_xowa/src/gplx/xowa2/wikis/Xowv_wiki.java index 8ca9ad34d..66810a229 100644 --- a/400_xowa/src/gplx/xowa2/wikis/Xowv_wiki.java +++ b/400_xowa/src/gplx/xowa2/wikis/Xowv_wiki.java @@ -36,8 +36,7 @@ public class Xowv_wiki implements Xow_wiki, Xow_ttl_parser { this.html__hdump_rdr = new Xohd_hdump_rdr(app, this); this.xwiki_mgr = new Xow_xwiki_mgr(); this.special_mgr = new Xosp_special_mgr(this); - Io_url wiki_file_dir = domain_tid == Xow_domain_.Tid_int_home ? wiki_root_dir : wiki_root_dir.OwnerDir().OwnerDir().GenSubDir_nest("file", domain_str); - this.fsys_mgr = new Xow_fsys_mgr(wiki_root_dir, wiki_file_dir); + this.fsys_mgr = new Xow_fsys_mgr(wiki_root_dir, wiki_root_dir); this.fsdb_mgr = new Xof_fsdb_mgr__sql(); } public Xoa_app App() {return app;} diff --git a/400_xowa/src_040_io/gplx/ios/BinaryHeap_Io_line_rdr_tst.java b/400_xowa/src_040_io/gplx/ios/BinaryHeap_Io_line_rdr_tst.java index 6cbc922ad..b42a7337a 100644 --- a/400_xowa/src_040_io/gplx/ios/BinaryHeap_Io_line_rdr_tst.java +++ b/400_xowa/src_040_io/gplx/ios/BinaryHeap_Io_line_rdr_tst.java @@ -32,7 +32,7 @@ class BinaryHeap_Io_line_rdr_fxt { for (int i = 0; i < file_total; i++) { Io_url url = Io_url_.mem_fil_("mem/fil_" + ary[i] + ".txt"); Io_mgr._.SaveFilStr(url, ary[i]); - Io_line_rdr stream = new Io_line_rdr(Gfo_usr_dlg_base.test_(), url); + Io_line_rdr stream = new Io_line_rdr(Gfo_usr_dlg_.Test(), url); stream.Read_next(); heap.Add(stream); } diff --git a/400_xowa/src_040_io/gplx/ios/Io_line_rdr_tst.java b/400_xowa/src_040_io/gplx/ios/Io_line_rdr_tst.java index 899d2f2cc..194200e25 100644 --- a/400_xowa/src_040_io/gplx/ios/Io_line_rdr_tst.java +++ b/400_xowa/src_040_io/gplx/ios/Io_line_rdr_tst.java @@ -49,7 +49,7 @@ public class Io_line_rdr_tst { class Io_line_rdr_fxt { Io_line_rdr rdr; ListAdp lines = ListAdp_.new_(); Bry_bfr tmp = Bry_bfr.new_(); - public Io_line_rdr_fxt(Io_url... urls) {rdr = new Io_line_rdr(Gfo_usr_dlg_base.test_(), urls);} + public Io_line_rdr_fxt(Io_url... urls) {rdr = new Io_line_rdr(Gfo_usr_dlg_.Test(), urls);} public Io_line_rdr_fxt Load_len_lines_(int v) {return Load_len_(v * 3);} // 3: 2=##, 1=\n public Io_line_rdr_fxt Load_len_(int v) {rdr.Load_len_(v); return this;} public Io_line_rdr_fxt File_lines_(int count) { diff --git a/400_xowa/src_040_io/gplx/ios/Io_sort_misc_tst.java b/400_xowa/src_040_io/gplx/ios/Io_sort_misc_tst.java index 97cea3957..8f9be34e1 100644 --- a/400_xowa/src_040_io/gplx/ios/Io_sort_misc_tst.java +++ b/400_xowa/src_040_io/gplx/ios/Io_sort_misc_tst.java @@ -48,7 +48,7 @@ public class Io_sort_misc_tst { Io_line_rdr new_Io_line_rdr(String url_str, String text) { Io_url url = Io_url_.mem_fil_(url_str); Io_mgr._.SaveFilStr(url, text); - Io_line_rdr rv = new Io_line_rdr(Gfo_usr_dlg_base.test_(), url); + Io_line_rdr rv = new Io_line_rdr(Gfo_usr_dlg_.Test(), url); rv.Read_next(); return rv; } diff --git a/400_xowa/src_040_io/gplx/ios/Io_sort_tst.java b/400_xowa/src_040_io/gplx/ios/Io_sort_tst.java index f0c163c0b..d1df1e40c 100644 --- a/400_xowa/src_040_io/gplx/ios/Io_sort_tst.java +++ b/400_xowa/src_040_io/gplx/ios/Io_sort_tst.java @@ -38,7 +38,7 @@ class Io_sort_fxt { Io_mgr._.SaveFilStr(src_url, src); - Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_base.test_(); + Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Test(); Io_url_gen src_fil_gen = Io_url_gen_.fil_(src_url); Io_url[] tmp_url_ary = externalSort.Split(usr_dlg, src_fil_gen, Io_url_gen_.dir_(src_url.OwnerDir()), Io_line_rdr_key_gen_.first_pipe); Io_sort_fil_basic cmd = new Io_sort_fil_basic(usr_dlg, Io_url_gen_.fil_(trg_url), Io_mgr.Len_kb); diff --git a/400_xowa/src_060_utl/gplx/App_cmd_mgr_tst.java b/400_xowa/src_060_utl/gplx/App_cmd_mgr_tst.java index f9f741699..b88880568 100644 --- a/400_xowa/src_060_utl/gplx/App_cmd_mgr_tst.java +++ b/400_xowa/src_060_utl/gplx/App_cmd_mgr_tst.java @@ -91,14 +91,14 @@ public class App_cmd_mgr_tst { } } class App_cmd_mgr_fxt { - public Gfo_usr_dlg Usr_dlg() {return dlg_mgr;} Gfo_usr_dlg dlg_mgr; + public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} Gfo_usr_dlg usr_dlg; public App_cmd_mgr Mgr() {return mgr;} App_cmd_mgr mgr = new App_cmd_mgr(); Tst_mgr tst_mgr = new Tst_mgr(); public App_cmd_mgr_fxt Clear() { - if (dlg_mgr == null) { - dlg_mgr = Gfo_usr_dlg_base.test_(); + if (usr_dlg == null) { + usr_dlg = Gfo_usr_dlg_.Test(); } mgr.Clear(); - dlg_mgr.Clear(); + usr_dlg.Gui_wkr().Clear(); return this; } public App_cmd_arg arg_(String key) {return arg_(key, false);} @@ -124,7 +124,7 @@ class App_cmd_mgr_fxt { return this; } public App_cmd_mgr_fxt tst_write(String... expd) { - String[] actl = ((Gfo_usr_dlg_ui_test)dlg_mgr.Ui_wkr()).Xto_str_ary(); + String[] actl = ((Gfo_usr_dlg__gui_test)usr_dlg.Gui_wkr()).Xto_str_ary(); Tfds.Eq_ary_str(expd, actl); return this; } diff --git a/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_ui_opt.java b/400_xowa/src_060_utl/gplx/Gfo_usr_dlg__gui__opt.java similarity index 94% rename from 400_xowa/src_060_utl/gplx/Gfo_usr_dlg_ui_opt.java rename to 400_xowa/src_060_utl/gplx/Gfo_usr_dlg__gui__opt.java index b583bfa0f..7db307f3a 100644 --- a/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_ui_opt.java +++ b/400_xowa/src_060_utl/gplx/Gfo_usr_dlg__gui__opt.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx; -public interface Gfo_usr_dlg_ui_opt { +public interface Gfo_usr_dlg__gui__opt { boolean Warn_enabled(); boolean Note_enabled(); } diff --git a/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_ui_swt.java b/400_xowa/src_060_utl/gplx/Gfo_usr_dlg__gui__swt.java similarity index 89% rename from 400_xowa/src_060_utl/gplx/Gfo_usr_dlg_ui_swt.java rename to 400_xowa/src_060_utl/gplx/Gfo_usr_dlg__gui__swt.java index 68db4f4ac..d34467ddf 100644 --- a/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_ui_swt.java +++ b/400_xowa/src_060_utl/gplx/Gfo_usr_dlg__gui__swt.java @@ -17,9 +17,9 @@ along with this program. If not, see . */ package gplx; import gplx.core.strings.*; import gplx.gfui.*; -public class Gfo_usr_dlg_ui_swt implements Gfo_usr_dlg_ui, GfoInvkAble { - private final GfuiInvkCmd cmd_sync; private final GfuiTextBox prog_box, info_box; private final Gfo_usr_dlg_ui_opt opt; - public Gfo_usr_dlg_ui_swt(Gfui_kit kit, GfuiTextBox prog_box, GfuiTextBox info_box, GfuiTextBox warn_box, Gfo_usr_dlg_ui_opt opt) { +public class Gfo_usr_dlg__gui__swt implements Gfo_usr_dlg__gui, GfoInvkAble { + private final GfuiInvkCmd cmd_sync; private final GfuiTextBox prog_box, info_box; private final Gfo_usr_dlg__gui__opt opt; + public Gfo_usr_dlg__gui__swt(Gfui_kit kit, GfuiTextBox prog_box, GfuiTextBox info_box, GfuiTextBox warn_box, Gfo_usr_dlg__gui__opt opt) { this.cmd_sync = kit.New_cmd_sync(this); // NOTE: cmd_sync needed else progress messages may be sent out of order this.prog_box = prog_box; this.info_box = info_box; this.opt = opt; diff --git a/400_xowa/src_120_wiki/gplx/xowa/Xowe_wiki.java b/400_xowa/src_120_wiki/gplx/xowa/Xowe_wiki.java index 34b002f85..3a4818b58 100644 --- a/400_xowa/src_120_wiki/gplx/xowa/Xowe_wiki.java +++ b/400_xowa/src_120_wiki/gplx/xowa/Xowe_wiki.java @@ -248,7 +248,7 @@ public class Xowe_wiki implements Xow_wiki, GfoInvkAble { File_repos_assert(app, this); xtn_mgr.Init_by_wiki(this); log_bfr.Add("wiki.init.end"); - app.Log_wtr().Log_msg_to_session_direct(log_bfr.Xto_str()); + app.Log_wtr().Log_to_session_direct(log_bfr.Xto_str()); init_in_process = false; } private void Html__hdump_enabled_(boolean v) { diff --git a/400_xowa/src_162_xfer/gplx/xowa/Xof_xfer_mgr.java b/400_xowa/src_162_xfer/gplx/xowa/Xof_xfer_mgr.java index 134cdc0cd..b94ab13d9 100644 --- a/400_xowa/src_162_xfer/gplx/xowa/Xof_xfer_mgr.java +++ b/400_xowa/src_162_xfer/gplx/xowa/Xof_xfer_mgr.java @@ -16,8 +16,9 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa; import gplx.*; -import gplx.core.primitives.*; import gplx.gfui.*; import gplx.xowa.files.*; import gplx.xowa.files.repos.*; -import gplx.xowa.wmfs.*; import gplx.xowa.wmfs.apis.*; import gplx.xowa.files.exts.*; +import gplx.core.primitives.*; import gplx.gfui.*; +import gplx.xowa.files.*; import gplx.xowa.files.repos.*; import gplx.xowa.files.exts.*; import gplx.xowa.files.downloads.*; +import gplx.xowa.wmfs.*; import gplx.xowa.wmfs.apis.*; public class Xof_xfer_mgr { public Xof_xfer_mgr(Xof_file_mgr file_mgr, Xowmf_mgr wmf_mgr) {this.file_mgr = file_mgr; this.wmf_mgr = wmf_mgr;} private final Xof_file_mgr file_mgr; private final Xowmf_mgr wmf_mgr; public Xof_xfer_rslt Rslt() {return rslt;} private Xof_xfer_rslt rslt = new Xof_xfer_rslt(); diff --git a/400_xowa/src_162_xfer/gplx/xowa/Xof_xfer_queue_html_fxt.java b/400_xowa/src_162_xfer/gplx/xowa/Xof_xfer_queue_html_fxt.java index e44765f48..1ee8eb29a 100644 --- a/400_xowa/src_162_xfer/gplx/xowa/Xof_xfer_queue_html_fxt.java +++ b/400_xowa/src_162_xfer/gplx/xowa/Xof_xfer_queue_html_fxt.java @@ -57,5 +57,5 @@ public class Xof_xfer_queue_html_fxt extends Xof_xfer_queue_base_fxt { if (this.Html_w() != -1) Tfds.Eq(this.Html_w(), xfer_itm.Html_w()); if (this.Html_h() != -1) Tfds.Eq(this.Html_h(), xfer_itm.Html_h()); queue.Clear(); - } private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Null; + } private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Noop; } diff --git a/400_xowa/src_200_bldr/gplx/xowa/Io_sort_cmd_img_tst.java b/400_xowa/src_200_bldr/gplx/xowa/Io_sort_cmd_img_tst.java index d4b957ff4..4465adf9a 100644 --- a/400_xowa/src_200_bldr/gplx/xowa/Io_sort_cmd_img_tst.java +++ b/400_xowa/src_200_bldr/gplx/xowa/Io_sort_cmd_img_tst.java @@ -34,7 +34,7 @@ public class Io_sort_cmd_img_tst { Io_url trg_fil = Io_url_.mem_fil_("mem/trg.csv"); Io_mgr._.SaveFilStr(src_fil, raw); Io_sort_cmd_img cmd = new Io_sort_cmd_img().Make_url_gen_(Io_url_gen_.fil_(trg_fil)); - Io_line_rdr rdr = new Io_line_rdr(Gfo_usr_dlg_base.test_(), src_fil).Key_gen_(new Io_line_rdr_key_gen_img()); + Io_line_rdr rdr = new Io_line_rdr(Gfo_usr_dlg_.Test(), src_fil).Key_gen_(new Io_line_rdr_key_gen_img()); cmd.Sort_bgn(); while (rdr.Read_next()) { cmd.Sort_do(rdr); diff --git a/400_xowa/src_200_bldr/gplx/xowa/Xob_xdat_file_wtr_tst.java b/400_xowa/src_200_bldr/gplx/xowa/Xob_xdat_file_wtr_tst.java index e24e4eb5d..23aec2e9e 100644 --- a/400_xowa/src_200_bldr/gplx/xowa/Xob_xdat_file_wtr_tst.java +++ b/400_xowa/src_200_bldr/gplx/xowa/Xob_xdat_file_wtr_tst.java @@ -47,7 +47,7 @@ public class Xob_xdat_file_wtr_tst { } private void tst_Flush(Xob_xdat_file_wtr wtr, String expd) { Io_url url = wtr.Fil_url(); - wtr.Flush(Gfo_usr_dlg_base.test_()); + wtr.Flush(Gfo_usr_dlg_.Test()); String actl = Io_mgr._.LoadFilStr(url); Tfds.Eq(expd, actl); } diff --git a/400_xowa/src_200_bldr/gplx/xowa/Xobd_rdr.java b/400_xowa/src_200_bldr/gplx/xowa/Xobd_rdr.java index 75919a2f5..f396b7270 100644 --- a/400_xowa/src_200_bldr/gplx/xowa/Xobd_rdr.java +++ b/400_xowa/src_200_bldr/gplx/xowa/Xobd_rdr.java @@ -57,14 +57,14 @@ public class Xobd_rdr implements Xob_cmd { long dividend = fil.Fil_pos(); if (dividend >= fil_len) dividend = fil_len - 1; // prevent % from going over 100 String msg = DecimalAdp_.CalcPctStr(dividend, fil_len, "00.00") + "|" + String_.new_utf8_(page.Ttl_full_db()) + "|" + Err_.Message_lang(e) + "|" + Xot_tmpl_wtr.Err_string; Xot_tmpl_wtr.Err_string = ""; - bldr.Usr_dlg().Log_wtr().Log_msg_to_session(msg); + bldr.Usr_dlg().Log_wkr().Log_to_session(msg); ConsoleAdp._.WriteLine(msg); } } } catch (Exception e) { String msg = Err_.Message_lang(e); - bldr.Usr_dlg().Log_wtr().Log_msg_to_session(msg); + bldr.Usr_dlg().Log_wkr().Log_to_session(msg); ConsoleAdp._.WriteLine(msg); throw Err_.err_(e, "error while reading dump"); } diff --git a/400_xowa/src_210_bldr_core/gplx/xowa/Sql_file_parser_tst.java b/400_xowa/src_210_bldr_core/gplx/xowa/Sql_file_parser_tst.java index fad66d542..3322aa9ca 100644 --- a/400_xowa/src_210_bldr_core/gplx/xowa/Sql_file_parser_tst.java +++ b/400_xowa/src_210_bldr_core/gplx/xowa/Sql_file_parser_tst.java @@ -67,7 +67,7 @@ class Sql_file_parser_fxt { Io_mgr._.SaveFilBry(src_fil, Bry_.new_utf8_(raw_str)); Io_url trg_fil = Io_url_.new_fil_("mem/test.csv"); parser.Src_fil_(src_fil).Trg_fil_gen_(Io_url_gen_.fil_(trg_fil)); - parser.Parse(Gfo_usr_dlg_base.test_()); + parser.Parse(Gfo_usr_dlg_.Test()); byte[] actl = Io_mgr._.LoadFilBry(trg_fil); Tfds.Eq(expd, String_.new_utf8_(actl)); } diff --git a/400_xowa/src_240_install/gplx/xowa/Xoi_cmd_wiki_tst.java b/400_xowa/src_240_install/gplx/xowa/Xoi_cmd_wiki_tst.java index bd9f5af18..6299bb440 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xoi_cmd_wiki_tst.java +++ b/400_xowa/src_240_install/gplx/xowa/Xoi_cmd_wiki_tst.java @@ -19,7 +19,7 @@ package gplx.xowa; import gplx.*; import org.junit.*; import gplx.brys.*; import gplx.core.threads.*; import gplx.xowa.wikis.*; import gplx.xowa.setup.maints.*; import gplx.xowa.xtns.wdatas.imports.*; public class Xoi_cmd_wiki_tst { - @Test public void Run() { // MAIN + @Test public void Run() { // MAINT // Bld_import_list(Xow_wmf_api_mgr.Wikis); // Bld_cfg_files(Xow_wmf_api_mgr.Wikis); // NOTE: remember to carry over the wikisource / page / index commands from the existing xowa_build_cfg.gfs; also, only run the xowa_build_cfg.gfs once; DATE:2013-10-15; last run: DATE:2014-09-09 } diff --git a/400_xowa/src_240_install/gplx/xowa/Xoi_css_offline_mgr.java b/400_xowa/src_240_install/gplx/xowa/Xoi_css_offline_mgr.java deleted file mode 100644 index b7ab93c79..000000000 --- a/400_xowa/src_240_install/gplx/xowa/Xoi_css_offline_mgr.java +++ /dev/null @@ -1,242 +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 . -*/ -package gplx.xowa; import gplx.*; -import gplx.core.primitives.*; import gplx.core.btries.*; -class Xoi_css_offline_itm { - public Xoi_css_offline_itm(byte[] http_url) {this.http_url = http_url;} - public byte[] Http_url() {return http_url;} private byte[] http_url; - public byte[] File_url() {return file_url;} public void File_url_(byte[] v) {file_url = v;} private byte[] file_url; -} -class Xoi_css_url_info { -// private Gfo_usr_dlg usr_dlg; - public int Bgn_pos() {return bgn_pos;} public void Bgn_pos_(int v) {bgn_pos = v;} private int bgn_pos; - public int End_pos() {return end_pos;} public void End_pos_(int v) {end_pos = v;} private int end_pos; - public boolean Found() {return found;} public void Found_(boolean v) {found = v;} private boolean found; - public void Init(Gfo_usr_dlg usr_dlg) { -// this.usr_dlg = usr_dlg; - } - public void Clear() { - bgn_pos = end_pos = -1; - found = false; - } - public void Quote_data(byte end_byte, boolean quoted) { - } - public Xoi_css_url_info Rslt_fail(int end_pos, String fmt, Object... args) { - this.end_pos = end_pos; -// if (bgn_pos == src_len) {usr_dlg.Warn_many("", "", "eos after 'url(': bgn=~{bgn}", tkn_bgn); return Bry_finder.Not_found;} - return this; - } - public Xoi_css_url_info Rslt_pass(int end_pos) { - this.end_pos = end_pos; - return this; - } - public Xoi_css_url_info Rslt_pass(int end_pos, byte[] url_clean) { - this.end_pos = end_pos; - return this; - } -} -class Xoi_css_offline_mgr { - private Bry_bfr bfr; - private byte[] src; - private int src_len, pos; - private OrderedHash download_queue; - private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Null; - public void Offline(Bry_bfr bfr, OrderedHash download_queue, Object download_wkr, byte[] src) { - this.bfr = bfr; - this.download_queue = download_queue; - this.src = src; this.src_len = src.length; - this.pos = 0; - while (true) { - boolean last = pos == src_len; - byte b = last ? Byte_ascii.NewLine : src[pos]; - Object o = tkns_trie.Match_bgn_w_byte(b, src, pos, src_len); - if (o == null) { - bfr.Add_byte(b); - ++pos; - } - else { - byte tkn_tid = ((Byte_obj_val)o).Val(); - int match_pos = tkns_trie.Match_pos(); - int nxt_pos = -1; - switch (tkn_tid) { - case Tkn_url: nxt_pos = Process_url(pos, match_pos); break; - case Tkn_import: nxt_pos = Process_import(pos, match_pos); break; - } - pos = nxt_pos; - } - } - - } - // "//id.wikibooks.org/w/index.php?title=MediaWiki:Common.css&oldid=43393&action=raw&ctype=text/css"; - private int Process_import(int tkn_bgn, int tkn_end) { // @import - // get url - // if null, add to bfr and exit; - // else download, and recursively call self -// int bgn_pos = Bry_finder.Find_fwd(src, end_byte, bgn_pos, src_len); -// int end_pos = Bry_finder.Find_fwd(src, end_byte, bgn_pos, src_len); - return -1; - } - private int Process_url(int tkn_bgn, int tkn_end) { // " url" - int bgn_pos = Bry_finder.Find_fwd_while_ws(src, tkn_end, src_len); // skip any ws after " url(" - if (bgn_pos == src_len) {usr_dlg.Warn_many("", "", "eos after 'url(': bgn=~{bgn}", tkn_bgn); return Bry_finder.Not_found;} - byte end_byte = src[bgn_pos]; boolean quoted = true; - switch (end_byte) { - case Byte_ascii.Quote: case Byte_ascii.Apos: // quoted; increment position - ++bgn_pos; - break; - default: // not quoted; end byte is ")" - end_byte = Byte_ascii.Paren_end; - quoted = false; - break; - } - int end_pos = Bry_finder.Find_fwd(src, end_byte, bgn_pos, src_len); - if (end_pos == Bry_.NotFound) { // unclosed "url("; exit since nothing else will be found - usr_dlg.Warn_many("", "", "could not end_byte for 'url(': bgn='~{0}' end='~{1}'", bgn_pos, String_.new_utf8_len_safe_(src, tkn_bgn, tkn_bgn + 25)); - bfr.Add_mid(src, tkn_bgn, src_len); - return Bry_finder.Not_found; - } - if (end_pos - bgn_pos == 0) { // empty; "url()"; ignore - usr_dlg.Warn_many("", "", "'url(' is empty: bgn='~{0}' end='~{1}'", tkn_bgn, String_.new_utf8_len_safe_(src, tkn_bgn, tkn_bgn + 25)); - return end_pos; - } - byte[] url_raw = Bry_.Mid(src, bgn_pos, end_pos); int url_raw_len = url_raw.length; - if (Bry_.HasAtBgn(url_raw, Bry_data_image, 0, url_raw_len)) { // base64 - ++end_pos; // include end_byte; - bfr.Add_mid(src, tkn_bgn, end_pos); // nothing to download; just add entire String - return end_pos; - } - byte[] url_cleaned = Clean_url(url_raw, url_raw_len); - if (url_cleaned == null) { // could not clean url - usr_dlg.Warn_many("", "", "could not extract valid url: bgn='~{0}' end='~{1}'", tkn_bgn, String_.new_utf8_(url_raw)); - bfr.Add_mid(src, tkn_bgn, bgn_pos); - return bgn_pos; - } - Xoi_css_offline_itm url_itm = (Xoi_css_offline_itm)download_queue.Fetch(url_cleaned); - if (url_itm == null) { // only add unique items for download; - url_itm = new Xoi_css_offline_itm(url_cleaned); - download_queue.Add(url_cleaned, url_itm); - } - byte[] file_url = Replace_invalid_chars(Bry_.Copy(url_cleaned)); // NOTE: must call ByteAry.Copy else url_cleaned will change *inside* bry - url_itm.File_url_(file_url); - bfr.Add_mid(src, tkn_bgn, tkn_end); - if (!quoted) bfr.Add_byte(Byte_ascii.Quote); - bfr.Add(file_url); - if (!quoted) bfr.Add_byte(Byte_ascii.Quote); - return end_pos; - } - public static Xoi_css_url_info Process_url(byte[] src, int src_len, int tkn_bgn, int tkn_end, Xoi_css_url_info inf) { // " url" - inf.Clear(); - int bgn_pos = Bry_finder.Find_fwd_while_ws(src, tkn_end, src_len); // skip any ws after " url(" - if (bgn_pos == src_len) return inf.Rslt_fail(src_len, "eos after 'url(': bgn=~{bgn}"); - byte end_byte = src[bgn_pos]; boolean quoted = true; - switch (end_byte) { - case Byte_ascii.Quote: case Byte_ascii.Apos: // quoted; increment position - ++bgn_pos; - break; - default: // not quoted; end byte is ")" - end_byte = Byte_ascii.Paren_end; - quoted = false; - break; - } - inf.Quote_data(end_byte, quoted); - int end_pos = Bry_finder.Find_fwd(src, end_byte, bgn_pos, src_len); - if (end_pos == Bry_.NotFound) { // unclosed "url("; exit since nothing else will be found - return inf.Rslt_fail(src_len, "could not end_byte for 'url(': bgn='~{0}' end='~{1}'"); - } - if (end_pos - bgn_pos == 0) { // empty; "url()"; ignore - return inf.Rslt_fail(end_pos + 1, "'url(' is empty: bgn='~{0}' end='~{1}'"); - } - byte[] url_raw = Bry_.Mid(src, bgn_pos, end_pos); int url_raw_len = url_raw.length; - if (Bry_.HasAtBgn(url_raw, Bry_data_image, 0, url_raw_len)) { // base64 - return inf.Rslt_pass(end_pos + 1); // nothing to download; just add entire String - } - byte[] url_cleaned = Clean_url(url_raw, url_raw_len); - if (url_cleaned == null) // could not clean url - return inf.Rslt_fail(bgn_pos, "could not extract valid url: bgn='~{0}' end='~{1}'"); - return inf.Rslt_pass(end_pos, url_cleaned); -// Xoi_css_offline_itm url_itm = (Xoi_css_offline_itm)download_queue.Fetch(url_cleaned); -// if (url_itm == null) { // only add unique items for download; -// url_itm = new Xoi_css_offline_itm(url_cleaned); -// download_queue.Add(url_cleaned, url_itm); -// } -// byte[] file_url = Replace_invalid_chars(Bry_.Copy(url_cleaned)); // NOTE: must call ByteAry.Copy else url_cleaned will change *inside* bry -// url_itm.File_url_(file_url); -// bfr.Add_mid(src, tkn_bgn, tkn_end); -// if (!quoted) bfr.Add_byte(Byte_ascii.Quote); -// bfr.Add(file_url); -// if (!quoted) bfr.Add_byte(Byte_ascii.Quote); -// return inf; - } - public static byte[] Clean_url(byte[] raw, int len) { // return "site/img.png" if "//site/img.png" or "http://site/img.png", "img.png?key=val" - int bgn = 0; - if (Bry_.HasAtBgn(raw, Bry_fwd_slashes , 0, len)) bgn = Bry_fwd_slashes.length; // skip if starts with "//" - else if (Bry_.HasAtBgn(raw, Bry_http , 0, len)) bgn = Bry_http.length; // skip if starts with "http://" - else if (Bry_.HasAtBgn(raw, Bry_https , 0, len)) bgn = Bry_https.length; // skip if starts with "https://" - int slash_pos = Bry_finder.Find_fwd(raw, Byte_ascii.Slash, bgn, len); // find 1st slash - if ( slash_pos == Bry_finder.Not_found // no slashes; must have at least 1 slash to have 2 segments; EX: site.org/img.png - || slash_pos == len - 1 // first slash is last char; EX: "site.org/" - ) - return null; // invalid - int end = len; - int question_pos = Bry_finder.Find_bwd(raw, Byte_ascii.Question); - if (question_pos != Bry_finder.Not_found) // url has query String; EX:site.org/img.png?key=val - end = question_pos; // remove query String - return Bry_.Mid(raw, bgn, end); - } - public static byte[] Replace_invalid_chars(byte[] src) { - int len = src.length; - for (int i = 0; i < len; i++) { // convert invalid wnt chars to underscores - byte b = src[i]; - switch (b) { - //case Byte_ascii.Slash: - case Byte_ascii.Backslash: case Byte_ascii.Colon: case Byte_ascii.Asterisk: case Byte_ascii.Question: - case Byte_ascii.Quote: case Byte_ascii.Lt: case Byte_ascii.Gt: case Byte_ascii.Pipe: - src[i] = Byte_ascii.Underline; - break; - } - } - return src; - } - - public static final byte[] Tkn_url_bry = Bry_.new_ascii_(" url("); - private static final byte Tkn_import = 1, Tkn_url = 2; - private static final Btrie_slim_mgr tkns_trie = Btrie_slim_mgr.ci_ascii_() - .Add_str_byte("@import" , Tkn_import) - .Add_bry_bval(Tkn_url_bry , Tkn_url) - ; - private static final byte[] - Bry_data_image = Bry_.new_ascii_("data:image/") - , Bry_http = Bry_.new_ascii_("http://") - , Bry_https = Bry_.new_ascii_("https://") - , Bry_fwd_slashes = Bry_.new_ascii_("//") -// , Bry_http_protocol = Bry_.new_ascii_("http"), Bry_url = Bry_.new_ascii_("url("), Bry_import = Bry_.new_ascii_("@import ") - ; - public static final byte[] - Bry_comment_bgn = Bry_.new_ascii_("/*XOWA:") - , Bry_comment_end = Bry_.new_ascii_("*/") - ; -// private static final int Bry_url_len = Bry_url.length, Bry_import_len = Bry_import.length; -} -// class Io_download_itm { -// public byte[] Src_url() {return src_url;} public void Src_url_(byte[] v) {src_url = v;} private byte[] src_url; -// public Io_url Trg_url() {return trg_url;} public void Trg_url_(Io_url v) {trg_url = v;} private Io_url trg_url;] -// public String Download_err() {return download_err;} public void Download_err_(String v) {download_err = v;} private String download_err; -// } -// interface Io_download_mgr { -// void Download(Io_download_itm itm); -// } diff --git a/400_xowa/src_240_install/gplx/xowa/Xoi_css_offline_mgr_tst.java b/400_xowa/src_240_install/gplx/xowa/Xoi_css_offline_mgr_tst.java deleted file mode 100644 index b4fb7e83f..000000000 --- a/400_xowa/src_240_install/gplx/xowa/Xoi_css_offline_mgr_tst.java +++ /dev/null @@ -1,52 +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 . -*/ -package gplx.xowa; import gplx.*; -import org.junit.*; -public class Xoi_css_offline_mgr_tst { - @Before public void init() {fxt.Clear();} private Xoi_css_offline_mgr_fxt fxt = new Xoi_css_offline_mgr_fxt(); - @Test public void Basic() { -// fxt.Test_extract_url_warn("url(" , "end of stream"); -// fxt.Test_extract_url_warn("url(abc" , "end not found"); -// fxt.Test_extract_url_warn("url()" , "url is empty"); - fxt.Test_extract_url_pass("url('a/b')" , "url is empty"); - } -} -class Xoi_css_offline_mgr_fxt { - private Xoi_css_url_info info = new Xoi_css_url_info(); - private Gfo_usr_dlg usr_dlg = null; -// private Xoi_css_offline_mgr mgr; - public void Clear() { - info.Init(usr_dlg); -// mgr = new Xoi_css_offline_mgr(); - } - public void Test_extract_url_warn(String raw, String err) { - } - public void Test_extract_url_pass(String src_str, String expd) { - byte[] src = Bry_.new_utf8_(src_str); - Test_extract_url(src); -// String actl = String_.new_ascii_(src, info.Bgn_pos(), info.End_pos()); -// Tfds.Eq(expd, actl); - } - private void Test_extract_url(byte[] src) { - int src_len = src.length; - info.Clear(); - int tkn_bgn = Bry_finder.Find_fwd(src, Xoi_css_offline_mgr.Tkn_url_bry, 0, src_len); - int tkn_end = tkn_bgn + Xoi_css_offline_mgr.Tkn_url_bry.length; - Xoi_css_offline_mgr.Process_url(src, src_len, tkn_bgn, tkn_end, info); - } -} diff --git a/400_xowa/src_400_parser/gplx/xowa/Xop_fxt.java b/400_xowa/src_400_parser/gplx/xowa/Xop_fxt.java index 1ce196c62..6909f87a6 100644 --- a/400_xowa/src_400_parser/gplx/xowa/Xop_fxt.java +++ b/400_xowa/src_400_parser/gplx/xowa/Xop_fxt.java @@ -327,7 +327,7 @@ public class Xop_fxt { } public void tst_Warn(String... expd) { Gfo_usr_dlg usr_dlg = app.Usr_dlg(); - Gfo_usr_dlg_ui_test ui_wkr = (Gfo_usr_dlg_ui_test)usr_dlg.Ui_wkr(); + Gfo_usr_dlg__gui_test ui_wkr = (Gfo_usr_dlg__gui_test)usr_dlg.Gui_wkr(); String[] actl = ui_wkr.Warns().XtoStrAry(); Tfds.Eq_ary_str(expd, actl); } diff --git a/400_xowa/src_490_xnde/gplx/xowa/Xop_xatr_hash.java b/400_xowa/src_490_xnde/gplx/xowa/Xop_xatr_hash.java new file mode 100644 index 000000000..fde5980dd --- /dev/null +++ b/400_xowa/src_490_xnde/gplx/xowa/Xop_xatr_hash.java @@ -0,0 +1,47 @@ +/* +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 . +*/ +package gplx.xowa; import gplx.*; +public class Xop_xatr_hash { + private final OrderedHash hash = OrderedHash_.new_bry_(); + private final byte[] src; + Xop_xatr_hash(byte[] src) {this.src = src;} + public int Len() {return hash.Count();} + public Xop_xatr_itm Get_at(int idx) { + return (Xop_xatr_itm)hash.FetchAt(idx); + } + public Xop_xatr_itm Get_by(String key) { + return (Xop_xatr_itm)hash.Fetch(Bry_.new_utf8_(key)); + } + public byte[] Get_as_bry_or(String key, byte[] or) { + Xop_xatr_itm itm = Get_by(key); + return itm == null ? or : itm.Val_as_bry(src); + } + public boolean Match(String key, String val) { + Xop_xatr_itm itm = Get_by(key); if (itm == null) return false; + return String_.Eq(itm.Val_as_str(src), val); + } + private void Add(Xop_xatr_itm itm) { + hash.AddReplace(itm.Key_bry(), itm); + } + public static Xop_xatr_hash new_ary(byte[] src, Xop_xatr_itm[] ary) { + Xop_xatr_hash rv = new Xop_xatr_hash(src); + for (Xop_xatr_itm itm : ary) + rv.Add(itm); + return rv; + } +} diff --git a/400_xowa/src_490_xnde/gplx/xowa/Xop_xatr_parser.java b/400_xowa/src_490_xnde/gplx/xowa/Xop_xatr_parser.java index 126c70f6d..e6f13a2c0 100644 --- a/400_xowa/src_490_xnde/gplx/xowa/Xop_xatr_parser.java +++ b/400_xowa/src_490_xnde/gplx/xowa/Xop_xatr_parser.java @@ -18,14 +18,15 @@ along with this program. If not, see . package gplx.xowa; import gplx.*; import gplx.core.primitives.*; public class Xop_xatr_parser { // REF.MW:Sanitizer.php|decodeTagAttributes;MW_ATTRIBS_REGEX - private ListAdp xatrs = ListAdp_.new_(); + private final ListAdp xatrs = ListAdp_.new_(); private static final byte Mode_atr_bgn = 1, Mode_invalid = 2, Mode_key = 3, Mode_eq = 4, Mode_val_bgn = 5, Mode_val_quote = 6, Mode_val_raw = 7; private byte mode = Mode_atr_bgn; private int atr_bgn = -1, key_bgn = -1, key_end = -1, eq_pos = -1, val_bgn = -1, val_end = -1; boolean valid = true; private byte quote_byte = Byte_ascii.Nil; - private Hash_adp_bry repeated_atrs_hash = Hash_adp_bry.ci_ascii_(); // ASCII:xnde_atrs - private Bry_bfr key_bfr = Bry_bfr.new_(), val_bfr = Bry_bfr.new_(); boolean key_bfr_on = false, val_bfr_on = false, ws_is_before_val = false; - public Bry_obj_ref Bry_obj() {return bry_ref;} private Bry_obj_ref bry_ref = Bry_obj_ref.null_(); + private final Hash_adp_bry repeated_atrs_hash = Hash_adp_bry.ci_ascii_(); // ASCII:xnde_atrs + private final Bry_bfr key_bfr = Bry_bfr.new_(), val_bfr = Bry_bfr.new_(); + private boolean key_bfr_on = false, val_bfr_on = false, ws_is_before_val = false; + public Bry_obj_ref Bry_obj() {return bry_ref;} private final Bry_obj_ref bry_ref = Bry_obj_ref.null_(); public int Xnde_find_gt_find(byte[] src, int pos, int end) { bry_ref.Val_(null); byte b = src[pos]; diff --git a/400_xowa/src_500_tmpl/gplx/xowa/Xop_brack_bgn_lxr.java b/400_xowa/src_500_tmpl/gplx/xowa/Xop_brack_bgn_lxr.java new file mode 100644 index 000000000..e341ab397 --- /dev/null +++ b/400_xowa/src_500_tmpl/gplx/xowa/Xop_brack_bgn_lxr.java @@ -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 . +*/ +package gplx.xowa; import gplx.*; +import gplx.core.btries.*; +public class Xop_brack_bgn_lxr implements Xop_lxr { + public byte Lxr_tid() {return Xop_lxr_.Tid_brack_bgn;} + public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_bgn, this);} + public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {} + public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) { + Xop_tkn_itm tkn = tkn_mkr.Brack_bgn(bgn_pos, cur_pos); + ctx.Subs_add_and_stack(root, tkn); + return cur_pos; + } + public static final Xop_brack_bgn_lxr _ = new Xop_brack_bgn_lxr(); Xop_brack_bgn_lxr() {} +} diff --git a/400_xowa/src_500_tmpl/gplx/xowa/Xop_brack_end_lxr.java b/400_xowa/src_500_tmpl/gplx/xowa/Xop_brack_end_lxr.java new file mode 100644 index 000000000..32924569e --- /dev/null +++ b/400_xowa/src_500_tmpl/gplx/xowa/Xop_brack_end_lxr.java @@ -0,0 +1,33 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa; import gplx.*; +import gplx.core.btries.*; +public class Xop_brack_end_lxr implements Xop_lxr { + public byte Lxr_tid() {return Xop_lxr_.Tid_brack_end;} + public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_end, this);} + public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {} + public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) { + int acs_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_brack_bgn); + if (acs_pos != -1 && ctx.Cur_tkn_tid() != Xop_tkn_itm_.Tid_tmpl_curly_bgn) // NOTE: do not pop tkn if inside tmpl; EX: [[a|{{#switch:{{{1}}}|b=c]]|d=e]]|f]]}} + ctx.Stack_pop_til(root, src, acs_pos, true, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_tmpl_curly_bgn); + Xop_tkn_itm tkn = tkn_mkr.Brack_end(bgn_pos, cur_pos); + ctx.Subs_add(root, tkn); + return cur_pos; + } + public static final Xop_brack_end_lxr _ = new Xop_brack_end_lxr(); Xop_brack_end_lxr() {} +} diff --git a/400_xowa/src_500_tmpl/gplx/xowa/Xop_curly_bgn_tkn.java b/400_xowa/src_500_tmpl/gplx/xowa/Xop_curly_bgn_tkn.java index 8e9349f36..3f09d8f03 100644 --- a/400_xowa/src_500_tmpl/gplx/xowa/Xop_curly_bgn_tkn.java +++ b/400_xowa/src_500_tmpl/gplx/xowa/Xop_curly_bgn_tkn.java @@ -21,35 +21,3 @@ public class Xop_curly_bgn_tkn extends Xop_tkn_itm_base { @Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tmpl_curly_bgn;} public Xop_curly_bgn_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);} } -class Xop_curly_end_lxr implements Xop_lxr { - public byte Lxr_tid() {return Xop_lxr_.Tid_curly_end;} - public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Hook, this);} public static final byte[] Hook = new byte[] {Byte_ascii.Curly_end, Byte_ascii.Curly_end}; - public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {} - public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {return ctx.Curly().MakeTkn_end(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos);} - public static final Xop_curly_end_lxr _ = new Xop_curly_end_lxr(); Xop_curly_end_lxr() {} -} -class Xop_brack_bgn_lxr implements Xop_lxr { - public byte Lxr_tid() {return Xop_lxr_.Tid_brack_bgn;} - public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_bgn, this);} - public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {} - public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) { - Xop_tkn_itm tkn = tkn_mkr.Brack_bgn(bgn_pos, cur_pos); - ctx.Subs_add_and_stack(root, tkn); - return cur_pos; - } - public static final Xop_brack_bgn_lxr _ = new Xop_brack_bgn_lxr(); Xop_brack_bgn_lxr() {} -} -class Xop_brack_end_lxr implements Xop_lxr { - public byte Lxr_tid() {return Xop_lxr_.Tid_brack_end;} - public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_end, this);} - public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {} - public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) { - int acs_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_brack_bgn); - if (acs_pos != -1 && ctx.Cur_tkn_tid() != Xop_tkn_itm_.Tid_tmpl_curly_bgn) // NOTE: do not pop tkn if inside tmpl; EX: [[a|{{#switch:{{{1}}}|b=c]]|d=e]]|f]]}} - ctx.Stack_pop_til(root, src, acs_pos, true, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_tmpl_curly_bgn); - Xop_tkn_itm tkn = tkn_mkr.Brack_end(bgn_pos, cur_pos); - ctx.Subs_add(root, tkn); - return cur_pos; - } - public static final Xop_brack_end_lxr _ = new Xop_brack_end_lxr(); Xop_brack_end_lxr() {} -} diff --git a/400_xowa/src_500_tmpl/gplx/xowa/Xop_curly_end_lxr.java b/400_xowa/src_500_tmpl/gplx/xowa/Xop_curly_end_lxr.java new file mode 100644 index 000000000..6c14fd987 --- /dev/null +++ b/400_xowa/src_500_tmpl/gplx/xowa/Xop_curly_end_lxr.java @@ -0,0 +1,26 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa; import gplx.*; +import gplx.core.btries.*; +public class Xop_curly_end_lxr implements Xop_lxr { + public byte Lxr_tid() {return Xop_lxr_.Tid_curly_end;} + public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Hook, this);} public static final byte[] Hook = new byte[] {Byte_ascii.Curly_end, Byte_ascii.Curly_end}; + public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {} + public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {return ctx.Curly().MakeTkn_end(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos);} + public static final Xop_curly_end_lxr _ = new Xop_curly_end_lxr(); Xop_curly_end_lxr() {} +} diff --git a/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-text.xowa b/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-text.xowa index 7f444eeca..fff1fbf5d 100644 Binary files a/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-text.xowa and b/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-text.xowa differ