Tiled Gallery Carousel Without JetPack - Version 2.0

Version Description

  • Tested upto 4.0
Download this release

Release Info

Developer raja3c
Plugin Icon wp plugin Tiled Gallery Carousel Without JetPack
Version 2.0
Comparing to
See all releases

Code changes from version 2.2 to 2.0

readme.txt CHANGED
@@ -1,133 +1,55 @@
1
  === Plugin Name ===
2
-
3
  Tiled Gallery Carousel Without JetPack
4
-
5
  Contributors:raja3c
6
-
7
  Tags: Tiled gallery, carousel, gallery carousel, jetpack, Lightbox, Jetpack Lite
8
-
9
  Requires at least: 3.4.1
10
-
11
- Tested up to: 4.7.4
12
-
13
- Stable tag: 2.2
14
-
15
  License: GPLv2 or later
16
-
17
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
18
 
19
-
20
-
21
  Tiled Gallery Carousel allows you to display image galleries in mosaic styles without Jetpack.
22
 
23
-
24
-
25
  == Description ==
26
 
27
-
28
-
29
  There is no doubt that JetPack packed with tons of features. However, many users don't want all that monstrous codes in their blog for one or two modules. Also, You should connect your blog to wordpress.com to get the JetPack features.
30
 
31
-
32
-
33
  I really like that Tiled Gallery with Full Screen carousel module in JetPack and don't want other modules. That's why I've made the this Tiled Gallery Carousel Without JetPack Plugin from JetPack.
34
 
35
-
36
-
37
  Tiled Gallery with carousel will completely transform your galleries to new look and your users will love this. Tiled Gallery allows you to display image galleries in following styles, a rectangular mosaic, a square mosaic, and a circular grid.
38
 
39
 
