From: David Mark on
Scott Sauyet wrote:
> On Jan 5, 12:59 am, Thomas 'PointedEars' Lahn <PointedE...(a)web.de>
> wrote:
>> Scott Sauyet wrote:
>>> When the user clicks
>>> "Save", the JS collects the data it needs, and POSTs it to the server,
>>> which verifies the data and then serves up a new version of the page
>>> with
>>> Content-Disposition: attachment; filename="[name derived from
>>> data].html"
>>> Then with the browser file save dialog, the user can save this file
>>> locally.
>> You could save the roundtrip if you rewrote the document based on its
>> serialization.
>
> I've never tested to see whether "File > Save Page As" or its
> equivalents save some version of the dynamically altered page or the
> page as originally sent by the server. Even if the current crop of
> browsers all save the dynamic page (and I'd be surprised, honestly), I
> don't see that I could count on that behavior.
>
>
>> But the user might need to trigger the "Save As" dialog
>> manually, depending on the runtime environment.
>
> And that's the real problem for me. I want the "save" action to be
> part of the page UI and not depend upon the browser's chrome.

"The browser" suffices here (or you could refer to its _commands_). It
has nothing to do with the "chrome" (which refers to the UI rendering).
From: Scott Sauyet on
On Jan 5, 9:17 am, David Mark <dmark.cins...(a)gmail.com> wrote:
> Scott Sauyet wrote:
>> On Jan 5, 12:59 am, Thomas 'PointedEars' Lahn <PointedE...(a)web.de>
>> wrote:
>>>  But the user might need to trigger the "Save As" dialog
>>> manually, depending on the runtime environment.
>
>> And that's the real problem for me.  I want the "save" action to be
>> part of the page UI and not depend upon the browser's chrome.
>
> "The browser" suffices here (or you could refer to its _commands_).  It
> has nothing to do with the "chrome" (which refers to the UI rendering).

I stand corrected.

-- Scott
From: Scott Sauyet on
On Jan 4, 4:13 pm, I <scott.sau...(a)gmail.com> wrote:
> On Jan 4, 3:21 pm, "Paul Hovnanian P.E." <p...(a)hovnanian.com> wrote:
>> [ ... ]
>> Basically, what I'm trying to do is too get out of the document storage
>> business for my customers. While they are using this app, the data
>> transferred to/from my back end application should only persist on the
>> server for the duration of that transaction. Is Javascript even the right
>> way to go for  such an app?
>
> I've been considering a very similar problem for few weeks now, and
> can't say for certain if what I want to attempt will work at all, as I
> have yet to start coding.  But I think it will.


Okay, I've made a proof-of-concept. This will work. If you're
curious, it's running here:

http://scott.sauyet.com/Javascript/Test/SaveTest/

And you can see the PHP code here:

http://scott.sauyet.com/Javascript/Test/SaveTest/index.phps

I reiterate that this is a proof-of-concept. There are probably huge
problems with it. The code might not only be poorly written, but it
might also steal your girlfriend and set off a world-wide nuclear
conflagration. You've been warned. I have tested only in Firefox
3.5.6 and IE8. It works fine in FF, and in well enough in IE, modulo
a warning about "prompt"ing for data.

The editable interface is, for the demo, extremely limited. In fact,
there is only one datum available for change. A click on the "Edit"
button prompts for a new value of that field. This is of course where
the guts of a real application would live. And in this version at
least, all the data would live in a single object in global scope,
here called "model". But clearly adding additional fields would be
straightforward, and in the application I'm planning, I would have
three or four such objects, I believe.

It pretty much follows the design I described in my first response
[1]. It uses a minified version of the JSON parser from json.org [2]
to save the data model in a form field as a string of JSON. The
original page, and any subsequent ones point back to the server for
the save. Users without JS would see only the viewable portion of the
page, without any editing interface.

Several obvious variations can be considered. First of all, if the
page is called from a GET rather than a POST, I'm simply supplying a
default model. But the page could instead offer a choice of the
default model or a file upload of a previously-saved version. That
would involve some server-side parsing of the generated HTML, but it
would be relatively easy to add some token that could be recognized,
perhaps in a comment in the line above the model definition.
Secondly, mine is a single-page interface. Pretty much everything
would be done client-side, with the server doing nothing more than
serving the page and formatting versions to be saved. But it's easy
enough to imagine a multi-page interface, where the server session
maintains all the data, but each output page saved contains enough
information to restore the server state.

There is one serious limitation to this technique. Each saved version
is tightly coupled with the server that built it. Unless the saved
page is simply an upload to the server for restoring the state, the
page is the only place to keep the information regarding the location
of the server-side code. If you want to have multiple servers that
could handle the output, then there would be significant additional
complexities. That's not an issue for my project, but might well be
for yours.

I hope that this might help for your project. Good luck,

-- Scott
____________________
[1] http://groups.google.com/group/comp.lang.javascript/msg/21b5e76f7276e9f6
[2] http://www.json.org/json2.js
From: Paul Hovnanian P.E. on
Scott Sauyet wrote:

> On Jan 5, 12:59 am, Thomas 'PointedEars' Lahn <PointedE...(a)web.de>
> wrote:
>> Scott Sauyet wrote:
>>> When the user clicks
>>> "Save", the JS collects the data it needs, and POSTs it to the server,
>>> which verifies the data and then serves up a new version of the page
>>> with
>>
>>> Content-Disposition: attachment; filename="[name derived from
>>> data].html"
>>
>>> Then with the browser file save dialog, the user can save this file
>>> locally.
>>
>> You could save the roundtrip if you rewrote the document based on its
>> serialization.
>
> I've never tested to see whether "File > Save Page As" or its
> equivalents save some version of the dynamically altered page or the
> page as originally sent by the server. Even if the current crop of
> browsers all save the dynamic page (and I'd be surprised, honestly), I
> don't see that I could count on that behavior.

From what I've seen, the original text copy is what is saved. Your JS
application modifies the objects that this was parsed into, but the text
copy is not modified. There could be a browser out there that does mod the
text, but I think that would be the exception.

>
>>But the user might need to trigger the "Save As" dialog
>> manually, depending on the runtime environment.
>
> And that's the real problem for me. I want the "save" action to be
> part of the page UI and not depend upon the browser's chrome.
> Although I've seen TiddlyWiki's [1] ability to save a file, I don't
> want to get into the complexities of elevating the permissions that
> they have to deal with.

Adding a 'File|Save' function to the page might work. The challenge will be
to prevent the user from using the 'wrong' Save function (the browser's).

It might be possible (in my app) to spawn a new window that lacks the
standard menu bar. Users would expect the Save function on a particular
window to save that window. So if the UI menu looked similar to the browser
menu, that might be good enough to keep them from saving the wrong page.

The round trip might not be avoidable for my other issue: That of security
based on the document.domain property. I'm still trying to figure out how
to get a locally loaded page to use the server's scripts rather than ones
saved with the page. The XMLHttpRequest has a similar problem in that the
security model won't let the file system copy talk to my server any more.
But if the page is bounced off my server, the returned copy will have the
proper domain value.

I've seen simple apps that work this way. But they were able to capture
their entire data structure in form content elements with a hidden
attribute. I'm not certain if this concept can be extended to more complex
structures without some mind bending serialization trickery.

--
Paul Hovnanian paul(a)hovnanian.com
----------------------------------------------------------------------
Have gnu, will travel.
From: Scott Sauyet on
On Jan 5, 1:47 pm, "Paul Hovnanian P.E." <p...(a)hovnanian.com> wrote:
> Scott Sauyet wrote:

>> I've never tested to see whether "File > Save Page As" or its
>> equivalents save some version of the dynamically altered page or the
>> page as originally sent by the server.  Even if the current crop of
>> browsers all save the dynamic page (and I'd be surprised, honestly), I
>> don't see that I could count on that behavior.
>
> From what I've seen, the original text copy is what is saved. Your JS
> application modifies the objects that this was parsed into, but the text
> copy is not modified. There could be a browser out there that does mod the
> text, but I think that would be the exception.

Actually, in my testing with FF, the altered page was stored, but when
I reloaded it, the JS was run again, giving duplicate DOM
manipulations...

>> And that's the real problem for me.  I want the "save" action to be
>> part of the page UI and not depend upon the browser's chrome.
>> Although I've seen TiddlyWiki's [1] ability to save a file, I don't
>> want to get into the complexities of elevating the permissions that
>> they have to deal with.
>
> Adding a 'File|Save' function to the page might work. The challenge will be
> to prevent the user from using the 'wrong' Save function (the browser's).
>
> It might be possible (in my app) to spawn a new window that lacks the
> standard menu bar. Users would expect the Save function on a particular
> window to save that window. So if the UI menu looked similar to the browser
> menu, that might be good enough to keep them from saving the wrong page.


That depends. If you're trying to make your page look as much like a
desktop application as you can, then this is probably a good
strategy. But it is by no means necessary. You can choose a very
different UI if you like. If your "Save" button is prominent -- you
might implement a yellow fade on the button for significant model
changes -- then users will not likely head to the browser's menu bar,
ribbon, or such.


> The round trip might not be avoidable for my  other issue: That of security
> based on the document.domain property. I'm still trying to figure out how
> to get a locally loaded page to use the server's scripts rather than ones
> saved with the page. The XMLHttpRequest has a similar problem in that the
> security model won't let the file system copy talk to my server any more.
> But if the page is bounced off my server, the returned copy will have the
> proper domain value.

If you look at TiddlyWiki [1], you will see that it's possible to do
without a round-trip, but it's quite difficult and requires the user
to willingly accept elevated privileges in most browsers. It seems to
me that server-side pieces are much simpler.

My later message [2] gives a simple example that uses the server only
for serving the page and processing a POST request for the updated
version. It could easily be extended to move the scripts out of the
page, as I already do with the JSON script. The domain is not an
issue for <script> tags in the markup, nor for script elements added
dynamically with Javascript; these are not subject to cross-domain
restrictions. The standard problems that many people have with the
latter can be solved with JSONP [3] but probably won't plague you
anyway as you're not really trying to use these scripts to mash-up
with internal data. Since you control both the internal data and the
external scripts, they can share state via the global namespace.


> I've seen simple apps that work this way. But they were able to capture
> their entire data structure in form content elements with a hidden
> attribute. I'm not certain if this concept can be extended to more complex
> structures without some mind bending serialization trickery.  

That's what I was testing in my demo, and I think it will work quite
well for complex models with many KB or maybes several MB of data
stored in a few JS objects serialized to Strings. But as I've only
tested with one small String field, I'm not making any guarantees.


-- Scott
____________________
[1] http://tiddlywiki.com/
[2] http://groups.google.com/group/comp.lang.javascript/msg/3b751ce8a7107c61
[3] http://en.wikipedia.org/wiki/JSON#JSONP