Gallery Carousel Without JetPack - Version 0.1

Version Description

Download this release

Release Info

Developer smub
Plugin Icon 128x128 Gallery Carousel Without JetPack
Version 0.1
Comparing to
See all releases

Version 0.1

images/arrows-2x.png ADDED
Binary file
images/arrows.png ADDED
Binary file
images/carousel-likereblog-2x.png ADDED
Binary file
images/carousel-likereblog.png ADDED
Binary file
images/carousel-link-2x.png ADDED
Binary file
images/carousel-link.png ADDED
Binary file
images/carousel-sprite-2x.png ADDED
Binary file
images/carousel-sprite.png ADDED
Binary file
jetpack-carousel.css ADDED
@@ -0,0 +1,1035 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * {
2
+ line-height:inherit; /* prevent declarations of line-height in the universal selector */
3
+ }
4
+
5
+ .jp-carousel-overlay {
6
+ background: #000;
7
+ }
8
+
9
+ div.jp-carousel-buttons a.jp-carousel-permalink {
10
+ background: url(./images/carousel-link.png) no-repeat;
11
+ background-size: 12px 32px;
12
+ }
13
+
14
+ div.jp-carousel-fadeaway {
15
+ background: -moz-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0));
16
+ background: -webkit-gradient(linear, left bottom, left top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0)));
17
+ position: fixed;
18
+ bottom: 0;
19
+ z-index: 99999;
20
+ width: 100%;
21
+ height: 15px;
22
+ }
23
+
24
+ .jp-carousel-next-button span,
25
+ .jp-carousel-previous-button span {
26
+ background: url(./images/arrows.png) no-repeat center center;
27
+ background-size: 200px 126px;
28
+ }
29
+
30
+ div.jp-carousel-buttons a.jp-carousel-permalink {
31
+ background-position: 2px 6px;
32
+ margin-right:0;
33
+ }
34
+
35
+ div.jp-carousel-buttons a.jp-carousel-permalink:hover {
36
+ background-position: 2px -14px;
37
+ }
38
+
39
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
40
+ div.jp-carousel-buttons a.jp-carousel-permalink {
41
+ background-image: url(./images/carousel-link-2x.png);
42
+ background-position: 2px 6px;
43
+ }
44
+ .jp-carousel-next-button span,
45
+ .jp-carousel-previous-button span {
46
+ background-image: url(./images/arrows-2x.png);
47
+ }
48
+ }
49
+
50
+ .jp-carousel-wrap {
51
+ font-family: "Helvetica Neue", sans-serif !important;
52
+ }
53
+
54
+ .jp-carousel-info {
55
+ position: absolute;
56
+ bottom: 0;
57
+ text-align: left !important;
58
+ -webkit-font-smoothing: subpixel-antialiased !important;
59
+ }
60
+
61
+ .jp-carousel-info ::selection {
62
+ background: #68c9e8; /* Safari */
63
+ color: #fff;
64
+ }
65
+
66
+ .jp-carousel-info ::-moz-selection {
67
+ background: #68c9e8; /* Firefox */
68
+ color: #fff;
69
+ }
70
+
71
+ .jp-carousel-photo-info {
72
+ position: relative;
73
+ -webkit-transition: 400ms ease-out;
74
+ -moz-transition: 400ms ease-out;
75
+ -o-transition: 400ms ease-out;
76
+ transition: 400ms ease-out;
77
+ left: 25%;
78
+ width: 50%;
79
+ }
80
+
81
+ .jp-carousel-info h2 {
82
+ background: none !important;
83
+ border: none !important;
84
+ color: #999;
85
+ display: block !important;
86
+ font: normal 13px/1.25em "Helvetica Neue", sans-serif !important;
87
+ letter-spacing: 0 !important;
88
+ margin: 7px 0 0 0 !important;
89
+ padding: 10px 0 0 !important;
90
+ overflow: hidden;
91
+ text-align: left;
92
+ text-shadow: none !important;
93
+ text-transform: none !important;
94
+ -webkit-font-smoothing: subpixel-antialiased;
95
+ }
96
+
97
+ .jp-carousel-next-button,
98
+ .jp-carousel-previous-button {
99
+ text-indent: -9999px;
100
+ overflow: hidden;
101
+ cursor: pointer;
102
+ }
103
+
104
+ .jp-carousel-next-button span,
105
+ .jp-carousel-previous-button span {
106
+ position: absolute;
107
+ top: 0;
108
+ bottom: 0;
109
+ width: 82px;
110
+ zoom: 1;
111
+ filter: alpha(opacity=20);
112
+ opacity: 0.2;
113
+ -webkit-transition: 500ms opacity ease-out;
114
+ -moz-transition: 500ms opacity ease-out;
115
+ -o-transition: 500ms opacity ease-out;
116
+ transition: 500ms opacity ease-out;
117
+ }
118
+
119
+ .jp-carousel-next-button:hover span,
120
+ .jp-carousel-previous-button:hover span {
121
+ filter: alpha(opacity=60);
122
+ opacity: 0.6;
123
+ }
124
+ .jp-carousel-next-button span {
125
+ background-position: -110px center;
126
+ right: 0;
127
+ }
128
+
129
+ .jp-carousel-previous-button span {
130
+ background-position: -10px center;
131
+ left:0;
132
+ }
133
+
134
+ .jp-carousel-buttons {
135
+ margin:0 0 15px 0;
136
+ padding-bottom:15px;
137
+ border-bottom:1px solid #222;
138
+ }
139
+
140
+ div.jp-carousel-buttons a {
141
+ border: none !important;
142
+ color: #999;
143
+ font: normal 13px/1.2em "Helvetica Neue", sans-serif !important;
144
+ letter-spacing: 0 !important;
145
+ padding: 5px 2px 5px 20px !important;
146
+ text-decoration: none !important;
147
+ text-shadow: none !important;
148
+ vertical-align: baseline !important;
149
+ -webkit-font-smoothing: subpixel-antialiased;
150
+ }
151
+
152
+ div.jp-carousel-buttons a:hover {
153
+ color: #68c9e8;
154
+ border: none !important;
155
+ -webkit-transition: none !important;
156
+ -moz-transition: none !important;
157
+ -o-transition: none !important;
158
+ transition: none !important;
159
+ }
160
+
161
+ .jp-carousel-slide, .jp-carousel-slide img, .jp-carousel-next-button,
162
+ .jp-carousel-previous-button {
163
+ -webkit-transform:translate3d(0, 0, 0);
164
+ -moz-transform:translate3d(0, 0, 0);
165
+ -o-transform:translate3d(0, 0, 0);
166
+ -ms-transform:translate3d(0, 0, 0);
167
+ }
168
+
169
+ .jp-carousel-slide {
170
+ position:absolute;
171
+ width:0;
172
+ bottom:0;
173
+ background-color:#000;
174
+ border-radius:2px;
175
+ -webkit-border-radius:2px;
176
+ -moz-border-radius:2px;
177
+ -ms-border-radius:2px;
178
+ -o-border-radius:2px;
179
+ -webkit-transition: 400ms ease-out;
180
+ -moz-transition: 400ms ease-out;
181
+ -o-transition: 400ms ease-out;
182
+ transition: 400ms ease-out;
183
+ }
184
+
185
+ .jp-carousel-slide img {
186
+ display: block;
187
+ width: 100%;
188
+ height: 100%;
189
+ background: none !important;
190
+ border: none !important;
191
+ padding: 0 !important;
192
+ -webkit-box-shadow: 0 2px 8px rgba(0,0,0,0.1);
193
+ -moz-box-shadow: 0 2px 8px rgba(0,0,0,0.1);
194
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
195
+ zoom: 1;
196
+ filter: alpha(opacity=25);
197
+ opacity: 0.25;
198
+ -webkit-transition: opacity 400ms linear;
199
+ -moz-transition: opacity 400ms linear;
200
+ -o-transition: opacity 400ms linear;
201
+ transition: opacity 400ms linear;
202
+ }
203
+
204
+ .jp-carousel-slide.selected img {
205
+ filter: alpha(opacity=100);
206
+ opacity: 1;
207
+ }
208
+
209
+ .jp-carousel-close-hint {
210
+ color: #999;
211
+ cursor: default;
212
+ font: 16px/1 "Helvetica Neue", sans-serif !important;
213
+ font-weight: 600 !important;
214
+ letter-spacing: 0 !important;
215
+ padding:0.55em 0 0;
216
+ text-align: left;
217
+ width: 100%;
218
+ position: absolute;
219
+ -webkit-transition: color 200ms linear;
220
+ -moz-transition: color 200ms linear;
221
+ -o-transition: color 200ms linear;
222
+ transition: color 200ms linear;
223
+ }
224
+
225
+ .jp-carousel-close-hint span {
226
+ cursor:pointer;
227
+ background-color: black;
228
+ background-color: rgba(0,0,0,0.8);
229
+ height: 26px;
230
+ width: 26px;
231
+ display: block;
232
+ text-align: center;
233
+ vertical-align: middle;
234
+ line-height: 22px;
235
+ margin: 0 0 0 0.4em;
236
+ -moz-border-radius: 4px;
237
+ -webkit-border-radius: 4px;
238
+ border-radius: 4px;
239
+ -webkit-transition: border-color 200ms linear;
240
+ -moz-transition: border-color 200ms linear;
241
+ -o-transition: border-color 200ms linear;
242
+ transition: border-color 200ms linear;
243
+ }
244
+
245
+ .jp-carousel-close-hint:hover {
246
+ cursor: default;
247
+ color: #fff;
248
+ }
249
+
250
+ .jp-carousel-close-hint:hover span {
251
+ border-color: #fff;
252
+ }
253
+
254
+ div.jp-carousel-buttons a.jp-carousel-like,
255
+ div.jp-carousel-buttons a.jp-carousel-reblog,
256
+ a.jp-carousel-image-download {
257
+ background: url(./images/carousel-sprite.png?3) no-repeat;
258
+ background-size: 16px 120px;
259
+ }
260
+
261
+ div.jp-carousel-buttons a.jp-carousel-reblog {
262
+ margin:0 5px 0 -5px !important;
263
+ }
264
+
265
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged,
266
+ div.jp-carousel-buttons a.jp-carousel-like.liked {
267
+ background-color: #222;
268
+ padding-right: 8px !important;
269
+ border-radius: 3px;
270
+ border-radius:3px;
271
+ -webkit-border-radius:3px;
272
+ -moz-border-radius:3px;
273
+ -ms-border-radius:3px;
274
+ -o-border-radius:3px;
275
+ }
276
+
277
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged {
278
+ margin:0 5px 0 0 !important;
279
+ }
280
+
281
+
282
+ div.jp-carousel-buttons a.jp-carousel-reblog,
283
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged:hover {
284
+ background-position: 6px -36px;
285
+ padding-left: 26px !important;
286
+ color: #999;
287
+ }
288
+
289
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged:hover {
290
+ cursor: default;
291
+ }
292
+
293
+ div.jp-carousel-buttons a.jp-carousel-reblog:hover {
294
+ background-position: 6px -56px;
295
+ color: #68c9e8;
296
+ }
297
+
298
+ div.jp-carousel-buttons a.jp-carousel-like {
299
+ background-position: 5px 5px;
300
+ padding-left: 24px !important;
301
+ }
302
+
303
+ div.jp-carousel-buttons a.jp-carousel-like:hover {
304
+ background-position: 5px -15px;
305
+ }
306
+
307
+ @media
308
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
309
+ only screen and (-o-min-device-pixel-ratio: 3/2),
310
+ only screen and (min--moz-device-pixel-ratio: 1.5),
311
+ only screen and (min-device-pixel-ratio: 1.5) {
312
+ div.jp-carousel-buttons a.jp-carousel-like,
313
+ div.jp-carousel-buttons a.jp-carousel-reblog,
314
+ a.jp-carousel-image-download {
315
+ background-image: url(./images/carousel-sprite-2x.png?3);
316
+ }
317
+ }
318
+
319
+ /* reblog */
320
+ div#carousel-reblog-box {
321
+ background: #222;
322
+ background: -moz-linear-gradient(bottom, #222, #333);
323
+ background: -webkit-gradient(linear, left bottom, left top, from(#222), to(#333));
324
+ padding: 3px 0 0;
325
+ display: none;
326
+ margin: 5px auto 0;
327
+ -moz-border-radius: 2px;
328
+ -webkit-border-radius: 2px;
329
+ border-radius: 2px;
330
+ -webkit-box-shadow: 0 0 20px rgba(0,0,0,0.9);
331
+ -moz-box-shadow: 0 0 20px rgba(0,0,0,0.9);
332
+ box-shadow: 0 0 20px rgba(0,0,0,0.9);
333
+ height: 74px;
334
+ width: 565px;
335
+ }
336
+
337
+ #carousel-reblog-box textarea {
338
+ background: #999;
339
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
340
+ color: #444;
341
+ padding: 3px 6px;
342
+ width: 370px;
343
+ height: 48px;
344
+ float: left;
345
+ margin: 6px 9px 0 9px;
346
+ border: 1px solid #666;
347
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
348
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
349
+ -moz-border-radius: 2px;
350
+ -webkit-border-radius: 2px;
351
+ border-radius: 2px;
352
+ }
353
+
354
+ #carousel-reblog-box textarea:focus {
355
+ background: #ccc;
356
+ color: #222;
357
+ }
358
+
359
+ #carousel-reblog-box label {
360
+ color: #aaa;
361
+ font-size: 11px;
362
+ padding-right: 2px;
363
+ padding-left: 2px;
364
+ display: inline;
365
+ font-weight: normal;
366
+ }
367
+
368
+ #carousel-reblog-box select {
369
+ width: 110px;
370
+ padding: 0;
371
+ font-size: 12px;
372
+ font-family: "Helvetica Neue", sans-serif !important;
373
+ background: #333;
374
+ color: #eee;
375
+ border: 1px solid #444;
376
+ margin-top:5px;
377
+ }
378
+
379
+ #carousel-reblog-box .submit,
380
+ #wrapper #carousel-reblog-box p.response {
381
+ float: left;
382
+ width: 154px;
383
+ padding-top: 0;
384
+ padding-left: 1px;
385
+ overflow: hidden;
386
+ height: 34px;
387
+ margin:3px 0 0 2px !important;
388
+ }
389
+
390
+ #wrapper #carousel-reblog-box p.response {
391
+ font-size: 13px;
392
+ clear: none;
393
+ padding-left: 2px;
394
+ height: 34px;
395
+ color: #aaa;
396
+ }
397
+
398
+ #carousel-reblog-box input#carousel-reblog-submit, #jp-carousel-comment-form-button-submit {
399
+ font: 13px/24px "Helvetica Neue", sans-serif !important;
400
+ margin-top: 8px;
401
+ padding: 0 10px !important;
402
+ border-radius: 1em;
403
+ height: 24px;
404
+ color: #333;
405
+ cursor:pointer;
406
+ font-weight: normal;
407
+ background: #aaa;
408
+ background: -moz-linear-gradient(bottom, #aaa, #ccc);
409
+ background: -webkit-gradient(linear, left bottom, left top, from(#aaa), to(#ccc));
410
+ border: 1px solid #444;
411
+ }
412
+
413
+ #carousel-reblog-box input#carousel-reblog-submit:hover, #jp-carousel-comment-form-button-submit:hover {
414
+ background: #ccc;
415
+ background: -moz-linear-gradient(bottom, #ccc, #eee);
416
+ background: -webkit-gradient(linear, left bottom, left top, from(#ccc), to(#eee));
417
+ }
418
+
419
+ #carousel-reblog-box .canceltext {
420
+ color: #aaa;
421
+ font-size: 11px;
422
+ line-height: 24px;
423
+ }
424
+
425
+ #carousel-reblog-box .canceltext a {
426
+ color: #fff;
427
+ }
428
+ /* reblog end */
429
+
430
+
431
+ /** Title and Desc Start **/
432
+ .jp-carousel-titleanddesc {
433
+ border-top: 1px solid #222;
434
+ color: #999;
435
+ font-size: 15px;
436
+ padding-top: 24px;
437
+ margin-bottom: 20px;
438
+ font-weight:400;
439
+ }
440
+ .jp-carousel-titleanddesc-title {
441
+ font: 300 1.5em/1.1 "Helvetica Neue", sans-serif !important;
442
+ text-transform: none !important; /* prevents uppercase from leaking through */
443
+ color: #fff;
444
+ margin: 0 0 15px;
445
+ padding:0;
446
+ }
447
+
448
+ .jp-carousel-titleanddesc-desc p {
449
+ color: #999;
450
+ line-height:1.4;
451
+ margin-bottom: 0.75em;
452
+ }
453
+
454
+ .jp-carousel-titleanddesc p a,
455
+ .jp-carousel-comments p a,
456
+ .jp-carousel-info h2 a {
457
+ color: #fff !important;
458
+ border: none !important;
459
+ text-decoration: underline !important;
460
+ font-weight: normal !important;
461
+ font-style: normal !important;
462
+ }
463
+
464
+ .jp-carousel-titleanddesc p strong,
465
+ .jp-carousel-titleanddesc p b {
466
+ font-weight: bold;
467
+ color: #999;
468
+ }
469
+
470
+ .jp-carousel-titleanddesc p em,
471
+ .jp-carousel-titleanddesc p i {
472
+ font-style: italic;
473
+ color: #999;
474
+ }
475
+
476
+
477
+ .jp-carousel-titleanddesc p a:hover,
478
+ .jp-carousel-comments p a:hover,
479
+ .jp-carousel-info h2 a:hover {
480
+ color: #68c9e8 !important;
481
+ }
482
+
483
+ .jp-carousel-titleanddesc p:empty {
484
+ display: none;
485
+ }
486
+
487
+ h1:before, h1:after {
488
+ content:none !important;
489
+ }
490
+ /** Title and Desc End **/
491
+
492
+ /** Meta Box Start **/
493
+ .jp-carousel-image-meta {
494
+ background: #111;
495
+ padding: 18px 20px;
496
+ color: #fff;
497
+ font-size: 13px;
498
+ font: 12px/1.4 "Helvetica Neue", sans-serif !important;
499
+ width: 209px !important;
500
+ border: 1px solid #222;
501
+ }
502
+
503
+ .jp-carousel-image-meta li,
504
+ .jp-carousel-image-meta h5 {
505
+ font-family: "Helvetica Neue", sans-serif !important;
506
+ position: inherit !important;
507
+ top: auto !important;
508
+ right: auto !important;
509
+ left: auto !important;
510
+ bottom: auto !important;
511
+ background: none !important;
512
+ border: none !important;
513
+ font-weight: 400 !important;
514
+ line-height: 1.3em !important;
515
+ }
516
+
517
+ .jp-carousel-image-meta ul {
518
+ margin: 0 !important;
519
+ padding: 0 !important;
520
+ list-style: none !important;
521
+ }
522
+
523
+ .jp-carousel-image-meta li {
524
+ width: 48% !important;
525
+ float: left !important;
526
+ margin: 0 2% 15px 0 !important;
527
+ color: #fff !important;
528
+ font-size:13px !important;
529
+ }
530
+
531
+ .jp-carousel-image-meta h5 {
532
+ color: #999 !important;
533
+ text-transform: uppercase !important;
534
+ font-size:10px !important;
535
+ margin:0 0 2px !important;
536
+ letter-spacing: 0.1em !important;
537
+ }
538
+
539
+ a.jp-carousel-image-download {
540
+ padding-left: 23px;
541
+ display: inline-block;
542
+ clear: both;
543
+ color: #999;
544
+ line-height: 1;
545
+ font-weight: 400;
546
+ font-size: 13px;
547
+ text-decoration: none;
548
+ background-position: 0 -82px;
549
+ }
550
+
551
+ a.jp-carousel-image-download span.photo-size {
552
+ font-size: 11px;
553
+ border-radius: 1em;
554
+ margin-left: 2px;
555
+ display: inline-block;
556
+ }
557
+
558
+ a.jp-carousel-image-download span.photo-size-times {
559
+ padding: 0 1px 0 2px;
560
+ }
561
+
562
+ a.jp-carousel-image-download:hover {
563
+ background-position: 0 -102px;
564
+ color: #68c9e8;
565
+ border: none !important;
566
+ }
567
+
568
+ /** Meta Box End **/
569
+
570
+ /** GPS Map Start **/
571
+ .jp-carousel-image-map {
572
+ position: relative;
573
+ margin: -20px -20px 20px;
574
+ border-bottom: 1px solid rgba( 255, 255, 255, 0.17 );
575
+ height: 154px;
576
+ }
577
+
578
+ .jp-carousel-image-map img.gmap-main {
579
+ -moz-border-radius-topleft: 6px;
580
+ border-top-left-radius: 6px;
581
+ border-right: 1px solid rgba( 255, 255, 255, 0.17 );
582
+ }
583
+ .jp-carousel-image-map div.gmap-topright {
584
+ width: 94px;
585
+ height: 154px;
586
+ position: absolute;
587
+ top: 0;
588
+ right: 0;
589
+ }
590
+ .jp-carousel-image-map div.imgclip {
591
+ overflow: hidden;
592
+ -moz-border-radius-topright: 6px;
593
+ border-top-right-radius: 6px;
594
+ }
595
+ .jp-carousel-image-map div.gmap-topright img {
596
+ margin-left: -40px;
597
+ }
598
+ .jp-carousel-image-map img.gmap-bottomright {
599
+ position: absolute;
600
+ top: 96px;
601
+ right: 0;
602
+ }
603
+
604
+ /** Comments Start **/
605
+ .jp-carousel-comments {
606
+ font: 15px/1.7 "Helvetica Neue", sans-serif !important;
607
+ font-weight: 400;
608
+ background:none transparent;
609
+ }
610
+
611
+ .jp-carousel-comments p a:hover, .jp-carousel-comments p a:focus, .jp-carousel-comments p a:active {
612
+ color: #68c9e8 !important;
613
+ }
614
+
615
+ .jp-carousel-comment {
616
+ background:none transparent;
617
+ color: #999;
618
+ margin-bottom: 20px;
619
+ clear:left;
620
+ overflow: auto;
621
+ width: 100%
622
+ }
623
+
624
+ .jp-carousel-comment p {
625
+ color: #999 !important;
626
+ }
627
+
628
+ .jp-carousel-comment .comment-author {
629
+ font-size: 13px;
630
+ font-weight:400;
631
+ padding:0;
632
+ width:auto;
633
+ display: inline;
634
+ float:none;
635
+ }
636
+
637
+ .jp-carousel-comment .comment-author a {
638
+ color: #fff;
639
+ }
640
+
641
+ .jp-carousel-comment .comment-gravatar {
642
+ float:left;
643
+ }
644
+
645
+ .jp-carousel-comment .comment-content {
646
+ border:none;
647
+ margin-left:85px;
648
+ }
649
+
650
+ .jp-carousel-comment .avatar {
651
+ margin:0 20px 0 0;
652
+ -moz-border-radius: 4px;
653
+ -webkit-border-radius: 4px;
654
+ border-radius: 4px;
655
+ border: none !important;
656
+ padding: 0 !important;
657
+ background-color: transparent !important;
658
+ }
659
+
660
+ .jp-carousel-comment .comment-date {
661
+ color:#999;
662
+ margin-top: 4px;
663
+ font-size:11px;
664
+ display: inline;
665
+ float: right;
666
+ /*clear: right;*/
667
+ }
668
+
669
+ #jp-carousel-comment-form {
670
+ margin:0 0 10px !important;
671
+ float: left;
672
+ width: 100%;
673
+ }
674
+
675
+ textarea#jp-carousel-comment-form-comment-field {
676
+ background: rgba(34,34,34,0.9);
677
+ border: 1px solid #3a3a3a;
678
+ color: #aaa;
679
+ font: 15px/1.4 "Helvetica Neue", sans-serif !important;
680
+ width: 100%;
681
+ padding: 10px 10px 5px;
682
+ margin: 0;
683
+ float: none;
684
+ height: 147px;
685
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
686
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
687
+ -moz-border-radius: 3px;
688
+ -webkit-border-radius: 3px;
689
+ border-radius: 3px;
690
+ overflow: hidden;
691
+ -webkit-box-sizing: border-box;
692
+ -moz-box-sizing: border-box;
693
+ box-sizing: border-box;
694
+ }
695
+
696
+ textarea#jp-carousel-comment-form-comment-field::-webkit-input-placeholder {
697
+ color: #555;
698
+ }
699
+
700
+ textarea#jp-carousel-comment-form-comment-field:focus {
701
+ background: #ccc;
702
+ color: #222;
703
+ }
704
+
705
+ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder {
706
+ color: #aaa;
707
+ }
708
+
709
+ #jp-carousel-comment-form-spinner {
710
+ color: #fff;
711
+ margin:22px 0 0 10px;
712
+ display: block;
713
+ width: 20px;
714
+ height: 20px;
715
+ float: left;
716
+ }
717
+
718
+ #jp-carousel-comment-form-submit-and-info-wrapper {
719
+ display: none;
720
+ /*margin-bottom:15px;*/
721
+ overflow: hidden;
722
+ width: 100%
723
+ }
724
+
725
+ #jp-carousel-comment-form-commenting-as {
726
+ }
727
+
728
+ #jp-carousel-comment-form-commenting-as input {
729
+ background: rgba(34,34,34,0.9);
730
+ border: 1px solid #3a3a3a;
731
+ color: #aaa;
732
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
733
+ padding: 3px 6px;
734
+ float: left;
735
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
736
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
737
+ -moz-border-radius: 2px;
738
+ -webkit-border-radius: 2px;
739
+ border-radius: 2px;
740
+ width:285px;
741
+ }
742
+
743
+ #jp-carousel-comment-form-commenting-as input:focus {
744
+ background: #ccc;
745
+ color: #222;
746
+ }
747
+
748
+ #jp-carousel-comment-form-commenting-as p {
749
+ font: 400 13px/1.7 "Helvetica Neue", sans-serif !important;
750
+ margin:22px 0 0;
751
+ float: left;
752
+ }
753
+
754
+ #jp-carousel-comment-form-commenting-as fieldset {
755
+ float:left;
756
+ border:none;
757
+ margin:20px 0 0 0;
758
+ padding:0;
759
+ }
760
+
761
+ #jp-carousel-comment-form-commenting-as fieldset {
762
+ clear: both;
763
+ }
764
+
765
+ #jp-carousel-comment-form-commenting-as label {
766
+ font: 400 13px/1.7 "Helvetica Neue", sans-serif !important;
767
+ margin:0 20px 3px 0;
768
+ float:left;
769
+ width:100px;
770
+ }
771
+
772
+ #jp-carousel-comment-form-button-submit {
773
+ margin-top: 20px;
774
+ float:right;
775
+ }
776
+
777
+ #js-carousel-comment-form-container {
778
+ margin-bottom:15px;
779
+ overflow: auto;
780
+ width: 100%;
781
+ }
782
+
783
+ #jp-carousel-comment-form-container {
784
+ margin-bottom:15px;
785
+ overflow: auto;
786
+ width: 100%;
787
+ }
788
+
789
+ #jp-carousel-comment-post-results {
790
+ display: none;
791
+ overflow:auto;
792
+ width:100%;
793
+ }
794
+
795
+ #jp-carousel-comment-post-results span {
796
+ display:block;
797
+ text-align: center;
798
+ margin-top:20px;
799
+ width: 100%;
800
+ overflow: auto;
801
+ padding: 1em 0;
802
+ box-sizing: border-box;
803
+ background: rgba( 0, 0, 0, 0.7 );
804
+ border-radius: 2px;
805
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
806
+ border: 1px solid rgba( 255, 255, 255, 0.17 );
807
+ -webkit-box-shadow: inset 0px 0px 5px 5px rgba(0, 0, 0, 1);
808
+ box-shadow: inset 0px 0px 5px 5px rgba(0, 0, 0, 1);
809
+ }
810
+
811
+ .jp-carousel-comment-post-error {
812
+ color:#DF4926;
813
+ }
814
+
815
+ .jp-carousel-comment-post-success {
816
+ /*color:#21759B;*/
817
+ }
818
+
819
+ #jp-carousel-comments-closed {
820
+ display: none;
821
+ color: #999;
822
+ }
823
+
824
+ #jp-carousel-comments-loading {
825
+ font: 444 15px/1.7 "Helvetica Neue", sans-serif !important;
826
+ display: none;
827
+ color: #999;
828
+ text-align: left;
829
+ margin-bottom: 20px;
830
+ }
831
+
832
+
833
+ /* ----- Light variant ----- */
834
+
835
+ .jp-carousel-light .jp-carousel-overlay {
836
+ background: #fff;
837
+ }
838
+
839
+ .jp-carousel-light .jp-carousel-next-button:hover span,
840
+ .jp-carousel-light .jp-carousel-previous-button:hover span {
841
+ opacity: 0.8;
842
+ }
843
+
844
+ .jp-carousel-light .jp-carousel-close-hint:hover,
845
+ .jp-carousel-light .jp-carousel-titleanddesc div {
846
+ color: #000 !important;
847
+ }
848
+
849
+ .jp-carousel-light .jp-carousel-comments p a,
850
+ .jp-carousel-light .jp-carousel-comment .comment-author a,
851
+ .jp-carousel-light .jp-carousel-titleanddesc p a,
852
+ .jp-carousel-light .jp-carousel-titleanddesc p a,
853
+ .jp-carousel-light .jp-carousel-comments p a,
854
+ .jp-carousel-light .jp-carousel-info h2 a {
855
+ color: #1e8cbe !important;
856
+ }
857
+
858
+ .jp-carousel-light .jp-carousel-comments p a:hover,
859
+ .jp-carousel-light .jp-carousel-comment .comment-author a:hover,
860
+ .jp-carousel-light .jp-carousel-titleanddesc p a:hover,
861
+ .jp-carousel-light .jp-carousel-titleanddesc p a:hover,
862
+ .jp-carousel-light .jp-carousel-comments p a:hover,
863
+ .jp-carousel-light .jp-carousel-info h2 a:hover {
864
+ color: #f1831e !important;
865
+ }
866
+
867
+ .jp-carousel-light .jp-carousel-info h2,
868
+ .jp-carousel-light .jp-carousel-titleanddesc,
869
+ .jp-carousel-light .jp-carousel-titleanddesc p,
870
+ .jp-carousel-light .jp-carousel-comment,
871
+ .jp-carousel-light .jp-carousel-comment p,
872
+ .jp-carousel-light div.jp-carousel-buttons a,
873
+ .jp-carousel-light .jp-carousel-titleanddesc p strong,
874
+ .jp-carousel-light .jp-carousel-titleanddesc p b,
875
+ .jp-carousel-light .jp-carousel-titleanddesc p em,
876
+ .jp-carousel-light .jp-carousel-titleanddesc p i {
877
+ color: #666;
878
+ }
879
+
880
+ .jp-carousel-light .jp-carousel-buttons {
881
+ border-bottom-color: #dfdfdf;
882
+ }
883
+
884
+ .jp-carousel-light div.jp-carousel-buttons a:hover {
885
+ text-decoration: none;
886
+ color: #f1831e;
887
+ }
888
+
889
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog,
890
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog:hover {
891
+ background-position: 4px -56px;
892
+ padding-left: 24px !important;
893
+ }
894
+
895
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog.reblogged,
896
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like.liked {
897
+ background-color: #2ea2cc;
898
+ color: #fff;
899
+ }
900
+
901
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like,
902
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like:hover {
903
+ background-position: 5px -15px;
904
+ padding-left: 23px !important;
905
+ }
906
+
907
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog.reblogged {
908
+ background-position: 5px -36px;
909
+ }
910
+
911
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like.liked {
912
+ background-position: 5px 5px;
913
+ }
914
+
915
+ .jp-carousel-light div#carousel-reblog-box {
916
+ background: #eee;
917
+ background: -moz-linear-gradient(bottom, #ececec, #f7f7f7);
918
+ background: -webkit-gradient(linear, left bottom, left top, from(#ececec), to(#f7f7f7));
919
+ -webkit-box-shadow: 0 2px 6px rgba(0,0,0,0.1);
920
+ -moz-box-shadow: 0 2px 10px rgba(0,0,0,0.1);
921
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
922
+ border:1px solid #ddd;
923
+ }
924
+
925
+ .jp-carousel-light #carousel-reblog-box textarea {
926
+ border: 1px inset #ccc;
927
+ color: #666;
928
+ border: 1px solid #cfcfcf;
929
+ background: #fff;
930
+ }
931
+
932
+ .jp-carousel-light #carousel-reblog-box .canceltext {
933
+ color: #888;
934
+ }
935
+
936
+ .jp-carousel-light #carousel-reblog-box .canceltext a {
937
+ color: #666;
938
+ }
939
+
940
+ .jp-carousel-light #carousel-reblog-box select {
941
+ background: #eee;
942
+ color: #333;
943
+ border: 1px solid #aaa;
944
+ }
945
+
946
+ .jp-carousel-light #carousel-reblog-box input#carousel-reblog-submit, #jp-carousel-comment-form-button-submit {
947
+ color: #333;
948
+ background: #fff;
949
+ background: -moz-linear-gradient(bottom, #ddd, #fff);
950
+ background: -webkit-gradient(linear, left bottom, left top, from(#ddd), to(#fff));
951
+ border: 1px solid #aaa;
952
+ }
953
+
954
+ .jp-carousel-light .jp-carousel-image-meta {
955
+ background: #fafafa;
956
+ border: 1px solid #eee;
957
+ border-top-color: #f5f5f5;
958
+ border-left-color: #f5f5f5;
959
+ color: #333;
960
+ }
961
+
962
+ .jp-carousel-light .jp-carousel-image-meta li {
963
+ color: #000 !important;
964
+ }
965
+
966
+ .jp-carousel-light .jp-carousel-close-hint {
967
+ color: #ccc;
968
+ }
969
+
970
+ .jp-carousel-light .jp-carousel-close-hint span {
971
+ background-color: white;
972
+ border-color: #ccc;
973
+ }
974
+
975
+ .jp-carousel-light #jp-carousel-comment-form-comment-field::-webkit-input-placeholder {
976
+ color: #aaa;
977
+ }
978
+
979
+ .jp-carousel-light #jp-carousel-comment-form-comment-field:focus {
980
+ color: #333;
981
+ }
982
+
983
+ .jp-carousel-light #jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder {
984
+ color: #ddd;
985
+ }
986
+
987
+ .jp-carousel-light a.jp-carousel-image-download {
988
+ background-position: 0 -102px;
989
+ }
990
+
991
+ .jp-carousel-light a.jp-carousel-image-download:hover {
992
+ background-position: 0 -102px;
993
+ color: #f1831e;
994
+ }
995
+
996
+ .jp-carousel-light textarea#jp-carousel-comment-form-comment-field {
997
+ background: #fbfbfb;
998
+ color: #333;
999
+ border: 1px solid #dfdfdf;
1000
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1001
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1002
+ }
1003
+
1004
+ .jp-carousel-light #jp-carousel-comment-form-commenting-as input {
1005
+ background: #fbfbfb;
1006
+ border: 1px solid #dfdfdf;
1007
+ color: #333;
1008
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1009
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1010
+ }
1011
+
1012
+ .jp-carousel-light #jp-carousel-comment-form-commenting-as input:focus {
1013
+ background: #fbfbfb;
1014
+ color: #333;
1015
+ }
1016
+
1017
+ .jp-carousel-light #jp-carousel-comment-post-results span {
1018
+ background: #f7f7f7;
1019
+ border:1px solid #dfdfdf;
1020
+ -webkit-box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.05);
1021
+ box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.05);
1022
+ }
1023
+
1024
+ .jp-carousel-light .jp-carousel-slide {
1025
+ background-color:#fff;
1026
+ }
1027
+
1028
+ .jp-carousel-light .jp-carousel-titleanddesc {
1029
+ border-top: 1px solid #eee;
1030
+ }
1031
+
1032
+ .jp-carousel-light .jp-carousel-fadeaway {
1033
+ background: -moz-linear-gradient(bottom, rgba(255,255,255,0.75), rgba(255,255,255,0));
1034
+ background: -webkit-gradient(linear, left bottom, left top, from(rgba(255,255,255,0.75)), to(rgba(255,255,255,0)));
1035
+ }
jetpack-carousel.js ADDED
@@ -0,0 +1,1140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ jQuery(document).ready(function($) {
3
+
4
+ // gallery faded layer and container elements
5
+ var overlay, comments, gallery, container, nextButton, previousButton, info, title,
6
+ caption, resizeTimeout, mouseTimeout, photo_info, close_hint, commentInterval, buttons,
7
+ screenPadding = 110, originalOverflow = $('body').css('overflow'), proportion = 85;
8
+
9
+ var keyListener = function(e){
10
+ switch(e.which){
11
+ case 38: // up
12
+ e.preventDefault();
13
+ container.scrollTop(container.scrollTop() - 100);
14
+ break;
15
+ case 40: // down
16
+ e.preventDefault();
17
+ container.scrollTop(container.scrollTop() + 100);
18
+ break;
19
+ case 39: // right
20
+ e.preventDefault();
21
+ gallery.jp_carousel('clearCommentTextAreaValue');
22
+ gallery.jp_carousel('next');
23
+ break;
24
+ case 37: // left
25
+ e.preventDefault();
26
+ gallery.jp_carousel('clearCommentTextAreaValue');
27
+ gallery.jp_carousel('previous');
28
+ break;
29
+ case 27: // escape
30
+ e.preventDefault();
31
+ gallery.jp_carousel('clearCommentTextAreaValue');
32
+ container.jp_carousel('close');
33
+ break;
34
+ default:
35
+ // making jslint happy
36
+ break;
37
+ }
38
+ };
39
+
40
+ var resizeListener = function(e){
41
+ clearTimeout(resizeTimeout);
42
+ resizeTimeout = setTimeout(function(){
43
+ gallery
44
+ .jp_carousel('slides')
45
+ .jp_carousel('fitSlide', true);
46
+ gallery
47
+ .jp_carousel('fitInfo', true)
48
+ .jp_carousel('fitMeta', true);
49
+ }, 200);
50
+ };
51
+
52
+ var prepareGallery = function(){
53
+ if (!overlay) {
54
+
55
+ overlay = $('<div></div>')
56
+ .addClass('jp-carousel-overlay')
57
+ .css({
58
+ 'position' : 'absolute',
59
+ 'top' : 0,
60
+ 'right' : 0,
61
+ 'bottom' : 0,
62
+ 'left' : 0
63
+ });
64
+
65
+ buttons = $('<div class="jp-carousel-buttons">' + buttons + '</div>');
66
+
67
+ caption = $('<h2></h2>');
68
+ photo_info = $('<div class="jp-carousel-photo-info"></div>').append(caption);
69
+
70
+ imageMeta = $('<div></div>')
71
+ .addClass('jp-carousel-image-meta')
72
+ .css({
73
+ 'float' : 'right',
74
+ 'margin-top' : '20px',
75
+ 'width' : '250px'
76
+ });
77
+
78
+ titleAndDescription = $('<div></div>')
79
+ .addClass('jp-carousel-titleanddesc')
80
+ .css({
81
+ 'width' : '100%',
82
+ 'margin-top' : imageMeta.css('margin-top')
83
+ });
84
+
85
+ var commentFormMarkup = '';
86
+ var iframeSrc = '';
87
+
88
+ commentFormMarkup = '<div id="jp-carousel-comment-form-container">';
89
+ if (iframeSrc && iframeSrc.length) {
90
+ // We're using Jetpack comments!
91
+ var iframeHeight = (jetpackCarouselStrings.is_logged_in || iframeSrc.match('comment_registration=1')) ? 220 : 340;
92
+ iframeSrc = iframeSrc.replace(/(blogid=\d+)/, '$1&postid='+window.location.hash.replace(/#jp-carousel-/,'')); // get initial attachment id from URL hash
93
+ commentFormMarkup += '<iframe src="'+iframeSrc+'" width="100%" height="'+iframeHeight+'" style="width:100%;height:'+iframeHeight+'px;" allowtransparency="true" frameBorder="0" scrolling="no" name="jp-carousel-comment-iframe" id="jp-carousel-comment-iframe"></iframe>';
94
+ } else if ( jetpackCarouselStrings.local_comments_commenting_as && jetpackCarouselStrings.local_comments_commenting_as.length ) {
95
+ // Jetpack comments not enabled, fallback to local comments
96
+ commentFormMarkup += '<form id="jp-carousel-comment-form">';
97
+ commentFormMarkup += '<textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="Write a comment&hellip;"></textarea>';
98
+ commentFormMarkup += '<div id="jp-carousel-comment-form-submit-and-info-wrapper">';
99
+ commentFormMarkup += '<div id="jp-carousel-comment-form-commenting-as">' + jetpackCarouselStrings.local_comments_commenting_as + '</div>';
100
+ commentFormMarkup += '<input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="'+jetpackCarouselStrings.post_comment+'" />';
101
+ commentFormMarkup += '<span id="jp-carousel-comment-form-spinner">&nbsp;</span>';
102
+ commentFormMarkup += '<div id="jp-carousel-comment-post-results"></div>';
103
+ commentFormMarkup += '</div>';
104
+ commentFormMarkup += '</form>';
105
+ }
106
+ commentFormMarkup += '</div>';
107
+
108
+ commentForm = $(commentFormMarkup)
109
+ .css({
110
+ 'width' : '100%',
111
+ 'margin-top' : '20px',
112
+ 'color' : '#999'
113
+ });
114
+
115
+ comments = $('<div></div>')
116
+ .addClass('jp-carousel-comments')
117
+ .css({
118
+ 'width' : '100%',
119
+ 'bottom' : '10px',
120
+ 'margin-top' : '20px'
121
+ });
122
+
123
+ commentsLoading = $('<div id="jp-carousel-comments-loading"><span>'+jetpackCarouselStrings.loading_comments+'</span></div>')
124
+ .css({
125
+ 'width' : '100%',
126
+ 'bottom' : '10px',
127
+ 'margin-top' : '20px'
128
+ });
129
+
130
+ leftWidth = ( $(window).width() - ( screenPadding * 2 ) ) - (imageMeta.width() + 40);
131
+ if ( $.browser.mozilla )
132
+ leftWidth -= 55;
133
+ else if ( $.browser.msie )
134
+ leftWidth -= 20;
135
+ leftWidth += 'px';
136
+
137
+ leftColWrapper = $('<div></div>')
138
+ .addClass('jp-carousel-left-column-wrapper')
139
+ .css({
140
+ 'width' : leftWidth
141
+ })
142
+ .append(titleAndDescription)
143
+ .append(commentForm)
144
+ .append(comments)
145
+ .append(commentsLoading);
146
+
147
+ fadeaway = $('<div></div>')
148
+ .addClass('jp-carousel-fadeaway');
149
+
150
+ info = $('<div></div>')
151
+ .addClass('jp-carousel-info')
152
+ .css({
153
+ 'top' : ($(window).height() / 100) * proportion,
154
+ 'left' : screenPadding,
155
+ 'right' : screenPadding
156
+ })
157
+ .append(photo_info)
158
+ .append(imageMeta)
159
+ .append(leftColWrapper);
160
+
161
+ targetBottomPos = ( $(window).height() - parseInt( info.css('top'), 10 ) ) + 'px';
162
+
163
+ nextButton = $("<div><span></span></div>")
164
+ .addClass('jp-carousel-next-button')
165
+ .css({
166
+ 'position' : 'fixed',
167
+ 'top' : 0,
168
+ 'right' : 0,
169
+ 'bottom' : 0,
170
+ 'width' : screenPadding
171
+ });
172
+
173
+ $('span', nextButton).css({
174
+ 'top' : '40px',
175
+ 'bottom' : targetBottomPos
176
+ });
177
+
178
+ previousButton = $("<div><span></span></div>")
179
+ .addClass('jp-carousel-previous-button')
180
+ .css({
181
+ 'position' : 'fixed',
182
+ 'top' : 0,
183
+ 'left' : 0,
184
+ 'bottom' : 0,
185
+ 'width' : screenPadding
186
+ });
187
+
188
+ $('span', previousButton).css({
189
+ 'top' : '40px',
190
+ 'bottom' : targetBottomPos
191
+ });
192
+
193
+ gallery = $('<div></div>')
194
+ .addClass('jp-carousel')
195
+ .css({
196
+ 'position' : 'absolute',
197
+ 'top' : 0,
198
+ 'bottom' : targetBottomPos,
199
+ 'left' : 0,
200
+ 'right' : 0
201
+ });
202
+
203
+ close_hint = $('<div class="jp-carousel-close-hint"><span>&times;</span></div>')
204
+ .css({
205
+ position : 'fixed'
206
+ });
207
+
208
+ container = $("<div></div>")
209
+ .addClass('jp-carousel-wrap');
210
+
211
+ if ( 'white' == jetpackCarouselStrings.background_color )
212
+ container.addClass('jp-carousel-light');
213
+
214
+ container.css({
215
+ 'position' : 'fixed',
216
+ 'top' : 0,
217
+ 'right' : 0,
218
+ 'bottom' : 0,
219
+ 'left' : 0,
220
+ 'z-index' : 999999,
221
+ 'overflow-x' : 'hidden',
222
+ 'overflow-y' : 'auto',
223
+ 'direction' : 'ltr'
224
+ })
225
+ .hide()
226
+ .append(overlay)
227
+ .append(gallery)
228
+ .append(fadeaway)
229
+ .append(info)
230
+ .append(nextButton)
231
+ .append(previousButton)
232
+ .append(close_hint)
233
+ .appendTo($('body'))
234
+ .click(function(e){
235
+ var target = $(e.target), wrap = target.parents('div.jp-carousel-wrap'), data = wrap.data('carousel-extra'),
236
+ slide = wrap.find('div.selected'), attachment_id = slide.data('attachment-id');
237
+ data = data || [];
238
+
239
+ if ( target.is(gallery) || target.parents().add(target).is(close_hint) ) {
240
+ container.jp_carousel('close');
241
+ } else if ( target.parents('#jp-carousel-comment-form-container').length ) {
242
+ var textarea = $('#jp-carousel-comment-form-comment-field')
243
+ .blur(function(){
244
+ $(window).bind('keydown', keyListener);
245
+ })
246
+ .focus(function(){
247
+ $(window).unbind('keydown', keyListener);
248
+ });
249
+
250
+ var emailField = $('#jp-carousel-comment-form-email-field')
251
+ .blur(function(){
252
+ $(window).bind('keydown', keyListener);
253
+ })
254
+ .focus(function(){
255
+ $(window).unbind('keydown', keyListener);
256
+ });
257
+
258
+ var authorField = $('#jp-carousel-comment-form-author-field')
259
+ .blur(function(){
260
+ $(window).bind('keydown', keyListener);
261
+ })
262
+ .focus(function(){
263
+ $(window).unbind('keydown', keyListener);
264
+ });
265
+
266
+ var urlField = $('#jp-carousel-comment-form-url-field')
267
+ .blur(function(){
268
+ $(window).bind('keydown', keyListener);
269
+ })
270
+ .focus(function(){
271
+ $(window).unbind('keydown', keyListener);
272
+ });
273
+
274
+ if ( textarea && textarea.attr('id') == target.attr('id')) {
275
+ // For first page load
276
+ $(window).unbind('keydown', keyListener);
277
+ $('#jp-carousel-comment-form-submit-and-info-wrapper').slideDown('fast');
278
+ } else if ( target.is( 'input[type="submit"]' ) ) {
279
+ e.preventDefault();
280
+ e.stopPropagation();
281
+
282
+ $('#jp-carousel-comment-form-spinner').spin('small', 'white');
283
+
284
+ var ajaxData = {
285
+ action: 'post_attachment_comment',
286
+ nonce: jetpackCarouselStrings.nonce,
287
+ blog_id: data['blog_id'],
288
+ id: attachment_id,
289
+ comment: textarea.val()
290
+ };
291
+
292
+ if ( ! ajaxData['comment'].length ) {
293
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.no_comment_text});
294
+ return;
295
+ }
296
+
297
+ if ( 1 != jetpackCarouselStrings.is_logged_in ) {
298
+ ajaxData['email'] = emailField.val();
299
+ ajaxData['author'] = authorField.val();
300
+ ajaxData['url'] = urlField.val();
301
+
302
+ if ( ! ajaxData['email'].length || ! ajaxData['email'].match('@') ) {
303
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-email-field', 'error': jetpackCarouselStrings.no_comment_email});
304
+ return;
305
+ } else if ( ! ajaxData['author'].length ) {
306
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-author-field', 'error': jetpackCarouselStrings.no_comment_author});
307
+ return;
308
+ }
309
+ }
310
+
311
+ $.ajax({
312
+ type: 'POST',
313
+ url: jetpackCarouselStrings.ajaxurl,
314
+ data: ajaxData,
315
+ dataType: 'json',
316
+ success: function(response, status, xhr) {
317
+ if ( 'approved' == response.comment_status ) {
318
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-success">' + jetpackCarouselStrings.comment_approved + '</span>').slideDown('fast');
319
+ } else if ( 'unapproved' == response.comment_status ) {
320
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-success">' + jetpackCarouselStrings.comment_unapproved + '</span>').slideDown('fast');
321
+ } else {
322
+ // 'deleted', 'spam', false
323
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-error">' + jetpackCarouselStrings.comment_post_error + '</span>').slideDown('fast');
324
+ }
325
+ gallery.jp_carousel('clearCommentTextAreaValue');
326
+ gallery.jp_carousel('getComments', {attachment_id: attachment_id, offset: 0, clear: true});
327
+ $('#jp-carousel-comment-form-button-submit').val(jetpackCarouselStrings.post_comment);
328
+ $('#jp-carousel-comment-form-spinner').spin(false);
329
+ },
330
+ error: function(xhr, status, error) {
331
+ // TODO: Add error handling and display here
332
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.comment_post_error});
333
+ return;
334
+ }
335
+ });
336
+ }
337
+ } else if ( ! target.parents( '.jp-carousel-info' ).length ) {
338
+ container.jp_carousel('next');
339
+ }
340
+ })
341
+ .bind('jp_carousel.afterOpen', function(){
342
+ $(window).bind('keydown', keyListener);
343
+ $(window).bind('resize', resizeListener);
344
+ })
345
+ .bind('jp_carousel.beforeClose', function(){
346
+ var scroll = $(window).scrollTop();
347
+
348
+ $(window).unbind('keydown', keyListener);
349
+ $(window).unbind('resize', resizeListener);
350
+ document.location.hash = '';
351
+ $(window).scrollTop(scroll);
352
+ });
353
+
354
+ nextButton.add(previousButton).click(function(e){
355
+ e.preventDefault();
356
+ e.stopPropagation();
357
+ if ( nextButton.is(this) ) {
358
+ gallery.jp_carousel('next');
359
+ } else {
360
+ gallery.jp_carousel('previous');
361
+ }
362
+ });
363
+ }
364
+ };
365
+
366
+ var methods = {
367
+ open: function(options) {
368
+ var settings = {
369
+ 'items_selector' : ".gallery-item [data-attachment-id]",
370
+ 'start_index': 0
371
+ },
372
+ data = $(this).data('carousel-extra');
373
+
374
+ if ( !data )
375
+ return; // don't run if the default gallery functions weren't used
376
+
377
+ // make sure to stop the page from scrolling behind the carousel overlay, so we don't trigger
378
+ // infiniscroll for it when enabled (Reader, theme infiniscroll, etc).
379
+ originalOverflow = $('body').css('overflow');
380
+ $('body').css('overflow', 'hidden');
381
+
382
+ prepareGallery();
383
+ container.data('carousel-extra', data);
384
+
385
+ return this.each(function() {
386
+ // If options exist, lets merge them
387
+ // with our default settings
388
+ var $this = $(this);
389
+
390
+ if ( options )
391
+ $.extend( settings, options );
392
+ if ( -1 == settings.start_index )
393
+ settings.start_index = 0; //-1 returned if can't find index, so start from beginning
394
+
395
+ container.trigger('jp_carousel.beforeOpen').fadeIn('fast',function(){
396
+ container.trigger('jp_carousel.afterOpen');
397
+ gallery
398
+ .jp_carousel('initSlides', $this.find(settings.items_selector), settings.start_index)
399
+ .jp_carousel('start', settings.start_index);
400
+ });
401
+ gallery.html('');
402
+ });
403
+ },
404
+
405
+ start : function(start_index){
406
+ var slides = this.jp_carousel('slides'), selected = slides.eq(start_index);
407
+
408
+ if ( 0 === selected.length )
409
+ selected = slides.eq(0);
410
+
411
+ gallery.jp_carousel('selectSlide', selected, false);
412
+ return this;
413
+ },
414
+
415
+ close : function(){
416
+ // make sure to let the page scroll again
417
+ $('body').css('overflow', originalOverflow);
418
+ return container
419
+ .trigger('jp_carousel.beforeClose')
420
+ .fadeOut('fast', function(){
421
+ container.trigger('jp_carousel.afterClose');
422
+ });
423
+
424
+ },
425
+
426
+ next : function(){
427
+ var selected = this.jp_carousel('selectedSlide'), slide;
428
+ container.animate({scrollTop:0}, 'fast');
429
+ if ( 0 === selected.length ) { // no selection return first item
430
+ slide = this.jp_carousel('slides').first(0);
431
+ } else if( selected.is( this.jp_carousel('slides').last() ) ) {
432
+ gallery.jp_carousel('loopSlides');
433
+ } else {
434
+ slide = selected.next();
435
+ }
436
+ if (!slide) {
437
+ return this;
438
+ } else {
439
+ return this.jp_carousel('selectSlide', slide);
440
+ }
441
+ },
442
+
443
+ previous : function(){
444
+ var selected = this.jp_carousel('selectedSlide'), slide;
445
+ container.animate({scrollTop:0}, 'fast');
446
+ if ( 0 === selected.length ) { // no selection return first item
447
+ slide = this.jp_carousel('slides').first();
448
+ } else if ( selected.is( this.jp_carousel('slides').first() ) ) { // if it's the last slide
449
+ gallery.jp_carousel('loopSlides', true);
450
+ } else {
451
+ slide = selected.prev();
452
+ }
453
+ if (!slide) {
454
+ return this;
455
+ } else {
456
+ return this.jp_carousel('selectSlide', slide);
457
+ }
458
+ },
459
+
460
+ resetButtons : function(current) {
461
+ },
462
+
463
+ loopSlides : function(reverse){
464
+ var slides = gallery.jp_carousel('slides'), last, first;
465
+ gallery.jp_carousel('selectedSlide').removeClass('selected').css({'position': 'fixed'});
466
+ if (reverse !== true ) {
467
+ last = slides.last();
468
+ slides.first().nextAll().not(last).css({'left':gallery.width()+slides.first().width()}).hide();
469
+ last.css({
470
+ 'left' : -last.width()
471
+ });
472
+ last.prev().css({
473
+ 'left' : -last.width() - last.prev().width()
474
+ });
475
+ slides.first().css({'left':gallery.width()});
476
+ setTimeout(function(){
477
+ gallery.jp_carousel('selectSlide', slides.show().first());
478
+ }, 400);
479
+
480
+ } else {
481
+ first = slides.first();
482
+ first.css({
483
+ 'left':gallery.width()
484
+ });
485
+ first.next().css({
486
+ 'left':gallery.width() + first.width()
487
+ });
488
+ first.next().nextAll().hide().css({'left':-slides.last().width()});
489
+ slides.last().css({'left':-slides.last().width()});
490
+ slides.last().prevAll().not(first, first.next()).hide().css({'left':-slides.last().width()-slides.last().prev().width()});
491
+ setTimeout(function(){
492
+ gallery.jp_carousel('selectSlide', slides.show().last());
493
+ }, 400);
494
+
495
+ }
496
+ },
497
+
498
+ selectedSlide : function(){
499
+ return this.find('.selected');
500
+ },
501
+
502
+ selectSlide : function(slide, animate){
503
+ var last = this.find('.selected').removeClass('selected'),
504
+ slides = gallery.jp_carousel('slides').css({'position': 'fixed'}),
505
+ current = $(slide).addClass('selected').css({'position': 'relative'}),
506
+ previous = current.prev(),
507
+ next = current.next(),
508
+ width = $(window).width(),
509
+ previous_previous = previous.prev(),
510
+ next_next = next.next(),
511
+ left = (gallery.width() - current.width()) * 0.5,
512
+ info_left,
513
+ animated,
514
+ info_min;
515
+ // center the main image
516
+
517
+ caption.hide();
518
+
519
+ method = 'css';
520
+ animated = current
521
+ .add(previous)
522
+ .add(previous.prev())
523
+ .add(next)
524
+ .add(next.next())
525
+ .jp_carousel('loadSlide');
526
+ // slide the whole view to the x we want
527
+ slides.not(animated).hide();
528
+
529
+ current[method]({left:left}).show();
530
+
531
+ // minimum width
532
+ gallery.jp_carousel('fitInfo', animate);
533
+
534
+ // prep the slides
535
+ var direction = last.is(current.prevAll()) ? 1 : -1;
536
+ if ( 1 == direction ) {
537
+ next_next.css({'left':gallery.width() + next.width()}).show();
538
+ next.hide().css({'left':gallery.width() + current.width()}).show();
539
+ previous_previous.css({'left':-previous_previous.width() - current.width()});
540
+ } else {
541
+ previous.css({'left':-previous.width() - current.width()});
542
+ next_next.css({'left':gallery.width() + current.width()});
543
+ }
544
+
545
+ // if advancing prepare the slide that will enter the screen
546
+ previous[method]({left:-previous.width() + (screenPadding * 0.75) }).show();
547
+ next[method]({left:gallery.width() - (screenPadding * 0.75) }).show();
548
+
549
+ setTimeout( function() {
550
+ document.location.href = document.location.href.replace(/#.*/, '') + '#jp-carousel-' + current.data('attachment-id');
551
+ gallery.jp_carousel('resetButtons', current);
552
+ container.trigger('jp_carousel.selectSlide', [current]);
553
+
554
+ $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' ).html('');
555
+
556
+ gallery.jp_carousel('getTitleDesc', { title: current.data('title'), desc: current.data('desc') } );
557
+ gallery.jp_carousel('getMeta', current.data('image-meta'));
558
+ gallery.jp_carousel('getFullSizeLink', current);
559
+ gallery.jp_carousel('getMap', current.data('image-meta'));
560
+ gallery.jp_carousel('testCommentsOpened', current.data('comments-opened'));
561
+ gallery.jp_carousel('getComments', {'attachment_id': current.data('attachment-id'), 'offset': 0, 'clear': true});
562
+
563
+ $('#jp-carousel-comment-post-results').slideUp();
564
+
565
+ // $('<div />').html(sometext).text() is a trick to go to HTML to plain text (including HTML emntities decode, etc)
566
+ if ( current.data('caption') ) {
567
+ if ( $('<div />').html(current.data('caption')).text() == $('<div />').html(current.data('title')).text() )
568
+ $('.jp-carousel-titleanddesc-title').fadeOut('fast').empty();
569
+ if ( $('<div />').html(current.data('caption')).text() == $('<div />').html(current.data('desc')).text() )
570
+ $('.jp-carousel-titleanddesc-desc').fadeOut('fast').empty();
571
+ caption.html( current.data('caption') ).fadeIn('slow');
572
+ } else {
573
+ caption.fadeOut('fast').empty();
574
+ }
575
+ }, 600 );
576
+
577
+ },
578
+
579
+ slides : function(){
580
+ return this.find('.jp-carousel-slide');
581
+ },
582
+
583
+ slideDimensions : function(){
584
+ return {
585
+ width: $(window).width() - (screenPadding * 2),
586
+ height: $(window).height() / 100 * proportion - 60
587
+ };
588
+ },
589
+
590
+ loadSlide : function(){
591
+ return this.each(function(){
592
+ var slide = $(this);
593
+ slide.find('img')
594
+ .one('load', function(){
595
+ // set the width/height of the image if it's too big
596
+ slide
597
+ .jp_carousel('fitSlide',false);
598
+ });
599
+ });
600
+ },
601
+
602
+ bestFit : function(){
603
+ var max = gallery.jp_carousel('slideDimensions'),
604
+ orig = this.jp_carousel('originalDimensions'),
605
+ orig_ratio = orig.width / orig.height,
606
+ w_ratio = 1,
607
+ h_ratio = 1;
608
+
609
+ if ( orig.width > max.width )
610
+ w_ratio = max.width / orig.width;
611
+ if ( orig.height > max.height )
612
+ h_ratio = max.height / orig.height;
613
+
614
+ if ( w_ratio < h_ratio ) {
615
+ width = max.width;
616
+ height = width / orig_ratio;
617
+ } else if ( h_ratio < w_ratio ) {
618
+ height = max.height;
619
+ width = height * orig_ratio;
620
+ } else {
621
+ width = orig.width;
622
+ height = orig.height;
623
+ }
624
+
625
+ return {
626
+ width: width,
627
+ height: height
628
+ };
629
+ },
630
+
631
+ fitInfo : function(animated){
632
+ var current = this.jp_carousel('selectedSlide'),
633
+ size = current.jp_carousel('bestFit');
634
+
635
+ photo_info.css({
636
+ 'left' : (info.width() - size.width) * 0.5,
637
+ 'width' : size.width
638
+ });
639
+ return this;
640
+ },
641
+
642
+ fitMeta : function(animated){
643
+ var newInfoTop = { top: ( $(window).height() / 100 * proportion + 5 ) + 'px' };
644
+ var newLeftWidth = { width: ( info.width() - (imageMeta.width() + 80) ) + 'px' };
645
+
646
+ if (animated) {
647
+ info.animate(newInfoTop);
648
+ leftColWrapper.animate(newLeftWidth);
649
+ } else {
650
+ info.animate(newInfoTop);
651
+ leftColWrapper.css(newLeftWidth);
652
+ }
653
+ },
654
+
655
+ fitSlide : function(animated){
656
+ return this.each(function(){
657
+ var selected = gallery.jp_carousel('selectedSlide'),
658
+ $this = $(this),
659
+ dimensions = $this.jp_carousel('bestFit'),
660
+ method = 'css',
661
+ max = gallery.jp_carousel('slideDimensions');
662
+
663
+ if ( 0 === selected.length ) {
664
+ dimensions.left = $(window).width();
665
+ } else if ($this.is(selected)) {
666
+ dimensions.left = ($(window).width() - dimensions.width) * 0.5;
667
+ } else if ($this.is(selected.next())) {
668
+ dimensions.left = gallery.width() - ( screenPadding * 0.75 );
669
+ } else if ($this.is(selected.prev())) {
670
+ dimensions.left = -dimensions.width + screenPadding * 0.75;
671
+ } else {
672
+ if ($this.is(selected.nextAll())) {
673
+ dimensions.left = $(window).width();
674
+ } else {
675
+ dimensions.left = -dimensions.width;
676
+ }
677
+ }
678
+ dimensions.top = ( (max.height - dimensions.height) * 0.5 ) + 40;
679
+ $this[method](dimensions);
680
+ });
681
+ },
682
+
683
+ texturize : function(text) {
684
+ text = text.replace("'", '&#8217;').replace('&#039;', '&#8217;').replace(/[\u2019]/, '&#8217;');
685
+ text = text.replace('"', '&#8221;').replace('&#034;', '&#8221;').replace('&quot;', '&#8221;').replace(/[\u201D]/, '&#8221;');
686
+ return $.trim(text);
687
+ },
688
+
689
+ initSlides : function(items, start_index){
690
+ var width = this.jp_carousel('slideDimensions').width,
691
+ x = 0;
692
+
693
+ // Calculate the new src.
694
+ items.each(function(i){
695
+ var src_item = $(this),
696
+ orig_size = src_item.data('orig-size') || 0,
697
+ max = gallery.jp_carousel('slideDimensions'),
698
+ parts = orig_size.split(',');
699
+ orig_size = {width: parseInt(parts[0], 10), height: parseInt(parts[1], 10)},
700
+ medium_file = src_item.data('medium-file') || '',
701
+ large_file = src_item.data('large-file') || '';
702
+
703
+ src = src_item.data('orig-file');
704
+
705
+ src = gallery.jp_carousel('selectBestImageSize', {
706
+ orig_file : src,
707
+ orig_width : orig_size.width,
708
+ max_width : max.width,
709
+ medium_file : medium_file,
710
+ large_file : large_file
711
+ });
712
+
713
+ // Set the final src
714
+ $(this).data( 'gallery-src', src );
715
+ });
716
+
717
+ // If the start_index is not 0 then preload the clicked image first.
718
+ if ( 0 !== start_index )
719
+ $('<img/>')[0].src = $(items[start_index]).data('gallery-src');
720
+
721
+ // create the 'slide'
722
+ items.each(function(i){
723
+ var src_item = $(this),
724
+ attachment_id = src_item.data('attachment-id') || 0,
725
+ comments_opened = src_item.data('comments-opened') || 0,
726
+ image_meta = src_item.data('image-meta') || {},
727
+ orig_size = src_item.data('orig-size') || 0,
728
+ title = src_item.attr('title') || '',
729
+ description = src_item.data('image-description') || '',
730
+ caption = src_item.parents('dl').find('dd.gallery-caption').html() || '',
731
+ src = src_item.data('gallery-src') || '',
732
+ medium_file = src_item.data('medium-file') || '',
733
+ large_file = src_item.data('large-file') || '';
734
+
735
+ if ( !attachment_id || !orig_size )
736
+ return false; // break the loop if we are missing the data-* attributes
737
+
738
+ title = gallery.jp_carousel('texturize', title);
739
+ description = gallery.jp_carousel('texturize', description);
740
+ caption = gallery.jp_carousel('texturize', caption);
741
+
742
+ var slide = $('<div class="jp-carousel-slide"></div>')
743
+ .hide()
744
+ .css({
745
+ 'position' : 'fixed',
746
+ 'left' : i < start_index ? -1000 : gallery.width()
747
+ })
748
+ .append($('<img>'))
749
+ .appendTo(gallery)
750
+ .data('src', src )
751
+ .data('title', title)
752
+ .data('desc', description)
753
+ .data('caption', caption)
754
+ .data('attachment-id', attachment_id)
755
+ .data('permalink', src_item.parents('a').attr('href'))
756
+ .data('orig-size', orig_size)
757
+ .data('comments-opened', comments_opened)
758
+ .data('image-meta', image_meta)
759
+ .data('medium-file', medium_file)
760
+ .data('large-file', large_file)
761
+ .jp_carousel('fitSlide', false);
762
+
763
+
764
+ // Preloading all images
765
+ slide.find('img').first().attr('src', src );
766
+ });
767
+ return this;
768
+ },
769
+
770
+ selectBestImageSize: function(args) {
771
+ if ( 'object' != typeof args )
772
+ args = {};
773
+
774
+ if ( 'undefined' == typeof args.orig_file )
775
+ return '';
776
+
777
+ if ( 'undefined' == typeof args.orig_width || 'undefined' == typeof args.max_width )
778
+ return args.orig_file;
779
+
780
+ if ( 'undefined' == typeof args.medium_file || 'undefined' == typeof args.large_file )
781
+ return args.orig_file;
782
+
783
+ var medium_size = args.medium_file.replace(/^https?:\/\/.+-([\d]+x[\d]+)\..+$/, '$1'),
784
+ medium_size_parts = (medium_size != args.medium_file) ? medium_size.split('x') : [args.orig_width, 0],
785
+ medium_width = parseInt( medium_size_parts[0], 10 ),
786
+ large_size = args.large_file.replace(/^https?:\/\/.+-([\d]+x[\d]+)\..+$/, '$1'),
787
+ large_size_parts = (large_size != args.large_file) ? large_size.split('x') : [args.orig_width, 0],
788
+ large_width = parseInt( large_size_parts[0], 10 );
789
+
790
+ // Give devices with a higher devicePixelRatio higher-res images (Retina display = 2, Android phones = 1.5, etc)
791
+ if ('undefined' != typeof window.devicePixelRatio && window.devicePixelRatio > 1)
792
+ args.max_width = args.max_width * window.devicePixelRatio;
793
+
794
+ if ( medium_width >= args.max_width )
795
+ return args.medium_file;
796
+
797
+ if ( large_width >= args.max_width )
798
+ return args.large_file;
799
+
800
+ return args.orig_file;
801
+ },
802
+
803
+
804
+ originalDimensions: function() {
805
+ var splitted = $(this).data('orig-size').split(',');
806
+ return {width: parseInt(splitted[0], 10), height: parseInt(splitted[1], 10)};
807
+ },
808
+
809
+ format: function( args ) {
810
+ if ( 'object' != typeof args )
811
+ args = {};
812
+ if ( ! args.text || 'undefined' == typeof args.text )
813
+ return;
814
+ if ( ! args.replacements || 'undefined' == typeof args.replacements )
815
+ return args.text;
816
+ return args.text.replace(/{(\d+)}/g, function(match, number) {
817
+ return typeof args.replacements[number] != 'undefined' ? args.replacements[number] : match;
818
+ });
819
+ },
820
+
821
+ shutterSpeed: function(d) {
822
+ if (d >= 1)
823
+ Math.round(d) + 's';
824
+ var df = 1, top = 1, bot = 1;
825
+ var limit = 1e5; //Increase for greater precision.
826
+ while (df != d && limit-- > 0) {
827
+ if (df < d) {
828
+ top += 1;
829
+ }
830
+ else {
831
+ bot += 1;
832
+ top = parseInt(d * bot, 10);
833
+ }
834
+ df = top / bot;
835
+ }
836
+ if (top > 1) {
837
+ bot = Math.round(bot / top);
838
+ top = 1;
839
+ }
840
+ if (bot <= 1)
841
+ return '1s';
842
+ return top + '/' + bot + 's';
843
+ },
844
+
845
+ parseTitleDesc: function( value ) {
846
+ if ( !value.match(' ') && value.match('_') )
847
+ return '';
848
+ // Prefix list originally based on http://commons.wikimedia.org/wiki/MediaWiki:Filename-prefix-blacklist
849
+ var prefixes = $([
850
+ 'CIMG', // Casio
851
+ 'DSC_', // Nikon
852
+ 'DSCF', // Fuji
853
+ 'DSCN', // Nikon
854
+ 'DUW', // some mobile phones
855
+ 'GEDC', // GE
856
+ 'IMG', // generic
857
+ 'JD', // Jenoptik
858
+ 'MGP', // Pentax
859
+ 'PICT', // misc.
860
+ 'Imagen', // misc.
861
+ 'Foto', // misc.
862
+ 'DSC', // misc.
863
+ 'Scan', // Scanners
864
+ 'SANY', // Sanyo
865
+ 'SAM', // Samsung
866
+ 'Screen Shot [0-9]+' // Mac screenshots
867
+ ])
868
+ .each(function(key, val){
869
+ regex = new RegExp('^' + val);
870
+ if ( regex.test(value) ) {
871
+ value = '';
872
+ return;
873
+ }
874
+ });
875
+ return value;
876
+ },
877
+
878
+ getTitleDesc: function( data ) {
879
+ var title ='', desc = '', markup = '', target, commentWrappere;
880
+
881
+ target = $( 'div.jp-carousel-titleanddesc', 'div.jp-carousel-wrap' );
882
+ target.hide();
883
+
884
+ title = gallery.jp_carousel('parseTitleDesc', data.title) || '';
885
+ desc = gallery.jp_carousel('parseTitleDesc', data.desc) || '';
886
+
887
+ if ( title.length || desc.length ) {
888
+ // $('<div />').html(sometext).text() is a trick to go to HTML to plain text (including HTML emntities decode, etc)
889
+ if ( $('<div />').html(title).text() == $('<div />').html(desc).text() )
890
+ title = '';
891
+
892
+ markup = ( title.length ) ? '<div class="jp-carousel-titleanddesc-title">' + title + '</div>' : '';
893
+ markup += ( desc.length ) ? '<div class="jp-carousel-titleanddesc-desc">' + desc + '</div>' : '';
894
+
895
+ target.html( markup ).fadeIn('slow');
896
+ }
897
+
898
+ $( 'div#jp-carousel-comment-form-container' ).css('margin-top', '20px');
899
+ $( 'div#jp-carousel-comments-loading' ).css('margin-top', '20px');
900
+ },
901
+
902
+ getMeta: function( meta ) {
903
+ if ( !meta || 1 != jetpackCarouselStrings.display_exif )
904
+ return false;
905
+
906
+ var $ul = $( '<ul></ul>' );
907
+ $.each( meta, function( key, val ) {
908
+ if ( 0 === parseFloat(val) || !val.length || -1 === $.inArray( key, [ 'camera', 'aperture', 'shutter_speed', 'focal_length' ] ) )
909
+ return;
910
+
911
+ switch( key ) {
912
+ case 'focal_length':
913
+ val = val + 'mm';
914
+ break;
915
+ case 'shutter_speed':
916
+ val = gallery.jp_carousel('shutterSpeed', val);
917
+ break;
918
+ case 'aperture':
919
+ val = 'f/' + val;
920
+ break;
921
+ default:
922
+ // making jslint happy
923
+ break;
924
+ }
925
+
926
+ $ul.append( '<li><h5>' + jetpackCarouselStrings[key] + '</h5>' + val + '</li>' );
927
+ });
928
+
929
+
930
+ $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' )
931
+ .append( $ul );
932
+ },
933
+
934
+ getFullSizeLink: function(current) {
935
+ if(!current || !current.data)
936
+ return false;
937
+ var original = current.data('src').replace(/\?.+$/, ''),
938
+ origSize = current.data('orig-size').split(','),
939
+ permalink = $( '<a>'+gallery.jp_carousel('format', {'text': jetpackCarouselStrings.download_original, 'replacements': origSize})+'</a>' )
940
+ .addClass( 'jp-carousel-image-download' )
941
+ .attr( 'href', original )
942
+ .attr( 'target', '_blank' );
943
+
944
+ $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' )
945
+ .append( permalink );
946
+ },
947
+
948
+ getMap: function( meta ) {
949
+ if ( !meta.latitude || !meta.longitude || 1 != jetpackCarouselStrings.display_geo )
950
+ return;
951
+
952
+ var latitude = meta.latitude,
953
+ longitude = meta.longitude,
954
+ $metabox = $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' ),
955
+ $mapbox = $( '<div></div>' ),
956
+ style = '&scale=2&style=feature:all|element:all|invert_lightness:true|hue:0x0077FF|saturation:-50|lightness:-5|gamma:0.91';
957
+
958
+ $mapbox
959
+ .addClass( 'jp-carousel-image-map' )
960
+ .html( '<img width="154" height="154" src="https://maps.googleapis.com/maps/api/staticmap?\
961
+ center=' + latitude + ',' + longitude + '&\
962
+ zoom=8&\
963
+ size=154x154&\
964
+ sensor=false&\
965
+ markers=size:medium%7Ccolor:blue%7C' + latitude + ',' + longitude + style +'" class="gmap-main" />\
966
+ \
967
+ <div class="gmap-topright"><div class="imgclip"><img width="175" height="154" src="https://maps.googleapis.com/maps/api/staticmap?\
968
+ center=' + latitude + ',' + longitude + '&\
969
+ zoom=3&\
970
+ size=175x154&\
971
+ sensor=false&\
972
+ markers=size:small%7Ccolor:blue%7C' + latitude + ',' + longitude + style + '"c /></div></div>\
973
+ \
974
+ ' )
975
+ .prependTo( $metabox );
976
+ },
977
+
978
+ testCommentsOpened: function( opened ) {
979
+ if ( 1 == parseInt( opened, 10 ) ) {
980
+ commentForm.fadeIn('fast');
981
+ } else {
982
+ commentForm.fadeOut('fast');
983
+ }
984
+ },
985
+
986
+ getComments: function( args ) {
987
+ if ( 'object' != typeof args )
988
+ args = {};
989
+
990
+ if ( ! args.attachment_id || 'undefined' == typeof args.attachment_id )
991
+ return;
992
+
993
+ if ( ! args.offset || 'undefined' == typeof args.offset || args.offset < 1 )
994
+ args.offset = 0;
995
+
996
+ var comments = $('.jp-carousel-comments'),
997
+ commentsLoading = $('#jp-carousel-comments-loading');
998
+
999
+ commentsLoading.show();
1000
+
1001
+ if ( args.clear ) {
1002
+ comments.hide();
1003
+ comments.empty();
1004
+ }
1005
+
1006
+ $.ajax({
1007
+ type: 'GET',
1008
+ url: jetpackCarouselStrings.ajaxurl,
1009
+ dataType: 'json',
1010
+ data: {
1011
+ action: 'get_attachment_comments',
1012
+ nonce: jetpackCarouselStrings.nonce,
1013
+ id: args.attachment_id,
1014
+ offset: args.offset
1015
+ },
1016
+ success: function(data, status, xhr) {
1017
+ if ( args.clear ) {
1018
+ comments.fadeOut('fast');
1019
+ comments.empty();
1020
+ }
1021
+
1022
+ $( data ).each(function(){
1023
+ var comment = $('<div></div>')
1024
+ .addClass('jp-carousel-comment')
1025
+ .attr('id', 'jp-carousel-comment-' + this['id'])
1026
+ .css({})
1027
+ .html(
1028
+ '<div class="comment-gravatar">'
1029
+ + this['gravatar_markup']
1030
+ + '</div>'
1031
+ + '<div class="comment-author">'
1032
+ + this['author_markup']
1033
+ + '</div>'
1034
+ + '<div class="comment-date">'
1035
+ + this['date_gmt']
1036
+ + '</div>'
1037
+ + '<div class="comment-content">'
1038
+ + this['content']
1039
+ + '</div>'
1040
+ );
1041
+ comments.append(comment);
1042
+
1043
+ // Set the interval to check for a new page of comments.
1044
+ clearInterval( commentInterval );
1045
+ commentInterval = setInterval( function() {
1046
+ if ( ( $('.jp-carousel-overlay').height() - 150 ) < $('.jp-carousel-wrap').scrollTop() + $(window).height() ) {
1047
+ gallery.jp_carousel('getComments',{ attachment_id: args.attachment_id, offset: args.offset + 10, clear: false });
1048
+ clearInterval( commentInterval );
1049
+ }
1050
+ }, 150 );
1051
+ });
1052
+
1053
+ // Verify (late) that the user didn't repeatldy click the arrows really fast, in which case the requested
1054
+ // attachment id might no longer match the current attachment id by the time we get the data back or a now
1055
+ // registered infiniscroll event kicks in, so we don't ever display comments for the wrong image by mistake.
1056
+ var current = $('.jp-carousel div.selected');
1057
+ if ( current && current.data && current.data('attachment-id') != args.attachment_id ) {
1058
+ comments.fadeOut('fast');
1059
+ comments.empty();
1060
+ return;
1061
+ }
1062
+
1063
+ // Increase the height of the background, semi-transparent overlay to match the new length of the comments list.
1064
+ $('.jp-carousel-overlay').height( $(window).height() + titleAndDescription.height() + commentForm.height() + ( (comments.height() > 0) ? comments.height() : imageMeta.height() ) + 200 );
1065
+
1066
+ comments.show();
1067
+ commentsLoading.hide();
1068
+ },
1069
+ error: function(xhr, status, error) {
1070
+ // TODO: proper error handling
1071
+ console.log( 'Comment get fail...', xhr, status, error );
1072
+ comments.fadeIn('fast');
1073
+ commentsLoading.fadeOut('fast');
1074
+ }
1075
+ });
1076
+ },
1077
+
1078
+ postCommentError: function(args) {
1079
+ if ( 'object' != typeof args )
1080
+ args = {};
1081
+ if ( ! args.field || 'undefined' == typeof args.field || ! args.error || 'undefined' == typeof args.error )
1082
+ return;
1083
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-error">'+args.error+'</span>').slideDown('fast');
1084
+ $('#jp-carousel-comment-form-spinner').spin(false);
1085
+ },
1086
+
1087
+ setCommentIframeSrc: function(attachment_id) {
1088
+ var iframe = $('#jp-carousel-comment-iframe');
1089
+ // Set the proper irame src for the current attachment id
1090
+ if (iframe && iframe.length) {
1091
+ iframe.attr('src', iframe.attr('src').replace(/(postid=)\d+/, '$1'+attachment_id) );
1092
+ iframe.attr('src', iframe.attr('src').replace(/(%23.+)?$/, '%23jp-carousel-'+attachment_id) );
1093
+ }
1094
+ },
1095
+
1096
+ clearCommentTextAreaValue: function() {
1097
+ var commentTextArea = $('#jp-carousel-comment-form-comment-field');
1098
+ if ( commentTextArea )
1099
+ commentTextArea.val('');
1100
+ }
1101
+ };
1102
+
1103
+ $.fn.jp_carousel = function(method){
1104
+ // ask for the HTML of the gallery
1105
+ // Method calling logic
1106
+ if ( methods[method] ) {
1107
+ return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
1108
+ } else if ( typeof method === 'object' || ! method ) {
1109
+ return methods.open.apply( this, arguments );
1110
+ } else {
1111
+ $.error( 'Method ' + method + ' does not exist on jQuery.jp_carousel' );
1112
+ }
1113
+
1114
+ };
1115
+
1116
+ // register the event listener for staring the gallery
1117
+ $( document.body ).on( 'click', 'div.gallery', function(e) {
1118
+ e.preventDefault();
1119
+ $(this).jp_carousel('open', {start_index: $(this).find('.gallery-item').index($(e.target).parents('.gallery-item'))});
1120
+ });
1121
+
1122
+ // start on page load if hash exists
1123
+ if ( document.location.hash && document.location.hash.match(/jp-carousel-(\d+)/) ) {
1124
+ $(document).ready(function(){
1125
+ var gallery = $('div.gallery'), index = -1, n = document.location.hash.match(/jp-carousel-(\d+)/);
1126
+
1127
+ n = parseInt(n[1], 10);
1128
+
1129
+ gallery.find('img').each(function(num, el){
1130
+ if ( n && $(el).data('attachment-id') == n ) { // n cannot be 0 (zero)
1131
+ index = num;
1132
+ return false;
1133
+ }
1134
+ });
1135
+
1136
+ if ( index != -1 )
1137
+ gallery.jp_carousel('open', {start_index: index});
1138
+ });
1139
+ }
1140
+ });
jetpack-carousel.php ADDED
@@ -0,0 +1,464 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: Gallery Carousel Without JetPack
4
+ Plugin URI: http://www.wpbeginner.com/
5
+ Description: Transform your standard galleries into an immersive full-screen experience without requiring you to connect to WordPress.com
6
+ Version: 0.1
7
+ Author: Syed Balkhi
8
+ Author URI: http://www.wpbeginner.com
9
+ License: GPLv2 or later
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
+
12
+
13
+ Note: This is a fork of Carousel Module from JetPack. I just wanted the Carousel to work
14
+ without logging into WordPress.com because I shouldn't be forced to (that's evil). So I'm releasing
15
+ this little plugin which is exactly the copy of JetPack module. I will update this plugin everytime that JetPack updates.
16
+
17
+ */
18
+ class No_Jetpack_Carousel {
19
+
20
+ var $prebuilt_widths = array( 370, 700, 1000, 1200, 1400, 2000 );
21
+
22
+ var $first_run = true;
23
+
24
+ var $in_jetpack = true;
25
+
26
+ function __construct() {
27
+ add_action( 'init', array( $this, 'init' ) );
28
+ }
29
+
30
+ function init() {
31
+ if ( $this->maybe_disable_jp_carousel() )
32
+ return;
33
+
34
+ $this->in_jetpack = ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'enable_module_configurable' ) ) ? true : false;
35
+
36
+ if ( is_admin() ) {
37
+ // Register the Carousel-related related settings
38
+ add_action( 'admin_init', array( $this, 'register_settings' ), 5 );
39
+ if ( ! $this->in_jetpack ) {
40
+ if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
41
+ return; // Carousel disabled, abort early, but still register setting so user can switch it back on
42
+ }
43
+ // If in admin, register the ajax endpoints.
44
+ add_action( 'wp_ajax_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
45
+ add_action( 'wp_ajax_nopriv_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
46
+ add_action( 'wp_ajax_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
47
+ add_action( 'wp_ajax_nopriv_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
48
+ } else {
49
+ if ( ! $this->in_jetpack ) {
50
+ if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
51
+ return; // Carousel disabled, abort early
52
+ }
53
+ // If on front-end, do the Carousel thang.
54
+ $this->prebuilt_widths = apply_filters( 'jp_carousel_widths', $this->prebuilt_widths );
55
+ add_filter( 'post_gallery', array( $this, 'enqueue_assets' ), 1000, 2 ); // load later than other callbacks hooked it
56
+ add_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
57
+ add_filter( 'wp_get_attachment_link', array( $this, 'add_data_to_images' ), 10, 2 );
58
+ }
59
+
60
+ if ( $this->in_jetpack && method_exists( 'Jetpack', 'module_configuration_load' ) ) {
61
+ Jetpack::enable_module_configurable( dirname( dirname( __FILE__ ) ) . '/carousel.php' );
62
+ Jetpack::module_configuration_load( dirname( dirname( __FILE__ ) ) . '/carousel.php', array( $this, 'jetpack_configuration_load' ) );
63
+ }
64
+ }
65
+
66
+ function maybe_disable_jp_carousel() {
67
+ return apply_filters( 'jp_carousel_maybe_disable', false );
68
+ }
69
+
70
+ function jetpack_configuration_load() {
71
+ wp_safe_redirect( admin_url( 'options-media.php#carousel_background_color' ) );
72
+ exit;
73
+ }
74
+
75
+ function asset_version( $version ) {
76
+ return apply_filters( 'jp_carousel_asset_version', $version );
77
+ }
78
+
79
+ function enqueue_assets( $output ) {
80
+ global $wp_query;
81
+ $postid = $wp_query->post->ID;
82
+ if (is_single() && get_post_meta($postid, 'wpb_gallery', true)) {
83
+
84
+ if ( ! empty( $output ) ) {
85
+ // Bail because someone is overriding the [gallery] shortcode.
86
+ remove_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
87
+ remove_filter( 'wp_get_attachment_link', array( $this, 'add_data_to_images' ) );
88
+ return $output;
89
+ }
90
+
91
+ do_action( 'jp_carousel_thumbnails_shown' );
92
+
93
+ if ( $this->first_run ) {
94
+ if ( ! has_action( 'wp_enqueue_scripts', 'register_spin_scripts' ) ) {
95
+ wp_enqueue_script( 'spin', plugins_url( 'spin.js', __FILE__ ), false, '1.2.4' );
96
+ wp_enqueue_script( 'jquery.spin', plugins_url( 'jquery.spin.js', __FILE__ ) , array( 'jquery', 'spin' ) );
97
+ }
98
+
99
+ wp_enqueue_script( 'jetpack-carousel', plugins_url( 'jetpack-carousel.js', __FILE__ ), array( 'jquery' ), $this->asset_version( '20120629' ), true );
100
+
101
+ // Note: using home_url() instead of admin_url() for ajaxurl to be sure to get same domain on wpcom when using mapped domains (also works on self-hosted)
102
+ // Also: not hardcoding path since there is no guarantee site is running on site root in self-hosted context.
103
+ $is_logged_in = is_user_logged_in();
104
+ $current_user = wp_get_current_user();
105
+ $localize_strings = array(
106
+ 'widths' => $this->prebuilt_widths,
107
+ 'is_logged_in' => $is_logged_in,
108
+ 'ajaxurl' => admin_url( 'admin-ajax.php', is_ssl() ? 'https' : 'http' ),
109
+ 'nonce' => wp_create_nonce( 'carousel_nonce' ),
110
+ 'display_exif' => $this->test_1or0_option( get_option( 'carousel_display_exif' ), true ),
111
+ 'display_geo' => $this->test_1or0_option( get_option( 'carousel_display_geo' ), true ),
112
+ 'background_color' => $this->carousel_background_color_sanitize( get_option( 'carousel_background_color' ) ),
113
+ 'post_comment' => __( 'Post Comment', 'jetpack' ),
114
+ 'loading_comments' => __( 'Loading Comments...', 'jetpack' ),
115
+ 'download_original' => __( 'View full size <span class="photo-size">{0}<span class="photo-size-times">&times;</span>{1}</span>', 'jetpack' ),
116
+ 'no_comment_text' => __( 'Please be sure to submit some text with your comment.', 'jetpack' ),
117
+ 'no_comment_email' => __( 'Please provide an email address to comment.', 'jetpack' ),
118
+ 'no_comment_author' => __( 'Please provide your name to comment.', 'jetpack' ),
119
+ 'comment_post_error' => __( 'Sorry, but there was an error posting your comment. Please try again later.', 'jetpack' ),
120
+ 'comment_approved' => __( 'Your comment was approved.', 'jetpack' ),
121
+ 'comment_unapproved' => __( 'Your comment is in moderation.', 'jetpack' ),
122
+ 'camera' => __( 'Camera', 'jetpack' ),
123
+ 'aperture' => __( 'Aperture', 'jetpack' ),
124
+ 'shutter_speed' => __( 'Shutter Speed', 'jetpack' ),
125
+ 'focal_length' => __( 'Focal Length', 'jetpack' ),
126
+ );
127
+
128
+ if ( ! isset( $localize_strings['jetpack_comments_iframe_src'] ) || empty( $localize_strings['jetpack_comments_iframe_src'] ) ) {
129
+ // We're not using Jetpack comments after all, so fallback to standard local comments.
130
+
131
+ if ( $is_logged_in ) {
132
+ $localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . sprintf( __( 'Commenting as %s', 'jetpack' ), $current_user->data->display_name ) . '</p>';
133
+ } else {
134
+ $localize_strings['local_comments_commenting_as'] = ''
135
+ . '<fieldset><label for="email">' . __( 'Email (Required)', 'jetpack' ) . '</label> '
136
+ . '<input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field" /></fieldset>'
137
+ . '<fieldset><label for="author">' . __( 'Name (Required)', 'jetpack' ) . '</label> '
138
+ . '<input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field" /></fieldset>'
139
+ . '<fieldset><label for="url">' . __( 'Website', 'jetpack' ) . '</label> '
140
+ . '<input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field" /></fieldset>';
141
+ }
142
+ }
143
+
144
+ $localize_strings = apply_filters( 'jp_carousel_localize_strings', $localize_strings );
145
+ wp_localize_script( 'jetpack-carousel', 'jetpackCarouselStrings', $localize_strings );
146
+ wp_enqueue_style( 'jetpack-carousel', plugins_url( 'jetpack-carousel.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
147
+
148
+ do_action( 'jp_carousel_enqueue_assets', $this->first_run, $localize_strings );
149
+
150
+ $this->first_run = false;
151
+ }
152
+
153
+ return $output;
154
+
155
+ }
156
+ wp_reset_query();
157
+ }
158
+
159
+ function add_data_to_images( $html, $attachment_id ) {
160
+ if ( $this->first_run ) // not in a gallery
161
+ return $html;
162
+
163
+ $attachment_id = intval( $attachment_id );
164
+ $orig_file = wp_get_attachment_url( $attachment_id );
165
+ $meta = wp_get_attachment_metadata( $attachment_id );
166
+ $size = isset( $meta['width'] ) ? intval( $meta['width'] ) . ',' . intval( $meta['height'] ) : '';
167
+ $img_meta = $meta['image_meta'];
168
+ $comments_opened = intval( comments_open( $attachment_id ) );
169
+
170
+ /*
171
+ * Note: Cannot generate a filename from the width and height wp_get_attachment_image_src() returns because
172
+ * it takes the $content_width global variable themes can set in consideration, therefore returning sizes
173
+ * which when used to generate a filename will likely result in a 404 on the image.
174
+ * $content_width has no filter we could temporarily de-register, run wp_get_attachment_image_src(), then
175
+ * re-register. So using returned file URL instead, which we can define the sizes from through filename
176
+ * parsing in the JS, as this is a failsafe file reference.
177
+ *
178
+ * EG with Twenty Eleven activated:
179
+ * array(4) { [0]=> string(82) "http://vanillawpinstall.blah/wp-content/uploads/2012/06/IMG_3534-1024x764.jpg" [1]=> int(584) [2]=> int(435) [3]=> bool(true) }
180
+ *
181
+ * EG with Twenty Ten activated:
182
+ * array(4) { [0]=> string(82) "http://vanillawpinstall.blah/wp-content/uploads/2012/06/IMG_3534-1024x764.jpg" [1]=> int(640) [2]=> int(477) [3]=> bool(true) }
183
+ */
184
+
185
+ $medium_file_info = wp_get_attachment_image_src( $attachment_id, 'medium' );
186
+ $medium_file = isset( $medium_file_info[0] ) ? $medium_file_info[0] : '';
187
+
188
+ $large_file_info = wp_get_attachment_image_src( $attachment_id, 'large' );
189
+ $large_file = isset( $large_file_info[0] ) ? $large_file_info[0] : '';
190
+
191
+ $attachment = get_post( $attachment_id );
192
+ $attachment_desc = wpautop( wptexturize( $attachment->post_content ) );
193
+
194
+ // Not yet providing geo-data, need to "fuzzify" for privacy
195
+ if ( ! empty( $img_meta ) ) {
196
+ foreach ( $img_meta as $k => $v ) {
197
+ if ( 'latitude' == $k || 'longitude' == $k )
198
+ unset( $img_meta[$k] );
199
+ }
200
+ }
201
+
202
+ $img_meta = json_encode( $img_meta );
203
+
204
+ $html = str_replace(
205
+ '<img ',
206
+ sprintf(
207
+ '<img data-attachment-id="%1$d" data-orig-file="%2$s" data-orig-size="%3$s" data-comments-opened="%4$s" data-image-meta="%5$s" data-image-description="%6$s" data-medium-file="%7$s" data-large-file="%8$s" ',
208
+ $attachment_id,
209
+ esc_attr( $orig_file ),
210
+ $size,
211
+ $comments_opened,
212
+ esc_attr( $img_meta ),
213
+ esc_attr( $attachment_desc ),
214
+ esc_attr( $medium_file ),
215
+ esc_attr( $large_file )
216
+ ),
217
+ $html
218
+ );
219
+
220
+ $html = apply_filters( 'jp_carousel_add_data_to_images', $html, $attachment_id );
221
+
222
+ return $html;
223
+ }
224
+
225
+ function add_data_to_container( $html ) {
226
+ global $post;
227
+
228
+ if ( isset( $post ) ) {
229
+ $blog_id = (int) get_current_blog_id();
230
+ $extra_data = array( 'data-carousel-extra' => array( 'blog_id' => $blog_id, 'permalink' => get_permalink( $post->ID ) ) );
231
+
232
+ $extra_data = apply_filters( 'jp_carousel_add_data_to_container', $extra_data );
233
+ foreach ( (array) $extra_data as $data_key => $data_values ) {
234
+ $html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . json_encode( $data_values ) . "' ", $html );
235
+ }
236
+ }
237
+
238
+ return $html;
239
+ }
240
+
241
+ function get_attachment_comments() {
242
+ if ( ! headers_sent() )
243
+ header('Content-type: text/javascript');
244
+
245
+ do_action('jp_carousel_check_blog_user_privileges');
246
+
247
+ $attachment_id = ( isset( $_REQUEST['id'] ) ) ? (int) $_REQUEST['id'] : 0;
248
+ $offset = ( isset( $_REQUEST['offset'] ) ) ? (int) $_REQUEST['offset'] : 0;
249
+
250
+ if ( ! $attachment_id ) {
251
+ echo json_encode( __( 'Missing attachment ID.', 'jetpack' ) );
252
+ die();
253
+ }
254
+
255
+ if ( $offset < 1 )
256
+ $offset = 0;
257
+
258
+ $comments = get_comments( array(
259
+ 'status' => 'approve',
260
+ 'order' => ( 'asc' == get_option('comment_order') ) ? 'ASC' : 'DESC',
261
+ 'number' => 10,
262
+ 'offset' => $offset,
263
+ 'post_id' => $attachment_id,
264
+ ) );
265
+
266
+ $out = array();
267
+
268
+ // Can't just send the results, they contain the commenter's email address.
269
+ foreach ( $comments as $comment ) {
270
+ $author_markup = '<a href="' . esc_url( $comment->comment_author_url ) . '">' . esc_html( $comment->comment_author ) . '</a>';
271
+ $out[] = array(
272
+ 'id' => $comment->comment_ID,
273
+ 'parent_id' => $comment->comment_parent,
274
+ 'author_markup' => $author_markup,
275
+ 'gravatar_markup' => get_avatar( $comment->comment_author_email, 64 ),
276
+ 'date_gmt' => $comment->comment_date_gmt,
277
+ 'content' => wpautop($comment->comment_content),
278
+ );
279
+ }
280
+
281
+ die( json_encode( $out ) );
282
+ }
283
+
284
+ function post_attachment_comment() {
285
+ if ( ! headers_sent() )
286
+ header('Content-type: text/javascript');
287
+
288
+ if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce($_POST['nonce'], 'carousel_nonce') )
289
+ die( json_encode( array( 'error' => __( 'Nonce verification failed.', 'jetpack' ) ) ) );
290
+
291
+ $_blog_id = (int) $_POST['blog_id'];
292
+ $_post_id = (int) $_POST['id'];
293
+ $comment = $_POST['comment'];
294
+
295
+ if ( empty( $_blog_id ) )
296
+ die( json_encode( array( 'error' => __( 'Missing target blog ID.', 'jetpack' ) ) ) );
297
+
298
+ if ( empty( $_post_id ) )
299
+ die( json_encode( array( 'error' => __( 'Missing target post ID.', 'jetpack' ) ) ) );
300
+
301
+ if ( empty( $comment ) )
302
+ die( json_encode( array( 'error' => __( 'No comment text was submitted.', 'jetpack' ) ) ) );
303
+
304
+ // Used in context like NewDash
305
+ $switched = false;
306
+ if ( $_blog_id != get_current_blog_id() ) {
307
+ switch_to_blog( $_blog_id );
308
+ $switched = true;
309
+ }
310
+
311
+ do_action('jp_carousel_check_blog_user_privileges');
312
+
313
+ if ( ! comments_open( $_post_id ) )
314
+ die( json_encode( array( 'error' => __( 'Comments on this post are closed.', 'jetpack' ) ) ) );
315
+
316
+ if ( is_user_logged_in() ) {
317
+ $user = wp_get_current_user();
318
+ $user_id = $user->ID;
319
+ $display_name = $user->display_name;
320
+ $email = $user->user_email;
321
+ $url = $user->user_url;
322
+
323
+ if ( empty( $user_id ) )
324
+ die( json_encode( array( 'error' => __( 'Sorry, but we could not authenticate your request.', 'jetpack' ) ) ) );
325
+ } else {
326
+ $user_id = 0;
327
+ $display_name = $_POST['author'];
328
+ $email = $_POST['email'];
329
+ $url = $_POST['url'];
330
+
331
+ if ( empty( $display_name ) )
332
+ die( json_encode( array( 'error' => __( 'Please provide your name.', 'jetpack' ) ) ) );
333
+
334
+ if ( empty( $email ) )
335
+ die( json_encode( array( 'error' => __( 'Please provide an email address.', 'jetpack' ) ) ) );
336
+
337
+ if ( ! is_email( $email ) )
338
+ die( json_encode( array( 'error' => __( 'Please provide a valid email address.', 'jetpack' ) ) ) );
339
+ }
340
+
341
+ $comment_data = array(
342
+ 'comment_content' => $comment,
343
+ 'comment_post_ID' => $_post_id,
344
+ 'comment_author' => $display_name,
345
+ 'comment_author_email' => $email,
346
+ 'comment_author_url' => $url,
347
+ 'comment_approved' => 0,
348
+ );
349
+
350
+ if ( ! empty( $user_id ) )
351
+ $comment_data['user_id'] = $user_id;
352
+
353
+ // Note: wp_new_comment() sanitizes and validates the values (too).
354
+ $comment_id = wp_new_comment( $comment_data );
355
+ do_action( 'jp_carousel_post_attachment_comment' );
356
+ $comment_status = wp_get_comment_status( $comment_id );
357
+
358
+ if ( true == $switched )
359
+ restore_current_blog();
360
+
361
+ die( json_encode( array( 'comment_id' => $comment_id, 'comment_status' => $comment_status ) ) );
362
+ }
363
+
364
+ function register_settings() {
365
+ add_settings_section('carousel_section', __( 'Image Gallery Carousel', 'jetpack' ), array( $this, 'carousel_section_callback' ), 'media');
366
+
367
+ if ( ! $this->in_jetpack ) {
368
+ add_settings_field('carousel_enable_it', __( 'Enable carousel', 'jetpack' ), array( $this, 'carousel_enable_it_callback' ), 'media', 'carousel_section' );
369
+ register_setting( 'media', 'carousel_enable_it', array( $this, 'carousel_enable_it_sanitize' ) );
370
+ }
371
+
372
+ add_settings_field('carousel_background_color', __( 'Background color', 'jetpack' ), array( $this, 'carousel_background_color_callback' ), 'media', 'carousel_section' );
373
+ register_setting( 'media', 'carousel_background_color', array( $this, 'carousel_background_color_sanitize' ) );
374
+
375
+ add_settings_field('carousel_display_exif', __( 'Metadata', 'jetpack'), array( $this, 'carousel_display_exif_callback' ), 'media', 'carousel_section' );
376
+ register_setting( 'media', 'carousel_display_exif', array( $this, 'carousel_display_exif_sanitize' ) );
377
+
378
+ // No geo setting yet, need to "fuzzify" data first, for privacy
379
+ // add_settings_field('carousel_display_geo', __( 'Geolocation', 'jetpack' ), array( $this, 'carousel_display_geo_callback' ), 'media', 'carousel_section' );
380
+ // register_setting( 'media', 'carousel_display_geo', array( $this, 'carousel_display_geo_sanitize' ) );
381
+ }
382
+
383
+ // Fulfill the settings section callback requirement by returning nothing
384
+ function carousel_section_callback() {
385
+ return;
386
+ }
387
+
388
+ function test_1or0_option( $value, $default_to_1 = true ) {
389
+ if ( true == $default_to_1 ) {
390
+ // Binary false (===) of $value means it has not yet been set, in which case we do want to default sites to 1
391
+ if ( false === $value )
392
+ $value = 1;
393
+ }
394
+ return ( 1 == $value ) ? 1 : 0;
395
+ }
396
+
397
+ function sanitize_1or0_option( $value ) {
398
+ return ( 1 == $value ) ? 1 : 0;
399
+ }
400
+
401
+ function settings_checkbox($name, $label_text, $extra_text = '', $default_to_checked = true) {
402
+ if ( empty( $name ) )
403
+ return;
404
+ $option = $this->test_1or0_option( get_option( $name ), $default_to_checked );
405
+ echo '<fieldset>';
406
+ echo '<input type="checkbox" name="'.esc_attr($name).'" id="'.esc_attr($name).'" value="1" ';
407
+ checked( '1', $option );
408
+ echo '/> <label for="'.esc_attr($name).'">'.$label_text.'</label>';
409
+ if ( ! empty( $extra_text ) )
410
+ echo '<p class="description">'.$extra_text.'</p>';
411
+ echo '</fieldset>';
412
+ }
413
+
414
+ function settings_select($name, $values, $extra_text = '') {
415
+ if ( empty( $name ) || ! is_array( $values ) || empty( $values ) )
416
+ return;
417
+ $option = get_option( $name );
418
+ echo '<fieldset>';
419
+ echo '<select name="'.esc_attr($name).'" id="'.esc_attr($name).'">';
420
+ foreach( $values as $key => $value ) {
421
+ echo '<option value="'.esc_attr($key).'" ';
422
+ selected( $key, $option );
423
+ echo '>'.esc_html($value).'</option>';
424
+ }
425
+ echo '</select>';
426
+ if ( ! empty( $extra_text ) )
427
+ echo '<p class="description">'.$extra_text.'</p>';
428
+ echo '</fieldset>';
429
+ }
430
+
431
+ function carousel_display_exif_callback() {
432
+ $this->settings_checkbox( 'carousel_display_exif', __( 'Show photo metadata (<a href="http://en.wikipedia.org/wiki/Exchangeable_image_file_format" target="_blank">Exif</a>) in carousel, when available.', 'jetpack' ) );
433
+ }
434
+
435
+ function carousel_display_exif_sanitize( $value ) {
436
+ return $this->sanitize_1or0_option( $value );
437
+ }
438
+
439
+ function carousel_display_geo_callback() {
440
+ $this->settings_checkbox( 'carousel_display_geo', __( 'Show map of photo location in carousel, when available.', 'jetpack' ) );
441
+ }
442
+
443
+ function carousel_display_geo_sanitize( $value ) {
444
+ return $this->sanitize_1or0_option( $value );
445
+ }
446
+
447
+ function carousel_background_color_callback() {
448
+ $this->settings_select( 'carousel_background_color', array( 'black' => __( 'Black', 'jetpack' ), 'white' => __( 'White', 'jetpack', 'jetpack' ) ) );
449
+ }
450
+
451
+ function carousel_background_color_sanitize( $value ) {
452
+ return ( 'white' == $value ) ? 'white' : 'black';
453
+ }
454
+
455
+ function carousel_enable_it_callback() {
456
+ $this->settings_checkbox( 'carousel_enable_it', __( 'Display images in full-size carousel slideshow.', 'jetpack' ) );
457
+ }
458
+
459
+ function carousel_enable_it_sanitize( $value ) {
460
+ return $this->sanitize_1or0_option( $value );
461
+ }
462
+ }
463
+
464
+ new No_Jetpack_Carousel;
jquery.spin.js ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Matt Husby https://github.com/matthusby/spin.js
3
+ * Based on the jquery plugin by Bradley Smith
4
+ * https://gist.github.com/1290439
5
+ */
6
+
7
+ /*
8
+ Add spin to the jQuery object
9
+ If color is not passed the spinner will be black
10
+ You can now create a spinner using any of the variants below:
11
+ $("#el").spin(); // Produces default Spinner
12
+ $("#el").spin("small"); // Produces a 'small' Spinner
13
+ $("#el").spin("large", "white"); // Produces a 'large' Spinner in white (or any valid CSS color).
14
+ $("#el").spin({ ... }); // Produces a Spinner using your custom settings.
15
+ $("#el").spin("small-right"); // Pin the small spinner to the right edge
16
+ $("#el").spin("{small, medium, large}-{left, right, top, bottom}"); // All options for where to pin
17
+ $("#el").spin(false); // Kills the spinner.
18
+ */
19
+
20
+ ( function( $ ) {
21
+ $.fn.spin = function( opts, color ) {
22
+ var presets = {
23
+ "small": { lines: 8, length: 2, width: 2, radius: 3, trail: 60, speed: 1.3 },
24
+ "medium": { lines: 8, length: 4, width: 3, radius: 5, trail: 60, speed: 1.3 },
25
+ "large": { lines: 10, length: 6, width: 4, radius: 7, trail: 60, speed: 1.3 }
26
+ };
27
+ if ( Spinner ) {
28
+ return this.each( function() {
29
+ var $this = $( this ),
30
+ data = $this.data();
31
+
32
+ if ( data.spinner ) {
33
+ data.spinner.stop();
34
+ delete data.spinner;
35
+ }
36
+ if ( opts !== false ) {
37
+ var spinner_options;
38
+ if ( typeof opts === "string" ) {
39
+ var spinner_base = opts.indexOf( '-' );
40
+ if( spinner_base == -1 ) {
41
+ spinner_base = opts;
42
+ } else {
43
+ spinner_base = opts.substring( 0, spinner_base );
44
+ }
45
+ if ( spinner_base in presets ) {
46
+ spinner_options = presets[spinner_base];
47
+ } else {
48
+ spinner_options = {};
49
+ }
50
+ var padding;
51
+ if ( opts.indexOf( "-right" ) != -1 ) {
52
+ padding = jQuery( this ).css( 'padding-left' );
53
+ if( typeof padding === "undefined" ) {
54
+ padding = 0;
55
+ } else {
56
+ padding = padding.replace( 'px', '' );
57
+ }
58
+ spinner_options.left = jQuery( this ).outerWidth() - ( 2 * ( spinner_options.length + spinner_options.width + spinner_options.radius ) ) - padding - 5;
59
+ }
60
+ if ( opts.indexOf( '-left' ) != -1 ) {
61
+ spinner_options.left = 5;
62
+ }
63
+ if ( opts.indexOf( '-top' ) != -1 ) {
64
+ spinner_options.top = 5;
65
+ }
66
+ if ( opts.indexOf( '-bottom' ) != -1 ) {
67
+ padding = jQuery( this ).css( 'padding-top' );
68
+ if( typeof padding === "undefined" ) {
69
+ padding = 0;
70
+ } else {
71
+ padding = padding.replace( 'px', '' );
72
+ }
73
+ spinner_options.top = jQuery( this ).outerHeight() - ( 2 * ( spinner_options.length + spinner_options.width + spinner_options.radius ) ) - padding - 5;
74
+ }
75
+ }
76
+ if( color ){
77
+ spinner_options.color = color;
78
+ }
79
+ data.spinner = new Spinner( spinner_options ).spin( this );
80
+ }
81
+ });
82
+ } else {
83
+ throw "Spinner class not available.";
84
+ }
85
+ };
86
+ })( jQuery );
readme.txt ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Gallery Carousel Without JetPack ===
2
+ Contributors: smub
3
+ Donate link:http://www.wpbeginner.com/wpbeginner-needs-your-help/
4
+ Tags: gallery, lightbox, carousel, gallery carousel, jetpack
5
+ Requires at least: 3.4.1
6
+ Tested up to: 3.4.1
7
+ Stable tag: 0.1
8
+ License: GPLv2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ Transform your standard galleries into an immersive full-screen experience without requiring you to connect to WordPress.com
12
+
13
+ == Description ==
14
+
15
+ I love this Carousel feature that is part of JetPack however I didn't like that I was being forced to connect my site with WordPress.com to use a feature that has no connection with WordPress.com. Well, I simply forked the Carousel module from JetPack. I am releasing it for all those who want to use this feature with freedom of choice.
16
+
17
+ The carousel feature transform your standard galleries into an immersive full-screen experience with comments and EXIF metadata.
18
+
19
+
20
+ [Visit WPBeginner for tutorials or support](http://www.wpbeginner.com "Visit WPBeginner for any tutorials or support")
21
+
22
+ [Take a look at plugins I'm using at WPBeginner](http://www.wpbeginner.com/blueprint/ "Take a look at plugins I'm using at WPBeginner")
23
+
24
+ [Learn WordPress with free WPBeginner videos](http://videos.wpbeginner.com "Checkout out WPBeginner's WordPress tutorial videos")
25
+
26
+ Plugin Header Photo Credit: [Muffit](http://www.flickr.com/photos/calliope/3715986729/ "Carousel photo by Muffet's Flickr")
27
+
28
+
29
+ == Installation ==
30
+
31
+ Extract the zip file and just drop the contents in the wp-content/plugins/ directory of your WordPress installation and then activate the Plugin from Plugins page.
32
+
33
+ Go to Settings > Media for further options.
34
+
35
+ == Screenshots ==
36
+
37
+ 1. Gallery Carousel.
38
+
39
+
40
+ == Frequently Asked Questions ==
41
+
42
+ **How will you make sure to keep this upto date?**
43
+
44
+ Well this code is literally a copy of JetPack module. I will keep a close eye on every JetPack update. If they update this module, then I will be sure to update this plugin as well.�
45
+
46
+ == Changelog ==
47
+ 0.1 - Initial Release
screenshot-1.png ADDED
Binary file
spin.js ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //fgnass.github.com/spin.js#v1.2.4
2
+ (function(window, document, undefined) {
3
+
4
+ /**
5
+ * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
6
+ * Licensed under the MIT license
7
+ */
8
+
9
+ var prefixes = ['webkit', 'Moz', 'ms', 'O']; /* Vendor prefixes */
10
+ var animations = {}; /* Animation rules keyed by their name */
11
+ var useCssAnimations;
12
+
13
+ /**
14
+ * Utility function to create elements. If no tag name is given,
15
+ * a DIV is created. Optionally properties can be passed.
16
+ */
17
+ function createEl(tag, prop) {
18
+ var el = document.createElement(tag || 'div');
19
+ var n;
20
+
21
+ for(n in prop) {
22
+ el[n] = prop[n];
23
+ }
24
+ return el;
25
+ }
26
+
27
+ /**
28
+ * Appends children and returns the parent.
29
+ */
30
+ function ins(parent /* child1, child2, ...*/) {
31
+ for (var i=1, n=arguments.length; i<n; i++) {
32
+ parent.appendChild(arguments[i]);
33
+ }
34
+ return parent;
35
+ }
36
+
37
+ /**
38
+ * Insert a new stylesheet to hold the @keyframe or VML rules.
39
+ */
40
+ var sheet = function() {
41
+ var el = createEl('style');
42
+ ins(document.getElementsByTagName('head')[0], el);
43
+ return el.sheet || el.styleSheet;
44
+ }();
45
+
46
+ /**
47
+ * Creates an opacity keyframe animation rule and returns its name.
48
+ * Since most mobile Webkits have timing issues with animation-delay,
49
+ * we create separate rules for each line/segment.
50
+ */
51
+ function addAnimation(alpha, trail, i, lines) {
52
+ var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-');
53
+ var start = 0.01 + i/lines*100;
54
+ var z = Math.max(1-(1-alpha)/trail*(100-start) , alpha);
55
+ var prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase();
56
+ var pre = prefix && '-'+prefix+'-' || '';
57
+
58
+ if (!animations[name]) {
59
+ sheet.insertRule(
60
+ '@' + pre + 'keyframes ' + name + '{' +
61
+ '0%{opacity:'+z+'}' +
62
+ start + '%{opacity:'+ alpha + '}' +
63
+ (start+0.01) + '%{opacity:1}' +
64
+ (start+trail)%100 + '%{opacity:'+ alpha + '}' +
65
+ '100%{opacity:'+ z + '}' +
66
+ '}', 0);
67
+ animations[name] = 1;
68
+ }
69
+ return name;
70
+ }
71
+
72
+ /**
73
+ * Tries various vendor prefixes and returns the first supported property.
74
+ **/
75
+ function vendor(el, prop) {
76
+ var s = el.style;
77
+ var pp;
78
+ var i;
79
+
80
+ if(s[prop] !== undefined) return prop;
81
+ prop = prop.charAt(0).toUpperCase() + prop.slice(1);
82
+ for(i=0; i<prefixes.length; i++) {
83
+ pp = prefixes[i]+prop;
84
+ if(s[pp] !== undefined) return pp;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Sets multiple style properties at once.
90
+ */
91
+ function css(el, prop) {
92
+ for (var n in prop) {
93
+ el.style[vendor(el, n)||n] = prop[n];
94
+ }
95
+ return el;
96
+ }
97
+
98
+ /**
99
+ * Fills in default values.
100
+ */
101
+ function merge(obj) {
102
+ for (var i=1; i < arguments.length; i++) {
103
+ var def = arguments[i];
104
+ for (var n in def) {
105
+ if (obj[n] === undefined) obj[n] = def[n];
106
+ }
107
+ }
108
+ return obj;
109
+ }
110
+
111
+ /**
112
+ * Returns the absolute page-offset of the given element.
113
+ */
114
+ function pos(el) {
115
+ var o = {x:el.offsetLeft, y:el.offsetTop};
116
+ while((el = el.offsetParent)) {
117
+ o.x+=el.offsetLeft;
118
+ o.y+=el.offsetTop;
119
+ }
120
+ return o;
121
+ }
122
+
123
+ var defaults = {
124
+ lines: 12, // The number of lines to draw
125
+ length: 7, // The length of each line
126
+ width: 5, // The line thickness
127
+ radius: 10, // The radius of the inner circle
128
+ color: '#000', // #rgb or #rrggbb
129
+ speed: 1, // Rounds per second
130
+ trail: 100, // Afterglow percentage
131
+ opacity: 1/4, // Opacity of the lines
132
+ fps: 20, // Frames per second when using setTimeout()
133
+ zIndex: 2e9, // Use a high z-index by default
134
+ className: 'spinner', // CSS class to assign to the element
135
+ top: 'auto', // center vertically
136
+ left: 'auto' // center horizontally
137
+ };
138
+
139
+ /** The constructor */
140
+ var Spinner = function Spinner(o) {
141
+ if (!this.spin) return new Spinner(o);
142
+ this.opts = merge(o || {}, Spinner.defaults, defaults);
143
+ };
144
+
145
+ Spinner.defaults = {};
146
+ Spinner.prototype = {
147
+ spin: function(target) {
148
+ this.stop();
149
+ var self = this;
150
+ var o = self.opts;
151
+ var el = self.el = css(createEl(0, {className: o.className}), {position: 'relative', zIndex: o.zIndex});
152
+ var mid = o.radius+o.length+o.width;
153
+ var ep; // element position
154
+ var tp; // target position
155
+
156
+ if (target) {
157
+ target.insertBefore(el, target.firstChild||null);
158
+ tp = pos(target);
159
+ ep = pos(el);
160
+ css(el, {
161
+ left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : o.left+mid) + 'px',
162
+ top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : o.top+mid) + 'px'
163
+ });
164
+ }
165
+
166
+ el.setAttribute('aria-role', 'progressbar');
167
+ self.lines(el, self.opts);
168
+
169
+ if (!useCssAnimations) {
170
+ // No CSS animation support, use setTimeout() instead
171
+ var i = 0;
172
+ var fps = o.fps;
173
+ var f = fps/o.speed;
174
+ var ostep = (1-o.opacity)/(f*o.trail / 100);
175
+ var astep = f/o.lines;
176
+
177
+ !function anim() {
178
+ i++;
179
+ for (var s=o.lines; s; s--) {
180
+ var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
181
+ self.opacity(el, o.lines-s, alpha, o);
182
+ }
183
+ self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
184
+ }();
185
+ }
186
+ return self;
187
+ },
188
+ stop: function() {
189
+ var el = this.el;
190
+ if (el) {
191
+ clearTimeout(this.timeout);
192
+ if (el.parentNode) el.parentNode.removeChild(el);
193
+ this.el = undefined;
194
+ }
195
+ return this;
196
+ },
197
+ lines: function(el, o) {
198
+ var i = 0;
199
+ var seg;
200
+
201
+ function fill(color, shadow) {
202
+ return css(createEl(), {
203
+ position: 'absolute',
204
+ width: (o.length+o.width) + 'px',
205
+ height: o.width + 'px',
206
+ background: color,
207
+ boxShadow: shadow,
208
+ transformOrigin: 'left',
209
+ transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
210
+ borderRadius: (o.width>>1) + 'px'
211
+ });
212
+ }
213
+ for (; i < o.lines; i++) {
214
+ seg = css(createEl(), {
215
+ position: 'absolute',
216
+ top: 1+~(o.width/2) + 'px',
217
+ transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
218
+ opacity: o.opacity,
219
+ animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
220
+ });
221
+ if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
222
+ ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
223
+ }
224
+ return el;
225
+ },
226
+ opacity: function(el, i, val) {
227
+ if (i < el.childNodes.length) el.childNodes[i].style.opacity = val;
228
+ }
229
+ };
230
+
231
+ /////////////////////////////////////////////////////////////////////////
232
+ // VML rendering for IE
233
+ /////////////////////////////////////////////////////////////////////////
234
+
235
+ /**
236
+ * Check and init VML support
237
+ */
238
+ !function() {
239
+ var s = css(createEl('group'), {behavior: 'url(#default#VML)'});
240
+ var i;
241
+
242
+ if (!vendor(s, 'transform') && s.adj) {
243
+
244
+ // VML support detected. Insert CSS rules ...
245
+ for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');
246
+
247
+ Spinner.prototype.lines = function(el, o) {
248
+ var r = o.length+o.width;
249
+ var s = 2*r;
250
+
251
+ function grp() {
252
+ return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
253
+ }
254
+
255
+ var margin = -(o.width+o.length)*2+'px';
256
+ var g = css(grp(), {position: 'absolute', top: margin, left: margin});
257
+
258
+ var i;
259
+
260
+ function seg(i, dx, filter) {
261
+ ins(g,
262
+ ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
263
+ ins(css(createEl('roundrect', {arcsize: 1}), {
264
+ width: r,
265
+ height: o.width,
266
+ left: o.radius,
267
+ top: -o.width>>1,
268
+ filter: filter
269
+ }),
270
+ createEl('fill', {color: o.color, opacity: o.opacity}),
271
+ createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
272
+ )
273
+ )
274
+ );
275
+ }
276
+
277
+ if (o.shadow) {
278
+ for (i = 1; i <= o.lines; i++) {
279
+ seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
280
+ }
281
+ }
282
+ for (i = 1; i <= o.lines; i++) seg(i);
283
+ return ins(el, g);
284
+ };
285
+ Spinner.prototype.opacity = function(el, i, val, o) {
286
+ var c = el.firstChild;
287
+ o = o.shadow && o.lines || 0;
288
+ if (c && i+o < c.childNodes.length) {
289
+ c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild;
290
+ if (c) c.opacity = val;
291
+ }
292
+ };
293
+ }
294
+ else {
295
+ useCssAnimations = vendor(s, 'animation');
296
+ }
297
+ }();
298
+
299
+ window.Spinner = Spinner;
300
+
301
+ })(window, document);