Gui: Strip `about:` from links [#799]

staging v4.6.11.2009
gnosygnu 4 years ago
parent de841f8ff2
commit caad4145d5

@ -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,301 +13,347 @@ 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.gfui.kits.swts; import gplx.*; import gplx.gfui.*; import gplx.gfui.kits.*; package gplx.gfui.kits.swts;
import gplx.core.envs.System_;
import gplx.core.primitives.*; import gplx.Bool_;
import gplx.core.threads.Thread_adp_; import gplx.Bry_bfr;
import gplx.gfui.controls.elems.GfuiElem; import gplx.Bry_bfr_;
import gplx.gfui.controls.gxws.GxwCbkHost; import gplx.Byte_ascii;
import gplx.gfui.controls.gxws.GxwCore_base; import gplx.Err_;
import gplx.gfui.controls.gxws.GxwElem; import gplx.GfoMsg;
import gplx.gfui.controls.gxws.Gxw_html; import gplx.Gfo_evt_itm;
import gplx.gfui.controls.gxws.Gxw_html_load_tid_; import gplx.Gfo_evt_mgr;
import gplx.gfui.controls.standards.Gfui_html; import gplx.Gfo_evt_mgr_;
import gplx.gfui.controls.standards.Gfui_tab_mgr; import gplx.Gfo_evt_mgr_owner;
import gplx.gfui.draws.ColorAdp; import gplx.Gfo_invk;
import gplx.gfui.draws.ColorAdp_; import gplx.Gfo_invk_;
import gplx.gfui.ipts.*; import gplx.GfsCtx;
import gplx.gfui.kits.core.Swt_kit; import gplx.Int_;
import gplx.Io_mgr;
import java.security.acl.Owner; import gplx.Io_url;
import gplx.*; import gplx.Keyval_hash;
import gplx.Long_;
import org.eclipse.swt.SWT; import gplx.Object_;
import org.eclipse.swt.browser.*; import gplx.String_;
import org.eclipse.swt.events.*; import gplx.Type_;
import org.eclipse.swt.graphics.*; import gplx.UsrDlg_;
import org.eclipse.swt.widgets.*; import gplx.core.envs.System_;
import java.security.acl.Owner; import gplx.gfui.controls.elems.GfuiElem;
import gplx.gfui.controls.gxws.GxwCbkHost;
import org.eclipse.swt.SWT; import gplx.gfui.controls.gxws.GxwCore_base;
import org.eclipse.swt.browser.*; import gplx.gfui.controls.gxws.GxwElem;
import org.eclipse.swt.events.*; import gplx.gfui.controls.gxws.Gxw_html;
import org.eclipse.swt.graphics.*; import gplx.gfui.controls.gxws.Gxw_html_load_tid_;
import org.eclipse.swt.widgets.*; import gplx.gfui.controls.standards.Gfui_html;
import gplx.gfui.ipts.IptEvtDataMouse;
public class Swt_html implements Gxw_html, Swt_control, FocusListener, Gfo_evt_mgr_owner { import gplx.gfui.ipts.IptMouseBtn;
private Swt_html_lnr_location lnr_location; private Swt_html_lnr_status lnr_status; import gplx.gfui.ipts.IptMouseBtn_;
public Swt_html(Swt_kit kit, Swt_control owner_control, Keyval_hash ctorArgs) { import gplx.gfui.ipts.IptMouseWheel_;
this.kit = kit; import gplx.gfui.kits.core.Swt_kit;
lnr_location = new Swt_html_lnr_location(this); import org.eclipse.swt.SWT;
lnr_status = new Swt_html_lnr_status(this); import org.eclipse.swt.browser.Browser;
Object browser_tid_obj = ctorArgs.Get_val_or(Swt_kit.Cfg_Html_BrowserType, null); import org.eclipse.swt.browser.BrowserFunction;
this.browser_tid = browser_tid_obj == null ? Browser_tid_none : Int_.Cast(browser_tid_obj); import org.eclipse.swt.browser.LocationEvent;
browser = new Browser(owner_control.Under_composite(), browser_tid); import org.eclipse.swt.browser.LocationListener;
core = new Swt_core_cmds_html(this, browser); import org.eclipse.swt.browser.ProgressEvent;
browser.addKeyListener(new Swt_lnr_key(this)); import org.eclipse.swt.browser.ProgressListener;
browser.addMouseListener(new Swt_html_lnr_mouse(this, browser, kit)); import org.eclipse.swt.browser.StatusTextEvent;
browser.addLocationListener(lnr_location); import org.eclipse.swt.browser.StatusTextListener;
browser.addProgressListener(new Swt_html_lnr_progress(this)); import org.eclipse.swt.browser.TitleEvent;
browser.addStatusTextListener(lnr_status); import org.eclipse.swt.browser.TitleListener;
browser.addFocusListener(this); import org.eclipse.swt.events.FocusEvent;
browser.addTitleListener(new Swt_html_lnr_title(this)); import org.eclipse.swt.events.FocusListener;
browser.addMouseWheelListener(new Swt_html_lnr_wheel(this)); import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
// browser.addOpenWindowListener(new Swt_open_window_listener(this)); // handle target='blank' import org.eclipse.swt.events.MouseWheelListener;
// browser.addTraverseListener(new Swt_html_lnr_Traverse(this)); import org.eclipse.swt.events.TraverseEvent;
} import org.eclipse.swt.events.TraverseListener;
public Swt_kit Kit() {return kit;} private Swt_kit kit; import org.eclipse.swt.graphics.Point;
public Gfo_evt_mgr Evt_mgr() {return ev_mgr;} private Gfo_evt_mgr ev_mgr; public void Evt_mgr_(Gfo_evt_mgr v) {ev_mgr = v;} import org.eclipse.swt.widgets.Composite;
@Override public Control Under_control() {return browser;} private Browser browser; import org.eclipse.swt.widgets.Control;
@Override public Composite Under_composite() {return null;}
@Override public Control Under_menu_control() {return browser;} public class Swt_html implements Gxw_html, Swt_control, FocusListener, Gfo_evt_mgr_owner {
public int Browser_tid() {return browser_tid;} private final int browser_tid; private Swt_html_lnr_location lnr_location; private Swt_html_lnr_status lnr_status;
public String Load_by_url_path() {return load_by_url_path;} private String load_by_url_path; public Swt_html(Swt_kit kit, Swt_control owner_control, Keyval_hash ctorArgs) {
public void Html_doc_html_load_by_mem(String html) { this.kit = kit;
this.html_doc_html_load_tid = Gxw_html_load_tid_.Tid_mem; lnr_location = new Swt_html_lnr_location(this);
this.load_by_url_path = null; lnr_status = new Swt_html_lnr_status(this);
browser.setText(html); // DBG: Io_mgr.I.SaveFilStr(Io_url_.new_fil_("C:\\temp.txt"), s) Object browser_tid_obj = ctorArgs.Get_val_or(Swt_kit.Cfg_Html_BrowserType, null);
} this.browser_tid = browser_tid_obj == null ? Browser_tid_none : Int_.Cast(browser_tid_obj);
public void Html_doc_html_load_by_url(Io_url path, String html) { browser = new Browser(owner_control.Under_composite(), browser_tid);
this.html_doc_html_load_tid = Gxw_html_load_tid_.Tid_url; core = new Swt_core_cmds_html(this, browser);
this.load_by_url_path = path.To_http_file_str(); browser.addKeyListener(new Swt_lnr_key(this));
Io_mgr.Instance.SaveFilStr(path, html); browser.addMouseListener(new Swt_html_lnr_mouse(this, browser, kit));
browser.setUrl(path.Xto_api()); browser.addLocationListener(lnr_location);
} browser.addProgressListener(new Swt_html_lnr_progress(this));
public byte Html_doc_html_load_tid() {return html_doc_html_load_tid;} private byte html_doc_html_load_tid; browser.addStatusTextListener(lnr_status);
public void Html_doc_html_load_tid_(byte v) {html_doc_html_load_tid = v;} browser.addFocusListener(this);
public void Html_js_enabled_(boolean v) {browser.setJavascriptEnabled(v);} browser.addTitleListener(new Swt_html_lnr_title(this));
public void Html_js_cbks_add(String func_name, Gfo_invk invk) {new Swt_html_func(browser, func_name, invk);} browser.addMouseWheelListener(new Swt_html_lnr_wheel(this));
public String Html_js_eval_script(String script) {return Eval_script_as_str(script);}
public Object Html_js_eval_script_as_obj(String script) {return Eval_script(script);} // browser.addOpenWindowListener(new Swt_open_window_listener(this)); // handle target='blank'
public boolean Html_js_eval_proc_as_bool(String proc, Object... args) {return Bool_.Cast(Html_js_eval_proc_as_obj(proc, args));} // browser.addTraverseListener(new Swt_html_lnr_Traverse(this));
public String Html_js_eval_proc_as_str(String proc, Object... args) {return Object_.Xto_str_strict_or_null(Html_js_eval_proc_as_obj(proc, args));} }
public String Html_js_send_json(String name, String data) { public Swt_kit Kit() {return kit;} private Swt_kit kit;
String script = String_.Format("return {0}('{1}');", name, String_.Replace(data, "\n", "") ); public Gfo_evt_mgr Evt_mgr() {return ev_mgr;} private Gfo_evt_mgr ev_mgr; public void Evt_mgr_(Gfo_evt_mgr v) {ev_mgr = v;}
return (String)Eval_script(script); @Override public Control Under_control() {return browser;} private Browser browser;
} @Override public Composite Under_composite() {return null;}
private Object Html_js_eval_proc_as_obj(String proc, Object... args) { @Override public Control Under_menu_control() {return browser;}
Bry_bfr bfr = Bry_bfr_.New(); public int Browser_tid() {return browser_tid;} private final int browser_tid;
bfr.Add_str_a7("return ").Add_str_u8(proc).Add_byte(Byte_ascii.Paren_bgn); public String Load_by_url_path() {return load_by_url_path;} private String load_by_url_path;
int args_len = args.length; public void Html_doc_html_load_by_mem(String html) {
for (int i = 0; i < args_len; ++i) { this.html_doc_html_load_tid = Gxw_html_load_tid_.Tid_mem;
Object arg = args[i]; this.load_by_url_path = null;
if (i != 0) bfr.Add_byte(Byte_ascii.Comma); browser.setText(html); // DBG: Io_mgr.I.SaveFilStr(Io_url_.new_fil_("C:\\temp.txt"), s)
boolean quote_val = true; }
if ( Type_.Eq_by_obj(arg, Bool_.Cls_ref_type) public void Html_doc_html_load_by_url(Io_url path, String html) {
|| Type_.Eq_by_obj(arg, Int_.Cls_ref_type) this.html_doc_html_load_tid = Gxw_html_load_tid_.Tid_url;
|| Type_.Eq_by_obj(arg, Long_.Cls_ref_type) this.load_by_url_path = path.To_http_file_str();
) { Io_mgr.Instance.SaveFilStr(path, html);
quote_val = false; browser.setUrl(path.Xto_api());
} }
if (quote_val) bfr.Add_byte(Byte_ascii.Apos); public byte Html_doc_html_load_tid() {return html_doc_html_load_tid;} private byte html_doc_html_load_tid;
if (quote_val) public void Html_doc_html_load_tid_(byte v) {html_doc_html_load_tid = v;}
bfr.Add_str_u8(Escape_quote(Object_.Xto_str_strict_or_null_mark(arg))); public void Html_js_enabled_(boolean v) {browser.setJavascriptEnabled(v);}
else public void Html_js_cbks_add(String func_name, Gfo_invk invk) {new Swt_html_func(browser, func_name, invk);}
bfr.Add_obj_strict(arg); public String Html_js_eval_script(String script) {return Eval_script_as_str(script);}
if (quote_val) bfr.Add_byte(Byte_ascii.Apos); public Object Html_js_eval_script_as_obj(String script) {return Eval_script(script);}
} public boolean Html_js_eval_proc_as_bool(String proc, Object... args) {return Bool_.Cast(Html_js_eval_proc_as_obj(proc, args));}
bfr.Add_byte(Byte_ascii.Paren_end).Add_byte(Byte_ascii.Semic); public String Html_js_eval_proc_as_str(String proc, Object... args) {return Object_.Xto_str_strict_or_null(Html_js_eval_proc_as_obj(proc, args));}
return Eval_script(bfr.To_str_and_clear()); public String Html_js_send_json(String name, String data) {
} String script = String_.Format("return {0}('{1}');", name, String_.Replace(data, "\n", "") );
public static String Escape_quote(String v) { return (String)Eval_script(script);
String rv = v; }
rv = String_.Replace(rv, "'", "\\'"); private Object Html_js_eval_proc_as_obj(String proc, Object... args) {
rv = String_.Replace(rv, "\"", "\\\""); Bry_bfr bfr = Bry_bfr_.New();
rv = String_.Replace(rv, "\n", "\\n"); bfr.Add_str_a7("return ").Add_str_u8(proc).Add_byte(Byte_ascii.Paren_bgn);
return rv; int args_len = args.length;
} for (int i = 0; i < args_len; ++i) {
public void Html_invk_src_(Gfo_evt_itm invk) {lnr_location.Host_set(invk); lnr_status.Host_set(invk);} Object arg = args[i];
public void Html_dispose() { if (i != 0) bfr.Add_byte(Byte_ascii.Comma);
browser.dispose(); boolean quote_val = true;
delete_owner.SubElems().DelOrFail(delete_cur); // NOTE: must delete cur from owner, else new tab will fail after closing one; DATE:2014-07-09 if ( Type_.Eq_by_obj(arg, Bool_.Cls_ref_type)
System_.Garbage_collect(); || Type_.Eq_by_obj(arg, Int_.Cls_ref_type)
} || Type_.Eq_by_obj(arg, Long_.Cls_ref_type)
private GfuiElem delete_owner, delete_cur; ) {
public void Delete_elems_(GfuiElem delete_owner, GfuiElem delete_cur) {this.delete_owner = delete_owner; this.delete_cur = delete_cur;} // HACK: set owner / cur so delete can work; quote_val = false;
@Override public GxwCore_base Core() {return core;} private GxwCore_base core; }
@Override public GxwCbkHost Host() {return host;} @Override public void Host_set(GxwCbkHost host) {this.host = host;} GxwCbkHost host; if (quote_val) bfr.Add_byte(Byte_ascii.Apos);
@Override public String TextVal() {return browser.getText();} if (quote_val)
@Override public void TextVal_set(String v) {browser.setText(v);} bfr.Add_str_u8(Escape_quote(Object_.Xto_str_strict_or_null_mark(arg)));
@Override public void EnableDoubleBuffering() {} else
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return Gfo_invk_.Rv_unhandled;} bfr.Add_obj_strict(arg);
private String Eval_script_as_str(String script) {return (String)Eval_script(script);} if (quote_val) bfr.Add_byte(Byte_ascii.Apos);
public Object Eval_script(String script) { }
eval_rslt.Clear(); bfr.Add_byte(Byte_ascii.Paren_end).Add_byte(Byte_ascii.Semic);
try { return Eval_script(bfr.To_str_and_clear());
eval_rslt.Result_set(browser.evaluate(script)); }
return eval_rslt.Result(); public static String Escape_quote(String v) {
} String rv = v;
catch (Exception e) {eval_rslt.Error_set(e.getMessage()); return eval_rslt.Error();} rv = String_.Replace(rv, "'", "\\'");
} private Swt_html_eval_rslt eval_rslt = new Swt_html_eval_rslt(); rv = String_.Replace(rv, "\"", "\\\"");
@Override public void focusGained(FocusEvent arg0) {} rv = String_.Replace(rv, "\n", "\\n");
@Override public void focusLost(FocusEvent arg0) {} return rv;
public static final int }
Browser_tid_none = SWT.NONE public void Html_invk_src_(Gfo_evt_itm invk) {lnr_location.Host_set(invk); lnr_status.Host_set(invk);}
, Browser_tid_mozilla = SWT.MOZILLA public void Html_dispose() {
, Browser_tid_webkit = SWT.WEBKIT browser.dispose();
; delete_owner.SubElems().DelOrFail(delete_cur); // NOTE: must delete cur from owner, else new tab will fail after closing one; DATE:2014-07-09
} System_.Garbage_collect();
class Swt_core_cmds_html extends Swt_core__basic { }
public Swt_core_cmds_html(Swt_html html_box, Control control) {super(control);} private GfuiElem delete_owner, delete_cur;
@Override public void Focus() { public void Delete_elems_(GfuiElem delete_owner, GfuiElem delete_cur) {this.delete_owner = delete_owner; this.delete_cur = delete_cur;} // HACK: set owner / cur so delete can work;
if (Focus_able()) @Override public GxwCore_base Core() {return core;} private GxwCore_base core;
control.forceFocus(); @Override public GxwCbkHost Host() {return host;} @Override public void Host_set(GxwCbkHost host) {this.host = host;} GxwCbkHost host;
} @Override public String TextVal() {return browser.getText();}
@Override public void Select_exec() { @Override public void TextVal_set(String v) {browser.setText(v);}
this.Focus(); @Override public void EnableDoubleBuffering() {}
} @Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return Gfo_invk_.Rv_unhandled;}
} private String Eval_script_as_str(String script) {return (String)Eval_script(script);}
class Swt_html_lnr_traverse implements TraverseListener { public Object Eval_script(String script) {
public Swt_html_lnr_traverse(Swt_html html_box) {} eval_rslt.Clear();
@Override public void keyTraversed(TraverseEvent arg0) {} try {
} eval_rslt.Result_set(browser.evaluate(script));
class Swt_html_lnr_title implements TitleListener { return eval_rslt.Result();
private Swt_html html_box; }
public Swt_html_lnr_title(Swt_html html_box) {this.html_box = html_box;} catch (Exception e) {eval_rslt.Error_set(e.getMessage()); return eval_rslt.Error();}
@Override public void changed(TitleEvent ev) { } private Swt_html_eval_rslt eval_rslt = new Swt_html_eval_rslt();
try {UsrDlg_.Instance.Note(ev.title);} @Override public void focusGained(FocusEvent arg0) {}
catch (Exception e) {html_box.Kit().Ask_ok("xowa.swt.html_box", "title.fail", Err_.Message_gplx_full(e));} // NOTE: must catch error or will cause app to lock; currently called inside displaySync @Override public void focusLost(FocusEvent arg0) {}
} public static final int
} Browser_tid_none = SWT.NONE
class Swt_html_func extends BrowserFunction { , Browser_tid_mozilla = SWT.MOZILLA
private final Gfo_invk invk; , Browser_tid_webkit = SWT.WEBKIT
private final Browser browser; ;
public Swt_html_func(Browser browser, String name, Gfo_invk invk) { private static final String URL_ABOUT_PREFIX = "about:";
super (browser, name); public static String StripAboutFromUrl(String url) {
this.browser = browser; return String_.Has_at_bgn(url, URL_ABOUT_PREFIX)
this.invk = invk; ? String_.Mid(url, URL_ABOUT_PREFIX.length())
} : url;
public Object function (Object[] args) { }
try { }
return gplx.gfui.controls.standards.Gfui_html.Js_args_exec(invk, args); class Swt_core_cmds_html extends Swt_core__basic {
} public Swt_core_cmds_html(Swt_html html_box, Control control) {super(control);}
catch (Exception e) { @Override public void Focus() {
String rv = Err_.Message_gplx_full(e); if (Focus_able())
browser.execute("alert('" + Swt_html.Escape_quote(rv) + "')"); control.forceFocus();
return rv; }
} @Override public void Select_exec() {
} this.Focus();
} }
class Swt_html_lnr_status implements StatusTextListener { }
public Swt_html_lnr_status(Swt_html html_box) {this.html_box = html_box;} private Swt_html html_box; class Swt_html_lnr_traverse implements TraverseListener {
public void Host_set(Gfo_evt_itm host) {this.host = host;} Gfo_evt_itm host; public Swt_html_lnr_traverse(Swt_html html_box) {}
@Override public void changed(StatusTextEvent ev) { @Override public void keyTraversed(TraverseEvent arg0) {}
if (html_box.Kit().Kit_mode__term()) return; // shutting down raises status changed events; ignore, else SWT exception thrown; DATE:2014-05-29 }
String ev_text = ev.text; class Swt_html_lnr_title implements TitleListener {
String load_by_url_path = html_box.Load_by_url_path(); private Swt_html html_box;
if (load_by_url_path != null) ev_text = String_.Replace(ev_text, load_by_url_path, ""); // remove "C:/xowa/tab_1.html" public Swt_html_lnr_title(Swt_html html_box) {this.html_box = html_box;}
// if (String_.Has(ev_text, "Loading [MathJax]")) return; // suppress MathJax messages; // NOTE: disabled for 2.1 (which no longer outputs messages to status); DATE:2013-05-03 @Override public void changed(TitleEvent ev) {
try {if (host != null) Gfo_evt_mgr_.Pub_obj(host, Gfui_html.Evt_link_hover, "v", ev_text);} try {UsrDlg_.Instance.Note(ev.title);}
catch (Exception e) {html_box.Kit().Ask_ok("xowa.gui.html_box", "status.fail", Err_.Message_gplx_full(e));} // NOTE: must catch error or will cause app to lock; currently called inside displaySync catch (Exception e) {html_box.Kit().Ask_ok("xowa.swt.html_box", "title.fail", Err_.Message_gplx_full(e));} // NOTE: must catch error or will cause app to lock; currently called inside displaySync
} }
} }
class Swt_html_lnr_progress implements ProgressListener { class Swt_html_func extends BrowserFunction {
public Swt_html_lnr_progress(Swt_html html_box) {} private final Gfo_invk invk;
@Override public void changed(ProgressEvent arg0) {} private final Browser browser;
@Override public void completed(ProgressEvent arg0) { public Swt_html_func(Browser browser, String name, Gfo_invk invk) {
// UsrDlg_._.Note("done"); super (browser, name);
} this.browser = browser;
} this.invk = invk;
class Swt_html_lnr_location implements LocationListener { }
public Swt_html_lnr_location(Swt_html html_box) {this.html_box = html_box;} private Swt_html html_box; public Object function (Object[] args) {
public void Host_set(Gfo_evt_itm host) {this.host = host;} private Gfo_evt_itm host; try {
@Override public void changed(LocationEvent arg) {Pub_evt(arg, Gfui_html.Evt_location_changed);} return gplx.gfui.controls.standards.Gfui_html.Js_args_exec(invk, args);
@Override public void changing(LocationEvent arg) {Pub_evt(arg, Gfui_html.Evt_location_changing);} }
private void Pub_evt(LocationEvent arg, String evt) { catch (Exception e) {
String location = arg.location; String rv = Err_.Message_gplx_full(e);
if (String_.Eq(location, "about:blank")) return; // location changing event fires once when page is loaded; ignore browser.execute("alert('" + Swt_html.Escape_quote(rv) + "')");
if ( html_box.Browser_tid() == Swt_html.Browser_tid_webkit // webkit prefixes "about:blank" to anchors; causes TOC to fail when clicking on links; EX:about:blank#TOC1; DATE:2015-06-09 return rv;
&& String_.Has_at_bgn(location, "about:blank")) { }
location = String_.Mid(location, 11); // 11 = "about:blank".length }
} }
if ( html_box.Html_doc_html_load_tid() == Gxw_html_load_tid_.Tid_url // navigating to file://page.html will fire location event; ignore if url mode class Swt_html_lnr_status implements StatusTextListener {
&& String_.Has_at_bgn(location, "file:") public Swt_html_lnr_status(Swt_html html_box) {this.html_box = html_box;} private Swt_html html_box;
&& String_.Has_at_end(location, ".html") public void Host_set(Gfo_evt_itm host) {this.host = host;} Gfo_evt_itm host;
) @Override public void changed(StatusTextEvent ev) {
return; if (html_box.Kit().Kit_mode__term()) return; // shutting down raises status changed events; ignore, else SWT exception thrown; DATE:2014-05-29
try { String ev_text = ev.text;
Gfo_evt_mgr_.Pub_obj(host, evt, "v", location); ev_text = Swt_html.StripAboutFromUrl(ev_text); // 2020-09-19|ISSUE#:799|strip "about:/" from url due to SWT 4.16
arg.doit = false; // cancel navigation event, else there will be an error when trying to go to invalid location 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"
catch (Exception e) {html_box.Kit().Ask_ok("xowa.gui.html_box", evt, Err_.Message_gplx_full(e));} // NOTE: must catch error or will cause app to lock; currently called inside displaySync // if (String_.Has(ev_text, "Loading [MathJax]")) return; // suppress MathJax messages; // NOTE: disabled for 2.1 (which no longer outputs messages to status); DATE:2013-05-03
} try {if (host != null) Gfo_evt_mgr_.Pub_obj(host, Gfui_html.Evt_link_hover, "v", ev_text);}
} catch (Exception e) {html_box.Kit().Ask_ok("xowa.gui.html_box", "status.fail", Err_.Message_gplx_full(e));} // NOTE: must catch error or will cause app to lock; currently called inside displaySync
class Swt_html_lnr_mouse implements MouseListener { }
private GxwElem elem; private Browser browser; private Swt_kit kit; }
public Swt_html_lnr_mouse(GxwElem elem, Browser browser, Swt_kit kit) {this.elem = elem; this.browser = browser; this.kit = kit;} class Swt_html_lnr_progress implements ProgressListener {
@Override public void mouseDown(MouseEvent ev) { public Swt_html_lnr_progress(Swt_html html_box) {}
if (Is_at_scrollbar_area()) return; @Override public void changed(ProgressEvent arg0) {}
elem.Host().MouseDownCbk(XtoMouseData(ev)); @Override public void completed(ProgressEvent arg0) {
} // UsrDlg_._.Note("done");
@Override public void mouseUp(MouseEvent ev) { }
if (Is_at_scrollbar_area()) return; }
elem.Host().MouseUpCbk(XtoMouseData(ev)); class Swt_html_lnr_location implements LocationListener {
} public Swt_html_lnr_location(Swt_html html_box) {this.html_box = html_box;} private Swt_html html_box;
private boolean Is_at_scrollbar_area() { public void Host_set(Gfo_evt_itm host) {this.host = host;} private Gfo_evt_itm host;
// WORKAROUND.SWT: SEE:NOTE_1:browser scrollbar and click @Override public void changed(LocationEvent arg) {Pub_evt(arg, Gfui_html.Evt_location_changed);}
Point browser_size = browser.getSize(); @Override public void changing(LocationEvent arg) {Pub_evt(arg, Gfui_html.Evt_location_changing);}
Point click_pos = kit.Swt_display().getCursorLocation(); private void Pub_evt(LocationEvent arg, String evt) {
return click_pos.x >= browser_size.x - 12; String location = arg.location;
}
@Override public void mouseDoubleClick(MouseEvent ev) {} // location_changing fires once when page is loaded; ignore
IptEvtDataMouse XtoMouseData(MouseEvent ev) { if (String_.Eq(location, "about:blank")) {
IptMouseBtn btn = null; return;
switch (ev.button) { }
case 1: btn = IptMouseBtn_.Left; break;
case 2: btn = IptMouseBtn_.Middle; break; // webkit prefixes "about:blank" to anchors; causes TOC to fail when clicking on links; EX:about:blank#TOC1; DATE:2015-06-09
case 3: btn = IptMouseBtn_.Right; break; if (html_box.Browser_tid() == Swt_html.Browser_tid_webkit
case 4: btn = IptMouseBtn_.X1; break; && String_.Has_at_bgn(location, "about:blank")) {
case 5: btn = IptMouseBtn_.X2; break; location = String_.Mid(location, 11); // 11 = "about:blank".length
} }
return IptEvtDataMouse.new_(btn, IptMouseWheel_.None, ev.x, ev.y);
} // 2020-09-19|ISSUE#:799|strip "about:/" from url due to SWT 4.16
} location = Swt_html.StripAboutFromUrl(location);
class Swt_html_lnr_wheel implements MouseWheelListener {
private final Swt_html html_box; // navigating to file://page.html will fire location event; ignore if url mode
public Swt_html_lnr_wheel(Swt_html html_box) { if (html_box.Html_doc_html_load_tid() == Gxw_html_load_tid_.Tid_url
this.html_box = html_box; && String_.Has_at_bgn(location, "file:")
} && String_.Has_at_end(location, ".html")
@Override public void mouseScrolled(MouseEvent evt) { ) {
if (evt.stateMask == SWT.CTRL) { // ctrl held; return;
Gfo_evt_mgr_.Pub_obj(html_box, Gfui_html.Evt_zoom_changed, "clicks_is_positive", evt.count > 0); }
}
} try {
} Gfo_evt_mgr_.Pub_obj(host, evt, "v", location);
//class Swt_open_window_listener implements OpenWindowListener { arg.doit = false; // cancel navigation event, else there will be an error when trying to go to invalid location
// private final Swt_html html_box; }
// public Swt_open_window_listener(Swt_html html_box) {this.html_box = html_box;} catch (Exception e) {html_box.Kit().Ask_ok("xowa.gui.html_box", evt, Err_.Message_gplx_full(e));} // NOTE: must catch error or will cause app to lock; currently called inside displaySync
// @Override public void open(WindowEvent arg0) { }
// Tfds.Write(); }
// } class Swt_html_lnr_mouse implements MouseListener {
//} private GxwElem elem; private Browser browser; private Swt_kit kit;
/* public Swt_html_lnr_mouse(GxwElem elem, Browser browser, Swt_kit kit) {this.elem = elem; this.browser = browser; this.kit = kit;}
NOTE_1:browser scrollbar and click @Override public void mouseDown(MouseEvent ev) {
a click in the scrollbar area will raise a mouse-down/mouse-up event in content-editable mode if (Is_at_scrollbar_area()) return;
. a click should be consumed by the scrollbar and not have any effect elsewhere on the window elem.Host().MouseDownCbk(XtoMouseData(ev));
. instead, a click event is raised, and counted twice }
1) for the scroll bar this will scroll the area. @Override public void mouseUp(MouseEvent ev) {
2) for the window. if keyboard-focus is set on a link, then it will activate the link. if (Is_at_scrollbar_area()) return;
elem.Host().MouseUpCbk(XtoMouseData(ev));
swt does not expose any scrollbar information (visible, width), b/c the scrollbar is controlled by the underlying browser }
so, assume: private boolean Is_at_scrollbar_area() {
. scrollbar is always present // WORKAROUND.SWT: SEE:NOTE_1:browser scrollbar and click
. scrollbar has arbitrary width (currently 12) Point browser_size = browser.getSize();
. and discard if click is in this scrollbar area Point click_pos = kit.Swt_display().getCursorLocation();
return click_pos.x >= browser_size.x - 12;
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 @Override public void mouseDoubleClick(MouseEvent ev) {}
2) click -> hold -> move mouse over to left -> release; the mouse up should be absorbed, but it is not due to position of release IptEvtDataMouse XtoMouseData(MouseEvent ev) {
*/ IptMouseBtn btn = null;
switch (ev.button) {
case 1: btn = IptMouseBtn_.Left; break;
case 2: btn = IptMouseBtn_.Middle; break;
case 3: btn = IptMouseBtn_.Right; break;
case 4: btn = IptMouseBtn_.X1; break;
case 5: btn = IptMouseBtn_.X2; break;
}
return IptEvtDataMouse.new_(btn, IptMouseWheel_.None, ev.x, ev.y);
}
}
class Swt_html_lnr_wheel implements MouseWheelListener {
private final Swt_html html_box;
public Swt_html_lnr_wheel(Swt_html html_box) {
this.html_box = html_box;
}
@Override public void mouseScrolled(MouseEvent evt) {
if (evt.stateMask == SWT.CTRL) { // ctrl held;
Gfo_evt_mgr_.Pub_obj(html_box, Gfui_html.Evt_zoom_changed, "clicks_is_positive", evt.count > 0);
}
}
}
//class Swt_open_window_listener implements OpenWindowListener {
// private final Swt_html html_box;
// public Swt_open_window_listener(Swt_html html_box) {this.html_box = html_box;}
// @Override public void open(WindowEvent arg0) {
// Tfds.Write();
// }
//}
/*
NOTE_1:browser scrollbar and click
a click in the scrollbar area will raise a mouse-down/mouse-up event in content-editable mode
. a click should be consumed by the scrollbar and not have any effect elsewhere on the window
. instead, a click event is raised, and counted twice
1) for the scroll bar this will scroll the area.
2) for the window. if keyboard-focus is set on a link, then it will activate the link.
swt does not expose any scrollbar information (visible, width), b/c the scrollbar is controlled by the underlying browser
so, assume:
. scrollbar is always present
. scrollbar has arbitrary width (currently 12)
. and discard if click is in this scrollbar area
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
2) click -> hold -> move mouse over to left -> release; the mouse up should be absorbed, but it is not due to position of release
*/

Loading…
Cancel
Save