Opened 12 years ago

Closed 11 years ago

#5878 closed enhancement (fixed)

Add Jaxer Support

Reported by: kriszyp Owned by: James Burke
Priority: high Milestone: 1.1
Component: General Version: 1.0
Keywords: Cc:
Blocked By: Blocking:

Description

Currently Dojo doesn't run on the Jaxer server (on the server side using runat="server") for the following reasons:

  1. Auto-detection of the dojo root doesn't work. I can't figure how it is even possible in Jaxer. The script object has a null value for the src attribute. The Error.fileName returns the filename of the enclosing HTML file. I don't know how it can be done other than manual configuration djConfig:{baseUrl:...}

  1. global.load is not available and document.write and appending a script tag do not work because they don't set the runat attribute to "server" (and even then who knows). This can be corrected by setting this.load = Jaxer.Includer.load. This appears to fix this problem. I am including a patch for dojo.js for to fix this.

  1. I can't find any way to programmaticly detect when the DOM is loaded on the server side. There is an onserverload attribute which works from the HTML, but the obvious programmatic equivalents seem to have no effect. (document.onserverload = dojo._loadInit and document.addEventListener('serverload', ...)). The only thing that seems to work is <body onserverload="dojo._loadInit">

Attachments (9)

hostenv_browser.diff (469 bytes) - added by kriszyp 12 years ago.
Patch for hostenv_browser.js
hostenv_jaxer.js (593 bytes) - added by kriszyp 11 years ago.
hostenv_jaxer.js
demo_Templated_Jaxer.html (3.8 KB) - added by kriszyp 11 years ago.
Updated Demo File
dojo.diff (1.0 KB) - added by kriszyp 11 years ago.
Updated Patch for dojo.js
jrb-dojo.js.patch (564 bytes) - added by James Burke 11 years ago.
Patch made by jburke based on kriszyp's patch.
jaxer.js (258 bytes) - added by James Burke 11 years ago.
Instead of using hostenv_jaxer.js, create a dojo.jaxer module.
jrb-demo_Templated_Jaxer.html (3.7 KB) - added by James Burke 11 years ago.
jburke's test file based on kriszyp's test file.
oncallback.html (1.8 KB) - added by James Burke 11 years ago.
Place in a dojo/tests/jaxer directory. Tests the "oncallback" case
dojoToJson_TestCase.html (1.3 KB) - added by guest 11 years ago.
test case for server side, client side, callback use of dojo.toJson

Download all attachments as: .zip

Change History (32)

comment:1 Changed 12 years ago by James Burke

I am ignorant on how Jaxer works, but I thought it basically ran the gecko engine on the server, and not just Spidermonkey. I wonder if you use a browser build of Dojo, does that work? For instance, does XMLHttpRequest work on the server?

comment:2 Changed 12 years ago by kriszyp

I am using the buildless/svn version of Dojo, which does detect that it is in browser environment, which is what we want. And yes, I believe XMLHttpRequest does work on the server. However, loading files was the one issue that I _did_ fix. It is the detection of the root of Dojo library and registering for the server side DOM parsing that I couldn't figure out.

comment:3 Changed 12 years ago by James Burke

Milestone: 1.11.2

Moving to 1.2 since we are trying to wrap up 1.1 for a beta build, and there are still some unresolved issues in this ticket. If they get sorted in time for 1.1, we can leverage the changes to see if we can move this back to 1.1.

Changed 12 years ago by kriszyp

Attachment: hostenv_browser.diff added

Patch for hostenv_browser.js

comment:4 Changed 12 years ago by kriszyp

I found a fix for issue #3. Adding a onserverload = dojo_loadInit() in the hostenv_browser.js file fixes this problem. I attached the patch. Alex had mentioned that it may be better to create a new hostenv_jaxer.js. However, at the moment there is only that couple lines of code that are needed to get Jaxer going, so I figured I would just leave it as hostenv_browser.js patch for now.

comment:5 Changed 12 years ago by kriszyp

Also added a new demo attachment that omits the step regarding calling dojo._loadInit, since this in now handled in hostenv_browser.js with the previous patch.

comment:6 Changed 12 years ago by James Burke

Do we expect for users to ever use a "built" version of dojo? If so, then the changes done in dojo.js will not be there in the built version (the source version of dojo.js is just replaced with a list of concatenated files from _base).

If we want to support built versions of dojo, then we are probably better off putting the changes from the patches into a new hostenv_jaxer.js file.

I'm also hesitant to put Jaxer changes in hostenv_browser.js if we can avoid it. If necessary, we can work out changes to support loading both hostenv_browser.js and hostenv_jaxer.js if they would both be needed for Jaxer execution.

