Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype for node selection & copying elis - alternative version #234

Closed
wants to merge 1 commit into from

Conversation

andreasphil
Copy link
Member

@andreasphil andreasphil commented Apr 5, 2024

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:

  • It's a bit less elaborate and doesn't support as many features
  • Uses a slightly different approach (less "smart", more manual work, but therefore perhaps more robust and easier to understand)

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

  • Keeping track of the currently selected nodes
  • Toggling a selected class on the relevant nodes

For 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:

  • Again, register an event handler specifically for each relevant element
  • In the event handler, grab the rect and coordinates of the element
  • Use this information to fixed or absolutely position the UI
  • Unlike the other prototype: no slots or teleports

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:

  • No changes to the XSLT
  • The rendering is used to highlight stuff, provide a UI and to identify elements, not as the source for the data
  • The actual changes to the data always happen directly on the XML

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.

@andreasphil andreasphil added the do not merge For sharing prototypes or ideas that are not intended for merging label Apr 9, 2024
@andreasphil andreasphil changed the title [DO NOT MERGE] Prototype for node selection & copying elis - alternative version Prototype for node selection & copying elis - alternative version Apr 9, 2024
@andreasphil andreasphil force-pushed the risdev-3714-node-selection-prototype branch from 995cea1 to 16f50c7 Compare April 9, 2024 15:10
@malte-laukoetter
Copy link
Member

Closed for now, we implemented parts already, the "Additional UI in the Preview" parts are still in discussion but we don't want to keep this pr open

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do not merge For sharing prototypes or ideas that are not intended for merging
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants