Opened 13 years ago

Closed 12 years ago

#1460 closed defect (wontfix)

TabContainers loaded in Content panes appears broken on Opera 9

Reported by: jared.jurkiewicz@… Owned by: mumme
Priority: high Milestone: 1.0
Component: Dijit Version: 0.3
Keywords: Cc: bill, koranteng
Blocked By: Blocking:

Description

I've been using DOJO for a bit now to develop a demo/prototype application to stress the value of AJAX at the place I work. For the most part, DOJO has worked very well and I'm impressed with out easy it is to build custom widgets and communicate between them via topics and the like. I've also been impressed how well it works across browsers. For the most part I've found everything behaves consistently. But, I have encountered a situation where it is not and was wondering if anyone in the community has encountered this or understands what is going on. Here's the basic situation:

I have a three pane view using LayoutContainer?, SplutContainer?, and ContentPane?. It follows the common pattern seen in a typical tree, view, and results window set. The vew pane is loaded via setUrl() calls to the ContentPane?, so that I can load in template views. The one I'm normally loading in, is a view that contains a TabContainer? with around five tabs or so on it. In IE 6.0 and Mozilla 1.7.12 (as well as FireFox? 1.5), this all works fine.

So, wanting to support as many browsers as possible, I went and tried Opera 9 ... and all is not well. For some reason I haven't been able to determine yet, when Opera loads the TabContainer? into my 'view' pane, none of the labels show up. But, if I load the tabView.html template directly, the labels show up fine. Both the top level page and the tabContainer page use the same CSS. I've included a sample application where this occurs, along with two screenshots that show the odd behavior (A set of screenshots of the tri-view page, and just the tabView page so you can easily see the labels missing in tri-view). Both images are inside the attached testcase zip (please ignore the 'Saved by Trial' version text. I had to use a quick and dirty way to convert the BMP screenshots into a more manageable size).

You can also run the test if you want by

1.) Unzip the test case into a directory, such as <testcase>/

2.) Put a copy of DOJO into the directory at <testcase>/dojo (The testcase loads dojo.js relative to the HTML. dojo/dojo.js)

3.) Open the file in Opera 9: <testcase>/index.html (Labels will not show on the tabs)

4.) Then open the file in Opera 9: <testcase>/abView.html (Labels will show on the tabs)

The only difference between the two is that in index.html, a ContentPane? loads tabView.html.

As an aside, I have tried many revisions of DOJO and had the same result. The current nightly revision I'm using is: SVN revision: 5529

Sincerely, -- Jared Jurkiewicz

Attachments (1)

tabcontainer_opera_issue.zip (34.6 KB) - added by jared.jurkiewicz@… 13 years ago.
Testcase that demonstrates the Opera 9 issue

Download all attachments as: .zip

Change History (7)

Changed 13 years ago by jared.jurkiewicz@…

Testcase that demonstrates the Opera 9 issue

comment:1 Changed 13 years ago by dylan

Component: GeneralWidgets
Milestone: 0.4
Owner: changed from anonymous to bill
Version: 0.40.3

comment:2 Changed 13 years ago by bill

Milestone: 0.40.5
Owner: changed from bill to mumme

Hmm, that's a weird one. I reproduced the behavior here but I don't know what's causing it. It's a pretty unusual case. Basically, the label tags are not taking effect even though they are written in the file. If you add these lines to <head> you will see that all the tabs get labeled w/that default string, rather than picking up the value specified in the markup. Not sure why though.

dojo.addOnLoad(function(){
	dojo.lang.extend(dojo.widget.ContentPane, {label: "default label"});
});

Fredrik, any ideas?

comment:3 Changed 13 years ago by mumme

Cc: bill@… added

Well this is the issue: The require call for dojo.widget.TabContainer? lies in the tabView.html

This means it will be called after the mainpage ContentPanes? are constructed. Normaly this isnt a problem, however TabContainer? requires PageContainer? and that injects 3 properties to dojo.widget.Widget, 'label', 'selected' and 'tabCloseButton'.

Again normally this isnt a problem, but when the ContentPanes? for the tabs are created, and in mixInProperties we check if there is a property in the widget with this name, label in this case, and there is as we already injected it when PageContainer? evaled.

However Opera decides that 'labelä is a special atttribute so it Uppercases it, label->LABEL, again this isnt a problem for dojo because if it cant find the property it matches with all lowercased properties. And here is the issue the lowercased properties gets cached the first time we constructs a widget of particular type, ContentPane? in this case. So the ContentPanes? in the main page already has filled this cache, and as the label injection in the PageContainer? were'nt done yet when that caching took place, we doesnt match the LABEL property.

It works in other browsers because they dont change label to LABEL.

Im realy not sure if we should do a workaround for this, because the obvious fix is to require TabContainer? in index.html instead of tabView.html. It may seem suboptimal, but if we plan to fix it, it would require a cachebuster in Widget.js something similar to this:

Index: trunk/src/widget/Widget.js
===================================================================
--- trunk/src/widget/Widget.js	(revision 5813)
+++ trunk/src/widget/Widget.js	(working copy)
@@ -419,6 +419,8 @@
 				lcArgs[((new String(y)).toLowerCase())] = y;
 			}
 			dojo.widget.lcArgsCache[this.widgetType] = lcArgs;
+		}else{
+			lcArgs.__cached__ = true;
 		}
 		var visited = {};
 		for(var x in args){
@@ -426,7 +428,16 @@
 				var y = lcArgs[(new String(x)).toLowerCase()];
 				if(y){
 					args[y] = args[x];
-					x = y; 
+					x = y;
+				}else if(lcArgs.__cached__ && !this.__noBustArgumentsCache){
+					// This is realy a corner case, some attributes in Opera translates to UPPER case
+					// ie. label, class etc.
+					// if we require a package that mixin properties to a already
+					// cached widget prototype, we wont get this in lcArgs, clear cache  and check again
+					dojo.widget.lcArgsCache[this.widgetType] = null;
+					this.__noBustArgumentsCache = true;
+					dojo.debug("busting "+this.widgetType+" arguments cache", y, x.toLowerCase());
+					arguments.callee.apply(this, arguments);
 				}
 			}
 			if(visited[x]){ continue; }

It doesnt take a genius to understand that this eats up the benefit of having the cache in the first place, so I dont think this is the answer.

Either extend Widget API with these settings or include them in ContentPane? or just document why it is this way and leave it at that.

Bill what du you think we should do?

/ Fredrik

comment:4 Changed 13 years ago by bill

Milestone: 0.50.6

Wow, good explanation. I don't mind adding label to Widget.js (although I always wonder whether "label", "title", or "caption" is a better name). That's my initial instinct; I'll think about it some more.

comment:5 Changed 12 years ago by Adam Peller

Cc: bill koranteng added; bill@… removed
Component: WidgetsDijit

comment:6 Changed 12 years ago by mumme

Resolution: wontfix
Status: newclosed

This isn't relevant anymore since we don't support require calls in the ContentPane? content in 0.9.

Note: See TracTickets for help on using tickets.