corkboard 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.env.template +1 -0
- data/.gitignore +15 -0
- data/.rspec.template +2 -0
- data/.rvmrc.template +4 -0
- data/.wiprc +0 -0
- data/.yardopts +1 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +223 -0
- data/app/assets/images/corkboard/.gitkeep +0 -0
- data/corkboard.gemspec +41 -0
- data/lib/corkboard/version.rb +1 -1
- data/script/rails +8 -0
- data/spec/controllers/corkboard/application_controller_spec.rb +7 -0
- data/spec/controllers/corkboard/authorizations_controller_spec.rb +26 -0
- data/spec/controllers/corkboard/board_controller_spec.rb +29 -0
- data/spec/controllers/corkboard/posts_controller_spec.rb +7 -0
- data/spec/corkboard/client_spec.rb +52 -0
- data/spec/corkboard/clients/instagram_spec.rb +30 -0
- data/spec/corkboard/engine_spec.rb +11 -0
- data/spec/corkboard/provider_spec.rb +28 -0
- data/spec/corkboard/providers/instagram_spec.rb +44 -0
- data/spec/corkboard/publishers/mock_spec.rb +12 -0
- data/spec/corkboard/publishers/pusher_spec.rb +12 -0
- data/spec/corkboard/service/config_spec.rb +12 -0
- data/spec/corkboard_spec.rb +136 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +65 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/corkboard.rb +45 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/jasmine.rb +5 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/.gitkeep +0 -0
- data/spec/dummy/db/migrate/20121212222912_create_corkboard_authorizations.corkboard.rb +18 -0
- data/spec/dummy/db/schema.rb +31 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/helpers/corkboard/application_helper_spec.rb +7 -0
- data/spec/javascripts/fixtures/board.html +3 -0
- data/spec/javascripts/helpers/jasmine-jquery.js +340 -0
- data/spec/javascripts/spec.css +3 -0
- data/spec/javascripts/spec.js +5 -0
- data/spec/javascripts/spec_helper.js +41 -0
- data/spec/javascripts/specs/corkboard/app/board_spec.js +68 -0
- data/spec/javascripts/specs/corkboard/base_spec.js +17 -0
- data/spec/javascripts/specs/corkboard/lib/publisher_spec.js +101 -0
- data/spec/javascripts/specs/corkboard/lib/weighted_randomizer_spec.js +23 -0
- data/spec/javascripts/specs/corkboard_spec.js +45 -0
- data/spec/javascripts/support/jasmine.yml +75 -0
- data/spec/javascripts/support/jasmine_config.rb +1 -0
- data/spec/models/corkboard/authorization_spec.rb +7 -0
- data/spec/models/corkboard/post_spec.rb +7 -0
- data/spec/models/corkboard/subscription_spec.rb +7 -0
- data/spec/requests/authorizations_spec.rb +39 -0
- data/spec/requests/board_spec.rb +70 -0
- data/spec/routing/authorizations_routing_spec.rb +25 -0
- data/spec/routing/board_routing_spec.rb +7 -0
- data/spec/routing/posts_routing_spec.rb +15 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/support/helpers/config_helpers.rb +26 -0
- data/spec/support/helpers/controller_helpers.rb +12 -0
- data/spec/support/helpers/post_helpers.rb +119 -0
- data/vendor/assets/javascripts/jquery.masonry-extensions.js +203 -0
- data/vendor/assets/javascripts/jquery.masonry.js +499 -0
- data/vendor/assets/javascripts/modernizr.js +821 -0
- data/vendor/assets/javascripts/pusher.js +48 -0
- metadata +176 -11
@@ -0,0 +1,499 @@
|
|
1
|
+
/**
|
2
|
+
* jQuery Masonry v2.1.05
|
3
|
+
* A dynamic layout plugin for jQuery
|
4
|
+
* The flip-side of CSS Floats
|
5
|
+
* http://masonry.desandro.com
|
6
|
+
*
|
7
|
+
* Licensed under the MIT license.
|
8
|
+
* Copyright 2012 David DeSandro
|
9
|
+
*/
|
10
|
+
|
11
|
+
/*jshint browser: true, curly: true, eqeqeq: true, forin: false, immed: false, newcap: true, noempty: true, strict: true, undef: true */
|
12
|
+
/*global jQuery: false */
|
13
|
+
|
14
|
+
(function( window, $, undefined ){
|
15
|
+
|
16
|
+
'use strict';
|
17
|
+
|
18
|
+
/*
|
19
|
+
* smartresize: debounced resize event for jQuery
|
20
|
+
*
|
21
|
+
* latest version and complete README available on Github:
|
22
|
+
* https://github.com/louisremi/jquery.smartresize.js
|
23
|
+
*
|
24
|
+
* Copyright 2011 @louis_remi
|
25
|
+
* Licensed under the MIT license.
|
26
|
+
*/
|
27
|
+
|
28
|
+
var $event = $.event,
|
29
|
+
resizeTimeout;
|
30
|
+
|
31
|
+
$event.special.smartresize = {
|
32
|
+
setup: function() {
|
33
|
+
$(this).bind( "resize", $event.special.smartresize.handler );
|
34
|
+
},
|
35
|
+
teardown: function() {
|
36
|
+
$(this).unbind( "resize", $event.special.smartresize.handler );
|
37
|
+
},
|
38
|
+
handler: function( event, execAsap ) {
|
39
|
+
// Save the context
|
40
|
+
var context = this,
|
41
|
+
args = arguments;
|
42
|
+
|
43
|
+
// set correct event type
|
44
|
+
event.type = "smartresize";
|
45
|
+
|
46
|
+
if ( resizeTimeout ) { clearTimeout( resizeTimeout ); }
|
47
|
+
resizeTimeout = setTimeout(function() {
|
48
|
+
$.event.handle.apply( context, args );
|
49
|
+
}, execAsap === "execAsap"? 0 : 100 );
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
$.fn.smartresize = function( fn ) {
|
54
|
+
return fn ? this.bind( "smartresize", fn ) : this.trigger( "smartresize", ["execAsap"] );
|
55
|
+
};
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
// ========================= Masonry ===============================
|
60
|
+
|
61
|
+
|
62
|
+
// our "Widget" object constructor
|
63
|
+
$.Mason = function( options, element ){
|
64
|
+
this.element = $( element );
|
65
|
+
|
66
|
+
this._create( options );
|
67
|
+
this._init();
|
68
|
+
};
|
69
|
+
|
70
|
+
$.Mason.settings = {
|
71
|
+
isResizable: true,
|
72
|
+
isAnimated: false,
|
73
|
+
animationOptions: {
|
74
|
+
queue: false,
|
75
|
+
duration: 500
|
76
|
+
},
|
77
|
+
gutterWidth: 0,
|
78
|
+
isRTL: false,
|
79
|
+
isFitWidth: false,
|
80
|
+
containerStyle: {
|
81
|
+
position: 'relative'
|
82
|
+
}
|
83
|
+
};
|
84
|
+
|
85
|
+
$.Mason.prototype = {
|
86
|
+
|
87
|
+
_filterFindBricks: function( $elems ) {
|
88
|
+
var selector = this.options.itemSelector;
|
89
|
+
// if there is a selector
|
90
|
+
// filter/find appropriate item elements
|
91
|
+
return !selector ? $elems : $elems.filter( selector ).add( $elems.find( selector ) );
|
92
|
+
},
|
93
|
+
|
94
|
+
_getBricks: function( $elems ) {
|
95
|
+
var $bricks = this._filterFindBricks( $elems )
|
96
|
+
.css({ position: 'absolute' })
|
97
|
+
.addClass('masonry-brick');
|
98
|
+
return $bricks;
|
99
|
+
},
|
100
|
+
|
101
|
+
// sets up widget
|
102
|
+
_create : function( options ) {
|
103
|
+
|
104
|
+
this.options = $.extend( true, {}, $.Mason.settings, options );
|
105
|
+
this.styleQueue = [];
|
106
|
+
|
107
|
+
// get original styles in case we re-apply them in .destroy()
|
108
|
+
var elemStyle = this.element[0].style;
|
109
|
+
this.originalStyle = {
|
110
|
+
// get height
|
111
|
+
height: elemStyle.height || ''
|
112
|
+
};
|
113
|
+
// get other styles that will be overwritten
|
114
|
+
var containerStyle = this.options.containerStyle;
|
115
|
+
for ( var prop in containerStyle ) {
|
116
|
+
this.originalStyle[ prop ] = elemStyle[ prop ] || '';
|
117
|
+
}
|
118
|
+
|
119
|
+
this.element.css( containerStyle );
|
120
|
+
|
121
|
+
this.horizontalDirection = this.options.isRTL ? 'right' : 'left';
|
122
|
+
|
123
|
+
this.offset = {
|
124
|
+
x: parseInt( this.element.css( 'padding-' + this.horizontalDirection ), 10 ),
|
125
|
+
y: parseInt( this.element.css( 'padding-top' ), 10 )
|
126
|
+
};
|
127
|
+
|
128
|
+
this.isFluid = this.options.columnWidth && typeof this.options.columnWidth === 'function';
|
129
|
+
|
130
|
+
// add masonry class first time around
|
131
|
+
var instance = this;
|
132
|
+
setTimeout( function() {
|
133
|
+
instance.element.addClass('masonry');
|
134
|
+
}, 0 );
|
135
|
+
|
136
|
+
// bind resize method
|
137
|
+
if ( this.options.isResizable ) {
|
138
|
+
$(window).bind( 'smartresize.masonry', function() {
|
139
|
+
instance.resize();
|
140
|
+
});
|
141
|
+
}
|
142
|
+
|
143
|
+
|
144
|
+
// need to get bricks
|
145
|
+
this.reloadItems();
|
146
|
+
|
147
|
+
},
|
148
|
+
|
149
|
+
// _init fires when instance is first created
|
150
|
+
// and when instance is triggered again -> $el.masonry();
|
151
|
+
_init : function( callback ) {
|
152
|
+
this._getColumns();
|
153
|
+
this._reLayout( callback );
|
154
|
+
},
|
155
|
+
|
156
|
+
option: function( key, value ){
|
157
|
+
// set options AFTER initialization:
|
158
|
+
// signature: $('#foo').bar({ cool:false });
|
159
|
+
if ( $.isPlainObject( key ) ){
|
160
|
+
this.options = $.extend(true, this.options, key);
|
161
|
+
}
|
162
|
+
},
|
163
|
+
|
164
|
+
// ====================== General Layout ======================
|
165
|
+
|
166
|
+
// used on collection of atoms (should be filtered, and sorted before )
|
167
|
+
// accepts atoms-to-be-laid-out to start with
|
168
|
+
layout : function( $bricks, callback ) {
|
169
|
+
|
170
|
+
// place each brick
|
171
|
+
for (var i=0, len = $bricks.length; i < len; i++) {
|
172
|
+
this._placeBrick( $bricks[i] );
|
173
|
+
}
|
174
|
+
|
175
|
+
// set the size of the container
|
176
|
+
var containerSize = {};
|
177
|
+
containerSize.height = Math.max.apply( Math, this.colYs );
|
178
|
+
if ( this.options.isFitWidth ) {
|
179
|
+
var unusedCols = 0;
|
180
|
+
i = this.cols;
|
181
|
+
// count unused columns
|
182
|
+
while ( --i ) {
|
183
|
+
if ( this.colYs[i] !== 0 ) {
|
184
|
+
break;
|
185
|
+
}
|
186
|
+
unusedCols++;
|
187
|
+
}
|
188
|
+
// fit container to columns that have been used;
|
189
|
+
containerSize.width = (this.cols - unusedCols) * this.columnWidth - this.options.gutterWidth;
|
190
|
+
}
|
191
|
+
this.styleQueue.push({ $el: this.element, style: containerSize });
|
192
|
+
|
193
|
+
// are we animating the layout arrangement?
|
194
|
+
// use plugin-ish syntax for css or animate
|
195
|
+
var styleFn = !this.isLaidOut ? 'css' : (
|
196
|
+
this.options.isAnimated ? 'animate' : 'css'
|
197
|
+
),
|
198
|
+
animOpts = this.options.animationOptions;
|
199
|
+
|
200
|
+
// process styleQueue
|
201
|
+
var obj;
|
202
|
+
for (i=0, len = this.styleQueue.length; i < len; i++) {
|
203
|
+
obj = this.styleQueue[i];
|
204
|
+
obj.$el[ styleFn ]( obj.style, animOpts );
|
205
|
+
}
|
206
|
+
|
207
|
+
// clear out queue for next time
|
208
|
+
this.styleQueue = [];
|
209
|
+
|
210
|
+
// provide $elems as context for the callback
|
211
|
+
if ( callback ) {
|
212
|
+
callback.call( $bricks );
|
213
|
+
}
|
214
|
+
|
215
|
+
this.isLaidOut = true;
|
216
|
+
},
|
217
|
+
|
218
|
+
// calculates number of columns
|
219
|
+
// i.e. this.columnWidth = 200
|
220
|
+
_getColumns : function() {
|
221
|
+
var container = this.options.isFitWidth ? this.element.parent() : this.element,
|
222
|
+
containerWidth = container.width();
|
223
|
+
|
224
|
+
// use fluid columnWidth function if there
|
225
|
+
this.columnWidth = this.isFluid ? this.options.columnWidth( containerWidth ) :
|
226
|
+
// if not, how about the explicitly set option?
|
227
|
+
this.options.columnWidth ||
|
228
|
+
// or use the size of the first item
|
229
|
+
this.$bricks.outerWidth(true) ||
|
230
|
+
// if there's no items, use size of container
|
231
|
+
containerWidth;
|
232
|
+
|
233
|
+
this.columnWidth += this.options.gutterWidth;
|
234
|
+
|
235
|
+
this.cols = Math.floor( ( containerWidth + this.options.gutterWidth ) / this.columnWidth );
|
236
|
+
this.cols = Math.max( this.cols, 1 );
|
237
|
+
|
238
|
+
},
|
239
|
+
|
240
|
+
// layout logic
|
241
|
+
_placeBrick: function( brick ) {
|
242
|
+
var $brick = $(brick),
|
243
|
+
colSpan, groupCount, groupY, groupColY, j;
|
244
|
+
|
245
|
+
//how many columns does this brick span
|
246
|
+
colSpan = Math.ceil( $brick.outerWidth(true) / this.columnWidth );
|
247
|
+
colSpan = Math.min( colSpan, this.cols );
|
248
|
+
|
249
|
+
if ( colSpan === 1 ) {
|
250
|
+
// if brick spans only one column, just like singleMode
|
251
|
+
groupY = this.colYs;
|
252
|
+
} else {
|
253
|
+
// brick spans more than one column
|
254
|
+
// how many different places could this brick fit horizontally
|
255
|
+
groupCount = this.cols + 1 - colSpan;
|
256
|
+
groupY = [];
|
257
|
+
|
258
|
+
// for each group potential horizontal position
|
259
|
+
for ( j=0; j < groupCount; j++ ) {
|
260
|
+
// make an array of colY values for that one group
|
261
|
+
groupColY = this.colYs.slice( j, j+colSpan );
|
262
|
+
// and get the max value of the array
|
263
|
+
groupY[j] = Math.max.apply( Math, groupColY );
|
264
|
+
}
|
265
|
+
|
266
|
+
}
|
267
|
+
|
268
|
+
// get the minimum Y value from the columns
|
269
|
+
var minimumY = Math.min.apply( Math, groupY ),
|
270
|
+
shortCol = 0;
|
271
|
+
|
272
|
+
// Find index of short column, the first from the left
|
273
|
+
for (var i=0, len = groupY.length; i < len; i++) {
|
274
|
+
if ( groupY[i] === minimumY ) {
|
275
|
+
shortCol = i;
|
276
|
+
break;
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
// position the brick
|
281
|
+
var position = {
|
282
|
+
top: minimumY + this.offset.y
|
283
|
+
};
|
284
|
+
// position.left or position.right
|
285
|
+
position[ this.horizontalDirection ] = this.columnWidth * shortCol + this.offset.x;
|
286
|
+
this.styleQueue.push({ $el: $brick, style: position });
|
287
|
+
|
288
|
+
// apply setHeight to necessary columns
|
289
|
+
var setHeight = minimumY + $brick.outerHeight(true),
|
290
|
+
setSpan = this.cols + 1 - len;
|
291
|
+
for ( i=0; i < setSpan; i++ ) {
|
292
|
+
this.colYs[ shortCol + i ] = setHeight;
|
293
|
+
}
|
294
|
+
|
295
|
+
},
|
296
|
+
|
297
|
+
|
298
|
+
resize: function() {
|
299
|
+
var prevColCount = this.cols;
|
300
|
+
// get updated colCount
|
301
|
+
this._getColumns();
|
302
|
+
if ( this.isFluid || this.cols !== prevColCount ) {
|
303
|
+
// if column count has changed, trigger new layout
|
304
|
+
this._reLayout();
|
305
|
+
}
|
306
|
+
},
|
307
|
+
|
308
|
+
|
309
|
+
_reLayout : function( callback ) {
|
310
|
+
// reset columns
|
311
|
+
var i = this.cols;
|
312
|
+
this.colYs = [];
|
313
|
+
while (i--) {
|
314
|
+
this.colYs.push( 0 );
|
315
|
+
}
|
316
|
+
// apply layout logic to all bricks
|
317
|
+
this.layout( this.$bricks, callback );
|
318
|
+
},
|
319
|
+
|
320
|
+
// ====================== Convenience methods ======================
|
321
|
+
|
322
|
+
// goes through all children again and gets bricks in proper order
|
323
|
+
reloadItems : function() {
|
324
|
+
this.$bricks = this._getBricks( this.element.children() );
|
325
|
+
},
|
326
|
+
|
327
|
+
|
328
|
+
reload : function( callback ) {
|
329
|
+
this.reloadItems();
|
330
|
+
this._init( callback );
|
331
|
+
},
|
332
|
+
|
333
|
+
|
334
|
+
// convienence method for working with Infinite Scroll
|
335
|
+
appended : function( $content, isAnimatedFromBottom, callback ) {
|
336
|
+
if ( isAnimatedFromBottom ) {
|
337
|
+
// set new stuff to the bottom
|
338
|
+
this._filterFindBricks( $content ).css({ top: this.element.height() });
|
339
|
+
var instance = this;
|
340
|
+
setTimeout( function(){
|
341
|
+
instance._appended( $content, callback );
|
342
|
+
}, 1 );
|
343
|
+
} else {
|
344
|
+
this._appended( $content, callback );
|
345
|
+
}
|
346
|
+
},
|
347
|
+
|
348
|
+
_appended : function( $content, callback ) {
|
349
|
+
var $newBricks = this._getBricks( $content );
|
350
|
+
// add new bricks to brick pool
|
351
|
+
this.$bricks = this.$bricks.add( $newBricks );
|
352
|
+
this.layout( $newBricks, callback );
|
353
|
+
},
|
354
|
+
|
355
|
+
// removes elements from Masonry widget
|
356
|
+
remove : function( $content ) {
|
357
|
+
this.$bricks = this.$bricks.not( $content );
|
358
|
+
$content.remove();
|
359
|
+
},
|
360
|
+
|
361
|
+
// destroys widget, returns elements and container back (close) to original style
|
362
|
+
destroy : function() {
|
363
|
+
|
364
|
+
this.$bricks
|
365
|
+
.removeClass('masonry-brick')
|
366
|
+
.each(function(){
|
367
|
+
this.style.position = '';
|
368
|
+
this.style.top = '';
|
369
|
+
this.style.left = '';
|
370
|
+
});
|
371
|
+
|
372
|
+
// re-apply saved container styles
|
373
|
+
var elemStyle = this.element[0].style;
|
374
|
+
for ( var prop in this.originalStyle ) {
|
375
|
+
elemStyle[ prop ] = this.originalStyle[ prop ];
|
376
|
+
}
|
377
|
+
|
378
|
+
this.element
|
379
|
+
.unbind('.masonry')
|
380
|
+
.removeClass('masonry')
|
381
|
+
.removeData('masonry');
|
382
|
+
|
383
|
+
$(window).unbind('.masonry');
|
384
|
+
|
385
|
+
}
|
386
|
+
|
387
|
+
};
|
388
|
+
|
389
|
+
|
390
|
+
// ======================= imagesLoaded Plugin ===============================
|
391
|
+
/*!
|
392
|
+
* jQuery imagesLoaded plugin v1.1.0
|
393
|
+
* http://github.com/desandro/imagesloaded
|
394
|
+
*
|
395
|
+
* MIT License. by Paul Irish et al.
|
396
|
+
*/
|
397
|
+
|
398
|
+
|
399
|
+
// $('#my-container').imagesLoaded(myFunction)
|
400
|
+
// or
|
401
|
+
// $('img').imagesLoaded(myFunction)
|
402
|
+
|
403
|
+
// execute a callback when all images have loaded.
|
404
|
+
// needed because .load() doesn't work on cached images
|
405
|
+
|
406
|
+
// callback function gets image collection as argument
|
407
|
+
// `this` is the container
|
408
|
+
|
409
|
+
$.fn.imagesLoaded = function( callback ) {
|
410
|
+
var $this = this,
|
411
|
+
$images = $this.find('img').add( $this.filter('img') ),
|
412
|
+
len = $images.length,
|
413
|
+
blank = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==',
|
414
|
+
loaded = [];
|
415
|
+
|
416
|
+
function triggerCallback() {
|
417
|
+
callback.call( $this, $images );
|
418
|
+
}
|
419
|
+
|
420
|
+
function imgLoaded( event ) {
|
421
|
+
var img = event.target;
|
422
|
+
if ( img.src !== blank && $.inArray( img, loaded ) === -1 ){
|
423
|
+
loaded.push( img );
|
424
|
+
if ( --len <= 0 ){
|
425
|
+
setTimeout( triggerCallback );
|
426
|
+
$images.unbind( '.imagesLoaded', imgLoaded );
|
427
|
+
}
|
428
|
+
}
|
429
|
+
}
|
430
|
+
|
431
|
+
// if no images, trigger immediately
|
432
|
+
if ( !len ) {
|
433
|
+
triggerCallback();
|
434
|
+
}
|
435
|
+
|
436
|
+
$images.bind( 'load.imagesLoaded error.imagesLoaded', imgLoaded ).each( function() {
|
437
|
+
// cached images don't fire load sometimes, so we reset src.
|
438
|
+
var src = this.src;
|
439
|
+
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
|
440
|
+
// data uri bypasses webkit log warning (thx doug jones)
|
441
|
+
this.src = blank;
|
442
|
+
this.src = src;
|
443
|
+
});
|
444
|
+
|
445
|
+
return $this;
|
446
|
+
};
|
447
|
+
|
448
|
+
|
449
|
+
// helper function for logging errors
|
450
|
+
// $.error breaks jQuery chaining
|
451
|
+
var logError = function( message ) {
|
452
|
+
if ( window.console ) {
|
453
|
+
window.console.error( message );
|
454
|
+
}
|
455
|
+
};
|
456
|
+
|
457
|
+
// ======================= Plugin bridge ===============================
|
458
|
+
// leverages data method to either create or return $.Mason constructor
|
459
|
+
// A bit from jQuery UI
|
460
|
+
// https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js
|
461
|
+
// A bit from jcarousel
|
462
|
+
// https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js
|
463
|
+
|
464
|
+
$.fn.masonry = function( options ) {
|
465
|
+
if ( typeof options === 'string' ) {
|
466
|
+
// call method
|
467
|
+
var args = Array.prototype.slice.call( arguments, 1 );
|
468
|
+
|
469
|
+
this.each(function(){
|
470
|
+
var instance = $.data( this, 'masonry' );
|
471
|
+
if ( !instance ) {
|
472
|
+
logError( "cannot call methods on masonry prior to initialization; " +
|
473
|
+
"attempted to call method '" + options + "'" );
|
474
|
+
return;
|
475
|
+
}
|
476
|
+
if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
|
477
|
+
logError( "no such method '" + options + "' for masonry instance" );
|
478
|
+
return;
|
479
|
+
}
|
480
|
+
// apply method
|
481
|
+
instance[ options ].apply( instance, args );
|
482
|
+
});
|
483
|
+
} else {
|
484
|
+
this.each(function() {
|
485
|
+
var instance = $.data( this, 'masonry' );
|
486
|
+
if ( instance ) {
|
487
|
+
// apply options & init
|
488
|
+
instance.option( options || {} );
|
489
|
+
instance._init();
|
490
|
+
} else {
|
491
|
+
// initialize new instance
|
492
|
+
$.data( this, 'masonry', new $.Mason( options, this ) );
|
493
|
+
}
|
494
|
+
});
|
495
|
+
}
|
496
|
+
return this;
|
497
|
+
};
|
498
|
+
|
499
|
+
})( window, jQuery );
|