I've tried onclick but that gets removed when the markdown is rendered. Instead I started using this href="#node/01236b2a218a1740" but that's not working ... any ideas?
What I really want to do is a RED.search.show('function 2'); to avoid hardcoding the node id. That could be done in the onclick of the link. Or add the support of an extra data attribute data-search='function 2' on any documentional link (to avoid phishing).
[{"id":"cf62fec0c5a535cf","type":"function","z":"6a4884ae4f27e246","name":"function 1","func":"\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":454.375,"y":492.5,"wires":[[]],"info":"<a href=\"#node/01236b2a218a1740\">Function 2</a> does all the work."},{"id":"01236b2a218a1740","type":"function","z":"6a4884ae4f27e246","name":"function 2","func":"\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":668.125,"y":671.25,"wires":[[]]}]
I did think about (and ask, and look into) this for comment nodes but they are rendered in SVG (so was not simple).
Now we have the popover (which is HTML) we could permit specially crafted markdown hyperlinks e.g. [function 2](#node/01236b2a218a1740) that when rendered attach a click handler to call the appropriate RED function (we do something similar in FlowFuse)
At the moment, we have deep-linking for opening (and editing) nodes in the form of http://<ip>/#node/55820643ea60d8cd and they CAN be rendered as hyperlinks and DO work (e.g. [see function 2](http://<ip>/#node/55820643ea60d8cd)) but they cause new tab to be opened due to having _blank target.
In theory, a plugin could target the content of the popover (.red-ui-flow-annotation-popover-body) and specially crafted text (or anchors with a particular attribute) could be modified to have a click handler that ultimately calls RED.view.reveal('a411ef027c9d796f', true) (true means highlight the node).
The reason onclick gets removed is due to dom sanitizer.
While I suggested a plugin could do this, It would be far better to be a core feature to avoid competing ideas.
IMO, we should be able to do way more:
A way to open the edit panel of a node (this is also supported deep link today)
A way to initiate ANY action i.e. the search panel
e.g. Search for [all function nodes](#action/search?term=type:"function")
A way to show/hide panels
e.g. You will see the output in the [debug panel](#panel/debug/open)
On the other hand doing something like we did with the groupflow plugin, i.e. having a plugin demonstrate the feature which then can be used in the meantime is probably the golden middle road.
I'm pretty sure that something like the groupflow will - eventually - make it into core. Having a plugin to test the feature and add suggestions before then is really useful.
Can I ask does FlowFuse parse the url and to determine what functionality is to be called? I.e. could I add something like [Name](#search/search%20term) so that I can trigger the RED.search.open("search term") functionality?
I know that extending the markdown rendered isn't rocket science, just whether that is possible via a plugin remains a mystery to me.
I think this isn't a good idea for portability - hardcoding both the IP and node id means that importing the flow somewhere else will probably break the documentation ....
onclick is definitely no solution. I totally forgot to use markdown notation (because I started with onclick), so having [..](#<function>/<arg>) convention for markdown links would be the way to go...
Yes. Specially crafted urls are intercepted and converted into actions. This is done in a beforeSanitizeAttributes and afterSanitizeAttributes hooks on DOMPuirfy
works. The leading . represents the current URL route and takes into account any admin route path changes. Clicking on that link does correctly change the browser's URL but does not highlight the target node. The important point being that it isn't stripped by the sanitizer and it does not trigger a new tab to open and it is totally portable.
Incidentally, I've no idea where the node name fn_router came from. That is the node's ID in the flow but it isn't it's name which is "Lookup + build redirect". Hmm, I wonder if I imported someone else's code and that code was generated by an AI originally and it set the ID to that name instead of a UID?
What I use here is [00-base.html.js](#/search/00-base.html.js) - so the "action" is action and the "argument" is 00-base-html.js. I prefer that to using ?searchTerm=.... - but each to their own!
The frontend code for this was (not my finest hour):
DOMPurify.addHook("afterSanitizeAttributes", (e, h, c) => {
if (typeof e === "object" && Object.getPrototypeOf(e) === HTMLAnchorElement.prototype) {
let mth = e.href.match(/#\/search\/(.+)/)
if (mth) {
window.handleSearch = (term) => {
RED.search.show(term)
$('.red-ui-flow-annotation-popover').hide()
}
e.href = `javascript:window.handleSearch('${mth[1]}')`
}
}
})
A couple of problems:
onclick cannot be set, DOMPurify will not include it in the final result, that is because the configuration doesn't allow it. So the only thing that becomes usable is the href.
there is no clean why of hiding the popover (at least not that I found) because there is no RED.popover.close() functionality. If that isn't done, the popover and the search interface are shown at the same time so the popover has to be closed.
This also works from the info box in the sidebar, so overall, a good solution to solving the problem!