1 /** 2 * @fileOverview resizable support for kissy 3 * @author yiminghe@gmail.com 4 */ 5 KISSY.add("resizable", function (S, Node, Base, D, undefined) { 6 7 var $ = Node.all, 8 i, 9 j, 10 Draggable = D.Draggable, 11 CLS_PREFIX = "ks-resizable-handler", 12 horizontal = ["l", "r"], 13 vertical = ["t", "b"], 14 hcNormal = { 15 t:function (minW, maxW, minH, maxH, ot, ol, ow, oh, diffT) { 16 var h = getBoundValue(minH, maxH, oh - diffT), 17 t = ot + oh - h; 18 return [0, h, t, 0] 19 }, 20 b:function (minW, maxW, minH, maxH, ot, ol, ow, oh, diffT) { 21 var h = getBoundValue(minH, maxH, oh + diffT); 22 return [0, h, 0, 0]; 23 }, 24 r:function (minW, maxW, minH, maxH, ot, ol, ow, oh, diffT, diffL) { 25 var w = getBoundValue(minW, maxW, ow + diffL); 26 return [w, 0, 0, 0]; 27 }, 28 l:function (minW, maxW, minH, maxH, ot, ol, ow, oh, diffT, diffL) { 29 var w = getBoundValue(minW, maxW, ow - diffL), 30 l = ol + ow - w; 31 return [w, 0, 0, l] 32 } 33 }; 34 35 36 for (i = 0; i < horizontal.length; i++) { 37 for (j = 0; j < vertical.length; j++) { 38 (function (h, v) { 39 hcNormal[ h + v] = hcNormal[ v + h] = function () { 40 return merge(hcNormal[h].apply(this, arguments), 41 hcNormal[v].apply(this, arguments)); 42 }; 43 })(horizontal[i], vertical[j]); 44 } 45 } 46 function merge(a1, a2) { 47 var a = []; 48 for (i = 0; i < a1.length; i++) { 49 a[i] = a1[i] || a2[i]; 50 } 51 return a; 52 } 53 54 function getBoundValue(min, max, v) { 55 return Math.min(Math.max(min, v), max); 56 } 57 58 function _uiSetHandlers(e) { 59 var self = this, 60 v = e.newVal, 61 dds = self.dds, 62 node = self.get("node"); 63 self.destroy(); 64 for (i = 0; i < v.length; i++) { 65 var hc = v[i], 66 el = $("<div class='" + 67 CLS_PREFIX + 68 " " + CLS_PREFIX + 69 "-" + hc + 70 "'></div>") 71 .prependTo(node, undefined), 72 dd = dds[hc] = new Draggable({ 73 node:el, 74 cursor:null 75 }); 76 dd.on("drag", _drag, self); 77 dd.on("dragstart", _dragStart, self); 78 } 79 } 80 81 function _dragStart() { 82 var self = this, 83 node = self.get("node"); 84 self._width = node.width(); 85 self._top = parseInt(node.css("top")); 86 self._left = parseInt(node.css("left")); 87 self._height = node.height(); 88 } 89 90 function _drag(ev) { 91 var self = this, 92 node = self.get("node"), 93 dd = ev.target, 94 hc = _getHandlerC(self, dd), 95 ow = self._width, 96 oh = self._height, 97 minW = self.get("minWidth"), 98 maxW = self.get("maxWidth"), 99 minH = self.get("minHeight"), 100 maxH = self.get("maxHeight"), 101 diffT = ev.top - dd.startNodePos.top, 102 diffL = ev.left - dd.startNodePos.left, 103 ot = self._top, 104 ol = self._left, 105 pos = hcNormal[hc](minW, maxW, minH, maxH, ot, ol, ow, oh, diffT, diffL), 106 attr = ["width", "height", "top", "left"]; 107 for (i = 0; i < attr.length; i++) { 108 if (pos[i]) { 109 node.css(attr[i], pos[i]); 110 } 111 } 112 } 113 114 function _getHandlerC(self, dd) { 115 var dds = self.dds; 116 for (var d in dds) { 117 if (dds[d] == dd) { 118 return d; 119 } 120 } 121 return 0; 122 } 123 124 /** 125 * @class 126 * Make a element resizable. 127 * @extends Base 128 * @name Resizable 129 */ 130 function Resizable(cfg) { 131 var self = this, 132 node; 133 Resizable.superclass.constructor.apply(self, arguments); 134 self.on("afterHandlersChange", _uiSetHandlers, self); 135 node = self.get("node"); 136 self.dds = {}; 137 if (node.css("position") == "static") { 138 node.css("position", "relative"); 139 } 140 _uiSetHandlers.call(self, { 141 newVal:self.get("handlers") 142 }); 143 } 144 145 S.extend(Resizable, Base, 146 /** 147 * @lends Resizable# 148 */ 149 { 150 /** 151 * make current resizable 's node not resizable. 152 */ 153 destroy:function () { 154 var self = this, 155 dds = self.dds; 156 for (var d in dds) { 157 if (dds.hasOwnProperty(d)) { 158 dds[d].destroy(); 159 dds[d].get("node").remove(); 160 delete dds[d]; 161 } 162 } 163 } 164 }, { 165 ATTRS:/** 166 * @lends Resizable# 167 */ 168 { 169 /** 170 * KISSY Node to be resizable. 171 * @type Node 172 */ 173 node:{ 174 setter:function (v) { 175 return $(v); 176 } 177 }, 178 /** 179 * Minimum width can current node resize to. 180 * @type Number 181 */ 182 minWidth:{ 183 value:0 184 }, 185 /** 186 * Minimum height can current node resize to. 187 * @type Number 188 */ 189 minHeight:{ 190 value:0 191 }, 192 /** 193 * Maximum width can current node resize to. 194 * @type Number 195 */ 196 maxWidth:{ 197 value:Number.MAX_VALUE 198 }, 199 /** 200 * Maximum height can current node resize to. 201 * @type Number 202 */ 203 maxHeight:{ 204 value:Number.MAX_VALUE 205 }, 206 /** 207 * Enumeration of directions can current node resize to. 208 * Directions: 209 * "t": top. 210 * "tr": top-right. 211 * "r": right. 212 * "b": bottom. 213 * "l": left. 214 * "tl": top-left. 215 * "bl": bottom-left. 216 * "br": bottom-right. 217 * @type String[] 218 */ 219 handlers:{ 220 // t,tr,r,br,b,bl,l,tl 221 value:[] 222 } 223 } 224 }); 225 226 return Resizable; 227 228 }, { requires:["node", "base", "dd"] }); 229