Gui: Strip `about:/wiki/` from links [#823]

master
gnosygnu 4 years ago
parent aeef520228
commit 0ef5058cfd

@ -185,25 +185,6 @@ public class Swt_html implements Gxw_html, Swt_control, FocusListener, Gfo_evt_m
, Browser_tid_mozilla = SWT.MOZILLA , Browser_tid_mozilla = SWT.MOZILLA
, Browser_tid_webkit = SWT.WEBKIT , Browser_tid_webkit = SWT.WEBKIT
; ;
private static final String URL_PREFIX_ABOUT = "about:";
private static final String URL_PREFIX_BLANK = "blank";
public static String NormalizeSwtUrl(String url) {
String rv = url;
// 2020-09-19|ISSUE#:799|strip "about:" from url due to SWT 4.16
rv = String_.Has_at_bgn(rv, URL_PREFIX_ABOUT)
? String_.Mid(rv, URL_PREFIX_ABOUT.length())
: rv;
// 2015-06-09|webkit prefixes "about:blank" to anchors; causes TOC to fail when clicking on links; EX:about:blank#TOC1
// 2020-09-22|removed webkit check due to SWT 4.16; `html_box.Browser_tid() == Swt_html.Browser_tid_webkit`
// still strip "blank"; note that SWT 4.16 changes anchors from "file:///#anchor" to "en.w/wiki/page/#anchor"
rv = String_.Has_at_bgn(rv, URL_PREFIX_BLANK)
? String_.Mid(rv, URL_PREFIX_BLANK.length())
: rv;
return rv;
}
} }
class Swt_core_cmds_html extends Swt_core__basic { class Swt_core_cmds_html extends Swt_core__basic {
public Swt_core_cmds_html(Swt_html html_box, Control control) {super(control);} public Swt_core_cmds_html(Swt_html html_box, Control control) {super(control);}
@ -253,7 +234,7 @@ class Swt_html_lnr_status implements StatusTextListener {
if (html_box.Kit().Kit_mode__term()) return; // shutting down raises status changed events; ignore, else SWT exception thrown; DATE:2014-05-29 if (html_box.Kit().Kit_mode__term()) return; // shutting down raises status changed events; ignore, else SWT exception thrown; DATE:2014-05-29
// 2020-09-22|ISSUE#:799|normalize URL due to SWT 4.16 // 2020-09-22|ISSUE#:799|normalize URL due to SWT 4.16
String ev_text = Swt_html.NormalizeSwtUrl(ev.text); String ev_text = Swt_html_utl.NormalizeSwtUrl(ev.text);
String load_by_url_path = html_box.Load_by_url_path(); String load_by_url_path = html_box.Load_by_url_path();
if (load_by_url_path != null) ev_text = String_.Replace(ev_text, load_by_url_path, ""); // remove "C:/xowa/tab_1.html" if (load_by_url_path != null) ev_text = String_.Replace(ev_text, load_by_url_path, ""); // remove "C:/xowa/tab_1.html"
@ -276,7 +257,7 @@ class Swt_html_lnr_location implements LocationListener {
@Override public void changing(LocationEvent arg) {Pub_evt(arg, Gfui_html.Evt_location_changing);} @Override public void changing(LocationEvent arg) {Pub_evt(arg, Gfui_html.Evt_location_changing);}
private void Pub_evt(LocationEvent arg, String evt) { private void Pub_evt(LocationEvent arg, String evt) {
// 2020-09-22|ISSUE#:799|normalize URL due to SWT 4.16 // 2020-09-22|ISSUE#:799|normalize URL due to SWT 4.16
String location = Swt_html.NormalizeSwtUrl(arg.location); String location = Swt_html_utl.NormalizeSwtUrl(arg.location);
// location_changing fires once when page is loaded -> ignore // location_changing fires once when page is loaded -> ignore
if (String_.Eq(location, String_.Empty)) { if (String_.Eq(location, String_.Empty)) {
@ -344,7 +325,7 @@ class Swt_html_lnr_wheel implements MouseWheelListener {
// public Swt_open_window_listener(Swt_html html_box) {this.html_box = html_box;} // public Swt_open_window_listener(Swt_html html_box) {this.html_box = html_box;}
// @Override public void open(WindowEvent arg0) { // @Override public void open(WindowEvent arg0) {
// Tfds.Write(); // Tfds.Write();
// } // }
//} //}
/* /*
NOTE_1:browser scrollbar and click NOTE_1:browser scrollbar and click
@ -362,5 +343,5 @@ so, assume:
two issues still occur with the workaround two issues still occur with the workaround
1) even if the scrollbar is not present, any click on the right-hand edge of the screen will be ignored 1) even if the scrollbar is not present, any click on the right-hand edge of the screen will be ignored
2) click -> hold -> move mouse over to left -> release; the mouse up should be absorbed, but it is not due to position of release 2) click -> hold -> move mouse over to left -> release; the mouse up should be absorbed, but it is not due to position of release
*/ */

@ -0,0 +1,40 @@
/*
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.gfui.kits.swts;
import gplx.String_;
public class Swt_html_utl {
private static final String URL_PREFIX_ABOUT = "about:";
private static final String URL_PREFIX_BLANK = "blank";
public static String NormalizeSwtUrl(String url) {
String rv = url;
// 2020-09-19|ISSUE#:799|strip "about:" from url due to SWT 4.16
rv = String_.Has_at_bgn(rv, URL_PREFIX_ABOUT)
? String_.Mid(rv, URL_PREFIX_ABOUT.length())
: rv;
// 2015-06-09|webkit prefixes "about:blank" to anchors; causes TOC to fail when clicking on links; EX:about:blank#TOC1
// 2020-09-22|removed webkit check due to SWT 4.16; `html_box.Browser_tid() == Swt_html.Browser_tid_webkit`
// still strip "blank"; note that SWT 4.16 changes anchors from "file:///#anchor" to "en.w/wiki/page/#anchor"
rv = String_.Has_at_bgn(rv, URL_PREFIX_BLANK)
? String_.Mid(rv, URL_PREFIX_BLANK.length())
: rv;
return rv;
}
}

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application 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, 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. or alternatively under the terms of the Apache License Version 2.0.
@ -13,264 +13,299 @@ 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 GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.guis.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.guis.*; package gplx.xowa.guis.views;
import gplx.gfui.*; import gplx.gfui.kits.core.*; import gplx.gfui.draws.*; import gplx.gfui.controls.gxws.*; import gplx.gfui.controls.tabs.*; import gplx.gfui.controls.standards.*;
import gplx.xowa.apps.apis.xowa.gui.browsers.*; import gplx.xowa.specials.*; import gplx.Bool_;
import gplx.xowa.apps.urls.*; import gplx.Err_;
public class Xog_tab_mgr implements Gfo_evt_itm { import gplx.GfoMsg;
private Ordered_hash tab_regy = Ordered_hash_.New(); private int tab_uid = 0; import gplx.Gfo_evt_itm;
private boolean btns__hide_if_one; private int btns__height; import gplx.Gfo_evt_mgr;
public Xog_tab_mgr(Xog_win_itm win) { import gplx.Gfo_evt_mgr_;
this.win = win; import gplx.Gfo_invk_;
ev_mgr = new Gfo_evt_mgr(this); import gplx.GfsCtx;
} import gplx.Int_;
public Gfo_evt_mgr Evt_mgr() {return ev_mgr;} private Gfo_evt_mgr ev_mgr; import gplx.List_adp;
public Xog_win_itm Win() {return win;} private Xog_win_itm win; import gplx.List_adp_;
public Gfui_tab_mgr Tab_mgr() {return tab_mgr;} private Gfui_tab_mgr tab_mgr; import gplx.Ordered_hash;
public int Btns__min_chars() {return btns__min_chars;} private int btns__min_chars; import gplx.Ordered_hash_;
public int Btns__max_chars() {return btns__max_chars;} private int btns__max_chars; import gplx.String_;
public boolean Javascript_enabled() {return javascript_enabled;} private boolean javascript_enabled = true; import gplx.gfui.controls.gxws.Gxw_html_load_tid_;
private byte page_load_mode; import gplx.gfui.controls.standards.Gfui_tab_itm;
public boolean Page_load_mode_is_url() {return page_load_mode == Gxw_html_load_tid_.Tid_url;} import gplx.gfui.controls.standards.Gfui_tab_itm_data;
public void Init_by_kit(Gfui_kit kit) { import gplx.gfui.controls.standards.Gfui_tab_mgr;
tab_mgr = kit.New_tab_mgr("xowa.tab_mgr", win.Win_box()); import gplx.gfui.controls.tabs.TabBox_;
active_tab = Xog_tab_itm_.Null; import gplx.gfui.kits.core.Gfui_kit;
Gfo_evt_mgr_.Sub_same_many(tab_mgr, this, Gfui_tab_mgr.Evt_tab_selected, Gfui_tab_mgr.Evt_tab_closed, Gfui_tab_mgr.Evt_tab_switched); import gplx.gfui.kits.swts.Swt_html_utl;
win.App().Cfg().Bind_many_app(this, Cfg__page_load_mode import gplx.xowa.Xoa_ttl;
, Cfg__place_on_top, Cfg__height, Cfg__hide_if_one, Cfg__curved, Cfg__close_btn_visible, Cfg__unselected_close_btn_visible, Cfg__max_chars, Cfg__min_chars); import gplx.xowa.Xoa_url;
} import gplx.xowa.Xoae_page;
public Xog_tab_itm Active_tab() {return active_tab;} private Xog_tab_itm active_tab; import gplx.xowa.Xowe_wiki;
public Xog_tab_itm Active_tab_assert() { import gplx.xowa.htmls.hrefs.Xoh_href_;
if (active_tab == Xog_tab_itm_.Null) this.Tabs_new_dflt(true); import gplx.xowa.specials.Xow_special_meta_;
return active_tab;
} public class Xog_tab_mgr implements Gfo_evt_itm {
public boolean Active_tab_is_null() {return active_tab == Xog_tab_itm_.Null;} private Ordered_hash tab_regy = Ordered_hash_.New(); private int tab_uid = 0;
private void Btns_text_recalc() { private boolean btns__hide_if_one; private int btns__height;
int len = this.Tabs_len(); public Xog_tab_mgr(Xog_win_itm win) {
for (int i = 0; i < len; i++) { this.win = win;
Xog_tab_itm tab_itm = this.Tabs_get_at(i); ev_mgr = new Gfo_evt_mgr(this);
tab_itm.Tab_name_(); }
} public Gfo_evt_mgr Evt_mgr() {return ev_mgr;} private Gfo_evt_mgr ev_mgr;
} public Xog_win_itm Win() {return win;} private Xog_win_itm win;
public int Tabs_len() {return tab_regy.Count();} public Gfui_tab_mgr Tab_mgr() {return tab_mgr;} private Gfui_tab_mgr tab_mgr;
public Xog_tab_itm Tabs_new_init(Xowe_wiki wiki, Xoae_page page) {return this.Tabs_new(true, true, wiki, page);} public int Btns__min_chars() {return btns__min_chars;} private int btns__min_chars;
public Xog_tab_itm Tabs_get_at(int i) {return (Xog_tab_itm)tab_regy.Get_at(i);} public int Btns__max_chars() {return btns__max_chars;} private int btns__max_chars;
public Xog_tab_itm Tabs_new_dflt() {return Tabs_new_dflt(false);} public boolean Javascript_enabled() {return javascript_enabled;} private boolean javascript_enabled = true;
public Xog_tab_itm Tabs_new_dflt(boolean focus) { private byte page_load_mode;
boolean active_tab_is_null = this.Active_tab_is_null(); public boolean Page_load_mode_is_url() {return page_load_mode == Gxw_html_load_tid_.Tid_url;}
Xowe_wiki cur_wiki = active_tab_is_null ? win.App().Usere().Wiki() : active_tab.Wiki(); public void Init_by_kit(Gfui_kit kit) {
Xoa_ttl ttl = Xoa_ttl.Parse(cur_wiki, Xow_special_meta_.Itm__default_tab.Ttl_bry()); tab_mgr = kit.New_tab_mgr("xowa.tab_mgr", win.Win_box());
Xoa_url url = cur_wiki.Utl__url_parser().Parse_by_urlbar_or_null(ttl.Full_db_as_str()); if (url == null) throw Err_.new_("url", "invalid url", "url", url); active_tab = Xog_tab_itm_.Null;
Xog_tab_itm rv = Tabs_new(focus, active_tab_is_null, cur_wiki, Xoae_page.New(cur_wiki, ttl)); Gfo_evt_mgr_.Sub_same_many(tab_mgr, this, Gfui_tab_mgr.Evt_tab_selected, Gfui_tab_mgr.Evt_tab_closed, Gfui_tab_mgr.Evt_tab_switched);
rv.Page_update_ui(); win.App().Cfg().Bind_many_app(this, Cfg__page_load_mode
rv.Show_url_bgn(url); , Cfg__place_on_top, Cfg__height, Cfg__hide_if_one, Cfg__curved, Cfg__close_btn_visible, Cfg__unselected_close_btn_visible, Cfg__max_chars, Cfg__min_chars);
return rv; }
} public Xog_tab_itm Active_tab() {return active_tab;} private Xog_tab_itm active_tab;
private Xog_tab_itm Tabs_new(boolean focus, boolean active_tab_is_null, Xowe_wiki wiki, Xoae_page page) { public Xog_tab_itm Active_tab_assert() {
String tab_key = "tab_" + Int_.To_str(tab_uid++); int tab_idx = tab_regy.Count(); if (active_tab == Xog_tab_itm_.Null) this.Tabs_new_dflt(true);
Gfui_tab_itm_data tab_data = new Gfui_tab_itm_data(tab_key, tab_idx); return active_tab;
Xog_tab_itm rv = new Xog_tab_itm(this, tab_data, wiki, page); }
Gfui_tab_itm tab_box = tab_mgr.Tabs_add(tab_data); public boolean Active_tab_is_null() {return active_tab == Xog_tab_itm_.Null;}
rv.Make_html_box(tab_uid, tab_box, win, tab_mgr); private void Btns_text_recalc() {
rv.Html_itm().Js_enabled_(javascript_enabled); int len = this.Tabs_len();
tab_box.Subs_add(rv.Html_itm().Html_box()); for (int i = 0; i < len; i++) {
tab_regy.Add(tab_key, rv); Xog_tab_itm tab_itm = this.Tabs_get_at(i);
if ( focus tab_itm.Tab_name_();
|| active_tab_is_null // NOTE: must select 1st tab, else nothing will show in tab box }
) { }
tab_mgr.Tabs_select_by_idx(rv.Tab_idx()); public int Tabs_len() {return tab_regy.Count();}
active_tab = rv; public Xog_tab_itm Tabs_new_init(Xowe_wiki wiki, Xoae_page page) {return this.Tabs_new(true, true, wiki, page);}
} public Xog_tab_itm Tabs_get_at(int i) {return (Xog_tab_itm)tab_regy.Get_at(i);}
Tabs_hide_if_one_chk(false); public Xog_tab_itm Tabs_new_dflt() {return Tabs_new_dflt(false);}
return rv; public Xog_tab_itm Tabs_new_dflt(boolean focus) {
} boolean active_tab_is_null = this.Active_tab_is_null();
public void Tabs_new_dupe(boolean focus) { Xowe_wiki cur_wiki = active_tab_is_null ? win.App().Usere().Wiki() : active_tab.Wiki();
if (this.Active_tab_is_null()) return; Xoa_ttl ttl = Xoa_ttl.Parse(cur_wiki, Xow_special_meta_.Itm__default_tab.Ttl_bry());
String url = active_tab.Page().Url().To_str(); Xoa_url url = cur_wiki.Utl__url_parser().Parse_by_urlbar_or_null(ttl.Full_db_as_str()); if (url == null) throw Err_.new_("url", "invalid url", "url", url);
Tabs_new_dflt(focus); Xog_tab_itm rv = Tabs_new(focus, active_tab_is_null, cur_wiki, Xoae_page.New(cur_wiki, ttl));
win.Page__navigate_by_url_bar(url); rv.Page_update_ui();
} rv.Show_url_bgn(url);
public void Tabs_javascript_enabled_(boolean v) { return rv;
this.javascript_enabled = v; }
int len = tab_regy.Count(); private Xog_tab_itm Tabs_new(boolean focus, boolean active_tab_is_null, Xowe_wiki wiki, Xoae_page page) {
for (int i = 0; i < len; i++) { String tab_key = "tab_" + Int_.To_str(tab_uid++); int tab_idx = tab_regy.Count();
Xog_tab_itm tab = Tabs_get_by_idx_or_warn(i); Gfui_tab_itm_data tab_data = new Gfui_tab_itm_data(tab_key, tab_idx);
tab.Html_itm().Js_enabled_(v); Xog_tab_itm rv = new Xog_tab_itm(this, tab_data, wiki, page);
} Gfui_tab_itm tab_box = tab_mgr.Tabs_add(tab_data);
} rv.Make_html_box(tab_uid, tab_box, win, tab_mgr);
private void Tabs_selected(String key) { rv.Html_itm().Js_enabled_(javascript_enabled);
Xog_tab_itm tab = Tabs_get_by_key_or_warn(key); if (tab == null) return; tab_box.Subs_add(rv.Html_itm().Html_box());
active_tab = tab; tab_regy.Add(tab_key, rv);
Xoae_page page = tab.Page(); if ( focus
Xog_tab_itm_read_mgr.Update_selected_tab(win, page.Url(), page.Ttl()); || active_tab_is_null // NOTE: must select 1st tab, else nothing will show in tab box
tab.Html_itm().Tab_selected(page); ) {
} tab_mgr.Tabs_select_by_idx(rv.Tab_idx());
public void Tabs_close_cur() { active_tab = rv;
if (this.Active_tab_is_null()) return; }
Tabs__pub_close(active_tab); Tabs_hide_if_one_chk(false);
tab_mgr.Tabs_close_by_idx(active_tab.Tab_idx()); return rv;
Xog_tab_itm cur_tab = this.Active_tab(); // get new current tab for line below }
if (cur_tab != null) cur_tab.Html_box().Focus(); // NOTE: needed to focus tab box else tab button will be focused; DATE:2014-07-13 public void Tabs_new_dupe(boolean focus) {
} if (this.Active_tab_is_null()) return;
public void Tabs_close_others() {this.Tabs_close_to_bgn(); this.Tabs_close_to_end();} String url = active_tab.Page().Url().To_str();
public void Tabs_close_to_bgn() {if (Active_tab_is_null()) return; Tabs_close_rng(0 , active_tab.Tab_idx());} Tabs_new_dflt(focus);
public void Tabs_close_to_end() {if (Active_tab_is_null()) return; Tabs_close_rng(active_tab.Tab_idx() + 1 , tab_regy.Count());} win.Page__navigate_by_url_bar(url);
public void Tabs_close_rng(int bgn, int end) { }
for (int i = bgn; i < end; i++) { public void Tabs_javascript_enabled_(boolean v) {
Xog_tab_itm tab = Tabs_get_at(bgn); this.javascript_enabled = v;
if (!Tabs__pub_close(tab)) return; int len = tab_regy.Count();
} for (int i = 0; i < len; i++) {
for (int i = bgn; i < end; i++) Xog_tab_itm tab = Tabs_get_by_idx_or_warn(i);
tab_mgr.Tabs_close_by_idx(bgn); // NOTE: close at bgn, not at i, b/c each close will remove a tab from collection tab.Html_itm().Js_enabled_(v);
} }
public boolean Tabs__pub_close_all() {return Tabs__pub_close_rng(0, this.Tabs_len());} }
public boolean Tabs__pub_close_rng(int bgn, int end) { private void Tabs_selected(String key) {
boolean rv = true; Xog_tab_itm tab = Tabs_get_by_key_or_warn(key); if (tab == null) return;
for (int i = bgn; i < end; i++) { active_tab = tab;
Xog_tab_itm tab = Tabs_get_at(i); Xoae_page page = tab.Page();
boolean close_allowed = Tabs__pub_close(tab); Xog_tab_itm_read_mgr.Update_selected_tab(win, page.Url(), page.Ttl());
if (!close_allowed) rv = false; tab.Html_itm().Tab_selected(page);
} }
return rv; public void Tabs_close_cur() {
} if (this.Active_tab_is_null()) return;
public boolean Tabs__pub_close(Xog_tab_itm tab) { Tabs__pub_close(active_tab);
return tab.Page().Tab_data().Close_mgr().When_close(tab, Xoa_url.Null); tab_mgr.Tabs_close_by_idx(active_tab.Tab_idx());
} Xog_tab_itm cur_tab = this.Active_tab(); // get new current tab for line below
public void Tabs_close_undo() { if (cur_tab != null) cur_tab.Html_box().Focus(); // NOTE: needed to focus tab box else tab button will be focused; DATE:2014-07-13
if (closed_undo_list.Count() == 0) return; }
String url = (String)List_adp_.Pop(closed_undo_list); public void Tabs_close_others() {this.Tabs_close_to_bgn(); this.Tabs_close_to_end();}
Tabs_new_dflt(true); public void Tabs_close_to_bgn() {if (Active_tab_is_null()) return; Tabs_close_rng(0 , active_tab.Tab_idx());}
win.Page__navigate_by_url_bar(url); public void Tabs_close_to_end() {if (Active_tab_is_null()) return; Tabs_close_rng(active_tab.Tab_idx() + 1 , tab_regy.Count());}
} public void Tabs_close_rng(int bgn, int end) {
private List_adp closed_undo_list = List_adp_.New(); for (int i = bgn; i < end; i++) {
private void Tabs_closed(String key) { Xog_tab_itm tab = Tabs_get_at(bgn);
Xog_tab_itm itm = Tabs_get_by_key_or_warn(key); if (itm == null) return; if (!Tabs__pub_close(tab)) return;
itm.Html_box().Html_dispose(); }
closed_undo_list.Add(itm.Page().Url().To_str()); for (int i = bgn; i < end; i++)
tab_regy.Del(key); tab_mgr.Tabs_close_by_idx(bgn); // NOTE: close at bgn, not at i, b/c each close will remove a tab from collection
if (tab_regy.Count() == 0) { }
active_tab = Xog_tab_itm_.Null; public boolean Tabs__pub_close_all() {return Tabs__pub_close_rng(0, this.Tabs_len());}
Xog_tab_itm_read_mgr.Update_selected_tab_blank(win); public boolean Tabs__pub_close_rng(int bgn, int end) {
} boolean rv = true;
else for (int i = bgn; i < end; i++) {
Tabs_recalc_idx(); Xog_tab_itm tab = Tabs_get_at(i);
Tabs_hide_if_one_chk(false); boolean close_allowed = Tabs__pub_close(tab);
} if (!close_allowed) rv = false;
private Xog_tab_itm Tabs_get_by_key_or_warn(String key) { }
Xog_tab_itm rv = (Xog_tab_itm)tab_regy.Get_by(key); if (rv == null) win.App().Usr_dlg().Warn_many("", "", "tab.selected could not find tab; key={0}", key); return rv;
return rv; }
} public boolean Tabs__pub_close(Xog_tab_itm tab) {
private Xog_tab_itm Tabs_get_by_idx_or_warn(int idx) { return tab.Page().Tab_data().Close_mgr().When_close(tab, Xoa_url.Null);
Xog_tab_itm rv = (Xog_tab_itm)tab_regy.Get_at(idx); if (rv == null) win.App().Usr_dlg().Warn_many("", "", "tab.selected could not find tab; idx={0}", idx); }
return rv; public void Tabs_close_undo() {
} if (closed_undo_list.Count() == 0) return;
private void Tabs_recalc_idx() { String url = (String)List_adp_.Pop(closed_undo_list);
int len = tab_regy.Count(); Tabs_new_dflt(true);
for (int i = 0; i < len; i++) { win.Page__navigate_by_url_bar(url);
Xog_tab_itm itm = Tabs_get_by_idx_or_warn(i); }
itm.Tab_idx_(i); private List_adp closed_undo_list = List_adp_.New();
} private void Tabs_closed(String key) {
} Xog_tab_itm itm = Tabs_get_by_key_or_warn(key); if (itm == null) return;
public void Tabs_select(boolean fwd) { itm.Html_box().Html_dispose();
if (this.Active_tab_is_null()) return; closed_undo_list.Add(itm.Page().Url().To_str());
int new_idx = TabBox_.Cycle(fwd, active_tab.Tab_idx(), tab_regy.Count()); tab_regy.Del(key);
tab_mgr.Tabs_select_by_idx(new_idx); if (tab_regy.Count() == 0) {
} active_tab = Xog_tab_itm_.Null;
public void Tabs_select_by_idx(int v) { Xog_tab_itm_read_mgr.Update_selected_tab_blank(win);
if (v < 0 || v >= tab_regy.Count()) return; }
tab_mgr.Tabs_select_by_idx(v); else
} Tabs_recalc_idx();
public void Tabs_move(boolean fwd) { Tabs_hide_if_one_chk(false);
if (this.Active_tab_is_null()) return; }
int src_idx = active_tab.Tab_idx(); private Xog_tab_itm Tabs_get_by_key_or_warn(String key) {
int trg_idx = TabBox_.Cycle(fwd, src_idx, tab_regy.Count()); Xog_tab_itm rv = (Xog_tab_itm)tab_regy.Get_by(key); if (rv == null) win.App().Usr_dlg().Warn_many("", "", "tab.selected could not find tab; key={0}", key);
tab_mgr.Tabs_switch(src_idx, trg_idx); return rv;
} }
private void Tabs_switched(String src_key, String trg_key) { private Xog_tab_itm Tabs_get_by_idx_or_warn(int idx) {
Xog_tab_itm src_itm = Tabs_get_by_key_or_warn(src_key); Xog_tab_itm rv = (Xog_tab_itm)tab_regy.Get_at(idx); if (rv == null) win.App().Usr_dlg().Warn_many("", "", "tab.selected could not find tab; idx={0}", idx);
Xog_tab_itm trg_itm = Tabs_get_by_key_or_warn(trg_key); return rv;
src_itm.Switch_mem(trg_itm); }
active_tab = trg_itm; // NOTE: src_itm initiated switch, but trg_itm is now active b/c everything in src_itm has now been reparented to trg_itm; DATE:2014-05-12 private void Tabs_recalc_idx() {
} int len = tab_regy.Count();
public void Tabs_new_link(boolean focus, String link) { // handle empty link for (int i = 0; i < len; i++) {
if (String_.Len_eq_0(link)) { Xog_tab_itm itm = Tabs_get_by_idx_or_warn(i);
if (this.Active_tab_is_null()) return; itm.Tab_idx_(i);
link = gplx.langs.htmls.encoders.Gfo_url_encoder_.Http_url.Decode_str(active_tab.Html_itm().Html_selected_get_active_or_selection()); // NOTE: must decode else url-encoded special pages don't work; EX:home/wiki/Special:XowaCfg%3Fgrp%3Dxowa.html.css; DATE:2017-01-02 }
} }
if (String_.Len_eq_0(link)) {win.App().Usr_dlg().Prog_many("", "", "no link or text selected"); return;} public void Tabs_select(boolean fwd) {
Tabs_new_link(link, focus); if (this.Active_tab_is_null()) return;
} int new_idx = TabBox_.Cycle(fwd, active_tab.Tab_idx(), tab_regy.Count());
public void Tabs_new_link(String link, boolean focus) { tab_mgr.Tabs_select_by_idx(new_idx);
Xowe_wiki wiki = active_tab.Wiki(); }
Xog_tab_itm new_tab = Tabs_new(focus, false, wiki, Xoae_page.New(wiki, active_tab.Page().Ttl())); // NOTE: do not use ttl from link, else middle-clicking pages with anchors won't work; DATE:2015-05-03 public void Tabs_select_by_idx(int v) {
Xoa_url url = wiki.Utl__url_parser().Parse_by_urlbar_or_null(link); if (url == null) return; // NOTE: link must be of form domain/wiki/page; DATE:2014-05-27 if (v < 0 || v >= tab_regy.Count()) return;
new_tab.Show_url_bgn(url); tab_mgr.Tabs_select_by_idx(v);
if (focus) }
tab_mgr.Tabs_select_by_idx(new_tab.Tab_idx()); public void Tabs_move(boolean fwd) {
} if (this.Active_tab_is_null()) return;
private void Tabs_hide_if_one_chk(boolean force) { int src_idx = active_tab.Tab_idx();
if (btns__hide_if_one || force) {// run code only if enabled or forced int trg_idx = TabBox_.Cycle(fwd, src_idx, tab_regy.Count());
if (tab_regy.Count() == 1) { tab_mgr.Tabs_switch(src_idx, trg_idx);
int desired_height = btns__hide_if_one ? 0 : btns__height; }
if (tab_mgr.Btns_height() != desired_height) private void Tabs_switched(String src_key, String trg_key) {
tab_mgr.Btns_height_(desired_height); Xog_tab_itm src_itm = Tabs_get_by_key_or_warn(src_key);
} Xog_tab_itm trg_itm = Tabs_get_by_key_or_warn(trg_key);
else { src_itm.Switch_mem(trg_itm);
if (tab_mgr.Btns_height() != btns__height) active_tab = trg_itm; // NOTE: src_itm initiated switch, but trg_itm is now active b/c everything in src_itm has now been reparented to trg_itm; DATE:2014-05-12
tab_mgr.Btns_height_(btns__height); }
} public void Tabs_new_link(boolean focus, String link) { // handle empty link
} if (String_.Len_eq_0(link)) {
} if (this.Active_tab_is_null()) return;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { link = active_tab.Html_itm().Html_selected_get_active_or_selection();
if (ctx.Match(k, Invk_tabs_new_dflt__at_dflt__focus_y)) Tabs_new_dflt(Bool_.Y); // 2020-12-16|ISSUE#:823|Open in new tab creates links like `about:/wiki/PAGE_NAME` or `about:/site/WIKI_NAME/wiki/PAGE_NAME`
else if (ctx.Match(k, Invk_tabs_new_link__at_dflt__focus_n)) Tabs_new_link(Bool_.N, m.ReadStrOr("v", null)); link = Swt_html_utl.NormalizeSwtUrl(link);
else if (ctx.Match(k, Invk_tabs_new_link__at_dflt__focus_y)) Tabs_new_link(Bool_.Y, m.ReadStrOr("v", null)); if (link.startsWith(Xoh_href_.Str__site)) {
else if (ctx.Match(k, Gfui_tab_mgr.Evt_tab_selected)) Tabs_selected(m.ReadStr("key")); link = link.substring(Xoh_href_.Str__site.length());
else if (ctx.Match(k, Gfui_tab_mgr.Evt_tab_closed)) Tabs_closed(m.ReadStr("key")); }
else if (ctx.Match(k, Gfui_tab_mgr.Evt_tab_switched)) Tabs_switched(m.ReadStr("src"), m.ReadStr("trg")); else if (link.startsWith(Xoh_href_.Str__wiki)) {
else if (ctx.Match(k, Invk_tabs_close_cur)) Tabs_close_cur(); link = active_tab.Wiki().Domain_str() + link;
else if (ctx.Match(k, Invk_tabs_select_bwd)) Tabs_select(Bool_.N); }
else if (ctx.Match(k, Invk_tabs_select_fwd)) Tabs_select(Bool_.Y); link = gplx.langs.htmls.encoders.Gfo_url_encoder_.Http_url.Decode_str(link); // NOTE: must decode else url-encoded special pages don't work; EX:home/wiki/Special:XowaCfg%3Fgrp%3Dxowa.html.css; DATE:2017-01-02
else if (ctx.Match(k, Invk_tabs_switch_cur_bwd)) Tabs_move(Bool_.N); }
else if (ctx.Match(k, Invk_tabs_switch_cur_fwd)) Tabs_move(Bool_.Y); if (String_.Len_eq_0(link)) {win.App().Usr_dlg().Prog_many("", "", "no link or text selected"); return;}
Tabs_new_link(link, focus);
else if (ctx.Match(k, Cfg__place_on_top)) tab_mgr.Btns_place_on_top_(m.ReadYn("v")); }
else if (ctx.Match(k, Cfg__height)) {btns__height = m.ReadInt("v"); tab_mgr.Btns_height_(btns__height);} public void Tabs_new_link(String link, boolean focus) {
else if (ctx.Match(k, Cfg__hide_if_one)) {btns__hide_if_one = m.ReadYn("v"); Tabs_hide_if_one_chk(true);} Xowe_wiki wiki = active_tab.Wiki();
else if (ctx.Match(k, Cfg__curved)) tab_mgr.Btns_curved_(m.ReadYn("v")); Xog_tab_itm new_tab = Tabs_new(focus, false, wiki, Xoae_page.New(wiki, active_tab.Page().Ttl())); // NOTE: do not use ttl from link, else middle-clicking pages with anchors won't work; DATE:2015-05-03
else if (ctx.Match(k, Cfg__close_btn_visible)) tab_mgr.Btns_close_visible_(m.ReadYn("v")); Xoa_url url = wiki.Utl__url_parser().Parse_by_urlbar_or_null(link); if (url == null) return; // NOTE: link must be of form domain/wiki/page; DATE:2014-05-27
else if (ctx.Match(k, Cfg__unselected_close_btn_visible)) tab_mgr.Btns_unselected_close_visible_(m.ReadYn("v")); new_tab.Show_url_bgn(url);
else if (ctx.Match(k, Cfg__max_chars)) {btns__max_chars = m.ReadInt("v"); Btns_text_recalc();} if (focus)
else if (ctx.Match(k, Cfg__min_chars)) {btns__min_chars = m.ReadInt("v"); Btns_text_recalc();} tab_mgr.Tabs_select_by_idx(new_tab.Tab_idx());
}
else if (ctx.Match(k, Cfg__javascript_enabled)) Tabs_javascript_enabled_(m.ReadYnOrY("v")); // NOTE: must be "OrY" else broken cfg.db will break cfg_maint; DATE:2016-12-15 private void Tabs_hide_if_one_chk(boolean force) {
else if (ctx.Match(k, Cfg__page_load_mode)) Page_load_mode_(m.ReadStr("v")); if (btns__hide_if_one || force) {// run code only if enabled or forced
else return Gfo_invk_.Rv_unhandled; if (tab_regy.Count() == 1) {
return this; int desired_height = btns__hide_if_one ? 0 : btns__height;
} if (tab_mgr.Btns_height() != desired_height)
private void Page_load_mode_(String v) { tab_mgr.Btns_height_(desired_height);
page_load_mode = Gxw_html_load_tid_.Xto_tid(v); }
// Gfo_evt_mgr_.Pub_val(this, Evt_load_tid_changed, load_tid); else {
} if (tab_mgr.Btns_height() != btns__height)
tab_mgr.Btns_height_(btns__height);
public static final String }
Invk_tabs_select_fwd = "tabs_select_fwd" , Invk_tabs_select_bwd = "tabs_select_bwd" }
, Invk_tabs_switch_cur_fwd = "tabs_switch_cur_fwd" , Invk_tabs_switch_cur_bwd = "tabs_switch_cur_bwd" }
, Invk_tabs_new_dflt__at_dflt__focus_y = "tabs_new_dflt__at_dflt__focus_y" public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
, Invk_tabs_new_link__at_dflt__focus_n = "tabs_new_link__at_dflt__focus_n" if (ctx.Match(k, Invk_tabs_new_dflt__at_dflt__focus_y)) Tabs_new_dflt(Bool_.Y);
, Invk_tabs_new_link__at_dflt__focus_y = "tabs_new_link__at_dflt__focus_y" else if (ctx.Match(k, Invk_tabs_new_link__at_dflt__focus_n)) Tabs_new_link(Bool_.N, m.ReadStrOr("v", null));
, Invk_tabs_close_cur = "tabs_close_cur" else if (ctx.Match(k, Invk_tabs_new_link__at_dflt__focus_y)) Tabs_new_link(Bool_.Y, m.ReadStrOr("v", null));
; else if (ctx.Match(k, Gfui_tab_mgr.Evt_tab_selected)) Tabs_selected(m.ReadStr("key"));
private static final String else if (ctx.Match(k, Gfui_tab_mgr.Evt_tab_closed)) Tabs_closed(m.ReadStr("key"));
Cfg__place_on_top = "xowa.gui.tabs.place_on_top" else if (ctx.Match(k, Gfui_tab_mgr.Evt_tab_switched)) Tabs_switched(m.ReadStr("src"), m.ReadStr("trg"));
, Cfg__height = "xowa.gui.tabs.height" else if (ctx.Match(k, Invk_tabs_close_cur)) Tabs_close_cur();
, Cfg__hide_if_one = "xowa.gui.tabs.hide_if_one" else if (ctx.Match(k, Invk_tabs_select_bwd)) Tabs_select(Bool_.N);
, Cfg__curved = "xowa.gui.tabs.curved" else if (ctx.Match(k, Invk_tabs_select_fwd)) Tabs_select(Bool_.Y);
, Cfg__close_btn_visible = "xowa.gui.tabs.close_btn_visible" else if (ctx.Match(k, Invk_tabs_switch_cur_bwd)) Tabs_move(Bool_.N);
, Cfg__unselected_close_btn_visible = "xowa.gui.tabs.unselected_close_btn_visible" else if (ctx.Match(k, Invk_tabs_switch_cur_fwd)) Tabs_move(Bool_.Y);
, Cfg__max_chars = "xowa.gui.tabs.max_chars"
, Cfg__min_chars = "xowa.gui.tabs.min_chars" else if (ctx.Match(k, Cfg__place_on_top)) tab_mgr.Btns_place_on_top_(m.ReadYn("v"));
, Cfg__javascript_enabled = "xowa.gui.html_box.javascript_enabled" else if (ctx.Match(k, Cfg__height)) {btns__height = m.ReadInt("v"); tab_mgr.Btns_height_(btns__height);}
, Cfg__page_load_mode = "xowa.gui.html_box.page_load_mode" else if (ctx.Match(k, Cfg__hide_if_one)) {btns__hide_if_one = m.ReadYn("v"); Tabs_hide_if_one_chk(true);}
; else if (ctx.Match(k, Cfg__curved)) tab_mgr.Btns_curved_(m.ReadYn("v"));
} else if (ctx.Match(k, Cfg__close_btn_visible)) tab_mgr.Btns_close_visible_(m.ReadYn("v"));
else if (ctx.Match(k, Cfg__unselected_close_btn_visible)) tab_mgr.Btns_unselected_close_visible_(m.ReadYn("v"));
else if (ctx.Match(k, Cfg__max_chars)) {btns__max_chars = m.ReadInt("v"); Btns_text_recalc();}
else if (ctx.Match(k, Cfg__min_chars)) {btns__min_chars = m.ReadInt("v"); Btns_text_recalc();}
else if (ctx.Match(k, Cfg__javascript_enabled)) Tabs_javascript_enabled_(m.ReadYnOrY("v")); // NOTE: must be "OrY" else broken cfg.db will break cfg_maint; DATE:2016-12-15
else if (ctx.Match(k, Cfg__page_load_mode)) Page_load_mode_(m.ReadStr("v"));
else return Gfo_invk_.Rv_unhandled;
return this;
}
private void Page_load_mode_(String v) {
page_load_mode = Gxw_html_load_tid_.Xto_tid(v);
// Gfo_evt_mgr_.Pub_val(this, Evt_load_tid_changed, load_tid);
}
public static final String
Invk_tabs_select_fwd = "tabs_select_fwd" , Invk_tabs_select_bwd = "tabs_select_bwd"
, Invk_tabs_switch_cur_fwd = "tabs_switch_cur_fwd" , Invk_tabs_switch_cur_bwd = "tabs_switch_cur_bwd"
, Invk_tabs_new_dflt__at_dflt__focus_y = "tabs_new_dflt__at_dflt__focus_y"
, Invk_tabs_new_link__at_dflt__focus_n = "tabs_new_link__at_dflt__focus_n"
, Invk_tabs_new_link__at_dflt__focus_y = "tabs_new_link__at_dflt__focus_y"
, Invk_tabs_close_cur = "tabs_close_cur"
;
private static final String
Cfg__place_on_top = "xowa.gui.tabs.place_on_top"
, Cfg__height = "xowa.gui.tabs.height"
, Cfg__hide_if_one = "xowa.gui.tabs.hide_if_one"
, Cfg__curved = "xowa.gui.tabs.curved"
, Cfg__close_btn_visible = "xowa.gui.tabs.close_btn_visible"
, Cfg__unselected_close_btn_visible = "xowa.gui.tabs.unselected_close_btn_visible"
, Cfg__max_chars = "xowa.gui.tabs.max_chars"
, Cfg__min_chars = "xowa.gui.tabs.min_chars"
, Cfg__javascript_enabled = "xowa.gui.html_box.javascript_enabled"
, Cfg__page_load_mode = "xowa.gui.html_box.page_load_mode"
;
}

Loading…
Cancel
Save