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/pom.xml b/pom.xml index 6fe652a..701afab 100644 --- a/pom.xml +++ b/pom.xml @@ -51,11 +51,6 @@ unlegitlibrary 1.6.2 - - org.python - jython-standalone - 2.7.4 - \ No newline at end of file diff --git a/src/main/java/org/openautonomousconnection/StringUtils_Remove_Please.java b/src/main/java/org/openautonomousconnection/StringUtils_Remove_Please.java deleted file mode 100644 index 3ba996b..0000000 --- a/src/main/java/org/openautonomousconnection/StringUtils_Remove_Please.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.openautonomousconnection; - -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Will be removed once UnlegitLibrary.StringUtils contains these methods - */ - -@Deprecated(since = "1.0") -public class StringUtils_Remove_Please { - - public static boolean equalsIgnoreWhiteSpaces(String s1, String s2) { - - return s1.replaceAll("\\s", "") - .equalsIgnoreCase(s2.replaceAll("\\s", "")); - } - - public static String[] splitSeq(String[] tokens, String seq) { - List _tokens = new ArrayList<>(); - - for(int i = 0; i < tokens.length; i++) { - String s = tokens[i]; - - if(!s.contains(seq)) { - _tokens.add(s); - continue; - } - - String[] split = s.split(seq); - - for(int j = 0; j < split.length-1; j++) - _tokens.add(split[j] + seq); - - if(s.endsWith(seq)) - _tokens.add(split[split.length-1] + seq); - else - _tokens.add(split[split.length-1]); - - - } - - String lastToken = _tokens.getLast(); - - if(!lastToken.isEmpty()) - _tokens.set(_tokens.size()-1, lastToken.substring(0, lastToken.length()-1)); - - return _tokens.toArray(new String[0]); - } - - public static int countSeq(String string, String seq) { - int amount = -1; - - for(String s : string.split(seq)) - amount++; - - return amount; - } - - public static List> getEncapsulatedTexts(String text, String... capsules) { - List> lists = new ArrayList<>(); - - lists.add(new ArrayList<>()); - lists.add(new ArrayList<>()); - - while (!text.isEmpty()) - { - String capsule = containsManySorted(text, capsules)[0]; - - if(capsule.isEmpty()) { - lists.getFirst().add(text); - break; - } - - - String out = text.substring(0, text.indexOf(capsule)); - - text = text.substring(text.indexOf(capsule) + capsule.length()); - - String in = text.substring(0, text.indexOf(capsule)); - - text = text.substring(text.indexOf(capsule) + capsule.length()); - - lists.get(0).add(out); - lists.get(1).add(in); - - } - - return lists; - } - - public static String[] containsMany(String string, String... strings) { - String[] result = new String[strings.length]; - - for(int i = 0; i < strings.length; i++) - if(string.contains(strings[i])) - result[i] = strings[i]; - - return result; - } - - public static String[] containsManySorted(String string, String... strings) { - String[] result = new String[strings.length]; - - StringPositionSorted[] records = new StringPositionSorted[strings.length]; - - for(int i = 0; i < strings.length; i++) - if(string.contains(strings[i])) - records[i] = new StringPositionSorted(strings[i], string.indexOf(strings[i])); - else - records[i] = new StringPositionSorted("", -1); - - Arrays.sort(records); - - int off = 0; - - for(int i = 0; i + off < strings.length; i++) { - while (records[i + off].position == -1 && - i + off + 1 < strings.length) - off++; - result[i] = records[i + off].string(); - } - - return result; - } - - private record StringPositionSorted(String string, int position) implements Comparable { - @Override - public int compareTo(@NotNull StringPositionSorted o) { - return this.position - o.position; - } - } -} diff --git a/src/main/java/org/openautonomousconnection/htmlparser/DocumentBuilder.java b/src/main/java/org/openautonomousconnection/htmlparser/DocumentBuilder.java deleted file mode 100644 index a7a469f..0000000 --- a/src/main/java/org/openautonomousconnection/htmlparser/DocumentBuilder.java +++ /dev/null @@ -1,157 +0,0 @@ -// Author: maple -// date: 9/24/25 - -package org.openautonomousconnection.htmlparser; - -import dev.unlegitdqrk.unlegitlibrary.string.StringUtils; -import org.openautonomousconnection.htmlparser.html.body.misc.HTMLComment; -import lombok.Getter; -import lombok.Setter; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class DocumentBuilder { - @Getter @Setter - protected String content; - - @Getter - protected List comments; - - @Getter - protected List attributes, texts, tags; - - public DocumentBuilder(String content) { - this.content = content; //content.replace("\n", ""); - this.comments = new ArrayList<>(); - this.attributes = new ArrayList<>(); - this.texts = new ArrayList<>(); - } - - /** - * Extracts all comments and strings into lists - */ - public void extract() { - this.extractComments(); - this.extractStringsAndAttributes(); - this.extractTexts(); - - } - - /** - * inserts the extracts back into the content string - */ - public void insert() { - this.insertTexts(); - this.insertStringsAndAttributes(); - this.insertComments(); - } - - protected void extractComments() { - Pattern pattern = Pattern.compile("", Pattern.DOTALL); - - Matcher matcher = pattern.matcher(content); - - - int index = 0; - - while (matcher.find()) { - this.content = this.content.replace("", ""); - - this.comments.add(new HTMLComment(matcher.group(1))); - - index++; - } - } - - protected void insertComments() { - if(this.comments.isEmpty()) - return; - - int i = 0; - for(; i < this.comments.size(); i++) - this.content = this.content.replace("", this.comments.get(i).toString()); - - for(; i > 0; i--) - this.comments.removeFirst(); - } - - - - protected void extractStringsAndAttributes() { - Pattern pattern = Pattern.compile("\"(.*?)\"|'(.*?)'", Pattern.DOTALL); - - Matcher matcher = pattern.matcher(this.content); - - - int index = 0; - - while (matcher.find()) { - - if(matcher.group(1) != null) { - this.content = this.content.replace("\"" + matcher.group(1) + "\"", "\"S" + index + "\""); - - this.attributes.add(matcher.group(1)); - } - - else { - this.content = this.content.replace("'" + matcher.group(2) + "'", "'S" + index + "'"); - - this.attributes.add(matcher.group(2)); - } - - index++; - } - } - - protected void insertStringsAndAttributes() { - if(this.attributes.isEmpty()) - return; - int i = 0; - for(; i < this.attributes.size(); i++) { - this.content = this.content.replace("\"S" + i + "\"", "\"" + attributes.get(i) + "\""); - this.content = this.content.replace("'S" + i + "'", "'" + attributes.get(i) + "'"); - } - - for(; i > 0; i--) - this.attributes.removeFirst(); - } - - protected void extractTexts() { - Pattern pattern = Pattern.compile(">([^<]+)(?=<)", Pattern.DOTALL); - - Matcher matcher = pattern.matcher(content); - - - int index = 0; - - while (matcher.find()) { - if(StringUtils.isEmptyString(matcher.group(1))) - continue; - - this.content = this.content.replace(">" + matcher.group(1) + "<", ">T" + index + "<"); - - this.texts.add(matcher.group(1)); - - index++; - } - } - - protected void insertTexts() { - if(this.texts.isEmpty()) - return; - - int i = 0; - for(; i < this.texts.size(); i++) - this.content = this.content.replace(">T" + i + "<", ">" + this.texts.get(i) + "<"); - - for(; i > 0; i--) - this.texts.removeFirst(); - } - - protected void extractTags() { - - } -} diff --git a/src/main/java/org/openautonomousconnection/htmlparser/HtmlApp.java b/src/main/java/org/openautonomousconnection/htmlparser/HtmlApp.java new file mode 100644 index 0000000..3d64618 --- /dev/null +++ b/src/main/java/org/openautonomousconnection/htmlparser/HtmlApp.java @@ -0,0 +1,106 @@ +package org.openautonomousconnection.htmlparser; + +import org.openautonomousconnection.htmlparser.css.*; +import org.openautonomousconnection.htmlparser.dom.Document; +import org.openautonomousconnection.htmlparser.dom.Element; +import org.openautonomousconnection.htmlparser.events.Event; + +import javax.swing.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Map; + +public class HtmlApp { + private final SwingRendererPanel panel = new SwingRendererPanel(); + + private Document document; + private Stylesheet stylesheet; + private Map computed; + private LayoutTree layout; + + public void load(String htmlSource) { + MiniParser.ParsedPage parsed = MiniParser.parse(htmlSource); + + this.document = parsed.document; + this.stylesheet = CssParser.parse(parsed.styleText); + + // basic demo events: click on #btn changes text via Java listener + Element btn = document.getElementById("btn"); + if (btn != null) { + btn.addEventListener("click", e -> { + Element out = document.getElementById("out"); + if (out != null) out.setText("clicked (java event) ✅"); + rerender(); + }); + } + + rerender(); + } + + private void rerender() { + this.computed = StyleEngine.compute(document.getRoot(), stylesheet); + this.layout = LayoutEngine.layout(document.getRoot(), computed, panel.getWidth() <= 0 ? 900 : panel.getWidth()); + panel.setScene(layout, computed); + } + + public JComponent ui() { + panel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + // super-minimal hit test: first element box that contains point triggers click + if (layout == null) return; + for (var box : layout.boxes) { + if (box.isText()) continue; + if (e.getX() >= box.x && e.getX() <= box.x + box.w && + e.getY() >= box.y && e.getY() <= box.y + box.h) { + box.element.dispatchEvent(new Event("click", true)); + rerender(); + break; + } + } + } + }); + return panel; + } + + public static void main(String[] args) { + // Beispiel HTML-Quellcode + String demo = """ + + + + +
+
Mini HTML Demo
+
pyscript ran: no
+
click me
+
+ + + + + + """; + + // Erstelle das GUI und lade das Beispiel + SwingUtilities.invokeLater(() -> { + HtmlApp app = new HtmlApp(); + JFrame f = new JFrame("html Renderer"); + f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + f.setSize(900, 600); + f.setContentPane(app.ui()); + f.setVisible(true); + + app.load(demo); // Lädt das HTML-Dokument und startet die PyScript-Verarbeitung + }); + } +} diff --git a/src/main/java/org/openautonomousconnection/htmlparser/MiniParser.java b/src/main/java/org/openautonomousconnection/htmlparser/MiniParser.java new file mode 100644 index 0000000..d6438cd --- /dev/null +++ b/src/main/java/org/openautonomousconnection/htmlparser/MiniParser.java @@ -0,0 +1,141 @@ +package org.openautonomousconnection.htmlparser; + +import org.openautonomousconnection.htmlparser.dom.Document; +import org.openautonomousconnection.htmlparser.dom.Element; +import org.openautonomousconnection.htmlparser.dom.TextNode; + +import java.util.ArrayDeque; +import java.util.Deque; + +public class MiniParser { + + public static final class ParsedPage { + public final Document document; + public final String styleText; + public final String pyText; + + public ParsedPage(Document document, String styleText, String pyText) { + this.document = document; + this.styleText = styleText; + this.pyText = pyText; + } + } + + public static ParsedPage parse(String src) { + Element root = new Element("html"); + Document doc = new Document(root); + + StringBuilder style = new StringBuilder(); + StringBuilder py = new StringBuilder(); + + Deque stack = new ArrayDeque<>(); + stack.push(root); + + int i = 0; + while (i < src.length()) { + char c = src.charAt(i); + + if (c == '<') { + int gt = src.indexOf('>', i + 1); + if (gt < 0) { + stack.peek().appendChild(new TextNode(src.substring(i))); + break; + } + + String inside = src.substring(i + 1, gt).trim(); + i = gt + 1; + + if (inside.startsWith("!")) continue; + + boolean closing = inside.startsWith("/"); + if (closing) { + String tag = inside.substring(1).trim().toLowerCase(); + while (stack.size() > 1 && !stack.peek().tag().equals(tag)) stack.pop(); + if (stack.size() > 1) stack.pop(); + continue; + } + + boolean selfClose = inside.endsWith("/"); + if (selfClose) inside = inside.substring(0, inside.length() - 1).trim(); + + String tag = readName(inside).toLowerCase(); + Element el = new Element(tag); + + // attributes + readAttrs(inside, el); + + // capture ".length(); + } + continue; + } + if (tag.equals("script")) { + int end = indexOfClose(src, "script", i); + if (end >= 0) { + py.append(src, i, end); + i = end + "".length(); + } + continue; + } + + stack.peek().appendChild(el); + if (!selfClose) stack.push(el); + continue; + } + + int next = src.indexOf('<', i); + if (next < 0) next = src.length(); + String text = src.substring(i, next); + if (!text.isBlank()) stack.peek().appendChild(new TextNode(text)); + i = next; + } + + return new ParsedPage(doc, style.toString(), py.toString()); + } + + private static String readName(String s) { + int i = 0; + while (i < s.length() && !Character.isWhitespace(s.charAt(i))) i++; + return i == 0 ? "div" : s.substring(0, i); + } + + private static void readAttrs(String inside, Element el) { + int i = 0; + while (i < inside.length() && !Character.isWhitespace(inside.charAt(i))) i++; + while (i < inside.length()) { + while (i < inside.length() && Character.isWhitespace(inside.charAt(i))) i++; + if (i >= inside.length()) break; + + int eq = inside.indexOf('=', i); + if (eq < 0) break; + + String key = inside.substring(i, eq).trim(); + i = eq + 1; + + String val; + if (i < inside.length() && (inside.charAt(i) == '"' || inside.charAt(i) == '\'')) { + char q = inside.charAt(i++); + int end = inside.indexOf(q, i); + if (end < 0) break; + val = inside.substring(i, end); + i = end + 1; + } else { + int end = i; + while (end < inside.length() && !Character.isWhitespace(inside.charAt(end))) end++; + val = inside.substring(i, end); + i = end; + } + + el.setAttribute(key, val); + } + } + + private static int indexOfClose(String src, String tag, int from) { + String needle = ""; + return src.toLowerCase().indexOf(needle, from); + } +} diff --git a/src/main/java/org/openautonomousconnection/htmlparser/ParseResult.java b/src/main/java/org/openautonomousconnection/htmlparser/ParseResult.java deleted file mode 100644 index e73b81b..0000000 --- a/src/main/java/org/openautonomousconnection/htmlparser/ParseResult.java +++ /dev/null @@ -1,18 +0,0 @@ -// Author: maple -// date: 9/24/25 - -package org.openautonomousconnection.htmlparser; - -import org.jetbrains.annotations.NotNull; - -public record ParseResult(String tagname, String assumption) implements Comparable { - - public int compareSelf() { - return this.tagname.compareToIgnoreCase(this.assumption); - } - - @Override - public int compareTo(@NotNull ParseResult o) { - return this.compareSelf() - o.compareSelf(); - } -} diff --git a/src/main/java/org/openautonomousconnection/htmlparser/Parser.java b/src/main/java/org/openautonomousconnection/htmlparser/Parser.java deleted file mode 100644 index d615ec7..0000000 --- a/src/main/java/org/openautonomousconnection/htmlparser/Parser.java +++ /dev/null @@ -1,105 +0,0 @@ -// Author: maple -// date: 9/20/25 - -package org.openautonomousconnection.htmlparser; - -import org.openautonomousconnection.htmlparser.html.CustomHTMLElement; -import org.openautonomousconnection.htmlparser.html.HTML; -import org.openautonomousconnection.htmlparser.html.HTMLElement; -import org.openautonomousconnection.htmlparser.interpreter.HTMLInterpreter; -import lombok.Getter; -import org.openautonomousconnection.htmlparser.interpreter.script.pyscript.PyScriptInterpreter; - -import java.util.Arrays; -import java.util.Objects; - -import static org.openautonomousconnection.StringUtils_Remove_Please.splitSeq; - - -public class Parser { - - public static String DEFAULT_TITLE = "untitled"; - - @Getter - private final TagManager tagManager; - - @Getter - private HTML html; - - private final String[] tokens; - - public Parser(String content, TagManager tagManager) { - - this.html = new HTML(); - this.tagManager = tagManager; - - String[] split = splitSeq(new String[]{content}, ">"); - - // TODO: you can do this using regex \\s in one line instead of 3 - - String[] split_spaces = splitSeq(split, " "); - String[] split_tabs = splitSeq(split_spaces, "\t"); - - this.tokens = splitSeq(split_tabs, "\n"); - -// for(String s : tokens) -// System.out.print(s); -// System.out.println(); - -// List> l = StringUtils_Remove_Please.getEncapsulatedTexts(""" -// -// part UNO"part dos'stillpartdos'" 'PART TRES YAYAYYA' and gone bye. -// -// """, "\"", "'"); -// -// for(List 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 getByTagname(String tagName) { - tagName = tagName.toLowerCase(); - - Class 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 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 ""; - } - - protected String cutTag(String string, String _attributes) { - return string.replaceFirst("<" + tagName + " " + _attributes + ">", "").replaceFirst("", "").trim(); - } - - protected String cutTag(String string) { - return cutTag(string, ""); - } - -// protected static Class 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 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 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 + '>' : ""; - - 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("") || 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; -// } -}