From c1d84249e10c04299295b43318cc592bdd771ffd Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Sat, 15 Oct 2016 18:21:46 -0400 Subject: [PATCH] Simplify scripting api; add support for multiple extensions; support lua extensions --- 400_xowa/.classpath | 1 + .../htmls/scripts/Gfh_script_engine.java | 8 +- .../htmls/scripts/Gfh_script_engine_.java | 31 +++++ .../scripts/Gfh_script_engine__java.java | 68 ----------- .../Gfh_script_engine__javascript.java | 72 ++++++++++++ .../scripts/Gfh_script_engine__luaj.java | 108 ++++++++++++++++++ .../scripts/Gfh_script_engine__noop.java | 26 +++++ .../addons/htmls/scripts/Xoscript_env.java | 30 ++++- .../addons/htmls/scripts/Xoscript_mgr.java | 56 +++++---- .../htmls/scripts/apis/Xoscript_doc.java | 42 +++---- .../scripts/apis/Xoscript_doc_head__tst.java | 20 ++-- .../scripts/apis/Xoscript_doc_sect_base.java | 48 ++++---- .../htmls/scripts/apis/Xoscript_log.java | 23 ++++ .../htmls/scripts/apis/Xoscript_page.java | 14 +-- .../htmls/scripts/apis/Xoscript_url.java | 6 +- .../htmls/scripts/xtns/Xoscript_xtn_itm.java | 29 +++++ .../htmls/scripts/xtns/Xoscript_xtn_mgr.java | 67 +++++++++++ .../src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java | 5 +- 18 files changed, 482 insertions(+), 172 deletions(-) create mode 100644 400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine_.java delete mode 100644 400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__java.java create mode 100644 400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__javascript.java create mode 100644 400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__luaj.java create mode 100644 400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__noop.java create mode 100644 400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_log.java create mode 100644 400_xowa/src/gplx/xowa/addons/htmls/scripts/xtns/Xoscript_xtn_itm.java create mode 100644 400_xowa/src/gplx/xowa/addons/htmls/scripts/xtns/Xoscript_xtn_mgr.java diff --git a/400_xowa/.classpath b/400_xowa/.classpath index a5620aadc..93a6d2c5f 100644 --- a/400_xowa/.classpath +++ b/400_xowa/.classpath @@ -1,5 +1,6 @@ + diff --git a/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine.java b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine.java index 14829df1c..00efbea5e 100644 --- a/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine.java +++ b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine.java @@ -20,11 +20,7 @@ public interface Gfh_script_engine { void Load_script(Io_url url); Object Get_object(String obj_name); void Put_object(String name, Object obj); + Object Eval_script(String script); Object Invoke_method(Object obj, String func, Object... args); -} -class Gfh_script_engine__noop implements Gfh_script_engine { - public void Load_script(Io_url url) {} - public Object Get_object(String obj_name) {return null;} - public void Put_object(String name, Object obj) {} - public Object Invoke_method(Object obj, String func, Object... args) {return null;} + Object Invoke_function(String func, Object... args); } diff --git a/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine_.java b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine_.java new file mode 100644 index 000000000..b22197611 --- /dev/null +++ b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine_.java @@ -0,0 +1,31 @@ +/* +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 . +*/ +package gplx.langs.htmls.scripts; import gplx.*; import gplx.langs.*; import gplx.langs.htmls.*; +public class Gfh_script_engine_ { + public static Gfh_script_engine New_by_key(String key) { + if (String_.Eq(key, "javascript.java")) return new Gfh_script_engine__javascript(); + else if (String_.Eq(key, "lua.luaj")) return new Gfh_script_engine__luaj(); + else if (String_.Eq(key, "noop")) return new Gfh_script_engine__noop(); + else throw Err_.new_unhandled(key); + } + public static Gfh_script_engine New_by_ext(String ext) { + if (String_.Eq(ext, ".js")) return new Gfh_script_engine__javascript(); + else if (String_.Eq(ext, ".lua")) return new Gfh_script_engine__luaj(); + else throw Err_.new_unhandled(ext); + } +} diff --git a/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__java.java b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__java.java deleted file mode 100644 index 3cd57aab1..000000000 --- a/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__java.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -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 . -*/ -package gplx.langs.htmls.scripts; import gplx.*; import gplx.langs.*; import gplx.langs.htmls.*; -import java.io.FileReader; - -import javax.script.Invocable; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -public class Gfh_script_engine__java implements Gfh_script_engine { - private final ScriptEngine engine; - private final Invocable invk; - public Gfh_script_engine__java() { - ScriptEngineManager manager = new ScriptEngineManager(); - this.engine = manager.getEngineByName("JavaScript"); - this.invk = (Invocable)engine; - } - public void Load_script(Io_url url) { - FileReader rdr = null; - try { - rdr = new FileReader(url.Xto_api()); - engine.eval(rdr); -// return engine.eval(script); - } catch (Exception e) { - System.out.println(e); - } - finally { - try { - rdr.close(); - } catch (Exception e) { - System.out.println(e); - } - } - } - public void Put_object(String key, Object val) { - engine.put(key, val); - } - public Object Get_object(String obj_name) { - try { - return engine.get(obj_name); - } catch (Exception e) { - System.out.println(e); - return null; - } - } - public Object Invoke_method(Object obj, String func, Object... args) { - try { - return invk.invokeMethod(obj, func, args); - } catch (Exception e) { - System.out.println(e); - return null; - } - } -} diff --git a/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__javascript.java b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__javascript.java new file mode 100644 index 000000000..0cd073636 --- /dev/null +++ b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__javascript.java @@ -0,0 +1,72 @@ +/* +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 . +*/ +package gplx.langs.htmls.scripts; import gplx.*; import gplx.langs.*; import gplx.langs.htmls.*; +import javax.script.Invocable; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +public class Gfh_script_engine__javascript implements Gfh_script_engine { + private final ScriptEngine engine; + private final Invocable invk; + public Gfh_script_engine__javascript() { + ScriptEngineManager manager = new ScriptEngineManager(); + this.engine = manager.getEngineByName("JavaScript"); + this.invk = (Invocable)engine; + } + public void Load_script(Io_url url) { + try {engine.eval(Io_mgr.Instance.LoadFilStr(url));} + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to load_script; url=~{0} err=~{1}", url, Err_.Message_lang(e)); + } + } + public void Put_object(String key, Object val) { + engine.put(key, val); + } + public Object Get_object(String obj_name) { + try {return engine.get(obj_name);} + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to get object; obj_name=~{0} err=~{1}", obj_name, Err_.Message_lang(e)); + return null; + } + } + public Object Eval_script(String script) { + try {return engine.eval(script);} + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to eval; script=~{0} err=~{1}", script, Err_.Message_lang(e)); + return null; + } + } + public Object Invoke_method(Object obj, String func, Object... args) { + try {return invk.invokeMethod(obj, func, args);} + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to invoke method; method=~{0} err=~{1}", func, Err_.Message_lang(e)); + return null; + } + } + public Object Invoke_function(String func, Object... args) { + try {return invk.invokeFunction(func, args);} + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to invoke method; method=~{0} err=~{1}", func, Err_.Message_lang(e)); + return null; + } + } +} diff --git a/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__luaj.java b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__luaj.java new file mode 100644 index 000000000..94a672d1d --- /dev/null +++ b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__luaj.java @@ -0,0 +1,108 @@ +/* +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 . +*/ +package gplx.langs.htmls.scripts; import gplx.*; import gplx.langs.*; import gplx.langs.htmls.*; +import javax.script.Invocable; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.SimpleBindings; +import javax.script.Bindings; +import javax.script.Compilable; +import javax.script.CompiledScript; + +import org.luaj.vm2.LuaClosure; +import org.luaj.vm2.LuaFunction; +import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; +import org.luaj.vm2.lib.jse.CoerceJavaToLua; +public class Gfh_script_engine__luaj implements Gfh_script_engine { + private final ScriptEngine engine; +// private final Invocable invk; + String sss = ""; + public Gfh_script_engine__luaj() { + ScriptEngineManager manager = new ScriptEngineManager(); + this.engine = manager.getEngineByName("luaj"); +// this.invk = (Invocable)engine; + } + public void Load_script(Io_url url) { + try { + sss = Io_mgr.Instance.LoadFilStr(url); + engine.eval(sss); + } + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to load_script; url=~{0} err=~{1}", url, Err_.Message_lang(e)); + } + } + public void Put_object(String key, Object val) { + engine.put(key, val); + } + public Object Get_object(String obj_name) { + try {return engine.get(obj_name);} + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to get object; obj_name=~{0} err=~{1}", obj_name, Err_.Message_lang(e)); + return null; + } + } + public Object Eval_script(String script) { + try {return engine.eval(script);} + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to eval; script=~{0} err=~{1}", script, Err_.Message_lang(e)); + return null; + } + } + public Object Invoke_method(Object obj, String func, Object... args) { + try { + CompiledScript script = ((Compilable) engine).compile(sss); + Bindings sb = new SimpleBindings(); + script.eval(sb); +// LuaTable lfunc = (LuaTable)sb.get("xo_script"); +// LuaClosure lfunc2 = (LuaClosure)lfunc.get(func); + LuaValue arg = CoerceJavaToLua.coerce(args[0]); + LuaFunction lfunc = (LuaFunction)sb.get("write_end"); + lfunc.call(arg); + return null; +// return engine.eval(obj); + } + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to invoke method; method=~{0} err=~{1}", func, Err_.Message_lang(e)); + return null; + } + } + public Object Invoke_function(String func, Object... args) { + try { + CompiledScript script = ((Compilable) engine).compile(sss); + Bindings sb = new SimpleBindings(); + script.eval(sb); +// LuaTable lfunc = (LuaTable)sb.get("xo_script"); +// LuaClosure lfunc2 = (LuaClosure)lfunc.get(func); + LuaValue arg = CoerceJavaToLua.coerce(args[0]); + LuaFunction lfunc = (LuaFunction)sb.get(func); + lfunc.call(arg); + return null; +// return engine.eval(obj); + } + catch (Exception e) { + System.out.println(e.getMessage()); + Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to invoke method; method=~{0} err=~{1}", func, Err_.Message_lang(e)); + return null; + } + } +} diff --git a/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__noop.java b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__noop.java new file mode 100644 index 000000000..1dc9a0f62 --- /dev/null +++ b/400_xowa/src/gplx/langs/htmls/scripts/Gfh_script_engine__noop.java @@ -0,0 +1,26 @@ +/* +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 . +*/ +package gplx.langs.htmls.scripts; import gplx.*; import gplx.langs.*; import gplx.langs.htmls.*; +public class Gfh_script_engine__noop implements Gfh_script_engine { + public void Load_script(Io_url url) {} + public Object Get_object(String obj_name) {return null;} + public void Put_object(String name, Object obj) {} + public Object Eval_script(String script) {return null;} + public Object Invoke_method(Object obj, String func, Object... args) {return null;} + public Object Invoke_function(String func, Object... args) {return null;} +} diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/Xoscript_env.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/Xoscript_env.java index 58693b1b9..3ca57856b 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/scripts/Xoscript_env.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/Xoscript_env.java @@ -16,7 +16,35 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.addons.htmls.scripts; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*; +import gplx.core.envs.*; +import gplx.langs.htmls.scripts.*; public class Xoscript_env { - public Xoscript_env(Io_url root_dir) {this.root_dir = root_dir;} + private final Gfh_script_engine engine; + public Xoscript_env(Gfh_script_engine engine, Io_url root_dir) { + this.root_dir = root_dir; + this.engine = engine; + } public Io_url Root_dir() {return root_dir;} private final Io_url root_dir; + public void load_script(String file) { + engine.Load_script(Io_url_.new_fil_(Xoscript_env.Resolve_file(Bool_.N, root_dir, file))); + } + public static String Resolve_file(boolean use_file_protocol, Io_url root_dir, String file) { + String rv = file; + + // resolve relative urls; EX: "./a.js" -> "/xowa/wiki/simple.wikipedia.org/bin/script/a.js" + if (String_.Has_at_bgn(rv, "./")) { + // remove "./" + rv = String_.Mid(rv, 2); + + if (use_file_protocol) + rv = root_dir.To_http_file_str() + rv; + else { + // if fsys_url && wnt, replace "\" with "/" + if (Op_sys.Cur().Tid_is_wnt()) + rv = String_.Replace(rv, Op_sys.Lnx.Fsys_dir_spr_str(), Op_sys.Wnt.Fsys_dir_spr_str()); + rv = root_dir.Xto_api() + Op_sys.Cur().Fsys_dir_spr_str() + rv; + } + } + return rv; + } } diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/Xoscript_mgr.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/Xoscript_mgr.java index 7182e438c..06aacaff4 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/scripts/Xoscript_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/Xoscript_mgr.java @@ -18,45 +18,43 @@ along with this program. If not, see . package gplx.xowa.addons.htmls.scripts; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*; import gplx.langs.htmls.scripts.*; import gplx.xowa.wikis.pages.tags.*; -import gplx.xowa.addons.htmls.scripts.apis.*; +import gplx.xowa.addons.htmls.scripts.apis.*; import gplx.xowa.addons.htmls.scripts.xtns.*; public class Xoscript_mgr { private Io_url root_dir; - private Io_url[] script_urls; private int script_urls_len; +// private Io_url[] script_urls; private int script_urls_len; + private Xoscript_xtn_mgr xtn_mgr; public void Init(Xow_wiki wiki) { // check script_dir - this.root_dir = wiki.Fsys_mgr().Root_dir().GenSubDir_nest("bin", "html", "script"); + this.root_dir = wiki.Fsys_mgr().Root_dir().GenSubDir_nest("bin", "any", "script"); if (!Io_mgr.Instance.ExistsDir(root_dir)) return; - - // xowa.boot.js - // find script urls - this.script_urls = Io_mgr.Instance.QueryDir_args(root_dir).FilPath_("*.js").ExecAsUrlAry(); - this.script_urls_len = script_urls.length; - if (script_urls_len == 0) { - Gfo_usr_dlg_.Instance.Warn_many("", "", "xoscript:no '.js' files found; dir=~{0}", root_dir.Raw()); - return; - } + this.xtn_mgr = new Xoscript_xtn_mgr(root_dir); } public void Write(Bry_bfr rv, Xow_wiki wiki, Xoa_page page) { // init this.Init(wiki); - if (script_urls_len == 0) return; + if (xtn_mgr == null) return; - // create engine and load scripts - Gfh_script_engine engine = new Gfh_script_engine__java(); - for (int i = 0; i < script_urls_len; ++i) { - engine.Load_script(script_urls[i]); - } + xtn_mgr.Load_root(); + xtn_mgr.Run(rv, wiki, page); - // call script - Object xowa_script = engine.Get_object("xowa_script"); - Xoscript_env env = new Xoscript_env(root_dir); - Xoscript_page spg = new Xoscript_page(rv, env, new Xoscript_url(page.Wiki().Domain_str(), String_.new_u8(page.Url().Page_bry()))); - engine.Invoke_method(xowa_script, "main", spg); - - // overwrite html - if (spg.Doc().Dirty()) { - rv.Clear(); - rv.Add_str_u8(spg.Doc().Html()); - } +// // create engine and load scripts +// Gfh_script_engine engine = new Gfh_script_engine__luaj(); +// engine.Put_object("xolog", new Xoscript_log()); +// for (int i = 0; i < script_urls_len; ++i) { +// engine.Load_script(script_urls[i]); +// } +// +// // call script +// Xoscript_env env = new Xoscript_env(engine, root_dir); +// engine.Invoke_function("xoscript__init", env); +// +// Xoscript_page spg = new Xoscript_page(rv, env, new Xoscript_url(page.Wiki().Domain_str(), String_.new_u8(page.Url().Page_bry()))); +// engine.Invoke_function("xoscript__page_write_end", spg); +// +// // overwrite html +// if (spg.doc().dirty()) { +// rv.Clear(); +// rv.Add_str_u8(spg.doc().html()); +// } } } diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc.java index d1bcda9de..38271099f 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc.java @@ -19,31 +19,31 @@ package gplx.xowa.addons.htmls.scripts.apis; import gplx.*; import gplx.xowa.*; public class Xoscript_doc { private final Bry_bfr bfr; private final Bry_bfr tmp_bfr = Bry_bfr_.New(); - public Xoscript_doc(Bry_bfr bfr, Xoscript_page page) { + public Xoscript_doc(Bry_bfr bfr, Xoscript_page page_var) { this.bfr = bfr; - this.page = page; - this.head = new Xoscript_doc_head(this); - this.tail = new Xoscript_doc_tail(this); + this.page_var = page_var; + this.head_var = new Xoscript_doc_head(this); + this.tail_var = new Xoscript_doc_tail(this); - head.Reg_marker("", "top", Xoscript_doc_sect_base.Pos__default); - head.Reg_marker("", "bot"); - tail.Reg_marker("", "top", Xoscript_doc_sect_base.Pos__default); + head_var.reg_marker("", "top", Xoscript_doc_sect_base.Pos__default); + head_var.reg_marker("", "bot"); + tail_var.reg_marker("", "top", Xoscript_doc_sect_base.Pos__default); } - public Xoscript_page Page() {return page;} private final Xoscript_page page; - public Xoscript_doc_head Head() {return head;} private final Xoscript_doc_head head; - public Xoscript_doc_tail Tail() {return tail;} private final Xoscript_doc_tail tail; - public String Html() { - if (html == null) { - html = bfr.To_str(); + public Xoscript_page page() {return page_var;} private final Xoscript_page page_var; + public Xoscript_doc_head head() {return head_var;} private final Xoscript_doc_head head_var; + public Xoscript_doc_tail tail() {return tail_var;} private final Xoscript_doc_tail tail_var; + public String html() { + if (html_var == null) { + html_var = bfr.To_str(); } - return html; - } private String html; - public void Html_(String s) { - html = s; + return html_var; + } private String html_var; + public void html(String s) { + html_var = s; html_dirty = true; } - public void Html_by_marker_(byte[] marker, byte[] marker_html) { - byte[] html_bry = Bry_.new_u8(this.Html()); + public void html_by_marker(byte[] marker, byte[] marker_html) { + byte[] html_bry = Bry_.new_u8(this.html()); // find marker, and splice it in int marker_pos = Bry_find_.Find_fwd(html_bry, marker); @@ -53,9 +53,9 @@ public class Xoscript_doc { tmp_bfr.Add_mid(html_bry, marker_pos, html_bry.length); html_bry = tmp_bfr.To_bry_and_clear(); } - Html_(String_.new_u8(html_bry)); + this.html(String_.new_u8(html_bry)); } - public boolean Dirty() { + public boolean dirty() { return html_dirty; } private boolean html_dirty; } diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc_head__tst.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc_head__tst.java index de4091c4c..c9e0573b7 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc_head__tst.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc_head__tst.java @@ -52,23 +52,23 @@ class Xoscript_doc_head__fxt { private Xoscript_doc_sect_base sect; public Xoscript_doc_head__fxt() { Bry_bfr rv = Bry_bfr_.New(); - Xoscript_env env = new Xoscript_env(Io_url_.new_any_("mem/wiki/test_wiki/bin/script/")); + Xoscript_env env = new Xoscript_env(new gplx.langs.htmls.scripts.Gfh_script_engine__noop(), Io_url_.new_any_("mem/wiki/test_wiki/bin/script/")); Xoscript_url url = new Xoscript_url("test_wiki", "test_page"); spg = new Xoscript_page(rv, env, url); } public void Init__sect(String sect_name) { if (String_.Eq(sect_name, "head")) - sect = spg.Doc().Head(); + sect = spg.doc().head(); else if (String_.Eq(sect_name, "tail")) - sect = spg.Doc().Tail(); + sect = spg.doc().tail(); } - public void Exec__doc__html(String html) {spg.Doc().Html_(html);} - public void Exec__reg_marker(String marker, String... pos_ary) {sect.Reg_marker(marker, pos_ary);} - public void Exec__add_js_file(String pos, String file) {sect.Add_js_file(pos, file);} - public void Exec__add_html(String html) {sect.Add_html(html);} - public void Exec__add_html(String pos, String html) {sect.Add_html(pos, html);} - public void Exec__add_tag(String pos, String tag, String body, String... head_atrs) {sect.Add_tag(pos, tag, body, head_atrs);} + public void Exec__doc__html(String html) {spg.doc().html(html);} + public void Exec__reg_marker(String marker, String... pos_ary) {sect.reg_marker(marker, pos_ary);} + public void Exec__add_js_file(String pos, String file) {sect.add_js_file(pos, file);} + public void Exec__add_html(String html) {sect.add_html(html);} + public void Exec__add_html(String pos, String html) {sect.add_html(pos, html);} + public void Exec__add_tag(String pos, String tag, String body, String... head_atrs) {sect.add_tag(pos, tag, body, head_atrs);} public void Test__html(String... expd) { - Gftest.Eq__ary__lines(String_.Concat_lines_nl_skip_last(expd), spg.Doc().Html(), "html"); + Gftest.Eq__ary__lines(String_.Concat_lines_nl_skip_last(expd), spg.doc().html(), "html"); } } diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc_sect_base.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc_sect_base.java index 35ede3dda..7d0fd51b5 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc_sect_base.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_doc_sect_base.java @@ -21,32 +21,33 @@ public abstract class Xoscript_doc_sect_base { private final Hash_adp_bry marker_hash = Hash_adp_bry.cs(); private final Bry_bfr tmp_bfr = Bry_bfr_.New(); public Xoscript_doc_sect_base(Xoscript_doc doc) {this.doc = doc;} - private byte[] Get_marker_by_pos(byte[] pos_bry) { + private byte[] get_marker_by_pos(byte[] pos_bry) { return (byte[])marker_hash.Get_by_or_fail(pos_bry); } - public void Reg_marker(String marker_str, String... pos_ary) { + public void reg_marker(String marker_str, String... pos_ary) { int len = pos_ary.length; byte[] marker_bry = Bry_.new_u8(marker_str); for (int i = 0; i < len; ++i) { marker_hash.Add_if_dupe_use_nth(Bry_.new_u8(pos_ary[i]), marker_bry); } } - public void Add_html(String html) {Add_html(Pos__default, html);} - public void Add_html(String pos_str, String html) {Add_html(Pos__default, Bry_.new_u8(html));} - public void Add_html(String pos_str, byte[] html) { - doc.Html_by_marker_(Get_marker_by_pos(Bry_.new_u8(pos_str)), html); + public void add_html(String html) {add_html(Pos__default, html);} + public void add_html(String pos_str, String html) {add_html(Pos__default, Bry_.new_u8(html));} + public void add_html(String pos_str, byte[] html) { + doc.html_by_marker(get_marker_by_pos(Bry_.new_u8(pos_str)), html); } - public void Add_tag(String pos_str, String tag_str, String body, String... head_atrs) { +// public void add_tag_by_objs(String pos_str, String tag_str, String body, params String[] head_atrs) { + public void add_tag(String pos_str, String tag_str, String body, Object... head_atrs) { // build tag.bgn; EX: '' tmp_bfr.Add_byte(Byte_ascii.Angle_bgn); tmp_bfr.Add_str_u8(tag_str); int head_atrs_len = head_atrs.length; for (int i = 0; i < head_atrs_len; i += 2) { tmp_bfr.Add_byte_space(); - tmp_bfr.Add_str_u8(head_atrs[i]); + tmp_bfr.Add_obj_strict(head_atrs[i]); tmp_bfr.Add_byte_eq(); tmp_bfr.Add_byte_quote(); - tmp_bfr.Add_str_u8(head_atrs[i + 1]); + tmp_bfr.Add_obj_strict(head_atrs[i + 1]); tmp_bfr.Add_byte_quote(); } tmp_bfr.Add_byte(Byte_ascii.Angle_end); @@ -60,22 +61,23 @@ public abstract class Xoscript_doc_sect_base { tmp_bfr.Add_byte(Byte_ascii.Angle_end); tmp_bfr.Add_byte_nl(); - Add_html(pos_str, tmp_bfr.To_bry_and_clear()); + add_html(pos_str, tmp_bfr.To_bry_and_clear()); } - public void Add_js_file(String file_str) {Add_js_file(file_str, Pos__default);} - public void Add_js_file(String pos_str, String file_str) { - // resolve file - file_str = Resolve_file(file_str, doc.Page().Env().Root_dir()); - - // build script tag - Add_tag(pos_str, "script", Body__empty, "src", file_str, "type", "text/javascript"); + public void add_js_file(String file_str) {add_js_file(Pos__default, file_str);} + public void add_js_file(String pos_str, String file_str) { + add_tag(pos_str, "script", Body__empty, "src", Xoscript_env.Resolve_file(Bool_.Y, doc.page().env().Root_dir(), file_str), "type", "text/javascript"); } - private String Resolve_file(String file, Io_url root_dir) { - String rv = file; - // resolve relative urls; EX: "./a.js" -> "/xowa/wiki/simple.wikipedia.org/bin/script/a.js" - if (String_.Has_at_bgn(file, "./")) - rv = String_.Replace(file, "./", root_dir.To_http_file_str()); - return rv; + public void add_js_code(String code_str) {add_js_file(Pos__default, code_str);} + public void add_js_code(String pos_str, String code_str) { + add_tag(pos_str, "script", code_str, "type", "text/javascript"); + } + public void add_css_file(String file_str) {add_js_file(Pos__default, file_str);} + public void add_css_file(String pos_str, String file_str) { + add_tag(pos_str, "link", Body__empty, "rel", "stylesheet", "href", Xoscript_env.Resolve_file(Bool_.Y, doc.page().env().Root_dir(), file_str), "type", "text/css"); + } + public void add_css_code(String code_str) {add_css_code(Pos__default, code_str);} + public void add_css_code(String pos_str, String code_str) { + add_tag(pos_str, "style", code_str, "type", "text/css"); } public static final String Pos__default = "default", Body__empty = ""; } diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_log.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_log.java new file mode 100644 index 000000000..f89665bd0 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_log.java @@ -0,0 +1,23 @@ +/* +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 . +*/ +package gplx.xowa.addons.htmls.scripts.apis; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*; import gplx.xowa.addons.htmls.scripts.*; +public class Xoscript_log { + public void log(String... v) { + Gfo_usr_dlg_.Instance.Log_many("", "", String_.Concat_with_str(" ", v)); + } +} \ No newline at end of file diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_page.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_page.java index 7709a1050..a043641dc 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_page.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_page.java @@ -17,12 +17,12 @@ along with this program. If not, see . */ package gplx.xowa.addons.htmls.scripts.apis; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*; import gplx.xowa.addons.htmls.scripts.*; public class Xoscript_page { - public Xoscript_page(Bry_bfr rv, Xoscript_env env, Xoscript_url url) { - this.env = env; - this.url = url; - this.doc = new Xoscript_doc(rv, this); + public Xoscript_page(Bry_bfr rv, Xoscript_env env_var, Xoscript_url url_var) { + this.env_var = env_var; + this.url_var = url_var; + this.doc_var = new Xoscript_doc(rv, this); } - public Xoscript_env Env() {return env;} private final Xoscript_env env; - public Xoscript_url Url() {return url;} private final Xoscript_url url; - public Xoscript_doc Doc() {return doc;} private final Xoscript_doc doc; + public Xoscript_env env() {return env_var;} private final Xoscript_env env_var; + public Xoscript_url url() {return url_var;} private final Xoscript_url url_var; + public Xoscript_doc doc() {return doc_var;} private final Xoscript_doc doc_var; } diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_url.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_url.java index ded36502e..e27bcbfdc 100644 --- a/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_url.java +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/apis/Xoscript_url.java @@ -17,7 +17,7 @@ along with this program. If not, see . */ package gplx.xowa.addons.htmls.scripts.apis; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*; import gplx.xowa.addons.htmls.scripts.*; public class Xoscript_url { - public Xoscript_url(String wiki_name, String page_name) {this.wiki_name = wiki_name; this.page_name = page_name;} - public String Wiki_name() {return wiki_name;} private final String wiki_name; - public String Page_name() {return page_name;} private final String page_name; + public Xoscript_url(String wiki_name_var, String page_name_var) {this.wiki_name_var = wiki_name_var; this.page_name_var = page_name_var;} + public String wiki_name() {return wiki_name_var;} private final String wiki_name_var; + public String page_name() {return page_name_var;} private final String page_name_var; } diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/xtns/Xoscript_xtn_itm.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/xtns/Xoscript_xtn_itm.java new file mode 100644 index 000000000..b0ff739d5 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/xtns/Xoscript_xtn_itm.java @@ -0,0 +1,29 @@ +/* +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 . +*/ +package gplx.xowa.addons.htmls.scripts.xtns; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*; import gplx.xowa.addons.htmls.scripts.*; +import gplx.langs.htmls.scripts.*; +public class Xoscript_xtn_itm { + public Xoscript_xtn_itm(String key, Io_url url, Gfh_script_engine engine) { + this.key = key; + this.url = url; + this.engine = engine; + } + public String Key() {return key;} private final String key; + public Io_url Url() {return url;} private final Io_url url; + public Gfh_script_engine Engine() {return engine;} private final Gfh_script_engine engine; +} diff --git a/400_xowa/src/gplx/xowa/addons/htmls/scripts/xtns/Xoscript_xtn_mgr.java b/400_xowa/src/gplx/xowa/addons/htmls/scripts/xtns/Xoscript_xtn_mgr.java new file mode 100644 index 000000000..4899ae8e4 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/htmls/scripts/xtns/Xoscript_xtn_mgr.java @@ -0,0 +1,67 @@ +/* +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 . +*/ +package gplx.xowa.addons.htmls.scripts.xtns; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.htmls.*; import gplx.xowa.addons.htmls.scripts.*; +import gplx.langs.htmls.scripts.*; +import gplx.xowa.addons.htmls.scripts.apis.*; +public class Xoscript_xtn_mgr { + private Xoscript_xtn_itm root_itm; + private final Io_url root_dir; + private final Ordered_hash hash = Ordered_hash_.New(); + public Xoscript_xtn_mgr(Io_url root_dir) { + this.root_dir = root_dir; + } + public void reg_xtn(String key, String file) { + Io_url url = Io_url_.new_fil_(Xoscript_env.Resolve_file(Bool_.N, root_dir, file)); + Xoscript_xtn_itm itm = new Xoscript_xtn_itm(key, url, Gfh_script_engine_.New_by_ext(url.Ext())); + hash.Add(key, itm); + } + public void Load_root() { + Io_url[] root_urls = Io_mgr.Instance.QueryDir_args(root_dir).ExecAsUrlAry(); + int root_urls_len = root_urls.length; + for (int i = 0; i < root_urls_len; ++i) { + Io_url root_url = root_urls[0]; + String root_name_and_ext = root_url.NameAndExt(); + if (String_.EqAny(root_name_and_ext, "xowa.script.main.js", "xowa.script.main.lua")) { + this.root_itm = new Xoscript_xtn_itm("xowa.root", root_url, Gfh_script_engine_.New_by_ext(root_url.Ext())); + break; + } + } + root_itm.Engine().Load_script(root_itm.Url()); + root_itm.Engine().Invoke_function("xoscript__main", this); + } + public void Run(Bry_bfr rv, Xow_wiki wiki, Xoa_page page) { + int len = hash.Len(); + Xoscript_log log = new Xoscript_log(); + for (int i = 0; i < len; ++i) { + Xoscript_xtn_itm itm = (Xoscript_xtn_itm)hash.Get_at(i); + Gfh_script_engine engine = (Gfh_script_engine)itm.Engine(); + Xoscript_env env = new Xoscript_env(engine, itm.Url().OwnerDir()); + Xoscript_page spg = new Xoscript_page(rv, env, new Xoscript_url(page.Wiki().Domain_str(), String_.new_u8(page.Url().Page_bry()))); + engine.Put_object("xolog", log); + engine.Load_script(itm.Url()); + engine.Invoke_function("xoscript__init", env); + engine.Invoke_function("xoscript__page_write_end", spg); + + // overwrite html + if (spg.doc().dirty()) { + rv.Clear(); + rv.Add_str_u8(spg.doc().html()); + } + } + } +} diff --git a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java index 1d1b3485f..edbd63d52 100644 --- a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java +++ b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java @@ -57,13 +57,10 @@ public class Xoh_page_wtr_wkr { hctx = Xoh_wtr_ctx.Basic; Write_body(page_bfr, ctx, hctx, page); Write_page_by_tid(ctx, hctx, view_mode, rv, fmtr, page_bfr.To_bry_and_rls()); + new gplx.xowa.addons.htmls.scripts.Xoscript_mgr().Write(rv, wiki, page); if (page_mode == Xopg_page_.Tid_html) // if html, write page again, but wrap it in html skin this time Write_page_by_tid(ctx, hctx, page_mode, rv, mgr.Page_html_fmtr(), Gfh_utl.Escape_html_as_bry(rv.To_bry_and_clear())); wdata_lang_wtr.Page_(null); - - if (page_mode == Xopg_page_.Tid_read) { // EXPERIMENTAL - new gplx.xowa.addons.htmls.scripts.Xoscript_mgr().Write(rv, wiki, page); - } } } else