Does Jaxer support setTimeout? If so, then we might not need the onserverload, and can use the new djConfig.afterOnLoad support I just put in. If you set djConfig.afterOnLoad to true, it fires dojo._loadInit after 1 second. The functionality is in there so you can add dojo to a page after it is loaded, but it might also work in this case? Although, I'm not sure of the contract with onserverload (maybe other things are needed before onserverload is true), so maybe that would be a hazardous approach. Might be better to stick with onserverload.

comment:7 Changed 11 years ago by kriszyp

I didn't realize dojo.js wasn't a part of the built versions. I will go ahead and make a hostenv_jaxer.js, although it will probably be very similar to hostenv_browser.js.

comment:8 Changed 11 years ago by James Burke

Kris: if the jaxer env needs hostenv_browser, then we can make changes in dojo.js (the source version that you modified before) and in the build system to make sure both hostenv_browser.js and hostenv_jaxer.js get loaded. So hopefully that will limit what you need to put in hostenv_jaxer.js to just what is new for jaxer, and not have to duplicate all of hostenv_browser.js in hostenv_jaxer.js.

How does that sound?

comment:9 Changed 11 years ago by alex

kris: any chance of an updated patch? I'd love to get this into 1.1

Changed 11 years ago by kriszyp

Attachment: hostenv_jaxer.js added

hostenv_jaxer.js

Changed 11 years ago by kriszyp

Attachment: demo_Templated_Jaxer.html added

Updated Demo File

Changed 11 years ago by kriszyp

Attachment: dojo.diff added

Updated Patch for dojo.js

comment:10 Changed 11 years ago by kriszyp

I attached a hostenv_jaxer.js, an updated demo file and an updated dojo.js patch. I am not sure if I understand correctly how the hostenv_*.js files work. Are they supposed to be loaded automatically? If so, I don't see how that works. I am guessing that they must be loaded manually (by adding a script tag pointing hostenv_jaxer.js in this case). Is that correct?

comment:11 Changed 11 years ago by James Burke

Milestone: 1.21.1
Owner: changed from anonymous to James Burke

In the svn source case, the dojo.js you patched does the loading, and it looks like you have that working correctly: no need to manually include the hostenv_jaxer.js in the test page. When doing a build, there is logic in util/buildscripts/jslib/buildUtil.js to concat the loader files (including the hostenv files) into the built dojo.js.

I'll pick up this ticket, since I have the attached example working in Jaxer now. I can do the build modifications needed to allowing doing a build for the jaxer hostenv.

I will integrate what you have here, but some questions/comments:

  • There are changes in the dojo.js patch around line 100 about catching an error and determining root from it. This is for the SpiderMonkey? env, and not part of the Jaxer pathways, so I will be removing that part of the patch. Let me know if this change is needed for a specific reason. I removed it in my local patched code and Jaxer still seems to work.
  • hostenv_jaxer.js assigns directly to onserverload. I would rather use something like addEventListener if it is available. Do you know if it is? I might play around with that.
  • It would be nice, as you indicated in the original ticket, to automatically determine the location of dojo. Setting baseUrl works, but it would be nice to know if Jaxer exposes anything like Jaxer.loadedScripts or something that lists the paths of all the scripts jaxer has loaded. If we can get that, then we can modify hostenv_jaxer.js to find dojo.js in that list and set a default for baseUrl if the user does not set a value.

comment:12 Changed 11 years ago by kriszyp

  • > I can do the build modifications needed to

    allowing doing a build for the jaxer hostenv

There will be a separate build for Jaxer and the browser? I don't think we want that, because with Jaxer users would probably normally load Dojo with runat="both", so the same script is loaded on the server and browser. If the build creates a version that is specific to Jaxer, wouldn't that be bad for the browser environment? I am probably misunderstanding how this works...

  • > around line 100 about catching an error

Originally I had used the SpiderMonkey? path (because it is SM, and I was adding "load" to the global), and the try/catch was creating bad paths. However, Jaxer is no longer considered SpiderMonkey?, so you can remove that part of the patch.

  • > rather use something like addEventListener

That would be nice. I played around with it a little bit, but wasn't successful.

comment:13 Changed 11 years ago by James Burke

That is a good point about wanting to use the same build on the jaxer server as well as on the client. I think if we put a typeof Jaxer != "undefined" check around the code in hostenv_jaxer.js, then it should work out.

However, a custom build will still be required to generate a dojo build that will work in Jaxer. In other words, it will not be possible to take the normal dojo.js from the download.dojotoolkit.org and drop it into jaxer. Maybe we can do a jaxer build and put it on download.dojotoolkit.org, but it will be a different deliverable than the normal dojo build.

The other option is to inline the code in hostenv_jaxer into hostenv_browser so we just have one deliverable for everyone, but I do not want to take the extra code weight for a beta environment that is a small minority of dojo usage. I do not want everyone to pay the cost for jaxer support when most people using dojo will not be using it.

comment:14 Changed 11 years ago by kriszyp

