source: Dev/trunk/src/client/dojox/mobile/iconUtils.js @ 532

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

Added Dojo 1.9.3 release.

File size: 7.6 KB
Line 
1define([
2        "dojo/_base/array",
3        "dojo/_base/config",
4        "dojo/_base/connect",
5        "dojo/_base/event",
6        "dojo/_base/lang",
7        "dojo/_base/window",
8        "dojo/dom-class",
9        "dojo/dom-construct",
10        "dojo/dom-style",
11        "./sniff"
12], function(array, config, connect, event, lang, win, domClass, domConstruct, domStyle, has){
13
14        var dm = lang.getObject("dojox.mobile", true);
15
16        // module:
17        //              dojox/mobile/iconUtils
18
19        var IconUtils = function(){
20                // summary:
21                //              Utilities to create an icon (image, CSS sprite image, or DOM Button).
22
23                this.setupSpriteIcon = function(/*DomNode*/iconNode, /*String*/iconPos){
24                        // summary:
25                        //              Sets up CSS sprite for a foreground image.
26                        if(iconNode && iconPos){
27                                var arr = array.map(iconPos.split(/[ ,]/),function(item){return item-0});
28                                var t = arr[0]; // top
29                                var r = arr[1] + arr[2]; // right
30                                var b = arr[0] + arr[3]; // bottom
31                                var l = arr[1]; // left
32                                domStyle.set(iconNode, {
33                                        position: "absolute",
34                                        clip: "rect("+t+"px "+r+"px "+b+"px "+l+"px)",
35                                        top: (iconNode.parentNode ? domStyle.get(iconNode, "top") : 0) - t + "px",
36                                        left: -l + "px"
37                                });
38                                domClass.add(iconNode, "mblSpriteIcon");
39                        }
40                };
41
42                this.createDomButton = function(/*DomNode*/refNode, /*Object?*/style, /*DomNode?*/toNode){
43                        // summary:
44                        //              Creates a DOM button.
45                        // description:
46                        //              DOM button is a simple graphical object that consists of one or
47                        //              more nested DIV elements with some CSS styling. It can be used
48                        //              in place of an icon image on ListItem, IconItem, and so on.
49                        //              The kind of DOM button to create is given as a class name of
50                        //              refNode. The number of DIVs to create is searched from the style
51                        //              sheets in the page. However, if the class name has a suffix that
52                        //              starts with an underscore, like mblDomButtonGoldStar_5, then the
53                        //              suffixed number is used instead. A class name for DOM button
54                        //              must starts with 'mblDomButton'.
55                        // refNode:
56                        //              A node that has a DOM button class name.
57                        // style:
58                        //              A hash object to set styles to the node.
59                        // toNode:
60                        //              A root node to create a DOM button. If omitted, refNode is used.
61
62                        if(!this._domButtons){
63                                if(has("webkit")){
64                                        var findDomButtons = function(sheet, dic){
65                                                // summary:
66                                                //              Searches the style sheets for DOM buttons.
67                                                // description:
68                                                //              Returns a key-value pair object whose keys are DOM
69                                                //              button class names and values are the number of DOM
70                                                //              elements they need.
71                                                var i, j;
72                                                if(!sheet){
73                                                        var _dic = {};
74                                                        var ss = win.doc.styleSheets;
75                                                        for (i = 0; i < ss.length; i++){
76                                                                ss[i] && findDomButtons(ss[i], _dic);
77                                                        }
78                                                        return _dic;
79                                                }
80                                                var rules = sheet.cssRules || [];
81                                                for (i = 0; i < rules.length; i++){
82                                                        var rule = rules[i];
83                                                        if(rule.href && rule.styleSheet){
84                                                                findDomButtons(rule.styleSheet, dic);
85                                                        }else if(rule.selectorText){
86                                                                var sels = rule.selectorText.split(/,/);
87                                                                for (j = 0; j < sels.length; j++){
88                                                                        var sel = sels[j];
89                                                                        var n = sel.split(/>/).length - 1;
90                                                                        if(sel.match(/(mblDomButton\w+)/)){
91                                                                                var cls = RegExp.$1;
92                                                                                if(!dic[cls] || n > dic[cls]){
93                                                                                        dic[cls] = n;
94                                                                                }
95                                                                        }
96                                                                }
97                                                        }
98                                                }
99                                                return dic;
100                                        }
101                                        this._domButtons = findDomButtons();
102                                }else{
103                                        this._domButtons = {};
104                                }
105                        }
106
107                        var s = refNode.className;
108                        var node = toNode || refNode;
109                        if(s.match(/(mblDomButton\w+)/) && s.indexOf("/") === -1){
110                                var btnClass = RegExp.$1;
111                                var nDiv = 4;
112                                if(s.match(/(mblDomButton\w+_(\d+))/)){
113                                        nDiv = RegExp.$2 - 0;
114                                }else if(this._domButtons[btnClass] !== undefined){
115                                        nDiv = this._domButtons[btnClass];
116                                }
117                                var props = null;
118                                if(has("bb") && config["mblBBBoxShadowWorkaround"] !== false){
119                                        // Removes box-shadow because BlackBerry incorrectly renders it.
120                                        props = {style:"-webkit-box-shadow:none"};
121                                }
122                                for(var i = 0, p = node; i < nDiv; i++){
123                                        p = p.firstChild || domConstruct.create("div", props, p);
124                                }
125                                if(toNode){
126                                        setTimeout(function(){
127                                                domClass.remove(refNode, btnClass);
128                                        }, 0);
129                                        domClass.add(toNode, btnClass);
130                                }
131                        }else if(s.indexOf(".") !== -1){ // file name
132                                domConstruct.create("img", {src:s}, node);
133                        }else{
134                                return null;
135                        }
136                        domClass.add(node, "mblDomButton");
137                        !!style && domStyle.set(node, style);
138                        return node;
139                };
140
141                this.createIcon = function(/*String*/icon, /*String?*/iconPos, /*DomNode?*/node, /*String?*/title, /*DomNode?*/parent, /*DomNode?*/refNode, /*String?*/pos){
142                        // summary:
143                        //              Creates or updates an icon node
144                        // description:
145                        //              If node exists, updates the existing node. Otherwise, creates a new one.
146                        // icon:
147                        //              Path for an image, or DOM button class name.
148                        title = title || "";
149                        if(icon && icon.indexOf("mblDomButton") === 0){
150                                // DOM button
151                                if(!node){
152                                        node = domConstruct.create("div", null, refNode || parent, pos);
153                                }else{
154                                        if(node.className.match(/(mblDomButton\w+)/)){
155                                                domClass.remove(node, RegExp.$1);
156                                        }
157                                }
158                                node.title = title;
159                                domClass.add(node, icon);
160                                this.createDomButton(node);
161                        }else if(icon && icon !== "none"){
162                                // Image
163                                if(!node || node.nodeName !== "IMG"){
164                                        node = domConstruct.create("img", {
165                                                alt: title
166                                        }, refNode || parent, pos);
167                                }
168                                node.src = (icon || "").replace("${theme}", dm.currentTheme);
169                                this.setupSpriteIcon(node, iconPos);
170                                if(iconPos && parent){
171                                        var arr = iconPos.split(/[ ,]/);
172                                        domStyle.set(parent, {
173                                                position: "relative",
174                                                width: arr[2] + "px",
175                                                height: arr[3] + "px"
176                                        });
177                                        domClass.add(parent, "mblSpriteIconParent");
178                                }
179                                connect.connect(node, "ondragstart", event, "stop");
180                        }
181                        return node;
182                };
183
184                this.iconWrapper = false;
185                this.setIcon = function(/*String*/icon, /*String*/iconPos, /*DomNode*/iconNode, /*String?*/alt, /*DomNode*/parent, /*DomNode?*/refNode, /*String?*/pos){
186                        // summary:
187                        //              A setter function to set an icon.
188                        // description:
189                        //              This function is intended to be used by icon setters (e.g. _setIconAttr)
190                        // icon:
191                        //              An icon path or a DOM button class name.
192                        // iconPos:
193                        //              The position of an aggregated icon. IconPos is comma separated
194                        //              values like top,left,width,height (ex. "0,0,29,29").
195                        // iconNode:
196                        //              An icon node.
197                        // alt:
198                        //              An alt text for the icon image.
199                        // parent:
200                        //              Parent node of the icon.
201                        // refNode:
202                        //              A node reference to place the icon.
203                        // pos:
204                        //              The position of the icon relative to refNode.
205                        if(!parent || !icon && !iconNode){ return null; }
206                        if(icon && icon !== "none"){ // create or update an icon
207                                if(!this.iconWrapper && icon.indexOf("mblDomButton") !== 0 && !iconPos){ // image
208                                        if(iconNode && iconNode.tagName === "DIV"){
209                                                domConstruct.destroy(iconNode);
210                                                iconNode = null;
211                                        }
212                                        iconNode = this.createIcon(icon, null, iconNode, alt, parent, refNode, pos);
213                                        domClass.add(iconNode, "mblImageIcon");
214                                }else{ // sprite or DOM button
215                                        if(iconNode && iconNode.tagName === "IMG"){
216                                                domConstruct.destroy(iconNode);
217                                                iconNode = null;
218                                        }
219                                        iconNode && domConstruct.empty(iconNode);
220                                        if(!iconNode){
221                                                iconNode = domConstruct.create("div", null, refNode || parent, pos);
222                                        }
223                                        this.createIcon(icon, iconPos, null, null, iconNode);
224                                        if(alt){
225                                                iconNode.title = alt;
226                                        }
227                                }
228                                domClass.remove(parent, "mblNoIcon");
229                                return iconNode;
230                        }else{ // clear the icon
231                                domConstruct.destroy(iconNode);
232                                domClass.add(parent, "mblNoIcon");
233                                return null;
234                        }
235                };
236        };
237
238        // Return singleton.  (TODO: can we replace IconUtils class and singleton w/a simple hash of functions?)
239        return new IconUtils();
240});
Note: See TracBrowser for help on using the repository browser.