Is there a mime type or deserialiser for JavaScript function like in bookmarklets

I have one or more bookmarklets and would like to develop a user friendly way to share them. Here is the example content of one;

javascript:(function()%20%7B%0A%24tw.wiki.addTiddlers(%5B%7B%22created%22%3A%2220221108061024852%22%2C%22text%22%3A%22%5C%5Cwhitespace%20trim%5Cn%3C%24button%20tooltip%3D%7B%7B%24%3A%2FPSaT%2FButtons%2Fdownload-wiki!!description%7D%7D%20aria-label%3D%7B%7B%24%3A%2FPSaT%2FButtons%2Fdownload-wiki!!description%7D%7D%20class%3D%3C%3Ctv-config-toolbar-class%3E%3E%3E%5Cn%3C%24wikify%20name%3D%5C%22site-title%5C%22%20text%3D%7B%7B%24%3A%2Fconfig%2FSaveWikiButton%2FFilename%7D%7D%3E%5Cn%3C%24action-sendmessage%20%24message%3D%5C%22tm-download-file%5C%22%20%24param%3D%7B%7B%24%3A%2Fconfig%2FSaveWikiButton%2FTemplate%7D%7D%20filename%3D%3C%3Csite-title%3E%3E%20filename%3D%5C%22mywiki%5C%22%2F%3E%5Cn%3C%2F%24wikify%3E%5Cn%3Cspan%20class%3D%5C%22tc-dirty-indicator%5C%22%3E%5Cn%3C%24list%20filter%3D%5C%22%5B%3Ctv-config-toolbar-icons%3Ematch%5Byes%5D%5D%5C%22%3E%5Cn%7B%7B%24%3A%2Fcore%2Fimages%2Fsave-button%7D%7D%5Cn%3C%2F%24list%3E%5Cn%3C%24list%20filter%3D%5C%22%5B%3Ctv-config-toolbar-text%3Ematch%5Byes%5D%5D%5C%22%3E%5Cn%3Cspan%20class%3D%5C%22tc-btn-text%5C%22%3E%5Cn%3C%24text%20text%3D%7B%7B%24%3A%2FPSaT%2FButtons%2Fdownload-wiki!!caption%7D%7D%2F%3E%5Cn%3C%2Fspan%3E%5Cn%3C%2F%24list%3E%5Cn%3C%2Fspan%3E%5Cn%3C%2F%24button%3E%22%2C%22title%22%3A%22%24%3A%2FPSaT%2FButtons%2Fdownload-wiki%22%2C%22tags%22%3A%22%24%3A%2Ftags%2FPageControls%22%2C%22caption%22%3A%22%7B%7B%24%3A%2Fcore%2Fimages%2Fsave-button%7D%7D%20Download%20Wiki%20with%20changes%22%2C%22description%22%3A%22Download%20Wiki%20with%20changes%22%2C%22modified%22%3A%2220221108062657583%22%7D%5D)%3B%0A%7D)()

I am wondering if there is, or we could build a mime type or deserialiser for JavaScript function like in bookmarklets, such that when they are dropped on a wiki they can import then use a new type and view template of the form

<a href={{!!text}}>{{!!title}}</a> or something similar.

The result?

  • Any file containing a bookmarklet function can be imported to a wiki as a tiddler and automatically become a link;
    • If clicked the function will be performed, like silently install the payload as tiddlers.
    • The link can also be dragged and dropped into the bookmarks to be used on any tiddlywiki.

Ideally they can also be posted here to make sharing a reusable payload with anyone. eg bookmarklet.txt.json (1.7 KB)