My suggestion in the demo was to include:

<script runat="server" type="text/javascript" src="../../../dojo/_base/_loader/hostenv_jaxer.js"></script>

This only runs on the server, and so there is no extra code for the client.

comment:15 Changed 11 years ago by James Burke

Maybe it would be better just to have the code in a dojo.jaxer module that you get by doing a dojo.require("dojo.jaxer"). I could also see later extending that module to do things like set up a different dojo.query search to find widgets to process only on the server (like looking for dojoServerType or something like that).

I'll look at doing that, then remove the the hostenv_jaxer addition to the source dojo.js. That way, things will work with a normal dojo build, and we can use the normal dojo.require syntax to load the module, instead of referencing a "private" file path.

Changed 11 years ago by James Burke

Attachment: jrb-dojo.js.patch added

Patch made by jburke based on kriszyp's patch.

Changed 11 years ago by James Burke

Attachment: jaxer.js added

Instead of using hostenv_jaxer.js, create a dojo.jaxer module.

Changed 11 years ago by James Burke

jburke's test file based on kriszyp's test file.

comment:16 Changed 11 years ago by James Burke

Status update: I attached a few files to the ticket:

  • jrb-dojo.js.patch: Patch made by jburke based on kriszyp's patch.
  • jaxer.js: Instead of using hostenv_jaxer.js, create a dojo.jaxer module.
  • jrb-demo_Templated_Jaxer.html jburke's test file based on kriszyp's test file. Uses the dojo.jaxer module.

I asked on the jaxer forums about a way for us to know about loaded scripts, so the user does not have to explicitly set djConfig.baseUrl. Looks like there is a bug that needs to be fixed first.

That forum post also pointed to Tony Issakov's blog. He has played around with Dojo and Jaxer. One of the interesting posts is about the oncallback type of DOM, which is different than the first server rendered DOM. I think we need to get that working too, but my test (attached) was not successful. More stuff to figure out.

Changed 11 years ago by James Burke

Attachment: oncallback.html added

Place in a dojo/tests/jaxer directory. Tests the "oncallback" case

comment:17 Changed 11 years ago by James Burke

comment:18 Changed 11 years ago by James Burke

(In [12808]) Refs #5878: initial jaxer support. The oncallback() usage of Jaxer does not work yet, but the normal page request version does. !strict for dojo.js

comment:19 Changed 11 years ago by James Burke

(In [12809]) Refs #5878: initial jaxer support. The oncallback() usage of Jaxer does not work yet, but the normal page request version does.

Changed 11 years ago by guest

Attachment: dojoToJson_TestCase.html added

test case for server side, client side, callback use of dojo.toJson

comment:20 Changed 11 years ago by guest

Added test case for dojo.toJson

It seems callback usage of dojo.toJson does not output as expected. [1,2,3] becomes {"0":1,"1":2,"2":3}

I'm testing with build 0.9.4.2191 on windows.

Also I found the "if" test inside the oncallback is not reliable. The "if" test itself can cause all proxy functions to fail. If I force dojo to reload then proxy functions work fine.

I'm happy to be corrected if I'm doing something obviously wrong.

Tony Issakov

comment:21 Changed 11 years ago by James Burke

Tony, thanks for the test case. I wonder if the dojo.toJson issue is limited to the oncallback case. When I do the following in a runat="server" script after doing a dojo load with runat="server", it outputs correctly without having to modify dojo.toJson:

dojo.addOnLoad(function(){
    var newThing = document.createElement("div");
    newThing.innerHTML = dojo.toJson([1,2,3]);
    dojo.body().appendChild(newThing);
});

It seems like the oncallback invocation of Jaxer still needs some work. I'm not sure how robust it is yet. I'll also look at always loading and binding dojo in the oncallback case to see if that helps the oncallback test page I am trying to construct.

Thanks for your insight, please feel free to continue to share you experiences or issues in this ticket (or open new ones as you deem appropriate).

comment:22 in reply to:  21 Changed 11 years ago by guest

Replying to jburke:

I wonder if the dojo.toJson issue is limited to the oncallback case.

Yep, absolutely. In my test case it shows that dojo.toJson generally works, except for the callback. I'm guessing the way Jaxer defines the Array Type in the callback state is a different from the normal browser Type and dojo is translating it literally while Jaxer.Serialize is doing some form of translation to make it correct JSON.

Not a show stopper (especially if you use Jaxer.Serialize for callbacks) but just a little oddity to be aware of in current Jaxer builds.

comment:23 Changed 11 years ago by James Burke

Resolution: fixed
Status: newclosed

A new ticket was opened for the oncallback support, so closing this ticket as fixed, and we'll track the oncallback support in ticket #6066. oncallback support will likely need later versions of Jaxer to work smoothly, so full support will likely not come until Dojo 1.2.

Note: See TracTickets for help on using tickets.