Section_edit: Add basic merge support

v3.3.4
gnosygnu 8 years ago
parent 150454fd67
commit 5d27bff298

@ -23,7 +23,7 @@ public class Xog_tab_itm_edit_mgr {
public static void Save(Xog_tab_itm tab, boolean quick_save) { public static void Save(Xog_tab_itm tab, boolean quick_save) {
if (tab.View_mode() != Xopg_page_.Tid_edit) return; // exit if not edit; handles ctrl+s being pressed in read/html modes if (tab.View_mode() != Xopg_page_.Tid_edit) return; // exit if not edit; handles ctrl+s being pressed in read/html modes
Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win(); Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
byte[] new_text = Get_new_text(tab); byte[] new_text = Get_new_text(tab, page.Db().Text().Text_bry());
if (page.Edit_mode() == Xoa_page_.Edit_mode_create) { if (page.Edit_mode() == Xoa_page_.Edit_mode_create) {
int page_id = wiki.Db_mgr().Save_mgr().Data_create(page.Ttl(), new_text); int page_id = wiki.Db_mgr().Save_mgr().Data_create(page.Ttl(), new_text);
page.Db().Page().Id_(page_id); page.Db().Page().Id_(page_id);
@ -42,6 +42,7 @@ public class Xog_tab_itm_edit_mgr {
Xoae_page stack_page = tab.History_mgr().Cur_page(wiki); // NOTE: must be to CurPage() else changes will be lost when going Bwd,Fwd Xoae_page stack_page = tab.History_mgr().Cur_page(wiki); // NOTE: must be to CurPage() else changes will be lost when going Bwd,Fwd
stack_page.Db().Text().Text_bry_(page.Db().Text().Text_bry()); // NOTE: overwrite with "saved" changes stack_page.Db().Text().Text_bry_(page.Db().Text().Text_bry()); // NOTE: overwrite with "saved" changes
stack_page.Wikie().Parser_mgr().Parse(page, true); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save stack_page.Wikie().Parser_mgr().Parse(page, true); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save
page.Url_(Xoa_url.New(tab.Wiki().Domain_bry(), tab.Page().Ttl().Full_db()));
win_itm.Page__mode_(Xopg_page_.Tid_read); win_itm.Page__mode_(Xopg_page_.Tid_read);
win_itm.Page__async__bgn(tab); win_itm.Page__async__bgn(tab);
} }
@ -52,7 +53,7 @@ public class Xog_tab_itm_edit_mgr {
Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win(); Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
Xog_html_itm html_itm = tab.Html_itm(); Xog_html_itm html_itm = tab.Html_itm();
byte[] new_text = Get_new_text(tab); byte[] new_text = Get_new_text(tab, null);
Xoae_page new_page = Xoae_page.New(wiki, page.Ttl()); Xoae_page new_page = Xoae_page.New(wiki, page.Ttl());
new_page.Db().Page().Id_(page.Db().Page().Id()); // NOTE: page_id needed for sqlite (was not needed for xdat) new_page.Db().Page().Id_(page.Db().Page().Id()); // NOTE: page_id needed for sqlite (was not needed for xdat)
new_page.Db().Text().Text_bry_(new_text); new_page.Db().Text().Text_bry_(new_text);
@ -121,9 +122,10 @@ public class Xog_tab_itm_edit_mgr {
wiki.Parser_mgr().Scrib().Core_term(); wiki.Parser_mgr().Scrib().Core_term();
wiki.Cache_mgr().Free_mem_all(); wiki.Cache_mgr().Free_mem_all();
} }
private static byte[] Get_new_text(Xog_tab_itm tab) { private static byte[] Get_new_text(Xog_tab_itm tab, byte[] orig) {
byte[] rv = tab.Html_itm().Get_elem_value_for_edit_box_as_bry(); byte[] rv = tab.Html_itm().Get_elem_value_for_edit_box_as_bry();
// tab.Wiki().Parser_mgr().Hdr__section_editable__mgr().Merge(rv); if (orig != null) // orig == null for Preview
rv = tab.Wiki().Parser_mgr().Hdr__section_editable__mgr().Merge_section(tab.Page().Url(), rv, orig);
rv = Bry_.Trim(rv, 0, rv.length, false, true, Bry_.Trim_ary_ws); // MW: trim all trailing ws; REF:EditPage.php!safeUnicodeInput; DATE:2014-04-25 rv = Bry_.Trim(rv, 0, rv.length, false, true, Bry_.Trim_ary_ws); // MW: trim all trailing ws; REF:EditPage.php!safeUnicodeInput; DATE:2014-04-25
return rv; return rv;
} }

@ -22,7 +22,7 @@ class Xop_section_list implements Xomw_hdr_cbk {
private final Ordered_hash hash = Ordered_hash_.New_bry(); private final Ordered_hash hash = Ordered_hash_.New_bry();
private byte[] src; private byte[] src;
public Xop_section_list Parse(byte[] ttl_full_db, byte[] src) { public Xop_section_list Parse(byte[] src) {
this.src = src; this.src = src;
Xomw_parser_ctx pctx = new Xomw_parser_ctx(); Xomw_parser_ctx pctx = new Xomw_parser_ctx();
hdr_wkr.Parse(pctx, src, 0, src.length, this); hdr_wkr.Parse(pctx, src, 0, src.length, this);
@ -33,17 +33,39 @@ class Xop_section_list implements Xomw_hdr_cbk {
Xop_section_itm itm = (Xop_section_itm)hash.Get_by(key); Xop_section_itm itm = (Xop_section_itm)hash.Get_by(key);
if (itm == null) return null; if (itm == null) return null;
int src_bgn = itm.Src_bgn(); int src_bgn = Get_src_bgn(itm.Src_bgn());
if (src[src_bgn] == Byte_ascii.Nl) src_bgn++; int src_end = Get_src_end(itm);
return Bry_.Mid(src, src_bgn, src_end);
}
public byte[] Merge_bry_or_null(byte[] key, byte[] edit) {
// find section matching key
Xop_section_itm itm = (Xop_section_itm)hash.Get_by(key);
if (itm == null) return null;
int src_bgn = Get_src_bgn(itm.Src_bgn());
int src_end = Get_src_end(itm);
// merge edit into orig
Bry_bfr bfr = Bry_bfr_.New();
bfr.Add_mid(src, 0, src_bgn);
bfr.Add(edit);
bfr.Add_mid(src, src_end, src.length);
return bfr.To_bry_and_clear();
}
private int Get_src_bgn(int src_bgn) {
if (src[src_bgn] == Byte_ascii.Nl) src_bgn++;
return src_bgn;
}
private int Get_src_end(Xop_section_itm itm) {
int src_end = src.length; int src_end = src.length;
if (itm.Idx() != hash.Len() - 1) { // if not last, get next if (itm.Idx() != hash.Len() - 1) { // if not last, get next
Xop_section_itm nxt = (Xop_section_itm)hash.Get_at(itm.Idx() + 1); Xop_section_itm nxt = (Xop_section_itm)hash.Get_at(itm.Idx() + 1);
src_end = nxt.Src_bgn(); src_end = nxt.Src_bgn();
} }
src_end = Bry_find_.Find_bwd__skip_ws(src, src_end, src_bgn); src_end = Bry_find_.Find_bwd__skip_ws(src, src_end, itm.Src_bgn());
return src_end;
return Bry_.Mid(src, src_bgn, src_end);
} }
public void On_hdr_seen(Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr) { public void On_hdr_seen(Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr) {
byte[] src = wkr.Src(); byte[] src = wkr.Src();

@ -19,7 +19,7 @@ package gplx.xowa.parsers.hdrs.sections; import gplx.*; import gplx.xowa.*; impo
import org.junit.*; import gplx.core.tests.*; import org.junit.*; import gplx.core.tests.*;
public class Xop_section_list__tst { public class Xop_section_list__tst {
private final Xop_section_list__fxt fxt = new Xop_section_list__fxt(); private final Xop_section_list__fxt fxt = new Xop_section_list__fxt();
@Test public void Basic() { @Test public void Extract__basic() {
fxt.Exec__parse fxt.Exec__parse
( "== Hdr 1 ==" ( "== Hdr 1 =="
, "Para 1" , "Para 1"
@ -43,15 +43,45 @@ public class Xop_section_list__tst {
, "Para 3" , "Para 3"
); );
} }
@Test public void Merge__basic() {
fxt.Exec__parse
( "== Hdr 1 =="
, "Para 1"
, ""
, "== Hdr 2 =="
, "Para 2"
, ""
, "== Hdr 3 =="
, "Para 3"
);
fxt.Test__merge_bry_or_null("Hdr 2", String_.Concat_lines_nl_skip_last
( "== Hdr 2 =="
, "abcd"
), String_.Concat_lines_nl_skip_last
( "== Hdr 1 =="
, "Para 1"
, ""
, "== Hdr 2 =="
, "abcd"
, ""
, "== Hdr 3 =="
, "Para 3"
)
);
}
} }
class Xop_section_list__fxt { class Xop_section_list__fxt {
private final Xop_section_list list = new Xop_section_list(); private final Xop_section_list list = new Xop_section_list();
public void Exec__parse(String... lines) { public void Exec__parse(String... lines) {
list.Parse(Bry_.Empty, Bry_.new_u8(String_.Concat_lines_nl_skip_last(lines))); list.Parse(Bry_.new_u8(String_.Concat_lines_nl_skip_last(lines)));
} }
public void Test__extract_bry_or_null(String key, String... lines) { public void Test__extract_bry_or_null(String key, String... lines) {
String expd = String_.Concat_lines_nl_skip_last(lines); String expd = String_.Concat_lines_nl_skip_last(lines);
byte[] actl = list.Extract_bry_or_null(Bry_.new_u8(key)); byte[] actl = list.Extract_bry_or_null(Bry_.new_u8(key));
Gftest.Eq__ary__lines(expd, actl, key); Gftest.Eq__ary__lines(expd, actl, key);
} }
public void Test__merge_bry_or_null(String key, String edit, String expd) {
byte[] actl = list.Merge_bry_or_null(Bry_.new_u8(key), Bry_.new_u8(edit));
Gftest.Eq__ary__lines(expd, actl, key);
}
} }

@ -37,34 +37,29 @@ public class Xop_section_mgr implements Gfo_invk {
if (section_key == null) return src; if (section_key == null) return src;
// parse wikitext into list of headers // parse wikitext into list of headers
Xop_section_list section_list = new Xop_section_list().Parse(ttl.Full_db(), src); Xop_section_list section_list = new Xop_section_list().Parse(src);
byte[] rv = section_list.Extract_bry_or_null(section_key); byte[] rv = section_list.Extract_bry_or_null(section_key);
if (rv == null) if (rv == null)
throw Err_.new_wo_type("section_key not found", "page", ttl.Full_db(), "section_key", section_key); throw Err_.new_wo_type("section_key not found", "page", ttl.Full_db(), "section_key", section_key);
return rv; return rv;
} }
public void Parse(Xop_hdr_tkn hdr, byte[] page_ttl, byte[] src, int cur_pos, int src_len) { public byte[] Merge_section(Xoa_url url, byte[] edit, byte[] orig) {
// get page ttl // return edit if not enabled
int page_ttl_bgn = cur_pos + Bry__meta.length; if (!enabled) return edit;
int page_ttl_end = Bry_find_.Find_fwd(src, Byte_ascii.Pipe, page_ttl_bgn, src_len);
if (page_ttl_end == Bry_find_.Not_found) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "invalid section ttl; page=~{0} excerpt=~{1}", page_ttl, Bry_.Mid(src, cur_pos, cur_pos + 100));
return;
}
byte[] section_page = Bry_.Mid(src, page_ttl_bgn, page_ttl_end);
// get section idx // return edit if section_key not in qargs
int section_idx_bgn = page_ttl_end + 1; byte[] section_key = url.Qargs_mgr().Get_val_bry_or(Qarg__section_key, null);
int section_idx_end = Bry_find_.Find_fwd(src, Gfh_tag_.Comm_end, section_idx_bgn, src_len); if (section_key == null) return edit;
int section_idx = Bry_.To_int_or(src, section_idx_bgn, section_idx_end, -1);
if (page_ttl_end == -1) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "invalid section idx; page=~{0} excerpt=~{1}", page_ttl, Bry_.Mid(src, cur_pos, cur_pos + 100));
return;
}
hdr.Section_editable_(section_page, section_idx); // parse orig
Xop_section_list section_list = new Xop_section_list().Parse(orig);
byte[] rv = section_list.Merge_bry_or_null(section_key, edit);
if (rv == null)
throw Err_.new_wo_type("could not merge section_key", "page", url.To_str(), "section_key", section_key);
return rv;
} }
public void Write_html(Bry_bfr bfr, byte[] src, byte[] page_ttl, Xop_hdr_tkn hdr, byte[] name) { public void Write_html(Bry_bfr bfr, byte[] src, byte[] page_ttl, Xop_hdr_tkn hdr, byte[] name) {
// make key by (a) taking 1st and nth sub; (b) skipping ws at both ends
Xop_tkn_itm[] subs = hdr.Subs(); Xop_tkn_itm[] subs = hdr.Subs();
if (subs.length == 0) return; // GUARD:should not happen, but avoid array-index error if (subs.length == 0) return; // GUARD:should not happen, but avoid array-index error
int key_bgn = subs[0].Src_bgn(); int key_bgn = subs[0].Src_bgn();
@ -72,6 +67,7 @@ public class Xop_section_mgr implements Gfo_invk {
key_bgn = Bry_find_.Find_fwd_while_ws(src, key_bgn, key_end); key_bgn = Bry_find_.Find_fwd_while_ws(src, key_bgn, key_end);
key_end = Bry_find_.Find_bwd__skip_ws(src, key_end, key_bgn); key_end = Bry_find_.Find_bwd__skip_ws(src, key_end, key_bgn);
byte[] key = Bry_.Mid(src, key_bgn, key_end); byte[] key = Bry_.Mid(src, key_bgn, key_end);
section_editable_fmt.Bld_many(bfr, page_ttl, key, name); section_editable_fmt.Bld_many(bfr, page_ttl, key, name);
} }
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {

@ -51,6 +51,7 @@ public class Xowe_page_mgr {
// load from html_dbs if no wtxt found and option just marked as not read_preferred // load from html_dbs if no wtxt found and option just marked as not read_preferred
if ( Bry_.Len_eq_0(page.Db().Text().Text_bry()) // no wtxt found if ( Bry_.Len_eq_0(page.Db().Text().Text_bry()) // no wtxt found
&& !ttl.Ns().Id_is_special() // skip special
&& !wiki.Appe().Api_root().Wiki().Hdump().Read_preferred() // read preferred not marked && !wiki.Appe().Api_root().Wiki().Hdump().Read_preferred() // read preferred not marked
) { ) {
wiki.Html__hdump_mgr().Load_mgr().Load_by_edit(page); wiki.Html__hdump_mgr().Load_mgr().Load_by_edit(page);

@ -250,7 +250,7 @@ public class Pp_pages_nde implements Xox_xnde, Mwh_atr_itm_owner1 {
end_page_int = num_parser.Rv_as_int(); end_page_int = num_parser.Rv_as_int();
} }
if (bgn_page_int > end_page_int) { if (bgn_page_int > end_page_int) {
Fail_args("from must be less than to: from={0} to={0}", bgn_page_int, end_page_int); Fail_args("from must be less than to: from={0} to={1}", bgn_page_int, end_page_int);
return null; return null;
} }
for (int i = bgn_page_int; i <= end_page_int; i++) for (int i = bgn_page_int; i <= end_page_int; i++)

Loading…
Cancel
Save