From 02d39e23034aab997efc3ba8d6298c1ffd248b36 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 16 Jan 2026 21:47:04 +0100 Subject: [PATCH] first commit --- .gitignore | 39 +++ .idea/.gitignore | 10 + .idea/copilot.data.migration.agent.xml | 6 + .idea/encodings.xml | 7 + .idea/misc.xml | 18 ++ .idea/vcs.xml | 6 + pom.xml | 135 ++++++++++ .../luascript/dom/jsoup/JsoupDomHost.java | 232 ++++++++++++++++++ .../luascript/events/JavaToLua.java | 47 ++++ .../luascript/events/LuaEventDispatcher.java | 100 ++++++++ .../luascript/events/UiEvent.java | 33 +++ .../luascript/events/UiEventRegistry.java | 18 ++ .../luascript/hosts/ConsoleHost.java | 21 ++ .../luascript/hosts/DomHost.java | 150 +++++++++++ .../luascript/hosts/EventHost.java | 37 +++ .../luascript/hosts/HostServices.java | 121 +++++++++ .../luascript/hosts/ResourceHost.java | 16 ++ .../luascript/hosts/UiHost.java | 59 +++++ .../luascript/runtime/LuaDomBinder.java | 52 ++++ .../luascript/runtime/LuaEventRouter.java | 30 +++ .../luascript/runtime/LuaRuntime.java | 64 +++++ .../luascript/runtime/LuaScriptBootstrap.java | 69 ++++++ .../luascript/runtime/LuaScriptExecutor.java | 28 +++ .../security/LuaExecutionPolicy.java | 29 +++ .../security/LuaSecurityManager.java | 143 +++++++++++ .../luascript/tables/DomTable.java | 179 ++++++++++++++ .../luascript/tables/EventsTable.java | 87 +++++++ .../luascript/tables/UiTable.java | 225 +++++++++++++++++ .../tables/console/ConsoleLogTable.java | 42 ++++ .../console/ConsoleStacktraceTable.java | 34 +++ .../tables/console/ConsoleTable.java | 19 ++ .../luascript/utils/LuaGlobalsFactory.java | 137 +++++++++++ .../luascript/utils/ScriptTable.java | 77 ++++++ src/main/resources/license/jsoup/jsoup | 13 + .../resources/license/lombok/projectlombok | 104 ++++++++ src/main/resources/license/luaj/mit | 21 ++ src/main/resources/license/oapl | 1 + .../resources/license/unlegitlibrary/GNUv3 | 210 ++++++++++++++++ .../resources/license/unlegitlibrary/oapl | 1 + src/test/java/Main.java | 38 +++ 40 files changed, 2658 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/copilot.data.migration.agent.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 pom.xml create mode 100644 src/main/java/org/openautonomousconnection/luascript/dom/jsoup/JsoupDomHost.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/events/JavaToLua.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/events/LuaEventDispatcher.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/events/UiEvent.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/events/UiEventRegistry.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/hosts/ConsoleHost.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/hosts/DomHost.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/hosts/EventHost.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/hosts/HostServices.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/hosts/ResourceHost.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/hosts/UiHost.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/runtime/LuaDomBinder.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/runtime/LuaEventRouter.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/runtime/LuaRuntime.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/runtime/LuaScriptBootstrap.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/runtime/LuaScriptExecutor.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/security/LuaExecutionPolicy.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/security/LuaSecurityManager.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/tables/DomTable.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/tables/EventsTable.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/tables/UiTable.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/tables/console/ConsoleLogTable.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/tables/console/ConsoleStacktraceTable.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/tables/console/ConsoleTable.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/utils/LuaGlobalsFactory.java create mode 100644 src/main/java/org/openautonomousconnection/luascript/utils/ScriptTable.java create mode 100644 src/main/resources/license/jsoup/jsoup create mode 100644 src/main/resources/license/lombok/projectlombok create mode 100644 src/main/resources/license/luaj/mit create mode 100644 src/main/resources/license/oapl create mode 100644 src/main/resources/license/unlegitlibrary/GNUv3 create mode 100644 src/main/resources/license/unlegitlibrary/oapl create mode 100644 src/test/java/Main.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..480bdf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +.kotlin + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml new file mode 100644 index 0000000..4ea72a9 --- /dev/null +++ b/.idea/copilot.data.migration.agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..f1e8302 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..0613ce1 --- /dev/null +++ b/pom.xml @@ -0,0 +1,135 @@ + + + 4.0.0 + + org.openautonomousconnection + LuaScript + 1.0-BETA.1.0 + + + Open Autonomous Connection + https://open-autonomous-connection.org/ + + https://open-autonomous-connection.org/ + The default DNS-Server + + + 23 + 23 + UTF-8 + + + + + UnlegitDqrk + Open Autonomous Connection + https://open-autonomous-connection.org/ + https://unlegitdqrk.dev/ + + Owner + Head Developer + + + + Maple + Open Autonomous Connection + https://open-autonomous-connection.org/ + https://niumaple.carrd.co/ + + Owner + Head Developer + + + + + + Issue Tracker + https://repo.open-autonomous-connection.org/open-autonomous-connection/LuaScript/issues + + + + + Open Autonomous Public License (OAPL) + https://open-autonomous-connection.org/license.html + + + GNU General Public License v3.0 + https://www.gnu.org/licenses/gpl-3.0.html + + Default license: Applies to all users and projects unless an explicit alternative license has been granted. + + + + projectlombok + https://github.com/projectlombok/lombok?tab=License-1-ov-file + + + + + + oac + https://repo.open-autonomous-connection.org/api/packages/open-autonomous-connection/maven + + true + + + + + + + dev.unlegitdqrk + unlegitlibrary + 1.6.9 + + + org.luaj + luaj-jse + 3.0.1 + + + org.projectlombok + lombok + 1.18.38 + provided + + + org.jsoup + jsoup + 1.22.1 + compile + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.3.0 + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.3 + + + attach-javadocs + + jar + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/openautonomousconnection/luascript/dom/jsoup/JsoupDomHost.java b/src/main/java/org/openautonomousconnection/luascript/dom/jsoup/JsoupDomHost.java new file mode 100644 index 0000000..5a2121e --- /dev/null +++ b/src/main/java/org/openautonomousconnection/luascript/dom/jsoup/JsoupDomHost.java @@ -0,0 +1,232 @@ +package org.openautonomousconnection.luascript.dom.jsoup; + +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.openautonomousconnection.luascript.hosts.DomHost; + +import java.util.*; +import java.util.concurrent.atomic.AtomicLong; + +/** + * DomHost implementation backed by a jsoup Document. + * + *