40
-
41
-
42
-
43
  Demo Tiled Gallery : [Demo link](http://demo.themepacific.com/plugin-tiled-gallery-carousel/2013/10/13/tiled-gallery-carousel-without-jetpack-wordpress-plugin/ "Demo Link")
44
 
45
-
46
-
47
 
48
-
49
  If you like this plugin then follow ThemePacific on [Twitter](http://twitter.com/themepacific "Twitter"), [Facebook](http://facebook.com/themepacific "Facebook"), and [Google+](https://plus.google.com/u/0/111626044701452949912 "Google+")
50
-
51
 
52
 
53
 
54
-
55
-
56
-
57
  == Installation ==
58
 
59
-
60
-
61
  Download the Plugin here. 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.
62
 
63
-
64
-
65
  Tiled Gallery and Carousel: Go to Settings > Media . There you will find more options.
66
-
67
 
68
 
69
 
70
-
71
-
72
-
73
  == Frequently Asked Questions ==
74
 
75
-
76
-
77
  **About Update?**
78
 
79
-
80
-
81
  This plugin will be updated whenever JetPack releases new version.
82
-
83
-
84
-
85
-
86
-
87
- == Upgrade Notice ==
88
-
89
-
90
-
91
- = 2.2 =
92
-
93
- Compatible with latest version of the WordPress
94
-
95
-
96
 
97
  == Changelog ==
98
-
99
-
100
-
101
- = 2.2 =
102
-
103
- * Compatible with latest version of the WordPress. Will Be Actively Maintained
104
-
105
-
106
-
107
- = 2.1 =
108
-
109
- * version not updated
110
-
111
-
112
-
113
  = 2.0 =
114
-
115
  * Tested upto 4.0
116
 
117
-
118
-
119
  = 1.9 =
120
-
121
  * Fatal error: Class 'Jetpack_Options' not found Fixed
122
-
123
  * image_resize depreciated fixed
124
 
125
-
126
-
127
  = 1.3 =
128
-
129
  * Tested upto 3.9
130
-
131
  = 0.1 =
132
-
133
  *Initial Release
1
  === Plugin Name ===
 
2
  Tiled Gallery Carousel Without JetPack
 
3
  Contributors:raja3c
 
4
  Tags: Tiled gallery, carousel, gallery carousel, jetpack, Lightbox, Jetpack Lite
 
5
  Requires at least: 3.4.1
6
+ Tested up to: 4.0
7
+ Stable tag: 2.0
 
 
 
8
  License: GPLv2 or later
 
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
 
 
11
  Tiled Gallery Carousel allows you to display image galleries in mosaic styles without Jetpack.
12
 
 
 
13
  == Description ==
14
 
 
 
15
  There is no doubt that JetPack packed with tons of features. However, many users don't want all that monstrous codes in their blog for one or two modules. Also, You should connect your blog to wordpress.com to get the JetPack features.
16
 
 
 
17
  I really like that Tiled Gallery with Full Screen carousel module in JetPack and don't want other modules. That's why I've made the this Tiled Gallery Carousel Without JetPack Plugin from JetPack.
18
 
 
 
19
  Tiled Gallery with carousel will completely transform your galleries to new look and your users will love this. Tiled Gallery allows you to display image galleries in following styles, a rectangular mosaic, a square mosaic, and a circular grid.
20
 
21
 
 
 
 
22
  Demo Tiled Gallery : [Demo link](http://demo.themepacific.com/plugin-tiled-gallery-carousel/2013/10/13/tiled-gallery-carousel-without-jetpack-wordpress-plugin/ "Demo Link")
23
 
 
 
24
 
 
25
  If you like this plugin then follow ThemePacific on [Twitter](http://twitter.com/themepacific "Twitter"), [Facebook](http://facebook.com/themepacific "Facebook"), and [Google+](https://plus.google.com/u/0/111626044701452949912 "Google+")
 
26
 
27
 
28
 
 
 
 
29
  == Installation ==
30
 
 
 
31
  Download the Plugin here. 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
  Tiled Gallery and Carousel: Go to Settings > Media . There you will find more options.
 
34
 
35
 
36
 
 
 
 
37
  == Frequently Asked Questions ==
38
 
 
 
39
  **About Update?**
40
 
 
 
41
  This plugin will be updated whenever JetPack releases new version.
42
+
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  = 2.0 =
 
46
  * Tested upto 4.0
47
 
 
 
48
  = 1.9 =
 
49
  * Fatal error: Class 'Jetpack_Options' not found Fixed
 
50
  * image_resize depreciated fixed
51
 
 
 
52
  = 1.3 =
 
53
  * Tested upto 3.9
 
54
  = 0.1 =
 
55
  *Initial Release
tiled-gallery.php CHANGED
@@ -2,11 +2,11 @@
2
 
3
  /*
4
  Plugin Name: Tiled Galleries Carousel Without Jetpack
5
- Plugin URL: https://themepacific.com/
6
  Description: Transform your standard image galleries into an immersive full-screen experience without Jetpack.This plugin is made from Jetpack Modules. You can get the tiled galleries with Full screen carousel with out connecting to wordpress.com account.
7
- Version: 2.2
8
  Author: Raja CRN
9
- Author URI: https://themepacific.com/
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
2
 
3
  /*
4
  Plugin Name: Tiled Galleries Carousel Without Jetpack
5
+ Plugin URL: http://themepacific.com
6
  Description: Transform your standard image galleries into an immersive full-screen experience without Jetpack.This plugin is made from Jetpack Modules. You can get the tiled galleries with Full screen carousel with out connecting to wordpress.com account.
7
+ Version: 1.4
8
  Author: Raja CRN
9
+ Author URI: http://themepacific.com
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
trunk/class.jetpack-user-agent.php ADDED
@@ -0,0 +1,1363 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function themePacific_jetpack_is_mobile( $kind = 'any', $return_matched_agent = false ) {
4
+ static $kinds = array( 'smart' => false, 'dumb' => false, 'any' => false );
5
+ static $first_run = true;
6
+ static $matched_agent = '';
7
+
8
+ $ua_info = new themePacific_jetpack_User_Agent_Info();
9
+
10
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) || strpos( strtolower( $_SERVER['HTTP_USER_AGENT'] ), 'ipad' ) )
11
+ return false;
12
+
13
+ if( $ua_info->is_android_tablet() && $ua_info->is_kindle_touch() === false )
14
+ return false;
15
+
16
+ if( $ua_info->is_blackberry_tablet() )
17
+ return false;
18
+
19
+ if ( $first_run ) {
20
+ $first_run = false;
21
+
22
+ //checks for iPhoneTier devices & RichCSS devices
23
+ if ( $ua_info->isTierIphone() || $ua_info->isTierRichCSS() ) {
24
+ $kinds['smart'] = true;
25
+ $matched_agent = $ua_info->matched_agent;
26
+ }
27
+
28
+ if ( !$kinds['smart'] ) {
29
+ // if smart, we are not dumb so no need to check
30
+ $dumb_agents = $ua_info->dumb_agents;
31
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
32
+ foreach ( $dumb_agents as $dumb_agent ) {
33
+ if ( false !== strpos( $agent, $dumb_agent ) ) {
34
+ $kinds['dumb'] = true;
35
+ $matched_agent = $dumb_agent;
36
+ break;
37
+ }
38
+ }
39
+
40
+ if ( !$kinds['dumb'] ) {
41
+ if ( isset( $_SERVER['HTTP_X_WAP_PROFILE'] ) ) {
42
+ $kinds['dumb'] = true;
43
+ $matched_agent = 'http_x_wap_profile';
44
+ } elseif ( isset( $_SERVER['HTTP_ACCEPT']) && ( preg_match( '/wap\.|\.wap/i', $_SERVER['HTTP_ACCEPT'] ) || false !== strpos( strtolower( $_SERVER['HTTP_ACCEPT'] ), 'application/vnd.wap.xhtml+xml' ) ) ) {
45
+ $kinds['dumb'] = true;
46
+ $matched_agent = 'vnd.wap.xhtml+xml';
47
+ }
48
+ }
49
+ }
50
+
51
+ if ( $kinds['dumb'] || $kinds['smart'] )
52
+ $kinds['any'] = true;
53
+ }
54
+
55
+ if ( $return_matched_agent )
56
+ return $matched_agent;
57
+
58
+ return $kinds[$kind];
59
+ }
60
+
61
+ class themePacific_jetpack_User_Agent_Info {
62
+
63
+ var $useragent;
64
+ var $matched_agent;
65
+ var $isTierIphone; //Stores whether is the iPhone tier of devices.
66
+ var $isTierRichCss; //Stores whether the device can probably support Rich CSS, but JavaScript (jQuery) support is not assumed.
67
+ var $isTierGenericMobile; //Stores whether it is another mobile device, which cannot be assumed to support CSS or JS (eg, older BlackBerry, RAZR)
68
+
69
+ private $_platform = null; //Stores the device platform name
70
+ const PLATFORM_WINDOWS = 'windows';
71
+ const PLATFORM_IPHONE = 'iphone';
72
+ const PLATFORM_IPOD = 'ipod';
73
+ const PLATFORM_IPAD = 'ipad';
74
+ const PLATFORM_BLACKBERRY = 'blackberry';
75
+ const PLATFORM_BLACKBERRY_10 = 'blackberry_10';
76
+ const PLATFORM_SYMBIAN = 'symbian_series60';
77
+ const PLATFORM_SYMBIAN_S40 = 'symbian_series40';
78
+ const PLATFORM_J2ME_MIDP = 'j2me_midp';
79
+ const PLATFORM_ANDROID = 'android';
80
+ const PLATFORM_ANDROID_TABLET = 'android_tablet';
81
+ const PLATFORM_FIREFOX_OS = 'firefoxOS';
82
+
83
+ var $dumb_agents = array(
84
+ 'nokia', 'blackberry', 'philips', 'samsung', 'sanyo', 'sony', 'panasonic', 'webos',
85
+ 'ericsson', 'alcatel', 'palm',
86
+ 'windows ce', 'opera mini', 'series60', 'series40',
87
+ 'au-mic,', 'audiovox', 'avantgo', 'blazer',
88
+ 'danger', 'docomo', 'epoc',
89
+ 'ericy', 'i-mode', 'ipaq', 'midp-',
90
+ 'mot-', 'netfront', 'nitro',
91
+ 'palmsource', 'pocketpc', 'portalmmm',
92
+ 'rover', 'sie-',
93
+ 'symbian', 'cldc-', 'j2me',
94
+ 'smartphone', 'up.browser', 'up.link',
95
+ 'up.link', 'vodafone/', 'wap1.', 'wap2.', 'mobile', 'googlebot-mobile',
96
+ );
97
+
98
+ //The constructor. Initializes default variables.
99
+ function themePacific_jetpack_User_Agent_Info()
100
+ {
101
+ if ( !empty( $_SERVER['HTTP_USER_AGENT'] ) )
102
+ $this->useragent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
103
+ }
104
+
105
+ /**
106
+ * This method detects the mobile User Agent name.
107
+ *
108
+ * @return string The matched User Agent name, false otherwise.
109
+ */
110
+ function get_mobile_user_agent_name() {
111
+ if( $this->is_chrome_for_iOS( ) ) //keep this check before the safari rule
112
+ return 'chrome-for-ios';
113
+ elseif ( $this->is_iphone_or_ipod( 'iphone-safari' ) )
114
+ return 'iphone';
115
+ elseif ( $this->is_ipad( 'ipad-safari' ) )
116
+ return 'ipad';
117
+ elseif ( $this->is_android_tablet() ) //keep this check before the android rule
118
+ return 'android_tablet';
119
+ elseif ( $this->is_android() )
120
+ return 'android';
121
+ elseif ( $this->is_blackberry_10() )
122
+ return 'blackberry_10';
123
+ elseif ( $this->is_blackbeberry() )
124
+ return 'blackberry';
125
+ elseif ( $this->is_WindowsPhone7() )
126
+ return 'win7';
127
+ elseif ( $this->is_windows_phone_8() )
128
+ return 'winphone8';
129
+ elseif ( $this->is_opera_mini() )
130
+ return 'opera-mini';
131
+ elseif ( $this->is_opera_mini_dumb() )
132
+ return 'opera-mini-dumb';
133
+ elseif ( $this->is_opera_mobile() )
134
+ return 'opera-mobi';
135
+ elseif ( $this->is_blackberry_tablet() )
136
+ return 'blackberry_tablet';
137
+ elseif ( $this->is_kindle_fire() )
138
+ return 'kindle-fire';
139
+ elseif ( $this->is_PalmWebOS() )
140
+ return 'webos';
141
+ elseif ( $this->is_S60_OSSBrowser() )
142
+ return 'series60';
143
+ elseif ( $this->is_firefox_os() )
144
+ return 'firefoxOS';
145
+ elseif ( $this->is_firefox_mobile() )
146
+ return 'firefox_mobile';
147
+ elseif ( $this->is_MaemoTablet() )
148
+ return 'maemo';
149
+ elseif ( $this->is_MeeGo() )
150
+ return 'meego';
151
+ elseif( $this->is_TouchPad() )
152
+ return 'hp_tablet';
153
+ elseif ( $this->is_facebook_for_iphone() )
154
+ return 'facebook-for-iphone';
155
+ elseif ( $this->is_facebook_for_ipad() )
156
+ return 'facebook-for-ipad';
157
+ elseif ( $this->is_twitter_for_iphone() )
158
+ return 'twitter-for-iphone';
159
+ elseif ( $this->is_twitter_for_ipad() )
160
+ return 'twitter-for-ipad';
161
+ elseif ( $this->is_wordpress_for_ios() )
162
+ return 'ios-app';
163
+ elseif ( $this->is_iphone_or_ipod( 'iphone-not-safari' ) )
164
+ return 'iphone-unknown';
165
+ elseif ( $this->is_ipad( 'ipad-not-safari' ) )
166
+ return 'ipad-unknown';
167
+ else {
168
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
169
+ $dumb_agents = $this->dumb_agents;
170
+ foreach ( $dumb_agents as $dumb_agent ) {
171
+ if ( false !== strpos( $agent, $dumb_agent ) ) {
172
+ return $dumb_agent;
173
+ }
174
+ }
175
+ }
176
+
177
+ return false;
178
+ }
179
+
180
+ /**
181
+ * This method detects the mobile device's platform. All return strings are from the class constants.
182
+ * Note that this function returns the platform name, not the UA name/type. You should use a different function
183
+ * if you need to test the UA capabilites.
184
+ *
185
+ * @return string Name of the platform, false otherwise.
186
+ */
187
+ public function get_platform() {
188
+ if ( isset( $this->_platform ) ) {
189
+ return $this->_platform;
190
+ }
191
+
192
+ if ( strpos( $this->useragent, 'windows phone' ) !== false ) {
193
+ $this->_platform = self::PLATFORM_WINDOWS;
194
+ }
195
+ elseif ( strpos( $this->useragent, 'windows ce' ) !== false ) {
196
+ $this->_platform = self::PLATFORM_WINDOWS;
197
+ }
198
+ elseif ( strpos( $this->useragent, 'ipad' ) !== false ) {
199
+ $this->_platform = self::PLATFORM_IPAD;
200
+ }
201
+ else if ( strpos( $this->useragent, 'ipod' ) !== false ) {
202
+ $this->_platform = self::PLATFORM_IPOD;
203
+ }
204
+ else if ( strpos( $this->useragent, 'iphone' ) !== false ) {
205
+ $this->_platform = self::PLATFORM_IPHONE;
206
+ }
207
+ elseif ( strpos( $this->useragent, 'android' ) !== false ) {
208
+ if ( $this->is_android_tablet() )
209
+ $this->_platform = self::PLATFORM_ANDROID_TABLET;
210
+ else
211
+ $this->_platform = self::PLATFORM_ANDROID;
212
+ }
213
+ elseif ( $this->is_kindle_fire() ) {
214
+ $this->_platform = self::PLATFORM_ANDROID_TABLET;
215
+ }
216
+ elseif ( $this->is_blackberry_10() ) {
217
+ $this->_platform = self::PLATFORM_BLACKBERRY_10;
218
+ }
219
+ elseif ( strpos( $this->useragent, 'blackberry' ) !== false ) {
220
+ $this->_platform = self::PLATFORM_BLACKBERRY;
221
+ }
222
+ elseif ( $this->is_blackberry_tablet() ) {
223
+ $this->_platform = self::PLATFORM_BLACKBERRY;
224
+ }
225
+ elseif ( $this->is_symbian_platform() ) {
226
+ $this->_platform = self::PLATFORM_SYMBIAN;
227
+ }
228
+ elseif ( $this->is_symbian_s40_platform() ) {
229
+ $this->_platform = self::PLATFORM_SYMBIAN_S40;
230
+ }
231
+ elseif ( $this->is_J2ME_platform() ) {
232
+ $this->_platform = self::PLATFORM_J2ME_MIDP;
233
+ }
234
+ elseif ( $this->is_firefox_os() ) {
235
+ $this->_platform = self::PLATFORM_FIREFOX_OS;
236
+ }
237
+ else
238
+ $this->_platform = false;
239
+
240
+ return $this->_platform;
241
+ }
242
+
243
+ /*
244
+ * This method detects for UA which can display iPhone-optimized web content.
245
+ * Includes iPhone, iPod Touch, Android, WebOS, Fennec (Firefox mobile), etc.
246
+ *
247
+ */
248
+ function isTierIphone() {
249
+ if ( isset( $this->isTierIphone ) ) {
250
+ return $this->isTierIphone;
251
+ }
252
+ if ( $this->is_iphoneOrIpod() ) {
253
+ $this->matched_agent = 'iphone';
254
+ $this->isTierIphone = true;
255
+ $this->isTierRichCss = false;
256
+ $this->isTierGenericMobile = false;
257
+ }
258
+ elseif ( $this->is_android() ) {
259
+ $this->matched_agent = 'android';
260
+ $this->isTierIphone = true;
261
+ $this->isTierRichCss = false;
262
+ $this->isTierGenericMobile = false;
263
+ }
264
+ elseif ( $this->is_windows_phone_8() ) {
265
+ $this->matched_agent = 'winphone8';
266
+ $this->isTierIphone = true;
267
+ $this->isTierRichCss = false;
268
+ $this->isTierGenericMobile = false;
269
+ }
270
+ elseif ( $this->is_WindowsPhone7() ) {
271
+ $this->matched_agent = 'win7';
272
+ $this->isTierIphone = true;
273
+ $this->isTierRichCss = false;
274
+ $this->isTierGenericMobile = false;
275
+ }
276
+ elseif ( $this->is_blackberry_10() ) {
277
+ $this->matched_agent = 'blackberry-10';
278
+ $this->isTierIphone = true;
279
+ $this->isTierRichCss = false;
280
+ $this->isTierGenericMobile = false;
281
+ }
282
+ elseif ( $this->is_blackbeberry() && $this->detect_blackberry_browser_version() == 'blackberry-webkit' ) {
283
+ $this->matched_agent = 'blackberry-webkit';
284
+ $this->isTierIphone = true;
285
+ $this->isTierRichCss = false;
286
+ $this->isTierGenericMobile = false;
287
+ }
288
+ elseif ( $this->is_blackberry_tablet() ) {
289
+ $this->matched_agent = 'blackberry_tablet';
290
+ $this->isTierIphone = true;
291
+ $this->isTierRichCss = false;
292
+ $this->isTierGenericMobile = false;
293
+ }
294
+ elseif ( $this->is_PalmWebOS() ) {
295
+ $this->matched_agent = 'webos';
296
+ $this->isTierIphone = true;
297
+ $this->isTierRichCss = false;
298
+ $this->isTierGenericMobile = false;
299
+ }
300
+ elseif ( $this->is_TouchPad() ) {
301
+ $this->matched_agent = 'hp_tablet';
302
+ $this->isTierIphone = true;
303
+ $this->isTierRichCss = false;
304
+ $this->isTierGenericMobile = false;
305
+ }
306
+ elseif ( $this->is_firefox_os() ) {
307
+ $this->matched_agent = 'firefoxOS';
308
+ $this->isTierIphone = true;
309
+ $this->isTierRichCss = false;
310
+ $this->isTierGenericMobile = false;
311
+ }
312
+ elseif ( $this->is_firefox_mobile() ) {
313
+ $this->matched_agent = 'fennec';
314
+ $this->isTierIphone = true;
315
+ $this->isTierRichCss = false;
316
+ $this->isTierGenericMobile = false;
317
+ }
318
+ elseif ( $this->is_opera_mobile() ) {
319
+ $this->matched_agent = 'opera-mobi';
320
+ $this->isTierIphone = true;
321
+ $this->isTierRichCss = false;
322
+ $this->isTierGenericMobile = false;
323
+ }
324
+ elseif ( $this->is_MaemoTablet() ) {
325
+ $this->matched_agent = 'maemo';
326
+ $this->isTierIphone = true;
327
+ $this->isTierRichCss = false;
328
+ $this->isTierGenericMobile = false;
329
+ }
330
+ elseif ( $this->is_MeeGo() ) {
331
+ $this->matched_agent = 'meego';
332
+ $this->isTierIphone = true;
333
+ $this->isTierRichCss = false;
334
+ $this->isTierGenericMobile = false;
335
+ }
336
+ elseif ( $this->is_kindle_touch() ) {
337
+ $this->matched_agent = 'kindle-touch';
338
+ $this->isTierIphone = true;
339
+ $this->isTierRichCss = false;
340
+ $this->isTierGenericMobile = false;
341
+ }
342
+ else {
343
+ $this->isTierIphone = false;
344
+ }
345
+ return $this->isTierIphone;
346
+ }
347
+
348
+ /*
349
+ * This method detects for UA which are likely to be capable
350
+ * but may not necessarily support JavaScript.
351
+ * Excludes all iPhone Tier UA.
352
+ *
353
+ */
354
+ function isTierRichCss(){
355
+ if ( isset( $this->isTierRichCss ) ) {
356
+ return $this->isTierRichCss;
357
+ }
358
+ if ($this->isTierIphone())
359
+ return false;
360
+
361
+ //The following devices are explicitly ok.
362
+ if ( $this->is_S60_OSSBrowser() ) {
363
+ $this->matched_agent = 'series60';
364
+ $this->isTierIphone = false;
365
+ $this->isTierRichCss = true;
366
+ $this->isTierGenericMobile = false;
367
+ }
368
+ elseif ( $this->is_opera_mini() ) {
369
+ $this->matched_agent = 'opera-mini';
370
+ $this->isTierIphone = false;
371
+ $this->isTierRichCss = true;
372
+ $this->isTierGenericMobile = false;
373
+ }
374
+ elseif ( $this->is_blackbeberry() ) {
375
+ $detectedDevice = $this->detect_blackberry_browser_version();
376
+ if ( $detectedDevice === 'blackberry-5' || $detectedDevice == 'blackberry-4.7' || $detectedDevice === 'blackberry-4.6' ) {
377
+ $this->matched_agent = $detectedDevice;
378
+ $this->isTierIphone = false;
379
+ $this->isTierRichCss = true;
380
+ $this->isTierGenericMobile = false;
381
+ }
382
+ }
383
+ else {
384
+ $this->isTierRichCss = false;
385
+ }
386
+
387
+ return $this->isTierRichCss;
388
+ }
389
+
390
+ // Detects if the user is using a tablet.
391
+ // props Corey Gilmore, BGR.com
392
+ static function is_tablet() {
393
+ return ( 0 // never true, but makes it easier to manage our list of tablet conditions
394
+ || self::is_ipad()
395
+ || self::is_android_tablet()
396
+ || self::is_blackberry_tablet()
397
+ || self::is_kindle_fire()
398
+ || self::is_MaemoTablet()
399
+ || self::is_TouchPad()
400
+ );
401
+ }
402
+
403
+ /*
404
+ * Detects if the current UA is the default iPhone or iPod Touch Browser.
405
+ *
406
+ * DEPRECATED: use is_iphone_or_ipod
407
+ *
408
+ */
409
+ static function is_iphoneOrIpod(){
410
+
411
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
412
+ return false;
413
+
414
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
415
+ if ( ( strpos( $ua, 'iphone' ) !== false ) || ( strpos( $ua,'ipod' ) !== false ) ) {
416
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
417
+ return false;
418
+ else
419
+ return true;
420
+ }
421
+ else
422
+ return false;
423
+ }
424
+
425
+
426
+ /*
427
+ * Detects if the current UA is iPhone Mobile Safari or another iPhone or iPod Touch Browser.
428
+ *
429
+ * They type can check for any iPhone, an iPhone using Safari, or an iPhone using something other than Safari.
430
+ *
431
+ * Note: If you want to check for Opera mini, Opera mobile or Firefox mobile (or any 3rd party iPhone browser),
432
+ * you should put the check condition before the check for 'iphone-any' or 'iphone-not-safari'.
433
+ * Otherwise those browsers will be 'catched' by the iphone string.
434
+ *
435
+ */
436
+ static function is_iphone_or_ipod( $type = 'iphone-any' ) {
437
+
438
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
439
+ return false;
440
+
441
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
442
+ $is_iphone = ( strpos( $ua, 'iphone' ) !== false ) || ( strpos( $ua,'ipod' ) !== false );
443
+ $is_safari = ( false !== strpos( $ua, 'safari' ) );
444
+
445
+ if ( 'iphone-safari' == $type )
446
+ return $is_iphone && $is_safari;
447
+ elseif ( 'iphone-not-safari' == $type )
448
+ return $is_iphone && !$is_safari;
449
+ else
450
+ return $is_iphone;
451
+ }
452
+
453
+
454
+ /*
455
+ * Detects if the current UA is Chrome for iOS
456
+ *
457
+ * The User-Agent string in Chrome for iOS is the same as the Mobile Safari User-Agent, with CriOS/<ChromeRevision> instead of Version/<VersionNum>.
458
+ * - Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3
459
+ */
460
+ static function is_chrome_for_iOS( ) {
461
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
462
+ return false;
463
+
464
+ if ( self::is_iphone_or_ipod( 'iphone-safari' ) === false ) return false;
465
+
466
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
467
+
468
+ if ( strpos( $ua, 'crios/' ) !== false )
469
+ return true;
470
+ else
471
+ return false;
472
+ }
473
+
474
+
475
+ /*
476
+ * Detects if the current UA is Twitter for iPhone
477
+ *
478
+ * Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_5 like Mac OS X; nb-no) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8L1 Twitter for iPhone
479
+ * Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 Twitter for iPhone
480
+ *
481
+ */
482
+ static function is_twitter_for_iphone( ) {
483
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
484
+ return false;
485
+
486
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
487
+
488
+ if ( strpos( $ua, 'ipad' ) !== false )
489
+ return false;
490
+
491
+ if ( strpos( $ua, 'twitter for iphone' ) !== false )
492
+ return true;
493
+ else
494
+ return false;
495
+ }
496
+
497
+ /*
498
+ * Detects if the current UA is Twitter for iPad
499
+ *
500
+ * Old version 4.X - Mozilla/5.0 (iPad; U; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8L1 Twitter for iPad
501
+ * Ver 5.0 or Higher - Mozilla/5.0 (iPad; CPU OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 Twitter for iPhone
502
+ *
503
+ */
504
+ static function is_twitter_for_ipad( ) {
505
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
506
+ return false;
507
+
508
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
509
+
510
+ if ( strpos( $ua, 'twitter for ipad' ) !== false )
511
+ return true;
512
+ elseif( strpos( $ua, 'ipad' ) !== false && strpos( $ua, 'twitter for iphone' ) !== false )
513
+ return true;
514
+ else
515
+ return false;
516
+ }
517
+
518
+
519
+ /*
520
+ * Detects if the current UA is Facebook for iPhone
521
+ * - Facebook 4020.0 (iPhone; iPhone OS 5.0.1; fr_FR)
522
+ * - Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_0 like Mac OS X; en_US) AppleWebKit (KHTML, like Gecko) Mobile [FBAN/FBForIPhone;FBAV/4.0.2;FBBV/4020.0;FBDV/iPhone3,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/5.0;FBSS/2; FBCR/O2;FBID/phone;FBLC/en_US;FBSF/2.0]
523
+ * - Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 [FBAN/FBIOS;FBAV/5.0;FBBV/47423;FBDV/iPhone3,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/5.1.1;FBSS/2; FBCR/3ITA;FBID/phone;FBLC/en_US]
524
+ */
525
+ static function is_facebook_for_iphone( ) {
526
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
527
+ return false;
528
+
529
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
530
+
531
+ if( strpos( $ua, 'iphone' ) === false )
532
+ return false;
533
+
534
+ if ( strpos( $ua, 'facebook' ) !== false && strpos( $ua, 'ipad' ) === false )
535
+ return true;
536
+ else if ( strpos( $ua, 'fbforiphone' ) !== false && strpos( $ua, 'tablet' ) === false )
537
+ return true;
538
+ else if ( strpos( $ua, 'fban/fbios;' ) !== false && strpos( $ua, 'tablet' ) === false ) //FB app v5.0 or higher
539
+ return true;
540
+ else
541
+ return false;
542
+ }
543
+
544
+ /*
545
+ * Detects if the current UA is Facebook for iPad
546
+ * - Facebook 4020.0 (iPad; iPhone OS 5.0.1; en_US)
547
+ * - Mozilla/5.0 (iPad; U; CPU iPhone OS 5_0 like Mac OS X; en_US) AppleWebKit (KHTML, like Gecko) Mobile [FBAN/FBForIPhone;FBAV/4.0.2;FBBV/4020.0;FBDV/iPad2,1;FBMD/iPad;FBSN/iPhone OS;FBSV/5.0;FBSS/1; FBCR/;FBID/tablet;FBLC/en_US;FBSF/1.0]
548
+ * - Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10A403 [FBAN/FBIOS;FBAV/5.0;FBBV/47423;FBDV/iPad2,1;FBMD/iPad;FBSN/iPhone OS;FBSV/6.0;FBSS/1; FBCR/;FBID/tablet;FBLC/en_US]
549
+ */
550
+ static function is_facebook_for_ipad( ) {
551
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
552
+ return false;
553
+
554
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
555
+
556
+ if ( strpos( $ua, 'ipad' ) === false )
557
+ return false;
558
+
559
+ if ( strpos( $ua, 'facebook' ) !== false || strpos( $ua, 'fbforiphone' ) !== false || strpos( $ua, 'fban/fbios;' ) !== false )
560
+ return true;
561
+ else
562
+ return false;
563
+ }
564
+
565
+ /*
566
+ * Detects if the current UA is WordPress for iOS
567
+ */
568
+ static function is_wordpress_for_ios( ) {
569
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
570
+ return false;
571
+
572
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
573
+ if ( strpos( $ua, 'wp-iphone' ) !== false )
574
+ return true;
575
+ else
576
+ return false;
577
+ }
578
+
579
+ /*
580
+ * Detects if the current device is an iPad.
581
+ * They type can check for any iPad, an iPad using Safari, or an iPad using something other than Safari.
582
+ *
583
+ * Note: If you want to check for Opera mini, Opera mobile or Firefox mobile (or any 3rd party iPad browser),
584
+ * you should put the check condition before the check for 'iphone-any' or 'iphone-not-safari'.
585
+ * Otherwise those browsers will be 'catched' by the ipad string.
586
+ *
587
+ */
588
+ static function is_ipad( $type = 'ipad-any' ) {
589
+
590
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
591
+ return false;
592
+
593
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
594
+
595
+ $is_ipad = ( false !== strpos( $ua, 'ipad' ) );
596
+ $is_safari = ( false !== strpos( $ua, 'safari' ) );
597
+
598
+ if ( 'ipad-safari' == $type )
599
+ return $is_ipad && $is_safari;
600
+ elseif ( 'ipad-not-safari' == $type )
601
+ return $is_ipad && !$is_safari;
602
+ else
603
+ return $is_ipad;
604
+ }
605
+
606
+ /*
607
+ * Detects if the current browser is Firefox Mobile (Fennec)
608
+ *
609
+ * http://www.useragentstring.com/pages/Fennec/
610
+ * Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.1.1) Gecko/20110415 Firefox/4.0.2pre Fennec/4.0.1
611
+ * Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b2pre) Gecko/20081015 Fennec/1.0a1
612
+ */
613
+ static function is_firefox_mobile( ) {
614
+
615
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
616
+ return false;
617
+
618
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
619
+
620
+ if ( strpos( $ua, 'fennec' ) !== false )
621
+ return true;
622
+ else
623
+ return false;
624
+ }
625
+
626
+
627
+ /*
628
+ * Detects if the current browser is FirefoxOS Native browser
629
+ *
630
+ * Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0
631
+ *
632
+ */
633
+ static function is_firefox_os( ) {
634
+
635
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
636
+ return false;
637
+
638
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
639
+
640
+ if ( strpos( $ua, 'mozilla' ) !== false && strpos( $ua, 'mobile' ) !== false && strpos( $ua, 'gecko' ) !== false && strpos( $ua, 'firefox' ) !== false)
641
+ return true;
642
+ else
643
+ return false;
644
+ }
645
+
646
+
647
+ /*
648
+ * Detects if the current browser is Opera Mobile
649
+ *
650
+ * What is the difference between Opera Mobile and Opera Mini?
651
+ * - Opera Mobile is a full Internet browser for mobile devices.
652
+ * - Opera Mini always uses a transcoder to convert the page for a small display.
653
+ * (it uses Opera advanced server compression technology to compress web content before it gets to a device.
654
+ * The rendering engine is on Opera's server.)
655
+ *
656
+ * Opera/9.80 (Windows NT 6.1; Opera Mobi/14316; U; en) Presto/2.7.81 Version/11.00"
657
+ */
658
+ static function is_opera_mobile( ) {
659
+
660
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
661
+ return false;
662
+
663
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
664
+
665
+ if ( strpos( $ua, 'opera' ) !== false && strpos( $ua, 'mobi' ) !== false )
666
+ return true;
667
+ else
668
+ return false;
669
+ }
670
+
671
+
672
+ /*
673
+ * Detects if the current browser is Opera Mini
674
+ *
675
+ * Opera/8.01 (J2ME/MIDP; Opera Mini/3.0.6306/1528; en; U; ssr)
676
+ * Opera/9.80 (Android;Opera Mini/6.0.24212/24.746 U;en) Presto/2.5.25 Version/10.5454
677
+ * Opera/9.80 (iPhone; Opera Mini/5.0.019802/18.738; U; en) Presto/2.4.15
678
+ * Opera/9.80 (J2ME/iPhone;Opera Mini/5.0.019802/886; U; ja) Presto/2.4.15
679
+ * Opera/9.80 (J2ME/iPhone;Opera Mini/5.0.019802/886; U; ja) Presto/2.4.15
680
+ * Opera/9.80 (Series 60; Opera Mini/5.1.22783/23.334; U; en) Presto/2.5.25 Version/10.54
681
+ * Opera/9.80 (BlackBerry; Opera Mini/5.1.22303/22.387; U; en) Presto/2.5.25 Version/10.54
682
+ *
683
+ */
684
+ static function is_opera_mini( ) {
685
+
686
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
687
+ return false;
688
+
689
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
690
+
691
+ if ( strpos( $ua, 'opera' ) !== false && strpos( $ua, 'mini' ) !== false )
692
+ return true;
693
+ else
694
+ return false;
695
+ }
696
+
697
+ /*
698
+ * Detects if the current browser is Opera Mini, but not on a smart device OS(Android, iOS, etc)
699
+ * Used to send users on dumb devices to m.wor
700
+ */
701
+ static function is_opera_mini_dumb( ) {
702
+
703
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
704
+ return false;
705
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
706
+
707
+ if ( self::is_opera_mini() ) {
708
+ if ( strpos( $ua, 'android' ) !== false || strpos( $ua, 'iphone' ) !== false || strpos( $ua, 'ipod' ) !== false
709
+ || strpos( $ua, 'ipad' ) !== false || strpos( $ua, 'blackberry' ) !== false)
710
+ return false;
711
+ else
712
+ return true;
713
+ } else {
714
+ return false;
715
+ }
716
+ }
717
+
718
+ /*
719
+ * Detects if the current browser is Opera Mobile or Mini.
720
+ * DEPRECATED: use is_opera_mobile or is_opera_mini
721
+ *
722
+ * Opera Mini 5 Beta: Opera/9.80 (J2ME/MIDP; Opera Mini/5.0.15650/756; U; en) Presto/2.2.0
723
+ * Opera Mini 8: Opera/8.01 (J2ME/MIDP; Opera Mini/3.0.6306/1528; en; U; ssr)
724
+ */
725
+ static function is_OperaMobile() {
726
+ _deprecated_function( __FUNCTION__, 'always', 'is_opera_mini() or is_opera_mobile()' );
727
+
728
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
729
+ return false;
730
+
731
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
732
+
733
+ if ( strpos( $ua, 'opera' ) !== false ) {
734
+ if ( ( strpos( $ua, 'mini' ) !== false ) || ( strpos( $ua,'mobi' ) !== false ) )
735
+ return true;
736
+ else
737
+ return false;
738
+ } else {
739
+ return false;
740
+ }
741
+ }
742
+
743
+ /*
744
+ * Detects if the current browser is a Windows Phone 7 device.
745
+ * ex: Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; LG; GW910)
746
+ */
747
+ static function is_WindowsPhone7() {
748
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
749
+ return false;
750
+
751
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
752
+
753
+ if ( strpos( $ua, 'windows phone os 7' ) === false ) {
754
+ return false;
755
+ } else {
756
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
757
+ return false;
758
+ else
759
+ return true;
760
+ }
761
+ }
762
+
763
+ /*
764
+ * Detects if the current browser is a Windows Phone 8 device.
765
+ * ex: Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; ARM; Touch; IEMobile/10.0; <Manufacturer>; <Device> [;<Operator>])
766
+ */
767
+ static function is_windows_phone_8() {
768
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
769
+ return false;
770
+
771
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
772
+ if ( strpos( $ua, 'windows phone 8' ) === false ) {
773
+ return false;
774
+ } else {
775
+ return true;
776
+ }
777
+ }
778
+
779
+
780
+ /*
781
+ * Detects if the current browser is on a Palm device running the new WebOS. This EXCLUDES TouchPad.
782
+ *
783
+ * ex1: Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pre/1.1
784
+ * ex2: Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pixi/1.1
785
+ *
786
+ */
787
+ static function is_PalmWebOS() {
788
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
789
+ return false;
790
+
791
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
792
+
793
+ if ( strpos( $ua, 'webos' ) === false ) {
794
+ return false;
795
+ } else {
796
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
797
+ return false;
798
+ else
799
+ return true;
800
+ }
801
+ }
802
+
803
+ /*
804
+ * Detects if the current browser is the HP TouchPad default browser. This excludes phones wt WebOS.
805
+ *
806
+ * TouchPad Emulator: Mozilla/5.0 (hp-desktop; Linux; hpwOS/2.0; U; it-IT) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.70 Safari/534.6 Desktop/1.0
807
+ * TouchPad: Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.0; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.70 Safari/534.6 TouchPad/1.0
808
+ *
809
+ */
810
+ static function is_TouchPad() {
811
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
812
+ return false;
813
+
814
+ $http_user_agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
815
+ if ( false !== strpos( $http_user_agent, 'hp-tablet' ) || false !== strpos( $http_user_agent, 'hpwos' ) || false !== strpos( $http_user_agent, 'touchpad' ) ) {
816
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
817
+ return false;
818
+ else
819
+ return true;
820
+ }
821
+ else
822
+ return false;
823
+ }
824
+
825
+
826
+ /*
827
+ * Detects if the current browser is the Series 60 Open Source Browser.
828
+ *
829
+ * OSS Browser 3.2 on E75: Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1/110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413
830
+ *
831
+ * 7.0 Browser (Nokia 5800 XpressMusic (v21.0.025)) : Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0 Nokia5800d-1/21.0.025; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413
832
+ *
833
+ * Browser 7.1 (Nokia N97 (v12.0.024)) : Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/12.0.024; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.12344
834
+ *
835
+ */
836
+ static function is_S60_OSSBrowser() {
837
+
838
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
839
+ return false;
840
+
841
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
842
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
843
+ return false;
844
+
845
+ $pos_webkit = strpos( $agent, 'webkit' );
846
+ if ( $pos_webkit !== false ) {
847
+ //First, test for WebKit, then make sure it's either Symbian or S60.
848
+ if ( strpos( $agent, 'symbian' ) !== false || strpos( $agent, 'series60' ) !== false ) {
849
+ return true;
850
+ } else
851
+ return false;
852
+ } elseif ( strpos( $agent, 'symbianos' ) !== false && strpos( $agent,'series60' ) !== false ) {
853
+ return true;
854
+ } elseif ( strpos( $agent, 'nokia' ) !== false && strpos( $agent,'series60' ) !== false ) {
855
+ return true;
856
+ }
857
+
858
+ return false;
859
+ }
860
+
861
+ /*
862
+ *
863
+ * Detects if the device platform is the Symbian Series 60.
864
+ *
865
+ */
866
+ static function is_symbian_platform() {
867
+
868
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
869
+ return false;
870
+
871
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
872
+
873
+ $pos_webkit = strpos( $agent, 'webkit' );
874
+ if ( $pos_webkit !== false ) {
875
+ //First, test for WebKit, then make sure it's either Symbian or S60.
876
+ if ( strpos( $agent, 'symbian' ) !== false || strpos( $agent, 'series60' ) !== false ) {
877
+ return true;
878
+ } else
879
+ return false;
880
+ } elseif ( strpos( $agent, 'symbianos' ) !== false && strpos( $agent,'series60' ) !== false ) {
881
+ return true;
882
+ } elseif ( strpos( $agent, 'nokia' ) !== false && strpos( $agent,'series60' ) !== false ) {
883
+ return true;
884
+ } elseif ( strpos( $agent, 'opera mini' ) !== false ) {
885
+ if( strpos( $agent,'symbianos' ) !== false || strpos( $agent,'symbos' ) !== false || strpos( $agent,'series 60' ) !== false )
886
+ return true;
887
+ }
888
+
889
+ return false;
890
+ }
891
+
892
+ /*
893
+ *
894
+ * Detects if the device platform is the Symbian Series 40.
895
+ * Nokia Browser for Series 40 is a proxy based browser, previously known as Ovi Browser.
896
+ * This browser will report 'NokiaBrowser' in the header, however some older version will also report 'OviBrowser'.
897
+ *
898
+ */
899
+ static function is_symbian_s40_platform() {
900
+
901
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
902
+ return false;
903
+
904
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
905
+
906
+ if ( strpos( $agent, 'series40' ) !== false ) {
907
+ if( strpos( $agent,'nokia' ) !== false || strpos( $agent,'ovibrowser' ) !== false || strpos( $agent,'nokiabrowser' ) !== false )
908
+ return true;
909
+ }
910
+
911
+ return false;
912
+ }
913
+
914
+ static function is_J2ME_platform() {
915
+
916
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
917
+ return false;
918
+
919
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
920
+
921
+ if ( strpos( $agent, 'j2me/midp' ) !== false ) {
922
+ return true;
923
+ } elseif ( strpos( $agent, 'midp' ) !== false && strpos( $agent, 'cldc' ) ) {
924
+ return true;
925
+ }
926
+
927
+ return false;
928
+ }
929
+
930
+
931
+ /*
932
+ * Detects if the current UA is on one of the Maemo-based Nokia Internet Tablets.
933
+ */
934
+ static function is_MaemoTablet() {
935
+
936
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
937
+ return false;
938
+
939
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
940
+
941
+ $pos_maemo = strpos( $agent, 'maemo' );
942
+ if ( $pos_maemo === false ) return false;
943
+
944
+ //Must be Linux + Tablet, or else it could be something else.
945
+ if ( strpos( $agent, 'tablet' ) !== false && strpos( $agent, 'linux' ) !== false ) {
946
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
947
+ return false;
948
+ else
949
+ return true;
950
+ } else
951
+ return false;
952
+ }
953
+
954
+ /*
955
+ * Detects if the current UA is a MeeGo device (Nokia Smartphone).
956
+ */
957
+ static function is_MeeGo() {
958
+
959
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
960
+ return false;
961
+
962
+ $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
963
+
964
+ if ( strpos( $ua, 'meego' ) === false ) {
965
+ return false;
966
+ } else {
967
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
968
+ return false;
969
+ else
970
+ return true;
971
+ }
972
+ }
973
+
974
+
975
+ /*
976
+ is_webkit() can be used to check the User Agent for an webkit generic browser
977
+ */
978
+ static function is_webkit() {
979
+
980
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
981
+ return false;
982
+
983
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
984
+
985
+ $pos_webkit = strpos( $agent, 'webkit' );
986
+
987
+ if ( $pos_webkit !== false )
988
+ return true;
989
+ else
990
+ return false;
991
+ }
992
+
993
+ /**
994
+ * Detects if the current browser is the Native Android browser.
995
+ * @return boolean true if the browser is Android otherwise false
996
+ */
997
+ static function is_android() {
998
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
999
+ return false;
1000
+
1001
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1002
+ $pos_android = strpos( $agent, 'android' );
1003
+ if ( $pos_android !== false ) {
1004
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
1005
+ return false;
1006
+ else
1007
+ return true;
1008
+ }
1009
+ else
1010
+ return false;
1011
+ }
1012
+
1013
+
1014
+ /**
1015
+ * Detects if the current browser is the Native Android Tablet browser.
1016
+ * Assumes 'Android' should be in the user agent, but not 'mobile'
1017
+ *
1018
+ * @return boolean true if the browser is Android and not 'mobile' otherwise false
1019
+ */
1020
+ static function is_android_tablet( ) {
1021
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1022
+ return false;
1023
+
1024
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1025
+
1026
+ $pos_android = strpos( $agent, 'android' );
1027
+ $pos_mobile = strpos( $agent, 'mobile' );
1028
+ $post_android_app = strpos( $agent, 'wp-android' );
1029
+
1030
+ if ( $pos_android !== false && $pos_mobile === false && $post_android_app === false ) {
1031
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
1032
+ return false;
1033
+ else
1034
+ return true;
1035
+ } else
1036
+ return false;
1037
+ }
1038
+
1039
+ /**
1040
+ * Detects if the current browser is the Kindle Fire Native browser.
1041
+ *
1042
+ * Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-84) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true
1043
+ * Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-84) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=false
1044
+ *
1045
+ * @return boolean true if the browser is Kindle Fire Native browser otherwise false
1046
+ */
1047
+ static function is_kindle_fire( ) {
1048
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1049
+ return false;
1050
+
1051
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1052
+ $pos_silk = strpos( $agent, 'silk/' );
1053
+ $pos_silk_acc = strpos( $agent, 'silk-accelerated=' );
1054
+ if ( $pos_silk !== false && $pos_silk_acc !== false )
1055
+ return true;
1056
+ else
1057
+ return false;
1058
+ }
1059
+
1060
+
1061
+ /**
1062
+ * Detects if the current browser is the Kindle Touch Native browser
1063
+ *
1064
+ * Mozilla/5.0 (X11; U; Linux armv7l like Android; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/533.2+ Kindle/3.0+
1065
+ *
1066
+ * @return boolean true if the browser is Kindle monochrome Native browser otherwise false
1067
+ */
1068
+ static function is_kindle_touch( ) {
1069
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1070
+ return false;
1071
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1072
+ $pos_kindle_touch = strpos( $agent, 'kindle/3.0+' );
1073
+ if ( $pos_kindle_touch !== false && self::is_kindle_fire() === false )
1074
+ return true;
1075
+ else
1076
+ return false;
1077
+ }
1078
+
1079
+
1080
+ // Detect if user agent is the WordPress.com Windows 8 app (used ONLY on the custom oauth stylesheet)
1081
+ static function is_windows8_auth( ) {
1082
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1083
+ return false;
1084
+
1085
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1086
+ $pos = strpos( $agent, 'msauthhost' );
1087
+ if ( $pos !== false )
1088
+ return true;
1089
+ else
1090
+ return false;
1091
+ }
1092
+
1093
+ // Detect if user agent is the WordPress.com Windows 8 app.
1094
+ static function is_wordpress_for_win8( ) {
1095
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1096
+ return false;
1097
+
1098
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1099
+ $pos = strpos( $agent, 'wp-windows8' );
1100
+ if ( $pos !== false )
1101
+ return true;
1102
+ else
1103
+ return false;
1104
+ }
1105
+
1106
+
1107
+ /*
1108
+ * is_blackberry_tablet() can be used to check the User Agent for a RIM blackberry tablet
1109
+ * The user agent of the BlackBerry® Tablet OS follows a format similar to the following:
1110
+ * Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/0.0.1 Safari/534.8+
1111
+ *
1112
+ */
1113
+ static function is_blackberry_tablet() {
1114
+
1115
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1116
+ return false;
1117
+
1118
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1119
+ $pos_playbook = stripos( $agent, 'PlayBook' );
1120
+ $pos_rim_tablet = stripos( $agent, 'RIM Tablet' );
1121
+
1122
+ if ( ($pos_playbook === false) || ($pos_rim_tablet === false) )
1123
+ {
1124
+ return false;
1125
+ } else {
1126
+ return true;
1127
+ }
1128
+ }
1129
+
1130
+ /*
1131
+ is_blackbeberry() can be used to check the User Agent for a blackberry device
1132
+ Note that opera mini on BB matches this rule.
1133
+ */
1134
+ static function is_blackbeberry() {
1135
+
1136
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1137
+ return false;
1138
+
1139
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1140
+
1141
+ $pos_blackberry = strpos( $agent, 'blackberry' );
1142
+ if ( $pos_blackberry !== false ) {
1143
+ if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
1144
+ return false;
1145
+ else
1146
+ return true;
1147
+ } else {
1148
+ return false;
1149
+ }
1150
+ }
1151
+
1152
+ /*
1153
+ is_blackberry_10() can be used to check the User Agent for a BlackBerry 10 device.
1154
+ */
1155
+ static function is_blackberry_10() {
1156
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1157
+ return ( strpos( $agent, 'bb10' ) !== false ) && ( strpos( $agent, 'mobile' ) !== false );
1158
+ }
1159
+
1160
+ /**
1161
+ * Retrieve the blackberry OS version.
1162
+ *
1163
+ * Return strings are from the following list:
1164
+ * - blackberry-10
1165
+ * - blackberry-7
1166
+ * - blackberry-6
1167
+ * - blackberry-torch //only the first edition. The 2nd edition has the OS7 onboard and doesn't need any special rule.
1168
+ * - blackberry-5
1169
+ * - blackberry-4.7
1170
+ * - blackberry-4.6
1171
+ * - blackberry-4.5
1172
+ *
1173
+ * @return string Version of the BB OS.
1174
+ * If version is not found, get_blackbeberry_OS_version will return boolean false.
1175
+ */
1176
+ static function get_blackbeberry_OS_version() {
1177
+
1178
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1179
+ return false;
1180
+
1181
+ if ( self::is_blackberry_10() )
1182
+ return 'blackberry-10';
1183
+
1184
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1185
+
1186
+ $pos_blackberry = stripos( $agent, 'blackberry' );
1187
+ if ( $pos_blackberry === false ) {
1188
+ //not a blackberry device
1189
+ return false;
1190
+ }
1191
+
1192
+ //blackberry devices OS 6.0 or higher
1193
+ //Mozilla/5.0 (BlackBerry; U; BlackBerry 9670; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+
1194
+ //Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1+
1195
+ //Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0 Mobile Safari/534.11+
1196
+ $pos_webkit = stripos( $agent, 'webkit' );
1197
+ if ( $pos_webkit !== false ) {
1198
+ //detected blackberry webkit browser
1199
+ $pos_torch = stripos( $agent, 'BlackBerry 9800' );
1200
+ if ( $pos_torch !== false ) {
1201
+ return 'blackberry-torch'; //match the torch first edition. the 2nd edition should use the OS7 and doesn't need any special rule
1202
+ } else {
1203
+ //detecting the BB OS version for devices running OS 6.0 or higher
1204
+ if ( preg_match( '#Version\/([\d\.]+)#i', $agent, $matches ) ) {
1205
+ $version = $matches[1];
1206
+ $version_num = explode( '.', $version );
1207
+ if( is_array( $version_num ) === false || count( $version_num ) <= 1 )
1208
+ return 'blackberry-6'; //not a BB device that match our rule.
1209
+ else
1210
+ return 'blackberry-'.$version_num[0];
1211
+ } else {
1212
+ //if doesn't match returns the minimun version with a webkit browser. we should never fall here.
1213
+ return 'blackberry-6'; //not a BB device that match our rule.
1214
+ }
1215
+ }
1216
+ }
1217
+
1218
+ //blackberry devices <= 5.XX
1219
+ //BlackBerry9000/5.0.0.93 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/179
1220
+ if ( preg_match( '#BlackBerry\w+\/([\d\.]+)#i', $agent, $matches ) ) {
1221
+ $version = $matches[1];
1222
+ } else {
1223
+ return false; //not a BB device that match our rule.
1224
+ }
1225
+
1226
+ $version_num = explode( '.', $version );
1227
+
1228
+ if( is_array( $version_num ) === false || count( $version_num ) <= 1 )
1229
+ return false;
1230
+ if ( $version_num[0] == 5 ) {
1231
+ return 'blackberry-5';
1232
+ } elseif ( $version_num[0] == 4 && $version_num[1] == 7 ) {
1233
+ return 'blackberry-4.7';
1234
+ } elseif ( $version_num[0] == 4 && $version_num[1] == 6 ) {
1235
+ return 'blackberry-4.6';
1236
+ } elseif ( $version_num[0] == 4 && $version_num[1] == 5 ) {
1237
+ return 'blackberry-4.5';
1238
+ } else {
1239
+ return false;
1240
+ }
1241
+
1242
+ return false;
1243
+ }
1244
+
1245
+ /**
1246
+ * Retrieve the blackberry browser version.
1247
+ *
1248
+ * Return string are from the following list:
1249
+ * - blackberry-10
1250
+ * - blackberry-webkit
1251
+ * - blackberry-5
1252
+ * - blackberry-4.7
1253
+ * - blackberry-4.6
1254
+ *
1255
+ * @return string Type of the BB browser.
1256
+ * If browser's version is not found, detect_blackbeberry_browser_version will return boolean false.
1257
+ */
1258
+ static function detect_blackberry_browser_version() {
1259
+
1260
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1261
+ return false;
1262
+
1263
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1264
+
1265
+ if ( self::is_blackberry_10() )
1266
+ return 'blackberry-10';
1267
+
1268
+ $pos_blackberry = strpos( $agent, 'blackberry' );
1269
+ if ( $pos_blackberry === false ) {
1270
+ //not a blackberry device
1271
+ return false;
1272
+ }
1273
+
1274
+ $pos_webkit = strpos( $agent, 'webkit' );
1275
+
1276
+ if ( ! ( $pos_webkit === false ) ) {
1277
+ return 'blackberry-webkit';
1278
+ } else {
1279
+ if ( preg_match( '#BlackBerry\w+\/([\d\.]+)#i', $agent, $matches ) ) {
1280
+ $version = $matches[1];
1281
+ } else {
1282
+ return false; //not a BB device that match our rule.
1283
+ }
1284
+
1285
+ $version_num = explode( '.', $version );
1286
+
1287
+ if( is_array( $version_num ) === false || count( $version_num ) <= 1 )
1288
+ return false;
1289
+
1290
+ if ( $version_num[0] == 5 ) {
1291
+ return 'blackberry-5';
1292
+ } elseif ( $version_num[0] == 4 && $version_num[1] == 7 ) {
1293
+ return 'blackberry-4.7';
1294
+ } elseif ( $version_num[0] == 4 && $version_num[1] == 6 ) {
1295
+ return 'blackberry-4.6';
1296
+ } else {
1297
+ //A very old BB device is found or this is a BB device that doesn't match our rules.
1298
+ return false;
1299
+ }
1300
+ }
1301
+ return false;
1302
+ }
1303
+
1304
+ //Checks if a visitor is coming from one of the WordPress mobile apps
1305
+ static function is_mobile_app() {
1306
+
1307
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1308
+ return false;
1309
+
1310
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1311
+
1312
+ if ( isset( $_SERVER['X_USER_AGENT'] ) && preg_match( '|wp-webos|', $_SERVER['X_USER_AGENT'] ) )
1313
+ return true; //wp4webos 1.1 or higher
1314
+
1315
+ $app_agents = array( 'wp-android', 'wp-blackberry', 'wp-iphone', 'wp-nokia', 'wp-webos', 'wp-windowsphone' );
1316
+ // the mobile reader on iOS has an incorrect UA when loading the reader
1317
+ // currently it is the default one provided by the iOS framework which
1318
+ // causes problems with 2-step-auth
1319
+ // User-Agent WordPress/3.1.4 CFNetwork/609 Darwin/13.0.0
1320
+ $app_agents[] = 'wordpress/3.1';
1321
+
1322
+ foreach ( $app_agents as $app_agent ) {
1323
+ if ( false !== strpos( $agent, $app_agent ) )
1324
+ return true;
1325
+ }
1326
+ return false;
1327
+ }
1328
+
1329
+ static function is_bot() {
1330
+ static $is_bot = false;
1331
+ static $first_run = true;
1332
+
1333
+ if ( $first_run ) {
1334
+ $first_run = false;
1335
+
1336
+ /*
1337
+ $bot_ips = array( );
1338
+
1339
+ foreach ( $bot_ips as $bot_ip ) {
1340
+ if ( $_SERVER['REMOTE_ADDR'] == $bot_ip )
1341
+ $is_bot = true;
1342
+ }
1343
+ */
1344
+
1345
+ $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1346
+
1347
+ $bot_agents = array(
1348
+ 'alexa', 'altavista', 'ask jeeves', 'attentio', 'baiduspider', 'bingbot', 'chtml generic', 'crawler', 'fastmobilecrawl',
1349
+ 'feedfetcher-google', 'firefly', 'froogle', 'gigabot', 'googlebot', 'googlebot-mobile', 'heritrix', 'ia_archiver', 'irlbot',
1350
+ 'infoseek', 'jumpbot', 'lycos', 'mediapartners', 'mediobot', 'motionbot', 'msnbot', 'mshots', 'openbot',
1351
+ 'pythumbnail', 'scooter', 'slurp', 'snapbot', 'spider', 'surphace scout', 'taptubot', 'technoratisnoop',
1352
+ 'teoma', 'twiceler', 'yahooseeker', 'yahooysmcm', 'yammybot',
1353
+ );
1354
+
1355
+ foreach ( $bot_agents as $bot_agent ) {
1356
+ if ( false !== strpos( $agent, $bot_agent ) )
1357
+ $is_bot = true;
1358
+ }
1359
+ }
1360
+
1361
+ return $is_bot;
1362
+ }
1363
+ }
trunk/functions.gallery.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Renders extra controls in the Gallery Settings section of the new media UI.
5
+ */
6
+ class themePacific_Jetpack_Gallery_Settings {
7
+ function __construct() {
8
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
9
+ }
10
+
11
+ function admin_init() {
12
+ $this->gallery_types = apply_filters( 'jetpack_gallery_types', array( 'default' => __( 'Thumbnail Grid', 'themepacific_gallery' ) ) );
13
+
14
+ // Enqueue the media UI only if needed.
15
+ if ( count( $this->gallery_types ) > 1 ) {
16
+ add_action( 'wp_enqueue_media', array( $this, 'wp_enqueue_media' ) );
17
+ add_action( 'print_media_templates', array( $this, 'print_media_templates' ) );
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Registers/enqueues the gallery settings admin js.
23
+ */
24
+ function wp_enqueue_media() {
25
+ if ( ! wp_script_is( 'jetpack-gallery-settings', 'registered' ) )
26
+ wp_register_script( 'jetpack-gallery-settings', plugins_url( 'gallery-settings.js', __FILE__ ), array( 'media-views' ), '20121225' );
27
+
28
+ wp_enqueue_script( 'jetpack-gallery-settings' );
29
+ }
30
+
31
+ /**
32
+ * Outputs a view template which can be used with wp.media.template
33
+ */
34
+ function print_media_templates() {
35
+ $default_gallery_type = apply_filters( 'jetpack_default_gallery_type', 'default' );
36
+
37
+ ?>
38
+ <script type="text/html" id="tmpl-jetpack-gallery-settings">
39
+ <label class="setting">
40
+ <span><?php _e( 'Type', 'themepacific_gallery' ); ?></span>
41
+ <select class="type" name="type" data-setting="type">
42
+ <?php foreach ( $this->gallery_types as $value => $caption ) : ?>
43
+ <option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $default_gallery_type ); ?>><?php echo esc_html( $caption ); ?></option>
44
+ <?php endforeach; ?>
45
+ </select>
46
+ </label>
47
+ </script>
48
+ <?php
49
+ }
50
+ }
51
+ new themePacific_Jetpack_Gallery_Settings;
trunk/gallery-settings.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Jetpack Gallery Settings
3
+ */
4
+ (function($) {
5
+ var media = wp.media;
6
+
7
+ // Wrap the render() function to append controls.
8
+ media.view.Settings.Gallery = media.view.Settings.Gallery.extend({
9
+ render: function() {
10
+ var $el = this.$el;
11
+
12
+ media.view.Settings.prototype.render.apply( this, arguments );
13
+
14
+ // Append the type template and update the settings.
15
+ $el.append( media.template( 'jetpack-gallery-settings' ) );
16
+ media.gallery.defaults.type = 'default'; // lil hack that lets media know there's a type attribute.
17
+ this.update.apply( this, ['type'] );
18
+
19
+ // Hide the Columns setting for all types except Default
20
+ $el.find( 'select[name=type]' ).on( 'change', function () {
21
+ var columnSetting = $el.find( 'select[name=columns]' ).closest( 'label.setting' );
22
+
23
+ if ( 'default' == $( this ).val() )
24
+ columnSetting.show();
25
+ else
26
+ columnSetting.hide();
27
+ } ).change();
28
+
29
+ return this;
30
+ }
31
+ });
32
+ })(jQuery);
trunk/images/arrows-2x.png ADDED
Binary file
trunk/images/arrows.png ADDED
Binary file
trunk/images/carousel-likereblog-2x.png ADDED
Binary file
trunk/images/carousel-likereblog.png ADDED
Binary file
trunk/images/carousel-link-2x.png ADDED
Binary file
trunk/images/carousel-link.png ADDED
Binary file
trunk/images/carousel-sprite-2x.png ADDED
Binary file
trunk/images/carousel-sprite.png ADDED
Binary file
trunk/jetpack-carousel-ie8fix.css ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ .jp-carousel .jp-carousel-slide {
2
+ display: none !important;
3
+ }
4
+
5
+ .jp-carousel .selected {
6
+ margin: 0 auto;
7
+ display: block !important;
8
+ }
trunk/jetpack-carousel.css ADDED
@@ -0,0 +1,1104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-fadeaway {
10
+ background: -moz-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0));
11
+ background: -webkit-gradient(linear, left bottom, left top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0)));
12
+ position: fixed;
13
+ bottom: 0;
14
+ z-index: 2147483647;
15
+ width: 100%;
16
+ height: 15px;
17
+ }
18
+
19
+ .jp-carousel-next-button span,
20
+ .jp-carousel-previous-button span {
21
+ background: url(./images/arrows.png) no-repeat center center;
22
+ background-size: 200px 126px;
23
+ }
24
+
25
+ @media
26
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
27
+ only screen and (-o-min-device-pixel-ratio: 3/2),
28
+ only screen and (min--moz-device-pixel-ratio: 1.5),
29
+ only screen and (min-device-pixel-ratio: 1.5) {
30
+ .jp-carousel-next-button span,
31
+ .jp-carousel-previous-button span {
32
+ background-image: url(./images/arrows-2x.png);
33
+ }
34
+ }
35
+
36
+ .jp-carousel-wrap {
37
+ font-family: "Helvetica Neue", sans-serif !important;
38
+ }
39
+
40
+ .jp-carousel-info {
41
+ position: absolute;
42
+ bottom: 0;
43
+ text-align: left !important;
44
+ -webkit-font-smoothing: subpixel-antialiased !important;
45
+ }
46
+
47
+ .jp-carousel-info ::selection {
48
+ background: #68c9e8; /* Safari */
49
+ color: #fff;
50
+ }
51
+
52
+ .jp-carousel-info ::-moz-selection {
53
+ background: #68c9e8; /* Firefox */
54
+ color: #fff;
55
+ }
56
+
57
+ .jp-carousel-photo-info {
58
+ position: relative;
59
+ -webkit-transition: 400ms ease-out;
60
+ -moz-transition: 400ms ease-out;
61
+ -o-transition: 400ms ease-out;
62
+ transition: 400ms ease-out;
63
+ left: 25%;
64
+ width: 50%;
65
+ }
66
+
67
+ .jp-carousel-info h2 {
68
+ background: none !important;
69
+ border: none !important;
70
+ color: #999;
71
+ display: block !important;
72
+ font: normal 13px/1.25em "Helvetica Neue", sans-serif !important;
73
+ letter-spacing: 0 !important;
74
+ margin: 7px 0 0 0 !important;
75
+ padding: 10px 0 0 !important;
76
+ overflow: hidden;
77
+ text-align: left;
78
+ text-shadow: none !important;
79
+ text-transform: none !important;
80
+ -webkit-font-smoothing: subpixel-antialiased;
81
+ }
82
+
83
+ .jp-carousel-next-button,
84
+ .jp-carousel-previous-button {
85
+ text-indent: -9999px;
86
+ overflow: hidden;
87
+ cursor: pointer;
88
+ }
89
+
90
+ .jp-carousel-next-button span,
91
+ .jp-carousel-previous-button span {
92
+ position: absolute;
93
+ top: 0;
94
+ bottom: 0;
95
+ width: 82px;
96
+ zoom: 1;
97
+ filter: alpha(opacity=20);
98
+ opacity: 0.2;
99
+ -webkit-transition: 500ms opacity ease-out;
100
+ -moz-transition: 500ms opacity ease-out;
101
+ -o-transition: 500ms opacity ease-out;
102
+ transition: 500ms opacity ease-out;
103
+ }
104
+
105
+ .jp-carousel-next-button:hover span,
106
+ .jp-carousel-previous-button:hover span {
107
+ filter: alpha(opacity=60);
108
+ opacity: 0.6;
109
+ }
110
+ .jp-carousel-next-button span {
111
+ background-position: -110px center;
112
+ right: 0;
113
+ }
114
+
115
+ .jp-carousel-previous-button span {
116
+ background-position: -10px center;
117
+ left:0;
118
+ }
119
+
120
+ .jp-carousel-buttons {
121
+ margin:-18px -20px 15px;
122
+ padding:8px 10px;
123
+ border-bottom:1px solid #222;
124
+ background: #222;
125
+ text-align: center;
126
+ }
127
+
128
+ div.jp-carousel-buttons a {
129
+ border: none !important;
130
+ color: #999;
131
+ font: normal 11px/1.2em "Helvetica Neue", sans-serif !important;
132
+ letter-spacing: 0 !important;
133
+ padding: 5px 2px 5px 0;
134
+ text-decoration: none !important;
135
+ text-shadow: none !important;
136
+ vertical-align: middle;
137
+ -webkit-font-smoothing: subpixel-antialiased;
138
+ }
139
+
140
+ div.jp-carousel-buttons a:hover {
141
+ color: #68c9e8;
142
+ border: none !important;
143
+ -webkit-transition: none !important;
144
+ -moz-transition: none !important;
145
+ -o-transition: none !important;
146
+ transition: none !important;
147
+ }
148
+
149
+ .jp-carousel-slide, .jp-carousel-slide img, .jp-carousel-next-button,
150
+ .jp-carousel-previous-button {
151
+ -webkit-transform:translate3d(0, 0, 0);
152
+ -moz-transform:translate3d(0, 0, 0);
153
+ -o-transform:translate3d(0, 0, 0);
154
+ -ms-transform:translate3d(0, 0, 0);
155
+ }
156
+
157
+ .jp-carousel-slide {
158
+ position:absolute;
159
+ width:0;
160
+ bottom:0;
161
+ background-color:#000;
162
+ border-radius:2px;
163
+ -webkit-border-radius:2px;
164
+ -moz-border-radius:2px;
165
+ -ms-border-radius:2px;
166
+ -o-border-radius:2px;
167
+ -webkit-transition: 400ms ease-out;
168
+ -moz-transition: 400ms ease-out;
169
+ -o-transition: 400ms ease-out;
170
+ transition: 400ms ease-out;
171
+ }
172
+
173
+ .jp-carousel-slide img {
174
+ display: block;
175
+ width: 100% !important;
176
+ height: 100% !important;
177
+ max-width: 100% !important;
178
+ max-height: 100% !important;
179
+ background: none !important;
180
+ border: none !important;
181
+ padding: 0 !important;
182
+ -webkit-box-shadow: 0 2px 8px rgba(0,0,0,0.1);
183
+ -moz-box-shadow: 0 2px 8px rgba(0,0,0,0.1);
184
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
185
+ zoom: 1;
186
+ filter: alpha(opacity=25);
187
+ opacity: 0.25;
188
+ -webkit-transition: opacity 400ms linear;
189
+ -moz-transition: opacity 400ms linear;
190
+ -o-transition: opacity 400ms linear;
191
+ transition: opacity 400ms linear;
192
+ }
193
+
194
+ .jp-carousel-slide.selected img {
195
+ filter: alpha(opacity=100);
196
+ opacity: 1;
197
+ }
198
+
199
+ .jp-carousel-close-hint {
200
+ color: #999;
201
+ cursor: default;
202
+ letter-spacing: 0 !important;
203
+ padding:0.35em 0 0;
204
+ position: absolute;
205
+ text-align: left;
206
+ width: 90%;
207
+ -webkit-transition: color 200ms linear;
208
+ -moz-transition: color 200ms linear;
209
+ -o-transition: color 200ms linear;
210
+ transition: color 200ms linear;
211
+ }
212
+
213
+ .jp-carousel-close-hint span {
214
+ cursor: pointer;
215
+ background-color: black;
216
+ background-color: rgba(0,0,0,0.8);
217
+ display: block;
218
+ height: 22px;
219
+ font: 400 24px/1 "Helvetica Neue", sans-serif !important;
220
+ line-height: 22px;
221
+ margin: 0 0 0 0.4em;
222
+ text-align: center;
223
+ vertical-align: middle;
224
+ width: 22px;
225
+ -moz-border-radius: 4px;
226
+ -webkit-border-radius: 4px;
227
+ border-radius: 4px;
228
+ -webkit-transition: border-color 200ms linear;
229
+ -moz-transition: border-color 200ms linear;
230
+ -o-transition: border-color 200ms linear;
231
+ transition: border-color 200ms linear;
232
+ }
233
+
234
+ .jp-carousel-close-hint:hover {
235
+ cursor: default;
236
+ color: #fff;
237
+ }
238
+
239
+ .jp-carousel-close-hint:hover span {
240
+ border-color: #fff;
241
+ }
242
+
243
+ div.jp-carousel-buttons a.jp-carousel-like,
244
+ div.jp-carousel-buttons a.jp-carousel-reblog,
245
+ div.jp-carousel-buttons a.jp-carousel-commentlink,
246
+ a.jp-carousel-image-download {
247
+ background: url(./images/carousel-sprite.png?4) no-repeat;
248
+ background-size: 16px 160px;
249
+ }
250
+
251
+ div.jp-carousel-buttons a.jp-carousel-reblog,
252
+ div.jp-carousel-buttons a.jp-carousel-commentlink {
253
+ margin:0 14px 0 0 !important;
254
+ }
255
+
256
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged,
257
+ div.jp-carousel-buttons a.jp-carousel-like.liked {
258
+ background-color: #303030;
259
+ padding-right: 8px !important;
260
+ border-radius: 2px;
261
+ border-radius:2px;
262
+ -webkit-border-radius:2px;
263
+ -moz-border-radius:2px;
264
+ -ms-border-radius:2px;
265
+ -o-border-radius:2px;
266
+ }
267
+
268
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged {
269
+ margin:0 2px 0 -12px !important;
270
+ }
271
+
272
+
273
+ div.jp-carousel-buttons a.jp-carousel-reblog,
274
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged:hover {
275
+ background-position: 6px -36px;
276
+ padding-left: 26px !important;
277
+ color: #999;
278
+ }
279
+
280
+ div.jp-carousel-buttons a.jp-carousel-commentlink {
281
+ background-position: 0px -116px;
282
+ padding-left: 19px !important;
283
+ }
284
+
285
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged:hover {
286
+ cursor: default;
287
+ }
288
+
289
+ div.jp-carousel-buttons a.jp-carousel-reblog:hover {
290
+ background-position: 6px -56px;
291
+ color: #68c9e8;
292
+ }
293
+
294
+ div.jp-carousel-buttons a.jp-carousel-like {
295
+ background-position: 5px 5px;
296
+ padding-left: 24px !important;
297
+ }
298
+
299
+ div.jp-carousel-buttons a.jp-carousel-like:hover {
300
+ background-position: 5px -15px;
301
+ }
302
+
303
+ @media
304
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
305
+ only screen and (-o-min-device-pixel-ratio: 3/2),
306
+ only screen and (min--moz-device-pixel-ratio: 1.5),
307
+ only screen and (min-device-pixel-ratio: 1.5) {
308
+ div.jp-carousel-buttons a.jp-carousel-like,
309
+ div.jp-carousel-buttons a.jp-carousel-reblog,
310
+ div.jp-carousel-buttons a.jp-carousel-commentlink,
311
+ a.jp-carousel-image-download {
312
+ background-image: url(./images/carousel-sprite-2x.png?4);
313
+ }
314
+ }
315
+
316
+ /* reblog */
317
+ div#carousel-reblog-box {
318
+ background: #222;
319
+ background: -moz-linear-gradient(bottom, #222, #333);
320
+ background: -webkit-gradient(linear, left bottom, left top, from(#222), to(#333));
321
+ padding: 3px 0 0;
322
+ display: none;
323
+ margin: 5px auto 0;
324
+ -moz-border-radius: 2px;
325
+ -webkit-border-radius: 2px;
326
+ border-radius: 2px;
327
+ -webkit-box-shadow: 0 0 20px rgba(0,0,0,0.9);
328
+ -moz-box-shadow: 0 0 20px rgba(0,0,0,0.9);
329
+ box-shadow: 0 0 20px rgba(0,0,0,0.9);
330
+ height: 74px;
331
+ width: 565px;
332
+ }
333
+
334
+ #carousel-reblog-box textarea {
335
+ background: #999;
336
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
337
+ color: #444;
338
+ padding: 3px 6px;
339
+ width: 370px;
340
+ height: 48px;
341
+ float: left;
342
+ margin: 6px 9px 0 9px;
343
+ border: 1px solid #666;
344
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
345
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
346
+ -moz-border-radius: 2px;
347
+ -webkit-border-radius: 2px;
348
+ border-radius: 2px;
349
+ }
350
+
351
+ #carousel-reblog-box textarea:focus {
352
+ background: #ccc;
353
+ color: #222;
354
+ }
355
+
356
+ #carousel-reblog-box label {
357
+ color: #aaa;
358
+ font-size: 11px;
359
+ padding-right: 2px;
360
+ padding-left: 2px;
361
+ display: inline;
362
+ font-weight: normal;
363
+ }
364
+
365
+ #carousel-reblog-box select {
366
+ width: 110px;
367
+ padding: 0;
368
+ font-size: 12px;
369
+ font-family: "Helvetica Neue", sans-serif !important;
370
+ background: #333;
371
+ color: #eee;
372
+ border: 1px solid #444;
373
+ margin-top:5px;
374
+ }
375
+
376
+ #carousel-reblog-box .submit,
377
+ #wrapper #carousel-reblog-box p.response {
378
+ float: left;
379
+ width: 154px;
380
+ padding-top: 0;
381
+ padding-left: 1px;
382
+ overflow: hidden;
383
+ height: 34px;
384
+ margin:3px 0 0 2px !important;
385
+ }
386
+
387
+ #wrapper #carousel-reblog-box p.response {
388
+ font-size: 13px;
389
+ clear: none;
390
+ padding-left: 2px;
391
+ height: 34px;
392
+ color: #aaa;
393
+ }
394
+
395
+ #carousel-reblog-box input#carousel-reblog-submit, #jp-carousel-comment-form-button-submit {
396
+ font: 13px/24px "Helvetica Neue", sans-serif !important;
397
+ margin-top: 8px;
398
+ padding: 0 10px !important;
399
+ border-radius: 1em;
400
+ height: 24px;
401
+ color: #333;
402
+ cursor:pointer;
403
+ font-weight: normal;
404
+ background: #aaa;
405
+ background: -moz-linear-gradient(bottom, #aaa, #ccc);
406
+ background: -webkit-gradient(linear, left bottom, left top, from(#aaa), to(#ccc));
407
+ border: 1px solid #444;
408
+ }
409
+
410
+ #carousel-reblog-box input#carousel-reblog-submit:hover, #jp-carousel-comment-form-button-submit:hover {
411
+ background: #ccc;
412
+ background: -moz-linear-gradient(bottom, #ccc, #eee);
413
+ background: -webkit-gradient(linear, left bottom, left top, from(#ccc), to(#eee));
414
+ }
415
+
416
+ #carousel-reblog-box .canceltext {
417
+ color: #aaa;
418
+ font-size: 11px;
419
+ line-height: 24px;
420
+ }
421
+
422
+ #carousel-reblog-box .canceltext a {
423
+ color: #fff;
424
+ }
425
+ /* reblog end */
426
+
427
+
428
+ /** Title and Desc Start **/
429
+ .jp-carousel-titleanddesc {
430
+ border-top: 1px solid #222;
431
+ color: #999;
432
+ font-size: 15px;
433
+ padding-top: 24px;
434
+ margin-bottom: 20px;
435
+ font-weight:400;
436
+ }
437
+ .jp-carousel-titleanddesc-title {
438
+ font: 300 1.5em/1.1 "Helvetica Neue", sans-serif !important;
439
+ text-transform: none !important; /* prevents uppercase from leaking through */
440
+ color: #fff;
441
+ margin: 0 0 15px;
442
+ padding:0;
443
+ }
444
+
445
+ .jp-carousel-titleanddesc-desc p {
446
+ color: #999;
447
+ line-height:1.4;
448
+ margin-bottom: 0.75em;
449
+ }
450
+
451
+ .jp-carousel-titleanddesc p a,
452
+ .jp-carousel-comments p a,
453
+ .jp-carousel-info h2 a {
454
+ color: #fff !important;
455
+ border: none !important;
456
+ text-decoration: underline !important;
457
+ font-weight: normal !important;
458
+ font-style: normal !important;
459
+ }
460
+
461
+ .jp-carousel-titleanddesc p strong,
462
+ .jp-carousel-titleanddesc p b {
463
+ font-weight: bold;
464
+ color: #999;
465
+ }
466
+
467
+ .jp-carousel-titleanddesc p em,
468
+ .jp-carousel-titleanddesc p i {
469
+ font-style: italic;
470
+ color: #999;
471
+ }
472
+
473
+
474
+ .jp-carousel-titleanddesc p a:hover,
475
+ .jp-carousel-comments p a:hover,
476
+ .jp-carousel-info h2 a:hover {
477
+ color: #68c9e8 !important;
478
+ }
479
+
480
+ .jp-carousel-titleanddesc p:empty {
481
+ display: none;
482
+ }
483
+
484
+ .jp-carousel-photo-info h1:before,
485
+ .jp-carousel-photo-info h1:after,
486
+ .jp-carousel-left-column-wrapper h1:before,
487
+ .jp-carousel-left-column-wrapper 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
+ border: 1px solid #222;
496
+ color: #fff;
497
+ font-size: 13px;
498
+ font: 12px/1.4 "Helvetica Neue", sans-serif !important;
499
+ overflow: hidden;
500
+ padding: 18px 20px;
501
+ width: 209px !important;
502
+ }
503
+
504
+ .jp-carousel-image-meta li,
505
+ .jp-carousel-image-meta h5 {
506
+ font-family: "Helvetica Neue", sans-serif !important;
507
+ position: inherit !important;
508
+ top: auto !important;
509
+ right: auto !important;
510
+ left: auto !important;
511
+ bottom: auto !important;
512
+ background: none !important;
513
+ border: none !important;
514
+ font-weight: 400 !important;
515
+ line-height: 1.3em !important;
516
+ }
517
+
518
+ .jp-carousel-image-meta ul {
519
+ margin: 0 !important;
520
+ padding: 0 !important;
521
+ list-style: none !important;
522
+ }
523
+
524
+ .jp-carousel-image-meta li {
525
+ width: 48% !important;
526
+ float: left !important;
527
+ margin: 0 2% 15px 0 !important;
528
+ color: #fff !important;
529
+ font-size:13px !important;
530
+ }
531
+
532
+ .jp-carousel-image-meta h5 {
533
+ color: #999 !important;
534
+ text-transform: uppercase !important;
535
+ font-size:10px !important;
536
+ margin:0 0 2px !important;
537
+ letter-spacing: 0.1em !important;
538
+ }
539
+
540
+ a.jp-carousel-image-download {
541
+ padding-left: 23px;
542
+ display: inline-block;
543
+ clear: both;
544
+ color: #999;
545
+ line-height: 1;
546
+ font-weight: 400;
547
+ font-size: 13px;
548
+ text-decoration: none;
549
+ background-position: 0 -82px;
550
+ }
551
+
552
+ a.jp-carousel-image-download span.photo-size {
553
+ font-size: 11px;
554
+ border-radius: 1em;
555
+ margin-left: 2px;
556
+ display: inline-block;
557
+ }
558
+
559
+ a.jp-carousel-image-download span.photo-size-times {
560
+ padding: 0 1px 0 2px;
561
+ }
562
+
563
+ a.jp-carousel-image-download:hover {
564
+ background-position: 0 -102px;
565
+ color: #68c9e8;
566
+ border: none !important;
567
+ }
568
+
569
+ /** Meta Box End **/
570
+
571
+ /** GPS Map Start **/
572
+ .jp-carousel-image-map {
573
+ position: relative;
574
+ margin: -20px -20px 20px;
575
+ border-bottom: 1px solid rgba( 255, 255, 255, 0.17 );
576
+ height: 154px;
577
+ }
578
+
579
+ .jp-carousel-image-map img.gmap-main {
580
+ -moz-border-radius-topleft: 6px;
581
+ border-top-left-radius: 6px;
582
+ border-right: 1px solid rgba( 255, 255, 255, 0.17 );
583
+ }
584
+ .jp-carousel-image-map div.gmap-topright {
585
+ width: 94px;
586
+ height: 154px;
587
+ position: absolute;
588
+ top: 0;
589
+ right: 0;
590
+ }
591
+ .jp-carousel-image-map div.imgclip {
592
+ overflow: hidden;
593
+ -moz-border-radius-topright: 6px;
594
+ border-top-right-radius: 6px;
595
+ }
596
+ .jp-carousel-image-map div.gmap-topright img {
597
+ margin-left: -40px;
598
+ }
599
+ .jp-carousel-image-map img.gmap-bottomright {
600
+ position: absolute;
601
+ top: 96px;
602
+ right: 0;
603
+ }
604
+
605
+ /** Comments Start **/
606
+ .jp-carousel-comments {
607
+ font: 15px/1.7 "Helvetica Neue", sans-serif !important;
608
+ font-weight: 400;
609
+ background:none transparent;
610
+ }
611
+
612
+ .jp-carousel-comments p a:hover, .jp-carousel-comments p a:focus, .jp-carousel-comments p a:active {
613
+ color: #68c9e8 !important;
614
+ }
615
+
616
+ .jp-carousel-comment {
617
+ background:none transparent;
618
+ color: #999;
619
+ margin-bottom: 20px;
620
+ clear:left;
621
+ overflow: auto;
622
+ width: 100%
623
+ }
624
+
625
+ .jp-carousel-comment p {
626
+ color: #999 !important;
627
+ }
628
+
629
+ .jp-carousel-comment .comment-author {
630
+ font-size: 13px;
631
+ font-weight:400;
632
+ padding:0;
633
+ width:auto;
634
+ display: inline;
635
+ float:none;
636
+ border:none;
637
+ margin:0;
638
+ }
639
+
640
+ .jp-carousel-comment .comment-author a {
641
+ color: #fff;
642
+ }
643
+
644
+ .jp-carousel-comment .comment-gravatar {
645
+ float:left;
646
+ }
647
+
648
+ .jp-carousel-comment .comment-content {
649
+ border:none;
650
+ margin-left:85px;
651
+ padding: 0;
652
+ }
653
+
654
+ .jp-carousel-comment .avatar {
655
+ margin:0 20px 0 0;
656
+ -moz-border-radius: 4px;
657
+ -webkit-border-radius: 4px;
658
+ border-radius: 4px;
659
+ border: none !important;
660
+ padding: 0 !important;
661
+ background-color: transparent !important;
662
+ }
663
+
664
+ .jp-carousel-comment .comment-date {
665
+ color:#999;
666
+ margin-top: 4px;
667
+ font-size:11px;
668
+ display: inline;
669
+ float: right;
670
+ /*clear: right;*/
671
+ }
672
+
673
+ #jp-carousel-comment-form {
674
+ margin:0 0 10px !important;
675
+ float: left;
676
+ width: 100%;
677
+ }
678
+
679
+ textarea#jp-carousel-comment-form-comment-field {
680
+ background: rgba(34,34,34,0.9);
681
+ border: 1px solid #3a3a3a;
682
+ color: #aaa;
683
+ font: 15px/1.4 "Helvetica Neue", sans-serif !important;
684
+ width: 100%;
685
+ padding: 10px 10px 5px;
686
+ margin: 0;
687
+ float: none;
688
+ height: 147px;
689
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
690
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
691
+ -moz-border-radius: 3px;
692
+ -webkit-border-radius: 3px;
693
+ border-radius: 3px;
694
+ overflow: hidden;
695
+ -webkit-box-sizing: border-box;
696
+ -moz-box-sizing: border-box;
697
+ box-sizing: border-box;
698
+ }
699
+
700
+ textarea#jp-carousel-comment-form-comment-field::-webkit-input-placeholder {
701
+ color: #555;
702
+ }
703
+
704
+ textarea#jp-carousel-comment-form-comment-field:focus {
705
+ background: #ccc;
706
+ color: #222;
707
+ }
708
+
709
+ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder {
710
+ color: #aaa;
711
+ }
712
+
713
+ #jp-carousel-comment-form-spinner {
714
+ color: #fff;
715
+ margin:22px 0 0 10px;
716
+ display: block;
717
+ width: 20px;
718
+ height: 20px;
719
+ float: left;
720
+ }
721
+
722
+ #jp-carousel-comment-form-submit-and-info-wrapper {
723
+ display: none;
724
+ /*margin-bottom:15px;*/
725
+ overflow: hidden;
726
+ width: 100%
727
+ }
728
+
729
+ #jp-carousel-comment-form-commenting-as {
730
+ }
731
+
732
+ #jp-carousel-comment-form-commenting-as input {
733
+ background: rgba(34,34,34,0.9);
734
+ border: 1px solid #3a3a3a;
735
+ color: #aaa;
736
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
737
+ padding: 3px 6px;
738
+ float: left;
739
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
740
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
741
+ -moz-border-radius: 2px;
742
+ -webkit-border-radius: 2px;
743
+ border-radius: 2px;
744
+ width:285px;
745
+ }
746
+
747
+ #jp-carousel-comment-form-commenting-as input:focus {
748
+ background: #ccc;
749
+ color: #222;
750
+ }
751
+
752
+ #jp-carousel-comment-form-commenting-as p {
753
+ font: 400 13px/1.7 "Helvetica Neue", sans-serif !important;
754
+ margin:22px 0 0;
755
+ float: left;
756
+ }
757
+
758
+ #jp-carousel-comment-form-commenting-as fieldset {
759
+ float:left;
760
+ border:none;
761
+ margin:20px 0 0 0;
762
+ padding:0;
763
+ }
764
+
765
+ #jp-carousel-comment-form-commenting-as fieldset {
766
+ clear: both;
767
+ }
768
+
769
+ #jp-carousel-comment-form-commenting-as label {
770
+ font: 400 13px/1.7 "Helvetica Neue", sans-serif !important;
771
+ margin:0 20px 3px 0;
772
+ float:left;
773
+ width:100px;
774
+ }
775
+
776
+ #jp-carousel-comment-form-button-submit {
777
+ margin-top: 20px;
778
+ float:right;
779
+ }
780
+
781
+ #js-carousel-comment-form-container {
782
+ margin-bottom:15px;
783
+ overflow: auto;
784
+ width: 100%;
785
+ }
786
+
787
+ #jp-carousel-comment-form-container {
788
+ margin-bottom:15px;
789
+ overflow: auto;
790
+ width: 100%;
791
+ }
792
+
793
+ #jp-carousel-comment-post-results {
794
+ display: none;
795
+ overflow:auto;
796
+ width:100%;
797
+ }
798
+
799
+ #jp-carousel-comment-post-results span {
800
+ display:block;
801
+ text-align: center;
802
+ margin-top:20px;
803
+ width: 100%;
804
+ overflow: auto;
805
+ padding: 1em 0;
806
+ box-sizing: border-box;
807
+ background: rgba( 0, 0, 0, 0.7 );
808
+ border-radius: 2px;
809
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
810
+ border: 1px solid rgba( 255, 255, 255, 0.17 );
811
+ -webkit-box-shadow: inset 0px 0px 5px 5px rgba(0, 0, 0, 1);
812
+ box-shadow: inset 0px 0px 5px 5px rgba(0, 0, 0, 1);
813
+ }
814
+
815
+ .jp-carousel-comment-post-error {
816
+ color:#DF4926;
817
+ }
818
+
819
+ .jp-carousel-comment-post-success {
820
+ /*color:#21759B;*/
821
+ }
822
+
823
+ #jp-carousel-comments-closed {
824
+ display: none;
825
+ color: #999;
826
+ }
827
+
828
+ #jp-carousel-comments-loading {
829
+ font: 444 15px/1.7 "Helvetica Neue", sans-serif !important;
830
+ display: none;
831
+ color: #999;
832
+ text-align: left;
833
+ margin-bottom: 20px;
834
+ }
835
+
836
+
837
+ /* ----- Light variant ----- */
838
+
839
+ .jp-carousel-light .jp-carousel-overlay {
840
+ background: #fff;
841
+ }
842
+
843
+ .jp-carousel-light .jp-carousel-next-button:hover span,
844
+ .jp-carousel-light .jp-carousel-previous-button:hover span {
845
+ opacity: 0.8;
846
+ }
847
+
848
+ .jp-carousel-light .jp-carousel-close-hint:hover,
849
+ .jp-carousel-light .jp-carousel-titleanddesc div {
850
+ color: #000 !important;
851
+ }
852
+
853
+ .jp-carousel-light .jp-carousel-comments p a,
854
+ .jp-carousel-light .jp-carousel-comment .comment-author a,
855
+ .jp-carousel-light .jp-carousel-titleanddesc p a,
856
+ .jp-carousel-light .jp-carousel-titleanddesc p a,
857
+ .jp-carousel-light .jp-carousel-comments p a,
858
+ .jp-carousel-light .jp-carousel-info h2 a {
859
+ color: #1e8cbe !important;
860
+ }
861
+
862
+ .jp-carousel-light .jp-carousel-comments p a:hover,
863
+ .jp-carousel-light .jp-carousel-comment .comment-author a:hover,
864
+ .jp-carousel-light .jp-carousel-titleanddesc p a:hover,
865
+ .jp-carousel-light .jp-carousel-titleanddesc p a:hover,
866
+ .jp-carousel-light .jp-carousel-comments p a:hover,
867
+ .jp-carousel-light .jp-carousel-info h2 a:hover {
868
+ color: #f1831e !important;
869
+ }
870
+
871
+ .jp-carousel-light .jp-carousel-info h2,
872
+ .jp-carousel-light .jp-carousel-titleanddesc,
873
+ .jp-carousel-light .jp-carousel-titleanddesc p,
874
+ .jp-carousel-light .jp-carousel-comment,
875
+ .jp-carousel-light .jp-carousel-comment p,
876
+ .jp-carousel-light div.jp-carousel-buttons a,
877
+ .jp-carousel-light .jp-carousel-titleanddesc p strong,
878
+ .jp-carousel-light .jp-carousel-titleanddesc p b,
879
+ .jp-carousel-light .jp-carousel-titleanddesc p em,
880
+ .jp-carousel-light .jp-carousel-titleanddesc p i {
881
+ color: #666;
882
+ }
883
+
884
+ .jp-carousel-light .jp-carousel-buttons {
885
+ border-bottom-color: #f0f0f0;
886
+ background: #f5f5f5;
887
+ }
888
+
889
+ .jp-carousel-light div.jp-carousel-buttons a:hover {
890
+ text-decoration: none;
891
+ color: #f1831e;
892
+ }
893
+
894
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog,
895
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog:hover {
896
+ background-position: 4px -56px;
897
+ padding-left: 24px !important;
898
+ }
899
+
900
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog.reblogged,
901
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like.liked {
902
+ background-color: #2ea2cc;
903
+ color: #fff;
904
+ }
905
+
906
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-commentlink {
907
+ background-position: 0px -136px;
908
+ }
909
+
910
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like,
911
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like:hover {
912
+ background-position: 5px -15px;
913
+ padding-left: 23px !important;
914
+ }
915
+
916
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog.reblogged {
917
+ background-position: 5px -36px;
918
+ }
919
+
920
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like.liked {
921
+ background-position: 5px 5px;
922
+ }
923
+
924
+ .jp-carousel-light div#carousel-reblog-box {
925
+ background: #eee;
926
+ background: -moz-linear-gradient(bottom, #ececec, #f7f7f7);
927
+ background: -webkit-gradient(linear, left bottom, left top, from(#ececec), to(#f7f7f7));
928
+ -webkit-box-shadow: 0 2px 6px rgba(0,0,0,0.1);
929
+ -moz-box-shadow: 0 2px 10px rgba(0,0,0,0.1);
930
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
931
+ border:1px solid #ddd;
932
+ }
933
+
934
+ .jp-carousel-light #carousel-reblog-box textarea {
935
+ border: 1px inset #ccc;
936
+ color: #666;
937
+ border: 1px solid #cfcfcf;
938
+ background: #fff;
939
+ }
940
+
941
+ .jp-carousel-light #carousel-reblog-box .canceltext {
942
+ color: #888;
943
+ }
944
+
945
+ .jp-carousel-light #carousel-reblog-box .canceltext a {
946
+ color: #666;
947
+ }
948
+
949
+ .jp-carousel-light #carousel-reblog-box select {
950
+ background: #eee;
951
+ color: #333;
952
+ border: 1px solid #aaa;
953
+ }
954
+
955
+ .jp-carousel-light #carousel-reblog-box input#carousel-reblog-submit, #jp-carousel-comment-form-button-submit {
956
+ color: #333;
957
+ background: #fff;
958
+ background: -moz-linear-gradient(bottom, #ddd, #fff);
959
+ background: -webkit-gradient(linear, left bottom, left top, from(#ddd), to(#fff));
960
+ border: 1px solid #aaa;
961
+ }
962
+
963
+ .jp-carousel-light .jp-carousel-image-meta {
964
+ background: #fafafa;
965
+ border: 1px solid #eee;
966
+ border-top-color: #f5f5f5;
967
+ border-left-color: #f5f5f5;
968
+ color: #333;
969
+ }
970
+
971
+ .jp-carousel-light .jp-carousel-image-meta li {
972
+ color: #000 !important;
973
+ }
974
+
975
+ .jp-carousel-light .jp-carousel-close-hint {
976
+ color: #ccc;
977
+ }
978
+
979
+ .jp-carousel-light .jp-carousel-close-hint span {
980
+ background-color: white;
981
+ border-color: #ccc;
982
+ }
983
+
984
+ .jp-carousel-light #jp-carousel-comment-form-comment-field::-webkit-input-placeholder {
985
+ color: #aaa;
986
+ }
987
+
988
+ .jp-carousel-light #jp-carousel-comment-form-comment-field:focus {
989
+ color: #333;
990
+ }
991
+
992
+ .jp-carousel-light #jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder {
993
+ color: #ddd;
994
+ }
995
+
996
+ .jp-carousel-light a.jp-carousel-image-download {
997
+ background-position: 0 -102px;
998
+ }
999
+
1000
+ .jp-carousel-light a.jp-carousel-image-download:hover {
1001
+ background-position: 0 -102px;
1002
+ color: #f1831e;
1003
+ }
1004
+
1005
+ .jp-carousel-light textarea#jp-carousel-comment-form-comment-field {
1006
+ background: #fbfbfb;
1007
+ color: #333;
1008
+ border: 1px solid #dfdfdf;
1009
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1010
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1011
+ }
1012
+
1013
+ .jp-carousel-light #jp-carousel-comment-form-commenting-as input {
1014
+ background: #fbfbfb;
1015
+ border: 1px solid #dfdfdf;
1016
+ color: #333;
1017
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1018
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1019
+ }
1020
+
1021
+ .jp-carousel-light #jp-carousel-comment-form-commenting-as input:focus {
1022
+ background: #fbfbfb;
1023
+ color: #333;
1024
+ }
1025
+
1026
+ .jp-carousel-light #jp-carousel-comment-post-results span {
1027
+ background: #f7f7f7;
1028
+ border:1px solid #dfdfdf;
1029
+ -webkit-box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.05);
1030
+ box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.05);
1031
+ }
1032
+
1033
+ .jp-carousel-light .jp-carousel-slide {
1034
+ background-color:#fff;
1035
+ }
1036
+
1037
+ .jp-carousel-light .jp-carousel-titleanddesc {
1038
+ border-top: 1px solid #eee;
1039
+ }
1040
+
1041
+ .jp-carousel-light .jp-carousel-fadeaway {
1042
+ background: -moz-linear-gradient(bottom, rgba(255,255,255,0.75), rgba(255,255,255,0));
1043
+ background: -webkit-gradient(linear, left bottom, left top, from(rgba(255,255,255,0.75)), to(rgba(255,255,255,0)));
1044
+ }
1045
+
1046
+ /* Small screens */
1047
+ @media only screen and (max-width: 760px) {
1048
+
1049
+ .jp-carousel-info {
1050
+ margin: 0 10px !important;
1051
+ }
1052
+
1053
+ .jp-carousel-next-button, .jp-carousel-previous-button {
1054
+ display: none !important;
1055
+ }
1056
+
1057
+ .jp-carousel-buttons {
1058
+ display: none !important;
1059
+ }
1060
+
1061
+ .jp-carousel-image-meta {
1062
+ float: none !important;
1063
+ width: 100% !important;
1064
+ -moz-box-sizing:border-box;
1065
+ -webkit-box-sizing:border-box;
1066
+ box-sizing: border-box;
1067
+ }
1068
+
1069
+ .jp-carousel-close-hint {
1070
+ font-weight: 800 !important;
1071
+ font-size: 26px !important;
1072
+ position: fixed !important;
1073
+ top: -10px;
1074
+ }
1075
+
1076
+ .jp-carousel-slide img {
1077
+ filter: alpha(opacity=100);
1078
+ opacity: 1;
1079
+ }
1080
+
1081
+ .jp-carousel-wrap {
1082
+ background-color: #000;
1083
+ }
1084
+
1085
+ .jp-carousel-fadeaway {
1086
+ display: none;
1087
+ }
1088
+
1089
+ #jp-carousel-comment-form-container {
1090
+ display: none !important;
1091
+ }
1092
+
1093
+ .jp-carousel-titleanddesc {
1094
+ padding-top: 0 !important;
1095
+ border: none !important;
1096
+ }
1097
+ .jp-carousel-titleanddesc-title {
1098
+ font-size: 1em !important;
1099
+ }
1100
+
1101
+ .jp-carousel-left-column-wrapper {
1102
+ padding: 0;
1103
+ }
1104
+ }
trunk/jetpack-carousel.js ADDED
@@ -0,0 +1,1328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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'), originalHOverflow = $('html').css('overflow'), proportion = 85, isMobile;
8
+
9
+ isMobile = /Android|iPhone|iPod/i.test(navigator.userAgent);
10
+
11
+ if (isMobile)
12
+ screenPadding = 0;
13
+
14
+ var keyListener = function(e){
15
+ switch(e.which){
16
+ case 38: // up
17
+ e.preventDefault();
18
+ container.scrollTop(container.scrollTop() - 100);
19
+ break;
20
+ case 40: // down
21
+ e.preventDefault();
22
+ container.scrollTop(container.scrollTop() + 100);
23
+ break;
24
+ case 39: // right
25
+ e.preventDefault();
26
+ gallery.jp_carousel('clearCommentTextAreaValue');
27
+ gallery.jp_carousel('next');
28
+ break;
29
+ case 37: // left
30
+ e.preventDefault();
31
+ gallery.jp_carousel('clearCommentTextAreaValue');
32
+ gallery.jp_carousel('previous');
33
+ break;
34
+ case 27: // escape
35
+ e.preventDefault();
36
+ gallery.jp_carousel('clearCommentTextAreaValue');
37
+ container.jp_carousel('close');
38
+ break;
39
+ default:
40
+ // making jslint happy
41
+ break;
42
+ }
43
+ };
44
+
45
+ var resizeListener = function(e){
46
+ clearTimeout(resizeTimeout);
47
+ resizeTimeout = setTimeout(function(){
48
+ gallery
49
+ .jp_carousel('slides')
50
+ .jp_carousel('fitSlide', true);
51
+ gallery
52
+ .jp_carousel('fitInfo', true)
53
+ .jp_carousel('fitMeta', true);
54
+ }, 200);
55
+ };
56
+
57
+ // For each image in the carousel, emit likes widget markup
58
+ var getCarouselLikeWidgets = function( dataCarouselExtra ) {
59
+
60
+ // Only do this if likes is enabled
61
+ if ( "undefined" === typeof jetpackLikesWidgetQueue )
62
+ return "";
63
+
64
+ var blogId = dataCarouselExtra.likes_blog_id;
65
+ var attachmentId = 0;
66
+ var protocol = 'http';
67
+ var originDomain = 'http://wordpress.com';
68
+
69
+ if ( dataCarouselExtra.permalink.length ) {
70
+ var parts = dataCarouselExtra.permalink.split( ':' );
71
+ var protocol = parts[0];
72
+ if ( ( protocol != 'http' ) && ( protocol != 'https' ) ) {
73
+ protocol = 'http';
74
+ }
75
+
76
+ parts = dataCarouselExtra.permalink.split( '/' );
77
+ if ( parts.length >= 2 ) {
78
+ originDomain = protocol + "://" + parts[2];
79
+ }
80
+ }
81
+
82
+ var likesWidgetContainer = $("<div class='likes-widget-container'></div>");
83
+
84
+ $( 'div.gallery, div.tiled-gallery' ).find( 'img' ).each( function() {
85
+
86
+ attachmentId = $( this ).attr( "data-attachment-id" );
87
+ var dataSource = protocol + "://widgets.wp.com/likes/#blog_id=" + blogId + "&amp;post_id=" + attachmentId + "&amp;slim=1&amp;origin=" + originDomain;
88
+
89
+ if ( 'en' !== jetpackCarouselStrings.lang ) {
90
+ dataSource += "&amp;lang=" + jetpackCarouselStrings.lang;
91
+ }
92
+
93
+ var likesWidgetWrapper = $( "<div></div>" );
94
+ likesWidgetWrapper.addClass( "jetpack-likes-widget-wrapper" )
95
+ .addClass( "jetpack-likes-widget-unloaded" )
96
+ .addClass( "slim-likes-widget" )
97
+ .attr( "id", "like-post-wrapper-" + blogId + "-" + attachmentId )
98
+ .attr( "data-src", dataSource )
99
+ .attr( "data-name", "like-post-frame-" + blogId + "-" + attachmentId )
100
+ .attr( "data-attachment-id", attachmentId )
101
+ .css( "display", "none" )
102
+ .css( "vertical-align", "middle" );
103
+
104
+ var likesWidget = $( "<iframe class='post-likes-widget jetpack-likes-widget jetpack-resizeable'></iframe>" );
105
+ likesWidget.attr( "name", "like-post-frame-" + blogId + "-" + attachmentId )
106
+ .attr( "src", dataSource );
107
+ likesWidget.css( "display", "inline-block" );
108
+ likesWidgetWrapper.append( likesWidget );
109
+
110
+ likesWidgetWrapper.append( "<div class='post-likes-widget-placeholder'></div>" );
111
+
112
+ likesWidgetContainer.append( likesWidgetWrapper );
113
+ });
114
+
115
+ return likesWidgetContainer.html();
116
+ };
117
+
118
+ var prepareGallery = function( dataCarouselExtra ){
119
+ if (!overlay) {
120
+ overlay = $('<div></div>')
121
+ .addClass('jp-carousel-overlay')
122
+ .css({
123
+ 'position' : 'absolute',
124
+ 'top' : 0,
125
+ 'right' : 0,
126
+ 'bottom' : 0,
127
+ 'left' : 0
128
+ });
129
+
130
+ buttons = '<a class="jp-carousel-commentlink" href="#">' + jetpackCarouselStrings.comment + '</a>';
131
+ if ( 1 == jetpackCarouselStrings.is_logged_in ) {
132
+ }
133
+ buttons += getCarouselLikeWidgets( dataCarouselExtra );
134
+ buttons = $('<div class="jp-carousel-buttons">' + buttons + '</div>');
135
+
136
+ caption = $('<h2></h2>');
137
+ photo_info = $('<div class="jp-carousel-photo-info"></div>').append(caption);
138
+
139
+ imageMeta = $('<div></div>')
140
+ .addClass('jp-carousel-image-meta')
141
+ .css({
142
+ 'float' : 'right',
143
+ 'margin-top' : '20px',
144
+ 'width' : '250px'
145
+ });
146
+
147
+ imageMeta.append( buttons );
148
+ imageMeta.append( "<ul class='jp-carousel-image-exif' style='display:none;'></ul>" );
149
+ imageMeta.append( "<a class='jp-carousel-image-download' style='display:none;'></a>" );
150
+ imageMeta.append( "<div class='jp-carousel-image-map' style='display:none;'></div>" );
151
+
152
+ titleAndDescription = $('<div></div>')
153
+ .addClass('jp-carousel-titleanddesc')
154
+ .css({
155
+ 'width' : '100%',
156
+ 'margin-top' : imageMeta.css('margin-top')
157
+ });
158
+
159
+ var commentFormMarkup = '';
160
+ var iframeSrc = '';
161
+
162
+ commentFormMarkup = '<div id="jp-carousel-comment-form-container">';
163
+ if (iframeSrc && iframeSrc.length) {
164
+ // We're using Jetpack comments!
165
+ var iframeHeight = (jetpackCarouselStrings.is_logged_in || iframeSrc.match('comment_registration=1')) ? 220 : 340;
166
+ iframeSrc = iframeSrc.replace(/(blogid=\d+)/, '$1&postid='+window.location.hash.replace(/#jp-carousel-/,'')); // get initial attachment id from URL hash
167
+ 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>';
168
+ } else if ( jetpackCarouselStrings.local_comments_commenting_as && jetpackCarouselStrings.local_comments_commenting_as.length ) {
169
+ // Jetpack comments not enabled, fallback to local comments
170
+
171
+ if ( 1 != jetpackCarouselStrings.is_logged_in && 1 == jetpackCarouselStrings.comment_registration ) {
172
+ commentFormMarkup += '<div id="jp-carousel-comment-form-commenting-as">' + jetpackCarouselStrings.local_comments_commenting_as + '</div>';
173
+ } else {
174
+ commentFormMarkup += '<form id="jp-carousel-comment-form">';
175
+ 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>';
176
+ commentFormMarkup += '<div id="jp-carousel-comment-form-submit-and-info-wrapper">';
177
+ commentFormMarkup += '<div id="jp-carousel-comment-form-commenting-as">' + jetpackCarouselStrings.local_comments_commenting_as + '</div>';
178
+ commentFormMarkup += '<input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="'+jetpackCarouselStrings.post_comment+'" />';
179
+ commentFormMarkup += '<span id="jp-carousel-comment-form-spinner">&nbsp;</span>';
180
+ commentFormMarkup += '<div id="jp-carousel-comment-post-results"></div>';
181
+ commentFormMarkup += '</div>';
182
+ commentFormMarkup += '</form>';
183
+ }
184
+ }
185
+ commentFormMarkup += '</div>';
186
+
187
+ commentForm = $(commentFormMarkup)
188
+ .css({
189
+ 'width' : '100%',
190
+ 'margin-top' : '20px',
191
+ 'color' : '#999'
192
+ });
193
+
194
+ comments = $('<div></div>')
195
+ .addClass('jp-carousel-comments')
196
+ .css({
197
+ 'width' : '100%',
198
+ 'bottom' : '10px',
199
+ 'margin-top' : '20px'
200
+ });
201
+
202
+ commentsLoading = $('<div id="jp-carousel-comments-loading"><span>'+jetpackCarouselStrings.loading_comments+'</span></div>')
203
+ .css({
204
+ 'width' : '100%',
205
+ 'bottom' : '10px',
206
+ 'margin-top' : '20px'
207
+ });
208
+
209
+ leftWidth = ( $(window).width() - ( screenPadding * 2 ) ) - (imageMeta.width() + 40);
210
+ leftWidth += 'px';
211
+
212
+ if (isMobile)
213
+ leftWidth = '100%';
214
+
215
+ leftColWrapper = $('<div></div>')
216
+ .addClass('jp-carousel-left-column-wrapper')
217
+ .css({
218
+ 'width' : leftWidth
219
+ })
220
+ .append(titleAndDescription)
221
+ .append(commentForm)
222
+ .append(comments)
223
+ .append(commentsLoading);
224
+
225
+ fadeaway = $('<div></div>')
226
+ .addClass('jp-carousel-fadeaway');
227
+
228
+ info = $('<div></div>')
229
+ .addClass('jp-carousel-info')
230
+ .css({
231
+ 'top' : ($(window).height() / 100) * proportion,
232
+ 'left' : screenPadding,
233
+ 'right' : screenPadding
234
+ })
235
+ .append(photo_info)
236
+ .append(imageMeta)
237
+ .append(leftColWrapper);
238
+
239
+ if (isMobile)
240
+ info.prepend(leftColWrapper);
241
+ else
242
+ info.append(leftColWrapper);
243
+
244
+ targetBottomPos = ( $(window).height() - parseInt( info.css('top'), 10 ) ) + 'px';
245
+
246
+ nextButton = $("<div><span></span></div>")
247
+ .addClass('jp-carousel-next-button')
248
+ .css({
249
+ 'position' : 'fixed',
250
+ 'top' : 0,
251
+ 'right' : '15px',
252
+ 'bottom' : 0,
253
+ 'width' : screenPadding
254
+ });
255
+
256
+ $('span', nextButton).css({
257
+ 'top' : '40px',
258
+ 'bottom' : targetBottomPos
259
+ });
260
+
261
+ previousButton = $("<div><span></span></div>")
262
+ .addClass('jp-carousel-previous-button')
263
+ .css({
264
+ 'position' : 'fixed',
265
+ 'top' : 0,
266
+ 'left' : 0,
267
+ 'bottom' : 0,
268
+ 'width' : screenPadding
269
+ });
270
+
271
+ $('span', previousButton).css({
272
+ 'top' : '40px',
273
+ 'bottom' : targetBottomPos
274
+ });
275
+
276
+ gallery = $('<div></div>')
277
+ .addClass('jp-carousel')
278
+ .css({
279
+ 'position' : 'absolute',
280
+ 'top' : 0,
281
+ 'bottom' : targetBottomPos,
282
+ 'left' : 0,
283
+ 'right' : 0
284
+ });
285
+
286
+ close_hint = $('<div class="jp-carousel-close-hint"><span>&times;</span></div>')
287
+ .css({
288
+ position : 'fixed'
289
+ });
290
+
291
+ container = $("<div></div>")
292
+ .addClass('jp-carousel-wrap');
293
+
294
+ if ( 'white' == jetpackCarouselStrings.background_color )
295
+ container.addClass('jp-carousel-light');
296
+
297
+ container.css({
298
+ 'position' : 'fixed',
299
+ 'top' : 0,
300
+ 'right' : 0,
301
+ 'bottom' : 0,
302
+ 'left' : 0,
303
+ 'z-index' : 2147483647,
304
+ 'overflow-x' : 'hidden',
305
+ 'overflow-y' : 'auto',
306
+ 'direction' : 'ltr'
307
+ })
308
+ .hide()
309
+ .append(overlay)
310
+ .append(gallery)
311
+ .append(fadeaway)
312
+ .append(info)
313
+ .append(nextButton)
314
+ .append(previousButton)
315
+ .append(close_hint)
316
+ .appendTo($('body'))
317
+ .click(function(e){
318
+ var target = $(e.target), wrap = target.parents('div.jp-carousel-wrap'), data = wrap.data('carousel-extra'),
319
+ slide = wrap.find('div.selected'), attachment_id = slide.data('attachment-id');
320
+ data = data || [];
321
+
322
+ if ( target.is(gallery) || target.parents().add(target).is(close_hint) ) {
323
+ container.jp_carousel('close');
324
+ } else if ( target.hasClass('jp-carousel-commentlink') ) {
325
+ e.preventDefault();
326
+ e.stopPropagation();
327
+ $(window).unbind('keydown', keyListener);
328
+ container.animate({scrollTop: parseInt(info.position()['top'], 10)}, 'fast');
329
+ $('#jp-carousel-comment-form-submit-and-info-wrapper').slideDown('fast');
330
+ $('#jp-carousel-comment-form-comment-field').focus();
331
+ } else if ( target.hasClass('jp-carousel-comment-login') ) {
332
+ var url = jetpackCarouselStrings.login_url + '%23jp-carousel-' + attachment_id;
333
+
334
+ document.location.href = url;
335
+ } else if ( target.parents('#jp-carousel-comment-form-container').length ) {
336
+ var textarea = $('#jp-carousel-comment-form-comment-field')
337
+ .blur(function(){
338
+ $(window).bind('keydown', keyListener);
339
+ })
340
+ .focus(function(){
341
+ $(window).unbind('keydown', keyListener);
342
+ });
343
+
344
+ var emailField = $('#jp-carousel-comment-form-email-field')
345
+ .blur(function(){
346
+ $(window).bind('keydown', keyListener);
347
+ })
348
+ .focus(function(){
349
+ $(window).unbind('keydown', keyListener);
350
+ });
351
+
352
+ var authorField = $('#jp-carousel-comment-form-author-field')
353
+ .blur(function(){
354
+ $(window).bind('keydown', keyListener);
355
+ })
356
+ .focus(function(){
357
+ $(window).unbind('keydown', keyListener);
358
+ });
359
+
360
+ var urlField = $('#jp-carousel-comment-form-url-field')
361
+ .blur(function(){
362
+ $(window).bind('keydown', keyListener);
363
+ })
364
+ .focus(function(){
365
+ $(window).unbind('keydown', keyListener);
366
+ });
367
+
368
+ if ( textarea && textarea.attr('id') == target.attr('id')) {
369
+ // For first page load
370
+ $(window).unbind('keydown', keyListener);
371
+ $('#jp-carousel-comment-form-submit-and-info-wrapper').slideDown('fast');
372
+ } else if ( target.is( 'input[type="submit"]' ) ) {
373
+ e.preventDefault();
374
+ e.stopPropagation();
375
+
376
+ $('#jp-carousel-comment-form-spinner').spin('small', 'white');
377
+
378
+ var ajaxData = {
379
+ action: 'post_attachment_comment',
380
+ nonce: jetpackCarouselStrings.nonce,
381
+ blog_id: data['blog_id'],
382
+ id: attachment_id,
383
+ comment: textarea.val()
384
+ };
385
+
386
+ if ( ! ajaxData['comment'].length ) {
387
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.no_comment_text});
388
+ return;
389
+ }
390
+
391
+ if ( 1 != jetpackCarouselStrings.is_logged_in ) {
392
+ ajaxData['email'] = emailField.val();
393
+ ajaxData['author'] = authorField.val();
394
+ ajaxData['url'] = urlField.val();
395
+
396
+ if ( 1 == jetpackCarouselStrings.require_name_email ) {
397
+ if ( ! ajaxData['email'].length || ! ajaxData['email'].match('@') ) {
398
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-email-field', 'error': jetpackCarouselStrings.no_comment_email});
399
+ return;
400
+ } else if ( ! ajaxData['author'].length ) {
401
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-author-field', 'error': jetpackCarouselStrings.no_comment_author});
402
+ return;
403
+ }
404
+ }
405
+ }
406
+
407
+ $.ajax({
408
+ type: 'POST',
409
+ url: jetpackCarouselStrings.ajaxurl,
410
+ data: ajaxData,
411
+ dataType: 'json',
412
+ success: function(response, status, xhr) {
413
+ if ( 'approved' == response.comment_status ) {
414
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-success">' + jetpackCarouselStrings.comment_approved + '</span>').slideDown('fast');
415
+ } else if ( 'unapproved' == response.comment_status ) {
416
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-success">' + jetpackCarouselStrings.comment_unapproved + '</span>').slideDown('fast');
417
+ } else {
418
+ // 'deleted', 'spam', false
419
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-error">' + jetpackCarouselStrings.comment_post_error + '</span>').slideDown('fast');
420
+ }
421
+ gallery.jp_carousel('clearCommentTextAreaValue');
422
+ gallery.jp_carousel('getComments', {attachment_id: attachment_id, offset: 0, clear: true});
423
+ $('#jp-carousel-comment-form-button-submit').val(jetpackCarouselStrings.post_comment);
424
+ $('#jp-carousel-comment-form-spinner').spin(false);
425
+ },
426
+ error: function(xhr, status, error) {
427
+ // TODO: Add error handling and display here
428
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.comment_post_error});
429
+ return;
430
+ }
431
+ });
432
+ }
433
+ } else if ( ! target.parents( '.jp-carousel-info' ).length ) {
434
+ container.jp_carousel('next');
435
+ }
436
+ })
437
+ .bind('jp_carousel.afterOpen', function(){
438
+ $(window).bind('keydown', keyListener);
439
+ $(window).bind('resize', resizeListener);
440
+ gallery.opened = true;
441
+ })
442
+ .bind('jp_carousel.beforeClose', function(){
443
+ var scroll = $(window).scrollTop();
444
+
445
+ $(window).unbind('keydown', keyListener);
446
+ $(window).unbind('resize', resizeListener);
447
+ $(window).scrollTop(scroll);
448
+ })
449
+ .bind('jp_carousel.afterClose', function(){
450
+ if ( history.pushState ) {
451
+ history.pushState("", document.title, window.location.pathname + window.location.search);
452
+ } else {
453
+ document.location.hash = '';
454
+ }
455
+ gallery.opened = false;
456
+ });
457
+
458
+ $('.jp-carousel').touchwipe({
459
+ wipeLeft: function() { gallery.jp_carousel('next'); },
460
+ wipeRight: function() { gallery.jp_carousel('previous'); },
461
+ min_move_x: 20,
462
+ min_move_y: 20,
463
+ preventDefaultEvents: true
464
+ });
465
+
466
+ $( '.jetpack-likes-widget-unloaded' ).each( function() {
467
+ jetpackLikesWidgetQueue.push( this.id );
468
+ });
469
+
470
+ nextButton.add(previousButton).click(function(e){
471
+ e.preventDefault();
472
+ e.stopPropagation();
473
+ if ( nextButton.is(this) ) {
474
+ gallery.jp_carousel('next');
475
+ } else {
476
+ gallery.jp_carousel('previous');
477
+ }
478
+ });
479
+ }
480
+ };
481
+
482
+ var methods = {
483
+ testForData: function(gallery) {
484
+ gallery = $( gallery ); // make sure we have it as a jQuery object.
485
+ if ( ! gallery.length || undefined == gallery.data( 'carousel-extra' ) ) {
486
+ return false;
487
+ }
488
+ return true;
489
+ },
490
+
491
+ testIfOpened: function() {
492
+ if ( 'undefined' != typeof(gallery) && 'undefined' != typeof(gallery.opened) && true == gallery.opened )
493
+ return true;
494
+ return false;
495
+ },
496
+
497
+ open: function(options) {
498
+ var settings = {
499
+ 'items_selector' : ".gallery-item [data-attachment-id], .tiled-gallery-item [data-attachment-id]",
500
+ 'start_index': 0
501
+ },
502
+ data = $(this).data('carousel-extra');
503
+
504
+ if ( !data )
505
+ return; // don't run if the default gallery functions weren't used
506
+
507
+ prepareGallery( data );
508
+
509
+ if ( gallery.jp_carousel( 'testIfOpened' ) )
510
+ return; // don't open if already opened
511
+
512
+ // make sure to stop the page from scrolling behind the carousel overlay, so we don't trigger
513
+ // infiniscroll for it when enabled (Reader, theme infiniscroll, etc).
514
+ originalOverflow = $('body').css('overflow');
515
+ $('body').css('overflow', 'hidden');
516
+ // prevent html from overflowing on some of the new themes.
517
+ originalHOverflow = $('html').css('overflow');
518
+ $('html').css('overflow', 'hidden');
519
+
520
+ // Re-apply inline-block style here and give an initial value for the width
521
+ // This value will get replaced with a more appropriate value once the slide is loaded
522
+ // This avoids the likes widget appearing initially full width below the comment button and then shuffling up
523
+ jQuery( '.slim-likes-widget' ).find( 'iframe' ).css( 'display', 'inline-block' ).css( 'width', '60px' );
524
+
525
+ container.data('carousel-extra', data);
526
+
527
+ return this.each(function() {
528
+ // If options exist, lets merge them
529
+ // with our default settings
530
+ var $this = $(this);
531
+
532
+ if ( options )
533
+ $.extend( settings, options );
534
+ if ( -1 == settings.start_index )
535
+ settings.start_index = 0; //-1 returned if can't find index, so start from beginning
536
+
537
+ container.trigger('jp_carousel.beforeOpen').fadeIn('fast',function(){
538
+ container.trigger('jp_carousel.afterOpen');
539
+ gallery
540
+ .jp_carousel('initSlides', $this.find(settings.items_selector), settings.start_index)
541
+ .jp_carousel('start', settings.start_index);
542
+ });
543
+ gallery.html('');
544
+ });
545
+ },
546
+
547
+ start : function(start_index){
548
+ var slides = this.jp_carousel('slides'), selected = slides.eq(start_index);
549
+
550
+ if ( 0 === selected.length )
551
+ selected = slides.eq(0);
552
+
553
+ gallery.jp_carousel('selectSlide', selected, false);
554
+ return this;
555
+ },
556
+
557
+ close : function(){
558
+ // make sure to let the page scroll again
559
+ $('body').css('overflow', originalOverflow);
560
+ $('html').css('overflow', originalHOverflow);
561
+ return container
562
+ .trigger('jp_carousel.beforeClose')
563
+ .fadeOut('fast', function(){
564
+ container.trigger('jp_carousel.afterClose');
565
+ });
566
+
567
+ },
568
+
569
+ next : function(){
570
+ var selected = this.jp_carousel('selectedSlide'), slide;
571
+ container.animate({scrollTop:0}, 'fast');
572
+ if ( 0 === selected.length ) { // no selection return first item
573
+ slide = this.jp_carousel('slides').first(0);
574
+ } else if( selected.is( this.jp_carousel('slides').last() ) ) {
575
+ gallery.jp_carousel('loopSlides');
576
+ } else {
577
+ slide = selected.next();
578
+ }
579
+ if (!slide) {
580
+ return this;
581
+ } else {
582
+ return this.jp_carousel('selectSlide', slide);
583
+ }
584
+ },
585
+
586
+ previous : function(){
587
+ var selected = this.jp_carousel('selectedSlide'), slide;
588
+ container.animate({scrollTop:0}, 'fast');
589
+ if ( 0 === selected.length ) { // no selection return first item
590
+ slide = this.jp_carousel('slides').first();
591
+ } else if ( selected.is( this.jp_carousel('slides').first() ) ) { // if it's the last slide
592
+ gallery.jp_carousel('loopSlides', true);
593
+ } else {
594
+ slide = selected.prev();
595
+ }
596
+ if (!slide) {
597
+ return this;
598
+ } else {
599
+ return this.jp_carousel('selectSlide', slide);
600
+ }
601
+ },
602
+
603
+ resetButtons : function(current) {
604
+ if ( current.data('liked') )
605
+ $('.jp-carousel-buttons a.jp-carousel-like').addClass('liked').text(jetpackCarouselStrings.unlike);
606
+ else
607
+ $('.jp-carousel-buttons a.jp-carousel-like').removeClass('liked').text(jetpackCarouselStrings.like);
608
+ },
609
+
610
+ loopSlides : function(reverse){
611
+ var slides = gallery.jp_carousel('slides'), last, first;
612
+ gallery.jp_carousel('selectedSlide').removeClass('selected').css({'position': 'fixed'});
613
+ if (reverse !== true ) {
614
+ last = slides.last();
615
+ slides.first().nextAll().not(last).jp_carousel('setSlidePosition', gallery.width()+slides.first().width()).hide();
616
+ last.jp_carousel('setSlidePosition', -last.width());
617
+ last.prev().jp_carousel('setSlidePosition', -last.width() - last.prev().width());
618
+ slides.first().jp_carousel('setSlidePosition', gallery.width());
619
+ setTimeout(function(){
620
+ gallery.jp_carousel('selectSlide', slides.show().first());
621
+ }, 400);
622
+
623
+ } else {
624
+ first = slides.first();
625
+ first.jp_carousel('setSlidePosition', gallery.width());
626
+ first.next().jp_carousel('setSlidePosition', gallery.width() + first.width());
627
+ first.next().nextAll().hide().jp_carousel('setSlidePosition', -slides.last().width());
628
+ slides.last().jp_carousel('setSlidePosition', -slides.last().width());
629
+ slides.last().prevAll().not(first, first.next()).hide().jp_carousel('setSlidePosition', -slides.last().width()-slides.last().prev().width());
630
+ setTimeout(function(){
631
+ gallery.jp_carousel('selectSlide', slides.show().last());
632
+ }, 400);
633
+
634
+ }
635
+ },
636
+
637
+ selectedSlide : function(){
638
+ return this.find('.selected');
639
+ },
640
+
641
+ setSlidePosition : function(x) {
642
+ return this.css({
643
+ '-webkit-transform':'translate3d(' + x + 'px,0,0)',
644
+ '-moz-transform':'translate3d(' + x + 'px,0,0)',
645
+ '-ms-transform':'translate(' + x + 'px,0)',
646
+ '-o-transform':'translate(' + x + 'px,0)',
647
+ 'transform':'translate3d(' + x + 'px,0,0)'
648
+ });
649
+ },
650
+
651
+ selectSlide : function(slide, animate){
652
+ var last = this.find('.selected').removeClass('selected'),
653
+ slides = gallery.jp_carousel('slides').css({'position': 'fixed'}),
654
+ current = $(slide).addClass('selected').css({'position': 'relative'}),
655
+ previous = current.prev(),
656
+ next = current.next(),
657
+ width = $(window).width(),
658
+ previous_previous = previous.prev(),
659
+ next_next = next.next(),
660
+ left = (gallery.width() - current.width()) * 0.5,
661
+ info_left,
662
+ animated,
663
+ info_min;
664
+ // center the main image
665
+
666
+ caption.hide();
667
+
668
+ method = 'css';
669
+ animated = current
670
+ .add(previous)
671
+ .add(previous.prev())
672
+ .add(next)
673
+ .add(next.next())
674
+ .jp_carousel('loadSlide');
675
+ // slide the whole view to the x we want
676
+ slides.not(animated).hide();
677
+
678
+ current.jp_carousel('setSlidePosition', left).show();
679
+
680
+ // minimum width
681
+ gallery.jp_carousel('fitInfo', animate);
682
+
683
+ // prep the slides
684
+ var direction = last.is(current.prevAll()) ? 1 : -1;
685
+ if ( 1 == direction ) {
686
+ next_next.jp_carousel('setSlidePosition', gallery.width() + next.width()).show();
687
+ next.hide().jp_carousel('setSlidePosition', gallery.width() + current.width()).show();
688
+ previous_previous.jp_carousel('setSlidePosition', -previous_previous.width() - current.width()).show();
689
+ } else {
690
+ previous.jp_carousel('setSlidePosition', -previous.width() - current.width()).show();
691
+ next_next.jp_carousel('setSlidePosition', gallery.width() + current.width()).show();
692
+ }
693
+
694
+ // if advancing prepare the slide that will enter the screen
695
+ previous.jp_carousel('setSlidePosition', -previous.width() + (screenPadding * 0.75)).show();
696
+ next.jp_carousel('setSlidePosition', gallery.width() - (screenPadding * 0.75)).show();
697
+ next.css({'position': ''});
698
+ document.location.href = document.location.href.replace(/#.*/, '') + '#jp-carousel-' + current.data('attachment-id');
699
+ gallery.jp_carousel('resetButtons', current);
700
+ container.trigger('jp_carousel.selectSlide', [current]);
701
+
702
+ gallery.jp_carousel( 'getTitleDesc', { title: current.data( 'title' ), desc: current.data( 'desc' ) } );
703
+ gallery.jp_carousel( 'updateLikesWidgetVisibility', current.data( 'attachment-id' ) )
704
+ gallery.jp_carousel( 'updateExif', current.data( 'image-meta' ) );
705
+ gallery.jp_carousel( 'updateFullSizeLink', current );
706
+ gallery.jp_carousel( 'updateMap', current.data( 'image-meta' ) );
707
+ gallery.jp_carousel( 'testCommentsOpened', current.data( 'comments-opened' ) );
708
+ gallery.jp_carousel( 'getComments', { 'attachment_id': current.data( 'attachment-id' ), 'offset': 0, 'clear': true } );
709
+
710
+ $('#jp-carousel-comment-post-results').slideUp();
711
+
712
+ // $('<div />').text(sometext).html() is a trick to go to HTML to plain text (including HTML entities decode, etc)
713
+ if ( current.data('caption') ) {
714
+ if ( $('<div />').text(current.data('caption')).html() == $('<div />').text(current.data('title')).html() )
715
+ $('.jp-carousel-titleanddesc-title').fadeOut('fast').empty();
716
+ if ( $('<div />').text(current.data('caption')).html() == $('<div />').text(current.data('desc')).html() )
717
+ $('.jp-carousel-titleanddesc-desc').fadeOut('fast').empty();
718
+ caption.html( current.data('caption') ).fadeIn('slow');
719
+ } else {
720
+ caption.fadeOut('fast').empty();
721
+ }
722
+
723
+ },
724
+
725
+ slides : function(){
726
+ return this.find('.jp-carousel-slide');
727
+ },
728
+
729
+ slideDimensions : function(){
730
+ return {
731
+ width: $(window).width() - (screenPadding * 2),
732
+ height: $(window).height() / 100 * proportion - 60
733
+ };
734
+ },
735
+
736
+ loadSlide : function() {
737
+ return this.each(function(){
738
+ var slide = $(this);
739
+ slide.find('img')
740
+ .one('load', function(){
741
+ // set the width/height of the image if it's too big
742
+ slide
743
+ .jp_carousel('fitSlide',false);
744
+ });
745
+ });
746
+ },
747
+
748
+ bestFit : function(){
749
+ var max = gallery.jp_carousel('slideDimensions'),
750
+ orig = this.jp_carousel('originalDimensions'),
751
+ orig_ratio = orig.width / orig.height,
752
+ w_ratio = 1,
753
+ h_ratio = 1;
754
+
755
+ if ( orig.width > max.width )
756
+ w_ratio = max.width / orig.width;
757
+ if ( orig.height > max.height )
758
+ h_ratio = max.height / orig.height;
759
+
760
+ if ( w_ratio < h_ratio ) {
761
+ width = max.width;
762
+ height = width / orig_ratio;
763
+ } else if ( h_ratio < w_ratio ) {
764
+ height = max.height;
765
+ width = height * orig_ratio;
766
+ } else {
767
+ width = orig.width;
768
+ height = orig.height;
769
+ }
770
+
771
+ return {
772
+ width: width,
773
+ height: height
774
+ };
775
+ },
776
+
777
+ fitInfo : function(animated){
778
+ var current = this.jp_carousel('selectedSlide'),
779
+ size = current.jp_carousel('bestFit');
780
+
781
+ photo_info.css({
782
+ 'left' : (info.width() - size.width) * 0.5,
783
+ 'width' : size.width
784
+ });
785
+
786
+ if (isMobile){
787
+ photo_info.css('left', '0px');
788
+ photo_info.css('top', '-20px');
789
+ }
790
+
791
+ return this;
792
+ },
793
+
794
+ fitMeta : function(animated){
795
+ var newInfoTop = { top: ( $(window).height() / 100 * proportion + 5 ) + 'px' };
796
+ var newLeftWidth = { width: ( info.width() - (imageMeta.width() + 80) ) + 'px' };
797
+
798
+ if (animated) {
799
+ info.animate(newInfoTop);
800
+ leftColWrapper.animate(newLeftWidth);
801
+ } else {
802
+ info.animate(newInfoTop);
803
+ leftColWrapper.css(newLeftWidth);
804
+ }
805
+ },
806
+
807
+ fitSlide : function(animated){
808
+ return this.each(function(){
809
+ var selected = gallery.jp_carousel('selectedSlide'),
810
+ $this = $(this),
811
+ dimensions = $this.jp_carousel('bestFit'),
812
+ method = 'css',
813
+ max = gallery.jp_carousel('slideDimensions');
814
+
815
+ dimensions.left = 0;
816
+ dimensions.top = ( (max.height - dimensions.height) * 0.5 ) + 40;
817
+ $this[method](dimensions);
818
+ });
819
+ },
820
+
821
+ texturize : function(text) {
822
+ text = new String(text); // make sure we get a string. Title "1" came in as int 1, for example, which did not support .replace().
823
+ text = text.replace(/'/g, '&#8217;').replace(/&#039;/g, '&#8217;').replace(/[\u2019]/g, '&#8217;');
824
+ text = text.replace(/"/g, '&#8221;').replace(/&#034;/g, '&#8221;').replace(/&quot;/g, '&#8221;').replace(/[\u201D]/g, '&#8221;');
825
+ text = text.replace(/([\w]+)=&#[\d]+;(.+?)&#[\d]+;/g, '$1="$2"'); // untexturize allowed HTML tags params double-quotes
826
+ return $.trim(text);
827
+ },
828
+
829
+ initSlides : function(items, start_index){
830
+ var width = this.jp_carousel('slideDimensions').width,
831
+ x = 0;
832
+
833
+ // Calculate the new src.
834
+ items.each(function(i){
835
+ var src_item = $(this),
836
+ orig_size = src_item.data('orig-size') || '',
837
+ max = gallery.jp_carousel('slideDimensions'),
838
+ parts = orig_size.split(',');
839
+ orig_size = {width: parseInt(parts[0], 10), height: parseInt(parts[1], 10)},
840
+ medium_file = src_item.data('medium-file') || '',
841
+ large_file = src_item.data('large-file') || '';
842
+
843
+ src = src_item.data('orig-file');
844
+
845
+ src = gallery.jp_carousel('selectBestImageSize', {
846
+ orig_file : src,
847
+ orig_width : orig_size.width,
848
+ orig_height : orig_size.height,
849
+ max_width : max.width,
850
+ max_height : max.height,
851
+ medium_file : medium_file,
852
+ large_file : large_file
853
+ });
854
+
855
+ // Set the final src
856
+ $(this).data( 'gallery-src', src );
857
+ });
858
+
859
+ // If the start_index is not 0 then preload the clicked image first.
860
+ if ( 0 !== start_index )
861
+ $('<img/>')[0].src = $(items[start_index]).data('gallery-src');
862
+
863
+ // create the 'slide'
864
+ items.each(function(i){
865
+ var src_item = $(this),
866
+ attachment_id = src_item.data('attachment-id') || 0,
867
+ comments_opened = src_item.data('comments-opened') || 0,
868
+ image_meta = src_item.data('image-meta') || {},
869
+ orig_size = src_item.data('orig-size') || '',
870
+ title = src_item.data('image-title') || '',
871
+ description = src_item.data('image-description') || '',
872
+ caption = src_item.parents('dl').find('dd.gallery-caption').html() || '',
873
+ src = src_item.data('gallery-src') || '',
874
+ medium_file = src_item.data('medium-file') || '',
875
+ large_file = src_item.data('large-file') || '',
876
+ orig_file = src_item.data('orig-file') || '';
877
+
878
+ var tiledCaption = src_item.parents('div.tiled-gallery-item').find('div.tiled-gallery-caption').html();
879
+ if ( tiledCaption )
880
+ caption = tiledCaption;
881
+
882
+ if ( attachment_id && orig_size.length ) {
883
+ title = gallery.jp_carousel('texturize', title);
884
+ description = gallery.jp_carousel('texturize', description);
885
+ caption = gallery.jp_carousel('texturize', caption);
886
+
887
+ var slide = $('<div class="jp-carousel-slide"></div>')
888
+ .hide()
889
+ .css({
890
+ //'position' : 'fixed',
891
+ 'left' : i < start_index ? -1000 : gallery.width()
892
+ })
893
+ .append($('<img>'))
894
+ .appendTo(gallery)
895
+ .data('src', src )
896
+ .data('title', title)
897
+ .data('desc', description)
898
+ .data('caption', caption)
899
+ .data('attachment-id', attachment_id)
900
+ .data('permalink', src_item.parents('a').attr('href'))
901
+ .data('orig-size', orig_size)
902
+ .data('comments-opened', comments_opened)
903
+ .data('image-meta', image_meta)
904
+ .data('medium-file', medium_file)
905
+ .data('large-file', large_file)
906
+ .data('orig-file', orig_file)
907
+ .jp_carousel('fitSlide', false);
908
+
909
+ // Preloading all images
910
+ slide.find('img').first().attr('src', src );
911
+ }
912
+ });
913
+ return this;
914
+ },
915
+
916
+ selectBestImageSize: function(args) {
917
+ if ( 'object' != typeof args )
918
+ args = {};
919
+
920
+ if ( 'undefined' == typeof args.orig_file )
921
+ return '';
922
+
923
+ if ( 'undefined' == typeof args.orig_width || 'undefined' == typeof args.max_width )
924
+ return args.orig_file;
925
+
926
+ if ( 'undefined' == typeof args.medium_file || 'undefined' == typeof args.large_file )
927
+ return args.orig_file;
928
+
929
+ var medium_size = args.medium_file.replace(/-([\d]+x[\d]+)\..+$/, '$1'),
930
+ medium_size_parts = (medium_size != args.medium_file) ? medium_size.split('x') : [args.orig_width, 0],
931
+ medium_width = parseInt( medium_size_parts[0], 10 ),
932
+ medium_height = parseInt( medium_size_parts[1], 10 ),
933
+ large_size = args.large_file.replace(/-([\d]+x[\d]+)\..+$/, '$1'),
934
+ large_size_parts = (large_size != args.large_file) ? large_size.split('x') : [args.orig_width, 0],
935
+ large_width = parseInt( large_size_parts[0], 10 ),
936
+ large_height = parseInt( large_size_parts[1], 10 );
937
+
938
+ // Give devices with a higher devicePixelRatio higher-res images (Retina display = 2, Android phones = 1.5, etc)
939
+ if ('undefined' != typeof window.devicePixelRatio && window.devicePixelRatio > 1) {
940
+ args.max_width = args.max_width * window.devicePixelRatio;
941
+ args.max_height = args.max_height * window.devicePixelRatio;
942
+ }
943
+
944
+ if ( large_width >= args.max_width || large_height >= args.max_height )
945
+ return args.large_file;
946
+
947
+ if ( medium_width >= args.max_width || medium_height >= args.max_height )
948
+ return args.medium_file;
949
+
950
+ return args.orig_file;
951
+ },
952
+
953
+
954
+ originalDimensions: function() {
955
+ var splitted = $(this).data('orig-size').split(',');
956
+ return {width: parseInt(splitted[0], 10), height: parseInt(splitted[1], 10)};
957
+ },
958
+
959
+ format: function( args ) {
960
+ if ( 'object' != typeof args )
961
+ args = {};
962
+ if ( ! args.text || 'undefined' == typeof args.text )
963
+ return;
964
+ if ( ! args.replacements || 'undefined' == typeof args.replacements )
965
+ return args.text;
966
+ return args.text.replace(/{(\d+)}/g, function(match, number) {
967
+ return typeof args.replacements[number] != 'undefined' ? args.replacements[number] : match;
968
+ });
969
+ },
970
+
971
+ shutterSpeed: function(d) {
972
+ if (d >= 1)
973
+ return Math.round(d) + 's';
974
+ var df = 1, top = 1, bot = 1;
975
+ var limit = 1e5; //Increase for greater precision.
976
+ while (df != d && limit-- > 0) {
977
+ if (df < d) {
978
+ top += 1;
979
+ }
980
+ else {
981
+ bot += 1;
982
+ top = parseInt(d * bot, 10);
983
+ }
984
+ df = top / bot;
985
+ }
986
+ if (top > 1) {
987
+ bot = Math.round(bot / top);
988
+ top = 1;
989
+ }
990
+ if (bot <= 1)
991
+ return '1s';
992
+ return top + '/' + bot + 's';
993
+ },
994
+
995
+ parseTitleDesc: function( value ) {
996
+ if ( !value.match(' ') && value.match('_') )
997
+ return '';
998
+ // Prefix list originally based on http://commons.wikimedia.org/wiki/MediaWiki:Filename-prefix-blacklist
999
+ var prefixes = $([
1000
+ 'CIMG', // Casio
1001
+ 'DSC_', // Nikon
1002
+ 'DSCF', // Fuji
1003
+ 'DSCN', // Nikon
1004
+ 'DUW', // some mobile phones
1005
+ 'GEDC', // GE
1006
+ 'IMG', // generic
1007
+ 'JD', // Jenoptik
1008
+ 'MGP', // Pentax
1009
+ 'PICT', // misc.
1010
+ 'Imagen', // misc.
1011
+ 'Foto', // misc.
1012
+ 'DSC', // misc.
1013
+ 'Scan', // Scanners
1014
+ 'SANY', // Sanyo
1015
+ 'SAM', // Samsung
1016
+ 'Screen Shot [0-9]+' // Mac screenshots
1017
+ ])
1018
+ .each(function(key, val){
1019
+ regex = new RegExp('^' + val);
1020
+ if ( regex.test(value) ) {
1021
+ value = '';
1022
+ return;
1023
+ }
1024
+ });
1025
+ return value;
1026
+ },
1027
+
1028
+ getTitleDesc: function( data ) {
1029
+ var title ='', desc = '', markup = '', target, commentWrappere;
1030
+
1031
+ target = $( 'div.jp-carousel-titleanddesc', 'div.jp-carousel-wrap' );
1032
+ target.hide();
1033
+
1034
+ title = gallery.jp_carousel('parseTitleDesc', data.title) || '';
1035
+ desc = gallery.jp_carousel('parseTitleDesc', data.desc) || '';
1036
+
1037
+ if ( title.length || desc.length ) {
1038
+ // $('<div />').text(sometext).html() is a trick to go to HTML to plain text (including HTML entities decode, etc)
1039
+ if ( $('<div />').text(title).html() == $('<div />').text(desc).html() )
1040
+ title = '';
1041
+
1042
+ markup = ( title.length ) ? '<div class="jp-carousel-titleanddesc-title">' + title + '</div>' : '';
1043
+ markup += ( desc.length ) ? '<div class="jp-carousel-titleanddesc-desc">' + desc + '</div>' : '';
1044
+
1045
+ target.html( markup ).fadeIn('slow');
1046
+ }
1047
+
1048
+ $( 'div#jp-carousel-comment-form-container' ).css('margin-top', '20px');
1049
+ $( 'div#jp-carousel-comments-loading' ).css('margin-top', '20px');
1050
+ },
1051
+
1052
+ updateLikesWidgetVisibility: function( attachmentId ) {
1053
+ // Hide all likes widgets except for the one for the attachmentId passed in
1054
+
1055
+ $( '.jp-carousel-buttons' ).find( '.jetpack-likes-widget-wrapper' ).each( function() {
1056
+ var widgetWrapper = $( this );
1057
+ if ( widgetWrapper.attr('data-attachment-id') == attachmentId ) {
1058
+ widgetWrapper.css( 'display', 'inline-block' );
1059
+ } else {
1060
+ widgetWrapper.css( 'display', 'none' );
1061
+ }
1062
+ });
1063
+ },
1064
+
1065
+ // updateExif updates the contents of the exif UL (.jp-carousel-image-exif)
1066
+ updateExif: function( meta ) {
1067
+ if ( !meta || 1 != jetpackCarouselStrings.display_exif )
1068
+ return false;
1069
+
1070
+ var $ul = $( "<ul class='jp-carousel-image-exif'></ul>" );
1071
+ $.each( meta, function( key, val ) {
1072
+ if ( 0 === parseFloat(val) || !val.length || -1 === $.inArray( key, [ 'camera', 'aperture', 'shutter_speed', 'focal_length' ] ) )
1073
+ return;
1074
+
1075
+ switch( key ) {
1076
+ case 'focal_length':
1077
+ val = val + 'mm';
1078
+ break;
1079
+ case 'shutter_speed':
1080
+ val = gallery.jp_carousel('shutterSpeed', val);
1081
+ break;
1082
+ case 'aperture':
1083
+ val = 'f/' + val;
1084
+ break;
1085
+ default:
1086
+ // making jslint happy
1087
+ break;
1088
+ }
1089
+
1090
+ $ul.append( '<li><h5>' + jetpackCarouselStrings[key] + '</h5>' + val + '</li>' );
1091
+ });
1092
+
1093
+ // Update (replace) the content of the ul
1094
+ $( 'div.jp-carousel-image-meta ul.jp-carousel-image-exif' ).replaceWith( $ul );
1095
+ },
1096
+
1097
+ // updateFullSizeLink updates the contents of the jp-carousel-image-download link
1098
+ updateFullSizeLink: function(current) {
1099
+ if(!current || !current.data)
1100
+ return false;
1101
+ var original = current.data('orig-file').replace(/\?.+$/, ''),
1102
+ origSize = current.data('orig-size').split(','),
1103
+ permalink = $( '<a>'+gallery.jp_carousel('format', {'text': jetpackCarouselStrings.download_original, 'replacements': origSize})+'</a>' )
1104
+ .addClass( 'jp-carousel-image-download' )
1105
+ .attr( 'href', original )
1106
+ .attr( 'target', '_blank' );
1107
+
1108
+ // Update (replace) the content of the anchor
1109
+ $( 'div.jp-carousel-image-meta a.jp-carousel-image-download' ).replaceWith( permalink );
1110
+ },
1111
+
1112
+ updateMap: function( meta ) {
1113
+ if ( !meta.latitude || !meta.longitude || 1 != jetpackCarouselStrings.display_geo )
1114
+ return;
1115
+
1116
+ var latitude = meta.latitude,
1117
+ longitude = meta.longitude,
1118
+ $metabox = $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' ),
1119
+ $mapbox = $( '<div></div>' ),
1120
+ style = '&scale=2&style=feature:all|element:all|invert_lightness:true|hue:0x0077FF|saturation:-50|lightness:-5|gamma:0.91';
1121
+
1122
+ $mapbox
1123
+ .addClass( 'jp-carousel-image-map' )
1124
+ .html( '<img width="154" height="154" src="https://maps.googleapis.com/maps/api/staticmap?\
1125
+ center=' + latitude + ',' + longitude + '&\
1126
+ zoom=8&\
1127
+ size=154x154&\
1128
+ sensor=false&\
1129
+ markers=size:medium%7Ccolor:blue%7C' + latitude + ',' + longitude + style +'" class="gmap-main" />\
1130
+ \
1131
+ <div class="gmap-topright"><div class="imgclip"><img width="175" height="154" src="https://maps.googleapis.com/maps/api/staticmap?\
1132
+ center=' + latitude + ',' + longitude + '&\
1133
+ zoom=3&\
1134
+ size=175x154&\
1135
+ sensor=false&\
1136
+ markers=size:small%7Ccolor:blue%7C' + latitude + ',' + longitude + style + '"c /></div></div>\
1137
+ \
1138
+ ' )
1139
+ .prependTo( $metabox );
1140
+ },
1141
+
1142
+ testCommentsOpened: function( opened ) {
1143
+ if ( 1 == parseInt( opened, 10 ) ) {
1144
+ $('.jp-carousel-buttons').fadeIn('fast');
1145
+ commentForm.fadeIn('fast');
1146
+ } else {
1147
+ $('.jp-carousel-buttons').fadeOut('fast');
1148
+ commentForm.fadeOut('fast');
1149
+ }
1150
+ },
1151
+
1152
+ getComments: function( args ) {
1153
+ if ( 'object' != typeof args )
1154
+ args = {};
1155
+
1156
+ if ( ! args.attachment_id || 'undefined' == typeof args.attachment_id )
1157
+ return;
1158
+
1159
+ if ( ! args.offset || 'undefined' == typeof args.offset || args.offset < 1 )
1160
+ args.offset = 0;
1161
+
1162
+ var comments = $('.jp-carousel-comments'),
1163
+ commentsLoading = $('#jp-carousel-comments-loading');
1164
+
1165
+ commentsLoading.show();
1166
+
1167
+ if ( args.clear ) {
1168
+ comments.hide();
1169
+ comments.empty();
1170
+ }
1171
+
1172
+ $.ajax({
1173
+ type: 'GET',
1174
+ url: jetpackCarouselStrings.ajaxurl,
1175
+ dataType: 'json',
1176
+ data: {
1177
+ action: 'get_attachment_comments',
1178
+ nonce: jetpackCarouselStrings.nonce,
1179
+ id: args.attachment_id,
1180
+ offset: args.offset
1181
+ },
1182
+ success: function(data, status, xhr) {
1183
+ if ( args.clear ) {
1184
+ comments.fadeOut('fast');
1185
+ comments.empty();
1186
+ }
1187
+
1188
+ $( data ).each(function(){
1189
+ var comment = $('<div></div>')
1190
+ .addClass('jp-carousel-comment')
1191
+ .attr('id', 'jp-carousel-comment-' + this['id'])
1192
+ .css({})
1193
+ .html(
1194
+ '<div class="comment-gravatar">'
1195
+ + this['gravatar_markup']
1196
+ + '</div>'
1197
+ + '<div class="comment-author">'
1198
+ + this['author_markup']
1199
+ + '</div>'
1200
+ + '<div class="comment-date">'
1201
+ + this['date_gmt']
1202
+ + '</div>'
1203
+ + '<div class="comment-content">'
1204
+ + this['content']
1205
+ + '</div>'
1206
+ );
1207
+ comments.append(comment);
1208
+
1209
+ // Set the interval to check for a new page of comments.
1210
+ clearInterval( commentInterval );
1211
+ commentInterval = setInterval( function() {
1212
+ if ( ( $('.jp-carousel-overlay').height() - 150 ) < $('.jp-carousel-wrap').scrollTop() + $(window).height() ) {
1213
+ gallery.jp_carousel('getComments',{ attachment_id: args.attachment_id, offset: args.offset + 10, clear: false });
1214
+ clearInterval( commentInterval );
1215
+ }
1216
+ }, 150 );
1217
+ });
1218
+
1219
+ // Verify (late) that the user didn't repeatldy click the arrows really fast, in which case the requested
1220
+ // attachment id might no longer match the current attachment id by the time we get the data back or a now
1221
+ // registered infiniscroll event kicks in, so we don't ever display comments for the wrong image by mistake.
1222
+ var current = $('.jp-carousel div.selected');
1223
+ if ( current && current.data && current.data('attachment-id') != args.attachment_id ) {
1224
+ comments.fadeOut('fast');
1225
+ comments.empty();
1226
+ return;
1227
+ }
1228
+
1229
+ // Increase the height of the background, semi-transparent overlay to match the new length of the comments list.
1230
+ $('.jp-carousel-overlay').height( $(window).height() + titleAndDescription.height() + commentForm.height() + ( (comments.height() > 0) ? comments.height() : imageMeta.height() ) + 200 );
1231
+
1232
+ comments.show();
1233
+ commentsLoading.hide();
1234
+ },
1235
+ error: function(xhr, status, error) {
1236
+ // TODO: proper error handling
1237
+ console.log( 'Comment get fail...', xhr, status, error );
1238
+ comments.fadeIn('fast');
1239
+ commentsLoading.fadeOut('fast');
1240
+ }
1241
+ });
1242
+ },
1243
+
1244
+ postCommentError: function(args) {
1245
+ if ( 'object' != typeof args )
1246
+ args = {};
1247
+ if ( ! args.field || 'undefined' == typeof args.field || ! args.error || 'undefined' == typeof args.error )
1248
+ return;
1249
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-error">'+args.error+'</span>').slideDown('fast');
1250
+ $('#jp-carousel-comment-form-spinner').spin(false);
1251
+ },
1252
+
1253
+ setCommentIframeSrc: function(attachment_id) {
1254
+ var iframe = $('#jp-carousel-comment-iframe');
1255
+ // Set the proper irame src for the current attachment id
1256
+ if (iframe && iframe.length) {
1257
+ iframe.attr('src', iframe.attr('src').replace(/(postid=)\d+/, '$1'+attachment_id) );
1258
+ iframe.attr('src', iframe.attr('src').replace(/(%23.+)?$/, '%23jp-carousel-'+attachment_id) );
1259
+ }
1260
+ },
1261
+
1262
+ clearCommentTextAreaValue: function() {
1263
+ var commentTextArea = $('#jp-carousel-comment-form-comment-field');
1264
+ if ( commentTextArea )
1265
+ commentTextArea.val('');
1266
+ }
1267
+ };
1268
+
1269
+ $.fn.jp_carousel = function(method){
1270
+ // ask for the HTML of the gallery
1271
+ // Method calling logic
1272
+ if ( methods[method] ) {
1273
+ return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
1274
+ } else if ( typeof method === 'object' || ! method ) {
1275
+ return methods.open.apply( this, arguments );
1276
+ } else {
1277
+ $.error( 'Method ' + method + ' does not exist on jQuery.jp_carousel' );
1278
+ }
1279
+
1280
+ };
1281
+
1282
+ // register the event listener for starting the gallery
1283
+ $( document.body ).on( 'click', 'div.gallery,div.tiled-gallery', function(e) {
1284
+ if ( ! $(this).jp_carousel( 'testForData', e.currentTarget ) )
1285
+ return;
1286
+ if ( $(e.target).parent().hasClass('gallery-caption') )
1287
+ return;
1288
+ e.preventDefault();
1289
+ $(this).jp_carousel('open', {start_index: $(this).find('.gallery-item, .tiled-gallery-item').index($(e.target).parents('.gallery-item, .tiled-gallery-item'))});
1290
+ });
1291
+
1292
+ // Set an interval on page load to load the carousel if hash exists and not already opened.
1293
+ // Makes carousel work on page load and when back button leads to same URL with carousel hash (ie: no actual document.ready trigger)
1294
+ $(document).ready(function(){
1295
+ last_known_location_hash = '';
1296
+
1297
+ var jp_carousel_open_interval = window.setInterval(function(){
1298
+ // We should have a URL hash by now.
1299
+ if ( ! document.location.hash || ! document.location.hash.match(/jp-carousel-(\d+)/) )
1300
+ return;
1301
+
1302
+ if ( document.location.hash == last_known_location_hash )
1303
+ return;
1304
+
1305
+ last_known_location_hash = document.location.hash;
1306
+
1307
+ var gallery = $('div.gallery, div.tiled-gallery'), index = -1, n = document.location.hash.match(/jp-carousel-(\d+)/);
1308
+
1309
+ if ( ! $(this).jp_carousel( 'testForData', gallery ) )
1310
+ return;
1311
+
1312
+ n = parseInt(n[1], 10);
1313
+
1314
+ gallery.find('img').each(function(num, el){
1315
+ if ( n && $(el).data('attachment-id') == n ) { // n cannot be 0 (zero)
1316
+ index = num;
1317
+ return false;
1318
+ }
1319
+ });
1320
+
1321
+ if ( index != -1 )
1322
+ gallery.jp_carousel('open', {start_index: index}); // open method checks if already opened
1323
+ }, 1000);
1324
+ });
1325
+ });
1326
+
1327
+ // Swipe gesture detection
1328
+ (function($){$.fn.touchwipe=function(settings){var config={min_move_x:20,min_move_y:20,wipeLeft:function(){},wipeRight:function(){},wipeUp:function(){},wipeDown:function(){},preventDefaultEvents:true};if(settings)$.extend(config,settings);this.each(function(){var startX;var startY;var isMoving=false;function cancelTouch(){this.removeEventListener('touchmove',onTouchMove);startX=null;isMoving=false}function onTouchMove(e){if(config.preventDefaultEvents){e.preventDefault()}if(isMoving){var x=e.touches[0].pageX;var y=e.touches[0].pageY;var dx=startX-x;var dy=startY-y;if(Math.abs(dx)>=config.min_move_x){cancelTouch();if(dx>0){config.wipeLeft()}else{config.wipeRight()}}else if(Math.abs(dy)>=config.min_move_y){cancelTouch();if(dy>0){config.wipeDown()}else{config.wipeUp()}}}}function onTouchStart(e){if(e.touches.length==1){startX=e.touches[0].pageX;startY=e.touches[0].pageY;isMoving=true;this.addEventListener('touchmove',onTouchMove,false)}}if('ontouchstart'in document.documentElement){this.addEventListener('touchstart',onTouchStart,false)}});return this}})(jQuery);
trunk/jetpack-carousel.php ADDED
@@ -0,0 +1,494 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Module Name:Image Gallery Carousel Without Jetpack
5
+ Plugin URL: http://themepacific.com/
6
+ Description: Transform your standard image galleries into an immersive full-screen experience.
7
+ Version: 0.1
8
+ Author: Raja CRN
9
+ Author URI: http://themepacific.com
10
+ License: GPLv2 or later
11
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
+
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+ */
19
+
20
+ class themepacific_Jetpack_Carousel {
21
+
22
+ var $prebuilt_widths = array( 370, 700, 1000, 1200, 1400, 2000 );
23
+
24
+ var $first_run = true;
25
+
26
+ var $in_jetpack = true;
27
+
28
+ function __construct() {
29
+ add_action( 'init', array( $this, 'init' ) );
30
+ }
31
+
32
+ function init() {
33
+ if ( $this->maybe_disable_jp_carousel() )
34
+ return;
35
+
36
+ $this->in_jetpack = ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'enable_module_configurable' ) ) ? true : false;
37
+
38
+ if ( is_admin() ) {
39
+ // Register the Carousel-related related settings
40
+ add_action( 'admin_init', array( $this, 'register_settings' ), 5 );
41
+ if ( ! $this->in_jetpack ) {
42
+ if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
43
+ return; // Carousel disabled, abort early, but still register setting so user can switch it back on
44
+ }
45
+ // If in admin, register the ajax endpoints.
46
+ add_action( 'wp_ajax_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
47
+ add_action( 'wp_ajax_nopriv_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
48
+ add_action( 'wp_ajax_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
49
+ add_action( 'wp_ajax_nopriv_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
50
+ } else {
51
+ if ( ! $this->in_jetpack ) {
52
+ if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
53
+ return; // Carousel disabled, abort early
54
+ }
55
+ // If on front-end, do the Carousel thang.
56
+ $this->prebuilt_widths = apply_filters( 'jp_carousel_widths', $this->prebuilt_widths );
57
+ add_filter( 'post_gallery', array( $this, 'enqueue_assets' ), 1000, 2 ); // load later than other callbacks hooked it
58
+ add_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
59
+ add_filter( 'wp_get_attachment_link', array( $this, 'add_data_to_images' ), 10, 2 );
60
+ }
61
+
62
+ if ( $this->in_jetpack && method_exists( 'Jetpack', 'module_configuration_load' ) ) {
63
+ Jetpack::enable_module_configurable( dirname( dirname( __FILE__ ) ) . '/carousel.php' );
64
+ Jetpack::module_configuration_load( dirname( dirname( __FILE__ ) ) . '/carousel.php', array( $this, 'jetpack_configuration_load' ) );
65
+ }
66
+ }
67
+
68
+ function maybe_disable_jp_carousel() {
69
+ return apply_filters( 'jp_carousel_maybe_disable', false );
70
+ }
71
+
72
+ function jetpack_configuration_load() {
73
+ wp_safe_redirect( admin_url( 'options-media.php#carousel_background_color' ) );
74
+ exit;
75
+ }
76
+
77
+ function asset_version( $version ) {
78
+ return apply_filters( 'jp_carousel_asset_version', $version );
79
+ }
80
+
81
+ function enqueue_assets( $output ) {
82
+ if ( ! empty( $output ) && ! apply_filters( 'jp_carousel_force_enable', false ) ) {
83
+ // Bail because someone is overriding the [gallery] shortcode.
84
+ remove_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
85
+ remove_filter( 'wp_get_attachment_link', array( $this, 'add_data_to_images' ) );
86
+ return $output;
87
+ }
88
+
89
+ do_action( 'jp_carousel_thumbnails_shown' );
90
+
91
+ if ( $this->first_run ) {
92
+ wp_register_script( 'spin', plugins_url( 'spin.js', __FILE__ ), false, '1.3' );
93
+ wp_register_script( 'jquery.spin', plugins_url( 'jquery.spin.js', __FILE__ ) , array( 'jquery', 'spin' ) );
94
+
95
+ wp_enqueue_script( 'jetpack-carousel', plugins_url( 'jetpack-carousel.js', __FILE__ ), array( 'jquery.spin' ), $this->asset_version( '20130109' ), true );
96
+
97
+ // 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)
98
+ // Also: not hardcoding path since there is no guarantee site is running on site root in self-hosted context.
99
+ $is_logged_in = is_user_logged_in();
100
+ $current_user = wp_get_current_user();
101
+ $comment_registration = intval( get_option( 'comment_registration' ) );
102
+ $require_name_email = intval( get_option( 'require_name_email' ) );
103
+ $localize_strings = array(
104
+ 'widths' => $this->prebuilt_widths,
105
+ 'is_logged_in' => $is_logged_in,
106
+ 'lang' => strtolower( substr( get_locale(), 0, 2 ) ),
107
+ 'ajaxurl' => admin_url( 'admin-ajax.php', is_ssl() ? 'https' : 'http' ),
108
+ 'nonce' => wp_create_nonce( 'carousel_nonce' ),
109
+ 'display_exif' => $this->test_1or0_option( get_option( 'carousel_display_exif' ), true ),
110
+ 'display_geo' => $this->test_1or0_option( get_option( 'carousel_display_geo' ), true ),
111
+ 'background_color' => $this->carousel_background_color_sanitize( get_option( 'carousel_background_color' ) ),
112
+ 'comment' => __( 'Comment', 'themepacific_gallery' ),
113
+ 'post_comment' => __( 'Post Comment', 'themepacific_gallery' ),
114
+ 'loading_comments' => __( 'Loading Comments...', 'themepacific_gallery' ),
115
+ 'download_original' => sprintf( __( 'View full size <span class="photo-size">%1$s<span class="photo-size-times">&times;</span>%2$s</span>', 'themepacific_gallery' ), '{0}', '{1}' ),
116
+ 'no_comment_text' => __( 'Please be sure to submit some text with your comment.', 'themepacific_gallery' ),
117
+ 'no_comment_email' => __( 'Please provide an email address to comment.', 'themepacific_gallery' ),
118
+ 'no_comment_author' => __( 'Please provide your name to comment.', 'themepacific_gallery' ),
119
+ 'comment_post_error' => __( 'Sorry, but there was an error posting your comment. Please try again later.', 'themepacific_gallery' ),
120
+ 'comment_approved' => __( 'Your comment was approved.', 'themepacific_gallery' ),
121
+ 'comment_unapproved' => __( 'Your comment is in moderation.', 'themepacific_gallery' ),
122
+ 'camera' => __( 'Camera', 'themepacific_gallery' ),
123
+ 'aperture' => __( 'Aperture', 'themepacific_gallery' ),
124
+ 'shutter_speed' => __( 'Shutter Speed', 'themepacific_gallery' ),
125
+ 'focal_length' => __( 'Focal Length', 'themepacific_gallery' ),
126
+ 'comment_registration' => $comment_registration,
127
+ 'require_name_email' => $require_name_email,
128
+ 'login_url' => wp_login_url( apply_filters( 'the_permalink', get_permalink() ) ),
129
+ );
130
+
131
+ if ( ! isset( $localize_strings['jetpack_comments_iframe_src'] ) || empty( $localize_strings['jetpack_comments_iframe_src'] ) ) {
132
+ // We're not using Jetpack comments after all, so fallback to standard local comments.
133
+
134
+ if ( $is_logged_in ) {
135
+ $localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . sprintf( __( 'Commenting as %s', 'themepacific_gallery' ), $current_user->data->display_name ) . '</p>';
136
+ } else {
137
+ if ( $comment_registration ) {
138
+ $localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . __( 'You must be <a href="#" class="jp-carousel-comment-login">logged in</a> to post a comment.', 'themepacific_gallery' ) . '</p>';
139
+ } else {
140
+ $required = ( $require_name_email ) ? __( '%s (Required)', 'themepacific_gallery' ) : '%s';
141
+ $localize_strings['local_comments_commenting_as'] = ''
142
+ . '<fieldset><label for="email">' . sprintf( $required, __( 'Email', 'themepacific_gallery' ) ) . '</label> '
143
+ . '<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>'
144
+ . '<fieldset><label for="author">' . sprintf( $required, __( 'Name', 'themepacific_gallery' ) ) . '</label> '
145
+ . '<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>'
146
+ . '<fieldset><label for="url">' . __( 'Website', 'themepacific_gallery' ) . '</label> '
147
+ . '<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>';
148
+ }
149
+ }
150
+ }
151
+
152
+ $localize_strings = apply_filters( 'jp_carousel_localize_strings', $localize_strings );
153
+ wp_localize_script( 'jetpack-carousel', 'jetpackCarouselStrings', $localize_strings );
154
+ wp_enqueue_style( 'jetpack-carousel', plugins_url( 'jetpack-carousel.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
155
+ global $is_IE;
156
+ if( $is_IE )
157
+ {
158
+ $msie = strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) + 4;
159
+ $version = (float) substr( $_SERVER['HTTP_USER_AGENT'], $msie, strpos( $_SERVER['HTTP_USER_AGENT'], ';', $msie ) - $msie );
160
+ if( $version < 9 )
161
+ wp_enqueue_style( 'jetpack-carousel-ie8fix', plugins_url( 'jetpack-carousel-ie8fix.css', __FILE__ ), array(), $this->asset_version( '20121024' ) );
162
+ }
163
+ do_action( 'jp_carousel_enqueue_assets', $this->first_run, $localize_strings );
164
+
165
+ $this->first_run = false;
166
+ }
167
+
168
+ return $output;
169
+ }
170
+
171
+ function add_data_to_images( $html, $attachment_id ) {
172
+ if ( $this->first_run ) // not in a gallery
173
+ return $html;
174
+
175
+ $attachment_id = intval( $attachment_id );
176
+ $orig_file = wp_get_attachment_image_src( $attachment_id, 'full' );
177
+ $orig_file = isset( $orig_file[0] ) ? $orig_file[0] : wp_get_attachment_url( $attachment_id );
178
+ $meta = wp_get_attachment_metadata( $attachment_id );
179
+ $size = isset( $meta['width'] ) ? intval( $meta['width'] ) . ',' . intval( $meta['height'] ) : '';
180
+ $img_meta = ( ! empty( $meta['image_meta'] ) ) ? (array) $meta['image_meta'] : array();
181
+ $comments_opened = intval( comments_open( $attachment_id ) );
182
+
183
+ /*
184
+ * Note: Cannot generate a filename from the width and height wp_get_attachment_image_src() returns because
185
+ * it takes the $content_width global variable themes can set in consideration, therefore returning sizes
186
+ * which when used to generate a filename will likely result in a 404 on the image.
187
+ * $content_width has no filter we could temporarily de-register, run wp_get_attachment_image_src(), then
188
+ * re-register. So using returned file URL instead, which we can define the sizes from through filename
189
+ * parsing in the JS, as this is a failsafe file reference.
190
+ *
191
+ * EG with Twenty Eleven activated:
192
+ * 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) }
193
+ *
194
+ * EG with Twenty Ten activated:
195
+ * 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) }
196
+ */
197
+
198
+ $medium_file_info = wp_get_attachment_image_src( $attachment_id, 'medium' );
199
+ $medium_file = isset( $medium_file_info[0] ) ? $medium_file_info[0] : '';
200
+
201
+ $large_file_info = wp_get_attachment_image_src( $attachment_id, 'large' );
202
+ $large_file = isset( $large_file_info[0] ) ? $large_file_info[0] : '';
203
+
204
+ $attachment = get_post( $attachment_id );
205
+ $attachment_title = wptexturize( $attachment->post_title );
206
+ $attachment_desc = wpautop( wptexturize( $attachment->post_content ) );
207
+
208
+ // Not yet providing geo-data, need to "fuzzify" for privacy
209
+ if ( ! empty( $img_meta ) ) {
210
+ foreach ( $img_meta as $k => $v ) {
211
+ if ( 'latitude' == $k || 'longitude' == $k )
212
+ unset( $img_meta[$k] );
213
+ }
214
+ }
215
+
216
+ $img_meta = json_encode( array_map( 'strval', $img_meta ) );
217
+
218
+ $html = str_replace(
219
+ '<img ',
220
+ sprintf(
221
+ '<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-title="%6$s" data-image-description="%7$s" data-medium-file="%8$s" data-large-file="%9$s" ',
222
+ $attachment_id,
223
+ esc_attr( $orig_file ),
224
+ $size,
225
+ $comments_opened,
226
+ esc_attr( $img_meta ),
227
+ esc_attr( $attachment_title ),
228
+ esc_attr( $attachment_desc ),
229
+ esc_attr( $medium_file ),
230
+ esc_attr( $large_file )
231
+ ),
232
+ $html
233
+ );
234
+
235
+ $html = apply_filters( 'jp_carousel_add_data_to_images', $html, $attachment_id );
236
+
237
+ return $html;
238
+ }
239
+
240
+ function add_data_to_container( $html ) {
241
+ global $post;
242
+
243
+ if ( isset( $post ) ) {
244
+ $blog_id = (int) get_current_blog_id();
245
+
246
+ if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
247
+ $likes_blog_id = $blog_id;
248
+ } else {
249
+ //$likes_blog_id = Jetpack_Options::get_option( 'id' );
250
+ }
251
+
252
+ $extra_data = array(
253
+ 'data-carousel-extra' => array(
254
+ 'blog_id' => $blog_id,
255
+ 'permalink' => get_permalink( $post->ID ),
256
+ //'likes_blog_id' => $likes_blog_id
257
+ )
258
+ );
259
+
260
+ $extra_data = apply_filters( 'jp_carousel_add_data_to_container', $extra_data );
261
+ foreach ( (array) $extra_data as $data_key => $data_values ) {
262
+ $html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . json_encode( $data_values ) . "' ", $html );
263
+ }
264
+ }
265
+
266
+ return $html;
267
+ }
268
+
269
+ function get_attachment_comments() {
270
+ if ( ! headers_sent() )
271
+ header('Content-type: text/javascript');
272
+
273
+ do_action('jp_carousel_check_blog_user_privileges');
274
+
275
+ $attachment_id = ( isset( $_REQUEST['id'] ) ) ? (int) $_REQUEST['id'] : 0;
276
+ $offset = ( isset( $_REQUEST['offset'] ) ) ? (int) $_REQUEST['offset'] : 0;
277
+
278
+ if ( ! $attachment_id ) {
279
+ echo json_encode( __( 'Missing attachment ID.', 'themepacific_gallery' ) );
280
+ die();
281
+ }
282
+
283
+ if ( $offset < 1 )
284
+ $offset = 0;
285
+
286
+ $comments = get_comments( array(
287
+ 'status' => 'approve',
288
+ 'order' => ( 'asc' == get_option('comment_order') ) ? 'ASC' : 'DESC',
289
+ 'number' => 10,
290
+ 'offset' => $offset,
291
+ 'post_id' => $attachment_id,
292
+ ) );
293
+
294
+ $out = array();
295
+
296
+ // Can't just send the results, they contain the commenter's email address.
297
+ foreach ( $comments as $comment ) {
298
+ $out[] = array(
299
+ 'id' => $comment->comment_ID,
300
+ 'parent_id' => $comment->comment_parent,
301
+ 'author_markup' => get_comment_author_link( $comment->comment_ID ),
302
+ 'gravatar_markup' => get_avatar( $comment->comment_author_email, 64 ),
303
+ 'date_gmt' => $comment->comment_date_gmt,
304
+ 'content' => wpautop($comment->comment_content),
305
+ );
306
+ }
307
+
308
+ die( json_encode( $out ) );
309
+ }
310
+
311
+ function post_attachment_comment() {
312
+ if ( ! headers_sent() )
313
+ header('Content-type: text/javascript');
314
+
315
+ if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce($_POST['nonce'], 'carousel_nonce') )
316
+ die( json_encode( array( 'error' => __( 'Nonce verification failed.', 'themepacific_gallery' ) ) ) );
317
+
318
+ $_blog_id = (int) $_POST['blog_id'];
319
+ $_post_id = (int) $_POST['id'];
320
+ $comment = $_POST['comment'];
321
+
322
+ if ( empty( $_blog_id ) )
323
+ die( json_encode( array( 'error' => __( 'Missing target blog ID.', 'themepacific_gallery' ) ) ) );
324
+
325
+ if ( empty( $_post_id ) )
326
+ die( json_encode( array( 'error' => __( 'Missing target post ID.', 'themepacific_gallery' ) ) ) );
327
+
328
+ if ( empty( $comment ) )
329
+ die( json_encode( array( 'error' => __( 'No comment text was submitted.', 'themepacific_gallery' ) ) ) );
330
+
331
+ // Used in context like NewDash
332
+ $switched = false;
333
+ if ( is_multisite() && $_blog_id != get_current_blog_id() ) {
334
+ switch_to_blog( $_blog_id );
335
+ $switched = true;
336
+ }
337
+
338
+ do_action('jp_carousel_check_blog_user_privileges');
339
+
340
+ if ( ! comments_open( $_post_id ) )
341
+ die( json_encode( array( 'error' => __( 'Comments on this post are closed.', 'themepacific_gallery' ) ) ) );
342
+
343
+ if ( is_user_logged_in() ) {
344
+ $user = wp_get_current_user();
345
+ $user_id = $user->ID;
346
+ $display_name = $user->display_name;
347
+ $email = $user->user_email;
348
+ $url = $user->user_url;
349
+
350
+ if ( empty( $user_id ) )
351
+ die( json_encode( array( 'error' => __( 'Sorry, but we could not authenticate your request.', 'themepacific_gallery' ) ) ) );
352
+ } else {
353
+ $user_id = 0;
354
+ $display_name = $_POST['author'];
355
+ $email = $_POST['email'];
356
+ $url = $_POST['url'];
357
+
358
+ if ( get_option( 'require_name_email' ) ) {
359
+ if ( empty( $display_name ) )
360
+ die( json_encode( array( 'error' => __( 'Please provide your name.', 'themepacific_gallery' ) ) ) );
361
+
362
+ if ( empty( $email ) )
363
+ die( json_encode( array( 'error' => __( 'Please provide an email address.', 'themepacific_gallery' ) ) ) );
364
+
365
+ if ( ! is_email( $email ) )
366
+ die( json_encode( array( 'error' => __( 'Please provide a valid email address.', 'themepacific_gallery' ) ) ) );
367
+ }
368
+ }
369
+
370
+ $comment_data = array(
371
+ 'comment_content' => $comment,
372
+ 'comment_post_ID' => $_post_id,
373
+ 'comment_author' => $display_name,
374
+ 'comment_author_email' => $email,
375
+ 'comment_author_url' => $url,
376
+ 'comment_approved' => 0,
377
+ 'comment_type' => '',
378
+ );
379
+
380
+ if ( ! empty( $user_id ) )
381
+ $comment_data['user_id'] = $user_id;
382
+
383
+ // Note: wp_new_comment() sanitizes and validates the values (too).
384
+ $comment_id = wp_new_comment( $comment_data );
385
+ do_action( 'jp_carousel_post_attachment_comment' );
386
+ $comment_status = wp_get_comment_status( $comment_id );
387
+
388
+ if ( true == $switched )
389
+ restore_current_blog();
390
+
391
+ die( json_encode( array( 'comment_id' => $comment_id, 'comment_status' => $comment_status ) ) );
392
+ }
393
+
394
+ function register_settings() {
395
+ add_settings_section('carousel_section', __( 'Image Gallery Carousel', 'themepacific_gallery' ), array( $this, 'carousel_section_callback' ), 'media');
396
+
397
+ if ( ! $this->in_jetpack ) {
398
+ add_settings_field('carousel_enable_it', __( 'Enable carousel', 'themepacific_gallery' ), array( $this, 'carousel_enable_it_callback' ), 'media', 'carousel_section' );
399
+ register_setting( 'media', 'carousel_enable_it', array( $this, 'carousel_enable_it_sanitize' ) );
400
+ }
401
+
402
+ add_settings_field('carousel_background_color', __( 'Background color', 'themepacific_gallery' ), array( $this, 'carousel_background_color_callback' ), 'media', 'carousel_section' );
403
+ register_setting( 'media', 'carousel_background_color', array( $this, 'carousel_background_color_sanitize' ) );
404
+
405
+ add_settings_field('carousel_display_exif', __( 'Metadata', 'themepacific_gallery'), array( $this, 'carousel_display_exif_callback' ), 'media', 'carousel_section' );
406
+ register_setting( 'media', 'carousel_display_exif', array( $this, 'carousel_display_exif_sanitize' ) );
407
+
408
+ // No geo setting yet, need to "fuzzify" data first, for privacy
409
+ // add_settings_field('carousel_display_geo', __( 'Geolocation', 'themepacific_gallery' ), array( $this, 'carousel_display_geo_callback' ), 'media', 'carousel_section' );
410
+ // register_setting( 'media', 'carousel_display_geo', array( $this, 'carousel_display_geo_sanitize' ) );
411
+ }
412
+
413
+ // Fulfill the settings section callback requirement by returning nothing
414
+ function carousel_section_callback() {
415
+ return;
416
+ }
417
+
418
+ function test_1or0_option( $value, $default_to_1 = true ) {
419
+ if ( true == $default_to_1 ) {
420
+ // Binary false (===) of $value means it has not yet been set, in which case we do want to default sites to 1
421
+ if ( false === $value )
422
+ $value = 1;
423
+ }
424
+ return ( 1 == $value ) ? 1 : 0;
425
+ }
426
+
427
+ function sanitize_1or0_option( $value ) {
428
+ return ( 1 == $value ) ? 1 : 0;
429
+ }
430
+
431
+ function settings_checkbox($name, $label_text, $extra_text = '', $default_to_checked = true) {
432
+ if ( empty( $name ) )
433
+ return;
434
+ $option = $this->test_1or0_option( get_option( $name ), $default_to_checked );
435
+ echo '<fieldset>';
436
+ echo '<input type="checkbox" name="'.esc_attr($name).'" id="'.esc_attr($name).'" value="1" ';
437
+ checked( '1', $option );
438
+ echo '/> <label for="'.esc_attr($name).'">'.$label_text.'</label>';
439
+ if ( ! empty( $extra_text ) )
440
+ echo '<p class="description">'.$extra_text.'</p>';
441
+ echo '</fieldset>';
442
+ }
443
+
444
+ function settings_select($name, $values, $extra_text = '') {
445
+ if ( empty( $name ) || ! is_array( $values ) || empty( $values ) )
446
+ return;
447
+ $option = get_option( $name );
448
+ echo '<fieldset>';
449
+ echo '<select name="'.esc_attr($name).'" id="'.esc_attr($name).'">';
450
+ foreach( $values as $key => $value ) {
451
+ echo '<option value="'.esc_attr($key).'" ';
452
+ selected( $key, $option );
453
+ echo '>'.esc_html($value).'</option>';
454
+ }
455
+ echo '</select>';
456
+ if ( ! empty( $extra_text ) )
457
+ echo '<p class="description">'.$extra_text.'</p>';
458
+ echo '</fieldset>';
459
+ }
460
+
461
+ function carousel_display_exif_callback() {
462
+ $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.', 'themepacific_gallery' ) );
463
+ }
464
+
465
+ function carousel_display_exif_sanitize( $value ) {
466
+ return $this->sanitize_1or0_option( $value );
467
+ }
468
+
469
+ function carousel_display_geo_callback() {
470
+ $this->settings_checkbox( 'carousel_display_geo', __( 'Show map of photo location in carousel, when available.', 'themepacific_gallery' ) );
471
+ }
472
+
473
+ function carousel_display_geo_sanitize( $value ) {
474
+ return $this->sanitize_1or0_option( $value );
475
+ }
476
+
477
+ function carousel_background_color_callback() {
478
+ $this->settings_select( 'carousel_background_color', array( 'black' => __( 'Black', 'themepacific_gallery' ), 'white' => __( 'White', 'themepacific_gallery', 'themepacific_gallery' ) ) );
479
+ }
480
+
481
+ function carousel_background_color_sanitize( $value ) {
482
+ return ( 'white' == $value ) ? 'white' : 'black';
483
+ }
484
+
485
+ function carousel_enable_it_callback() {
486
+ $this->settings_checkbox( 'carousel_enable_it', __( 'Display images in full-size carousel slideshow.', 'themepacific_gallery' ) );
487
+ }
488
+
489
+ function carousel_enable_it_sanitize( $value ) {
490
+ return $this->sanitize_1or0_option( $value );
491
+ }
492
+ }
493
+
494
+ new themepacific_Jetpack_Carousel;
trunk/jquery.spin.js ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Copyright (c) 2011-2013 Felix Gnass
3
+ * Licensed under the MIT license
4
+ */
5
+
6
+ /*
7
+
8
+ Basic Usage:
9
+ ============
10
+
11
+ $('#el').spin(); // Creates a default Spinner using the text color of #el.
12
+ $('#el').spin({ ... }); // Creates a Spinner using the provided options.
13
+
14
+ $('#el').spin(false); // Stops and removes the spinner.
15
+
16
+ Using Presets:
17
+ ==============
18
+
19
+ $('#el').spin('small'); // Creates a 'small' Spinner using the text color of #el.
20
+ $('#el').spin('large', '#fff'); // Creates a 'large' white Spinner.
21
+
22
+ Adding a custom preset:
23
+ =======================
24
+
25
+ $.fn.spin.presets.flower = {
26
+ lines: 9
27
+ length: 10
28
+ width: 20
29
+ radius: 0
30
+ }
31
+
32
+ $('#el').spin('flower', 'red');
33
+
34
+ */
35
+
36
+ (function(factory) {
37
+
38
+ if (typeof exports == 'object') {
39
+ // CommonJS
40
+ factory(require('jquery'), require('spin'))
41
+ }
42
+ else if (typeof define == 'function' && define.amd) {
43
+ // AMD, register as anonymous module
44
+ define(['jquery', 'spin'], factory)
45
+ }
46
+ else {
47
+ // Browser globals
48
+ if (!window.Spinner) throw new Error('Spin.js not present')
49
+ factory(window.jQuery, window.Spinner)
50
+ }
51
+
52
+ }(function($, Spinner) {
53
+
54
+ $.fn.spin = function(opts, color) {
55
+
56
+ return this.each(function() {
57
+ var $this = $(this),
58
+ data = $this.data();
59
+
60
+ if (data.spinner) {
61
+ data.spinner.stop();
62
+ delete data.spinner;
63
+ }
64
+ if (opts !== false) {
65
+ opts = $.extend(
66
+ { color: color || $this.css('color') },
67
+ $.fn.spin.presets[opts] || opts
68
+ )
69
+ // Begin WordPress Additions
70
+ // To use opts.right, you need to have specified a length, width, and radius.
71
+ if ( typeof opts.right !== 'undefined' && typeof opts.length !== 'undefined'
72
+ && typeof opts.width !== 'undefined' && typeof opts.radius !== 'undefined' ) {
73
+ var pad = $this.css( 'padding-left' );
74
+ pad = ( typeof pad === 'undefined' ) ? 0 : parseInt( pad, 10 );
75
+ opts.left = $this.outerWidth() - ( 2 * ( opts.length + opts.width + opts.radius ) ) - pad - opts.right;
76
+ delete opts.right;
77
+ }
78
+ // End WordPress Additions
79
+ data.spinner = new Spinner(opts).spin(this)
80
+ }
81
+ })
82
+ }
83
+
84
+ $.fn.spin.presets = {
85
+ tiny: { lines: 8, length: 2, width: 2, radius: 3 },
86
+ small: { lines: 8, length: 4, width: 3, radius: 5 },
87
+ large: { lines: 10, length: 8, width: 4, radius: 8 }
88
+ }
89
+
90
+ }));
91
+
92
+ // Jetpack Presets Overrides:
93
+ (function($){
94
+ $.fn.spin.presets.wp = { trail: 60, speed: 1.3 };
95
+ $.fn.spin.presets.small = $.extend( { lines: 8, length: 2, width: 2, radius: 3 }, $.fn.spin.presets.wp );
96
+ $.fn.spin.presets.medium = $.extend( { lines: 8, length: 4, width: 3, radius: 5 }, $.fn.spin.presets.wp );
97
+ $.fn.spin.presets.large = $.extend( { lines: 10, length: 6, width: 4, radius: 7 }, $.fn.spin.presets.wp );
98
+ $.fn.spin.presets['small-left'] = $.extend( { left: 5 }, $.fn.spin.presets.small );
99
+ $.fn.spin.presets['small-right'] = $.extend( { right: 5 }, $.fn.spin.presets.small );
100
+ $.fn.spin.presets['medium-left'] = $.extend( { left: 5 }, $.fn.spin.presets.medium );
101
+ $.fn.spin.presets['medium-right'] = $.extend( { right: 5 }, $.fn.spin.presets.medium );
102
+ $.fn.spin.presets['large-left'] = $.extend( { left: 5 }, $.fn.spin.presets.large );
103
+ $.fn.spin.presets['large-right'] = $.extend( { right: 5 }, $.fn.spin.presets.large );
104
+ })(jQuery);
trunk/languages/default.mo ADDED
Binary file
trunk/languages/default.po ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Gallery Carousel ThemePacific\n"
4
+ "POT-Creation-Date: 2013-10-13 21:28+0530\n"
5
+ "PO-Revision-Date: 2013-10-13 21:29+0530\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: ThemePacific <support@themepacific.com>\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 1.5.4\n"
12
+ "X-Poedit-KeywordsList: __;_e\n"
13
+ "X-Poedit-Basepath: .\n"
14
+ "X-Poedit-SearchPath-0: /home/om/public_html/themepacific/wp-content/plugins/"
15
+ "tiled-gallery-carousel-without-jetpack\n"
16
+
17
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/functions.gallery.php:12
18
+ msgid "Thumbnail Grid"
19
+ msgstr ""
20
+
21
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/functions.gallery.php:40
22
+ msgid "Type"
23
+ msgstr ""
24
+
25
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:112
26
+ msgid "Comment"
27
+ msgstr ""
28
+
29
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:113
30
+ msgid "Post Comment"
31
+ msgstr ""
32
+
33
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:114
34
+ msgid "Loading Comments..."
35
+ msgstr ""
36
+
37
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:115
38
+ #, php-format
39
+ msgid ""
40
+ "View full size <span class=\"photo-size\">%1$s<span class=\"photo-size-times"
41
+ "\">&times;</span>%2$s</span>"
42
+ msgstr ""
43
+
44
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:116
45
+ msgid "Please be sure to submit some text with your comment."
46
+ msgstr ""
47
+
48
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:117
49
+ msgid "Please provide an email address to comment."
50
+ msgstr ""
51
+
52
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:118
53
+ msgid "Please provide your name to comment."
54
+ msgstr ""
55
+
56
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:119
57
+ msgid ""
58
+ "Sorry, but there was an error posting your comment. Please try again later."
59
+ msgstr ""
60
+
61
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:120
62
+ msgid "Your comment was approved."
63
+ msgstr ""
64
+
65
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:121
66
+ msgid "Your comment is in moderation."
67
+ msgstr ""
68
+
69
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:122
70
+ msgid "Camera"
71
+ msgstr ""
72
+
73
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:123
74
+ msgid "Aperture"
75
+ msgstr ""
76
+
77
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:124
78
+ msgid "Shutter Speed"
79
+ msgstr ""
80
+
81
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:125
82
+ msgid "Focal Length"
83
+ msgstr ""
84
+
85
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:135
86
+ #, php-format
87
+ msgid "Commenting as %s"
88
+ msgstr ""
89
+
90
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:138
91
+ msgid ""
92
+ "You must be <a href=\"#\" class=\"jp-carousel-comment-login\">logged in</a> "
93
+ "to post a comment."
94
+ msgstr ""
95
+
96
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:140
97
+ #, php-format
98
+ msgid "%s (Required)"
99
+ msgstr ""
100
+
101
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:142
102
+ msgid "Email"
103
+ msgstr ""
104
+
105
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:144
106
+ msgid "Name"
107
+ msgstr ""
108
+
109
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:146
110
+ msgid "Website"
111
+ msgstr ""
112
+
113
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:279
114
+ msgid "Missing attachment ID."
115
+ msgstr ""
116
+
117
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:316
118
+ msgid "Nonce verification failed."
119
+ msgstr ""
120
+
121
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:323
122
+ msgid "Missing target blog ID."
123
+ msgstr ""
124
+
125
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:326
126
+ msgid "Missing target post ID."
127
+ msgstr ""
128
+
129
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:329
130
+ msgid "No comment text was submitted."
131
+ msgstr ""
132
+
133
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:341
134
+ msgid "Comments on this post are closed."
135
+ msgstr ""
136
+
137
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:351
138
+ msgid "Sorry, but we could not authenticate your request."
139
+ msgstr ""
140
+
141
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:360
142
+ msgid "Please provide your name."
143
+ msgstr ""
144
+
145
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:363
146
+ msgid "Please provide an email address."
147
+ msgstr ""
148
+
149
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:366
150
+ msgid "Please provide a valid email address."
151
+ msgstr ""
152
+
153
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:395
154
+ msgid "Image Gallery Carousel"
155
+ msgstr ""
156
+
157
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:398
158
+ msgid "Enable carousel"
159
+ msgstr ""
160
+
161
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:402
162
+ msgid "Background color"
163
+ msgstr ""
164
+
165
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:405
166
+ msgid "Metadata"
167
+ msgstr ""
168
+
169
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:462
170
+ msgid ""
171
+ "Show photo metadata (<a href=\"http://en.wikipedia.org/wiki/"
172
+ "Exchangeable_image_file_format\" target=\"_blank\">Exif</a>) in carousel, "
173
+ "when available."
174
+ msgstr ""
175
+
176
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:470
177
+ msgid "Show map of photo location in carousel, when available."
178
+ msgstr ""
179
+
180
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:478
181
+ msgid "Black"
182
+ msgstr ""
183
+
184
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:478
185
+ msgid "White"
186
+ msgstr ""
187
+
188
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/jetpack-carousel.php:486
189
+ msgid "Display images in full-size carousel slideshow."
190
+ msgstr ""
191
+
192
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/tiled-gallery.php:420
193
+ msgid "Tiled Mosaic"
194
+ msgstr ""
195
+
196
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/tiled-gallery.php:421
197
+ msgid "Square Tiles"
198
+ msgstr ""
199
+
200
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/tiled-gallery.php:422
201
+ msgid "Circles"
202
+ msgstr ""
203
+
204
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/tiled-gallery.php:444
205
+ msgid "Tiled Galleries"
206
+ msgstr ""
207
+
208
+ #: /home/om/public_html/themepacific/wp-content/plugins/tiled-gallery-carousel-without-jetpack/tiled-gallery.php:451
209
+ msgid "Display all your gallery pictures in a cool mosaic."
210
+ msgstr ""
trunk/math/class-constrained-array-rounding.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Lets you round the numeric elements of an array to integers while preserving their sum.
5
+ *
6
+ * Usage:
7
+ *
8
+ * Jetpack_Constrained_Array_Rounding::get_rounded_constrained_array( $bound_array )
9
+ * if a specific sum doesn't need to be specified for the bound array
10
+ *
11
+ * Jetpack_Constrained_Array_Rounding::get_rounded_constrained_array( $bound_array, $sum )
12
+ * If the sum of $bound_array must equal $sum after rounding.
13
+ *
14
+ * If $sum is less than the sum of the floor of the elements of the array, the class defaults to using the sum of the array elements.
15
+ */
16
+ class themePacific_Jetpack_Constrained_Array_Rounding {
17
+ public static function get_rounded_constrained_array( $bound_array, $sum = false ) {
18
+ // Convert associative arrays before working with them and convert them back before returning the values
19
+ $keys = array_keys( $bound_array );
20
+ $bound_array = array_values( $bound_array );
21
+
22
+ $bound_array_int = self::get_int_floor_array( $bound_array );
23
+
24
+ $lower_sum = array_sum( wp_list_pluck( $bound_array_int, 'floor' ) );
25
+ if ( ! $sum || ( $sum < $lower_sum ) ) {
26
+ // If value of sum is not supplied or is invalid, calculate the sum that the returned array is constrained to match
27
+ $sum = array_sum( $bound_array );
28
+ }
29
+ $diff_sum = $sum - $lower_sum;
30
+
31
+ self::adjust_constrained_array( $bound_array_int, $diff_sum );
32
+
33
+ $bound_array_fin = wp_list_pluck( $bound_array_int, 'floor' );
34
+ return array_combine( $keys, $bound_array_fin );
35
+ }
36
+
37
+ private static function get_int_floor_array( $bound_array ) {
38
+ $bound_array_int_floor = array();
39
+ foreach ( $bound_array as $i => $value ){
40
+ $bound_array_int_floor[$i] = array(
41
+ 'floor' => (int) floor( $value ),
42
+ 'fraction' => $value - floor( $value ),
43
+ 'index' => $i,
44
+ );
45
+ }
46
+
47
+ return $bound_array_int_floor;
48
+ }
49
+
50
+ private static function adjust_constrained_array( &$bound_array_int, $adjustment ) {
51
+ usort( $bound_array_int, array( 'self', 'cmp_desc_fraction' ) );
52
+
53
+ $start = 0;
54
+ $end = $adjustment - 1;
55
+ $length = count( $bound_array_int );
56
+
57
+ for ( $i = $start; $i <= $end; $i++ ) {
58
+ $bound_array_int[ $i % $length ]['floor']++;
59
+ }
60
+
61
+ usort( $bound_array_int, array( 'self', 'cmp_asc_index' ) );
62
+ }
63
+
64
+ private static function cmp_desc_fraction( $a, $b ) {
65
+ if ( $a['fraction'] == $b['fraction'] )
66
+ return 0;
67
+ return $a['fraction'] > $b['fraction'] ? -1 : 1;
68
+ }
69
+
70
+ private static function cmp_asc_index( $a, $b ) {
71
+ if ( $a['index'] == $b['index'] )
72
+ return 0;
73
+ return $a['index'] < $b['index'] ? -1 : 1;
74
+ }
75
+ }
trunk/readme.txt ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Plugin Name ===
2
+
3
+ Tiled Gallery Carousel Without JetPack
4
+
5
+ Contributors:raja3c
6
+
7
+ Tags: Tiled gallery, carousel, gallery carousel, jetpack, Lightbox, Jetpack Lite
8
+
9
+ Requires at least: 3.4.1
10
+
11
+ Tested up to: 4.7.4
12
+
13
+ Stable tag: 2.2
14
+
15
+ License: GPLv2 or later
16
+
17
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
18
+
19
+
20
+
21
+ Tiled Gallery Carousel allows you to display image galleries in mosaic styles without Jetpack.
22
+
23
+
24
+
25
+ == Description ==
26
+
27
+
28
+
29
+ There is no doubt that JetPack packed with tons of features. However, many users don't want all that monstrous codes in their blog for one or two modules. Also, You should connect your blog to wordpress.com to get the JetPack features.
30
+
31
+
32
+
33
+ I really like that Tiled Gallery with Full Screen carousel module in JetPack and don't want other modules. That's why I've made the this Tiled Gallery Carousel Without JetPack Plugin from JetPack.
34
+
35
+
36
+
37
+ Tiled Gallery with carousel will completely transform your galleries to new look and your users will love this. Tiled Gallery allows you to display image galleries in following styles, a rectangular mosaic, a square mosaic, and a circular grid.
38
+
39
+
40
+
41
+
42
+
43
+ Demo Tiled Gallery : [Demo link](http://demo.themepacific.com/plugin-tiled-gallery-carousel/2013/10/13/tiled-gallery-carousel-without-jetpack-wordpress-plugin/ "Demo Link")
44
+
45
+
46
+
47
+
48
+
49
+ If you like this plugin then follow ThemePacific on [Twitter](http://twitter.com/themepacific "Twitter"), [Facebook](http://facebook.com/themepacific "Facebook"), and [Google+](https://plus.google.com/u/0/111626044701452949912 "Google+")
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+ == Installation ==
58
+
59
+
60
+
61
+ Download the Plugin here. 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.
62
+
63
+
64
+
65
+ Tiled Gallery and Carousel: Go to Settings > Media . There you will find more options.
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+ == Frequently Asked Questions ==
74
+
75
+
76
+
77
+ **About Update?**
78
+
79
+
80
+
81
+ This plugin will be updated whenever JetPack releases new version.
82
+
83
+
84
+
85
+
86
+
87
+ == Upgrade Notice ==
88
+
89
+
90
+
91
+ = 2.2 =
92
+
93
+ Compatible with latest version of the WordPress
94
+
95
+
96
+
97
+ == Changelog ==
98
+
99
+
100
+
101
+ = 2.2 =
102
+
103
+ * Compatible with latest version of the WordPress. Will Be Actively Maintained
104
+
105
+
106
+
107
+ = 2.1 =
108
+
109
+ * version not updated
110
+
111
+
112
+
113
+ = 2.0 =
114
+
115
+ * Tested upto 4.0
116
+
117
+
118
+
119
+ = 1.9 =
120
+
121
+ * Fatal error: Class 'Jetpack_Options' not found Fixed
122
+
123
+ * image_resize depreciated fixed
124
+
125
+
126
+
127
+ = 1.3 =
128
+
129
+ * Tested upto 3.9
130
+
131
+ = 0.1 =
132
+
133
+ *Initial Release
trunk/rtl/jetpack-carousel-rtl.css ADDED
@@ -0,0 +1,1106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file was automatically generated on Apr 17 2013 14:28:54 */
2
+
3
+ * {
4
+ line-height:inherit; /* prevent declarations of line-height in the universal selector */
5
+ }
6
+
7
+ .jp-carousel-overlay {
8
+ background: #000;
9
+ }
10
+
11
+ div.jp-carousel-fadeaway {
12
+ background: -moz-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0));
13
+ background: -webkit-gradient(linear, right bottom, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0)));
14
+ position: fixed;
15
+ bottom: 0;
16
+ z-index: 2147483647;
17
+ width: 100%;
18
+ height: 15px;
19
+ }
20
+
21
+ .jp-carousel-next-button span,
22
+ .jp-carousel-previous-button span {
23
+ background: url(.././images/arrows.png) no-repeat center center;
24
+ background-size: 200px 126px;
25
+ }
26
+
27
+ @media
28
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
29
+ only screen and (-o-min-device-pixel-ratio: 3/2),
30
+ only screen and (min--moz-device-pixel-ratio: 1.5),
31
+ only screen and (min-device-pixel-ratio: 1.5) {
32
+ .jp-carousel-next-button span,
33
+ .jp-carousel-previous-button span {
34
+ background-image: url(.././images/arrows-2x.png);
35
+ }
36
+ }
37
+
38
+ .jp-carousel-wrap {
39
+ font-family: "Helvetica Neue", sans-serif !important;
40
+ }
41
+
42
+ .jp-carousel-info {
43
+ position: absolute;
44
+ bottom: 0;
45
+ text-align: right !important;
46
+ -webkit-font-smoothing: subpixel-antialiased !important;
47
+ }
48
+
49
+ .jp-carousel-info ::selection {
50
+ background: #68c9e8; /* Safari */
51
+ color: #fff;
52
+ }
53
+
54
+ .jp-carousel-info ::-moz-selection {
55
+ background: #68c9e8; /* Firefox */
56
+ color: #fff;
57
+ }
58
+
59
+ .jp-carousel-photo-info {
60
+ position: relative;
61
+ -webkit-transition: 400ms ease-out;
62
+ -moz-transition: 400ms ease-out;
63
+ -o-transition: 400ms ease-out;
64
+ transition: 400ms ease-out;
65
+ right: 25%;
66
+ width: 50%;
67
+ }
68
+
69
+ .jp-carousel-info h2 {
70
+ background: none !important;
71
+ border: none !important;
72
+ color: #999;
73
+ display: block !important;
74
+ font: normal 13px/1.25em "Helvetica Neue", sans-serif !important;
75
+ letter-spacing: 0 !important;
76
+ margin: 7px 0 0 0 !important;
77
+ padding: 10px 0 0 !important;
78
+ overflow: hidden;
79
+ text-align: right;
80
+ text-shadow: none !important;
81
+ text-transform: none !important;
82
+ -webkit-font-smoothing: subpixel-antialiased;
83
+ }
84
+
85
+ .jp-carousel-next-button,
86
+ .jp-carousel-previous-button {
87
+ text-indent: -9999px;
88
+ overflow: hidden;
89
+ cursor: pointer;
90
+ }
91
+
92
+ .jp-carousel-next-button span,
93
+ .jp-carousel-previous-button span {
94
+ position: absolute;
95
+ top: 0;
96
+ bottom: 0;
97
+ width: 82px;
98
+ zoom: 1;
99
+ filter: alpha(opacity=20);
100
+ opacity: 0.2;
101
+ -webkit-transition: 500ms opacity ease-out;
102
+ -moz-transition: 500ms opacity ease-out;
103
+ -o-transition: 500ms opacity ease-out;
104
+ transition: 500ms opacity ease-out;
105
+ }
106
+
107
+ .jp-carousel-next-button:hover span,
108
+ .jp-carousel-previous-button:hover span {
109
+ filter: alpha(opacity=60);
110
+ opacity: 0.6;
111
+ }
112
+ .jp-carousel-next-button span {
113
+ background-position: -110px center;
114
+ left: 0;
115
+ }
116
+
117
+ .jp-carousel-previous-button span {
118
+ background-position: -10px center;
119
+ right:0;
120
+ }
121
+
122
+ .jp-carousel-buttons {
123
+ margin:-18px -20px 15px;
124
+ padding:8px 10px;
125
+ border-bottom:1px solid #222;
126
+ background: #222;
127
+ text-align: center;
128
+ }
129
+
130
+ div.jp-carousel-buttons a {
131
+ border: none !important;
132
+ color: #999;
133
+ font: normal 11px/1.2em "Helvetica Neue", sans-serif !important;
134
+ letter-spacing: 0 !important;
135
+ padding: 5px 0 5px 2px;
136
+ text-decoration: none !important;
137
+ text-shadow: none !important;
138
+ vertical-align: middle;
139
+ -webkit-font-smoothing: subpixel-antialiased;
140
+ }
141
+
142
+ div.jp-carousel-buttons a:hover {
143
+ color: #68c9e8;
144
+ border: none !important;
145
+ -webkit-transition: none !important;
146
+ -moz-transition: none !important;
147
+ -o-transition: none !important;
148
+ transition: none !important;
149
+ }
150
+
151
+ .jp-carousel-slide, .jp-carousel-slide img, .jp-carousel-next-button,
152
+ .jp-carousel-previous-button {
153
+ -webkit-transform:translate3d(0, 0, 0);
154
+ -moz-transform:translate3d(0, 0, 0);
155
+ -o-transform:translate3d(0, 0, 0);
156
+ -ms-transform:translate3d(0, 0, 0);
157
+ }
158
+
159
+ .jp-carousel-slide {
160
+ position:absolute;
161
+ width:0;
162
+ bottom:0;
163
+ background-color:#000;
164
+ border-radius:2px;
165
+ -webkit-border-radius:2px;
166
+ -moz-border-radius:2px;
167
+ -ms-border-radius:2px;
168
+ -o-border-radius:2px;
169
+ -webkit-transition: 400ms ease-out;
170
+ -moz-transition: 400ms ease-out;
171
+ -o-transition: 400ms ease-out;
172
+ transition: 400ms ease-out;
173
+ }
174
+
175
+ .jp-carousel-slide img {
176
+ display: block;
177
+ width: 100% !important;
178
+ height: 100% !important;
179
+ max-width: 100% !important;
180
+ max-height: 100% !important;
181
+ background: none !important;
182
+ border: none !important;
183
+ padding: 0 !important;
184
+ -webkit-box-shadow: 0 2px 8px rgba(0,0,0,0.1);
185
+ -moz-box-shadow: 0 2px 8px rgba(0,0,0,0.1);
186
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
187
+ zoom: 1;
188
+ filter: alpha(opacity=25);
189
+ opacity: 0.25;
190
+ -webkit-transition: opacity 400ms linear;
191
+ -moz-transition: opacity 400ms linear;
192
+ -o-transition: opacity 400ms linear;
193
+ transition: opacity 400ms linear;
194
+ }
195
+
196
+ .jp-carousel-slide.selected img {
197
+ filter: alpha(opacity=100);
198
+ opacity: 1;
199
+ }
200
+
201
+ .jp-carousel-close-hint {
202
+ color: #999;
203
+ cursor: default;
204
+ letter-spacing: 0 !important;
205
+ padding:0.35em 0 0;
206
+ position: absolute;
207
+ text-align: right;
208
+ width: 90%;
209
+ -webkit-transition: color 200ms linear;
210
+ -moz-transition: color 200ms linear;
211
+ -o-transition: color 200ms linear;
212
+ transition: color 200ms linear;
213
+ }
214
+
215
+ .jp-carousel-close-hint span {
216
+ cursor: pointer;
217
+ background-color: black;
218
+ background-color: rgba(0,0,0,0.8);
219
+ display: block;
220
+ height: 22px;
221
+ font: 400 24px/1 "Helvetica Neue", sans-serif !important;
222
+ line-height: 22px;
223
+ margin: 0 0.4em 0 0;
224
+ text-align: center;
225
+ vertical-align: middle;
226
+ width: 22px;
227
+ -moz-border-radius: 4px;
228
+ -webkit-border-radius: 4px;
229
+ border-radius: 4px;
230
+ -webkit-transition: border-color 200ms linear;
231
+ -moz-transition: border-color 200ms linear;
232
+ -o-transition: border-color 200ms linear;
233
+ transition: border-color 200ms linear;
234
+ }
235
+
236
+ .jp-carousel-close-hint:hover {
237
+ cursor: default;
238
+ color: #fff;
239
+ }
240
+
241
+ .jp-carousel-close-hint:hover span {
242
+ border-color: #fff;
243
+ }
244
+
245
+ div.jp-carousel-buttons a.jp-carousel-like,
246
+ div.jp-carousel-buttons a.jp-carousel-reblog,
247
+ div.jp-carousel-buttons a.jp-carousel-commentlink,
248
+ a.jp-carousel-image-download {
249
+ background: url(.././images/carousel-sprite.png?4) no-repeat;
250
+ background-size: 16px 160px;
251
+ }
252
+
253
+ div.jp-carousel-buttons a.jp-carousel-reblog,
254
+ div.jp-carousel-buttons a.jp-carousel-commentlink {
255
+ margin:0 0 0 14px !important;
256
+ }
257
+
258
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged,
259
+ div.jp-carousel-buttons a.jp-carousel-like.liked {
260
+ background-color: #303030;
261
+ padding-left: 8px !important;
262
+ border-radius: 2px;
263
+ border-radius:2px;
264
+ -webkit-border-radius:2px;
265
+ -moz-border-radius:2px;
266
+ -ms-border-radius:2px;
267
+ -o-border-radius:2px;
268
+ }
269
+
270
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged {
271
+ margin:0 -12px 0 2px !important;
272
+ }
273
+
274
+
275
+ div.jp-carousel-buttons a.jp-carousel-reblog,
276
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged:hover {
277
+ background-position: 6px -36px;
278
+ padding-right: 26px !important;
279
+ color: #999;
280
+ }
281
+
282
+ div.jp-carousel-buttons a.jp-carousel-commentlink {
283
+ background-position: 0px -116px;
284
+ padding-right: 19px !important;
285
+ }
286
+
287
+ div.jp-carousel-buttons a.jp-carousel-reblog.reblogged:hover {
288
+ cursor: default;
289
+ }
290
+
291
+ div.jp-carousel-buttons a.jp-carousel-reblog:hover {
292
+ background-position: 6px -56px;
293
+ color: #68c9e8;
294
+ }
295
+
296
+ div.jp-carousel-buttons a.jp-carousel-like {
297
+ background-position: 5px 5px;
298
+ padding-right: 24px !important;
299
+ }
300
+
301
+ div.jp-carousel-buttons a.jp-carousel-like:hover {
302
+ background-position: 5px -15px;
303
+ }
304
+
305
+ @media
306
+ only screen and (-webkit-min-device-pixel-ratio: 1.5),
307
+ only screen and (-o-min-device-pixel-ratio: 3/2),
308
+ only screen and (min--moz-device-pixel-ratio: 1.5),
309
+ only screen and (min-device-pixel-ratio: 1.5) {
310
+ div.jp-carousel-buttons a.jp-carousel-like,
311
+ div.jp-carousel-buttons a.jp-carousel-reblog,
312
+ div.jp-carousel-buttons a.jp-carousel-commentlink,
313
+ a.jp-carousel-image-download {
314
+ background-image: url(.././images/carousel-sprite-2x.png?4);
315
+ }
316
+ }
317
+
318
+ /* reblog */
319
+ div#carousel-reblog-box {
320
+ background: #222;
321
+ background: -moz-linear-gradient(bottom, #222, #333);
322
+ background: -webkit-gradient(linear, right bottom, right top, from(#222), to(#333));
323
+ padding: 3px 0 0;
324
+ display: none;
325
+ margin: 5px auto 0;
326
+ -moz-border-radius: 2px;
327
+ -webkit-border-radius: 2px;
328
+ border-radius: 2px;
329
+ -webkit-box-shadow: 0 0 20px rgba(0,0,0,0.9);
330
+ -moz-box-shadow: 0 0 20px rgba(0,0,0,0.9);
331
+ box-shadow: 0 0 20px rgba(0,0,0,0.9);
332
+ height: 74px;
333
+ width: 565px;
334
+ }
335
+
336
+ #carousel-reblog-box textarea {
337
+ background: #999;
338
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
339
+ color: #444;
340
+ padding: 3px 6px;
341
+ width: 370px;
342
+ height: 48px;
343
+ float: right;
344
+ margin: 6px 9px 0 9px;
345
+ border: 1px solid #666;
346
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
347
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
348
+ -moz-border-radius: 2px;
349
+ -webkit-border-radius: 2px;
350
+ border-radius: 2px;
351
+ }
352
+
353
+ #carousel-reblog-box textarea:focus {
354
+ background: #ccc;
355
+ color: #222;
356
+ }
357
+
358
+ #carousel-reblog-box label {
359
+ color: #aaa;
360
+ font-size: 11px;
361
+ padding-left: 2px;
362
+ padding-right: 2px;
363
+ display: inline;
364
+ font-weight: normal;
365
+ }
366
+
367
+ #carousel-reblog-box select {
368
+ width: 110px;
369
+ padding: 0;
370
+ font-size: 12px;
371
+ font-family: "Helvetica Neue", sans-serif !important;
372
+ background: #333;
373
+ color: #eee;
374
+ border: 1px solid #444;
375
+ margin-top:5px;
376
+ }
377
+
378
+ #carousel-reblog-box .submit,
379
+ #wrapper #carousel-reblog-box p.response {
380
+ float: right;
381
+ width: 154px;
382
+ padding-top: 0;
383
+ padding-right: 1px;
384
+ overflow: hidden;
385
+ height: 34px;
386
+ margin:3px 2px 0 0 !important;
387
+ }
388
+
389
+ #wrapper #carousel-reblog-box p.response {
390
+ font-size: 13px;
391
+ clear: none;
392
+ padding-right: 2px;
393
+ height: 34px;
394
+ color: #aaa;
395
+ }
396
+
397
+ #carousel-reblog-box input#carousel-reblog-submit, #jp-carousel-comment-form-button-submit {
398
+ font: 13px/24px "Helvetica Neue", sans-serif !important;
399
+ margin-top: 8px;
400
+ padding: 0 10px !important;
401
+ border-radius: 1em;
402
+ height: 24px;
403
+ color: #333;
404
+ cursor:pointer;
405
+ font-weight: normal;
406
+ background: #aaa;
407
+ background: -moz-linear-gradient(bottom, #aaa, #ccc);
408
+ background: -webkit-gradient(linear, right bottom, right top, from(#aaa), to(#ccc));
409
+ border: 1px solid #444;
410
+ }
411
+
412
+ #carousel-reblog-box input#carousel-reblog-submit:hover, #jp-carousel-comment-form-button-submit:hover {
413
+ background: #ccc;
414
+ background: -moz-linear-gradient(bottom, #ccc, #eee);
415
+ background: -webkit-gradient(linear, right bottom, right top, from(#ccc), to(#eee));
416
+ }
417
+
418
+ #carousel-reblog-box .canceltext {
419
+ color: #aaa;
420
+ font-size: 11px;
421
+ line-height: 24px;
422
+ }
423
+
424
+ #carousel-reblog-box .canceltext a {
425
+ color: #fff;
426
+ }
427
+ /* reblog end */
428
+
429
+
430
+ /** Title and Desc Start **/
431
+ .jp-carousel-titleanddesc {
432
+ border-top: 1px solid #222;
433
+ color: #999;
434
+ font-size: 15px;
435
+ padding-top: 24px;
436
+ margin-bottom: 20px;
437
+ font-weight:400;
438
+ }
439
+ .jp-carousel-titleanddesc-title {
440
+ font: 300 1.5em/1.1 "Helvetica Neue", sans-serif !important;
441
+ text-transform: none !important; /* prevents uppercase from leaking through */
442
+ color: #fff;
443
+ margin: 0 0 15px;
444
+ padding:0;
445
+ }
446
+
447
+ .jp-carousel-titleanddesc-desc p {
448
+ color: #999;
449
+ line-height:1.4;
450
+ margin-bottom: 0.75em;
451
+ }
452
+
453
+ .jp-carousel-titleanddesc p a,
454
+ .jp-carousel-comments p a,
455
+ .jp-carousel-info h2 a {
456
+ color: #fff !important;
457
+ border: none !important;
458
+ text-decoration: underline !important;
459
+ font-weight: normal !important;
460
+ font-style: normal !important;
461
+ }
462
+
463
+ .jp-carousel-titleanddesc p strong,
464
+ .jp-carousel-titleanddesc p b {
465
+ font-weight: bold;
466
+ color: #999;
467
+ }
468
+
469
+ .jp-carousel-titleanddesc p em,
470
+ .jp-carousel-titleanddesc p i {
471
+ font-style: italic;
472
+ color: #999;
473
+ }
474
+
475
+
476
+ .jp-carousel-titleanddesc p a:hover,
477
+ .jp-carousel-comments p a:hover,
478
+ .jp-carousel-info h2 a:hover {
479
+ color: #68c9e8 !important;
480
+ }
481
+
482
+ .jp-carousel-titleanddesc p:empty {
483
+ display: none;
484
+ }
485
+
486
+ .jp-carousel-photo-info h1:before,
487
+ .jp-carousel-photo-info h1:after,
488
+ .jp-carousel-left-column-wrapper h1:before,
489
+ .jp-carousel-left-column-wrapper h1:after {
490
+ content:none !important;
491
+ }
492
+ /** Title and Desc End **/
493
+
494
+ /** Meta Box Start **/
495
+ .jp-carousel-image-meta {
496
+ background: #111;
497
+ border: 1px solid #222;
498
+ color: #fff;
499
+ font-size: 13px;
500
+ font: 12px/1.4 "Helvetica Neue", sans-serif !important;
501
+ overflow: hidden;
502
+ padding: 18px 20px;
503
+ width: 209px !important;
504
+ }
505
+
506
+ .jp-carousel-image-meta li,
507
+ .jp-carousel-image-meta h5 {
508
+ font-family: "Helvetica Neue", sans-serif !important;
509
+ position: inherit !important;
510
+ top: auto !important;
511
+ left: auto !important;
512
+ right: auto !important;
513
+ bottom: auto !important;
514
+ background: none !important;
515
+ border: none !important;
516
+ font-weight: 400 !important;
517
+ line-height: 1.3em !important;
518
+ }
519
+
520
+ .jp-carousel-image-meta ul {
521
+ margin: 0 !important;
522
+ padding: 0 !important;
523
+ list-style: none !important;
524
+ }
525
+
526
+ .jp-carousel-image-meta li {
527
+ width: 48% !important;
528
+ float: right !important;
529
+ margin: 0 0 15px 2% !important;
530
+ color: #fff !important;
531
+ font-size:13px !important;
532
+ }
533
+
534
+ .jp-carousel-image-meta h5 {
535
+ color: #999 !important;
536
+ text-transform: uppercase !important;
537
+ font-size:10px !important;
538
+ margin:0 0 2px !important;
539
+ letter-spacing: 0.1em !important;
540
+ }
541
+
542
+ a.jp-carousel-image-download {
543
+ padding-right: 23px;
544
+ display: inline-block;
545
+ clear: both;
546
+ color: #999;
547
+ line-height: 1;
548
+ font-weight: 400;
549
+ font-size: 13px;
550
+ text-decoration: none;
551
+ background-position: 0 -82px;
552
+ }
553
+
554
+ a.jp-carousel-image-download span.photo-size {
555
+ font-size: 11px;
556
+ border-radius: 1em;
557
+ margin-right: 2px;
558
+ display: inline-block;
559
+ }
560
+
561
+ a.jp-carousel-image-download span.photo-size-times {
562
+ padding: 0 2px 0 1px;
563
+ }
564
+
565
+ a.jp-carousel-image-download:hover {
566
+ background-position: 0 -102px;
567
+ color: #68c9e8;
568
+ border: none !important;
569
+ }
570
+
571
+ /** Meta Box End **/
572
+
573
+ /** GPS Map Start **/
574
+ .jp-carousel-image-map {
575
+ position: relative;
576
+ margin: -20px -20px 20px;
577
+ border-bottom: 1px solid rgba( 255, 255, 255, 0.17 );
578
+ height: 154px;
579
+ }
580
+
581
+ .jp-carousel-image-map img.gmap-main {
582
+ -moz-border-radius-topleft: 6px;
583
+ border-top-right-radius: 6px;
584
+ border-left: 1px solid rgba( 255, 255, 255, 0.17 );
585
+ }
586
+ .jp-carousel-image-map div.gmap-topright {
587
+ width: 94px;
588
+ height: 154px;
589
+ position: absolute;
590
+ top: 0;
591
+ left: 0;
592
+ }
593
+ .jp-carousel-image-map div.imgclip {
594
+ overflow: hidden;
595
+ -moz-border-radius-topright: 6px;
596
+ border-top-left-radius: 6px;
597
+ }
598
+ .jp-carousel-image-map div.gmap-topright img {
599
+ margin-right: -40px;
600
+ }
601
+ .jp-carousel-image-map img.gmap-bottomright {
602
+ position: absolute;
603
+ top: 96px;
604
+ left: 0;
605
+ }
606
+
607
+ /** Comments Start **/
608
+ .jp-carousel-comments {
609
+ font: 15px/1.7 "Helvetica Neue", sans-serif !important;
610
+ font-weight: 400;
611
+ background:none transparent;
612
+ }
613
+
614
+ .jp-carousel-comments p a:hover, .jp-carousel-comments p a:focus, .jp-carousel-comments p a:active {
615
+ color: #68c9e8 !important;
616
+ }
617
+
618
+ .jp-carousel-comment {
619
+ background:none transparent;
620
+ color: #999;
621
+ margin-bottom: 20px;
622
+ clear:right;
623
+ overflow: auto;
624
+ width: 100%
625
+ }
626
+
627
+ .jp-carousel-comment p {
628
+ color: #999 !important;
629
+ }
630
+
631
+ .jp-carousel-comment .comment-author {
632
+ font-size: 13px;
633
+ font-weight:400;
634
+ padding:0;
635
+ width:auto;
636
+ display: inline;
637
+ float:none;
638
+ border:none;
639
+ margin:0;
640
+ }
641
+
642
+ .jp-carousel-comment .comment-author a {
643
+ color: #fff;
644
+ }
645
+
646
+ .jp-carousel-comment .comment-gravatar {
647
+ float:right;
648
+ }
649
+
650
+ .jp-carousel-comment .comment-content {
651
+ border:none;
652
+ margin-right:85px;
653
+ padding: 0;
654
+ }
655
+
656
+ .jp-carousel-comment .avatar {
657
+ margin:0 0 0 20px;
658
+ -moz-border-radius: 4px;
659
+ -webkit-border-radius: 4px;
660
+ border-radius: 4px;
661
+ border: none !important;
662
+ padding: 0 !important;
663
+ background-color: transparent !important;
664
+ }
665
+
666
+ .jp-carousel-comment .comment-date {
667
+ color:#999;
668
+ margin-top: 4px;
669
+ font-size:11px;
670
+ display: inline;
671
+ float: left;
672
+ /*clear: right;*/
673
+ }
674
+
675
+ #jp-carousel-comment-form {
676
+ margin:0 0 10px !important;
677
+ float: right;
678
+ width: 100%;
679
+ }
680
+
681
+ textarea#jp-carousel-comment-form-comment-field {
682
+ background: rgba(34,34,34,0.9);
683
+ border: 1px solid #3a3a3a;
684
+ color: #aaa;
685
+ font: 15px/1.4 "Helvetica Neue", sans-serif !important;
686
+ width: 100%;
687
+ padding: 10px 10px 5px;
688
+ margin: 0;
689
+ float: none;
690
+ height: 147px;
691
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
692
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
693
+ -moz-border-radius: 3px;
694
+ -webkit-border-radius: 3px;
695
+ border-radius: 3px;
696
+ overflow: hidden;
697
+ -webkit-box-sizing: border-box;
698
+ -moz-box-sizing: border-box;
699
+ box-sizing: border-box;
700
+ }
701
+
702
+ textarea#jp-carousel-comment-form-comment-field::-webkit-input-placeholder {
703
+ color: #555;
704
+ }
705
+
706
+ textarea#jp-carousel-comment-form-comment-field:focus {
707
+ background: #ccc;
708
+ color: #222;
709
+ }
710
+
711
+ textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder {
712
+ color: #aaa;
713
+ }
714
+
715
+ #jp-carousel-comment-form-spinner {
716
+ color: #fff;
717
+ margin:22px 10px 0 0;
718
+ display: block;
719
+ width: 20px;
720
+ height: 20px;
721
+ float: right;
722
+ }
723
+
724
+ #jp-carousel-comment-form-submit-and-info-wrapper {
725
+ display: none;
726
+ /*margin-bottom:15px;*/
727
+ overflow: hidden;
728
+ width: 100%
729
+ }
730
+
731
+ #jp-carousel-comment-form-commenting-as {
732
+ }
733
+
734
+ #jp-carousel-comment-form-commenting-as input {
735
+ background: rgba(34,34,34,0.9);
736
+ border: 1px solid #3a3a3a;
737
+ color: #aaa;
738
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
739
+ padding: 3px 6px;
740
+ float: right;
741
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
742
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
743
+ -moz-border-radius: 2px;
744
+ -webkit-border-radius: 2px;
745
+ border-radius: 2px;
746
+ width:285px;
747
+ }
748
+
749
+ #jp-carousel-comment-form-commenting-as input:focus {
750
+ background: #ccc;
751
+ color: #222;
752
+ }
753
+
754
+ #jp-carousel-comment-form-commenting-as p {
755
+ font: 400 13px/1.7 "Helvetica Neue", sans-serif !important;
756
+ margin:22px 0 0;
757
+ float: right;
758
+ }
759
+
760
+ #jp-carousel-comment-form-commenting-as fieldset {
761
+ float:right;
762
+ border:none;
763
+ margin:20px 0 0 0;
764
+ padding:0;
765
+ }
766
+
767
+ #jp-carousel-comment-form-commenting-as fieldset {
768
+ clear: both;
769
+ }
770
+
771
+ #jp-carousel-comment-form-commenting-as label {
772
+ font: 400 13px/1.7 "Helvetica Neue", sans-serif !important;
773
+ margin:0 0 3px 20px;
774
+ float:right;
775
+ width:100px;
776
+ }
777
+
778
+ #jp-carousel-comment-form-button-submit {
779
+ margin-top: 20px;
780
+ float:left;
781
+ }
782
+
783
+ #js-carousel-comment-form-container {
784
+ margin-bottom:15px;
785
+ overflow: auto;
786
+ width: 100%;
787
+ }
788
+
789
+ #jp-carousel-comment-form-container {
790
+ margin-bottom:15px;
791
+ overflow: auto;
792
+ width: 100%;
793
+ }
794
+
795
+ #jp-carousel-comment-post-results {
796
+ display: none;
797
+ overflow:auto;
798
+ width:100%;
799
+ }
800
+
801
+ #jp-carousel-comment-post-results span {
802
+ display:block;
803
+ text-align: center;
804
+ margin-top:20px;
805
+ width: 100%;
806
+ overflow: auto;
807
+ padding: 1em 0;
808
+ box-sizing: border-box;
809
+ background: rgba( 0, 0, 0, 0.7 );
810
+ border-radius: 2px;
811
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
812
+ border: 1px solid rgba( 255, 255, 255, 0.17 );
813
+ -webkit-box-shadow: inset 0px 5px 5px 0px rgba(0, 0, 0, 1);
814
+ box-shadow: inset 0px 5px 5px 0px rgba(0, 0, 0, 1);
815
+ }
816
+
817
+ .jp-carousel-comment-post-error {
818
+ color:#DF4926;
819
+ }
820
+
821
+ .jp-carousel-comment-post-success {
822
+ /*color:#21759B;*/
823
+ }
824
+
825
+ #jp-carousel-comments-closed {
826
+ display: none;
827
+ color: #999;
828
+ }
829
+
830
+ #jp-carousel-comments-loading {
831
+ font: 444 15px/1.7 "Helvetica Neue", sans-serif !important;
832
+ display: none;
833
+ color: #999;
834
+ text-align: right;
835
+ margin-bottom: 20px;
836
+ }
837
+
838
+
839
+ /* ----- Light variant ----- */
840
+
841
+ .jp-carousel-light .jp-carousel-overlay {
842
+ background: #fff;
843
+ }
844
+
845
+ .jp-carousel-light .jp-carousel-next-button:hover span,
846
+ .jp-carousel-light .jp-carousel-previous-button:hover span {
847
+ opacity: 0.8;
848
+ }
849
+
850
+ .jp-carousel-light .jp-carousel-close-hint:hover,
851
+ .jp-carousel-light .jp-carousel-titleanddesc div {
852
+ color: #000 !important;
853
+ }
854
+
855
+ .jp-carousel-light .jp-carousel-comments p a,
856
+ .jp-carousel-light .jp-carousel-comment .comment-author a,
857
+ .jp-carousel-light .jp-carousel-titleanddesc p a,
858
+ .jp-carousel-light .jp-carousel-titleanddesc p a,
859
+ .jp-carousel-light .jp-carousel-comments p a,
860
+ .jp-carousel-light .jp-carousel-info h2 a {
861
+ color: #1e8cbe !important;
862
+ }
863
+
864
+ .jp-carousel-light .jp-carousel-comments p a:hover,
865
+ .jp-carousel-light .jp-carousel-comment .comment-author a:hover,
866
+ .jp-carousel-light .jp-carousel-titleanddesc p a:hover,
867
+ .jp-carousel-light .jp-carousel-titleanddesc p a:hover,
868
+ .jp-carousel-light .jp-carousel-comments p a:hover,
869
+ .jp-carousel-light .jp-carousel-info h2 a:hover {
870
+ color: #f1831e !important;
871
+ }
872
+
873
+ .jp-carousel-light .jp-carousel-info h2,
874
+ .jp-carousel-light .jp-carousel-titleanddesc,
875
+ .jp-carousel-light .jp-carousel-titleanddesc p,
876
+ .jp-carousel-light .jp-carousel-comment,
877
+ .jp-carousel-light .jp-carousel-comment p,
878
+ .jp-carousel-light div.jp-carousel-buttons a,
879
+ .jp-carousel-light .jp-carousel-titleanddesc p strong,
880
+ .jp-carousel-light .jp-carousel-titleanddesc p b,
881
+ .jp-carousel-light .jp-carousel-titleanddesc p em,
882
+ .jp-carousel-light .jp-carousel-titleanddesc p i {
883
+ color: #666;
884
+ }
885
+
886
+ .jp-carousel-light .jp-carousel-buttons {
887
+ border-bottom-color: #f0f0f0;
888
+ background: #f5f5f5;
889
+ }
890
+
891
+ .jp-carousel-light div.jp-carousel-buttons a:hover {
892
+ text-decoration: none;
893
+ color: #f1831e;
894
+ }
895
+
896
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog,
897
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog:hover {
898
+ background-position: 4px -56px;
899
+ padding-right: 24px !important;
900
+ }
901
+
902
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog.reblogged,
903
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like.liked {
904
+ background-color: #2ea2cc;
905
+ color: #fff;
906
+ }
907
+
908
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-commentlink {
909
+ background-position: 0px -136px;
910
+ }
911
+
912
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like,
913
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like:hover {
914
+ background-position: 5px -15px;
915
+ padding-right: 23px !important;
916
+ }
917
+
918
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog.reblogged {
919
+ background-position: 5px -36px;
920
+ }
921
+
922
+ .jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like.liked {
923
+ background-position: 5px 5px;
924
+ }
925
+
926
+ .jp-carousel-light div#carousel-reblog-box {
927
+ background: #eee;
928
+ background: -moz-linear-gradient(bottom, #ececec, #f7f7f7);
929
+ background: -webkit-gradient(linear, right bottom, right top, from(#ececec), to(#f7f7f7));
930
+ -webkit-box-shadow: 0 2px 6px rgba(0,0,0,0.1);
931
+ -moz-box-shadow: 0 2px 10px rgba(0,0,0,0.1);
932
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
933
+ border:1px solid #ddd;
934
+ }
935
+
936
+ .jp-carousel-light #carousel-reblog-box textarea {
937
+ border: 1px inset #ccc;
938
+ color: #666;
939
+ border: 1px solid #cfcfcf;
940
+ background: #fff;
941
+ }
942
+
943
+ .jp-carousel-light #carousel-reblog-box .canceltext {
944
+ color: #888;
945
+ }
946
+
947
+ .jp-carousel-light #carousel-reblog-box .canceltext a {
948
+ color: #666;
949
+ }
950
+
951
+ .jp-carousel-light #carousel-reblog-box select {
952
+ background: #eee;
953
+ color: #333;
954
+ border: 1px solid #aaa;
955
+ }
956
+
957
+ .jp-carousel-light #carousel-reblog-box input#carousel-reblog-submit, #jp-carousel-comment-form-button-submit {
958
+ color: #333;
959
+ background: #fff;
960
+ background: -moz-linear-gradient(bottom, #ddd, #fff);
961
+ background: -webkit-gradient(linear, right bottom, right top, from(#ddd), to(#fff));
962
+ border: 1px solid #aaa;
963
+ }
964
+
965
+ .jp-carousel-light .jp-carousel-image-meta {
966
+ background: #fafafa;
967
+ border: 1px solid #eee;
968
+ border-top-color: #f5f5f5;
969
+ border-right-color: #f5f5f5;
970
+ color: #333;
971
+ }
972
+
973
+ .jp-carousel-light .jp-carousel-image-meta li {
974
+ color: #000 !important;
975
+ }
976
+
977
+ .jp-carousel-light .jp-carousel-close-hint {
978
+ color: #ccc;
979
+ }
980
+
981
+ .jp-carousel-light .jp-carousel-close-hint span {
982
+ background-color: white;
983
+ border-color: #ccc;
984
+ }
985
+
986
+ .jp-carousel-light #jp-carousel-comment-form-comment-field::-webkit-input-placeholder {
987
+ color: #aaa;
988
+ }
989
+
990
+ .jp-carousel-light #jp-carousel-comment-form-comment-field:focus {
991
+ color: #333;
992
+ }
993
+
994
+ .jp-carousel-light #jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder {
995
+ color: #ddd;
996
+ }
997
+
998
+ .jp-carousel-light a.jp-carousel-image-download {
999
+ background-position: 0 -102px;
1000
+ }
1001
+
1002
+ .jp-carousel-light a.jp-carousel-image-download:hover {
1003
+ background-position: 0 -102px;
1004
+ color: #f1831e;
1005
+ }
1006
+
1007
+ .jp-carousel-light textarea#jp-carousel-comment-form-comment-field {
1008
+ background: #fbfbfb;
1009
+ color: #333;
1010
+ border: 1px solid #dfdfdf;
1011
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1012
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1013
+ }
1014
+
1015
+ .jp-carousel-light #jp-carousel-comment-form-commenting-as input {
1016
+ background: #fbfbfb;
1017
+ border: 1px solid #dfdfdf;
1018
+ color: #333;
1019
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1020
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
1021
+ }
1022
+
1023
+ .jp-carousel-light #jp-carousel-comment-form-commenting-as input:focus {
1024
+ background: #fbfbfb;
1025
+ color: #333;
1026
+ }
1027
+
1028
+ .jp-carousel-light #jp-carousel-comment-post-results span {
1029
+ background: #f7f7f7;
1030
+ border:1px solid #dfdfdf;
1031
+ -webkit-box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.05);
1032
+ box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.05);
1033
+ }
1034
+
1035
+ .jp-carousel-light .jp-carousel-slide {
1036
+ background-color:#fff;
1037
+ }
1038
+
1039
+ .jp-carousel-light .jp-carousel-titleanddesc {
1040
+ border-top: 1px solid #eee;
1041
+ }
1042
+
1043
+ .jp-carousel-light .jp-carousel-fadeaway {
1044
+ background: -moz-linear-gradient(bottom, rgba(255,255,255,0.75), rgba(255,255,255,0));
1045
+ background: -webkit-gradient(linear, right bottom, right top, from(rgba(255,255,255,0.75)), to(rgba(255,255,255,0)));
1046
+ }
1047
+
1048
+ /* Small screens */
1049
+ @media only screen and (max-width: 760px) {
1050
+
1051
+ .jp-carousel-info {
1052
+ margin: 0 10px !important;
1053
+ }
1054
+
1055
+ .jp-carousel-next-button, .jp-carousel-previous-button {
1056
+ display: none !important;
1057
+ }
1058
+
1059
+ .jp-carousel-buttons {
1060
+ display: none !important;
1061
+ }
1062
+
1063
+ .jp-carousel-image-meta {
1064
+ float: none !important;
1065
+ width: 100% !important;
1066
+ -moz-box-sizing:border-box;
1067
+ -webkit-box-sizing:border-box;
1068
+ box-sizing: border-box;
1069
+ }
1070
+
1071
+ .jp-carousel-close-hint {
1072
+ font-weight: 800 !important;
1073
+ font-size: 26px !important;
1074
+ position: fixed !important;
1075
+ top: -10px;
1076
+ }
1077
+
1078
+ .jp-carousel-slide img {
1079
+ filter: alpha(opacity=100);
1080
+ opacity: 1;
1081
+ }
1082
+
1083
+ .jp-carousel-wrap {
1084
+ background-color: #000;
1085
+ }
1086
+
1087
+ .jp-carousel-fadeaway {
1088
+ display: none;
1089
+ }
1090
+
1091
+ #jp-carousel-comment-form-container {
1092
+ display: none !important;
1093
+ }
1094
+
1095
+ .jp-carousel-titleanddesc {
1096
+ padding-top: 0 !important;
1097
+ border: none !important;
1098
+ }
1099
+ .jp-carousel-titleanddesc-title {
1100
+ font-size: 1em !important;
1101
+ }
1102
+
1103
+ .jp-carousel-left-column-wrapper {
1104
+ padding: 0;
1105
+ }
1106
+ }
trunk/spin.js ADDED
@@ -0,0 +1,349 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //fgnass.github.com/spin.js#v1.3
2
+
3
+ /**
4
+ * Copyright (c) 2011-2013 Felix Gnass
5
+ * Licensed under the MIT license
6
+ */
7
+ (function(root, factory) {
8
+
9
+ /* CommonJS */
10
+ if (typeof exports == 'object') module.exports = factory()
11
+
12
+ /* AMD module */
13
+ else if (typeof define == 'function' && define.amd) define(factory)
14
+
15
+ /* Browser global */
16
+ else root.Spinner = factory()
17
+ }
18
+ (this, function() {
19
+ "use strict";
20
+
21
+ var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */
22
+ , animations = {} /* Animation rules keyed by their name */
23
+ , useCssAnimations /* Whether to use CSS animations or setTimeout */
24
+
25
+ /**
26
+ * Utility function to create elements. If no tag name is given,
27
+ * a DIV is created. Optionally properties can be passed.
28
+ */
29
+ function createEl(tag, prop) {
30
+ var el = document.createElement(tag || 'div')
31
+ , n
32
+
33
+ for(n in prop) el[n] = prop[n]
34
+ return el
35
+ }
36
+
37
+ /**
38
+ * Appends children and returns the parent.
39
+ */
40
+ function ins(parent /* child1, child2, ...*/) {
41
+ for (var i=1, n=arguments.length; i<n; i++)
42
+ parent.appendChild(arguments[i])
43
+
44
+ return parent
45
+ }
46
+
47
+ /**
48
+ * Insert a new stylesheet to hold the @keyframe or VML rules.
49
+ */
50
+ var sheet = (function() {
51
+ var el = createEl('style', {type : 'text/css'})
52
+ ins(document.getElementsByTagName('head')[0], el)
53
+ return el.sheet || el.styleSheet
54
+ }())
55
+
56
+ /**
57
+ * Creates an opacity keyframe animation rule and returns its name.
58
+ * Since most mobile Webkits have timing issues with animation-delay,
59
+ * we create separate rules for each line/segment.
60
+ */
61
+ function addAnimation(alpha, trail, i, lines) {
62
+ var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-')
63
+ , start = 0.01 + i/lines * 100
64
+ , z = Math.max(1 - (1-alpha) / trail * (100-start), alpha)
65
+ , prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase()
66
+ , pre = prefix && '-' + prefix + '-' || ''
67
+
68
+ if (!animations[name]) {
69
+ sheet.insertRule(
70
+ '@' + pre + 'keyframes ' + name + '{' +
71
+ '0%{opacity:' + z + '}' +
72
+ start + '%{opacity:' + alpha + '}' +
73
+ (start+0.01) + '%{opacity:1}' +
74
+ (start+trail) % 100 + '%{opacity:' + alpha + '}' +
75
+ '100%{opacity:' + z + '}' +
76
+ '}', sheet.cssRules.length)
77
+
78
+ animations[name] = 1
79
+ }
80
+
81
+ return name
82
+ }
83
+
84
+ /**
85
+ * Tries various vendor prefixes and returns the first supported property.
86
+ */
87
+ function vendor(el, prop) {
88
+ var s = el.style
89
+ , pp
90
+ , i
91
+
92
+ if(s[prop] !== undefined) return prop
93
+ prop = prop.charAt(0).toUpperCase() + prop.slice(1)
94
+ for(i=0; i<prefixes.length; i++) {
95
+ pp = prefixes[i]+prop
96
+ if(s[pp] !== undefined) return pp
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Sets multiple style properties at once.
102
+ */
103
+ function css(el, prop) {
104
+ for (var n in prop)
105
+ el.style[vendor(el, n)||n] = prop[n]
106
+
107
+ return el
108
+ }
109
+
110
+ /**
111
+ * Fills in default values.
112
+ */
113
+ function merge(obj) {
114
+ for (var i=1; i < arguments.length; i++) {
115
+ var def = arguments[i]
116
+ for (var n in def)
117
+ if (obj[n] === undefined) obj[n] = def[n]
118
+ }
119
+ return obj
120
+ }
121
+
122
+ /**
123
+ * Returns the absolute page-offset of the given element.
124
+ */
125
+ function pos(el) {
126
+ var o = { x:el.offsetLeft, y:el.offsetTop }
127
+ while((el = el.offsetParent))
128
+ o.x+=el.offsetLeft, o.y+=el.offsetTop
129
+
130
+ return o
131
+ }
132
+
133
+ // Built-in defaults
134
+
135
+ var defaults = {
136
+ lines: 12, // The number of lines to draw
137
+ length: 7, // The length of each line
138
+ width: 5, // The line thickness
139
+ radius: 10, // The radius of the inner circle
140
+ rotate: 0, // Rotation offset
141
+ corners: 1, // Roundness (0..1)
142
+ color: '#000', // #rgb or #rrggbb
143
+ direction: 1, // 1: clockwise, -1: counterclockwise
144
+ speed: 1, // Rounds per second
145
+ trail: 100, // Afterglow percentage
146
+ opacity: 1/4, // Opacity of the lines
147
+ fps: 20, // Frames per second when using setTimeout()
148
+ zIndex: 2e9, // Use a high z-index by default
149
+ className: 'spinner', // CSS class to assign to the element
150
+ top: 'auto', // center vertically
151
+ left: 'auto', // center horizontally
152
+ position: 'relative' // element position
153
+ }
154
+
155
+ /** The constructor */
156
+ function Spinner(o) {
157
+ if (typeof this == 'undefined') return new Spinner(o)
158
+ this.opts = merge(o || {}, Spinner.defaults, defaults)
159
+ }
160
+
161
+ // Global defaults that override the built-ins:
162
+ Spinner.defaults = {}
163
+
164
+ merge(Spinner.prototype, {
165
+
166
+ /**
167
+ * Adds the spinner to the given target element. If this instance is already
168
+ * spinning, it is automatically removed from its previous target b calling
169
+ * stop() internally.
170
+ */
171
+ spin: function(target) {
172
+ this.stop()
173
+
174
+ var self = this
175
+ , o = self.opts
176
+ , el = self.el = css(createEl(0, {className: o.className}), {position: o.position, width: 0, zIndex: o.zIndex})
177
+ , mid = o.radius+o.length+o.width
178
+ , ep // element position
179
+ , tp // target position
180
+
181
+ if (target) {
182
+ target.insertBefore(el, target.firstChild||null)
183
+ tp = pos(target)
184
+ ep = pos(el)
185
+ css(el, {
186
+ left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : parseInt(o.left, 10) + mid) + 'px',
187
+ top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px'
188
+ })
189
+ }
190
+
191
+ el.setAttribute('role', 'progressbar')
192
+ self.lines(el, self.opts)
193
+
194
+ if (!useCssAnimations) {
195
+ // No CSS animation support, use setTimeout() instead
196
+ var i = 0
197
+ , start = (o.lines - 1) * (1 - o.direction) / 2
198
+ , alpha
199
+ , fps = o.fps
200
+ , f = fps/o.speed
201
+ , ostep = (1-o.opacity) / (f*o.trail / 100)
202
+ , astep = f/o.lines
203
+
204
+ ;(function anim() {
205
+ i++;
206
+ for (var j = 0; j < o.lines; j++) {
207
+ alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity)
208
+
209
+ self.opacity(el, j * o.direction + start, alpha, o)
210
+ }
211
+ self.timeout = self.el && setTimeout(anim, ~~(1000/fps))
212
+ })()
213
+ }
214
+ return self
215
+ },
216
+
217
+ /**
218
+ * Stops and removes the Spinner.
219
+ */
220
+ stop: function() {
221
+ var el = this.el
222
+ if (el) {
223
+ clearTimeout(this.timeout)
224
+ if (el.parentNode) el.parentNode.removeChild(el)
225
+ this.el = undefined
226
+ }
227
+ return this
228
+ },
229
+
230
+ /**
231
+ * Internal method that draws the individual lines. Will be overwritten
232
+ * in VML fallback mode below.
233
+ */
234
+ lines: function(el, o) {
235
+ var i = 0
236
+ , start = (o.lines - 1) * (1 - o.direction) / 2
237
+ , seg
238
+
239
+ function fill(color, shadow) {
240
+ return css(createEl(), {
241
+ position: 'absolute',
242
+ width: (o.length+o.width) + 'px',
243
+ height: o.width + 'px',
244
+ background: color,
245
+ boxShadow: shadow,
246
+ transformOrigin: 'left',
247
+ transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
248
+ borderRadius: (o.corners * o.width>>1) + 'px'
249
+ })
250
+ }
251
+
252
+ for (; i < o.lines; i++) {
253
+ seg = css(createEl(), {
254
+ position: 'absolute',
255
+ top: 1+~(o.width/2) + 'px',
256
+ transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
257
+ opacity: o.opacity,
258
+ animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1/o.speed + 's linear infinite'
259
+ })
260
+
261
+ if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}))
262
+
263
+ ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')))
264
+ }
265
+ return el
266
+ },
267
+
268
+ /**
269
+ * Internal method that adjusts the opacity of a single line.
270
+ * Will be overwritten in VML fallback mode below.
271
+ */
272
+ opacity: function(el, i, val) {
273
+ if (i < el.childNodes.length) el.childNodes[i].style.opacity = val
274
+ }
275
+
276
+ })
277
+
278
+
279
+ function initVML() {
280
+
281
+ /* Utility function to create a VML tag */
282
+ function vml(tag, attr) {
283
+ return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr)
284
+ }
285
+
286
+ // No CSS transforms but VML support, add a CSS rule for VML elements:
287
+ sheet.addRule('.spin-vml', 'behavior:url(#default#VML)')
288
+
289
+ Spinner.prototype.lines = function(el, o) {
290
+ var r = o.length+o.width
291
+ , s = 2*r
292
+
293
+ function grp() {
294
+ return css(
295
+ vml('group', {
296
+ coordsize: s + ' ' + s,
297
+ coordorigin: -r + ' ' + -r
298
+ }),
299
+ { width: s, height: s }
300
+ )
301
+ }
302
+
303
+ var margin = -(o.width+o.length)*2 + 'px'
304
+ , g = css(grp(), {position: 'absolute', top: margin, left: margin})
305
+ , i
306
+
307
+ function seg(i, dx, filter) {
308
+ ins(g,
309
+ ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
310
+ ins(css(vml('roundrect', {arcsize: o.corners}), {
311
+ width: r,
312
+ height: o.width,
313
+ left: o.radius,
314
+ top: -o.width>>1,
315
+ filter: filter
316
+ }),
317
+ vml('fill', {color: o.color, opacity: o.opacity}),
318
+ vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
319
+ )
320
+ )
321
+ )
322
+ }
323
+
324
+ if (o.shadow)
325
+ for (i = 1; i <= o.lines; i++)
326
+ seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)')
327
+
328
+ for (i = 1; i <= o.lines; i++) seg(i)
329
+ return ins(el, g)
330
+ }
331
+
332
+ Spinner.prototype.opacity = function(el, i, val, o) {
333
+ var c = el.firstChild
334
+ o = o.shadow && o.lines || 0
335
+ if (c && i+o < c.childNodes.length) {
336
+ c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild
337
+ if (c) c.opacity = val
338
+ }
339
+ }
340
+ }
341
+
342
+ var probe = css(createEl('group'), {behavior: 'url(#default#VML)'})
343
+
344
+ if (!vendor(probe, 'transform') && probe.adj) initVML()
345
+ else useCssAnimations = vendor(probe, 'animation')
346
+
347
+ return Spinner
348
+
349
+ }));
trunk/tiled-gallery.php ADDED
@@ -0,0 +1,724 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Plugin Name: Tiled Galleries Carousel Without Jetpack
5
+ Plugin URL: https://themepacific.com/
6
+ Description: Transform your standard image galleries into an immersive full-screen experience without Jetpack.This plugin is made from Jetpack Modules. You can get the tiled galleries with Full screen carousel with out connecting to wordpress.com account.
7
+ Version: 2.2
8
+ Author: Raja CRN
9
+ Author URI: https://themepacific.com/
10
+ License: GPLv2 or later
11
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+ */
18
+ /* */
19
+
20
+ // Include the class file containing methods for rounding constrained array elements.
21
+ // Here the constrained array element is the dimension of a row, group or an image in the tiled gallery.
22
+ include_once dirname( __FILE__ ) . '/math/class-constrained-array-rounding.php';
23
+ include( plugin_dir_path( __FILE__ ) . 'class.jetpack-user-agent.php');
24
+ include( plugin_dir_path( __FILE__ ) . 'functions.gallery.php');
25
+ include( plugin_dir_path( __FILE__ ) . 'jetpack-carousel.php');
26
+ load_plugin_textdomain('themepacific_gallery', false, basename( dirname( __FILE__ ) ) . '/languages' );
27
+ class themePacific_Jetpack_Tiled_Gallery {
28
+
29
+ public function __construct() {
30
+ add_action( 'admin_init', array( $this, 'settings_api_init' ) );
31
+ add_filter( 'jetpack_gallery_types', array( $this, 'jetpack_gallery_types' ), 9 );
32
+ add_filter( 'jetpack_default_gallery_type', array( $this, 'jetpack_default_gallery_type' ) );
33
+ }
34
+
35
+ public function tiles_enabled() {
36
+ // Check the setting status
37
+ return '' != get_option( 'tiled_galleries' );
38
+ }
39
+
40
+ public function set_atts( $atts ) {
41
+ global $post;
42
+
43
+ $this->atts = shortcode_atts( array(
44
+ 'order' => 'ASC',
45
+ 'orderby' => 'menu_order ID',
46
+ 'id' => $post->ID,
47
+ 'include' => '',
48
+ 'exclude' => '',
49
+ 'type' => '',
50
+ 'grayscale' => false,
51
+ 'link' => '',
52
+ ), $atts );
53
+
54
+ $this->atts['id'] = (int) $this->atts['id'];
55
+ $this->float = is_rtl() ? 'right' : 'left';
56
+
57
+ // Default to rectangular is tiled galleries are checked
58
+ if ( $this->tiles_enabled() && ( ! $this->atts['type'] || 'default' == $this->atts['type'] ) )
59
+ $this->atts['type'] = 'rectangular';
60
+
61
+ if ( !$this->atts['orderby'] ) {
62
+ $this->atts['orderby'] = sanitize_sql_orderby( $this->atts['orderby'] );
63
+ if ( !$this->atts['orderby'] )
64
+ $this->atts['orderby'] = 'menu_order ID';
65
+ }
66
+
67
+ if ( 'RAND' == $this->atts['order'] )
68
+ $this->atts['orderby'] = 'none';
69
+ }
70
+
71
+ public function get_attachments() {
72
+ extract( $this->atts );
73
+
74
+ if ( !empty( $include ) ) {
75
+ $include = preg_replace( '/[^0-9,]+/', '', $include );
76
+ $_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
77
+
78
+ $attachments = array();
79
+ foreach ( $_attachments as $key => $val ) {
80
+ $attachments[$val->ID] = $_attachments[$key];
81
+ }
82
+ } elseif ( !empty( $exclude ) ) {
83
+ $exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
84
+ $attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
85
+ } else {
86
+ $attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby ) );
87
+ }
88
+ return $attachments;
89
+ }
90
+
91
+ public function get_attachment_link( $attachment_id, $orig_file ) {
92
+ if ( isset( $this->atts['link'] ) && $this->atts['link'] == 'file' )
93
+ return $orig_file;
94
+ else
95
+ return get_attachment_link( $attachment_id );
96
+ }
97
+
98
+ public function default_scripts_and_styles() {
99
+ wp_enqueue_script( 'tiled-gallery', plugins_url( 'tiled-gallery/tiled-gallery.js', __FILE__ ), array( 'jquery' ) );
100
+ wp_enqueue_style( 'tiled-gallery', plugins_url( 'tiled-gallery/tiled-gallery.css', __FILE__ ), array(), '2012-09-21' );
101
+ }
102
+
103
+ public function gallery_shortcode( $val, $atts ) {
104
+ if ( ! empty( $val ) ) // something else is overriding post_gallery, like a custom VIP shortcode
105
+ return $val;
106
+
107
+ global $post;
108
+
109
+ $this->set_atts( $atts );
110
+
111
+ $attachments = $this->get_attachments();
112
+ if ( empty( $attachments ) )
113
+ return '';
114
+
115
+ if ( is_feed() || defined( 'IS_HTML_EMAIL' ) )
116
+ return '';
117
+
118
+ if ( method_exists( $this, $this->atts['type'] . '_talavera' ) ) {
119
+ // Enqueue styles and scripts
120
+ $this->default_scripts_and_styles();
121
+ $gallery_html = call_user_func_array( array( $this, $this->atts['type'] . '_talavera' ), array( $attachments ) );
122
+
123
+ if ( $gallery_html && class_exists( 'Jetpack' ) && class_exists( 'Jetpack_Photon' ) ) {
124
+ // Tiled Galleries in Jetpack require that Photon be active.
125
+ // If it's not active, run it just on the gallery output.
126
+ if ( ! in_array( 'photon', Jetpack::get_active_modules() ) )
127
+ $gallery_html = Jetpack_Photon::filter_the_content( $gallery_html );
128
+ }
129
+
130
+ return $gallery_html;
131
+ }
132
+
133
+ return '';
134
+ }
135
+
136
+ public function vt_resize( $attach_id = null, $img_url = null, $width, $height, $crop = false ) {
137
+
138
+ // this is an attachment, so we have the ID
139
+ if ( $attach_id ) {
140
+
141
+ $image_src = wp_get_attachment_image_src( $attach_id, 'full' );
142
+ $file_path = get_attached_file( $attach_id );
143
+
144
+ // this is not an attachment, let's use the image url
145
+ } else if ( $img_url ) {
146
+
147
+ $file_path = parse_url( $img_url );
148
+ $file_path = ltrim( $file_path['path'], '/' );
149
+ //$file_path = rtrim( ABSPATH, '/' ).$file_path['path'];
150
+
151
+ $orig_size = getimagesize( $file_path );
152
+
153
+ $image_src[0] = $img_url;
154
+ $image_src[1] = $orig_size[0];
155
+ $image_src[2] = $orig_size[1];
156
+ }
157
+
158
+ $file_info = pathinfo( $file_path );
159
+ $extension = '.'. $file_info['extension'];
160
+
161
+ // the image path without the extension
162
+ $no_ext_path = $file_info['dirname'].'/'.$file_info['filename'];
163
+
164
+ $cropped_img_path = $no_ext_path.'-'.$width.'x'.$height.$extension;
165
+
166
+ // checking if the file size is larger than the target size
167
+ // if it is smaller or the same size, stop right here and return
168
+ if ( $image_src[1] > $width || $image_src[2] > $height ) {
169
+
170
+ // the file is larger, check if the resized version already exists (for crop = true but will also work for crop = false if the sizes match)
171
+ if ( file_exists( $cropped_img_path ) ) {
172
+
173
+ $cropped_img_url = str_replace( basename( $image_src[0] ), basename( $cropped_img_path ), $image_src[0] );
174
+
175
+ $vt_image = array (
176
+ 'url' => $cropped_img_url,
177
+ 'width' => $width,
178
+ 'height' => $height
179
+ );
180
+
181
+ return $vt_image;
182
+ }
183
+
184
+ // crop = false
185
+ if ( $crop == false ) {
186
+
187
+ // calculate the size proportionaly
188
+ $proportional_size = wp_constrain_dimensions( $image_src[1], $image_src[2], $width, $height );
189
+ $resized_img_path = $no_ext_path.'-'.$proportional_size[0].'x'.$proportional_size[1].$extension;
190
+
191
+ // checking if the file already exists
192
+ if ( file_exists( $resized_img_path ) ) {
193
+
194
+ $resized_img_url = str_replace( basename( $image_src[0] ), basename( $resized_img_path ), $image_src[0] );
195
+
196
+ $vt_image = array (
197
+ 'url' => $resized_img_url,
198
+ 'width' => $new_img_size[0],
199
+ 'height' => $new_img_size[1]
200
+ );
201
+
202
+ return $vt_image;
203
+ }
204
+ }
205
+
206
+ // no cached files - let's finally resize it
207
+ $tp_image = wp_get_image_editor( $file_path );
208
+ if ( ! is_wp_error( $tp_image ) ) {
209
+ $tp_image->resize( $width, $height, $crop );
210
+ $new_img_array = $tp_image->save();
211
+ }
212
+ $new_img_size = getimagesize( $new_img_array['path'] );
213
+ $new_img = str_replace( basename( $image_src[0] ), basename( $new_img_array['path'] ), $image_src[0] );
214
+
215
+
216
+
217
+
218
+
219
+
220
+ // resized output
221
+ $vt_image = array (
222
+ 'url' => $new_img,
223
+ 'width' => $new_img_size[0],
224
+ 'height' => $new_img_size[1]
225
+ );
226
+
227
+ return $vt_image;
228
+ }
229
+
230
+ // default output - without resizing
231
+ $vt_image = array (
232
+ 'url' => $image_src[0],
233
+ 'width' => $image_src[1],
234
+ 'height' => $image_src[2]
235
+ );
236
+
237
+ return $vt_image;
238
+ }
239
+
240
+ public function rectangular_talavera( $attachments ) {
241
+ $grouper = new themePacific_Jetpack_Tiled_Gallery_Grouper( $attachments );
242
+
243
+ themePacific_Jetpack_Tiled_Gallery_Shape::reset_last_shape();
244
+
245
+ $output = $this->generate_carousel_container();
246
+ foreach ( $grouper->grouped_images as $row ) {
247
+ $output .= '<div class="gallery-row" style="' . esc_attr( 'width: ' . $row->width . 'px; height: ' . ( $row->height - 4 ) . 'px;' ) . '">';
248
+ foreach( $row->groups as $group ) {
249
+ $count = count( $group->images );
250
+ $output .= '<div class="gallery-group images-' . esc_attr( $count ) . '" style="' . esc_attr( 'width: ' . $group->width . 'px; height: ' . $group->height . 'px;' ) . '">';
251
+ foreach ( $group->images as $image ) {
252
+
253
+ $size = 'large';
254
+ if ( $image->width < 250 )
255
+ $size = 'small';
256
+
257
+ $image_title = $image->post_title;
258
+ $orig_file = wp_get_attachment_url( $image->ID );
259
+ $link = $this->get_attachment_link( $image->ID, $orig_file );
260
+
261
+ $img_src = $this->vt_resize( $image->ID,'' , $image->width, $image->height, true );
262
+ $output .= '<div class="tiled-gallery-item tiled-gallery-item-' . esc_attr( $size ) . '"><a href="' . esc_url( $link ) . '"><img ' . $this->generate_carousel_image_args( $image ) . ' src="' . esc_url( $img_src['url'] ) . '" width="' . esc_attr( $image->width ) . '" height="' . esc_attr( $image->height ) . '" align="left" title="' . esc_attr( $image_title ) . '" /></a>';
263
+
264
+ if ( $this->atts['grayscale'] == true ) {
265
+ $img_src_grayscale = jetpack_photon_url( $img_src['url'], array( 'filter' => 'grayscale' ) );
266
+ $output .= '<a href="'. esc_url( $link ) . '"><img ' . $this->generate_carousel_image_args( $image ) . ' class="grayscale" src="' . esc_url( $img_src_grayscale ) . '" width="' . esc_attr( $image->width ) . '" height="' . esc_attr( $image->height ) . '" align="left" title="' . esc_attr( $image_title ) . '" /></a>';
267
+ }
268
+
269
+ if ( trim( $image->post_excerpt ) )
270
+ $output .= '<div class="tiled-gallery-caption">' . wptexturize( $image->post_excerpt ) . '</div>';
271
+
272
+ $output .= '</div>';
273
+ }
274
+ $output .= '</div>';
275
+ }
276
+ $output .= '</div>';
277
+ }
278
+ $output .= '</div>';
279
+ return $output;
280
+ }
281
+
282
+ public function square_talavera( $attachments ) {
283
+ $content_width = self::get_content_width();
284
+ $images_per_row = 3;
285
+ $margin = 2;
286
+
287
+ $margin_space = ( $images_per_row * $margin ) * 2;
288
+ $size = floor( ( $content_width - $margin_space ) / $images_per_row );
289
+ $remainder = count( $attachments ) % $images_per_row;
290
+ if ( $remainder > 0 ) {
291
+ $remainder_space = ( $remainder * $margin ) * 2;
292
+ $remainder_size = ceil( ( $content_width - $remainder_space - $margin ) / $remainder );
293
+ }
294
+ $output = $this->generate_carousel_container();
295
+ $c = 1;
296
+ foreach( $attachments as $image ) {
297
+ if ( $remainder > 0 && $c <= $remainder )
298
+ $img_size = $remainder_size;
299
+ else
300
+ $img_size = $size;
301
+
302
+ $img_src = $this->vt_resize( $image->ID,'' , $img_size, $img_size, true );
303
+ $orig_file = wp_get_attachment_url( $image->ID );
304
+ $link = $this->get_attachment_link( $image->ID, $orig_file );
305
+ $image_title = $image->post_title;
306
+
307
+
308
+ $output .= '<div class="tiled-gallery-item">';
309
+ $output .= '<a border="0" href="' . esc_url( $link ) . '"><img ' . $this->generate_carousel_image_args( $image ) . ' style="' . esc_attr( 'margin: ' . $margin . 'px' ) . '" src="' . $img_src['url'] . '" width=' . esc_attr( $img_size ) . ' height=' . esc_attr( $img_size ) . ' title="' . esc_attr( $image_title ) . '" /></a>';
310
+
311
+ // Grayscale effect
312
+ if ( $this->atts['grayscale'] == true ) {
313
+ $src = urlencode( $image->guid );
314
+ $output .= '<a border="0" href="' . esc_url( $link ) . '"><img ' . $this->generate_carousel_image_args( $image ) . ' style="margin: 2px" class="grayscale" src="' . esc_url( 'http://en.wordpress.com/imgpress?url=' . urlencode( $image->guid ) . '&resize=' . $img_size . ',' . $img_size . '&filter=grayscale' ) . '" width=' . esc_attr( $img_size ) . ' height=' . esc_attr( $img_size ) . ' title="' . esc_attr( $image_title ) . '" /></a>';
315
+ }
316
+
317
+ // Captions
318
+ if ( trim( $image->post_excerpt ) )
319
+ $output .= '<div class="tiled-gallery-caption">' . wptexturize( $image->post_excerpt ) . '</div>';
320
+ $output .= '</div>';
321
+ $c ++;
322
+ }
323
+ $output .= '</div>';
324
+ return $output;
325
+ }
326
+
327
+ public function circle_talavera( $attachments ) {
328
+ return $this->square_talavera( $attachments );
329
+ }
330
+
331
+ public function rectangle_talavera( $attachments ) {
332
+ return $this->rectangular_talavera( $attachments );
333
+ }
334
+
335
+ function generate_carousel_container() {
336
+ global $post;
337
+
338
+ $html = '<div '. $this->gallery_classes() . ' data-original-width="' . esc_attr( self::get_content_width() ) . '">';
339
+ $blog_id = (int) get_current_blog_id();
340
+ $extra_data = array( 'data-carousel-extra' => array( 'blog_id' => $blog_id, 'permalink' => get_permalink( $post->ID ) ) );
341
+
342
+ foreach ( (array) $extra_data as $data_key => $data_values ) {
343
+ $html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . json_encode( $data_values ) . "' ", $html );
344
+ }
345
+
346
+ return $html;
347
+ }
348
+
349
+ function generate_carousel_image_args( $image ) {
350
+ $attachment_id = $image->ID;
351
+ $orig_file = wp_get_attachment_url( $attachment_id );
352
+ $meta = wp_get_attachment_metadata( $attachment_id );
353
+ $size = isset( $meta['width'] ) ? intval( $meta['width'] ) . ',' . intval( $meta['height'] ) : '';
354
+ $img_meta = ( ! empty( $meta['image_meta'] ) ) ? (array) $meta['image_meta'] : array();
355
+ $comments_opened = intval( comments_open( $attachment_id ) );
356
+
357
+ $medium_file_info = wp_get_attachment_image_src( $attachment_id, 'medium' );
358
+ $medium_file = isset( $medium_file_info[0] ) ? $medium_file_info[0] : '';
359
+
360
+ $large_file_info = wp_get_attachment_image_src( $attachment_id, 'large' );
361
+ $large_file = isset( $large_file_info[0] ) ? $large_file_info[0] : '';
362
+ $attachment_title = wptexturize( $image->post_title );
363
+ $attachment_desc = wpautop( wptexturize( $image->post_content ) );
364
+
365
+ // Not yet providing geo-data, need to "fuzzify" for privacy
366
+ if ( ! empty( $img_meta ) ) {
367
+ foreach ( $img_meta as $k => $v ) {
368
+ if ( 'latitude' == $k || 'longitude' == $k )
369
+ unset( $img_meta[$k] );
370
+ }
371
+ }
372
+
373
+ $img_meta = json_encode( array_map( 'strval', $img_meta ) );
374
+
375
+ $output = sprintf(
376
+ '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-title="%6$s" data-image-description="%7$s" data-medium-file="%8$s" data-large-file="%9$s"',
377
+ esc_attr( $attachment_id ),
378
+ esc_url( wp_get_attachment_url( $attachment_id ) ),
379
+ esc_attr( $size ),
380
+ esc_attr( $comments_opened ),
381
+ esc_attr( $img_meta ),
382
+ esc_attr( $attachment_title ),
383
+ esc_attr( $attachment_desc ),
384
+ esc_url( $medium_file ),
385
+ esc_url( $large_file )
386
+ );
387
+ return $output;
388
+ }
389
+
390
+ public function gallery_classes() {
391
+ $classes = 'class="tiled-gallery type-' . esc_attr( $this->atts['type'] ) . '"';
392
+ return $classes;
393
+ }
394
+
395
+ public static function gallery_already_redefined() {
396
+ global $shortcode_tags;
397
+ if ( ! isset( $shortcode_tags[ 'gallery' ] ) || $shortcode_tags[ 'gallery' ] !== 'gallery_shortcode' )
398
+ return true;
399
+ }
400
+
401
+ public static function init() {
402
+ if ( self::gallery_already_redefined() )
403
+ return;
404
+
405
+ $gallery = new themePacific_Jetpack_Tiled_Gallery;
406
+ add_filter( 'post_gallery', array( $gallery, 'gallery_shortcode' ), 1001, 2 );
407
+ }
408
+
409
+ public static function get_content_width() {
410
+ global $content_width;
411
+
412
+ $tiled_gallery_content_width = $content_width;
413
+
414
+ if ( ! $tiled_gallery_content_width )
415
+ $tiled_gallery_content_width = 500;
416
+
417
+ return apply_filters( 'tiled_gallery_content_width', $tiled_gallery_content_width );
418
+ }
419
+
420
+ /**
421
+ * Media UI integration
422
+ */
423
+ function jetpack_gallery_types( $types ) {
424
+ if ( get_option( 'tiled_galleries' ) && isset( $types['default'] ) ) {
425
+ // Tiled is set as the default, meaning that type='default'
426
+ // will still display the mosaic.
427
+ $types['thumbnails'] = $types['default'];
428
+ unset( $types['default'] );
429
+ }
430
+
431
+ $types['rectangular'] = __( 'Tiled Mosaic', 'themepacific_gallery' );
432
+ $types['square'] = __( 'Square Tiles', 'themepacific_gallery' );
433
+ $types['circle'] = __( 'Circles', 'themepacific_gallery' );
434
+
435
+ return $types;
436
+ }
437
+
438
+ function jetpack_default_gallery_type( $default ) {
439
+ return ( get_option( 'tiled_galleries' ) ? 'rectangular' : 'default' );
440
+ }
441
+
442
+ /**
443
+ * Add a checkbox field to the Carousel section in Settings > Media
444
+ * for setting tiled galleries as the default.
445
+ */
446
+ function settings_api_init() {
447
+ global $wp_settings_sections;
448
+
449
+ // Add the setting field [tiled_galleries] and place it in Settings > Media
450
+ if ( isset( $wp_settings_sections['media']['carousel_section'] ) )
451
+ $section = 'carousel_section';
452
+ else
453
+ $section = 'default';
454
+
455
+ add_settings_field( 'tiled_galleries', __( 'Tiled Galleries', 'themepacific_gallery' ), array( $this, 'setting_html' ), 'media', $section );
456
+ register_setting( 'media', 'tiled_galleries', 'esc_attr' );
457
+ }
458
+
459
+ function setting_html() {
460
+ echo '<label><input name="tiled_galleries" type="checkbox" value="1" ' .
461
+ checked( 1, '' != get_option( 'tiled_galleries' ), false ) . ' /> ' .
462
+ __( 'Display all your gallery pictures in a cool mosaic.', 'themepacific_gallery' ) . '</br></label>';
463
+ }
464
+ }
465
+
466
+ class themePacific_Jetpack_Tiled_Gallery_Shape {
467
+ static $shapes_used = array();
468
+
469
+ public function __construct( $images ) {
470
+ $this->images = $images;
471
+ $this->images_left = count( $images );
472
+ }
473
+
474
+ public function sum_ratios( $number_of_images = 3 ) {
475
+ return array_sum( array_slice( wp_list_pluck( $this->images, 'ratio' ), 0, $number_of_images ) );
476
+ }
477
+
478
+ public function next_images_are_symmetric() {
479
+ return $this->images_left > 2 && $this->images[0]->ratio == $this->images[2]->ratio;
480
+ }
481
+
482
+ public function is_not_as_previous( $n = 1 ) {
483
+ return ! in_array( get_class( $this ), array_slice( self::$shapes_used, -$n ) );
484
+ }
485
+
486
+ public function is_wide_theme() {
487
+ global $content_width;
488
+ return $content_width > 1000;
489
+ }
490
+
491
+ public static function set_last_shape( $last_shape ) {
492
+ self::$shapes_used[] = $last_shape;
493
+ }
494
+
495
+ public static function reset_last_shape() {
496
+ self::$shapes_used = array();
497
+ }
498
+ }
499
+
500
+ class themePacific_Jetpack_Tiled_Gallery_Three extends themePacific_Jetpack_Tiled_Gallery_Shape {
501
+ public $shape = array( 1, 1, 1 );
502
+
503
+ public function is_possible() {
504
+ $ratio = $this->sum_ratios( 3 );
505
+ return $this->images_left > 2 && $this->is_not_as_previous() &&
506
+ ( ( $ratio < 2.5 ) || ( $ratio < 5 && $this->next_images_are_symmetric() ) || $this->is_wide_theme() );
507
+ }
508
+ }
509
+
510
+ class themePacific_Jetpack_Tiled_Gallery_Four extends themePacific_Jetpack_Tiled_Gallery_Shape {
511
+ public $shape = array( 1, 1, 1, 1 );
512
+
513
+ public function is_possible() {
514
+ return $this->is_not_as_previous() && $this->sum_ratios( 4 ) < 3.5 &&
515
+ ( $this->images_left == 4 || ( $this->images_left != 8 && $this->images_left > 5 ) );
516
+ }
517
+ }
518
+
519
+ class themePacific_Jetpack_Tiled_Gallery_Five extends themePacific_Jetpack_Tiled_Gallery_Shape {
520
+ public $shape = array( 1, 1, 1, 1, 1 );
521
+
522
+ public function is_possible() {
523
+ return $this->is_wide_theme() && $this->is_not_as_previous() && $this->sum_ratios( 5 ) < 5 &&
524
+ ( $this->images_left == 5 || ( $this->images_left != 10 && $this->images_left > 6 ) );
525
+ }
526
+ }
527
+
528
+ class themePacific_Jetpack_Tiled_Gallery_Two_One extends themePacific_Jetpack_Tiled_Gallery_Shape {
529
+ public $shape = array( 2, 1 );
530
+
531
+ public function is_possible() {
532
+ return $this->is_not_as_previous( 3 ) && $this->images_left >= 2 &&
533
+ $this->images[2]->ratio < 1.6 && $this->images[0]->ratio >=0.9 && $this->images[1]->ratio >= 0.9;
534
+ }
535
+ }
536
+
537
+ class themePacific_Jetpack_Tiled_Gallery_One_Two extends themePacific_Jetpack_Tiled_Gallery_Shape {
538
+ public $shape = array( 1, 2 );
539
+
540
+ public function is_possible() {
541
+ return $this->is_not_as_previous( 3 ) && $this->images_left >= 2 &&
542
+ $this->images[0]->ratio < 1.6 && $this->images[1]->ratio >=0.9 && $this->images[2]->ratio >= 0.9;
543
+ }
544
+ }
545
+
546
+ class themePacific_Jetpack_Tiled_Gallery_One_Three extends themePacific_Jetpack_Tiled_Gallery_Shape {
547
+ public $shape = array( 1, 3 );
548
+
549
+ public function is_possible() {
550
+ return $this->is_not_as_previous() && $this->images_left >= 3 &&
551
+ $this->images[0]->ratio < 0.8 && $this->images[1]->ratio >=0.9 && $this->images[2]->ratio >= 0.9 && $this->images[3]->ratio >= 0.9;
552
+ }
553
+ }
554
+
555
+ class themePacific_Jetpack_Tiled_Gallery_Symmetric_Row extends themePacific_Jetpack_Tiled_Gallery_Shape {
556
+ public $shape = array( 1, 2, 1 );
557
+
558
+ public function is_possible() {
559
+ return $this->is_not_as_previous() && $this->images_left >= 3 && $this->images_left != 5 &&
560
+ $this->images[0]->ratio < 0.8 && $this->images[0]->ratio == $this->images[3]->ratio;
561
+ }
562
+ }
563
+
564
+ class themePacific_Jetpack_Tiled_Gallery_Grouper {
565
+ public $margin = 4;
566
+ public function __construct( $attachments ) {
567
+ $content_width = themePacific_Jetpack_Tiled_Gallery::get_content_width();
568
+ //$ua_info = new Jetpack_User_Agent_Info();
569
+
570
+ $this->last_shape = '';
571
+ $this->images = $this->get_images_with_sizes( $attachments );
572
+ $this->grouped_images = $this->get_grouped_images();
573
+ $this->apply_content_width( $content_width - 5 ); //reduce the margin hack to 5px. It will be further reduced when we fix more themes and the rounding error.
574
+ }
575
+
576
+ public function get_current_row_size() {
577
+ $images_left = count( $this->images );
578
+ if ( $images_left < 3 )
579
+ return array_fill( 0, $images_left, 1 );
580
+
581
+ foreach ( array( 'One_Three', 'One_Two', 'Five', 'Four', 'Three', 'Two_One', 'Symmetric_Row' ) as $shape_name ) {
582
+ $class_name = "themePacific_Jetpack_Tiled_Gallery_$shape_name";
583
+ $shape = new $class_name( $this->images );
584
+ if ( $shape->is_possible() ) {
585
+ themePacific_Jetpack_Tiled_Gallery_Shape::set_last_shape( $class_name );
586
+ return $shape->shape;
587
+ }
588
+ }
589
+
590
+ themePacific_Jetpack_Tiled_Gallery_Shape::set_last_shape( 'Two' );
591
+ return array( 1, 1 );
592
+ }
593
+
594
+ public function get_images_with_sizes( $attachments ) {
595
+ $images_with_sizes = array();
596
+
597
+ foreach ( $attachments as $image ) {
598
+ $meta = wp_get_attachment_metadata( $image->ID );
599
+ $image->width_orig = ( $meta['width'] > 0 )? $meta['width'] : 1;
600
+ $image->height_orig = ( $meta['height'] > 0 )? $meta['height'] : 1;
601
+ $image->ratio = $image->width_orig / $image->height_orig;
602
+ $image->ratio = $image->ratio? $image->ratio : 1;
603
+ $images_with_sizes[] = $image;
604
+ }
605
+
606
+ return $images_with_sizes;
607
+ }
608
+
609
+ public function read_row() {
610
+ $vector = $this->get_current_row_size();
611
+
612
+ $row = array();
613
+ foreach ( $vector as $group_size ) {
614
+ $row[] = new themePacific_Jetpack_Tiled_Gallery_Group( array_splice( $this->images, 0, $group_size ) );
615
+ }
616
+
617
+ return $row;
618
+ }
619
+
620
+ public function get_grouped_images() {
621
+ $grouped_images = array();
622
+
623
+ while( !empty( $this->images ) ) {
624
+ $grouped_images[] = new themePacific_Jetpack_Tiled_Gallery_Row( $this->read_row() );
625
+ }
626
+
627
+ return $grouped_images;
628
+ }
629
+
630
+ // todo: split in functions
631
+ // todo: do not stretch images
632
+ public function apply_content_width( $width ) {
633
+ foreach ( $this->grouped_images as $row ) {
634
+ $row->width = $width;
635
+ $row->raw_height = 1 / $row->ratio * ( $width - $this->margin * ( count( $row->groups ) - $row->weighted_ratio ) );
636
+ $row->height = round( $row->raw_height );
637
+
638
+ $this->calculate_group_sizes( $row );
639
+ }
640
+ }
641
+
642
+ public function calculate_group_sizes( $row ) {
643
+ // Storing the calculated group heights in an array for rounding them later while preserving their sum
644
+ // This fixes the rounding error that can lead to a few ugly pixels sticking out in the gallery
645
+ $group_widths_array = array();
646
+ foreach ( $row->groups as $group ) {
647
+ $group->height = $row->height;
648
+ // Storing the raw calculations in a separate property to prevent rounding errors from cascading down and for diagnostics
649
+ $group->raw_width = ( $row->raw_height - $this->margin * count( $group->images ) ) * $group->ratio + $this->margin;
650
+ $group_widths_array[] = $group->raw_width;
651
+ }
652
+ $rounded_group_widths_array = themePacific_Jetpack_Constrained_Array_Rounding::get_rounded_constrained_array( $group_widths_array, $row->width );
653
+
654
+ foreach ( $row->groups as $group ) {
655
+ $group->width = array_shift( $rounded_group_widths_array );
656
+ $this->calculate_image_sizes( $group );
657
+ }
658
+ }
659
+
660
+ public function calculate_image_sizes( $group ) {
661
+ // Storing the calculated image heights in an array for rounding them later while preserving their sum
662
+ // This fixes the rounding error that can lead to a few ugly pixels sticking out in the gallery
663
+ $image_heights_array = array();
664
+ foreach ( $group->images as $image ) {
665
+ $image->width = $group->width - $this->margin;
666
+ // Storing the raw calculations in a separate property for diagnostics
667
+ $image->raw_height = ( $group->raw_width - $this->margin ) / $image->ratio;
668
+ $image_heights_array[] = $image->raw_height;
669
+ }
670
+
671
+ $image_height_sum = $group->height - count( $image_heights_array ) * $this->margin;
672
+ $rounded_image_heights_array = themePacific_Jetpack_Constrained_Array_Rounding::get_rounded_constrained_array( $image_heights_array, $image_height_sum );
673
+
674
+ foreach ( $group->images as $image ) {
675
+ $image->height = array_shift( $rounded_image_heights_array );
676
+ }
677
+ }
678
+ }
679
+
680
+ class themePacific_Jetpack_Tiled_Gallery_Row {
681
+ public function __construct( $groups ) {
682
+ $this->groups = $groups;
683
+ $this->ratio = $this->get_ratio();
684
+ $this->weighted_ratio = $this->get_weighted_ratio();
685
+ }
686
+
687
+ public function get_ratio() {
688
+ $ratio = 0;
689
+ foreach ( $this->groups as $group ) {
690
+ $ratio += $group->ratio;
691
+ }
692
+ return $ratio > 0? $ratio : 1;
693
+ }
694
+
695
+ public function get_weighted_ratio() {
696
+ $weighted_ratio = 0;
697
+ foreach ( $this->groups as $group ) {
698
+ $weighted_ratio += $group->ratio * count( $group->images );
699
+ }
700
+ return $weighted_ratio > 0 ? $weighted_ratio : 1;
701
+ }
702
+ }
703
+
704
+ class themePacific_Jetpack_Tiled_Gallery_Group {
705
+ public function __construct( $images ) {
706
+ $this->images = $images;
707
+ $this->ratio = $this->get_ratio();
708
+ }
709
+
710
+ public function get_ratio() {
711
+ $ratio = 0;
712
+ foreach ( $this->images as $image ) {
713
+ if ( $image->ratio )
714
+ $ratio += 1/$image->ratio;
715
+ }
716
+ if ( !$ratio )
717
+ return 1;
718
+
719
+ return 1/$ratio;
720
+ }
721
+ }
722
+
723
+ add_action( 'init', array( 'themePacific_Jetpack_Tiled_Gallery', 'init' ) );
724
+
trunk/tiled-gallery/rtl/tiled-gallery-rtl.css ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file was automatically generated on Jan 05 2013 15:45:53 */
2
+
3
+ /* =Tiled Gallery Default Styles
4
+ -------------------------------------------------------------- */
5
+
6
+ .tiled-gallery {
7
+ clear: both;
8
+ margin: 0;
9
+ overflow: hidden;
10
+ }
11
+ .tiled-gallery img {
12
+ margin: 2px !important; /* Ensure that this value isn't overridden by themes that give content images blanket margins */
13
+ }
14
+ .tiled-gallery .gallery-group {
15
+ float: right;
16
+ position: relative;
17
+ }
18
+ .tiled-gallery .tiled-gallery-item {
19
+ float: right;
20
+ margin: 0;
21
+ position: relative;
22
+ width: inherit; /* prevents ie8 bug with inline width styles */
23
+ }
24
+ .tiled-gallery .gallery-row {
25
+ overflow: hidden;
26
+ margin-bottom: 2px;
27
+ }
28
+ .tiled-gallery .tiled-gallery-item a { /* Needs to reset some properties for theme compatibility */
29
+ background: transparent;
30
+ border: none;
31
+ color: none;
32
+ margin: 0;
33
+ padding: 0;
34
+ text-decoration: none;
35
+ width: auto;
36
+ }
37
+ .tiled-gallery .tiled-gallery-item img,
38
+ .tiled-gallery .tiled-gallery-item img:hover { /* Needs to reset some properties for theme compatibility */
39
+ background: none;
40
+ border: none;
41
+ box-shadow: none;
42
+ max-width: 100%;
43
+ padding: 0;
44
+ vertical-align: middle;
45
+ }
46
+ .tiled-gallery-caption { /* Captions */
47
+ background: #eee;
48
+ background: rgba( 255,255,255,0.8 );
49
+ color: #333;
50
+ font-size: 13px;
51
+ font-weight: 400;
52
+ overflow: hidden;
53
+ padding: 10px 0;
54
+ position: absolute;
55
+ bottom: 0;
56
+ text-indent: 10px;
57
+ text-overflow: ellipsis;
58
+ width: 100%;
59
+ white-space: nowrap;
60
+ }
61
+ .tiled-gallery .tiled-gallery-item-small .tiled-gallery-caption { /* Smaller captions */
62
+ font-size: 11px;
63
+ }
64
+
65
+
66
+ /* =Greyscale
67
+ -------------------------------------------------------------- */
68
+
69
+ .tiled-gallery .tiled-gallery-item img.grayscale {
70
+ position: absolute;
71
+ right: 0;
72
+ top: 0;
73
+ }
74
+ .tiled-gallery .tiled-gallery-item img.grayscale:hover {
75
+ opacity: 0;
76
+ }
77
+
78
+
79
+ /* =Circles Layout
80
+ -------------------------------------------------------------- */
81
+
82
+ .tiled-gallery.type-circle .tiled-gallery-item img {
83
+ border-radius: 50% !important; /* Ensure that circles are displayed in themes that add border-radius to all images as a default */
84
+ }
85
+ .tiled-gallery.type-circle .tiled-gallery-caption {
86
+ display: none;
87
+ opacity: 0;
88
+ }
trunk/tiled-gallery/tiled-gallery.css ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* =Tiled Gallery Default Styles
2
+ -------------------------------------------------------------- */
3
+
4
+ .tiled-gallery {
5
+ clear: both;
6
+ margin: 0;
7
+ overflow: hidden;
8
+ }
9
+ .tiled-gallery img {
10
+ margin: 2px !important; /* Ensure that this value isn't overridden by themes that give content images blanket margins */
11
+ }
12
+ .tiled-gallery .gallery-group {
13
+ float: left;
14
+ position: relative;
15
+ }
16
+ .tiled-gallery .tiled-gallery-item {
17
+ float: left;
18
+ margin: 0;
19
+ position: relative;
20
+ width: inherit; /* prevents ie8 bug with inline width styles */
21
+ }
22
+ .tiled-gallery .gallery-row {
23
+ overflow: hidden;
24
+ margin-bottom: 2px;
25
+ }
26
+ .tiled-gallery .tiled-gallery-item a { /* Needs to reset some properties for theme compatibility */
27
+ background: transparent;
28
+ border: none;
29
+ color: none;
30
+ margin: 0;
31
+ padding: 0;
32
+ text-decoration: none;
33
+ width: auto;
34
+ }
35
+ .tiled-gallery .tiled-gallery-item img,
36
+ .tiled-gallery .tiled-gallery-item img:hover { /* Needs to reset some properties for theme compatibility */
37
+ background: none;
38
+ border: none;
39
+ box-shadow: none;
40
+ max-width: 100%;
41
+ padding: 0;
42
+ vertical-align: middle;
43
+ }
44
+ .tiled-gallery-caption { /* Captions */
45
+ background: #eee;
46
+ background: rgba( 255,255,255,0.8 );
47
+ color: #333;
48
+ font-size: 13px;
49
+ font-weight: 400;
50
+ overflow: hidden;
51
+ padding: 10px 0;
52
+ position: absolute;
53
+ bottom: 0;
54
+ text-indent: 10px;
55
+ text-overflow: ellipsis;
56
+ width: 100%;
57
+ white-space: nowrap;
58
+ }
59
+ .tiled-gallery .tiled-gallery-item-small .tiled-gallery-caption { /* Smaller captions */
60
+ font-size: 11px;
61
+ }
62
+
63
+
64
+ /* =Greyscale
65
+ -------------------------------------------------------------- */
66
+
67
+ .tiled-gallery .tiled-gallery-item img.grayscale {
68
+ position: absolute;
69
+ left: 0;
70
+ top: 0;
71
+ }
72
+ .tiled-gallery .tiled-gallery-item img.grayscale:hover {
73
+ opacity: 0;
74
+ }
75
+
76
+
77
+ /* =Circles Layout
78
+ -------------------------------------------------------------- */
79
+
80
+ .tiled-gallery.type-circle .tiled-gallery-item img {
81
+ border-radius: 50% !important; /* Ensure that circles are displayed in themes that add border-radius to all images as a default */
82
+ }
83
+ .tiled-gallery.type-circle .tiled-gallery-caption {
84
+ display: none;
85
+ opacity: 0;
86
+ }
trunk/tiled-gallery/tiled-gallery.js ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function($) {
2
+
3
+ var TiledGallery = function() {
4
+ this.resizeTimeout = null;
5
+
6
+ this.populate();
7
+
8
+ var self = this;
9
+
10
+ $( window ).on( 'resize', function () {
11
+ clearTimeout( self.resizeTimeout );
12
+
13
+ self.resizeTimeout = setTimeout( function () { self.resize(); }, 150 );
14
+ } );
15
+
16
+ // Make any new galleries loaded by Infinite Scroll flexible
17
+ $( 'body' ).on( 'post-load', $.proxy( self.initialize, self ) );
18
+
19
+ // Populate and set up captions on newdash galleries.
20
+ $( document ).on( 'page-rendered.wpcom-newdash', $.proxy( self.populate, self ) );
21
+
22
+ this.resize();
23
+ };
24
+
25
+ TiledGallery.prototype.populate = function() {
26
+ this.gallery = $( '.tiled-gallery' );
27
+ this.item = this.gallery.find( '.tiled-gallery-item' );
28
+ this.caption = this.gallery.find( '.tiled-gallery-caption' );
29
+
30
+ this.Captions();
31
+ };
32
+
33
+ TiledGallery.prototype.initialize = function() {
34
+ var self = this;
35
+
36
+ self.populate();
37
+
38
+ // After each image load, run resize in case all images in the gallery are loaded.
39
+ self.gallery.find( 'img' ).off( 'load.tiled-gallery' ).on( 'load.tiled-gallery', function () {
40
+ self.resize();
41
+ } );
42
+
43
+ // Run resize now in case all images loaded from cache.
44
+ self.resize();
45
+ };
46
+
47
+ /**
48
+ * Story
49
+ */
50
+ TiledGallery.prototype.Captions = function() {
51
+ /* Hide captions */
52
+ this.caption.hide();
53
+
54
+ this.item.on( 'hover', function() {
55
+ $( this ).find( '.tiled-gallery-caption' ).slideToggle( 'fast' );
56
+ });
57
+ };
58
+
59
+ TiledGallery.prototype.resize = function() {
60
+ var resizeableElements = '.gallery-row, .gallery-group, .tiled-gallery-item img';
61
+
62
+ this.gallery.each( function ( galleryIndex, galleryElement ) {
63
+ var thisGallery = $( galleryElement );
64
+
65
+ // All images must be loaded before proceeding.
66
+ var imagesLoaded = true;
67
+
68
+ thisGallery.find( 'img' ).each( function () {
69
+ if ( ! this.complete ) {
70
+ imagesLoaded = false;
71
+ return false;
72
+ }
73
+ } );
74
+
75
+ if ( ! imagesLoaded ) {
76
+ var loadCallback = arguments.callee;
77
+
78
+ // Once all of the images have loaded,
79
+ // re-call this containing function.
80
+ $( window ).load( function () {
81
+ loadCallback( null, thisGallery );
82
+ } );
83
+
84
+ return;
85
+ }
86
+
87
+ if ( ! thisGallery.data( 'sizes-set' ) ) {
88
+ // Maintain a record of the original widths and heights of these elements
89
+ // for proper scaling.
90
+ thisGallery.data( 'sizes-set', true );
91
+
92
+ thisGallery.find( resizeableElements ).each( function () {
93
+ var thisGalleryElement = $( this );
94
+
95
+ // Don't change margins, but remember what they were so they can be
96
+ // accounted for in size calculations. When the screen width gets
97
+ // small enough, ignoring the margins can cause images to overflow
98
+ // into new rows.
99
+ var extraWidth = ( parseInt( thisGalleryElement.css( 'marginLeft' ), 10 ) || 0 ) + ( parseInt( thisGalleryElement.css( 'marginRight' ), 10 ) || 0 );
100
+ var extraHeight = ( parseInt( thisGalleryElement.css( 'marginTop' ), 10 ) || 0 ) + ( parseInt( thisGalleryElement.css( 'marginBottom' ), 10 ) || 0 )
101
+
102
+ // In some situations, tiled galleries in Firefox have shown scrollbars on the images because
103
+ // the .outerWidth() call on the image returns a value larger than the container. Restrict
104
+ // widths used in the resizing functions to the maximum width of the container.
105
+ var parentElement = $( thisGalleryElement.parents( resizeableElements ).get( 0 ) );
106
+
107
+ if ( parentElement && parentElement.data( 'original-width' ) ) {
108
+ thisGalleryElement
109
+ .data( 'original-width', Math.min( parentElement.data( 'original-width' ), thisGalleryElement.outerWidth( true ) ) )
110
+ .data( 'original-height', Math.min( parentElement.data( 'original-height' ), thisGalleryElement.outerHeight( true ) ) );
111
+ }
112
+ else {
113
+ thisGalleryElement
114
+ .data( 'original-width', thisGalleryElement.outerWidth( true ) )
115
+ .data( 'original-height', thisGalleryElement.outerHeight( true ) );
116
+ }
117
+
118
+ thisGalleryElement
119
+ .data( 'extra-width', extraWidth )
120
+ .data( 'extra-height', extraHeight );
121
+ } );
122
+ }
123
+
124
+ // Resize everything in the gallery based on the ratio of the current content width
125
+ // to the original content width;
126
+ var originalWidth = thisGallery.data( 'original-width' );
127
+ var currentWidth = thisGallery.parent().width();
128
+ var resizeRatio = Math.min( 1, currentWidth / originalWidth );
129
+
130
+ thisGallery.find( resizeableElements ).each( function () {
131
+ var thisGalleryElement = $( this );
132
+
133
+ thisGalleryElement
134
+ .width( Math.floor( resizeRatio * thisGalleryElement.data( 'original-width' ) ) - thisGalleryElement.data( 'extra-width' ) )
135
+ .height( Math.floor( resizeRatio * thisGalleryElement.data( 'original-height' ) ) - thisGalleryElement.data( 'extra-height' ) );
136
+ } );
137
+ } );
138
+ };
139
+
140
+ /**
141
+ * Ready, set...
142
+ */
143
+ $( document ).ready( function() {
144
+
145
+ // Instance!
146
+ var TiledGalleryInstance = new TiledGallery;
147
+
148
+ });
149
+
150
+ })(jQuery);