define("dojox/mobile/IconItem", [ "dojo/_base/declare", "dojo/_base/event", "dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/window", "dojo/dom-class", "dojo/dom-construct", "dojo/dom-geometry", "dojo/dom-style", "./_ItemBase", "./Badge", "./TransitionEvent", "./iconUtils", "./lazyLoadUtils", "./viewRegistry" ], function(declare, event, lang, has, win, domClass, domConstruct, domGeometry, domStyle, ItemBase, Badge, TransitionEvent, iconUtils, lazyLoadUtils, viewRegistry){ // module: // dojox/mobile/IconItem return declare("dojox.mobile.IconItem", ItemBase, { // summary: // An icon item widget. // description: // IconItem represents an item that has an application component // and its icon image. You can tap the icon to open the // corresponding application component. You can also use the icon // to move to a different view by specifying either of the moveTo, // href or url parameters. // lazy: String // If true, the content of the widget, which includes dojo markup, // is instantiated lazily. That is, only when the widget is opened // by the user, the required modules are loaded and the content // widgets are instantiated. // This option works both in the sync and async loader mode. lazy: false, // requires: String // Comma-separated required module names to be lazily loaded. This // property is effective only when lazy=true. All the modules // specified with data-dojo-type and their depending modules are // automatically loaded by the IconItem when it is opened. // However, if you need other extra modules to be loaded, use this parameter. // This option works both in the sync and async loader mode. requires: "", // timeout: String // Duration of highlight in seconds. timeout: 10, // content: String // An HTML fragment to embed as icon content. content: "", // badge: String // A text to show in a badge (ex. "55"). badge: "", // badgeClass: String // A class name of a DOM button for a badge. badgeClass: "mblDomButtonRedBadge", // deletable: Boolean // If true, you can delete this IconItem by clicking on the delete // icon during edit mode. // If false, the delete icon is not displayed during edit mode so // that it cannot be deleted. deletable: true, // deleteIcon: String // A delete icon to display at the top-left corner of the item // during edit mode. The value can be either a path for an image // file or a class name of a DOM button. deleteIcon: "", // tag: String // A name of the HTML tag to create as domNode. tag: "li", /* internal properties */ // Note these are overrides for similar properties defined in _ItemBase. paramsToInherit: "transition,icon,deleteIcon,badgeClass,deleteIconTitle,deleteIconRole", baseClass: "mblIconItem", _selStartMethod: "touch", _selEndMethod: "none", destroy: function(){ if(this.badgeObj){ delete this.badgeObj; } this.inherited(arguments); }, buildRendering: function(){ this.domNode = this.srcNodeRef || domConstruct.create(this.tag); if(this.srcNodeRef){ // reparent this._tmpNode = domConstruct.create("div"); for(var i = 0, len = this.srcNodeRef.childNodes.length; i < len; i++){ this._tmpNode.appendChild(this.srcNodeRef.firstChild); } } this.iconDivNode = domConstruct.create("div", {className:"mblIconArea"}, this.domNode); this.iconParentNode = domConstruct.create("div", {className:"mblIconAreaInner"}, this.iconDivNode); this.labelNode = domConstruct.create("span", {className:"mblIconAreaTitle"}, this.iconDivNode); this.inherited(arguments); }, startup: function(){ if(this._started){ return; } var p = this.getParent(); require([p.iconItemPaneClass], lang.hitch(this, function(module){ var w = this.paneWidget = new module(p.iconItemPaneProps); this.containerNode = w.containerNode; if(this._tmpNode){ // reparent for(var i = 0, len = this._tmpNode.childNodes.length; i < len; i++){ w.containerNode.appendChild(this._tmpNode.firstChild); } this._tmpNode = null; } p.paneContainerWidget.addChild(w, this.getIndexInParent()); w.set("label", this.label); this._clickCloseHandle = this.connect(w.closeIconNode, "onclick", "_closeIconClicked"); this._keydownCloseHandle = this.connect(w.closeIconNode, "onkeydown", "_closeIconClicked"); // for desktop browsers })); this.inherited(arguments); if(!this._isOnLine){ this._isOnLine = true; // retry applying the attribute for which the custom setter delays the actual // work until _isOnLine is true. this.set("icon", this._pendingIcon !== undefined ? this._pendingIcon : this.icon); // Not needed anymore (this code executes only once per life cycle): delete this._pendingIcon; } if(!this.icon && p.defaultIcon){ this.set("icon", p.defaultIcon); } this._dragstartHandle = this.connect(this.domNode, "ondragstart", event.stop); this._keydownHandle = this.connect(this.domNode, "onkeydown", "_onClick"); // for desktop browsers }, highlight: function(/*Number?*/timeout){ // summary: // Shakes the icon 10 seconds. domClass.add(this.iconDivNode, "mblVibrate"); timeout = (timeout !== undefined) ? timeout : this.timeout; if(timeout > 0){ var _this = this; setTimeout(function(){ _this.unhighlight(); }, timeout*1000); } }, unhighlight: function(){ // summary: // Stops shaking the icon. domClass.remove(this.iconDivNode, "mblVibrate"); }, isOpen: function(e){ // summary: // Returns true if the icon is open. return this.paneWidget.isOpen(); }, _onClick: function(e){ // summary: // Internal handler for click events. // tags: // private if(this.getParent().isEditing || e && e.type === "keydown" && e.keyCode !== 13){ return; } if(this.onClick(e) === false){ return; } // user's click action this.defaultClickAction(e); }, onClick: function(/*Event*/ /*===== e =====*/){ // summary: // User-defined function to handle clicks. // tags: // callback }, _onNewWindowOpened: function(e){ // Override from _ItemBase this.set("selected", false); }, _prepareForTransition: function(e, transOpts){ // Override from _ItemBase if(transOpts){ setTimeout(lang.hitch(this, function(d){ this.set("selected", false); }), 1500); return true; }else{ if(this.getParent().transition === "below" && this.isOpen()){ this.close(); }else{ this.open(e); } return false; } }, _closeIconClicked: function(e){ // summary: // Internal handler for click events. // tags: // private if(e){ if(e.type === "keydown" && e.keyCode !== 13){ return; } if(this.closeIconClicked(e) === false){ return; } // user's click action setTimeout(lang.hitch(this, function(d){ this._closeIconClicked(); }), 0); return; } this.close(); }, closeIconClicked: function(/*Event*/ /*===== e =====*/){ // summary: // User-defined function to handle clicks for the close icon. // tags: // callback }, open: function(e){ // summary: // Opens the icon content, or makes a transition. var parent = this.getParent(); // IconContainer if(this.transition === "below"){ if(parent.single){ parent.closeAll(); } this._open_1(); }else{ parent._opening = this; if(parent.single){ this.paneWidget.closeHeaderNode.style.display = "none"; if(!this.isOpen()){ parent.closeAll(); } parent.appView._heading.set("label", this.label); } this.moveTo = parent.id + "_mblApplView"; new TransitionEvent(this.domNode, this.getTransOpts(), e).dispatch(); } }, _open_1: function(){ // tags: // private this.paneWidget.show(); this.unhighlight(); if(this.lazy){ lazyLoadUtils.instantiateLazyWidgets(this.containerNode, this.requires); this.lazy = false; } this.scrollIntoView(this.paneWidget.domNode); this.onOpen(); }, scrollIntoView: function(/*DomNode*/node){ // summary: // Scrolls until the given node is in the view. var s = viewRegistry.getEnclosingScrollable(node); if(s){ // this node is placed inside scrollable s.scrollIntoView(node, true); }else{ win.global.scrollBy(0, domGeometry.position(node, false).y); } }, close: function(/*Boolean?*/noAnimation){ // summary: // Closes the icon content. if(!this.isOpen()){ return; } this.set("selected", false); if(has("webkit") && !noAnimation){ var contentNode = this.paneWidget.domNode; if(this.getParent().transition == "below"){ domClass.add(contentNode, "mblCloseContent mblShrink"); var nodePos = domGeometry.position(contentNode, true); var targetPos = domGeometry.position(this.domNode, true); var origin = (targetPos.x + targetPos.w/2 - nodePos.x) + "px " + (targetPos.y + targetPos.h/2 - nodePos.y) + "px"; domStyle.set(contentNode, { webkitTransformOrigin:origin }); }else{ domClass.add(contentNode, "mblCloseContent mblShrink0"); } }else{ this.paneWidget.hide(); } this.onClose(); }, onOpen: function(){ // summary: // Stub method to allow the application to connect. }, onClose: function(){ // summary: // Stub method to allow the application to connect. }, _setLabelAttr: function(/*String*/text){ // tags: // private this.label = text; var s = this._cv ? this._cv(text) : text; this.labelNode.innerHTML = s; if(this.paneWidget){ this.paneWidget.set("label", text); } }, _getBadgeAttr: function(){ // tags: // private return this.badgeObj ? this.badgeObj.getValue() : null; }, _setBadgeAttr: function(/*String*/value){ // tags: // private if(!this.badgeObj){ this.badgeObj = new Badge({fontSize:14, className:this.badgeClass}); domStyle.set(this.badgeObj.domNode, { position: "absolute", top: "-2px", right: "2px" }); } this.badgeObj.setValue(value); if(value){ this.iconDivNode.appendChild(this.badgeObj.domNode); }else{ this.iconDivNode.removeChild(this.badgeObj.domNode); } }, _setDeleteIconAttr: function(icon){ // tags: // private if(!this.getParent()){ return; } // icon may be invalid because inheritParams is not called yet this._set("deleteIcon", icon); icon = this.deletable ? icon : ""; this.deleteIconNode = iconUtils.setIcon(icon, this.deleteIconPos, this.deleteIconNode, this.deleteIconTitle || this.alt, this.iconDivNode); if(this.deleteIconNode){ domClass.add(this.deleteIconNode, "mblIconItemDeleteIcon"); if(this.deleteIconRole){ this.deleteIconNode.setAttribute("role", this.deleteIconRole); } } }, _setContentAttr: function(/*String|DomNode*/data){ // tags: // private var root; if(!this.paneWidget){ if(!this._tmpNode){ this._tmpNode = domConstruct.create("div"); } root = this._tmpNode; }else{ root = this.paneWidget.containerNode; } if(typeof data === "object"){ domConstruct.empty(root); root.appendChild(data); }else{ root.innerHTML = data; } }, _setSelectedAttr: function(/*Boolean*/selected){ // summary: // Makes this widget in the selected or unselected state. // tags: // private this.inherited(arguments); this.iconNode && domStyle.set(this.iconNode, "opacity", selected ? this.getParent().pressedIconOpacity : 1); } }); });