Plugins with Javascript code that references the window and/or document objects

The Javascript code of my simple highlight widget (Simple HighlightWidget (again)) is structured in the way TiddlyWiki widget code is structured (e.g., button.js) and works well in a single HTML file TiddlyWiki. I am currently working on making the widget a plugin with node.js. When serving the plugin with the code as is I get a reference error:

Error executing boot module HighlightWidget.js: ReferenceError: window is not defined

(or with a slight modification in the code document is not defined; the code requires both the window and document objects).

Following https://groups.google.com/g/TiddlyWiki/c/pjqXOaHGw1w/m/7oXkXEdhAQAJ I restructured the code as follows:

exports.name = "highlight";
exports.after = ["story"];
exports.highlight = HighlightWidget;

exports.startup = function() {
  // The code is now here
}

It is unclear what the value of exports.name should be: highlight, anttt/highlight, $:/plugins/anttt/highlight", or something else?

The references error(s) no longer occur with the modified structure, but … as the debugger tells me, the exports.startup function is never called and the widget is not created, not in the single HTML file with only the plugin and not when the plugin is served with node.js. I seem to be overlooking something or doing something wrong.

Also, what are the various options for exports.after and are they documented anywhere?

Thanks for helping me solve this problem.

maybe you need $tw.browser

1 Like

The function exports.startup is only called when the module-type of the Javascript tiddler is startup. But the widget code requires it to be widget to work. Analogously, defining a function with exports.widget = function() { … } does not work. Also, when I change the module-type to startup, I get a reference error for “story” (or “rootwidget”, …).

In short, this approach, for now, seems to lead nowhere. Correct me if I am wrong. I wish there were some documentation. I am certainly not the first to want to write a widget plugin that references window and document and that works both in single file wikis and in node.js versions. I am reminded of what I used to tell my now grown-up son: There comes a time when you have to find answers to your questions yourself.

There is a step by step widget tutorial in the TW Dev edition: https://tiddlywiki.com/dev/#Javascript%20Widget%20Tutorial

Your code will not work as a widget. Your code shows a startup module, which is something completely different.

So have a closer look at the linked tutorial.

My code is a widget, not a startup module, which works very well in (my) standalone single file wikis (see the screenshot in Simple HighlightWidget (again)) and which I continue to find very useful. I ran into reference errors when trying to make it a plugin using the nodejs approach to share it to the community. My search to solve the reference error problem turned up only the reference given above, which does discuss a startup module, not a widget, which at first I had overlooked. I used the tutorial you mention more than a year ago when I developed my music player widget (never published, although perfectly willing to do so, as it is very specialized (for classical music) and, based on discussions with classical music lover friends, apparently not of interest). I have looked at the code of various other plugins but have so far not found a way to make my widget work as a plugin using the nodejs approach, as documented e.g. in Grok TiddlyWiki — Build a deep, lasting understanding of TiddlyWiki (and other places). On the other hand, there is no problem with Eric Shulman’s approach (Plugin Development Workflow - #6 by EricShulman), at least not for local standalone wikis.

@Jan it is extremely difficult to provide any guidance without being able to see your code. I recommend uploading the code somewhere we can see it, or pasting it here in the forum.

1 Like

It sounds very much to me like @oeyoews has the right suggestion:

His screenshot is showing the use of $tw.browser in an if statement to prevent code which will only work in the browser from executing while in nodejs.

In your case you’d want to use the $tw.browser check to prevent code referencing window from executing in nodejs.

I understood @oeyoews reply. My code does require window and document though. As @saqimtiaz suggested, I’ll upload code (tomorrow) with detailed explanations. Thanks all for your replies.

When running under nodejs, the javascript in plugins will first execute server side in nodejs when you launch nodejs. Then when you load the page in your browser the javascript will run again, this time in your browser.

Using $tw.browser allows you to access window and document only when running in the browser.

I explain the above in case that is the misunderstanding. If you already understand that, then the question is why does the code need to reference window and document on the server side? Isn’t client side enough?

1 Like

Also, are you aware of the dynannotate plugin? I think there is overlap between yours and its functionality.

The reference above (https://groups.google.com/g/TiddlyWiki/c/pjqXOaHGw1w/m/7oXkXEdhAQAJ) put me on the wrong track. $tw.browser is indeed the solution.

I did not know that the code is executed twice, the second time in the browser.

When I still worked as a programmer I often thought that a single explanatory sentence (e.g. just one comment in code) can often make a big difference.

Thanks!

In one of my wikis I felt the need to be able to find words, automatically open the tiddlers that contain them and have the words automatically highlighted, whence my interest in highlighting. It turns out after having used the highlighting for some time that the highlighting by itself is very useful, whence the desire to share it as a plugin. This forum has been extremely helpful.

1 Like

Thanks to you @oeyoews and to @btheado