Skin: Change to mustache-backed Skin.Vector (temporary commit) [#797]

staging
gnosygnu 4 years ago
parent 5c3d6a173b
commit 2f4693ac47

@ -1,40 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.jsons; import gplx.*; import gplx.langs.*;
public class Json_doc_bldr {
public Json_nde Nde(Json_doc jdoc) {return factory.Nde(jdoc, -1);}
public Json_nde Nde(Json_doc jdoc, Json_grp owner) {
Json_nde rv = factory.Nde(jdoc, -1);
owner.Add(rv);
return rv;
}
public Json_itm Str(byte[] v) {return Str(String_.new_u8(v));}
public Json_itm Str(String v) {return Json_itm_tmp.new_str_(v);}
public Json_itm Int(int v) {return Json_itm_tmp.new_int_(v);}
public Json_kv Kv_int(Json_grp owner, String key, int val) {Json_kv rv = factory.Kv(Json_itm_tmp.new_str_(key), Json_itm_tmp.new_int_(val)); owner.Add(rv); return rv;}
public Json_kv Kv_str(Json_grp owner, String key, String val) {Json_kv rv = factory.Kv(Json_itm_tmp.new_str_(key), Json_itm_tmp.new_str_(val)); owner.Add(rv); return rv;}
public Json_ary Kv_ary(Json_grp owner, String key, Json_itm... subs) {
Json_itm key_itm = Json_itm_tmp.new_str_(key);
Json_ary val_ary = factory.Ary(-1, -1);
Json_kv kv = factory.Kv(key_itm, val_ary);
owner.Add(kv);
int len = subs.length;
for (int i = 0; i < len; i++)
val_ary.Add(subs[i]);
return val_ary;
}
Json_doc doc = new Json_doc(); Json_factory factory = new Json_factory();
}

@ -1,6 +1,6 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
@ -13,140 +13,155 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.jsons; import gplx.*; import gplx.langs.*;
import gplx.objects.strings.unicodes.*;
import gplx.core.encoders.*;
public class Json_doc_wtr {
private int indent = -2;
private Bry_bfr bfr = Bry_bfr_.Reset(255);
public void Opt_unicode_y_() {opt_unicode = true;} private boolean opt_unicode;
public Json_doc_wtr Indent() {return Indent(indent);}
private Json_doc_wtr Indent(int v) {if (v > 0) bfr.Add_byte_repeat(Byte_ascii.Space, v); return this;}
public Json_doc_wtr Indent_add() {indent += 2; return this;}
public Json_doc_wtr Indent_del() {indent -= 2; return this;}
public Json_doc_wtr Nde_bgn() {Indent_add(); Indent(); bfr.Add_byte(Byte_ascii.Curly_bgn).Add_byte_nl(); return this;}
public Json_doc_wtr Nde_end() { Indent(); bfr.Add_byte(Byte_ascii.Curly_end).Add_byte_nl(); Indent_del(); return this;}
public Json_doc_wtr Ary_bgn() {Indent_add(); Indent(); bfr.Add_byte(Byte_ascii.Brack_bgn).Add_byte_nl(); return this;}
public Json_doc_wtr Ary_end() { Indent(); bfr.Add_byte(Byte_ascii.Brack_end).Add_byte_nl(); Indent_del(); return this;}
public Json_doc_wtr New_line() {bfr.Add_byte_nl(); return this;}
public Json_doc_wtr Str(byte[] v) {
if (v == null)
bfr.Add(Object_.Bry__null);
else {
bfr.Add_byte(Byte_ascii.Quote);
if (opt_unicode) {
Ustring ustr = Ustring_.New_codepoints(String_.new_u8(v));
int ustr_len = ustr.Len_in_data();
for (int i = 0; i < ustr_len; i++) {
int cp = ustr.Get_data(i);
Write_str_codepoint(bfr, cp);
}
}
else {
bfr.Add_bry_escape(Byte_ascii.Quote, Escaped__quote, v, 0, v.length);
}
bfr.Add_byte(Byte_ascii.Quote);
}
return this;
}
private void Write_str_codepoint(Bry_bfr bfr, int val) {
switch (val) { // REF: https://www.json.org/
case Byte_ascii.Quote:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Quote);
break;
case Byte_ascii.Backslash:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Backslash);
break;
case Byte_ascii.Backfeed:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_b);
break;
case Byte_ascii.Formfeed:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_f);
break;
case Byte_ascii.Nl:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_n);
break;
case Byte_ascii.Cr:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_r);
break;
case Byte_ascii.Tab:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_t);
break;
default:
if ( val < Byte_ascii.Space // control characters
|| val == 160 // nbsp
|| val == 8206 // left to right
|| val == 8207 // right to left
) {
// convert to \u1234
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_u).Add_str_a7(Hex_utl_.To_str(val, 4));
}
else {
bfr.Add_u8_int(val);
}
break;
}
}
public Json_doc_wtr Int(int v) {bfr.Add_int_variable(v); return this;}
public Json_doc_wtr Double(double v) {bfr.Add_double(v); return this;}
public Json_doc_wtr Comma() {Indent(); bfr.Add_byte(Byte_ascii.Comma).Add_byte_nl(); return this;}
public Json_doc_wtr Kv_ary_empty(boolean comma, byte[] key) {
Key_internal(comma, key);
bfr.Add_byte(Byte_ascii.Brack_bgn).Add_byte(Byte_ascii.Brack_end);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Kv(boolean comma, byte[] key, byte[] val) {
Key_internal(comma, key);
Str(val);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Kv_double(boolean comma, byte[] key, double v) {
Key_internal(comma, key);
Double(v);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Kv(boolean comma, byte[] key, int v) {
Key_internal(comma, key);
Int(v);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Key(boolean comma, String key) {return Key(comma, Bry_.new_u8(key));}
public Json_doc_wtr Key(boolean comma, byte[] key) {
Key_internal(comma, key);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Val(boolean comma, int v) {
Val_internal(comma);
Int(v);
New_line();
return this;
}
public Json_doc_wtr Val(boolean comma, byte[] v) {
Val_internal(comma);
Str(v);
New_line();
return this;
}
Json_doc_wtr Val_internal(boolean comma) {
Indent();
bfr.Add_byte(comma ? Byte_ascii.Comma : Byte_ascii.Space);
bfr.Add_byte(Byte_ascii.Space);
return this;
}
Json_doc_wtr Key_internal(boolean comma, byte[] key) {
Indent();
bfr.Add_byte(comma ? Byte_ascii.Comma : Byte_ascii.Space);
bfr.Add_byte(Byte_ascii.Space);
Str(key);
bfr.Add_byte(Byte_ascii.Colon);
return this;
}
public byte[] Bld() {return bfr.To_bry_and_clear();}
public String Bld_as_str() {return bfr.To_str_and_clear();}
private static final byte[] Escaped__quote = Bry_.new_a7("\\\"");
}
package gplx.langs.jsons;
import gplx.Bool_;
import gplx.Bry_;
import gplx.Bry_bfr;
import gplx.Bry_bfr_;
import gplx.Byte_ascii;
import gplx.Double_;
import gplx.Object_;
import gplx.String_;
import gplx.core.encoders.Hex_utl_;
import gplx.objects.strings.unicodes.Ustring;
import gplx.objects.strings.unicodes.Ustring_;
public class Json_doc_wtr {
private int indent = -2;
private Bry_bfr bfr = Bry_bfr_.Reset(255);
public void Opt_unicode_y_() {opt_unicode = true;} private boolean opt_unicode;
public Json_doc_wtr Indent() {return Indent(indent);}
private Json_doc_wtr Indent(int v) {if (v > 0) bfr.Add_byte_repeat(Byte_ascii.Space, v); return this;}
public Json_doc_wtr Indent_add() {indent += 2; return this;}
public Json_doc_wtr Indent_del() {indent -= 2; return this;}
public Json_doc_wtr Nde_bgn() {Indent_add(); Indent(); bfr.Add_byte(Byte_ascii.Curly_bgn).Add_byte_nl(); return this;}
public Json_doc_wtr Nde_end() { Indent(); bfr.Add_byte(Byte_ascii.Curly_end).Add_byte_nl(); Indent_del(); return this;}
public Json_doc_wtr Ary_bgn() {Indent_add(); Indent(); bfr.Add_byte(Byte_ascii.Brack_bgn).Add_byte_nl(); return this;}
public Json_doc_wtr Ary_end() { Indent(); bfr.Add_byte(Byte_ascii.Brack_end).Add_byte_nl(); Indent_del(); return this;}
public Json_doc_wtr New_line() {bfr.Add_byte_nl(); return this;}
public Json_doc_wtr Str(byte[] v) {
if (v == null)
bfr.Add(Object_.Bry__null);
else {
bfr.Add_byte(Byte_ascii.Quote);
if (opt_unicode) {
Ustring ustr = Ustring_.New_codepoints(String_.new_u8(v));
int ustr_len = ustr.Len_in_data();
for (int i = 0; i < ustr_len; i++) {
int cp = ustr.Get_data(i);
Write_str_codepoint(bfr, cp);
}
}
else {
bfr.Add_bry_escape(Byte_ascii.Quote, Escaped__quote, v, 0, v.length);
}
bfr.Add_byte(Byte_ascii.Quote);
}
return this;
}
private void Write_str_codepoint(Bry_bfr bfr, int val) {
switch (val) { // REF: https://www.json.org/
case Byte_ascii.Quote:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Quote);
break;
case Byte_ascii.Backslash:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Backslash);
break;
case Byte_ascii.Backfeed:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_b);
break;
case Byte_ascii.Formfeed:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_f);
break;
case Byte_ascii.Nl:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_n);
break;
case Byte_ascii.Cr:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_r);
break;
case Byte_ascii.Tab:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_t);
break;
default:
if ( val < Byte_ascii.Space // control characters
|| val == 160 // nbsp
|| val == 8206 // left to right
|| val == 8207 // right to left
) {
// convert to \u1234
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_u).Add_str_a7(Hex_utl_.To_str(val, 4));
}
else {
bfr.Add_u8_int(val);
}
break;
}
}
public Json_doc_wtr Int(int v) {bfr.Add_int_variable(v); return this;}
public Json_doc_wtr Double(double v) {bfr.Add_double(v); return this;}
public Json_doc_wtr Comma() {Indent(); bfr.Add_byte(Byte_ascii.Comma).Add_byte_nl(); return this;}
public Json_doc_wtr Kv_ary_empty(boolean comma, byte[] key) {
Key_internal(comma, key);
bfr.Add_byte(Byte_ascii.Brack_bgn).Add_byte(Byte_ascii.Brack_end);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Kv(boolean comma, String key, byte[] val) {return Kv(comma, Bry_.new_u8(key), val);}
public Json_doc_wtr Kv(boolean comma, byte[] key, byte[] val) {
Key_internal(comma, key);
Str(val);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Kv_double(boolean comma, byte[] key, double v) {
Key_internal(comma, key);
Double(v);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Kv(boolean comma, String key, int v) {return Kv(comma, Bry_.new_u8(key), v);}
public Json_doc_wtr Kv(boolean comma, byte[] key, int v) {
Key_internal(comma, key);
Int(v);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Kv(boolean comma, String key, double v) {return Kv(comma, Bry_.new_u8(key), Bry_.new_u8(Double_.To_str(v)));}
public Json_doc_wtr Kv(boolean comma, String key, boolean v) {return Kv(comma, Bry_.new_u8(key), v ? Bool_.Y_bry : Bool_.N_bry);}
public Json_doc_wtr Key(boolean comma, String key) {return Key(comma, Bry_.new_u8(key));}
public Json_doc_wtr Key(boolean comma, byte[] key) {
Key_internal(comma, key);
bfr.Add_byte_nl();
return this;
}
public Json_doc_wtr Val(boolean comma, int v) {
Val_internal(comma);
Int(v);
New_line();
return this;
}
public Json_doc_wtr Val(boolean comma, byte[] v) {
Val_internal(comma);
Str(v);
New_line();
return this;
}
Json_doc_wtr Val_internal(boolean comma) {
Indent();
bfr.Add_byte(comma ? Byte_ascii.Comma : Byte_ascii.Space);
bfr.Add_byte(Byte_ascii.Space);
return this;
}
Json_doc_wtr Key_internal(boolean comma, byte[] key) {
Indent();
bfr.Add_byte(comma ? Byte_ascii.Comma : Byte_ascii.Space);
bfr.Add_byte(Byte_ascii.Space);
Str(key);
bfr.Add_byte(Byte_ascii.Colon);
return this;
}
public byte[] Bld() {return bfr.To_bry_and_clear();}
public String Bld_as_str() {return bfr.To_str_and_clear();}
private static final byte[] Escaped__quote = Bry_.new_a7("\\\"");
}

@ -1,23 +1,39 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.jsons; import gplx.*; import gplx.langs.*;
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.jsons;
import gplx.Bry_;
import gplx.Bry_bfr;
public class Json_itm_int extends Json_itm_base {
private final Json_doc doc;
private byte[] data_bry; private int data; private boolean data_is_null = true;
public Json_itm_int(Json_doc doc, int src_bgn, int src_end) {this.Ctor(src_bgn, src_end); this.doc = doc;}
private byte[] data_bry;
private int data;
private boolean data_is_null = true;
public Json_itm_int(Json_doc doc, int src_bgn, int src_end) {
this.Ctor(src_bgn, src_end);
this.doc = doc;
}
public Json_itm_int(int val) {
this.Ctor(-1, -1);
this.doc = null;
this.data = val;
this.data_is_null = false;
}
@Override public byte Tid() {return Json_itm_.Tid__int;}
public int Data_as_int() {
if (data_is_null) {
@ -27,7 +43,16 @@ public class Json_itm_int extends Json_itm_base {
return data;
}
@Override public Object Data() {return Data_as_int();}
@Override public byte[] Data_bry() {if (data_bry == null) data_bry = Bry_.Mid(doc.Src(), this.Src_bgn(), this.Src_end()); return data_bry;}
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add_mid(doc.Src(), this.Src_bgn(), this.Src_end());}
@Override public byte[] Data_bry() {
if (data_bry == null)
data_bry = Bry_.Mid(doc.Src(), this.Src_bgn(), this.Src_end());
return data_bry;
}
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
if (doc != null && this.Src_bgn() >= 0)
bfr.Add_mid(doc.Src(), this.Src_bgn(), this.Src_end());
else
bfr.Add_int_variable(data);
}
public static Json_itm_int cast(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid__int ? null : (Json_itm_int)v;}
}
}

@ -1,31 +1,65 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.jsons; import gplx.*; import gplx.langs.*;
import gplx.core.intls.*;
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.jsons;
import gplx.Bry_;
import gplx.Bry_bfr;
import gplx.Bry_bfr_;
import gplx.Byte_ascii;
import gplx.String_;
import gplx.core.intls.Utf16_;
public class Json_itm_str extends Json_itm_base {
private final boolean exact; private final Json_doc doc;
private String data_str; private byte[] data_bry = null;
public Json_itm_str(Json_doc doc, int src_bgn, int src_end, boolean exact) {this.Ctor(src_bgn + 1, src_end - 1); this.doc = doc; this.exact = exact;}
private final boolean exact;
private final Json_doc doc;
private String data_str;
private byte[] data_bry = null;
private byte[] src = null;
public Json_itm_str(Json_doc doc, int src_bgn, int src_end, boolean exact) {
this.Ctor(src_bgn + 1, src_end - 1);
this.doc = doc;
this.exact = exact;
}
public Json_itm_str(byte[] src, boolean exact) {
this.doc = null;
this.src = src;
this.exact = exact;
}
@Override public byte Tid() {return Json_itm_.Tid__str;}
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
bfr.Add_byte(Byte_ascii.Quote);
gplx.langs.htmls.Gfh_utl.Escape_html_to_bfr(bfr, doc.Src(), this.Src_bgn(), this.Src_end(), true, true, true, true, false); // false to apos for backwards compatibility
byte[] src_doc;
int bgn;
int end;
if (src == null) {
src_doc = doc.Src();
bgn = this.Src_bgn();
end = this.Src_end();
}
else {
src_doc = src;
bgn = 0;
end = src.length;
}
gplx.langs.htmls.Gfh_utl.Escape_html_to_bfr(bfr, src_doc, bgn, end, true, true, true, true, false); // false to apos for backwards compatibility
bfr.Add_byte(Byte_ascii.Quote);
}
@Override public Object Data() {return this.Data_as_str();}
public void Overwrite_bry(byte[] v) {data_bry = v;} //needed by MapLink/MapFrame
public String Data_as_str() {
if (data_str == null) {
if (data_bry == null)
@ -41,15 +75,32 @@ public class Json_itm_str extends Json_itm_base {
return Bry_.Match(data_bry, comp);
}
private byte[] Data_make_bry() {
byte[] src = doc.Src(); int bgn = this.Src_bgn(), end = this.Src_end();
if (exact) return Bry_.Mid(src, bgn, end);
Bry_bfr bfr = doc.Bfr();
byte[] utf8_bry = doc.Tmp_u8_bry();
byte[] src_doc;
int bgn;
int end;
Bry_bfr bfr;
byte[] utf8_bry;
if (src == null) {
src_doc = doc.Src();
bgn = this.Src_bgn();
end = this.Src_end();
if (exact) return Bry_.Mid(src_doc, bgn, end);
bfr = doc.Bfr();
utf8_bry = doc.Tmp_u8_bry();
}
else {
if (exact) return src;
src_doc = src;
bgn = 0;
end = src.length;
bfr = Bry_bfr_.New();
utf8_bry = new byte[6];
}
for (int i = bgn; i < end; i++) {
byte b = src[i];
byte b = src_doc[i];
switch (b) {
case Byte_ascii.Backslash:
b = src[++i];
b = src_doc[++i];
switch (b) { // NOTE: must properly unescape chars; EX:wd.q:2; DATE:2014-04-23
case Byte_ascii.Ltr_t: bfr.Add_byte(Byte_ascii.Tab); break;
case Byte_ascii.Ltr_n: bfr.Add_byte(Byte_ascii.Nl); break;
@ -58,16 +109,16 @@ public class Json_itm_str extends Json_itm_base {
case Byte_ascii.Ltr_f: bfr.Add_byte(Byte_ascii.Formfeed); break;
case Byte_ascii.Ltr_u:
i += 1; // +1 to skip "u"
int utf8_val = gplx.core.encoders.Hex_utl_.Parse_or(src, i, i + 4, -1);
int utf8_val = gplx.core.encoders.Hex_utl_.Parse_or(src_doc, i, i + 4, -1);
// check for UTF surrogate-pairs; ISSUE#:487; DATE:2019-06-02
// hi: 0xD800-0xDBFF; 55,296-56,319
if (utf8_val >= Utf16_.Surrogate_hi_bgn && utf8_val <= Utf16_.Surrogate_hi_end) {
int lo_bgn = i + 4; // +4 to skip 4 hex-dec chars
if (lo_bgn + 6 <= end // +6 to handle encoded String; EX: '\u0022'
&& src[lo_bgn] == Byte_ascii.Backslash
&& src[lo_bgn + 1] == Byte_ascii.Ltr_u) {
&& src_doc[lo_bgn] == Byte_ascii.Backslash
&& src_doc[lo_bgn + 1] == Byte_ascii.Ltr_u) {
lo_bgn = lo_bgn + 2; // +2 to skip '\' and 'u'
int lo = gplx.core.encoders.Hex_utl_.Parse_or(src, lo_bgn, lo_bgn + 4, -1);
int lo = gplx.core.encoders.Hex_utl_.Parse_or(src_doc, lo_bgn, lo_bgn + 4, -1);
// lo: 0xDC00-0xDFFF; 56,320-57,343
if (lo >= Utf16_.Surrogate_lo_bgn && lo <= Utf16_.Surrogate_lo_end) {
utf8_val = Utf16_.Surrogate_merge(utf8_val, lo);
@ -88,8 +139,8 @@ public class Json_itm_str extends Json_itm_base {
default:
bfr.Add_byte(b);
break;
}
}
}
return bfr.To_bry_and_clear();
}
}
}

@ -0,0 +1,62 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.jsons;
import gplx.Bry_;
import gplx.Bry_bfr;
import gplx.Bry_bfr_;
public class Json_mustache {
public static Json_kv Add_text(String keystr, byte[] bytes) {
if (bytes == null) return null;
Json_itm_str key = new Json_itm_str(Bry_.new_a7(keystr), true);
Json_itm_str val = new Json_itm_str(bytes, false);
return new Json_kv(key, val);
}
public static Json_kv Add_int(String keystr, int intval) {
Json_itm_str key = new Json_itm_str(Bry_.new_a7(keystr), true);
Json_itm_int val = new Json_itm_int(intval);
return new Json_kv(key, val);
}
public static Json_kv Add_double(String keystr, double doubleval) {
// eek
Json_itm_str key = new Json_itm_str(Bry_.new_a7(keystr), true);
Bry_bfr bfr = Bry_bfr_.New();
byte[] bytes = bfr.Add_double(doubleval).To_bry();
Json_itm_str val = new Json_itm_str(bytes, true);
return new Json_kv(key, val);
}
public static Json_kv Add_bool(String keystr, boolean bool) {
Json_itm_str key = new Json_itm_str(Bry_.new_a7(keystr), true);
Json_itm_bool val = new Json_itm_bool(bool);
return new Json_kv(key, val);
}
public static Json_kv Add_nde(String keystr, Json_nde nde) {
Json_itm_str key = new Json_itm_str(Bry_.new_a7(keystr), true);
return new Json_kv(key, nde);
}
public static Json_kv Add_ary(String keystr, Json_ary ary) {
if (ary == null) return null;
Json_itm_str key = new Json_itm_str(Bry_.new_a7(keystr), true);
return new Json_kv(key, ary);
}
}

@ -119,7 +119,7 @@ public class Json_nde extends Json_itm_base implements Json_grp {
public Json_itm Get_itm(byte[] key) {
for (int i = 0; i < subs_len; i++) {
Json_itm itm = subs[i];
if (itm.Tid() == Json_itm_.Tid__kv) {
if (itm != null && itm.Tid() == Json_itm_.Tid__kv) {
Json_kv itm_as_kv = (Json_kv)itm;
if (Bry_.Eq(key, itm_as_kv.Key().Data_bry()))
return itm;

@ -1,22 +1,24 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.mustaches; import gplx.*; import gplx.langs.*;
import gplx.langs.jsons.*;
public class Mustache_render_ctx {
private final List_adp stack = List_adp_.New();
private final List_adp stack = List_adp_.New();
private Mustache_doc_itm cur;
private Json_itm nde; private Json_ary subary;
private Mustache_doc_itm[] subs; private int subs_idx, subs_len; private byte cur_is_bool;
public Mustache_render_ctx Init(Mustache_doc_itm cur) {
this.cur = cur;
@ -24,75 +26,193 @@ public class Mustache_render_ctx {
this.subs_idx = subs_len = 0; this.cur_is_bool = Bool_.__byte;
return this;
}
public Mustache_render_ctx Init(Json_nde nde) {
this.cur = null;
this.nde = nde;
this.subs = null;
this.subs_idx = subs_len = 0; this.cur_is_bool = Bool_.__byte;
return this;
}
// partial implementation of {{.}}
public boolean Render_variable(Mustache_bfr bfr, String key) {
boolean rv = false;
int stack_pos = stack.Len();
Mustache_doc_itm itm = cur;
while (itm != Mustache_doc_itm_.Null_itm) {
boolean resolved = itm.Mustache__write(key, bfr);
if (resolved) {
rv = true;
break;
}
else {
if (cur == null) {
Json_itm itm = nde;
while (itm != null) {
if (itm instanceof Json_nde) {
Json_nde n = (Json_nde)itm;
Json_kv kv = (Json_kv)n.Get_itm(Bry_.new_u8(key));
if (kv == null)
return rv;
Json_itm jitm = kv.Val();
if (jitm instanceof Json_itm_str) {
Json_itm_str s = (Json_itm_str)jitm;
bfr.Add_bry(s.Data_bry());
return true;
}
else if (jitm instanceof Json_itm_int) {
Json_itm_int s = (Json_itm_int)jitm;
bfr.Bfr().Add_int_variable(s.Data_as_int());
return true;
}
else {
int a = 1/0;
}
}
else if (key.equals(".") && itm instanceof Json_itm_str) {
Json_itm_str s = (Json_itm_str)itm;
bfr.Add_bry(s.Data_bry());
return true;
}
--stack_pos;
if (stack_pos == -1) // nothing else in stack
break;
else
itm = ((Mustache_stack_itm)stack.Get_at(stack_pos)).cur;
itm = ((Mustache_stack_itm)stack.Get_at(stack_pos)).nde;
}
}
else {
Mustache_doc_itm itm = cur;
while (itm != Mustache_doc_itm_.Null_itm) {
boolean resolved = itm.Mustache__write(key, bfr);
if (resolved) {
rv = true;
break;
}
else {
--stack_pos;
if (stack_pos == -1) // nothing else in stack
break;
else
itm = ((Mustache_stack_itm)stack.Get_at(stack_pos)).cur;
}
}
}
return rv;
}
public void Section_bgn(String key) {
Mustache_stack_itm stack_itm = new Mustache_stack_itm(cur, subs, subs_idx, subs_len, cur_is_bool); // note that cur is "owner" since subs_idx == 0
stack.Add(stack_itm);
subs = cur.Mustache__subs(key); if (subs == null) subs = Mustache_doc_itm_.Ary__empty; // subs == null if property does not exist; EX: "folder{{#files}}file{{/files}}" and folder = new Folder(File[0]);
subs_len = subs.length;
if (cur == null) {
Mustache_stack_itm stack_itm = new Mustache_stack_itm(nde, subs, subs_idx, subs_len, cur_is_bool); // note that cur is "owner" since subs_idx == 0
stack.Add(stack_itm);
Json_nde n = null;
Json_itm itm = nde;
int stack_pos = stack.Len();
while (stack_pos >= 0) {
if (itm instanceof Json_nde) {
n = (Json_nde)itm;
break;
}
else {
stack_pos--;
itm = ((Mustache_stack_itm)stack.Get_at(stack_pos)).nde;
}
}
Json_kv kv = null;
if (n != null)
kv = (Json_kv)n.Get_itm(Bry_.new_u8(key));
if (kv == null)
nde = null;
else {
nde = kv.Val();
if (nde instanceof Json_ary) {
subary = (Json_ary)nde;
subs_len = subary.Len();
}
else
subs_len = 1;
}
}
else {
Mustache_stack_itm stack_itm = new Mustache_stack_itm(cur, subs, subs_idx, subs_len, cur_is_bool); // note that cur is "owner" since subs_idx == 0
stack.Add(stack_itm);
subs = cur.Mustache__subs(key); if (subs == null) subs = Mustache_doc_itm_.Ary__empty; // subs == null if property does not exist; EX: "folder{{#files}}file{{/files}}" and folder = new Folder(File[0]);
subs_len = subs.length;
}
subs_idx = -1;
}
public boolean Section_do(boolean inverted) {
if (++subs_idx >= subs_len) return false;
Mustache_doc_itm sub = subs[subs_idx];
if (subs_idx == 0) { // special logic to handle 1st item; note that there always be at least one item
if (sub == Mustache_doc_itm_.Itm__bool__n) {
boolean rv = Bool_.N;
if (inverted) rv = !rv;
cur_is_bool = Bool_.To_byte(rv);
return rv;
if (cur == null) {
if (++subs_idx >= subs_len) return false;
if (nde == null) return false;
if (nde instanceof Json_itm_bool) {
Json_itm_bool b = (Json_itm_bool)nde;
if (b.Data_as_bool() == false) {
boolean rv = Bool_.N;
if (inverted) rv = !rv;
cur_is_bool = Bool_.To_byte(rv);
return rv;
}
else {
boolean rv = Bool_.Y;
if (inverted) rv = !rv;
cur_is_bool = Bool_.To_byte(rv);
return rv;
}
}
else if (sub == Mustache_doc_itm_.Itm__bool__y) {
boolean rv = Bool_.Y;
if (inverted) rv = !rv;
cur_is_bool = Bool_.To_byte(rv);
return rv;
else if (subary != null) {
nde = subary.Get_at(subs_idx);
}
}
else {
if (++subs_idx >= subs_len) return false;
Mustache_doc_itm sub = subs[subs_idx];
if (subs_idx == 0) { // special logic to handle 1st item; note that there always be at least one item
if (sub == Mustache_doc_itm_.Itm__bool__n) {
boolean rv = Bool_.N;
if (inverted) rv = !rv;
cur_is_bool = Bool_.To_byte(rv);
return rv;
}
else if (sub == Mustache_doc_itm_.Itm__bool__y) {
boolean rv = Bool_.Y;
if (inverted) rv = !rv;
cur_is_bool = Bool_.To_byte(rv);
return rv;
}
else
cur_is_bool = Bool_.__byte;
}
else
cur_is_bool = Bool_.__byte;
}
cur = sub;
cur = sub;
}
return true;
}
public void Section_end() {
Mustache_stack_itm itm = (Mustache_stack_itm)List_adp_.Pop(stack);
if (cur == null) {
nde = itm.nde;
subary = null;
}
else {
cur = itm.cur;
}
subs = itm.subs;
subs_len = itm.subs_len;
subs_idx = itm.subs_idx;
cur = itm.cur;
cur_is_bool = itm.cur_is_bool;
}
}
class Mustache_stack_itm {
public Mustache_stack_itm(Mustache_doc_itm cur, Mustache_doc_itm[] subs, int subs_idx, int subs_len, byte cur_is_bool) {
this.cur = cur;
this.nde = null;
this.cur_is_bool = cur_is_bool;
this.subs = subs;
this.subs_idx = subs_idx;
this.subs_len = subs_len;
}
public Mustache_stack_itm(Json_itm nde, Mustache_doc_itm[] subs, int subs_idx, int subs_len, byte cur_is_bool) {
this.cur = null;
this.nde = nde;
this.cur_is_bool = cur_is_bool;
this.subs = subs;
this.subs_idx = subs_idx;
this.subs_len = subs_len;
}
public final Mustache_doc_itm cur;
public final byte cur_is_bool;
public final Mustache_doc_itm[] subs;
public final int subs_idx;
public final int subs_len;
public final Json_itm nde;
public final Mustache_doc_itm cur;
public final byte cur_is_bool;
public final Mustache_doc_itm[] subs;
public final int subs_idx;
public final int subs_len;
}

@ -1,18 +1,18 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.mustaches; import gplx.*; import gplx.langs.*;
class Mustache_tkn_def {
public byte[] Variable_lhs = Dflt_variable_lhs;
@ -31,7 +31,7 @@ class Mustache_tkn_def {
, Grp_end = Byte_ascii.Slash // {{/section}}
, Inverted = Byte_ascii.Pow // {{^inverted}}
, Comment = Byte_ascii.Bang // {{!comment}}
, Partial = Byte_ascii.Angle_bgn // {{>partial}}
, Partial = Byte_ascii.Angle_end // {{>partial}}
, Delimiter_bgn = Byte_ascii.Eq // {{=<% %>=}}
, Delimiter_end = Byte_ascii.Curly_end // {{=<% %>=}}
;

@ -1,18 +1,18 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.mustaches; import gplx.*; import gplx.langs.*;
public interface Mustache_tkn_itm {
int Tid();
@ -103,7 +103,21 @@ class Mustache_tkn_inverted extends Mustache_tkn_base { // EX: {{^section}}missi
@Override public void Render(Mustache_bfr bfr, Mustache_render_ctx ctx) {Mustache_tkn_section.Render_static(Bool_.Y, this, bfr, ctx);}
}
class Mustache_tkn_partial extends Mustache_tkn_base { // EX: {{>a}} -> abc (deferred eval)
public Mustache_tkn_partial(byte[] key) {super(Mustache_tkn_itm_.Tid__partial, key);}
private Mustache_tkn_itm template_root;
public Mustache_tkn_partial(byte[] key, Io_url dir) {
super(Mustache_tkn_itm_.Tid__partial, key);
int key_len = key.length;
int i;
for (i = 0; i < key_len; i++) {
if (key[i] != ' ')
break;
}
Mustache_tkn_parser parser = new Mustache_tkn_parser(dir);
template_root = parser.Parse(String_.new_a7(Bry_.Mid(key, i, key_len)));
}
@Override public void Render(Mustache_bfr bfr, Mustache_render_ctx ctx) {
template_root.Render(bfr, ctx);
}
}
class Mustache_tkn_delimiter extends Mustache_tkn_base {// EX: {{=<% %>=}} -> <% variable %>
public Mustache_tkn_delimiter(byte[] key) {super(Mustache_tkn_itm_.Tid__delimiter, key);}

@ -1,22 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.mustaches; import gplx.*; import gplx.langs.*;
public class Mustache_tkn_parser {
private byte[] src; private int src_end;
private Io_url template_root;
private final Mustache_tkn_def tkn_def = new Mustache_tkn_def();
public Mustache_tkn_parser() {
}
public Mustache_tkn_parser(Io_url template_root) {
this.template_root = template_root;
}
public Mustache_tkn_itm Parse(String template) { return Parse(template, Bry_.Empty); }
public Mustache_tkn_itm Parse(String template, byte[] default_text) {
byte[] template_data = Io_mgr.Instance.LoadFilBryOr(template_root.GenSubFil_nest(template + ".mustache"), default_text);
return Parse(template_data, 0, template_data.length);
}
public Mustache_tkn_itm Parse(byte[] src) {return Parse(src, 0, src.length);}
public Mustache_tkn_itm Parse(byte[] src, int src_bgn, int src_end) {
this.src = src; this.src_end = src_end;
@ -80,7 +91,7 @@ public class Mustache_tkn_parser {
default: throw Err_.new_unhandled(tkn_data.tid);
case Mustache_tkn_def.Variable: tkn = new Mustache_tkn_variable(val_bry); break;
case Mustache_tkn_def.Comment: tkn = new Mustache_tkn_comment(); break;
case Mustache_tkn_def.Partial: tkn = new Mustache_tkn_partial(val_bry); break;
case Mustache_tkn_def.Partial: tkn = new Mustache_tkn_partial(val_bry, template_root); break;
case Mustache_tkn_def.Delimiter_bgn: tkn = new Mustache_tkn_delimiter(val_bry); break; // TODO_OLD: implement delimiter; EX: {{=<% %>=}}
case Mustache_tkn_def.Escape_bgn: tkn = new Mustache_tkn_escape(val_bry); break;
case Mustache_tkn_def.Section: tkn = new Mustache_tkn_section(val_bry); break;

@ -0,0 +1,292 @@
package gplx.xowa;
import gplx.*;
import gplx.langs.mustaches.*;
//import gplx.langs.mustaches.Mustache_tkn_itm;
//import gplx.langs.mustaches.Mustache_tkn_parser;
import gplx.xowa.Xowe_wiki;
import gplx.langs.jsons.Json_nde;
import gplx.langs.jsons.Json_mustache;
import gplx.xowa.langs.msgs.Xol_msg_mgr;
public class Db_Nav_template {
public Mustache_tkn_itm Navigation_root() {return navigation_root;} private Mustache_tkn_itm navigation_root;
private Xol_msg_mgr msg_mgr;
private Json_nde msgdata;
private Xowe_wiki wiki;
private static boolean once = true;
private static Mustache_tkn_itm menu_root;
public static void Build_Sidebar(Xowe_wiki wiki, Bry_bfr bfr, byte[] id, byte[] text, byte[] itms) {
if (once) {
once = false;
Io_url template_root = wiki.Appe().Fsys_mgr().Bin_any_dir().GenSubDir_nest("xowa", "xtns", "Skin-Vector", "templates");
Mustache_tkn_parser parser = new Mustache_tkn_parser(template_root);
menu_root = parser.Parse("Menu");
}
Json_nde data = s_getMenuData(wiki,
text,
itms,
MENU_TYPE_PORTAL
);
//Bry_bfr tmp_bfr = Bry_bfr_.New();
Mustache_render_ctx mctx = new Mustache_render_ctx().Init(data);
Mustache_bfr mbfr = Mustache_bfr.New_bfr(bfr);
menu_root.Render(mbfr, mctx);
// byte[] result = mbfr.To_bry_and_clear();
//System.out.println(String_.new_u8(result));
}
public void Init(Xowe_wiki wiki) {
Io_url template_root = wiki.Appe().Fsys_mgr().Bin_any_dir().GenSubDir_nest("xowa", "xtns", "Skin-Vector", "templates");
Mustache_tkn_parser parser = new Mustache_tkn_parser(template_root);
navigation_root = parser.Parse("Navigation");
this.wiki = wiki;
msg_mgr = wiki.Lang().Msg_mgr();
build_msg();
Test();
}
private String[] msgs = new String[] {
"vector-opt-out-tooltip",
"vector-opt-out",
"navigation-heading",
"vector-action-toggle-sidebar",
"vector-jumptonavigation",
"vector-jumptosearch",
"vector-jumptocontent",
"sitesubtitle",
"sitetitle",
"tagline"
};
//all thes messages should be preprocessed (per language) as $data["msg-{$message}"] = $this->msg( $message )->text();
private void build_msg() {
int msg_len = msgs.length;
msgdata = new Json_nde(null, -1);
for (int i = 0; i < msg_len; i++) {
String msg = msgs[i];
msgdata.Add( Json_mustache.Add_text("msg-" + msg, msg_mgr.Val_by_str_or_empty(msg)));
}
}
private void Test() {
Json_nde namespaces = new Json_nde(null, -1);
Json_nde jnde = new Json_nde(null, -1);
jnde.Add_many(
Json_mustache.Add_text("class", Bry_.new_a7("CLASS"))
,Json_mustache.Add_text("text", Bry_.new_a7("TEXT"))
,Json_mustache.Add_text("href", Bry_.new_a7("URL_str"))
,Json_mustache.Add_bool("exists", true)
,Json_mustache.Add_bool("primary", true)
,Json_mustache.Add_text("link-class", Bry_.Empty)
);
jnde.Add(Json_mustache.Add_text("context", Bry_.new_a7("subject")));
namespaces.Add(Json_mustache.Add_nde("subject", jnde));
//Json_nde data_namespaces = new Json_nde(null, -1);
msgdata.Add(Json_mustache.Add_nde("data-namespace-tabs", getMenuData(
Bry_.new_a7("namespaces"),
namespaces,
MENU_TYPE_TABS
)));
Bry_bfr tmp_bfr = Bry_bfr_.New();
Mustache_render_ctx mctx = new Mustache_render_ctx().Init(msgdata);
Mustache_bfr mbfr = Mustache_bfr.New_bfr(tmp_bfr);
navigation_root.Render(mbfr, mctx);
byte[] result = mbfr.To_bry_and_clear();
System.out.println(String_.new_u8(result));
}
/* Vector/SkinVector.php */
private static int MENU_TYPE_DROPDOWN = 0, MENU_TYPE_TABS = 1, MENU_TYPE_PORTAL = 2, MENU_TYPE_DEFAULT = 3;
private static byte[][] extraClasses = new byte[][] {
Bry_.new_a7("vector-menu vector-menu-dropdown vectorMenu"),
Bry_.new_a7("vector-menu vector-menu-tabs vectorTabs"),
Bry_.new_a7("vector-menu vector-menu-portal portal"),
Bry_.new_a7("vector-menu")
};
private Json_nde getMenuData(byte[] label, Json_nde urls, int type) { return getMenuData(label, urls, type, false); }
private Json_nde getMenuData(byte[] label, Json_nde urls, int type, boolean setLabelToSelected) {
/*
private function getMenuData(
string $label,
array $urls = [],
int $type = self::MENU_TYPE_DEFAULT,
bool $setLabelToSelected = false
) : array {
$skin = $this->getSkin();
$extraClasses = [
self::MENU_TYPE_DROPDOWN => 'vector-menu vector-menu-dropdown vectorMenu',
self::MENU_TYPE_TABS => 'vector-menu vector-menu-tabs vectorTabs',
self::MENU_TYPE_PORTAL => 'vector-menu vector-menu-portal portal',
self::MENU_TYPE_DEFAULT => 'vector-menu',
];
// A list of classes to apply the list element and override the default behavior.
$listClasses = [
// `.menu` is on the portal for historic reasons.
// It should not be applied elsewhere per T253329.
self::MENU_TYPE_DROPDOWN => 'menu vector-menu-content-list',
];
$isPortal = $type === self::MENU_TYPE_PORTAL;
*/
boolean isPortal = type == MENU_TYPE_PORTAL;
/*
// For some menu items, there is no language key corresponding with its menu key.
// These inconsitencies are captured in MENU_LABEL_KEYS
$msgObj = $skin->msg( self::MENU_LABEL_KEYS[ $label ] ?? $label );
$props = [
'id' => "p-$label",
*/
byte[] listClasses;
byte[] msg = label; // for now
byte[] linkertooltip = Bry_.Empty;
if (type == MENU_TYPE_DROPDOWN)
listClasses = Bry_.new_a7("menu vector-menu-content-list");
else
listClasses = Bry_.new_a7("vector-menu-content-list");
byte[] plabel = Bry_.Add(Bry_.new_a7("p-"), label);
Json_nde props = new Json_nde(null, -1);
props.Add_many(
Json_mustache.Add_text("id", plabel)
/*
'label-id' => "p-{$label}-label",
*/
,Json_mustache.Add_text("label-id", Bry_.Add(plabel, Bry_.new_a7("-label")))
/*
// If no message exists fallback to plain text (T252727)
'label' => $msgObj->exists() ? $msgObj->text() : $label,
*/
,Json_mustache.Add_text("label", msg)
/*
'list-classes' => $listClasses[$type] ?? 'vector-menu-content-list',
*/
,Json_mustache.Add_text("list-classes", listClasses)
/*
'html-items' => '',
'is-dropdown' => $type === self::MENU_TYPE_DROPDOWN,
*/
,Json_mustache.Add_bool("is-dropdown", type == MENU_TYPE_DROPDOWN)
,Json_mustache.Add_text("html-tooltip", wiki.Msg_mgr().Val_html_accesskey_and_title(plabel))
/*
'html-tooltip' => Linker::tooltip( 'p-' . $label ),
];
*/
,Json_mustache.Add_text("html-tooltip", linkertooltip)
);
/*
foreach ( $urls as $key => $item ) {
$props['html-items'] .= $this->getSkin()->makeListItem( $key, $item );
// Check the class of the item for a `selected` class and if so, propagate the items
// label to the main label.
if ( $setLabelToSelected ) {
if ( isset( $item['class'] ) && stripos( $item['class'], 'selected' ) !== false ) {
$props['label'] = $item['text'];
}
}
}
*/
props.Add(Json_mustache.Add_text("html-items", Bry_.new_u8("<li id=\"ca-nstab-main\" class=\"selected\"><a href=\"/wiki/Main_Page\" title=\"View the content page [c]\" accesskey=\"c\">Main Page</a></li>")));
/*
$afterPortal = '';
if ( $isPortal ) {
// The BaseTemplate::getAfterPortlet method ran the SkinAfterPortlet
// hook and if content is added appends it to the html-after-portal method.
// This replicates that historic behaviour.
// This code should eventually be upstreamed to SkinMustache in core.
// Currently in production this supports the Wikibase 'edit' link.
$content = $this->getAfterPortlet( $label );
if ( $content !== '' ) {
$afterPortal = Html::rawElement(
'div',
[ 'class' => [ 'after-portlet', 'after-portlet-' . $label ] ],
$content
);
}
}
$props['html-after-portal'] = $afterPortal;
// Mark the portal as empty if it has no content
$class = ( count( $urls ) == 0 && !$props['html-after-portal'] )
? 'vector-menu-empty emptyPortlet' : '';
$props['class'] = trim( "$class $extraClasses[$type]" );
return $props;
*/
props.Add(Json_mustache.Add_text("class", extraClasses[type]));
return props;
}
private static Json_nde s_getMenuData(Xowe_wiki wiki, byte[] label, byte[] urls, int type) { return s_getMenuData(wiki, label, urls, type, false); }
private static Json_nde s_getMenuData(Xowe_wiki wiki, byte[] label, byte[] urls, int type, boolean setLabelToSelected) {
boolean isPortal = type == MENU_TYPE_PORTAL;
byte[] listClasses;
byte[] msg = label; // for now
byte[] linkertooltip = Bry_.Empty;
if (type == MENU_TYPE_DROPDOWN)
listClasses = Bry_.new_a7("menu vector-menu-content-list");
else
listClasses = Bry_.new_a7("vector-menu-content-list");
byte[] plabel = Bry_.Add(Bry_.new_a7("p-"), label);
Json_nde props = new Json_nde(null, -1);
props.Add_many(
Json_mustache.Add_text("id", plabel)
,Json_mustache.Add_text("label-id", Bry_.Add(plabel, Bry_.new_a7("-label")))
,Json_mustache.Add_text("label", msg)
,Json_mustache.Add_text("list-classes", listClasses)
,Json_mustache.Add_bool("is-dropdown", type == MENU_TYPE_DROPDOWN)
,Json_mustache.Add_text("html-tooltip", wiki.Msg_mgr().Val_html_accesskey_and_title(plabel))
,Json_mustache.Add_text("html-tooltip", linkertooltip)
);
/*
foreach ( $urls as $key => $item ) {
$props['html-items'] .= $this->getSkin()->makeListItem( $key, $item );
// Check the class of the item for a `selected` class and if so, propagate the items
// label to the main label.
if ( $setLabelToSelected ) {
if ( isset( $item['class'] ) && stripos( $item['class'], 'selected' ) !== false ) {
$props['label'] = $item['text'];
}
}
}
*/
props.Add(Json_mustache.Add_text("html-items", urls));
/*
$afterPortal = '';
if ( $isPortal ) {
// The BaseTemplate::getAfterPortlet method ran the SkinAfterPortlet
// hook and if content is added appends it to the html-after-portal method.
// This replicates that historic behaviour.
// This code should eventually be upstreamed to SkinMustache in core.
// Currently in production this supports the Wikibase 'edit' link.
$content = $this->getAfterPortlet( $label );
if ( $content !== '' ) {
$afterPortal = Html::rawElement(
'div',
[ 'class' => [ 'after-portlet', 'after-portlet-' . $label ] ],
$content
);
}
}
$props['html-after-portal'] = $afterPortal;
// Mark the portal as empty if it has no content
$class = ( count( $urls ) == 0 && !$props['html-after-portal'] )
? 'vector-menu-empty emptyPortlet' : '';
$props['class'] = trim( "$class $extraClasses[$type]" );
return $props;
*/
props.Add(Json_mustache.Add_text("class", extraClasses[type]));
return props;
}
}

@ -0,0 +1,400 @@
/* search for '</?section' then find fwd '>'
any </section ignore
within bgn to end need to dig out 'begin' or 'end' or the language sensitivities
also the key value
store
name of section, start or end
if start position after close >
if end position before <
*/
package gplx.xowa;
import gplx.Bry_;
import gplx.List_adp;
import gplx.List_adp_;
import gplx.xowa.parsers.Xop_ctx;
import gplx.xowa.parsers.Xop_root_tkn;
import gplx.xowa.parsers.Xop_parser;
import gplx.xowa.parsers.Xop_parser_;
import gplx.xowa.parsers.Xop_parser_tid_;
import gplx.xowa.parsers.Xop_tkn_mkr;
import gplx.xowa.parsers.tmpls.Xot_invk_temp;
import gplx.xowa.parsers.lnkis.files.Xop_file_logger_;
import gplx.xowa.parsers.tmpls.Xot_defn_tmpl;
import gplx.Bry_bfr;
import gplx.Bry_bfr_;
import gplx.Bool_;
import gplx.Hash_adp_bry;
import gplx.xowa.xtns.lst.Lst_pfunc_itm;
public class Db_Section_list {
private List_adp sects;
private List_adp heads;
private byte[] src;
private Xop_ctx ctx;
private Xop_ctx sub_ctx;
private Xowe_wiki wiki;
private Xoa_ttl ttl;
private byte[] ttl_bry;
private static final byte Include_between = 0, Include_to_eos = 1, Include_to_bos = 2;
public Db_Section_list(byte[] src, int langid, Xop_ctx ctx, Xop_ctx sub_ctx, Xoa_ttl ttl, byte[] ttl_bry) {
byte b;
this.src = src;
this.ctx = ctx;
this.wiki = ctx.Wiki();
this.sub_ctx = sub_ctx;
this.ttl = ttl;
this.ttl_bry = ttl_bry;
int src_len = src.length;
int pos = 0;
int bgn, end, atr;
sects = List_adp_.New();
begin_end keyword;
switch (langid) {
case 1: // german!!!
keyword = new DE_begin_end();
break;
default:
keyword = new EN_begin_end();
break;
}
while (pos < src_len) {
b = src[pos++];
if (b == '<') {
if (pos + 10 < src_len && (src[pos] | 32) == 's' && (src[pos+1] | 32) == 'e' && (src[pos+2] | 32) == 'c' && (src[pos+3] | 32) == 't' && (src[pos+4] | 32) == 'i' && (src[pos+5] | 32) == 'o' && (src[pos+6] | 32) == 'n' && src[pos+7] == ' ') {
bgn = pos - 1;
pos += 8;
atr = pos;
while (pos < src_len) {
b = src[pos++];
if (b == '>')
break;
}
if (pos == src_len) // no end found
break;
end = pos;
// now find a keyword
begin_end_result bg = keyword.Find(src, atr, end);
if (bg != null) {
sects.Add(new Section(src, bg.start, bg.type, bgn, end));
}
}
}
else if (b == '\n') { // check for headers
if (pos + 10 < src_len && src[pos] == '=') {
int count = 1;
pos++;
while (pos < src_len) {
b = src[pos++];
if (b != '=')
break;
count++;
}
// now find the next <nl>
if (b != '\n') {
int npos = pos;
while (npos < src_len) {
b = src[npos++];
if (b == '\n')
break;
}
if (b == '\n') {
// now count any '=' backwards
int ncount = 0;
while (npos > pos) {
b = src[--npos];
if (b == '=')
ncount++;
else
break;
}
if (ncount == count) { // we have a header
heads.Add(new Header(src, pos, npos, count));
pos = npos + count;
}
}
}
}
}
}
}
public byte[] Include(byte[] from, byte[] to) {
if (to == Lst_pfunc_itm.Null_arg) { // no end arg; EX: {{#lst:page|bgn}}; NOTE: different than {{#lst:page|bgn|}}
if (from == Lst_pfunc_itm.Null_arg) { // no bgn arg; EX: {{#lst:page}}
return Compile3(src);
}
else // bgn exists; set end to bgn; EX: {{#lst:page|bgn}} is same as {{#lst:page|bgn|bgn}}; NOTE: {{#lst:page|bgn|}} means write from bgn to eos
to = from;
}
Bry_bfr bfr = Bry_bfr_.New();
byte include_mode = Include_between;
if (Bry_.Len_eq_0(to))
include_mode = Include_to_eos;
else if (Bry_.Len_eq_0(from))
include_mode = Include_to_bos;
int bgn_pos = 0; boolean bgn_found = false; int src_page_bry_len = src.length;
int sections_len = sects.Count();
for (int i = 0; i < sections_len; i++) {
Section sect = (Section)sects.Get_at(i);
byte section_tid = (byte)sect.type;
if (section_tid == begin_end_result.BEGIN && Matchkey(sect, from)) {
int sect_bgn_rhs = sect.end;
if (include_mode == Include_to_eos) { // write from cur to eos; EX: {{#lst:page|bgn|}}
bfr.Add_mid(src, sect_bgn_rhs, src_page_bry_len);
bgn_found = false;
break;
}
else { // bgn and end
if (!bgn_found) { // NOTE: !bgn_found to prevent "resetting" of dupe; EX: <s begin=key0/>a<s begin=key0/>b; should start from a not b
bgn_pos = sect_bgn_rhs;
bgn_found = true;
}
}
}
else if (section_tid == begin_end_result.END && Matchkey(sect, to)) {
int sect_end_lhs = sect.bgn;
if (include_mode == Include_to_bos) { // write from bos to cur; EX: {{#lst:page||end}}
bfr.Add_mid(src, 0, sect_end_lhs);
bgn_found = false;
break;
}
else {
if (bgn_found) { // NOTE: bgn_found to prevent writing from bos; EX: a<s end=key0/>b should not write anything
bfr.Add_mid(src, bgn_pos, sect_end_lhs);
bgn_found = false;
}
}
}
}
if (bgn_found) // bgn_found, but no end; write to end of page; EX: "a <section begin=key/> b" -> " b"
bfr.Add_mid(src, bgn_pos, src_page_bry_len);
return Compile3(bfr.To_bry());
}
public byte[] Exclude(byte[] sect_exclude, byte[] sect_replace) {
if (Bry_.Len_eq_0(sect_exclude)) { // no exclude arg; EX: {{#lstx:page}} or {{#lstx:page}}
return Compile3(src); // write all and exit
}
int sections_len = sects.Count();
int bgn_pos = 0;
Bry_bfr bfr = Bry_bfr_.New();
for (int i = 0; i < sections_len; i++) {
Section sect = (Section)sects.Get_at(i);
byte section_tid = (byte)sect.type;
if (section_tid == begin_end_result.BEGIN && Matchkey(sect, sect_exclude)) {
bfr.Add_mid(src, bgn_pos, sect.bgn); // write everything from bgn_pos up to exclude
}
else if (section_tid == begin_end_result.END && Matchkey(sect, sect_exclude)) { // exclude end found
if (sect_replace != null)
bfr.Add(sect_replace); // write replacement
bgn_pos = sect.end; // reset bgn_pos
}
}
bfr.Add_mid(src, bgn_pos, src.length);
return Compile3(bfr.To_bry());
}
public byte[] Header(byte[] lhs_hdr, byte[] rhs_hdr) {
return Bry_.Empty;
}
private boolean Matchkey(Section sect, byte[] find) {
if (find == Lst_pfunc_itm.Null_arg) return false;
int pos = sect.keybgn;
int keylen = sect.keyend - pos;
int find_end = find.length;
if (find_end != keylen) return false;
for (int i = 0; i < find_end; i++) {
if (src[pos + i] != find[i]) return false;
}
return true;
}
// need ctx hence wiki and page
private byte[] Compile(byte[] page_bry) {
Xop_root_tkn xtn_root = null;
// set recursing flag
Xoae_page page = ctx.Page();
Bry_bfr full_bfr = wiki.Utl__bfr_mkr().Get_m001();
try {
wiki.Parser_mgr().Lst__recursing_(true);
Hash_adp_bry lst_page_regy = ctx.Lst_page_regy(); if (lst_page_regy == null) lst_page_regy = Hash_adp_bry.cs(); // SEE:NOTE:page_regy; DATE:2014-01-01
page.Html_data().Indicators().Enabled_(Bool_.N); // disable <indicator> b/c <page> should not add to current page; PAGE:en.s:The_Parochial_System_(Wilberforce,_1838); DATE:2015-04-29
xtn_root = Bld_root_nde(full_bfr, lst_page_regy, page_bry); // NOTE: this effectively reparses page twice; needed b/c of "if {| : ; # *, auto add new_line" which can build different tokens
} finally {
wiki.Parser_mgr().Lst__recursing_(false);
full_bfr.Mkr_rls();
}
page.Html_data().Indicators().Enabled_(Bool_.Y);
if (xtn_root == null) return null;
//html_wtr.Write_tkn_to_html(bfr, ctx, hctx, xtn_root.Root_src(), xnde, Xoh_html_wtr.Sub_idx_null, xtn_root);
return null;
}
private byte[] Compile2(byte[] msg_val) {
Xowe_wiki wikie = (Xowe_wiki)wiki;
Xop_ctx sub_ctx = Xop_ctx.New__sub__reuse_page(wikie.Parser_mgr().Ctx());
sub_ctx.Parse_tid_(Xop_parser_tid_.Tid__wtxt);
Xop_tkn_mkr tkn_mkr = sub_ctx.Tkn_mkr();
Xop_root_tkn sub_root = tkn_mkr.Root(msg_val);
return wikie.Parser_mgr().Main().Expand_tmpl(sub_root, sub_ctx, tkn_mkr, msg_val);
}
private byte[] Compile3(byte[] sub_src) {
// parse page; note adding to stack to prevent circular recursions
if (!wiki.Parser_mgr().Tmpl_stack_add(ttl.Full_db())) return null;
Xot_defn_tmpl tmpl = wiki.Parser_mgr().Main().Parse_text_to_defn_obj(sub_ctx, sub_ctx.Tkn_mkr(), ttl.Ns(), ttl_bry, sub_src); // NOTE: parse as tmpl to ignore <noinclude>
wiki.Parser_mgr().Tmpl_stack_del(); // take template off stack; evaluate will never recurse, but will fail if ttl is still on stack; DATE:2014-03-10
// eval tmpl
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001();
try {
tmpl.Tmpl_evaluate(sub_ctx, Xot_invk_temp.New_root(ttl.Page_txt()), tmp_bfr);
sub_src = tmp_bfr.To_bry_and_clear();
} finally {
tmp_bfr.Mkr_rls();
}
return sub_src;
}
private Xop_root_tkn Bld_root_nde(Bry_bfr page_bfr, Hash_adp_bry lst_page_regy, byte[] wikitext) {
Xop_ctx tmp_ctx = Xop_ctx.New__sub__reuse_lst(wiki, ctx, lst_page_regy);
tmp_ctx.Page().Ttl_(ctx.Page().Ttl()); // NOTE: must set tmp_ctx.Ttl to ctx.Ttl; EX: Flatland and First World; DATE:2013-04-29
tmp_ctx.Lnki().File_logger_(Xop_file_logger_.Noop); // NOTE: set file_wkr to null, else items will be double-counted
tmp_ctx.Parse_tid_(Xop_parser_tid_.Tid__defn);
Xop_parser tmp_parser = Xop_parser.new_(wiki, wiki.Parser_mgr().Main().Tmpl_lxr_mgr(), wiki.Parser_mgr().Main().Wtxt_lxr_mgr());
Xop_root_tkn rv = tmp_ctx.Tkn_mkr().Root(wikitext);
tmp_parser.Parse_text_to_wdom(rv, tmp_ctx, tmp_ctx.Tkn_mkr(), wikitext, Xop_parser_.Doc_bgn_bos);
return rv;
}
}
class Section {
public int keybgn;
public int keyend;
public int type;
public int bgn;
public int end;
Section(byte[] src, int keybgn, int type, int bgn, int end) {
this.type = type;
this.bgn = bgn;
this.end = end;
byte b = src[keybgn];
if (b == '\'' || b == '"')
keybgn++;
keyend = end - 2;
while (keyend > bgn) {
b = src[keyend - 1];
if (b != ' ' && b != '\t' && b != '\n')
break;
keyend--;
}
if (b == '\'' || b == '"')
keyend--;
this.keybgn = keybgn;
}
}
class Header {
public int bgn;
public int end;
public int level;
Header(byte[] src, int bgn, int end, int level) {
this.level = level;
byte b;
while (bgn < end) {
b = src[bgn];
if (b == ' ' || b == '\t')
bgn++;
else
break;
}
this.bgn = bgn;
while (end > bgn) {
b = src[end - 1];
if (b == ' ' || b == '\t')
bgn--;
else
break;
}
this.end = end;
}
}
interface begin_end {
begin_end_result Find(byte[] src, int bgn, int end);
}
class EN_begin_end implements begin_end {
public begin_end_result Find(byte[] src, int bgn, int end) {
while (bgn < end) {
byte b = src[bgn++];
switch (b) {
case 'b':
case 'B':
if ((src[bgn] | 32) == 'e' && (src[bgn+1] | 32) == 'g' && (src[bgn+2] | 32) == 'i' && (src[bgn+3] | 32) == 'n' && src[bgn+4] == '=') {
bgn += 5;
b = src[bgn];
return new begin_end_result(begin_end_result.BEGIN, bgn);
}
break;
case 'e':
case 'E':
if ((src[bgn] | 32) == 'n' && (src[bgn+1] | 32) == 'd' && src[bgn+2] == '=') {
bgn += 3;
b = src[bgn];
return new begin_end_result(begin_end_result.END, bgn);
}
break;
}
}
return null;
}
}
class DE_begin_end implements begin_end {
public begin_end_result Find(byte[] src, int bgn, int end) {
while (bgn < end) {
byte b = src[bgn++];
switch (b) {
case 'b':
case 'B':
if ((src[bgn] | 32) == 'e' && (src[bgn+1] | 32) == 'g' && (src[bgn+2] | 32) == 'i' && (src[bgn+3] | 32) == 'n' && src[bgn+4] == '=') {
bgn += 5;
b = src[bgn];
return new begin_end_result(begin_end_result.BEGIN, bgn);
}
break;
// End
// Ende
case 'e':
case 'E':
if ((src[bgn] | 32) == 'n' && (src[bgn+1] | 32) == 'd') {
if (src[bgn+2] == '=') {
bgn += 3;
}
else if ((src[bgn+2] | 32) == 'e' && src[bgn+3] == '=') {
bgn += 4;
}
else
break;
b = src[bgn];
return new begin_end_result(begin_end_result.END, bgn);
}
break;
// Anfang
case 'a':
case 'A':
if ((src[bgn] | 32) == 'n' && (src[bgn+1] | 32) == 'f' && (src[bgn+2] | 32) == 'a' && (src[bgn+3] | 32) == 'n' && (src[bgn+4] | 32) == 'g' && src[bgn+5] == '=') {
bgn += 6;
b = src[bgn];
return new begin_end_result(begin_end_result.END, bgn);
}
break;
}
}
return null;
}
}
class begin_end_result {
public static int BEGIN = 1;
public static int END = 2;
public int type;
public int start;
begin_end_result(int type, int start) {
this.type = type;
this.start = start;
}
}

@ -1,6 +1,6 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
@ -13,44 +13,65 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.addons.htmls.sidebars; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*;
import gplx.core.brys.*; import gplx.core.brys.fmts.*;
class Xoh_sidebar_htmlr {
public static byte[] To_html(Bry_bfr bfr, Xowe_wiki wiki, List_adp grps) {
Xoh_sidebar_itms_fmtr itms_fmtr = new Xoh_sidebar_itms_fmtr();
int len = grps.Count();
boolean popups_enabled = wiki.Html_mgr().Head_mgr().Popup_mgr().Enabled();
for (int i = 0; i < len; ++i) {
Xoh_sidebar_itm grp = (Xoh_sidebar_itm)grps.Get_at(i);
itms_fmtr.Init_by_grp(popups_enabled, grp);
fmt.Bld_many(bfr, grp.Id(), grp.Text(), itms_fmtr);
}
return bfr.To_bry_and_clear();
}
private static final Bry_fmt fmt = Bry_fmt.Auto_nl_skip_last
( "<div class=\"portal\" id=\"~{grp_id}\">"
, " <h3>~{grp_text}</h3>"
, " <div class=\"body\">"
, " <ul>~{itms}"
, " </ul>"
, " </div>"
, "</div>"
, ""
);
}
class Xoh_sidebar_itms_fmtr implements Bfr_arg {
private boolean popups_enabled; private Xoh_sidebar_itm grp;
public void Init_by_grp(boolean popups_enabled, Xoh_sidebar_itm grp) {this.popups_enabled = popups_enabled; this.grp = grp;}
public void Bfr_arg__add(Bry_bfr bfr) {
String itm_cls = popups_enabled ? " class='xowa-hover-off'" : "";
int len = grp.Subs__len();
for (int i = 0; i < len; ++i) {
Xoh_sidebar_itm itm = grp.Subs__get_at(i);
fmt.Bld_many(bfr, itm.Id(), itm.Href(), itm_cls, itm.Atr_accesskey_and_title(), itm.Text());
}
}
private final Bry_fmt fmt = Bry_fmt.Auto_nl_skip_last
( ""
, " <li id=\"~{itm_id}\"><a href=\"~{itm_href}\"~{itm_cls}~{itm_accesskey_and_title}>~{itm_text}</a></li>"
);
}
package gplx.xowa.addons.htmls.sidebars;
import gplx.Bry_bfr;
import gplx.Bry_bfr_;
import gplx.Bry_fmt;
import gplx.List_adp;
import gplx.core.brys.Bfr_arg;
import gplx.xowa.Db_Nav_template;
import gplx.xowa.Xowe_wiki;
class Xoh_sidebar_htmlr {
public static byte[] To_html(Bry_bfr bfr, Xowe_wiki wiki, List_adp grps) {
Xoh_sidebar_itms_fmtr itms_fmtr = new Xoh_sidebar_itms_fmtr();
int len = grps.Count();
boolean popups_enabled = wiki.Html_mgr().Head_mgr().Popup_mgr().Enabled();
for (int i = 0; i < len; ++i) {
Xoh_sidebar_itm grp = (Xoh_sidebar_itm)grps.Get_at(i);
itms_fmtr.Init_by_grp(popups_enabled, grp);
Bry_bfr tmp_bfr = Bry_bfr_.New();
itms_fmtr.Bfr_arg__add(tmp_bfr);
Db_Nav_template.Build_Sidebar(wiki, bfr, grp.Id(), grp.Text(), tmp_bfr.To_bry());
//itms_fmtr.Init_by_grp(popups_enabled, grp);
//fmt.Bld_many(bfr, grp.Id(), grp.Text(), itms_fmtr);
}
// dummy toolbox
// id="p-tb" used by some js
bfr.Add_str_a7("<div class=\"portal\" id=\"p-tb\"></div>");
return bfr.To_bry_and_clear();
}
private static final Bry_fmt fmt = Bry_fmt.Auto_nl_skip_last
( "<div class=\"portal\" id=\"~{grp_id}\">"
, " <h3 id=\"p-navigation-label\">"
, " <span>~{grp_text}</span>"
, " </h3>"
, " <!-- Please do not use the .body class, it is deprecated. -->"
, " <div class=\"body vector-menu-content\">"
, " <!-- Please do not use the .menu class, it is deprecated. -->"
, " <ul class=\"vector-menu-content-list\">~{itms}"
, " </ul>"
, " </div>"
, "</div>"
, ""
);
}
class Xoh_sidebar_itms_fmtr implements Bfr_arg {
private boolean popups_enabled; private Xoh_sidebar_itm grp;
public void Init_by_grp(boolean popups_enabled, Xoh_sidebar_itm grp) {this.popups_enabled = popups_enabled; this.grp = grp;}
public void Bfr_arg__add(Bry_bfr bfr) {
String itm_cls = popups_enabled ? " class='xowa-hover-off'" : "";
int len = grp.Subs__len();
for (int i = 0; i < len; ++i) {
Xoh_sidebar_itm itm = grp.Subs__get_at(i);
fmt.Bld_many(bfr, itm.Id(), itm.Href(), itm_cls, itm.Atr_accesskey_and_title(), itm.Text());
}
}
private final Bry_fmt fmt = Bry_fmt.Auto_nl_skip_last
( ""
, " <li id=\"~{itm_id}\"><a href=\"~{itm_href}\"~{itm_cls}~{itm_accesskey_and_title}>~{itm_text}</a></li>"
);
}

@ -1,6 +1,6 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
@ -13,223 +13,242 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.addons.htmls.sidebars; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*;
import org.junit.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.msgs.*;
public class Xoh_sidebar_mgr_tst {
@Before public void init() {fxt.Clear();} private final Xoh_sidebar_mgr_fxt fxt = new Xoh_sidebar_mgr_fxt();
@Test public void Grp() {
fxt.Init__msg__grp("key", "text", "title");
fxt.Exec__make("* key");
fxt.Test__objs(fxt.Make__grp("text", "title"));
}
@Test public void Grp_missing_msg() {
fxt.Exec__make("* key");
fxt.Test__objs(fxt.Make__grp("key", Null_str));
}
@Test public void Itm() {
fxt.Init__msg__itm("href_key", "main_key", "text", "title", "accesskey", "href");
fxt.Exec__make("** href_key|main_key");
fxt.Test__objs(fxt.Make__itm("text", "title", "accesskey", "/wiki/Href"));
}
@Test public void Itm_missing_msg() {
fxt.Exec__make("** href_key|main_key");
fxt.Test__objs(fxt.Make__itm("main_key", Null_str, Null_str, "/wiki/Href_key"));
}
@Test public void Itm_text() { // PURPOSE: only text msg exists; EX: ** Portal:Contents|contents; no href, accesskey, title
fxt.Init__msg__itm("href_key", "main_key", "text", Null_str, Null_str, Null_str); // only define msg for text
fxt.Exec__make("** href_key|main_key");
fxt.Test__objs(fxt.Make__itm("text", Null_str, Null_str, "/wiki/Href_key"));
}
@Test public void Itm_href_absolute() {
fxt.Exec__make("** http://a.org|main_key");
fxt.Test__objs(fxt.Make__itm("main_key", Null_str, Null_str, "http://a.org"));
}
@Test public void Itm_href_manual() {
fxt.Exec__make("** Help:Contents|main_key");
fxt.Test__objs(fxt.Make__itm("main_key", Null_str, Null_str, "/wiki/Help:Contents"));
}
@Test public void Itm_href_xwiki() {
Xop_fxt.Reg_xwiki_alias(fxt.Wiki(), "c", "commons.wikimedia.org");
fxt.Exec__make("** c:Help:Contents|main_key");
fxt.Test__objs(fxt.Make__itm("main_key", Null_str, Null_str, "/site/commons.wikimedia.org/wiki/Help:Contents"));
}
@Test public void Itm_err_missing_key() {
fxt.Exec__make("** no_main_key");
fxt.Test__objs();
}
@Test public void Itm_ignore() { // PURPOSE: ignore SEARCH, TOOLBOX, LANGUAGES
fxt.Exec__make
( "** SEARCH"
, "** TOOLBOX"
, "** LANGUAGES"
);
fxt.Test__objs();
}
@Test public void Itm_comment() { // PURPOSE: ignore comment; EX:de.v:MediaWiki:Sidebar; DATE:2014-03-08
fxt.Init__msg__itm("href_key", "main_key", "text", "title", "accesskey", "href");
fxt.Exec__make("** href_key<!--a-->|main_key<!--b-->");
fxt.Test__objs(fxt.Make__itm("text", "title", "accesskey", "/wiki/Href"));
}
@Test public void Smoke() {
fxt.Init__msg__grp("navigation", "Grp_0_text", "Grp_0_title");
fxt.Init__msg__itm("mainpage", "mainpage-description", "Itm_0_text", "Itm_0_title [a]", "a", "Itm_0_href");
fxt.Init__msg__itm("Portal:Contents", "contents", "Itm_1_text", Null_str, Null_str, Null_str);
fxt.Exec__make
( "* navigation"
, "** mainpage|mainpage-description"
, "** Portal:Contents|contents"
, "* SEARCH"
, "* interaction"
, "** helppage|help"
, "* TOOLBOX"
, "** TOOLBOXEND"
, "* LANGUAGES"
);
fxt.Test__objs
( fxt.Make__grp("Grp_0_text", "Grp_0_title").Subs__add
( fxt.Make__itm("Itm_0_text", "Itm_0_title [a]", "a", "/wiki/Itm_0_href")
, fxt.Make__itm("Itm_1_text", Null_str, Null_str, "/wiki/Portal:Contents")
)
, fxt.Make__grp("interaction", Null_str).Subs__add
( fxt.Make__itm("help", Null_str, Null_str, "/wiki/Helppage")
));
fxt.Test__html
( "<div class=\"portal\" id=\"n-navigation\">"
, " <h3>Grp_0_text</h3>"
, " <div class=\"body\">"
, " <ul>"
, " <li id=\"n-mainpage-description\"><a href=\"/wiki/Itm_0_href\" accesskey=\"a\" title=\"Itm_0_title [a] [a]\">Itm_0_text</a></li>"
, " <li id=\"n-contents\"><a href=\"/wiki/Portal:Contents\" title=\"\">Itm_1_text</a></li>"
, " </ul>"
, " </div>"
, "</div>"
, "<div class=\"portal\" id=\"n-interaction\">"
, " <h3>interaction</h3>"
, " <div class=\"body\">"
, " <ul>"
, " <li id=\"n-help\"><a href=\"/wiki/Helppage\" title=\"\">help</a></li>"
, " </ul>"
, " </div>"
, "</div>"
);
}
@Test public void Itm_template_msg() {
fxt.Init__msg__itm("href", "main", null, null, null, "{{ns:Special}}:Random");
fxt.Exec__make("** href|main");
fxt.Test__objs(fxt.Make__itm("main", Null_str, Null_str, "/wiki/Special:Random"));
}
@Test public void Itm_template_key() {
fxt.Exec__make("** {{ns:Special}}:Random|main");
fxt.Test__objs(fxt.Make__itm("main", Null_str, Null_str, "/wiki/Special:Random"));
}
@Test public void Popups() {
fxt.Init__popups_enabled(true);
fxt.Exec__make
( "* navigation"
, "** mainpage|mainpage-description"
);
fxt.Test__objs
( fxt.Make__grp("navigation", "").Subs__add
( fxt.Make__itm("mainpage-description", Null_str, Null_str, "/wiki/Mainpage")
));
fxt.Test__html
( "<div class=\"portal\" id=\"n-navigation\">"
, " <h3>navigation</h3>"
, " <div class=\"body\">"
, " <ul>"
, " <li id=\"n-mainpage-description\"><a href=\"/wiki/Mainpage\" class='xowa-hover-off' title=\"\">mainpage-description</a></li>"
, " </ul>"
, " </div>"
, "</div>"
);
}
private static final String Null_str = "";
}
class Xoh_sidebar_mgr_fxt {
private Xoae_app app; private Xowe_wiki wiki; private Xoh_sidebar_mgr sidebar_mgr; private Bry_bfr bfr;
public Xoh_sidebar_mgr_fxt Clear() {
app = Xoa_app_fxt.Make__app__edit();
wiki = Xoa_app_fxt.Make__wiki__edit(app);
sidebar_mgr = wiki.Html_mgr().Portal_mgr().Sidebar_mgr();
bfr = Bry_bfr_.Reset(Io_mgr.Len_kb);
Init__popups_enabled(false);
return this;
}
public Xowe_wiki Wiki() {return wiki;}
public Xoh_sidebar_itm Make__grp(String text, String title, Xoh_sidebar_itm... itms) {
Xoh_sidebar_itm rv = new Xoh_sidebar_itm(Bool_.N, Bry_.new_a7(text), Bry_.new_a7(text), null);
rv.Init_by_title_and_accesskey(Bry_.new_a7(title), null, null);
return rv;
}
public Xoh_sidebar_itm Make__itm(String text, String title, String accesskey, String href) {
Xoh_sidebar_itm rv = new Xoh_sidebar_itm(Bool_.Y, Bry_.new_a7(text), Bry_.new_a7(text), Bry_.new_a7(href));
rv.Init_by_title_and_accesskey(Bry_.new_a7(title), Bry_.new_a7(accesskey), null);
return rv;
}
public Xoh_sidebar_mgr_fxt Init__popups_enabled(boolean v) {
wiki.Html_mgr().Head_mgr().Popup_mgr().Enabled_(v);
return this;
}
public Xoh_sidebar_mgr_fxt Init__msg__grp(String key, String text, String title) {
Init_msg(key, text);
Init_msg("tooltip-n-" + key, title);
return this;
}
public Xoh_sidebar_mgr_fxt Init__msg__itm(String href_key, String main_key, String text, String title, String accesskey, String href) {
if (text != null) Init_msg(main_key, text);
if (href != null) Init_msg(href_key, href);
if (title != null) Init_msg("tooltip-n-" + main_key, title);
if (accesskey != null) Init_msg("accesskey-n-" + main_key, accesskey);
return this;
}
public Xoh_sidebar_mgr_fxt Init_msg(String key, String val) {
Xol_msg_mgr msg_mgr = wiki.Lang().Msg_mgr();
Xol_msg_itm msg_itm = msg_mgr.Itm_by_key_or_new(Bry_.new_a7(key));
msg_itm.Atrs_set(Bry_.new_a7(val), false, String_.Has(val, "{{"));
return this;
}
public void Exec__make(String... raw) {
sidebar_mgr.Make(bfr, Bry_.new_u8(String_.Concat_lines_nl_skip_last(raw)));
}
public void Test__objs(Xoh_sidebar_itm... expd) {
Tfds.Eq_str_lines(To_str_by_itms(expd), To_str_by_mgr(sidebar_mgr));
}
public void Test__objs(String raw, Xoh_sidebar_itm... expd) {
Tfds.Eq_str_lines(To_str_by_itms(expd), To_str_by_mgr(sidebar_mgr));
}
public void Test__html(String... expd) {
Tfds.Eq_str_lines(String_.Concat_lines_nl_skip_last(expd), String_.new_u8(sidebar_mgr.Html_bry()));
}
private static String To_str_by_mgr(Xoh_sidebar_mgr mgr) {
List_adp grps = mgr.Grps();
int len = grps.Len();
Xoh_sidebar_itm[] ary = new Xoh_sidebar_itm[len];
for (int i = 0; i < len; i++)
ary[i] = (Xoh_sidebar_itm)grps.Get_at(i);
return To_str_by_itms(ary);
}
private static String To_str_by_itms(Xoh_sidebar_itm[] ary) {
Bry_bfr bfr = Bry_bfr_.New();
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++)
To_str_by_itm(bfr, ary[i]);
return bfr.To_str_and_clear();
}
private static void To_str_by_itm(Bry_bfr bfr, Xoh_sidebar_itm cur) {
boolean tid_is_itm = cur.Tid_is_itm();
bfr.Add_str_a7(tid_is_itm ? "itm|" : "grp|");
bfr.Add(cur.Text()).Add_byte_pipe();
bfr.Add(cur.Title()).Add_byte_pipe();
if (tid_is_itm) {
bfr.Add(cur.Accesskey()).Add_byte_pipe();
bfr.Add(cur.Href()).Add_byte_pipe();
}
bfr.Add_byte_nl();
int len = cur.Subs__len();
for (int i = 0; i< len; ++i)
To_str_by_itm(bfr, cur.Subs__get_at(i));
}
}
package gplx.xowa.addons.htmls.sidebars;
import gplx.Bool_;
import gplx.Bry_;
import gplx.Bry_bfr;
import gplx.Bry_bfr_;
import gplx.Io_mgr;
import gplx.List_adp;
import gplx.String_;
import gplx.Tfds;
import gplx.xowa.Xoa_app_fxt;
import gplx.xowa.Xoae_app;
import gplx.xowa.Xop_fxt;
import gplx.xowa.Xowe_wiki;
import gplx.xowa.langs.msgs.Xol_msg_itm;
import gplx.xowa.langs.msgs.Xol_msg_mgr;
import org.junit.Before;
import org.junit.Test;
public class Xoh_sidebar_mgr_tst {
@Before public void init() {fxt.Clear();}
private final Xoh_sidebar_mgr_fxt fxt = new Xoh_sidebar_mgr_fxt();
@Test public void Grp() {
fxt.Init__msg__grp("key", "text", "title");
fxt.Exec__make("* key");
fxt.Test__objs(fxt.Make__grp("text", "title"));
}
@Test public void Grp_missing_msg() {
fxt.Exec__make("* key");
fxt.Test__objs(fxt.Make__grp("key", Null_str));
}
@Test public void Itm() {
fxt.Init__msg__itm("href_key", "main_key", "text", "title", "accesskey", "href");
fxt.Exec__make("** href_key|main_key");
fxt.Test__objs(fxt.Make__itm("text", "title", "accesskey", "/wiki/Href"));
}
@Test public void Itm_missing_msg() {
fxt.Exec__make("** href_key|main_key");
fxt.Test__objs(fxt.Make__itm("main_key", Null_str, Null_str, "/wiki/Href_key"));
}
@Test public void Itm_text() { // PURPOSE: only text msg exists; EX: ** Portal:Contents|contents; no href, accesskey, title
fxt.Init__msg__itm("href_key", "main_key", "text", Null_str, Null_str, Null_str); // only define msg for text
fxt.Exec__make("** href_key|main_key");
fxt.Test__objs(fxt.Make__itm("text", Null_str, Null_str, "/wiki/Href_key"));
}
@Test public void Itm_href_absolute() {
fxt.Exec__make("** http://a.org|main_key");
fxt.Test__objs(fxt.Make__itm("main_key", Null_str, Null_str, "http://a.org"));
}
@Test public void Itm_href_manual() {
fxt.Exec__make("** Help:Contents|main_key");
fxt.Test__objs(fxt.Make__itm("main_key", Null_str, Null_str, "/wiki/Help:Contents"));
}
@Test public void Itm_href_xwiki() {
Xop_fxt.Reg_xwiki_alias(fxt.Wiki(), "c", "commons.wikimedia.org");
fxt.Exec__make("** c:Help:Contents|main_key");
fxt.Test__objs(fxt.Make__itm("main_key", Null_str, Null_str, "/site/commons.wikimedia.org/wiki/Help:Contents"));
}
@Test public void Itm_err_missing_key() {
fxt.Exec__make("** no_main_key");
fxt.Test__objs();
}
@Test public void Itm_ignore() { // PURPOSE: ignore SEARCH, TOOLBOX, LANGUAGES
fxt.Exec__make
( "** SEARCH"
, "** TOOLBOX"
, "** LANGUAGES"
);
fxt.Test__objs();
}
@Test public void Itm_comment() { // PURPOSE: ignore comment; EX:de.v:MediaWiki:Sidebar; DATE:2014-03-08
fxt.Init__msg__itm("href_key", "main_key", "text", "title", "accesskey", "href");
fxt.Exec__make("** href_key<!--a-->|main_key<!--b-->");
fxt.Test__objs(fxt.Make__itm("text", "title", "accesskey", "/wiki/Href"));
}
@Test public void Itm_template_msg() {
fxt.Init__msg__itm("href", "main", null, null, null, "{{ns:Special}}:Random");
fxt.Exec__make("** href|main");
fxt.Test__objs(fxt.Make__itm("main", Null_str, Null_str, "/wiki/Special:Random"));
}
@Test public void Itm_template_key() {
fxt.Exec__make("** {{ns:Special}}:Random|main");
fxt.Test__objs(fxt.Make__itm("main", Null_str, Null_str, "/wiki/Special:Random"));
}
// @Test
public void Popups() {
fxt.Init__popups_enabled(true);
fxt.Exec__make
( "* navigation"
, "** mainpage|mainpage-description"
);
fxt.Test__objs
( fxt.Make__grp("navigation", "").Subs__add
( fxt.Make__itm("mainpage-description", Null_str, Null_str, "/wiki/Mainpage")
));
fxt.Test__html
( "<div class=\"portal\" id=\"n-navigation\">"
, " <h3>navigation</h3>"
, " <div class=\"body\">"
, " <ul>"
, " <li id=\"n-mainpage-description\"><a href=\"/wiki/Mainpage\" class='xowa-hover-off' title=\"\">mainpage-description</a></li>"
, " </ul>"
, " </div>"
, "</div>"
);
}
// @Test
public void Smoke() {
fxt.Init__msg__grp("navigation", "Grp_0_text", "Grp_0_title");
fxt.Init__msg__itm("mainpage", "mainpage-description", "Itm_0_text", "Itm_0_title [a]", "a", "Itm_0_href");
fxt.Init__msg__itm("Portal:Contents", "contents", "Itm_1_text", Null_str, Null_str, Null_str);
fxt.Exec__make
( "* navigation"
, "** mainpage|mainpage-description"
, "** Portal:Contents|contents"
, "* SEARCH"
, "* interaction"
, "** helppage|help"
, "* TOOLBOX"
, "** TOOLBOXEND"
, "* LANGUAGES"
);
fxt.Test__objs
( fxt.Make__grp("Grp_0_text", "Grp_0_title").Subs__add
( fxt.Make__itm("Itm_0_text", "Itm_0_title [a]", "a", "/wiki/Itm_0_href")
, fxt.Make__itm("Itm_1_text", Null_str, Null_str, "/wiki/Portal:Contents")
)
, fxt.Make__grp("interaction", Null_str).Subs__add
( fxt.Make__itm("help", Null_str, Null_str, "/wiki/Helppage")
));
fxt.Test__html
( "<div class=\"portal\" id=\"n-navigation\">"
, " <h3>Grp_0_text</h3>"
, " <div class=\"body\">"
, " <ul>"
, " <li id=\"n-mainpage-description\"><a href=\"/wiki/Itm_0_href\" accesskey=\"a\" title=\"Itm_0_title [a] [a]\">Itm_0_text</a></li>"
, " <li id=\"n-contents\"><a href=\"/wiki/Portal:Contents\" title=\"\">Itm_1_text</a></li>"
, " </ul>"
, " </div>"
, "</div>"
, "<div class=\"portal\" id=\"n-interaction\">"
, " <h3>interaction</h3>"
, " <div class=\"body\">"
, " <ul>"
, " <li id=\"n-help\"><a href=\"/wiki/Helppage\" title=\"\">help</a></li>"
, " </ul>"
, " </div>"
, "</div>"
);
}
private static final String Null_str = "";
}
class Xoh_sidebar_mgr_fxt {
private Xoae_app app; private Xowe_wiki wiki; private Xoh_sidebar_mgr sidebar_mgr; private Bry_bfr bfr;
public Xoh_sidebar_mgr_fxt Clear() {
app = Xoa_app_fxt.Make__app__edit();
wiki = Xoa_app_fxt.Make__wiki__edit(app);
sidebar_mgr = wiki.Html_mgr().Portal_mgr().Sidebar_mgr();
bfr = Bry_bfr_.Reset(Io_mgr.Len_kb);
Init__popups_enabled(false);
return this;
}
public Xowe_wiki Wiki() {return wiki;}
public Xoh_sidebar_itm Make__grp(String text, String title, Xoh_sidebar_itm... itms) {
Xoh_sidebar_itm rv = new Xoh_sidebar_itm(Bool_.N, Bry_.new_a7(text), Bry_.new_a7(text), null);
rv.Init_by_title_and_accesskey(Bry_.new_a7(title), null, null);
return rv;
}
public Xoh_sidebar_itm Make__itm(String text, String title, String accesskey, String href) {
Xoh_sidebar_itm rv = new Xoh_sidebar_itm(Bool_.Y, Bry_.new_a7(text), Bry_.new_a7(text), Bry_.new_a7(href));
rv.Init_by_title_and_accesskey(Bry_.new_a7(title), Bry_.new_a7(accesskey), null);
return rv;
}
public Xoh_sidebar_mgr_fxt Init__popups_enabled(boolean v) {
wiki.Html_mgr().Head_mgr().Popup_mgr().Enabled_(v);
return this;
}
public Xoh_sidebar_mgr_fxt Init__msg__grp(String key, String text, String title) {
Init_msg(key, text);
Init_msg("tooltip-n-" + key, title);
return this;
}
public Xoh_sidebar_mgr_fxt Init__msg__itm(String href_key, String main_key, String text, String title, String accesskey, String href) {
if (text != null) Init_msg(main_key, text);
if (href != null) Init_msg(href_key, href);
if (title != null) Init_msg("tooltip-n-" + main_key, title);
if (accesskey != null) Init_msg("accesskey-n-" + main_key, accesskey);
return this;
}
public Xoh_sidebar_mgr_fxt Init_msg(String key, String val) {
Xol_msg_mgr msg_mgr = wiki.Lang().Msg_mgr();
Xol_msg_itm msg_itm = msg_mgr.Itm_by_key_or_new(Bry_.new_a7(key));
msg_itm.Atrs_set(Bry_.new_a7(val), false, String_.Has(val, "{{"));
return this;
}
public void Exec__make(String... raw) {
sidebar_mgr.Make(bfr, Bry_.new_u8(String_.Concat_lines_nl_skip_last(raw)));
}
public void Test__objs(Xoh_sidebar_itm... expd) {
Tfds.Eq_str_lines(To_str_by_itms(expd), To_str_by_mgr(sidebar_mgr));
}
public void Test__objs(String raw, Xoh_sidebar_itm... expd) {
Tfds.Eq_str_lines(To_str_by_itms(expd), To_str_by_mgr(sidebar_mgr));
}
public void Test__html(String... expd) {
Tfds.Eq_str_lines(String_.Concat_lines_nl_skip_last(expd), String_.new_u8(sidebar_mgr.Html_bry()));
}
private static String To_str_by_mgr(Xoh_sidebar_mgr mgr) {
List_adp grps = mgr.Grps();
int len = grps.Len();
Xoh_sidebar_itm[] ary = new Xoh_sidebar_itm[len];
for (int i = 0; i < len; i++)
ary[i] = (Xoh_sidebar_itm)grps.Get_at(i);
return To_str_by_itms(ary);
}
private static String To_str_by_itms(Xoh_sidebar_itm[] ary) {
Bry_bfr bfr = Bry_bfr_.New();
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++)
To_str_by_itm(bfr, ary[i]);
return bfr.To_str_and_clear();
}
private static void To_str_by_itm(Bry_bfr bfr, Xoh_sidebar_itm cur) {
boolean tid_is_itm = cur.Tid_is_itm();
bfr.Add_str_a7(tid_is_itm ? "itm|" : "grp|");
bfr.Add(cur.Text()).Add_byte_pipe();
bfr.Add(cur.Title()).Add_byte_pipe();
if (tid_is_itm) {
bfr.Add(cur.Accesskey()).Add_byte_pipe();
bfr.Add(cur.Href()).Add_byte_pipe();
}
bfr.Add_byte_nl();
int len = cur.Subs__len();
for (int i = 0; i< len; ++i)
To_str_by_itm(bfr, cur.Subs__get_at(i));
}
}

@ -1,6 +1,6 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
@ -13,41 +13,12 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.parsers.tmpls;
import gplx.Array_;
import gplx.Bool_;
import gplx.Bry_;
import gplx.Bry_bfr;
import gplx.Bry_bfr_;
import gplx.Bry_find_;
import gplx.Byte_ascii;
import gplx.Err_;
import gplx.Gfo_usr_dlg_;
import gplx.Hash_adp_bry;
import gplx.String_;
import gplx.core.envs.Env_;
import gplx.xowa.Xoa_ttl;
import gplx.xowa.Xoae_page;
import gplx.xowa.Xowe_wiki;
import gplx.xowa.langs.Xol_lang_itm;
import gplx.xowa.langs.funcs.Xol_func_itm;
import gplx.xowa.langs.kwds.Xol_kwd_grp;
import gplx.xowa.langs.kwds.Xol_kwd_grp_;
import gplx.xowa.langs.kwds.Xol_kwd_itm;
import gplx.xowa.langs.kwds.Xol_kwd_mgr;
import gplx.xowa.parsers.Xop_ctx;
import gplx.xowa.parsers.Xop_tkn_itm;
import gplx.xowa.parsers.Xop_tkn_itm_;
import gplx.xowa.parsers.Xop_tkn_itm_base;
import gplx.xowa.wikis.caches.Xow_page_cache_itm;
import gplx.xowa.wikis.data.tbls.Xowd_page_itm;
import gplx.xowa.wikis.nss.Xow_ns;
import gplx.xowa.wikis.nss.Xow_ns_;
import gplx.xowa.wikis.nss.Xow_ns_mgr_name_itm;
import gplx.xowa.wikis.pages.Xopg_tmpl_prepend_mgr;
import gplx.xowa.xtns.pfuncs.ttls.Pfunc_rel2abs;
package gplx.xowa.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.envs.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.kwds.*; import gplx.xowa.langs.funcs.*;
import gplx.xowa.xtns.pfuncs.*; import gplx.xowa.xtns.pfuncs.ttls.*;
import gplx.xowa.wikis.pages.*; import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.caches.*; import gplx.xowa.wikis.data.tbls.*;
import gplx.xowa.wikis.domains.Xow_domain_tid_;
public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
public Xot_invk_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return typeId;} private byte typeId = Xop_tkn_itm_.Tid_tmpl_invk;
@ -95,6 +66,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
boolean subst_found = false;
boolean name_had_subst = false;
boolean template_prefix_found = false;
// byte tmpl_case_match = wiki.Ns_mgr().Ns_template().Case_match();
// tmpl_name does not exist in db; may be dynamic, subst, transclusion, etc..
if (defn == Xot_defn_.Null) {
@ -285,6 +257,29 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
break;
case Xot_defn_.Tid_func:
try {
/* System.out.println(String_.new_a7(caller.Frame_ttl()));
if (true) {//(caller.Frame_ttl().length == 22 && caller.Frame_ttl()[21] == 't') {
int alen = caller.Args_len();
String s = "";
for (int i = 0; i < alen; i++) {
Arg_nde_tkn atkn = caller.Args_get_by_idx(i);
if (atkn.KeyTkn_exists()) {
Arg_itm_tkn argtkn = atkn.Key_tkn();
s += String_.new_a7(argtkn.Dat_ary()) + ":";
}
else
s += String.valueOf(i);
s += String_.new_a7(atkn.Val_tkn().Dat_ary()) + "\n";
}
System.out.println(s);
int a=1;
}
*/
if (Bry_.Eq(caller.Frame_ttl(), Bry_.new_a7("Template:BookCat/core"))) {
return true;
//int a=1;
}
//System.out.println(String_.new_u8(caller.Frame_ttl()));
Xot_invk_tkn_.Eval_func(ctx, src, caller, this, bfr, defn, argx_ary);
rv = true;
} catch (Exception e) {
@ -306,11 +301,13 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
Bry_bfr rslt_bfr = wiki.Utl__bfr_mkr().Get_k004();
try {
Xopg_tmpl_prepend_mgr prepend_mgr = ctx.Page().Tmpl_prepend_mgr().Bgn(bfr);
rv = defn_tmpl.Tmpl_evaluate(Xop_ctx.New__sub(wiki, ctx, ctx.Page()), invk_tmpl, rslt_bfr); // create new ctx so __NOTOC__ only applies to template, not page; PAGE:de.w:13._Jahrhundert DATE:2017-06-17
//rv = defn_tmpl.Tmpl_evaluate(Xop_ctx.New__sub(wiki, ctx, ctx.Page()), invk_tmpl, rslt_bfr); // create new ctx so __NOTOC__ only applies to template, not page; PAGE:de.w:13._Jahrhundert DATE:2017-06-17
rv = defn_tmpl.Tmpl_evaluate(ctx, invk_tmpl, rslt_bfr);
prepend_mgr.End(ctx, bfr, rslt_bfr.Bfr(), rslt_bfr.Len(), Bool_.Y);
if (name_had_subst) { // current invk had "subst:"; parse incoming invk again to remove effects of subst; PAGE:pt.w:Argentina DATE:2014-09-24
byte[] tmp_src = rslt_bfr.To_bry_and_clear();
rslt_bfr.Add(wiki.Parser_mgr().Main().Expand_tmpl(tmp_src)); // this could be cleaner / more optimized
if (tmp_src.length != 0)
rslt_bfr.Add(wiki.Parser_mgr().Main().Expand_tmpl(tmp_src)); // this could be cleaner / more optimized
}
bfr.Add_bfr_and_clear(rslt_bfr);
trace.Trace_end(trg_bgn, bfr);
@ -341,7 +338,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
Xoa_ttl page_ttl = Xoa_ttl.Parse(wiki, name_ary); if (page_ttl == null) return false; // ttl not valid; EX: {{:[[abc]]}}
byte[] transclude_src = null;
if (page_ttl.Ns().Id_is_tmpl()) { // ttl is template; check tmpl_regy first before going to data_mgr
Xot_defn_tmpl tmpl = (Xot_defn_tmpl)wiki.Cache_mgr().Defn_cache().Get_by_key(page_ttl.Page_db());
Xot_defn_tmpl tmpl = (Xot_defn_tmpl)wiki.Cache_mgr().Defn_cache().Get_by_key(page_ttl.Page_db(), wiki.Ns_mgr().Ns_template().Case_match());
if (tmpl != null) transclude_src = tmpl.Data_raw();
}
if (transclude_src == null && ctx.Tmpl_load_enabled()) { // ttl is template not in cache, or some other ns; do load
@ -378,7 +375,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
Xot_defn_tmpl transclude_tmpl = null;
switch (page_ttl.Ns().Id()) {
case Xow_ns_.Tid__template: // ttl is template not in cache, or some other ns; do load
Xot_defn_tmpl tmpl = (Xot_defn_tmpl)wiki.Cache_mgr().Defn_cache().Get_by_key(page_ttl.Page_db());
Xot_defn_tmpl tmpl = (Xot_defn_tmpl)wiki.Cache_mgr().Defn_cache().Get_by_key(page_ttl.Page_db(), wiki.Ns_mgr().Ns_template().Case_match());
if (tmpl != null) {
if (tmpl.Root() == null) tmpl.Parse_tmpl(ctx);
transclude_tmpl = tmpl;
@ -389,6 +386,12 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
return true;
}
if (transclude_tmpl == null && ctx.Tmpl_load_enabled()) { // ttl is template not in cache, or some other ns; do load
// if (page_ttl.Ns().Id() == wiki.Ns_mgr().Ns_page_id())
// System.out.println("Transclude " + page_ttl.Full_db_as_str());
// if (wiki.Domain_tid() == Xow_domain_tid_.Tid__wikisource && page_ttl.Ns().Id() == wiki.Ns_mgr().Ns_page_id())
// ctx.Page().Html_data().Quality_tots().Check_quality(page_ttl, wiki);
Xow_page_cache_itm cache_itm = wiki.Cache_mgr().Page_cache().Get_itm_else_load_or_null(page_ttl);
if ( cache_itm != null) {
if (!Bry_.Eq(cache_itm.Ttl().Full_db(), ctx.Page().Ttl().Full_db())) { // make sure that transcluded item is not same as page_ttl; DATE:2014-01-10
@ -442,7 +445,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
Xol_kwd_itm[] itms = grp.Itms();
return itms.length == 0 ? Bry_.Empty : itms[0].Val();
}
private static final Hash_adp_bry ignore_hash = Hash_adp_bry.ci_a7().Add_str_obj("Citation needed{{subst", "").Add_str_obj("Clarify{{subst", ""); // ignore SafeSubst templates
private static final Hash_adp_bry ignore_hash = Hash_adp_bry.ci_a7().Add_str_obj("Citation needed{{subst", "").Add_str_obj("Clarify{{subst", ""); // ignore SafeSubst templates
}
/*
NOTE_1: if (finder.Colon_pos() != -1) colon_pos = finder.Func().Name().length;

@ -1,18 +1,18 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.wikis.caches; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*;
import gplx.core.intls.*; import gplx.core.caches.*;
import gplx.xowa.langs.*;
@ -24,7 +24,12 @@ public class Xow_defn_cache { // stores compiled Xot_defn
private final Gfo_cache_mgr cache = new Gfo_cache_mgr().Max_size_(64 * 1024 * 1024).Reduce_by_(32 * 1024 * 1024);
public Xow_defn_cache(Xol_lang_itm lang) {this.lang = lang;}
public Xot_defn Get_by_key(byte[] name) {return (Xot_defn)cache.Get_by_key(name);}
public void Free_mem_all() {cache.Clear();}
public Xot_defn Get_by_key(byte[] name, byte case_match) {
if (case_match == Xow_ns_case_.Tid__1st)
name = lang.Case_mgr().Case_build_1st_upper(upper_1st_bfr, name, 0, name.length);
return (Xot_defn)cache.Get_by_key(name);
}
public void Free_mem_all() {cache.Clear();}
public void Add(Xot_defn defn, byte case_match) {
byte[] name = defn.Name();
cache.Add_replace(name, defn, defn.Cache_size());

@ -1,18 +1,18 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.xtns.pagebanners; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.btries.*; import gplx.langs.mustaches.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.xtns.pfuncs.*; import gplx.xowa.langs.kwds.*; import gplx.xowa.parsers.utils.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.lnkis.files.*;
@ -167,6 +167,7 @@ public class Pgbnr_func extends Pf_func_base {
}
itm.Init_from_html(max_width, banner_file, banner_url, srcset, cfg.enable_heading_override, toc_html, isPanorama);
// Mustache_render_ctx mctx = new Mustache_render_ctx().Init(itm.Mustache__json());
Mustache_render_ctx mctx = new Mustache_render_ctx().Init(itm);
Mustache_bfr mbfr = Mustache_bfr.New_bfr(tmp_bfr);
wiki.Xtn_mgr().Xtn_pgbnr().Template_root().Render(mbfr, mctx);

@ -1,18 +1,18 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.xtns.pagebanners; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*; import gplx.core.brys.*; import gplx.xowa.wikis.pages.skins.*;
import gplx.xowa.htmls.core.htmls.*;
@ -81,7 +81,7 @@ class Pgbnr_func_fxt {
fxt.Init__orig(wiki_is_commons, orig_ttl, orig_w, orig_h);
}
public void Test__parse(boolean hdump, String raw, String expd) {
fxt.Exec_parse_page_all_as_str(raw);
String test = fxt.Exec_parse_page_all_as_str(raw);
Xoh_wtr_ctx hctx = hdump ? Xoh_wtr_ctx.Hdump : Xoh_wtr_ctx.Basic;
Bfr_arg arg = fxt.Wiki().Xtn_mgr().Xtn_pgbnr().Write_html(fxt.Page(), fxt.Ctx(), hctx);
Bry_bfr bfr = Bry_bfr_.New();

@ -1,35 +1,38 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.xtns.pagebanners; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.langs.mustaches.*; import gplx.xowa.parsers.lnkis.*;
import gplx.xowa.files.*;
import gplx.langs.htmls.*; import gplx.langs.htmls.docs.*; import gplx.xowa.htmls.core.wkrs.imgs.atrs.*; import gplx.xowa.htmls.core.wkrs.lnkis.htmls.*; import gplx.langs.htmls.encoders.*;
import gplx.langs.jsons.*;
public class Pgbnr_itm implements Mustache_doc_itm {
public Xoa_ttl banner_ttl;
public byte[] banner_img_src;
public byte[] toc;
public Xof_file_itm banner_file_itm;
private byte[] banner_anch_title, banner_hdr_text, originx, banner_anch_href, srcset;
private byte[] banner_anch_title, banner_hdr_text, originx, srcset;
private double data_pos_x, data_pos_y;
private int max_width;
private boolean bottomtoc, isHeadingOverrideEnabled;
public /**/ int max_width;
public /**/ byte[] banner_anch_href;
private boolean bottomtoc;
public /**/ boolean isHeadingOverrideEnabled;
private byte[] file_ttl;
private Pgbnr_icon[] icons;
private byte[] img_id_atr, img_xottl_atr, img_xoimg_atr;
private boolean isPanorama;
public /**/ boolean isPanorama;
private boolean enable_toc = true;
private boolean hasPosition = false;
@ -42,6 +45,15 @@ public class Pgbnr_itm implements Mustache_doc_itm {
public double Data_pos_y() {return data_pos_y;}
public boolean Show_toc_in_html() {return show_toc_in_html;} private boolean show_toc_in_html = false; // default to false so that TOC does not show up in both PageBanner and HTML body; DATE:2019-11-17
// hdump serialised info
public boolean Precoded() {return precoded;} private boolean precoded = false;
public byte[] Pgbnr_bry() {return pgbnr_bry;} private byte[] pgbnr_bry;
public void Pgbnr_bry_(byte[] v) {
if (v == null) return;
pgbnr_bry = v;
precoded = true;
}
public void Clear_by_hdump() {
this.exists = false;
this.srcset = style = null;
@ -63,11 +75,18 @@ public class Pgbnr_itm implements Mustache_doc_itm {
}
public void Init_from_wtxt(Xoa_ttl banner_ttl, Xof_file_itm banner_file_itm, byte[] banner_anch_title, byte[] banner_hdr_text, boolean bottomtoc
, byte[] toc, double data_pos_x, double data_pos_y, byte[] originx, Pgbnr_icon[] icons) {
Init_from_wtxt(banner_ttl, banner_file_itm, banner_anch_title, banner_hdr_text, bottomtoc
, toc, data_pos_x, data_pos_y, originx, icons, false);
}
public void Init_from_wtxt(Xoa_ttl banner_ttl, Xof_file_itm banner_file_itm, byte[] banner_anch_title, byte[] banner_hdr_text, boolean bottomtoc
, byte[] toc, double data_pos_x, double data_pos_y, byte[] originx, Pgbnr_icon[] icons, boolean enable_toc) {
this.banner_ttl = banner_ttl; this.banner_file_itm = banner_file_itm;
this.banner_anch_title = banner_anch_title; this.banner_hdr_text = banner_hdr_text; this.bottomtoc = bottomtoc; this.toc = toc; this.icons = icons;
this.data_pos_x = data_pos_x; this.data_pos_y = data_pos_y; this.originx = originx;
this.banner_img_src = banner_file_itm.Html_view_url().To_http_file_bry();
this.file_ttl = Gfo_url_encoder_.Href_quotes.Encode(banner_file_itm.Lnki_ttl()); // NOTE: Encode(Lnki_ttl) not Orig_ttl; else "%27s" instead of "'s" PAGE:en.v:'s-Hertogenbosch; DATE:2016-07-12
this.enable_toc = enable_toc;
show_toc_in_html = !enable_toc;
}
public void Init_from_html(int max_width, byte[] banner_anch_href, byte[] banner_img_src, byte[] srcset, boolean isHeadingOverrideEnabled, byte[] toc, boolean isPanorama) {
this.max_width = max_width;
@ -126,4 +145,112 @@ public class Pgbnr_itm implements Mustache_doc_itm {
, Atr_key__data_pos_y = Bry_.new_a7("data-pos-y")
, Atr_val__style_dflt = Bry_.new_a7("max-width:-1px")
;
public Json_nde Mustache__json() {
return buildargs();
}
private Json_nde buildargs() {
Json_ary ary = null;
if (json_icon_list != null) {
ary = new Json_ary(-1, -1);
int iconlen = json_icon_list.Len();
for (int i = 0; i < iconlen; i++) {
Json_nde inde = (Json_nde)json_icon_list.Get_at(i);
ary.Add(inde);
}
}
Json_doc_wtr wtr = new Json_doc_wtr();
wtr.Nde_bgn();
wtr.Kv(Bool_.N, "title", banner_hdr_text);
wtr.Kv(Bool_.Y, "tooltip", banner_anch_title);
wtr.Kv(Bool_.Y, "bannerfile", banner_anch_href);
wtr.Kv(Bool_.Y, "banner", banner_img_src);
wtr.Kv(Bool_.Y, "srcset", srcset == null ? Bry_.Empty : Bry_.Empty);
wtr.Kv(Bool_.Y, "originx", originx);
wtr.Kv(Bool_.Y, "toc", toc);
wtr.Kv(Bool_.Y, "img_id_atr", img_id_atr);
wtr.Kv(Bool_.Y, "img_xottl", img_xottl_atr);
wtr.Kv(Bool_.Y, "img_xoimg", img_xoimg_atr);
wtr.Kv(Bool_.Y, "file_ttl", file_ttl);
wtr.Kv(Bool_.Y, "data-pos-x", data_pos_x);
wtr.Kv(Bool_.Y, "data-pos-y", data_pos_y);
wtr.Kv(Bool_.Y, "maxWidth", max_width);
wtr.Kv(Bool_.Y, "hasIcons", icons.length > 0);
wtr.Kv(Bool_.Y, "bottomtoc", bottomtoc);
wtr.Kv(Bool_.Y, "isHeadingOverrideEnabled", isHeadingOverrideEnabled);
wtr.Kv(Bool_.Y, "isPanorama", isPanorama);
wtr.Kv(Bool_.Y, "enable-toc", enable_toc);
wtr.Kv(Bool_.Y, "hasPosition", hasPosition);
if (json_icon_list != null) {
wtr.Key(Bool_.N, "icons");
wtr.Ary_bgn();
for (int i = 0; i < json_icon_list.Len(); i++) {
Json_nde inde = (Json_nde)json_icon_list.Get_at(i);
for (int j = 0; j < inde.Len(); j++) {
Json_kv kv = inde.Get_at_as_kv(j);
wtr.Kv(i == 0, kv.Key_as_bry(), kv.Val_as_bry());
}
}
wtr.Ary_end();
}
wtr.Nde_end();
String jsonStr = wtr.Bld_as_str();
return Json_parser.ParseToJdoc(jsonStr).Root_nde();
/*
Json_nde jnde = new Json_nde(null, -1);
jnde.Add_many(
Json_mustache.Add_text("title", banner_hdr_text)
,Json_mustache.Add_text("tooltip", banner_anch_title)
,Json_mustache.Add_text("bannerfile", banner_anch_href)
,Json_mustache.Add_text("banner", banner_img_src)
,Json_mustache.Add_text("srcset", srcset == null ? Bry_.Empty : Bry_.Empty)
,Json_mustache.Add_text("originx", originx)
,Json_mustache.Add_text("toc", toc)
,Json_mustache.Add_text("img_id_atr", img_id_atr)
,Json_mustache.Add_text("img_xottl", img_xottl_atr)
,Json_mustache.Add_text("img_xoimg", img_xoimg_atr)
,Json_mustache.Add_text("file_ttl", file_ttl)
,Json_mustache.Add_double("data-pos-x", data_pos_x)
,Json_mustache.Add_double("data-pos-y", data_pos_y)
,Json_mustache.Add_int("maxWidth", max_width)
,Json_mustache.Add_bool("hasIcons", icons.length > 0)
,Json_mustache.Add_bool("bottomtoc", bottomtoc)
,Json_mustache.Add_bool("isHeadingOverrideEnabled", isHeadingOverrideEnabled)
,Json_mustache.Add_bool("isPanorama", isPanorama)
,Json_mustache.Add_bool("enable-toc", enable_toc)
,Json_mustache.Add_bool("hasPosition", hasPosition)
,Json_mustache.Add_ary("icons", ary)
);
//Bry_bfr bfr = Bry_bfr_.New();
//jnde.Print_as_json(bfr, 0);
//System.out.println(String_.new_u8(bfr.To_bry()));
return jnde;
*/
}
private List_adp json_icon_list;
public void Add_new_icon(Bry_bfr tmp_bfr, byte[] name, byte[] title, byte[] href) {
if (json_icon_list == null) json_icon_list = List_adp_.New();
json_icon_list.Add(Pgbnr_iconx(tmp_bfr, name, title, href));
}
private Json_nde Pgbnr_iconx(Bry_bfr tmp_bfr, byte[] name, byte[] title, byte[] href) {
fmt.Bld_many(tmp_bfr, name, title);
byte[] html = tmp_bfr.To_bry_and_clear();
Json_nde jnde = new Json_nde(null, -1);
jnde.Add_many(
Json_mustache.Add_text("name", name)
,Json_mustache.Add_text("title", title)
,Json_mustache.Add_text("url", href)
,Json_mustache.Add_text("html", html)
);
return jnde;
}
public static final Bry_fmt fmt = Bry_fmt.New
( Bry_.New_u8_nl_apos("<span aria-disabled=\"false\" title=\"~{title}\" class=\"oo-ui-widget oo-ui-widget-enabled oo-ui-iconElement-icon oo-ui-icon-~{name} oo-ui-iconElement oo-ui-iconWidget\"></span>")
, "name", "title"
);
}

@ -86,9 +86,11 @@ public class Pgbnr_xtn_mgr extends Xox_mgr_base implements Bfr_arg {
if (!enabled) return;
// load template file;
byte[] template_data = Io_mgr.Instance.LoadFilBryOr(wiki.Appe().Fsys_mgr().Bin_any_dir().GenSubDir_nest("xowa", "xtns", "WikidataPageBanner", "templates", "banner.mustache"), Template_dflt);
Mustache_tkn_parser parser = new Mustache_tkn_parser();
template_root = parser.Parse(template_data, 0, template_data.length);
//byte[] template_data = Io_mgr.Instance.LoadFilBryOr(wiki.Appe().Fsys_mgr().Bin_any_dir().GenSubDir_nest("xowa", "xtns", "WikidataPageBanner", "templates", "banner.mustache"), Template_dflt);
//Mustache_tkn_parser parser = new Mustache_tkn_parser();
//template_root = parser.Parse(template_data, 0, template_data.length);
Mustache_tkn_parser parser = new Mustache_tkn_parser(wiki.Appe().Fsys_mgr().Bin_any_dir().GenSubDir_nest("xowa", "xtns", "WikidataPageBanner", "templates"));
template_root = parser.Parse("banner", Template_dflt);
}
public Bfr_arg Write_html(Xoae_page wpg, Xop_ctx pctx, Xoh_wtr_ctx hctx) {
this.wpg = wpg; this.pctx = pctx; this.hctx = hctx;

@ -140,10 +140,15 @@ app.wikis.get('~{wiki_key}') {
app.wikis.get('~{wiki_key}').html.portal {
div_personal =
<:["
<div id="p-personal" class="">
<h3>~{<>msgs.get('personaltools');<>}</h3>
<nav id="p-personal" class="vector-menu" aria-labelledby="p-personal-label" role="navigation"
>
<h3 id="p-personal-label">
<span>~{<>app.user.msgs.get('personaltools');<>}</span>
</h3>
<div class="body vector-menu-content">
~{portal_indicators_pagesource}
</div>
</div>
</nav>
"]:>
;
div_ns =
@ -228,13 +233,16 @@ app.wikis.get('~{wiki_key}').html.portal {
;
div_wikis =
<:["
<div id="xowa-portal-wikis" class="portal">
<h3>~{toggle_btn}</h3>
<div class="body">
<nav id="xowa-portal-wikis" class="vector-menu vector-menu-portal portal" aria-labelledby="xowa-portal-wikis" role="navigation"
>
<h3 id="p-wiki">
<span>~{toggle_btn}</span>
</h3>
<div class="body vector-menu-content">
<ul~{toggle_hdr}>~{<>app.gui.html.portal.wikis.itms_as_html;<>}
</ul>
</div>
</div>
</nav>
"]:>
;
}
@ -472,9 +480,14 @@ app.wikis.scripts.set
app.wikis.get('~{wiki_key}').html.portal
.div_personal_(
<:["
<div id="p-personal" class="">
<h3>~{<>app.user.msgs.get('personaltools');<>}</h3>
</div>
<nav id="p-personal" class="vector-menu" aria-labelledby="p-personal-label" role="navigation"
>
<h3 id="p-personal-label">
<span>~{<>app.user.msgs.get('personaltools');<>}</span>
</h3>
<div class="body vector-menu-content">
</div>
</nav>
"]:>
)
;

File diff suppressed because it is too large Load Diff

@ -104,6 +104,18 @@ if (!window.xowa) {
},
remove: function () {},
fire: function () {}
} : name === 'wikipage.collapsibleContent' ? {
add: function (f) {
//fc = f;
f(mw.collapsibleContent);
// f(window.jQuery ? $collapsible.find( '> .mw-collapsible-content' ) : null);
},
remove: function () {},
fire: function (t) {
// different order!!!! wrong order HACK
mw.collapsibleContent = t;
//fc(t);
}
} : {
add: function () {},
remove: function () {},

@ -0,0 +1,22 @@
{{!
See @typedef MenuDefinition
}}
{{! `role` is unnecessary but kept to support selectors in any gadgets or user styles. }}
<!-- Please do not use role attribute as CSS selector, it is deprecated. -->
<nav id="{{id}}" {{#class}}class="{{.}}"{{/class}} aria-labelledby="{{label-id}}" role="navigation" {{{html-tooltip}}}
{{{html-user-language-attributes}}}>
{{#is-dropdown}}
<input type="checkbox" class="vector-menu-checkbox vectorMenuCheckbox" aria-labelledby="{{label-id}}" />
{{/is-dropdown}}
<h3 id="{{label-id}}">
<span>{{label}}</span>
</h3>
{{! `body` class for backwards compatibility but let editors know not to use
it via HTML comment below: }}
<!-- Please do not use the .body class, it is deprecated. -->
<div class="body vector-menu-content">
<!-- Please do not use the .menu class, it is deprecated. -->
<ul class="{{list-classes}}">{{{html-items}}}</ul>
{{{html-after-portal}}}
</div>
</nav>

@ -0,0 +1,16 @@
<div id="mw-navigation">
<h2>{{msg-navigation-heading}}</h2>
<div id="mw-head">
{{#data-personal-menu}}{{>Menu}}{{/data-personal-menu}}
<div id="left-navigation">
{{#data-namespace-tabs}}{{>Menu}}{{/data-namespace-tabs}}
{{#data-variants}}{{>Menu}}{{/data-variants}}
</div>
<div id="right-navigation">
{{#data-page-actions}}{{>Menu}}{{/data-page-actions}}
{{#data-page-actions-more}}{{>Menu}}{{/data-page-actions-more}}
{{#data-search-box}}{{>SearchBox}}{{/data-search-box}}
</div>
</div>
{{#data-sidebar}}{{>legacy/Sidebar}}{{/data-sidebar}}
</div>

@ -0,0 +1,13 @@
{{!
See @typedef SidebarData
string html-logo-attributes for site logo. Must be used inside tag e.g. `class="logo" lang="en-gb"`
}}
<div id="mw-panel">
<div id="p-logo" role="banner">
<a {{{html-logo-attributes}}}></a>
</div>
{{#data-portals-first}}{{>Menu}}{{/data-portals-first}}
{{#array-portals-rest}}{{>Menu}}{{/array-portals-rest}}
{{#data-portals-languages}}{{>Menu}}{{/data-portals-languages}}
</div>

@ -0,0 +1,69 @@
{{!
string|null html-site-notice the contents of a banner defined in MediaWiki:Sitenotice.
Also used by CentralNotice to inject banners into Vector.
Indicator[] array-indicators wiki-defined badges such as "good article",
"featured article". An empty array if none are defined.
string page-langcode the content language of the article. Assumed to be escaped HTML.
string html-title
bool page-isarticle
string msg-tagline
string html-subtitle
string html-undelete-link
string html-newtalk
string msg-vector-jumptonavigation
string msg-vector-jumptosearch
string html-body-content
string html-categories
string html-after-content
string msg-navigation-heading heading for entire navigation that is
usually hidden to screen readers
MenuDefinition data-personal-menu
MenuDefinition data-namespace-tabs
MenuDefinition data-variants
MenuDefinition data-page-actions
MenuDefinition data-page-actions-more
object data-search-box. See SearchBox.mustache for documentation.
object data-sidebar. See Sidebar.mustache for documentation.
object data-footer for footer template partial. see Footer.mustache for documentation.
}}
<div id="mw-page-base" class="noprint"></div>
<div id="mw-head-base" class="noprint"></div>
<div id="content" class="mw-body" role="main">
<a id="top"></a>
<div id="siteNotice" class="mw-body-content">{{{html-site-notice}}}</div>
{{>Indicators}}
<h1 id="firstHeading" class="firstHeading" lang="{{page-langcode}}">{{{html-title}}}</h1>
<div id="bodyContent" class="mw-body-content">
{{#page-isarticle}}<div id="siteSub" class="noprint">{{msg-tagline}}</div>{{/page-isarticle}}
<div id="contentSub"{{{html-user-language-attributes}}}>{{{html-subtitle}}}</div>
<div id="contentSub2">{{{html-undelete-link}}}</div>
{{{html-newtalk}}}
{{!
Keep this empty `div` for compatibility with gadgets and user scripts
using this place to insert extra elements before.
}}
<div id="jump-to-nav"></div>
<a class="mw-jump-link" href="#mw-head">{{msg-vector-jumptonavigation}}</a>
<a class="mw-jump-link" href="#searchInput">{{msg-vector-jumptosearch}}</a>
{{{html-body-content}}}
{{{html-categories}}}
</div>
</div>
{{{html-after-content}}}
<div id="mw-navigation">
<h2>{{msg-navigation-heading}}</h2>
<div id="mw-head">
{{#data-personal-menu}}{{>Menu}}{{/data-personal-menu}}
<div id="left-navigation">
{{#data-namespace-tabs}}{{>Menu}}{{/data-namespace-tabs}}
{{#data-variants}}{{>Menu}}{{/data-variants}}
</div>
<div id="right-navigation">
{{#data-page-actions}}{{>Menu}}{{/data-page-actions}}
{{#data-page-actions-more}}{{>Menu}}{{/data-page-actions-more}}
{{#data-search-box}}{{>SearchBox}}{{/data-search-box}}
</div>
</div>
{{#data-sidebar}}{{>legacy/Sidebar}}{{/data-sidebar}}
</div>
{{#data-footer}}{{>Footer}}{{/data-footer}}

@ -1,7 +1,7 @@
<div class="ext-wpb-pagebanner pre-content">
<div class="ext-wpb-pagebanner">
<div class="{{#isPanorama}}wpb-banner-image-panorama {{/isPanorama}}wpb-topbanner{{extraClass}}">
{{#isHeadingOverrideEnabled}}<h1 class="wpb-name">{{title}}</h1>{{/isHeadingOverrideEnabled}}
<a class="image" dir="ltr" title="{{tooltip}}" href="{{bannerfile}}" xowa_title="{{file_ttl}}"><img{{{img_id_atr}}}{{{img_xottl}}}{{{img_xoimg}}} src="{{banner}}" srcset="{{srcset}}" class="wpb-banner-image"{{#hasPosition}} data-pos-x="{{data-pos-x}}" data-pos-y="{{data-pos-y}}" {{/hasPosition}} style="max-width:{{maxWidth}}px"></a>
<a class="image" dir="ltr" title="{{tooltip}}" href="{{bannerfile}}" xowa_title="{{file_ttl}}"><img{{{img_id_atr}}}{{{img_xottl}}}{{{img_xoimg}}} src="{{banner}}" srcset="{{srcset}}" class="wpb-banner-image"{{#hasPosition}} data-pos-x="{{data-pos-x}}" data-pos-y="{{data-pos-y}}"{{/hasPosition}}></a>
{{#hasIcons}}
<div class="wpb-iconbox">
{{#icons}}

Loading…
Cancel
Save