1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2024-10-27 20:34:16 +00:00
This commit is contained in:
gnosygnu 2015-05-10 23:00:43 -04:00
parent 0b5aa9aefe
commit 6eec99a713
157 changed files with 2148 additions and 975 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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();

View File

@ -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();}

View File

@ -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();
}

View File

@ -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<String> 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);
}

View File

@ -16,21 +16,20 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
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);
}

View File

@ -17,15 +17,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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() {}
}

View File

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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);

View File

@ -17,12 +17,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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);}

View File

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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);

View File

@ -16,17 +16,16 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
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();
}

View File

@ -16,21 +16,20 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
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;}
}

View File

@ -17,7 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;}

View File

@ -17,30 +17,30 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;}
}

View File

@ -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);}

View File

@ -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++) {

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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);}

View File

@ -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_"

View File

@ -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) {

View File

@ -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)));}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}

View File

@ -0,0 +1,68 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.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); // &amp; -> &
// 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: "<abcEOS"
if (name_bgn == name_end) return tkn_end; // ws; EX: "< "
Object o = handler.Get_or_null(src, name_bgn, name_end);
if (o == null) return name_end; // unknown name: EX: "<unknown >"
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: "<name lots_of_text_but_no_gt EOS"
Xop_xatr_itm[] xatr_ary = xatr_parser.Parse(msg_log, src, name_end, node_end);
Gfo_html_tkn tkn = (Gfo_html_tkn)o;
tkn.Process(src, Xop_xatr_hash.new_ary(src, xatr_ary));
return node_end;
}
}

View File

@ -0,0 +1,22 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.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);
}

View File

@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.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) {}
}

View File

@ -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);}

View File

@ -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();

View File

@ -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.");
}

View File

@ -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;

View File

@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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.*;

View File

@ -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());

View File

@ -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

View File

@ -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");

View File

@ -17,11 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;

View File

@ -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() {

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -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;");
}

View File

@ -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();

View File

@ -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";
}

View File

@ -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)) {

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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);
// }
// }

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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); // &amp; -> &
css_url_bry = Bry_.Replace(css_url_bry, Css_amp_find, Css_amp_repl); // &amp; -> &
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));

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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));

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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();

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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_();

View File

@ -0,0 +1,56 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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)
;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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\"] {")
;
}

View File

@ -0,0 +1,38 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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);
}
}

View File

@ -0,0 +1,58 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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/");
}

View File

@ -0,0 +1,60 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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));
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -0,0 +1,59 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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();
}
}
}

View File

@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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));
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -0,0 +1,42 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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)));
}
}

View File

@ -0,0 +1,25 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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;
}

View File

@ -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);

View File

@ -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));

View File

@ -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();
}

View File

@ -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);

View File

@ -0,0 +1,23 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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();
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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());

View File

@ -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);}

View File

@ -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

View File

@ -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);

View File

@ -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;}
}

View File

@ -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";
}

View File

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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();

View File

@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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();

View File

@ -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));

View File

@ -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");

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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<EFBFBD>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);
}
}

View File

@ -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()));
}
}

View File

@ -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);
}

View File

@ -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
}
}

View File

@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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();
}

View File

@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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 href=\"/wiki/A\" xowa_redlink='1'>A</a>"
, "<a href=\"/wiki/B\" xowa_redlink='2'>B</a>"
@ -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) {

View File

@ -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"

View File

@ -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();

View File

@ -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

View File

@ -16,14 +16,12 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.hdumps.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.hdumps.*;
import gplx.core.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();

View File

@ -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)));}

View File

@ -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_("</a>")
, Find_img_xatrs = Bry_.new_ascii_("xatrs='")
;

View File

