1(function($, window, document, undefined) { 2 'use strict'; 3 4 var Diamonds = function(customOptions) { 5 this.options = { 6 itemSelector : ".item", 7 size : 250, 8 gap : 0.5, 9 autoRedraw : true, 10 hideIncompleteRow : false, 11 scrollbarWidth : 0, 12 minDiamondsPerRow : 2, 13 eventPrefix : "diamonds:", 14 itemWrap : $('<div class="diamond-box-wrap"><div class="diamond-box"><div class="diamond-box-inner"></div></div></div>'), 15 rowWrap : $('<div class="diamond-row-wrap"></div>'), 16 rowUpperWrap : $('<div class="diamond-row-upper"></div>'), 17 rowLowerWrap : $('<div class="diamond-row-lower"></div>'), 18 diamondWrap : $('<div class="diamonds"></div>'), 19 overrideCss : '.diamonds-{{guid}} .diamond-box { border-width: {{gap}}px }', 20 debugEnabled : false, 21 debugEvent : function(event, data) { if(console && console.log) { console.log("Event: " + event, data) }}, 22 debugMethod : function(method, args) { if(console && console.log) { console.log("Method: " + method, args) }} 23 }; 24 this.wrapElement = customOptions.wrapElement; 25 26 if(this._triggerEvent("beforeInit")) return; 27 28 this.setOptions(customOptions, false); 29 30 this.itemElements = $(this.options.itemSelector, this.wrapElement); 31 32 this.guid = this._createGuid(); 33 34 // Create override css 35 this.styleElement = this._createOverrideCss(); 36 37 // Initial draw 38 this.draw(); 39 40 // Auto redraw 41 this.startAutoRedraw(); 42 43 this._triggerEvent("afterInit"); 44 }; 45 46 /** 47 * Returns true if we should stop 48 */ 49 Diamonds.prototype._triggerEvent = function(event, data) { 50 if(this.options.debugEnabled) this.options.debugEvent(event, data); 51 var e = $.Event(this.options.eventPrefix + event); 52 this.wrapElement.trigger(e, data); 53 return e.isDefaultPrevented(); 54 }; 55 56 Diamonds.prototype._createGuid = function() { 57 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = Math.random()*16|0,v=c=='x'?r:r&0x3|0x8;return v.toString(16);}); 58 }; 59 60 Diamonds.prototype.destroy = function() { 61 if(this._triggerEvent("beforeDestroy")) return; 62 63 this._removeOverrideCss(); 64 this.stopAutoRedraw(); 65 this._emptyElement(this.wrapElement); 66 this.wrapElement.append(this.itemElements); 67 this.wrapElement.removeData("diamonds"); 68 69 this._triggerEvent("afterDestroy"); 70 }; 71 72 Diamonds.prototype._createOverrideCss = function() { 73 var css = this.options.overrideCss; 74 var data = { 75 "size" : this.options.size, 76 "gap" : this.options.gap, 77 "guid" : this.guid 78 } 79 for(var key in data) { 80 if(data.hasOwnProperty(key)) { 81 css = css.replace(new RegExp("{{" + key + "}}", 'g'), data[key]); 82 } 83 } 84 85 var style = $('<style type="text/css"></style>'); 86 style.html(css); 87 88 $("head").append(style); 89 return style; 90 }; 91 92 Diamonds.prototype._removeOverrideCss = function() { 93 if(this.styleElement) this.styleElement.remove(); 94 }; 95 96 Diamonds.prototype._updateOverrideCss = function() { 97 this._removeOverrideCss(); 98 this._createOverrideCss(); 99 }; 100 101 Diamonds.prototype.stopAutoRedraw = function() { 102 if(this._triggerEvent("beforeStopAutoRedraw")) return; 103 window.clearInterval(this.redrawer); 104 this._triggerEvent("afterStopAutoRedraw"); 105 }; 106 107 Diamonds.prototype.startAutoRedraw = function() { 108 window.clearInterval(this.redrawer); // Stop previous 109 var lastWidth = this.wrapElement.width(); 110 if(this.options.autoRedraw) { 111 if(this._triggerEvent("beforeStartAutoRedraw")) return; 112 113 this.redrawer = window.setInterval(function() { 114 var curWidth = this.wrapElement.width(); 115 if(curWidth !== lastWidth) { 116 if(this._triggerEvent("onAutoResize", {before: lastWidth, current: curWidth})) return; 117 lastWidth = curWidth; 118 this.draw(); 119 } 120 }.bind(this), 50); 121 122 this._triggerEvent("afterStartAutoRedraw"); 123 } 124 }; 125 126 Diamonds.prototype.setOptions = function(customOptions, redraw) { 127 redraw = redraw === undefined ? true : redraw; 128 if(customOptions !== null && typeof customOptions === "object") { 129 130 if(this._triggerEvent("beforeSetOptions", customOptions)) return; 131 132 // Stop or start redraw 133 if(this.options.autoRedraw && !customOptions.autoRedraw) { 134 this.stopAutoRedraw(); 135 } 136 else if(!this.options.autoRedraw && customOptions.autoRedraw) { 137 this.startAutoRedraw(); 138 } 139 140 $.extend(true, this.options, customOptions); 141 142 if(redraw) { 143 this._updateOverrideCss(); 144 this.draw(); 145 } 146 147 this._triggerEvent("afterSetOptions", customOptions); 148 } 149 }; 150 151 Diamonds.prototype._getScrollbarWidth = function() { 152 if($.isNumeric(this.options.scrollbarWidth) && this.options.scrollbarWidth >= 0) { 153 return this.options.scrollbarWidth; 154 } 155
156 var $inner = $('<div style="width: 100%; height:200px;">test</div>'), 157 $outer = $('<div style="width:200px;height:150px; position: absolute; top: 0; left: 0; visibility: hidden; overflow:hidden;"></div>').append($inner), 158 inner = $inner[0], 159 outer = $outer[0]; 160 161 $('body').append(outer); 162 var width1 = inner.offsetWidth; 163 $outer.css('overflow', 'scroll'); 164 var width2 = outer.clientWidth; 165 $outer.remove(); 166 167 return this.scrollbarWidth = (width1 - width2); 168 }; 169 170 Diamonds.prototype._emptyElement = function(element) { 171 $("> *", element).detach(); 172 }; 173 174 Diamonds.prototype._groupIntoRows = function(items, maxDiamondsPerRow, hideIncompleteRow) { 175 // Max number of diamonds per row 176 maxDiamondsPerRow = Math.max(this.options.minDiamondsPerRow, 0 + maxDiamondsPerRow); 177 178 // Draw rows 179 var rows = new Array(); 180 for(var i = 0; i < items.length; i++) { 181 var item = items[i]; 182 // Append or create new row? 183 var max = rows.length % 2 === 0 ? maxDiamondsPerRow - 1 : maxDiamondsPerRow; 184 if(!rows.hasOwnProperty(rows.length - 1) || rows[rows.length - 1].length == max) { 185 rows.push(new Array()); 186 } 187 rows[rows.length - 1].push(item); 188 } 189 190 // Hide incomplete rows 191 if(hideIncompleteRow) { 192 if(rows.hasOwnProperty(rows.length - 1) && rows[rows.length - 1].length < rows.length % 2 === 0 ? maxDiamondsPerRow - 1 : maxDiamondsPerRow) { 193 rows.pop(); 194 } 195 } 196 197 return rows; 198 }; 199 200 Diamonds.prototype._renderHtml = function(rows) { 201 var wrap = this.options.diamondWrap.clone(); 202 wrap.addClass("diamonds-" + this.guid); 203 for(var i = 0; i < rows.length; i += 2) { 204 var row = this.options.rowWrap.clone(); 205 var upper = this.options.rowUpperWrap.clone(); 206 var lower = this.options.rowLowerWrap.clone(); 207 row.append(upper).append(lower); 208 wrap.append(row); 209 210 for(var j = 0; j < rows[i].length; j++) { 211 upper.append(rows[i][j]); 212 $(rows[i][j]).wrap(this.options.itemWrap); 213 } 214 if(!rows.hasOwnProperty(i + 1)) break; 215 for(var j = 0; j < rows[i + 1].length; j++) { 216 lower.append(rows[i + 1][j]); 217 $(rows[i + 1][j]).wrap(this.options.itemWrap); 218 } 219 } 220 221 //wrap.css("min-width", this.options.minDiamondsPerRow * this.options.size); 222 223 return wrap; 224 }; 225 226 Diamonds.prototype.draw = function() { 227 if(this._triggerEvent("beforeDraw")) return; 228 229 this._emptyElement(this.wrapElement); 230 231 var width = this.options.wrapElement.width() - this._getScrollbarWidth(); 232 233 var rows = this._groupIntoRows(this.itemElements, 234 Math.floor(width / this.options.size), 235 this.options.hideIncompleteRow); 236 237 var html = this._renderHtml(rows); 238 239 this.wrapElement.append(html); 240 241 this._triggerEvent("afterDraw"); 242 }; 243 244 245 // jQuery stuff 246 $.fn.diamonds = function(method) { 247 248 // Initialize 249 if(method === undefined || $.isPlainObject(method)) { 250 method = method || {}; 251 method.wrapElement = this; 252 this.data("diamonds", new Diamonds(method)); 253 return this; 254 } 255 256 // Call method 257 var inst = this.data("diamonds"); 258 if(inst == null) throw new Error("Diamonds not initialized on this element."); 259 260 if(Diamonds.prototype.hasOwnProperty(method)) { 261 var args = Array.prototype.slice.call(arguments); 262 args.shift(); 263 if(inst.options.debugEnabled) inst.options.debugMethod(method, args); 264 var ret = Diamonds.prototype[method].apply(inst, args); 265 return ret === undefined ? this : ret; 266 } 267 }; 268})(window.hasOwnProperty("Zepto") ? window.Zepto : window.jQuery, window, document);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.