Opened 8 years ago

Closed 7 years ago

Last modified 7 years ago

#14243 closed defect (fixed)

dojo.parser is used even if we import dojox.mobile.parser

Reported by: Ming Zhe Huang Owned by: ykami
Priority: high Milestone: 1.8
Component: DojoX Mobile Version: 1.7.0
Keywords: Cc: Adam Peller, bill
Blocked By: Blocking:

Description

Please see the attached HTML.
The test HTML only uses dojo mobile components. However, if you imports "dijit/Dialog" (but not use it), you'll find that dojo.parser will be used, which will cause error message "Uncaught Error: Tried to register widget with id==list but that id is already registered".

Attachments (1)

testParser.html (864 bytes) - added by Ming Zhe Huang 8 years ago.
test case

Download all attachments as: .zip

Change History (14)

Changed 8 years ago by Ming Zhe Huang

Attachment: testParser.html added

test case

comment:1 Changed 8 years ago by bill

The practical solution/workaround is to stop setting parseOnLoad: true, and instead call the parser you want manually, ex:

dojo.ready(100, dojo.parser, "parse");

comment:2 Changed 8 years ago by ykami

Archer, did Bill's suggestion solve your problem?

comment:3 Changed 7 years ago by bill

Cc: Adam Peller added

For a fix, how about modifying dojox/mobile/parser to defer to dojo/parser if it is loaded too? Code like this:

if(config.parseOnLoad){
	ready(100, function(){
		// Now that all the modules are loaded, check if the app loaded dojo/parser too.
		// If it did, let dojo/parser handle the parseOnLoad flag instead of me.
		if(!require("dojo/parser")){
			parser.parse();
		}
	});
}

(By "fix" I mean a way to stop both parsers from running.)

Last edited 7 years ago by bill (previous) (diff)

comment:4 Changed 7 years ago by bill

PS: Or vice-versa: you could add code to dojo/parser.js to defer to dojox/mobile/parser.js. When both parsers are loaded does it usually mean that the user wants to use dojox/mobile/parser?

comment:5 Changed 7 years ago by ykami

Cc: bill added

Bill, it doesn't look like the problem is caused by parseOnLoad:true.

dojo/html.js has dojo/parser in its deps list, which seems to be pulling dojo.parser in this case.

In dojo-1.6, I had been doing like this in dojox.mobile.parser so as not to accidentally load dojo.parser, and it was working well.

dojo.provide("dojo.parser"); // not to load dojo.parser unexpectedly

Isn't there any equivalent technique available for AMD loader?

comment:6 Changed 7 years ago by bill

AMD has an alias modules feature but I don't think it's appropriate here. I don't see an easy way to prevent both parsers from being loaded.

So, the question (to me) becomes how to prevent parseOnLoad:true from running both parsers... hence my suggestion above.

Also, I don't think it's safe to replace dojo/parser with dojox/mobile/parser in the above example, because Dialog (based on ContentPane) depends on the stopParser feature, only in dojo/parser. Maybe other reasons too.

Last edited 7 years ago by bill (previous) (diff)

comment:7 Changed 7 years ago by ykami

I don't think parseOnLoad:true would be a problem, because the automatic dojo.parser loading is guarded by an existence check code as below. And dojox.mobile.parser defines dojo.parser. (The original intention was to allow user apps to call the parser like dojo.parser.parse() instead of dojox.mobile.parser.parse(), but fortunately that also prevents the parseOnLoad:true from loading dojo.parser.)

if(has("dojo-sync-loader") && dojo.config.parseOnLoad && !dojo.isAsync){
    ready(99, function(){
        if(!dojo.parser){
            dojo.deprecated("Add explicit require(['dojo/parser']);", "", "2.0");
            require(["dojo/parser"]);
        }
    });
}

comment:8 Changed 7 years ago by ykami

Bill, now I understood what you meant. I was thinking about how to prevent 'loading' of the two parsers, but you were actually talking about how to prevent 'running' both of them. Let me consider your suggested code.

comment:9 Changed 7 years ago by ykami

Milestone: 1.8

comment:10 Changed 7 years ago by ykami

Resolution: fixed
Status: newclosed

In [27164]:

Fixes #14243 !strict. If both dojo.parser and dojox.mobile.parser are loaded, always use dojo.parser, because dojox.mobile.parser is a pure subset of dojo.parser without any extensions. There is no point in using the subset one.

comment:11 Changed 7 years ago by ykami

Bill, this code does not seem to work on IE6. parser.parse() is never called for some reason. Too bad..
Although mobile does not officially support IE6, NONE of the test cases work on IE6 due to this problem.
I guess non-mobile dojo/dijit/dojox, where IE6 is still supported, have the same problem?

try{
	require("dojo/parser");
}catch(e){
	parser.parse();
}

comment:12 Changed 7 years ago by bill

In [27303]:

workaround IE6 bug where thrown exceptions are ignored (see http://support.microsoft.com/kb/944397), refs #14243 !strict.

comment:13 Changed 7 years ago by ykami

Thank you for the fix!
I personally think contextRequire should not throw exceptions, though.

Note: See TracTickets for help on using tickets.