diff options
author | Theo Chatzimichos <tampakrap@gentoo.org> | 2012-07-27 15:14:42 +0200 |
---|---|---|
committer | Theo Chatzimichos <tampakrap@gentoo.org> | 2012-07-27 15:14:42 +0200 |
commit | 79de32efcb1c1a2cc8651b7063d04cc9e8ffe1b3 (patch) | |
tree | dd9a16332c2c47d445f00ab89fb4973af7b5af08 /plugins/jetpack/modules | |
parent | Add kpicasa-gallery plugin (diff) | |
download | blogs-gentoo-79de32efcb1c1a2cc8651b7063d04cc9e8ffe1b3.tar.gz blogs-gentoo-79de32efcb1c1a2cc8651b7063d04cc9e8ffe1b3.tar.bz2 blogs-gentoo-79de32efcb1c1a2cc8651b7063d04cc9e8ffe1b3.zip |
Update jetpack
Diffstat (limited to 'plugins/jetpack/modules')
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 Binary files differnew file mode 100644 index 00000000..12a0bd97 --- /dev/null +++ b/plugins/jetpack/modules/carousel/images/arrows-2x.png diff --git a/plugins/jetpack/modules/carousel/images/arrows.png b/plugins/jetpack/modules/carousel/images/arrows.png Binary files differnew file mode 100644 index 00000000..45d3ef66 --- /dev/null +++ b/plugins/jetpack/modules/carousel/images/arrows.png diff --git a/plugins/jetpack/modules/carousel/images/carousel-likereblog-2x.png b/plugins/jetpack/modules/carousel/images/carousel-likereblog-2x.png Binary files differnew file mode 100644 index 00000000..1dd594fe --- /dev/null +++ b/plugins/jetpack/modules/carousel/images/carousel-likereblog-2x.png diff --git a/plugins/jetpack/modules/carousel/images/carousel-likereblog.png b/plugins/jetpack/modules/carousel/images/carousel-likereblog.png Binary files differnew file mode 100644 index 00000000..e4cd0596 --- /dev/null +++ b/plugins/jetpack/modules/carousel/images/carousel-likereblog.png diff --git a/plugins/jetpack/modules/carousel/images/carousel-link-2x.png b/plugins/jetpack/modules/carousel/images/carousel-link-2x.png Binary files differnew file mode 100644 index 00000000..9939ecba --- /dev/null +++ b/plugins/jetpack/modules/carousel/images/carousel-link-2x.png diff --git a/plugins/jetpack/modules/carousel/images/carousel-link.png b/plugins/jetpack/modules/carousel/images/carousel-link.png Binary files differnew file mode 100644 index 00000000..225348db --- /dev/null +++ b/plugins/jetpack/modules/carousel/images/carousel-link.png diff --git a/plugins/jetpack/modules/carousel/images/carousel-sprite-2x.png b/plugins/jetpack/modules/carousel/images/carousel-sprite-2x.png Binary files differnew file mode 100644 index 00000000..db5f1029 --- /dev/null +++ b/plugins/jetpack/modules/carousel/images/carousel-sprite-2x.png diff --git a/plugins/jetpack/modules/carousel/images/carousel-sprite.png b/plugins/jetpack/modules/carousel/images/carousel-sprite.png Binary files differnew file mode 100644 index 00000000..f941bf9b --- /dev/null +++ b/plugins/jetpack/modules/carousel/images/carousel-sprite.png 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…"></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"> </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>×</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("'", '’').replace(''', '’').replace(/[\u2019]/, '’'); + text = text.replace('"', '”').replace('"', '”').replace('"', '”').replace(/[\u201D]/, '”'); + 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">×</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 |