@ -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 xtid='a_lnki_text_n' href=\"/wiki/A\" id='xowa_lnki_0' title='A'>A</a>");
fxt.Test_load(brys, "<a href='/wiki/A' title='A'>A</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 xtid='a_lnki_text_n' href=\"/wiki/A\" id=\"xowa_lnki_3\" title='A'>A</a>");
fxt.Test_load(brys, "<a href='/wiki/A' id='xowa_lnki_3' title='A'>A</a>");
}
@Test public void Srl_lnki_text_n_alt_case() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), Bry_.new_ascii_("a"), Xow_hzip_dict.Escape_bry);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/A\" id='xowa_lnki_0' title='A'>a</a>");
fxt.Test_load(brys, "<a href='/wiki/A' title='a'>a</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 xtid='a_lnki_text_n' href=\"/wiki/A\" id=\"xowa_lnki_3\" title='A'>a</a>");
fxt.Test_load(brys, "<a href='/wiki/A' id='xowa_lnki_3' title='a'>a</a>");
}
@Test public void Srl_lnki_text_n_ns() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(12), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/Template:A\" id='xowa_lnki_0' title='Template:A'>Template:A</a>");
fxt.Test_load(brys, "<a href='/wiki/Template:A' title='Template:A'>Template:A</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, "<a xtid='a_lnki_text_n' href=\"/wiki/Template:A\" id=\"xowa_lnki_3\" title='Template:A'>Template:A</a>");
fxt.Test_load(brys, "<a href='/wiki/Template:A' id='xowa_lnki_3' title='Template:A'>Template:A</a>");
}
@Test public void Srl_lnki_text_n_apos() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(12), Bry_.new_ascii_("A'b"), Xow_hzip_dict.Escape_bry);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/Template:A'b\" id='xowa_lnki_0' title='Template:A'b'>Template:A'b</a>");
fxt.Test_load(brys, "<a href='/wiki/Template:A&#39;b' title='Template:A&#39;b'>Template:A'b</a>");
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, "<a xtid='a_lnki_text_n' href=\"/wiki/Template:A'b\" id=\"xowa_lnki_3\" title='Template:A'b'>Template:A'b</a>");
fxt.Test_load(brys, "<a href='/wiki/Template:A&#39;b' id='xowa_lnki_3' title='Template:A&#39;b'>Template:A'b</a>");
}
@Test public void Srl_lnki_text_n_xwiki() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), 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 xtid='a_lnki_text_n' href=\"/site/en.wiktionary.org/wiki/A\" id='xowa_lnki_0' title='A'>A</a>");
fxt.Test_load(brys, "<a href='/site/en.wiktionary.org/wiki/A' title='A'>A</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 xtid='a_lnki_text_n' href=\"/site/en.wiktionary.org/wiki/A\" id=\"xowa_lnki_3\" title='A'>A</a>");
fxt.Test_load(brys, "<a href='/site/en.wiktionary.org/wiki/A' id='xowa_lnki_3' title='A'>A</a>");
}
@Test public void Srl_lnki_text_n_smoke() {
byte[][] brys = Bry_.Ary(Bry_.new_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_1<a xtid='a_lnki_text_n' href=\"/wiki/A\" id='xowa_lnki_0' title='A'>A</a>a_2");
fxt.Test_load(brys, "a_1<a href='/wiki/A' title='A'>A</a>a_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_1<a xtid='a_lnki_text_n' href=\"/wiki/A\" id=\"xowa_lnki_3\" title='A'>A</a>a_2");
fxt.Test_load(brys, "a_1<a href='/wiki/A' id='xowa_lnki_3' title='A'>A</a>a_2");
}
@Test public void Srl_lnki_text_y() {
byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry, Bry_.new_ascii_("A1"), Xow_hzip_dict.Bry_a_rhs);
fxt.Test_save(brys, "<a xtid='a_lnki_text_y' href=\"/wiki/A\" id='xowa_lnki_0' title='A'>A1</a>");
fxt.Test_load(brys, "<a href='/wiki/A' title='A'>A1</a>");
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, "<a xtid='a_lnki_text_y' href=\"/wiki/A\" id=\"xowa_lnki_3\" title='A'>A1</a>");
fxt.Test_load(brys, "<a href='/wiki/A' id='xowa_lnki_3' title='A'>A1</a>");
}
@Test public void Srl_lnki_text_y_nest() {
byte[][] brys = Bry_.Ary
( Xow_hzip_dict.Bry_lnki_text_y, Bry_.ints_(2), 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, "<a xtid='a_lnki_text_y' href=\"/wiki/A\">B<a xtid='a_lnki_text_y' href=\"/wiki/C\">C1</a>D</a>");
fxt.Test_load(brys, "<a href='/wiki/A' title='A'>B<a href='/wiki/C' title='C'>C1</a>D</a>");
fxt.Test_save(brys, "<a xtid='a_lnki_text_y' href=\"/wiki/A\" id=\"xowa_lnki_3\">B<a xtid='a_lnki_text_y' href=\"/wiki/C\" id=\"xowa_lnki_3\">C1</a>D</a>");
fxt.Test_load(brys, "<a href='/wiki/A' id='xowa_lnki_3' title='A'>B<a href='/wiki/C' id='xowa_lnki_3' title='C'>C1</a>D</a>");
}
@Test public void Srl_noop() {
byte[][] brys = Bry_.Ary(Bry_.new_utf8_("<a href='/wiki/A'>A"), Xow_hzip_dict.Bry_a_rhs);
byte[][] brys = Bry_.Ary(Bry_.new_utf8_("<a href='/wiki/A'>A"), Xow_hzip_dict.Bry_a_rhs); // NOTE: still converts "</a>" to hzip
fxt.Test_save(brys, "<a href='/wiki/A'>A</a>");
fxt.Test_load(brys, "<a href='/wiki/A'>A</a>");
}
@Test public void Srl_lnki_text_y__multiple() { // PURPOSE: if id is missing from 1st anchor, do not get from second
byte[][] brys = Bry_.Ary(Bry_.new_utf8_("<a xtid='a_lnki_text_n' href=\"/wiki/A\" title=\"A\">A")
, Xow_hzip_dict.Bry_a_rhs
, Xow_hzip_dict.Bry_lnki_text_n, Bry_.ints_(2), fxt.Make_int(3), Bry_.new_ascii_("B"), Xow_hzip_dict.Escape_bry
);
fxt.Test_save(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/A\" title=\"A\">A</a><a xtid='a_lnki_text_n' href=\"/wiki/B\" id=\"xowa_lnki_3\" title=\"B\">B</a>");
fxt.Test_load(brys, "<a xtid='a_lnki_text_n' href=\"/wiki/A\" title=\"A\">A</a><a href='/wiki/B' id='xowa_lnki_3' title='B'>B</a>");
}
@Test public void Srl_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]]", "<a xtid='a_lnki_text_n' href=\"/site/en.wiktionary.org/wiki/A\" xowa_redlink='0'>wikt:A</a>");
fxt.Test_html("[[wikt:A]]", "<a xtid='a_lnki_text_n' href=\"/site/en.wiktionary.org/wiki/A\" xowa_redlink='1'>wikt:A</a>");
}
@Test public void Html_lnke_txt() {
fxt.Test_html("http://a.org", "<a xtid='a_lnke_txt' href=\"http://a.org\" class=\"external text\" rel=\"nofollow\">http://a.org</a>");

View File

@ -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;

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