mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
Source: Restore broken commit
This commit is contained in:
52
400_xowa/src/gplx/xowa/guis/history/Xog_history_itm.java
Normal file
52
400_xowa/src/gplx/xowa/guis/history/Xog_history_itm.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.guis.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.guis.*;
|
||||
public class Xog_history_itm {
|
||||
private final boolean redirect_force;
|
||||
public Xog_history_itm(byte[] wiki, byte[] page, byte[] anch, byte[] qarg, boolean redirect_force, String bmk_pos) {
|
||||
this.key = Bry_.Add_w_dlm(Byte_ascii.Pipe, wiki, page, anch, qarg, redirect_force ? Bool_.Y_bry : Bool_.N_bry);
|
||||
this.wiki = wiki; this.page = page; this.anch = anch; this.qarg = qarg;
|
||||
this.redirect_force = redirect_force; this.bmk_pos = bmk_pos;
|
||||
}
|
||||
public byte[] Key() {return key;} private final byte[] key;
|
||||
public byte[] Wiki() {return wiki;} private final byte[] wiki;
|
||||
public byte[] Page() {return page;} private final byte[] page;
|
||||
public byte[] Anch() {return anch;} private final byte[] anch;
|
||||
public byte[] Qarg() {return qarg;} private final byte[] qarg;
|
||||
public String Bmk_pos() {return bmk_pos;} public void Bmk_pos_(String v) {bmk_pos = v;} private String bmk_pos;
|
||||
public boolean Eq_wo_bmk_pos(Xog_history_itm comp) {
|
||||
return Bry_.Eq(wiki, comp.wiki)
|
||||
&& Bry_.Eq(page, comp.page)
|
||||
&& Bry_.Eq(anch, comp.anch)
|
||||
&& Bry_.Eq(qarg, comp.qarg)
|
||||
&& redirect_force == comp.redirect_force
|
||||
;
|
||||
}
|
||||
public void Srl_save(Bry_bfr bfr) {
|
||||
byte[] bmk_bry = Bry_.Replace(Bry_.new_u8(bmk_pos), Byte_ascii.Pipe, Byte_ascii.Tilde); // replace | with ~; EX: "0|1|2" -> "0~1~2"
|
||||
bfr.Add(key).Add_byte_pipe().Add(bmk_bry).Add_byte_nl();
|
||||
}
|
||||
public static Xog_history_itm Srl_load(byte[] raw) {
|
||||
byte[][] atrs = Bry_split_.Split(raw, Byte_ascii.Pipe);
|
||||
byte[] bmk_bry = atrs.length == 6 ? atrs[5] : Bry_.Empty;
|
||||
bmk_bry = Bry_.Replace(bmk_bry, Byte_ascii.Tilde, Byte_ascii.Pipe);
|
||||
return new Xog_history_itm(atrs[0], atrs[1], atrs[2], atrs[3], atrs[4] == Bool_.Y_bry, String_.new_a7(bmk_bry));
|
||||
}
|
||||
public static final String Html_doc_pos_toc = "top";
|
||||
public static final Xog_history_itm Null = new Xog_history_itm(null, null, null, null, false, null);
|
||||
}
|
||||
77
400_xowa/src/gplx/xowa/guis/history/Xog_history_mgr.java
Normal file
77
400_xowa/src/gplx/xowa/guis/history/Xog_history_mgr.java
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.guis.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.guis.*;
|
||||
public class Xog_history_mgr {
|
||||
private final Ordered_hash hash = Ordered_hash_.New_bry(); private final Xog_history_stack stack = new Xog_history_stack();
|
||||
public int Count() {return hash.Count();}
|
||||
public Xoae_page Cur_page(Xowe_wiki wiki) {return Get_or_fetch(wiki, stack.Cur_itm());}
|
||||
public Xoae_page Go_bwd(Xowe_wiki wiki) {return Go_by_dir(wiki, Bool_.N);}
|
||||
public Xoae_page Go_fwd(Xowe_wiki wiki) {return Go_by_dir(wiki, Bool_.Y);}
|
||||
public Xoae_page Go_by_dir(Xowe_wiki wiki, boolean fwd) {
|
||||
Xog_history_itm itm = fwd ? stack.Go_fwd() : stack.Go_bwd();
|
||||
if (itm == Xog_history_itm.Null) return Xoae_page.Empty;
|
||||
Xoae_page rv = Get_or_fetch(wiki, itm);
|
||||
byte[] anch_key = itm.Anch();
|
||||
rv.Url().Anch_bry_(anch_key); // must override anchor as it may be different for cached page
|
||||
rv.Html_data().Bmk_pos_(itm.Bmk_pos());
|
||||
return rv;
|
||||
}
|
||||
public void Add(Xoae_page page) {
|
||||
Xog_history_itm new_itm = Xog_history_mgr.new_(page);
|
||||
stack.Add(new_itm);
|
||||
byte[] page_key = Build_page_key(page);
|
||||
if (!hash.Has(page_key))
|
||||
hash.Add(page_key, page);
|
||||
}
|
||||
public void Update_html_doc_pos(Xoae_page page, byte history_nav_type) {
|
||||
Xog_history_itm itm = Get_recent(page, history_nav_type);
|
||||
if (itm != null) itm.Bmk_pos_(page.Html_data().Bmk_pos());
|
||||
}
|
||||
private Xog_history_itm Get_recent(Xoae_page page, byte history_nav_type) {
|
||||
int pos = -1;
|
||||
int list_pos = stack.Cur_pos();
|
||||
switch (history_nav_type) {
|
||||
case Xog_history_stack.Nav_fwd: pos = list_pos - 1; break;
|
||||
case Xog_history_stack.Nav_bwd: pos = list_pos + 1; break;
|
||||
case Xog_history_stack.Nav_by_anchor: pos = list_pos; break;
|
||||
}
|
||||
if (pos < 0 || pos >= stack.Len()) return null;
|
||||
Xog_history_itm recent = stack.Get_at(pos);
|
||||
Xog_history_itm page_itm = Xog_history_mgr.new_(page);
|
||||
return page_itm.Eq_wo_bmk_pos(recent) ? recent : null; // check that recent page actually matches current; DATE:2014-05-10
|
||||
}
|
||||
private Xoae_page Get_or_fetch(Xowe_wiki wiki, Xog_history_itm itm) {
|
||||
byte[] page_key = Build_page_key(itm.Wiki(), itm.Page(), itm.Qarg());
|
||||
Xoae_page rv = (Xoae_page)hash.Get_by(page_key);
|
||||
if (rv != null) return rv;
|
||||
Xoa_ttl ttl = Xoa_ttl.Parse(wiki, itm.Page());
|
||||
return wiki.Data_mgr().Load_page_by_ttl(ttl);
|
||||
}
|
||||
private static byte[] Build_page_key(Xoae_page page) {return Build_page_key(page.Wiki().Domain_bry(), page.Ttl().Full_url(), page.Url().Qargs_mgr().To_bry());}
|
||||
private static byte[] Build_page_key(byte[] wiki_key, byte[] page_key, byte[] args_key) {return Bry_.Add_w_dlm(Byte_ascii.Pipe, wiki_key, page_key, args_key);}
|
||||
public static Xog_history_itm new_(Xoae_page pg) {
|
||||
byte[] wiki = pg.Wiki().Domain_bry();
|
||||
byte[] page = pg.Ttl().Full_url(); // get page_name only (no anchor; no query args)
|
||||
byte[] anch = pg.Url().Anch_bry();
|
||||
byte[] qarg = pg.Url().Qargs_mgr().To_bry();
|
||||
boolean redirect_force = pg.Url().Qargs_mgr().Match(Xoa_url_.Qarg__redirect, Xoa_url_.Qarg__redirect__no);
|
||||
String bmk_pos = pg.Html_data().Bmk_pos();
|
||||
if (bmk_pos == null) bmk_pos = Xog_history_itm.Html_doc_pos_toc; // never allow null doc_pos; set to top
|
||||
return new Xog_history_itm(wiki, page, anch, qarg, redirect_force, bmk_pos);
|
||||
}
|
||||
}
|
||||
70
400_xowa/src/gplx/xowa/guis/history/Xog_history_stack.java
Normal file
70
400_xowa/src/gplx/xowa/guis/history/Xog_history_stack.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.guis.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.guis.*;
|
||||
public class Xog_history_stack {
|
||||
private final List_adp list = List_adp_.New();
|
||||
public int Len() {return list.Count();}
|
||||
public void Clear() {list.Clear(); cur_pos = 0;}
|
||||
public Xog_history_itm Get_at(int i) {return (Xog_history_itm)list.Get_at(i);}
|
||||
public int Cur_pos() {return cur_pos;} private int cur_pos = 0;
|
||||
public Xog_history_itm Cur_itm() {return list.Count() == 0 ? Xog_history_itm.Null : (Xog_history_itm)list.Get_at(cur_pos);}
|
||||
public void Add(Xog_history_itm new_itm) {
|
||||
Xog_history_itm cur_itm = this.Cur_itm();
|
||||
if (cur_itm != Xog_history_itm.Null && cur_itm.Eq_wo_bmk_pos(new_itm)) return; // do not add if last itm is same;
|
||||
this.Del_from(cur_pos + 1);
|
||||
list.Add(new_itm);
|
||||
cur_pos = list.Count() - 1;
|
||||
}
|
||||
public Xog_history_itm Go_bwd() {
|
||||
if (list.Count() == 0) return Xog_history_itm.Null;
|
||||
if (cur_pos == 0) return Xog_history_itm.Null;
|
||||
--cur_pos;
|
||||
return this.Cur_itm();
|
||||
}
|
||||
public Xog_history_itm Go_fwd() {
|
||||
int list_count = list.Count();
|
||||
if (list_count == 0) return Xog_history_itm.Null;
|
||||
if (cur_pos == list_count - 1) return Xog_history_itm.Null;
|
||||
++cur_pos;
|
||||
return this.Cur_itm();
|
||||
}
|
||||
private void Del_from(int from) {
|
||||
int len = list.Count();
|
||||
if (from <= len - 1)
|
||||
list.Del_range(from, len - 1);
|
||||
}
|
||||
public void Srl_save(Bry_bfr bfr) {
|
||||
int len = list.Count();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Xog_history_itm itm = (Xog_history_itm)list.Get_at(i);
|
||||
itm.Srl_save(bfr);
|
||||
}
|
||||
}
|
||||
public void Srl_load(byte[] bry) {
|
||||
list.Clear();
|
||||
byte[][] lines = Bry_split_.Split_lines(bry);
|
||||
int len = lines.length;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
byte[] line = lines[i];
|
||||
Xog_history_itm itm = Xog_history_itm.Srl_load(line);
|
||||
this.Add(itm);
|
||||
}
|
||||
}
|
||||
public void Cur_pos_(int v) {this.cur_pos = v;}
|
||||
public static final byte Nav_fwd = 1, Nav_bwd = 2, Nav_by_anchor = 3;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.guis.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.guis.*;
|
||||
import org.junit.*;
|
||||
public class Xog_history_stack_tst {
|
||||
@Before public void init() {fxt.Clear();} private Xog_history_stack_fxt fxt = new Xog_history_stack_fxt();
|
||||
@Test public void Init() {fxt.Test_cur(null);}
|
||||
@Test public void Add_1() {fxt.Exec_add_many("A").Test_cur("A").Test_len(1).Test_pos(0);}
|
||||
@Test public void Add_same() {fxt.Exec_add_many("A", "A").Test_cur("A").Test_len(1).Test_pos(0);}
|
||||
@Test public void Add_3() {fxt.Exec_add_many("A", "B", "C").Test_cur("C").Test_len(3).Test_pos(2);}
|
||||
@Test public void Add_3_bwd() {fxt.Exec_add_many("A", "B", "C").Exec_go_bwd().Test_cur("B").Test_pos(1);}
|
||||
@Test public void Add_3_bwd_fwd() {fxt.Exec_add_many("A", "B", "C").Exec_go_bwd().Exec_go_fwd().Test_cur("C").Test_pos(2);}
|
||||
@Test public void Add_3_bwd_add() {fxt.Exec_add_many("A", "B", "C").Exec_go_bwd().Exec_add_many("D").Test_len(3).Test_cur("D").Test_pos(2);}
|
||||
@Test public void Add_3_bwd_bwd_add() {fxt.Exec_add_many("A", "B", "C").Exec_go_bwd().Exec_go_bwd().Exec_add_many("D").Test_len(2).Test_cur("D").Test_pos(1);}
|
||||
@Test public void Add_dif_ns() {fxt.Exec_add_many("A", "Help:A").Test_cur("Help:A");} // PURPOSE.fix: page_stack was only differtiating by Page_db, not Full; EX: Unicode -> Category:Unicode
|
||||
@Test public void Add_qargs() {// PURPOSE.fix: page_stack was only differentiating by qtxt args
|
||||
fxt .Exec_add_one("Special:AllPages", "?from=A")
|
||||
.Exec_add_one("Special:AllPages", "?from=B")
|
||||
.Exec_add_many("B")
|
||||
.Exec_go_bwd()
|
||||
.Test_cur("Special:AllPages")
|
||||
.Test_cur_qargs("?from=B")
|
||||
;
|
||||
}
|
||||
}
|
||||
class Xog_history_stack_fxt {
|
||||
public Xog_history_stack_fxt Clear() {
|
||||
stack.Clear();
|
||||
if (app == null) {
|
||||
app = Xoa_app_fxt.Make__app__edit();
|
||||
wiki = Xoa_app_fxt.Make__wiki__edit(app);
|
||||
}
|
||||
return this;
|
||||
} private Xoae_app app; private Xowe_wiki wiki; private Xog_history_stack stack = new Xog_history_stack();
|
||||
public Xog_history_stack_fxt Test_cur(String expd) {
|
||||
Xog_history_itm page = stack.Cur_itm();
|
||||
String actl = page == null ? null : String_.new_u8(page.Page());
|
||||
Tfds.Eq(expd, actl, "cur");
|
||||
return this;
|
||||
}
|
||||
public Xog_history_stack_fxt Test_cur_qargs(String expd) {
|
||||
Xog_history_itm page = stack.Cur_itm();
|
||||
String actl = page == null ? null : String_.new_u8(page.Qarg());
|
||||
Tfds.Eq(expd, actl, "cur_qargs");
|
||||
return this;
|
||||
}
|
||||
public Xog_history_stack_fxt Exec_go_bwd() {stack.Go_bwd(); return this;}
|
||||
public Xog_history_stack_fxt Exec_go_fwd() {stack.Go_fwd(); return this;}
|
||||
public Xog_history_stack_fxt Exec_add_many(String... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
String ttl = ary[i];
|
||||
Exec_add_one(ttl, null);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Xog_history_stack_fxt Exec_add_one(String ttl_str, String arg_str) {
|
||||
byte[] ttl_bry = Bry_.new_u8(ttl_str);
|
||||
Xoa_ttl ttl = Xoa_ttl.Parse(wiki, ttl_bry);
|
||||
Xoae_page page = Xoae_page.New_test(wiki, ttl);
|
||||
byte[] url_bry = ttl_bry;
|
||||
if (arg_str != null) url_bry = Bry_.Add(url_bry, Bry_.new_u8(arg_str));
|
||||
Xoa_url url = app.User().Wikii().Utl__url_parser().Parse(url_bry);
|
||||
page.Url_(url); // set url b/c history_mgr.Add uses url
|
||||
stack.Add(Xog_history_mgr.new_(page));
|
||||
return this;
|
||||
}
|
||||
public Xog_history_stack_fxt Test_pos(int expd) {Tfds.Eq(expd, stack.Cur_pos(), "pos"); return this;}
|
||||
public Xog_history_stack_fxt Test_len(int expd) {Tfds.Eq(expd, stack.Len(), "len"); return this;}
|
||||
}
|
||||
Reference in New Issue
Block a user