summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo Chatzimichos <tampakrap@gentoo.org>2012-07-27 15:14:42 +0200
committerTheo Chatzimichos <tampakrap@gentoo.org>2012-07-27 15:14:42 +0200
commit79de32efcb1c1a2cc8651b7063d04cc9e8ffe1b3 (patch)
treedd9a16332c2c47d445f00ab89fb4973af7b5af08 /plugins/jetpack/modules
parentAdd kpicasa-gallery plugin (diff)
downloadblogs-gentoo-79de32efcb1c1a2cc8651b7063d04cc9e8ffe1b3.tar.gz
blogs-gentoo-79de32efcb1c1a2cc8651b7063d04cc9e8ffe1b3.tar.bz2
blogs-gentoo-79de32efcb1c1a2cc8651b7063d04cc9e8ffe1b3.zip
Update jetpack
Diffstat (limited to 'plugins/jetpack/modules')
-rw-r--r--plugins/jetpack/modules/carousel.php10
-rw-r--r--plugins/jetpack/modules/carousel/README1
-rw-r--r--plugins/jetpack/modules/carousel/images/arrows-2x.pngbin0 -> 10916 bytes
-rw-r--r--plugins/jetpack/modules/carousel/images/arrows.pngbin0 -> 5382 bytes
-rw-r--r--plugins/jetpack/modules/carousel/images/carousel-likereblog-2x.pngbin0 -> 1096 bytes
-rw-r--r--plugins/jetpack/modules/carousel/images/carousel-likereblog.pngbin0 -> 547 bytes
-rw-r--r--plugins/jetpack/modules/carousel/images/carousel-link-2x.pngbin0 -> 867 bytes
-rw-r--r--plugins/jetpack/modules/carousel/images/carousel-link.pngbin0 -> 431 bytes
-rw-r--r--plugins/jetpack/modules/carousel/images/carousel-sprite-2x.pngbin0 -> 1546 bytes
-rw-r--r--plugins/jetpack/modules/carousel/images/carousel-sprite.pngbin0 -> 806 bytes
-rw-r--r--plugins/jetpack/modules/carousel/jetpack-carousel.css1035
-rw-r--r--plugins/jetpack/modules/carousel/jetpack-carousel.js1140
-rw-r--r--plugins/jetpack/modules/carousel/jetpack-carousel.php456
-rw-r--r--plugins/jetpack/modules/carousel/jquery.spin.js86
-rw-r--r--plugins/jetpack/modules/carousel/spin.js301
-rw-r--r--plugins/jetpack/modules/module-info.php28
16 files changed, 3055 insertions, 2 deletions
diff --git a/plugins/jetpack/modules/carousel.php b/plugins/jetpack/modules/carousel.php
new file mode 100644
index 00000000..4afe419f
--- /dev/null
+++ b/plugins/jetpack/modules/carousel.php
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * Module Name: Carousel
+ * Module Description: Transform your standard image galleries into an immersize full-screen experience.
+ * Sort Order: 13
+ * First Introduced: 1.4
+ */
+
+include dirname( __FILE__ ) . '/carousel/jetpack-carousel.php';
diff --git a/plugins/jetpack/modules/carousel/README b/plugins/jetpack/modules/carousel/README
new file mode 100644
index 00000000..9cc24a05
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/README
@@ -0,0 +1 @@
+Team Carousel will rock your world! \ No newline at end of file
diff --git a/plugins/jetpack/modules/carousel/images/arrows-2x.png b/plugins/jetpack/modules/carousel/images/arrows-2x.png
new file mode 100644
index 00000000..12a0bd97
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/images/arrows-2x.png
Binary files differ
diff --git a/plugins/jetpack/modules/carousel/images/arrows.png b/plugins/jetpack/modules/carousel/images/arrows.png
new file mode 100644
index 00000000..45d3ef66
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/images/arrows.png
Binary files differ
diff --git a/plugins/jetpack/modules/carousel/images/carousel-likereblog-2x.png b/plugins/jetpack/modules/carousel/images/carousel-likereblog-2x.png
new file mode 100644
index 00000000..1dd594fe
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/images/carousel-likereblog-2x.png
Binary files differ
diff --git a/plugins/jetpack/modules/carousel/images/carousel-likereblog.png b/plugins/jetpack/modules/carousel/images/carousel-likereblog.png
new file mode 100644
index 00000000..e4cd0596
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/images/carousel-likereblog.png
Binary files differ
diff --git a/plugins/jetpack/modules/carousel/images/carousel-link-2x.png b/plugins/jetpack/modules/carousel/images/carousel-link-2x.png
new file mode 100644
index 00000000..9939ecba
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/images/carousel-link-2x.png
Binary files differ
diff --git a/plugins/jetpack/modules/carousel/images/carousel-link.png b/plugins/jetpack/modules/carousel/images/carousel-link.png
new file mode 100644
index 00000000..225348db
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/images/carousel-link.png
Binary files differ
diff --git a/plugins/jetpack/modules/carousel/images/carousel-sprite-2x.png b/plugins/jetpack/modules/carousel/images/carousel-sprite-2x.png
new file mode 100644
index 00000000..db5f1029
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/images/carousel-sprite-2x.png
Binary files differ
diff --git a/plugins/jetpack/modules/carousel/images/carousel-sprite.png b/plugins/jetpack/modules/carousel/images/carousel-sprite.png
new file mode 100644
index 00000000..f941bf9b
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/images/carousel-sprite.png
Binary files differ
diff --git a/plugins/jetpack/modules/carousel/jetpack-carousel.css b/plugins/jetpack/modules/carousel/jetpack-carousel.css
new file mode 100644
index 00000000..28cda5c7
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/jetpack-carousel.css
@@ -0,0 +1,1035 @@
+* {
+ line-height:inherit; /* prevent declarations of line-height in the universal selector */
+}
+
+.jp-carousel-overlay {
+ background: #000;
+}
+
+div.jp-carousel-buttons a.jp-carousel-permalink {
+ background: url(./images/carousel-link.png) no-repeat;
+ background-size: 12px 32px;
+}
+
+div.jp-carousel-fadeaway {
+ background: -moz-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0));
+ background: -webkit-gradient(linear, left bottom, left top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0)));
+ position: fixed;
+ bottom: 0;
+ z-index: 99999;
+ width: 100%;
+ height: 15px;
+}
+
+.jp-carousel-next-button span,
+.jp-carousel-previous-button span {
+ background: url(./images/arrows.png) no-repeat center center;
+ background-size: 200px 126px;
+}
+
+div.jp-carousel-buttons a.jp-carousel-permalink {
+ background-position: 2px 6px;
+ margin-right:0;
+}
+
+div.jp-carousel-buttons a.jp-carousel-permalink:hover {
+ background-position: 2px -14px;
+}
+
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
+ div.jp-carousel-buttons a.jp-carousel-permalink {
+ background-image: url(./images/carousel-link-2x.png);
+ background-position: 2px 6px;
+ }
+ .jp-carousel-next-button span,
+ .jp-carousel-previous-button span {
+ background-image: url(./images/arrows-2x.png);
+ }
+}
+
+.jp-carousel-wrap {
+ font-family: "Helvetica Neue", sans-serif !important;
+}
+
+.jp-carousel-info {
+ position: absolute;
+ bottom: 0;
+ text-align: left !important;
+ -webkit-font-smoothing: subpixel-antialiased !important;
+}
+
+.jp-carousel-info ::selection {
+ background: #68c9e8; /* Safari */
+ color: #fff;
+ }
+
+.jp-carousel-info ::-moz-selection {
+ background: #68c9e8; /* Firefox */
+ color: #fff;
+}
+
+.jp-carousel-photo-info {
+ position: relative;
+ -webkit-transition: 400ms ease-out;
+ -moz-transition: 400ms ease-out;
+ -o-transition: 400ms ease-out;
+ transition: 400ms ease-out;
+ left: 25%;
+ width: 50%;
+}
+
+.jp-carousel-info h2 {
+ background: none !important;
+ border: none !important;
+ color: #999;
+ display: block !important;
+ font: normal 13px/1.25em "Helvetica Neue", sans-serif !important;
+ letter-spacing: 0 !important;
+ margin: 7px 0 0 0 !important;
+ padding: 10px 0 0 !important;
+ overflow: hidden;
+ text-align: left;
+ text-shadow: none !important;
+ text-transform: none !important;
+ -webkit-font-smoothing: subpixel-antialiased;
+}
+
+.jp-carousel-next-button,
+.jp-carousel-previous-button {
+ text-indent: -9999px;
+ overflow: hidden;
+ cursor: pointer;
+}
+
+.jp-carousel-next-button span,
+.jp-carousel-previous-button span {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 82px;
+ zoom: 1;
+ filter: alpha(opacity=20);
+ opacity: 0.2;
+ -webkit-transition: 500ms opacity ease-out;
+ -moz-transition: 500ms opacity ease-out;
+ -o-transition: 500ms opacity ease-out;
+ transition: 500ms opacity ease-out;
+}
+
+.jp-carousel-next-button:hover span,
+.jp-carousel-previous-button:hover span {
+ filter: alpha(opacity=60);
+ opacity: 0.6;
+}
+.jp-carousel-next-button span {
+ background-position: -110px center;
+ right: 0;
+}
+
+.jp-carousel-previous-button span {
+ background-position: -10px center;
+ left:0;
+}
+
+.jp-carousel-buttons {
+ margin:0 0 15px 0;
+ padding-bottom:15px;
+ border-bottom:1px solid #222;
+}
+
+div.jp-carousel-buttons a {
+ border: none !important;
+ color: #999;
+ font: normal 13px/1.2em "Helvetica Neue", sans-serif !important;
+ letter-spacing: 0 !important;
+ padding: 5px 2px 5px 20px !important;
+ text-decoration: none !important;
+ text-shadow: none !important;
+ vertical-align: baseline !important;
+ -webkit-font-smoothing: subpixel-antialiased;
+}
+
+div.jp-carousel-buttons a:hover {
+ color: #68c9e8;
+ border: none !important;
+ -webkit-transition: none !important;
+ -moz-transition: none !important;
+ -o-transition: none !important;
+ transition: none !important;
+}
+
+.jp-carousel-slide, .jp-carousel-slide img, .jp-carousel-next-button,
+.jp-carousel-previous-button {
+ -webkit-transform:translate3d(0, 0, 0);
+ -moz-transform:translate3d(0, 0, 0);
+ -o-transform:translate3d(0, 0, 0);
+ -ms-transform:translate3d(0, 0, 0);
+}
+
+.jp-carousel-slide {
+ position:absolute;
+ width:0;
+ bottom:0;
+ background-color:#000;
+ border-radius:2px;
+ -webkit-border-radius:2px;
+ -moz-border-radius:2px;
+ -ms-border-radius:2px;
+ -o-border-radius:2px;
+ -webkit-transition: 400ms ease-out;
+ -moz-transition: 400ms ease-out;
+ -o-transition: 400ms ease-out;
+ transition: 400ms ease-out;
+}
+
+.jp-carousel-slide img {
+ display: block;
+ width: 100%;
+ height: 100%;
+ background: none !important;
+ border: none !important;
+ padding: 0 !important;
+ -webkit-box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+ -moz-box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+ zoom: 1;
+ filter: alpha(opacity=25);
+ opacity: 0.25;
+ -webkit-transition: opacity 400ms linear;
+ -moz-transition: opacity 400ms linear;
+ -o-transition: opacity 400ms linear;
+ transition: opacity 400ms linear;
+}
+
+.jp-carousel-slide.selected img {
+ filter: alpha(opacity=100);
+ opacity: 1;
+}
+
+.jp-carousel-close-hint {
+ color: #999;
+ cursor: default;
+ font: 16px/1 "Helvetica Neue", sans-serif !important;
+ font-weight: 600 !important;
+ letter-spacing: 0 !important;
+ padding:0.55em 0 0;
+ text-align: left;
+ width: 100%;
+ position: absolute;
+ -webkit-transition: color 200ms linear;
+ -moz-transition: color 200ms linear;
+ -o-transition: color 200ms linear;
+ transition: color 200ms linear;
+}
+
+.jp-carousel-close-hint span {
+ cursor:pointer;
+ background-color: black;
+ background-color: rgba(0,0,0,0.8);
+ height: 26px;
+ width: 26px;
+ display: block;
+ text-align: center;
+ vertical-align: middle;
+ line-height: 22px;
+ margin: 0 0 0 0.4em;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-transition: border-color 200ms linear;
+ -moz-transition: border-color 200ms linear;
+ -o-transition: border-color 200ms linear;
+ transition: border-color 200ms linear;
+}
+
+.jp-carousel-close-hint:hover {
+ cursor: default;
+ color: #fff;
+}
+
+.jp-carousel-close-hint:hover span {
+ border-color: #fff;
+}
+
+div.jp-carousel-buttons a.jp-carousel-like,
+div.jp-carousel-buttons a.jp-carousel-reblog,
+a.jp-carousel-image-download {
+ background: url(./images/carousel-sprite.png?3) no-repeat;
+ background-size: 16px 120px;
+}
+
+div.jp-carousel-buttons a.jp-carousel-reblog {
+ margin:0 5px 0 -5px !important;
+}
+
+div.jp-carousel-buttons a.jp-carousel-reblog.reblogged,
+div.jp-carousel-buttons a.jp-carousel-like.liked {
+ background-color: #222;
+ padding-right: 8px !important;
+ border-radius: 3px;
+ border-radius:3px;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+ -ms-border-radius:3px;
+ -o-border-radius:3px;
+}
+
+div.jp-carousel-buttons a.jp-carousel-reblog.reblogged {
+ margin:0 5px 0 0 !important;
+}
+
+
+div.jp-carousel-buttons a.jp-carousel-reblog,
+div.jp-carousel-buttons a.jp-carousel-reblog.reblogged:hover {
+ background-position: 6px -36px;
+ padding-left: 26px !important;
+ color: #999;
+}
+
+div.jp-carousel-buttons a.jp-carousel-reblog.reblogged:hover {
+ cursor: default;
+}
+
+div.jp-carousel-buttons a.jp-carousel-reblog:hover {
+ background-position: 6px -56px;
+ color: #68c9e8;
+}
+
+div.jp-carousel-buttons a.jp-carousel-like {
+ background-position: 5px 5px;
+ padding-left: 24px !important;
+}
+
+div.jp-carousel-buttons a.jp-carousel-like:hover {
+ background-position: 5px -15px;
+}
+
+@media
+only screen and (-webkit-min-device-pixel-ratio: 1.5),
+only screen and (-o-min-device-pixel-ratio: 3/2),
+only screen and (min--moz-device-pixel-ratio: 1.5),
+only screen and (min-device-pixel-ratio: 1.5) {
+ div.jp-carousel-buttons a.jp-carousel-like,
+ div.jp-carousel-buttons a.jp-carousel-reblog,
+ a.jp-carousel-image-download {
+ background-image: url(./images/carousel-sprite-2x.png?3);
+ }
+}
+
+/* reblog */
+div#carousel-reblog-box {
+ background: #222;
+ background: -moz-linear-gradient(bottom, #222, #333);
+ background: -webkit-gradient(linear, left bottom, left top, from(#222), to(#333));
+ padding: 3px 0 0;
+ display: none;
+ margin: 5px auto 0;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ -webkit-box-shadow: 0 0 20px rgba(0,0,0,0.9);
+ -moz-box-shadow: 0 0 20px rgba(0,0,0,0.9);
+ box-shadow: 0 0 20px rgba(0,0,0,0.9);
+ height: 74px;
+ width: 565px;
+}
+
+#carousel-reblog-box textarea {
+ background: #999;
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
+ color: #444;
+ padding: 3px 6px;
+ width: 370px;
+ height: 48px;
+ float: left;
+ margin: 6px 9px 0 9px;
+ border: 1px solid #666;
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+}
+
+#carousel-reblog-box textarea:focus {
+ background: #ccc;
+ color: #222;
+}
+
+#carousel-reblog-box label {
+ color: #aaa;
+ font-size: 11px;
+ padding-right: 2px;
+ padding-left: 2px;
+ display: inline;
+ font-weight: normal;
+}
+
+#carousel-reblog-box select {
+ width: 110px;
+ padding: 0;
+ font-size: 12px;
+ font-family: "Helvetica Neue", sans-serif !important;
+ background: #333;
+ color: #eee;
+ border: 1px solid #444;
+ margin-top:5px;
+}
+
+#carousel-reblog-box .submit,
+#wrapper #carousel-reblog-box p.response {
+ float: left;
+ width: 154px;
+ padding-top: 0;
+ padding-left: 1px;
+ overflow: hidden;
+ height: 34px;
+ margin:3px 0 0 2px !important;
+}
+
+#wrapper #carousel-reblog-box p.response {
+ font-size: 13px;
+ clear: none;
+ padding-left: 2px;
+ height: 34px;
+ color: #aaa;
+}
+
+#carousel-reblog-box input#carousel-reblog-submit, #jp-carousel-comment-form-button-submit {
+ font: 13px/24px "Helvetica Neue", sans-serif !important;
+ margin-top: 8px;
+ padding: 0 10px !important;
+ border-radius: 1em;
+ height: 24px;
+ color: #333;
+ cursor:pointer;
+ font-weight: normal;
+ background: #aaa;
+ background: -moz-linear-gradient(bottom, #aaa, #ccc);
+ background: -webkit-gradient(linear, left bottom, left top, from(#aaa), to(#ccc));
+ border: 1px solid #444;
+}
+
+#carousel-reblog-box input#carousel-reblog-submit:hover, #jp-carousel-comment-form-button-submit:hover {
+ background: #ccc;
+ background: -moz-linear-gradient(bottom, #ccc, #eee);
+ background: -webkit-gradient(linear, left bottom, left top, from(#ccc), to(#eee));
+}
+
+#carousel-reblog-box .canceltext {
+ color: #aaa;
+ font-size: 11px;
+ line-height: 24px;
+}
+
+#carousel-reblog-box .canceltext a {
+ color: #fff;
+}
+/* reblog end */
+
+
+/** Title and Desc Start **/
+.jp-carousel-titleanddesc {
+ border-top: 1px solid #222;
+ color: #999;
+ font-size: 15px;
+ padding-top: 24px;
+ margin-bottom: 20px;
+ font-weight:400;
+}
+.jp-carousel-titleanddesc-title {
+ font: 300 1.5em/1.1 "Helvetica Neue", sans-serif !important;
+ text-transform: none !important; /* prevents uppercase from leaking through */
+ color: #fff;
+ margin: 0 0 15px;
+ padding:0;
+}
+
+.jp-carousel-titleanddesc-desc p {
+ color: #999;
+ line-height:1.4;
+ margin-bottom: 0.75em;
+}
+
+.jp-carousel-titleanddesc p a,
+.jp-carousel-comments p a,
+.jp-carousel-info h2 a {
+ color: #fff !important;
+ border: none !important;
+ text-decoration: underline !important;
+ font-weight: normal !important;
+ font-style: normal !important;
+}
+
+.jp-carousel-titleanddesc p strong,
+.jp-carousel-titleanddesc p b {
+ font-weight: bold;
+ color: #999;
+}
+
+.jp-carousel-titleanddesc p em,
+.jp-carousel-titleanddesc p i {
+ font-style: italic;
+ color: #999;
+}
+
+
+.jp-carousel-titleanddesc p a:hover,
+.jp-carousel-comments p a:hover,
+.jp-carousel-info h2 a:hover {
+ color: #68c9e8 !important;
+}
+
+.jp-carousel-titleanddesc p:empty {
+ display: none;
+}
+
+h1:before, h1:after {
+ content:none !important;
+}
+/** Title and Desc End **/
+
+/** Meta Box Start **/
+.jp-carousel-image-meta {
+ background: #111;
+ padding: 18px 20px;
+ color: #fff;
+ font-size: 13px;
+ font: 12px/1.4 "Helvetica Neue", sans-serif !important;
+ width: 209px !important;
+ border: 1px solid #222;
+}
+
+.jp-carousel-image-meta li,
+.jp-carousel-image-meta h5 {
+ font-family: "Helvetica Neue", sans-serif !important;
+ position: inherit !important;
+ top: auto !important;
+ right: auto !important;
+ left: auto !important;
+ bottom: auto !important;
+ background: none !important;
+ border: none !important;
+ font-weight: 400 !important;
+ line-height: 1.3em !important;
+}
+
+.jp-carousel-image-meta ul {
+ margin: 0 !important;
+ padding: 0 !important;
+ list-style: none !important;
+}
+
+.jp-carousel-image-meta li {
+ width: 48% !important;
+ float: left !important;
+ margin: 0 2% 15px 0 !important;
+ color: #fff !important;
+ font-size:13px !important;
+}
+
+.jp-carousel-image-meta h5 {
+ color: #999 !important;
+ text-transform: uppercase !important;
+ font-size:10px !important;
+ margin:0 0 2px !important;
+ letter-spacing: 0.1em !important;
+}
+
+a.jp-carousel-image-download {
+ padding-left: 23px;
+ display: inline-block;
+ clear: both;
+ color: #999;
+ line-height: 1;
+ font-weight: 400;
+ font-size: 13px;
+ text-decoration: none;
+ background-position: 0 -82px;
+}
+
+a.jp-carousel-image-download span.photo-size {
+ font-size: 11px;
+ border-radius: 1em;
+ margin-left: 2px;
+ display: inline-block;
+}
+
+a.jp-carousel-image-download span.photo-size-times {
+ padding: 0 1px 0 2px;
+}
+
+a.jp-carousel-image-download:hover {
+ background-position: 0 -102px;
+ color: #68c9e8;
+ border: none !important;
+}
+
+/** Meta Box End **/
+
+/** GPS Map Start **/
+.jp-carousel-image-map {
+ position: relative;
+ margin: -20px -20px 20px;
+ border-bottom: 1px solid rgba( 255, 255, 255, 0.17 );
+ height: 154px;
+}
+
+.jp-carousel-image-map img.gmap-main {
+ -moz-border-radius-topleft: 6px;
+ border-top-left-radius: 6px;
+ border-right: 1px solid rgba( 255, 255, 255, 0.17 );
+}
+.jp-carousel-image-map div.gmap-topright {
+ width: 94px;
+ height: 154px;
+ position: absolute;
+ top: 0;
+ right: 0;
+}
+.jp-carousel-image-map div.imgclip {
+ overflow: hidden;
+ -moz-border-radius-topright: 6px;
+ border-top-right-radius: 6px;
+}
+.jp-carousel-image-map div.gmap-topright img {
+ margin-left: -40px;
+}
+.jp-carousel-image-map img.gmap-bottomright {
+ position: absolute;
+ top: 96px;
+ right: 0;
+}
+
+/** Comments Start **/
+.jp-carousel-comments {
+ font: 15px/1.7 "Helvetica Neue", sans-serif !important;
+ font-weight: 400;
+ background:none transparent;
+}
+
+.jp-carousel-comments p a:hover, .jp-carousel-comments p a:focus, .jp-carousel-comments p a:active {
+ color: #68c9e8 !important;
+}
+
+.jp-carousel-comment {
+ background:none transparent;
+ color: #999;
+ margin-bottom: 20px;
+ clear:left;
+ overflow: auto;
+ width: 100%
+}
+
+.jp-carousel-comment p {
+ color: #999 !important;
+}
+
+.jp-carousel-comment .comment-author {
+ font-size: 13px;
+ font-weight:400;
+ padding:0;
+ width:auto;
+ display: inline;
+ float:none;
+}
+
+.jp-carousel-comment .comment-author a {
+ color: #fff;
+}
+
+.jp-carousel-comment .comment-gravatar {
+ float:left;
+}
+
+.jp-carousel-comment .comment-content {
+ border:none;
+ margin-left:85px;
+}
+
+.jp-carousel-comment .avatar {
+ margin:0 20px 0 0;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ border: none !important;
+ padding: 0 !important;
+ background-color: transparent !important;
+}
+
+.jp-carousel-comment .comment-date {
+ color:#999;
+ margin-top: 4px;
+ font-size:11px;
+ display: inline;
+ float: right;
+ /*clear: right;*/
+}
+
+#jp-carousel-comment-form {
+ margin:0 0 10px !important;
+ float: left;
+ width: 100%;
+}
+
+textarea#jp-carousel-comment-form-comment-field {
+ background: rgba(34,34,34,0.9);
+ border: 1px solid #3a3a3a;
+ color: #aaa;
+ font: 15px/1.4 "Helvetica Neue", sans-serif !important;
+ width: 100%;
+ padding: 10px 10px 5px;
+ margin: 0;
+ float: none;
+ height: 147px;
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ overflow: hidden;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+textarea#jp-carousel-comment-form-comment-field::-webkit-input-placeholder {
+ color: #555;
+}
+
+textarea#jp-carousel-comment-form-comment-field:focus {
+ background: #ccc;
+ color: #222;
+}
+
+textarea#jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder {
+ color: #aaa;
+}
+
+#jp-carousel-comment-form-spinner {
+ color: #fff;
+ margin:22px 0 0 10px;
+ display: block;
+ width: 20px;
+ height: 20px;
+ float: left;
+}
+
+#jp-carousel-comment-form-submit-and-info-wrapper {
+ display: none;
+ /*margin-bottom:15px;*/
+ overflow: hidden;
+ width: 100%
+}
+
+#jp-carousel-comment-form-commenting-as {
+}
+
+#jp-carousel-comment-form-commenting-as input {
+ background: rgba(34,34,34,0.9);
+ border: 1px solid #3a3a3a;
+ color: #aaa;
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
+ padding: 3px 6px;
+ float: left;
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ width:285px;
+}
+
+#jp-carousel-comment-form-commenting-as input:focus {
+ background: #ccc;
+ color: #222;
+}
+
+#jp-carousel-comment-form-commenting-as p {
+ font: 400 13px/1.7 "Helvetica Neue", sans-serif !important;
+ margin:22px 0 0;
+ float: left;
+}
+
+#jp-carousel-comment-form-commenting-as fieldset {
+ float:left;
+ border:none;
+ margin:20px 0 0 0;
+ padding:0;
+}
+
+#jp-carousel-comment-form-commenting-as fieldset {
+ clear: both;
+}
+
+#jp-carousel-comment-form-commenting-as label {
+ font: 400 13px/1.7 "Helvetica Neue", sans-serif !important;
+ margin:0 20px 3px 0;
+ float:left;
+ width:100px;
+}
+
+#jp-carousel-comment-form-button-submit {
+ margin-top: 20px;
+ float:right;
+}
+
+#js-carousel-comment-form-container {
+ margin-bottom:15px;
+ overflow: auto;
+ width: 100%;
+}
+
+#jp-carousel-comment-form-container {
+ margin-bottom:15px;
+ overflow: auto;
+ width: 100%;
+}
+
+#jp-carousel-comment-post-results {
+ display: none;
+ overflow:auto;
+ width:100%;
+}
+
+#jp-carousel-comment-post-results span {
+ display:block;
+ text-align: center;
+ margin-top:20px;
+ width: 100%;
+ overflow: auto;
+ padding: 1em 0;
+ box-sizing: border-box;
+ background: rgba( 0, 0, 0, 0.7 );
+ border-radius: 2px;
+ font: 13px/1.4 "Helvetica Neue", sans-serif !important;
+ border: 1px solid rgba( 255, 255, 255, 0.17 );
+ -webkit-box-shadow: inset 0px 0px 5px 5px rgba(0, 0, 0, 1);
+ box-shadow: inset 0px 0px 5px 5px rgba(0, 0, 0, 1);
+}
+
+.jp-carousel-comment-post-error {
+ color:#DF4926;
+}
+
+.jp-carousel-comment-post-success {
+ /*color:#21759B;*/
+}
+
+#jp-carousel-comments-closed {
+ display: none;
+ color: #999;
+}
+
+#jp-carousel-comments-loading {
+ font: 444 15px/1.7 "Helvetica Neue", sans-serif !important;
+ display: none;
+ color: #999;
+ text-align: left;
+ margin-bottom: 20px;
+}
+
+
+/* ----- Light variant ----- */
+
+.jp-carousel-light .jp-carousel-overlay {
+ background: #fff;
+}
+
+.jp-carousel-light .jp-carousel-next-button:hover span,
+.jp-carousel-light .jp-carousel-previous-button:hover span {
+ opacity: 0.8;
+}
+
+.jp-carousel-light .jp-carousel-close-hint:hover,
+.jp-carousel-light .jp-carousel-titleanddesc div {
+ color: #000 !important;
+}
+
+.jp-carousel-light .jp-carousel-comments p a,
+.jp-carousel-light .jp-carousel-comment .comment-author a,
+.jp-carousel-light .jp-carousel-titleanddesc p a,
+.jp-carousel-light .jp-carousel-titleanddesc p a,
+.jp-carousel-light .jp-carousel-comments p a,
+.jp-carousel-light .jp-carousel-info h2 a {
+ color: #1e8cbe !important;
+}
+
+.jp-carousel-light .jp-carousel-comments p a:hover,
+.jp-carousel-light .jp-carousel-comment .comment-author a:hover,
+.jp-carousel-light .jp-carousel-titleanddesc p a:hover,
+.jp-carousel-light .jp-carousel-titleanddesc p a:hover,
+.jp-carousel-light .jp-carousel-comments p a:hover,
+.jp-carousel-light .jp-carousel-info h2 a:hover {
+ color: #f1831e !important;
+}
+
+.jp-carousel-light .jp-carousel-info h2,
+.jp-carousel-light .jp-carousel-titleanddesc,
+.jp-carousel-light .jp-carousel-titleanddesc p,
+.jp-carousel-light .jp-carousel-comment,
+.jp-carousel-light .jp-carousel-comment p,
+.jp-carousel-light div.jp-carousel-buttons a,
+.jp-carousel-light .jp-carousel-titleanddesc p strong,
+.jp-carousel-light .jp-carousel-titleanddesc p b,
+.jp-carousel-light .jp-carousel-titleanddesc p em,
+.jp-carousel-light .jp-carousel-titleanddesc p i {
+ color: #666;
+}
+
+.jp-carousel-light .jp-carousel-buttons {
+ border-bottom-color: #dfdfdf;
+}
+
+.jp-carousel-light div.jp-carousel-buttons a:hover {
+ text-decoration: none;
+ color: #f1831e;
+}
+
+.jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog,
+.jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog:hover {
+ background-position: 4px -56px;
+ padding-left: 24px !important;
+}
+
+.jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog.reblogged,
+.jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like.liked {
+ background-color: #2ea2cc;
+ color: #fff;
+}
+
+.jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like,
+.jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like:hover {
+ background-position: 5px -15px;
+ padding-left: 23px !important;
+}
+
+.jp-carousel-light div.jp-carousel-buttons a.jp-carousel-reblog.reblogged {
+ background-position: 5px -36px;
+}
+
+.jp-carousel-light div.jp-carousel-buttons a.jp-carousel-like.liked {
+ background-position: 5px 5px;
+}
+
+.jp-carousel-light div#carousel-reblog-box {
+ background: #eee;
+ background: -moz-linear-gradient(bottom, #ececec, #f7f7f7);
+ background: -webkit-gradient(linear, left bottom, left top, from(#ececec), to(#f7f7f7));
+ -webkit-box-shadow: 0 2px 6px rgba(0,0,0,0.1);
+ -moz-box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+ border:1px solid #ddd;
+}
+
+.jp-carousel-light #carousel-reblog-box textarea {
+ border: 1px inset #ccc;
+ color: #666;
+ border: 1px solid #cfcfcf;
+ background: #fff;
+}
+
+.jp-carousel-light #carousel-reblog-box .canceltext {
+ color: #888;
+}
+
+.jp-carousel-light #carousel-reblog-box .canceltext a {
+ color: #666;
+}
+
+.jp-carousel-light #carousel-reblog-box select {
+ background: #eee;
+ color: #333;
+ border: 1px solid #aaa;
+}
+
+.jp-carousel-light #carousel-reblog-box input#carousel-reblog-submit, #jp-carousel-comment-form-button-submit {
+ color: #333;
+ background: #fff;
+ background: -moz-linear-gradient(bottom, #ddd, #fff);
+ background: -webkit-gradient(linear, left bottom, left top, from(#ddd), to(#fff));
+ border: 1px solid #aaa;
+}
+
+.jp-carousel-light .jp-carousel-image-meta {
+ background: #fafafa;
+ border: 1px solid #eee;
+ border-top-color: #f5f5f5;
+ border-left-color: #f5f5f5;
+ color: #333;
+}
+
+.jp-carousel-light .jp-carousel-image-meta li {
+ color: #000 !important;
+}
+
+.jp-carousel-light .jp-carousel-close-hint {
+ color: #ccc;
+}
+
+.jp-carousel-light .jp-carousel-close-hint span {
+ background-color: white;
+ border-color: #ccc;
+}
+
+.jp-carousel-light #jp-carousel-comment-form-comment-field::-webkit-input-placeholder {
+ color: #aaa;
+}
+
+.jp-carousel-light #jp-carousel-comment-form-comment-field:focus {
+ color: #333;
+}
+
+.jp-carousel-light #jp-carousel-comment-form-comment-field:focus::-webkit-input-placeholder {
+ color: #ddd;
+}
+
+.jp-carousel-light a.jp-carousel-image-download {
+ background-position: 0 -102px;
+}
+
+.jp-carousel-light a.jp-carousel-image-download:hover {
+ background-position: 0 -102px;
+ color: #f1831e;
+}
+
+.jp-carousel-light textarea#jp-carousel-comment-form-comment-field {
+ background: #fbfbfb;
+ color: #333;
+ border: 1px solid #dfdfdf;
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
+}
+
+.jp-carousel-light #jp-carousel-comment-form-commenting-as input {
+ background: #fbfbfb;
+ border: 1px solid #dfdfdf;
+ color: #333;
+ -webkit-box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
+ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.1);
+}
+
+.jp-carousel-light #jp-carousel-comment-form-commenting-as input:focus {
+ background: #fbfbfb;
+ color: #333;
+}
+
+.jp-carousel-light #jp-carousel-comment-post-results span {
+ background: #f7f7f7;
+ border:1px solid #dfdfdf;
+ -webkit-box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.05);
+}
+
+.jp-carousel-light .jp-carousel-slide {
+ background-color:#fff;
+}
+
+.jp-carousel-light .jp-carousel-titleanddesc {
+ border-top: 1px solid #eee;
+}
+
+.jp-carousel-light .jp-carousel-fadeaway {
+ background: -moz-linear-gradient(bottom, rgba(255,255,255,0.75), rgba(255,255,255,0));
+ background: -webkit-gradient(linear, left bottom, left top, from(rgba(255,255,255,0.75)), to(rgba(255,255,255,0)));
+}
diff --git a/plugins/jetpack/modules/carousel/jetpack-carousel.js b/plugins/jetpack/modules/carousel/jetpack-carousel.js
new file mode 100644
index 00000000..d58fa10c
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/jetpack-carousel.js
@@ -0,0 +1,1140 @@
+
+jQuery(document).ready(function($) {
+
+ // gallery faded layer and container elements
+ var overlay, comments, gallery, container, nextButton, previousButton, info, title,
+ caption, resizeTimeout, mouseTimeout, photo_info, close_hint, commentInterval, buttons,
+ screenPadding = 110, originalOverflow = $('body').css('overflow'), proportion = 85;
+
+ var keyListener = function(e){
+ switch(e.which){
+ case 38: // up
+ e.preventDefault();
+ container.scrollTop(container.scrollTop() - 100);
+ break;
+ case 40: // down
+ e.preventDefault();
+ container.scrollTop(container.scrollTop() + 100);
+ break;
+ case 39: // right
+ e.preventDefault();
+ gallery.jp_carousel('clearCommentTextAreaValue');
+ gallery.jp_carousel('next');
+ break;
+ case 37: // left
+ e.preventDefault();
+ gallery.jp_carousel('clearCommentTextAreaValue');
+ gallery.jp_carousel('previous');
+ break;
+ case 27: // escape
+ e.preventDefault();
+ gallery.jp_carousel('clearCommentTextAreaValue');
+ container.jp_carousel('close');
+ break;
+ default:
+ // making jslint happy
+ break;
+ }
+ };
+
+ var resizeListener = function(e){
+ clearTimeout(resizeTimeout);
+ resizeTimeout = setTimeout(function(){
+ gallery
+ .jp_carousel('slides')
+ .jp_carousel('fitSlide', true);
+ gallery
+ .jp_carousel('fitInfo', true)
+ .jp_carousel('fitMeta', true);
+ }, 200);
+ };
+
+ var prepareGallery = function(){
+ if (!overlay) {
+
+ overlay = $('<div></div>')
+ .addClass('jp-carousel-overlay')
+ .css({
+ 'position' : 'absolute',
+ 'top' : 0,
+ 'right' : 0,
+ 'bottom' : 0,
+ 'left' : 0
+ });
+
+ buttons = $('<div class="jp-carousel-buttons">' + buttons + '</div>');
+
+ caption = $('<h2></h2>');
+ photo_info = $('<div class="jp-carousel-photo-info"></div>').append(caption);
+
+ imageMeta = $('<div></div>')
+ .addClass('jp-carousel-image-meta')
+ .css({
+ 'float' : 'right',
+ 'margin-top' : '20px',
+ 'width' : '250px'
+ });
+
+ titleAndDescription = $('<div></div>')
+ .addClass('jp-carousel-titleanddesc')
+ .css({
+ 'width' : '100%',
+ 'margin-top' : imageMeta.css('margin-top')
+ });
+
+ var commentFormMarkup = '';
+ var iframeSrc = '';
+
+ commentFormMarkup = '<div id="jp-carousel-comment-form-container">';
+ if (iframeSrc && iframeSrc.length) {
+ // We're using Jetpack comments!
+ var iframeHeight = (jetpackCarouselStrings.is_logged_in || iframeSrc.match('comment_registration=1')) ? 220 : 340;
+ iframeSrc = iframeSrc.replace(/(blogid=\d+)/, '$1&postid='+window.location.hash.replace(/#jp-carousel-/,'')); // get initial attachment id from URL hash
+ 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>';
+ } else if ( jetpackCarouselStrings.local_comments_commenting_as && jetpackCarouselStrings.local_comments_commenting_as.length ) {
+ // Jetpack comments not enabled, fallback to local comments
+ commentFormMarkup += '<form id="jp-carousel-comment-form">';
+ 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>';
+ commentFormMarkup += '<div id="jp-carousel-comment-form-submit-and-info-wrapper">';
+ commentFormMarkup += '<div id="jp-carousel-comment-form-commenting-as">' + jetpackCarouselStrings.local_comments_commenting_as + '</div>';
+ commentFormMarkup += '<input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="'+jetpackCarouselStrings.post_comment+'" />';
+ commentFormMarkup += '<span id="jp-carousel-comment-form-spinner">&nbsp;</span>';
+ commentFormMarkup += '<div id="jp-carousel-comment-post-results"></div>';
+ commentFormMarkup += '</div>';
+ commentFormMarkup += '</form>';
+ }
+ commentFormMarkup += '</div>';
+
+ commentForm = $(commentFormMarkup)
+ .css({
+ 'width' : '100%',
+ 'margin-top' : '20px',
+ 'color' : '#999'
+ });
+
+ comments = $('<div></div>')
+ .addClass('jp-carousel-comments')
+ .css({
+ 'width' : '100%',
+ 'bottom' : '10px',
+ 'margin-top' : '20px'
+ });
+
+ commentsLoading = $('<div id="jp-carousel-comments-loading"><span>'+jetpackCarouselStrings.loading_comments+'</span></div>')
+ .css({
+ 'width' : '100%',
+ 'bottom' : '10px',
+ 'margin-top' : '20px'
+ });
+
+ leftWidth = ( $(window).width() - ( screenPadding * 2 ) ) - (imageMeta.width() + 40);
+ if ( $.browser.mozilla )
+ leftWidth -= 55;
+ else if ( $.browser.msie )
+ leftWidth -= 20;
+ leftWidth += 'px';
+
+ leftColWrapper = $('<div></div>')
+ .addClass('jp-carousel-left-column-wrapper')
+ .css({
+ 'width' : leftWidth
+ })
+ .append(titleAndDescription)
+ .append(commentForm)
+ .append(comments)
+ .append(commentsLoading);
+
+ fadeaway = $('<div></div>')
+ .addClass('jp-carousel-fadeaway');
+
+ info = $('<div></div>')
+ .addClass('jp-carousel-info')
+ .css({
+ 'top' : ($(window).height() / 100) * proportion,
+ 'left' : screenPadding,
+ 'right' : screenPadding
+ })
+ .append(photo_info)
+ .append(imageMeta)
+ .append(leftColWrapper);
+
+ targetBottomPos = ( $(window).height() - parseInt( info.css('top'), 10 ) ) + 'px';
+
+ nextButton = $("<div><span></span></div>")
+ .addClass('jp-carousel-next-button')
+ .css({
+ 'position' : 'fixed',
+ 'top' : 0,
+ 'right' : 0,
+ 'bottom' : 0,
+ 'width' : screenPadding
+ });
+
+ $('span', nextButton).css({
+ 'top' : '40px',
+ 'bottom' : targetBottomPos
+ });
+
+ previousButton = $("<div><span></span></div>")
+ .addClass('jp-carousel-previous-button')
+ .css({
+ 'position' : 'fixed',
+ 'top' : 0,
+ 'left' : 0,
+ 'bottom' : 0,
+ 'width' : screenPadding
+ });
+
+ $('span', previousButton).css({
+ 'top' : '40px',
+ 'bottom' : targetBottomPos
+ });
+
+ gallery = $('<div></div>')
+ .addClass('jp-carousel')
+ .css({
+ 'position' : 'absolute',
+ 'top' : 0,
+ 'bottom' : targetBottomPos,
+ 'left' : 0,
+ 'right' : 0
+ });
+
+ close_hint = $('<div class="jp-carousel-close-hint"><span>&times;</span></div>')
+ .css({
+ position : 'fixed'
+ });
+
+ container = $("<div></div>")
+ .addClass('jp-carousel-wrap');
+
+ if ( 'white' == jetpackCarouselStrings.background_color )
+ container.addClass('jp-carousel-light');
+
+ container.css({
+ 'position' : 'fixed',
+ 'top' : 0,
+ 'right' : 0,
+ 'bottom' : 0,
+ 'left' : 0,
+ 'z-index' : 999999,
+ 'overflow-x' : 'hidden',
+ 'overflow-y' : 'auto',
+ 'direction' : 'ltr'
+ })
+ .hide()
+ .append(overlay)
+ .append(gallery)
+ .append(fadeaway)
+ .append(info)
+ .append(nextButton)
+ .append(previousButton)
+ .append(close_hint)
+ .appendTo($('body'))
+ .click(function(e){
+ var target = $(e.target), wrap = target.parents('div.jp-carousel-wrap'), data = wrap.data('carousel-extra'),
+ slide = wrap.find('div.selected'), attachment_id = slide.data('attachment-id');
+ data = data || [];
+
+ if ( target.is(gallery) || target.parents().add(target).is(close_hint) ) {
+ container.jp_carousel('close');
+ } else if ( target.parents('#jp-carousel-comment-form-container').length ) {
+ var textarea = $('#jp-carousel-comment-form-comment-field')
+ .blur(function(){
+ $(window).bind('keydown', keyListener);
+ })
+ .focus(function(){
+ $(window).unbind('keydown', keyListener);
+ });
+
+ var emailField = $('#jp-carousel-comment-form-email-field')
+ .blur(function(){
+ $(window).bind('keydown', keyListener);
+ })
+ .focus(function(){
+ $(window).unbind('keydown', keyListener);
+ });
+
+ var authorField = $('#jp-carousel-comment-form-author-field')
+ .blur(function(){
+ $(window).bind('keydown', keyListener);
+ })
+ .focus(function(){
+ $(window).unbind('keydown', keyListener);
+ });
+
+ var urlField = $('#jp-carousel-comment-form-url-field')
+ .blur(function(){
+ $(window).bind('keydown', keyListener);
+ })
+ .focus(function(){
+ $(window).unbind('keydown', keyListener);
+ });
+
+ if ( textarea && textarea.attr('id') == target.attr('id')) {
+ // For first page load
+ $(window).unbind('keydown', keyListener);
+ $('#jp-carousel-comment-form-submit-and-info-wrapper').slideDown('fast');
+ } else if ( target.is( 'input[type="submit"]' ) ) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ $('#jp-carousel-comment-form-spinner').spin('small', 'white');
+
+ var ajaxData = {
+ action: 'post_attachment_comment',
+ nonce: jetpackCarouselStrings.nonce,
+ blog_id: data['blog_id'],
+ id: attachment_id,
+ comment: textarea.val()
+ };
+
+ if ( ! ajaxData['comment'].length ) {
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.no_comment_text});
+ return;
+ }
+
+ if ( 1 != jetpackCarouselStrings.is_logged_in ) {
+ ajaxData['email'] = emailField.val();
+ ajaxData['author'] = authorField.val();
+ ajaxData['url'] = urlField.val();
+
+ if ( ! ajaxData['email'].length || ! ajaxData['email'].match('@') ) {
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-email-field', 'error': jetpackCarouselStrings.no_comment_email});
+ return;
+ } else if ( ! ajaxData['author'].length ) {
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-author-field', 'error': jetpackCarouselStrings.no_comment_author});
+ return;
+ }
+ }
+
+ $.ajax({
+ type: 'POST',
+ url: jetpackCarouselStrings.ajaxurl,
+ data: ajaxData,
+ dataType: 'json',
+ success: function(response, status, xhr) {
+ if ( 'approved' == response.comment_status ) {
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-success">' + jetpackCarouselStrings.comment_approved + '</span>').slideDown('fast');
+ } else if ( 'unapproved' == response.comment_status ) {
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-success">' + jetpackCarouselStrings.comment_unapproved + '</span>').slideDown('fast');
+ } else {
+ // 'deleted', 'spam', false
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-error">' + jetpackCarouselStrings.comment_post_error + '</span>').slideDown('fast');
+ }
+ gallery.jp_carousel('clearCommentTextAreaValue');
+ gallery.jp_carousel('getComments', {attachment_id: attachment_id, offset: 0, clear: true});
+ $('#jp-carousel-comment-form-button-submit').val(jetpackCarouselStrings.post_comment);
+ $('#jp-carousel-comment-form-spinner').spin(false);
+ },
+ error: function(xhr, status, error) {
+ // TODO: Add error handling and display here
+ gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.comment_post_error});
+ return;
+ }
+ });
+ }
+ } else if ( ! target.parents( '.jp-carousel-info' ).length ) {
+ container.jp_carousel('next');
+ }
+ })
+ .bind('jp_carousel.afterOpen', function(){
+ $(window).bind('keydown', keyListener);
+ $(window).bind('resize', resizeListener);
+ })
+ .bind('jp_carousel.beforeClose', function(){
+ var scroll = $(window).scrollTop();
+
+ $(window).unbind('keydown', keyListener);
+ $(window).unbind('resize', resizeListener);
+ document.location.hash = '';
+ $(window).scrollTop(scroll);
+ });
+
+ nextButton.add(previousButton).click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ if ( nextButton.is(this) ) {
+ gallery.jp_carousel('next');
+ } else {
+ gallery.jp_carousel('previous');
+ }
+ });
+ }
+ };
+
+ var methods = {
+ open: function(options) {
+ var settings = {
+ 'items_selector' : ".gallery-item [data-attachment-id]",
+ 'start_index': 0
+ },
+ data = $(this).data('carousel-extra');
+
+ if ( !data )
+ return; // don't run if the default gallery functions weren't used
+
+ // make sure to stop the page from scrolling behind the carousel overlay, so we don't trigger
+ // infiniscroll for it when enabled (Reader, theme infiniscroll, etc).
+ originalOverflow = $('body').css('overflow');
+ $('body').css('overflow', 'hidden');
+
+ prepareGallery();
+ container.data('carousel-extra', data);
+
+ return this.each(function() {
+ // If options exist, lets merge them
+ // with our default settings
+ var $this = $(this);
+
+ if ( options )
+ $.extend( settings, options );
+ if ( -1 == settings.start_index )
+ settings.start_index = 0; //-1 returned if can't find index, so start from beginning
+
+ container.trigger('jp_carousel.beforeOpen').fadeIn('fast',function(){
+ container.trigger('jp_carousel.afterOpen');
+ gallery
+ .jp_carousel('initSlides', $this.find(settings.items_selector), settings.start_index)
+ .jp_carousel('start', settings.start_index);
+ });
+ gallery.html('');
+ });
+ },
+
+ start : function(start_index){
+ var slides = this.jp_carousel('slides'), selected = slides.eq(start_index);
+
+ if ( 0 === selected.length )
+ selected = slides.eq(0);
+
+ gallery.jp_carousel('selectSlide', selected, false);
+ return this;
+ },
+
+ close : function(){
+ // make sure to let the page scroll again
+ $('body').css('overflow', originalOverflow);
+ return container
+ .trigger('jp_carousel.beforeClose')
+ .fadeOut('fast', function(){
+ container.trigger('jp_carousel.afterClose');
+ });
+
+ },
+
+ next : function(){
+ var selected = this.jp_carousel('selectedSlide'), slide;
+ container.animate({scrollTop:0}, 'fast');
+ if ( 0 === selected.length ) { // no selection return first item
+ slide = this.jp_carousel('slides').first(0);
+ } else if( selected.is( this.jp_carousel('slides').last() ) ) {
+ gallery.jp_carousel('loopSlides');
+ } else {
+ slide = selected.next();
+ }
+ if (!slide) {
+ return this;
+ } else {
+ return this.jp_carousel('selectSlide', slide);
+ }
+ },
+
+ previous : function(){
+ var selected = this.jp_carousel('selectedSlide'), slide;
+ container.animate({scrollTop:0}, 'fast');
+ if ( 0 === selected.length ) { // no selection return first item
+ slide = this.jp_carousel('slides').first();
+ } else if ( selected.is( this.jp_carousel('slides').first() ) ) { // if it's the last slide
+ gallery.jp_carousel('loopSlides', true);
+ } else {
+ slide = selected.prev();
+ }
+ if (!slide) {
+ return this;
+ } else {
+ return this.jp_carousel('selectSlide', slide);
+ }
+ },
+
+ resetButtons : function(current) {
+ },
+
+ loopSlides : function(reverse){
+ var slides = gallery.jp_carousel('slides'), last, first;
+ gallery.jp_carousel('selectedSlide').removeClass('selected').css({'position': 'fixed'});
+ if (reverse !== true ) {
+ last = slides.last();
+ slides.first().nextAll().not(last).css({'left':gallery.width()+slides.first().width()}).hide();
+ last.css({
+ 'left' : -last.width()
+ });
+ last.prev().css({
+ 'left' : -last.width() - last.prev().width()
+ });
+ slides.first().css({'left':gallery.width()});
+ setTimeout(function(){
+ gallery.jp_carousel('selectSlide', slides.show().first());
+ }, 400);
+
+ } else {
+ first = slides.first();
+ first.css({
+ 'left':gallery.width()
+ });
+ first.next().css({
+ 'left':gallery.width() + first.width()
+ });
+ first.next().nextAll().hide().css({'left':-slides.last().width()});
+ slides.last().css({'left':-slides.last().width()});
+ slides.last().prevAll().not(first, first.next()).hide().css({'left':-slides.last().width()-slides.last().prev().width()});
+ setTimeout(function(){
+ gallery.jp_carousel('selectSlide', slides.show().last());
+ }, 400);
+
+ }
+ },
+
+ selectedSlide : function(){
+ return this.find('.selected');
+ },
+
+ selectSlide : function(slide, animate){
+ var last = this.find('.selected').removeClass('selected'),
+ slides = gallery.jp_carousel('slides').css({'position': 'fixed'}),
+ current = $(slide).addClass('selected').css({'position': 'relative'}),
+ previous = current.prev(),
+ next = current.next(),
+ width = $(window).width(),
+ previous_previous = previous.prev(),
+ next_next = next.next(),
+ left = (gallery.width() - current.width()) * 0.5,
+ info_left,
+ animated,
+ info_min;
+ // center the main image
+
+ caption.hide();
+
+ method = 'css';
+ animated = current
+ .add(previous)
+ .add(previous.prev())
+ .add(next)
+ .add(next.next())
+ .jp_carousel('loadSlide');
+ // slide the whole view to the x we want
+ slides.not(animated).hide();
+
+ current[method]({left:left}).show();
+
+ // minimum width
+ gallery.jp_carousel('fitInfo', animate);
+
+ // prep the slides
+ var direction = last.is(current.prevAll()) ? 1 : -1;
+ if ( 1 == direction ) {
+ next_next.css({'left':gallery.width() + next.width()}).show();
+ next.hide().css({'left':gallery.width() + current.width()}).show();
+ previous_previous.css({'left':-previous_previous.width() - current.width()});
+ } else {
+ previous.css({'left':-previous.width() - current.width()});
+ next_next.css({'left':gallery.width() + current.width()});
+ }
+
+ // if advancing prepare the slide that will enter the screen
+ previous[method]({left:-previous.width() + (screenPadding * 0.75) }).show();
+ next[method]({left:gallery.width() - (screenPadding * 0.75) }).show();
+
+ setTimeout( function() {
+ document.location.href = document.location.href.replace(/#.*/, '') + '#jp-carousel-' + current.data('attachment-id');
+ gallery.jp_carousel('resetButtons', current);
+ container.trigger('jp_carousel.selectSlide', [current]);
+
+ $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' ).html('');
+
+ gallery.jp_carousel('getTitleDesc', { title: current.data('title'), desc: current.data('desc') } );
+ gallery.jp_carousel('getMeta', current.data('image-meta'));
+ gallery.jp_carousel('getFullSizeLink', current);
+ gallery.jp_carousel('getMap', current.data('image-meta'));
+ gallery.jp_carousel('testCommentsOpened', current.data('comments-opened'));
+ gallery.jp_carousel('getComments', {'attachment_id': current.data('attachment-id'), 'offset': 0, 'clear': true});
+
+ $('#jp-carousel-comment-post-results').slideUp();
+
+ // $('<div />').html(sometext).text() is a trick to go to HTML to plain text (including HTML emntities decode, etc)
+ if ( current.data('caption') ) {
+ if ( $('<div />').html(current.data('caption')).text() == $('<div />').html(current.data('title')).text() )
+ $('.jp-carousel-titleanddesc-title').fadeOut('fast').empty();
+ if ( $('<div />').html(current.data('caption')).text() == $('<div />').html(current.data('desc')).text() )
+ $('.jp-carousel-titleanddesc-desc').fadeOut('fast').empty();
+ caption.html( current.data('caption') ).fadeIn('slow');
+ } else {
+ caption.fadeOut('fast').empty();
+ }
+ }, 600 );
+
+ },
+
+ slides : function(){
+ return this.find('.jp-carousel-slide');
+ },
+
+ slideDimensions : function(){
+ return {
+ width: $(window).width() - (screenPadding * 2),
+ height: $(window).height() / 100 * proportion - 60
+ };
+ },
+
+ loadSlide : function(){
+ return this.each(function(){
+ var slide = $(this);
+ slide.find('img')
+ .one('load', function(){
+ // set the width/height of the image if it's too big
+ slide
+ .jp_carousel('fitSlide',false);
+ });
+ });
+ },
+
+ bestFit : function(){
+ var max = gallery.jp_carousel('slideDimensions'),
+ orig = this.jp_carousel('originalDimensions'),
+ orig_ratio = orig.width / orig.height,
+ w_ratio = 1,
+ h_ratio = 1;
+
+ if ( orig.width > max.width )
+ w_ratio = max.width / orig.width;
+ if ( orig.height > max.height )
+ h_ratio = max.height / orig.height;
+
+ if ( w_ratio < h_ratio ) {
+ width = max.width;
+ height = width / orig_ratio;
+ } else if ( h_ratio < w_ratio ) {
+ height = max.height;
+ width = height * orig_ratio;
+ } else {
+ width = orig.width;
+ height = orig.height;
+ }
+
+ return {
+ width: width,
+ height: height
+ };
+ },
+
+ fitInfo : function(animated){
+ var current = this.jp_carousel('selectedSlide'),
+ size = current.jp_carousel('bestFit');
+
+ photo_info.css({
+ 'left' : (info.width() - size.width) * 0.5,
+ 'width' : size.width
+ });
+ return this;
+ },
+
+ fitMeta : function(animated){
+ var newInfoTop = { top: ( $(window).height() / 100 * proportion + 5 ) + 'px' };
+ var newLeftWidth = { width: ( info.width() - (imageMeta.width() + 80) ) + 'px' };
+
+ if (animated) {
+ info.animate(newInfoTop);
+ leftColWrapper.animate(newLeftWidth);
+ } else {
+ info.animate(newInfoTop);
+ leftColWrapper.css(newLeftWidth);
+ }
+ },
+
+ fitSlide : function(animated){
+ return this.each(function(){
+ var selected = gallery.jp_carousel('selectedSlide'),
+ $this = $(this),
+ dimensions = $this.jp_carousel('bestFit'),
+ method = 'css',
+ max = gallery.jp_carousel('slideDimensions');
+
+ if ( 0 === selected.length ) {
+ dimensions.left = $(window).width();
+ } else if ($this.is(selected)) {
+ dimensions.left = ($(window).width() - dimensions.width) * 0.5;
+ } else if ($this.is(selected.next())) {
+ dimensions.left = gallery.width() - ( screenPadding * 0.75 );
+ } else if ($this.is(selected.prev())) {
+ dimensions.left = -dimensions.width + screenPadding * 0.75;
+ } else {
+ if ($this.is(selected.nextAll())) {
+ dimensions.left = $(window).width();
+ } else {
+ dimensions.left = -dimensions.width;
+ }
+ }
+ dimensions.top = ( (max.height - dimensions.height) * 0.5 ) + 40;
+ $this[method](dimensions);
+ });
+ },
+
+ texturize : function(text) {
+ text = text.replace("'", '&#8217;').replace('&#039;', '&#8217;').replace(/[\u2019]/, '&#8217;');
+ text = text.replace('"', '&#8221;').replace('&#034;', '&#8221;').replace('&quot;', '&#8221;').replace(/[\u201D]/, '&#8221;');
+ return $.trim(text);
+ },
+
+ initSlides : function(items, start_index){
+ var width = this.jp_carousel('slideDimensions').width,
+ x = 0;
+
+ // Calculate the new src.
+ items.each(function(i){
+ var src_item = $(this),
+ orig_size = src_item.data('orig-size') || 0,
+ max = gallery.jp_carousel('slideDimensions'),
+ parts = orig_size.split(',');
+ orig_size = {width: parseInt(parts[0], 10), height: parseInt(parts[1], 10)},
+ medium_file = src_item.data('medium-file') || '',
+ large_file = src_item.data('large-file') || '';
+
+ src = src_item.data('orig-file');
+
+ src = gallery.jp_carousel('selectBestImageSize', {
+ orig_file : src,
+ orig_width : orig_size.width,
+ max_width : max.width,
+ medium_file : medium_file,
+ large_file : large_file
+ });
+
+ // Set the final src
+ $(this).data( 'gallery-src', src );
+ });
+
+ // If the start_index is not 0 then preload the clicked image first.
+ if ( 0 !== start_index )
+ $('<img/>')[0].src = $(items[start_index]).data('gallery-src');
+
+ // create the 'slide'
+ items.each(function(i){
+ var src_item = $(this),
+ attachment_id = src_item.data('attachment-id') || 0,
+ comments_opened = src_item.data('comments-opened') || 0,
+ image_meta = src_item.data('image-meta') || {},
+ orig_size = src_item.data('orig-size') || 0,
+ title = src_item.attr('title') || '',
+ description = src_item.data('image-description') || '',
+ caption = src_item.parents('dl').find('dd.gallery-caption').html() || '',
+ src = src_item.data('gallery-src') || '',
+ medium_file = src_item.data('medium-file') || '',
+ large_file = src_item.data('large-file') || '';
+
+ if ( !attachment_id || !orig_size )
+ return false; // break the loop if we are missing the data-* attributes
+
+ title = gallery.jp_carousel('texturize', title);
+ description = gallery.jp_carousel('texturize', description);
+ caption = gallery.jp_carousel('texturize', caption);
+
+ var slide = $('<div class="jp-carousel-slide"></div>')
+ .hide()
+ .css({
+ 'position' : 'fixed',
+ 'left' : i < start_index ? -1000 : gallery.width()
+ })
+ .append($('<img>'))
+ .appendTo(gallery)
+ .data('src', src )
+ .data('title', title)
+ .data('desc', description)
+ .data('caption', caption)
+ .data('attachment-id', attachment_id)
+ .data('permalink', src_item.parents('a').attr('href'))
+ .data('orig-size', orig_size)
+ .data('comments-opened', comments_opened)
+ .data('image-meta', image_meta)
+ .data('medium-file', medium_file)
+ .data('large-file', large_file)
+ .jp_carousel('fitSlide', false);
+
+
+ // Preloading all images
+ slide.find('img').first().attr('src', src );
+ });
+ return this;
+ },
+
+ selectBestImageSize: function(args) {
+ if ( 'object' != typeof args )
+ args = {};
+
+ if ( 'undefined' == typeof args.orig_file )
+ return '';
+
+ if ( 'undefined' == typeof args.orig_width || 'undefined' == typeof args.max_width )
+ return args.orig_file;
+
+ if ( 'undefined' == typeof args.medium_file || 'undefined' == typeof args.large_file )
+ return args.orig_file;
+
+ var medium_size = args.medium_file.replace(/^https?:\/\/.+-([\d]+x[\d]+)\..+$/, '$1'),
+ medium_size_parts = (medium_size != args.medium_file) ? medium_size.split('x') : [args.orig_width, 0],
+ medium_width = parseInt( medium_size_parts[0], 10 ),
+ large_size = args.large_file.replace(/^https?:\/\/.+-([\d]+x[\d]+)\..+$/, '$1'),
+ large_size_parts = (large_size != args.large_file) ? large_size.split('x') : [args.orig_width, 0],
+ large_width = parseInt( large_size_parts[0], 10 );
+
+ // Give devices with a higher devicePixelRatio higher-res images (Retina display = 2, Android phones = 1.5, etc)
+ if ('undefined' != typeof window.devicePixelRatio && window.devicePixelRatio > 1)
+ args.max_width = args.max_width * window.devicePixelRatio;
+
+ if ( medium_width >= args.max_width )
+ return args.medium_file;
+
+ if ( large_width >= args.max_width )
+ return args.large_file;
+
+ return args.orig_file;
+ },
+
+
+ originalDimensions: function() {
+ var splitted = $(this).data('orig-size').split(',');
+ return {width: parseInt(splitted[0], 10), height: parseInt(splitted[1], 10)};
+ },
+
+ format: function( args ) {
+ if ( 'object' != typeof args )
+ args = {};
+ if ( ! args.text || 'undefined' == typeof args.text )
+ return;
+ if ( ! args.replacements || 'undefined' == typeof args.replacements )
+ return args.text;
+ return args.text.replace(/{(\d+)}/g, function(match, number) {
+ return typeof args.replacements[number] != 'undefined' ? args.replacements[number] : match;
+ });
+ },
+
+ shutterSpeed: function(d) {
+ if (d >= 1)
+ Math.round(d) + 's';
+ var df = 1, top = 1, bot = 1;
+ var limit = 1e5; //Increase for greater precision.
+ while (df != d && limit-- > 0) {
+ if (df < d) {
+ top += 1;
+ }
+ else {
+ bot += 1;
+ top = parseInt(d * bot, 10);
+ }
+ df = top / bot;
+ }
+ if (top > 1) {
+ bot = Math.round(bot / top);
+ top = 1;
+ }
+ if (bot <= 1)
+ return '1s';
+ return top + '/' + bot + 's';
+ },
+
+ parseTitleDesc: function( value ) {
+ if ( !value.match(' ') && value.match('_') )
+ return '';
+ // Prefix list originally based on http://commons.wikimedia.org/wiki/MediaWiki:Filename-prefix-blacklist
+ var prefixes = $([
+ 'CIMG', // Casio
+ 'DSC_', // Nikon
+ 'DSCF', // Fuji
+ 'DSCN', // Nikon
+ 'DUW', // some mobile phones
+ 'GEDC', // GE
+ 'IMG', // generic
+ 'JD', // Jenoptik
+ 'MGP', // Pentax
+ 'PICT', // misc.
+ 'Imagen', // misc.
+ 'Foto', // misc.
+ 'DSC', // misc.
+ 'Scan', // Scanners
+ 'SANY', // Sanyo
+ 'SAM', // Samsung
+ 'Screen Shot [0-9]+' // Mac screenshots
+ ])
+ .each(function(key, val){
+ regex = new RegExp('^' + val);
+ if ( regex.test(value) ) {
+ value = '';
+ return;
+ }
+ });
+ return value;
+ },
+
+ getTitleDesc: function( data ) {
+ var title ='', desc = '', markup = '', target, commentWrappere;
+
+ target = $( 'div.jp-carousel-titleanddesc', 'div.jp-carousel-wrap' );
+ target.hide();
+
+ title = gallery.jp_carousel('parseTitleDesc', data.title) || '';
+ desc = gallery.jp_carousel('parseTitleDesc', data.desc) || '';
+
+ if ( title.length || desc.length ) {
+ // $('<div />').html(sometext).text() is a trick to go to HTML to plain text (including HTML emntities decode, etc)
+ if ( $('<div />').html(title).text() == $('<div />').html(desc).text() )
+ title = '';
+
+ markup = ( title.length ) ? '<div class="jp-carousel-titleanddesc-title">' + title + '</div>' : '';
+ markup += ( desc.length ) ? '<div class="jp-carousel-titleanddesc-desc">' + desc + '</div>' : '';
+
+ target.html( markup ).fadeIn('slow');
+ }
+
+ $( 'div#jp-carousel-comment-form-container' ).css('margin-top', '20px');
+ $( 'div#jp-carousel-comments-loading' ).css('margin-top', '20px');
+ },
+
+ getMeta: function( meta ) {
+ if ( !meta || 1 != jetpackCarouselStrings.display_exif )
+ return false;
+
+ var $ul = $( '<ul></ul>' );
+ $.each( meta, function( key, val ) {
+ if ( 0 === parseFloat(val) || !val.length || -1 === $.inArray( key, [ 'camera', 'aperture', 'shutter_speed', 'focal_length' ] ) )
+ return;
+
+ switch( key ) {
+ case 'focal_length':
+ val = val + 'mm';
+ break;
+ case 'shutter_speed':
+ val = gallery.jp_carousel('shutterSpeed', val);
+ break;
+ case 'aperture':
+ val = 'f/' + val;
+ break;
+ default:
+ // making jslint happy
+ break;
+ }
+
+ $ul.append( '<li><h5>' + jetpackCarouselStrings[key] + '</h5>' + val + '</li>' );
+ });
+
+
+ $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' )
+ .append( $ul );
+ },
+
+ getFullSizeLink: function(current) {
+ if(!current || !current.data)
+ return false;
+ var original = current.data('src').replace(/\?.+$/, ''),
+ origSize = current.data('orig-size').split(','),
+ permalink = $( '<a>'+gallery.jp_carousel('format', {'text': jetpackCarouselStrings.download_original, 'replacements': origSize})+'</a>' )
+ .addClass( 'jp-carousel-image-download' )
+ .attr( 'href', original )
+ .attr( 'target', '_blank' );
+
+ $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' )
+ .append( permalink );
+ },
+
+ getMap: function( meta ) {
+ if ( !meta.latitude || !meta.longitude || 1 != jetpackCarouselStrings.display_geo )
+ return;
+
+ var latitude = meta.latitude,
+ longitude = meta.longitude,
+ $metabox = $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' ),
+ $mapbox = $( '<div></div>' ),
+ style = '&scale=2&style=feature:all|element:all|invert_lightness:true|hue:0x0077FF|saturation:-50|lightness:-5|gamma:0.91';
+
+ $mapbox
+ .addClass( 'jp-carousel-image-map' )
+ .html( '<img width="154" height="154" src="https://maps.googleapis.com/maps/api/staticmap?\
+ center=' + latitude + ',' + longitude + '&\
+ zoom=8&\
+ size=154x154&\
+ sensor=false&\
+ markers=size:medium%7Ccolor:blue%7C' + latitude + ',' + longitude + style +'" class="gmap-main" />\
+ \
+ <div class="gmap-topright"><div class="imgclip"><img width="175" height="154" src="https://maps.googleapis.com/maps/api/staticmap?\
+ center=' + latitude + ',' + longitude + '&\
+ zoom=3&\
+ size=175x154&\
+ sensor=false&\
+ markers=size:small%7Ccolor:blue%7C' + latitude + ',' + longitude + style + '"c /></div></div>\
+ \
+ ' )
+ .prependTo( $metabox );
+ },
+
+ testCommentsOpened: function( opened ) {
+ if ( 1 == parseInt( opened, 10 ) ) {
+ commentForm.fadeIn('fast');
+ } else {
+ commentForm.fadeOut('fast');
+ }
+ },
+
+ getComments: function( args ) {
+ if ( 'object' != typeof args )
+ args = {};
+
+ if ( ! args.attachment_id || 'undefined' == typeof args.attachment_id )
+ return;
+
+ if ( ! args.offset || 'undefined' == typeof args.offset || args.offset < 1 )
+ args.offset = 0;
+
+ var comments = $('.jp-carousel-comments'),
+ commentsLoading = $('#jp-carousel-comments-loading');
+
+ commentsLoading.show();
+
+ if ( args.clear ) {
+ comments.hide();
+ comments.empty();
+ }
+
+ $.ajax({
+ type: 'GET',
+ url: jetpackCarouselStrings.ajaxurl,
+ dataType: 'json',
+ data: {
+ action: 'get_attachment_comments',
+ nonce: jetpackCarouselStrings.nonce,
+ id: args.attachment_id,
+ offset: args.offset
+ },
+ success: function(data, status, xhr) {
+ if ( args.clear ) {
+ comments.fadeOut('fast');
+ comments.empty();
+ }
+
+ $( data ).each(function(){
+ var comment = $('<div></div>')
+ .addClass('jp-carousel-comment')
+ .attr('id', 'jp-carousel-comment-' + this['id'])
+ .css({})
+ .html(
+ '<div class="comment-gravatar">'
+ + this['gravatar_markup']
+ + '</div>'
+ + '<div class="comment-author">'
+ + this['author_markup']
+ + '</div>'
+ + '<div class="comment-date">'
+ + this['date_gmt']
+ + '</div>'
+ + '<div class="comment-content">'
+ + this['content']
+ + '</div>'
+ );
+ comments.append(comment);
+
+ // Set the interval to check for a new page of comments.
+ clearInterval( commentInterval );
+ commentInterval = setInterval( function() {
+ if ( ( $('.jp-carousel-overlay').height() - 150 ) < $('.jp-carousel-wrap').scrollTop() + $(window).height() ) {
+ gallery.jp_carousel('getComments',{ attachment_id: args.attachment_id, offset: args.offset + 10, clear: false });
+ clearInterval( commentInterval );
+ }
+ }, 150 );
+ });
+
+ // Verify (late) that the user didn't repeatldy click the arrows really fast, in which case the requested
+ // attachment id might no longer match the current attachment id by the time we get the data back or a now
+ // registered infiniscroll event kicks in, so we don't ever display comments for the wrong image by mistake.
+ var current = $('.jp-carousel div.selected');
+ if ( current && current.data && current.data('attachment-id') != args.attachment_id ) {
+ comments.fadeOut('fast');
+ comments.empty();
+ return;
+ }
+
+ // Increase the height of the background, semi-transparent overlay to match the new length of the comments list.
+ $('.jp-carousel-overlay').height( $(window).height() + titleAndDescription.height() + commentForm.height() + ( (comments.height() > 0) ? comments.height() : imageMeta.height() ) + 200 );
+
+ comments.show();
+ commentsLoading.hide();
+ },
+ error: function(xhr, status, error) {
+ // TODO: proper error handling
+ console.log( 'Comment get fail...', xhr, status, error );
+ comments.fadeIn('fast');
+ commentsLoading.fadeOut('fast');
+ }
+ });
+ },
+
+ postCommentError: function(args) {
+ if ( 'object' != typeof args )
+ args = {};
+ if ( ! args.field || 'undefined' == typeof args.field || ! args.error || 'undefined' == typeof args.error )
+ return;
+ $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-error">'+args.error+'</span>').slideDown('fast');
+ $('#jp-carousel-comment-form-spinner').spin(false);
+ },
+
+ setCommentIframeSrc: function(attachment_id) {
+ var iframe = $('#jp-carousel-comment-iframe');
+ // Set the proper irame src for the current attachment id
+ if (iframe && iframe.length) {
+ iframe.attr('src', iframe.attr('src').replace(/(postid=)\d+/, '$1'+attachment_id) );
+ iframe.attr('src', iframe.attr('src').replace(/(%23.+)?$/, '%23jp-carousel-'+attachment_id) );
+ }
+ },
+
+ clearCommentTextAreaValue: function() {
+ var commentTextArea = $('#jp-carousel-comment-form-comment-field');
+ if ( commentTextArea )
+ commentTextArea.val('');
+ }
+ };
+
+ $.fn.jp_carousel = function(method){
+ // ask for the HTML of the gallery
+ // Method calling logic
+ if ( methods[method] ) {
+ return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
+ } else if ( typeof method === 'object' || ! method ) {
+ return methods.open.apply( this, arguments );
+ } else {
+ $.error( 'Method ' + method + ' does not exist on jQuery.jp_carousel' );
+ }
+
+ };
+
+ // register the event listener for staring the gallery
+ $( document.body ).on( 'click', 'div.gallery', function(e) {
+ e.preventDefault();
+ $(this).jp_carousel('open', {start_index: $(this).find('.gallery-item').index($(e.target).parents('.gallery-item'))});
+ });
+
+ // start on page load if hash exists
+ if ( document.location.hash && document.location.hash.match(/jp-carousel-(\d+)/) ) {
+ $(document).ready(function(){
+ var gallery = $('div.gallery'), index = -1, n = document.location.hash.match(/jp-carousel-(\d+)/);
+
+ n = parseInt(n[1], 10);
+
+ gallery.find('img').each(function(num, el){
+ if ( n && $(el).data('attachment-id') == n ) { // n cannot be 0 (zero)
+ index = num;
+ return false;
+ }
+ });
+
+ if ( index != -1 )
+ gallery.jp_carousel('open', {start_index: index});
+ });
+ }
+});
diff --git a/plugins/jetpack/modules/carousel/jetpack-carousel.php b/plugins/jetpack/modules/carousel/jetpack-carousel.php
new file mode 100644
index 00000000..2fa59f6f
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/jetpack-carousel.php
@@ -0,0 +1,456 @@
+<?php
+
+/*
+Plugin Name: Jetpack Carousel
+Plugin URL: http://wordpress.com/
+Description: Transform your standard image galleries into an immersive full-screen experience.
+Version: 0.1
+Author: Automattic
+
+Released under the GPL v.2 license.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+*/
+class Jetpack_Carousel {
+
+ var $prebuilt_widths = array( 370, 700, 1000, 1200, 1400, 2000 );
+
+ var $first_run = true;
+
+ var $in_jetpack = true;
+
+ function __construct() {
+ add_action( 'init', array( $this, 'init' ) );
+ }
+
+ function init() {
+ if ( $this->maybe_disable_jp_carousel() )
+ return;
+
+ $this->in_jetpack = ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'enable_module_configurable' ) ) ? true : false;
+
+ if ( is_admin() ) {
+ // Register the Carousel-related related settings
+ add_action( 'admin_init', array( $this, 'register_settings' ), 5 );
+ if ( ! $this->in_jetpack ) {
+ if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
+ return; // Carousel disabled, abort early, but still register setting so user can switch it back on
+ }
+ // If in admin, register the ajax endpoints.
+ add_action( 'wp_ajax_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
+ add_action( 'wp_ajax_nopriv_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
+ add_action( 'wp_ajax_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
+ add_action( 'wp_ajax_nopriv_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
+ } else {
+ if ( ! $this->in_jetpack ) {
+ if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
+ return; // Carousel disabled, abort early
+ }
+ // If on front-end, do the Carousel thang.
+ $this->prebuilt_widths = apply_filters( 'jp_carousel_widths', $this->prebuilt_widths );
+ add_filter( 'post_gallery', array( $this, 'enqueue_assets' ), 1000, 2 ); // load later than other callbacks hooked it
+ add_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
+ add_filter( 'wp_get_attachment_link', array( $this, 'add_data_to_images' ), 10, 2 );
+ }
+
+ if ( $this->in_jetpack && method_exists( 'Jetpack', 'module_configuration_load' ) ) {
+ Jetpack::enable_module_configurable( dirname( dirname( __FILE__ ) ) . '/carousel.php' );
+ Jetpack::module_configuration_load( dirname( dirname( __FILE__ ) ) . '/carousel.php', array( $this, 'jetpack_configuration_load' ) );
+ }
+ }
+
+ function maybe_disable_jp_carousel() {
+ return apply_filters( 'jp_carousel_maybe_disable', false );
+ }
+
+ function jetpack_configuration_load() {
+ wp_safe_redirect( admin_url( 'options-media.php#carousel_background_color' ) );
+ exit;
+ }
+
+ function asset_version( $version ) {
+ return apply_filters( 'jp_carousel_asset_version', $version );
+ }
+
+ function enqueue_assets( $output ) {
+ if ( ! empty( $output ) ) {
+ // Bail because someone is overriding the [gallery] shortcode.
+ remove_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
+ remove_filter( 'wp_get_attachment_link', array( $this, 'add_data_to_images' ) );
+ return $output;
+ }
+
+ do_action( 'jp_carousel_thumbnails_shown' );
+
+ if ( $this->first_run ) {
+ if ( ! has_action( 'wp_enqueue_scripts', 'register_spin_scripts' ) ) {
+ wp_enqueue_script( 'spin', plugins_url( 'spin.js', __FILE__ ), false, '1.2.4' );
+ wp_enqueue_script( 'jquery.spin', plugins_url( 'jquery.spin.js', __FILE__ ) , array( 'jquery', 'spin' ) );
+ }
+
+ wp_enqueue_script( 'jetpack-carousel', plugins_url( 'jetpack-carousel.js', __FILE__ ), array( 'jquery' ), $this->asset_version( '20120629' ), true );
+
+ // 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)
+ // Also: not hardcoding path since there is no guarantee site is running on site root in self-hosted context.
+ $is_logged_in = is_user_logged_in();
+ $current_user = wp_get_current_user();
+ $localize_strings = array(
+ 'widths' => $this->prebuilt_widths,
+ 'is_logged_in' => $is_logged_in,
+ 'ajaxurl' => admin_url( 'admin-ajax.php', is_ssl() ? 'https' : 'http' ),
+ 'nonce' => wp_create_nonce( 'carousel_nonce' ),
+ 'display_exif' => $this->test_1or0_option( get_option( 'carousel_display_exif' ), true ),
+ 'display_geo' => $this->test_1or0_option( get_option( 'carousel_display_geo' ), true ),
+ 'background_color' => $this->carousel_background_color_sanitize( get_option( 'carousel_background_color' ) ),
+ 'post_comment' => __( 'Post Comment', 'jetpack' ),
+ 'loading_comments' => __( 'Loading Comments...', 'jetpack' ),
+ 'download_original' => __( 'View full size <span class="photo-size">{0}<span class="photo-size-times">&times;</span>{1}</span>', 'jetpack' ),
+ 'no_comment_text' => __( 'Please be sure to submit some text with your comment.', 'jetpack' ),
+ 'no_comment_email' => __( 'Please provide an email address to comment.', 'jetpack' ),
+ 'no_comment_author' => __( 'Please provide your name to comment.', 'jetpack' ),
+ 'comment_post_error' => __( 'Sorry, but there was an error posting your comment. Please try again later.', 'jetpack' ),
+ 'comment_approved' => __( 'Your comment was approved.', 'jetpack' ),
+ 'comment_unapproved' => __( 'Your comment is in moderation.', 'jetpack' ),
+ 'camera' => __( 'Camera', 'jetpack' ),
+ 'aperture' => __( 'Aperture', 'jetpack' ),
+ 'shutter_speed' => __( 'Shutter Speed', 'jetpack' ),
+ 'focal_length' => __( 'Focal Length', 'jetpack' ),
+ );
+
+ if ( ! isset( $localize_strings['jetpack_comments_iframe_src'] ) || empty( $localize_strings['jetpack_comments_iframe_src'] ) ) {
+ // We're not using Jetpack comments after all, so fallback to standard local comments.
+
+ if ( $is_logged_in ) {
+ $localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . sprintf( __( 'Commenting as %s', 'jetpack' ), $current_user->data->display_name ) . '</p>';
+ } else {
+ $localize_strings['local_comments_commenting_as'] = ''
+ . '<fieldset><label for="email">' . __( 'Email (Required)', 'jetpack' ) . '</label> '
+ . '<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>'
+ . '<fieldset><label for="author">' . __( 'Name (Required)', 'jetpack' ) . '</label> '
+ . '<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>'
+ . '<fieldset><label for="url">' . __( 'Website', 'jetpack' ) . '</label> '
+ . '<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>';
+ }
+ }
+
+ $localize_strings = apply_filters( 'jp_carousel_localize_strings', $localize_strings );
+ wp_localize_script( 'jetpack-carousel', 'jetpackCarouselStrings', $localize_strings );
+ wp_enqueue_style( 'jetpack-carousel', plugins_url( 'jetpack-carousel.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
+
+ do_action( 'jp_carousel_enqueue_assets', $this->first_run, $localize_strings );
+
+ $this->first_run = false;
+ }
+
+ return $output;
+ }
+
+ function add_data_to_images( $html, $attachment_id ) {
+ if ( $this->first_run ) // not in a gallery
+ return $html;
+
+ $attachment_id = intval( $attachment_id );
+ $orig_file = wp_get_attachment_url( $attachment_id );
+ $meta = wp_get_attachment_metadata( $attachment_id );
+ $size = isset( $meta['width'] ) ? intval( $meta['width'] ) . ',' . intval( $meta['height'] ) : '';
+ $img_meta = $meta['image_meta'];
+ $comments_opened = intval( comments_open( $attachment_id ) );
+
+ /*
+ * Note: Cannot generate a filename from the width and height wp_get_attachment_image_src() returns because
+ * it takes the $content_width global variable themes can set in consideration, therefore returning sizes
+ * which when used to generate a filename will likely result in a 404 on the image.
+ * $content_width has no filter we could temporarily de-register, run wp_get_attachment_image_src(), then
+ * re-register. So using returned file URL instead, which we can define the sizes from through filename
+ * parsing in the JS, as this is a failsafe file reference.
+ *
+ * EG with Twenty Eleven activated:
+ * 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) }
+ *
+ * EG with Twenty Ten activated:
+ * 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) }
+ */
+
+ $medium_file_info = wp_get_attachment_image_src( $attachment_id, 'medium' );
+ $medium_file = isset( $medium_file_info[0] ) ? $medium_file_info[0] : '';
+
+ $large_file_info = wp_get_attachment_image_src( $attachment_id, 'large' );
+ $large_file = isset( $large_file_info[0] ) ? $large_file_info[0] : '';
+
+ $attachment = get_post( $attachment_id );
+ $attachment_desc = wpautop( wptexturize( $attachment->post_content ) );
+
+ // Not yet providing geo-data, need to "fuzzify" for privacy
+ if ( ! empty( $img_meta ) ) {
+ foreach ( $img_meta as $k => $v ) {
+ if ( 'latitude' == $k || 'longitude' == $k )
+ unset( $img_meta[$k] );
+ }
+ }
+
+ $img_meta = json_encode( $img_meta );
+
+ $html = str_replace(
+ '<img ',
+ sprintf(
+ '<img data-attachment-id="%1$d" data-orig-file="%2$s" data-orig-size="%3$s" data-comments-opened="%4$s" data-image-meta="%5$s" data-image-description="%6$s" data-medium-file="%7$s" data-large-file="%8$s" ',
+ $attachment_id,
+ esc_attr( $orig_file ),
+ $size,
+ $comments_opened,
+ esc_attr( $img_meta ),
+ esc_attr( $attachment_desc ),
+ esc_attr( $medium_file ),
+ esc_attr( $large_file )
+ ),
+ $html
+ );
+
+ $html = apply_filters( 'jp_carousel_add_data_to_images', $html, $attachment_id );
+
+ return $html;
+ }
+
+ function add_data_to_container( $html ) {
+ global $post;
+
+ if ( isset( $post ) ) {
+ $blog_id = (int) get_current_blog_id();
+ $extra_data = array( 'data-carousel-extra' => array( 'blog_id' => $blog_id, 'permalink' => get_permalink( $post->ID ) ) );
+
+ $extra_data = apply_filters( 'jp_carousel_add_data_to_container', $extra_data );
+ foreach ( (array) $extra_data as $data_key => $data_values ) {
+ $html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . json_encode( $data_values ) . "' ", $html );
+ }
+ }
+
+ return $html;
+ }
+
+ function get_attachment_comments() {
+ if ( ! headers_sent() )
+ header('Content-type: text/javascript');
+
+ do_action('jp_carousel_check_blog_user_privileges');
+
+ $attachment_id = ( isset( $_REQUEST['id'] ) ) ? (int) $_REQUEST['id'] : 0;
+ $offset = ( isset( $_REQUEST['offset'] ) ) ? (int) $_REQUEST['offset'] : 0;
+
+ if ( ! $attachment_id ) {
+ echo json_encode( __( 'Missing attachment ID.', 'jetpack' ) );
+ die();
+ }
+
+ if ( $offset < 1 )
+ $offset = 0;
+
+ $comments = get_comments( array(
+ 'status' => 'approve',
+ 'order' => ( 'asc' == get_option('comment_order') ) ? 'ASC' : 'DESC',
+ 'number' => 10,
+ 'offset' => $offset,
+ 'post_id' => $attachment_id,
+ ) );
+
+ $out = array();
+
+ // Can't just send the results, they contain the commenter's email address.
+ foreach ( $comments as $comment ) {
+ $author_markup = '<a href="' . esc_url( $comment->comment_author_url ) . '">' . esc_html( $comment->comment_author ) . '</a>';
+ $out[] = array(
+ 'id' => $comment->comment_ID,
+ 'parent_id' => $comment->comment_parent,
+ 'author_markup' => $author_markup,
+ 'gravatar_markup' => get_avatar( $comment->comment_author_email, 64 ),
+ 'date_gmt' => $comment->comment_date_gmt,
+ 'content' => wpautop($comment->comment_content),
+ );
+ }
+
+ die( json_encode( $out ) );
+ }
+
+ function post_attachment_comment() {
+ if ( ! headers_sent() )
+ header('Content-type: text/javascript');
+
+ if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce($_POST['nonce'], 'carousel_nonce') )
+ die( json_encode( array( 'error' => __( 'Nonce verification failed.', 'jetpack' ) ) ) );
+
+ $_blog_id = (int) $_POST['blog_id'];
+ $_post_id = (int) $_POST['id'];
+ $comment = $_POST['comment'];
+
+ if ( empty( $_blog_id ) )
+ die( json_encode( array( 'error' => __( 'Missing target blog ID.', 'jetpack' ) ) ) );
+
+ if ( empty( $_post_id ) )
+ die( json_encode( array( 'error' => __( 'Missing target post ID.', 'jetpack' ) ) ) );
+
+ if ( empty( $comment ) )
+ die( json_encode( array( 'error' => __( 'No comment text was submitted.', 'jetpack' ) ) ) );
+
+ // Used in context like NewDash
+ $switched = false;
+ if ( $_blog_id != get_current_blog_id() ) {
+ switch_to_blog( $_blog_id );
+ $switched = true;
+ }
+
+ do_action('jp_carousel_check_blog_user_privileges');
+
+ if ( ! comments_open( $_post_id ) )
+ die( json_encode( array( 'error' => __( 'Comments on this post are closed.', 'jetpack' ) ) ) );
+
+ if ( is_user_logged_in() ) {
+ $user = wp_get_current_user();
+ $user_id = $user->ID;
+ $display_name = $user->display_name;
+ $email = $user->user_email;
+ $url = $user->user_url;
+
+ if ( empty( $user_id ) )
+ die( json_encode( array( 'error' => __( 'Sorry, but we could not authenticate your request.', 'jetpack' ) ) ) );
+ } else {
+ $user_id = 0;
+ $display_name = $_POST['author'];
+ $email = $_POST['email'];
+ $url = $_POST['url'];
+
+ if ( empty( $display_name ) )
+ die( json_encode( array( 'error' => __( 'Please provide your name.', 'jetpack' ) ) ) );
+
+ if ( empty( $email ) )
+ die( json_encode( array( 'error' => __( 'Please provide an email address.', 'jetpack' ) ) ) );
+
+ if ( ! is_email( $email ) )
+ die( json_encode( array( 'error' => __( 'Please provide a valid email address.', 'jetpack' ) ) ) );
+ }
+
+ $comment_data = array(
+ 'comment_content' => $comment,
+ 'comment_post_ID' => $_post_id,
+ 'comment_author' => $display_name,
+ 'comment_author_email' => $email,
+ 'comment_author_url' => $url,
+ 'comment_approved' => 0,
+ );
+
+ if ( ! empty( $user_id ) )
+ $comment_data['user_id'] = $user_id;
+
+ // Note: wp_new_comment() sanitizes and validates the values (too).
+ $comment_id = wp_new_comment( $comment_data );
+ do_action( 'jp_carousel_post_attachment_comment' );
+ $comment_status = wp_get_comment_status( $comment_id );
+
+ if ( true == $switched )
+ restore_current_blog();
+
+ die( json_encode( array( 'comment_id' => $comment_id, 'comment_status' => $comment_status ) ) );
+ }
+
+ function register_settings() {
+ add_settings_section('carousel_section', __( 'Image Gallery Carousel', 'jetpack' ), array( $this, 'carousel_section_callback' ), 'media');
+
+ if ( ! $this->in_jetpack ) {
+ add_settings_field('carousel_enable_it', __( 'Enable carousel', 'jetpack' ), array( $this, 'carousel_enable_it_callback' ), 'media', 'carousel_section' );
+ register_setting( 'media', 'carousel_enable_it', array( $this, 'carousel_enable_it_sanitize' ) );
+ }
+
+ add_settings_field('carousel_background_color', __( 'Background color', 'jetpack' ), array( $this, 'carousel_background_color_callback' ), 'media', 'carousel_section' );
+ register_setting( 'media', 'carousel_background_color', array( $this, 'carousel_background_color_sanitize' ) );
+
+ add_settings_field('carousel_display_exif', __( 'Metadata', 'jetpack'), array( $this, 'carousel_display_exif_callback' ), 'media', 'carousel_section' );
+ register_setting( 'media', 'carousel_display_exif', array( $this, 'carousel_display_exif_sanitize' ) );
+
+ // No geo setting yet, need to "fuzzify" data first, for privacy
+ // add_settings_field('carousel_display_geo', __( 'Geolocation', 'jetpack' ), array( $this, 'carousel_display_geo_callback' ), 'media', 'carousel_section' );
+ // register_setting( 'media', 'carousel_display_geo', array( $this, 'carousel_display_geo_sanitize' ) );
+ }
+
+ // Fulfill the settings section callback requirement by returning nothing
+ function carousel_section_callback() {
+ return;
+ }
+
+ function test_1or0_option( $value, $default_to_1 = true ) {
+ if ( true == $default_to_1 ) {
+ // Binary false (===) of $value means it has not yet been set, in which case we do want to default sites to 1
+ if ( false === $value )
+ $value = 1;
+ }
+ return ( 1 == $value ) ? 1 : 0;
+ }
+
+ function sanitize_1or0_option( $value ) {
+ return ( 1 == $value ) ? 1 : 0;
+ }
+
+ function settings_checkbox($name, $label_text, $extra_text = '', $default_to_checked = true) {
+ if ( empty( $name ) )
+ return;
+ $option = $this->test_1or0_option( get_option( $name ), $default_to_checked );
+ echo '<fieldset>';
+ echo '<input type="checkbox" name="'.esc_attr($name).'" id="'.esc_attr($name).'" value="1" ';
+ checked( '1', $option );
+ echo '/> <label for="'.esc_attr($name).'">'.$label_text.'</label>';
+ if ( ! empty( $extra_text ) )
+ echo '<p class="description">'.$extra_text.'</p>';
+ echo '</fieldset>';
+ }
+
+ function settings_select($name, $values, $extra_text = '') {
+ if ( empty( $name ) || ! is_array( $values ) || empty( $values ) )
+ return;
+ $option = get_option( $name );
+ echo '<fieldset>';
+ echo '<select name="'.esc_attr($name).'" id="'.esc_attr($name).'">';
+ foreach( $values as $key => $value ) {
+ echo '<option value="'.esc_attr($key).'" ';
+ selected( $key, $option );
+ echo '>'.esc_html($value).'</option>';
+ }
+ echo '</select>';
+ if ( ! empty( $extra_text ) )
+ echo '<p class="description">'.$extra_text.'</p>';
+ echo '</fieldset>';
+ }
+
+ function carousel_display_exif_callback() {
+ $this->settings_checkbox( 'carousel_display_exif', __( 'Show photo metadata (<a href="http://en.wikipedia.org/wiki/Exchangeable_image_file_format" target="_blank">Exif</a>) in carousel, when available.', 'jetpack' ) );
+ }
+
+ function carousel_display_exif_sanitize( $value ) {
+ return $this->sanitize_1or0_option( $value );
+ }
+
+ function carousel_display_geo_callback() {
+ $this->settings_checkbox( 'carousel_display_geo', __( 'Show map of photo location in carousel, when available.', 'jetpack' ) );
+ }
+
+ function carousel_display_geo_sanitize( $value ) {
+ return $this->sanitize_1or0_option( $value );
+ }
+
+ function carousel_background_color_callback() {
+ $this->settings_select( 'carousel_background_color', array( 'black' => __( 'Black', 'jetpack' ), 'white' => __( 'White', 'jetpack', 'jetpack' ) ) );
+ }
+
+ function carousel_background_color_sanitize( $value ) {
+ return ( 'white' == $value ) ? 'white' : 'black';
+ }
+
+ function carousel_enable_it_callback() {
+ $this->settings_checkbox( 'carousel_enable_it', __( 'Display images in full-size carousel slideshow.', 'jetpack' ) );
+ }
+
+ function carousel_enable_it_sanitize( $value ) {
+ return $this->sanitize_1or0_option( $value );
+ }
+}
+
+new Jetpack_Carousel;
diff --git a/plugins/jetpack/modules/carousel/jquery.spin.js b/plugins/jetpack/modules/carousel/jquery.spin.js
new file mode 100644
index 00000000..4642af13
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/jquery.spin.js
@@ -0,0 +1,86 @@
+/*
+ * Matt Husby https://github.com/matthusby/spin.js
+ * Based on the jquery plugin by Bradley Smith
+ * https://gist.github.com/1290439
+ */
+
+/*
+Add spin to the jQuery object
+If color is not passed the spinner will be black
+You can now create a spinner using any of the variants below:
+$("#el").spin(); // Produces default Spinner
+$("#el").spin("small"); // Produces a 'small' Spinner
+$("#el").spin("large", "white"); // Produces a 'large' Spinner in white (or any valid CSS color).
+$("#el").spin({ ... }); // Produces a Spinner using your custom settings.
+$("#el").spin("small-right"); // Pin the small spinner to the right edge
+$("#el").spin("{small, medium, large}-{left, right, top, bottom}"); // All options for where to pin
+$("#el").spin(false); // Kills the spinner.
+*/
+
+( function( $ ) {
+ $.fn.spin = function( opts, color ) {
+ var presets = {
+ "small": { lines: 8, length: 2, width: 2, radius: 3, trail: 60, speed: 1.3 },
+ "medium": { lines: 8, length: 4, width: 3, radius: 5, trail: 60, speed: 1.3 },
+ "large": { lines: 10, length: 6, width: 4, radius: 7, trail: 60, speed: 1.3 }
+ };
+ if ( Spinner ) {
+ return this.each( function() {
+ var $this = $( this ),
+ data = $this.data();
+
+ if ( data.spinner ) {
+ data.spinner.stop();
+ delete data.spinner;
+ }
+ if ( opts !== false ) {
+ var spinner_options;
+ if ( typeof opts === "string" ) {
+ var spinner_base = opts.indexOf( '-' );
+ if( spinner_base == -1 ) {
+ spinner_base = opts;
+ } else {
+ spinner_base = opts.substring( 0, spinner_base );
+ }
+ if ( spinner_base in presets ) {
+ spinner_options = presets[spinner_base];
+ } else {
+ spinner_options = {};
+ }
+ var padding;
+ if ( opts.indexOf( "-right" ) != -1 ) {
+ padding = jQuery( this ).css( 'padding-left' );
+ if( typeof padding === "undefined" ) {
+ padding = 0;
+ } else {
+ padding = padding.replace( 'px', '' );
+ }
+ spinner_options.left = jQuery( this ).outerWidth() - ( 2 * ( spinner_options.length + spinner_options.width + spinner_options.radius ) ) - padding - 5;
+ }
+ if ( opts.indexOf( '-left' ) != -1 ) {
+ spinner_options.left = 5;
+ }
+ if ( opts.indexOf( '-top' ) != -1 ) {
+ spinner_options.top = 5;
+ }
+ if ( opts.indexOf( '-bottom' ) != -1 ) {
+ padding = jQuery( this ).css( 'padding-top' );
+ if( typeof padding === "undefined" ) {
+ padding = 0;
+ } else {
+ padding = padding.replace( 'px', '' );
+ }
+ spinner_options.top = jQuery( this ).outerHeight() - ( 2 * ( spinner_options.length + spinner_options.width + spinner_options.radius ) ) - padding - 5;
+ }
+ }
+ if( color ){
+ spinner_options.color = color;
+ }
+ data.spinner = new Spinner( spinner_options ).spin( this );
+ }
+ });
+ } else {
+ throw "Spinner class not available.";
+ }
+ };
+})( jQuery ); \ No newline at end of file
diff --git a/plugins/jetpack/modules/carousel/spin.js b/plugins/jetpack/modules/carousel/spin.js
new file mode 100644
index 00000000..f506cd2b
--- /dev/null
+++ b/plugins/jetpack/modules/carousel/spin.js
@@ -0,0 +1,301 @@
+//fgnass.github.com/spin.js#v1.2.4
+(function(window, document, undefined) {
+
+/**
+ * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
+ * Licensed under the MIT license
+ */
+
+ var prefixes = ['webkit', 'Moz', 'ms', 'O']; /* Vendor prefixes */
+ var animations = {}; /* Animation rules keyed by their name */
+ var useCssAnimations;
+
+ /**
+ * Utility function to create elements. If no tag name is given,
+ * a DIV is created. Optionally properties can be passed.
+ */
+ function createEl(tag, prop) {
+ var el = document.createElement(tag || 'div');
+ var n;
+
+ for(n in prop) {
+ el[n] = prop[n];
+ }
+ return el;
+ }
+
+ /**
+ * Appends children and returns the parent.
+ */
+ function ins(parent /* child1, child2, ...*/) {
+ for (var i=1, n=arguments.length; i<n; i++) {
+ parent.appendChild(arguments[i]);
+ }
+ return parent;
+ }
+
+ /**
+ * Insert a new stylesheet to hold the @keyframe or VML rules.
+ */
+ var sheet = function() {
+ var el = createEl('style');
+ ins(document.getElementsByTagName('head')[0], el);
+ return el.sheet || el.styleSheet;
+ }();
+
+ /**
+ * Creates an opacity keyframe animation rule and returns its name.
+ * Since most mobile Webkits have timing issues with animation-delay,
+ * we create separate rules for each line/segment.
+ */
+ function addAnimation(alpha, trail, i, lines) {
+ var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-');
+ var start = 0.01 + i/lines*100;
+ var z = Math.max(1-(1-alpha)/trail*(100-start) , alpha);
+ var prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase();
+ var pre = prefix && '-'+prefix+'-' || '';
+
+ if (!animations[name]) {
+ sheet.insertRule(
+ '@' + pre + 'keyframes ' + name + '{' +
+ '0%{opacity:'+z+'}' +
+ start + '%{opacity:'+ alpha + '}' +
+ (start+0.01) + '%{opacity:1}' +
+ (start+trail)%100 + '%{opacity:'+ alpha + '}' +
+ '100%{opacity:'+ z + '}' +
+ '}', 0);
+ animations[name] = 1;
+ }
+ return name;
+ }
+
+ /**
+ * Tries various vendor prefixes and returns the first supported property.
+ **/
+ function vendor(el, prop) {
+ var s = el.style;
+ var pp;
+ var i;
+
+ if(s[prop] !== undefined) return prop;
+ prop = prop.charAt(0).toUpperCase() + prop.slice(1);
+ for(i=0; i<prefixes.length; i++) {
+ pp = prefixes[i]+prop;
+ if(s[pp] !== undefined) return pp;
+ }
+ }
+
+ /**
+ * Sets multiple style properties at once.
+ */
+ function css(el, prop) {
+ for (var n in prop) {
+ el.style[vendor(el, n)||n] = prop[n];
+ }
+ return el;
+ }
+
+ /**
+ * Fills in default values.
+ */
+ function merge(obj) {
+ for (var i=1; i < arguments.length; i++) {
+ var def = arguments[i];
+ for (var n in def) {
+ if (obj[n] === undefined) obj[n] = def[n];
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * Returns the absolute page-offset of the given element.
+ */
+ function pos(el) {
+ var o = {x:el.offsetLeft, y:el.offsetTop};
+ while((el = el.offsetParent)) {
+ o.x+=el.offsetLeft;
+ o.y+=el.offsetTop;
+ }
+ return o;
+ }
+
+ var defaults = {
+ lines: 12, // The number of lines to draw
+ length: 7, // The length of each line
+ width: 5, // The line thickness
+ radius: 10, // The radius of the inner circle
+ color: '#000', // #rgb or #rrggbb
+ speed: 1, // Rounds per second
+ trail: 100, // Afterglow percentage
+ opacity: 1/4, // Opacity of the lines
+ fps: 20, // Frames per second when using setTimeout()
+ zIndex: 2e9, // Use a high z-index by default
+ className: 'spinner', // CSS class to assign to the element
+ top: 'auto', // center vertically
+ left: 'auto' // center horizontally
+ };
+
+ /** The constructor */
+ var Spinner = function Spinner(o) {
+ if (!this.spin) return new Spinner(o);
+ this.opts = merge(o || {}, Spinner.defaults, defaults);
+ };
+
+ Spinner.defaults = {};
+ Spinner.prototype = {
+ spin: function(target) {
+ this.stop();
+ var self = this;
+ var o = self.opts;
+ var el = self.el = css(createEl(0, {className: o.className}), {position: 'relative', zIndex: o.zIndex});
+ var mid = o.radius+o.length+o.width;
+ var ep; // element position
+ var tp; // target position
+
+ if (target) {
+ target.insertBefore(el, target.firstChild||null);
+ tp = pos(target);
+ ep = pos(el);
+ css(el, {
+ left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : o.left+mid) + 'px',
+ top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : o.top+mid) + 'px'
+ });
+ }
+
+ el.setAttribute('aria-role', 'progressbar');
+ self.lines(el, self.opts);
+
+ if (!useCssAnimations) {
+ // No CSS animation support, use setTimeout() instead
+ var i = 0;
+ var fps = o.fps;
+ var f = fps/o.speed;
+ var ostep = (1-o.opacity)/(f*o.trail / 100);
+ var astep = f/o.lines;
+
+ !function anim() {
+ i++;
+ for (var s=o.lines; s; s--) {
+ var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
+ self.opacity(el, o.lines-s, alpha, o);
+ }
+ self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
+ }();
+ }
+ return self;
+ },
+ stop: function() {
+ var el = this.el;
+ if (el) {
+ clearTimeout(this.timeout);
+ if (el.parentNode) el.parentNode.removeChild(el);
+ this.el = undefined;
+ }
+ return this;
+ },
+ lines: function(el, o) {
+ var i = 0;
+ var seg;
+
+ function fill(color, shadow) {
+ return css(createEl(), {
+ position: 'absolute',
+ width: (o.length+o.width) + 'px',
+ height: o.width + 'px',
+ background: color,
+ boxShadow: shadow,
+ transformOrigin: 'left',
+ transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
+ borderRadius: (o.width>>1) + 'px'
+ });
+ }
+ for (; i < o.lines; i++) {
+ seg = css(createEl(), {
+ position: 'absolute',
+ top: 1+~(o.width/2) + 'px',
+ transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
+ opacity: o.opacity,
+ animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
+ });
+ if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
+ ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
+ }
+ return el;
+ },
+ opacity: function(el, i, val) {
+ if (i < el.childNodes.length) el.childNodes[i].style.opacity = val;
+ }
+ };
+
+ /////////////////////////////////////////////////////////////////////////
+ // VML rendering for IE
+ /////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Check and init VML support
+ */
+ !function() {
+ var s = css(createEl('group'), {behavior: 'url(#default#VML)'});
+ var i;
+
+ if (!vendor(s, 'transform') && s.adj) {
+
+ // VML support detected. Insert CSS rules ...
+ for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');
+
+ Spinner.prototype.lines = function(el, o) {
+ var r = o.length+o.width;
+ var s = 2*r;
+
+ function grp() {
+ return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
+ }
+
+ var margin = -(o.width+o.length)*2+'px';
+ var g = css(grp(), {position: 'absolute', top: margin, left: margin});
+
+ var i;
+
+ function seg(i, dx, filter) {
+ ins(g,
+ ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
+ ins(css(createEl('roundrect', {arcsize: 1}), {
+ width: r,
+ height: o.width,
+ left: o.radius,
+ top: -o.width>>1,
+ filter: filter
+ }),
+ createEl('fill', {color: o.color, opacity: o.opacity}),
+ createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
+ )
+ )
+ );
+ }
+
+ if (o.shadow) {
+ for (i = 1; i <= o.lines; i++) {
+ seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
+ }
+ }
+ for (i = 1; i <= o.lines; i++) seg(i);
+ return ins(el, g);
+ };
+ Spinner.prototype.opacity = function(el, i, val, o) {
+ var c = el.firstChild;
+ o = o.shadow && o.lines || 0;
+ if (c && i+o < c.childNodes.length) {
+ c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild;
+ if (c) c.opacity = val;
+ }
+ };
+ }
+ else {
+ useCssAnimations = vendor(s, 'animation');
+ }
+ }();
+
+ window.Spinner = Spinner;
+
+})(window, document); \ No newline at end of file
diff --git a/plugins/jetpack/modules/module-info.php b/plugins/jetpack/modules/module-info.php
index 885b3fd2..4e0ca64c 100644
--- a/plugins/jetpack/modules/module-info.php
+++ b/plugins/jetpack/modules/module-info.php
@@ -429,8 +429,7 @@ add_action( 'jetpack_module_more_info_contact-form', 'jetpack_contact_form_more_
add_action( 'jetpack_module_more_info_connected_contact-form', 'jetpack_contact_form_more_info' );
// Contact Form: STOP
-// Jetpack Comments
-
+// Jetpack Comments: START
function jetpack_comments_learn_more_button() {
echo '<a class="button more-info-link" href="#">' . __( 'Learn More', 'jetpack' ) . '</a>';
}
@@ -459,3 +458,28 @@ function jetpack_comments_more_info() {
add_action( 'jetpack_learn_more_button_comments', 'jetpack_comments_learn_more_button' );
add_action( 'jetpack_module_more_info_comments', 'jetpack_comments_more_info' );
add_action( 'jetpack_module_more_info_connected_comments', 'jetpack_comments_more_info' );
+// Jetpack Comments: STOP
+
+// Gallery Carousel: START
+function jetpack_carousel_learn_more_button() {
+ echo '<a class="button more-info-link" href="#">' . __( 'Learn More', 'jetpack' ) . '</a>';
+}
+
+function jetpack_carousel_more_info() {
+?>
+ <div class="jp-info-img">
+ <img class="jp-info-img" src="<?php echo plugins_url( basename( dirname( dirname( __FILE__ ) ) ) . '/screenshot-6.png' ) ?>" alt="<?php esc_attr_e( 'Gallery Carousel Screenshot', 'jetpack' ) ?>" width="300" height="188" />
+ </div>
+
+ <h4><?php esc_html_e( 'Carousel', 'jetpack' ); ?></h4>
+
+ <p>
+ With Carousel active, any standard WordPress galleries you have embedded in posts or pages will launch a gorgeous full-screen photo browsing experience with comments and EXIF metadata.
+ </p>
+<?php
+}
+
+add_action( 'jetpack_learn_more_button_carousel', 'jetpack_carousel_learn_more_button' );
+add_action( 'jetpack_module_more_info_carousel', 'jetpack_carousel_more_info' );
+add_action( 'jetpack_module_more_info_connected_carousel', 'jetpack_carousel_more_info' );
+// Gallery Carousel: STOP