Prototype for node selection & copying elis - alternative version #234
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
DO NOT MERGE - This is just a prototype and has neither tests nor documentation and includes changes that are just there to demonstrate the abilities of it. If we want to use (some of) this approach we should copy the needed parts to a new PR and add tests, docs, ...
Ideas tested in this prototype
This prototype broadly tries to achieve similar results as #233, but:
General approach
We're using an
init
function which is run whenever the HTML content of the preview changes. This function:Cleans up any artifacts (event handlers, etc.) from previous runs of
init
to make sure we're not producing memory leaks.Queries certain types of elements from the HTML and progressively enhances them, e.g. by registering event handlers and adding properties such as tab index and aria attributes for accessibility where applicable.
For each element, relevant additional information (e.g. the eId) is read from the
dataset
of the element and can be used by the event handler.This approach allows us to create event handlers that are very specific to each relevant element. This avoids the need of parsing the eId in order to get the type of the element.
Clicking on nodes
Currently all events are handled inside the
RisLawPreview
component, but for the actual application, the component should emit the event so it can be handled by the parent component instead.This can easily be done by making the event handlers emit an event similar to
content:click
in the other prototype, with the added benefit that the parent doesn't need to figure out the type of the element that is being clicked on.Highlighting selected nodes
This happens by
selected
class on the relevant nodesFor the actual application we would also put a v-model behind this so the selection is accessible to and can be managed from the outside. We can then watch the model and make the DOM changes accordingly.
Additional UI in the preview
This is not implemented in this prototype, but I would solve it somehow like this:
Loading data for inputs
Similarly to the other prototype, elements are identified by their type + eId, both pieces of information being available in the HTML. This information is used to find the element in XML and extract additional data.
I also tried parsing it from the HTML, but that seems unnecessarily complicated if it's all in the XML already.
Furthermore, I tried using
querySelector
instead of XPath. This feels more familiar and natural in the frontend, but I agree with @malte-laukoetter that it would be better to keep the selectors consistent with the backend, which will most likely use/already uses XPath.Saving data from the inputs
Just the other way around as loading: Query selectors in XML, replace data, send back to the backend using the XML endpoints.
Multiselect
See "Highlighting selected nodes" above.
Overall
Some principles are shared with the other prototype:
It diverges in that it doesn't use any Vue APIs or components for wiring up interactions or positioning UIs. Instead, it uses regular DOM APIs such as
addEventListener
,HTMLElement.dataset
, ... in an imperative way. While admittedly more verbose and less elegant, I prefer this approach because I believe it to be more robust and simpler to understand and extend.The important bit is that all this complexity is hidden inside the preview component and therefore contained in one specific spot.
Thoughts
For the reasons mentioned above, I prefer this approach to the teleports/slots approach of the other prototype, especially since that "is not 100% the way vue recommends using
<Teleport />
" (according to @malte-laukoetter)I also think it's a good idea to have individual, optimized listeners on all events instead of one big listener that manages all the possible cases.
Using XML as the data source in the frontend and manipulating that instead of using an abstraction such as a JSON API feels like the correct way to go—more flexible, less complexity both in the frontend and the backend, and we need the XML endpoints anyways for the code editors.
The XSLT doesn't need to include anything specifically for the preview except some high level information about element types and identifiers. Those can then be used to make the connection to the real data in the XML.
Also have some ideas how the
init
method could be turned into some kind of plug-in system that just calls/exposes certain methods of "plugins". We could then have plugins for change commands, articles, ... whatever. That way the entire thing would be quite modular and maybe a bit more manageable.