The work around is for me to make a view template cascade that detects if the text has a prefix of javascript: or javascript:(function()

  • It would be better if we used a deserialiser and the type field if an appropriate value exists.

I don’t understand the goal. Bookmarklets can already execute javascript on the page when you click on them.

If I understand correctly you want a custom widget. There are two concerns to be addressed. If you want to store the bookmarklet code as a tiddler you will have to decide how you want to store the bookmarklet. If you want to store it as readable JavaScript you will need to also write a transpiler/encoder to convert it to one line and URI encoded (possibly running it through a minimizer).

A custom parser would be easiest but that lacks the fidelity to make your own link label. A custom macro only returns a string which isn’t as helpful here as we want an <a> node.

I think a custom widget is what you want. Sadly I’m mobil and don’t have the tools to write an example here.

The Javascript Widget Tutorial is where I’d start. I’ll try to come back to this thread later when I have more availability to play with the idea. If I’m absent hit me up on Discord.

  • Let me try and reword it.
  • No see below

See my attachment above, it contains a javascript function. it is in the text field of a tiddler you can import or drag between wikis.

I want to drag and drop such tiddlers carrying a bookmarklet “payload”, or import a text file containing this and have it become an active and draggable link.

I already have the workaround below;

I would like to know it its feasible and if there is a content type for such content, so just as if you import a pdf, json image etc… tiddlywiki will recognise its a javascript function or bookmarklet and display it as a link. Assign and handle this “type”.

  • I believe the words are “provide a deserialiser for the import of such javascript functions”.

The ultimate objective is a minor core change so the exchange of such bookmarklets and javascript function tiddlers are native to tiddlywiki permitting their easy publishing, acquisition, installation, sharing etc…

  • I already have Proof of concept macros to easily create such bookmarklets from any tiddler, search result or filter.
  • I also have a way of recording the current users changes to a wiki, such they can move these to a bookmarklet and apply them to any wiki with one click.

Behind this would be the addition of considerable utility, with very few bytes needed.

I personally think distributing executable code as bookmarklets shouldn’t be promoted.

Users can’t read the code and most of the time don’t know what’s going on. In combination with TW I would consider it problematic.

2 Likes

I understand your concern however;

With the right view, it should be easy to display what the content is, especially since for tiddlywiki they are typically just a payload of tiddlers.

  • For example drop it on a single file read only wiki - what can it do?
  • In fact a viewer that exposed the tiddlers within, if it fails it would suggest there is something else in it.
  • You could even ask for a confirmation etc…

The functionality it delivers is substantial.

  • sets of config tiddlers eg preferences.
  • Set of macros and features
  • Drop a set of tiddlers on a wiki and store them for application/reapplication with a click
  • Use for rapid distribution of a package on multiple wikis without leaving the browser.

Bookmarklets do not have an official mime type as far as I know. But you can make your own. The spec has the prs prefix for such occasions.

You could use text/prs.bookmarklet and make a parser that knows how to render the code maybe even minify it on the fly.

I tried this but a parser only renders the text content and has no access to other fields like title and this I was only able to make a link with the label “Bookmarklet” while the parsed code was in the href attribute.

I can post this code if that is what you wanted. I suggested a widget because then not only could you parse the bookmarklet text as a link but also have a way to customize the label.

Sounds interesting @sukima, do share if it not too much trouble. I may be able to build more around it.

I think this plugin is what you might want. Least it is my interpretation on the solution:

https://tritarget.org/wikis/bookmarklet-plugin.html

I included the minified version of Uglify.js for the browser adding a exports and a custom Widget to output an <a> tag.

Thanks @sukima this is perhaps part of the solution;

  • This is helpful to know

Ultimately I want a standardised bookmarklet tiddler standard to support the interchange of solutions.

Are you are already generating the tiddler json which contains the bookmarklet? If so, then what about generating it already in the <a href=... form? That way you don’t need to depend on any mime type or deserializer in the core. Your json is completely self-contained.

Or if for some reason you are forced or prefer to keep the javascript:(function()... format you could include your own view template in the payload. That view template could take care of displaying the <a href=... form when the tiddler body matches javascript:.

In TW-Script, I use a wikitext macro to create a link contains a bookmarklet of filtered tiddlers and you can simply drag and drop that link to your browser bookmark bar.

I use this to inject a set of my selected plugins (like utility, links-to-tab, commander, shiraz, favorites, …) and few configuration tiddlers when I visit other TW on the web.

This is kind of spying :wink: and should be hidden from TW police eyes :wink:

1 Like

Note that you can call the macro with different filter and create several bookmarklets as you like.

This is what we may call a live link, that is it drags the tiddlers in their current state into the bookmarklet, and this is a great way to save the current state. Once a bookmarklet they are frozen in time.

  • A button in advanced search filter to bookmark or capture the result of the filter would be great.

However if we want to capture tiddlers with specific values, not the one they happen to have at that moment, they need to be frozen in time if we want to exchange them for others to use. We may not care what the values are in someone else’s wiki, only that when used, it uses tiddler in the state captured in the “bookmarklet tiddler” I created elsewhere.

The point here is to allow us to share bookmarklets via the exchange of tiddlers.

  • I take from your comments @Mohammad that a bookmarklet tiddler could contain a list of tiddlers or a filter for live bookmarklets, not just as captured, recaptured.
  • Also to allow a click in the wiki on the bookmarklet, to apply the tiddlers without it being placed in the bookmarks, a live bookmarklet will only set the tiddlers to what they currently are.
  • me too, multiple times a day.

All, Thanks for your feedback.

  • It has helped me move forward with a new approach see below
  • Sorry I could not work out how to use it.
  • This is a good idea, I have considered it before, it would be good if there were a tiddlywiki standard supporting this so we could distribute tiddlers with their own view template.
  • I previously developed something similar, called local-viewtemplate local-viewtemplate.json (5.0 KB) where with this in place any tiddler can has its own view Template.

A new approach

I have realised that the key to a bookmarklet is a tiddler filter, and those same tiddlers captured in time - which ultimately is just a JSON of tiddlers.

  • We already have a deserialiser and an Import process for JSON files so It makes sense to stick with that.
  • Imported JSON can be both plugins and simple JSON, but arguably any JSON can thus be a Bookmarklet.
  • A few fields and or naming can be used on any JSON file or an accompanying tiddler to support a bookmarklet JSON.
  • Each tiddler within the JSON can have a field that determines how a bookmarklet generator could handle that tiddler. Currently its only tw.wiki.addTiddlers but perhaps we could add other functions such as delete tiddler, or other functions?

Let me know if you want to collaborate on a solution.

So I suppose I have answered the OT

Is there a mime type or deserialiser for JavaScript function like in bookmarklets?

The answer is yes, application/json

I will keep this thread alive because, I intend to expand the functionality around the application/json type to support bookmarklets.

If you have insight as to how tiddlywiki handles the mime types in general an/or specifically application/json please share.

Please elaborate. That link is a standard TiddlyWiki plugin with examples and uses standard TiddlyWiki widget syntax, How could its use be more approachable?

Overloading an already supported mimetype seems like a recipe for disaster. If need why not use a custom mimetype like text/prs.bookmarklet and then you can make your own parser for said type.

bookmarklets are encoded javascript sources. They have a javascript: prefix, The content is one line and URI encoded. Since JavaScript has built-in ASI (Auto Semi-colon Insertion) it is difficult to cleanly convert a JS file into a single line using a simple join algorithm. The better solution is to use a minifier which not only would compact to one line with ASI taken into account but also make the output much smaller as it knows how to intelligently compact identifiers. That adds the advantage that a bookmarklet is less likely to reach any browsers’ URL size limit.

Since converting any JS source via a minifier and then URI encoding it would either need to be done before adding it to a tiddlywiki for use or have it compiled within the tiddlywiki itself. In my plugin example I included uglify.js to minify in the browser so no build tools would be necessary.

The plugin adds a widget that knows how to take a tiddler of type application/javascript and takes its text field run it through uglifyjs, encode it with encodeURIComponent, and prefix javascript: to the string and that is the rendered output.

To make it a clickable link that a user can either right click to add as bookmark or drag drop to the bookmark bar it renders it as an <a href="..."> tag.

Originally I concidered making a parser for a custom MIME type like text/prs.bookmarklet but that would only provide the compiled textual bookmarklet output and not a interactive link like you would want. Granted through a series of macro calls you could use that to show such a link (see makedatauri macro) but the usage would be way more complicated. With a widget you add a tiddler of type application.javascript and where you want a bookmarklet link use <$bookmarklet tiddler="tiddler title"/>

It’s not what I though it would be, but that is OK.

  • In your solution which I like, the tiddler contains the javascript function

To quote myself,

I would ask you @sukima to work with me to extend the functionality of your bookmarklet widget for it to turn an application/JSON tiddler into a payload bookmarklet, or alternatively accept a filter parameter and do the same as Mohamad’s solution, and keep your existing functionality.