source: Dev/trunk/src/client/dojox/mobile/migrationAssist.js @ 529

Last change on this file since 529 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 14.9 KB
Line 
1/*
2
3About migrationAssist
4=====================
5
6The migrationAssist is a Dojo module that helps you migrate your
7dojox/mobile 1.6/1.7 applications to 1.8. To enable migrationAssist,
8all you need to do is require this module as shown in the examples below.
9
10        <script language="JavaScript" type="text/javascript">
11                dojo.require("dojox.mobile.migrationAssist");
12                dojo.require("dojox.mobile"); // This is a mobile app.
13                ....
14        </script>
15
16        <script language="JavaScript" type="text/javascript">
17                require([
18                        "dojox/mobile/migrationAssist",
19                        "dojox/mobile", // This is a mobile app.
20                        ....
21                ]);
22        </script>
23
24If your application uses deprecated or no longer available functions,
25this module detects them and displays messages in the browser console.
26
27Also, it tries to dynamically fix them as much as possible so that
28the target application can work somehow.
29
30Note, however, that the purpose of migrationAssist is not to
31run the older applications as they are, but to assist migration.
32
33
34Changes from 1.6/1.7 to 1.8
35===========================
36
37Carousel
38--------
39 - Carousel has no backward compatibility, since it was experimental in 1.7.
40   There are two subclasses that support data stores.
41   Use DataCarousel if you want to use carousel with dojo/data.
42   Use StoreCarousel if you want to use carousel with dojo/store.
43
44FixedSplitter
45-------------
46 - FixedSplitter.css is no longer in the themes/common folder.
47   It is in the device theme folder. (e.g. themes/iphone/FixedSplitter.css)
48
49FlippableView
50-------------
51 - FlippableView was deprecated in 1.7, and removed in 1.8. Use SwapView instead.
52
53ListItem
54--------
55 - The sync property is no longer supported. It always behaves asynchronously.
56 - The btnClass property is no longer supported. Use rightIcon instead.
57 - The btnClass2 property is no longer supported. Use rightIcon2 instead.
58
59SpinWheel
60---------
61 - SpinWheel.css is no longer in the themes/common folder.
62   It is in the device theme folder. (e.g. themes/iphone/SpinWheel.css)
63 - getValue() is no longer supported. Use get("values") instead.
64 - setValue() is no longer supported. Use set("values", newValue) instead.
65
66SpinWheelSlot
67-------------
68 - getValue() is no longer supported. Use get("value") instead.
69 - getKey() is no longer supported. Use get("key") instead.
70 - setValue() is no longer supported. Use set("value", newValue) instead.
71
72Switch
73------
74 - When you place it in a ListItem, class="mblItemSwitch" is no longer necessary.
75
76TabBar
77------
78- In 1.7 or older, barType="segmentedControl" produced different UIs according to the
79  current theme. In the iphone theme, it was a segmented control, but in other themes,
80  it was tabs with or without icons. In 1.8, however, barType="segmentedControl"
81  always produces a segmented control UI regardless of the current theme.
82  If you still need the old behavior,
83      barType:{"iphone_theme":"segmentedControl","*":"tallTab"}
84  should produce a segmented control for the iphone theme, and a tall tab bar for
85  the other themes. You need to use deviceTheme.js to specify barType that way.
86  Also, if you want to hide the tab icons on the segmented control in the iphone theme,
87  you could apply a css like this:
88      <style>
89      .iphone_theme .mblTabBarSegmentedControl .mblTabBarButtonIconArea {
90          display: none;
91      }
92      </style>
93  See test_ScrollableView-demo.html for an example usage.
94
95TabBarButton
96-------------
97 - Specifying a DOM Button with the class attribute like class="mblDomButtonWhitePlus"
98   is no longer supported. Use icon="mblDomButtonWhitePlus" instead.
99 - select() and deselect() are no longer supported. Use set("selected", boolean) instead.
100
101ToolBarButton
102-------------
103 - Specifying the button color style with the class attribute like class="mblColorBlue"
104   is no longer supported. Use defaultColor="mblColorBlue" instead.
105 - Specifying a DOM Button with the class attribute like class="mblDomButtonWhitePlus"
106   is no longer supported. Use icon="mblDomButtonWhitePlus" instead.
107 - select() and deselect() are no longer supported. Use set("selected", boolean) instead.
108
109dojox/mobile/parser
110-------------------
111 - dojox/mobile/parser no longer accepts array-type attribute like
112     labels="['A','B','C','D','E']"
113   Instead, you should specify like labels="A,B,C,D,E", which is the format dojo/parser
114   accepts.
115
116bookmarkable
117------------
118 - To enable the bookmarkable feature, require dojox/mobile/bookmarkable
119   instead of dojo/hash
120
121*/
122
123define([
124        "dojo/_base/declare",
125        "dojo/_base/lang",
126        "dojo/_base/window",
127        "dojo/dom-class",
128        "dojo/dom-construct",
129        "dojo/dom-style",
130        "dojo/ready",
131        "dijit/_Container",
132        "dijit/_WidgetBase",
133        "./_ItemBase",
134        "./common",
135        "./FixedSplitterPane",
136        "./Heading",
137        "./iconUtils",
138        "./ListItem",
139        "./RoundRect",
140        "./SpinWheel",
141        "./SpinWheelSlot",
142        "./SwapView",
143        "./TabBarButton",
144        "./ToolBarButton",
145        "./View"
146], function(declare, lang, win, domClass, domConstruct, domStyle, ready, Container, WidgetBase, _ItemBase, mobile, FixedSplitterPane, Heading, iconUtils, ListItem, RoundRect, SpinWheel, SpinWheelSlot, SwapView, TabBarButton, ToolBarButton, View){
147
148        // module:
149        //              dojox/mobile/migrationAssist
150
151        var currentTheme;
152
153        var MigrationAssist = function(){
154                // summary:
155                //              Dojo Mobile 1.6/1.7 to 1.8 migration assistance.
156
157                var get = function(w, key){
158                        return w[key] || w.srcNodeRef && w.srcNodeRef.getAttribute(key);
159                };
160
161                this.dispatch = function(/*String*/cls, /*Widget*/ w){
162                        var base = cls.replace(/.*\./, "");
163                        this["check" + base] && this["check" + base](w);
164                };
165
166                this.checkCarousel = function(/*Widget*/ w){
167                        console.log('[MIG:error] Carousel has no backward compatibility, since it was experimental in 1.7. The new Carousel supports dojo/store instead of dojo/data.');
168                };
169
170                this.checkFixedSplitter = function(/*Widget*/ w){
171                        // FixedSplitter.css has been moved from the themes/common folder
172                        // to the device theme folder such as themes/android.
173                        if(!this._fixedSplitter_css_checked){
174                                this._fixedSplitter_css_checked = true;
175                                var dummy = domConstruct.create("div", {
176                                        className: "mblFixedSplitter"
177                                }, win.body());
178                                if(domStyle.get(dummy, "height") == 0){
179                                        domConstruct.create("link", {
180                                                href: "../themes/android/FixedSplitter.css",
181                                                type: "text/css",
182                                                rel: "stylesheet"
183                                        }, win.doc.getElementsByTagName('head')[0]);
184                                        console.log('[MIG:fixed] FixedSplitter.css does not seem to be loaded. Loaded it for you just now. It is in the device theme folder.');
185                                }
186                                win.body().removeChild(dummy);
187                                setTimeout(function(){
188                                        w.resize();
189                                }, 1000);
190                        }
191                };
192
193                this.checkFixedSplitterPane = function(/*Widget*/ w){
194                        console.log('[MIG:fixed] FixedSplitterPane: Deprecated. Use dojox/mobile/Container instead.');
195                };
196                this.checkFixedSplitter = function(/*Widget*/ w){
197                        // FixedSplitter.css has been moved from the themes/common folder
198                        // to the device theme folder such as themes/android.
199                        if(!this._fixedSplitter_css_checked){
200                                this._fixedSplitter_css_checked = true;
201                                var dummy = domConstruct.create("div", {
202                                        className: "mblFixedSplitter"
203                                }, win.body());
204                                if(domStyle.get(dummy, "height") == 0){
205                                        domConstruct.create("link", {
206                                                href: "../themes/android/FixedSplitter.css",
207                                                type: "text/css",
208                                                rel: "stylesheet"
209                                        }, win.doc.getElementsByTagName('head')[0]);
210                                        console.log('[MIG:fixed] FixedSplitter.css does not seem to be loaded. Loaded it for you just now. It is in the device theme folder.');
211                                }
212                                win.body().removeChild(dummy);
213                                setTimeout(function(){
214                                        w.resize();
215                                }, 1000);
216                        }
217                };
218
219                this.checkListItem = function(/*Widget*/ w){
220                        if(w.sync !== undefined || w.srcNodeRef && w.srcNodeRef.getAttribute("sync")){
221                                console.log('[MIG:fixed] ListItem: The sync property is no longer supported. (async always)');
222                        }
223                        if(w.btnClass !== undefined || w.srcNodeRef && w.srcNodeRef.getAttribute("btnClass")){
224                                console.log('[MIG:fixed] ListItem: The btnClass property is no longer supported. Use rightIcon instead.');
225                                w.rightIcon = w.btnClass || w.srcNodeRef && w.srcNodeRef.getAttribute("btnClass");
226                        }
227                        if(w.btnClass2 !== undefined || w.srcNodeRef && w.srcNodeRef.getAttribute("btnClass2")){
228                                console.log('[MIG:fixed] ListItem: The btnClass2 property is no longer supported. Use rightIcon2 instead.');
229                                w.rightIcon2 = w.btnClass2 || w.srcNodeRef && w.srcNodeRef.getAttribute("btnClass2");
230                        }
231                };
232
233                this.checkSpinWheelSlot = function(/*Widget*/ w){
234                        if(w.labels && w.labels[0] && w.labels[0].charAt(0) === '['){
235                                for(var i = 0; i < w.labels.length; i++){
236                                        w.labels[i] = w.labels[i].replace(/^\[*[\'\"]*/, '');
237                                        w.labels[i] = w.labels[i].replace(/[\'\"]*\]*$/, '');
238                                }
239                                console.log('[MIG:fixed] SpinWheelSlot: dojox/mobile/parser no longer accepts array-type attribute like labels="[\'A\',\'B\',\'C\',\'D\',\'E\']". Specify as labels="A,B,C,D,E" instead.' );
240                        }
241                };
242
243                this.checkSwapView = function(/*Widget*/ w){
244                        var n = w.srcNodeRef;
245                        if(n){
246                                var type = n.getAttribute("dojoType") || n.getAttribute("data-dojo-type");
247                                if(type === "dojox.mobile.FlippableView"){
248                                        console.log('[MIG:fixed] FlippableView: FlippableView is no longer supported. Use SwapView instead.');
249                                }
250                        }
251                };
252
253                this.checkSwitch = function(/*Widget*/ w){
254                        if(w["class"] === "mblItemSwitch"){
255                                console.log('[MIG:fixed] Switch: class="mblItemSwitch" is no longer necessary.');
256                        }
257                };
258
259                this.checkTabBar = function(/*Widget*/ w){
260                        if(get(w, "barType") === "segmentedControl"){
261                                console.log('[MIG:warning] TabBar: segmentedControl in 1.8 produces the same UI regardless of the current theme. See the inline doc in migrationAssist.js for details.');
262                                domConstruct.create("style", {
263                                        innerHTML: ".iphone_theme .mblTabBarSegmentedControl .mblTabBarButtonIconArea { display: none; }"
264                                }, win.doc.getElementsByTagName('head')[0]);
265                        }
266                };
267
268                this.checkTabBarButton = function(/*Widget*/ w){
269                        if((w["class"] || "").indexOf("mblDomButton") === 0){
270                                console.log('[MIG:fixed] TabBarButton: Use icon="' + w["class"] + '" instead of class="' + w["class"] + '".');
271                                w.icon = w["class"];
272                                w["class"] = "";
273                                if(w.srcNodeRef){
274                                        w.srcNodeRef.className = "";
275                                }
276                        }
277                };
278
279                this.checkToolBarButton = function(/*Widget*/ w){
280                        if((w["class"] || "").indexOf("mblColor") === 0){
281                                console.log('[MIG:fixed] ToolBarButton: Use defaultColor="' + w["class"] + '" instead of class="' + w["class"] + '".');
282                                w.defaultColor = w["class"];
283                                w["class"] = "";
284                                if(w.srcNodeRef){
285                                        w.srcNodeRef.className = "";
286                                }
287                        }
288
289                        if((w["class"] || "").indexOf("mblDomButton") === 0){
290                                console.log('[MIG:fixed] ToolBarButton: Use icon="' + w["class"] + '" instead of class="' + w["class"] + '".');
291                                w.icon = w["class"];
292                                w["class"] = "";
293                                if(w.srcNodeRef){
294                                        w.srcNodeRef.className = "";
295                                }
296                        }
297                };
298        };
299
300        dojox.mobile.FlippableView = SwapView;
301
302        var migrationAssist = new MigrationAssist();
303
304        // Hide from the API doc tool, we want to get the documentation for the normal WidgetBase.postMixInProperties()
305        WidgetBase.prototype.postMixInProperties = /*===== WidgetBase.prototype.postMixInProperties || =====*/ function(){
306                migrationAssist.dispatch(this.declaredClass, this);
307                dojo.forEach([FixedSplitterPane, Heading, RoundRect, SpinWheel, TabBarButton, ToolBarButton, View], function(module){
308                        if(this.declaredClass !== module.prototype.declaredClass && this instanceof module){
309                                migrationAssist.dispatch(module.prototype.declaredClass, this);
310                        }
311                }, this);
312
313        };
314
315
316        extendSelectFunction = function(obj) {
317                lang.extend(obj, {
318                        select: function(){
319                                console.log('[MIG:fixed] ' + this.declaredClass + '(id='+this.id+'): Use set("selected", boolean) instead of select/deselect.');
320                                obj.prototype.set.apply(this, ["selected", !arguments[0]]);
321                        },
322                        deselect: function(){
323                                this.select(true);
324                        }
325                });
326        };
327
328        extendSelectFunction(ToolBarButton);
329        extendSelectFunction(TabBarButton);
330
331        lang.extend(ListItem, {
332                set: function(key, value){
333                        if(key === "btnClass"){
334                                console.log('[MIG:fixed] ' + this.declaredClass + '(id='+this.id+'): Use set("rightIcon",x) instead of set("btnClass",x).');
335                                key = "rightIcon";
336                        }else if(key === "btnClass2"){
337                                console.log('[MIG:fixed] ' + this.declaredClass + '(id='+this.id+'): Use set("rightIcon2",x) instead of set("btnClass2",x).');
338                                key = "rightIcon2";
339                        }
340                        WidgetBase.prototype.set.apply(this, [key, value]);
341                }
342        });
343
344        lang.extend(SpinWheel, {
345                getValue: function(){
346                        console.log('[MIG:fixed] SpinWheel: getValue() is no longer supported. Use get("values") instead.');
347                        return this.get("values");
348                },
349                setValue: function(newValue){
350                        console.log('[MIG:fixed] SpinWheel: setValue() is no longer supported. Use set("values",x) instead.');
351                        return this.set("values", newValue);
352                }
353        });
354
355        lang.extend(SpinWheelSlot, {
356                getValue: function(){
357                        console.log('[MIG:fixed] SpinWheelSlot: getValue() is no longer supported. Use get("value") instead.');
358                        return this.get("value");
359                },
360                getKey: function(){
361                        console.log('[MIG:fixed] SpinWheelSlot: getKey() is no longer supported. Use get("key") instead.');
362                        return this.get("key");
363                },
364                setValue: function(newValue){
365                        console.log('[MIG:fixed] SpinWheelSlot: setValue() is no longer supported. Use set("value",x) instead.');
366                        return this.set("value", newValue);
367                }
368        });
369
370        lang.mixin(mobile, {
371                createDomButton: function(){
372                        console.log('[MIG:fixed] dojox.mobile(id='+arguments[0].id+'): createDomButton was moved to iconUtils.');
373                        return iconUtils.createDomButton.apply(this, arguments);
374                }
375        });
376
377        // check css
378        var cssFiles = [], i, j;
379
380        // collect @import
381        var s = win.doc.styleSheets;
382        for(i = 0; i < s.length; i++){
383                if(s[i].href){ continue; }
384                var r = s[i].cssRules || s[i].imports;
385                if(!r){ continue; }
386                for(j = 0; j < r.length; j++){
387                        if(r[j].href){
388                                cssFiles.push(r[j].href);
389                        }
390                }
391        }
392
393        // collect <link>
394        var elems = win.doc.getElementsByTagName("link");
395        for(i = 0; i < elems.length; i++){
396                cssFiles.push(elems[i].href);
397        }
398
399        for(i = 0; i < cssFiles.length; i++){
400                if(cssFiles[i].indexOf("/iphone/") !== -1){
401                        currentTheme = "iphone";
402                }else if(cssFiles[i].indexOf("/android/") !== -1){
403                        currentTheme = "android";
404                }else if(cssFiles[i].indexOf("/blackberry/") !== -1){
405                        currentTheme = "blackberry";
406                }else if(cssFiles[i].indexOf("/custom/") !== -1){
407                        currentTheme = "custom";
408                }
409                domClass.add(win.doc.documentElement, currentTheme + "_theme");
410
411                if(cssFiles[i].match(/themes\/common\/(FixedSplitter.css)|themes\/common\/(SpinWheel.css)/)){
412                        console.log('[MIG:error] ' + (RegExp.$1 || RegExp.$2) + ' is no longer in the themes/common folder. It is in the device theme folder.');
413                }
414        }
415
416        ready(function(){
417                if(dojo.hash){
418                        console.log('[MIG:fixed] dojo/hash detected. If you would like to enable the bookmarkable feature, require dojox/mobile/bookmarkable instead of dojo/hash');
419                        if(dojo.require){
420                                dojo["require"]("dojox.mobile.bookmarkable");
421                        }else{
422                                require(["dojox/mobile/bookmarkable"]);
423                        }
424                }
425        });
426
427        // Return singleton.  (TODO: can we replace LazyLoadUtils class and singleton w/a simple hash of functions?)
428        return migrationAssist;
429});
Note: See TracBrowser for help on using the repository browser.