list : l)
-// for(String s : list)
-// System.out.println("s: " + s);
-
- System.out.println();
- System.out.println(this.parse());
-
- }
-
- public HTML parse() {
- HTMLInterpreter interpreter = new HTMLInterpreter(this, new PyScriptInterpreter(this));
-
- for(String s : this.tokens)
- interpreter.nextState(s);
-
-
- return interpreter.getResult();
- }
-
- public Class extends HTMLElement> getByTagname(String tagName) {
- tagName = tagName.toLowerCase();
-
- Class extends HTMLElement> res = this.tagManager.tags.get(tagName);
-
- return Objects.requireNonNullElse(res, CustomHTMLElement.class);
- }
-
- public static void main(String[] args) {
-
- Parser parser = new Parser("""
-
-
-
- a paragraph in color! test
-
-
-
-
-
-
-
-
-
-
- """, new TagManager());
- }
-
-
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/SwingRendererPanel.java b/src/main/java/org/openautonomousconnection/htmlparser/SwingRendererPanel.java
new file mode 100644
index 0000000..c7a7a45
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/SwingRendererPanel.java
@@ -0,0 +1,63 @@
+package org.openautonomousconnection.htmlparser;
+
+import org.openautonomousconnection.htmlparser.css.ComputedStyle;
+import org.openautonomousconnection.htmlparser.css.LayoutBox;
+import org.openautonomousconnection.htmlparser.css.LayoutTree;
+import org.openautonomousconnection.htmlparser.css.StyleEngine;
+import org.openautonomousconnection.htmlparser.dom.Element;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Map;
+
+public final class SwingRendererPanel extends JPanel {
+
+ private LayoutTree layout;
+ private Map styles;
+
+ public void setScene(LayoutTree layout, Map styles) {
+ this.layout = layout;
+ this.styles = styles;
+ repaint();
+ }
+
+ @Override
+ protected void paintComponent(Graphics g0) {
+ super.paintComponent(g0);
+ if (layout == null) return;
+
+ Graphics2D g = (Graphics2D) g0.create();
+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+ // background
+ g.setColor(new Color(0x0f111a));
+ g.fillRect(0, 0, getWidth(), getHeight());
+
+ for (LayoutBox b : layout.boxes) {
+
+ if (b.isText()) {
+ g.setColor(new Color(0xe5e7eb));
+ g.drawString(b.text.getText(), b.x, b.y + 16);
+ continue;
+ }
+
+ Element el = b.element;
+ ComputedStyle st = styles != null ? styles.get(el) : null;
+
+ // background
+ String bg = st != null ? st.get(StyleEngine.BACKGROUND) : null;
+ if (bg != null && bg.startsWith("#") && bg.length() == 7) {
+ try {
+ g.setColor(Color.decode(bg));
+ g.fillRect(b.x, b.y, b.w, b.h);
+ } catch (Exception ignored) {}
+ }
+
+ // TODO optional debug outline
+ //g.setColor(new Color(0x2a2f45));
+ //g.drawRect(b.x, b.y, b.w, b.h);
+ }
+
+ g.dispose();
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/TagManager.java b/src/main/java/org/openautonomousconnection/htmlparser/TagManager.java
deleted file mode 100644
index 6fab1df..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/TagManager.java
+++ /dev/null
@@ -1,117 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser;
-
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-import org.openautonomousconnection.htmlparser.html.NoContent;
-import org.openautonomousconnection.htmlparser.html.body.HTMLBody;
-import org.openautonomousconnection.htmlparser.html.body.buttons.HTMLButton;
-import org.openautonomousconnection.htmlparser.html.body.form.HTMLForm;
-import org.openautonomousconnection.htmlparser.html.body.form.HTMLInput;
-import org.openautonomousconnection.htmlparser.html.body.form.HTMLLabel;
-import org.openautonomousconnection.htmlparser.html.body.link.HTMLArea;
-import org.openautonomousconnection.htmlparser.html.body.link.HTMLHyperlink;
-import org.openautonomousconnection.htmlparser.html.body.link.HTMLImage;
-import org.openautonomousconnection.htmlparser.html.body.misc.HTMLBreak;
-import org.openautonomousconnection.htmlparser.html.body.misc.HTMLComment;
-import org.openautonomousconnection.htmlparser.html.body.misc.HTMLDiv;
-import org.openautonomousconnection.htmlparser.html.body.misc.HTMLScript;
-import org.openautonomousconnection.htmlparser.html.body.texts.HTMLAbbreviation;
-import org.openautonomousconnection.htmlparser.html.body.texts.heading.HTMLHeading;
-import org.openautonomousconnection.htmlparser.html.body.texts.heading.HeadingType;
-import org.openautonomousconnection.htmlparser.html.body.texts.text.HTMLText;
-import org.openautonomousconnection.htmlparser.html.body.texts.text.TextType;
-import org.openautonomousconnection.htmlparser.html.header.HTMLHeader;
-import org.openautonomousconnection.htmlparser.html.header.HTMLTitle;
-
-import java.util.*;
-
-public class TagManager {
- public Map> tags;
-
- public void putTag(Class extends HTMLElement> tag) {
- try {
- this.tags.put((String) tag.getDeclaredField("TAG").get(tag), tag);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-
- public boolean isTag(String tagName) {
- return this.tags.containsKey(tagName);
- }
-
- public boolean isTagSpaced(String tagName) {
- return this.isTag(tagName.replaceAll("\\s", ""));
- }
-
-// public boolean hasClosingTag(String tagName) {
-// try {
-// return (boolean) this.tags.get(tagName).getField("CLOSEABLE").get(null);
-// } catch (NoSuchFieldException | IllegalAccessException e) {
-// throw new RuntimeException(e);
-// }
-// }
-
- public boolean hasText(String tagName) {
- if(!this.isTag(tagName))
- return false;
-
- return !this.tags.get(tagName).isAnnotationPresent(NoContent.class);
- }
-
- public TreeSet couldBe(String string) {
- TreeSet result = new TreeSet<>();
-
- for(String tagName : tags.keySet())
- if(tagName.contains(string))
- result.add(new ParseResult(string, tagName));
-
- return result;
- }
-
- public TagManager() {
- // Map default tags
-
- this.tags = new HashMap<>();
-
- // buttons
- this.putTag(HTMLButton.class);
-
- // forms
- this.putTag(HTMLForm.class);
- this.putTag(HTMLInput.class);
- this.putTag(HTMLLabel.class);
-
- // links
- this.putTag(HTMLArea.class);
- this.putTag(HTMLHyperlink.class);
- this.putTag(HTMLImage.class);
-
- // misc
- this.putTag(HTMLBreak.class);
- this.putTag(HTMLDiv.class);
- this.putTag(HTMLScript.class);
- this.putTag(HTMLComment.class);
-
- // headings
- for(HeadingType type : HeadingType.values())
- this.tags.put(type.getTag(), HTMLHeading.class);
-
- // texts
- for(TextType type : TextType.values())
- this.tags.put(type.getTag(), HTMLText.class);
-
- this.putTag(HTMLAbbreviation.class);
-
- // headers
- this.putTag(HTMLHeader.class);
- this.putTag(HTMLTitle.class);
-
- // main elements
- this.putTag(HTMLBody.class);
- this.putTag(HTMLHeader.class);
- this.putTag(HTMLImage.class);
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/ComputedStyle.java b/src/main/java/org/openautonomousconnection/htmlparser/css/ComputedStyle.java
new file mode 100644
index 0000000..64973fd
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/ComputedStyle.java
@@ -0,0 +1,23 @@
+package org.openautonomousconnection.htmlparser.css;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public final class ComputedStyle {
+ private final Map props = new LinkedHashMap<>();
+
+ public void set(String k, String v) { if (k != null) props.put(k, v); }
+ public String get(String k) { return k == null ? null : props.get(k); }
+ public Map asMap() { return props; }
+
+ // helpers
+ public int intPx(String key, int def) {
+ String v = get(key);
+ if (v == null) return def;
+ v = v.trim().toLowerCase();
+ try {
+ if (v.endsWith("px")) v = v.substring(0, v.length() - 2).trim();
+ return Integer.parseInt(v);
+ } catch (Exception ignored) { return def; }
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/CssParser.java b/src/main/java/org/openautonomousconnection/htmlparser/css/CssParser.java
new file mode 100644
index 0000000..6560a8f
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/CssParser.java
@@ -0,0 +1,73 @@
+package org.openautonomousconnection.htmlparser.css;
+
+import java.util.Locale;
+
+public final class CssParser {
+ private CssParser() {}
+
+ public static Stylesheet parse(String css) {
+ Stylesheet sheet = new Stylesheet();
+ if (css == null) return sheet;
+
+ String src = css;
+
+ int i = 0;
+ while (i < src.length()) {
+ i = skipWs(src, i);
+ if (i >= src.length()) break;
+
+ int selStart = i;
+ int brace = src.indexOf('{', i);
+ if (brace < 0) break;
+
+ String selRaw = src.substring(selStart, brace).trim();
+ i = brace + 1;
+
+ int end = src.indexOf('}', i);
+ if (end < 0) break;
+
+ String body = src.substring(i, end);
+ i = end + 1;
+
+ Selector selector = parseSelector(selRaw);
+ if (selector == null) continue;
+
+ CssRule rule = new CssRule(selector);
+
+ for (String decl : body.split(";")) {
+ String d = decl.trim();
+ if (d.isEmpty()) continue;
+ int colon = d.indexOf(':');
+ if (colon < 0) continue;
+ String k = d.substring(0, colon).trim().toLowerCase(Locale.ROOT);
+ String v = d.substring(colon + 1).trim();
+ rule.declarations.put(k, v);
+ }
+
+ sheet.rules.add(rule);
+ }
+
+ return sheet;
+ }
+
+ private static Selector parseSelector(String selRaw) {
+ if (selRaw == null) return null;
+ String s = selRaw.trim();
+ if (s.isEmpty()) return null;
+
+ // only first simple selector, no groups
+ // "#id" ".class" "tag"
+ if (s.startsWith("#")) return new Selector(Selector.Kind.ID, s.substring(1).trim());
+ if (s.startsWith(".")) return new Selector(Selector.Kind.CLASS, s.substring(1).trim());
+ return new Selector(Selector.Kind.TAG, s.toLowerCase(Locale.ROOT));
+ }
+
+ private static int skipWs(String s, int i) {
+ while (i < s.length()) {
+ char c = s.charAt(i);
+ if (!Character.isWhitespace(c)) return i;
+ i++;
+ }
+ return i;
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/CssRule.java b/src/main/java/org/openautonomousconnection/htmlparser/css/CssRule.java
new file mode 100644
index 0000000..9136d4c
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/CssRule.java
@@ -0,0 +1,13 @@
+package org.openautonomousconnection.htmlparser.css;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public final class CssRule {
+ public final Selector selector;
+ public final Map declarations = new LinkedHashMap<>();
+
+ public CssRule(Selector selector) {
+ this.selector = selector;
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/LayoutBox.java b/src/main/java/org/openautonomousconnection/htmlparser/css/LayoutBox.java
new file mode 100644
index 0000000..3e58647
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/LayoutBox.java
@@ -0,0 +1,16 @@
+package org.openautonomousconnection.htmlparser.css;
+
+import org.openautonomousconnection.htmlparser.dom.Element;
+import org.openautonomousconnection.htmlparser.dom.TextNode;
+
+public final class LayoutBox {
+ public Element element; // null for pure text boxes
+ public TextNode text; // non-null for text
+
+ public int x, y, w, h;
+
+ public LayoutBox(Element element) { this.element = element; }
+ public LayoutBox(TextNode text) { this.text = text; }
+
+ public boolean isText() { return text != null; }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/LayoutEngine.java b/src/main/java/org/openautonomousconnection/htmlparser/css/LayoutEngine.java
new file mode 100644
index 0000000..57fd223
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/LayoutEngine.java
@@ -0,0 +1,57 @@
+package org.openautonomousconnection.htmlparser.css;
+
+import org.openautonomousconnection.htmlparser.dom.Element;
+import org.openautonomousconnection.htmlparser.dom.TextNode;
+import org.openautonomousconnection.htmlparser.dom.DomNode;
+
+import java.util.Map;
+
+public final class LayoutEngine {
+
+ private LayoutEngine() {}
+
+ public static LayoutTree layout(Element root, Map styles, int viewportWidth) {
+ LayoutTree tree = new LayoutTree();
+ int x = 16, y = 16;
+ int contentW = Math.max(1, viewportWidth - 32);
+
+ y = layoutNode(root, styles, tree, x, y, contentW);
+ return tree;
+ }
+
+ private static int layoutNode(DomNode node, Map styles, LayoutTree tree,
+ int x, int y, int w) {
+
+ if (node instanceof TextNode tn) {
+ LayoutBox tb = new LayoutBox(tn);
+ tb.x = x;
+ tb.y = y;
+ tb.w = w;
+ tb.h = 20;
+ tree.boxes.add(tb);
+ return y + tb.h;
+ }
+
+ if (!(node instanceof Element el)) return y;
+
+ ComputedStyle st = styles.get(el);
+ int margin = st != null ? st.intPx(StyleEngine.MARGIN, 0) : 0;
+ int padding = st != null ? st.intPx(StyleEngine.PADDING, 0) : 0;
+
+ LayoutBox box = new LayoutBox(el);
+ box.x = x + margin;
+ box.y = y + margin;
+ box.w = Math.max(1, w - margin * 2);
+ tree.boxes.add(box);
+
+ int curY = box.y + padding;
+
+ for (DomNode c : el.getChildren()) {
+ curY = layoutNode(c, styles, tree, box.x + padding, curY, box.w - padding * 2);
+ }
+
+ int minH = 24;
+ box.h = Math.max(minH, (curY - box.y) + padding);
+ return box.y + box.h + margin;
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/LayoutTree.java b/src/main/java/org/openautonomousconnection/htmlparser/css/LayoutTree.java
new file mode 100644
index 0000000..6cfc127
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/LayoutTree.java
@@ -0,0 +1,8 @@
+package org.openautonomousconnection.htmlparser.css;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class LayoutTree {
+ public final List boxes = new ArrayList<>();
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/Selector.java b/src/main/java/org/openautonomousconnection/htmlparser/css/Selector.java
new file mode 100644
index 0000000..e3ee255
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/Selector.java
@@ -0,0 +1,33 @@
+package org.openautonomousconnection.htmlparser.css;
+
+
+import org.openautonomousconnection.htmlparser.dom.Element;
+
+public final class Selector {
+ public enum Kind { TAG, CLASS, ID }
+
+ public final Kind kind;
+ public final String value;
+
+ public Selector(Kind kind, String value) {
+ this.kind = kind;
+ this.value = value;
+ }
+
+ public boolean matches(Element el) {
+ if (el == null) return false;
+ return switch (kind) {
+ case TAG -> value.equals(el.tag());
+ case CLASS -> el.classList().contains(value);
+ case ID -> value.equals(el.id());
+ };
+ }
+
+ public int specificity() {
+ return switch (kind) {
+ case ID -> 100;
+ case CLASS -> 10;
+ case TAG -> 1;
+ };
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/StyleDeclaration.java b/src/main/java/org/openautonomousconnection/htmlparser/css/StyleDeclaration.java
new file mode 100644
index 0000000..79c8be3
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/StyleDeclaration.java
@@ -0,0 +1,22 @@
+package org.openautonomousconnection.htmlparser.css;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public final class StyleDeclaration {
+ private final Map props = new LinkedHashMap<>();
+
+ public void set(String key, String value) {
+ if (key == null) return;
+ String k = key.trim().toLowerCase();
+ String v = value == null ? "" : value.trim();
+ props.put(k, v);
+ }
+
+ public String get(String key) {
+ if (key == null) return null;
+ return props.get(key.trim().toLowerCase());
+ }
+
+ public Map asMap() { return props; }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/StyleEngine.java b/src/main/java/org/openautonomousconnection/htmlparser/css/StyleEngine.java
new file mode 100644
index 0000000..b02f35d
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/StyleEngine.java
@@ -0,0 +1,80 @@
+package org.openautonomousconnection.htmlparser.css;
+
+import org.openautonomousconnection.htmlparser.dom.DomNode;
+import org.openautonomousconnection.htmlparser.dom.Element;
+
+import java.util.*;
+
+public final class StyleEngine {
+
+ public static final String DISPLAY = "display";
+ public static final String FONT_SIZE = "font-size";
+ public static final String COLOR = "color";
+ public static final String BACKGROUND = "background";
+ public static final String PADDING = "padding";
+ public static final String MARGIN = "margin";
+
+ private StyleEngine() {}
+
+ public static Map compute(Element root, Stylesheet sheet) {
+ Map out = new IdentityHashMap<>();
+ walk(root, null, sheet, out);
+ return out;
+ }
+
+ private static void walk(DomNode node, ComputedStyle parent, Stylesheet sheet, Map out) {
+ ComputedStyle cur = parent;
+
+ if (node instanceof Element el) {
+ cur = new ComputedStyle();
+
+ // inheritance defaults
+ if (parent != null) {
+ String pc = parent.get(COLOR);
+ String pf = parent.get(FONT_SIZE);
+ if (pc != null) cur.set(COLOR, pc);
+ if (pf != null) cur.set(FONT_SIZE, pf);
+ } else {
+ cur.set(COLOR, "#e5e7eb");
+ cur.set(FONT_SIZE, "16px");
+ }
+
+ // 1) stylesheet rules by specificity (simple)
+ if (sheet != null) {
+ List matches = new ArrayList<>();
+ for (CssRule r : sheet.rules) if (r.selector.matches(el)) matches.add(r);
+ matches.sort(Comparator.comparingInt(a -> a.selector.specificity()));
+ for (CssRule r : matches) r.declarations.forEach(cur::set);
+ }
+
+ // 2) inline style attr
+ // if you store raw style="" somewhere: parse and apply
+ String styleAttr = el.getAttribute("style");
+ if (styleAttr != null && !styleAttr.isBlank()) {
+ applyInline(cur, styleAttr);
+ }
+
+ // 3) programmatic inline style (el.style().set)
+ el.style().asMap().forEach(cur::set);
+
+ // display default
+ if (cur.get(DISPLAY) == null) cur.set(DISPLAY, "block");
+
+ out.put(el, cur);
+ }
+
+ for (DomNode c : node.getChildren()) walk(c, cur, sheet, out);
+ }
+
+ private static void applyInline(ComputedStyle st, String style) {
+ for (String part : style.split(";")) {
+ String p = part.trim();
+ if (p.isEmpty()) continue;
+ int idx = p.indexOf(':');
+ if (idx < 0) continue;
+ String k = p.substring(0, idx).trim().toLowerCase();
+ String v = p.substring(idx + 1).trim();
+ st.set(k, v);
+ }
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/css/Stylesheet.java b/src/main/java/org/openautonomousconnection/htmlparser/css/Stylesheet.java
new file mode 100644
index 0000000..d0ec64b
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/css/Stylesheet.java
@@ -0,0 +1,8 @@
+package org.openautonomousconnection.htmlparser.css;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class Stylesheet {
+ public final List rules = new ArrayList<>();
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/dom/Document.java b/src/main/java/org/openautonomousconnection/htmlparser/dom/Document.java
new file mode 100644
index 0000000..cfca2ae
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/dom/Document.java
@@ -0,0 +1,35 @@
+package org.openautonomousconnection.htmlparser.dom;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+public final class Document {
+ private final Element root;
+
+ public Document(Element root) {
+ this.root = root;
+ }
+
+ public Element getRoot() { return root; }
+
+ public Element createElement(String tag) { return new Element(tag); }
+ public TextNode createTextNode(String text) { return new TextNode(text); }
+
+ public Element getElementById(String id) {
+ if (id == null) return null;
+ Deque stack = new ArrayDeque<>();
+ stack.push(root);
+ while (!stack.isEmpty()) {
+ DomNode n = stack.pop();
+ if (n instanceof Element e) {
+ if (id.equals(e.id())) return e;
+ }
+ for (int i = n.getChildren().size() - 1; i >= 0; i--) stack.push(n.getChildren().get(i));
+ }
+ return null;
+ }
+
+ public Element querySelector(String selector) {
+ return DomQuery.querySelector(root, selector);
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/dom/DomNode.java b/src/main/java/org/openautonomousconnection/htmlparser/dom/DomNode.java
new file mode 100644
index 0000000..42c7b55
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/dom/DomNode.java
@@ -0,0 +1,26 @@
+package org.openautonomousconnection.htmlparser.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class DomNode {
+ protected DomNode parent;
+ protected final List children = new ArrayList<>();
+
+ public DomNode getParent() { return parent; }
+ public List getChildren() { return children; }
+
+ public void appendChild(DomNode child) {
+ if (child == null) return;
+ if (child.parent != null) child.parent.children.remove(child);
+ child.parent = this;
+ children.add(child);
+ }
+
+ public void removeChild(DomNode child) {
+ if (child == null) return;
+ if (children.remove(child)) child.parent = null;
+ }
+
+ public abstract String nodeName();
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/dom/DomQuery.java b/src/main/java/org/openautonomousconnection/htmlparser/dom/DomQuery.java
new file mode 100644
index 0000000..7a1046d
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/dom/DomQuery.java
@@ -0,0 +1,36 @@
+package org.openautonomousconnection.htmlparser.dom;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+public final class DomQuery {
+ private DomQuery() {}
+
+ public static Element querySelector(Element root, String selector) {
+ if (root == null || selector == null) return null;
+ String s = selector.trim();
+ if (s.isEmpty()) return null;
+
+ boolean byId = s.startsWith("#");
+ boolean byClass = s.startsWith(".");
+ String needle = (byId || byClass) ? s.substring(1) : s.toLowerCase();
+
+ Deque stack = new ArrayDeque<>();
+ stack.push(root);
+
+ while (!stack.isEmpty()) {
+ DomNode n = stack.pop();
+ if (n instanceof Element e) {
+ if (byId) {
+ if (needle.equals(e.id())) return e;
+ } else if (byClass) {
+ if (e.classList().contains(needle)) return e;
+ } else {
+ if (needle.equals(e.tag())) return e;
+ }
+ }
+ for (int i = n.getChildren().size() - 1; i >= 0; i--) stack.push(n.getChildren().get(i));
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/dom/Element.java b/src/main/java/org/openautonomousconnection/htmlparser/dom/Element.java
new file mode 100644
index 0000000..e8ffce7
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/dom/Element.java
@@ -0,0 +1,86 @@
+package org.openautonomousconnection.htmlparser.dom;
+
+import org.openautonomousconnection.htmlparser.css.StyleDeclaration;
+import org.openautonomousconnection.htmlparser.events.Event;
+import org.openautonomousconnection.htmlparser.events.EventListener;
+import org.openautonomousconnection.htmlparser.events.EventTarget;
+
+import java.util.*;
+
+public final class Element extends DomNode implements EventTarget {
+ private final String tag;
+ private final Map attrs = new LinkedHashMap<>();
+ private final StyleDeclaration inlineStyle = new StyleDeclaration();
+
+ // listeners per type
+ private final Map> listeners = new HashMap<>();
+
+ public Element(String tag) {
+ this.tag = tag == null ? "div" : tag.toLowerCase();
+ }
+
+ @Override public String nodeName() { return tag; }
+ public String tag() { return tag; }
+
+ public void setAttribute(String key, String value) {
+ if (key == null) return;
+ attrs.put(key.toLowerCase(), value == null ? "" : value);
+ }
+
+ public String getAttribute(String key) {
+ if (key == null) return null;
+ return attrs.get(key.toLowerCase());
+ }
+
+ public Map attributes() { return attrs; }
+
+ public String id() { return getAttribute("id"); }
+
+ public Set classList() {
+ String c = getAttribute("class");
+ if (c == null || c.isBlank()) return Set.of();
+ String[] parts = c.trim().split("\\s+");
+ LinkedHashSet set = new LinkedHashSet<>();
+ for (String p : parts) if (!p.isBlank()) set.add(p.trim());
+ return set;
+ }
+
+ public StyleDeclaration style() { return inlineStyle; }
+
+ public void setText(String text) {
+ // replace children with a single text node
+ children.clear();
+ appendChild(new TextNode(text));
+ }
+
+ @Override
+ public void addEventListener(String type, org.openautonomousconnection.htmlparser.events.EventListener listener) {
+ if (type == null || listener == null) return;
+ String t = type.toLowerCase();
+ listeners.computeIfAbsent(t, k -> new ArrayList<>()).add(listener);
+ }
+
+ @Override
+ public void dispatchEvent(Event event) {
+ if (event == null) return;
+
+ event.setTarget(this);
+
+ // bubble: from current element up to root
+ DomNode cur = this;
+ while (cur != null) {
+ if (cur instanceof Element el) {
+ event.setCurrentTarget(el);
+ List list = el.listeners.get(event.getType());
+ if (list != null) {
+ for (EventListener l : List.copyOf(list)) {
+ l.handle(event);
+ if (event.isStopped()) return;
+ }
+ }
+ }
+ cur = cur.getParent();
+ if (!event.isBubbles()) break;
+ }
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/dom/TextNode.java b/src/main/java/org/openautonomousconnection/htmlparser/dom/TextNode.java
new file mode 100644
index 0000000..5088009
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/dom/TextNode.java
@@ -0,0 +1,11 @@
+package org.openautonomousconnection.htmlparser.dom;
+
+public final class TextNode extends DomNode {
+ private String text;
+
+ public TextNode(String text) { this.text = text == null ? "" : text; }
+ public String getText() { return text; }
+ public void setText(String text) { this.text = text == null ? "" : text; }
+
+ @Override public String nodeName() { return "#text"; }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/events/Event.java b/src/main/java/org/openautonomousconnection/htmlparser/events/Event.java
new file mode 100644
index 0000000..53869ef
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/events/Event.java
@@ -0,0 +1,36 @@
+package org.openautonomousconnection.htmlparser.events;
+
+import org.openautonomousconnection.htmlparser.dom.Element;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public final class Event {
+ private final String type;
+ private final boolean bubbles;
+ private boolean stopped;
+
+ private Element target;
+ private Element currentTarget;
+
+ private final Map data = new HashMap<>();
+
+ public Event(String type, boolean bubbles) {
+ this.type = type == null ? "event" : type.toLowerCase();
+ this.bubbles = bubbles;
+ }
+
+ public String getType() { return type; }
+ public boolean isBubbles() { return bubbles; }
+
+ public void stopPropagation() { this.stopped = true; }
+ public boolean isStopped() { return stopped; }
+
+ public Element getTarget() { return target; }
+ public Element getCurrentTarget() { return currentTarget; }
+
+ public void setTarget(Element target) { this.target = target; }
+ public void setCurrentTarget(Element currentTarget) { this.currentTarget = currentTarget; }
+
+ public Map data() { return data; }
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/events/EventListener.java b/src/main/java/org/openautonomousconnection/htmlparser/events/EventListener.java
new file mode 100644
index 0000000..db6aa0c
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/events/EventListener.java
@@ -0,0 +1,6 @@
+package org.openautonomousconnection.htmlparser.events;
+
+@FunctionalInterface
+public interface EventListener {
+ void handle(Event event);
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/events/EventTarget.java b/src/main/java/org/openautonomousconnection/htmlparser/events/EventTarget.java
new file mode 100644
index 0000000..b9597f9
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/htmlparser/events/EventTarget.java
@@ -0,0 +1,6 @@
+package org.openautonomousconnection.htmlparser.events;
+
+public interface EventTarget {
+ void addEventListener(String type, EventListener listener);
+ void dispatchEvent(Event event);
+}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/exception/NullTagException.java b/src/main/java/org/openautonomousconnection/htmlparser/exception/NullTagException.java
deleted file mode 100644
index 89f8b5a..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/exception/NullTagException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-// Author: maple
-// date: 9/24/25
-
-package org.openautonomousconnection.htmlparser.exception;
-
-public class NullTagException extends NullPointerException {
- public NullTagException() {
- super("Tag can't be null!");
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/CustomHTMLElement.java b/src/main/java/org/openautonomousconnection/htmlparser/html/CustomHTMLElement.java
deleted file mode 100644
index c834cdd..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/CustomHTMLElement.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html;
-
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.Map;
-import java.util.Optional;
-
-public class CustomHTMLElement extends HTMLElement{
-
- public static final boolean CLOSEABLE = true;
-
- @Getter @Setter
- private String text;
-
- public CustomHTMLElement(String tag, String text, Map attributes) {
- this.tagName = tag;
- this.text = text;
- this.attributes = attributes;
-
- this.id = Optional.of(attributes.get("id"));
- }
-
-// @Override
-// public String toString() {
-// return otag() + this.text + ctag();
-// }
-
- public static CustomHTMLElement instantiate(String text, Map attributes) {
- return new CustomHTMLElement("UNKNOWN_ELEMENT", text, attributes);
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/HTML.java b/src/main/java/org/openautonomousconnection/htmlparser/html/HTML.java
deleted file mode 100644
index 26aa779..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/HTML.java
+++ /dev/null
@@ -1,90 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html;
-
-import org.openautonomousconnection.htmlparser.html.body.HTMLBody;
-import org.openautonomousconnection.htmlparser.html.header.HTMLHeader;
-import org.openautonomousconnection.htmlparser.html.misc.HTMLClass;
-import lombok.Getter;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Parent element for all HTML content
- */
-public class HTML extends HTMLElement{
- public static final String TAG = "html";
-
- public static final boolean CLOSEABLE = true;
-
- public final List classes;
-
- public HTML(HTMLHeader header, HTMLBody body) {
- super(null);
- this.header = header;
- this.body = body;
-
- this.tagName = TAG;
-
- this.classes = new ArrayList<>();
- }
-
- public HTML() {
- this(null, null);
- }
-
- @Getter
- private HTMLHeader header;
-
- @Getter
- private HTMLBody body;
-
- @Override
- public HTMLElement append(HTMLElement element) {
- if(element instanceof HTMLHeader)
- this.header = (HTMLHeader) element;
- else if(element instanceof HTMLBody)
- this.body = (HTMLBody) element;
- else
- super.append(element);
-
- return element;
-
- }
-
- public HTMLBody setBody(HTMLBody body) {
- this.body = body;
-
- this.body.parent = this;
-
- return this.body;
- }
-
- public HTMLHeader setHeader(HTMLHeader header) {
- this.header = header;
-
- this.header.parent = this;
-
- return this.header;
- }
-
-// @Override
-// public String toString() {
-// return otag()
-// + "\n\t"
-// + header.toString() + "\n\t"
-// + body.toString() + "\n"
-// + ctag();
-// }
-
- public static HTML instantiate(String text, Map attributes) {
- HTML html = new HTML();
-
- html.setAttributes(attributes);
-
- return html;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/HTMLElement.java b/src/main/java/org/openautonomousconnection/htmlparser/html/HTMLElement.java
deleted file mode 100644
index 511c2d7..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/HTMLElement.java
+++ /dev/null
@@ -1,142 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html;
-
-import org.openautonomousconnection.htmlparser.html.misc.HTMLClass;
-import lombok.Getter;
-import lombok.Setter;
-import org.jetbrains.annotations.Nullable;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.*;
-
-public abstract class HTMLElement {
-
- @Getter
- protected HTMLElement parent;
-
- @Getter
- protected List children;
-
- @Getter
- protected String tagName;
-
- @Getter @Setter
- protected Optional id;
-
- @Getter @Setter
- protected Optional htmlClass;
-
- @Getter @Setter
- protected Map attributes;
-
- protected HTMLElement(@Nullable HTMLElement parent) {
- this.parent = parent;
-
- this.attributes = new HashMap<>();
-
- this.id = Optional.empty();
- this.htmlClass = Optional.empty();
-
- this.children = new ArrayList<>();
- }
-
- protected HTMLElement() {
- this(null);
- }
-
-
-// @Override
-// public abstract String toString();
-
- public HTMLElement append(HTMLElement element) {
- element.parent = this;
- this.children.add(element);
- return element;
- }
-
- public final String toString() {
- if(this.getClass().isAnnotationPresent(NoContent.class))
- return otag();
-
-
- StringBuilder sb = new StringBuilder(otag()).append("\n\t");
-
- for(HTMLElement child : this.children)
- sb.append(child).append("\n\t");
-
- return sb.append(ctag()).toString();
- }
-
- /**
- * Reload ID from attributes map
- */
- public void reloadId() {
- if(this.attributes.containsKey("id")) {
- this.id = Optional.of(this.attributes.get("id"));
- this.attributes.remove("id");
- }
- }
-
- protected String getIdString() {
- return this.id.map(string -> "id='" + string +"' ").orElse("");
- }
-
- protected String getClassString() {
- return this.htmlClass.map(htmlClass -> "class='" + htmlClass.getClassName() + "' ").orElse("");
- }
-
- protected String getAttributesString() {
- StringBuilder sb = new StringBuilder(" ");
- for(String string : this.attributes.keySet())
- sb.append(string)
- .append("='")
- .append(this.attributes.get(string))
- .append("' ");
-
- if(!sb.toString().equals(" "))
- return sb.substring(0, sb.length()-1);
- else
- return "";
- }
-
- protected String otag() {
- return "<" + this.tagName + getIdString() + getClassString() + getAttributesString() + ">";
- }
-
- protected String otag(String _attributes) {
- return "<" + this.tagName + getIdString() + getClassString() + " " + _attributes + getAttributesString() + ">";
- }
-
- protected String ctag() {
- return "" + this.tagName + ">";
- }
-
- protected String cutTag(String string, String _attributes) {
- return string.replaceFirst("<" + tagName + " " + _attributes + ">", "").replaceFirst("" + tagName + ">", "").trim();
- }
-
- protected String cutTag(String string) {
- return cutTag(string, "");
- }
-
-// protected static Class extends HTMLElement> getNext(Parser parser, String string) {
-// String sub = string.substring(string.indexOf("<" + 1)).split(" ")[0];
-//
-// return parser.getByTagname(sub);
-// }
-//
-
- /**
- * only use if child objects can exist
- * @return parsed child objects
- */
-
- // TODO: 1. handle comments 2. somehow handle non-tag >s & <s
-
- public static HTMLElement instantiate(Class extends HTMLElement> elementClass, String text, Map attributes) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- return (HTMLElement) elementClass.getMethod("instantiate", String.class, Map.class).invoke(null, text, attributes);
-
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/NoContent.java b/src/main/java/org/openautonomousconnection/htmlparser/html/NoContent.java
deleted file mode 100644
index 1437d5a..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/NoContent.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.openautonomousconnection.htmlparser.html;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface NoContent {
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/BodyElement.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/BodyElement.java
deleted file mode 100644
index 0e43814..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/BodyElement.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body;
-
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-import lombok.Getter;
-import lombok.Setter;
-import org.jetbrains.annotations.Nullable;
-
-public abstract class BodyElement extends HTMLElement {
- @Getter @Setter
- protected String text;
-
- protected BodyElement(@Nullable HTMLElement parent) {
- super(parent);
- }
-
- protected BodyElement() {
-
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/HTMLBody.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/HTMLBody.java
deleted file mode 100644
index 6c7c85e..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/HTMLBody.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body;
-
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-public class HTMLBody extends HTMLElement {
-
- public static final String TAG = "body";
-
- public static final boolean CLOSEABLE = true;
-
-
- public HTMLBody(List elements) {
- this.children = elements;
-
- this.tagName = TAG;
- }
-
- public HTMLBody(HTMLElement... elements) {
- this.children = new ArrayList<>(Arrays.stream(elements).toList());
-
- this.tagName = TAG;
- }
-
- public static HTMLBody instantiate(String text, Map attributes) {
- HTMLBody body = new HTMLBody();
-
- body.setAttributes(attributes);
-
- body.reloadId();
-
- return body;
- }
-
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/buttons/ButtonElement.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/buttons/ButtonElement.java
deleted file mode 100644
index 8a5ab57..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/buttons/ButtonElement.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.buttons;
-
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-
-public abstract class ButtonElement extends BodyElement {
- public String getScript() {
- return this.attributes.get("onclick");
- }
-
- public void setScript(String script) {
- this.attributes.replace("onclick", script);
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/buttons/HTMLButton.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/buttons/HTMLButton.java
deleted file mode 100644
index 029b5d9..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/buttons/HTMLButton.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.buttons;
-
-import java.util.Map;
-
-public class HTMLButton extends ButtonElement {
-
- public static final String TAG = "button";
-
- public static final boolean CLOSEABLE = false;
-
- public HTMLButton(String text) {
- this.text = text;
- this.tagName = TAG;
- }
- public HTMLButton(String text, String script) {
- this.text = text;
- this.setScript(script);
-
- this.tagName = TAG;
- }
-
- public static HTMLButton instantiate(String text, Map attributes) {
- HTMLButton form = new HTMLButton(text);
-
- form.setAttributes(attributes);
-
- form.reloadId();
-
- return form;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/FormElement.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/FormElement.java
deleted file mode 100644
index 88bf7bd..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/FormElement.java
+++ /dev/null
@@ -1,10 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.form;
-
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-
-public abstract class FormElement extends BodyElement {
-
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/HTMLForm.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/HTMLForm.java
deleted file mode 100644
index 50b84fd..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/HTMLForm.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.form;
-
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-
-import java.util.Map;
-
-public class HTMLForm extends HTMLElement {
-
- public static final String TAG = "form";
-
- public static final boolean CLOSEABLE = true;
-
- public HTMLForm() {
- this.tagName = TAG;
- }
-
- public HTMLForm(String action) {
- this.attributes.put("action", action);
- this.tagName = TAG;
- }
-
- public static HTMLForm instantiate(String text, Map attributes) {
- HTMLForm form = new HTMLForm();
-
- form.setAttributes(attributes);
-
- form.reloadId();
-
- return form;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/HTMLInput.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/HTMLInput.java
deleted file mode 100644
index 0529777..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/HTMLInput.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Author: maple
-// date: 9/24/25
-
-package org.openautonomousconnection.htmlparser.html.body.form;
-
-import org.openautonomousconnection.htmlparser.html.NoContent;
-
-import java.util.Map;
-
-@NoContent
-public class HTMLInput extends FormElement {
-
- public static final String TAG = "input";
-
- public static final boolean CLOSEABLE = false;
-
- public HTMLInput() {
-
- }
-
- public HTMLInput(String type, String name) {
- this.setType(type);
- this.setName(name);
-
- this.tagName = TAG;
- }
-
- public String getType() {
- return this.attributes.get("title");
- }
-
- public String getName() {
- return this.attributes.get("title");
- }
-
- public void setType(String type) {
- this.attributes.replace("type", type);
- }
-
- public void setName(String name) {
- this.attributes.replace("name", name);
- }
-
-
- public static HTMLInput instantiate(String text, Map attributes) {
- HTMLInput input = new HTMLInput(attributes.get("type"), attributes.get("name"));
-
- input.setText(text);
-
- attributes.remove("type");
- attributes.remove("name");
-
- input.setAttributes(attributes);
-
- input.reloadId();
-
- return input;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/HTMLLabel.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/HTMLLabel.java
deleted file mode 100644
index d4c212b..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/form/HTMLLabel.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.form;
-
-import java.util.Map;
-
-public class HTMLLabel extends FormElement {
-
- public static final String TAG = "label";
-
- public static final boolean CLOSEABLE = true;
-
- public HTMLLabel(String text) {
- this.text = text;
-
- this.tagName = TAG;
- }
-
- public String get_for() {
- return this.attributes.get("for");
- }
-
- public void set_for(String _for) {
- this.attributes.replace("for", _for);
- }
-
- public static HTMLLabel instantiate(String text, Map attributes) {
- HTMLLabel label = new HTMLLabel(text);
-
- label.setAttributes(attributes);
-
- label.reloadId();
-
- return label;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/HTMLArea.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/HTMLArea.java
deleted file mode 100644
index 6a1fb47..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/HTMLArea.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.link;
-
-import java.util.Map;
-
-public class HTMLArea extends LinkElement {
-
- public static final String TAG = "area";
-
- public static final boolean CLOSEABLE = true;
-
- public String getShape() {
- return this.attributes.get("shape");
- }
-
- public String getCoords() {
- return this.attributes.get("coords");
- }
-
- public void setShape(String shape) {
- this.attributes.replace("shape", shape);
- }
-
- public void setCoords(String coords) {
- this.attributes.replace("coords", coords);
- }
-
- public HTMLArea() {
- this.tagName = TAG;
- }
-
- public HTMLArea(String src, String shape, String coords) {
- this.setSource(src);
- this.setShape(shape);
- this.setCoords(coords);
-
- this.tagName = TAG;
- }
-
- public static HTMLArea instantiate(String text, Map attributes) {
- HTMLArea area = new HTMLArea();
-
- area.setText(text);
-
- area.setAttributes(attributes);
-
- area.reloadId();
-
- return area;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/HTMLHyperlink.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/HTMLHyperlink.java
deleted file mode 100644
index 9e5f5db..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/HTMLHyperlink.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.link;
-
-import java.util.Map;
-
-public class HTMLHyperlink extends LinkElement {
-
- public static final String TAG = "a";
-
- public static final boolean CLOSEABLE = true;
-
- public HTMLHyperlink(String text) {
- this.text = text;
-
- this.tagName = TAG;
- }
-
- public HTMLHyperlink(String text, String src) {
- this.text = text;
- this.setSource(src);
-
- this.tagName = TAG;
- }
-
- public static HTMLHyperlink instantiate(String text, Map attributes) {
- HTMLHyperlink hyperlink = new HTMLHyperlink(text);
-
- hyperlink.setAttributes(attributes);
-
- hyperlink.reloadId();
-
- return hyperlink;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/HTMLImage.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/HTMLImage.java
deleted file mode 100644
index 5e8c57b..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/HTMLImage.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.link;
-
-import java.util.Map;
-
-public class HTMLImage extends LinkElement {
-
- public static final String TAG = "img";
-
- public static final boolean CLOSEABLE = false;
-
- public HTMLImage() {
- this.tagName = TAG;
- }
-
- public HTMLImage(String src) {
- this.setSource(src);
- this.tagName = TAG;
- }
-
- public static HTMLImage instantiate(String text, Map attributes) {
- HTMLImage image = new HTMLImage();
-
- image.setText(text);
-
- image.setAttributes(attributes);
-
- image.reloadId();
-
- return image;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/LinkElement.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/LinkElement.java
deleted file mode 100644
index e3d47a4..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/link/LinkElement.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.link;
-
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-
-public abstract class LinkElement extends BodyElement {
- protected LinkElement() {
-
- }
-
- public String getSource() {
- return this.attributes.get("src");
- }
-
- public void setSource(String source) {
- this.attributes.replace("src", source);
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLBreak.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLBreak.java
deleted file mode 100644
index 8cd9e8d..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLBreak.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.misc;
-
-import org.openautonomousconnection.htmlparser.html.NoContent;
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-
-import java.util.Map;
-
-@NoContent
-public class HTMLBreak extends BodyElement {
-
- public static final String TAG = "br";
-
- public static final boolean CLOSEABLE = false;
-
- public HTMLBreak() {
- this.tagName = TAG;
- }
-
-
- public static HTMLBreak instantiate(String text, Map attributes) {
- HTMLBreak hbreak = new HTMLBreak();
-
- hbreak.setText(text);
-
- hbreak.setAttributes(attributes);
-
- hbreak.reloadId();
-
- return hbreak;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLComment.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLComment.java
deleted file mode 100644
index 7184338..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLComment.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.openautonomousconnection.htmlparser.html.body.misc;
-
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.Map;
-
-@Getter @Setter
-
-public class HTMLComment extends HTMLElement {
- public static String TAG = "--";
-
- private String text;
-
- public static final boolean CLOSEABLE = true;
-
- public HTMLComment(String text) {
- this.text = text;
- this.tagName = "";
- }
-
- public static HTMLComment instantiate(String text, Map attributes) {
- return new HTMLComment(text);
- }
-
- @Override
- protected String getIdString() {
- return "";
- }
-
- @Override
- protected String getClassString() {
- return "";
- }
-
- @Override
- protected String getAttributesString() {
- return "";
- }
-
- @Override
- protected String otag() {
- return "";
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLDiv.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLDiv.java
deleted file mode 100644
index b212b9b..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLDiv.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.misc;
-
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-
-import java.util.Map;
-
-public class HTMLDiv extends HTMLElement {
-
- public static final String TAG = "div";
-
- public static final boolean CLOSEABLE = true;
-
- public HTMLDiv() {
- this.tagName = TAG;
- }
-
- public static HTMLDiv instantiate(String text, Map attributes) {
- HTMLDiv div = new HTMLDiv();
-
- div.setAttributes(attributes);
-
- div.reloadId();
-
- return div;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLScript.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLScript.java
deleted file mode 100644
index 6b27a11..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/misc/HTMLScript.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.misc;
-
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-
-import java.util.Map;
-
-public class HTMLScript extends BodyElement {
-
- public static final String TAG = "script";
-
- public static final boolean CLOSEABLE = true;
-
- public HTMLScript(String text) {
- this.text = text;
- this.tagName = TAG;
- }
-
- public static HTMLScript instantiate(String text, Map attributes) {
- HTMLScript script = new HTMLScript(text);
-
- script.setAttributes(attributes);
-
- script.reloadId();
-
- return script;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/HTMLAbbreviation.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/HTMLAbbreviation.java
deleted file mode 100644
index 51ba23c..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/HTMLAbbreviation.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.openautonomousconnection.htmlparser.html.body.texts;
-
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-
-import java.util.Map;
-
-public class HTMLAbbreviation extends BodyElement {
-
- public static final String TAG = "abbr";
-
- public static final boolean CLOSEABLE = true;
-
- public HTMLAbbreviation(String text) {
- this.text = text;
- this.tagName = TAG;
- }
-
- public HTMLAbbreviation(String text, String title) {
- this.text = text;
- this.setTitle(title);
-
- this.tagName = TAG;
- }
-
- public String getTitle() {
- return this.attributes.get("title");
- }
-
- public void setTitle(String title) {
- this.attributes.replace("title", title);
- }
-
- public static HTMLAbbreviation instantiate(String text, Map attributes) {
- HTMLAbbreviation abbreviation = new HTMLAbbreviation(text);
-
- abbreviation.setAttributes(attributes);
-
- abbreviation.reloadId();
-
- return abbreviation;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/heading/HTMLHeading.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/heading/HTMLHeading.java
deleted file mode 100644
index 5c53eae..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/heading/HTMLHeading.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.texts.heading;
-
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-import lombok.Getter;
-
-import java.util.Map;
-
-public class HTMLHeading extends BodyElement {
-
- @Getter
- protected HeadingType type;
-
- public static final boolean CLOSEABLE = true;
-
- public HTMLHeading(String text, HeadingType type) {
- this.text = text;
- this.type = type;
-
- this.tagName = this.type.getTag();
- }
-
- public void setType(HeadingType type) {
- this.type = type;
- this.tagName = this.type.getTag();
- }
-
- public static HTMLHeading instantiate(String text, Map attributes) {
- HTMLHeading heading = new HTMLHeading(text, HeadingType.H1);
-
- heading.setAttributes(attributes);
-
- heading.reloadId();
-
- return heading;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/heading/HeadingType.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/heading/HeadingType.java
deleted file mode 100644
index 67502e5..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/heading/HeadingType.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.body.texts.heading;
-
-import lombok.Getter;
-
-public enum HeadingType {
-
- H1("h1"),
- H2("h2"),
- H3("h3"),
- H4("h4"),
- H5("h5"),
- H6("h6");
-
- @Getter
- private String tag;
-
- HeadingType(String tag) {
- this.tag = tag;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/text/HTMLText.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/text/HTMLText.java
deleted file mode 100644
index 98f58c6..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/text/HTMLText.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.openautonomousconnection.htmlparser.html.body.texts.text;
-
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-import lombok.Getter;
-
-import java.util.Map;
-
-public class HTMLText extends BodyElement {
-
- @Getter
- private TextType type;
-
- public static final boolean CLOSEABLE = true;
-
- protected HTMLText(String text, TextType type) {
- this.text = text;
- this.type = type;
-
- this.tagName = this.type.getTag();
- }
-
- public void setType(TextType type) {
- this.type = type;
- this.tagName = this.type.getTag();
- }
-
- public static HTMLText instantiate(String text, Map attributes) {
- HTMLText htext = new HTMLText(text, TextType.PARAGRAPH);
-
- htext.setAttributes(attributes);
-
- htext.reloadId();
-
- return htext;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/text/TextType.java b/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/text/TextType.java
deleted file mode 100644
index b44d9bf..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/body/texts/text/TextType.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.openautonomousconnection.htmlparser.html.body.texts.text;
-
-import lombok.Getter;
-
-public enum TextType {
- PARAGRAPH("p"),
- BOLD("b"),
- STRONG("strong"),
- ITALIC("i"),
- EMPHASIZED("em"),
- MARKED("mark"),
- SMALL("small"),
- DELETED("del"),
- INSERTED("ins"),
- SUBSCRIPT("sub"),
- SUPERSCRIPT("sup"),
- UNDERLINED("u"),
- SPAN("span");
-
- @Getter
- private String tag;
-
- TextType(String tag) {
- this.tag = tag;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/header/HTMLHeader.java b/src/main/java/org/openautonomousconnection/htmlparser/html/header/HTMLHeader.java
deleted file mode 100644
index 74b7e79..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/header/HTMLHeader.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.header;
-
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-import lombok.Getter;
-
-import java.util.*;
-
-public class HTMLHeader extends HTMLElement {
-
- public static final String TAG = "head";
-
- public static final boolean CLOSEABLE = true;
-
- @Getter
- private HTMLTitle title = null;
-
- public HTMLHeader(List elements) {
-
- for(HeaderElement element : elements)
- if(element instanceof HTMLTitle title)
- this.title = title;
- else
- this.append(element);
-
- //this.elements = elements;
-
- if(title == null)
- title = new HTMLTitle();
-
- this.tagName = TAG;
- }
-
- public HTMLHeader(HeaderElement... element) {
- this(new ArrayList<>(Arrays.stream(element).toList()));
- }
-
- public static HTMLHeader instantiate(String text, Map attributes) {
- HTMLHeader header = new HTMLHeader();
-
- header.setAttributes(attributes);
-
- header.reloadId();
-
- return header;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/header/HTMLTitle.java b/src/main/java/org/openautonomousconnection/htmlparser/html/header/HTMLTitle.java
deleted file mode 100644
index aa5d5bc..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/header/HTMLTitle.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.header;
-
-import org.openautonomousconnection.htmlparser.Parser;
-
-import java.util.Map;
-
-public class HTMLTitle extends HeaderElement {
-
- public static final String TAG = "title";
-
- public static final boolean CLOSEABLE = true;
-
- public HTMLTitle(String text) {
- this.text = text;
-
- this.tagName = TAG;
- }
-
- public HTMLTitle() {
- this(Parser.DEFAULT_TITLE);
- }
-
- public static HTMLTitle instantiate(String text, Map attributes) {
- HTMLTitle title = new HTMLTitle(text);
-
- title.setAttributes(attributes);
-
- title.reloadId();
-
- return title;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/header/HeaderElement.java b/src/main/java/org/openautonomousconnection/htmlparser/html/header/HeaderElement.java
deleted file mode 100644
index 2c9f804..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/header/HeaderElement.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.header;
-
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-import lombok.Getter;
-import lombok.Setter;
-import org.jetbrains.annotations.Nullable;
-
-public abstract class HeaderElement extends BodyElement {
- @Getter @Setter
- protected String text;
-
- protected HeaderElement(@Nullable HTMLElement parent) {
- super(parent);
- }
-
- protected HeaderElement() {
-
- }
-
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/html/misc/HTMLClass.java b/src/main/java/org/openautonomousconnection/htmlparser/html/misc/HTMLClass.java
deleted file mode 100644
index e575675..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/html/misc/HTMLClass.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Author: maple
-// date: 9/20/25
-
-package org.openautonomousconnection.htmlparser.html.misc;
-
-import org.openautonomousconnection.htmlparser.html.HTML;
-import org.openautonomousconnection.htmlparser.html.body.BodyElement;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class HTMLClass {
-
- @Getter @Setter
- protected String className;
-
- public List elements;
-
- public HTMLClass(String className, HTML document) {
- this.className = className;
-
- this.elements = new ArrayList<>();
-
- document.classes.add(this);
- }
-
-
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/ElementBuilder.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/ElementBuilder.java
deleted file mode 100644
index fbe5228..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/ElementBuilder.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Author: maple
-// date: 9/24/25
-
-package org.openautonomousconnection.htmlparser.interpreter;
-
-import org.openautonomousconnection.htmlparser.Parser;
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.HashMap;
-import java.util.Map;
-
-public class ElementBuilder {
- private Class extends HTMLElement> clazz;
-
- @Getter @Setter
- private Map attributes;
-
- @Getter @Setter
- private String text, tagName;
-
- /**
- * build a html Element
- * @param parser needed to retrieve element class (tagnames are relative)
- * @param tagName name of the tag
- */
- public ElementBuilder(Parser parser, String tagName) {
- this.clazz = parser.getByTagname(tagName);
-
- this.attributes = new HashMap<>();
-
- this.tagName = tagName;
-
- }
-
- public HTMLElement build() {
- try {
- System.out.println(clazz.getSimpleName());
-
- return HTMLElement.instantiate(clazz, text, attributes);
- } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-
- public void appendText(String text) {
- if(this.text != null)
- this.text = this.text + text;
- else
- this.text = text;
- }
-
- @Override
- public String toString() {
- return "ElementBuilder{" +
- "clazz=" + clazz.getSimpleName() +
- ", attributes=" + attributes +
- ", text='" + text + '\'' +
- ", tagName='" + tagName + '\'' +
- '}';
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/HTMLInterpreter.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/HTMLInterpreter.java
deleted file mode 100644
index 62b35e3..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/HTMLInterpreter.java
+++ /dev/null
@@ -1,447 +0,0 @@
-// Author: maple
-// date: 9/24/25
-
-package org.openautonomousconnection.htmlparser.interpreter;
-
-import org.openautonomousconnection.StringUtils_Remove_Please;
-import org.openautonomousconnection.htmlparser.Parser;
-import org.openautonomousconnection.htmlparser.TagManager;
-import org.openautonomousconnection.htmlparser.html.HTML;
-import org.openautonomousconnection.htmlparser.html.HTMLElement;
-import org.openautonomousconnection.htmlparser.interpreter.html.exception.ExpectStringException;
-import org.openautonomousconnection.htmlparser.interpreter.html.exception.UnexpectedTokenException;
-import org.openautonomousconnection.htmlparser.interpreter.html.state.HTMLState;
-import lombok.Getter;
-import org.openautonomousconnection.htmlparser.interpreter.script.ScriptInterpreter;
-
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Stack;
-
-public class HTMLInterpreter implements Interpreter {
- @Getter
- private HTMLState currentState = HTMLState.TAG;
-
- // Used to go up a layer after comment is opened
- private HTMLState inbetweenState = HTMLState.COMMENT;
-
- @Getter
- private Parser parser;
- private TagManager tagManager;
- private Stack elementBuilders;
- private StringBuilder currentAttribute, currentValue, currentText, currentClosingTag;
-
- public int currentLine = 1;
-
- private HTMLElement currentElement;
-
- private ScriptInterpreter scriptInterpreter;
-
- public HTMLInterpreter(Parser parser, ScriptInterpreter scriptInterpreter) {
- this.parser = parser;
- this.tagManager = parser.getTagManager();
- this.scriptInterpreter = scriptInterpreter;
-
- this.currentText = new StringBuilder();
- this.currentClosingTag = new StringBuilder();
- this.currentAttribute = new StringBuilder();
- this.currentValue = new StringBuilder();
-
- this.elementBuilders = new Stack<>();
- }
-
- @Override
- public void nextState(String token) {
- boolean newLine = token.endsWith("\n");
-
- if(token.isBlank()) {
- if (newLine)
- this.currentLine++;
-
- return;
- }
-
- this.currentState = switch (this.currentState) {
- case TAG -> tag(token.strip());
- case CLOSE_TAG -> close_tag(token.strip());
- case TEXT -> text(token);
- case DOCTYPE -> doctype(token.strip());
- case ATTRIBUTE -> attribute(token.strip());
- case ATTRIBUTE_EQUALS -> attribute_equals(token.strip());
- case COMMENT -> comment(token);
- case VALUE -> value(token);
- case SCRIPT -> script(token);
- default -> this.currentState;
- };
-
- if(newLine)
- this.currentLine++;
- }
-
- @Override
- public boolean finished() {
- return false;
- }
-
- public HTML getResult() {
- return (HTML) this.currentElement;
- }
-
- // Only public at the moment because of JavaScriptInterpreter
- public static String stripTag(String token) {
- return token.replace("<","").replace(">","");
- }
-
- /**
- * Open a script
- * @param token script
- * @return next state
- */
- private HTMLState script(String token) {
- this.scriptInterpreter.currentLine = this.currentLine;
-
- this.scriptInterpreter.nextState(token);
-
- // TODO: Change for release. This is debug code
- if(this.scriptInterpreter.finished()) {
- // the ScriptInterpreter already has its own ElementBuilder
- this.elementBuilders.pop();
-
- this.elementBuilders.push(this.scriptInterpreter.getElementBuilder());
-
- return this.close_tag(token);
- }
- else
- return HTMLState.SCRIPT;
-
- }
-
- /**
- * Open a tag
- * @param token tag
- * @return next state
- */
- private HTMLState tag(String token) {
- String tagName = stripTag(token);
-
- boolean hasText = this.tagManager.hasText(tagName);
-
- if(tagName.equalsIgnoreCase("!DOCTYPE"))
- return HTMLState.DOCTYPE;
-
- else if(tagName.stripLeading().startsWith("!--"))
- return returnCommentState();
-
- this.elementBuilders.push(new ElementBuilder(this.parser, tagName));
-
-
- String[] split = new String[] {token};
-
- if(token.contains(">"))
- split = StringUtils_Remove_Please.splitSeq(new String[]{
- token.substring(0, token.indexOf('>'))
- }, ">");
-
-
-// TODO: Change for release. This is debug code
- if(this.elementBuilders.peek().getTagName().equals("script"))
- return split.length == 1 ? HTMLState.SCRIPT : script(token.substring(token.indexOf(">")+1));
-
-
- if(!token.contains(">"))
- return HTMLState.ATTRIBUTE;
-
- if(split.length == 1)
- return hasText ? HTMLState.TEXT : HTMLState.TAG;
- else
- return attribute(token.substring(token.indexOf('>')+1));
-
- }
-
- /**
- * Close a tag
- * @param token closing tag
- * @return next state
- */
- private HTMLState close_tag(String token) {
- System.out.println(Arrays.toString(this.elementBuilders.toArray()));
- this.currentClosingTag.append(token.toLowerCase().strip());
-
- String ct = this.currentClosingTag.toString();
-
- String tagName = this.elementBuilders.peek().getTagName();
-
- // one instruction tags don't have a clo
- if(!this.tagManager.hasText(tagName)) {
- this.elementBuilders.pop();
-
- return HTMLState.TEXT;
- }
-
- // Comments are special
- String should = tagName.equals("--") ? tagName + '>' : "" + tagName + ">";
-
- System.out.println("should: " + should + " token: " + token);
-
- if(should.equals(ct)) {
-
- if(this.currentElement != null)
- this.currentElement = this.currentElement.append(this.elementBuilders.pop().build());
- else
- this.currentElement = this.elementBuilders.pop().build();
-
- if(!(this.currentElement instanceof HTML))
- this.currentElement = this.currentElement.getParent();
-
- this.currentClosingTag = new StringBuilder();
- return HTMLState.TEXT;
-
- }
-
- // not reached yet
- else if(should.startsWith(ct))
- return HTMLState.TEXT;
-
- // token not the same as
- else
- throw new UnexpectedTokenException(token, this.currentLine, this.currentState);
-
- }
-
- private HTMLState text(String token) {
- String strip = token.stripLeading();
-
- // handle string begin
- if(this.currentText.isEmpty()) {
- if(strip.startsWith("<"))
- return tag(strip);
-
- this.currentText.append(token);
-
- return HTMLState.TEXT;
- }
-
- // handle string end or nested elements
- else if(token.startsWith("<")) {
- this.elementBuilders.peek().setText(this.currentText.toString());
-
- // always reset
- this.currentText = new StringBuilder();
-
- if(token.startsWith(""))
- return close_tag(token.stripTrailing());
- else
- return tag(token.stripTrailing());
- }
-
- // continue as text
-
- else {
- this.currentText.append(token);
- return HTMLState.TEXT;
- }
- }
-
- /**
- * Declare an attribute
- * @param token attribute type
- * @return next state
- */
- private HTMLState attribute(String token) {
- if(token.startsWith(">") || token.endsWith(">"))
- return text(token);
-
- else if(token.contains("=")) {
- // Recursition if declaration and equals are same token
- this.currentAttribute = new StringBuilder(token.substring(0, token.indexOf('=')));
-
- return attribute_equals(token.substring(token.indexOf('=')));
- }
- else {
- this.currentAttribute = new StringBuilder(token);
- return HTMLState.ATTRIBUTE_EQUALS;
-
- }
-
- }
-
- /**
- * Handle equals operator between attribute declaration and definition (can only be '='; will throw otherwise)
- * @param token equals operator
- * @return next state
- */
- private HTMLState attribute_equals(String token) {
- boolean dq = token.contains("\""), sq = token.contains("'");
- if(dq || sq) {
- char quot = dq ? '"' : '\'';
- // Recursion if declaration and equals are same token
-
- return value(token.substring(token.indexOf(quot)-1), quot);
- }
- else if(token.equals("=")){
- return HTMLState.VALUE;
- }
- else {
- throw new UnexpectedTokenException(token, this.currentLine, this.currentState);
- }
- }
-
- /**
- * Define an attribute
- * @param token attribute value
- * @return next state
- */
- private HTMLState value(String token) {
- return value(token, ' ');
- }
-
- /**
- * Define a string attribute
- * @param token attribute value
- * @param quot quotation sign
- * @return next state
- */
- private HTMLState value(String token, char quot) {
-
- // expected string, got other
- if(!token.startsWith("'") && token.startsWith("\""))
- throw new ExpectStringException(token, this.currentLine, this.currentState);
-
- this.currentValue = new StringBuilder();
-
- quot = quot != ' ' ? quot : token.charAt(0);
-
- // split by quote character
- String[] split = token.split(String.valueOf(quot));
-
- for(int i = 0; i < split.length; i++)
-
- // handle escaped quote character
- if(split[i].endsWith("\\")) {
- this.currentValue.append(split[i]).append(quot);
- split[i] = "";
- }
-
- // delete first quotation character
- if(!this.currentValue.isEmpty())
- this.currentValue.deleteCharAt(0);
-
- StringBuilder rebuilt = new StringBuilder();
-
- // TODO possible error source
-
- for(String s : split)
-
- if(!s.isEmpty())
- rebuilt.append(s);
-
- if(!rebuilt.isEmpty() && this.tagManager.hasText(stripTag(token)))
- return text(token);
-
- return HTMLState.ATTRIBUTE;
- }
-
- /**
- * Comment on code
- * @param token comment
- * @return next state
- */
- private HTMLState comment(String token) {
- if(this.currentText.isEmpty())
- this.currentText = new StringBuilder();
-
- // append comment
- if(!token.contains("-->")) {
- this.currentText.append(token);
-
- return HTMLState.COMMENT;
- }
-
- // end comment
-
- ElementBuilder elementBuilder = new ElementBuilder(this.parser, "--");
- elementBuilder.setText(this.currentText.toString());
-
- // always reset
- this.currentText = new StringBuilder();
-
- this.elementBuilders.push(elementBuilder);
-
- if(token.split("-->").length == 1)
- return commentResetInbetween();
-
-
- this.currentState = commentResetInbetween();
-
- return close_tag(
- token.substring(token.indexOf("-->"))
- );
-
- }
-
- /**
- * Define the doctype
- * @param token document type
- * @return next state
- */
- private HTMLState doctype(String token) {
- String tag = stripTag(token);
- if(!tag.equalsIgnoreCase("HTML")) {
- /*
- Not implemented. Might do so in the future, might not.
- */
- }
-
- if(token.endsWith(">"))
- return HTMLState.TEXT;
- else
- return HTMLState.DOCTYPE;
- }
-
- // Helper methods
-
- /**
- * Reset inbetween state
- * @return previous inbetween state
- */
- private HTMLState commentResetInbetween() {
- HTMLState temp = this.inbetweenState;
-
- this.inbetweenState = HTMLState.COMMENT;
-
- return temp;
- }
-
- /**
- * Never forget to set the inbetween state!
- * @return HTMLState.COMMENT
- */
- private HTMLState returnCommentState() {
- this.inbetweenState = this.currentState;
- return HTMLState.COMMENT;
- }
-
- /**
- * Continue down without returning own State
- * @param token next token
- * @return this.currentState
- */
- private HTMLState nextTokenDontReturn(String token) {
- this.nextState(token);
-
- return this.currentState;
- }
-
- /**
- * Continue down without returning own State, and close the current tag
- * @param token next token
- * @return this.currentState
- */
- private HTMLState closeTagDontReturn(String token) {
- this.close_tag(token);
-
- return this.currentState;
- }
-
-
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/Interpreter.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/Interpreter.java
deleted file mode 100644
index 0b940cb..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/Interpreter.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.openautonomousconnection.htmlparser.interpreter;
-
-public interface Interpreter {
- void nextState(String token);
- boolean finished();
-
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/exception/ExpectStringException.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/exception/ExpectStringException.java
deleted file mode 100644
index afee1dd..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/exception/ExpectStringException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.openautonomousconnection.htmlparser.interpreter.html.exception;
-
-import org.openautonomousconnection.htmlparser.interpreter.html.state.HTMLState;
-
-public class ExpectStringException extends HTMLException {
- public ExpectStringException(String value, int currentLine, HTMLState currentState) {
- super("Expected string, got: " + value, currentLine, currentState);
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/exception/HTMLException.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/exception/HTMLException.java
deleted file mode 100644
index 449d2c6..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/exception/HTMLException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.openautonomousconnection.htmlparser.interpreter.html.exception;
-
-import org.openautonomousconnection.htmlparser.interpreter.html.state.HTMLState;
-
-public class HTMLException extends RuntimeException {
- public HTMLException(String message, int currentLine, HTMLState currentState) {
- super(message+ "\nat line: " + currentLine + "\nwith state: " + currentState.toString());
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/exception/UnexpectedTokenException.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/exception/UnexpectedTokenException.java
deleted file mode 100644
index f9ebf3d..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/exception/UnexpectedTokenException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.openautonomousconnection.htmlparser.interpreter.html.exception;
-
-import org.openautonomousconnection.htmlparser.interpreter.html.state.HTMLState;
-
-public class UnexpectedTokenException extends HTMLException {
- public UnexpectedTokenException(String token, int currentLine, HTMLState currentState) {
- super("Unexpected token: " + token, currentLine, currentState);
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/state/HTMLAttributeState.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/state/HTMLAttributeState.java
deleted file mode 100644
index d3827b4..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/state/HTMLAttributeState.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package org.openautonomousconnection.htmlparser.interpreter.html.state;
-
-public enum HTMLAttributeState {
- DECLARATION,
- EQUALS
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/state/HTMLState.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/state/HTMLState.java
deleted file mode 100644
index 583038f..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/html/state/HTMLState.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Author: maple
-// date: 9/24/25
-
-package org.openautonomousconnection.htmlparser.interpreter.html.state;
-
-public enum HTMLState {
- TAG,
- CLOSE_TAG,
- ATTRIBUTE,
- ATTRIBUTE_EQUALS,
- VALUE,
- TEXT,
- SCRIPT,
- COMMENT,
- DOCTYPE
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/script/ScriptInterpreter.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/script/ScriptInterpreter.java
deleted file mode 100644
index 9cc97d0..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/script/ScriptInterpreter.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Author: maple
-// date: 9/28/25
-
-package org.openautonomousconnection.htmlparser.interpreter.script;
-
-import lombok.Getter;
-import org.openautonomousconnection.StringUtils_Remove_Please;
-import org.openautonomousconnection.htmlparser.Parser;
-import org.openautonomousconnection.htmlparser.TagManager;
-import org.openautonomousconnection.htmlparser.interpreter.ElementBuilder;
-import org.openautonomousconnection.htmlparser.interpreter.Interpreter;
-
-public abstract class ScriptInterpreter implements Interpreter {
- @Getter
- protected Parser parser;
-
- @Getter
- protected ElementBuilder elementBuilder;
-
- protected TagManager tagManager;
-
- StringBuilder currentText = null;
-
- public int currentLine;
-
- public ScriptInterpreter(Parser parser) {
- this.parser = parser;
- this.tagManager = parser.getTagManager();
- }
-
- // We stole this spaghetti-abomination from chatgpt. Don't change it, it works (or do if you know better)
- public String parseScript(String html, int[] indexHolder) {
- if(this.currentText == null)
- this.currentText = new StringBuilder();
-
-
- int i = indexHolder[0];
- StringBuilder script = new StringBuilder();
-
- boolean inString = false;
- boolean inTriple = false;
- char stringChar = 0; // ' or "
- int tripleCount = 0;
-
- while (i < html.length()) {
- char c = html.charAt(i);
-
- if(c == '\n')
- this.currentLine++;
-
- if (!inString) {
- if (c == '\'' || c == '"') {
-
- int ahead = countSameQuotes(html, i, c);
- if (ahead >= 3) {
- inString = true;
- inTriple = true;
- stringChar = c;
- i += 3;
- script.append(stringChar).append(stringChar).append(stringChar);
- continue;
- } else {
- inString = true;
- inTriple = false;
- stringChar = c;
- }
- }
- } else {
- if (c == '\\') {
- script.append(c);
- i++;
- if (i < html.length())
- script.append(html.charAt(i));
- i++;
- continue;
- }
-
- if (inTriple) {
- int ahead = countSameQuotes(html, i, stringChar);
- if (ahead >= 3) {
- script.append(stringChar).append(stringChar).append(stringChar);
- i += 3;
- inString = false;
- inTriple = false;
- continue;
- }
- } else {
- if (c == stringChar) {
- inString = false;
- inTriple = false;
- }
- }
- }
-
- if (!inString) {
- int index = html.indexOf('>');
-
- if(index == -1)
- continue;
-
- String closingTag = html.substring(i, index);
-
- // if(this.tagManager.isTagSpaced(closingTag)) {
- if(StringUtils_Remove_Please.equalsIgnoreWhiteSpaces("", i)) {
-// indexHolder[0] = i + "".length();
-// return script.toString();
-// }
- }
-
- script.append(c);
- i++;
- }
-
- indexHolder[0] = i;
-
- this.currentText.append(script);
-
- return this.currentText.toString();
- }
-
- private int countSameQuotes(String s, int index, char quote) {
- int count = 0;
- int i = index;
- while (i < s.length() && s.charAt(i) == quote) {
- count++;
- i++;
- }
- return count;
- }
-
- @Override
- public boolean finished() {
- return this.currentText == null;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/script/javascript/JavaScriptInterpreter.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/script/javascript/JavaScriptInterpreter.java
deleted file mode 100644
index 45e6c4d..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/script/javascript/JavaScriptInterpreter.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Author: maple
-// date: 9/28/25
-
-package org.openautonomousconnection.htmlparser.interpreter.script.javascript;
-
-import lombok.Getter;
-import org.openautonomousconnection.StringUtils_Remove_Please;
-import org.openautonomousconnection.htmlparser.Parser;
-import org.openautonomousconnection.htmlparser.TagManager;
-import org.openautonomousconnection.htmlparser.interpreter.HTMLInterpreter;
-import org.openautonomousconnection.htmlparser.interpreter.script.ScriptInterpreter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class JavaScriptInterpreter extends ScriptInterpreter {
- // TODO: replace with actual interpreter
-
- @Getter
- private Parser parser;
- private TagManager tagManager;
-
- public JavaScriptInterpreter(Parser parser) {
- super(parser);
- this.parser = parser;
- this.tagManager = parser.getTagManager();
- }
-
- private boolean scriptFinished = false;
-
- private StringBuilder text = new StringBuilder();
-
- public String getText() {
- return this.text.toString();
- }
-
- boolean inSQ, inDQ;
-
- @Override
- public void nextState(String token) {
- String[] sorted = StringUtils_Remove_Please.containsManySorted(token, "\"", "'");
-
- this.text.append(token);
-
- if(sorted.length > 0)
- if(!sorted[0].isEmpty()) {
-
-
-
-// for(String s : token.split())
-
-
-// int indexQuoteChar = token.indexOf(quoteChar);
-
-
- // xor since this toggles the string case
- inSQ = sorted[0].equals("'") ^ inSQ;
- inDQ = sorted[0].equals("\"") ^ inDQ;
- }
-
-
-
-
- String[] split = token.split(sorted[0]);
-
-// if(!inSQ && !inDQ)
- }
-
- @Override
- public boolean finished() {
- return this.scriptFinished;
- }
-
-// private String[][] getTextWithStrings(String token) {
-// char previous = 0;
-//
-// int lastStringIndex = 0;
-//
-// List strings = new ArrayList<>(), tokens = new ArrayList<>();
-// for(char c : token.toCharArray()) {
-// if(this.isStringEncapsulator(c, previous)) {
-// if(this.inQuotes()) {
-// String string = token.substring(lastStringIndex, token.indexOf(c)-1);
-//
-// strings.add(string);
-//
-// token = string;
-// }
-// else
-//
-//
-// }
-//
-// }
-// }
-
- private boolean inQuotes() {
- return this.inDQ || this.inSQ;
- }
-
- private boolean isStringEncapsulator(char c, char previous) {
- boolean escaped = previous == '\\';
- if(c == '\'' && !escaped && !this.inDQ) {
- this.inSQ = !this.inSQ;
- return true;
- }
-
- else if (!escaped && !this.inSQ) {
- this.inDQ = !this.inDQ;
- return true;
- }
-
- return false;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/script/pyscript/PyScriptInterpreter.java b/src/main/java/org/openautonomousconnection/htmlparser/interpreter/script/pyscript/PyScriptInterpreter.java
deleted file mode 100644
index f244260..0000000
--- a/src/main/java/org/openautonomousconnection/htmlparser/interpreter/script/pyscript/PyScriptInterpreter.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.openautonomousconnection.htmlparser.interpreter.script.pyscript;
-
-import org.openautonomousconnection.htmlparser.Parser;
-import org.openautonomousconnection.htmlparser.interpreter.ElementBuilder;
-import org.openautonomousconnection.htmlparser.interpreter.script.ScriptInterpreter;
-
-public class PyScriptInterpreter extends ScriptInterpreter {
-
- public PyScriptInterpreter(Parser parser) {
- super(parser);
- }
-
- @Override
- public void nextState(String token) {
- if(this.elementBuilder == null)
- this.elementBuilder = new ElementBuilder(this.parser, "script");
- String r = this.parseScript(token, new int[] {0});
-
-// System.out.println(r);
-
-// if(r == null)
-// throw new UnexpectedTokenException("token", this.currentLine, HTMLState.SCRIPT);
-// if(this.finished())
-// this.currentElement = new HTMLScript(r);
-
- if(this.finished()) {
- this.elementBuilder.setText(r);
- System.out.println(r);
- }
-
- }
-//
-// @Override
-// public boolean finished() {
-// return this.currentElement != null;
-// }
-}