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 2014-07-06 22:58:35 -04:00
parent 57f65b4d0c
commit ecbe2918d8
187 changed files with 4184 additions and 2286 deletions

View File

@ -65,7 +65,7 @@ public class Bry_bfr {
bfr_len += len;
return this;
}
public Bry_bfr Add_bfr(Bry_bfr src) {
public Bry_bfr Add_bfr_and_preserve(Bry_bfr src) {
int len = src.bfr_len;
if (bfr_len + len > bfr_max) Resize((bfr_max + len) * 2);
Bry_.Copy_by_pos(src.bfr, 0, len, bfr, bfr_len);
@ -74,10 +74,15 @@ public class Bry_bfr {
return this;
}
public Bry_bfr Add_bfr_and_clear(Bry_bfr src) {
Add_bfr(src);
Add_bfr_and_preserve(src);
src.ClearAndReset();
return this;
}
public Bry_bfr Add_bfr_or_mid(boolean escaped, Bry_bfr tmp_bfr, byte[] src, int src_bgn, int src_end) {
return escaped
? this.Add_bfr_and_clear(tmp_bfr)
: this.Add_mid(src, src_bgn, src_end);
}
public Bry_bfr Add_bfr_trim_and_clear(Bry_bfr src, boolean trim_bgn, boolean trim_end) {return Add_bfr_trim_and_clear(src, trim_bgn, trim_end, Bry_.Trim_ary_ws);}
public Bry_bfr Add_bfr_trim_and_clear(Bry_bfr src, boolean trim_bgn, boolean trim_end, byte[] trim_ary) {
int src_len = src.bfr_len;
@ -326,7 +331,7 @@ public class Bry_bfr {
else if (o_type == Byte.class) Add_byte(Byte_.cast_(o));
else if (o_type == Long.class) Add_long_variable(Long_.cast_(o));
else if (o_type == String.class) Add_str((String)o);
else if (o_type == Bry_bfr.class) Add_bfr((Bry_bfr)o);
else if (o_type == Bry_bfr.class) Add_bfr_and_preserve((Bry_bfr)o);
else if (o_type == DateAdp.class) Add_dte((DateAdp)o);
else if (o_type == Io_url.class) Add(((Io_url)o).RawBry());
else if (o_type == boolean.class) Add_yn(Bool_.cast_(o));
@ -377,6 +382,20 @@ public class Bry_bfr {
if (new_len > -1) bfr_len = new_len;
return this;
}
public Bry_bfr Trim_end(byte trim_byte) {
if (bfr_len == 0) return this;
int count = 0;
for (int i = bfr_len - 1; i > -1; --i) {
byte b = bfr[i];
if (b == trim_byte)
++count;
else
break;
}
if (count > 0)
this.Del_by(count);
return this;
}
public Bry_bfr Concat_skip_empty(byte[] dlm, byte[]... ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {

View File

@ -0,0 +1,37 @@
/*
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;
public class Bry_bfr_ {
public static void Assert_at_end(Bry_bfr bfr, byte assert_byte) {
int len = bfr.Len(); if (len == 0) return;
int assert_count = 0;
byte[] bfr_bry = bfr.Bfr();
for (int i = len - 1; i > -1; --i) {
byte b = bfr_bry[i];
if (b == assert_byte)
++assert_count;
else
break;
}
switch (assert_count) {
case 0: bfr.Add_byte(assert_byte); break;
case 1: break;
default: bfr.Del_by(assert_count - 1); break;
}
}
}

View File

@ -117,7 +117,7 @@ public class Bry_finder {
}
return rv;
}
public static int Find_bwd_non_ws(byte[] src, int cur, int end) { // get pos of 1st char that is not ws;
public static int Find_bwd_non_ws_or_not_found(byte[] src, int cur, int end) { // get pos of 1st char that is not ws;
if (cur >= src.length) return Bry_finder.Not_found;
for (int i = cur; i >= end; i--) {
byte b = src[i];
@ -130,6 +130,19 @@ public class Bry_finder {
}
return Bry_finder.Not_found;
}
public static int Find_bwd_non_ws_or_end(byte[] src, int cur, int end) {
if (cur >= src.length) return Bry_finder.Not_found;
for (int i = cur; i >= end; i--) {
byte b = src[i];
switch (b) {
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.NewLine: case Byte_ascii.CarriageReturn:
break;
default:
return i;
}
}
return end;
}
public static int Find_bwd_while(byte[] src, int cur, int end, byte while_byte) {
--cur;
while (true) {

View File

@ -23,7 +23,7 @@ public class Bry_fmtr_arg_ {
public static Bry_fmtr_arg_byt byt_(byte v) {return new Bry_fmtr_arg_byt(v);}
public static Bry_fmtr_arg_int int_(int v) {return new Bry_fmtr_arg_int(v);}
public static Bry_fmtr_arg_bfr bfr_(Bry_bfr v) {return new Bry_fmtr_arg_bfr(v);}
public static Bry_fmtr_arg_bfr_retain bfr_retain_(Bry_bfr v) {return new Bry_fmtr_arg_bfr_retain(v);}
public static Bry_fmtr_arg_bfr_preserve bfr_retain_(Bry_bfr v) {return new Bry_fmtr_arg_bfr_preserve(v);}
public static Bry_fmtr_arg fmtr_(Bry_fmtr v, Bry_fmtr_arg... arg_ary) {return new Bry_fmtr_arg_fmtr(v, arg_ary);}
public static Bry_fmtr_arg_fmtr_objs fmtr_null_() {return new Bry_fmtr_arg_fmtr_objs(null, null);}
public static final Bry_fmtr_arg Null = new Bry_fmtr_arg_null();

View File

@ -70,7 +70,16 @@ public class Byte_ascii {
;
}
public static final byte[]
Dot_bry = new byte[] {Byte_ascii.Dot}
, NewLine_bry = new byte[] {Byte_ascii.NewLine}
Dot_bry = new byte[] {Byte_ascii.Dot}
, NewLine_bry = new byte[] {Byte_ascii.NewLine}
, Colon_bry = new byte[] {Byte_ascii.Colon}
, Lt_bry = new byte[] {Byte_ascii.Lt}
, Gt_bry = new byte[] {Byte_ascii.Gt}
, Brack_bgn_bry = new byte[] {Byte_ascii.Brack_bgn}
, Apos_bry = new byte[] {Byte_ascii.Apos}
, Pipe_bry = new byte[] {Byte_ascii.Pipe}
, Underline_bry = new byte[] {Byte_ascii.Underline}
, Asterisk_bry = new byte[] {Byte_ascii.Asterisk}
, Space_bry = new byte[] {Byte_ascii.Space}
;
}

View File

@ -16,8 +16,8 @@ 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.brys; import gplx.*;
public class Bry_fmtr_arg_bfr_retain implements Bry_fmtr_arg {
public Bry_fmtr_arg_bfr_retain Data_(Bry_bfr v) {bfr = v; return this;}
public void XferAry(Bry_bfr trg, int idx) {trg.Add_bfr(bfr);}
public Bry_fmtr_arg_bfr_retain(Bry_bfr bfr) {this.bfr = bfr;} Bry_bfr bfr;
public class Bry_fmtr_arg_bfr_preserve implements Bry_fmtr_arg {
public Bry_fmtr_arg_bfr_preserve Data_(Bry_bfr v) {bfr = v; return this;}
public void XferAry(Bry_bfr trg, int idx) {trg.Add_bfr_and_preserve(bfr);}
public Bry_fmtr_arg_bfr_preserve(Bry_bfr bfr) {this.bfr = bfr;} Bry_bfr bfr;
}

View File

@ -16,18 +16,23 @@ 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;
import gplx.intl.*;
public class Hash_adp_bry extends gplx.lists.HashAdp_base implements HashAdp {
Hash_adp_bry(boolean case_match) {
this.case_match = case_match;
key_ref = new Hash_adp_bry_ref(case_match, null, -1, -1);
} private final boolean case_match; private Hash_adp_bry_ref key_ref;
public Object Get_by_bry(byte[] src) {return super.Fetch_base(key_ref.Src_all_(src));}
public Object Get_by_mid(byte[] src, int bgn, int end) {return super.Fetch_base(key_ref.Src_all_set_(src, bgn, end));}
public Hash_adp_bry Add_bry_bry(byte[] key) {this.Add_base(key, key); return this;}
public Hash_adp_bry Add_str_byte(String key, byte val) {this.Add_base(Bry_.new_utf8_(key), Byte_obj_val.new_(val)); return this;}
public Hash_adp_bry Add_str_obj(String key, Object val) {this.Add_base(Bry_.new_utf8_(key), val); return this;}
public Hash_adp_bry Add_bry_byte(byte[] key, byte val) {this.Add_base(key, Byte_obj_val.new_(val)); return this;}
public Hash_adp_bry Add_bry_obj(byte[] key, Object val) {this.Add_base(key, val); return this;}
private final Hash_adp_bry_itm_base proto, key_ref;
Hash_adp_bry(Hash_adp_bry_itm_base proto) {
this.proto = proto;
key_ref = proto.New();
}
@Override protected Object Fetch_base(Object key) {return super.Fetch_base(key_ref.Init((byte[])key));}
@Override protected void Del_base(Object key) {super.Del_base(key_ref.Init((byte[])key));}
@Override protected boolean Has_base(Object key) {return super.Has_base(key_ref.Init((byte[])key));}
public Object Get_by_bry(byte[] src) {return super.Fetch_base(key_ref.Init(src));}
public Object Get_by_mid(byte[] src, int bgn, int end) {return super.Fetch_base(key_ref.Init(src, bgn, end));}
public Hash_adp_bry Add_bry_bry(byte[] key) {this.Add_base(key, key); return this;}
public Hash_adp_bry Add_str_byte(String key, byte val) {this.Add_base(Bry_.new_utf8_(key), Byte_obj_val.new_(val)); return this;}
public Hash_adp_bry Add_str_obj(String key, Object val) {this.Add_base(Bry_.new_utf8_(key), val); return this;}
public Hash_adp_bry Add_bry_byte(byte[] key, byte val) {this.Add_base(key, Byte_obj_val.new_(val)); return this;}
public Hash_adp_bry Add_bry_obj(byte[] key, Object val) {this.Add_base(key, val); return this;}
public Hash_adp_bry Add_many_str(String... ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
@ -39,38 +44,57 @@ public class Hash_adp_bry extends gplx.lists.HashAdp_base implements HashAdp {
}
@Override protected void Add_base(Object key, Object val) {
byte[] key_bry = (byte[])key;
super.Add_base(new Hash_adp_bry_ref(case_match, key_bry, 0, key_bry.length), val);
Hash_adp_bry_itm_base key_itm = proto.New();
key_itm.Init(key_bry, 0, key_bry.length);
super.Add_base(key_itm, val);
}
@Override protected void Del_base(Object key) {super.Del_base(key_ref.Src_all_((byte[])key));}
@Override protected boolean Has_base(Object key) {return super.Has_base(key_ref.Src_all_((byte[])key));}
@Override protected Object Fetch_base(Object key) {return super.Fetch_base(key_ref.Src_all_((byte[])key));}
public static Hash_adp_bry cs_() {return new Hash_adp_bry(true);}
public static Hash_adp_bry ci_() {return new Hash_adp_bry(false);}
public static Hash_adp_bry ci_ascii_() {return new Hash_adp_bry(false);}
public static Hash_adp_bry cs_() {return new Hash_adp_bry(Hash_adp_bry_itm_cs._);}
public static Hash_adp_bry ci_ascii_() {return new Hash_adp_bry(Hash_adp_bry_itm_ci_ascii._);}
public static Hash_adp_bry ci_utf8_(Gfo_case_mgr case_mgr) {return new Hash_adp_bry(Hash_adp_bry_itm_ci_utf8.get_or_new(case_mgr));}
public static Hash_adp_bry c__utf8_(boolean case_match, Gfo_case_mgr case_mgr) {return case_match ? cs_() : ci_utf8_(case_mgr);}
public static Hash_adp_bry ci_() {return new Hash_adp_bry(Hash_adp_bry_itm_ci_ascii._);}
}
class Hash_adp_bry_ref {
public Hash_adp_bry_ref(boolean case_match, byte[] src, int src_bgn, int src_end) {this.case_match = case_match; this.src = src; this.src_bgn = src_bgn; this.src_end = src_end;}
final boolean case_match;
public byte[] Src() {return src;} private byte[] src;
public Hash_adp_bry_ref Src_all_(byte[] v) {
this.src = v;
this.src_bgn = 0;
this.src_end = v.length;
return this;
}
public Hash_adp_bry_ref Src_all_set_(byte[] v, int src_bgn, int src_end) {
this.src = v;
this.src_bgn = src_bgn;
this.src_end = src_end;
return this;
}
public int Src_bgn() {return src_bgn;} int src_bgn;
public int Src_end() {return src_end;} int src_end;
abstract class Hash_adp_bry_itm_base {
public abstract Hash_adp_bry_itm_base New();
public Hash_adp_bry_itm_base Init(byte[] src) {return this.Init(src, 0, src.length);}
public abstract Hash_adp_bry_itm_base Init(byte[] src, int src_bgn, int src_end);
}
class Hash_adp_bry_itm_cs extends Hash_adp_bry_itm_base {
private byte[] src; int src_bgn, src_end;
@Override public Hash_adp_bry_itm_base New() {return new Hash_adp_bry_itm_cs();}
@Override public Hash_adp_bry_itm_base Init(byte[] src, int src_bgn, int src_end) {this.src = src; this.src_bgn = src_bgn; this.src_end = src_end; return this;}
@Override public int hashCode() {
int rv = 0;
for (int i = src_bgn; i < src_end; i++) {
int b_int = src[i] & 0xFF; // JAVA: patch
if (!case_match && b_int > 64 && b_int < 91) // 64=before A; 91=after Z; NOTE: lowering upper-case on PERF assumption that there will be more lower-case letters than upper-case
rv = (31 * rv) + b_int;
}
return rv;
}
@Override public boolean equals(Object obj) {
if (obj == null) return false;
Hash_adp_bry_itm_cs comp = (Hash_adp_bry_itm_cs)obj;
byte[] comp_src = comp.src; int comp_bgn = comp.src_bgn, comp_end = comp.src_end;
int comp_len = comp_end - comp_bgn, src_len = src_end - src_bgn;
if (comp_len != src_len) return false;
for (int i = 0; i < comp_len; i++) {
int src_pos = src_bgn + i;
if (src_pos >= src_end) return false; // ran out of src; exit; EX: src=ab; find=abc
if (src[src_pos] != comp_src[i + comp_bgn]) return false;
}
return true;
}
public static final Hash_adp_bry_itm_cs _ = new Hash_adp_bry_itm_cs(); Hash_adp_bry_itm_cs() {}
}
class Hash_adp_bry_itm_ci_ascii extends Hash_adp_bry_itm_base {
private byte[] src; int src_bgn, src_end;
@Override public Hash_adp_bry_itm_base New() {return new Hash_adp_bry_itm_ci_ascii();}
@Override public Hash_adp_bry_itm_base Init(byte[] src, int src_bgn, int src_end) {this.src = src; this.src_bgn = src_bgn; this.src_end = src_end; return this;}
@Override public int hashCode() {
int rv = 0;
for (int i = src_bgn; i < src_end; i++) {
int b_int = src[i] & 0xFF; // JAVA: patch
if (b_int > 64 && b_int < 91) // 64=before A; 91=after Z; NOTE: lowering upper-case on PERF assumption that there will be more lower-case letters than upper-case
b_int += 32;
rv = (31 * rv) + b_int;
}
@ -78,24 +102,77 @@ class Hash_adp_bry_ref {
}
@Override public boolean equals(Object obj) {
if (obj == null) return false;
Hash_adp_bry_ref comp = (Hash_adp_bry_ref)obj;
byte[] comp_src = comp.Src(); int comp_bgn = comp.Src_bgn(), comp_end = comp.Src_end();
Hash_adp_bry_itm_ci_ascii comp = (Hash_adp_bry_itm_ci_ascii)obj;
byte[] comp_src = comp.src; int comp_bgn = comp.src_bgn, comp_end = comp.src_end;
int comp_len = comp_end - comp_bgn, src_len = src_end - src_bgn;
if (comp_len != src_len) return false;
for (int i = 0; i < comp_len; i++) {
int src_pos = src_bgn + i;
if (src_pos >= src_end) return false; // ran out of src; exit; EX: src=ab; find=abc
if (case_match) {
if (src[src_pos] != comp_src[i + comp_bgn]) return false;
byte src_byte = src[src_pos];
if (src_byte > 64 && src_byte < 91) src_byte += 32;
byte comp_byte = comp_src[i + comp_bgn];
if (comp_byte > 64 && comp_byte < 91) comp_byte += 32;
if (src_byte != comp_byte) return false;
}
return true;
}
public static final Hash_adp_bry_itm_ci_ascii _ = new Hash_adp_bry_itm_ci_ascii(); Hash_adp_bry_itm_ci_ascii() {}
}
class Hash_adp_bry_itm_ci_utf8 extends Hash_adp_bry_itm_base {
private final Gfo_case_mgr case_mgr;
Hash_adp_bry_itm_ci_utf8(Gfo_case_mgr case_mgr) {this.case_mgr = case_mgr;}
private byte[] src; int src_bgn, src_end;
@Override public Hash_adp_bry_itm_base New() {return new Hash_adp_bry_itm_ci_utf8(case_mgr);}
@Override public Hash_adp_bry_itm_base Init(byte[] src, int src_bgn, int src_end) {this.src = src; this.src_bgn = src_bgn; this.src_end = src_end; return this;}
@Override public int hashCode() {
int rv = 0;
for (int i = src_bgn; i < src_end; i++) {
byte b = src[i];
int b_int = b & 0xFF; // JAVA: patch
Gfo_case_itm itm = case_mgr.Get_or_null(b, src, i, src_end);
if (itm == null) { // unknown itm; byte is a number, symbol, or unknown; just use the existing byte
}
else { // known itm; use its hash_code
b_int = itm.Hashcode_lo();
i += itm.Len_lo() - 1;
}
rv = (31 * rv) + b_int;
}
return rv;
}
@Override public boolean equals(Object obj) {
if (obj == null) return false;
Hash_adp_bry_itm_ci_utf8 trg_itm = (Hash_adp_bry_itm_ci_utf8)obj;
byte[] trg = trg_itm.src; int trg_bgn = trg_itm.src_bgn, trg_end = trg_itm.src_end;
int trg_len = trg_end - trg_bgn, src_len = src_end - src_bgn;
if (trg_len != src_len) return false;
for (int i = 0; i < trg_len; i++) { // ASSUME: upper/lower have same width; i.e.: upper'ing a character doesn't go from a 2-width byte to a 3-width byte
int src_pos = src_bgn + i;
if (src_pos >= src_end) return false; // ran out of src; exit; EX: src=ab; find=abc
byte src_byte = src[src_pos];
byte trg_byte = trg[i + trg_bgn];
Gfo_case_itm src_case_itm = case_mgr.Get_or_null(src_byte, src, i, src_len);
Gfo_case_itm trg_case_itm = case_mgr.Get_or_null(trg_byte, trg, i, trg_len);
if (src_case_itm != null && trg_case_itm == null) return false;
else if (src_case_itm == null && trg_case_itm != null) return false;
else if (src_case_itm == null && trg_case_itm == null) {
if (src_byte != trg_byte) return false;
}
else {
byte src_byte = src[src_pos];
if (src_byte > 64 && src_byte < 91) src_byte += 32;
byte comp_byte = comp_src[i + comp_bgn];
if (comp_byte > 64 && comp_byte < 91) comp_byte += 32;
if (src_byte != comp_byte) return false;
if (!src_case_itm.Eq_lo(trg_case_itm)) return false;
i += src_case_itm.Len_lo() - 1;
}
}
return true;
}
public static Hash_adp_bry_itm_ci_utf8 get_or_new(Gfo_case_mgr case_mgr) {
switch (case_mgr.Tid()) {
case Gfo_case_mgr_.Tid_ascii: if (Itm_ascii == null) Itm_ascii = new Hash_adp_bry_itm_ci_utf8(case_mgr); return Itm_ascii;
case Gfo_case_mgr_.Tid_utf8: if (Itm_utf8 == null) Itm_utf8 = new Hash_adp_bry_itm_ci_utf8(case_mgr); return Itm_utf8;
case Gfo_case_mgr_.Tid_custom: return new Hash_adp_bry_itm_ci_utf8(case_mgr);
default: throw Err_.unhandled(case_mgr.Tid());
}
}
private static Hash_adp_bry_itm_ci_utf8 Itm_ascii, Itm_utf8;
}

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.intl; import gplx.*;
public interface Gfo_case_itm {
boolean Eq_lo(Gfo_case_itm itm);
int Hashcode_lo();
int Len_lo();
}

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.intl; import gplx.*;
public interface Gfo_case_mgr {
byte Tid();
Gfo_case_itm Get_or_null(byte bgn_byte, byte[] src, int bgn, int end);
}

View File

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

View File

@ -24,6 +24,7 @@ public interface Gxw_html extends GxwElem {
String Html_doc_selected_get_src_or_empty();
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();
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

@ -25,6 +25,7 @@ public class Gfui_html extends GfuiElemBase {
public String Html_doc_selected_get_src_or_empty() {return under.Html_doc_selected_get_src_or_empty();}
public boolean Html_doc_find(String elem_id, String find, boolean dir_fwd, boolean case_match, boolean wrap_find) {return under.Html_doc_find(elem_id, find, dir_fwd, case_match, wrap_find);}
public void Html_doc_body_focus() {under.Html_doc_body_focus();}
public void Html_doc_selection_focus_toggle() {under.Html_doc_selection_focus_toggle();}
@gplx.Virtual public String Html_elem_atr_get_str(String elem_id, String atr_key) {return under.Html_elem_atr_get_str(elem_id, atr_key);}
@gplx.Virtual public boolean Html_elem_atr_get_bool(String elem_id, String atr_key) {return under.Html_elem_atr_get_bool(elem_id, atr_key);}
public boolean Html_elem_atr_set(String elem_id, String atr_key, String v) {return under.Html_elem_atr_set(elem_id, atr_key, v);}

View File

@ -19,6 +19,7 @@ package gplx.gfui; import gplx.*;
public class Gfui_html_cfg implements GfoInvkAble {
public String Doc_html() {return Exec_fmt(fmtr_doc_html);} private Bry_fmtr fmtr_doc_html = Bry_fmtr.new_();
public String Doc_body_focus() {return Exec_fmt(fmtr_doc_body_focus);} private Bry_fmtr fmtr_doc_body_focus = Bry_fmtr.new_();
public String Doc_selection_focus_toggle() {return Exec_fmt(fmtr_doc_selection_focus_toggle);} private Bry_fmtr fmtr_doc_selection_focus_toggle = Bry_fmtr.new_();
public String Doc_selected_get_text_or_href() {return Exec_fmt(fmtr_doc_selected_get_text_or_href);} private Bry_fmtr fmtr_doc_selected_get_text_or_href = Bry_fmtr.keys_();
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_();
@ -63,6 +64,7 @@ public class Gfui_html_cfg implements GfoInvkAble {
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_doc_html_)) fmtr_doc_html.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_doc_body_focus_)) fmtr_doc_body_focus.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_doc_selection_focus_toggle_)) fmtr_doc_selection_focus_toggle.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_doc_selected_get_text_or_href_)) fmtr_doc_selected_get_text_or_href.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_doc_selected_get_href_or_text_)) fmtr_doc_selected_get_href_or_text.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_doc_selected_get_src_or_empty_)) fmtr_doc_selected_get_src_or_empty.Fmt_(m.ReadBry("v"));
@ -95,7 +97,8 @@ 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_active_atr_get_ = "doc_active_atr_get_", Invk_doc_find_html_ = "doc_find_html_", Invk_doc_find_edit_ = "doc_find_edit_"
, Invk_doc_html_ = "doc_html_", Invk_doc_body_focus_ = "doc_body_focus_", Invk_doc_selection_focus_toggle_ = "doc_selection_focus_toggle_"
, 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_win_print_preview_ = "win_print_preview_"
, Invk_elem_atr_get_ = "elem_atr_get_", Invk_elem_atr_get_toString_ = "elem_atr_get_toString_", Invk_elem_atr_set_ = "elem_atr_set_", Invk_elem_atr_set_append_ = "elem_atr_set_append_"

View File

@ -62,6 +62,7 @@ class Mem_html extends GxwTextMemo_lang implements Gxw_html { public String Htm
return rv == null ? or : rv;
}
public void Html_doc_body_focus() {}
public void Html_doc_selection_focus_toggle() {}
public String Html_window_vpos() {return "";}
public boolean Html_window_vpos_(String v) {return true;}
public boolean Html_elem_focus(String v) {return true;}

View File

@ -52,6 +52,7 @@ class Swt_html implements Gxw_html, Swt_control, FocusListener {
public String Html_doc_selected_get_href_or_text() {return Eval_script_as_str(kit.Html_cfg().Doc_selected_get_href_or_text());}
public String Html_doc_selected_get_src_or_empty() {return Eval_script_as_str(kit.Html_cfg().Doc_selected_get_src_or_empty());}
public void Html_doc_body_focus() {Eval_script_as_exec(kit.Html_cfg().Doc_body_focus());}
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)));}
public Object Html_elem_atr_get_obj(String elem_id, String atr_key) {return Eval_script(kit.Html_cfg().Elem_atr_get(elem_id, atr_key));}

View File

@ -0,0 +1,50 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.regxs; import gplx.*; import gplx.core.*;
public class Gfo_pattern {
private Gfo_pattern_itm[] itms; int itms_len;
public Gfo_pattern(byte[] raw) {
this.raw = raw;
itms = Gfo_pattern_itm_.Compile(raw);
itms_len = itms.length;
}
public byte[] Raw() {return raw;} private byte[] raw;
private Gfo_pattern_ctx ctx = new Gfo_pattern_ctx();
public boolean Match(byte[] val) {
int val_len = val.length;
int val_pos = 0;
ctx.Init(itms_len);
for (int i = 0; i < itms_len; ++i) {
Gfo_pattern_itm itm = itms[i];
ctx.Itm_idx_(i);
val_pos = itm.Match(ctx, val, val_len, val_pos);
if (!ctx.Rslt_pass()) return false;
}
return ctx.Rslt_pass() && val_pos == val_len;
}
public static Gfo_pattern[] Parse_to_ary(byte[] raw) {
byte[][] patterns = Bry_.Split(raw, Byte_ascii.Semic, true);
int patterns_len = patterns.length;
Gfo_pattern[] rv = new Gfo_pattern[patterns_len];
for (int i = 0; i < patterns_len; ++i) {
byte[] pattern = patterns[i];
rv[i] = new Gfo_pattern(pattern);
}
return rv;
}
}

View File

@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.regxs; import gplx.*; import gplx.core.*;
public class Gfo_pattern_ctx {
public boolean Rslt_pass() {return rslt;} private boolean rslt;
public void Rslt_fail_() {rslt = false;}
public boolean Prv_was_wild() {return prv_was_wild;} public void Prv_was_wild_(boolean v) {prv_was_wild = v;} private boolean prv_was_wild;
private int itm_len;
public int Itm_idx() {return itm_idx;} public void Itm_idx_(int v) {itm_idx = v;} private int itm_idx;
public boolean Itm_idx_is_last() {return itm_idx == itm_len - 1;}
public void Init(int itm_len) {
rslt = true;
this.itm_len = itm_len;
}
}

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.core.regxs; import gplx.*; import gplx.core.*;
public interface Gfo_pattern_itm {
byte Tid();
void Compile(byte[] src, int bgn, int end);
int Match(Gfo_pattern_ctx ctx, byte[] src, int src_len, int pos);
void Xto_str(String_bldr sb);
}
class Gfo_pattern_itm_text implements Gfo_pattern_itm {
public Gfo_pattern_itm_text() {}
public byte Tid() {return Gfo_pattern_itm_.Tid_text;}
public byte[] Text() {return text;} private byte[] text; private int text_len;
public void Xto_str(String_bldr sb) {sb.Add(this.Tid()).Add("|" + String_.new_utf8_(text));}
public void Compile(byte[] src, int bgn, int end) {
this.text = Bry_.Mid(src, bgn, end);
this.text_len = end - bgn;
}
public int Match(Gfo_pattern_ctx ctx, byte[] src, int src_len, int pos) {
boolean pass = false;
int text_end = pos + text_len;
if (text_end > src_len) text_end = src_len;
if (ctx.Prv_was_wild()) {
int text_bgn = Bry_finder.Find_fwd(src, text, pos);
pass = text_bgn != Bry_finder.Not_found;
if (pass)
pos = text_bgn + text_len;
}
else {
pass = Bry_.Match(src, pos, text_end, text);
if (pass)
pos = text_end;
}
if (!pass) ctx.Rslt_fail_();
ctx.Prv_was_wild_(false);
return pos;
}
}
class Gfo_pattern_itm_wild implements Gfo_pattern_itm {
public byte Tid() {return Gfo_pattern_itm_.Tid_wild;}
public void Compile(byte[] src, int bgn, int end) {}
public int Match(Gfo_pattern_ctx ctx, byte[] src, int src_len, int pos) {
ctx.Prv_was_wild_(true);
return ctx.Itm_idx_is_last() ? src_len : pos;
}
public void Xto_str(String_bldr sb) {sb.Add(this.Tid()).Add("|*");}
public static final Gfo_pattern_itm_wild _ = new Gfo_pattern_itm_wild(); Gfo_pattern_itm_wild() {}
}

View File

@ -0,0 +1,51 @@
/*
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.regxs; import gplx.*; import gplx.core.*;
public class Gfo_pattern_itm_ {
public static final byte Tid_text = 0, Tid_wild = 1;
public static Gfo_pattern_itm[] Compile(byte[] raw) {
ListAdp rv = ListAdp_.new_();
int raw_len = raw.length;
int itm_bgn = -1;
Gfo_pattern_itm itm = null;
int pos = 0;
while (true) {
boolean last = pos == raw_len;
byte b = last ? Byte_ascii.Nil : raw[pos];
switch (b) {
case Byte_ascii.Nil:
if (itm != null) {itm.Compile(raw, itm_bgn, pos); itm = null;}
break;
case Byte_ascii.Asterisk:
if (itm != null) {itm.Compile(raw, itm_bgn, pos); itm = null;}
rv.Add(Gfo_pattern_itm_wild._);
break;
default:
if (itm_bgn == -1) {
itm_bgn = pos;
itm = new Gfo_pattern_itm_text();
rv.Add(itm);
}
break;
}
++pos;
if (last) break;
}
return (Gfo_pattern_itm[])rv.XtoAryAndClear(Gfo_pattern_itm.class);
}
}

View File

@ -0,0 +1,83 @@
/*
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.regxs; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Gfo_pattern_tst {
@Before public void init() {fxt.Clear();} private Gfo_pattern_itm_fxt fxt = new Gfo_pattern_itm_fxt();
@Test public void Compile() {
fxt.Test_Compile("a" , fxt.itm_text_("a"));
fxt.Test_Compile("*" , fxt.itm_wild_());
fxt.Test_Compile("a*" , fxt.itm_text_("a"), fxt.itm_wild_());
fxt.Test_Compile("*a" , fxt.itm_wild_(), fxt.itm_text_("a"));
fxt.Test_Compile("*ab*" , fxt.itm_wild_(), fxt.itm_text_("ab"), fxt.itm_wild_());
fxt.Test_Compile("" );
}
@Test public void Match() {
Gfo_pattern pattern = fxt.pattern_("abc");
fxt.Test_Match_y(pattern, "abc");
fxt.Test_Match_n(pattern, "ab", "a", "bc", "Abc", "");
}
@Test public void Match_all() {
Gfo_pattern pattern = fxt.pattern_("*");
fxt.Test_Match_y(pattern, "a", "abc", "");
}
@Test public void Match_bgn() {
Gfo_pattern pattern = fxt.pattern_("abc*");
fxt.Test_Match_y(pattern, "abc", "abcdef");
fxt.Test_Match_n(pattern, "abd", "aabc", "");
}
@Test public void Match_end() {
Gfo_pattern pattern = fxt.pattern_("*abc");
fxt.Test_Match_y(pattern, "abc", "xyzabc");
fxt.Test_Match_n(pattern, "abcd", "");
}
}
class Gfo_pattern_itm_fxt {
public void Clear() {}
public Gfo_pattern pattern_(String raw) {return new Gfo_pattern(Bry_.new_utf8_(raw));}
public void Test_Match_y(Gfo_pattern pattern, String... itms) {Test_Match(pattern, itms, Bool_.Y);}
public void Test_Match_n(Gfo_pattern pattern, String... itms) {Test_Match(pattern, itms, Bool_.N);}
private void Test_Match(Gfo_pattern pattern, String[] itms, boolean expd) {
int len = itms.length;
for (int i = 0; i < len; i++) {
String itm = itms[i];
Tfds.Eq(expd, pattern.Match(Bry_.new_utf8_(itm)), "pattern={0} itm={1} expd={2}", String_.new_utf8_(pattern.Raw()), itm, expd);
}
}
public Gfo_pattern_itm_wild itm_wild_() {return Gfo_pattern_itm_wild._;}
public Gfo_pattern_itm_text itm_text_(String raw) {
Gfo_pattern_itm_text rv = new Gfo_pattern_itm_text();
byte[] bry = Bry_.new_utf8_(raw);
rv.Compile(bry, 0, bry.length);
return rv;
}
public void Test_Compile(String raw, Gfo_pattern_itm... expd) {
Gfo_pattern_itm[] actl = Gfo_pattern_itm_.Compile(Bry_.new_utf8_(raw));
Tfds.Eq(Ary_xto_str(expd), Ary_xto_str(actl));
}
private static String Ary_xto_str(Gfo_pattern_itm[] ary) {
int len = ary.length;
String_bldr sb = String_bldr_.new_();
for (int i = 0; i < len; i++) {
if (i != 0) sb.Add_char_nl();
Gfo_pattern_itm itm = ary[i];
itm.Xto_str(sb);
}
return sb.XtoStrAndClear();
}
}

View File

@ -184,7 +184,7 @@ class Gfs_parser_fxt {
}
private void To_str_atr(Bry_bfr bfr, Bry_bfr path_bfr, byte[] src, byte[] name, byte[] val, int val_bgn, int val_end) {
if (val == null && val_bgn == -1 && val_end == -1) return;
bfr.Add_bfr(path_bfr).Add_byte(Byte_ascii.Colon);
bfr.Add_bfr_and_preserve(path_bfr).Add_byte(Byte_ascii.Colon);
bfr.Add(name);
if (val == null)
bfr.Add_mid(src, val_bgn, val_end);

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.html; import gplx.*;
public class Html_atrs {
public class Html_atr_ {
public static final String
Src_str = "src"
;

View File

@ -16,27 +16,19 @@ 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.html; import gplx.*;
public class Html_consts {
public static final String Nl_str = "&#10;";
public class Html_entity_ {
public static final String
Comm_bgn_str = "<!--"
, Comm_end_str = "-->"
, Img_str = "img"
Nl_str = "&#10;"
;
public static final byte[]
Lt = Bry_.new_ascii_("&lt;"), Gt = Bry_.new_ascii_("&gt;")
, Amp = Bry_.new_ascii_("&amp;"), Quote = Bry_.new_ascii_("&quot;"), Apos = Bry_.new_ascii_("&#39;")
, Eq = Bry_.new_ascii_("&#61;")
Lt_bry = Bry_.new_ascii_("&lt;"), Gt_bry = Bry_.new_ascii_("&gt;")
, Amp_bry = Bry_.new_ascii_("&amp;"), Quote_bry = Bry_.new_ascii_("&quot;")
, Apos_num_bry = Bry_.new_ascii_("&#39;")
, Apos_key_bry = Bry_.new_ascii_("&apos;")
, Eq_bry = Bry_.new_ascii_("&#61;")
, Nl_bry = Bry_.new_ascii_(Nl_str), Space_bry = Bry_.new_ascii_("&#32;")
, Comm_bgn = Bry_.new_ascii_(Comm_bgn_str), Comm_end = Bry_.new_ascii_(Comm_end_str)
, Hr_bry = Bry_.new_ascii_("<hr/>")
, Br_bry = Bry_.new_ascii_("<br/>")
, Td_bgn_bry = Bry_.new_ascii_("<td>")
, Td_end_bry = Bry_.new_ascii_("</td>")
, Ul_tag_bry = Bry_.new_ascii_("ul")
;
public static final int
Comm_bgn_len = Comm_bgn.length
, Comm_end_len = Comm_end.length
, Pipe_bry = Bry_.new_ascii_("&#124;")
, Colon_bry = Bry_.new_ascii_("&#58;"), Underline_bry = Bry_.new_ascii_("&#95;"), Asterisk_bry = Bry_.new_ascii_("&#42;")
, Brack_bgn_bry = Bry_.new_ascii_("&#91;")
;
}

View File

@ -16,10 +16,9 @@ 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.html; import gplx.*;
public class Html_tags {
public static final String
A_str = "a"
, Img_str = "img"
public class Html_tag_ {
public static final byte[]
Ul_name_bry = Bry_.new_ascii_("ul")
;
public static final byte[]
Body_lhs = Bry_.new_ascii_("<body>")
@ -32,5 +31,17 @@ public class Html_tags {
, Script_lhs = Bry_.new_ascii_("<script>")
, Script_lhs_w_type = Bry_.new_ascii_("<script type='text/javascript'>")
, Script_rhs = Bry_.new_ascii_("</script>")
, Hr_bry = Bry_.new_ascii_("<hr/>")
;
public static final String
Comm_bgn_str = "<!--"
, Comm_end_str = "-->"
;
public static final byte[]
Comm_bgn = Bry_.new_ascii_(Comm_bgn_str), Comm_end = Bry_.new_ascii_(Comm_end_str)
;
public static final int
Comm_bgn_len = Comm_bgn.length
, Comm_end_len = Comm_end.length
;
}

View File

@ -17,23 +17,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.html; import gplx.*;
public class Html_utl {
public static byte[] Escape_for_atr_val_as_bry(String s, byte quote_byte) {
Bry_bfr tmp_bfr = null;
public static byte[] Escape_for_atr_val_as_bry(Bry_bfr tmp_bfr, byte quote_byte, String s) {
if (s == null) return null;
byte[] bry = Bry_.new_utf8_(s);
int bry_len = bry.length;
boolean dirty = Escape_for_atr_val_as_bry(tmp_bfr, quote_byte, bry, 0, bry_len);
return dirty ? tmp_bfr.XtoAryAndClear() : bry;
}
public static boolean Escape_for_atr_val_as_bry(Bry_bfr tmp_bfr, byte quote_byte, byte[] src, int bgn, int end) {
boolean dirty = false;
int len = bry.length;
for (int i = 0; i < len; i++) {
byte b = bry[i];
for (int i = bgn; i < end; i++) {
byte b = src[i];
if (b == quote_byte) {
if (!dirty) {
tmp_bfr = Bry_bfr.reset_(256);
tmp_bfr.Add_mid(bry, 0, i);
tmp_bfr.Add_mid(src, bgn, i);
dirty = true;
}
switch (quote_byte) {
case Byte_ascii.Apos: tmp_bfr.Add(Html_consts.Apos); break;
case Byte_ascii.Quote: tmp_bfr.Add(Html_consts.Quote); break;
case Byte_ascii.Apos: tmp_bfr.Add(Html_entity_.Apos_num_bry); break;
case Byte_ascii.Quote: tmp_bfr.Add(Html_entity_.Quote_bry); break;
default: throw Err_.unhandled(quote_byte);
}
}
@ -42,7 +44,7 @@ public class Html_utl {
tmp_bfr.Add_byte(b);
}
}
return dirty ? tmp_bfr.XtoAryAndClear() : bry;
return dirty;
}
public static String Escape_html_as_str(String v) {return String_.new_utf8_(Escape_html_as_bry(Bry_.new_utf8_(v)));}
public static byte[] Escape_html_as_bry(Bry_bfr tmp, byte[] bry) {return Escape_html(false, tmp, bry, 0, bry.length, true, true, true, true, true);}
@ -60,11 +62,11 @@ public class Html_utl {
for (int i = bgn; i < end; i++) {
byte b = bry[i];
switch (b) {
case Byte_ascii.Lt: if (escape_lt) escaped = Html_consts.Lt; break;
case Byte_ascii.Gt: if (escape_gt) escaped = Html_consts.Gt; break;
case Byte_ascii.Amp: if (escape_amp) escaped = Html_consts.Amp; break;
case Byte_ascii.Quote: if (escape_quote) escaped = Html_consts.Quote; break;
case Byte_ascii.Apos: if (escape_apos) escaped = Html_consts.Apos; break;
case Byte_ascii.Lt: if (escape_lt) escaped = Html_entity_.Lt_bry; break;
case Byte_ascii.Gt: if (escape_gt) escaped = Html_entity_.Gt_bry; break;
case Byte_ascii.Amp: if (escape_amp) escaped = Html_entity_.Amp_bry; break;
case Byte_ascii.Quote: if (escape_quote) escaped = Html_entity_.Quote_bry; break;
case Byte_ascii.Apos: if (escape_apos) escaped = Html_entity_.Apos_num_bry; break;
default:
if (dirty || write_to_bfr)
bfr.Add_byte(b);
@ -91,11 +93,11 @@ public class Html_utl {
}
private static final ByteTrieMgr_slim unescape_trie = ByteTrieMgr_slim.ci_ascii_()
.Add_bry_bval(Html_consts.Lt , Byte_ascii.Lt)
.Add_bry_bval(Html_consts.Gt , Byte_ascii.Gt)
.Add_bry_bval(Html_consts.Amp , Byte_ascii.Amp)
.Add_bry_bval(Html_consts.Quote , Byte_ascii.Quote)
.Add_bry_bval(Html_consts.Apos , Byte_ascii.Apos)
.Add_bry_bval(Html_entity_.Lt_bry , Byte_ascii.Lt)
.Add_bry_bval(Html_entity_.Gt_bry , Byte_ascii.Gt)
.Add_bry_bval(Html_entity_.Amp_bry , Byte_ascii.Amp)
.Add_bry_bval(Html_entity_.Quote_bry , Byte_ascii.Quote)
.Add_bry_bval(Html_entity_.Apos_num_bry , Byte_ascii.Apos)
;
public static String Unescape_as_str(String src) {
Bry_bfr bfr = Bry_bfr.reset_(255);
@ -149,18 +151,18 @@ public class Html_utl {
public static byte[] Del_comments(Bry_bfr bfr, byte[] src, int pos, int end) {
while (true) {
if (pos >= end) break;
int comm_bgn = Bry_finder.Find_fwd(src, Html_consts.Comm_bgn, pos); // look for <!--
int comm_bgn = Bry_finder.Find_fwd(src, Html_tag_.Comm_bgn, pos); // look for <!--
if (comm_bgn == Bry_finder.Not_found) { // not found; consume rest
bfr.Add_mid(src, pos, end);
break;
}
int comm_end = Bry_finder.Find_fwd(src, Html_consts.Comm_end, comm_bgn + Html_consts.Comm_bgn_len); // look for -->
int comm_end = Bry_finder.Find_fwd(src, Html_tag_.Comm_end, comm_bgn + Html_tag_.Comm_bgn_len); // look for -->
if (comm_end == Bry_finder.Not_found) { // not found; consume rest
bfr.Add_mid(src, pos, end);
break;
}
bfr.Add_mid(src, pos, comm_bgn); // add everything between pos and comm_bgn
pos = comm_end + Html_consts.Comm_end_len; // reposition pos after comm_end
pos = comm_end + Html_tag_.Comm_end_len; // reposition pos after comm_end
}
return bfr.XtoAryAndClear();
}

View File

@ -51,7 +51,7 @@ class Html_utl_fxt {
Tfds.Eq(expd, String_.new_ascii_(actl));
}
public void Test_escape_for_atr(String src, boolean quote_is_apos, String expd) {
byte[] actl = Html_utl.Escape_for_atr_val_as_bry(src, quote_is_apos ? Byte_ascii.Apos : Byte_ascii.Quote);
byte[] actl = Html_utl.Escape_for_atr_val_as_bry(tmp_bfr, quote_is_apos ? Byte_ascii.Apos : Byte_ascii.Quote, src);
Tfds.Eq(expd, String_.new_utf8_(actl));
}
public void Test_unescape_html(boolean lt, boolean gt, boolean amp, boolean quote, boolean apos, String src, String expd) {

View File

@ -26,7 +26,9 @@ public abstract class Dsv_wkr_base implements GfoInvkAble {
tbl_parser.Init(this, this.Fld_parsers());
tbl_parser.Parse(src);
tbl_parser.Rls();
Load_by_bry_end();
}
@gplx.Virtual public void Load_by_bry_end() {}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_load_by_str)) Load_by_bry(m.ReadBry("v"));
else return GfoInvkAble_.Rv_unhandled;

View File

@ -23,7 +23,7 @@ public class Xoa_app_ {
boot_mgr.Run(args);
}
public static final String Name = "xowa";
public static final String Version = "1.6.5.1";
public static final String Version = "1.7.1.1";
public static String Build_date = "2012-12-30 00:00:00";
public static String Op_sys;
public static String User_agent = "";

View File

@ -36,7 +36,7 @@ public class Xoa_app_fxt {
public static Xow_wiki wiki_(Xoa_app app, String key) {return wiki_(app, key, app.Lang_mgr().Lang_en());}
public static Xow_wiki wiki_(Xoa_app app, String key, Xol_lang lang) {
Io_url wiki_dir = app.Fsys_mgr().Wiki_dir().GenSubDir(key);
Xow_wiki rv = new Xow_wiki(app, wiki_dir, Xow_ns_mgr_.default_(), lang);
Xow_wiki rv = new Xow_wiki(app, wiki_dir, Xow_ns_mgr_.default_(lang.Case_mgr()), lang);
rv.File_mgr().Meta_mgr().Depth_(2); // TEST: written for 2 depth
rv.Props().Main_page_(Xoa_page_.Main_page_bry); // TEST: default to Main Page (nothing tests loading Main Page from wiki.gfs)
rv.Ns_mgr().Ids_get_or_null(Xow_ns_.Id_main).Subpages_enabled_(true);

View File

@ -27,10 +27,16 @@ public class Xoapi_html_box implements GfoInvkAble {
if (tab.View_mode() != Xog_page_mode.Tid_read) // if edit / html, place focus in edit box
html_box.Html_elem_focus(Xog_html_itm.Elem_id__xowa_edit_data_box);
}
public void Selection_focus() {
Xog_tab_itm tab = win.Active_tab(); if (tab == Xog_tab_itm_.Null) return;
Gfui_html html_box = tab.Html_itm().Html_box();
html_box.Html_doc_selection_focus_toggle();
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_focus)) this.Focus();
else if (ctx.Match(k, Invk_selection_focus_toggle)) this.Selection_focus();
else return GfoInvkAble_.Rv_unhandled;
return this;
}
private static final String Invk_focus = "focus";
private static final String Invk_focus = "focus", Invk_selection_focus_toggle = "selection_focus_toggle";
}

View File

@ -24,25 +24,33 @@ public class Xoapi_popups implements GfoInvkAble, GfoEvMgrOwner {
}
public GfoEvMgr EvMgr() {return evMgr;} private GfoEvMgr evMgr;
public void Init_by_app(Xoa_app app) {this.app = app;}
public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled = false;
public int Show_init_word_count() {return show_init_word_count;} private int show_init_word_count = Dflt_show_init_word_count;
public int Show_more_word_count() {return show_more_word_count;} private int show_more_word_count = Dflt_show_more_word_count;
public int Show_all_if_less_than() {return show_all_if_less_than;} public void Show_all_if_less_than_(int v) {show_all_if_less_than = v;} private int show_all_if_less_than = Dflt_show_all_if_less_than;
public byte[] Html_fmt() {return html_fmt;} private byte[] html_fmt = Dflt_html_fmt;
public byte[] Html_fmt_dflt() {return html_fmt_dflt;} private byte[] html_fmt_dflt = Dflt_html_fmt;
public int Win_show_delay() {return win_show_delay;} private int win_show_delay = Dflt_win_show_delay;
public int Win_hide_delay() {return win_hide_delay;} private int win_hide_delay = Dflt_win_hide_delay;
public int Win_max_w() {return win_max_w;} private int win_max_w = Dflt_win_max_w;
public int Win_max_h() {return win_max_h;} private int win_max_h = Dflt_win_max_h;
public int Win_show_all_max_w() {return win_show_all_max_w;} private int win_show_all_max_w = Dflt_win_show_all_max_w;
public boolean Win_bind_focus_blur() {return win_bind_focus_blur;} private boolean win_bind_focus_blur = Dflt_win_bind_focus_blur;
public byte[] Xnde_ignore_ids() {return xnde_ignore_ids;} private byte[] xnde_ignore_ids = Dflt_coordinates;
public int Scan_len() {return scan_len;} private int scan_len = Dflt_scan_len;
public int Scan_max() {return scan_max;} private int scan_max = Dflt_scan_max;
public byte[] Ns_allowed() {return ns_allowed;} private byte[] ns_allowed = Dflt_ns_allowed;
public int Read_til_stop_fwd() {return read_til_stop_fwd;} private int read_til_stop_fwd = Dflt_read_til_stop_fwd;
public int Read_til_stop_bwd() {return read_til_stop_bwd;} private int read_til_stop_bwd = Dflt_read_til_stop_bwd;
public int Tmpl_tkn_max() {return tmpl_tkn_max;} private int tmpl_tkn_max = Dflt_tmpl_tkn_max;
public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled = true;
public int Show_init_word_count() {return show_init_word_count;} private int show_init_word_count = Dflt_show_init_word_count;
public int Show_more_word_count() {return show_more_word_count;} private int show_more_word_count = Dflt_show_more_word_count;
public int Show_all_if_less_than() {return show_all_if_less_than;} private int show_all_if_less_than = Dflt_show_all_if_less_than;
public int Win_show_delay() {return win_show_delay;} private int win_show_delay = Dflt_win_show_delay;
public int Win_hide_delay() {return win_hide_delay;} private int win_hide_delay = Dflt_win_hide_delay;
public int Win_max_w() {return win_max_w;} private int win_max_w = Dflt_win_max_w;
public int Win_max_h() {return win_max_h;} private int win_max_h = Dflt_win_max_h;
public int Win_show_all_max_w() {return win_show_all_max_w;} private int win_show_all_max_w = Dflt_win_show_all_max_w;
public boolean Win_bind_focus_blur() {return win_bind_focus_blur;} private boolean win_bind_focus_blur = Dflt_win_bind_focus_blur;
public byte[] Xnde_ignore_ids() {return xnde_ignore_ids;} private byte[] xnde_ignore_ids = Dflt_xnde_ignore_ids;
public int Scan_len() {return scan_len;} private int scan_len = Dflt_scan_len;
public int Scan_max() {return scan_max;} private int scan_max = Dflt_scan_max;
public byte[] Ns_allowed() {return ns_allowed;} private byte[] ns_allowed = Dflt_ns_allowed;
public int Read_til_stop_fwd() {return read_til_stop_fwd;} private int read_til_stop_fwd = Dflt_read_til_stop_fwd;
public int Read_til_stop_bwd() {return read_til_stop_bwd;} private int read_til_stop_bwd = Dflt_read_til_stop_bwd;
public int Stop_if_hdr_after() {return stop_if_hdr_after;} private int stop_if_hdr_after = Dflt_stop_if_hdr_after;
public int Tmpl_tkn_max() {return tmpl_tkn_max;} private int tmpl_tkn_max = Dflt_tmpl_tkn_max;
public byte[] Tmpl_keeplist() {return tmpl_keeplist;} private byte[] tmpl_keeplist = Dflt_tmpl_keeplist;
public byte[] Html_fmtr_popup() {return html_fmtr_popup;} private byte[] html_fmtr_popup = Dflt_html_fmtr_popup;
public byte[] Html_fmtr_popup_dflt() {return html_fmtr_popup_dflt;} private byte[] html_fmtr_popup_dflt = Dflt_html_fmtr_popup;
public byte[] Html_fmtr_viewed() {return html_fmtr_viewed;} private byte[] html_fmtr_viewed = Dflt_html_fmtr_viewed;
public byte[] Html_fmtr_viewed_dflt() {return html_fmtr_viewed_dflt;} private byte[] html_fmtr_viewed_dflt = Dflt_html_fmtr_viewed;
public byte[] Html_fmtr_wiki() {return html_fmtr_wiki;} private byte[] html_fmtr_wiki = Dflt_html_fmtr_wiki;
public byte[] Html_fmtr_wiki_dflt() {return html_fmtr_wiki_dflt;} private byte[] html_fmtr_wiki_dflt = Dflt_html_fmtr_wiki;
public byte[] Html_fmtr_next_sect_fmt() {return html_fmtr_next_sect;} private byte[] html_fmtr_next_sect = Dflt_html_fmtr_next_sect;
public byte[] Html_fmtr_next_sect_fmt_dflt() {return html_fmtr_next_sect_dflt;} private byte[] html_fmtr_next_sect_dflt = Dflt_html_fmtr_next_sect;
public void Show_more(String popup_id) {
Xow_wiki wiki = app.Gui_mgr().Browser_win().Active_tab().Page().Wiki();
wiki.Html_mgr().Module_mgr().Popup_mgr().Show_more(popup_id);
@ -80,18 +88,34 @@ public class Xoapi_popups implements GfoInvkAble, GfoEvMgrOwner {
else if (ctx.Match(k, Invk_scan_len_)) {scan_len = Set_int_gt_0(m, scan_len, Evt_scan_len_changed);}
else if (ctx.Match(k, Invk_scan_max)) return scan_max;
else if (ctx.Match(k, Invk_scan_max_)) {scan_max = Set_int_gt_0(m, scan_max, Evt_scan_max_changed);}
else if (ctx.Match(k, Invk_html_fmt)) return String_.new_utf8_(html_fmt);
else if (ctx.Match(k, Invk_html_fmt_)) {html_fmt = m.ReadBry("v"); GfoEvMgr_.PubVal(this, Evt_html_fmt_changed, html_fmt);}
else if (ctx.Match(k, Invk_html_fmt_dflt)) return String_.new_utf8_(html_fmt_dflt);
else if (ctx.Match(k, Invk_html_fmt_dflt_)) {html_fmt_dflt = m.ReadBry("v");}
else if (ctx.Match(k, Invk_read_til_stop_fwd)) return read_til_stop_fwd;
else if (ctx.Match(k, Invk_read_til_stop_fwd_)) {read_til_stop_fwd = m.ReadInt("v"); GfoEvMgr_.PubVal(this, Evt_read_til_stop_fwd_changed, read_til_stop_fwd);}
else if (ctx.Match(k, Invk_read_til_stop_bwd)) return read_til_stop_bwd;
else if (ctx.Match(k, Invk_read_til_stop_bwd_)) {read_til_stop_bwd = m.ReadInt("v"); GfoEvMgr_.PubVal(this, Evt_read_til_stop_bwd_changed, read_til_stop_bwd);}
else if (ctx.Match(k, Invk_stop_if_hdr_after)) return stop_if_hdr_after;
else if (ctx.Match(k, Invk_stop_if_hdr_after_)) {stop_if_hdr_after = m.ReadInt("v"); GfoEvMgr_.PubVal(this, Evt_stop_if_hdr_after_changed, stop_if_hdr_after);}
else if (ctx.Match(k, Invk_ns_allowed)) return String_.new_utf8_(ns_allowed);
else if (ctx.Match(k, Invk_ns_allowed_)) {ns_allowed = m.ReadBry("v"); GfoEvMgr_.PubVal(this, Evt_ns_allowed_changed, ns_allowed);}
else if (ctx.Match(k, Invk_tmpl_tkn_max)) return tmpl_tkn_max;
else if (ctx.Match(k, Invk_tmpl_tkn_max_)) {tmpl_tkn_max = m.ReadInt("v"); GfoEvMgr_.PubVal(this, Evt_tmpl_tkn_max_changed, tmpl_tkn_max);}
else if (ctx.Match(k, Invk_tmpl_tkn_max)) return tmpl_tkn_max;
else if (ctx.Match(k, Invk_tmpl_tkn_max_)) {tmpl_tkn_max = m.ReadInt("v"); GfoEvMgr_.PubVal(this, Evt_tmpl_tkn_max_changed, tmpl_tkn_max);}
else if (ctx.Match(k, Invk_tmpl_keeplist)) return String_.new_utf8_(tmpl_keeplist);
else if (ctx.Match(k, Invk_tmpl_keeplist_)) {tmpl_keeplist = m.ReadBry("v"); GfoEvMgr_.PubVal(this, Evt_tmpl_keeplist_changed, tmpl_keeplist);}
else if (ctx.Match(k, Invk_html_fmtr_popup)) return String_.new_utf8_(html_fmtr_popup);
else if (ctx.Match(k, Invk_html_fmtr_popup_)) {html_fmtr_popup = m.ReadBry("v"); GfoEvMgr_.PubVal(this, Evt_html_fmtr_popup_changed, html_fmtr_popup);}
else if (ctx.Match(k, Invk_html_fmtr_popup_dflt)) return String_.new_utf8_(html_fmtr_popup_dflt);
else if (ctx.Match(k, Invk_html_fmtr_popup_dflt_)) {html_fmtr_popup_dflt = m.ReadBry("v");}
else if (ctx.Match(k, Invk_html_fmtr_viewed)) return String_.new_utf8_(html_fmtr_viewed);
else if (ctx.Match(k, Invk_html_fmtr_viewed_)) {html_fmtr_viewed = m.ReadBry("v"); GfoEvMgr_.PubVal(this, Evt_html_fmtr_viewed_changed, html_fmtr_viewed);}
else if (ctx.Match(k, Invk_html_fmtr_viewed_dflt)) return String_.new_utf8_(html_fmtr_viewed_dflt);
else if (ctx.Match(k, Invk_html_fmtr_viewed_dflt_)) {html_fmtr_viewed_dflt = m.ReadBry("v");}
else if (ctx.Match(k, Invk_html_fmtr_wiki)) return String_.new_utf8_(html_fmtr_wiki);
else if (ctx.Match(k, Invk_html_fmtr_wiki_)) {html_fmtr_wiki = m.ReadBry("v"); GfoEvMgr_.PubVal(this, Evt_html_fmtr_wiki_changed, html_fmtr_wiki);}
else if (ctx.Match(k, Invk_html_fmtr_wiki_dflt)) return String_.new_utf8_(html_fmtr_wiki_dflt);
else if (ctx.Match(k, Invk_html_fmtr_wiki_dflt_)) {html_fmtr_wiki_dflt = m.ReadBry("v");}
else if (ctx.Match(k, Invk_html_fmtr_next_sect)) return String_.new_utf8_(html_fmtr_next_sect);
else if (ctx.Match(k, Invk_html_fmtr_next_sect_)) {html_fmtr_next_sect = m.ReadBry("v"); GfoEvMgr_.PubVal(this, Evt_html_fmtr_next_sect_changed, html_fmtr_next_sect);}
else if (ctx.Match(k, Invk_html_fmtr_next_sect_dflt)) return String_.new_utf8_(html_fmtr_next_sect_dflt);
else if (ctx.Match(k, Invk_html_fmtr_next_sect_dflt_)) {html_fmtr_next_sect_dflt = m.ReadBry("v");}
else return GfoInvkAble_.Rv_unhandled;
return this;
}
@ -115,8 +139,14 @@ public class Xoapi_popups implements GfoInvkAble, GfoEvMgrOwner {
, Invk_scan_len = "scan_len", Invk_scan_len_ = "scan_len_"
, Invk_scan_max = "scan_max", Invk_scan_max_ = "scan_max_"
, Invk_show_more = "show_more", Invk_show_all = "show_all"
, Invk_html_fmt = "html_fmt", Invk_html_fmt_ = "html_fmt_"
, Invk_html_fmt_dflt = "html_fmt_dflt", Invk_html_fmt_dflt_ = "html_fmt_dflt_"
, Invk_html_fmtr_popup = "html_fmtr_popup" , Invk_html_fmtr_popup_ = "html_fmtr_popup"
, Invk_html_fmtr_viewed = "html_fmtr_viewed" , Invk_html_fmtr_viewed_ = "html_fmtr_viewed_"
, Invk_html_fmtr_wiki = "html_fmtr_wiki" , Invk_html_fmtr_wiki_ = "html_fmtr_wiki_"
, Invk_html_fmtr_next_sect = "html_fmtr_next_sect" , Invk_html_fmtr_next_sect_ = "html_fmtr_next_sect_"
, Invk_html_fmtr_popup_dflt = "html_fmtr_popup_dflt" , Invk_html_fmtr_popup_dflt_ = "html_fmtr_popup_dflt_"
, Invk_html_fmtr_viewed_dflt = "html_fmtr_viewed_dflt" , Invk_html_fmtr_viewed_dflt_ = "html_fmtr_viewed_dflt_"
, Invk_html_fmtr_wiki_dflt = "html_fmtr_wiki_dflt" , Invk_html_fmtr_wiki_dflt_ = "html_fmtr_wiki_dflt_"
, Invk_html_fmtr_next_sect_dflt = "html_fmtr_next_sect_dflt" , Invk_html_fmtr_next_sect_dflt_ = "html_fmtr_next_sect_dflt_"
, Invk_win_show_delay = "win_show_delay", Invk_win_show_delay_ = "win_show_delay_"
, Invk_win_hide_delay = "win_hide_delay", Invk_win_hide_delay_ = "win_hide_delay_"
, Invk_win_bind_focus_blur = "win_bind_focus_blur", Invk_win_bind_focus_blur_ = "win_bind_focus_blur_"
@ -125,8 +155,10 @@ public class Xoapi_popups implements GfoInvkAble, GfoEvMgrOwner {
, Invk_win_show_all_max_w = "win_show_all_max_w", Invk_win_show_all_max_w_ = "win_show_all_max_w_"
, Invk_read_til_stop_fwd = "read_til_stop_fwd", Invk_read_til_stop_fwd_ = "read_til_stop_fwd_"
, Invk_read_til_stop_bwd = "read_til_stop_bwd", Invk_read_til_stop_bwd_ = "read_til_stop_bwd_"
, Invk_stop_if_hdr_after = "stop_if_hdr_after", Invk_stop_if_hdr_after_ = "stop_if_hdr_after_"
, Invk_ns_allowed = "ns_allowed", Invk_ns_allowed_ = "ns_allowed_"
, Invk_tmpl_tkn_max = "tmpl_tkn_max", Invk_tmpl_tkn_max_ = "tmpl_tkn_max_"
, Invk_tmpl_keeplist = "tmpl_keeplist", Invk_tmpl_keeplist_ = "tmpl_keeplist_"
;
public static final String
Evt_show_init_word_count_changed = "show_init_word_count_changed"
@ -139,23 +171,29 @@ public class Xoapi_popups implements GfoInvkAble, GfoEvMgrOwner {
, Evt_xnde_ignore_ids_changed = "xnde_ignore_ids_changed"
, Evt_scan_len_changed = "scan_len_changed"
, Evt_scan_max_changed = "scan_max_changed"
, Evt_html_fmt_changed = "html_fmt_changed"
, Evt_read_til_stop_fwd_changed = "read_til_stop_fwd_changed"
, Evt_read_til_stop_bwd_changed = "read_til_stop_bwd_changed"
, Evt_stop_if_hdr_after_changed = "stop_if_hdr_after_changed"
, Evt_ns_allowed_changed = "ns_allowed_changed"
, Evt_tmpl_tkn_max_changed = "tmpl_tkn_max_changed"
, Evt_tmpl_keeplist_changed = "tmpl_keeplist"
, Evt_html_fmtr_popup_changed = "html_fmtr_popup_changed"
, Evt_html_fmtr_viewed_changed = "html_fmtr_viewed_changed"
, Evt_html_fmtr_wiki_changed = "html_fmtr_wiki_changed"
, Evt_html_fmtr_next_sect_changed = "html_fmtr_next_sect_changed"
;
public static final byte[]
Dflt_coordinates = Bry_.new_ascii_("coordinates")
, Dflt_html_fmt = Bry_.new_ascii_(String_.Concat_lines_nl_skip_last
Dflt_xnde_ignore_ids = Bry_.new_ascii_("coordinates")
, Dflt_tmpl_keeplist = Bry_.new_ascii_("en.wikipedia.org|formatnum;age_in_days;as_of;gregorian_serial_date;currentminute;currentsecond;dmca;spaced_ndash;trim;month*;convert*;worldpop*;ipa*;lang*;nowrap*;h:*;vgy;iso_639_name;transl;translate;linktext;zh;nihongo;japanese_name;ko-hhrm;|\n")
, Dflt_html_fmtr_popup = Bry_.new_ascii_(String_.Concat_lines_nl_skip_last
( "<div dir=~{page_lang_ltr}>"
, " <div>~{content}"
, " </div>"
, " <hr/>"
, " <div>"
, " <span class='data_val'><b>~{page_title}</b></span>~{wiki_item}"
, " <span class='data_key'>~{<>msgs.get('api-xowa.html.modules.popups.msgs.size-name');<>}:</span><span class='data_val'>~{page_size}</span>"
, " <span class='data_key'>~{<>msgs.get('api-xowa.html.modules.popups.msgs.edited-name');<>}:</span><span class='data_val'>~{edit_time}</span>~{view_time_item}"
, " <span class='data_key'>~{<>msgs.get('api-xowa.html.modules.popups.msgs.size-name');<>}</span><span class='data_val'>~{page_size}</span>"
, " <span class='data_key'>~{<>msgs.get('api-xowa.html.modules.popups.msgs.edited-name');<>}</span><span class='data_val'>~{edit_time}</span>~{view_time_item}"
, " </div>"
, " <hr/>"
, " <div style='float:bottom;'>"
@ -165,28 +203,38 @@ public class Xoapi_popups implements GfoInvkAble, GfoEvMgrOwner {
, " <span><a href='xowa-cmd:xowa.api.usr.bookmarks.add(\"~{page_url}\");' title='~{<>msgs.get('api-xowa.usr.bookmarks.add-name');<>}'><img src='~{xowa_root_dir}user/anonymous/app/img/window/menu/bookmarks/add.png'></a></span>"
, " <span><a href='xowa-cmd:xowa.api.html.modules.popups.show_more(\"~{popup_id}\");' title='~{<>msgs.get('api-xowa.html.modules.popups.show_more-tip');<>}'><img src='~{xowa_root_dir}bin/any/xowa/html/modules/xowa.popups/imgs/show_more.png'></a></span>"
, " <span><a href='xowa-cmd:xowa.api.html.modules.popups.show_all (\"~{popup_id}\");' title='~{<>msgs.get('api-xowa.html.modules.popups.show_all-tip');<>}'> <img src='~{xowa_root_dir}bin/any/xowa/html/modules/xowa.popups/imgs/show_all.png' ></a></span>"
, " <span><a href='/wiki/Special:XowaPopupHistory' title='~{<>msgs.get('api-xowa.html.modules.popups.history-tip');<>}'><img src='~{xowa_root_dir}user/anonymous/app/img/window/menu/history/show.png'></a></span>"
, " <span><a href='xowa-cmd:xowa.api.gui.browser.tabs.new_link__at_dflt__focus_y(\"home/wiki/Help:Options/Popups\");' title='~{<>msgs.get('api-xowa.nav.cfg.main-name');<>}'><img src='~{xowa_root_dir}user/anonymous/app/img/window/menu/tools/options.png'></a></span>"
, " </div>"
, "</div>"
))
, Dflt_html_fmtr_viewed = Bry_.new_ascii_("\n <span class='data_key'>~{<>msgs.get('api-xowa.html.modules.popups.msgs.view_time-name');<>}</span><span class='data_val'>~{viewed_val}</span>")
, Dflt_html_fmtr_wiki = Bry_.new_ascii_("\n <span class='data_key'>~{<>msgs.get('api-xowa.html.modules.popups.msgs.wiki-name');<>}</span><span class='data_val'>~{wiki_val}</span>")
, Dflt_html_fmtr_next_sect = Bry_.new_ascii_("\n\n<span class='next_sect'>~{<>msgs.get('api-xowa.html.modules.popups.msgs.next_sect-name');<>}~{next_sect_val}</span>")
;
public static final String[]
Dflt_html_fmtr_popup_keys = String_.Ary("content", "page_lang_ltr", "page_url", "page_title", "popup_id", "wiki_item", "page_size", "edit_time", "view_time_item", "xowa_root_dir")
, Dflt_html_fmtr_viewed_keys = String_.Ary("viewed_val")
, Dflt_html_fmtr_wiki_keys = String_.Ary("wiki_val")
, Dflt_html_fmtr_next_sect_keys = String_.Ary("next_sect_val")
;
public static final String[] Dflt_html_fmt_keys = String_.Ary("content", "page_lang_ltr", "page_url", "page_title", "wiki_domain", "wiki_item", "page_size", "edit_time", "view_time_item", "xowa_root_dir", "popup_id");
public static final byte[]
Dflt_ns_allowed = Bry_.Empty
;
public static final int
Dflt_show_init_word_count = 64
, Dflt_show_more_word_count = 64
Dflt_show_init_word_count = 128
, Dflt_show_more_word_count = 192
, Dflt_show_all_if_less_than = -1
, Dflt_show_all_win_max_w = -1
, Dflt_win_show_delay = 400, Dflt_win_hide_delay = 400
, Dflt_win_show_delay = 600, Dflt_win_hide_delay = 600
, Dflt_win_max_w = -1, Dflt_win_max_h = -1
, Dflt_win_show_all_max_w = -1
, Dflt_win_show_all_max_w = 800
, Dflt_scan_len = 1 * Io_mgr.Len_kb
, Dflt_scan_max = 32 * Io_mgr.Len_kb
, Dflt_read_til_stop_fwd = -1
, Dflt_read_til_stop_bwd = -1
, Dflt_tmpl_tkn_max = 8192
, Dflt_read_til_stop_fwd = 32
, Dflt_read_til_stop_bwd = 16
, Dflt_stop_if_hdr_after = 96
, Dflt_tmpl_tkn_max = 8 * Io_mgr.Len_kb
;
public static final boolean
Dflt_win_bind_focus_blur = false

View File

@ -37,7 +37,12 @@ public class Xoa_gfs_mgr implements GfoInvkAble, GfoInvkRootWkr {
else if (String_.Eq(type, "xowa_user_cfg")) url = fsys_mgr.App_data_cfg_user_fil();
else if (String_.Eq(type, "xowa")) url = app.Fsys_mgr().Root_dir().GenSubFil("xowa.gfs");
else throw Err_mgr._.fmt_(GRP_KEY, "invalid_gfs_type", "invalid gfs type: ~{0}", type);
Run_url(url);
try {Run_url(url);}
catch (Exception e) { // gfs is corrupt; may happen if multiple XOWAs opened, and "Close all" chosen in OS; DATE:2014-07-01
if (!String_.Eq(type, "xowa")) // check if user.gfs
Io_mgr._.MoveFil(url, url.GenNewNameOnly(url.NameOnly() + "-" + DateAdp_.Now().XtoStr_fmt_yyyyMMdd_HHmmss())); // move file
app.Usr_dlg().Warn_many("", "", "invalid gfs; obsoleting: src=~{0} err=~{1}", url.Raw(), Err_.Message_gplx(e));
}
}
public GfoMsg Parse_root_msg(String v) {return gplx.gfs.Gfs_msg_bldr._.ParseToMsg(v);}
public Gfs_wtr Wtr() {return wtr;} private Gfs_wtr wtr = new Gfs_wtr();

View File

@ -28,14 +28,14 @@ public class Xoa_ttl__i18n_tst {
fxt.Init_ttl("&#x2c65;").Expd_full_txt("").Test();
}
@Test public void First_char_is_multi_byte() { // PURPOSE: if multi-byte, uppercasing is complicated; EX: µ -> Μ; DATE:2013-11-27
fxt.Wiki().Lang().Case_mgr().Add_bulk(Xol_case_itm_.Universal);
fxt.Wiki().Lang().Case_mgr_utf8_();
fxt.Init_ttl("µ").Expd_full_txt("Μ").Test(); // NOTE: this is not an ASCII "Μ"
fxt.Init_ttl("µab").Expd_full_txt("Μab").Test(); // check that rest of title works fine
fxt.Init_ttl("Help:µab").Expd_full_txt("Help:Μab").Test(); // check ns
fxt.Init_ttl("Ι").Expd_full_txt("Ι").Test(); // check that Ι is not upper-cased to COMBINING GREEK YPOGEGRAMMENI; DATE:2014-02-24
}
@Test public void First_char_is_multi_byte_assymetrical() { // PURPOSE: test multi-byte asymmetry (lc is 3 bytes; uc is 2 bytes)
fxt.Wiki().Lang().Case_mgr().Add_bulk(Xol_case_itm_.Universal);
fxt.Wiki().Lang().Case_mgr_utf8_();
fxt.Init_ttl("").Expd_full_txt("Ⱥ").Test();
fxt.Init_ttl("ⱥab").Expd_full_txt("Ⱥab").Test(); // check that rest of title works fine
fxt.Init_ttl("Help:ⱥab").Expd_full_txt("Help:Ⱥab").Test(); // check ns

View File

@ -56,7 +56,7 @@ public class Xob_lnki_temp_wkr extends Xob_dump_mgr_base implements Xop_lnki_log
property_wkr = this.Property_wkr(); // set member reference
property_wkr = log_mgr.Make_wkr_property();
wiki.App().Wiki_mgr().Wdata_mgr().Enabled_(wdata_enabled);
if (!xtn_ref_enabled) gplx.xowa.xtns.refs.References_nde.Enabled = false;
if (!xtn_ref_enabled) gplx.xowa.xtns.cite.References_nde.Enabled = false;
gplx.xowa.xtns.gallery.Gallery_xnde.Log_wkr = log_mgr.Make_wkr().Save_src_str_(Bool_.Y);
gplx.xowa.xtns.imageMap.Xop_imageMap_xnde.Log_wkr = log_mgr.Make_wkr();
gplx.xowa.Xop_xnde_wkr.Timeline_log_wkr = log_mgr.Make_wkr();

View File

@ -27,7 +27,7 @@ public class Xob_init_base_tst {
app.User().Wiki().Xwiki_mgr().Add_full("en.wikipedia.org", "en.wikipedia.org");
Tfds.Eq("", wikis_list.Itms_as_html()); // still empty
new Xob_init_txt(app.Bldr(), wiki).Cmd_end(); // mock "init" task
Tfds.Eq("\n <li><a href=\"/site/en.wikipedia.org/\">en.wikipedia.org</a></li>", wikis_list.Itms_as_html()); // no longer empty
Tfds.Eq("\n <li><a href=\"/site/en.wikipedia.org/\" class='xowa-hover-off'>en.wikipedia.org</a></li>", wikis_list.Itms_as_html()); // no longer empty
}
}
class Xob_init_base_fxt {

View File

@ -78,7 +78,7 @@ public class Xol_mw_lang_parser_tst {
;
}
@Test public void Xtn_keywords_fr() {fxt.Parse_xtn("$magicWords['fr'] = array('if' => array(0, 'si' ));").Tst_parse("{{si:|y|n}}", "n");}
@Test public void Xtn_keywords_de() {fxt.Parse_xtn("$magicWords['de'] = array('if' => array(0, 'si' ));").Tst_parse("{{si:|y|n}}", "<a href=\"/wiki/Template:si:\">Template:si:</a>");}
@Test public void Xtn_keywords_de() {fxt.Parse_xtn("$magicWords['de'] = array('if' => array(0, 'si' ));").Tst_parse("{{si:|y|n}}", "<a href=\"/wiki/Template:Si:\">Template:Si:</a>");} // should be "Si", not "si"; ALSO, should probably be "{{si:|y|n}}" not "[[:Template:si:]]" DATE:2014-07-04
@Test public void Core_messages() {
fxt.Parse_core("$messages = array('sunday' => 'dimanche');")
.Tst_message("sunday", 0, "dimanche", false)

View File

@ -23,7 +23,7 @@ public class Xob_xml_parser_tst {
Io_mgr._.InitEngine_mem();
Xoa_app app = Xoa_app_fxt.app_();
bldr = new Xob_bldr(app);
} private Xow_ns_mgr ns_mgr = Xow_ns_mgr_.default_();
} private Xow_ns_mgr ns_mgr = Xow_ns_mgr_.default_(gplx.xowa.langs.cases.Xol_case_mgr_.Ascii());
@Test public void Basic_docs_1() {
Xodb_page doc = doc_(1, "a", "a a", Date_1);
fil = page_bldr.Add(doc).XtoByteStreamRdr();

View File

@ -0,0 +1,106 @@
/*
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.cfgs.gui; import gplx.*; import gplx.xowa.*; import gplx.xowa.cfgs.*;
class Test_api implements GfoInvkAble {
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_meta)) return meta_mgr.Get_or_null(m.ReadStr("v"));
else return GfoInvkAble_.Rv_unhandled;
// return this;
} private static final String Invk_meta = "meta";
private static final String Invk_prop_1 = "prop_1", Invk_prop_2 = "prop_2", Invk_prop_3 = "prop_3", Invk_prop_bry = "bry", Invk_prop_enm = "enm";
private static final boolean Dflt_prop_1 = false;
private static final int Dflt_prop_2 = 2;
private static final String Dflt_prop_3 = "3";
private static final byte[] Dflt_prop_bry = Bry_.new_ascii_("bry");
private static final int Dflt_prop_enm = 5;
private static final Xocfg_meta_mgr meta_mgr = new Xocfg_meta_mgr().Add
( Xocfg_meta_itm_.bool_ (Invk_prop_1, Dflt_prop_1)
, Xocfg_meta_itm_.int_ (Invk_prop_2, Dflt_prop_2).Rng_bgn_(-1)
, Xocfg_meta_itm_.str_ (Invk_prop_3, Dflt_prop_3)
, Xocfg_meta_itm_.bry_ (Invk_prop_bry, Dflt_prop_bry)
, Xocfg_meta_itm_.enm_ (Invk_prop_enm, Dflt_prop_enm).Itms_list_("a", "b", "c")
, Xocfg_meta_itm_.str_ (Invk_prop_3, Dflt_prop_3).Gui_itm_(Xocfg_gui_itm_.memo_(40, 60))
// , Xocfg_meta_itm_.enum_ (Invk_prop_3, Dflt_prop_3).Add("a", "b").Add("b", "c").Data(Xocfg_gui.list("a"))
)
;
}
interface Xocfg_gui_itm {
}
class Xocfg_gui_itm_ {
public static Xocfg_gui_itm_memo memo_(int box_w, int box_h) {return new Xocfg_gui_itm_memo(box_w, box_h);}
}
class Xocfg_gui_itm_fld {
}
class Xocfg_gui_itm_memo implements Xocfg_gui_itm {
public Xocfg_gui_itm_memo(int box_w, int box_h) {this.box_w = box_w; this.box_h = box_h;}
public int Box_w() {return box_w;} private int box_w;
public int Box_h() {return box_h;} private int box_h;
}
class Xocfg_meta_mgr {
private HashAdp hash = HashAdp_.new_();
public Xocfg_meta_mgr Add(Xocfg_meta_itm_base... ary) {
int len = ary.length;
for (int i = 0; i < len; i++) {
Xocfg_meta_itm_base itm = (Xocfg_meta_itm_base)ary[i];
hash.Add(itm.Prop_key(), itm);
}
return this;
}
public Xocfg_meta_itm_base Get_or_null(String key) {return (Xocfg_meta_itm_base)hash.Fetch(key);}
}
abstract class Xocfg_meta_itm_base {
public void Set(int prop_type, String prop_key, Object prop_dflt) {
this.prop_key = prop_key; this.prop_type = prop_type; this.prop_dflt = prop_dflt;
}
public String Prop_key() {return prop_key;} private String prop_key;
public Object Prop_dflt() {return prop_dflt;} private Object prop_dflt;
public int Prop_type() {return prop_type;} private int prop_type;
}
class Xocfg_meta_itm_ {
public static Xocfg_meta_itm_bool bool_(String key, boolean dflt) {return new Xocfg_meta_itm_bool(key, dflt);}
public static Xocfg_meta_itm_int int_(String key, int dflt) {return new Xocfg_meta_itm_int(key, dflt);}
public static Xocfg_meta_itm_str str_(String key, String dflt) {return new Xocfg_meta_itm_str(key, dflt);}
public static Xocfg_meta_itm_bry bry_(String key, byte[] dflt) {return new Xocfg_meta_itm_bry(key, dflt);}
public static Xocfg_meta_itm_enm enm_(String key, int dflt) {return new Xocfg_meta_itm_enm(key, dflt);}
}
class Xodfg_pref_itm_type_ {
public static final int Tid_bool = 1, Tid_int = 2, Tid_str = 3, Tid_bry = 4, Tid_enm = 5;
}
class Xocfg_meta_itm_bool extends Xocfg_meta_itm_base {
public Xocfg_meta_itm_bool(String prop_key, boolean prop_dflt) {this.Set(Xodfg_pref_itm_type_.Tid_bool, prop_key, prop_dflt);}
}
class Xocfg_meta_itm_int extends Xocfg_meta_itm_base {
public Xocfg_meta_itm_int(String prop_key, int prop_dflt) {this.Set(Xodfg_pref_itm_type_.Tid_int, prop_key, prop_dflt);}
public Xocfg_meta_itm_int Rng_bgn_(int bgn) {return Rng_(bgn, Int_.MaxValue);}
public Xocfg_meta_itm_int Rng_(int bgn, int end) {
return this;
}
}
class Xocfg_meta_itm_str extends Xocfg_meta_itm_base {
public Xocfg_meta_itm_str(String prop_key, String prop_dflt) {this.Set(Xodfg_pref_itm_type_.Tid_str, prop_key, prop_dflt);}
public Xocfg_gui_itm Gui_itm() {return gui_itm;} public Xocfg_meta_itm_base Gui_itm_(Xocfg_gui_itm v) {gui_itm = v; return this;} private Xocfg_gui_itm gui_itm;
}
class Xocfg_meta_itm_bry extends Xocfg_meta_itm_base {
public Xocfg_meta_itm_bry(String prop_key, byte[] prop_dflt) {this.Set(Xodfg_pref_itm_type_.Tid_bry, prop_key, prop_dflt);}
}
class Xocfg_meta_itm_enm extends Xocfg_meta_itm_base {
public Xocfg_meta_itm_enm(String prop_key, int prop_dflt) {this.Set(Xodfg_pref_itm_type_.Tid_enm, prop_key, prop_dflt);}
public Xocfg_meta_itm_enm Itms_list_(String... ary) {
return this;
}
}

View File

@ -31,7 +31,7 @@ public class Xoctg_html_mgr implements GfoInvkAble {
Bld_html_v2(wiki, page, tmp_bfr);
else
Bld_html_v1(wiki, page, tmp_bfr);
bfr.Add_bfr(tmp_bfr.Mkr_rls());
bfr.Add_bfr_and_preserve(tmp_bfr.Mkr_rls());
}
catch (Exception e) { // ctg error should never cause page to fail
tmp_bfr.Mkr_rls();

View File

@ -21,7 +21,7 @@ class Xodb_ns_map_mgr {
public static Xodb_ns_map_mgr Parse(byte[] src) {
byte[][] lines = Bry_.Split(src, Byte_ascii.NewLine);
int lines_len = lines.length;
Xow_ns_mgr canonical_ns_mgr = Xow_ns_mgr_.default_();
Xow_ns_mgr canonical_ns_mgr = Xow_ns_mgr_.default_(gplx.xowa.langs.cases.Xol_case_mgr_.Ascii());
Xodb_ns_map_mgr rv = new Xodb_ns_map_mgr();
ListAdp itms = ListAdp_.new_();
for (int i = 0; i < lines_len; i++) {

View File

@ -93,6 +93,14 @@ public class Xow_file_mgr implements GfoInvkAble {
return xfer_itm.Atrs_calc_for_html();
}
}
public boolean Exists(byte[] ttl_bry) {
if (this.Version_1_y()) {
Xof_meta_itm meta = meta_mgr.Get_itm_or_new(ttl_bry);
return meta.Orig_exists() == Bool_.Y_byte || meta.Thumbs().length != 0;
}
else
return fsdb_mgr.Reg_select_itm_exists(ttl_bry);
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_repos)) return repo_mgr;

View File

@ -39,4 +39,5 @@ public interface Xof_fsdb_mgr extends RlsAble {
void Reg_insert(Xof_fsdb_itm itm, byte repo_id, byte status);
void Reg_select(Xoa_page page, byte exec_tid, ListAdp itms);
void Reg_select_only(Xoa_page page, byte exec_tid, ListAdp itms, OrderedHash hash);
boolean Reg_select_itm_exists(byte[] ttl);
}

View File

@ -93,6 +93,7 @@ public class Xof_fsdb_mgr_mem implements Xof_fsdb_mgr, Xof_bin_wkr {
}
Xof_fsdb_mgr_._.Fsdb_search(this, fs_dir, page, exec_tid, itms, bin_mgr.Repo_mgr(), url_bldr);
}
public boolean Reg_select_itm_exists(byte[] ttl) {return reg_hash.Has(ttl);}
public byte Bin_wkr_tid() {return Xof_bin_wkr_.Tid_fsdb_wiki;}
public gplx.ios.Io_stream_rdr Bin_wkr_get_as_rdr(ListAdp temp_files, Xof_fsdb_itm itm, boolean is_thumb, int w) {
byte[] wiki = itm.Orig_wiki();

View File

@ -80,6 +80,7 @@ public class Xof_fsdb_mgr_sql implements Xof_fsdb_mgr, GfoInvkAble {
bin_wkr_fsdb = new Xof_bin_wkr_fsdb_sql(this).Bin_bfr_len_(64 * Io_mgr.Len_kb); // most thumbs are 40 kb
cache_mgr = wiki.App().File_mgr().Cache_mgr();
} private boolean init = false;
public boolean Reg_select_itm_exists(byte[] ttl) {return Xof_wiki_orig_tbl.Select_itm_exists(img_regy_provider, ttl);}
public void Reg_select_only(Xoa_page page, byte exec_tid, ListAdp itms, OrderedHash hash) {
Xof_wiki_orig_tbl.Select_list(wiki.App().Usr_dlg(), img_regy_provider, exec_tid, itms, hash, url_bldr, bin_mgr.Repo_mgr());
}

View File

@ -52,8 +52,8 @@ public class Fs_root_fsdb_mgr implements Xof_fsdb_mgr, GfoInvkAble {
Js_img_mgr.Update_img(page, itm);
}
}
public void Reg_select_only(Xoa_page page, byte exec_tid, ListAdp itms, OrderedHash hash) {
}
public void Reg_select_only(Xoa_page page, byte exec_tid, ListAdp itms, OrderedHash hash) {}
public boolean Reg_select_itm_exists(byte[] ttl) {throw Err_.not_implemented_();}
public void Rls() {}
private Io_url Xto_url(byte[] v) {
if (Op_sys.Cur().Tid_is_wnt())

View File

@ -123,8 +123,8 @@ public class Xog_bnd_mgr {
Init_itm(Xog_cmd_itm_.Key_gui_page_view_mode_read , Xog_bnd_box_.Tid_browser , "mod.c+key.m,mod.c+key.r");
Init_itm(Xog_cmd_itm_.Key_gui_page_view_mode_edit , Xog_bnd_box_.Tid_browser , "mod.c+key.m,mod.c+key.e");
Init_itm(Xog_cmd_itm_.Key_gui_page_view_mode_html , Xog_bnd_box_.Tid_browser , "mod.c+key.m,mod.c+key.h");
Init_itm(Xog_cmd_itm_.Key_gui_page_view_reload , Xog_bnd_box_.Tid_browser , "key.f5");
Init_itm(Xog_cmd_itm_.Key_gui_page_view_refresh , Xog_bnd_box_.Tid_browser , "mod.s+key.f5");
Init_itm(Xog_cmd_itm_.Key_gui_page_view_reload , Xog_bnd_box_.Tid_browser , "mod.s+key.f5");
Init_itm(Xog_cmd_itm_.Key_gui_page_view_refresh , Xog_bnd_box_.Tid_browser , "key.f5");
Init_itm(Xog_cmd_itm_.Key_gui_page_view_save_as , Xog_bnd_box_.Tid_browser , "");
Init_itm(Xog_cmd_itm_.Key_gui_page_view_print , Xog_bnd_box_.Tid_browser , "");
@ -148,7 +148,7 @@ public class Xog_bnd_mgr {
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_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");
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");
Init_itm(Xog_cmd_itm_.Key_gui_browser_tabs_close_cur , Xog_bnd_box_.Tid_browser , "mod.c+key.w");
Init_itm(Xog_cmd_itm_.Key_gui_browser_tabs_close_others , Xog_bnd_box_.Tid_browser , "mod.cs+key.w,mod.cs+key.w");
Init_itm(Xog_cmd_itm_.Key_gui_browser_tabs_close_to_bgn , Xog_bnd_box_.Tid_browser , "mod.cs+key.w,mod.cs+key.left");
@ -172,6 +172,7 @@ public class Xog_bnd_mgr {
Init_itm(Xog_cmd_itm_.Key_gui_browser_html_focus , 2, Xog_bnd_box_.Tid_browser_search , "key.escape");
Init_itm(Xog_cmd_itm_.Key_gui_browser_html_focus , 3, Xog_bnd_box_.Tid_browser_prog , "key.escape");
Init_itm(Xog_cmd_itm_.Key_gui_browser_html_focus , 4, Xog_bnd_box_.Tid_browser_info , "key.escape");
Init_itm(Xog_cmd_itm_.Key_gui_browser_html_selection_focus_toggle , Xog_bnd_box_.Tid_browser , "mod.c+key.g,mod.c+key.g");
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");

View File

@ -103,6 +103,7 @@ public class Xog_cmd_itm_ {
, Key_gui_browser_tabs_close_undo = new_dflt_(Xog_ctg_itm_.Tid_tabs , "xowa.gui.browser.tabs.close_undo")
, Key_gui_browser_tabs_pin_toggle = new_dflt_(Xog_ctg_itm_.Tid_tabs , "xowa.gui.browser.tabs.pin_toggle")
, Key_gui_browser_html_focus = new_dflt_(Xog_ctg_itm_.Tid_browser , "xowa.gui.browser.html.focus")
, Key_gui_browser_html_selection_focus_toggle = new_dflt_(Xog_ctg_itm_.Tid_browser , "xowa.gui.browser.html.selection_focus_toggle")
, Key_gui_browser_find_show = new_dflt_(Xog_ctg_itm_.Tid_browser , "xowa.gui.browser.find.show")
, Key_gui_browser_find_show_by_paste = new_dflt_(Xog_ctg_itm_.Tid_browser , "xowa.gui.browser.find.show_by_paste")
, Key_gui_browser_find_hide = new_dflt_(Xog_ctg_itm_.Tid_browser , "xowa.gui.browser.find.hide")

View File

@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.gui.menus; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.xowa.gui.menus.dom.*;
public class Xog_menu_mgr implements GfoInvkAble {
private Xoa_app app;
public Xog_menu_mgr(Xoa_gui_mgr gui_mgr) {
menu_bldr = new Xog_mnu_bldr();
regy = new Xog_mnu_regy(gui_mgr);
@ -31,11 +32,16 @@ public class Xog_menu_mgr implements GfoInvkAble {
public void Init_by_app(Xoa_app app) {
this.app = app;
regy.Init_by_app(app);
} private Xoa_app app;
}
public void Init_by_kit() {
popup_mnu_mgr.Init_by_kit();
window_mnu_mgr.Init_by_kit();
Lang_changed(app.User().Lang());
try {
popup_mnu_mgr.Init_by_kit();
window_mnu_mgr.Init_by_kit();
Lang_changed(app.User().Lang());
}
catch (Exception e) { // ignore errors while loading custom menus, else fatal error; DATE:2014-07-01
app.Usr_dlg().Warn_many("", "", "error while loading menus; err=~{0}", Err_.Message_gplx(e));
}
}
public void Lang_changed(Xol_lang lang) {
window_mnu_mgr.Lang_changed(lang);

View File

@ -80,8 +80,12 @@ public class Xog_html_js_cbk implements GfoInvkAble {
return html_itm.Owner_tab().Page().Wiki().Html_mgr().Module_mgr().Popup_mgr().Show_init(href_bry, popups_id);
} catch (Exception e) {Err_.Noop(e); return null;}
}
private String[] Get_title_meta(Xow_wiki wiki, byte[] ttl) {
Pfunc_ifexist.Exists(tmp_page, wiki.Ctx(), ttl);
private String[] Get_title_meta(Xow_wiki wiki, byte[] ttl_bry) {
synchronized (tmp_page) {
tmp_page.Clear();
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ttl_bry);
wiki.Db_mgr().Load_mgr().Load_by_ttl(tmp_page, ttl.Ns(), ttl.Page_db());
}
return String_.Ary(tmp_page.Exists() ? "1" : "0", Int_.XtoStr(tmp_page.Id()), Int_.XtoStr(tmp_page.Ns_id()), String_.new_utf8_(tmp_page.Ttl_wo_ns()), Bool_.XtoStr_lower(tmp_page.Type_redirect()), tmp_page.Modified_on().XtoStr_fmt("yyyy-MM-dd HH:mm:ss"), Int_.XtoStr(tmp_page.Text_len()));
} private static final Xodb_page tmp_page = Xodb_page.tmp_();
private String[][] Get_titles_meta(GfoMsg m) {
@ -98,7 +102,7 @@ public class Xog_html_js_cbk implements GfoInvkAble {
} catch (Exception e) {Err_.Noop(e); return null;}
}
private boolean Get_title_exists(Xow_wiki wiki, byte[] ttl) {
return Pfunc_ifexist.Exists(tmp_page, wiki.Ctx(), ttl);
return Pfunc_ifexist.Exists(wiki, ttl);
}
private String[] Get_titles_exists(GfoMsg m) {
Xow_wiki wiki = html_itm.Owner_tab().Page().Wiki();

View File

@ -16,9 +16,9 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html; import gplx.*; import gplx.xowa.*;
import gplx.xowa.wikis.*; import gplx.xowa.net.*;
import gplx.html.*; import gplx.xowa.wikis.*; import gplx.xowa.net.*;
import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*;
import gplx.xowa.xtns.*; import gplx.xowa.xtns.dynamicPageList.*; import gplx.xowa.xtns.math.*; import gplx.xowa.langs.vnts.*; import gplx.xowa.xtns.refs.*;
import gplx.xowa.xtns.*; import gplx.xowa.xtns.dynamicPageList.*; import gplx.xowa.xtns.math.*; import gplx.xowa.langs.vnts.*; import gplx.xowa.xtns.cite.*;
public class Xoh_html_wtr {
private Xow_wiki wiki; private Xoa_app app; private Xoa_page page; private Xop_xatr_whitelist_mgr whitelist_mgr;
public Xoh_html_wtr(Xow_wiki wiki, Xow_html_mgr html_mgr) {
@ -583,9 +583,9 @@ public class Xoh_html_wtr {
break;
default:
byte[] tag_name = sub_xnde.Tag().Name_bry();
bfr.Add(Xop_xnde_wkr.Bry_escape_lt).Add(tag_name);
bfr.Add(Html_entity_.Lt_bry).Add(tag_name);
if (xnde.Atrs_bgn() > Xop_tblw_wkr.Atrs_ignore_check) Xnde_atrs(sub_xnde.Tag().Id(), hctx, src, sub_xnde.Atrs_bgn(), sub_xnde.Atrs_end(), xnde.Atrs_ary(), bfr);
bfr.Add(Xop_xnde_wkr.Bry_escape_gt);
bfr.Add(Html_entity_.Gt_bry);
break;
}
Xnde_subs_escape(ctx, hctx, bfr, src, sub_xnde, amp_enable, false);

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; import gplx.*; import gplx.xowa.*;
import gplx.xowa.parsers.amps.*;
import gplx.html.*; import gplx.xowa.parsers.amps.*;
public class Xoh_html_wtr_escaper {
public static byte[] Escape(Xoa_app app, Bry_bfr tmp_bfr, byte[] src) {
Escape(app, tmp_bfr, src, 0, src.length, true, false);
@ -40,17 +40,17 @@ public class Xoh_html_wtr_escaper {
}
}
}
bfr.Add(Xop_xnde_wkr.Bry_escape_lt);
bfr.Add(Html_entity_.Lt_bry);
break;
case Byte_ascii.Gt:
bfr.Add(Xop_xnde_wkr.Bry_escape_gt);
bfr.Add(Html_entity_.Gt_bry);
break;
case Byte_ascii.Amp:
if (interpret_amp) {
int text_bgn = i + 1; // i is &; i + 1 is first char after amp
Object o = (text_bgn < end) ? amp_trie.MatchAtCur(src, text_bgn, end) : null; // check if this is a valid &; note must check that text_bgn < end or else arrayIndex error; occurs when src is just "&"; DATE:2013-12-19
if (o == null) // invalid; EX: "a&b"; "&bad;"; "&#letters;";
bfr.Add(Xop_xnde_wkr.Bry_escape_amp); // escape & and continue
bfr.Add(Html_entity_.Amp_bry); // escape & and continue
else { // is either (1) a name or (2) an ncr (hex/dec)
Xop_amp_trie_itm itm = (Xop_amp_trie_itm)o;
int match_pos = amp_trie.Match_pos();
@ -67,15 +67,15 @@ public class Xoh_html_wtr_escaper {
i = end_pos - 1;
}
else // parse failed; escape and continue
bfr.Add(Xop_xnde_wkr.Bry_escape_amp);
bfr.Add(Html_entity_.Amp_bry);
}
}
}
else
bfr.Add(Xop_xnde_wkr.Bry_escape_amp);
bfr.Add(Html_entity_.Amp_bry);
break;
case Byte_ascii.Quote:
bfr.Add(Xop_xnde_wkr.Bry_escape_quote);
bfr.Add(Html_entity_.Quote_bry);
break;
default:
bfr.Add_byte(b);

View File

@ -35,7 +35,7 @@ public class Xoh_page_wtr_wkr_ {
public static void Bld_head_end(Bry_bfr html_bfr, Xoa_page page) {
byte[] head_end = page.Html_data().Custom_head_end();
if (head_end == null) return;
int insert_pos = Bry_finder.Find_fwd(html_bfr.Bfr(), Html_tags.Head_rhs);
int insert_pos = Bry_finder.Find_fwd(html_bfr.Bfr(), Html_tag_.Head_rhs);
if (insert_pos == Bry_finder.Not_found) {
page.App().Usr_dlg().Warn_many("", "", "could not find </head>");
return;
@ -45,7 +45,7 @@ public class Xoh_page_wtr_wkr_ {
public static void Bld_html_end(Bry_bfr html_bfr, Xoa_page page) {
byte[] html_end = page.Html_data().Custom_html_end();
if (html_end == null) return;
int insert_pos = Bry_finder.Find_bwd(html_bfr.Bfr(), Html_tags.Html_rhs, html_bfr.Len());
int insert_pos = Bry_finder.Find_bwd(html_bfr.Bfr(), Html_tag_.Html_rhs, html_bfr.Len());
if (insert_pos == Bry_finder.Not_found) {
page.App().Usr_dlg().Warn_many("", "", "could not find </html>");
return;

View File

@ -34,7 +34,7 @@ public class Xohp_title_wkr implements Bry_fmtr_arg {
if (tkn.Tkn_tid() == Xop_tkn_itm_.Tid_xnde) {
Xop_xnde_tkn xnde = (Xop_xnde_tkn)tkn;
if (xnde.Tag().Id() == Xop_xnde_tag_.Tid_ref) { // if ref, disable tkn
gplx.xowa.xtns.refs.Ref_nde ref_xnde = (gplx.xowa.xtns.refs.Ref_nde)xnde.Xnde_xtn();
gplx.xowa.xtns.cite.Ref_nde ref_xnde = (gplx.xowa.xtns.cite.Ref_nde)xnde.Xnde_xtn();
ref_xnde.Exists_in_lnki_title_(true); // ref found during html_title_wkr's generation; mark ref; will be ignored by references_html_wtr later; DATE:2014-03-05
}
}

View File

@ -33,7 +33,7 @@ public class Xoh_module_wtr {
public void Write_css_style_bgn() {
reset_bgn = bfr.Len();
Write_nl_and_indent();
bfr.Add(Html_tags.Style_lhs_w_type);
bfr.Add(Html_tag_.Style_lhs_w_type);
Indent_add();
reset_end = bfr.Len();
}
@ -41,7 +41,7 @@ public class Xoh_module_wtr {
Indent_del();
if (Reset()) return;
Write_nl_and_indent();
bfr.Add(Html_tags.Style_rhs);
bfr.Add(Html_tag_.Style_rhs);
}
public void Write_css_style_itm(byte[] bry) {
Write_nl_and_indent();
@ -54,7 +54,7 @@ public class Xoh_module_wtr {
public void Write_js_script_bgn() {
reset_bgn = bfr.Len();
Write_nl_and_indent();
bfr.Add(Html_tags.Script_lhs_w_type);
bfr.Add(Html_tag_.Script_lhs_w_type);
Indent_add();
reset_end = bfr.Len();
}
@ -62,7 +62,7 @@ public class Xoh_module_wtr {
Indent_del();
if (Reset()) return;
Write_nl_and_indent();
bfr.Add(Html_tags.Script_rhs);
bfr.Add(Html_tag_.Script_rhs);
}
public void Write_js_head_global_bgn() {
reset_bgn = bfr.Len();

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.xowa.html.modules.popups; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*;
public class Xopg_popup_mgr {
public OrderedHash Itms() {return itms;} private OrderedHash itms = OrderedHash_.new_();
public void Clear() {
itms.Clear();
}
}

View File

@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*;
import gplx.xowa.apis.xowa.html.modules.*;
public class Xow_popup_cfg {
public int Show_all_if_less_than() {return show_all_if_less_than;} public void Show_all_if_less_than_(int v) {show_all_if_less_than = v;} private int show_all_if_less_than = Xoapi_popups.Dflt_show_all_if_less_than;
public int Tmpl_read_max() {return tmpl_read_max;} public void Tmpl_read_max_(int v) {tmpl_read_max = v;} private int tmpl_read_max = Xoapi_popups.Dflt_scan_max;
public int Tmpl_read_len() {return tmpl_read_len;} public void Tmpl_read_len_(int v) {tmpl_read_len = v;} private int tmpl_read_len = Xoapi_popups.Dflt_scan_len;
public int Read_til_stop_fwd() {return read_til_stop_fwd;} public void Read_til_stop_fwd_(int v) {read_til_stop_fwd = v;} private int read_til_stop_fwd = Xoapi_popups.Dflt_read_til_stop_fwd;
public int Read_til_stop_bwd() {return read_til_stop_bwd;} public void Read_til_stop_bwd_(int v) {read_til_stop_bwd = v;} private int read_til_stop_bwd = Xoapi_popups.Dflt_read_til_stop_bwd;
public int Stop_if_hdr_after() {return stop_if_hdr_after;} public void Stop_if_hdr_after_(int v) {stop_if_hdr_after = v;} private int stop_if_hdr_after = Xoapi_popups.Dflt_stop_if_hdr_after;
public boolean Stop_if_hdr_after_enabled() {return stop_if_hdr_after > 0;}
public byte[] Ellipsis() {return ellipsis;} public void Ellipsis_(byte[] v) {ellipsis = v;} private byte[] ellipsis = Bry_.Empty;
public byte[] Notoc() {return notoc;} public void Notoc_(byte[] v) {notoc = v;} private byte[] notoc = Notoc_const;
public static final byte[]
Notoc_const = Bry_.new_ascii_("\n__NOTOC__") // NOTE: always add a whitespace tkn else __NOTOC__ will be deactivated if last tkn is lnke; DATE:2014-06-22
, Msg_key_ellipsis = Bry_.new_ascii_("ellipsis")
;
}

View File

@ -0,0 +1,49 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*;
class Xow_popup_hdr_finder {
private byte[] src, hdr;
private int src_len;
private int nl_pos;
public int Find(byte[] src, int src_len, byte[] hdr, int bgn) {
this.src = src; this.src_len = src_len; this.hdr = hdr;
int lhs_bgn = bgn;
while (true) {
boolean found = Find_hdr(lhs_bgn);
if (found) return lhs_bgn;
lhs_bgn = Bry_finder.Find_fwd(src, Hdr_bgn, nl_pos, src_len);
if (lhs_bgn == Bry_.NotFound) break; // "\n=" not found; exit;
++lhs_bgn; // skip \n
}
return Bry_finder.Not_found;
}
private boolean Find_hdr(int lhs_bgn) {
nl_pos = Bry_finder.Find_fwd(src, Byte_ascii.NewLine, lhs_bgn, src_len); // look for \n
if (nl_pos == Bry_finder.Not_found) nl_pos = src_len - 1; // no more \n; set to last idx
int lhs_end = Bry_finder.Find_fwd_while(src, lhs_bgn, nl_pos, Byte_ascii.Eq); // skip eq; EX: "\n==="
int rhs_end = Bry_finder.Find_bwd_non_ws_or_end(src, nl_pos, lhs_end); // skip ws bwd; EX: "== \n"
int rhs_bgn = Bry_finder.Find_bwd_while(src, rhs_end, lhs_end, Byte_ascii.Eq); // skip eq
if (rhs_bgn < lhs_end) return false; // eq found, but < lhs_end; exit; EX: "\n== \n"
++rhs_bgn; // rhs_bgn is 1st char before eq; position at eq;
if (rhs_end - rhs_bgn < 1) return false; // no eq; exit; EX: "\n==abc \n"
int txt_end = Bry_finder.Find_bwd_non_ws_or_end(src, rhs_bgn, lhs_end); // skip ws before ==; EX: "\n==a ==\n"
int txt_bgn = Bry_finder.Find_fwd_while_space_or_tab(src, lhs_end, nl_pos); // skip spaces after eq
return Bry_.Eq(hdr, src, txt_bgn, txt_end); // check for strict match
}
private static final byte[] Hdr_bgn = Bry_.new_ascii_("\n=");
}

View File

@ -0,0 +1,69 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*;
import org.junit.*;
import gplx.xowa.apis.xowa.html.modules.*;
import gplx.xowa.gui.views.*;
public class Xow_popup_hdr_finder_tst {
@Before public void init() {fxt.Clear();} private Xop_popup_hdr_finder_fxt fxt = new Xop_popup_hdr_finder_fxt();
@Test public void Basic() {
String src_str = String_.Concat_lines_nl_skip_last
( "a"
, "==b1=="
, "c"
);
fxt.Test_find(src_str, "b1", 2);
fxt.Test_find_not(src_str, "b");
fxt.Test_find_not(src_str, "a");
}
@Test public void Mid() {
String src_str = String_.Concat_lines_nl_skip_last
( "a"
, "==b=="
, "c"
, "==d=="
, "e"
);
fxt.Test_find(src_str, "d", 10);
}
@Test public void Eos() {
String src_str = String_.Concat_lines_nl_skip_last
( "a"
, "==b=="
);
fxt.Test_find(src_str, "b", 2);
}
@Test public void Bos() {
String src_str = String_.Concat_lines_nl_skip_last
( "==a=="
, "b"
);
fxt.Test_find(src_str, "a", 0);
}
}
class Xop_popup_hdr_finder_fxt {
private Xow_popup_hdr_finder finder = new Xow_popup_hdr_finder();
public void Clear() {
}
public void Test_find_not(String src_str, String hdr_str) {Test_find(src_str, hdr_str, Bry_finder.Not_found);}
public void Test_find(String src_str, String hdr_str, int expd) {
byte[] src = Bry_.new_utf8_(src_str);
byte[] hdr = Bry_.new_utf8_(hdr_str);
Tfds.Eq(expd, finder.Find(src, src.length, hdr, 0), hdr_str);
}
}

View File

@ -0,0 +1,69 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*;
import gplx.xowa.apis.xowa.html.modules.*;
public class Xow_popup_html_mkr {
private Xoa_app app; private Xow_wiki wiki;
public Bry_fmtr Fmtr_popup() {return fmtr_popup;} private Bry_fmtr fmtr_popup = Bry_fmtr.keys_(Xoapi_popups.Dflt_html_fmtr_popup_keys);
public Bry_fmtr Fmtr_viewed() {return fmtr_viewed;} private Bry_fmtr fmtr_viewed = Bry_fmtr.keys_(Xoapi_popups.Dflt_html_fmtr_viewed_keys);
public Bry_fmtr Fmtr_wiki() {return fmtr_wiki;} private Bry_fmtr fmtr_wiki = Bry_fmtr.keys_(Xoapi_popups.Dflt_html_fmtr_wiki_keys);
public Bry_fmtr Fmtr_next_sect() {return fmtr_next_sect;} private Bry_fmtr fmtr_next_sect = Bry_fmtr.keys_(Xoapi_popups.Dflt_html_fmtr_next_sect_keys);
public void Output_js_clean_(boolean v) {output_js_clean = v;} private boolean output_js_clean = true;
public void Output_tidy_(boolean v) {output_tidy = v;} private boolean output_tidy = true;
public void Ctor(Xoa_app app, Xow_wiki wiki) {
this.wiki = wiki; this.app = app;
wiki.Eval_mgr().Eval_mgr_(fmtr_popup, fmtr_viewed, fmtr_wiki, fmtr_next_sect);
}
public byte[] Bld(Xow_wiki cur_wiki, Xoa_page page, Xow_popup_itm popup_itm, Bry_bfr wrdx_bfr) {
if (output_js_clean) app.Html_mgr().Js_cleaner().Clean_bfr(wiki, page.Ttl(), wrdx_bfr, 0);
if (output_tidy) app.Html_mgr().Tidy_mgr().Run_tidy_html(page, wrdx_bfr);
byte[] hdom_bry = wrdx_bfr.XtoAryAndClear();
String page_url = wrdx_bfr.Add(page.Wiki().Domain_bry()).Add(Xoa_consts.Url_wiki_intermediary).Add(app.Url_converter_href()
.Encode(page.Ttl().Full_db())) // NOTE: was page.Url().Raw(), but that doesn't work for Special:Search; PAGE:en.w:Earth and "Quotations"; DATE:2014-06-29
.XtoStrAndClear()
;
fmtr_popup.Bld_bfr_many
( wrdx_bfr
, hdom_bry
, wiki.Lang().Dir_bry()
, page_url
, String_.new_utf8_(page.Ttl().Full_txt())
, popup_itm.Popup_id()
, Xow_popup_html_bldr_.Bld_fmtr_wiki(fmtr_wiki, wrdx_bfr, cur_wiki.Domain_bry(), page.Wiki().Domain_bry()) // NOTE: use cur_wiki, not page_wiki; DATE:2014-06-28
, gplx.ios.Io_size_.Xto_str(page.Data_raw().length)
, page.Revision_data().Modified_on().XtoStr_fmt_yyyy_MM_dd_HH_mm_ss()
, Xow_popup_html_bldr_.Bld_fmtr_viewed(fmtr_viewed, app, wiki, wrdx_bfr, page.Ttl())
, app.Fsys_mgr().Root_dir().To_http_file_bry()
);
return wrdx_bfr.XtoAryAndClear();
}
}
class Xow_popup_html_bldr_ {
public static byte[] Bld_fmtr_wiki(Bry_fmtr fmtr, Bry_bfr wrdx_bfr, byte[] wiki_domain, byte[] page_domain) {
return Bry_.Eq(wiki_domain, page_domain)
? Bry_.Empty // same domain; return "";
: fmtr.Bld_bry_many(wrdx_bfr, page_domain);
}
public static byte[] Bld_fmtr_viewed(Bry_fmtr fmtr, Xoa_app app, Xow_wiki wiki, Bry_bfr wrdx_bfr, Xoa_ttl ttl) {
byte[] view_time_item = Bry_.Empty;
gplx.xowa.users.history.Xou_history_itm history_itm = app.User().History_mgr().Get_or_null(wiki.Domain_bry(), ttl.Full_txt());
if (history_itm != null)
view_time_item = fmtr.Bld_bry_many(wrdx_bfr, history_itm.View_end().XtoStr_fmt_yyyy_MM_dd_HH_mm_ss());
return view_time_item;
}
}

View File

@ -25,21 +25,25 @@ public class Xow_popup_itm implements Cancelable {
public boolean Canceled() {return canceled;} private boolean canceled = false;
public void Cancel() {canceled = true;}
public void Cancel_reset() {canceled = false;}
public byte Mode() {return mode;} private byte mode = Mode_init;
public byte Mode() {return mode;} private byte mode = Mode_tid_init;
public Xow_popup_itm Mode_more_(int more_words) {
mode = Mode_more;
words_needed = popup_html_word_count + more_words;
mode = Mode_tid_more;
words_needed = words_found + more_words;
return this;
}
public boolean Mode_all() {return mode == Mode_tid_all;}
public Xow_popup_itm Mode_all_() {
mode = Mode_all;
mode = Mode_tid_all;
words_needed = Int_.MaxValue;
return this;
}
public String Popup_id() {return popup_id;} private String popup_id;
public byte[] Popup_html() {return popup_html;} public Xow_popup_itm Popup_html_(byte[] v) {popup_html = v; return this;} private byte[] popup_html;
public byte[] Popup_html() {return popup_html;} public void Popup_html_(byte[] v) {popup_html = v;} private byte[] popup_html;
public byte[] Wiki_domain() {return wiki_domain;} private byte[] wiki_domain;
public byte[] Page_href() {return page_href;} private byte[] page_href;
public int Popup_html_word_count() {return popup_html_word_count;} public void Popup_html_word_count_(int v) {popup_html_word_count = v;} private int popup_html_word_count;
public Xoa_ttl Page_ttl() {return page_ttl;} private Xoa_ttl page_ttl;
public void Init(byte[] wiki_domain, Xoa_ttl page_ttl) {this.wiki_domain = wiki_domain; this.page_ttl = page_ttl;}
public int Words_needed() {return words_needed;} private int words_needed;
public static final byte Mode_init = 0, Mode_more = 1, Mode_all = 2;
public int Words_found() {return words_found;} public void Words_found_(int v) {words_found = v;} private int words_found;
public static final byte Mode_tid_init = 0, Mode_tid_more = 1, Mode_tid_all = 2;
}

View File

@ -37,26 +37,27 @@ public class Xow_popup_mgr implements GfoInvkAble, GfoEvObj {
show_init_word_count = api_popups.Show_init_word_count();
show_more_word_count = api_popups.Show_more_word_count();
Ns_allowed_(api_popups.Ns_allowed());
parser.Show_all_if_less_than_(api_popups.Show_all_if_less_than());
parser.Xnde_ignore_ids_(api_popups.Xnde_ignore_ids());
parser.Scan_len_(api_popups.Scan_len());
parser.Scan_max_(api_popups.Scan_max());
parser.Html_fmtr().Fmt_(api_popups.Html_fmt());
parser.Read_til_stop_fwd_(api_popups.Read_til_stop_fwd());
parser.Read_til_stop_bwd_(api_popups.Read_til_stop_bwd());
parser.Cfg().Show_all_if_less_than_(api_popups.Show_all_if_less_than());
parser.Cfg().Tmpl_read_len_(api_popups.Scan_len());
parser.Cfg().Tmpl_read_max_(api_popups.Scan_max());
parser.Cfg().Read_til_stop_fwd_(api_popups.Read_til_stop_fwd());
parser.Cfg().Read_til_stop_bwd_(api_popups.Read_til_stop_bwd());
parser.Cfg().Stop_if_hdr_after_(api_popups.Stop_if_hdr_after());
parser.Tmpl_tkn_max_(api_popups.Tmpl_tkn_max());
if (!Env_.Mode_testing())
parser.Tmpl_keeplist_init_(api_popups.Tmpl_keeplist());
parser.Wrdx_mkr().Xnde_ignore_ids_(api_popups.Xnde_ignore_ids());
parser.Html_mkr().Fmtr_popup().Fmt_(api_popups.Html_fmtr_popup());
parser.Html_mkr().Fmtr_viewed().Fmt_(api_popups.Html_fmtr_viewed());
parser.Html_mkr().Fmtr_wiki().Fmt_(api_popups.Html_fmtr_wiki());
parser.Html_mkr().Fmtr_next_sect().Fmt_(api_popups.Html_fmtr_next_sect_fmt());
GfoEvMgr_.SubSame_many(api_popups, this
, Xoapi_popups.Evt_show_init_word_count_changed
, Xoapi_popups.Evt_show_more_word_count_changed
, Xoapi_popups.Evt_show_all_if_less_than_changed
, Xoapi_popups.Evt_xnde_ignore_ids_changed
, Xoapi_popups.Evt_scan_len_changed
, Xoapi_popups.Evt_scan_max_changed
, Xoapi_popups.Evt_html_fmt_changed
, Xoapi_popups.Evt_read_til_stop_fwd_changed
, Xoapi_popups.Evt_read_til_stop_bwd_changed
, Xoapi_popups.Evt_show_init_word_count_changed, Xoapi_popups.Evt_show_more_word_count_changed , Xoapi_popups.Evt_show_all_if_less_than_changed
, Xoapi_popups.Evt_scan_len_changed, Xoapi_popups.Evt_scan_max_changed
, Xoapi_popups.Evt_read_til_stop_fwd_changed, Xoapi_popups.Evt_read_til_stop_bwd_changed, Xoapi_popups.Evt_stop_if_hdr_after_changed
, Xoapi_popups.Evt_ns_allowed_changed
, Xoapi_popups.Evt_tmpl_tkn_max_changed
, Xoapi_popups.Evt_xnde_ignore_ids_changed, Xoapi_popups.Evt_tmpl_tkn_max_changed, Xoapi_popups.Evt_tmpl_keeplist_changed
, Xoapi_popups.Evt_html_fmtr_popup_changed, Xoapi_popups.Evt_html_fmtr_viewed_changed, Xoapi_popups.Evt_html_fmtr_wiki_changed, Xoapi_popups.Evt_html_fmtr_next_sect_changed
);
}
public String Show_init(byte[] href, int id) {
@ -93,14 +94,15 @@ public class Xow_popup_mgr implements GfoInvkAble, GfoEvObj {
try {
synchronized (async_thread_guard) {
if (itm.Canceled()) return null;
cur_page.Popup_itms().AddReplace(itm.Popup_id(), itm);
cur_page.Popup_mgr().Itms().AddReplace(itm.Popup_id(), itm);
app.Href_parser().Parse(temp_href, itm.Page_href(), wiki, cur_page.Ttl().Page_url());
Xow_wiki popup_wiki = app.Wiki_mgr().Get_by_key_or_null(temp_href.Wiki());
popup_wiki.Init_assert();
Xoa_ttl popup_ttl = Xoa_ttl.parse_(popup_wiki, temp_href.Page());
if (ns_allowed_regy.Count() > 0 && !ns_allowed_regy.Has(ns_allowed_regy_key.Val_(popup_ttl.Ns().Id()))) return Bry_.Empty;
itm.Init(popup_wiki.Domain_bry(), popup_ttl);
Xoa_page popup_page = popup_wiki.Data_mgr().Get_page(popup_ttl, false);
byte[] rv = popup_wiki.Html_mgr().Module_mgr().Popup_mgr().Parser().Parse(itm, popup_page, wiki.Domain_bry(), cur_page.Tab());
byte[] rv = popup_wiki.Html_mgr().Module_mgr().Popup_mgr().Parser().Parse(wiki, popup_page, cur_page.Tab(), itm);
Xog_win_itm__prog_href_mgr.Hover(app, cur_page, String_.new_utf8_(itm.Page_href())); // set page ttl again in prog bar; DATE:2014-06-28
return rv;
}
@ -163,20 +165,26 @@ public class Xow_popup_mgr implements GfoInvkAble, GfoEvObj {
return (Int_obj_ref[])rv.XtoAry(Int_obj_ref.class);
} private HashAdp ns_allowed_regy = HashAdp_.new_(); private Int_obj_ref ns_allowed_regy_key = Int_obj_ref.zero_();
private Xoa_page Cur_page() {return app.Gui_mgr().Browser_win().Active_page();}
private Xow_popup_itm Itms_get_or_null(Xoa_page page, String popup_id) {return (Xow_popup_itm)page.Popup_itms().Fetch(popup_id);}
private Xow_popup_itm Itms_get_or_null(Xoa_page page, String popup_id) {return (Xow_popup_itm)page.Popup_mgr().Itms().Fetch(popup_id);}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_show_popup_async)) Show_popup_async();
else if (ctx.Match(k, Invk_show_popup)) Show_popup();
else if (ctx.Match(k, Xoapi_popups.Evt_show_init_word_count_changed)) show_init_word_count = m.ReadInt("v");
else if (ctx.Match(k, Xoapi_popups.Evt_show_more_word_count_changed)) show_more_word_count = m.ReadInt("v");
else if (ctx.Match(k, Xoapi_popups.Evt_show_all_if_less_than_changed)) parser.Show_all_if_less_than_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_xnde_ignore_ids_changed)) parser.Xnde_ignore_ids_(m.ReadBry("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_scan_len_changed)) parser.Scan_len_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_scan_max_changed)) parser.Scan_max_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_html_fmt_changed)) parser.Html_fmtr().Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_read_til_stop_fwd_changed)) parser.Read_til_stop_fwd_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_show_all_if_less_than_changed)) parser.Cfg().Show_all_if_less_than_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_xnde_ignore_ids_changed)) parser.Wrdx_mkr().Xnde_ignore_ids_(m.ReadBry("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_scan_len_changed)) parser.Cfg().Tmpl_read_len_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_scan_max_changed)) parser.Cfg().Tmpl_read_max_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_read_til_stop_bwd_changed)) parser.Cfg().Read_til_stop_bwd_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_read_til_stop_fwd_changed)) parser.Cfg().Read_til_stop_fwd_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_stop_if_hdr_after_changed)) parser.Cfg().Stop_if_hdr_after_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_ns_allowed_changed)) Ns_allowed_(m.ReadBry("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_tmpl_tkn_max_changed)) parser.Tmpl_tkn_max_(m.ReadInt("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_tmpl_keeplist_changed)) parser.Tmpl_keeplist_init_(m.ReadBry("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_html_fmtr_popup_changed)) parser.Html_mkr().Fmtr_popup().Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_html_fmtr_viewed_changed)) parser.Html_mkr().Fmtr_viewed().Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_html_fmtr_wiki_changed)) parser.Html_mkr().Fmtr_wiki().Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Xoapi_popups.Evt_html_fmtr_next_sect_changed)) parser.Html_mkr().Fmtr_next_sect().Fmt_(m.ReadBry("v"));
else return GfoInvkAble_.Rv_unhandled;
return this;
}

View File

@ -16,388 +16,187 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*;
import gplx.html.*;
import gplx.xowa.apis.xowa.html.modules.*;
import gplx.xowa.parsers.lnkes.*;
import gplx.xowa.gui.views.*;
import gplx.xowa.html.modules.popups.keeplists.*;
public class Xow_popup_parser {
private Xoa_app app; private Xow_wiki wiki; private Xop_parser parser;
private ByteTrieMgr_fast orig_trie, wtxt_trie; private Xop_tkn_mkr tkn_mkr;
private Xop_ctx orig_ctx; private Xop_root_tkn orig_root, wtxt_root; private Xot_compile_data orig_props = new Xot_compile_data();
private Bry_bfr hdom_bfr = Bry_bfr.reset_(255);
private ByteTrieMgr_fast tmpl_trie, wtxt_trie; private Xop_tkn_mkr tkn_mkr;
private Xop_ctx tmpl_ctx; private Xop_root_tkn tmpl_root, wtxt_root; private Xot_compile_data tmpl_props = new Xot_compile_data();
private Xoh_html_wtr_ctx hctx = Xoh_html_wtr_ctx.Popup;
private boolean add_wtxt_skip_space = false;
private boolean stop_at_hdr_done;
private int words_found;
private int words_needed = -1;
private Cancelable cancelable; private Bry_bfr tmp_bfr = Bry_bfr.reset_(32);
public Xow_popup_cfg Cfg() {return cfg;} private Xow_popup_cfg cfg = new Xow_popup_cfg();
public Xow_popup_wrdx_mkr Wrdx_mkr() {return wrdx_mkr;} private Xow_popup_wrdx_mkr wrdx_mkr = new Xow_popup_wrdx_mkr();
public Xow_popup_html_mkr Html_mkr() {return html_mkr;} private Xow_popup_html_mkr html_mkr = new Xow_popup_html_mkr();
public Xow_popup_parser_data Data() {return data;} private Xow_popup_parser_data data = new Xow_popup_parser_data();
public Xop_keeplist_wiki Tmpl_keeplist() {return tmpl_keeplist;} private Xop_keeplist_wiki tmpl_keeplist; // private byte[] tmpl_keeplist_bry = Bry_.Empty;
public Xop_ctx Wtxt_ctx() {return wtxt_ctx;} private Xop_ctx wtxt_ctx;
private ListAdp words_found_list = ListAdp_.new_();
public int Scan_len() {return scan_len;} public void Scan_len_(int v) {scan_len = v;} private int scan_len = Xoapi_popups.Dflt_scan_len;
public int Scan_max() {return scan_max;} public void Scan_max_(int v) {scan_max = v;} private int scan_max = Xoapi_popups.Dflt_scan_max;
public int Show_all_if_less_than() {return show_all_if_less_than;} public void Show_all_if_less_than_(int v) {show_all_if_less_than = v;} private int show_all_if_less_than = Xoapi_popups.Dflt_show_all_if_less_than;
public byte[] Ellipsis() {return ellipsis;} public void Ellipsis_(byte[] v) {ellipsis = v;} private byte[] ellipsis = Ellipsis_const;
public byte[] Notoc() {return notoc;} public void Notoc_(byte[] v) {notoc = v;} private byte[] notoc = Notoc_const;
public boolean Stop_at_hdr() {return stop_at_hdr;} public void Stop_at_hdr_(boolean v) {stop_at_hdr = v;} private boolean stop_at_hdr = false;
public boolean Output_js_clean() {return output_js_clean;} public void Output_js_clean_(boolean v) {output_js_clean = v;} private boolean output_js_clean = true;
public boolean Output_tidy() {return output_tidy;} public void Output_tidy_(boolean v) {output_tidy = v;} private boolean output_tidy = true;
public int Read_til_stop_fwd() {return read_til_stop_fwd;} public void Read_til_stop_fwd_(int v) {read_til_stop_fwd = v;} private int read_til_stop_fwd = Xoapi_popups.Dflt_read_til_stop_fwd;
public int Read_til_stop_bwd() {return read_til_stop_bwd;} public void Read_til_stop_bwd_(int v) {read_til_stop_bwd = v;} private int read_til_stop_bwd = Xoapi_popups.Dflt_read_til_stop_bwd;
public int Tmpl_tkn_max() {return tmpl_tkn_max;}
public void Tmpl_tkn_max_(int v) {
if (v < 0) v = Int_.MaxValue; // allow -1 as shortcut to deactivate
orig_ctx.Tmpl_tkn_max_(v);
tmpl_ctx.Tmpl_tkn_max_(v);
wtxt_ctx.Tmpl_tkn_max_(v);
} private int tmpl_tkn_max = Xoapi_popups.Dflt_tmpl_tkn_max;
public Bry_fmtr Html_fmtr() {return html_fmtr;}
}
public void Init_by_wiki(Xow_wiki wiki) {
this.wiki = wiki; this.app = wiki.App(); this.parser = wiki.Parser(); this.tkn_mkr = app.Tkn_mkr();
this.orig_ctx = Xop_ctx.new_(wiki); this.wtxt_ctx = Xop_ctx.new_(wiki);
Xop_lxr_mgr orig_lxr_mgr = Xop_lxr_mgr.Popup_lxr_mgr;
orig_lxr_mgr.Init_by_wiki(wiki);
this.orig_trie = orig_lxr_mgr.Trie(); this.wtxt_trie = parser.Wtxt_lxr_mgr().Trie();
orig_ctx.Parse_tid_(Xop_parser_.Parse_tid_page_tmpl); wtxt_ctx.Parse_tid_(Xop_parser_.Parse_tid_page_wiki);
orig_ctx.Xnde_names_tid_(Xop_parser_.Parse_tid_page_wiki);
orig_ctx.Tid_is_popup_(true); wtxt_ctx.Tid_is_popup_(true);
orig_root = tkn_mkr.Root(Bry_.Empty); wtxt_root = tkn_mkr.Root(Bry_.Empty);
html_fmtr.Eval_mgr_(wiki.Eval_mgr());
view_time_fmtr.Eval_mgr_(wiki.Eval_mgr());
xwiki_fmtr.Eval_mgr_(wiki.Eval_mgr());
ellipsis = wiki.Msg_mgr().Val_by_key_obj(Msg_key_ellipsis);
} private static byte[] Msg_key_ellipsis = Bry_.new_ascii_("ellipsis");
private Hash_adp_bry xnde_id_ignore_list = Hash_adp_bry.ci_ascii_();
public void Xnde_ignore_ids_(byte[] xnde_id_ignore_bry) {
byte[][] ary = Bry_.Split(xnde_id_ignore_bry, Byte_ascii.Pipe);
int ary_len = ary.length;
xnde_id_ignore_list.Clear();
for (int i = 0; i < ary_len; i++) {
byte[] bry = ary[i];
if (bry.length == 0) continue; // ignore empty entries; EX: "a|"
xnde_id_ignore_list.Add(bry, bry);
}
this.tmpl_ctx = Xop_ctx.new_(wiki); this.wtxt_ctx = Xop_ctx.new_(wiki);
Xop_lxr_mgr tmpl_lxr_mgr = Xop_lxr_mgr.Popup_lxr_mgr;
tmpl_lxr_mgr.Init_by_wiki(wiki);
this.tmpl_trie = tmpl_lxr_mgr.Trie(); this.wtxt_trie = parser.Wtxt_lxr_mgr().Trie();
tmpl_ctx.Parse_tid_(Xop_parser_.Parse_tid_page_tmpl); wtxt_ctx.Parse_tid_(Xop_parser_.Parse_tid_page_wiki);
tmpl_ctx.Xnde_names_tid_(Xop_parser_.Parse_tid_page_wiki);
tmpl_ctx.Tid_is_popup_(true); wtxt_ctx.Tid_is_popup_(true);
tmpl_root = tkn_mkr.Root(Bry_.Empty); wtxt_root = tkn_mkr.Root(Bry_.Empty);
html_mkr.Ctor(app, wiki);
cfg.Ellipsis_(wiki.Msg_mgr().Val_by_key_obj(Xow_popup_cfg.Msg_key_ellipsis));
}
private int words_needed_orig = -1;
public byte[] Parse(Xow_popup_itm popup_itm, Xoa_page page, byte[] cur_wiki_domain, Xog_tab_itm cur_tab) {
byte[] orig_src = page.Data_raw(); int orig_len = orig_src.length; if (orig_len == 0) return Bry_.Empty;
String page_url = hdom_bfr.Add(page.Wiki().Domain_bry()).Add(Xoa_consts.Url_wiki_intermediary).Add(app.Url_converter_href()
.Encode(page.Ttl().Full_db())) // NOTE: was page.Url().Raw(), but that doesn't work for Special:Search; PAGE:en.w:Earth and "Quotations"; DATE:2014-06-29
.XtoStrAndClear()
;
this.cancelable = popup_itm;
int orig_pos = Xop_parser_.Doc_bgn_bos;
orig_ctx.Clear();
orig_ctx.Cur_page().Ttl_(page.Ttl()); // NOTE: must set cur_page, else page-dependent templates won't work; EX: {{FULLPAGENAME}}; PAGE:en.w:June_20; DATE:2014-06-20
orig_ctx.Page_bgn(orig_root, orig_src);
Wtxt_ctx_init(true, orig_src);
orig_ctx.Cur_page().Ttl_(page.Ttl()); // NOTE: must set cur_page, or rel lnkis won't work; EX: [[../A]]
hdom_bfr.Clear();
int scan_cur = scan_len;
words_found_list.Clear();
words_needed = popup_itm.Words_needed(); words_found = 0; stop_at_hdr_done = false;
if (read_til_stop_fwd > 0 && words_needed != Int_.MaxValue) {
words_needed_orig = words_needed;
words_needed += read_til_stop_fwd;
public void Tmpl_keeplist_(Xop_keeplist_wiki v) {this.tmpl_keeplist = v;}
public void Tmpl_keeplist_init_(byte[] raw) {
if (tmpl_keeplist == null) {
tmpl_keeplist = new Xop_keeplist_wiki(wiki);
tmpl_ctx.Tmpl_keeplist_(tmpl_keeplist);
}
else
words_needed_orig = -1;
if (orig_len < show_all_if_less_than) words_needed = Int_.MaxValue;
if (words_needed == Int_.MaxValue) scan_max = Int_.MaxValue; // if max words, automatically set scan to max
while (words_found < words_needed) {
if (cancelable.Canceled()) return null;
orig_root.Clear();
int orig_end = orig_pos + scan_cur; if (orig_end > orig_len) orig_end = orig_len; // limit to orig_len; EX: page is 16 bytes, but block is 1024
if (cur_tab != null && cur_tab.Tab_is_loading()) return null;
int new_pos = parser.Parse_to_stack_end(orig_root, orig_ctx, tkn_mkr, orig_src, orig_len, orig_trie, orig_pos, orig_end);
if (cur_tab != null && cur_tab.Tab_is_loading()) return null;
byte[] wtxt_bry = Parse_to_wtxt(orig_src);
int wtxt_len = wtxt_bry.length; // if (wtxt_len == 0) {break;}// no wtxt; continue; EX: blank page
if (!Bry_.HasAtEnd(raw, Byte_ascii.NewLine_bry)) raw = Bry_.Add(raw, Byte_ascii.NewLine_bry);
tmpl_keeplist.Srl().Load_by_bry(raw);
}
private boolean Canceled(Xow_popup_itm popup_itm, Xog_tab_itm cur_tab) {return popup_itm.Canceled() || cur_tab != null && cur_tab.Tab_is_loading();}
private void Init_ctxs(byte[] tmpl_src, Xoa_ttl ttl) {
tmpl_ctx.Clear();
tmpl_ctx.Cur_page().Ttl_(ttl); // NOTE: must set cur_page, else page-dependent templates won't work; EX: {{FULLPAGENAME}}; PAGE:en.w:June_20; DATE:2014-06-20
tmpl_ctx.Cur_page().Html_data().Restricted_(data.Html_restricted()); // NOTE: must set data.Html_restricted() if Special:XowaPopupHistory
tmpl_ctx.Page_bgn(tmpl_root, tmpl_src);
Wtxt_ctx_init(true, tmpl_src);
wtxt_ctx.Cur_page().Ttl_(ttl); // NOTE: must set cur_page, or rel lnkis won't work; EX: [[../A]]
}
public byte[] Parse(Xow_wiki cur_wiki, Xoa_page page, Xog_tab_itm cur_tab, Xow_popup_itm popup_itm) { // NOTE: must pass cur_wiki for xwiki label; DATE:2014-07-02
byte[] tmpl_src = page.Data_raw(); int tmpl_len = tmpl_src.length; if (tmpl_len == 0) return Bry_.Empty;
int tmpl_bgn = Xop_parser_.Doc_bgn_bos;
int tmpl_read_len_cur = cfg.Tmpl_read_len();
wrdx_mkr.Init();
data.Init(cfg, popup_itm, tmpl_len);
Init_ctxs(tmpl_src, page.Ttl());
while (data.Words_needed_chk()) {
if (Canceled(popup_itm, cur_tab)) return null;
tmpl_root.Clear();
int tmpl_end = tmpl_bgn + tmpl_read_len_cur; if (tmpl_end > tmpl_len) tmpl_end = tmpl_len; // limit to tmpl_len; EX: page is 16 bytes, but block is 1024
int new_tmpl_bgn = parser.Parse_to_stack_end(tmpl_root, tmpl_ctx, tkn_mkr, tmpl_src, tmpl_len, tmpl_trie, tmpl_bgn, tmpl_end);
if (Canceled(popup_itm, cur_tab)) return null;
byte[] wtxt_bry = Parse_to_wtxt(tmpl_src);
int wtxt_len = wtxt_bry.length;
wtxt_root.Clear();
int wtxt_bgn = (orig_pos == Xop_parser_.Doc_bgn_bos) ? Xop_parser_.Doc_bgn_bos : 0; // if first pass, parse from -1; needed for lxrs which assume nl at bos; EX: "*a"
if (cur_tab != null && cur_tab.Tab_is_loading()) return null;
int wtxt_bgn = (tmpl_bgn == Xop_parser_.Doc_bgn_bos) ? Xop_parser_.Doc_bgn_bos : 0; // if first pass, parse from -1; needed for lxrs which assume nl at bos; EX: "*a"
if (Canceled(popup_itm, cur_tab)) return null;
parser.Parse_to_src_end(wtxt_root, wtxt_ctx, tkn_mkr, wtxt_bry, wtxt_trie, wtxt_bgn, wtxt_len);
if ( wtxt_ctx.Stack_len() > 0 // dangling lnki / hdr / tblw
&& (orig_pos + scan_cur) < scan_max // too much read; stop and give whatever's available; PAGE:en.w:List_of_air_forces; DATE:2014-06-18
&& scan_cur < orig_len // only reparse if scan_cur is < entire page; needed for pages which have dangling items; EX:"<i>a"
if ( wtxt_ctx.Stack_len() > 0 // dangling lnki / hdr / tblw
&& (tmpl_bgn + tmpl_read_len_cur) < data.Tmpl_max() // too much read; stop and give whatever's available; PAGE:en.w:List_of_air_forces; DATE:2014-06-18
&& tmpl_read_len_cur < tmpl_len // only reparse if tmpl_read_len_cur is < entire page; needed for pages which have dangling items; EX:"<i>a"
) {
new_pos = orig_pos; //;stack_0.Src_bgn();
scan_cur += scan_len;
new_tmpl_bgn = tmpl_bgn;
tmpl_read_len_cur += cfg.Tmpl_read_len();
wtxt_ctx.Clear();
}
else {
Add_to_hdom_bfr(wtxt_root, wtxt_bry, wtxt_len);
scan_cur = scan_len;
wrdx_mkr.Process_tkn(cfg, data, data.Wrdx_bfr(), wtxt_root, wtxt_bry, wtxt_len);
tmpl_read_len_cur = cfg.Tmpl_read_len();
}
orig_pos = new_pos;
if ( orig_pos == orig_len
|| orig_pos > scan_max // too much read; stop and give whatever's available
) break;
tmpl_bgn = new_tmpl_bgn;
if ( tmpl_bgn == tmpl_len // end of template
|| tmpl_bgn > data.Tmpl_max() // too much read; stop and give whatever's available
)
break;
}
Adjust_for_header();
if ( words_found >= words_needed // don't add ellipsis if words_found < words_needed. note that it will add "..." if words_on_page == words_needed; DATE:2014-06-18
&& !stop_at_hdr_done // don't add ellipsis if stopped at hdr
)
hdom_bfr.Add(ellipsis);
if (cancelable.Canceled()) return null;
if (cur_tab != null && cur_tab.Tab_is_loading()) return null;
byte[] rv = Parse_to_html(page);
html_fmtr.Bld_bfr_many(hdom_bfr
, rv
, wiki.Lang().Dir_bry()
, page_url, String_.new_utf8_(page.Ttl().Full_txt())
, cur_wiki_domain // NOTE: use cur_wiki, not page_wiki; DATE:2014-06-28
, Get_xwiki_item(tmp_bfr, cur_wiki_domain, page.Wiki().Domain_bry())
, gplx.ios.Io_size_.Xto_str(page.Data_raw().length), page.Revision_data().Modified_on().XtoStr_fmt_yyyy_MM_dd_HH_mm_ss()
, Get_view_time(page.Ttl())
, app.Fsys_mgr().Root_dir().To_http_file_bry()
, popup_itm.Popup_id()
);
if (cancelable.Canceled()) return null;
popup_itm.Popup_html_word_count_(words_found);
return hdom_bfr.XtoAryAndClear();
if (Canceled(popup_itm, cur_tab)) return null;
Parse_wrdx_to_html(popup_itm, data.Wrdx_bfr());
byte[] rv = html_mkr.Bld(cur_wiki, page, popup_itm, data.Wrdx_bfr());
return (Canceled(popup_itm, cur_tab)) ? null : rv;
}
private void Adjust_for_header() {
Xow_popup_word[] words_found_ary = (Xow_popup_word[])words_found_list.XtoAryAndClear(Xow_popup_word.class);
int words_found_all = words_found_ary.length;
boolean read_til_stop_done = false;
if (read_til_stop_fwd != -1 && words_needed_orig != -1) {
Xow_popup_word hdr_word = null;
for (int i = words_needed_orig; i < words_found_all; ++i) {
Xow_popup_word word = words_found_ary[i];
private void Parse_wrdx_to_html(Xow_popup_itm popup_itm, Bry_bfr wrdx_bfr) {
Adjust_wrdx_end(popup_itm, wrdx_bfr);
wrdx_bfr.Add(cfg.Notoc()); // always add notoc at end
byte[] wrdx_bry = wrdx_bfr.XtoAryAndClear();
wtxt_root.Clear(); // now start parsing wrdx_bry from wtxt to html
Wtxt_ctx_init(false, wrdx_bry);
parser.Parse_to_src_end(wtxt_root, wtxt_ctx, tkn_mkr, wrdx_bry, wtxt_trie, Xop_parser_.Doc_bgn_bos, wrdx_bry.length);
wtxt_ctx.Page_end(wtxt_root, wrdx_bry, wrdx_bry.length);
wiki.Html_mgr().Html_wtr().Write_all(wrdx_bfr, wtxt_ctx, hctx, wrdx_bry, wtxt_root);
}
private void Adjust_wrdx_end(Xow_popup_itm popup_itm, Bry_bfr wrdx_bfr) {
popup_itm.Words_found_(data.Words_found());
if (popup_itm.Mode_all()) return; // mode_all needs no adjustments
Xow_popup_word[] words = data.Words_found_ary();
int words_len = words.length;
int last_word_idx = -1; Xow_popup_word last_hdr_tkn = null;
int words_needed_val = data.Words_needed_val();
if (cfg.Read_til_stop_fwd() != -1) {
for (int i = words_needed_val; i < words_len; ++i) { // find hdr after orig
Xow_popup_word word = words[i];
if (word.Tid() == Xop_tkn_itm_.Tid_hdr) {
hdr_word = word;
last_hdr_tkn = word;
break;
}
}
if (hdr_word == null) {
if (words_needed_orig < words_found_all) {
hdr_word = words_found_ary[words_needed_orig - 1];
hdom_bfr.Delete_rng_to_end(hdr_word.Bfr_end());
}
}
else {
hdr_word = words_found_ary[hdr_word.Idx() - 1];
hdom_bfr.Delete_rng_to_end(hdr_word.Bfr_end());
read_til_stop_done = true;
}
last_word_idx = (last_hdr_tkn == null) // no hdr found
? words_needed_val - ListAdp_.Base1 // get last word
: last_hdr_tkn.Idx() - 1 // get word before hdr
;
if (last_word_idx >= words_len)
last_word_idx = -1;
}
if ( read_til_stop_bwd != -1
&& !read_til_stop_done
boolean page_partially_parsed = data.Words_found() == data.Words_needed_max(); // adhoc way of figuring out if parsing prematurely stopped before eos; PAGE:en.q:Anaximander DATE:2014-07-02
if ( cfg.Read_til_stop_bwd() != -1
&& page_partially_parsed // never read bwd if entire tmpl is read; DATE:2014-07-01
) {
// Xow_popup_word hdr_word = null;
// for (int i = words_needed_orig; i < words_found_all; ++i) {
// Xow_popup_word word = words_found_ary[i];
// if (word.Tid() == Xop_tkn_itm_.Tid_hdr) {
// hdr_word = word;
// break;
// }
// }
int read_bwd_end = last_word_idx == -1 ? words_len - 1 : last_word_idx; // if !cfg.Read_til_stop_fwd() use last_wrd, else use read_fwd's last_word
int read_bwd_bgn = read_bwd_end - cfg.Read_til_stop_bwd();
if (read_bwd_bgn > -1) { // handle pages with "==a==" near start
int last_hdr_idx = -1;
for (int i = read_bwd_end; i >= read_bwd_bgn; i--) {
Xow_popup_word word = words[i];
if (word.Tid() == Xop_tkn_itm_.Tid_hdr) {
if (last_hdr_idx == -1) // last_hdr_idx not set
last_hdr_idx = i; // set it
else { // last_hdr_idx set
if (i + 1 == last_hdr_idx) // two consecutive hdrs; update earlier and continue
last_hdr_idx = i;
else // earlier hdr; ignore it and take later one
break;
}
last_hdr_tkn = word;
}
}
if (last_hdr_idx != -1) // hdr found
last_word_idx = last_hdr_idx - 1; // get word before last_word_idx
}
}
if (last_word_idx != -1) {
Xow_popup_word last_word = words[last_word_idx];
wrdx_bfr.Delete_rng_to_end(last_word.Bfr_end());// delete everything after last_word
popup_itm.Words_found_(last_word_idx + ListAdp_.Base1); // last_word_idx = 0 -> words_found = 1
if (last_word.Tid() == Xop_tkn_itm_.Tid_hdr) // on odd case where hdr is still last word, add \n else text will literally be "==A==" b/c no trailing \n
wrdx_bfr.Add_byte_nl();
}
if (last_hdr_tkn != null) {
wrdx_bfr.Trim_end(Byte_ascii.NewLine);
byte[] last_hdr_bry = ((Xop_hdr_tkn)last_hdr_tkn.Tkn()).Hdr_toc_text();
html_mkr.Fmtr_next_sect().Bld_bfr_one(wrdx_bfr, last_hdr_bry);
}
else {
if (page_partially_parsed)
wrdx_bfr.Add(cfg.Ellipsis());
}
}
private byte[] Parse_to_wtxt(byte[] src) {
int subs_len = orig_root.Subs_len();
for (int i = 0; i < subs_len; i++)
orig_root.Subs_get(i).Tmpl_compile(orig_ctx, src, orig_props);
return Xot_tmpl_wtr._.Write_all(orig_ctx, orig_root, src);
}
private byte[] Parse_to_html(Xoa_page page) {
hdom_bfr.Add(notoc);
byte[] hdom_bry = hdom_bfr.XtoAryAndClear();
wtxt_root.Clear();
Wtxt_ctx_init(Bool_.N, hdom_bry);
parser.Parse_to_src_end(wtxt_root, wtxt_ctx, tkn_mkr, hdom_bry, wtxt_trie, Xop_parser_.Doc_bgn_bos, hdom_bry.length);
wtxt_ctx.Page_end(wtxt_root, hdom_bry, hdom_bry.length);
wiki.Html_mgr().Html_wtr().Write_all(hdom_bfr, wtxt_ctx, hctx, hdom_bry, wtxt_root);
app.Html_mgr().Js_cleaner().Clean_bfr(wiki, page.Ttl(), hdom_bfr, 0);
if (output_tidy)
app.Html_mgr().Tidy_mgr().Run_tidy_html(page, hdom_bfr);
return hdom_bfr.XtoAryAndClear();
}
private void Wtxt_ctx_init(boolean incremental, byte[] bry) {
wtxt_ctx.Clear();
wtxt_ctx.Cur_page().Html_data().Restricted_(data.Html_restricted());
wtxt_ctx.Para().Enabled_(!incremental); // NOTE: if incremental, disable para; easier to work with \n rather than <p>; also, must be enabled before Page_bgn; DATE:2014-06-18DATE:2014-06-18
wtxt_ctx.Lnke().Dangling_goes_on_stack_(incremental);
wtxt_ctx.Page_bgn(wtxt_root, bry);
}
private byte[] Get_view_time(Xoa_ttl ttl) {
byte[] view_time_item = Bry_.Empty;
gplx.xowa.users.history.Xou_history_itm history_itm = app.User().History_mgr().Get_or_null(wiki.Domain_bry(), ttl.Full_txt());
if (history_itm != null)
view_time_item = view_time_fmtr.Bld_bry_many(hdom_bfr, history_itm.View_end().XtoStr_fmt_yyyy_MM_dd_HH_mm_ss());
return view_time_item;
private byte[] Parse_to_wtxt(byte[] src) {
int subs_len = tmpl_root.Subs_len();
for (int i = 0; i < subs_len; i++)
tmpl_root.Subs_get(i).Tmpl_compile(tmpl_ctx, src, tmpl_props);
return Xot_tmpl_wtr._.Write_all(tmpl_ctx, tmpl_root, src);
}
private byte[] Get_xwiki_item(Bry_bfr tmp_bfr, byte[] wiki_domain, byte[] page_domain) {
return Bry_.Eq(wiki_domain, page_domain)
? Bry_.Empty // same domain; return "";
: xwiki_fmtr.Bld_bry_many(tmp_bfr, page_domain);
}
private void Increment_words_found(Xop_tkn_itm tkn) {
words_found_list.Add(new Xow_popup_word(tkn.Tkn_tid(), hdom_bfr.Len(), words_found, tkn.Src_bgn(), tkn.Src_end()));
++words_found;
}
private void Add_to_hdom_bfr(Xop_tkn_itm tkn, byte[] wtxt_bry, int wtxt_len) {
if (cancelable.Canceled()) return;
boolean add = true, recur = true; Xop_xnde_tkn xnde = null;
int tkn_src_bgn = tkn.Src_bgn(), tkn_src_end = tkn.Src_end();
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_root:
add = false; // don't add root
break;
case Xop_tkn_itm_.Tid_txt:
Increment_words_found(tkn);
break;
case Xop_tkn_itm_.Tid_tblw_tb: case Xop_tkn_itm_.Tid_tblw_tc: case Xop_tkn_itm_.Tid_tblw_td:
case Xop_tkn_itm_.Tid_tblw_te: case Xop_tkn_itm_.Tid_tblw_th: case Xop_tkn_itm_.Tid_tblw_tr:
add = recur = false; // skip tblws
break;
case Xop_tkn_itm_.Tid_xnde:
xnde = (Xop_xnde_tkn)tkn;
switch (xnde.Tag().Id()) {
case Xop_xnde_tag_.Tid_ref:
case Xop_xnde_tag_.Tid_div:
case Xop_xnde_tag_.Tid_gallery:
case Xop_xnde_tag_.Tid_imageMap:
case Xop_xnde_tag_.Tid_xowa_html: // needed for Help:Options, else \n at top of doc; DATE:2014-06-22
case Xop_xnde_tag_.Tid_table: case Xop_xnde_tag_.Tid_tr: case Xop_xnde_tag_.Tid_td: case Xop_xnde_tag_.Tid_th:
case Xop_xnde_tag_.Tid_caption: case Xop_xnde_tag_.Tid_thead: case Xop_xnde_tag_.Tid_tfoot: case Xop_xnde_tag_.Tid_tbody:
add = recur = false; // skip tblxs
xnde = null;
break;
case Xop_xnde_tag_.Tid_br:
if (hdom_bfr.Len_eq_0()) // don't add <br/> to start of document; needed for Help:Options, but good to have everywhere; DATE:2014-06-22
add = recur = false;
break;
default:
add = false; // don't add xnde, but still recur
if (Xnde_id_ignore_list_chk(xnde, wtxt_bry)) {
recur = false;
xnde = null;
}
break;
}
break;
case Xop_tkn_itm_.Tid_lnke:
Xop_lnke_tkn lnke = (Xop_lnke_tkn)tkn;
switch (lnke.Lnke_typ()) {
case Xop_lnke_tkn.Lnke_typ_brack:
Add_to_hdom_bfr_recurse(tkn, wtxt_bry, wtxt_len, Bool_.N); // add subs which are caption tkns; note that Bool_.N will add all words so that captions don't get split; EX: "a [http://a.org b c d]" -> "a b c d" if words_needed == 2;
add = recur = false; // ignore lnke, but add any text tkns; EX: [http://a.org b c d] -> "b c d"
break;
case Xop_lnke_tkn.Lnke_typ_text:
Increment_words_found(tkn); // increment words_found; EX: a http://b.org c -> 3 words;
break;
}
break;
case Xop_tkn_itm_.Tid_lnki:
Xop_lnki_tkn lnki = (Xop_lnki_tkn)tkn;
switch (lnki.Ns_id()) {
case Xow_ns_.Id_category: // skip [[Category:]]
case Xow_ns_.Id_file: // skip [[File:]]
add = recur = false;
break;
default:
Increment_words_found(tkn); // increment words_found; EX: a [[B|c d e]] f -> 3 words;
break;
}
break;
case Xop_tkn_itm_.Tid_space:
if ( add_wtxt_skip_space // previous tkn skipped add and set add_wtxt_skip_space to true
&& hdom_bfr.Match_end_byt_nl_or_bos() // only ignore space if it will cause pre; note that some <ref>s will have spaces that should be preserved; EX:"a<ref>b</ref> c"; PAGE:en.w:Mehmed_the_Conqueror; DATE:2014-06-18
)
add = false; // skip ws
break;
case Xop_tkn_itm_.Tid_newLine: {
// heuristic to handle skipped <div> / <table> which does not skip \n; EX:"<div>a</div>\nb"; div is skipped, but "\n" remains; PAGE:en.w:Eulogy;DATE:2014-06-18
int hdom_bfr_len = hdom_bfr.Len();
if (hdom_bfr_len == 0) // don't add \n at bos; does not handle pages where bos intentionally has multiple \n\n
add = false;
else if (hdom_bfr_len > 2) { // bounds check
if (Wtxt_bfr_ends_w_2_nl(hdom_bfr_len)) // don't add \n if "\n\n"; does not handle intentional sequences of 2+ \n;
add = false;
}
break;
}
case Xop_tkn_itm_.Tid_hdr: {
if (stop_at_hdr && words_found != 0) { // if 1st word is header (no intro para), don't exit
words_found = words_needed;
stop_at_hdr_done = true;
return;
}
Increment_words_found(tkn); // count entire header as one word; not worth counting words in header
recur = false; // add entire tkn; do not recur
int hdom_bfr_len = hdom_bfr.Len();
if (hdom_bfr_len > 2) { // bounds check
if (Wtxt_bfr_ends_w_2_nl(hdom_bfr_len)) // heuristic: 2 \n in bfr, and about to add a hdr tkn which starts with "\n"; delete last \n
hdom_bfr.Del_by_1();
}
if ( tkn_src_end < wtxt_len // bounds check
&& wtxt_bry[tkn_src_end] == Byte_ascii.NewLine // hdr_tkn will not include trailing "\n". add it; note that this behavior is by design. NOTE:hdr.trailing_nl; DATE:2014-06-17
) {
hdom_bfr.Add_mid(wtxt_bry, tkn_src_bgn, tkn_src_end + 1); // +1 to add the trailing \n
add = false;
}
break;
}
default:
break;
}
add_wtxt_skip_space = false; // always reset; only used once above for Tid_space; DATE:2014-06-17
if (add) {
if (tkn_src_end - tkn_src_bgn > 0) // handle paras which have src_bgn == src_end
hdom_bfr.Add_mid(wtxt_bry, tkn_src_bgn, tkn_src_end);
}
else // tkn not added
add_wtxt_skip_space = true; // skip next space; note this is done with member variable to handle recursive iteration; DATE:2014-06-17
if (recur) {
if (xnde != null) hdom_bfr.Add_mid(wtxt_bry, xnde.Tag_open_bgn(), xnde.Tag_open_end()); // add open tag; EX: "<span id=a>"
Add_to_hdom_bfr_recurse(tkn, wtxt_bry, wtxt_len, Bool_.Y);
if (xnde != null) hdom_bfr.Add_mid(wtxt_bry, xnde.Tag_close_bgn(), xnde.Tag_close_end()); // add close tag; EX: "</span>"
}
}
private void Add_to_hdom_bfr_recurse(Xop_tkn_itm tkn, byte[] wtxt_bry, int wtxt_len, boolean chk_words_found) {
int subs_len = tkn.Subs_len();
for (int i = 0; i < subs_len; i++) {
Xop_tkn_itm sub = tkn.Subs_get(i);
Add_to_hdom_bfr(sub, wtxt_bry, wtxt_len);
if (chk_words_found && words_found >= words_needed) break;
}
}
private boolean Xnde_id_ignore_list_chk(Xop_xnde_tkn xnde, byte[] src) {
Xop_xatr_itm[] atrs_ary = xnde.Atrs_ary();
int atrs_len = atrs_ary.length;
for (int i = 0; i < atrs_len; i++) {
Xop_xatr_itm atr = atrs_ary[i];
if ( Bry_.Eq(atr.Key_bry(), Html_atrs.Id_bry)
&& xnde_id_ignore_list.Get_by_bry(atr.Val_as_bry(src)) != null
) {
return true;
}
}
return false;
}
private boolean Wtxt_bfr_ends_w_2_nl(int hdom_bfr_len) {
byte[] hdom_bfr_bry = hdom_bfr.Bfr();
return
( hdom_bfr_bry[hdom_bfr_len - 1] == Byte_ascii.NewLine // prv 2 bytes are \n
&& hdom_bfr_bry[hdom_bfr_len - 2] == Byte_ascii.NewLine
);
}
private static final byte[]
Notoc_const = Bry_.new_ascii_(" __NOTOC__") // NOTE: always add a space else __NOTOC__ will be deactivated if last tkn is lnke; DATE:2014-06-22
, Ellipsis_const = Bry_.new_ascii_("...")
;
private Bry_fmtr
html_fmtr = Bry_fmtr.keys_(Xoapi_popups.Dflt_html_fmt_keys)
, view_time_fmtr = Bry_fmtr.new_("\n <span class='data_key'>~{<>msgs.get('api-xowa.html.modules.popups.msgs.viewed-name');<>}:</span><span class='data_val'>~{view_time}</span>", "view_time")
, xwiki_fmtr = Bry_fmtr.new_("\n <span class='data_key'>~{<>msgs.get('api-xowa.html.modules.popups.msgs.wiki-name');<>}:</span><span class='data_val'>~{wiki_domain}</span>", "wiki_domain")
;
}
class Xow_popup_word {
public Xow_popup_word(int tid, int bfr_bgn, int idx, int bgn, int end) {this.tid = tid; this.bfr_bgn = bfr_bgn; this.idx = idx; this.bgn = bgn; this.end = end;}
public int Tid() {return tid;} private int tid;
public int Bfr_bgn() {return bfr_bgn;} private int bfr_bgn;
public int Bfr_end() {return bfr_bgn + this.Len();}
public int Idx() {return idx;} private int idx;
public int Bgn() {return bgn;} private int bgn;
public int End() {return end;} private int end;
public int Len() {return end - bgn;}
private static final String Comment_txt_str = "XOWA_SKIP";
public static final byte[] Comment_txt = Bry_.new_ascii_(Comment_txt_str);
public static final byte[] Comment_tkn = Bry_.new_ascii_("<!--" + Comment_txt_str + "-->");
}

View File

@ -0,0 +1,62 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*;
import gplx.xowa.apis.xowa.html.modules.*;
public class Xow_popup_parser_data {
public int Tmpl_max() {return tmpl_max;} private int tmpl_max;
public int Words_needed_val() {return words_needed_val;} private int words_needed_val;
public int Words_needed_max() {return words_needed_max;} private int words_needed_max;
private int words_needed_min;
public int Words_found() {return words_found;} private int words_found;
public Bry_bfr Wrdx_bfr() {return wrdx_bfr;} private Bry_bfr wrdx_bfr = Bry_bfr.reset_(255);
public Xow_popup_word[] Words_found_ary() {return (Xow_popup_word[])words_found_list.XtoAryAndClear(Xow_popup_word.class);} private ListAdp words_found_list = ListAdp_.new_();
private Xow_popup_itm popup_itm;
public boolean Html_restricted() {return html_restricted;} private boolean html_restricted;
public void Init(Xow_popup_cfg cfg, Xow_popup_itm popup_itm, int tmpl_len) {
words_found = 0;
words_found_list.Clear();
wrdx_bfr.Clear();
html_restricted = !gplx.xowa.specials.xowa.popup_history.Popup_history_page.Ttl_chk(popup_itm.Page_ttl());
this.popup_itm = popup_itm;
if (tmpl_len < cfg.Show_all_if_less_than()) popup_itm.Mode_all_();
words_needed_min = popup_itm.Words_found();
words_needed_val = words_needed_max = popup_itm.Words_needed();
switch (popup_itm.Mode()) {
case Xow_popup_itm.Mode_tid_all:
tmpl_max = Int_.MaxValue;
break;
case Xow_popup_itm.Mode_tid_init:
case Xow_popup_itm.Mode_tid_more:
tmpl_max = cfg.Tmpl_read_max();
if (cfg.Read_til_stop_fwd() > 0)
words_needed_max += cfg.Read_til_stop_fwd();
break;
}
}
public boolean Words_needed_chk() {return words_found < words_needed_max;}
public void Words_found_add(Xop_tkn_itm tkn) {
words_found_list.Add(new Xow_popup_word(tkn.Tkn_tid(), wrdx_bfr.Len(), words_found, tkn.Src_bgn(), tkn.Src_end(), tkn));
++words_found;
}
public boolean Stop_if_hdr_after_chk(Xow_popup_cfg cfg) {
boolean rv = words_found > words_needed_min + cfg.Stop_if_hdr_after() && !popup_itm.Mode_all();
if (rv) words_needed_max = words_found;
return rv;
}
}

View File

@ -58,14 +58,14 @@ public class Xow_popup_parser_tst {
));
}
@Test public void Lnke_brack() { // PURPOSE: count lnke caption words; DATE:2014-06-20
fxt.Init_scan_len_(32).Init_word_min_(5).Test_parse
fxt.Init_tmpl_read_len_(32).Init_word_needed_(5).Test_parse
( "a [http://b.org b c] d e f g", String_.Concat_lines_nl_skip_last
( "<p>a b c d e"
, "</p>"
));
}
@Test public void Lnke_text() { // PURPOSE: count entire lnke as one word
fxt.Init_scan_len_(32).Init_word_min_(5).Test_parse
fxt.Init_tmpl_read_len_(32).Init_word_needed_(5).Test_parse
( "a http://b.org c d e f g", String_.Concat_lines_nl_skip_last
( "<p>a <a href=\"http://b.org\" class=\"external text\" rel=\"nofollow\">http://b.org</a> c d e"
, "</p>"
@ -144,6 +144,24 @@ public class Xow_popup_parser_tst {
, "</p>"
));
}
@Test public void Xnde_br() { // PURPOSE: check that br is added correctly; PAGE:en.q:Earth; DATE:2014-06-30
fxt.Init_word_needed_(3).Test_parse
( "a<br>b<br/>"
, String_.Concat_lines_nl_skip_last
( "<p>a<br>b<br/>"
, "</p>"
));
}
@Test public void Xnde_math() { // PURPOSE: <math> should be treated as one word; PAGE:en.w:System_of_polynomial_equations; DATE:2014-07-01
fxt .Init_word_needed_(5) // need to read more words to pick up 1st word after header
.Init_read_til_stop_bwd_(2) // need to do read_bwd to start counting before ==e== into <math> node
.Test_parse
( "a <math>b c d</math> \n==e==\nf g h i"
, String_.Concat_lines_nl_skip_last
( "<p>a <span id='xowa_math_txt_0'>b c d</span> (e)" // used to fail as <p>a &lt;math&gt;b c d (e)
, "</p>"
));
}
@Test public void Ignore_tblw() {// also checks for tbl spanning multiple blocks; PAGE:en.w:Stratosphere; DATE:2014-06-17
fxt.Test_parse(String_.Concat_lines_nl_skip_last
( "a "
@ -284,7 +302,7 @@ public class Xow_popup_parser_tst {
));
}
@Test public void End_early_dangling() { // PURPOSE: dangling tkn is too long; end early; PAGE:en.w:List_of_air_forces; DATE:2014-06-18
fxt.Init_scan_max_(8).Test_parse
fxt.Init_tmpl_read_max_(8).Test_parse
( "a [[File:Test.png]] k"
, String_.Concat_lines_nl_skip_last
( "<p>a "
@ -304,21 +322,13 @@ public class Xow_popup_parser_tst {
( "<p>a"
, "</p>"
));
fxt.Test_parse // no ellipsis: entire extract with skip
fxt.Test_parse // no ellipsis: entire extract multiple reads
( "a <div>b</div>"
, String_.Concat_lines_nl_skip_last
( "<p>a "
, "</p>"
));
}
@Test public void Stop_at_hdr() {
fxt.Init_ellipsis_("...").Init_stop_at_header_(true).Test_parse
( "a\n==b==\nc"
, String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
));
}
@Test public void Ns_allowed() {
fxt.Test_ns_allowed("Help" , Xow_ns_.Id_help);
fxt.Test_ns_allowed("(Main)" , Xow_ns_.Id_main);
@ -326,24 +336,80 @@ public class Xow_popup_parser_tst {
fxt.Test_ns_allowed("(Main)|Help" , Xow_ns_.Id_main, Xow_ns_.Id_help);
}
@Test public void Read_til_stop_fwd() {
fxt.Init_word_min_(2).Init_read_til_stop_fwd_(2).Test_parse("a b c\n==d==", String_.Concat_lines_nl_skip_last
( "<p>a b c"
fxt.Init_word_needed_(2).Init_read_til_stop_fwd_(2) // read fwd found hdr
.Test_parse("a b c\n==d==", String_.Concat_lines_nl_skip_last
( "<p>a b c (d)"
, "</p>"
));
fxt.Init_word_min_(2).Init_read_til_stop_fwd_(2).Test_parse("a b c d", String_.Concat_lines_nl_skip_last
fxt.Init_word_needed_(2).Init_read_til_stop_fwd_(2) // read fwd did not find hdr; reset back to min
.Test_parse("a b c d", String_.Concat_lines_nl_skip_last
( "<p>a b"
, "</p>"
));
}
@Test public void Read_til_stop_bwd() {
fxt.Init_word_needed_(8).Init_read_til_stop_bwd_(4) // read bwd found hdr
.Test_parse("01 02 03 04 05\n==06==\n07 08 09 10 11 12 13 14 15 16", String_.Concat_lines_nl_skip_last
( "<p>01 02 03 04 05 (06)"
, "</p>"
));
fxt.Init_tmpl_read_len_(40).Init_word_needed_(5).Init_read_til_stop_bwd_(3) // read bwd at eos should not return "next_sect"; DATE:2014-07-01
.Test_parse("01 02 03 \n==04==\n", String_.Concat_lines_nl_skip_last
( "<p>01 02 03 "
, "</p>"
, ""
, "<h2>04</h2>"
));
}
@Test public void Stop_if_hdr_after() {
fxt.Init_word_needed_(5).Init_stop_if_hdr_after_(1)
.Test_parse("a b\n==c==\nd e", String_.Concat_lines_nl_skip_last
( "<p>a b"
, "</p>"
, ""
, "<h2>c</h2>"
));
}
@Test public void Tmpl_tkn_max() {
fxt.Init_tmpl_tkn_max_(5).Init_page("Template:A", "a");
fxt.Init_tmpl_tkn_max_(5).Init_page("Template:A", "a"); // eval
fxt.Test_parse
( "{{A}}"
, String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
));
fxt.Test_parse( "{{A|b|c}}", "<p>\n</p>");
fxt.Test_parse("{{A|b|c}}" , ""); // skip; NOTE: output should be blank, not <p>\n</p>; PAGE:en.w:List_of_countries_by_GDP_(PPP); DATE:2014-07-01
}
@Test public void Tmpl_tkn_max__comment_and_tblw() { // PURPOSE: garbled popup when tmpl_tkn_max is set and comments in front of tblw; PAGE:en.w:Gwynedd; DATE:2014-07-01
fxt .Init_tmpl_tkn_max_(5) // set tmpl_tkn_max
.Init_tmpl_read_len_(20) // set read_len to 20 (must read entire "<!---->\n{|" at once
.Test_parse(String_.Concat_lines_nl_skip_last
( "{{A|b}}"
, "{{A|b}}"
, "{|"
, "|-"
, "|a b c d"
, "|}"
), ""); // should be blank, not <table>]
}
@Test public void Tmpl_tkn_max__apos() { // PURPOSE: handle apos around skipped tmpl token; PAGE:en.w:Somalia; DATE:2014-07-02
fxt.Init_tmpl_tkn_max_(5).Test_parse("a''{{A|b}}''b", String_.Concat_lines_nl_skip_last
( "<p>a<i> </i>b"
, "</p>"
));
}
@Test public void Notoc_and_para_issue() { // PURPOSE.fix: issue with "\s__NOTOC__" and "a\n"b; PAGE:en.w:Spain; DATE:2014-07-05
fxt.Init_word_needed_(3).Init_notoc_(" __NOTOC__").Test_parse("a\nb", String_.Concat_lines_nl_skip_last
( "<p>a" // was <p>a</p>b
, "b "
, "</p>"
));
}
@Test public void Test_Assert_at_end() {
fxt.Test_Assert_at_end("a" , "a\n"); // add one
fxt.Test_Assert_at_end("a\n" , "a\n"); // noop
fxt.Test_Assert_at_end("a\n\n\n" , "a\n"); // remove til one
fxt.Test_Assert_at_end("" , ""); // empty check
}
}
class Xop_popup_parser_fxt {
@ -354,26 +420,31 @@ class Xop_popup_parser_fxt {
this.wiki = Xoa_app_fxt.wiki_(app, "en.wiki");
parser = wiki.Html_mgr().Module_mgr().Popup_mgr().Parser();
parser.Init_by_wiki(wiki);
parser.Scan_len_(4);
parser.Html_fmtr().Fmt_("~{content}");
parser.Ellipsis_(Bry_.Empty);
parser.Notoc_(Bry_.Empty);
parser.Stop_at_hdr_(false);
parser.Output_js_clean_(false);
parser.Output_tidy_(false);
parser.Show_all_if_less_than_(-1);
parser.Xnde_ignore_ids_(Xoapi_popups.Dflt_coordinates);
parser.Read_til_stop_fwd_(-1);
parser.Cfg().Tmpl_read_len_(4);
parser.Cfg().Ellipsis_(Bry_.Empty);
parser.Cfg().Notoc_(Bry_.Empty);
parser.Cfg().Show_all_if_less_than_(-1);
parser.Cfg().Read_til_stop_fwd_(-1);
parser.Cfg().Read_til_stop_bwd_(-1);
parser.Cfg().Stop_if_hdr_after_(-1);
parser.Html_mkr().Fmtr_popup().Fmt_("~{content}");
parser.Html_mkr().Output_js_clean_(false);
parser.Html_mkr().Output_tidy_(false);
parser.Html_mkr().Fmtr_next_sect().Fmt_(" (~{next_sect_val})");
parser.Wrdx_mkr().Xnde_ignore_ids_(Xoapi_popups.Dflt_xnde_ignore_ids);
word_min = 2;
}
public Xop_popup_parser_fxt Init_scan_len_(int v) {parser.Scan_len_(v); return this;}
public Xop_popup_parser_fxt Init_scan_max_(int v) {parser.Scan_max_(v); return this;}
public Xop_popup_parser_fxt Init_word_min_(int v) {word_min = v; return this;}
public Xop_popup_parser_fxt Init_notoc_(String v) {parser.Cfg().Notoc_(Bry_.new_utf8_(v)); return this;}
public Xop_popup_parser_fxt Init_tmpl_read_len_(int v) {parser.Cfg().Tmpl_read_len_(v); return this;}
public Xop_popup_parser_fxt Init_tmpl_read_max_(int v) {parser.Cfg().Tmpl_read_max_(v); return this;}
public Xop_popup_parser_fxt Init_word_needed_(int v) {word_min = v; return this;}
public Xop_popup_parser_fxt Init_para_enabled_(boolean v) {parser.Wtxt_ctx().Para().Enabled_(v); return this;}
public Xop_popup_parser_fxt Init_stop_at_header_(boolean v) {parser.Stop_at_hdr_(v); return this;}
public Xop_popup_parser_fxt Init_ellipsis_(String v) {parser.Ellipsis_(Bry_.new_utf8_(v)); return this;}
public Xop_popup_parser_fxt Init_read_til_stop_fwd_(int v) {parser.Read_til_stop_fwd_(v); return this;}
public Xop_popup_parser_fxt Init_ellipsis_(String v) {parser.Cfg().Ellipsis_(Bry_.new_utf8_(v)); return this;}
public Xop_popup_parser_fxt Init_read_til_stop_fwd_(int v) {parser.Cfg().Read_til_stop_fwd_(v); return this;}
public Xop_popup_parser_fxt Init_read_til_stop_bwd_(int v) {parser.Cfg().Read_til_stop_bwd_(v); return this;}
public Xop_popup_parser_fxt Init_stop_if_hdr_after_(int v) {parser.Cfg().Stop_if_hdr_after_(v); return this;}
public Xop_popup_parser_fxt Init_tmpl_tkn_max_(int v) {parser.Tmpl_tkn_max_(v); return this;}
public Xop_popup_parser_fxt Init_fmtr_next_sect_(String v) {parser.Html_mkr().Fmtr_next_sect().Fmt_(v); return this;}
public Xop_popup_parser_fxt Init_page(String ttl, String txt) {Xop_fxt.Init_page_create_static(wiki, ttl, txt); return this;}
public Xop_popup_parser_fxt Test_ns_allowed(String raw, int... expd) {
Int_obj_ref[] ids = Xow_popup_mgr.Ns_allowed_parse(wiki, Bry_.new_utf8_(raw));
@ -384,7 +455,14 @@ class Xop_popup_parser_fxt {
Xoa_page page = Xoa_page.create_(wiki, Xoa_ttl.parse_(wiki, Bry_.new_ascii_("Test_1")));
page.Data_raw_(Bry_.new_utf8_(raw));
Xow_popup_itm itm = new Xow_popup_itm(1, Bry_.new_utf8_(raw), word_min);
byte[] actl = parser.Parse(itm, page, wiki.Domain_bry(), null);
itm.Init(wiki.Domain_bry(), page.Ttl());
byte[] actl = parser.Parse(wiki, page, null, itm);
Tfds.Eq_str_lines(expd, String_.new_utf8_(actl));
}
public void Test_Assert_at_end(String raw, String expd) {
if (test_bfr == null) test_bfr = Bry_bfr.new_();
test_bfr.Clear().Add_str(raw);
Bry_bfr_.Assert_at_end(test_bfr, Byte_ascii.NewLine);
Tfds.Eq(expd, test_bfr.XtoStrAndClear());
} private Bry_bfr test_bfr;
}

View File

@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*;
public class Xow_popup_word {
public Xow_popup_word(int tid, int bfr_bgn, int idx, int bgn, int end, Xop_tkn_itm tkn) {this.tid = tid; this.bfr_bgn = bfr_bgn; this.idx = idx; this.bgn = bgn; this.end = end; this.tkn = tkn;}
public int Tid() {return tid;} private int tid;
public int Bfr_bgn() {return bfr_bgn;} private int bfr_bgn;
public int Bfr_end() {return bfr_bgn + this.Len();}
public int Idx() {return idx;} private int idx;
public int Bgn() {return bgn;} private int bgn;
public int End() {return end;} private int end;
public int Len() {return end - bgn;}
public Xop_tkn_itm Tkn() {return tkn;} private Xop_tkn_itm tkn;
}

View File

@ -0,0 +1,202 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*;
import gplx.html.*;
import gplx.xowa.parsers.lnkes.*;
public class Xow_popup_wrdx_mkr {
private boolean skip_space;
private Xop_tkn_itm prv_tkn_seen, prv_tkn_added;
public Hash_adp_bry Xnde_id_ignore_list() {return xnde_id_ignore_list;} private Hash_adp_bry xnde_id_ignore_list = Hash_adp_bry.ci_ascii_();
public void Init() {
skip_space = false;
prv_tkn_seen = prv_tkn_added = null;
}
public void Process_tkn(Xow_popup_cfg cfg, Xow_popup_parser_data data, Bry_bfr wrdx_bfr, Xop_tkn_itm tkn, byte[] wtxt_bry, int wtxt_len) {
boolean add_tkn = true, add_subs = true; Xop_xnde_tkn xnde = null;
int tkn_src_bgn = tkn.Src_bgn(), tkn_src_end = tkn.Src_end();
prv_tkn_seen = tkn;
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_root:
add_tkn = false; // don't add_tkn root
break;
case Xop_tkn_itm_.Tid_txt:
data.Words_found_add(tkn);
break;
case Xop_tkn_itm_.Tid_apos:
if ( prv_tkn_added != null
&& prv_tkn_seen != prv_tkn_added // prv seen tkn was skipped
&& prv_tkn_added.Tkn_tid() == Xop_tkn_itm_.Tid_apos // prv added tkn was apos
)
wrdx_bfr.Add_byte_space(); // prv && cur are apos, but something was skipped inbetween; add a space so that apos doesn't combine EX:''{{skip}}'' x> ''''; PAGE:en.w:Somalia; DATE:2014-07-02
break;
case Xop_tkn_itm_.Tid_ignore: // always skip ignores, particularly comments; PAGE:en.w:List_of_countries_by_GDP_(PPP); DATE:2014-07-01
case Xop_tkn_itm_.Tid_tblw_tb: case Xop_tkn_itm_.Tid_tblw_tc: case Xop_tkn_itm_.Tid_tblw_td:
case Xop_tkn_itm_.Tid_tblw_te: case Xop_tkn_itm_.Tid_tblw_th: case Xop_tkn_itm_.Tid_tblw_tr:
add_tkn = add_subs = false; // skip tblws
break;
case Xop_tkn_itm_.Tid_xnde:
xnde = (Xop_xnde_tkn)tkn;
switch (xnde.Tag().Id()) {
case Xop_xnde_tag_.Tid_div:
case Xop_xnde_tag_.Tid_table: case Xop_xnde_tag_.Tid_tr: case Xop_xnde_tag_.Tid_td: case Xop_xnde_tag_.Tid_th:
case Xop_xnde_tag_.Tid_caption: case Xop_xnde_tag_.Tid_thead: case Xop_xnde_tag_.Tid_tfoot: case Xop_xnde_tag_.Tid_tbody:
case Xop_xnde_tag_.Tid_ref: case Xop_xnde_tag_.Tid_gallery: case Xop_xnde_tag_.Tid_imageMap: case Xop_xnde_tag_.Tid_timeline:
case Xop_xnde_tag_.Tid_xowa_html: // needed for Help:Options, else \n at top of doc; DATE:2014-06-22
add_tkn = add_subs = false; // skip tblxs
xnde = null;
break;
case Xop_xnde_tag_.Tid_math: // add <math> as one unit; PAGE:en.w:System_of_polynomial_equations DATE:2014-07-01
add_subs = false; // never recur
xnde = null;
data.Words_found_add(tkn); // treat it as one word
break;
case Xop_xnde_tag_.Tid_br:
add_tkn = false; // never add_tkn Src_bgn / Src_end; note add_subs should still be true; PAGE:en.q:Earth; DATE:2014-06-30
if (wrdx_bfr.Len_eq_0()) // don't add <br/> to start of document; needed for Help:Options, but good to have everywhere; DATE:2014-06-22
add_subs = false;
break;
default:
add_tkn = false; // don't add_tkn xnde, but still add_subs
if (Xnde_id_ignore_list_chk(xnde, wtxt_bry)) {
add_subs = false;
xnde = null;
}
break;
}
break;
case Xop_tkn_itm_.Tid_lnke:
Xop_lnke_tkn lnke = (Xop_lnke_tkn)tkn;
switch (lnke.Lnke_typ()) {
case Xop_lnke_tkn.Lnke_typ_brack:
Process_subs(cfg, data, wrdx_bfr, tkn, wtxt_bry, wtxt_len, Bool_.N); // add subs which are caption tkns; note that Bool_.N will add all words so that captions don't get split; EX: "a [http://a.org b c d]" -> "a b c d" if words_needed == 2;
add_tkn = add_subs = false; // ignore lnke, but add any text tkns; EX: [http://a.org b c d] -> "b c d"
break;
case Xop_lnke_tkn.Lnke_typ_text:
data.Words_found_add(tkn); // increment words_found; EX: a http://b.org c -> 3 words;
break;
}
break;
case Xop_tkn_itm_.Tid_lnki:
Xop_lnki_tkn lnki = (Xop_lnki_tkn)tkn;
switch (lnki.Ns_id()) {
case Xow_ns_.Id_category: // skip [[Category:]]
case Xow_ns_.Id_file: // skip [[File:]]
add_tkn = add_subs = false;
break;
default:
data.Words_found_add(tkn); // increment words_found; EX: a [[B|c d e]] f -> 3 words;
break;
}
break;
case Xop_tkn_itm_.Tid_space:
if ( skip_space // previous tkn skipped add and set skip_space to true
&& wrdx_bfr.Match_end_byt_nl_or_bos() // only ignore space if it will cause pre; note that some <ref>s will have spaces that should be preserved; EX:"a<ref>b</ref> c"; PAGE:en.w:Mehmed_the_Conqueror; DATE:2014-06-18
)
add_tkn = false; // skip ws
break;
case Xop_tkn_itm_.Tid_newLine: {
// heuristic to handle skipped <div> / <table> which does not skip \n; EX:"<div>a</div>\nb"; div is skipped, but "\n" remains; PAGE:en.w:Eulogy;DATE:2014-06-18
int wrdx_bfr_len = wrdx_bfr.Len();
if (wrdx_bfr_len == 0) // don't add_tkn \n at bos; does not handle pages where bos intentionally has multiple \n\n
add_tkn = false;
else if (wrdx_bfr_len > 2) { // bounds check
if (Wtxt_bfr_ends_w_2_nl(wrdx_bfr, wrdx_bfr_len)) // don't add \n if "\n\n"; does not handle intentional sequences of 2+ \n;
add_tkn = false;
}
break;
}
case Xop_tkn_itm_.Tid_hdr: {
data.Words_found_add(tkn); // count entire header as one word; not worth counting words in header
add_subs = false; // add entire tkn; do not add_subs
int wrdx_bfr_len = wrdx_bfr.Len();
if (wrdx_bfr_len > 2) { // bounds check
if (Wtxt_bfr_ends_w_2_nl(wrdx_bfr, wrdx_bfr_len)) // heuristic: 2 \n in bfr, and about to add a hdr tkn which starts with "\n"; delete last \n
wrdx_bfr.Del_by_1();
}
if ( tkn_src_end < wtxt_len // bounds check
&& wtxt_bry[tkn_src_end] == Byte_ascii.NewLine // hdr_tkn will not include trailing "\n". add it; note that this behavior is by design. NOTE:hdr.trailing_nl; DATE:2014-06-17
) {
wrdx_bfr.Add_mid(wtxt_bry, tkn_src_bgn, tkn_src_end + 1); // +1 to add the trailing \n
add_tkn = false;
}
break;
}
default:
break;
}
skip_space = false; // always reset; only used once above for Tid_space; DATE:2014-06-17
if (add_tkn && xnde == null) {
if (tkn_src_end - tkn_src_bgn > 0) { // handle paras which have src_bgn == src_end
wrdx_bfr.Add_mid(wtxt_bry, tkn_src_bgn, tkn_src_end);
prv_tkn_added = tkn;
}
}
else // tkn not added
skip_space = true; // skip next space; note this is done with member variable to handle recursive iteration; DATE:2014-06-17
if (add_subs) {
if (xnde != null) wrdx_bfr.Add_mid(wtxt_bry, xnde.Tag_open_bgn(), xnde.Tag_open_end()); // add open tag; EX: "<span id=a>"
Process_subs(cfg, data, wrdx_bfr, tkn, wtxt_bry, wtxt_len, Bool_.Y);
if (xnde != null) wrdx_bfr.Add_mid(wtxt_bry, xnde.Tag_close_bgn(), xnde.Tag_close_end()); // add close tag; EX: "</span>"
}
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_hdr:
if ( cfg.Stop_if_hdr_after_enabled()
&& data.Stop_if_hdr_after_chk(cfg))
return;
break;
}
}
private void Process_subs(Xow_popup_cfg cfg, Xow_popup_parser_data data, Bry_bfr wrdx_bfr, Xop_tkn_itm tkn, byte[] wtxt_bry, int wtxt_len, boolean chk_words_found) {
int subs_len = tkn.Subs_len();
for (int i = 0; i < subs_len; i++) {
Xop_tkn_itm sub = tkn.Subs_get(i);
Process_tkn(cfg, data, wrdx_bfr, sub, wtxt_bry, wtxt_len);
if (chk_words_found && !data.Words_needed_chk()) break;
}
}
private boolean Xnde_id_ignore_list_chk(Xop_xnde_tkn xnde, byte[] src) {
Xop_xatr_itm[] atrs_ary = xnde.Atrs_ary();
int atrs_len = atrs_ary.length;
for (int i = 0; i < atrs_len; i++) {
Xop_xatr_itm atr = atrs_ary[i];
if ( Bry_.Eq(atr.Key_bry(), Html_atr_.Id_bry)
&& xnde_id_ignore_list.Get_by_bry(atr.Val_as_bry(src)) != null
) {
return true;
}
}
return false;
}
public void Xnde_ignore_ids_(byte[] xnde_id_ignore_bry) {
byte[][] ary = Bry_.Split(xnde_id_ignore_bry, Byte_ascii.Pipe);
int ary_len = ary.length;
xnde_id_ignore_list.Clear();
for (int i = 0; i < ary_len; i++) {
byte[] bry = ary[i];
if (bry.length == 0) continue; // ignore empty entries; EX: "a|"
xnde_id_ignore_list.Add(bry, bry);
}
}
private boolean Wtxt_bfr_ends_w_2_nl(Bry_bfr wrdx_bfr, int wrdx_bfr_len) {
byte[] hdom_bfr_bry = wrdx_bfr.Bfr();
return
( hdom_bfr_bry[wrdx_bfr_len - 1] == Byte_ascii.NewLine // prv 2 bytes are \n
&& hdom_bfr_bry[wrdx_bfr_len - 2] == Byte_ascii.NewLine
);
}
}

View File

@ -0,0 +1,47 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups.keeplists; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*; import gplx.xowa.html.modules.popups.*;
import gplx.core.regxs.*;
public class Xop_keeplist_rule {
public Xop_keeplist_rule(Gfo_pattern[] includes, Gfo_pattern[] excludes) {
this.includes = includes; this.includes_len = includes.length;
this.excludes = excludes; this.excludes_len = excludes.length;
}
public Gfo_pattern[] Includes() {return includes;} private Gfo_pattern[] includes; private int includes_len;
private Gfo_pattern[] excludes; private int excludes_len;
public boolean Match(byte[] ttl) {
boolean match_found = false;
for (int i = 0; i < includes_len; ++i) {
Gfo_pattern skip = includes[i];
if (skip.Match(ttl)) {
match_found = true;
break;
}
}
if (match_found) {
for (int i = 0; i < excludes_len; ++i) {
Gfo_pattern keep = excludes[i];
if (keep.Match(ttl)) {
match_found = false;
break;
}
}
}
return match_found;
}
}

View File

@ -0,0 +1,49 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups.keeplists; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*; import gplx.xowa.html.modules.popups.*;
import gplx.core.regxs.*;
public class Xop_keeplist_wiki {
public Xop_keeplist_wiki(Xow_wiki wiki) {
srl = new Xop_keeplist_wiki_srl(wiki);
}
public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled = false; // NOTE: default to false, b/c wikis that are not listed in cfg will not call Rules_seal
public Xop_keeplist_rule[] Rules() {return rules;} private Xop_keeplist_rule[] rules; private int rules_len;
public Xop_keeplist_wiki_srl Srl() {return srl;} private Xop_keeplist_wiki_srl srl;
public void Rules_add(Xop_keeplist_rule rule) {rules_list.Add(rule);} private ListAdp rules_list = ListAdp_.new_();
public void Rules_seal() {
this.rules = (Xop_keeplist_rule[])rules_list.XtoAryAndClear(Xop_keeplist_rule.class);
this.rules_len = rules.length;
if (rules_len == 0) return;
if (rules_len == 1) {
Xop_keeplist_rule rule_0 = rules[0];
if (rule_0.Includes().length == 0)
enabled = false;
else
enabled = true;
}
else
enabled = true;
}
public boolean Match(byte[] ttl) {
for (int i = 0; i < rules_len; ++i) {
Xop_keeplist_rule rule = rules[i];
if (rule.Match(ttl)) return true;
}
return false;
}
}

View File

@ -0,0 +1,66 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups.keeplists; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*; import gplx.xowa.html.modules.popups.*;
import gplx.srls.dsvs.*;
import gplx.core.regxs.*;
import gplx.xowa.langs.cases.*;
public class Xop_keeplist_wiki_srl extends Dsv_wkr_base {
private Xol_case_mgr case_mgr; private Xow_wiki wiki;
private byte[] wiki_bry;
private byte[] keeps_bry;
private byte[] skips_bry;
private int rules_count;
public Xop_keeplist_wiki_srl(Xow_wiki wiki) {this.wiki = wiki; this.case_mgr = wiki.Lang().Case_mgr();}
@Override public Dsv_fld_parser[] Fld_parsers() {return new Dsv_fld_parser[] {Dsv_fld_parser_.Bry_parser, Dsv_fld_parser_.Bry_parser, Dsv_fld_parser_.Bry_parser};}
@Override public boolean Write_bry(Dsv_tbl_parser parser, int fld_idx, byte[] src, int bgn, int end) {
switch (fld_idx) {
case 0: wiki_bry = Xoa_ttl.Replace_spaces(case_mgr.Case_build_lower(Bry_.Mid(src, bgn, end))); return true;
case 1: keeps_bry = Xoa_ttl.Replace_spaces(case_mgr.Case_build_lower(Bry_.Mid(src, bgn, end))); return true;
case 2: skips_bry = Xoa_ttl.Replace_spaces(case_mgr.Case_build_lower(Bry_.Mid(src, bgn, end))); return true;
default: return false;
}
}
@Override public void Commit_itm(Dsv_tbl_parser parser, int pos) {
if (wiki_bry == null) throw parser.Err_row_bgn("wikis missing", pos);
if (keeps_bry == null) throw parser.Err_row_bgn("keeps missing", pos);
if (skips_bry == null) throw parser.Err_row_bgn("skips missing", pos);
if (!Bry_.Eq(wiki_bry, wiki.Domain_bry())) return;
Xop_keeplist_wiki tmpl_keeplist = Get_tmpl_keeplist();
Gfo_pattern[] keeps = Gfo_pattern.Parse_to_ary(keeps_bry);
Gfo_pattern[] skips = Gfo_pattern.Parse_to_ary(skips_bry);
Xop_keeplist_rule rule = new Xop_keeplist_rule(keeps, skips);
tmpl_keeplist.Rules_add(rule);
wiki_bry = skips_bry = keeps_bry = null;
++rules_count;
}
@Override public void Load_by_bry_end() {
if (rules_count == 0) return; // NOTE: keeplist set in global cfg, so fires when each wiki loads; if loading wiki does not match keeplist, then noop; DATE:2014-07-05
Xop_keeplist_wiki tmpl_keeplist = Get_tmpl_keeplist();
tmpl_keeplist.Rules_seal();
rules_count = 0;
}
public Xop_keeplist_wiki Get_tmpl_keeplist() {
Xow_popup_parser popup_parser = wiki.Html_mgr().Module_mgr().Popup_mgr().Parser();
Xop_keeplist_wiki rv = popup_parser.Tmpl_keeplist();
if (rv == null) {
rv = new Xop_keeplist_wiki(wiki);
popup_parser.Tmpl_keeplist_(rv);
}
return rv;
}
}

View File

@ -0,0 +1,61 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.html.modules.popups.keeplists; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; import gplx.xowa.html.modules.*; import gplx.xowa.html.modules.popups.*;
import org.junit.*;
public class Xop_keeplist_wiki_tst {
@Before public void init() {fxt.Clear();} private Xop_keeplist_wiki_fxt fxt = new Xop_keeplist_wiki_fxt();
@Test public void Tmpl_keeplist() {
Xop_keeplist_wiki keeplist_wiki = fxt.keeplist_wiki_(String_.Concat_lines_nl
( "enwiki|a*|abc*"
));
fxt.Test_Match_y(keeplist_wiki, "a", "ab");
fxt.Test_Match_n(keeplist_wiki, "abc", "abcd", "d");
}
@Test public void Tmpl_keeplist2() {
Xop_keeplist_wiki keeplist_wiki = fxt.keeplist_wiki_(String_.Concat_lines_nl
( "enwiki|a*|abc*"
, "enwiki|b*|*xyz"
));
fxt.Test_Match_y(keeplist_wiki, "a", "ab");
fxt.Test_Match_n(keeplist_wiki, "d", "abc", "abcd");
fxt.Test_Match_y(keeplist_wiki, "b", "bxy");
fxt.Test_Match_n(keeplist_wiki, "bxyz", "bcdxyz");
}
}
class Xop_keeplist_wiki_fxt {
public void Clear() {
}
public Xop_keeplist_wiki keeplist_wiki_(String raw) {
Xoa_app app = Xoa_app_fxt.app_();
Xow_wiki wiki = Xoa_app_fxt.wiki_(app, "enwiki");
Xow_popup_mgr popup_mgr = wiki.Html_mgr().Module_mgr().Popup_mgr();
popup_mgr.Init_by_wiki(wiki);
popup_mgr.Parser().Tmpl_keeplist_init_(Bry_.new_utf8_(raw));
Xop_keeplist_wiki rv = popup_mgr.Parser().Tmpl_keeplist();
return rv;
}
public void Test_Match_y(Xop_keeplist_wiki keeplist_wiki, String... itms) {Test_Match(keeplist_wiki, itms, Bool_.Y);}
public void Test_Match_n(Xop_keeplist_wiki keeplist_wiki, String... itms) {Test_Match(keeplist_wiki, itms, Bool_.N);}
private void Test_Match(Xop_keeplist_wiki keeplist_wiki, String[] itms, boolean expd) {
int len = itms.length;
for (int i = 0; i < len; i++) {
String itm = itms[i];
Tfds.Eq(expd, keeplist_wiki.Match(Bry_.new_utf8_(itm)), "itm={0} expd={1}", itm, expd);
}
}
}

View File

@ -190,6 +190,7 @@ class Xowh_sidebar_mgr_fxt {
sidebar_mgr = wiki.Html_mgr().Portal_mgr().Sidebar_mgr();
bfr = Bry_bfr.reset_(Io_mgr.Len_kb);
comment_bfr = Bry_bfr.reset_(Io_mgr.Len_kb);
Init_popups_enabled_(false);
// }
return this;
}

View File

@ -63,9 +63,9 @@ public class Xoh_tidy_mgr implements GfoInvkAble {
}
public static boolean Tidy_unwrap(Bry_bfr bfr) {
byte[] bfr_bry = bfr.Bfr();
int find = Bry_finder.Find_fwd(bfr_bry, Html_tags.Body_lhs); if (find == Bry_finder.Not_found) return false;
bfr.Delete_rng_to_bgn(find + Html_tags.Body_lhs.length);
find = Bry_finder.Find_bwd(bfr_bry, Html_tags.Body_rhs, bfr.Len()); if (find == Bry_finder.Not_found) return false;
int find = Bry_finder.Find_fwd(bfr_bry, Html_tag_.Body_lhs); if (find == Bry_finder.Not_found) return false;
bfr.Delete_rng_to_bgn(find + Html_tag_.Body_lhs.length);
find = Bry_finder.Find_bwd(bfr_bry, Html_tag_.Body_rhs, bfr.Len()); if (find == Bry_finder.Not_found) return false;
bfr.Delete_rng_to_end(find);
return true;
}

View File

@ -48,7 +48,7 @@ public class Xoh_js_cleaner {
int frag_len = frag.length;
if (frag[0] == Byte_ascii.Lt) { // jscript node; EX: <script
if (!dirty) {bfr.Add_mid(src, bgn, pos); dirty = true;}
bfr.Add(gplx.html.Html_consts.Lt);
bfr.Add(gplx.html.Html_entity_.Lt_bry);
bfr.Add_mid(frag, 1, frag.length);
pos += frag_len;
}
@ -59,7 +59,7 @@ public class Xoh_js_cleaner {
else {
if (!dirty) {bfr.Add_mid(src, bgn, pos); dirty = true;}
bfr.Add(frag);
bfr.Add(gplx.html.Html_consts.Eq);
bfr.Add(gplx.html.Html_entity_.Eq_bry);
pos = atr_pos;
}
}

View File

@ -16,7 +16,8 @@ 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.langs.cases; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
public interface Xol_case_itm {
import gplx.intl.*;
public interface Xol_case_itm extends Gfo_case_itm {
byte Tid();
byte[] Src_ary();
byte[] Trg_ary();
@ -30,12 +31,12 @@ class Xol_case_itm_byt implements Xol_case_itm {
public Xol_case_itm_byt(byte tid, byte src_byte, byte trg_byte) {
this.tid = tid; this.src_byte = src_byte; this.trg_byte = trg_byte; this.src_ary = new byte[] {src_byte}; this.trg_ary = new byte[] {trg_byte};
switch (tid) {
case Xol_case_itm_.Tid_both: upper_byte = trg_byte; lower_byte = src_byte; break;
case Xol_case_itm_.Tid_upper: upper_byte = trg_byte; break;
case Xol_case_itm_.Tid_lower: lower_byte = trg_byte; break;
case Xol_case_itm_.Tid_both:
case Xol_case_itm_.Tid_upper: upper_byte = trg_byte; lower_byte = src_byte; break;
case Xol_case_itm_.Tid_lower: upper_byte = src_byte; lower_byte = trg_byte; break;
}
}
public byte Tid() {return tid;} public Xol_case_itm_byt Tid_(byte v) {tid = v; return this;} private byte tid;
public byte Tid() {return tid;} private byte tid;
public byte[] Src_ary() {return src_ary;} private byte[] src_ary;
public byte[] Trg_ary() {return trg_ary;} private byte[] trg_ary;
public byte Src_byte() {return src_byte;} private byte src_byte;
@ -45,17 +46,27 @@ class Xol_case_itm_byt implements Xol_case_itm {
public void Case_reuse_upper(byte[] ary, int bgn, int len) {ary[bgn] = upper_byte;}
public void Case_reuse_lower(byte[] ary, int bgn, int len) {ary[bgn] = lower_byte;}
public Xol_case_itm Clone() {return new Xol_case_itm_byt(tid, src_byte, trg_byte);}
public int Utf8_id_lower() {return lower_byte;}
public boolean Eq_lo(Gfo_case_itm trg_obj) {
Xol_case_itm_byt trg_itm = (Xol_case_itm_byt)trg_obj;
return lower_byte == trg_itm.lower_byte;
}
public int Hashcode_lo() {return lower_byte;}
public int Len_lo() {return 1;}
}
class Xol_case_itm_ary implements Xol_case_itm {
public Xol_case_itm_ary(byte tid, byte[] src_ary, byte[] trg_ary) {
class Xol_case_itm_bry implements Xol_case_itm {
public Xol_case_itm_bry(byte tid, byte[] src_ary, byte[] trg_ary) {
this.tid = tid; this.src_ary = src_ary; this.trg_ary = trg_ary;
switch (tid) {
case Xol_case_itm_.Tid_both: upper_ary = trg_ary; lower_ary = src_ary; break;
case Xol_case_itm_.Tid_upper: upper_ary = trg_ary; break;
case Xol_case_itm_.Tid_lower: lower_ary = trg_ary; break;
case Xol_case_itm_.Tid_both:
case Xol_case_itm_.Tid_upper: upper_ary = trg_ary; lower_ary = src_ary; break;
case Xol_case_itm_.Tid_lower: upper_ary = src_ary; lower_ary = trg_ary; break;
}
len_lo = lower_ary.length;
utf8_id_lo = Utf16_.Decode_to_int(lower_ary, 0);
hashcode_ci_lo = Bry_obj_ref.CalcHashCode(lower_ary, 0, len_lo);
}
public byte Tid() {return tid;} public Xol_case_itm_ary Tid_(byte v) {tid = v; return this;} private byte tid;
public byte Tid() {return tid;} public Xol_case_itm_bry Tid_(byte v) {tid = v; return this;} private byte tid;
public byte[] Src_ary() {return src_ary;} private byte[] src_ary;
public byte[] Trg_ary() {return trg_ary;} private byte[] trg_ary;
public void Case_build_upper(Bry_bfr bfr) {bfr.Add(upper_ary);} private byte[] upper_ary;
@ -68,5 +79,12 @@ class Xol_case_itm_ary implements Xol_case_itm {
for (int i = 0; i < len; i++)
ary[i + bgn] = lower_ary[i];
}
public Xol_case_itm Clone() {return new Xol_case_itm_ary(tid, src_ary, trg_ary);}
public Xol_case_itm Clone() {return new Xol_case_itm_bry(tid, src_ary, trg_ary);}
public int Len_lo() {return len_lo;} private int len_lo;
public int Utf8_id_lo() {return utf8_id_lo;} private int utf8_id_lo;
public boolean Eq_lo(Gfo_case_itm trg_obj) {
Xol_case_itm_bry trg_itm = (Xol_case_itm_bry)trg_obj;
return utf8_id_lo == trg_itm.utf8_id_lo;
}
public int Hashcode_lo() {return hashcode_ci_lo;} private int hashcode_ci_lo;
}

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,17 @@ 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.langs.cases; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
public class Xol_case_mgr implements GfoInvkAble {
import gplx.intl.*;
public class Xol_case_mgr implements GfoInvkAble, Gfo_case_mgr {
private Bry_bfr tmp_bfr = Bry_bfr.new_(); private ByteTrieMgr_fast upper_trie = ByteTrieMgr_fast.cs_(), lower_trie = ByteTrieMgr_fast.cs_(); private Xol_case_itm[] itms;
public Xol_case_mgr(byte tid) {this.tid = tid;}
public byte Tid() {return tid;} private byte tid;
public Gfo_case_itm Get_or_null(byte bgn_byte, byte[] src, int bgn, int end) {
Object rv = lower_trie.Match(bgn_byte, src, bgn, end);
return rv == null
? (Gfo_case_itm)upper_trie.Match(bgn_byte, src, bgn, end)
: (Gfo_case_itm)rv;
}
public void Clear() {upper_trie.Clear(); lower_trie.Clear();}
public boolean Match(byte b, byte[] src, int bgn_pos, int end_pos) {
return upper_trie.Match(b, src, bgn_pos, end_pos) != null
@ -117,18 +126,9 @@ public class Xol_case_mgr implements GfoInvkAble {
bfr.Add_mid(src, bgn + b_len, end);
return bfr.XtoAryAndClear();
}
public Xol_case_mgr Clone() {
Xol_case_mgr rv = new Xol_case_mgr();
int itms_len = itms == null ? 0 : itms.length;
Xol_case_itm[] rv_ary = new Xol_case_itm[itms_len];
for (int i = 0; i < itms_len; i++)
rv_ary[i] = itms[i].Clone();
rv.itms = rv_ary;
return rv;
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_add_bulk)) Add_bulk(m.ReadBry("v"));
else if (ctx.Match(k, Invk_clear)) Clear();
else if (ctx.Match(k, Invk_clear)) throw Err_.not_implemented_();
else return GfoInvkAble_.Rv_unhandled;
return this;
} private static final String Invk_clear = "clear", Invk_add_bulk = "add_bulk";

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.langs.cases; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
import org.junit.*;
public class Xol_case_mgr_tst {
Xol_case_mgr_fxt fxt = new Xol_case_mgr_fxt();
@Before public void init() {fxt.Clear();}
@Before public void init() {fxt.Clear();} private Xol_case_mgr_fxt fxt = new Xol_case_mgr_fxt();
@Test public void Mw_parse() {
fxt.parse_mw__tst(fxt.itm_both_("A", "a"), fxt.itm_both_("B", "b"));
}
@ -40,7 +39,7 @@ public class Xol_case_mgr_tst {
fxt.Test_reuse_1st_upper("É");
}
// @Test public void Hack() {
// Xol_case_itm[] ary = Xol_case_itm_.Universal;
// Xol_case_itm[] ary = Xol_case_mgr_.Utf_8;
// Bry_bfr bfr = Bry_bfr.new_();
// for (int i = 0; i < ary.length; i++) {
// Xol_case_itm itm = ary[i];
@ -52,13 +51,11 @@ public class Xol_case_mgr_tst {
// }
}
class Xol_case_mgr_fxt {
Xol_case_mgr case_mgr = new Xol_case_mgr();
public void Clear() {
case_mgr.Clear();
} String_bldr sb = String_bldr_.new_();
public Xol_case_itm_ary itm_both_(String src, String trg) {return new Xol_case_itm_ary(Xol_case_itm_.Tid_both , Bry_.new_utf8_(src), Bry_.new_utf8_(trg));}
public Xol_case_itm_ary itm_upper_(String src, String trg) {return new Xol_case_itm_ary(Xol_case_itm_.Tid_upper, Bry_.new_utf8_(src), Bry_.new_utf8_(trg));}
public Xol_case_itm_ary itm_lower_(String src, String trg) {return new Xol_case_itm_ary(Xol_case_itm_.Tid_lower, Bry_.new_utf8_(src), Bry_.new_utf8_(trg));}
private Xol_case_mgr case_mgr = Xol_case_mgr_.new_(); private String_bldr sb = String_bldr_.new_();
public void Clear() {case_mgr.Clear();}
public Xol_case_itm_bry itm_both_(String src, String trg) {return new Xol_case_itm_bry(Xol_case_itm_.Tid_both , Bry_.new_utf8_(src), Bry_.new_utf8_(trg));}
public Xol_case_itm_bry itm_upper_(String src, String trg) {return new Xol_case_itm_bry(Xol_case_itm_.Tid_upper, Bry_.new_utf8_(src), Bry_.new_utf8_(trg));}
public Xol_case_itm_bry itm_lower_(String src, String trg) {return new Xol_case_itm_bry(Xol_case_itm_.Tid_lower, Bry_.new_utf8_(src), Bry_.new_utf8_(trg));}
public String Init_ltrs_raw() {
return String_.Concat_lines_nl
( "0|a|A"
@ -67,11 +64,12 @@ class Xol_case_mgr_fxt {
);
}
public Xol_case_mgr_fxt Init_ltrs() {
case_mgr = Xol_case_mgr_.new_();
case_mgr.Add_bulk(Bry_.new_utf8_(Init_ltrs_raw()));
return this;
}
public Xol_case_mgr_fxt Init_ltrs_universal() {
case_mgr.Add_bulk(Xol_case_itm_.Universal);
case_mgr = Xol_case_mgr_.Utf8();
return this;
}
public Xol_case_mgr_fxt Upper(String raw_str, String expd) {return Case_build(Bool_.Y, raw_str, expd);}
@ -82,10 +80,10 @@ class Xol_case_mgr_fxt {
Tfds.Eq(expd, String_.new_utf8_(actl));
return this;
}
public void parse_xo__tst(String raw, Xol_case_itm_ary... expd) {
public void parse_xo__tst(String raw, Xol_case_itm_bry... expd) {
Tfds.Eq_str_lines(Xto_str(expd), Xto_str(Xol_case_itm_.parse_xo_(Bry_.new_utf8_(raw))));
}
public void parse_mw__tst(Xol_case_itm_ary... expd) {
public void parse_mw__tst(Xol_case_itm_bry... expd) {
String raw = raw_(expd);
Xol_case_itm[] actl = Xol_case_itm_.parse_mw_(Bry_.new_utf8_(raw));
Tfds.Eq_str_lines(Xto_str(expd), Xto_str(actl));
@ -98,11 +96,11 @@ class Xol_case_mgr_fxt {
}
return sb.XtoStrAndClear();
}
public String raw_(Xol_case_itm_ary[] itms) {
public String raw_(Xol_case_itm_bry[] itms) {
int itms_len = itms.length;
uppers_list.Clear(); lowers_list.Clear();
for (int i = 0; i < itms_len; i++) {
Xol_case_itm_ary itm = itms[i];
Xol_case_itm_bry itm = itms[i];
String src = String_.new_utf8_(itm.Src_ary());
String trg = String_.new_utf8_(itm.Trg_ary());
switch (itm.Tid()) {

View File

@ -21,19 +21,24 @@ import gplx.xowa.langs.vnts.*;
public class Xol_cnv_mgr_tst {
private Xol_cnv_mgr_fxt fxt = new Xol_cnv_mgr_fxt();
@Before public void init() {fxt.Clear();}
// @Test public void Basic() {
// fxt.Test_convert("zh", "zh-hant", "abcd", "AbCd");
// }
// @Test public void Convert() {
// Xol_cnv_mgr_fxt.Init_convert_file(fxt.App(), "zh", "zh-hans", KeyVal_.new_("a", "x"));
// fxt.Parser_fxt().Init_defn_clear();
// fxt.Parser_fxt().Init_defn_add("convert_x", "val");
// fxt.Parser_fxt().Test_parse_tmpl_str_test("{{convert_a}}", "{{test}}", "val");
// fxt.Parser_fxt().Init_defn_clear();
// }
@Test public void Ifexists() {
fxt.Parser_fxt().Init_page_create("Test_A");
fxt.Test_parse("{{#ifexist:Test_a|y|n}}", "y");
@Test public void Basic() {
fxt.Parser_fxt().Init_page_create("Template:Test_x1", "val");
fxt.Parser_fxt().Test_parse_tmpl_str_test("{{Test_x0}}", "{{test}}", "val");
}
@Test public void Upper_1st() { // PURPOSE: convert should call Xoa_ttl.parse_(), which will upper 1st letter; EX:{{jez-eng|sense}} -> Jez-eng; PAGE:sr.w:ДНК DATE:2014-07-06
fxt.Parser_fxt().Init_page_create("Template:X1", "val");
fxt.Parser_fxt().Test_parse_tmpl_str_test("{{x0}}", "{{test}}", "val");
}
@Test public void Redlink() { // PURPOSE: check redlink's Convert_ttl(Xow_wiki wiki, Xoa_ttl ttl); DATE:2014-07-06
fxt.Parser_fxt().Init_page_create("Template:Test_x1", "val");
fxt.Test_convert_by_ttl("zh", "Template:Test_x0", Bool_.Y); // Template:Test_xo should not be parsed to Template:Template:Test_x0; EX:Шаблон:Šablon:Jez-eng; PAGE:sr.w:ДНК DATE:2014-07-06
fxt.Test_convert_by_ttl("zh", "Template:Test_x1", Bool_.N); // note that convert of trg should not find title;
fxt.Test_convert_by_ttl("zh", "Template:Test_x2", Bool_.N); // test that non-convert characters return false
}
@Test public void Pfunc() {
fxt.Parser_fxt().Init_defn_clear();
fxt.Parser_fxt().Init_page_create("Test_x1");
fxt.Test_parse("{{#ifexist:Test_x0|y|n}}", "y");
}
}
class Xol_cnv_mgr_fxt {
@ -44,7 +49,7 @@ class Xol_cnv_mgr_fxt {
app = Xoa_app_fxt.app_();
Xol_lang lang = app.Lang_mgr().Get_by_key_or_new(Bry_.new_utf8_("zh"));
Xol_lang_.Lang_init(lang);
Init_cnv(app, "zh", "zh-hant", KeyVal_.new_("a", "A"));
Init_cnv(app, "zh", "zh-hant", KeyVal_.new_("x0", "x1"));
lang.Vnt_mgr().Enabled_(true);
lang.Vnt_mgr().Convert_ttl_init();
wiki = Xoa_app_fxt.wiki_(app, "zh.wikipedia.org", lang);
@ -62,14 +67,23 @@ class Xol_cnv_mgr_fxt {
vnt_itm.Convert_ary_(Bry_.Ary(vnt_key));
vnt_itm.Converter().Rebuild();
}
public void Test_convert(String lang, String vnt, String raw, String expd) {
// public void Test_convert(String lang, String vnt, String raw, String expd) {
// Xol_cnv_grp convert_grp = app.Lang_mgr().Get_by_key_or_new(Bry_.new_ascii_(lang)).Cnv_mgr().Get_or_new(Bry_.new_ascii_(vnt));
// Bry_bfr bfr = Bry_bfr.new_();
// boolean converted = convert_grp.Convert_to_bfr(bfr, Bry_.new_utf8_(raw));
// String actl = converted ? bfr.XtoStrAndClear() : raw;
// Tfds.Eq(expd, actl);
}
// }
public void Test_parse(String raw, String expd) {
parser_fxt.Test_parse_page_all_str(raw, expd);
}
public void Test_convert_by_ttl(String lang_key, String raw, boolean expd) {
Xol_lang lang = app.Lang_mgr().Get_by_key_or_new(Bry_.new_ascii_(lang_key));
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_utf8_(raw));
Xodb_page page = lang.Vnt_mgr().Convert_ttl(wiki, ttl);
if (expd)
Tfds.Eq_true(page.Exists());
else
Tfds.Eq_null(page);
}
}

View File

@ -118,7 +118,7 @@ class Xol_mw_parse_fxt {
private ListAdp tmp_itm_list = ListAdp_.new_();
private Xol_mw_parse_grp Parse_grp(Php_line_assign line) {
Xol_mw_parse_grp grp = new Xol_mw_parse_grp();
byte[] key = line.Key().Val_obj_bry(); // EX: "zh2Hant"
byte[] key = line.Key().Val_obj_bry(); // EX: "zh2Hant"
key = Bry_.Lower_ascii(key); // EX: "zh2hant"
byte[][] parts = Bry_.Split(key, Byte_ascii.Num_2); // EX: "zh", "hant"
byte[] src = parts[0];

View File

@ -48,7 +48,7 @@ public class Xol_vnt_mgr implements GfoInvkAble {
if (i == 0) cur_vnt = itm.Key(); // default to 1st item
}
}
public Xodb_page Convert_ttl(Xow_wiki wiki, Xoa_ttl ttl) {return Convert_ttl(wiki, ttl.Ns(), ttl.Full_db());}
public Xodb_page Convert_ttl(Xow_wiki wiki, Xoa_ttl ttl) {return Convert_ttl(wiki, ttl.Ns(), ttl.Page_db());} // NOTE: not Full_db as ttl.Ns is passed; EX:Шаблон:Šablon:Jez-eng; PAGE:sr.w:ДНК DATE:2014-07-06
public Xodb_page Convert_ttl(Xow_wiki wiki, Xow_ns ns, byte[] ttl_bry) {
Bry_bfr tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_b512();
Xodb_page rv = Convert_ttl(wiki, tmp_bfr, ns, ttl_bry);
@ -56,7 +56,7 @@ public class Xol_vnt_mgr implements GfoInvkAble {
return rv;
}
public Xodb_page Convert_ttl(Xow_wiki wiki, Bry_bfr tmp_bfr, Xow_ns ns, byte[] ttl_bry) { // REF.MW:LanguageConverter.php|findVariantLink
int converted = Convert_ttl_convert(tmp_bfr, ns, ttl_bry); // convert ttl for each vnt
int converted = Convert_ttl_convert(wiki, tmp_bfr, ns, ttl_bry); // convert ttl for each vnt
if (converted == 0) return Xodb_page.Null; // ttl_bry has no conversions; exit;
wiki.Db_mgr().Load_mgr().Load_by_ttls(Cancelable_.Never, tmp_page_list, true, 0, converted);
for (int i = 0; i < converted; i++) {
@ -65,15 +65,17 @@ public class Xol_vnt_mgr implements GfoInvkAble {
}
return Xodb_page.Null;
}
private int Convert_ttl_convert(Bry_bfr tmp_bfr, Xow_ns ns, byte[] ttl_bry) {
private int Convert_ttl_convert(Xow_wiki wiki, Bry_bfr tmp_bfr, Xow_ns ns, byte[] ttl_bry) {
tmp_page_list.Clear();
int rv = 0;
for (int i = 0; i < converter_ary_len; i++) { // convert ttl for each variant
for (int i = 0; i < converter_ary_len; i++) { // convert ttl for each variant
Xol_vnt_converter converter = converter_ary[i];
tmp_bfr.Clear();
if (!converter.Convert_text(tmp_bfr, ttl_bry)) continue; // ttl is not converted for variant; ignore
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ns.Id(), tmp_bfr.XtoAryAndClear()); // NOTE: must convert to ttl in order to upper 1st letter; EX:{{jez-eng|sense}} -> Jez-eng; PAGE:sr.w:ДНК DATE:2014-07-06
if (ttl == null) continue;
Xodb_page page = new Xodb_page();
page.Ttl_(ns, tmp_bfr.XtoAryAndClear());
page.Ttl_(ns, ttl.Page_db());
byte[] converted_ttl = page.Ttl_w_ns();
if (tmp_page_list.Has(converted_ttl)) continue;
tmp_page_list.Add(converted_ttl, page);

View File

@ -24,8 +24,8 @@ public class Xop_vnt_lxr_ {
Xop_vnt_lxr_eqgt._.Init_by_wiki(wiki, wiki_trie);
Xop_vnt_lxr_bgn._.Init_by_wiki(wiki, wiki_trie);
new Xop_vnt_lxr_end().Init_by_wiki(wiki, wiki_trie);
// ByteTrieMgr_fast tmpl_trie = wiki.Parser().Tmpl_trie();
// Xop_vnt_lxr_tmpl_bgn._.Init_by_wiki(wiki, tmpl_trie);
// ByteTrieMgr_fast tmpl_trie = wiki.Parser().Tmpl_trie(); // do not add to tmpl trie
// Xop_vnt_lxr_bgn._.Init_by_wiki(wiki, tmpl_trie);
}
}
public static final byte[] Hook_bgn = new byte[] {Byte_ascii.Dash, Byte_ascii.Curly_bgn}, Hook_end = new byte[] {Byte_ascii.Curly_end, Byte_ascii.Dash};
@ -65,7 +65,7 @@ class Xop_vnt_lxr_end implements Xop_lxr {
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
int stack_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_vnt);
if (stack_pos == Xop_ctx.Stack_not_found) return ctx.Lxr_make_txt_(cur_pos); // "}-" found but no "-{" in stack;
Xop_vnt_tkn vnt_tkn = (Xop_vnt_tkn)ctx.Stack_pop_til(root, src, stack_pos, false, bgn_pos, cur_pos);
Xop_vnt_tkn vnt_tkn = (Xop_vnt_tkn)ctx.Stack_pop_til(root, src, stack_pos, false, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_vnt);
try {
vnt_tkn.Src_end_(cur_pos);
vnt_tkn.Subs_move(root);

View File

@ -34,9 +34,13 @@ public class Xop_vnt_parser_tst { // uses zh-hant as cur_vnt
fxt.Parser_fxt().Init_page_create("Template:A", "B");
fxt.Test_parse("-{{{A}}}-", "B");
}
@Test public void Tmpl_arg() {
@Test public void Tmpl_arg_4() { // PURPOSE: handle "-{" + "{{{"
fxt.Parser_fxt().Init_page_create("Template:A", "-{{{{1}}}}-");
fxt.Test_parse("{{A|B}}", "B");
fxt.Test_parse("{{A|B}}", "B"); // -{ {{{1}}} }- -> -{B}- -> B
}
@Test public void Tmpl_arg_3() { // PURPOSE: handle "-" + "{{{"; PAGE:sr.w:ДНК; EX:<span id="interwiki-{{{1}}}-fa"></span> DATE:2014-07-03
fxt.Parser_fxt().Init_page_create("Template:A", "-{{{1}}}-");
fxt.Test_parse("{{A|B}}", "-B-");
}
@Test public void Parser_function() {
fxt.Test_parse("-{{{#expr:1}}}-", "1");

View File

@ -198,7 +198,7 @@ public class Xop_lnke_wkr implements Xop_ctx_wkr {
// }
int lnke_bgn_idx = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_lnke);
if (lnke_bgn_idx == -1) return ctx.Lxr_make_txt_(cur_pos); // no lnke_bgn tkn; occurs when just ]; EX: "a]b"
Xop_lnke_tkn bgnTkn = (Xop_lnke_tkn)ctx.Stack_pop_til(root, src, lnke_bgn_idx, false, bgn_pos, cur_pos);
Xop_lnke_tkn bgnTkn = (Xop_lnke_tkn)ctx.Stack_pop_til(root, src, lnke_bgn_idx, false, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_lnke);
bgnTkn.Src_end_(cur_pos);
bgnTkn.Subs_move(root);
return cur_pos;

View File

@ -30,14 +30,13 @@ public class Xop_lnke_wkr_text_tst {
fxt.Test_parse_page_wiki("irc://a b c", fxt.tkn_lnke_(0, 7).Lnke_rng_(0, 7), fxt.tkn_space_(7, 8), fxt.tkn_txt_(8, 9), fxt.tkn_space_(9, 10), fxt.tkn_txt_(10, 11));
}
@Test public void Text_before_ascii() { // PURPOSE: free form external urls should not match if preceded by letters; EX:de.w:Sylvie_und_Bruno; DATE:2014-05-11
fxt.Ctx().Lang().Case_mgr().Add_bulk(Xol_case_itm_.Universal);
fxt.Ctx().Lang().Case_mgr_utf8_();
String expd_lnke_html = "<a href=\"tel:a\" class=\"external text\" rel=\"nofollow\">tel:a</a>";
fxt.Test_parse_page_wiki_str("titel:a" , "titel:a");
fxt.Test_parse_page_wiki_str(" tel:a" , " " + expd_lnke_html);
fxt.Test_parse_page_wiki_str("!tel:a" , "!" + expd_lnke_html);
fxt.Test_parse_page_wiki_str("ätel:a" , "ätel:a");
fxt.Test_parse_page_wiki_str("€tel:a" , "" + expd_lnke_html);
fxt.Ctx().Lang().Case_mgr().Add_bulk(Xol_case_itm_.English);
}
@Test public void Xnde() {// NOTE: compare to Brace_lt
fxt.Test_parse_page_wiki("<span>irc://a</span>"

View File

@ -0,0 +1,69 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.html.*;
public class Nowiki_escape_itm {
public Nowiki_escape_itm(boolean tid_space, byte[] src, byte[] trg) {this.tid_space = tid_space; this.src = src; this.trg = trg;}
public byte[] Src() {return src;} private byte[] src;
public byte[] Trg() {return trg;} private byte[] trg;
public boolean Tid_space() {return tid_space;} private boolean tid_space;
public static boolean Escape(Bry_bfr tmp_bfr, byte[] src, int bgn, int end) {// <nowiki> works by escaping all wtxt symbols so that wtxt parser does not hook into any of them
boolean dirty = false;
for (int i = bgn; i < end; i++) {
byte b = src[i];
Object o = trie.Match(b, src, i, end);
if (o == null) {
if (dirty)
tmp_bfr.Add_byte(b);
}
else {
if (!dirty) {
tmp_bfr.Add_mid(src, bgn, i);
dirty = true;
}
Nowiki_escape_itm itm = (Nowiki_escape_itm)o;
if (itm.Tid_space()) { // NOTE: if space, check if preceding char is \n; else "\n\s" -> "\n&#32;" which will break prew; PAGE:ru.b:Rubyn DATE:2014-07-03
if (i > 0 && src[i - 1] == Byte_ascii.NewLine) { // bounds check && is_preceding_char_nl
tmp_bfr.Add_byte_space(); // don't escape space
continue;
}
}
tmp_bfr.Add(itm.Trg());
}
}
return dirty;
}
private static final ByteTrieMgr_slim trie = trie_new();
private static ByteTrieMgr_slim trie_new() {
ByteTrieMgr_slim rv = ByteTrieMgr_slim.cs_();
trie_new_itm(rv, Bool_.N, Byte_ascii.Lt_bry , Html_entity_.Lt_bry);
trie_new_itm(rv, Bool_.N, Byte_ascii.Brack_bgn_bry , Html_entity_.Brack_bgn_bry);
trie_new_itm(rv, Bool_.N, Byte_ascii.Pipe_bry , Html_entity_.Pipe_bry);
trie_new_itm(rv, Bool_.N, Byte_ascii.Apos_bry , Html_entity_.Apos_key_bry); // NOTE: for backward compatibility, use &apos; note that amp_wkr will turn &apos; -> &#39 but &#39 -> '; DATE:2014-07-03
trie_new_itm(rv, Bool_.N, Byte_ascii.Colon_bry , Html_entity_.Colon_bry);
trie_new_itm(rv, Bool_.N, Byte_ascii.Underline_bry , Html_entity_.Underline_bry);
trie_new_itm(rv, Bool_.N, Byte_ascii.Asterisk_bry , Html_entity_.Asterisk_bry);
trie_new_itm(rv, Bool_.Y, Byte_ascii.Space_bry , Html_entity_.Space_bry);
return rv;
}
private static void trie_new_itm(ByteTrieMgr_slim rv, boolean tid_space, byte[] src, byte[] trg) {
Nowiki_escape_itm itm = new Nowiki_escape_itm(tid_space, src, trg);
rv.Add(src, itm);
}
}

View File

@ -33,6 +33,7 @@ public class Gxw_html_server implements Gxw_html {
public String Html_doc_selected_get_src_or_empty() {return Exec(cfg.Doc_selected_get_src_or_empty());}
public boolean Html_doc_find(String id, String find, boolean dir_fwd, boolean case_match, boolean wrap_find) {throw Err_.not_implemented_();}
public void Html_doc_body_focus() {Exec(cfg.Doc_body_focus());}
public void Html_doc_selection_focus_toggle() {Exec(cfg.Doc_selection_focus_toggle());}
public String Html_elem_atr_get_str (String id, String atr_key) {return Exec(cfg.Elem_atr_get(id, atr_key));}
public boolean Html_elem_atr_get_bool (String id, String atr_key) {return Bool_.parse_(Exec(cfg.Elem_atr_get(id, atr_key)));}
public boolean Html_elem_atr_set (String id, String atr_key, String val) {return Exec_as_bool(cfg.Elem_atr_set(id, atr_key, val));}

View File

@ -41,7 +41,7 @@ public class Wmf_dump_list_parser_tst {
, fxt.itm("zh-classicalwiki", "20131128", Wmf_dump_itm.Status_tid_complete, "Dump complete", "2013-11-28 06:08:56")
);
}
// @Test public void Update() {
// @Test public void Update() { // 2014-07-06
// Hash_adp_bry excluded_domains = Hash_adp_bry.cs_().Add_many_str
// ( "advisory.wikipedia.org", "beta.wikiversity.org", "donate.wikipedia.org", "login.wikipedia.org"
// , "nostalgia.wikipedia.org", "outreach.wikipedia.org", "quality.wikipedia.org", "sources.wikipedia.org"

View File

@ -19,7 +19,7 @@ package gplx.xowa.specials; import gplx.*; import gplx.xowa.*;
import gplx.xowa.users.history.*;
import gplx.xowa.specials.*;
import gplx.xowa.specials.allPages.*; import gplx.xowa.specials.search.*; import gplx.xowa.specials.nearby.*; import gplx.xowa.specials.randoms.*; import gplx.xowa.specials.statistics.*; import gplx.xowa.xtns.translates.*; import gplx.xowa.specials.movePage.*;
import gplx.xowa.specials.xowa.system_data.*; import gplx.xowa.specials.xowa.default_tab.*;
import gplx.xowa.specials.xowa.system_data.*; import gplx.xowa.specials.xowa.default_tab.*; import gplx.xowa.specials.xowa.popup_history.*;
import gplx.xowa.xtns.wdatas.*;
public class Xows_mgr {
public Xows_mgr(Xow_wiki wiki) {
@ -40,6 +40,7 @@ public class Xows_mgr {
public Move_page Page_movePage() {return page_movePage;} private Move_page page_movePage = new Move_page();
public System_data_page Page_system_data() {return page_system_data;} private System_data_page page_system_data = new System_data_page();
public Default_tab_page Page_default_tab() {return page_default_tab;} private Default_tab_page page_default_tab = new Default_tab_page();
public Popup_history_page Page_popup_history() {return page_popup_history;} private Popup_history_page page_popup_history = new Popup_history_page();
public void Evt_lang_changed(Xol_lang lang) {
hash.Clear();
hash.Add_str_obj("search" , page_search);
@ -56,6 +57,7 @@ public class Xows_mgr {
hash.Add_str_obj("movePage" , page_movePage);
hash.Add_str_obj("XowaSystemData" , page_system_data);
hash.Add_str_obj(Default_tab_page.Ttl_name_str , page_default_tab);
hash.Add_bry_obj(Popup_history_page.Ttl_name_bry , page_popup_history);
}
public void Special_gen(Xoa_url calling_url, Xoa_page page, Xow_wiki wiki, Xoa_ttl ttl) {
int slash_pos = Bry_finder.Find_fwd(ttl.Page_txt_wo_qargs(), Xoa_ttl.Subpage_spr); // check for slash

View File

@ -0,0 +1,40 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.specials.xowa.popup_history; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.xowa.*;
import gplx.xowa.html.modules.popups.*;
public class Popup_history_page implements Xows_page {
public void Special_gen(Xoa_url url, Xoa_page page, Xow_wiki wiki, Xoa_ttl ttl) {
Xoa_page cur_page = wiki.App().Gui_mgr().Browser_win().Active_page(); if (cur_page == null) return;
OrderedHash hash = cur_page.Popup_mgr().Itms();
int len = hash.Count();
Bry_bfr bfr = wiki.Utl_bry_bfr_mkr().Get_k004();
for (int i = len - 1; i > -1; --i) {
Xow_popup_itm itm = (Xow_popup_itm)hash.FetchAt(i);
if (Ttl_chk(itm.Page_ttl())) continue;
fmtr_main.Bld_bfr_many(bfr, itm.Page_href(), itm.Page_ttl().Full_txt());
}
page.Data_raw_(bfr.Trim_end(Byte_ascii.NewLine).Mkr_rls().XtoAryAndClear());
page.Html_data().Restricted_n_();
}
private Bry_fmtr fmtr_main = Bry_fmtr.new_("<a href='~{href}'>~{ttl}</a>\n\n", "href", "ttl"); // NOTE: need to use anchor (as opposed to lnki or lnke) b/c xwiki will not work on all wikis
public static final byte[] Ttl_name_bry = Bry_.new_ascii_("XowaPopupHistory");
public static boolean Ttl_chk(Xoa_ttl ttl) {
return ttl.Ns().Id_special()
&& Bry_.Eq(ttl.Page_db(), Ttl_name_bry);
}
}

View File

@ -16,13 +16,13 @@ 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.users; import gplx.*; import gplx.xowa.*;
import gplx.xowa.wikis.*; import gplx.xowa.xtns.scribunto.*;
import gplx.xowa.langs.cases.*; import gplx.xowa.wikis.*; import gplx.xowa.xtns.scribunto.*;
class Xou_user_ {
public static Xow_wiki new_or_create_(Xou_user user, Xoa_app app) {
Io_url wiki_dir = user.Fsys_mgr().Home_wiki_dir().GenSubDir_nest("wiki", Xow_wiki_domain_.Key_home_str);
Xol_lang lang = app.Lang_mgr().Get_by_key_or_new(app.Lang_mgr().Default_lang());
lang.Init_by_load(); // NOTE: lang.Load() must occur before new Xow_wiki b/c wiki will create parsers based on lang
Xow_wiki rv = new Xow_wiki(app, wiki_dir, ns_home_(), lang);
Xow_wiki rv = new Xow_wiki(app, wiki_dir, ns_home_(lang.Case_mgr()), lang);
app.Wiki_mgr().Add(rv);
rv.Sys_cfg().Xowa_cmd_enabled_(true);
rv.Sys_cfg().Xowa_proto_enabled_(true);
@ -48,8 +48,8 @@ class Xou_user_ {
, ""
, "Please delete bookmarks by editing this page."
);
private static Xow_ns_mgr ns_home_() {
Xow_ns_mgr rv = new Xow_ns_mgr();
private static Xow_ns_mgr ns_home_(Xol_case_mgr case_mgr) {
Xow_ns_mgr rv = new Xow_ns_mgr(case_mgr);
rv = rv.Add_new(-2, "Media").Add_new(-1, "Special").Add_new(0, "").Add_new(1, "Talk").Add_new(2, "User").Add_new(3, "User talk").Add_new(4, "Wikipedia").Add_new(5, "Wikipedia talk")
.Add_new(6, "File").Add_new(7, "File talk").Add_new(8, "MediaWiki").Add_new(9, "MediaWiki talk").Add_new(10, "Template").Add_new(11, "Template talk")
.Add_new(12, "Help").Add_new(13, "Help talk").Add_new(14, "Category").Add_new(15, "Category talk").Add_new(100, "Portal").Add_new(101, "Portal talk")

View File

@ -54,9 +54,11 @@ public class Xou_history_mgr implements GfoInvkAble {// app.user.history
}
public void Add(Xoa_url url, Xoa_ttl ttl, byte[] page_ttl) {
if (!load_chk) Load(app);
byte[] page_db = ttl.Page_db();
if ( ttl.Ns().Id_special()
&& ( Bry_.Eq(ttl.Page_db(), Xou_history_mgr.Ttl_name) // do not add XowaPageHistory to history
|| Bry_.Eq(ttl.Page_db(), gplx.xowa.specials.xowa.default_tab.Default_tab_page.Ttl_name_bry)
&& ( Bry_.Eq(page_db, Xou_history_mgr.Ttl_name) // do not add XowaPageHistory to history
|| Bry_.Eq(page_db, gplx.xowa.specials.xowa.popup_history.Popup_history_page.Ttl_name_bry)
|| Bry_.Eq(page_db, gplx.xowa.specials.xowa.default_tab.Default_tab_page.Ttl_name_bry)
)
) return;
byte[] key = Xou_history_itm.key_(url.Wiki_bry(), page_ttl);

View File

@ -113,7 +113,7 @@ class Prefs_html_wtr {
}
private void Write__value_atr(Bry_bfr bfr, Object prop_val) {
bfr.Add(Atr_stub_value); // " value='"
bfr.Add(Html_utl.Escape_for_atr_val_as_bry(Object_.XtoStr_OrEmpty(prop_val), Byte_ascii.Apos));
bfr.Add(Html_utl.Escape_for_atr_val_as_bry(tmp_bfr, Byte_ascii.Apos, Object_.XtoStr_OrEmpty(prop_val)));
// "abcde"
bfr.Add_byte(Byte_ascii.Apos); // "'"
}

View File

@ -40,6 +40,11 @@ public class Xoa_wiki_mgr implements GfoInvkAble {
if (rv == null) rv = New_wiki(key);
return rv;
}
public Xow_wiki Wiki_commons() {
Xow_wiki rv = this.Get_by_key_or_null(Xow_wiki_domain_.Url_commons);
if (rv != null) rv.Init_assert();
return rv;
}
public Xow_wiki Add(Xow_wiki wiki) {
Xow_wiki rv = (Xow_wiki)hash.Get_by_bry(wiki.Domain_bry());
if (rv == null) {
@ -78,10 +83,10 @@ public class Xoa_wiki_mgr implements GfoInvkAble {
} private static final String Invk_get = "get", Invk_groups = "groups", Invk_scripts = "scripts", Invk_wdata = "wdata";
private static final String Invk_len = "len", Invk_get_at = "get_at";
private Xow_wiki New_wiki(byte[] key) {
Xow_ns_mgr ns_mgr = Xow_ns_mgr_.default_();
Xow_wiki_domain wiki_type = Xow_wiki_domain_.parse_by_domain(key);
byte[] lang_key = wiki_type.Lang(); if (lang_key == Xol_lang_itm_.Key__unknown) lang_key = Xol_lang_.Key_en;
Xol_lang lang = app.Lang_mgr().Get_by_key_or_new(lang_key);
Xow_ns_mgr ns_mgr = Xow_ns_mgr_.default_(lang.Case_mgr());
Io_url wiki_dir = app.Fsys_mgr().Wiki_dir().GenSubDir(String_.new_utf8_(key));
Xow_wiki rv = new Xow_wiki(app, wiki_dir, ns_mgr, lang);
Add(rv);

View File

@ -16,12 +16,14 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns; import gplx.*; import gplx.xowa.*;
import gplx.xowa.xtns.gallery.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.poems.*; import gplx.xowa.xtns.hiero.*;
import gplx.xowa.xtns.gallery.*; import gplx.xowa.xtns.cite.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.poems.*; import gplx.xowa.xtns.hiero.*;
import gplx.xowa.xtns.scores.*; import gplx.xowa.xtns.listings.*; import gplx.xowa.xtns.titleBlacklists.*;
public class Xow_xtn_mgr implements GfoInvkAble {
private OrderedHash regy = OrderedHash_.new_bry_();
public int Count() {return regy.Count();}
public Cite_xtn_mgr Xtn_cite() {return xtn_cite;} private Cite_xtn_mgr xtn_cite;
public Xow_xtn_mgr Ctor_by_app(Xoa_app app) { // NOTE: needed for options
Add(app, new Cite_xtn_mgr());
Add(app, new Scrib_xtn_mgr());
Add(app, new Gallery_xtn_mgr());
Add(app, new Poem_xtn_mgr());
@ -40,6 +42,7 @@ public class Xow_xtn_mgr implements GfoInvkAble {
Xox_mgr mgr = proto.Clone_new();
mgr.Xtn_ctor_by_wiki(wiki);
regy.Add(mgr.Xtn_key(), mgr);
Set_members(mgr);
}
return this;
}
@ -63,8 +66,12 @@ public class Xow_xtn_mgr implements GfoInvkAble {
private Xox_mgr Add(Xoa_app app, Xox_mgr xtn) {
xtn.Xtn_ctor_by_app(app);
regy.Add(xtn.Xtn_key(), xtn);
Set_members(xtn);
return xtn;
}
private void Set_members(Xox_mgr mgr) {
if (Bry_.Eq(mgr.Xtn_key(), Cite_xtn_mgr.XTN_KEY)) xtn_cite = (Cite_xtn_mgr)mgr;
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_get)) return Get_or_fail(m.ReadBry("v"));
else return GfoInvkAble_.Rv_unhandled;

View File

@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.cite; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
public class Cite_xtn_mgr extends Xox_mgr_base {
@Override public byte[] Xtn_key() {return XTN_KEY;} public static final byte[] XTN_KEY = Bry_.new_ascii_("cite");
public byte[] Group_default_name() {return group_default_name;} private byte[] group_default_name = Bry_.new_ascii_("lower-alpha");
@Override public Xox_mgr Clone_new() {return new Cite_xtn_mgr();}
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_group_default_name)) return String_.new_utf8_(group_default_name);
else if (ctx.Match(k, Invk_group_default_name_)) group_default_name = m.ReadBry("v");
else return super.Invk(ctx, ikey, k, m);
return this;
}
private static final String Invk_group_default_name = "group_default_name", Invk_group_default_name_ = "group_default_name_";
}

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.xtns.refs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.cite; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.html.*;
public class Ref_html_wtr {
public Ref_html_wtr(Xow_wiki wiki) {
@ -23,7 +23,7 @@ public class Ref_html_wtr {
}
public void Xnde_ref(Xoh_html_wtr_ctx opts, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde) {
Ref_nde itm = (Ref_nde)xnde.Xnde_xtn();
if (itm == null) return; // FUTURE: See Battle of Midway
if (itm == null) return;
if (itm.Follow_y()) return; // NOTE: "follow" is always appended to preceding ref; will never generate its own ^ a
cfg.Itm_html().Bld_bfr_many(bfr
, Itm_id(itm, true)
@ -70,7 +70,6 @@ public class Ref_html_wtr {
int itms_len = lst.Itms_len();
for (int j = 0; j < itms_len; j++) { // iterate over itms in grp
Ref_nde head_itm = lst.Itms_get_at(j);
// if (head_itm.Exists_in_lnki_title()) continue; // EX: if ref is in lnki_title only, ignore; EX:w:UK; DATE:2014-03-05
Bry_bfr tmp = Bry_bfr.new_();
int list_len = List_len(head_itm);
grp_list_fmtr.Init(ctx.Wiki(), cfg, head_itm);

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.xtns.refs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.cite; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
public class Ref_html_wtr_cfg {
public Bry_fmtr Itm_html() {return itm_html;} private Bry_fmtr itm_html; public Ref_html_wtr_cfg Itm_html_(String v) {itm_html = Bry_fmtr.new_(v, "itm_id", "grp_id", "grp_key"); return this;}
public Bry_fmtr Itm_id_uid() {return itm_id_uid;} private Bry_fmtr itm_id_uid; public Ref_html_wtr_cfg Itm_id_uid_(String v) {itm_id_uid = Bry_fmtr.new_(v, "uid"); return this;}

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.xtns.refs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.cite; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
public class Ref_itm_grp {
private ListAdp lsts = ListAdp_.new_();
public Ref_itm_grp(byte[] grp_name) {this.grp_name = grp_name;}

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.xtns.refs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.cite; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
public class Ref_itm_lst {
public Ref_itm_lst(byte[] grp_name) {this.grp_name = grp_name;}
byte[] grp_name; int idx_major_last = 0;

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