1 | define([ |
---|
2 | "dojo/_base/kernel", |
---|
3 | "dojo/_base/array", |
---|
4 | "dojo/_base/declare", |
---|
5 | "dojo/_base/lang", |
---|
6 | "dojo/_base/sniff", |
---|
7 | "dojo/_base/window", |
---|
8 | "dojo/dom-attr", |
---|
9 | "dojo/dom-class", |
---|
10 | "dojo/dom-construct", |
---|
11 | "dojo/dom-style", |
---|
12 | "dijit/registry", // registry.byId |
---|
13 | "./common", |
---|
14 | "./_ItemBase", |
---|
15 | "./TransitionEvent" |
---|
16 | ], function(dojo, array, declare, lang, has, win, domAttr, domClass, domConstruct, domStyle, registry, common, ItemBase, TransitionEvent){ |
---|
17 | |
---|
18 | /*===== |
---|
19 | var ItemBase = dojox.mobile._ItemBase; |
---|
20 | =====*/ |
---|
21 | |
---|
22 | // module: |
---|
23 | // dojox/mobile/IconItem |
---|
24 | // summary: |
---|
25 | // An icon item widget. |
---|
26 | |
---|
27 | return declare("dojox.mobile.IconItem", ItemBase, { |
---|
28 | // summary: |
---|
29 | // An icon item widget. |
---|
30 | // description: |
---|
31 | // IconItem represents an item that has an application component |
---|
32 | // and its icon image. You can tap the icon to open the |
---|
33 | // corresponding application component. You can also use the icon |
---|
34 | // to move to a different view by specifying either of the moveTo, |
---|
35 | // href or url parameters. |
---|
36 | |
---|
37 | // lazy: String |
---|
38 | // If true, the content of the item, which includes dojo markup, is |
---|
39 | // instantiated lazily. That is, only when the icon is opened by |
---|
40 | // the user, the required modules are loaded and dojo widgets are |
---|
41 | // instantiated. |
---|
42 | lazy: false, |
---|
43 | |
---|
44 | // requires: String |
---|
45 | // Comma-separated required module names to be loaded. All the |
---|
46 | // modules specified with dojoType and their depending modules are |
---|
47 | // automatically loaded by the IconItem. If you need other extra |
---|
48 | // modules to be loaded, use this parameter. If lazy is true, the |
---|
49 | // specified required modules are loaded when the user opens the |
---|
50 | // icon for the first time. |
---|
51 | requires: "", |
---|
52 | |
---|
53 | // timeout: String |
---|
54 | // Duration of highlight in seconds. |
---|
55 | timeout: 10, |
---|
56 | |
---|
57 | // closeBtnClass: String |
---|
58 | // A class name of a DOM button to be used as a close button. |
---|
59 | closeBtnClass: "mblDomButtonBlueMinus", |
---|
60 | |
---|
61 | // closeBtnProp: String |
---|
62 | // Properties for the close button. |
---|
63 | closeBtnProp: null, |
---|
64 | |
---|
65 | |
---|
66 | templateString: '<div class="mblIconArea" dojoAttachPoint="iconDivNode">'+ |
---|
67 | '<div><img src="${icon}" dojoAttachPoint="iconNode"></div><span dojoAttachPoint="labelNode1"></span>'+ |
---|
68 | '</div>', |
---|
69 | templateStringSub: '<li class="mblIconItemSub" lazy="${lazy}" style="display:none;" dojoAttachPoint="contentNode">'+ |
---|
70 | '<h2 class="mblIconContentHeading" dojoAttachPoint="closeNode">'+ |
---|
71 | '<div class="${closeBtnClass}" style="position:absolute;left:4px;top:2px;" dojoAttachPoint="closeIconNode"></div><span dojoAttachPoint="labelNode2"></span>'+ |
---|
72 | '</h2>'+ |
---|
73 | '<div class="mblContent" dojoAttachPoint="containerNode"></div>'+ |
---|
74 | '</li>', |
---|
75 | |
---|
76 | createTemplate: function(s){ |
---|
77 | array.forEach(["lazy","icon","closeBtnClass"], function(v){ |
---|
78 | while(s.indexOf("${"+v+"}") != -1){ |
---|
79 | s = s.replace("${"+v+"}", this[v]); |
---|
80 | } |
---|
81 | }, this); |
---|
82 | var div = win.doc.createElement("DIV"); |
---|
83 | div.innerHTML = s; |
---|
84 | |
---|
85 | /* |
---|
86 | array.forEach(query("[dojoAttachPoint]", domNode), function(node){ |
---|
87 | this[node.getAttribute("dojoAttachPoint")] = node; |
---|
88 | }, this); |
---|
89 | */ |
---|
90 | |
---|
91 | var nodes = div.getElementsByTagName("*"); |
---|
92 | var i, len, s1; |
---|
93 | len = nodes.length; |
---|
94 | for(i = 0; i < len; i++){ |
---|
95 | s1 = nodes[i].getAttribute("dojoAttachPoint"); |
---|
96 | if(s1){ |
---|
97 | this[s1] = nodes[i]; |
---|
98 | } |
---|
99 | } |
---|
100 | if(this.closeIconNode && this.closeBtnProp){ |
---|
101 | domAttr.set(this.closeIconNode, this.closeBtnProp); |
---|
102 | } |
---|
103 | var domNode = div.removeChild(div.firstChild); |
---|
104 | div = null; |
---|
105 | return domNode; |
---|
106 | }, |
---|
107 | |
---|
108 | buildRendering: function(){ |
---|
109 | this.inheritParams(); |
---|
110 | var node = this.createTemplate(this.templateString); |
---|
111 | this.subNode = this.createTemplate(this.templateStringSub); |
---|
112 | this.subNode._parentNode = this.domNode; // [custom property] |
---|
113 | |
---|
114 | this.domNode = this.srcNodeRef || domConstruct.create("LI"); |
---|
115 | domClass.add(this.domNode, "mblIconItem"); |
---|
116 | if(this.srcNodeRef){ |
---|
117 | // reparent |
---|
118 | for(var i = 0, len = this.srcNodeRef.childNodes.length; i < len; i++){ |
---|
119 | this.containerNode.appendChild(this.srcNodeRef.firstChild); |
---|
120 | } |
---|
121 | } |
---|
122 | this.domNode.appendChild(node); |
---|
123 | }, |
---|
124 | |
---|
125 | postCreate: function(){ |
---|
126 | common.createDomButton(this.closeIconNode, { |
---|
127 | top: "-2px", |
---|
128 | left: "1px" |
---|
129 | }); |
---|
130 | this.connect(this.iconNode, "onmousedown", "onMouseDownIcon"); |
---|
131 | this.connect(this.iconNode, "onclick", "iconClicked"); |
---|
132 | this.connect(this.closeIconNode, "onclick", "closeIconClicked"); |
---|
133 | this.connect(this.iconNode, "onerror", "onError"); |
---|
134 | }, |
---|
135 | |
---|
136 | highlight: function(){ |
---|
137 | // summary: |
---|
138 | // Shakes the icon 10 seconds. |
---|
139 | domClass.add(this.iconDivNode, "mblVibrate"); |
---|
140 | if(this.timeout > 0){ |
---|
141 | var _this = this; |
---|
142 | setTimeout(function(){ |
---|
143 | _this.unhighlight(); |
---|
144 | }, this.timeout*1000); |
---|
145 | } |
---|
146 | }, |
---|
147 | |
---|
148 | unhighlight: function(){ |
---|
149 | // summary: |
---|
150 | // Stops shaking the icon. |
---|
151 | domClass.remove(this.iconDivNode, "mblVibrate"); |
---|
152 | }, |
---|
153 | |
---|
154 | instantiateWidget: function(e){ |
---|
155 | // summary: |
---|
156 | // Instantiates the icon content. |
---|
157 | |
---|
158 | // avoid use of query |
---|
159 | /* |
---|
160 | var list = query('[dojoType]', this.containerNode); |
---|
161 | for(var i = 0, len = list.length; i < len; i++){ |
---|
162 | dojo["require"](list[i].getAttribute("dojoType")); |
---|
163 | } |
---|
164 | */ |
---|
165 | |
---|
166 | var nodes = this.containerNode.getElementsByTagName("*"); |
---|
167 | var len = nodes.length; |
---|
168 | var s; |
---|
169 | for(var i = 0; i < len; i++){ |
---|
170 | s = nodes[i].getAttribute("dojoType"); |
---|
171 | if(s){ |
---|
172 | dojo["require"](s); |
---|
173 | } |
---|
174 | } |
---|
175 | |
---|
176 | if(len > 0){ |
---|
177 | dojo.parser.parse(this.containerNode); |
---|
178 | } |
---|
179 | this.lazy = false; |
---|
180 | }, |
---|
181 | |
---|
182 | isOpen: function(e){ |
---|
183 | // summary: |
---|
184 | // Returns true if the icon is open. |
---|
185 | return this.containerNode.style.display != "none"; |
---|
186 | }, |
---|
187 | |
---|
188 | onMouseDownIcon: function (e){ |
---|
189 | domStyle.set(this.iconNode, "opacity", this.getParent().pressedIconOpacity); |
---|
190 | }, |
---|
191 | |
---|
192 | iconClicked: function(e){ |
---|
193 | if(e){ |
---|
194 | this.setTransitionPos(e); |
---|
195 | setTimeout(lang.hitch(this, function(d){ this.iconClicked(); }), 0); |
---|
196 | return; |
---|
197 | } |
---|
198 | |
---|
199 | if (this.href && this.hrefTarget) { |
---|
200 | common.openWindow(this.href, this.hrefTarget); |
---|
201 | dojo.style(this.iconNode, "opacity", 1); |
---|
202 | return; |
---|
203 | } |
---|
204 | |
---|
205 | var transOpts; |
---|
206 | if(this.moveTo || this.href || this.url || this.scene){ |
---|
207 | transOpts = {moveTo: this.moveTo, href: this.href, url: this.url, scene: this.scene, transitionDir: this.transitionDir, transition: this.transition}; |
---|
208 | }else if(this.transitionOptions){ |
---|
209 | transOpts = this.transitionOptions; |
---|
210 | } |
---|
211 | if(transOpts){ |
---|
212 | setTimeout(lang.hitch(this, function(d){ |
---|
213 | domStyle.set(this.iconNode, "opacity", 1); |
---|
214 | }), 1500); |
---|
215 | }else{ |
---|
216 | return this.open(e); |
---|
217 | } |
---|
218 | |
---|
219 | if(transOpts){ |
---|
220 | return new TransitionEvent(this.domNode,transOpts,e).dispatch(); |
---|
221 | } |
---|
222 | }, |
---|
223 | |
---|
224 | closeIconClicked: function(e){ |
---|
225 | if(e){ |
---|
226 | setTimeout(lang.hitch(this, function(d){ this.closeIconClicked(); }), 0); |
---|
227 | return; |
---|
228 | } |
---|
229 | this.close(); |
---|
230 | }, |
---|
231 | |
---|
232 | open: function(e){ |
---|
233 | // summary: |
---|
234 | // Opens the icon content, or makes a transition. |
---|
235 | var parent = this.getParent(); // IconContainer |
---|
236 | if(this.transition == "below"){ |
---|
237 | if(parent.single){ |
---|
238 | parent.closeAll(); |
---|
239 | domStyle.set(this.iconNode, "opacity", this.getParent().pressedIconOpacity); |
---|
240 | } |
---|
241 | this._open_1(); |
---|
242 | }else{ |
---|
243 | parent._opening = this; |
---|
244 | if(parent.single){ |
---|
245 | this.closeNode.style.display = "none"; |
---|
246 | parent.closeAll(); |
---|
247 | var view = registry.byId(parent.id+"_mblApplView"); |
---|
248 | view._heading._setLabelAttr(this.label); |
---|
249 | } |
---|
250 | var transOpts = this.transitionOptions || {transition: this.transition, transitionDir: this.transitionDir, moveTo: parent.id + "_mblApplView"}; |
---|
251 | new TransitionEvent(this.domNode, transOpts, e).dispatch(); |
---|
252 | } |
---|
253 | }, |
---|
254 | |
---|
255 | _open_1: function(){ |
---|
256 | this.contentNode.style.display = ""; |
---|
257 | this.unhighlight(); |
---|
258 | if(this.lazy){ |
---|
259 | if(this.requires){ |
---|
260 | array.forEach(this.requires.split(/,/), function(c){ |
---|
261 | dojo["require"](c); |
---|
262 | }); |
---|
263 | } |
---|
264 | this.instantiateWidget(); |
---|
265 | } |
---|
266 | this.contentNode.scrollIntoView(); |
---|
267 | this.onOpen(); |
---|
268 | }, |
---|
269 | |
---|
270 | close: function(){ |
---|
271 | // summary: |
---|
272 | // Closes the icon content. |
---|
273 | if(has("webkit")){ |
---|
274 | var t = this.domNode.parentNode.offsetWidth/8; |
---|
275 | var y = this.iconNode.offsetLeft; |
---|
276 | var pos = 0; |
---|
277 | for(var i = 1; i <= 3; i++){ |
---|
278 | if(t*(2*i-1) < y && y <= t*(2*(i+1)-1)){ |
---|
279 | pos = i; |
---|
280 | break; |
---|
281 | } |
---|
282 | } |
---|
283 | domClass.add(this.containerNode.parentNode, "mblCloseContent mblShrink"+pos); |
---|
284 | }else{ |
---|
285 | this.containerNode.parentNode.style.display = "none"; |
---|
286 | } |
---|
287 | domStyle.set(this.iconNode, "opacity", 1); |
---|
288 | this.onClose(); |
---|
289 | }, |
---|
290 | |
---|
291 | onOpen: function(){ |
---|
292 | // summary: |
---|
293 | // Stub method to allow the application to connect to. |
---|
294 | }, |
---|
295 | |
---|
296 | onClose: function(){ |
---|
297 | // summary: |
---|
298 | // Stub method to allow the application to connect to. |
---|
299 | }, |
---|
300 | |
---|
301 | onError: function(){ |
---|
302 | var icon = this.getParent().defaultIcon; |
---|
303 | if(icon){ |
---|
304 | this.iconNode.src = icon; |
---|
305 | } |
---|
306 | }, |
---|
307 | |
---|
308 | _setIconAttr: function(icon){ |
---|
309 | if(!this.getParent()){ return; } // icon may be invalid because inheritParams is not called yet |
---|
310 | this.icon = icon; |
---|
311 | common.createIcon(icon, this.iconPos, this.iconNode, this.alt); |
---|
312 | if(this.iconPos){ |
---|
313 | domClass.add(this.iconNode, "mblIconItemSpriteIcon"); |
---|
314 | var arr = this.iconPos.split(/[ ,]/); |
---|
315 | var p = this.iconNode.parentNode; |
---|
316 | domStyle.set(p, { |
---|
317 | width: arr[2] + "px", |
---|
318 | top: Math.round((p.offsetHeight - arr[3]) / 2) + 1 + "px", |
---|
319 | margin: "auto" |
---|
320 | }); |
---|
321 | } |
---|
322 | }, |
---|
323 | |
---|
324 | _setLabelAttr: function(/*String*/text){ |
---|
325 | this.label = text; |
---|
326 | var s = this._cv ? this._cv(text) : text; |
---|
327 | this.labelNode1.innerHTML = s; |
---|
328 | this.labelNode2.innerHTML = s; |
---|
329 | } |
---|
330 | }); |
---|
331 | }); |
---|