Opened 12 years ago

Closed 11 years ago

Last modified 10 years ago

#4462 closed defect (fixed)

xdomain loading of a layer file that contains dojo.gfx fails.

Reported by: James Burke Owned by: James Burke
Priority: high Milestone: 1.2
Component: Loader Version: 0.9
Keywords: Cc: jayant.b.sai@…
Blocked By: Blocking:

Description

It fails with an error that looks something like:

dojox is not defined
[Break on this error] ["requireIf", dojox.gfx.renderer == "svg", "dojox.gfx.svg"].

The issue is the requireIf test expression, dojox.gfx.renderer == "svg", is being evaled before the content of dojo.gfx is run, so the expression is invalid. This is a normal xdomain behavior, but I probably need to extend the xdomain loader to:

  • do a try/catch around requireIf calls.
  • after all the modules are run in the right order, check to make sure there are no outstanding modules still loading before calling the onload callbacks.

With these changes, I hope the following behavior will happen:

  • The xdomain loader tries to map dependencies before running the module code. When it hits a requireIf like this, it will exception out, but inside a try/catch so it is ignored.
  • Then the module will be run, and then the real requireIf call can be made.
  • This will put a new request on the xdomain module loading stack. Need to make sure it is totally empty before notifying the onload listeners.

Change History (9)

comment:1 Changed 12 years ago by James Burke

Thinking more about it, I think the following solution is the more robust. The above notes do not work if a module dojo.requires gfx code so it can "subclass" an object in one of the dojo.requireIf() calls.

We need to specify that a piece of JS code is needed by the loader in order to satisfy a dojo.requireIf() expression. The problem is the xdomain build process wraps the module code in a function call, and it extracts the dependencies to an array outside of that function. The dependency array is processed before calling the function that runs the module code.

In the case of dojox.gfx, there is code segment that determines the value for dojox.gfx.renderer, then that value is used in the dojo.requireIf() calls.

Proposed solution:

Introduce a new loader method: dojo.requireInit() or dojo.loaderInit() (or some other name?). Put the dojox.gfx.renderer code in a function that is passed to that method. The new loader method would just execute the function right away, but then we have a marker that we can use in the xdomain build process to extract that function out of the function that wraps the module code, and run the code as part of the dependency resolution step in the builder.

Example for previously mentioned dojox.gfx code:

dojo.loaderInit(function(){
	var renderers = (typeof djConfig["gfxRenderer"] == "string" ?
		djConfig["gfxRenderer"] : "svg,vml,silverlight").split(",");
	for(var i = 0; i < renderers.length; ++i){
		switch(renderers[i]){
			case "svg":
				if(dojo.isIE == 0){ dojox.gfx.renderer = "svg"; }
				break;
			case "vml":
				if(dojo.isIE != 0){ dojox.gfx.renderer = "vml"; }
				break;
			case "silverlight":
				if(window.Silverlight){ dojox.gfx.renderer = "silverlight"; }
				break;
		}
		if(dojox.gfx.renderer){ break; }
	}
});

I do not like having a new loader function that is really only needed for xdomain support. Makes API more confusing. But it is the best thing I can think of so far.

I have considered using the conditional comments support to do something equivalent to the method above, but I feel that will have problems down the line with build processes that remove comments. And I would have to put conditional code processing logic in the xdomain loader. I do not like that since it makes the xd loader even heavier.

The function call approach is a lot more lightweight on the xd loader. I still need to add "find matching parentheses" code, but we need that anyway for more robust loader support (for example, to fix ticket #256).

Alternatives ideas are welcome.

comment:2 Changed 12 years ago by James Burke

Milestone: 1.01.1

Punting to 1.1. I am not comfortable putting this change in so close to the 1.0 release.

comment:3 in reply to:  2 Changed 12 years ago by guest

Replying to jburke:

Punting to 1.1. I am not comfortable putting this change in so close to the 1.0 release.

Oh no, when will 1.1 be out? Do you think this issue and http://dojotoolkit.org/forum/dojox-dojox/dojox-support/cross-domain-proxy-cross-domain-build-not-working may be related? Also, please add jayant dot b dot sai at gmail dot com to the CC as I can't do it.

thanks Jayant

comment:4 Changed 12 years ago by James Burke

Cc: jayant.b.sai@… added

The forum post you mention is a different issue, and I have commented in that forum thread for it.

As for dojox.gfx and xdomain builds, I am not sure when 1.1 will come out, but there are some workarounds to using dojo.gfx in an xdomain fashion:

1) Include dojox/gfx.js directly in your page with a script tag in the HTML source, after the dojo.js script tag (do not use gfx.xd.js, use gfx.js).

2) Include dojox.gfx in a layer file that you load via a script tag in the HTML source (load the .js layer file, not the .xd.js layer file).

Not the ideal solution (hard to load the module "on-the-fly" after page load), but it works.

I really wanted to get this in for 1.0, but other things had priority.

comment:5 Changed 12 years ago by James Burke

Milestone: 1.11.2

comment:6 Changed 11 years ago by James Burke

(In [13851]) Refs #4462: Get xdomain loading to work for dojox.gfx. Requires a new loader function, dojo.loadInit() for this to work. Not my favorite, but it is the only robust option at this point.

comment:7 Changed 11 years ago by James Burke

(In [13852]) Refs #4462: Get xdomain loading to work for dojox.gfx. Requires a new loader function, dojo.loadInit() for this to work. Not my favorite, but it is the only robust option at this point.

comment:8 Changed 11 years ago by James Burke

Resolution: fixed
Status: newclosed

(In [13853]) Fixes #4462: Get xdomain loading to work for dojox.gfx. Requires a new loader function, dojo.loadInit() for this to work. Not my favorite, but it is the only robust option at this point.

comment:9 Changed 11 years ago by James Burke

(In [14786]) Refs #4462: xdomain loading works with dojox.gfx now so this profile is no longer needed.

Note: See TracTickets for help on using tickets.