Julie's Document Website / Delphi Menu Engine / Dev Journal / DOM Restructuring And Lots of Boring Systems
Publish Date
2025-02-19 18:00:00 +0200 UTC
Author
Julie

DOM Restructuring And Lots of Boring Systems

19-02-2025

Table Of Contents

Intro

Yeah, I kinda forgot about this project after I got a bit burned out. But I'm back and with some major changes to the structure of the API and the DOM tree.

But before all that, little sneak peek at the dev tools I started working on:

I'm just proud of how all of highlighting stuff and CSS style changing on the fly works.

DOM Restructuring

For context, before this, the actual part of the document represented by Delphi's API was the <body> element. No other parts like the head, or the root <page> element were not accessible. Those elements were parsed specially by the SAX parser and then disregarded.

That has changed, now the entire document's XML is represented inside the API. Mostly, this meant a big boring challenge for me to change things around. Before I needed only to worry about the DOM head elements during parsing, and that was it, now I needed DOM elements to represent them. Elements that could change arbitrarily at any time.

To make this task easier, I came up with a thing called ObjectModelSystems. Think of them like Systems, and think of elements like Components inside an Entity Component Framework.

And now, after 2 days of boring work I have created the following systems.

OptionElementSystem

This keeps the <option> elements in the head synced up to the actual options accessible through

Document.getOption(String name).

The difficulty with this system was figuring out how to handle the option element itself. Because it used 2 attributes "name" and "value" to store the option's value, and tracking both confused me.

I dropped support for the <options> element completely. It was too much to keep that synced up as well.

StyleElementSystem

This isn't the CSSOM system itself, just the system that keeps the stylesheets linked to and parsed from style elements synced.

When making this, I made a decision that set the precedent for the next 3 systems as well. This being that a style element can link a stylesheet with the "src" attribute, or specify the stylesheet in the text content of the element.

I opted to lock the "content source" to one type and only listen to changes to that type. This means that if you set the style element to use the "src" attribute, then it will not care about any changes to the element's content until the attribute is unset. This applies vice versa as well to the text content.

There was also a 2nd issue that would need solving. The systems that sync and handle all of these things are located in the delphidom module, but methods that access module files (loadItemStack(uri) and loadStylesheet(uri)) were implemented in the delphiplugin module. So these systems require that the document's view be initialized.

This was solved by just storing all the style elements that exist and iterating over them after the view had been initialized to check if they needed to fetch a stylesheet through the loader.

ItemElementSystem and ComponentElementSystem

These 2 function effectively identically but for different elements. The first, ItemElementSystem, handles <item> elements. The second, ComponentElementSystem handles <chat-component> elements. The most major difference with these from the previous style element system is that instead of requiring the document's view to be initialized for the "src" attribute to be loaded, they require it for both the attribute and for the text content.

Tag changes

Some tag names were changed because I felt the tag names should either match HTML names, or might be too broad to reserve them for system.

<page> renamed to <delphi>
The <page> (Now <delphi>) is the root element of any Delphi XML file. The "page" tag felt too broad to reserve as the root tag of a document.
<header> renamed to <head>
Consistency with HTML's <head> tag. And there's also the fact that "header" is an actual term for the top part of a document, so again, it felt wrong to reserve it as the keyword for a document's metadata section.
Dropping support for the <options> tag
The options tag allowed you to specify multiple options inside one XML element, like this:
1
<options screen-width="2" screen-height="3"/>

This was too much to manage with the aforementioned dom refactoring. So I dropped support for it.

Miscellaneous Stuff

I dropped a literally useless root function argument from all selectors (Test function signature used to be: boolean test(Element root, Element element)). That argument does not mean the root of the DOM tree, but rather the root element at which the query was started. I added that, because of a misunderstanding with how CSS selectors function.

Worries

This is a section that will just describe some of my issues or bugs that will probably pop up.


Notes

  1. ‘Content source’ means the source of the element’s data. This is a value that can be in one of 3 states: none, src_attribute or text_content
  2. The delphidom module is the DOM API implementation and parser. It can only access the DOM API and Chimera’s SCSS
  3. Contains Delphi’s plugin code: commands, event listeners, DocumentView implementation and module system implementation. Notably, it is also the only module with access to the backend code of Bukkit. That access is required to load item stacks.