From 4d55ecb842fab83e25adfd2cac76bc6b1ba8d0da Mon Sep 17 00:00:00 2001 From: JJ Date: Tue, 27 Dec 2022 22:26:54 -0800 Subject: encapsulation is evil --- checkstyle.xml | 2 +- src/main/model/BrowserState.java | 12 +-- src/main/model/html/ElementNode.java | 26 ++---- src/main/model/html/HtmlParser.java | 6 +- src/main/model/html/Node.java | 2 +- src/main/model/html/TextNode.java | 2 +- src/main/model/layout/BlockLayout.java | 22 ++--- src/main/model/layout/DocumentLayout.java | 8 +- src/main/model/layout/InlineLayout.java | 31 ++++--- src/main/model/layout/Layout.java | 140 ++++++------------------------ src/main/ui/BrowserApp.java | 4 +- src/main/ui/BrowserBar.java | 1 - src/main/ui/BrowserCanvas.java | 20 ++--- src/main/ui/BrowserWindow.java | 6 +- src/test/model/html/HtmlParserTest.java | 25 +++--- 15 files changed, 99 insertions(+), 208 deletions(-) diff --git a/checkstyle.xml b/checkstyle.xml index 6db1154..1bed3c9 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -15,7 +15,7 @@ - + diff --git a/src/main/model/BrowserState.java b/src/main/model/BrowserState.java index 7b05f8c..7fb880f 100644 --- a/src/main/model/BrowserState.java +++ b/src/main/model/BrowserState.java @@ -4,8 +4,8 @@ import java.util.ArrayDeque; // This BrowserState class collects the stateful portions of the browser into one modelable class. public class BrowserState { - private ArrayDeque tabs; - private String currentTab; + private final ArrayDeque tabs; + public String currentTab; public BrowserState(ArrayDeque tabs, String currentTab) { this.tabs = tabs; @@ -16,14 +16,6 @@ public class BrowserState { return this.tabs; } - public String getCurrentTab() { - return this.currentTab; - } - - public void setCurrentTab(String tab) { - this.currentTab = tab; - } - public void addTab(String added) { if (!this.tabs.contains(added)) { this.tabs.add(added); diff --git a/src/main/model/html/ElementNode.java b/src/main/model/html/ElementNode.java index 3faf4ae..358d97c 100644 --- a/src/main/model/html/ElementNode.java +++ b/src/main/model/html/ElementNode.java @@ -8,10 +8,10 @@ import java.util.ArrayList; * This ElementNode class represents an HTML tag and nested tags. */ public class ElementNode implements Node { - private final String tag; - private final ArrayList> attributes; + public final String tag; + public final ArrayList> attributes; - private final ArrayList children; + public final ArrayList children; public ElementNode(String tag, ArrayList> attributes, ArrayList children) { this.tag = tag; @@ -33,24 +33,8 @@ public class ElementNode implements Node { this(tag, new ArrayList<>(), new ArrayList<>()); } - public void addChild(Node child) { - this.children.add(child); - } - - public String getTag() { - return this.tag; - } - - public ArrayList> getAttributes() { - return this.attributes; - } - - public ArrayList getChildren() { - return this.children; - } - // We implement this method for easy debugging. - public String getData() { - return getTag() + " " + getAttributes().toString(); + public String data() { + return this.tag + " " + this.attributes.toString(); } } diff --git a/src/main/model/html/HtmlParser.java b/src/main/model/html/HtmlParser.java index 5e5e7ce..a3abe0f 100644 --- a/src/main/model/html/HtmlParser.java +++ b/src/main/model/html/HtmlParser.java @@ -219,9 +219,9 @@ public class HtmlParser { // Helper function to remove code duplication. private void addNewElementNode() { state = ParserState.HTML; - ElementNode node = new ElementNode(currentTag, currentAttributes); + var node = new ElementNode(currentTag, currentAttributes); if (unfinished.size() != 0) { - unfinished.getLast().addChild(node); + unfinished.getLast().children.add(node); if (!isSelfClosingTag(currentTag)) { unfinished.add(node); } @@ -238,7 +238,7 @@ public class HtmlParser { // Helper function to check method length boxes. private void addNewTextNode() { if (unfinished.size() != 0) { - unfinished.getLast().addChild(new TextNode(currentText)); + unfinished.getLast().children.add(new TextNode(currentText)); } else { result.add(new TextNode(currentText)); } diff --git a/src/main/model/html/Node.java b/src/main/model/html/Node.java index 9a846ee..be217f6 100644 --- a/src/main/model/html/Node.java +++ b/src/main/model/html/Node.java @@ -6,5 +6,5 @@ package model.html; */ public interface Node { // Return a representation of the Node. Useful for debugging. - public String getData(); + public String data(); } diff --git a/src/main/model/html/TextNode.java b/src/main/model/html/TextNode.java index c50ce0f..29f2791 100644 --- a/src/main/model/html/TextNode.java +++ b/src/main/model/html/TextNode.java @@ -5,7 +5,7 @@ package model.html; */ public record TextNode(String text) implements Node { // We implement this method for easy debugging. - public String getData() { + public String data() { return text(); } } diff --git a/src/main/model/layout/BlockLayout.java b/src/main/model/layout/BlockLayout.java index 9204b61..9264035 100644 --- a/src/main/model/layout/BlockLayout.java +++ b/src/main/model/layout/BlockLayout.java @@ -12,20 +12,20 @@ public class BlockLayout extends Layout { // recursively construct the layout tree public void layout() { - this.setLocation(this.getParent().getLocation()); - this.getPreviousSibling().ifPresent( - sibling -> this.setY(sibling.getY() + sibling.getHeight())); - this.getPreviousSibling().ifPresent( - sibling -> System.out.println("bluh" + sibling.getAssociatedNode().getData())); + this.location = (Point) this.parent.location.clone(); + this.previousSibling.ifPresent( + sibling -> this.location.y = sibling.location.y + sibling.dimension.height); +// this.previousSibling.ifPresent( +// sibling -> System.out.println("bluh" + sibling.associatedNode.data())); -// this.setDimension(this.getParent().getDimension()); +// this.dimension = (Dimension) this.parent.dimension.clone(); - for (Layout child : this.getChildren()) { + for (Layout child : this.children) { child.layout(); - this.setHeight(this.getHeight() + child.getHeight()); + this.dimension.height += child.dimension.height; } -// System.out.println(this.getAssociatedNode().getData() + this.getLocation()); -// System.out.println(System.identityHashCode(this.getLocation())); -// System.out.println(this.getAssociatedNode().getData() + this.getDimension()); +// System.out.println(this.associatedNode.data() + this.location); +// System.out.println(System.identityHashCode(this.location)); +// System.out.println(this.associatedNode.data() + this.dimension); } } diff --git a/src/main/model/layout/DocumentLayout.java b/src/main/model/layout/DocumentLayout.java index 2e9d778..df2a1b9 100644 --- a/src/main/model/layout/DocumentLayout.java +++ b/src/main/model/layout/DocumentLayout.java @@ -15,12 +15,12 @@ public class DocumentLayout extends Layout { // recursively construct the layout tree public void layout() { - this.setLocation(new Point(10, 20)); - this.setDimension(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT)); + this.location = new Point(10, 20); + this.dimension = new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); - for (Layout child : this.getChildren()) { + for (Layout child : this.children) { child.layout(); - this.setHeight(this.getHeight() + child.getHeight()); + this.dimension.height += child.dimension.height; } } } diff --git a/src/main/model/layout/InlineLayout.java b/src/main/model/layout/InlineLayout.java index c4c51b5..845a717 100644 --- a/src/main/model/layout/InlineLayout.java +++ b/src/main/model/layout/InlineLayout.java @@ -2,7 +2,6 @@ package model.layout; import model.html.ElementNode; import model.html.Node; -import model.html.TextNode; import java.awt.*; @@ -17,36 +16,36 @@ public class InlineLayout extends Layout { // recursively construct the layout tree public void layout() { - this.setLocation(this.getParent().getLocation()); - this.getPreviousSibling().ifPresent( - sibling -> this.setY(sibling.getY() + sibling.getHeight())); + this.location = (Point) this.parent.location.clone(); // java moment + this.previousSibling.ifPresent( + sibling -> this.location.y = sibling.location.y + sibling.dimension.height); - this.setWidth(this.getParent().getWidth()); - this.setCursor(this.getX(), this.getY()); + this.dimension.width = this.parent.dimension.width; + this.setCursor(this.location.x, this.location.y); - Node node = this.getAssociatedNode(); + Node node = this.associatedNode; switch (node) { case ElementNode e -> { - if (e.getTag().equals("a")) { - this.setX(this.getX() + this.getParent().getWidth()); + if (e.tag.equals("a")) { + this.location.x += this.parent.dimension.width; } } default -> { - if (node.getData().length() > 5) { - this.setHeight(20); -// this.setWidth(this.getWidth() + node.getData().length()); + if (node.data().length() > 5) { + this.dimension.height = 20; +// this.dimension.width = this.dimension.width + node.data().length(); } } } - for (Layout child : this.getChildren()) { + for (Layout child : this.children) { child.layout(); - this.setHeight(this.getHeight() + child.getHeight()); // fixme + this.dimension.height += child.dimension.height; // fixme } // todo: recurse to calculate cursor -// this.setHeight(cursor.getY() - this.getY()); -// System.out.println(this.getAssociatedNode().getData() + this.getLocation()); +// this.height = cursor.location.y - this.location.y; +// System.out.println(this.associatedNode.data() + this.location); } public void setCursor(Point cursor) { diff --git a/src/main/model/layout/Layout.java b/src/main/model/layout/Layout.java index 5a19302..d9c3954 100644 --- a/src/main/model/layout/Layout.java +++ b/src/main/model/layout/Layout.java @@ -8,17 +8,20 @@ import java.util.*; // Generic Layout class public abstract class Layout { - private Point location; - private Dimension dimension; + // fuck encapsulation all my homies hate encapsulation + // but seriously, what a garbage idea: get a better language + // (please read the above comment in the voice of https://www.youtube.com/watch?v=EdWSg6YwUeo) + public Point location; + public Dimension dimension; - private Node associatedNode; - private Layout parent; - private Optional previousSibling; - private Optional nextSibling; - private ArrayList children; + public final Node associatedNode; + public final Layout parent; + public Optional previousSibling; + public Optional nextSibling; + public ArrayList children; - public static final int DEFAULT_WIDTH = 1920; - public static final int DEFAULT_HEIGHT = 1080; + public static final int DEFAULT_WIDTH = 1000; + public static final int DEFAULT_HEIGHT = 800; // https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements public static final Set BLOCK_ELEMENTS = new HashSet<>( @@ -46,125 +49,36 @@ public abstract class Layout { // eh, probably the best place to put this // parent MAY BE nil: a handy call to Optional.ofNullable allows this public static ArrayList constructTree(ArrayList html, Layout parent) { - ArrayDeque result = new ArrayDeque<>(); + var result = new ArrayDeque(); for (Node node : html) { Layout layout; - if (node instanceof ElementNode) { - if (BLOCK_ELEMENTS.contains(((ElementNode) node).getTag())) { - layout = new BlockLayout(node, parent); - } else { + switch (node) { + case ElementNode e -> { + if (BLOCK_ELEMENTS.contains(e.tag)) { + layout = new BlockLayout(node, parent); + } else { + layout = new InlineLayout(node, parent); + } + layout.children = constructTree(e.children, layout); + } + default -> { layout = new InlineLayout(node, parent); } - layout.setChildren(constructTree(((ElementNode) node).getChildren(), layout)); - } else { - layout = new InlineLayout(node, parent); } if (result.size() > 0) { - layout.setPreviousSibling(result.getLast()); - result.getLast().setNextSibling(layout); + layout.previousSibling = Optional.of(result.getLast()); + result.getLast().nextSibling = Optional.of(layout); } - result.add(layout); } return new ArrayList<>(result); // haha } public static DocumentLayout constructTree(ArrayList html) { - DocumentLayout result = new DocumentLayout(); - result.setChildren(constructTree(html, result)); + var result = new DocumentLayout(); + result.children = constructTree(html, result); result.layout(); return result; } - - // man, fuck design patterns, this is so much goddamn code - - public void setLocation(Point point) { - this.location.x = point.x; - this.location.y = point.y; - } - - public void setX(double x) { - this.location.setLocation(x, this.getLocation().getY()); - } - - public void setY(double y) { - this.location.setLocation(this.getLocation().getX(), y); - } - - public void setDimension(Dimension dimension) { - this.dimension = dimension; - } - - public void setDimension(double x, double y) { - this.dimension.setSize(x, y); - } - - public void setWidth(double width) { - this.dimension.setSize(width, this.getDimension().getWidth()); - } - - public void setHeight(double height) { - this.dimension.setSize(this.getDimension().getHeight(), height); - } - - public void setPreviousSibling(Layout sibling) { - this.previousSibling = Optional.ofNullable(sibling); - } - - public void setNextSibling(Layout parent) { - this.nextSibling = Optional.ofNullable(parent); - } - - public void setChildren(ArrayList children) { - this.children = children; - } - - public void addChild(Layout child) { - this.children.add(child); - } - - public Node getAssociatedNode() { - return this.associatedNode; - } - - public Point getLocation() { - return this.location; - } - - public double getX() { - return this.location.getX(); - } - - public double getY() { - return this.location.getY(); - } - - public Dimension getDimension() { - return this.dimension; - } - - public double getWidth() { - return this.dimension.getWidth(); - } - - public double getHeight() { - return this.dimension.getHeight(); - } - - public Layout getParent() { - return this.parent; - } - - public Optional getPreviousSibling() { - return this.previousSibling; - } - - public Optional getNextSibling() { - return this.nextSibling; - } - - public ArrayList getChildren() { - return this.children; - } } diff --git a/src/main/ui/BrowserApp.java b/src/main/ui/BrowserApp.java index 36f2005..6f871c5 100644 --- a/src/main/ui/BrowserApp.java +++ b/src/main/ui/BrowserApp.java @@ -45,10 +45,10 @@ public class BrowserApp { for (Node node: html) { switch (node) { case ElementNode e -> { - renderHtml(e.getChildren()); + renderHtml(e.children); } default -> { - println(node.getData()); + println(node.data()); } } } diff --git a/src/main/ui/BrowserBar.java b/src/main/ui/BrowserBar.java index 131fe19..8026e49 100644 --- a/src/main/ui/BrowserBar.java +++ b/src/main/ui/BrowserBar.java @@ -29,7 +29,6 @@ public class BrowserBar extends JToolBar { openUriButton = new JButton("Go"); openUriButton.addActionListener(openTab()); add(openUriButton); - } private ActionListener openTab() { diff --git a/src/main/ui/BrowserCanvas.java b/src/main/ui/BrowserCanvas.java index 43481ef..ea20e81 100644 --- a/src/main/ui/BrowserCanvas.java +++ b/src/main/ui/BrowserCanvas.java @@ -13,13 +13,13 @@ public class BrowserCanvas extends JPanel { public BrowserCanvas(ArrayList html) { super(); this.currentLayout = Layout.constructTree(html); - printTree(this.currentLayout.getChildren()); + printTree(this.currentLayout.children); } private void printTree(ArrayList tree) { for (Layout node : tree) { - System.out.println(System.identityHashCode(node.getLocation())); - printTree((node).getChildren()); +// System.out.println(System.identityHashCode(node.location)); + printTree((node).children); } } @@ -27,21 +27,21 @@ public class BrowserCanvas extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); Point location = new Point(10, 20); // we need a mutable reference - renderHtml(this.currentLayout.getChildren(), g, location); + renderHtml(this.currentLayout.children, g, location); } private void renderHtml(ArrayList tree, Graphics g, Point location) { for (Layout layout : tree) { -// System.out.println(layout.getLocation()); - g.drawRect(layout.getLocation().x, layout.getLocation().y, layout.getDimension().width, layout.getDimension().height); - if (layout.getAssociatedNode() instanceof TextNode) { - if (layout.getAssociatedNode().getData().length() > 5) { +// System.out.println(layout.location); + g.drawRect(layout.location.x, layout.location.y, layout.dimension.width, layout.dimension.height); + if (layout.associatedNode instanceof TextNode) { + if (layout.associatedNode.data().length() > 5) { // System.out.println(location); - g.drawString(layout.getAssociatedNode().getData(), layout.getLocation().x, layout.getLocation().y); + g.drawString(layout.associatedNode.data(), layout.location.x, layout.location.y); g.drawString("X", 10, 20); } } else { - renderHtml(layout.getChildren(), g, location); + renderHtml(layout.children, g, location); } } } diff --git a/src/main/ui/BrowserWindow.java b/src/main/ui/BrowserWindow.java index 94bd2d8..abf164f 100644 --- a/src/main/ui/BrowserWindow.java +++ b/src/main/ui/BrowserWindow.java @@ -32,11 +32,11 @@ public class BrowserWindow extends JFrame { } public void render(String uri) { - state.setCurrentTab(uri); + state.currentTab = uri; remove(canvas); -// System.out.println(state.getCurrentTab()); +// System.out.println(state.currentTab); try { - String file = Files.readString(Path.of(state.getCurrentTab())); + String file = Files.readString(Path.of(state.currentTab)); HtmlParser parser = new HtmlParser(); canvas = new BrowserCanvas(parser.parseHtml(file)); } catch (Exception e) { diff --git a/src/test/model/html/HtmlParserTest.java b/src/test/model/html/HtmlParserTest.java index 879f316..4a35320 100644 --- a/src/test/model/html/HtmlParserTest.java +++ b/src/test/model/html/HtmlParserTest.java @@ -85,10 +85,12 @@ public class HtmlParserTest { */ private static void assertEqualsHtml(ArrayList html, ArrayList expected) { for (int i = 0; i < html.size(); i++) { - assertEquals(html.get(i).getData(), expected.get(i).getData()); + assertEquals(html.get(i).data(), expected.get(i).data()); // System.out.println(html.get(i).getData() + " " + expected.get(i).getData()); - if (html.get(i) instanceof ElementNode) { - assertEqualsHtml(((ElementNode) html.get(i)).getChildren(), ((ElementNode) expected.get(i)).getChildren()); + switch (html.get(i)) { + case ElementNode e -> + assertEqualsHtml(e.children, ((ElementNode) expected.get(i)).children); + default -> {} } } } @@ -99,15 +101,16 @@ public class HtmlParserTest { */ private void displayHtmlTree(ArrayList tree) { for (Node node : tree) { - if (node instanceof ElementNode) { - System.out.print(((ElementNode) node).getTag() + ": "); - for (Node n : ((ElementNode) node).getChildren()) { - System.out.print(n.getData() + " "); + switch (node) { + case ElementNode e -> { + System.out.print(e.tag + ": "); + for (Node n : e.children) { + System.out.print(n.data() + " "); + } + System.out.println(); + displayHtmlTree(e.children); } - System.out.println(); - displayHtmlTree(((ElementNode) node).getChildren()); - } else { - System.out.println("Text: " + node.getData()); + default -> System.out.println("Text: " + node.data()); } } } -- cgit v1.2.3-70-g09d2