1 /**
  2  * @fileOverview UIBase.Box
  3  * @author yiminghe@gmail.com
  4  */
  5 KISSY.add('component/uibase/boxrender', function (S) {
  6 
  7     var $ = S.all, doc = S.Env.host.document;
  8 
  9     function BoxRender() {
 10     }
 11 
 12     BoxRender.ATTRS = {
 13         el:{
 14             //容器元素
 15             setter:function (v) {
 16                 return $(v);
 17             }
 18         },
 19 
 20         // 构建时批量生成,不需要执行单个
 21         elCls:{
 22             sync:false
 23         },
 24 
 25         elStyle:{
 26             sync:false
 27         },
 28 
 29         width:{
 30             sync:false
 31         },
 32 
 33         height:{
 34             sync:false
 35         },
 36 
 37         elTagName:{
 38             sync:false,
 39             // 生成标签名字
 40             value:"div"
 41         },
 42 
 43         elAttrs:{
 44             sync:false
 45         },
 46 
 47         content:{
 48             sync:false
 49         },
 50 
 51         elBefore:{},
 52 
 53         render:{},
 54 
 55         visible:{},
 56 
 57         visibleMode:{
 58             value:"display"
 59         },
 60         // content 设置的内容节点,默认根节点
 61         contentEl:{
 62             valueFn:function () {
 63                 return this.get("el");
 64             }
 65         }
 66     };
 67 
 68     BoxRender.HTML_PARSER = {
 69         content:function (el) {
 70             // 从 contentElCls 的标志中读取
 71             var contentElCls = this.get("contentElCls");
 72             return (contentElCls ? el.one("." + contentElCls) : el).html();
 73         }
 74     };
 75 
 76     function wrapWH(v) {
 77         return typeof v == "number" ? (v + "px") : v;
 78     }
 79 
 80     function constructEl(cls, style, width, height, tag, attrs, html) {
 81         style = style || {};
 82 
 83         if (width) {
 84             style.width = wrapWH(width);
 85         }
 86 
 87         if (height) {
 88             style.height = wrapWH(height);
 89         }
 90 
 91         var htmlStr = html || "", styleStr = '';
 92 
 93         if (typeof html != 'string') {
 94             htmlStr = '';
 95         }
 96 
 97         for (var s in style) {
 98             if (style.hasOwnProperty(s)) {
 99                 styleStr += s + ":" + style[s] + ";";
100             }
101         }
102 
103         var attrStr = '';
104 
105         for (var a in attrs) {
106             if (attrs.hasOwnProperty(a)) {
107                 attrStr += " " + a + "='" + attrs[a] + "'" + " ";
108             }
109         }
110 
111         var node = $("<" + tag + (styleStr ? (" style='" + styleStr + "' ") : "")
112             + attrStr + (cls ? (" class='" + cls + "' ") : "")
113             + ">" + htmlStr + "<" + "/" + tag + ">");
114 
115         if (html && !S.isString(html)) {
116             node.append(html);
117         }
118 
119         return node;
120     }
121 
122     BoxRender.prototype =
123     /**
124      * @lends Component.UIBase.Box.Render#
125      */
126     {
127 
128         __renderUI:function () {
129             var self = this;
130             // 新建的节点才需要摆放定位
131             if (!self.get("srcNode")) {
132                 var render = self.get("render"),
133                     el = self.get("el"),
134                     elBefore = self.get("elBefore");
135                 if (elBefore) {
136                     el.insertBefore(elBefore, undefined);
137                 } else if (render) {
138                     el.appendTo(render, undefined);
139                 } else {
140                     el.appendTo(doc.body, undefined);
141                 }
142             }
143         },
144 
145         /**
146          * 只负责建立节点,如果是 decorate 过来的,甚至内容会丢失
147          * 通过 render 来重建原有的内容
148          */
149         __createDom:function () {
150             var self = this;
151             if (!self.get("srcNode")) {
152                 var elCls = self.get("elCls"),
153                     elStyle = self.get("elStyle"),
154                     width = self.get("width"),
155                     height = self.get("height"),
156                     content = self.get("content"),
157                     elAttrs = self.get("elAttrs"),
158                     el,
159                     contentEl = self.get("contentEl");
160 
161                 // 内容容器,content 需要设置到的容器
162                 if (contentEl) {
163                     contentEl.html(content);
164                     content = "";
165                 }
166                 el = constructEl(elCls,
167                     elStyle,
168                     width,
169                     height,
170                     self.get("elTagName"),
171                     elAttrs,
172                     content);
173                 if (contentEl) {
174                     el.append(contentEl);
175                 }
176                 self.__set("el", el);
177                 if (!contentEl) {
178                     // 没取到,这里设下值, uiSet 时可以 set("content")  取到
179                     self.__set("contentEl", el);
180                 }
181             }
182         },
183 
184         __syncUI:function () {
185             var self = this;
186             // 通过 srcNode 过来的,最后调整,防止 plugin render 又改过!
187             if (self.get("srcNode")) {
188                 var el = self.get("el"),
189                     attrs = [
190                         "elCls",
191                         "elStyle",
192                         "width",
193                         "height",
194                         "elAttrs"
195                     ];
196                 S.each(attrs, function (attr) {
197                     var v;
198                     if (v = self.get(attr)) {
199                         self["_uiSet" + S.ucfirst(attr)](v);
200                     }
201                 });
202             }
203         },
204 
205         _uiSetElAttrs:function (attrs) {
206             this.get("el").attr(attrs);
207         },
208 
209         _uiSetElCls:function (cls) {
210             this.get("el").addClass(cls);
211         },
212 
213         _uiSetElStyle:function (style) {
214             this.get("el").css(style);
215         },
216 
217         _uiSetWidth:function (w) {
218             this.get("el").width(w);
219         },
220 
221         _uiSetHeight:function (h) {
222             var self = this;
223             self.get("el").height(h);
224         },
225 
226         _uiSetContent:function (c) {
227             var self = this,
228                 el = self.get("contentEl");
229             if (typeof c == "string") {
230                 el.html(c);
231             } else if (c) {
232                 el.empty().append(c);
233             }
234         },
235 
236         _uiSetVisible:function (isVisible) {
237             var el = this.get("el"),
238                 visibleMode = this.get("visibleMode");
239             if (visibleMode == "visibility") {
240                 el.css("visibility", isVisible ? "visible" : "hidden");
241             } else {
242                 el.css("display", isVisible ? "" : "none");
243             }
244         },
245 
246         __destructor:function () {
247             var el = this.get("el");
248             if (el) {
249                 el.remove();
250             }
251         }
252     };
253 
254     return BoxRender;
255 }, {
256     requires:['node']
257 });
258