Have the LS notify the live preview about changes it initiates, so
the live preview can update its selection.
This is not possible for all edits the LS generates: Many are sent
to the editor which may or may not trigger them later, but the
notification happens when the LS adds changes on top of changes
requested by the live preview (e.g. by adding an import). This
fixes having a newly added element selected once it is rendered.
We need to decorate an Element so we can interact with it. I want
to decorate only *one* instance of a repeated element to avoid
cluttering up the screen. So pick one good candidate for decoration:
Ideally the one the user clicked on, got for the first one
otherwise.
Store this information so we can get it back after re-rendering,
and so that we can actually mark newly added elements for selection
after they get rendered.
Since the added Window no longer have a node, the current code that
checks that it has one doesn't work.
Instead, to skip the added window, just take the first element if the
root don't have a node
... and use it e.g. for the nodes the preview adds into the code itself.
Now that we mark the preview helper we add into the file as `ignore`, we
can make sure we never try to navigate to it. It was text that got
appended to the actual source code, so the editor tended to jump to the
end of the document when selecting the root element. That was created by
merging the artifical Preview node and the real root node, with the
artificial node being stored first.
The messages serialized through the LSP should use the LSP's url type.
And keep type information as long as possible.
Otherwise, we'd end up in show_document_request_from_element_callback
with either an URL or a path, depending if the preview is native or not,
and that would fail when re-serializing to an URL to send back to
through the LSP
This is a long odyssee :-/
I am back to file-based navigation now: The component-based navigation
felt so very tree-based again.
So you can click anywhere to select the "topmost" rendered element that
is defined in the same file that is getting previewed.
A double-click is again punching through the layers: It goes deeper into
the rendering layers, selecting an item at the same point but covered by
the current selection.
Ctrl makes the selection ignore file boundaries when picking something.
Shift reverses the search direction when double clicking: It will pick
an element in the click position that is rendered after the currently
selected item.
Try a more visual selection approach over the rather technical
tree-based one from earlier.
In this commit, a click selects the element that was rendered at the
click position *last*. I use rendered loosely here: It even takes
elements into account that are invisible but still cover the clicked
location.
A double-click punshes through to the item rendered earlier (behind) the
currently selected item that also covers the clicked position.
A shift-double-click moves towards the later rendered elements again,
usually undoing the last double-click.
It is tree based now: Allowing you to visit children, the siblings and
the parent of the current selection.
Advantage: You can actually get to all elements now, even those covered by
other elements.
Disadvantage: You basically need the document outline to make sense of
the navigation:-/
We need a more visual way to select elements! But how can we even tell
which elements are going to be visible in the UI and which are not?
Here is how you navigate in this PR:
* Click selects an element. If the click hits the currently selected
element, then it will do nothing. Otherwise it will look whether a
sibling was hit, working its way up the tree to the root element.
* Double-click selects a child of the current selection: the "foremost"
child that covers the click location will be selected.
* shift-double-click: Takes you to the current selections parent.
* Ctrl-click: Select a sibling of the current selected element "behind"
the sibling that covers the current click location.
* Shift-ctrl-click: Selects a sibling of the current selected element
in front of the current selection that cover s the click location.