flexlayout-rails 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,169 @@
1
+ /*!
2
+ jQuery Wookmark plugin 0.5
3
+ @name jquery.wookmark.js
4
+ @author Christoph Ono (chri@sto.ph or @gbks)
5
+ @version 0.5
6
+ @date 3/19/2012
7
+ @category jQuery plugin
8
+ @copyright (c) 2009-2012 Christoph Ono (www.wookmark.com)
9
+ @license Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
10
+ */
11
+ $.fn.wookmark = function(options) {
12
+
13
+ if(!this.wookmarkOptions) {
14
+ this.wookmarkOptions = $.extend( {
15
+ container: $('body'),
16
+ offset: 2,
17
+ autoResize: false,
18
+ itemWidth: $(this[0]).outerWidth(),
19
+ resizeDelay: 50
20
+ }, options);
21
+ } else if(options) {
22
+ this.wookmarkOptions = $.extend(this.wookmarkOptions, options);
23
+ }
24
+
25
+ // Layout variables.
26
+ if(!this.wookmarkColumns) {
27
+ this.wookmarkColumns = null;
28
+ this.wookmarkContainerWidth = null;
29
+ }
30
+
31
+ // Main layout function.
32
+ this.wookmarkLayout = function() {
33
+ // Calculate basic layout parameters.
34
+ var columnWidth = this.wookmarkOptions.itemWidth + this.wookmarkOptions.offset;
35
+ var containerWidth = this.wookmarkOptions.container.width();
36
+ var columns = Math.floor((containerWidth+this.wookmarkOptions.offset)/columnWidth);
37
+ var offset = Math.round((containerWidth - (columns*columnWidth-this.wookmarkOptions.offset))/2);
38
+
39
+ // If container and column count hasn't changed, we can only update the columns.
40
+ var bottom = 0;
41
+ if(this.wookmarkColumns != null && this.wookmarkColumns.length == columns) {
42
+ bottom = this.wookmarkLayoutColumns(columnWidth, offset);
43
+ } else {
44
+ bottom = this.wookmarkLayoutFull(columnWidth, columns, offset);
45
+ }
46
+
47
+ // Set container height to height of the grid.
48
+ this.wookmarkOptions.container.css('height', bottom+'px');
49
+ };
50
+
51
+ /**
52
+ * Perform a full layout update.
53
+ */
54
+ this.wookmarkLayoutFull = function(columnWidth, columns, offset) {
55
+ // Prepare Array to store height of columns.
56
+ var heights = [];
57
+ while(heights.length < columns) {
58
+ heights.push(0);
59
+ }
60
+
61
+ // Store column data.
62
+ this.wookmarkColumns = [];
63
+ while(this.wookmarkColumns.length < columns) {
64
+ this.wookmarkColumns.push([]);
65
+ }
66
+
67
+ // Loop over items.
68
+ var item, top, left, i=0, k=0, length=this.length, shortest=null, shortestIndex=null, bottom = 0;
69
+ for(; i<length; i++ ) {
70
+ item = $(this[i]);
71
+
72
+ // Find the shortest column.
73
+ shortest = null;
74
+ shortestIndex = 0;
75
+ for(k=0; k<columns; k++) {
76
+ if(shortest == null || heights[k] < shortest) {
77
+ shortest = heights[k];
78
+ shortestIndex = k;
79
+ }
80
+ }
81
+
82
+ // Postion the item.
83
+ item.css({
84
+ position: 'absolute',
85
+ top: shortest+'px',
86
+ left: (shortestIndex*columnWidth + offset)+'px'
87
+ });
88
+
89
+ // Update column height.
90
+ heights[shortestIndex] = shortest + item.outerHeight() + this.wookmarkOptions.offset;
91
+ bottom = Math.max(bottom, heights[shortestIndex]);
92
+
93
+ this.wookmarkColumns[shortestIndex].push(item);
94
+ }
95
+
96
+ return bottom;
97
+ };
98
+
99
+ /**
100
+ * This layout function only updates the vertical position of the
101
+ * existing column assignments.
102
+ */
103
+ this.wookmarkLayoutColumns = function(columnWidth, offset) {
104
+ var heights = [];
105
+ while(heights.length < this.wookmarkColumns.length) {
106
+ heights.push(0);
107
+ }
108
+
109
+ var i=0, length = this.wookmarkColumns.length, column;
110
+ var k=0, kLength, item;
111
+ var bottom = 0;
112
+ for(; i<length; i++) {
113
+ column = this.wookmarkColumns[i];
114
+ kLength = column.length;
115
+ for(k=0; k<kLength; k++) {
116
+ item = column[k];
117
+ item.css({
118
+ left: (i*columnWidth + offset)+'px',
119
+ top: heights[i]+'px'
120
+ });
121
+ heights[i] += item.outerHeight() + this.wookmarkOptions.offset;
122
+
123
+ bottom = Math.max(bottom, heights[i]);
124
+ }
125
+ }
126
+
127
+ return bottom;
128
+ };
129
+
130
+ // Listen to resize event if requested.
131
+ this.wookmarkResizeTimer = null;
132
+ if(!this.wookmarkResizeMethod) {
133
+ this.wookmarkResizeMethod = null;
134
+ }
135
+ if(this.wookmarkOptions.autoResize) {
136
+ // This timer ensures that layout is not continuously called as window is being dragged.
137
+ this.wookmarkOnResize = function(event) {
138
+ if(this.wookmarkResizeTimer) {
139
+ clearTimeout(this.wookmarkResizeTimer);
140
+ }
141
+ this.wookmarkResizeTimer = setTimeout($.proxy(this.wookmarkLayout, this), this.wookmarkOptions.resizeDelay)
142
+ };
143
+
144
+ // Bind event listener.
145
+ if(!this.wookmarkResizeMethod) {
146
+ this.wookmarkResizeMethod = $.proxy(this.wookmarkOnResize, this);
147
+ }
148
+ $(window).resize(this.wookmarkResizeMethod);
149
+ };
150
+
151
+ /**
152
+ * Clear event listeners and time outs.
153
+ */
154
+ this.wookmarkClear = function() {
155
+ if(this.wookmarkResizeTimer) {
156
+ clearTimeout(this.wookmarkResizeTimer);
157
+ this.wookmarkResizeTimer = null;
158
+ }
159
+ if(this.wookmarkResizeMethod) {
160
+ $(window).unbind('resize', this.wookmarkResizeMethod);
161
+ }
162
+ };
163
+
164
+ // Apply layout
165
+ this.wookmarkLayout();
166
+
167
+ // Display items (if hidden).
168
+ this.show();
169
+ };
@@ -0,0 +1,11 @@
1
+ /*!
2
+ jQuery Wookmark plugin 0.5
3
+ @name jquery.wookmark.js
4
+ @author Christoph Ono (chri@sto.ph or @gbks)
5
+ @version 0.5
6
+ @date 3/19/2012
7
+ @category jQuery plugin
8
+ @copyright (c) 2009-2012 Christoph Ono (www.wookmark.com)
9
+ @license Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
10
+ */
11
+ $.fn.wookmark=function(a){if(!this.wookmarkOptions){this.wookmarkOptions=$.extend({container:$("body"),offset:2,autoResize:false,itemWidth:$(this[0]).outerWidth(),resizeDelay:50},a)}else if(a){this.wookmarkOptions=$.extend(this.wookmarkOptions,a)}if(!this.wookmarkColumns){this.wookmarkColumns=null;this.wookmarkContainerWidth=null}this.wookmarkLayout=function(){var a=this.wookmarkOptions.itemWidth+this.wookmarkOptions.offset;var b=this.wookmarkOptions.container.width();var c=Math.floor((b+this.wookmarkOptions.offset)/a);var d=Math.round((b-(c*a-this.wookmarkOptions.offset))/2);var e=0;if(this.wookmarkColumns!=null&&this.wookmarkColumns.length==c){e=this.wookmarkLayoutColumns(a,d)}else{e=this.wookmarkLayoutFull(a,c,d)}this.wookmarkOptions.container.css("height",e+"px")};this.wookmarkLayoutFull=function(a,b,c){var d=[];while(d.length<b){d.push(0)}this.wookmarkColumns=[];while(this.wookmarkColumns.length<b){this.wookmarkColumns.push([])}var e,f,g,h=0,i=0,j=this.length,k=null,l=null,m=0;for(;h<j;h++){e=$(this[h]);k=null;l=0;for(i=0;i<b;i++){if(k==null||d[i]<k){k=d[i];l=i}}e.css({position:"absolute",top:k+"px",left:l*a+c+"px"});d[l]=k+e.outerHeight()+this.wookmarkOptions.offset;m=Math.max(m,d[l]);this.wookmarkColumns[l].push(e)}return m};this.wookmarkLayoutColumns=function(a,b){var c=[];while(c.length<this.wookmarkColumns.length){c.push(0)}var d=0,e=this.wookmarkColumns.length,f;var g=0,h,i;var j=0;for(;d<e;d++){f=this.wookmarkColumns[d];h=f.length;for(g=0;g<h;g++){i=f[g];i.css({left:d*a+b+"px",top:c[d]+"px"});c[d]+=i.outerHeight()+this.wookmarkOptions.offset;j=Math.max(j,c[d])}}return j};this.wookmarkResizeTimer=null;if(!this.wookmarkResizeMethod){this.wookmarkResizeMethod=null}if(this.wookmarkOptions.autoResize){this.wookmarkOnResize=function(a){if(this.wookmarkResizeTimer){clearTimeout(this.wookmarkResizeTimer)}this.wookmarkResizeTimer=setTimeout($.proxy(this.wookmarkLayout,this),this.wookmarkOptions.resizeDelay)};if(!this.wookmarkResizeMethod){this.wookmarkResizeMethod=$.proxy(this.wookmarkOnResize,this)}$(window).resize(this.wookmarkResizeMethod)}this.wookmarkClear=function(){if(this.wookmarkResizeTimer){clearTimeout(this.wookmarkResizeTimer);this.wookmarkResizeTimer=null}if(this.wookmarkResizeMethod){$(window).unbind("resize",this.wookmarkResizeMethod)}};this.wookmarkLayout();this.show()}
@@ -0,0 +1,403 @@
1
+ /*
2
+ Name: MultiColumn
3
+ Version: 0.0.2 (April 23 2010)
4
+ Author: Finn Rudolph
5
+ Company: http://stadtwerk.org/
6
+
7
+ License: This script is licensed under a Creative Commons
8
+ Attribution-Noncommercial 3.0 Unported License
9
+ (http://creativecommons.org/licenses/by-nc/3.0/).
10
+
11
+ You are free:
12
+ + to Share - to copy, distribute and transmit the work
13
+ + to Remix - to adapt the work
14
+
15
+ Under the following conditions:
16
+ + Attribution. You must attribute the work in the manner specified by the author or licensor
17
+ (but not in any way that suggests that they endorse you or your use of the work).
18
+ + Noncommercial. You may not use this work for commercial purposes.
19
+
20
+ + For any reuse or distribution, you must make clear to others the license terms of this work.
21
+ + Any of the above conditions can be waived if you get permission from the copyright holder.
22
+ + Nothing in this license impairs or restricts the author's moral rights.
23
+
24
+ Credits: This script uses the domReadyEvent from Tanny O'Haley [1].
25
+
26
+ [1] http://tanny.ica.com/ICA/TKO/tkoblog.nsf/dx/domcontentloaded-for-browsers-part-v
27
+ */
28
+
29
+ /* MultiColumn constructor */
30
+ function MultiColumn()
31
+ {
32
+ /* Setting option defaults */
33
+ this.defaults =
34
+ {
35
+ className: 'multi-column', /* CSS class name for the element that contains multiple columns */
36
+ columnName: 'column', /* CSS class name for the column element */
37
+ columnCount: 3, /* column-count */
38
+ columnGap: 30 /* column-gap */
39
+ };
40
+
41
+ /* Closure for this */
42
+ var my = this;
43
+
44
+ /* Initiate MultiColumn */
45
+ this.init = function (options)
46
+ {
47
+ /* Evaluate options */
48
+ for(var name in my.defaults)
49
+ {
50
+ this[name] = (options !== undefined && options[name] !== undefined) ? options[name] : my.defaults[name];
51
+ }
52
+
53
+ my.refresh();
54
+ my.Resize.init();
55
+ };
56
+
57
+ /* Refresh multiple columns */
58
+ this.refresh = function()
59
+ {
60
+ /* Get all elements that contain multiple columns */
61
+ var multiColumnElements = my.Tool.getElementsByClass(my.className, '*', document);
62
+ var max = multiColumnElements.length;
63
+ for(var i=0;i<max;i++)
64
+ {
65
+ /* Build multiple columns for each element */
66
+ my.build(multiColumnElements[i]);
67
+ }
68
+ };
69
+
70
+ /* Build multiple columns */
71
+ this.build = function(element)
72
+ {
73
+ /* Calculate column width in px */
74
+ var totalGapWidth = my.columnGap * (my.columnCount -1);
75
+ var totalWidth = parseInt(element.offsetWidth,10);
76
+ var columnWidth = Math.round((totalWidth - totalGapWidth) / my.columnCount);
77
+ var subPixel = (totalWidth-totalGapWidth)-(columnWidth*3);
78
+
79
+ /* Get or create columns element */
80
+ var columnsDiv = my.Tool.getElementsByClass('result', 'div', element);
81
+
82
+ if(columnsDiv != '')
83
+ {
84
+ element.removeChild(columnsDiv[0]);
85
+ }
86
+
87
+ columnsDiv = document.createElement('div');
88
+ my.Tool.setClassName(columnsDiv, 'result');
89
+ columnsDiv.style.width = totalWidth+'px';
90
+
91
+ var columns = my.getColumnElements(element);
92
+ var max = columns.length;
93
+ var gap = my.columnGap / 2;
94
+ var columnDiv;
95
+ for(var i=0;i<max;i++)
96
+ {
97
+ column = columns[i];
98
+
99
+ /* Create element */
100
+ columnDiv = document.createElement('div');
101
+ my.Tool.setClassName(columnDiv, my.columnName);
102
+ columnsDiv.appendChild(columnDiv);
103
+
104
+ /* Set width and padding */
105
+ columnDiv.style.width = columnWidth + 'px';
106
+ if(i === 0)
107
+ {
108
+ columnDiv.style.paddingRight = (gap + subPixel) + 'px';
109
+ }
110
+ else if(i+1 === max)
111
+ {
112
+ columnDiv.style.paddingLeft = gap + 'px';
113
+ }
114
+ else
115
+ {
116
+ columnDiv.style.padding = '0 '+gap+'px 0 '+gap+'px';
117
+ }
118
+
119
+ for(node in column)
120
+ {
121
+ columnDiv.appendChild(column[node].cloneNode(true));
122
+ }
123
+ }
124
+ element.appendChild(columnsDiv);
125
+ };
126
+
127
+
128
+ /* Get column elements */
129
+ this.getColumnElements = function(element)
130
+ {
131
+ /* Calculate max column height */
132
+ var totalHeight = parseInt(element.offsetHeight,10);
133
+ var maxColumnHeigth = totalHeight / my.columnCount;
134
+
135
+ /* Walk through all child nodes and get their height */
136
+ var children = element.childNodes;
137
+ var column = [], columnChilds = [], child, columnHeight = 0;
138
+ var max = children.length;
139
+ for(var i=0;i<max;i++)
140
+ {
141
+ child = children[i];
142
+
143
+ /* Only process element nodes */
144
+ if(child && child.nodeType === 1)
145
+ {
146
+ /* Calculate rendered height of the child element */
147
+ child.renderedHeight = child.offsetHeight;
148
+
149
+ /* Store column childs in an array */
150
+ columnChilds.push(child);
151
+ columnHeight += child.renderedHeight;
152
+
153
+ /* The end of a column has been reached if the elements hit the max column height */
154
+ if(columnHeight >= maxColumnHeigth)
155
+ {
156
+ column.push(columnChilds);
157
+
158
+ /* Reset column height and childs */
159
+ columnHeight = 0;
160
+ columnChilds = [];
161
+ }
162
+ }
163
+ }
164
+ column.push(columnChilds);
165
+
166
+ /* Return column array that holds the column elements */
167
+ return column;
168
+ };
169
+
170
+ /* Resize functions */
171
+ this.Resize =
172
+ {
173
+ init: function()
174
+ {
175
+ my.refresh();
176
+ var otherFunctions = window.onresize;
177
+ if(typeof window.onresize != 'function')
178
+ {
179
+ window.onresize = function()
180
+ {
181
+ my.refresh();
182
+ };
183
+ }
184
+ else
185
+ {
186
+ window.onresize = function()
187
+ {
188
+ if (otherFunctions)
189
+ {
190
+ otherFunctions();
191
+ }
192
+ my.refresh();
193
+ };
194
+ }
195
+ }
196
+ };
197
+
198
+
199
+ /* Helper functions */
200
+ this.Tool =
201
+ {
202
+ setClassName: function(element, className)
203
+ {
204
+ if(element)
205
+ {
206
+ element.setAttribute('class', className);
207
+ element.setAttribute('className', className);
208
+ }
209
+ },
210
+
211
+
212
+ getElementsByClass: function(searchClass, tag, node)
213
+ {
214
+ var classElements = [];
215
+ var elements = node.getElementsByTagName(tag);
216
+ var max = elements.length;
217
+ var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
218
+ for(var i = 0, j = 0; i < max; i++)
219
+ {
220
+ if(pattern.test(elements[i].className))
221
+ {
222
+ classElements[j] = elements[i];
223
+ j++;
224
+ }
225
+ }
226
+ return classElements;
227
+ }
228
+ };
229
+ }
230
+
231
+ /* DOMContentLoaded event handler - by Tanny O'Haley [1] */
232
+ var domReadyEvent =
233
+ {
234
+ name: "domReadyEvent",
235
+ /* Array of DOMContentLoaded event handlers.*/
236
+ events: {},
237
+ domReadyID: 1,
238
+ bDone: false,
239
+ DOMContentLoadedCustom: null,
240
+
241
+ /* Function that adds DOMContentLoaded listeners to the array.*/
242
+ add: function(handler)
243
+ {
244
+ /* Assign each event handler a unique ID. If the handler has an ID, it has already been added to the events object or been run.*/
245
+ if (!handler.$$domReadyID)
246
+ {
247
+ handler.$$domReadyID = this.domReadyID++;
248
+
249
+ /* If the DOMContentLoaded event has happened, run the function. */
250
+ if(this.bDone)
251
+ {
252
+ handler();
253
+ }
254
+
255
+ /* store the event handler in the hash table */
256
+ this.events[handler.$$domReadyID] = handler;
257
+ }
258
+ },
259
+
260
+ remove: function(handler)
261
+ {
262
+ /* Delete the event handler from the hash table */
263
+ if (handler.$$domReadyID)
264
+ {
265
+ delete this.events[handler.$$domReadyID];
266
+ }
267
+ },
268
+
269
+ /* Function to process the DOMContentLoaded events array. */
270
+ run: function()
271
+ {
272
+ /* quit if this function has already been called */
273
+ if (this.bDone)
274
+ {
275
+ return;
276
+ }
277
+
278
+ /* Flag this function so we don't do the same thing twice */
279
+ this.bDone = true;
280
+
281
+ /* iterates through array of registered functions */
282
+ for (var i in this.events)
283
+ {
284
+ this.events[i]();
285
+ }
286
+ },
287
+
288
+ schedule: function()
289
+ {
290
+ /* Quit if the init function has already been called*/
291
+ if (this.bDone)
292
+ {
293
+ return;
294
+ }
295
+
296
+ /* First, check for Safari or KHTML.*/
297
+ if(/KHTML|WebKit/i.test(navigator.userAgent))
298
+ {
299
+ if(/loaded|complete/.test(document.readyState))
300
+ {
301
+ this.run();
302
+ }
303
+ else
304
+ {
305
+ /* Not ready yet, wait a little more.*/
306
+ setTimeout(this.name + ".schedule()", 100);
307
+ }
308
+ }
309
+ else if(document.getElementById("__ie_onload"))
310
+ {
311
+ /* Second, check for IE.*/
312
+ return true;
313
+ }
314
+
315
+ /* Check for custom developer provided function.*/
316
+ if(typeof this.DOMContentLoadedCustom === "function")
317
+ {
318
+ /* if DOM methods are supported, and the body element exists (using a double-check
319
+ including document.body, for the benefit of older moz builds [eg ns7.1] in which
320
+ getElementsByTagName('body')[0] is undefined, unless this script is in the body section) */
321
+ if(typeof document.getElementsByTagName !== 'undefined' && (document.getElementsByTagName('body')[0] !== null || document.body !== null))
322
+ {
323
+ /* Call custom function. */
324
+ if(this.DOMContentLoadedCustom())
325
+ {
326
+ this.run();
327
+ }
328
+ else
329
+ {
330
+ /* Not ready yet, wait a little more. */
331
+ setTimeout(this.name + ".schedule()", 250);
332
+ }
333
+ }
334
+ }
335
+ return true;
336
+ },
337
+
338
+ init: function()
339
+ {
340
+ /* If addEventListener supports the DOMContentLoaded event.*/
341
+ if(document.addEventListener)
342
+ {
343
+ document.addEventListener("DOMContentLoaded", function() { domReadyEvent.run(); }, false);
344
+ }
345
+
346
+ /* Schedule to run the init function.*/
347
+ setTimeout("domReadyEvent.schedule()", 100);
348
+
349
+ function run()
350
+ {
351
+ domReadyEvent.run();
352
+ }
353
+
354
+ /* Just in case window.onload happens first, add it to onload using an available method.*/
355
+ if(typeof addEvent !== "undefined")
356
+ {
357
+ addEvent(window, "load", run);
358
+ }
359
+ else if(document.addEventListener)
360
+ {
361
+ document.addEventListener("load", run, false);
362
+ }
363
+ else if(typeof window.onload === "function")
364
+ {
365
+ var oldonload = window.onload;
366
+ window.onload = function()
367
+ {
368
+ domReadyEvent.run();
369
+ oldonload();
370
+ };
371
+ }
372
+ else
373
+ {
374
+ window.onload = run;
375
+ }
376
+
377
+ /* for Internet Explorer */
378
+ /*@cc_on
379
+ @if (@_win32 || @_win64)
380
+ document.write("<script id=__ie_onload defer src=\"//:\"><\/script>");
381
+ var script = document.getElementById("__ie_onload");
382
+ script.onreadystatechange = function()
383
+ {
384
+ if (this.readyState == "complete")
385
+ {
386
+ domReadyEvent.run(); // call the onload handler
387
+ }
388
+ };
389
+ @end
390
+ @*/
391
+ }
392
+ };
393
+
394
+ var domReady = function(handler) { domReadyEvent.add(handler); };
395
+ domReadyEvent.init();
396
+
397
+
398
+ /* Create MultiColumn instance when the DOM structure has been loaded */
399
+ domReady(function()
400
+ {
401
+ var MultiColumnCSS = new MultiColumn();
402
+ MultiColumnCSS.init();
403
+ });