[Laszlo-dev] Deep linking and bookmarking (was Re: [Internal-Dev] Different JS files)
Max Carlson
max at openlaszlo.org
Tue Oct 16 13:41:36 PDT 2007
CC'ing laszlo-dev:
Here's the relevant bit for my application, from
http://state-machine.org/categories.lzx. This lives on the LZX canvas:
<attribute name="appstate" type="string"/>
<view name="appstatemanager">
<attribute name="appstate" value="{}"/>
<attribute name="callbacks" value="{}"/>
<attribute name="ignorecallback" value="false"/>
<method name="setState" args="name, value">
if (value == null) value = '';
this.appstate[name] = value;
var o = '';
for (var i in this.appstate) {
o += i + '^' + this.appstate[i] + '~';
}
this.ignorecallback = true;
Lz.setCanvasAttribute('appstate', o, true);
</method>
<method name="refreshState" event="onappstate" reference="canvas">
if (this.ignorecallback == true) {
this.ignorecallback = false;
return;
}
if (canvas['appstate'] == null) return;
var a = canvas.appstate.split('~');
for (var i = 0; i < a.length; i++) {
if (a[i].length == 0) continue;
var arg = a[i].split('^');
var methodname = arg[0];
this.appstate[methodname] = arg[1];
//if ($debug) Debug.write('refreshState', methodname, arg);
if (this.callbacks[methodname])
this.callbacks[methodname](arg[1]);
}
</method>
<method name="registerCallback" args="name, value">
this.callbacks[name] = value;
</method>
</view>
This sort of serialization/deserialization really should be a platform
feature. For that, I intended to use a URL-safe JSON encoding scheme
called RISON - http://mjtemplate.org/examples/rison.html
In any case, this should give you a template to get the
encoding/deconding you want.
Let me know if you have questions!
Jes Lefcourt wrote:
> Hi Max,
> Do you, perchance, have an example of the first option? All of the
> examples I've seen match the second option. However, the second option
> doesn't allow the deep linking that you talked about (since #4 doesn't
> mean anything when you come in from another page).
>
> Thanks!
>
> - Jes
>
>
>
> On Oct 16, 2007, at 8:11 PM, Max Carlson wrote:
>
>> This is fine, but I'd definitely prefer you use the built-in mechanism
>> so we can find bugs and improve it to suit your needs!
>>
>> If you call Lz.setCanvasAttribute() with the third argument set to
>> true (in dhtml or Flash) it will create a hash object for you and
>> ensure the state gets pushed onto the history stack.
>>
>> From there, you can register for events on that canvas attribute to
>> receive data. This is the mechanism I use on
>> http://state-machine.org/. As you browse through the visualization,
>> the complete application state is serialized to a single string value
>> that's stored on the hash mark, e.g.
>>
>> http://state-machine.org/#_lzappstate=s%5ES8MI00281%7CS6MO00305%7E
>>
>> This provides deep linking and bookmarkability.
>>
>> LzHistory can do all this for you in a much more elegant and
>> unobtrusive way. Instead of hanging all application state off of a
>> single string, LzHistory can store an arbitrary amount of application
>> state that's offset by a counter. In this case, '#0' is all that's
>> appended to the URL - much prettier. Provided persistence is turned
>> on, application state will live across reloads.
>>
>> Both of these are options built into the system. Please try to use
>> them and let me know if you run into issues and have ideas for
>> improvements!
>>
>> jlefcourt at laszlosystems.com wrote:
>>> Hi Max,
>>> I couldn't find test/history/history.lzx. I didn't want to wait
>>> until you were back on to continue working, though, so I got it going
>>> by creating my own anchor string structure and directly calling
>>> Lz.history.set(). I then added the reading hooks in by adding my own
>>> Lz.setCanvasAttribute line to the JS _historyEvent function.
>>> Everything seems to work very well, with one exception. This is a
>>> minor issue, but I believe I've found a bug in Firefox. It's
>>> demonstrated by the following HTML:
>>> ----
>>> <html>
>>> <body>
>>> <script type="text/javascript">
>>> var val = 0;
>>> </script>
>>> <input type="button" onclick="val++; top.location.hash = '#'
>>> + val;" value="Advance"></input>
>>> </body>
>>> </html>
>>> -----
>>> If you go to this page, and start clicking on the button, then the
>>> value of the anchor increments, as you expect it to. However, if you
>>> manually change the value of the anchor and hit enter, then the
>>> button no longer advances the anchor value. It's like it's stuck. I
>>> verified that this does not happen in IE.
>>> I was going to file a bug with Firefox, but their process for filing
>>> is a bit too long for my taste. I thought you might want to know
>>> about it, though.
>>> - Jes
>>
>> Ah yes, this isn't a bug - it's a feature :P. Once a user manually
>> changes the URL in Firefox, Javascript no longer has access to change
>> it for security reasons. Some browsers do this, others don't...
>>
>>> On Mon, Oct 15, 2007 at 10:10 PM, Max Carlson wrote:
>>>> Hi Jes,
>>>>
>>>> Are you looking to do this in Flash? If so, LzHistory already has
>>>> what you need - see this in test/history/history.lzx:
>>>>
>>>> <method event="oninit">
>>>> LzHistory.setPersist(true);
>>>> </method>
>>>>
>>>> You can also use setCanvasAttribute(name, value, true) to set a
>>>> canvas attribute to an arbitrary string via an anchor - this works
>>>> across runtimes. If neither of these does what you want I'd like to
>>>> work together to get you something that does.
>>>>
>>>> Let me know if you have more questions!
>>>>
>>>> Jes Lefcourt wrote:
>>>>> Thank you, gentlemen! Fantastic service, as always (and I'll
>>>>> imagine that you're smiling)!
>>>>>
>>>>> Max: You might be interested in what we're working on... As part
>>>>> of the project for XXXX, we're modifying LzHistory so that it's
>>>>> preserved when you leave the page and come back. So, in summary,
>>>>> the plan is to change it to use a meaningful value for the anchor
>>>>> instead of the incremented numbers and to create a handler to
>>>>> convert variables and values to and from anchor strings. Do you
>>>>> have any advice? Would the platform be interested in the code when
>>>>> we're done?
>>>>>
>>>>> Thanks again!
>>>>>
>>>>> - Jes
>>>>>
>>>>>
>>>>>
>>>>> On Oct 15, 2007, at 12:05 PM, John Sundman wrote:
>>>>>
>>>>>> Documentation issue filed as
>>>>>>
>>>>>> http://www.openlaszlo.org/jira/browse/LPP-4899
>>>>>>
>>>>>> (This applies to documentation, not to any free-standing examples
>>>>>> in the examples directory.)
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> jrs
>>>>>>
>>>>>> On Oct 15, 2007, at 11:55 AM, Max Carlson wrote:
>>>>>>
>>>>>>> embed-compressed.js is what's used by default. embed.js and
>>>>>>> vbembed.js are legacy versions left behind for backward
>>>>>>> compatibility.
>>>>>>>
>>>>>>> If you're looking for the source of embed-compressed.js, see
>>>>>>> lps/includes/source/embed-library.js for the top-level include.
>>>>>>>
>>>>>>> jlefcourt at laszlosystems.com wrote:
>>>>>>>> Hello,
>>>>>>>> Can someone please explain to me the difference between the
>>>>>>>> different embed scripts in OL 4? There are embed.js,
>>>>>>>> embed-compressed.js and vbembed.js. embed.js is what all of the
>>>>>>>> examples use, but the LzHistory support is only in
>>>>>>>> embed-compressed.js. Also, embed-compressed.js certainly isn't
>>>>>>>> a compressed version of embed.js, since it's more than twice the
>>>>>>>> size and with additional functionality.
>>>>>>>> Finally, if embed-compressed.js is the most complete version
>>>>>>>> (which it appears to be), is there an uncompressed version of it
>>>>>>>> somewhere that has tabbing and is generally readable?
>>>>>>>> Thanks!
>>>>>>>> - Jes
>>>>>>
>>>>>
>>>>
>>>> --
>>>> Regards,
>>>> Max Carlson
>>>> OpenLaszlo.org
>>
>> --
>> Regards,
>> Max Carlson
>> OpenLaszlo.org
>
--
Regards,
Max Carlson
OpenLaszlo.org
More information about the Laszlo-dev
mailing list