plugins accessing functions from outside their main code in 2.1 beta 4

5 views
Skip to first unread message

Mark Cheetham

unread,
Aug 11, 2006, 7:30:12 AM8/11/06
to Tiddly...@googlegroups.com
Hi,

I have a custom rss reader that downloads rss feeds and saves them as a
html tiddler. I used html because I wanted to target an iframe in
another tiddler. I know I could have done that in javascript but I also
wanted to be able to use the browsers rightclick menu to open links in a
new tab, for instance.

Anyway each feed has a toolbar which has a buttons to force an update
(outside of the normal update checks) and resize the box etc and each
entry also has buttons for hiding and showing of descriptions etc.
These use a onclick using functions inside my plugin. In pre 2.1 these
worked but in the 2.1 betas they dont.

The javascript console says the functions are not defined. Is there a
way I can access the functions from outside the main plugin code?

all the best
Mark Cheetham

Jeremy Ruston

unread,
Aug 16, 2006, 10:28:37 AM8/16/06
to Tiddly...@googlegroups.com
> The javascript console says the functions are not defined. Is there a
> way I can access the functions from outside the main plugin code?

Can you be more specific about which functions are being reported as
not defined? Better yet, can you share the code?

Cheers

Jeremy

--
Jeremy Ruston
mailto:jer...@osmosoft.com
http://www.tiddlywiki.com

Saq Imtiaz

unread,
Aug 19, 2006, 5:02:52 PM8/19/06
to Tiddly...@googlegroups.com
On 8/16/06, Jeremy Ruston <jeremy...@gmail.com > wrote:

> The javascript console says the functions are not defined.  Is there a
> way I can access the functions from outside the main plugin code?

Can you be more specific about which functions are being reported as
not defined? Better yet, can you share the code?

Jeremy, I believe I have run into the same problem myself.

Here is how to duplicate this problem:
  • create a tiddler called "a" and tag it with systemConfig
  • In the tiddler "a" put the following code:
    function say (text) {alert(text)}
  • create another tiddler called "z" and tag it with systemConfig
  • in tiddler z put the following code:
    say("hi");
  • save and reload. You get a message saying that 'say is undefined'
  • adding the following line to the tiddler "a" fixes this:
    window.say = say;
So it seems like functions in TW 2.1 have to be defined on the window scope to be available from outside the plugin code. This is NOT the case with TW 2.0.10. Using InlineJavaScript to try and access the functions defined in systemConfig tiddlers results in a similar problem.

It's not really a deal breaker, just a bit of an annoyance and developers could if necessary just learn to live with it.

