IconItem.js 9.2 KB

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