Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Calling custom scripts from passages in Harlowe [Solved]

edited January 2015 in Help! with 2.0
(New to the forum, and I only found one mostly-unrelated post mentioning any of this, but if it's already been discussed somewhere, just point me in the right direction.)

So I'm just now starting to work with Twine 2, and I was playing around with adding some UI elements on top of a Harlowe-format story. I ran into an issue with the scripting, and @twinethreads sent me this direction for some discussion.

The issue I ran into is, if I want to have a custom event handler in the Story Javascript:
<br />function myEventHandler() {<br />&nbsp; alert(&#039;custom handler called&#039;); <br />&nbsp; //actual work here<br />}<br />
...and then I want to call that from a passage:
<br />&lt;input type=&quot;button&quot; value=&quot;Testing&quot; onclick=&quot;myEventHandler();&quot;&gt;<br />
...the event handler isn't called (tested in latest Chrome and Firefox on Win7 x64). A little digging in Chrome's inspector shows that it doesn't think myEventHandler() is defined. A little more digging and I find that my Story Javascript in the Harlowe export is in an element like this:
<br />&lt;script role=&quot;script&quot; id=&quot;twine-user-script&quot; type=&quot;text/twine-javascript&quot;&gt;<br />
The "text/twine-javascript" seems to be the issue - if I change it to just "text/javascript" manually in the export, the custom event handler is called, but when I asked on Twitter, @twinethreads said the different type value is required for proper script execution order.

So I guess what I'm wondering is if this is a known issue/complication, and if I wanted to attach a function in my Story Javascript to an event handler in a passage, is there another way I should be doing that?

Thanks in advance.  :)

Comments

  • note: Processing of the Story Javascript was broken in the version of Harlowe that came with Twine 2.0 but this was fixed in Twine 2.0.1, so are you using Twine 2.0.1?

    Your function is not visible (in scope) to the passage.

    One way you can get around this problem is to use a Namespace to store your functions (which stops you from accidentally overriding an existing one) and then to add your Namespace to the global windows object.
    (note: Use a name more meaningful than my Bob, it should be unique so check that the Namespace does not already exist)

    if (typeof window.Bob == "undefined") {
    window.Bob = {
    myEventHandler: function() {
    alert('custom handler called');
    //actual work here
    }
    };
    };
    You can then use the fact that your namespace is now globally visible to solve your issue:

    <input type="button" value="Testing" onclick="Bob.myEventHandler();">
  • Yes this was in 2.0.1, and that does indeed fix it.

    I'm looking at the source for Harlowe now, and if I'm following correctly, instead of the browser executing the script in place (because of the type attribute difference), the main() function looks for scripts and passes them to eval(), so none of it ends up in the global scope? If so, then yeah that makes sense -- anything meaningful I ended up writing for this probably would have ended up in a namespace anyway, but I got nervous when the quick test version didn't work.

    Looks like I'm all set for now though, so thanks.  ;)
  • You are mostly right about what is causing your old code from not being in scope but it not the "the type attribute difference" as such, instead the story format's javascript engine needs to make sure that all of its javascript is setup and executed before anything the Author has added.

    Twine 2 does this by marking the hidden Authors script tag with the text/twine-javascript type so it wont be executed, and Harlowe then locates that hidden script when its ready and merges it into the page using an eval().

    In Twine 1 the creators of story formats had the ability to influence how the generated HTML file was assembled thus allowing them to place the Authors javascript at the end of the <head> tag if they wished.
Sign In or Register to comment.