This introduces a much more consistent set of events within the editor
for whenever a element is added, removed or modified.
The events emited on the `RED.events` event system. The event names
take the form: `"<thing>:<action>"`.
`<thing>` can be one of:
- nodes
- flows
- subflows
- groups
- links
`<action>` can be one of:
- add
- remove
- change
The payload of the events is the object in question.
There is also:
- flows:reorder - when tabs are reordered. Payload is array of flow ids.
- workspace:clear - when the workspace is emptied - part of switching projects
The `nodes:change` event was already used by RED.nodes.dirty() to cause
the Deploy button to become active. This renames that event to:
- workspace:dirty - Payload is boolean flag for the dirty state
This commit also updates the Palette to use the subflows:change event to
only redraw subflows that have actually changed rather than refresh them
all whenever one of them *might* have changed. This removes a noticable
flicker of the icon which was needlessly being redrawn.
Fixes#2513
If a node inside a subflow accessed its context object in its
constructor, the subflow-instance flow context would not yet
have been created. This would cause a place holder context
to get created on its behalf, but that place holder doesn't
have its parent set properly. This then breaks the usage
of $parent inside such a subflow.
This fix has changed it so flows (and subflows) create their
flow context as part of their initial creation. That ensures
it exists when individual nodes from the subflow are created,
allowing them to safely access their context.
This has also fixed a related issue where any attempt to use
$parent to access beyond the root parent would seemingly hang
as the callback was never being called. This would cause
messages to get stuck in flows. The fix ensures the callback
is used in the root context objects and undefined is returned.
This moves the expensive redraw code out of the event handling phase
and onto the browser's repaint phase. This makes the event handling
more responsive, particularly when dragging a large number of nodes.
It also removes lots of unnecessary anonymous functions in the redraw
code that should also improve performance.