Now, take what I am about to say now with a grain of salt as this is a bit of a guess, but I believe this might be related to ticket 54 (http://trac.tiddlywiki.org/tiddlywiki/ticket/54 ). I remember the first time I read that ticket and the mention of anonymous functions, it set of warning bells for me as to the scope of variables and functions.....

Hope this helps,

Saq
 

Jeremy Ruston

unread,
Aug 19, 2006, 5:31:08 PM8/19/06
to Tiddly...@googlegroups.com
OK, this is because of a deliberate change to the way that plugins are
executed. What was once just a window.eval is now:

var f = new Function("tiddler","pluginInfo",tiddler.text);
f(tiddler,p);

It's how plugins get access to the new "tiddler" and "pluginInfo"
parameters. I hadn't realised the impact the change has on calling
things defined in other plugins, and I'd think that it maybe it *is* a
dealbreaker, because it's surely going to break a few things out
there, and the "window." workaround is clumsy. What do you reckon?

Cheers

Jeremy

Saq Imtiaz

unread,
Aug 19, 2006, 5:45:39 PM8/19/06
to Tiddly...@googlegroups.com
On 8/19/06, Jeremy Ruston <jeremy...@gmail.com> wrote:

OK, this is because of a deliberate change to the way that plugins are
executed. What was once just a window.eval is now:

var f = new Function("tiddler","pluginInfo",tiddler.text);
f(tiddler,p);

I figured as much. However, is there any other way to provide the extra parameters to the plugins?
 
It's how plugins get access to the new "tiddler" and "pluginInfo"
parameters. I hadn't realised the impact the change has on calling
things defined in other plugins, and I'd think that it maybe it *is* a
dealbreaker, because it's surely going to break a few things out
there, and the "window." workaround is clumsy. What do you reckon?

It definitely is inconvenient. However, it might be a case of weighing the pros and cons. If we can resolve this and still have the extra parameters available to plugins, then we definitely should keep it. If not, then it might honestly be better to revert to the old plugin handling in order to maintain backwards compatibility.

I agree the "window." workaround is clumsy. However, someone more experienced than myself might be able to suggest a better alternative.

One possible option might be for each plugin developer to set up his own namespace object on the window scope, and then add all functions to that.

var lewcid = {};
window.lewcid = lewcid;
lewcid.say=function(text){say(text)};

It might be a good idea to wait and see what Udo and the others have to say about this.

Cheers,
Saq

 

Saq Imtiaz

unread,
Aug 20, 2006, 1:29:35 PM8/20/06
to Tiddly...@googlegroups.com
Another thing that should be kept in mind is that sometimes a plugin may need to access a function defined in a different plugin.... this could get a whole lot more difficult with the new scope.

Cheers,

Saq

Jeremy Ruston

unread,
Aug 20, 2006, 4:40:37 PM8/20/06
to Tiddly...@googlegroups.com
I think the best thing to do is:

- Revert to the earlier behaviour of using window.eval to execute the
plugin code
- Pass the necessary parameters to the plugin via a global variable
(eg "pluginContext {tiddler, pluginInfo}")

The result will be to keep compatibility with 2.0.x but still provide
a means to access the parameters.

It's not pretty, but I think it's preferable to breaking backwards
compatibility.

Cheers

Jeremy

Saq Imtiaz

unread,
Aug 20, 2006, 4:45:18 PM8/20/06
to Tiddly...@googlegroups.com
On 8/20/06, Jeremy Ruston <jeremy...@gmail.com> wrote:

I think the best thing to do is:

- Revert to the earlier behaviour of using window.eval to execute the
plugin code
- Pass the necessary parameters to the plugin via a global variable
(eg "pluginContext {tiddler, pluginInfo}")

The result will be to keep compatibility with 2.0.x but still provide
a means to access the parameters.

I have to agree, that seems like the best option. We get the additional benefits from the extra parameters without breaking compatibility.

It's not pretty, but I think it's preferable to breaking backwards
compatibility.

I myself usually prefer the simple and elegant approach as well, but that isnt always an option...

Cheers,
Saq

Clint Checketts

unread,
Aug 20, 2006, 5:04:24 PM8/20/06
to Tiddly...@googlegroups.com
On 8/20/06, Jeremy Ruston <jeremy...@gmail.com> wrote:
I think the best thing to do is:
- Revert to the earlier behaviour of using window.eval to execute the plugin code

Rats. I prefer the current method. I realize that I should try to encourage backward compatibility and all but I can't help feeling that this is a good chance to improve TW and the corresponding plugins.

I only have two ideas right now and they aren't the best but I have to start somewhere:

1) First of all, we know how to work around this bug and fix any Plugins that cause problems. Once fixed, we just point the user to the update and they use the new ImportTiddlers to update. Done. We have a fix we can use.

2) What if someone 'accidentally' changes these global variables? They could confuse all the other TWs. It doesn't feel right.

So my arguments aren't the most convincing, and I suppose making it easy to write global functions is useful to some folks. I guess all I can say is: Rats.

Rats. Rats. Rats.

-Clint

Jeremy Ruston

unread,
Aug 20, 2006, 5:10:07 PM8/20/06
to Tiddly...@googlegroups.com
Actually, I've just discovered that there is a better solution that
pretty much combines the best of both worlds: the code executed by
window.eval() executes in the context of the calling function. That
means that the local variables of that function (eg "tiddler") can be
accessed within the eval-ed code without qualification. That means
that we can pass parameters that are not global without having to
incur the scope mismatch issue. Here's the proposed code:

http://trac.tiddlywiki.org/tiddlywiki/changeset/566

Cheers

Jeremy

Clint Checketts

unread,
Aug 20, 2006, 5:13:24 PM8/20/06
to Tiddly...@googlegroups.com
Wow. Remarkable solution! Thanks Jeremy! Backwards compatibility wins again!

-Clint
Reply all
Reply to author
Forward
0 new messages