Element identity is the HTML attribute {@code id}. This implementation auto-assigns ids to all + * elements that do not have one, making them addressable.

+ */ +public final class JsoupDomHost implements DomHost { + + private final Document document; + private final AtomicLong autoIdSeq = new AtomicLong(1); + + public JsoupDomHost(Document document) { + this.document = Objects.requireNonNull(document, "document"); + ensureAllElementsHaveId(); + } + + public Document document() { + return document; + } + + public void ensureAllElementsHaveId() { + Elements all = document.getAllElements(); + for (Element el : all) { + if (el == document) continue; + if (!hasUsableId(el)) { + el.attr("id", generateUniqueId()); + } + } + } + + @Override + public List getAllElementIds() { + Elements all = document.getAllElements(); + List ids = new ArrayList<>(all.size()); + for (Element el : all) { + if (el == document) continue; + String id = el.id(); + if (id != null && !id.isBlank()) ids.add(id); + } + return ids; + } + + @Override + public Map getAttributes(String elementId) { + Element el = byId(elementId); + Map out = new LinkedHashMap<>(); + el.attributes().forEach(a -> out.put(a.getKey(), a.getValue())); + return out; + } + + @Override + public String getTagName(String elementId) { + return byId(elementId).tagName().toLowerCase(Locale.ROOT); + } + + @Override + public String getTextContent(String elementId) { + return byId(elementId).text(); + } + + @Override + public void setTextContent(String elementId, String text) { + byId(elementId).text(text == null ? "" : text); + } + + @Override + public String getAttribute(String elementId, String name) { + Element el = byId(elementId); + String n = normalizeAttr(name); + if (!el.hasAttr(n)) return null; + return el.attr(n); + } + + @Override + public void setAttribute(String elementId, String name, String value) { + Element el = byId(elementId); + el.attr(normalizeAttr(name), value == null ? "" : value); + } + + @Override + public void removeAttribute(String elementId, String name) { + byId(elementId).removeAttr(normalizeAttr(name)); + } + + @Override + public String getParentId(String elementId) { + Element el = byId(elementId); + Element p = el.parent(); + if (p == null || p == document) return null; + if (!hasUsableId(p)) p.attr("id", generateUniqueId()); + return p.id(); + } + + @Override + public List getChildrenIds(String elementId) { + Element el = byId(elementId); + List out = new ArrayList<>(); + for (Element child : el.children()) { + if (!hasUsableId(child)) child.attr("id", generateUniqueId()); + out.add(child.id()); + } + return out; + } + + @Override + public String createElement(String tagName, String requestedId) { + String tag = normalizeTag(tagName); + String id = normalizeOrGenerateId(requestedId); + if (exists(id)) throw new IllegalArgumentException("Element id already exists: " + id); + + Element el = document.createElement(tag); + el.attr("id", id); + return id; + } + + @Override + public void removeElement(String elementId) { + byId(elementId).remove(); + } + + @Override + public void appendChild(String parentId, String childId) { + Element parent = byId(parentId); + Element child = byId(childId); + child.remove(); + parent.appendChild(child); + } + + @Override + public void insertBefore(String parentId, String childId, String beforeChildId) { + Element parent = byId(parentId); + Element child = byId(childId); + Element before = byId(beforeChildId); + + if (before.parent() == null || !Objects.equals(before.parent(), parent)) { + throw new IllegalArgumentException("beforeChildId is not a direct child of parentId: " + beforeChildId); + } + + child.remove(); + before.before(child); + } + + @Override + public boolean exists(String id) { + if (id == null || id.isBlank()) return false; + return document.getElementById(id) != null; + } + + @Override + public List queryByTag(String tagName) { + String tag = normalizeTag(tagName); + Elements els = document.getElementsByTag(tag); + + List out = new ArrayList<>(els.size()); + for (Element el : els) { + if (!hasUsableId(el)) el.attr("id", generateUniqueId()); + out.add(el.id()); + } + return out; + } + + @Override + public List queryByClass(String className) { + String cls = normalizeCssIdent(className); + Elements els = document.getElementsByClass(cls); + + List out = new ArrayList<>(els.size()); + for (Element el : els) { + if (!hasUsableId(el)) el.attr("id", generateUniqueId()); + out.add(el.id()); + } + return out; + } + + private Element byId(String id) { + if (id == null || id.isBlank()) throw new IllegalArgumentException("elementId is blank"); + Element el = document.getElementById(id); + if (el == null) throw new IllegalArgumentException("Unknown element id: " + id); + return el; + } + + private boolean hasUsableId(Element el) { + String id = el.id(); + return id != null && !id.isBlank(); + } + + private String generateUniqueId() { + while (true) { + String id = "__auto_" + autoIdSeq.getAndIncrement(); + if (!exists(id)) return id; + } + } + + private String normalizeTag(String tagName) { + if (tagName == null) throw new IllegalArgumentException("tagName is null"); + String t = tagName.trim().toLowerCase(Locale.ROOT); + if (t.isEmpty()) throw new IllegalArgumentException("tagName is empty"); + return t; + } + + private String normalizeAttr(String name) { + if (name == null) throw new IllegalArgumentException("attribute name is null"); + String n = name.trim(); + if (n.isEmpty()) throw new IllegalArgumentException("attribute name is empty"); + return n; + } + + private String normalizeCssIdent(String s) { + if (s == null) throw new IllegalArgumentException("identifier is null"); + String v = s.trim(); + if (v.isEmpty()) throw new IllegalArgumentException("identifier is empty"); + return v; + } + + private String normalizeOrGenerateId(String requestedId) { + if (requestedId != null) { + String id = requestedId.trim(); + if (!id.isEmpty()) return id; + } + return generateUniqueId(); + } +} diff --git a/src/main/java/org/openautonomousconnection/luascript/events/JavaToLua.java b/src/main/java/org/openautonomousconnection/luascript/events/JavaToLua.java new file mode 100644 index 0000000..dbd0312 --- /dev/null +++ b/src/main/java/org/openautonomousconnection/luascript/events/JavaToLua.java @@ -0,0 +1,47 @@ +package org.openautonomousconnection.luascript.events; + +import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; + +import java.util.List; +import java.util.Map; + +/** + * Coerces common Java values into Lua values. + */ +public final class JavaToLua { + + private JavaToLua() { } + + public static LuaValue coerce(Object v) { + if (v == null) return LuaValue.NIL; + if (v instanceof LuaValue lv) return lv; + if (v instanceof String s) return LuaValue.valueOf(s); + if (v instanceof Boolean b) return LuaValue.valueOf(b); + if (v instanceof Integer i) return LuaValue.valueOf(i); + if (v instanceof Long l) return LuaValue.valueOf(l); + if (v instanceof Float f) return LuaValue.valueOf(f); + if (v instanceof Double d) return LuaValue.valueOf(d); + + if (v instanceof Map m) { + LuaTable t = new LuaTable(); + for (Map.Entry e : m.entrySet()) { + Object k = e.getKey(); + if (k == null) continue; + t.set(String.valueOf(k), coerce(e.getValue())); + } + return t; + } + + if (v instanceof List list) { + LuaTable t = new LuaTable(); + int i = 1; + for (Object o : list) { + t.set(i++, coerce(o)); + } + return t; + } + + return LuaValue.valueOf(String.valueOf(v)); + } +} diff --git a/src/main/java/org/openautonomousconnection/luascript/events/LuaEventDispatcher.java b/src/main/java/org/openautonomousconnection/luascript/events/LuaEventDispatcher.java new file mode 100644 index 0000000..7d49573 --- /dev/null +++ b/src/main/java/org/openautonomousconnection/luascript/events/LuaEventDispatcher.java @@ -0,0 +1,100 @@ +package org.openautonomousconnection.luascript.events; + +import org.luaj.vm2.Globals; +import org.luaj.vm2.LuaError; +import org.luaj.vm2.LuaFunction; +import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; +import org.luaj.vm2.Varargs; +import org.openautonomousconnection.luascript.security.LuaExecutionPolicy; +import org.openautonomousconnection.luascript.security.LuaSecurityManager; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Stores bindings (elementId,eventName -> handlerPath) and dispatches events into Lua. + */ +public final class LuaEventDispatcher { + + private final Globals globals; + private final LuaSecurityManager securityManager; + private final LuaExecutionPolicy policy; + private final ConcurrentHashMap bindings = new ConcurrentHashMap<>(); + + public LuaEventDispatcher(Globals globals, LuaSecurityManager securityManager, LuaExecutionPolicy policy) { + this.globals = Objects.requireNonNull(globals, "globals"); + this.securityManager = Objects.requireNonNull(securityManager, "securityManager"); + this.policy = Objects.requireNonNull(policy, "policy"); + } + + public void bind(String elementId, String eventName, String handlerPath) { + Objects.requireNonNull(elementId, "elementId"); + Objects.requireNonNull(eventName, "eventName"); + Objects.requireNonNull(handlerPath, "handlerPath"); + + String k = key(elementId, UiEventRegistry.normalize(eventName)); + bindings.put(k, handlerPath); + } + + public void unbind(String elementId, String eventName) { + Objects.requireNonNull(elementId, "elementId"); + Objects.requireNonNull(eventName, "eventName"); + bindings.remove(key(elementId, UiEventRegistry.normalize(eventName))); + } + + public boolean hasBinding(String elementId, String eventName) { + return bindings.containsKey(key(elementId, UiEventRegistry.normalize(eventName))); + } + + public boolean dispatch(UiEvent event) { + Objects.requireNonNull(event, "event"); + + String k = key(event.targetId(), UiEventRegistry.normalize(event.type())); + String handlerPath = bindings.get(k); + if (handlerPath == null) return false; + + LuaValue fn = resolvePath(handlerPath); + if (fn.isnil() || !fn.isfunction()) { + throw new LuaError("Handler is not a function: " + handlerPath); + } + + LuaValue eventTable = toLuaEvent(event); + Varargs args = LuaValue.varargsOf(new LuaValue[]{eventTable}); + + securityManager.callGuarded(globals, (LuaFunction) fn, args, policy); + return true; + } + + private LuaValue resolvePath(String path) { + String[] parts = path.split("\\."); + LuaValue cur = globals; + for (String p : parts) { + String key = p.trim(); + if (key.isEmpty()) throw new LuaError("Invalid handler path: " + path); + cur = cur.get(key); + if (cur.isnil()) return LuaValue.NIL; + } + return cur; + } + + private LuaValue toLuaEvent(UiEvent event) { + LuaTable t = new LuaTable(); + t.set("target", LuaValue.valueOf(event.targetId())); + t.set("type", LuaValue.valueOf(event.type())); + + LuaTable d = new LuaTable(); + for (Map.Entry e : event.data().entrySet()) { + String k = e.getKey(); + if (k == null) continue; + d.set(k, JavaToLua.coerce(e.getValue())); + } + t.set("data", d); + return t; + } + + private static String key(String elementId, String event) { + return elementId + "\n" + event; + } +} diff --git a/src/main/java/org/openautonomousconnection/luascript/events/UiEvent.java b/src/main/java/org/openautonomousconnection/luascript/events/UiEvent.java new file mode 100644 index 0000000..1d889a1 --- /dev/null +++ b/src/main/java/org/openautonomousconnection/luascript/events/UiEvent.java @@ -0,0 +1,33 @@ +package org.openautonomousconnection.luascript.events; + +import java.util.Collections; +import java.util.Map; +import java.util.Objects; + +/** + * Event passed from host into Lua. + */ +public final class UiEvent { + + private final String targetId; + private final String type; + private final Map data; + + public UiEvent(String targetId, String type, Map data) { + this.targetId = Objects.requireNonNull(targetId, "targetId"); + this.type = Objects.requireNonNull(type, "type"); + this.data = (data == null) ? Collections.emptyMap() : Collections.unmodifiableMap(data); + } + + public String targetId() { + return targetId; + } + + public String type() { + return type; + } + + public Map data() { + return data; + } +} \ No newline at end of file diff --git a/src/main/java/org/openautonomousconnection/luascript/events/UiEventRegistry.java b/src/main/java/org/openautonomousconnection/luascript/events/UiEventRegistry.java new file mode 100644 index 0000000..ac3acaf --- /dev/null +++ b/src/main/java/org/openautonomousconnection/luascript/events/UiEventRegistry.java @@ -0,0 +1,18 @@ +package org.openautonomousconnection.luascript.events; + +import java.util.Locale; + +/** + * Normalizes event names. + */ +public final class UiEventRegistry { + + private UiEventRegistry() { } + + public static String normalize(String eventName) { + if (eventName == null) throw new IllegalArgumentException("eventName is null"); + String e = eventName.trim().toLowerCase(Locale.ROOT); + if (e.isEmpty()) throw new IllegalArgumentException("eventName is empty"); + return e; + } +} diff --git a/src/main/java/org/openautonomousconnection/luascript/hosts/ConsoleHost.java b/src/main/java/org/openautonomousconnection/luascript/hosts/ConsoleHost.java new file mode 100644 index 0000000..30e9be9 --- /dev/null +++ b/src/main/java/org/openautonomousconnection/luascript/hosts/ConsoleHost.java @@ -0,0 +1,21 @@ +package org.openautonomousconnection.luascript.hosts; + +/** + * Host capability for console logging. + */ +public interface ConsoleHost { + /** @param message message */ + void info(String message); + + /** @param message message */ + void log(String message); + + /** @param message message */ + void warn(String message); + + /** @param message message */ + void error(String message); + + /** @param message message */ + void exception(String message); +} diff --git a/src/main/java/org/openautonomousconnection/luascript/hosts/DomHost.java b/src/main/java/org/openautonomousconnection/luascript/hosts/DomHost.java new file mode 100644 index 0000000..9ecd3e0 --- /dev/null +++ b/src/main/java/org/openautonomousconnection/luascript/hosts/DomHost.java @@ -0,0 +1,150 @@ +package org.openautonomousconnection.luascript.hosts; + +import java.util.List; +import java.util.Map; + +/** + * Host capability that exposes a DOM-like API. + * + *

Element identity is the (stable) element id.

+ */ +public interface DomHost { + + /** + * Returns all element ids known to the renderer (must be stable). + * + * @return list of element ids + */ + List getAllElementIds(); + + /** + * Returns all attributes for the given element id. + * + * @param elementId element id + * @return attributes map (attributeName -> attributeValue) + */ + Map getAttributes(String elementId); + + /** + * Returns the tag name of the element (lowercase recommended), e.g. "script", "button". + * + * @param elementId element id + * @return tag name + */ + String getTagName(String elementId); + + /** + * Returns the text content of an element (used for inline