├── .gitmodules ├── css ├── rotatingtweets-sample.css └── style.css ├── images ├── Twitter_logo_blue_16.png ├── bird_16_black.png ├── bird_16_blue.png ├── bird_16_gray.png ├── bird_black_32_0.png ├── bird_black_48_0.png ├── bird_blue_32.png ├── bird_blue_48.png ├── bird_gray_32.png ├── bird_gray_48.png ├── favorite.png ├── favorite_hover.png ├── favorite_on.png ├── reply.png ├── reply_hover.png ├── retweet.png ├── retweet_hover.png ├── retweet_on.png ├── twitter-bird-16x16.png ├── twitter-bird-dark-bgs.png └── twitter-bird-light-bgs.png ├── js ├── jquery.cycle.all.js ├── jquery.cycle.all.min.js ├── jquery.cycle2.carousel.js ├── jquery.cycle2.carousel.renamed.js ├── jquery.cycle2.renamed.js ├── jquery.cycle2.scrollVert.js ├── jquery.cycle2.scrollVert.renamed.js ├── rotating_tweet.js ├── rotating_tweet.min.js ├── rotating_tweet_admin.js ├── rotatingtweets_v2.js └── rotatingtweets_v2_cyclone.js ├── languages ├── rotatingtweets-de_DE.mo ├── rotatingtweets-fr_FR.mo ├── rotatingtweets-it_IT.mo ├── rotatingtweets-nl_NL.mo ├── rotatingtweets-pt_BR.mo └── rotatingtweets-sr_RS.mo ├── lib ├── WP_OAuth.php └── wp_twitteroauth.php ├── readme.md ├── rotatingtweets.php ├── screenshot-1.gif ├── screenshot-2.png └── screenshot-3.png /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/loklak_php_api"] 2 | path = lib/loklak_php_api 3 | url = https://github.com/loklak/loklak_php_api 4 | -------------------------------------------------------------------------------- /css/rotatingtweets-sample.css: -------------------------------------------------------------------------------- 1 | /* Rename this file to rotatingtweets.css and upload it to /wp-content/uploads/rotatingtweets.css and it will automatically be included in the rotatingtweets CSS by the plug in */ 2 | /* It shouldn't be overwritten when the plug-in is upgraded! */ 3 | /* This particular CSS makes a bird appear to the left of your tweets - you can find more birds at https://dev.twitter.com/docs/image-resources */ 4 | div.rotatingtweets_format_0 p.rtw_main { 5 | background-image: url('../plugins/rotatingtweets/images/bird_blue_32.png'); 6 | background-repeat:no-repeat; 7 | background-position:0 7px; 8 | padding-left: 38px; 9 | min-height: 36px; 10 | } 11 | div.rotatingtweets_format_0 p.rtw_meta { 12 | padding-left: 38px; 13 | } -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | /* First - sort out the fonts */ 2 | /* 3 | .widget_rotatingtweets_widget { 4 | width: 100%; 5 | } 6 | */ 7 | div.rotatingtweet { 8 | font-size: 100%; 9 | word-wrap: break-word; 10 | vertical-align: top; 11 | } 12 | div.cycle-carousel-wrap div.rotatingtweet { 13 | padding-right: 1em; 14 | } 15 | /* 16 | div.rotatingtweets { 17 | clear:both; 18 | } 19 | */ 20 | p.rtw_meta,div.rtw_meta,div.rtw_meta_wide,div.rtw_name,div.rtw_id,div.rtw_time_short,div.rtw_rt_meta { 21 | font-size: 0.8em; 22 | line-height: normal; 23 | white-space: normal; 24 | } 25 | div.rtw_wide_block div.rtw_name { 26 | font-size: 1.0em; 27 | } 28 | 29 | /* Now the icon sizing */ 30 | div.rtw_icon img { 31 | max-width: 2.2em; 32 | max-height: 2.2em; 33 | } 34 | div.rtw_intents a img,span.rtw_intents a img { 35 | max-width: 1.2em; 36 | max-height: 1.2em; 37 | padding: 0; 38 | margin: 0; 39 | display: inline; 40 | } 41 | div.rtw_wide_icon img { 42 | padding-top: 8%; 43 | padding-left: 0; 44 | margin-left: 0; 45 | } 46 | div.rtw_meta img, 47 | div.rtw_rt_meta img { 48 | vertical-align: middle; 49 | } 50 | /* The main positioning */ 51 | .rtw_twitter_icon, 52 | .rtw_time_short { 53 | float:right; 54 | } 55 | div.rtw_wide_icon, 56 | div.rtw_icon { 57 | float:left; 58 | padding-right: 0.5em; 59 | } 60 | div.rtw_wide_icon { 61 | display: inline; 62 | } 63 | .rtw_wide_block .rtw_name, 64 | .rtw_wide_block .rtw_id { 65 | display: inline; 66 | } 67 | .rtw_wide_block { 68 | padding-left: 58px; 69 | } 70 | div.rtw_intents { 71 | display: inline; 72 | float:right; 73 | margin-left: 0.5em; 74 | } 75 | div.rtw_intents a,span.rtw_intents a { 76 | display: inline; 77 | } 78 | div.rtw_timestamp { 79 | display: inline; 80 | } 81 | .rotatingtweet p.rtw_main { 82 | clear: both; 83 | } 84 | .rtw_wide_block p.rtw_main,div.rtw_main { 85 | clear: none; 86 | } 87 | 88 | .norotatingtweets .rotatingtweet { 89 | border-bottom: 1px solid #DDD; 90 | } 91 | 92 | .rtw_media { 93 | clear: both; 94 | } 95 | .rtw_media img { 96 | margin: auto; 97 | height: 150px; 98 | max-height: 150px; 99 | } 100 | /* Pager CSS */ 101 | .rtw_pager { 102 | text-align: center; 103 | font-size: 2em; 104 | } 105 | .rtw_pager a { 106 | text-decoration: none !important; 107 | } 108 | .rtw_pager .cycle-pager-active, 109 | .rtw_pager .activeSlide { 110 | color: #DDD; 111 | } 112 | /* This sets the style for tweets in articles or posts */ 113 | #content .rotatingtweets, 114 | #content .norotatingtweets { 115 | border-top: 1px solid #DDD; 116 | border-bottom: 1px solid #DDD; 117 | margin-bottom: 3%; 118 | } 119 | 120 | /* Now to get the vertical spacing right */ 121 | #content .rotatingtweet { 122 | padding-top: 0.7em; 123 | padding-bottom: 0.7em; 124 | } 125 | 126 | #content p.rtw_main,p.rtw_main,div.rtw_main { 127 | margin-bottom: 0.6em; 128 | white-space: normal; 129 | } 130 | 131 | #content .rtw_wide p.rtw_main { 132 | margin-bottom: 0.35em; 133 | } 134 | 135 | 136 | p.rtw_meta,div.rtw_meta { 137 | margin-bottom: 1em; 138 | } 139 | #sidebar ul li div.rtw_name,div.rtw_name,div.rtw_name a { 140 | margin-bottom: 0; 141 | padding-bottom: 0; 142 | } 143 | #sidebar ul li div.rtw_id,div.rtw_id ,div.rtw_id a { 144 | margin-top: 0; 145 | padding-top: 0; 146 | } 147 | #sidebar ul li div.rtw_intents { 148 | margin-top: 0; 149 | padding-top: 0; 150 | } 151 | div.rtw_rt_meta { 152 | margin-top: 0.1em; 153 | margin-bottom: 0.1em; 154 | padding: 0; 155 | } 156 | 157 | /* Twitter fonts */ 158 | 159 | /* 160 | .rtw_main { 161 | font-family: Georgia,Palatino,serif; 162 | } 163 | .rtw_meta { 164 | font-family: 'Helvetica Neue', Arial, sans-serif; 165 | } 166 | .rtw_name a 167 | { 168 | color: #333; 169 | } 170 | .rtw_id a 171 | { 172 | color: #999; 173 | } 174 | .rtw_main a 175 | { 176 | color: #444; 177 | } 178 | .rtw_main a, 179 | .rtw_id a:hover 180 | { 181 | text-decoration: none; 182 | } 183 | .rtw_main a:hover, 184 | { 185 | text-decoration: underline; 186 | } 187 | */ -------------------------------------------------------------------------------- /images/Twitter_logo_blue_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/Twitter_logo_blue_16.png -------------------------------------------------------------------------------- /images/bird_16_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/bird_16_black.png -------------------------------------------------------------------------------- /images/bird_16_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/bird_16_blue.png -------------------------------------------------------------------------------- /images/bird_16_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/bird_16_gray.png -------------------------------------------------------------------------------- /images/bird_black_32_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/bird_black_32_0.png -------------------------------------------------------------------------------- /images/bird_black_48_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/bird_black_48_0.png -------------------------------------------------------------------------------- /images/bird_blue_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/bird_blue_32.png -------------------------------------------------------------------------------- /images/bird_blue_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/bird_blue_48.png -------------------------------------------------------------------------------- /images/bird_gray_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/bird_gray_32.png -------------------------------------------------------------------------------- /images/bird_gray_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/bird_gray_48.png -------------------------------------------------------------------------------- /images/favorite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/favorite.png -------------------------------------------------------------------------------- /images/favorite_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/favorite_hover.png -------------------------------------------------------------------------------- /images/favorite_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/favorite_on.png -------------------------------------------------------------------------------- /images/reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/reply.png -------------------------------------------------------------------------------- /images/reply_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/reply_hover.png -------------------------------------------------------------------------------- /images/retweet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/retweet.png -------------------------------------------------------------------------------- /images/retweet_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/retweet_hover.png -------------------------------------------------------------------------------- /images/retweet_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/retweet_on.png -------------------------------------------------------------------------------- /images/twitter-bird-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/twitter-bird-16x16.png -------------------------------------------------------------------------------- /images/twitter-bird-dark-bgs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/twitter-bird-dark-bgs.png -------------------------------------------------------------------------------- /images/twitter-bird-light-bgs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/images/twitter-bird-light-bgs.png -------------------------------------------------------------------------------- /js/jquery.cycle.all.min.js: -------------------------------------------------------------------------------- 1 | (function(f,e){function g(h){f.fn.cycle.debug&&a(h)}function a(){window.console&&console.log&&console.log("[cycle] "+Array.prototype.join.call(arguments," "))}function l(a,b,o){var c=f(a).data("cycle.opts"),e=!!a.cyclePause;e&&c.paused?c.paused(a,c,b,o):!e&&c.resumed&&c.resumed(a,c,b,o)}function j(h,b,c){function j(b,d,h){if(!b&&!0===d){b=f(h).data("cycle.opts");if(!b)return a("options not found, can not resume"),!1;h.cycleTimeout&&(clearTimeout(h.cycleTimeout),h.cycleTimeout=0);r(b.elements,b,1, 2 | !b.backwards)}}h.cycleStop===e&&(h.cycleStop=0);if(b===e||null===b)b={};if(b.constructor==String)switch(b){case "destroy":case "stop":c=f(h).data("cycle.opts");if(!c)return!1;h.cycleStop++;h.cycleTimeout&&clearTimeout(h.cycleTimeout);h.cycleTimeout=0;c.elements&&f(c.elements).stop();f(h).removeData("cycle.opts");if("destroy"==b){b=c;b.next&&f(b.next).unbind(b.prevNextEvent);b.prev&&f(b.prev).unbind(b.prevNextEvent);if(b.pager||b.pagerAnchorBuilder)f.each(b.pagerAnchors||[],function(){this.unbind().remove()}); 3 | b.pagerAnchors=null;f(h).unbind("mouseenter.cycle mouseleave.cycle");b.destroy&&b.destroy(b)}return!1;case "toggle":return h.cyclePause=1===h.cyclePause?0:1,j(h.cyclePause,c,h),l(h),!1;case "pause":return h.cyclePause=1,l(h),!1;case "resume":return h.cyclePause=0,j(!1,c,h),l(h),!1;case "prev":case "next":c=f(h).data("cycle.opts");if(!c)return a('options not found, "prev/next" ignored'),!1;f.fn.cycle[b](c);return!1;default:b={fx:b}}else if(b.constructor==Number){var p=b,b=f(h).data("cycle.opts");if(!b)return a("options not found, can not advance slide"), 4 | !1;if(0>p||p>=b.elements.length)return a("invalid slide index: "+p),!1;b.nextSlide=p;h.cycleTimeout&&(clearTimeout(h.cycleTimeout),h.cycleTimeout=0);"string"==typeof c&&(b.oneTimeFx=c);r(b.elements,b,1,p>=b.currSlide);return!1}return b}function c(a,b){if(!f.support.opacity&&b.cleartype&&a.style.filter)try{a.style.removeAttribute("filter")}catch(c){}}function u(h,b,o,j,p){var i,d=f.extend({},f.fn.cycle.defaults,j||{},f.metadata?h.metadata():f.meta?h.data():{}),k=f.isFunction(h.data)?h.data(d.metaAttr): 5 | null;k&&(d=f.extend(d,k));d.autostop&&(d.countdown=d.autostopCount||o.length);var u=h[0];h.data("cycle.opts",d);d.$cont=h;d.stopCount=u.cycleStop;d.elements=o;d.before=d.before?[d.before]:[];d.after=d.after?[d.after]:[];!f.support.opacity&&d.cleartype&&d.after.push(function(){c(this,d)});d.continuous&&d.after.push(function(){r(o,d,0,!d.backwards)});var s=d;s.original={before:[],after:[]};s.original.cssBefore=f.extend({},s.cssBefore);s.original.cssAfter=f.extend({},s.cssAfter);s.original.animIn=f.extend({}, 6 | s.animIn);s.original.animOut=f.extend({},s.animOut);f.each(s.before,function(){s.original.before.push(this)});f.each(s.after,function(){s.original.after.push(this)});!f.support.opacity&&(d.cleartype&&!d.cleartypeNoBg)&&B(b);"static"==h.css("position")&&h.css("position","relative");d.width&&h.width(d.width);d.height&&"auto"!=d.height&&h.height(d.height);d.startingSlide!==e?(d.startingSlide=parseInt(d.startingSlide,10),d.startingSlide>=o.length||0>d.startSlide?d.startingSlide=0:i=!0):d.startingSlide= 7 | d.backwards?o.length-1:0;if(d.random){d.randomMap=[];for(k=0;k=o.length&&(d.startingSlide=0);d.currSlide=d.startingSlide||0;var t=d.startingSlide;b.css({position:"absolute",top:0,left:0}).hide().each(function(b){b=d.backwards?t?b<=t?o.length+(b-t):t-b:o.length- 8 | b:t?b>=t?o.length-(b-t):t-b:o.length-b;f(this).css("z-index",b)});f(o[t]).css("opacity",1).show();c(o[t],d);d.fit&&(d.aspect?b.each(function(){var b=f(this),a=d.aspect===true?b.width()/b.height():d.aspect;if(d.width&&b.width()!=d.width){b.width(d.width);b.height(d.width/a)}if(d.height&&b.height()i?z: 10 | i;k=A>k?A:k}0=o.length-1?0:d.startingSlide+1;if(!d.multiFx)if(q=f.fn.cycle.transitions[d.fx],f.isFunction(q))q(h,b,d);else if("custom"!=d.fx&&!d.multiFx)return a("unknown transition: "+d.fx,"; slideshow terminating"),!1;h=b[t];d.skipInitializationCallbacks||(d.before.length&&d.before[0].apply(h,[h,h,d,!0]),d.after.length&&d.after[0].apply(h,[h,h,d,!0]));d.next&&f(d.next).bind(d.prevNextEvent,function(){return v(d,1)});d.prev&&f(d.prev).bind(d.prevNextEvent,function(){return v(d, 16 | 0)});if(d.pager||d.pagerAnchorBuilder){var x=d,E=f(x.pager);f.each(o,function(b,a){f.fn.cycle.createPagerAnchor(b,a,E,o,x)});x.updateActivePagerLink(x.pager,x.startingSlide,x.activePagerClass)}var m=d;m.addSlide=function(b,a){var d=f(b),h=d[0];m.autostopCount||m.countdown++;o[a?"unshift":"push"](h);if(m.els)m.els[a?"unshift":"push"](h);m.slideCount=o.length;if(m.random){m.randomMap.push(m.slideCount-1);m.randomMap.sort(function(){return Math.random()-0.5})}d.css("position","absolute");d[a?"prependTo": 17 | "appendTo"](m.$cont);if(a){m.currSlide++;m.nextSlide++}!f.support.opacity&&(m.cleartype&&!m.cleartypeNoBg)&&B(d);m.fit&&m.width&&d.width(m.width);m.fit&&(m.height&&m.height!="auto")&&d.height(m.height);h.cycleH=m.fit&&m.height?m.height:d.height();h.cycleW=m.fit&&m.width?m.width:d.width();d.css(m.cssBefore);(m.pager||m.pagerAnchorBuilder)&&f.fn.cycle.createPagerAnchor(o.length-1,h,f(m.pager),o,m);if(f.isFunction(m.onAddSlide))m.onAddSlide(d);else d.hide()};return d}function r(a,b,c,j){function l(){var d= 18 | 0;b.timeout&&!b.continuous?(d=n(a[b.currSlide],a[b.nextSlide],b,j),"shuffle"==b.fx&&(d-=b.speedOut)):b.continuous&&i.cyclePause&&(d=10);0=--b.countdown||b.nowrap&&!b.random&&b.nextSlide=b.fxs.length))b.lastFx=0;else if(!j&&(b.lastFx===e||0>--b.lastFx))b.lastFx=b.fxs.length-1;s=b.fxs[b.lastFx]}b.oneTimeFx&& 20 | (s=b.oneTimeFx,b.oneTimeFx=null);f.fn.cycle.resetState(b,s);b.before.length&&f.each(b.before,function(a,f){i.cycleStop==b.stopCount&&f.apply(k,[d,k,b,j])});var t=function(){b.busy=0;f.each(b.after,function(a,f){i.cycleStop==b.stopCount&&f.apply(k,[d,k,b,j])});i.cycleStop||l()};g("tx firing("+s+"); currSlide: "+b.currSlide+"; nextSlide: "+b.nextSlide);b.busy=1;if(b.fxFn)b.fxFn(d,k,b,t,j,c&&b.fastOnEvent);else if(f.isFunction(f.fn.cycle[b.fx]))f.fn.cycle[b.fx](d,k,b,t,j,c&&b.fastOnEvent);else f.fn.cycle.custom(d, 21 | k,b,t,j,c&&b.fastOnEvent)}else l();if(u||b.nextSlide==b.currSlide)if(b.lastSlide=b.currSlide,b.random){if(b.currSlide=b.nextSlide,++b.randomIndex==a.length&&(b.randomIndex=0,b.randomMap.sort(function(){return Math.random()-0.5})),b.nextSlide=b.randomMap[b.randomIndex],b.nextSlide==b.currSlide)b.nextSlide=b.currSlide==b.slideCount-1?0:b.currSlide+1}else b.backwards?(c=0>b.nextSlide-1)&&b.bounce?(b.backwards=!b.backwards,b.nextSlide=1,b.currSlide=0):(b.nextSlide=c?a.length-1:b.nextSlide-1,b.currSlide= 22 | c?0:b.nextSlide+1):(c=b.nextSlide+1==a.length)&&b.bounce?(b.backwards=!b.backwards,b.nextSlide=a.length-2,b.currSlide=a.length-1):(b.nextSlide=c?0:b.nextSlide+1,b.currSlide=c?a.length-1:b.nextSlide-1);u&&b.pager&&b.updateActivePagerLink(b.pager,b.currSlide,b.activePagerClass)}}function n(a,b,f,c){if(f.timeoutFn){for(a=f.timeoutFn.call(a,a,b,f,c);"none"!=f.fx&&250>a-f.speed;)a+=f.speed;g("calculated timeout: "+a+"; speed: "+f.speed);if(!1!==a)return a}return f.timeout}function v(a,b){var c=b?1:-1, 23 | j=a.elements,e=a.$cont[0],l=e.cycleTimeout;l&&(clearTimeout(l),e.cycleTimeout=0);if(a.random&&0>c)a.randomIndex--,-2==--a.randomIndex?a.randomIndex=j.length-2:-1==a.randomIndex&&(a.randomIndex=j.length-1),a.nextSlide=a.randomMap[a.randomIndex];else if(a.random)a.nextSlide=a.randomMap[a.randomIndex];else if(a.nextSlide=a.currSlide+c,0>a.nextSlide){if(a.nowrap)return!1;a.nextSlide=j.length-1}else if(a.nextSlide>=j.length){if(a.nowrap)return!1;a.nextSlide=0}e=a.onPrevNextEvent||a.prevNextClick;f.isFunction(e)&& 24 | e(0a.length?"0"+a:a}function c(a){for(;a&&"html"!=a.nodeName.toLowerCase();a=a.parentNode){var h=f.css(a,"background-color");if(h&&0<=h.indexOf("rgb"))return a=h.match(/\d+/g),"#"+b(a[0])+b(a[1])+b(a[2]);if(h&&"transparent"!=h)return h}return"#ffffff"}g("applying clearType background-color hack");a.each(function(){f(this).css("background-color",c(this))})}f.support===e&&(f.support= 25 | {opacity:!f.browser.msie});f.expr[":"].paused=function(a){return a.cyclePause};f.fn.cycle=function(c,b){var e={s:this.selector,c:this.context};if(this.length===0&&c!="stop"){if(!f.isReady&&e.s){a("DOM not ready, queuing slideshow");f(function(){f(e.s,e.c).cycle(c,b)});return this}a("terminating; zero elements found by selector"+(f.isReady?"":" (DOM not ready)"));return this}return this.each(function(){var l=j(this,c,b);if(l!==false){l.updateActivePagerLink=l.updateActivePagerLink||f.fn.cycle.updateActivePagerLink; 26 | this.cycleTimeout&&clearTimeout(this.cycleTimeout);this.cycleStop=this.cycleTimeout=this.cyclePause=0;var p=f(this),i=l.slideExpr?f(l.slideExpr,this):p.children(),d=i.get();if(d.length<2)a("terminating; too few slides: "+d.length);else{var k=u(p,i,d,l,e);if(k!==false)if(p=k.continuous?10:n(d[k.currSlide],d[k.nextSlide],k,!k.backwards)){p=p+(k.delay||0);p<10&&(p=10);g("first timeout: "+p);this.cycleTimeout=setTimeout(function(){r(d,k,0,!l.backwards)},p)}}}})};f.fn.cycle.resetState=function(a,b){b= 27 | b||a.fx;a.before=[];a.after=[];a.cssBefore=f.extend({},a.original.cssBefore);a.cssAfter=f.extend({},a.original.cssAfter);a.animIn=f.extend({},a.original.animIn);a.animOut=f.extend({},a.original.animOut);a.fxFn=null;f.each(a.original.before,function(){a.before.push(this)});f.each(a.original.after,function(){a.after.push(this)});var c=f.fn.cycle.transitions[b];f.isFunction(c)&&c(a.$cont,f(a.elements),a)};f.fn.cycle.updateActivePagerLink=function(a,b,c){f(a).each(function(){f(this).children().removeClass(c).eq(b).addClass(c)})}; 28 | f.fn.cycle.next=function(a){v(a,1)};f.fn.cycle.prev=function(a){v(a,0)};f.fn.cycle.createPagerAnchor=function(a,b,c,j,e){if(f.isFunction(e.pagerAnchorBuilder)){b=e.pagerAnchorBuilder(a,b);g("pagerAnchorBuilder("+a+", el) returned: "+b)}else b=''+(a+1)+"";if(b){var i=f(b);if(i.parents("body").length===0){var d=[];if(c.length>1){c.each(function(){var a=i.clone(true);f(this).append(a);d.push(a[0])});i=f(d)}else i.appendTo(c)}e.pagerAnchors=e.pagerAnchors||[];e.pagerAnchors.push(i);c= 29 | function(b){b.preventDefault();e.nextSlide=a;var b=e.$cont[0],d=b.cycleTimeout;if(d){clearTimeout(d);b.cycleTimeout=0}b=e.onPagerEvent||e.pagerClick;f.isFunction(b)&&b(e.nextSlide,j[e.nextSlide]);r(j,e,1,e.currSlidef?c-f:a.slideCount-f:c0)c.cssBefore.width=b.cycleW;if(c.slideResize&&j!==false&&b.cycleH>0)c.cssBefore.height=b.cycleH;c.cssAfter=c.cssAfter|| 31 | {};c.cssAfter.display="none";f(a).css("zIndex",c.slideCount+(l===true?1:0));f(b).css("zIndex",c.slideCount+(l===true?0:1))};f.fn.cycle.custom=function(a,b,c,e,j,l){var d=f(a),k=f(b),g=c.speedIn,a=c.speedOut,n=c.easeIn,b=c.easeOut;k.css(c.cssBefore);if(l){g=typeof l=="number"?a=l:a=1;n=b=null}var u=function(){k.animate(c.animIn,g,n,function(){e()})};d.animate(c.animOut,a,b,function(){d.css(c.cssAfter);c.sync||u()});c.sync&&u()};f.fn.cycle.transitions={fade:function(a,b,c){b.not(":eq("+c.currSlide+ 32 | ")").css("opacity",0);c.before.push(function(a,b,c){f.fn.cycle.commonReset(a,b,c);c.cssBefore.opacity=0});c.animIn={opacity:1};c.animOut={opacity:0};c.cssBefore={top:0,left:0}}};f.fn.cycle.ver=function(){return"2.9999.5"};f.fn.cycle.defaults={activePagerClass:"activeSlide",after:null,allowPagerClickBubble:!1,animIn:null,animOut:null,aspect:!1,autostop:0,autostopCount:0,backwards:!1,before:null,center:null,cleartype:!f.support.opacity,cleartypeNoBg:!1,containerResize:1,continuous:0,cssAfter:null,cssBefore:null, 33 | delay:0,easeIn:null,easeOut:null,easing:null,end:null,fastOnEvent:0,fit:0,fx:"fade",fxFn:null,height:"auto",manualTrump:!0,metaAttr:"cycle",next:null,nowrap:0,onPagerEvent:null,onPrevNextEvent:null,pager:null,pagerAnchorBuilder:null,pagerEvent:"click.cycle",pause:0,pauseOnPagerHover:0,prev:null,prevNextEvent:"click.cycle",random:0,randomizeEffects:1,requeueOnImageNotLoaded:!0,requeueTimeout:250,rev:0,shuffle:null,skipInitializationCallbacks:!1,slideExpr:null,slideResize:1,speed:1E3,speedIn:null,speedOut:null, 34 | startingSlide:e,sync:1,timeout:4E3,timeoutFn:null,updateActivePagerLink:null,width:null}})(jQuery); 35 | (function(f){f.fn.cycle.transitions.none=function(e,g,a){a.fxFn=function(a,e,c,g){f(e).show();f(a).hide();g()}};f.fn.cycle.transitions.fadeout=function(e,g,a){g.not(":eq("+a.currSlide+")").css({display:"block",opacity:1});a.before.push(function(a,e,c,g,r,n){f(a).css("zIndex",c.slideCount+(!0!==n?1:0));f(e).css("zIndex",c.slideCount+(!0!==n?0:1))});a.animIn.opacity=1;a.animOut.opacity=0;a.cssBefore.opacity=1;a.cssBefore.display="block";a.cssAfter.zIndex=0};f.fn.cycle.transitions.scrollUp=function(e, 36 | g,a){e.css("overflow","hidden");a.before.push(f.fn.cycle.commonReset);e=e.height();a.cssBefore.top=e;a.cssBefore.left=0;a.cssFirst.top=0;a.animIn.top=0;a.animOut.top=-e};f.fn.cycle.transitions.scrollDown=function(e,g,a){e.css("overflow","hidden");a.before.push(f.fn.cycle.commonReset);e=e.height();a.cssFirst.top=0;a.cssBefore.top=-e;a.cssBefore.left=0;a.animIn.top=0;a.animOut.top=e};f.fn.cycle.transitions.scrollLeft=function(e,g,a){e.css("overflow","hidden");a.before.push(f.fn.cycle.commonReset);e= 37 | e.width();a.cssFirst.left=0;a.cssBefore.left=e;a.cssBefore.top=0;a.animIn.left=0;a.animOut.left=0-e};f.fn.cycle.transitions.scrollRight=function(e,g,a){e.css("overflow","hidden");a.before.push(f.fn.cycle.commonReset);e=e.width();a.cssFirst.left=0;a.cssBefore.left=-e;a.cssBefore.top=0;a.animIn.left=0;a.animOut.left=e};f.fn.cycle.transitions.scrollHorz=function(e,g,a){e.css("overflow","hidden").width();a.before.push(function(a,e,c,g){c.rev&&(g=!g);f.fn.cycle.commonReset(a,e,c);c.cssBefore.left=g?e.cycleW- 38 | 1:1-e.cycleW;c.animOut.left=g?-a.cycleW:a.cycleW});a.cssFirst.left=0;a.cssBefore.top=0;a.animIn.left=0;a.animOut.top=0};f.fn.cycle.transitions.scrollVert=function(e,g,a){e.css("overflow","hidden");a.before.push(function(a,e,c,g){c.rev&&(g=!g);f.fn.cycle.commonReset(a,e,c);c.cssBefore.top=g?1-e.cycleH:e.cycleH-1;c.animOut.top=g?a.cycleH:-a.cycleH});a.cssFirst.top=0;a.cssBefore.left=0;a.animIn.top=0;a.animOut.left=0};f.fn.cycle.transitions.slideX=function(e,g,a){a.before.push(function(a,e,c){f(c.elements).not(a).hide(); 39 | f.fn.cycle.commonReset(a,e,c,!1,!0);c.animIn.width=e.cycleW});a.cssBefore.left=0;a.cssBefore.top=0;a.cssBefore.width=0;a.animIn.width="show";a.animOut.width=0};f.fn.cycle.transitions.slideY=function(e,g,a){a.before.push(function(a,e,c){f(c.elements).not(a).hide();f.fn.cycle.commonReset(a,e,c,!0,!1);c.animIn.height=e.cycleH});a.cssBefore.left=0;a.cssBefore.top=0;a.cssBefore.height=0;a.animIn.height="show";a.animOut.height=0};f.fn.cycle.transitions.shuffle=function(e,g,a){e=e.css("overflow","visible").width(); 40 | g.css({left:0,top:0});a.before.push(function(a,e,c){f.fn.cycle.commonReset(a,e,c,!0,!0,!0)});a.speedAdjusted||(a.speed/=2,a.speedAdjusted=!0);a.random=0;a.shuffle=a.shuffle||{left:-e,top:15};a.els=[];for(e=0;e opts.slideCount - opts.carouselVisible ) 19 | return; 20 | opts.API.advanceSlide( count ); 21 | opts.API.trigger('cycle-next', [ opts ]).log('cycle-next'); 22 | }; 23 | 24 | }); 25 | 26 | 27 | $.fn.cycle.transitions.carousel = { 28 | // transition API impl 29 | preInit: function( opts ) { 30 | opts.hideNonActive = false; 31 | 32 | opts.container.on('cycle-destroyed', $.proxy(this.onDestroy, opts.API)); 33 | // override default API implementation 34 | opts.API.stopTransition = this.stopTransition; 35 | 36 | // issue #10 37 | for (var i=0; i < opts.startingSlide; i++) { 38 | opts.container.append( opts.slides[0] ); 39 | } 40 | }, 41 | 42 | // transition API impl 43 | postInit: function( opts ) { 44 | var i, j, slide, pagerCutoffIndex, wrap; 45 | var vert = opts.carouselVertical; 46 | if (opts.carouselVisible && opts.carouselVisible > opts.slideCount) 47 | opts.carouselVisible = opts.slideCount - 1; 48 | var visCount = opts.carouselVisible || opts.slides.length; 49 | var slideCSS = { display: vert ? 'block' : 'inline-block', position: 'static' }; 50 | 51 | // required styles 52 | opts.container.css({ position: 'relative', overflow: 'hidden' }); 53 | opts.slides.css( slideCSS ); 54 | 55 | opts._currSlide = opts.currSlide; 56 | 57 | // wrap slides in a div; this div is what is animated 58 | wrap = $('') 59 | .prependTo( opts.container ) 60 | .css({ margin: 0, padding: 0, top: 0, left: 0, position: 'absolute' }) 61 | .append( opts.slides ); 62 | 63 | opts._carouselWrap = wrap; 64 | 65 | if ( !vert ) 66 | wrap.css('white-space', 'nowrap'); 67 | 68 | if ( opts.allowWrap !== false ) { 69 | // prepend and append extra slides so we don't see any empty space when we 70 | // near the end of the carousel. for fluid containers, add even more clones 71 | // so there is plenty to fill the screen 72 | // @todo: optimzie this based on slide sizes 73 | 74 | for ( j=0; j < (opts.carouselVisible === undefined ? 2 : 1); j++ ) { 75 | for ( i=0; i < opts.slideCount; i++ ) { 76 | wrap.append( opts.slides[i].cloneNode(true) ); 77 | } 78 | i = opts.slideCount; 79 | while ( i-- ) { // #160, #209 80 | wrap.prepend( opts.slides[i].cloneNode(true) ); 81 | } 82 | } 83 | 84 | wrap.find('.cycle-slide-active').removeClass('cycle-slide-active'); 85 | opts.slides.eq(opts.startingSlide).addClass('cycle-slide-active'); 86 | } 87 | 88 | if ( opts.pager && opts.allowWrap === false ) { 89 | // hide "extra" pagers 90 | pagerCutoffIndex = opts.slideCount - visCount; 91 | $( opts.pager ).children().filter( ':gt('+pagerCutoffIndex+')' ).hide(); 92 | } 93 | 94 | opts._nextBoundry = opts.slideCount - opts.carouselVisible; 95 | 96 | this.prepareDimensions( opts ); 97 | }, 98 | 99 | prepareDimensions: function( opts ) { 100 | var dim, offset, pagerCutoffIndex, tmp; 101 | var vert = opts.carouselVertical; 102 | var visCount = opts.carouselVisible || opts.slides.length; 103 | 104 | if ( opts.carouselFluid && opts.carouselVisible ) { 105 | if ( ! opts._carouselResizeThrottle ) { 106 | // fluid container AND fluid slides; slides need to be resized to fit container 107 | this.fluidSlides( opts ); 108 | } 109 | } 110 | else if ( opts.carouselVisible && opts.carouselSlideDimension ) { 111 | dim = visCount * opts.carouselSlideDimension; 112 | opts.container[ vert ? 'height' : 'width' ]( dim ); 113 | } 114 | else if ( opts.carouselVisible ) { 115 | dim = visCount * $(opts.slides[0])[vert ? 'outerHeight' : 'outerWidth'](true); 116 | opts.container[ vert ? 'height' : 'width' ]( dim ); 117 | } 118 | // else { 119 | // // fluid; don't size the container 120 | // } 121 | 122 | offset = ( opts.carouselOffset || 0 ); 123 | if ( opts.allowWrap !== false ) { 124 | if ( opts.carouselSlideDimension ) { 125 | offset -= ( (opts.slideCount + opts.currSlide) * opts.carouselSlideDimension ); 126 | } 127 | else { 128 | // calculate offset based on actual slide dimensions 129 | tmp = opts._carouselWrap.children(); 130 | for (var j=0; j < (opts.slideCount + opts.currSlide); j++) { 131 | offset -= $(tmp[j])[vert?'outerHeight':'outerWidth'](true); 132 | } 133 | } 134 | } 135 | 136 | opts._carouselWrap.css( vert ? 'top' : 'left', offset ); 137 | }, 138 | 139 | fluidSlides: function( opts ) { 140 | var timeout; 141 | var slide = opts.slides.eq(0); 142 | var adjustment = slide.outerWidth() - slide.width(); 143 | var prepareDimensions = this.prepareDimensions; 144 | 145 | // throttle resize event 146 | $(window).on( 'resize', resizeThrottle); 147 | 148 | opts._carouselResizeThrottle = resizeThrottle; 149 | onResize(); 150 | 151 | function resizeThrottle() { 152 | clearTimeout( timeout ); 153 | timeout = setTimeout( onResize, 20 ); 154 | } 155 | 156 | function onResize() { 157 | opts._carouselWrap.stop( false, true ); 158 | var slideWidth = opts.container.width() / opts.carouselVisible; 159 | slideWidth = Math.ceil( slideWidth - adjustment ); 160 | opts._carouselWrap.children().width( slideWidth ); 161 | if ( opts._sentinel ) 162 | opts._sentinel.width( slideWidth ); 163 | prepareDimensions( opts ); 164 | } 165 | }, 166 | 167 | // transition API impl 168 | transition: function( opts, curr, next, fwd, callback ) { 169 | var moveBy, props = {}; 170 | var hops = opts.nextSlide - opts.currSlide; 171 | var vert = opts.carouselVertical; 172 | var speed = opts.speed; 173 | 174 | // handle all the edge cases for wrapping & non-wrapping 175 | if ( opts.allowWrap === false ) { 176 | fwd = hops > 0; 177 | var currSlide = opts._currSlide; 178 | var maxCurr = opts.slideCount - opts.carouselVisible; 179 | if ( hops > 0 && opts.nextSlide > maxCurr && currSlide == maxCurr ) { 180 | hops = 0; 181 | } 182 | else if ( hops > 0 && opts.nextSlide > maxCurr ) { 183 | hops = opts.nextSlide - currSlide - (opts.nextSlide - maxCurr); 184 | } 185 | else if ( hops < 0 && opts.currSlide > maxCurr && opts.nextSlide > maxCurr ) { 186 | hops = 0; 187 | } 188 | else if ( hops < 0 && opts.currSlide > maxCurr ) { 189 | hops += opts.currSlide - maxCurr; 190 | } 191 | else 192 | currSlide = opts.currSlide; 193 | 194 | moveBy = this.getScroll( opts, vert, currSlide, hops ); 195 | opts.API.opts()._currSlide = opts.nextSlide > maxCurr ? maxCurr : opts.nextSlide; 196 | } 197 | else { 198 | if ( fwd && opts.nextSlide === 0 ) { 199 | // moving from last slide to first 200 | moveBy = this.getDim( opts, opts.currSlide, vert ); 201 | callback = this.genCallback( opts, fwd, vert, callback ); 202 | } 203 | else if ( !fwd && opts.nextSlide == opts.slideCount - 1 ) { 204 | // moving from first slide to last 205 | moveBy = this.getDim( opts, opts.currSlide, vert ); 206 | callback = this.genCallback( opts, fwd, vert, callback ); 207 | } 208 | else { 209 | moveBy = this.getScroll( opts, vert, opts.currSlide, hops ); 210 | } 211 | } 212 | 213 | props[ vert ? 'top' : 'left' ] = fwd ? ( "-=" + moveBy ) : ( "+=" + moveBy ); 214 | 215 | // throttleSpeed means to scroll slides at a constant rate, rather than 216 | // a constant speed 217 | if ( opts.throttleSpeed ) 218 | speed = (moveBy / $(opts.slides[0])[vert ? 'height' : 'width']() ) * opts.speed; 219 | 220 | opts._carouselWrap.animate( props, speed, opts.easing, callback ); 221 | }, 222 | 223 | getDim: function( opts, index, vert ) { 224 | var slide = $( opts.slides[index] ); 225 | return slide[ vert ? 'outerHeight' : 'outerWidth'](true); 226 | }, 227 | 228 | getScroll: function( opts, vert, currSlide, hops ) { 229 | var i, moveBy = 0; 230 | 231 | if (hops > 0) { 232 | for (i=currSlide; i < currSlide+hops; i++) 233 | moveBy += this.getDim( opts, i, vert); 234 | } 235 | else { 236 | for (i=currSlide; i > currSlide+hops; i--) 237 | moveBy += this.getDim( opts, i, vert); 238 | } 239 | return moveBy; 240 | }, 241 | 242 | genCallback: function( opts, fwd, vert, callback ) { 243 | // returns callback fn that resets the left/top wrap position to the "real" slides 244 | return function() { 245 | var pos = $(opts.slides[opts.nextSlide]).position(); 246 | var offset = 0 - pos[vert?'top':'left'] + (opts.carouselOffset || 0); 247 | opts._carouselWrap.css( opts.carouselVertical ? 'top' : 'left', offset ); 248 | callback(); 249 | }; 250 | }, 251 | 252 | // core API override 253 | stopTransition: function() { 254 | var opts = this.opts(); 255 | opts.slides.stop( false, true ); 256 | opts._carouselWrap.stop( false, true ); 257 | }, 258 | 259 | // core API supplement 260 | onDestroy: function( e ) { 261 | var opts = this.opts(); 262 | if ( opts._carouselResizeThrottle ) 263 | $( window ).off( 'resize', opts._carouselResizeThrottle ); 264 | opts.slides.prependTo( opts.container ); 265 | opts._carouselWrap.remove(); 266 | } 267 | }; 268 | 269 | })(jQuery); 270 | -------------------------------------------------------------------------------- /js/jquery.cycle2.carousel.renamed.js: -------------------------------------------------------------------------------- 1 | /*! carousel transition plugin for Cycle2; version: 20130528 */ 2 | (function($) { 3 | "use strict"; 4 | 5 | $( document ).on('cycle-bootstrap', function( e, opts, API ) { 6 | if ( opts.fx !== 'carousel' ) 7 | return; 8 | 9 | API.getSlideIndex = function( el ) { 10 | var slides = this.opts()._carouselWrap.children(); 11 | var i = slides.index( el ); 12 | return i % slides.length; 13 | }; 14 | 15 | // override default 'next' function 16 | API.next = function() { 17 | var count = opts.reverse ? -1 : 1; 18 | if ( opts.allowWrap === false && ( opts.currSlide + count ) > opts.slideCount - opts.carouselVisible ) 19 | return; 20 | opts.API.advanceSlide( count ); 21 | opts.API.trigger('cycle-next', [ opts ]).log('cycle-next'); 22 | }; 23 | 24 | }); 25 | 26 | 27 | $.fn.cycle2.transitions.carousel = { 28 | // transition API impl 29 | preInit: function( opts ) { 30 | opts.hideNonActive = false; 31 | 32 | opts.container.on('cycle-destroyed', $.proxy(this.onDestroy, opts.API)); 33 | // override default API implementation 34 | opts.API.stopTransition = this.stopTransition; 35 | 36 | // issue #10 37 | for (var i=0; i < opts.startingSlide; i++) { 38 | opts.container.append( opts.slides[0] ); 39 | } 40 | }, 41 | 42 | // transition API impl 43 | postInit: function( opts ) { 44 | var i, j, slide, pagerCutoffIndex, wrap; 45 | var vert = opts.carouselVertical; 46 | if (opts.carouselVisible && opts.carouselVisible > opts.slideCount) 47 | opts.carouselVisible = opts.slideCount - 1; 48 | var visCount = opts.carouselVisible || opts.slides.length; 49 | var slideCSS = { display: vert ? 'block' : 'inline-block', position: 'static' }; 50 | 51 | // required styles 52 | opts.container.css({ position: 'relative', overflow: 'hidden' }); 53 | opts.slides.css( slideCSS ); 54 | 55 | opts._currSlide = opts.currSlide; 56 | 57 | // wrap slides in a div; this div is what is animated 58 | wrap = $('') 59 | .prependTo( opts.container ) 60 | .css({ margin: 0, padding: 0, top: 0, left: 0, position: 'absolute' }) 61 | .append( opts.slides ); 62 | 63 | opts._carouselWrap = wrap; 64 | 65 | if ( !vert ) 66 | wrap.css('white-space', 'nowrap'); 67 | 68 | if ( opts.allowWrap !== false ) { 69 | // prepend and append extra slides so we don't see any empty space when we 70 | // near the end of the carousel. for fluid containers, add even more clones 71 | // so there is plenty to fill the screen 72 | // @todo: optimzie this based on slide sizes 73 | 74 | for ( j=0; j < (opts.carouselVisible === undefined ? 2 : 1); j++ ) { 75 | for ( i=0; i < opts.slideCount; i++ ) { 76 | wrap.append( opts.slides[i].cloneNode(true) ); 77 | } 78 | i = opts.slideCount; 79 | while ( i-- ) { // #160, #209 80 | wrap.prepend( opts.slides[i].cloneNode(true) ); 81 | } 82 | } 83 | 84 | wrap.find('.cycle2-slide-active').removeClass('cycle-slide-active'); 85 | opts.slides.eq(opts.startingSlide).addClass('cycle-slide-active'); 86 | } 87 | 88 | if ( opts.pager && opts.allowWrap === false ) { 89 | // hide "extra" pagers 90 | pagerCutoffIndex = opts.slideCount - visCount; 91 | $( opts.pager ).children().filter( ':gt('+pagerCutoffIndex+')' ).hide(); 92 | } 93 | 94 | opts._nextBoundry = opts.slideCount - opts.carouselVisible; 95 | 96 | this.prepareDimensions( opts ); 97 | }, 98 | 99 | prepareDimensions: function( opts ) { 100 | var dim, offset, pagerCutoffIndex, tmp; 101 | var vert = opts.carouselVertical; 102 | var visCount = opts.carouselVisible || opts.slides.length; 103 | 104 | if ( opts.carouselFluid && opts.carouselVisible ) { 105 | if ( ! opts._carouselResizeThrottle ) { 106 | // fluid container AND fluid slides; slides need to be resized to fit container 107 | this.fluidSlides( opts ); 108 | } 109 | } 110 | else if ( opts.carouselVisible && opts.carouselSlideDimension ) { 111 | dim = visCount * opts.carouselSlideDimension; 112 | opts.container[ vert ? 'height' : 'width' ]( dim ); 113 | } 114 | else if ( opts.carouselVisible ) { 115 | dim = visCount * $(opts.slides[0])[vert ? 'outerHeight' : 'outerWidth'](true); 116 | opts.container[ vert ? 'height' : 'width' ]( dim ); 117 | } 118 | // else { 119 | // // fluid; don't size the container 120 | // } 121 | 122 | offset = ( opts.carouselOffset || 0 ); 123 | if ( opts.allowWrap !== false ) { 124 | if ( opts.carouselSlideDimension ) { 125 | offset -= ( (opts.slideCount + opts.currSlide) * opts.carouselSlideDimension ); 126 | } 127 | else { 128 | // calculate offset based on actual slide dimensions 129 | tmp = opts._carouselWrap.children(); 130 | for (var j=0; j < (opts.slideCount + opts.currSlide); j++) { 131 | offset -= $(tmp[j])[vert?'outerHeight':'outerWidth'](true); 132 | } 133 | } 134 | } 135 | 136 | opts._carouselWrap.css( vert ? 'top' : 'left', offset ); 137 | }, 138 | 139 | fluidSlides: function( opts ) { 140 | var timeout; 141 | var slide = opts.slides.eq(0); 142 | var adjustment = slide.outerWidth() - slide.width(); 143 | var prepareDimensions = this.prepareDimensions; 144 | 145 | // throttle resize event 146 | $(window).on( 'resize', resizeThrottle); 147 | 148 | opts._carouselResizeThrottle = resizeThrottle; 149 | onResize(); 150 | 151 | function resizeThrottle() { 152 | clearTimeout( timeout ); 153 | timeout = setTimeout( onResize, 20 ); 154 | } 155 | 156 | function onResize() { 157 | opts._carouselWrap.stop( false, true ); 158 | var slideWidth = opts.container.width() / opts.carouselVisible; 159 | slideWidth = Math.ceil( slideWidth - adjustment ); 160 | opts._carouselWrap.children().width( slideWidth ); 161 | if ( opts._sentinel ) 162 | opts._sentinel.width( slideWidth ); 163 | prepareDimensions( opts ); 164 | } 165 | }, 166 | 167 | // transition API impl 168 | transition: function( opts, curr, next, fwd, callback ) { 169 | var moveBy, props = {}; 170 | var hops = opts.nextSlide - opts.currSlide; 171 | var vert = opts.carouselVertical; 172 | var speed = opts.speed; 173 | 174 | // handle all the edge cases for wrapping & non-wrapping 175 | if ( opts.allowWrap === false ) { 176 | fwd = hops > 0; 177 | var currSlide = opts._currSlide; 178 | var maxCurr = opts.slideCount - opts.carouselVisible; 179 | if ( hops > 0 && opts.nextSlide > maxCurr && currSlide == maxCurr ) { 180 | hops = 0; 181 | } 182 | else if ( hops > 0 && opts.nextSlide > maxCurr ) { 183 | hops = opts.nextSlide - currSlide - (opts.nextSlide - maxCurr); 184 | } 185 | else if ( hops < 0 && opts.currSlide > maxCurr && opts.nextSlide > maxCurr ) { 186 | hops = 0; 187 | } 188 | else if ( hops < 0 && opts.currSlide > maxCurr ) { 189 | hops += opts.currSlide - maxCurr; 190 | } 191 | else 192 | currSlide = opts.currSlide; 193 | 194 | moveBy = this.getScroll( opts, vert, currSlide, hops ); 195 | opts.API.opts()._currSlide = opts.nextSlide > maxCurr ? maxCurr : opts.nextSlide; 196 | } 197 | else { 198 | if ( fwd && opts.nextSlide === 0 ) { 199 | // moving from last slide to first 200 | moveBy = this.getDim( opts, opts.currSlide, vert ); 201 | callback = this.genCallback( opts, fwd, vert, callback ); 202 | } 203 | else if ( !fwd && opts.nextSlide == opts.slideCount - 1 ) { 204 | // moving from first slide to last 205 | moveBy = this.getDim( opts, opts.currSlide, vert ); 206 | callback = this.genCallback( opts, fwd, vert, callback ); 207 | } 208 | else { 209 | moveBy = this.getScroll( opts, vert, opts.currSlide, hops ); 210 | } 211 | } 212 | 213 | props[ vert ? 'top' : 'left' ] = fwd ? ( "-=" + moveBy ) : ( "+=" + moveBy ); 214 | 215 | // throttleSpeed means to scroll slides at a constant rate, rather than 216 | // a constant speed 217 | if ( opts.throttleSpeed ) 218 | speed = (moveBy / $(opts.slides[0])[vert ? 'height' : 'width']() ) * opts.speed; 219 | 220 | opts._carouselWrap.animate( props, speed, opts.easing, callback ); 221 | }, 222 | 223 | getDim: function( opts, index, vert ) { 224 | var slide = $( opts.slides[index] ); 225 | return slide[ vert ? 'outerHeight' : 'outerWidth'](true); 226 | }, 227 | 228 | getScroll: function( opts, vert, currSlide, hops ) { 229 | var i, moveBy = 0; 230 | 231 | if (hops > 0) { 232 | for (i=currSlide; i < currSlide+hops; i++) 233 | moveBy += this.getDim( opts, i, vert); 234 | } 235 | else { 236 | for (i=currSlide; i > currSlide+hops; i--) 237 | moveBy += this.getDim( opts, i, vert); 238 | } 239 | return moveBy; 240 | }, 241 | 242 | genCallback: function( opts, fwd, vert, callback ) { 243 | // returns callback fn that resets the left/top wrap position to the "real" slides 244 | return function() { 245 | var pos = $(opts.slides[opts.nextSlide]).position(); 246 | var offset = 0 - pos[vert?'top':'left'] + (opts.carouselOffset || 0); 247 | opts._carouselWrap.css( opts.carouselVertical ? 'top' : 'left', offset ); 248 | callback(); 249 | }; 250 | }, 251 | 252 | // core API override 253 | stopTransition: function() { 254 | var opts = this.opts(); 255 | opts.slides.stop( false, true ); 256 | opts._carouselWrap.stop( false, true ); 257 | }, 258 | 259 | // core API supplement 260 | onDestroy: function( e ) { 261 | var opts = this.opts(); 262 | if ( opts._carouselResizeThrottle ) 263 | $( window ).off( 'resize', opts._carouselResizeThrottle ); 264 | opts.slides.prependTo( opts.container ); 265 | opts._carouselWrap.remove(); 266 | } 267 | }; 268 | 269 | })(jQuery); 270 | -------------------------------------------------------------------------------- /js/jquery.cycle2.renamed.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cycle2; version: 2.1.6 build: 20141007 3 | * http://jquery.malsup.com/cycle2/ 4 | * Copyright (c) 2014 M. Alsup; Dual licensed: MIT/GPL 5 | */ 6 | 7 | /* Cycle2 core engine */ 8 | ;(function($) { 9 | "use strict"; 10 | 11 | var version = '2.1.6'; 12 | 13 | $.fn.cycle2 = function( options ) { 14 | // fix mistakes with the ready state 15 | var o; 16 | if ( this.length === 0 && !$.isReady ) { 17 | o = { s: this.selector, c: this.context }; 18 | $.fn.cycle2.log('requeuing slideshow (dom not ready)'); 19 | $(function() { 20 | $( o.s, o.c ).cycle2(options); 21 | }); 22 | return this; 23 | } 24 | 25 | return this.each(function() { 26 | var data, opts, shortName, val; 27 | var container = $(this); 28 | var log = $.fn.cycle2.log; 29 | 30 | if ( container.data('cycle.opts') ) 31 | return; // already initialized 32 | 33 | if ( container.data('cycle-log') === false || 34 | ( options && options.log === false ) || 35 | ( opts && opts.log === false) ) { 36 | log = $.noop; 37 | } 38 | 39 | log('--c2 init--'); 40 | data = container.data(); 41 | for (var p in data) { 42 | // allow props to be accessed sans 'cycle' prefix and log the overrides 43 | if (data.hasOwnProperty(p) && /^cycle[A-Z]+/.test(p) ) { 44 | val = data[p]; 45 | shortName = p.match(/^cycle(.*)/)[1].replace(/^[A-Z]/, lowerCase); 46 | log(shortName+':', val, '('+typeof val +')'); 47 | data[shortName] = val; 48 | } 49 | } 50 | 51 | opts = $.extend( {}, $.fn.cycle2.defaults, data, options || {}); 52 | 53 | opts.timeoutId = 0; 54 | opts.paused = opts.paused || false; // #57 55 | opts.container = container; 56 | opts._maxZ = opts.maxZ; 57 | 58 | opts.API = $.extend ( { _container: container }, $.fn.cycle2.API ); 59 | opts.API.log = log; 60 | opts.API.trigger = function( eventName, args ) { 61 | opts.container.trigger( eventName, args ); 62 | return opts.API; 63 | }; 64 | 65 | container.data( 'cycle.opts', opts ); 66 | container.data( 'cycle.API', opts.API ); 67 | 68 | // opportunity for plugins to modify opts and API 69 | opts.API.trigger('cycle-bootstrap', [ opts, opts.API ]); 70 | 71 | opts.API.addInitialSlides(); 72 | opts.API.preInitSlideshow(); 73 | 74 | if ( opts.slides.length ) 75 | opts.API.initSlideshow(); 76 | }); 77 | }; 78 | 79 | $.fn.cycle2.API = { 80 | opts: function() { 81 | return this._container.data( 'cycle.opts' ); 82 | }, 83 | addInitialSlides: function() { 84 | var opts = this.opts(); 85 | var slides = opts.slides; 86 | opts.slideCount = 0; 87 | opts.slides = $(); // empty set 88 | 89 | // add slides that already exist 90 | slides = slides.jquery ? slides : opts.container.find( slides ); 91 | 92 | if ( opts.random ) { 93 | slides.sort(function() {return Math.random() - 0.5;}); 94 | } 95 | 96 | opts.API.add( slides ); 97 | }, 98 | 99 | preInitSlideshow: function() { 100 | var opts = this.opts(); 101 | opts.API.trigger('cycle-pre-initialize', [ opts ]); 102 | var tx = $.fn.cycle2.transitions[opts.fx]; 103 | if (tx && $.isFunction(tx.preInit)) 104 | tx.preInit( opts ); 105 | opts._preInitialized = true; 106 | }, 107 | 108 | postInitSlideshow: function() { 109 | var opts = this.opts(); 110 | opts.API.trigger('cycle-post-initialize', [ opts ]); 111 | var tx = $.fn.cycle2.transitions[opts.fx]; 112 | if (tx && $.isFunction(tx.postInit)) 113 | tx.postInit( opts ); 114 | }, 115 | 116 | initSlideshow: function() { 117 | var opts = this.opts(); 118 | var pauseObj = opts.container; 119 | var slideOpts; 120 | opts.API.calcFirstSlide(); 121 | 122 | if ( opts.container.css('position') == 'static' ) 123 | opts.container.css('position', 'relative'); 124 | 125 | $(opts.slides[opts.currSlide]).css({ 126 | opacity: 1, 127 | display: 'block', 128 | visibility: 'visible' 129 | }); 130 | opts.API.stackSlides( opts.slides[opts.currSlide], opts.slides[opts.nextSlide], !opts.reverse ); 131 | 132 | if ( opts.pauseOnHover ) { 133 | // allow pauseOnHover to specify an element 134 | if ( opts.pauseOnHover !== true ) 135 | pauseObj = $( opts.pauseOnHover ); 136 | 137 | pauseObj.hover( 138 | function(){ opts.API.pause( true ); }, 139 | function(){ opts.API.resume( true ); } 140 | ); 141 | } 142 | 143 | // stage initial transition 144 | if ( opts.timeout ) { 145 | slideOpts = opts.API.getSlideOpts( opts.currSlide ); 146 | opts.API.queueTransition( slideOpts, slideOpts.timeout + opts.delay ); 147 | } 148 | 149 | opts._initialized = true; 150 | opts.API.updateView( true ); 151 | opts.API.trigger('cycle-initialized', [ opts ]); 152 | opts.API.postInitSlideshow(); 153 | }, 154 | 155 | pause: function( hover ) { 156 | var opts = this.opts(), 157 | slideOpts = opts.API.getSlideOpts(), 158 | alreadyPaused = opts.hoverPaused || opts.paused; 159 | 160 | if ( hover ) 161 | opts.hoverPaused = true; 162 | else 163 | opts.paused = true; 164 | 165 | if ( ! alreadyPaused ) { 166 | opts.container.addClass('cycle-paused'); 167 | opts.API.trigger('cycle-paused', [ opts ]).log('cycle-paused'); 168 | 169 | if ( slideOpts.timeout ) { 170 | clearTimeout( opts.timeoutId ); 171 | opts.timeoutId = 0; 172 | 173 | // determine how much time is left for the current slide 174 | opts._remainingTimeout -= ( $.now() - opts._lastQueue ); 175 | if ( opts._remainingTimeout < 0 || isNaN(opts._remainingTimeout) ) 176 | opts._remainingTimeout = undefined; 177 | } 178 | } 179 | }, 180 | 181 | resume: function( hover ) { 182 | var opts = this.opts(), 183 | alreadyResumed = !opts.hoverPaused && !opts.paused, 184 | remaining; 185 | 186 | if ( hover ) 187 | opts.hoverPaused = false; 188 | else 189 | opts.paused = false; 190 | 191 | 192 | if ( ! alreadyResumed ) { 193 | opts.container.removeClass('cycle-paused'); 194 | // #gh-230; if an animation is in progress then don't queue a new transition; it will 195 | // happen naturally 196 | if ( opts.slides.filter(':animated').length === 0 ) 197 | opts.API.queueTransition( opts.API.getSlideOpts(), opts._remainingTimeout ); 198 | opts.API.trigger('cycle-resumed', [ opts, opts._remainingTimeout ] ).log('cycle-resumed'); 199 | } 200 | }, 201 | 202 | add: function( slides, prepend ) { 203 | var opts = this.opts(); 204 | var oldSlideCount = opts.slideCount; 205 | var startSlideshow = false; 206 | var len; 207 | 208 | if ( $.type(slides) == 'string') 209 | slides = $.trim( slides ); 210 | 211 | $( slides ).each(function(i) { 212 | var slideOpts; 213 | var slide = $(this); 214 | 215 | if ( prepend ) 216 | opts.container.prepend( slide ); 217 | else 218 | opts.container.append( slide ); 219 | 220 | opts.slideCount++; 221 | slideOpts = opts.API.buildSlideOpts( slide ); 222 | 223 | if ( prepend ) 224 | opts.slides = $( slide ).add( opts.slides ); 225 | else 226 | opts.slides = opts.slides.add( slide ); 227 | 228 | opts.API.initSlide( slideOpts, slide, --opts._maxZ ); 229 | 230 | slide.data('cycle.opts', slideOpts); 231 | opts.API.trigger('cycle-slide-added', [ opts, slideOpts, slide ]); 232 | }); 233 | 234 | opts.API.updateView( true ); 235 | 236 | startSlideshow = opts._preInitialized && (oldSlideCount < 2 && opts.slideCount >= 1); 237 | if ( startSlideshow ) { 238 | if ( !opts._initialized ) 239 | opts.API.initSlideshow(); 240 | else if ( opts.timeout ) { 241 | len = opts.slides.length; 242 | opts.nextSlide = opts.reverse ? len - 1 : 1; 243 | if ( !opts.timeoutId ) { 244 | opts.API.queueTransition( opts ); 245 | } 246 | } 247 | } 248 | }, 249 | 250 | calcFirstSlide: function() { 251 | var opts = this.opts(); 252 | var firstSlideIndex; 253 | firstSlideIndex = parseInt( opts.startingSlide || 0, 10 ); 254 | if (firstSlideIndex >= opts.slides.length || firstSlideIndex < 0) 255 | firstSlideIndex = 0; 256 | 257 | opts.currSlide = firstSlideIndex; 258 | if ( opts.reverse ) { 259 | opts.nextSlide = firstSlideIndex - 1; 260 | if (opts.nextSlide < 0) 261 | opts.nextSlide = opts.slides.length - 1; 262 | } 263 | else { 264 | opts.nextSlide = firstSlideIndex + 1; 265 | if (opts.nextSlide == opts.slides.length) 266 | opts.nextSlide = 0; 267 | } 268 | }, 269 | 270 | calcNextSlide: function() { 271 | var opts = this.opts(); 272 | var roll; 273 | if ( opts.reverse ) { 274 | roll = (opts.nextSlide - 1) < 0; 275 | opts.nextSlide = roll ? opts.slideCount - 1 : opts.nextSlide-1; 276 | opts.currSlide = roll ? 0 : opts.nextSlide+1; 277 | } 278 | else { 279 | roll = (opts.nextSlide + 1) == opts.slides.length; 280 | opts.nextSlide = roll ? 0 : opts.nextSlide+1; 281 | opts.currSlide = roll ? opts.slides.length-1 : opts.nextSlide-1; 282 | } 283 | }, 284 | 285 | calcTx: function( slideOpts, manual ) { 286 | var opts = slideOpts; 287 | var tx; 288 | 289 | if ( opts._tempFx ) 290 | tx = $.fn.cycle2.transitions[opts._tempFx]; 291 | else if ( manual && opts.manualFx ) 292 | tx = $.fn.cycle2.transitions[opts.manualFx]; 293 | 294 | if ( !tx ) 295 | tx = $.fn.cycle2.transitions[opts.fx]; 296 | 297 | opts._tempFx = null; 298 | this.opts()._tempFx = null; 299 | 300 | if (!tx) { 301 | tx = $.fn.cycle2.transitions.fade; 302 | opts.API.log('Transition "' + opts.fx + '" not found. Using fade.'); 303 | } 304 | return tx; 305 | }, 306 | 307 | prepareTx: function( manual, fwd ) { 308 | var opts = this.opts(); 309 | var after, curr, next, slideOpts, tx; 310 | 311 | if ( opts.slideCount < 2 ) { 312 | opts.timeoutId = 0; 313 | return; 314 | } 315 | if ( manual && ( !opts.busy || opts.manualTrump ) ) { 316 | opts.API.stopTransition(); 317 | opts.busy = false; 318 | clearTimeout(opts.timeoutId); 319 | opts.timeoutId = 0; 320 | } 321 | if ( opts.busy ) 322 | return; 323 | if ( opts.timeoutId === 0 && !manual ) 324 | return; 325 | 326 | curr = opts.slides[opts.currSlide]; 327 | next = opts.slides[opts.nextSlide]; 328 | slideOpts = opts.API.getSlideOpts( opts.nextSlide ); 329 | tx = opts.API.calcTx( slideOpts, manual ); 330 | 331 | opts._tx = tx; 332 | 333 | if ( manual && slideOpts.manualSpeed !== undefined ) 334 | slideOpts.speed = slideOpts.manualSpeed; 335 | 336 | // if ( opts.nextSlide === opts.currSlide ) 337 | // opts.API.calcNextSlide(); 338 | 339 | // ensure that: 340 | // 1. advancing to a different slide 341 | // 2. this is either a manual event (prev/next, pager, cmd) or 342 | // a timer event and slideshow is not paused 343 | if ( opts.nextSlide != opts.currSlide && 344 | (manual || (!opts.paused && !opts.hoverPaused && opts.timeout) )) { // #62 345 | 346 | opts.API.trigger('cycle-before', [ slideOpts, curr, next, fwd ]); 347 | if ( tx.before ) 348 | tx.before( slideOpts, curr, next, fwd ); 349 | 350 | after = function() { 351 | opts.busy = false; 352 | // #76; bail if slideshow has been destroyed 353 | if (! opts.container.data( 'cycle.opts' ) ) 354 | return; 355 | 356 | if (tx.after) 357 | tx.after( slideOpts, curr, next, fwd ); 358 | opts.API.trigger('cycle-after', [ slideOpts, curr, next, fwd ]); 359 | opts.API.queueTransition( slideOpts); 360 | opts.API.updateView( true ); 361 | }; 362 | 363 | opts.busy = true; 364 | if (tx.transition) 365 | tx.transition(slideOpts, curr, next, fwd, after); 366 | else 367 | opts.API.doTransition( slideOpts, curr, next, fwd, after); 368 | 369 | opts.API.calcNextSlide(); 370 | opts.API.updateView(); 371 | } else { 372 | opts.API.queueTransition( slideOpts ); 373 | } 374 | }, 375 | 376 | // perform the actual animation 377 | doTransition: function( slideOpts, currEl, nextEl, fwd, callback) { 378 | var opts = slideOpts; 379 | var curr = $(currEl), next = $(nextEl); 380 | var fn = function() { 381 | // make sure animIn has something so that callback doesn't trigger immediately 382 | next.animate(opts.animIn || { opacity: 1}, opts.speed, opts.easeIn || opts.easing, callback); 383 | }; 384 | 385 | next.css(opts.cssBefore || {}); 386 | curr.animate(opts.animOut || {}, opts.speed, opts.easeOut || opts.easing, function() { 387 | curr.css(opts.cssAfter || {}); 388 | if (!opts.sync) { 389 | fn(); 390 | } 391 | }); 392 | if (opts.sync) { 393 | fn(); 394 | } 395 | }, 396 | 397 | queueTransition: function( slideOpts, specificTimeout ) { 398 | var opts = this.opts(); 399 | var timeout = specificTimeout !== undefined ? specificTimeout : slideOpts.timeout; 400 | if (opts.nextSlide === 0 && --opts.loop === 0) { 401 | opts.API.log('terminating; loop=0'); 402 | opts.timeout = 0; 403 | if ( timeout ) { 404 | setTimeout(function() { 405 | opts.API.trigger('cycle-finished', [ opts ]); 406 | }, timeout); 407 | } 408 | else { 409 | opts.API.trigger('cycle-finished', [ opts ]); 410 | } 411 | // reset nextSlide 412 | opts.nextSlide = opts.currSlide; 413 | return; 414 | } 415 | if ( opts.continueAuto !== undefined ) { 416 | if ( opts.continueAuto === false || 417 | ($.isFunction(opts.continueAuto) && opts.continueAuto() === false )) { 418 | opts.API.log('terminating automatic transitions'); 419 | opts.timeout = 0; 420 | if ( opts.timeoutId ) 421 | clearTimeout(opts.timeoutId); 422 | return; 423 | } 424 | } 425 | if ( timeout ) { 426 | opts._lastQueue = $.now(); 427 | if ( specificTimeout === undefined ) 428 | opts._remainingTimeout = slideOpts.timeout; 429 | 430 | if ( !opts.paused && ! opts.hoverPaused ) { 431 | opts.timeoutId = setTimeout(function() { 432 | opts.API.prepareTx( false, !opts.reverse ); 433 | }, timeout ); 434 | } 435 | } 436 | }, 437 | 438 | stopTransition: function() { 439 | var opts = this.opts(); 440 | if ( opts.slides.filter(':animated').length ) { 441 | opts.slides.stop(false, true); 442 | opts.API.trigger('cycle-transition-stopped', [ opts ]); 443 | } 444 | 445 | if ( opts._tx && opts._tx.stopTransition ) 446 | opts._tx.stopTransition( opts ); 447 | }, 448 | 449 | // advance slide forward or back 450 | advanceSlide: function( val ) { 451 | var opts = this.opts(); 452 | clearTimeout(opts.timeoutId); 453 | opts.timeoutId = 0; 454 | opts.nextSlide = opts.currSlide + val; 455 | 456 | if (opts.nextSlide < 0) 457 | opts.nextSlide = opts.slides.length - 1; 458 | else if (opts.nextSlide >= opts.slides.length) 459 | opts.nextSlide = 0; 460 | 461 | opts.API.prepareTx( true, val >= 0 ); 462 | return false; 463 | }, 464 | 465 | buildSlideOpts: function( slide ) { 466 | var opts = this.opts(); 467 | var val, shortName; 468 | var slideOpts = slide.data() || {}; 469 | for (var p in slideOpts) { 470 | // allow props to be accessed sans 'cycle' prefix and log the overrides 471 | if (slideOpts.hasOwnProperty(p) && /^cycle[A-Z]+/.test(p) ) { 472 | val = slideOpts[p]; 473 | shortName = p.match(/^cycle(.*)/)[1].replace(/^[A-Z]/, lowerCase); 474 | opts.API.log('['+(opts.slideCount-1)+']', shortName+':', val, '('+typeof val +')'); 475 | slideOpts[shortName] = val; 476 | } 477 | } 478 | 479 | slideOpts = $.extend( {}, $.fn.cycle2.defaults, opts, slideOpts ); 480 | slideOpts.slideNum = opts.slideCount; 481 | 482 | try { 483 | // these props should always be read from the master state object 484 | delete slideOpts.API; 485 | delete slideOpts.slideCount; 486 | delete slideOpts.currSlide; 487 | delete slideOpts.nextSlide; 488 | delete slideOpts.slides; 489 | } catch(e) { 490 | // no op 491 | } 492 | return slideOpts; 493 | }, 494 | 495 | getSlideOpts: function( index ) { 496 | var opts = this.opts(); 497 | if ( index === undefined ) 498 | index = opts.currSlide; 499 | 500 | var slide = opts.slides[index]; 501 | var slideOpts = $(slide).data('cycle.opts'); 502 | return $.extend( {}, opts, slideOpts ); 503 | }, 504 | 505 | initSlide: function( slideOpts, slide, suggestedZindex ) { 506 | var opts = this.opts(); 507 | slide.css( slideOpts.slideCss || {} ); 508 | if ( suggestedZindex > 0 ) 509 | slide.css( 'zIndex', suggestedZindex ); 510 | 511 | // ensure that speed settings are sane 512 | if ( isNaN( slideOpts.speed ) ) 513 | slideOpts.speed = $.fx.speeds[slideOpts.speed] || $.fx.speeds._default; 514 | if ( !slideOpts.sync ) 515 | slideOpts.speed = slideOpts.speed / 2; 516 | 517 | slide.addClass( opts.slideClass ); 518 | }, 519 | 520 | updateView: function( isAfter, isDuring, forceEvent ) { 521 | var opts = this.opts(); 522 | if ( !opts._initialized ) 523 | return; 524 | var slideOpts = opts.API.getSlideOpts(); 525 | var currSlide = opts.slides[ opts.currSlide ]; 526 | 527 | if ( ! isAfter && isDuring !== true ) { 528 | opts.API.trigger('cycle-update-view-before', [ opts, slideOpts, currSlide ]); 529 | if ( opts.updateView < 0 ) 530 | return; 531 | } 532 | 533 | if ( opts.slideActiveClass ) { 534 | opts.slides.removeClass( opts.slideActiveClass ) 535 | .eq( opts.currSlide ).addClass( opts.slideActiveClass ); 536 | } 537 | 538 | if ( isAfter && opts.hideNonActive ) 539 | opts.slides.filter( ':not(.' + opts.slideActiveClass + ')' ).css('visibility', 'hidden'); 540 | 541 | if ( opts.updateView === 0 ) { 542 | setTimeout(function() { 543 | opts.API.trigger('cycle-update-view', [ opts, slideOpts, currSlide, isAfter ]); 544 | }, slideOpts.speed / (opts.sync ? 2 : 1) ); 545 | } 546 | 547 | if ( opts.updateView !== 0 ) 548 | opts.API.trigger('cycle-update-view', [ opts, slideOpts, currSlide, isAfter ]); 549 | 550 | if ( isAfter ) 551 | opts.API.trigger('cycle-update-view-after', [ opts, slideOpts, currSlide ]); 552 | }, 553 | 554 | getComponent: function( name ) { 555 | var opts = this.opts(); 556 | var selector = opts[name]; 557 | if (typeof selector === 'string') { 558 | // if selector is a child, sibling combinator, adjancent selector then use find, otherwise query full dom 559 | return (/^\s*[\>|\+|~]/).test( selector ) ? opts.container.find( selector ) : $( selector ); 560 | } 561 | if (selector.jquery) 562 | return selector; 563 | 564 | return $(selector); 565 | }, 566 | 567 | stackSlides: function( curr, next, fwd ) { 568 | var opts = this.opts(); 569 | if ( !curr ) { 570 | curr = opts.slides[opts.currSlide]; 571 | next = opts.slides[opts.nextSlide]; 572 | fwd = !opts.reverse; 573 | } 574 | 575 | // reset the zIndex for the common case: 576 | // curr slide on top, next slide beneath, and the rest in order to be shown 577 | $(curr).css('zIndex', opts.maxZ); 578 | 579 | var i; 580 | var z = opts.maxZ - 2; 581 | var len = opts.slideCount; 582 | if (fwd) { 583 | for ( i = opts.currSlide + 1; i < len; i++ ) 584 | $( opts.slides[i] ).css( 'zIndex', z-- ); 585 | for ( i = 0; i < opts.currSlide; i++ ) 586 | $( opts.slides[i] ).css( 'zIndex', z-- ); 587 | } 588 | else { 589 | for ( i = opts.currSlide - 1; i >= 0; i-- ) 590 | $( opts.slides[i] ).css( 'zIndex', z-- ); 591 | for ( i = len - 1; i > opts.currSlide; i-- ) 592 | $( opts.slides[i] ).css( 'zIndex', z-- ); 593 | } 594 | 595 | $(next).css('zIndex', opts.maxZ - 1); 596 | }, 597 | 598 | getSlideIndex: function( el ) { 599 | return this.opts().slides.index( el ); 600 | } 601 | 602 | }; // API 603 | 604 | // default logger 605 | $.fn.cycle2.log = function log() { 606 | /*global console:true */ 607 | if (window.console && console.log) 608 | console.log('[cycle2] ' + Array.prototype.join.call(arguments, ' ') ); 609 | }; 610 | 611 | $.fn.cycle2.version = function() { return 'Cycle2: ' + version; }; 612 | 613 | // helper functions 614 | 615 | function lowerCase(s) { 616 | return (s || '').toLowerCase(); 617 | } 618 | 619 | // expose transition object 620 | $.fn.cycle2.transitions = { 621 | custom: { 622 | }, 623 | none: { 624 | before: function( opts, curr, next, fwd ) { 625 | opts.API.stackSlides( next, curr, fwd ); 626 | opts.cssBefore = { opacity: 1, visibility: 'visible', display: 'block' }; 627 | } 628 | }, 629 | fade: { 630 | before: function( opts, curr, next, fwd ) { 631 | var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {}; 632 | opts.API.stackSlides( curr, next, fwd ); 633 | opts.cssBefore = $.extend(css, { opacity: 0, visibility: 'visible', display: 'block' }); 634 | opts.animIn = { opacity: 1 }; 635 | opts.animOut = { opacity: 0 }; 636 | } 637 | }, 638 | fadeout: { 639 | before: function( opts , curr, next, fwd ) { 640 | var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {}; 641 | opts.API.stackSlides( curr, next, fwd ); 642 | opts.cssBefore = $.extend(css, { opacity: 1, visibility: 'visible', display: 'block' }); 643 | opts.animOut = { opacity: 0 }; 644 | } 645 | }, 646 | scrollHorz: { 647 | before: function( opts, curr, next, fwd ) { 648 | opts.API.stackSlides( curr, next, fwd ); 649 | var w = opts.container.css('overflow','hidden').width(); 650 | opts.cssBefore = { left: fwd ? w : - w, top: 0, opacity: 1, visibility: 'visible', display: 'block' }; 651 | opts.cssAfter = { zIndex: opts._maxZ - 2, left: 0 }; 652 | opts.animIn = { left: 0 }; 653 | opts.animOut = { left: fwd ? -w : w }; 654 | } 655 | } 656 | }; 657 | 658 | // @see: http://jquery.malsup.com/cycle2/api 659 | $.fn.cycle2.defaults = { 660 | allowWrap: true, 661 | autoSelector: '.rotatingtweets[data-cycle-auto-init!=false]', 662 | delay: 0, 663 | easing: null, 664 | fx: 'fade', 665 | hideNonActive: true, 666 | loop: 0, 667 | manualFx: undefined, 668 | manualSpeed: undefined, 669 | manualTrump: true, 670 | maxZ: 100, 671 | pauseOnHover: false, 672 | reverse: false, 673 | slideActiveClass: 'cycle-slide-active', 674 | slideClass: 'cycle-slide', 675 | slideCss: { position: 'absolute', top: 0, left: 0 }, 676 | slides: '> img', 677 | speed: 500, 678 | startingSlide: 0, 679 | sync: true, 680 | timeout: 4000, 681 | updateView: 0 682 | }; 683 | 684 | // automatically find and run slideshows 685 | $(document).ready(function() { 686 | $( $.fn.cycle2.defaults.autoSelector ).cycle2(); 687 | }); 688 | 689 | })(jQuery); 690 | 691 | /*! Cycle2 autoheight plugin; Copyright (c) M.Alsup, 2012; version: 20130913 */ 692 | (function($) { 693 | "use strict"; 694 | 695 | $.extend($.fn.cycle2.defaults, { 696 | autoHeight: 0, // setting this option to false disables autoHeight logic 697 | autoHeightSpeed: 250, 698 | autoHeightEasing: null 699 | }); 700 | 701 | $(document).on( 'cycle-initialized', function( e, opts ) { 702 | var autoHeight = opts.autoHeight; 703 | var t = $.type( autoHeight ); 704 | var resizeThrottle = null; 705 | var ratio; 706 | 707 | if ( t !== 'string' && t !== 'number' ) 708 | return; 709 | 710 | // bind events 711 | opts.container.on( 'cycle-slide-added cycle-slide-removed', initAutoHeight ); 712 | opts.container.on( 'cycle-destroyed', onDestroy ); 713 | 714 | if ( autoHeight == 'container' ) { 715 | opts.container.on( 'cycle-before', onBefore ); 716 | } 717 | else if ( t === 'string' && /\d+\:\d+/.test( autoHeight ) ) { 718 | // use ratio 719 | ratio = autoHeight.match(/(\d+)\:(\d+)/); 720 | ratio = ratio[1] / ratio[2]; 721 | opts._autoHeightRatio = ratio; 722 | } 723 | 724 | // if autoHeight is a number then we don't need to recalculate the sentinel 725 | // index on resize 726 | if ( t !== 'number' ) { 727 | // bind unique resize handler per slideshow (so it can be 'off-ed' in onDestroy) 728 | opts._autoHeightOnResize = function () { 729 | clearTimeout( resizeThrottle ); 730 | resizeThrottle = setTimeout( onResize, 50 ); 731 | }; 732 | 733 | $(window).on( 'resize orientationchange', opts._autoHeightOnResize ); 734 | } 735 | 736 | setTimeout( onResize, 30 ); 737 | 738 | function onResize() { 739 | initAutoHeight( e, opts ); 740 | } 741 | }); 742 | 743 | function initAutoHeight( e, opts ) { 744 | var clone, height, sentinelIndex; 745 | var autoHeight = opts.autoHeight; 746 | 747 | if ( autoHeight == 'container' ) { 748 | height = $( opts.slides[ opts.currSlide ] ).outerHeight(); 749 | opts.container.height( height ); 750 | } 751 | else if ( opts._autoHeightRatio ) { 752 | opts.container.height( opts.container.width() / opts._autoHeightRatio ); 753 | } 754 | else if ( autoHeight === 'calc' || ( $.type( autoHeight ) == 'number' && autoHeight >= 0 ) ) { 755 | if ( autoHeight === 'calc' ) 756 | sentinelIndex = calcSentinelIndex( e, opts ); 757 | else if ( autoHeight >= opts.slides.length ) 758 | sentinelIndex = 0; 759 | else 760 | sentinelIndex = autoHeight; 761 | 762 | // only recreate sentinel if index is different 763 | if ( sentinelIndex == opts._sentinelIndex ) 764 | return; 765 | 766 | opts._sentinelIndex = sentinelIndex; 767 | if ( opts._sentinel ) 768 | opts._sentinel.remove(); 769 | 770 | // clone existing slide as sentinel 771 | clone = $( opts.slides[ sentinelIndex ].cloneNode(true) ); 772 | 773 | // #50; remove special attributes from cloned content 774 | clone.removeAttr( 'id name rel' ).find( '[id],[name],[rel]' ).removeAttr( 'id name rel' ); 775 | 776 | clone.css({ 777 | position: 'static', 778 | visibility: 'hidden', 779 | display: 'block' 780 | }).prependTo( opts.container ).addClass('cycle-sentinel cycle-slide').removeClass('cycle-slide-active'); 781 | clone.find( '*' ).css( 'visibility', 'hidden' ); 782 | 783 | opts._sentinel = clone; 784 | } 785 | } 786 | 787 | function calcSentinelIndex( e, opts ) { 788 | var index = 0, max = -1; 789 | 790 | // calculate tallest slide index 791 | opts.slides.each(function(i) { 792 | var h = $(this).height(); 793 | if ( h > max ) { 794 | max = h; 795 | index = i; 796 | } 797 | }); 798 | return index; 799 | } 800 | 801 | function onBefore( e, opts, outgoing, incoming, forward ) { 802 | var h = $(incoming).outerHeight(); 803 | opts.container.animate( { height: h }, opts.autoHeightSpeed, opts.autoHeightEasing ); 804 | } 805 | 806 | function onDestroy( e, opts ) { 807 | if ( opts._autoHeightOnResize ) { 808 | $(window).off( 'resize orientationchange', opts._autoHeightOnResize ); 809 | opts._autoHeightOnResize = null; 810 | } 811 | opts.container.off( 'cycle-slide-added cycle-slide-removed', initAutoHeight ); 812 | opts.container.off( 'cycle-destroyed', onDestroy ); 813 | opts.container.off( 'cycle-before', onBefore ); 814 | 815 | if ( opts._sentinel ) { 816 | opts._sentinel.remove(); 817 | opts._sentinel = null; 818 | } 819 | } 820 | 821 | })(jQuery); 822 | 823 | /*! caption plugin for Cycle2; version: 20130306 */ 824 | (function($) { 825 | "use strict"; 826 | 827 | $.extend($.fn.cycle2.defaults, { 828 | caption: '> .cycle-caption', 829 | captionTemplate: '{{slideNum}} / {{slideCount}}', 830 | overlay: '> .cycle-overlay', 831 | overlayTemplate: '
{{title}}
{{desc}}
', 832 | captionModule: 'caption' 833 | }); 834 | 835 | $(document).on( 'cycle-update-view', function( e, opts, slideOpts, currSlide ) { 836 | if ( opts.captionModule !== 'caption' ) 837 | return; 838 | var el; 839 | $.each(['caption','overlay'], function() { 840 | var name = this; 841 | var template = slideOpts[name+'Template']; 842 | var el = opts.API.getComponent( name ); 843 | if( el.length && template ) { 844 | el.html( opts.API.tmpl( template, slideOpts, opts, currSlide ) ); 845 | el.show(); 846 | } 847 | else { 848 | el.hide(); 849 | } 850 | }); 851 | }); 852 | 853 | $(document).on( 'cycle-destroyed', function( e, opts ) { 854 | var el; 855 | $.each(['caption','overlay'], function() { 856 | var name = this, template = opts[name+'Template']; 857 | if ( opts[name] && template ) { 858 | el = opts.API.getComponent( 'caption' ); 859 | el.empty(); 860 | } 861 | }); 862 | }); 863 | 864 | })(jQuery); 865 | 866 | /*! command plugin for Cycle2; version: 20140415 */ 867 | (function($) { 868 | "use strict"; 869 | 870 | var c2 = $.fn.cycle2; 871 | 872 | $.fn.cycle2 = function( options ) { 873 | var cmd, cmdFn, opts; 874 | var args = $.makeArray( arguments ); 875 | 876 | if ( $.type( options ) == 'number' ) { 877 | return this.cycle2( 'goto', options ); 878 | } 879 | 880 | if ( $.type( options ) == 'string' ) { 881 | return this.each(function() { 882 | var cmdArgs; 883 | cmd = options; 884 | opts = $(this).data('cycle.opts'); 885 | 886 | if ( opts === undefined ) { 887 | c2.log('slideshow must be initialized before sending commands; "' + cmd + '" ignored'); 888 | return; 889 | } 890 | else { 891 | cmd = cmd == 'goto' ? 'jump' : cmd; // issue #3; change 'goto' to 'jump' internally 892 | cmdFn = opts.API[ cmd ]; 893 | if ( $.isFunction( cmdFn )) { 894 | cmdArgs = $.makeArray( args ); 895 | cmdArgs.shift(); 896 | return cmdFn.apply( opts.API, cmdArgs ); 897 | } 898 | else { 899 | c2.log( 'unknown command: ', cmd ); 900 | } 901 | } 902 | }); 903 | } 904 | else { 905 | return c2.apply( this, arguments ); 906 | } 907 | }; 908 | 909 | // copy props 910 | $.extend( $.fn.cycle2, c2 ); 911 | 912 | $.extend( c2.API, { 913 | next: function() { 914 | var opts = this.opts(); 915 | if ( opts.busy && ! opts.manualTrump ) 916 | return; 917 | 918 | var count = opts.reverse ? -1 : 1; 919 | if ( opts.allowWrap === false && ( opts.currSlide + count ) >= opts.slideCount ) 920 | return; 921 | 922 | opts.API.advanceSlide( count ); 923 | opts.API.trigger('cycle-next', [ opts ]).log('cycle-next'); 924 | }, 925 | 926 | prev: function() { 927 | var opts = this.opts(); 928 | if ( opts.busy && ! opts.manualTrump ) 929 | return; 930 | var count = opts.reverse ? 1 : -1; 931 | if ( opts.allowWrap === false && ( opts.currSlide + count ) < 0 ) 932 | return; 933 | 934 | opts.API.advanceSlide( count ); 935 | opts.API.trigger('cycle-prev', [ opts ]).log('cycle-prev'); 936 | }, 937 | 938 | destroy: function() { 939 | this.stop(); //#204 940 | 941 | var opts = this.opts(); 942 | var clean = $.isFunction( $._data ) ? $._data : $.noop; // hack for #184 and #201 943 | clearTimeout(opts.timeoutId); 944 | opts.timeoutId = 0; 945 | opts.API.stop(); 946 | opts.API.trigger( 'cycle-destroyed', [ opts ] ).log('cycle-destroyed'); 947 | opts.container.removeData(); 948 | clean( opts.container[0], 'parsedAttrs', false ); 949 | 950 | // #75; remove inline styles 951 | if ( ! opts.retainStylesOnDestroy ) { 952 | opts.container.removeAttr( 'style' ); 953 | opts.slides.removeAttr( 'style' ); 954 | opts.slides.removeClass( opts.slideActiveClass ); 955 | } 956 | opts.slides.each(function() { 957 | var slide = $(this); 958 | slide.removeData(); 959 | slide.removeClass( opts.slideClass ); 960 | clean( this, 'parsedAttrs', false ); 961 | }); 962 | }, 963 | 964 | jump: function( index, fx ) { 965 | // go to the requested slide 966 | var fwd; 967 | var opts = this.opts(); 968 | if ( opts.busy && ! opts.manualTrump ) 969 | return; 970 | var num = parseInt( index, 10 ); 971 | if (isNaN(num) || num < 0 || num >= opts.slides.length) { 972 | opts.API.log('goto: invalid slide index: ' + num); 973 | return; 974 | } 975 | if (num == opts.currSlide) { 976 | opts.API.log('goto: skipping, already on slide', num); 977 | return; 978 | } 979 | opts.nextSlide = num; 980 | clearTimeout(opts.timeoutId); 981 | opts.timeoutId = 0; 982 | opts.API.log('goto: ', num, ' (zero-index)'); 983 | fwd = opts.currSlide < opts.nextSlide; 984 | opts._tempFx = fx; 985 | opts.API.prepareTx( true, fwd ); 986 | }, 987 | 988 | stop: function() { 989 | var opts = this.opts(); 990 | var pauseObj = opts.container; 991 | clearTimeout(opts.timeoutId); 992 | opts.timeoutId = 0; 993 | opts.API.stopTransition(); 994 | if ( opts.pauseOnHover ) { 995 | if ( opts.pauseOnHover !== true ) 996 | pauseObj = $( opts.pauseOnHover ); 997 | pauseObj.off('mouseenter mouseleave'); 998 | } 999 | opts.API.trigger('cycle-stopped', [ opts ]).log('cycle-stopped'); 1000 | }, 1001 | 1002 | reinit: function() { 1003 | var opts = this.opts(); 1004 | opts.API.destroy(); 1005 | opts.container.cycle2(); 1006 | }, 1007 | 1008 | remove: function( index ) { 1009 | var opts = this.opts(); 1010 | var slide, slideToRemove, slides = [], slideNum = 1; 1011 | for ( var i=0; i < opts.slides.length; i++ ) { 1012 | slide = opts.slides[i]; 1013 | if ( i == index ) { 1014 | slideToRemove = slide; 1015 | } 1016 | else { 1017 | slides.push( slide ); 1018 | $( slide ).data('cycle.opts').slideNum = slideNum; 1019 | slideNum++; 1020 | } 1021 | } 1022 | if ( slideToRemove ) { 1023 | opts.slides = $( slides ); 1024 | opts.slideCount--; 1025 | $( slideToRemove ).remove(); 1026 | if (index == opts.currSlide) 1027 | opts.API.advanceSlide( 1 ); 1028 | else if ( index < opts.currSlide ) 1029 | opts.currSlide--; 1030 | else 1031 | opts.currSlide++; 1032 | 1033 | opts.API.trigger('cycle-slide-removed', [ opts, index, slideToRemove ]).log('cycle-slide-removed'); 1034 | opts.API.updateView(); 1035 | } 1036 | } 1037 | 1038 | }); 1039 | 1040 | // listen for clicks on elements with data-cycle-cmd attribute 1041 | $(document).on('click.cycle', '[data-cycle-cmd]', function(e) { 1042 | // issue cycle command 1043 | e.preventDefault(); 1044 | var el = $(this); 1045 | var command = el.data('cycle-cmd'); 1046 | var context = el.data('cycle-context') || '.cycle-slideshow'; 1047 | $(context).cycle2(command, el.data('cycle-arg')); 1048 | }); 1049 | 1050 | 1051 | })(jQuery); 1052 | 1053 | /*! hash plugin for Cycle2; version: 20130905 */ 1054 | (function($) { 1055 | "use strict"; 1056 | 1057 | $(document).on( 'cycle-pre-initialize', function( e, opts ) { 1058 | onHashChange( opts, true ); 1059 | 1060 | opts._onHashChange = function() { 1061 | onHashChange( opts, false ); 1062 | }; 1063 | 1064 | $( window ).on( 'hashchange', opts._onHashChange); 1065 | }); 1066 | 1067 | $(document).on( 'cycle-update-view', function( e, opts, slideOpts ) { 1068 | if ( slideOpts.hash && ( '#' + slideOpts.hash ) != window.location.hash ) { 1069 | opts._hashFence = true; 1070 | window.location.hash = slideOpts.hash; 1071 | } 1072 | }); 1073 | 1074 | $(document).on( 'cycle-destroyed', function( e, opts) { 1075 | if ( opts._onHashChange ) { 1076 | $( window ).off( 'hashchange', opts._onHashChange ); 1077 | } 1078 | }); 1079 | 1080 | function onHashChange( opts, setStartingSlide ) { 1081 | var hash; 1082 | if ( opts._hashFence ) { 1083 | opts._hashFence = false; 1084 | return; 1085 | } 1086 | 1087 | hash = window.location.hash.substring(1); 1088 | 1089 | opts.slides.each(function(i) { 1090 | if ( $(this).data( 'cycle-hash' ) == hash ) { 1091 | if ( setStartingSlide === true ) { 1092 | opts.startingSlide = i; 1093 | } 1094 | else { 1095 | var fwd = opts.currSlide < i; 1096 | opts.nextSlide = i; 1097 | opts.API.prepareTx( true, fwd ); 1098 | } 1099 | return false; 1100 | } 1101 | }); 1102 | } 1103 | 1104 | })(jQuery); 1105 | 1106 | /*! loader plugin for Cycle2; version: 20131121 */ 1107 | (function($) { 1108 | "use strict"; 1109 | 1110 | $.extend($.fn.cycle2.defaults, { 1111 | loader: false 1112 | }); 1113 | 1114 | $(document).on( 'cycle-bootstrap', function( e, opts ) { 1115 | var addFn; 1116 | 1117 | if ( !opts.loader ) 1118 | return; 1119 | 1120 | // override API.add for this slideshow 1121 | addFn = opts.API.add; 1122 | opts.API.add = add; 1123 | 1124 | function add( slides, prepend ) { 1125 | var slideArr = []; 1126 | if ( $.type( slides ) == 'string' ) 1127 | slides = $.trim( slides ); 1128 | else if ( $.type( slides) === 'array' ) { 1129 | for (var i=0; i < slides.length; i++ ) 1130 | slides[i] = $(slides[i])[0]; 1131 | } 1132 | 1133 | slides = $( slides ); 1134 | var slideCount = slides.length; 1135 | 1136 | if ( ! slideCount ) 1137 | return; 1138 | 1139 | slides.css('visibility','hidden').appendTo('body').each(function(i) { // appendTo fixes #56 1140 | var count = 0; 1141 | var slide = $(this); 1142 | var images = slide.is('img') ? slide : slide.find('img'); 1143 | slide.data('index', i); 1144 | // allow some images to be marked as unimportant (and filter out images w/o src value) 1145 | images = images.filter(':not(.cycle-loader-ignore)').filter(':not([src=""])'); 1146 | if ( ! images.length ) { 1147 | --slideCount; 1148 | slideArr.push( slide ); 1149 | return; 1150 | } 1151 | 1152 | count = images.length; 1153 | images.each(function() { 1154 | // add images that are already loaded 1155 | if ( this.complete ) { 1156 | imageLoaded(); 1157 | } 1158 | else { 1159 | $(this).load(function() { 1160 | imageLoaded(); 1161 | }).on("error", function() { 1162 | if ( --count === 0 ) { 1163 | // ignore this slide 1164 | opts.API.log('slide skipped; img not loaded:', this.src); 1165 | if ( --slideCount === 0 && opts.loader == 'wait') { 1166 | addFn.apply( opts.API, [ slideArr, prepend ] ); 1167 | } 1168 | } 1169 | }); 1170 | } 1171 | }); 1172 | 1173 | function imageLoaded() { 1174 | if ( --count === 0 ) { 1175 | --slideCount; 1176 | addSlide( slide ); 1177 | } 1178 | } 1179 | }); 1180 | 1181 | if ( slideCount ) 1182 | opts.container.addClass('cycle-loading'); 1183 | 1184 | 1185 | function addSlide( slide ) { 1186 | var curr; 1187 | if ( opts.loader == 'wait' ) { 1188 | slideArr.push( slide ); 1189 | if ( slideCount === 0 ) { 1190 | // #59; sort slides into original markup order 1191 | slideArr.sort( sorter ); 1192 | addFn.apply( opts.API, [ slideArr, prepend ] ); 1193 | opts.container.removeClass('cycle-loading'); 1194 | } 1195 | } 1196 | else { 1197 | curr = $(opts.slides[opts.currSlide]); 1198 | addFn.apply( opts.API, [ slide, prepend ] ); 1199 | curr.show(); 1200 | opts.container.removeClass('cycle-loading'); 1201 | } 1202 | } 1203 | 1204 | function sorter(a, b) { 1205 | return a.data('index') - b.data('index'); 1206 | } 1207 | } 1208 | }); 1209 | 1210 | })(jQuery); 1211 | 1212 | /*! pager plugin for Cycle2; version: 20140415 */ 1213 | (function($) { 1214 | "use strict"; 1215 | 1216 | $.extend($.fn.cycle2.defaults, { 1217 | pager: '> .cycle-pager', 1218 | pagerActiveClass: 'cycle-pager-active', 1219 | pagerEvent: 'click.cycle', 1220 | pagerEventBubble: undefined, 1221 | pagerTemplate: '' 1222 | }); 1223 | 1224 | $(document).on( 'cycle-bootstrap', function( e, opts, API ) { 1225 | // add method to API 1226 | API.buildPagerLink = buildPagerLink; 1227 | }); 1228 | 1229 | $(document).on( 'cycle-slide-added', function( e, opts, slideOpts, slideAdded ) { 1230 | if ( opts.pager ) { 1231 | opts.API.buildPagerLink ( opts, slideOpts, slideAdded ); 1232 | opts.API.page = page; 1233 | } 1234 | }); 1235 | 1236 | $(document).on( 'cycle-slide-removed', function( e, opts, index, slideRemoved ) { 1237 | if ( opts.pager ) { 1238 | var pagers = opts.API.getComponent( 'pager' ); 1239 | pagers.each(function() { 1240 | var pager = $(this); 1241 | $( pager.children()[index] ).remove(); 1242 | }); 1243 | } 1244 | }); 1245 | 1246 | $(document).on( 'cycle-update-view', function( e, opts, slideOpts ) { 1247 | var pagers; 1248 | 1249 | if ( opts.pager ) { 1250 | pagers = opts.API.getComponent( 'pager' ); 1251 | pagers.each(function() { 1252 | $(this).children().removeClass( opts.pagerActiveClass ) 1253 | .eq( opts.currSlide ).addClass( opts.pagerActiveClass ); 1254 | }); 1255 | } 1256 | }); 1257 | 1258 | $(document).on( 'cycle-destroyed', function( e, opts ) { 1259 | var pager = opts.API.getComponent( 'pager' ); 1260 | 1261 | if ( pager ) { 1262 | pager.children().off( opts.pagerEvent ); // #202 1263 | if ( opts.pagerTemplate ) 1264 | pager.empty(); 1265 | } 1266 | }); 1267 | 1268 | function buildPagerLink( opts, slideOpts, slide ) { 1269 | var pagerLink; 1270 | var pagers = opts.API.getComponent( 'pager' ); 1271 | pagers.each(function() { 1272 | var pager = $(this); 1273 | if ( slideOpts.pagerTemplate ) { 1274 | var markup = opts.API.tmpl( slideOpts.pagerTemplate, slideOpts, opts, slide[0] ); 1275 | pagerLink = $( markup ).appendTo( pager ); 1276 | } 1277 | else { 1278 | pagerLink = pager.children().eq( opts.slideCount - 1 ); 1279 | } 1280 | pagerLink.on( opts.pagerEvent, function(e) { 1281 | if ( ! opts.pagerEventBubble ) 1282 | e.preventDefault(); 1283 | opts.API.page( pager, e.currentTarget); 1284 | }); 1285 | }); 1286 | } 1287 | 1288 | function page( pager, target ) { 1289 | /*jshint validthis:true */ 1290 | var opts = this.opts(); 1291 | if ( opts.busy && ! opts.manualTrump ) 1292 | return; 1293 | 1294 | var index = pager.children().index( target ); 1295 | var nextSlide = index; 1296 | var fwd = opts.currSlide < nextSlide; 1297 | if (opts.currSlide == nextSlide) { 1298 | return; // no op, clicked pager for the currently displayed slide 1299 | } 1300 | opts.nextSlide = nextSlide; 1301 | opts._tempFx = opts.pagerFx; 1302 | opts.API.prepareTx( true, fwd ); 1303 | opts.API.trigger('cycle-pager-activated', [opts, pager, target ]); 1304 | } 1305 | 1306 | })(jQuery); 1307 | 1308 | /*! prevnext plugin for Cycle2; version: 20140408 */ 1309 | (function($) { 1310 | "use strict"; 1311 | 1312 | $.extend($.fn.cycle2.defaults, { 1313 | next: '> .cycle-next', 1314 | nextEvent: 'click.cycle', 1315 | disabledClass: 'disabled', 1316 | prev: '> .cycle-prev', 1317 | prevEvent: 'click.cycle', 1318 | swipe: false 1319 | }); 1320 | 1321 | $(document).on( 'cycle-initialized', function( e, opts ) { 1322 | opts.API.getComponent( 'next' ).on( opts.nextEvent, function(e) { 1323 | e.preventDefault(); 1324 | opts.API.next(); 1325 | }); 1326 | 1327 | opts.API.getComponent( 'prev' ).on( opts.prevEvent, function(e) { 1328 | e.preventDefault(); 1329 | opts.API.prev(); 1330 | }); 1331 | 1332 | if ( opts.swipe ) { 1333 | var nextEvent = opts.swipeVert ? 'swipeUp.cycle' : 'swipeLeft.cycle swipeleft.cycle'; 1334 | var prevEvent = opts.swipeVert ? 'swipeDown.cycle' : 'swipeRight.cycle swiperight.cycle'; 1335 | opts.container.on( nextEvent, function(e) { 1336 | opts._tempFx = opts.swipeFx; 1337 | opts.API.next(); 1338 | }); 1339 | opts.container.on( prevEvent, function() { 1340 | opts._tempFx = opts.swipeFx; 1341 | opts.API.prev(); 1342 | }); 1343 | } 1344 | }); 1345 | 1346 | $(document).on( 'cycle-update-view', function( e, opts, slideOpts, currSlide ) { 1347 | if ( opts.allowWrap ) 1348 | return; 1349 | 1350 | var cls = opts.disabledClass; 1351 | var next = opts.API.getComponent( 'next' ); 1352 | var prev = opts.API.getComponent( 'prev' ); 1353 | var prevBoundry = opts._prevBoundry || 0; 1354 | var nextBoundry = (opts._nextBoundry !== undefined)?opts._nextBoundry:opts.slideCount - 1; 1355 | 1356 | if ( opts.currSlide == nextBoundry ) 1357 | next.addClass( cls ).prop( 'disabled', true ); 1358 | else 1359 | next.removeClass( cls ).prop( 'disabled', false ); 1360 | 1361 | if ( opts.currSlide === prevBoundry ) 1362 | prev.addClass( cls ).prop( 'disabled', true ); 1363 | else 1364 | prev.removeClass( cls ).prop( 'disabled', false ); 1365 | }); 1366 | 1367 | 1368 | $(document).on( 'cycle-destroyed', function( e, opts ) { 1369 | opts.API.getComponent( 'prev' ).off( opts.nextEvent ); 1370 | opts.API.getComponent( 'next' ).off( opts.prevEvent ); 1371 | opts.container.off( 'swipeleft.cycle swiperight.cycle swipeLeft.cycle swipeRight.cycle swipeUp.cycle swipeDown.cycle' ); 1372 | }); 1373 | 1374 | })(jQuery); 1375 | 1376 | /*! progressive loader plugin for Cycle2; version: 20130315 */ 1377 | (function($) { 1378 | "use strict"; 1379 | 1380 | $.extend($.fn.cycle2.defaults, { 1381 | progressive: false 1382 | }); 1383 | 1384 | $(document).on( 'cycle-pre-initialize', function( e, opts ) { 1385 | if ( !opts.progressive ) 1386 | return; 1387 | 1388 | var API = opts.API; 1389 | var nextFn = API.next; 1390 | var prevFn = API.prev; 1391 | var prepareTxFn = API.prepareTx; 1392 | var type = $.type( opts.progressive ); 1393 | var slides, scriptEl; 1394 | 1395 | if ( type == 'array' ) { 1396 | slides = opts.progressive; 1397 | } 1398 | else if ($.isFunction( opts.progressive ) ) { 1399 | slides = opts.progressive( opts ); 1400 | } 1401 | else if ( type == 'string' ) { 1402 | scriptEl = $( opts.progressive ); 1403 | slides = $.trim( scriptEl.html() ); 1404 | if ( !slides ) 1405 | return; 1406 | // is it json array? 1407 | if ( /^(\[)/.test( slides ) ) { 1408 | try { 1409 | slides = $.parseJSON( slides ); 1410 | } 1411 | catch(err) { 1412 | API.log( 'error parsing progressive slides', err ); 1413 | return; 1414 | } 1415 | } 1416 | else { 1417 | // plain text, split on delimeter 1418 | slides = slides.split( new RegExp( scriptEl.data('cycle-split') || '\n') ); 1419 | 1420 | // #95; look for empty slide 1421 | if ( ! slides[ slides.length - 1 ] ) 1422 | slides.pop(); 1423 | } 1424 | } 1425 | 1426 | 1427 | 1428 | if ( prepareTxFn ) { 1429 | API.prepareTx = function( manual, fwd ) { 1430 | var index, slide; 1431 | 1432 | if ( manual || slides.length === 0 ) { 1433 | prepareTxFn.apply( opts.API, [ manual, fwd ] ); 1434 | return; 1435 | } 1436 | 1437 | if ( fwd && opts.currSlide == ( opts.slideCount-1) ) { 1438 | slide = slides[ 0 ]; 1439 | slides = slides.slice( 1 ); 1440 | opts.container.one('cycle-slide-added', function(e, opts ) { 1441 | setTimeout(function() { 1442 | opts.API.advanceSlide( 1 ); 1443 | },50); 1444 | }); 1445 | opts.API.add( slide ); 1446 | } 1447 | else if ( !fwd && opts.currSlide === 0 ) { 1448 | index = slides.length-1; 1449 | slide = slides[ index ]; 1450 | slides = slides.slice( 0, index ); 1451 | opts.container.one('cycle-slide-added', function(e, opts ) { 1452 | setTimeout(function() { 1453 | opts.currSlide = 1; 1454 | opts.API.advanceSlide( -1 ); 1455 | },50); 1456 | }); 1457 | opts.API.add( slide, true ); 1458 | } 1459 | else { 1460 | prepareTxFn.apply( opts.API, [ manual, fwd ] ); 1461 | } 1462 | }; 1463 | } 1464 | 1465 | if ( nextFn ) { 1466 | API.next = function() { 1467 | var opts = this.opts(); 1468 | if ( slides.length && opts.currSlide == ( opts.slideCount - 1 ) ) { 1469 | var slide = slides[ 0 ]; 1470 | slides = slides.slice( 1 ); 1471 | opts.container.one('cycle-slide-added', function(e, opts ) { 1472 | nextFn.apply( opts.API ); 1473 | opts.container.removeClass('cycle-loading'); 1474 | }); 1475 | opts.container.addClass('cycle-loading'); 1476 | opts.API.add( slide ); 1477 | } 1478 | else { 1479 | nextFn.apply( opts.API ); 1480 | } 1481 | }; 1482 | } 1483 | 1484 | if ( prevFn ) { 1485 | API.prev = function() { 1486 | var opts = this.opts(); 1487 | if ( slides.length && opts.currSlide === 0 ) { 1488 | var index = slides.length-1; 1489 | var slide = slides[ index ]; 1490 | slides = slides.slice( 0, index ); 1491 | opts.container.one('cycle-slide-added', function(e, opts ) { 1492 | opts.currSlide = 1; 1493 | opts.API.advanceSlide( -1 ); 1494 | opts.container.removeClass('cycle-loading'); 1495 | }); 1496 | opts.container.addClass('cycle-loading'); 1497 | opts.API.add( slide, true ); 1498 | } 1499 | else { 1500 | prevFn.apply( opts.API ); 1501 | } 1502 | }; 1503 | } 1504 | }); 1505 | 1506 | })(jQuery); 1507 | 1508 | /*! tmpl plugin for Cycle2; version: 20121227 */ 1509 | (function($) { 1510 | "use strict"; 1511 | 1512 | $.extend($.fn.cycle2.defaults, { 1513 | tmplRegex: '{{((.)?.*?)}}' 1514 | }); 1515 | 1516 | $.extend($.fn.cycle2.API, { 1517 | tmpl: function( str, opts /*, ... */) { 1518 | var regex = new RegExp( opts.tmplRegex || $.fn.cycle2.defaults.tmplRegex, 'g' ); 1519 | var args = $.makeArray( arguments ); 1520 | args.shift(); 1521 | return str.replace(regex, function(_, str) { 1522 | var i, j, obj, prop, names = str.split('.'); 1523 | for (i=0; i < args.length; i++) { 1524 | obj = args[i]; 1525 | if ( ! obj ) 1526 | continue; 1527 | if (names.length > 1) { 1528 | prop = obj; 1529 | for (j=0; j < names.length; j++) { 1530 | obj = prop; 1531 | prop = prop[ names[j] ] || str; 1532 | } 1533 | } else { 1534 | prop = obj[str]; 1535 | } 1536 | 1537 | if ($.isFunction(prop)) 1538 | return prop.apply(obj, args); 1539 | if (prop !== undefined && prop !== null && prop != str) 1540 | return prop; 1541 | } 1542 | return str; 1543 | }); 1544 | } 1545 | }); 1546 | 1547 | })(jQuery); 1548 | -------------------------------------------------------------------------------- /js/jquery.cycle2.scrollVert.js: -------------------------------------------------------------------------------- 1 | /*! scrollVert transition plugin for Cycle2; version: 20140128 */ 2 | (function($) { 3 | "use strict"; 4 | 5 | $.fn.cycle.transitions.scrollVert = { 6 | before: function( opts, curr, next, fwd ) { 7 | opts.API.stackSlides( opts, curr, next, fwd ); 8 | var height = opts.container.css('overflow','hidden').height(); 9 | opts.cssBefore = { top: fwd ? -height : height, left: 0, opacity: 1, display: 'block', visibility: 'visible' }; 10 | opts.animIn = { top: 0 }; 11 | opts.animOut = { top: fwd ? height : -height }; 12 | } 13 | }; 14 | 15 | })(jQuery); -------------------------------------------------------------------------------- /js/jquery.cycle2.scrollVert.renamed.js: -------------------------------------------------------------------------------- 1 | /*! scrollVert transition plugin for Cycle2; version: 20140128 */ 2 | (function($) { 3 | "use strict"; 4 | 5 | $.fn.cycle2.transitions.scrollVert = { 6 | before: function( opts, curr, next, fwd ) { 7 | opts.API.stackSlides( opts, curr, next, fwd ); 8 | var height = opts.container.css('overflow','hidden').height(); 9 | opts.cssBefore = { top: fwd ? -height : height, left: 0, opacity: 1, display: 'block', visibility: 'visible' }; 10 | opts.animIn = { top: 0 }; 11 | opts.animOut = { top: fwd ? height : -height }; 12 | } 13 | }; 14 | 15 | })(jQuery); 16 | -------------------------------------------------------------------------------- /js/rotating_tweet.js: -------------------------------------------------------------------------------- 1 | /* 2 | Script to cycle the rotating tweets 3 | */ 4 | function rotatingtweets_update_twitter_auth(arg) { 5 | jQuery("#rotatingtweets_api_key_input").prop('disabled', arg); 6 | jQuery("#rotatingtweets_api_secret_input").prop('disabled', arg); 7 | jQuery("#rotatingtweets_api_token_input").prop('disabled', arg); 8 | jQuery("#rotatingtweets_api_token_secret_input").prop('disabled', arg); 9 | } 10 | jQuery(document).ready(function() { 11 | if(jQuery("#rotatingtweets_api_loklak_api_input").prop('checked')){ 12 | rotatingtweets_update_twitter_auth(true); 13 | } 14 | console.log("init"); 15 | jQuery("#rotatingtweets_api_loklak_api_input").live('change', function() { 16 | if(jQuery(this).is(':checked')){ 17 | rotatingtweets_update_twitter_auth(true); 18 | } 19 | else { 20 | rotatingtweets_update_twitter_auth(false); 21 | } 22 | }); 23 | jQuery('.rotatingtweets').each(function() { 24 | /* Get the ID of the rotating tweets div - and parse it to get rotation speed and rotation fx */ 25 | var rotate_id = "#"+this.id, 26 | rotate_class = "."+this.id, 27 | rotate_timeout = jQuery(this).data('cycle-timeout'), 28 | rotate_fx = jQuery(this).data('cycle-fx'), 29 | rotate_speed = jQuery(this).data('cycle-speed'), 30 | rotate_pager = jQuery(this).data('cycle-pager'), 31 | rotate_pager_template = jQuery(this).data('cycle-pager-template'), 32 | rotate_wp_debug = jQuery(this).hasClass('wp_debug'); 33 | /* Handling old versions of jQuery that handle .data differently */ 34 | if ( rotate_timeout === undefined ) { 35 | var rotate_id_split = rotate_id.split('_'); 36 | rotate_timeout = rotate_id_split[1]; 37 | rotate_fx = rotate_id_split[2]; 38 | rotate_speed = rotate_id_split[3]; 39 | } 40 | if( typeof console === "undefined" || typeof console.log === "undefined" ) { 41 | rotate_wp_debug = false; 42 | } 43 | /* If the rotation type has not been set - then set it to scrollUp */ 44 | if(rotate_fx == null){rotate_fx = 'scrollUp'}; 45 | var rt_height_px = 'auto'; 46 | /* Now find the widget container width */ 47 | // Take the smaller of the parent and grandparent 48 | var rt_parent = jQuery(rotate_id).parent(), 49 | rt_grandparent = jQuery(rotate_id).parent().parent(); 50 | var rt_target_container_width = Math.min ( 51 | rt_parent.innerWidth() - parseFloat(rt_parent.css('padding-left')) - parseFloat(rt_parent.css('padding-right')), 52 | rt_grandparent.innerWidth() - parseFloat(rt_grandparent.css('padding-left')) - parseFloat(rt_grandparent.css('padding-right')) - parseFloat(rt_parent.css('padding-left')) - parseFloat(rt_parent.css('padding-right')) - parseFloat(rt_parent.css('margin-left')) - parseFloat(rt_parent.css('margin-right')) 53 | ); 54 | // Get the size of the parent box and subtract any padding 55 | var rt_target_width = rt_target_container_width - parseFloat(jQuery(this).css('padding-left')) - parseFloat(jQuery(this).css('padding-right')) - parseFloat(jQuery(this).css('margin-left')) - parseFloat(jQuery(this).css('margin-right')) - parseFloat(jQuery(this).css('border-left')) - parseFloat(jQuery(this).css('border-right') ) ; 56 | var rt_fit = 1; 57 | if( rt_target_width == null ) { 58 | rt_fit = 0; 59 | } 60 | if(rotate_wp_debug) { 61 | console.log('============================'); 62 | console.log('self_width = '+jQuery(rotate_id).innerWidth()); 63 | console.log('parent_width = '+rt_parent.innerWidth()); 64 | console.log('grandparent_width = '+rt_grandparent.innerWidth()); 65 | console.log('rt_target_container_width = '+rt_target_container_width); 66 | console.log('rt_target_width = '+rt_target_width); 67 | console.log('rotate_timeout = '+rotate_timeout); 68 | console.log('rotate_speed = '+rotate_speed); 69 | console.log('rotate_fx = '+rotate_fx); 70 | console.log('rotate_pager = '+rotate_pager); 71 | console.log('rotate_pager_template = '+rotate_pager_template); 72 | } 73 | /* If we're displaying an 'official' tweet, reset all the heights - this option is currently switched off! */ 74 | // var rt_official_child = rotate_id + ' .twitter-tweet'; 75 | // var rt_official_num = jQuery(rt_official_child).length; 76 | // if (rt_official_num > 0) rt_height_px = '211px'; 77 | var rotate_vars = { 78 | pause: 1, 79 | height: rt_height_px, 80 | timeout: rotate_timeout, 81 | cleartypeNoBg: true, 82 | width: rt_target_width, 83 | prev: rotate_class + '_rtw_prev', 84 | next: rotate_class + '_rtw_next', 85 | fx: rotate_fx, 86 | fit: rt_fit, 87 | speed: rotate_speed 88 | } 89 | if( rotate_timeout > 0) { 90 | rotate_vars.timeout = rotate_timeout; 91 | } else { 92 | rotate_vars.continuous = true; 93 | rotate_vars.easing = 'linear'; 94 | } 95 | if(typeof rotate_pager !== "undefined" ) { 96 | rotate_vars.pager = rotate_id + '_rtw_pager'; 97 | if(typeof rotate_pager_template !== "undefined") { 98 | rotate_vars.pagerAnchorBuilder = function(idx, slide) { 99 | return rotate_pager_template; 100 | } 101 | } 102 | } 103 | if(rotate_wp_debug) { 104 | console.log(rotate_vars); 105 | } 106 | /* Call the rotation */ 107 | jQuery(rotate_id).cycle(rotate_vars); 108 | /* If the height of the rotating tweet box is zero - kill the box and start again */ 109 | var rt_height = jQuery(rotate_id).height(); 110 | if(rotate_wp_debug) { 111 | console.log('Initial height: '+rt_height ); 112 | } 113 | if( rt_height < 1 ) { 114 | var rt_children_id = rotate_id + ' .rotatingtweet'; 115 | var rt_height = 0; 116 | /* Go through the tweets - get their height - and set the minimum height */ 117 | jQuery(rt_children_id).each(function() { 118 | var rt_tweet_height = jQuery(this).height(); 119 | if(rt_tweet_height > rt_height) { 120 | rt_height = rt_tweet_height; 121 | } 122 | }); 123 | rt_height = rt_height + 20; 124 | rt_height_px = rt_height + 'px'; 125 | rotate_vars.height = rt_height_px; 126 | if(rotate_wp_debug) { 127 | console.log('Resetting height to rt_height_px '+rt_height_px); 128 | } 129 | jQuery(rotate_id).cycle('destroy'); 130 | jQuery(rotate_id).cycle(rotate_vars); 131 | } 132 | 133 | /* Only do this if we're showing the official tweets - the first select is the size of the info box at the top of the tweet */ 134 | var rt_children_id = rotate_id + ' .rtw_info'; 135 | /* This shows the width of the icon on 'official version 2' - i.e. the one where the whole tweet is indented */ 136 | var rt_icon_id = rotate_id + ' .rtw_wide_icon a img'; 137 | /* This shows the width of the block containing the icon on 'official version 2' - i.e. the one where the whole tweet is indented */ 138 | var rt_block_id = rotate_id + ' .rtw_wide_block'; 139 | var rt_official_num = jQuery(rt_children_id).length; 140 | var rt_children_meta_id = rotate_id + ' .rtw_meta'; 141 | if(rt_official_num > 0) { 142 | /* Now run through and make sure all the boxes are the right size */ 143 | if(jQuery(rt_icon_id).length > 0) { 144 | if(rotate_wp_debug) { 145 | console.log('Adjusting widths for \'Official Twitter Version 2\''); 146 | console.log('- Width of Rotating Tweets container: ' + jQuery(this).width()); 147 | console.log('- Width of the icon container: ' + jQuery(rt_icon_id).show().width()); 148 | }; 149 | var rt_icon_width = 0; 150 | jQuery(rt_icon_id).each( function() { 151 | newiconsize = jQuery(this).width(); 152 | if(newiconsize>rt_icon_width) { 153 | rt_icon_width = newiconsize; 154 | } 155 | }); 156 | if(rotate_wp_debug) { 157 | console.log('- Width of the icon: '+rt_icon_width); 158 | }; 159 | if(rt_icon_width > 0) { 160 | /* 161 | jQuery(rt_block_id).each( function() { 162 | jQuery(this).css('padding-left', ( rt_icon_width + 10 ) + 'px'); 163 | }); 164 | */ 165 | jQuery(rt_block_id).css('padding-left', ( rt_icon_width + 10 ) + 'px'); 166 | } 167 | } 168 | /* Now get the padding-left dimension (if it exists) and subtract it from the max width */ 169 | if(rotate_wp_debug) { 170 | console.log ('Now check for \'padding-left\''); 171 | console.log ('- leftpadding - text : '+ jQuery(rt_block_id).css('padding-left') + ' and value: ' +parseFloat(jQuery(rt_block_id).css('padding-left'))); 172 | }; 173 | var rt_max_width = jQuery(rotate_id).width(); 174 | if( typeof jQuery(rt_block_id).css('padding-left') != 'undefined' ) { 175 | rt_max_width = rt_max_width - parseFloat(jQuery(rt_block_id).css('padding-left')) - 1 ; 176 | if(rotate_wp_debug) { 177 | console.log('- Padding is not undefined'); 178 | }; 179 | } else if(rotate_wp_debug) { 180 | console.log('- Padding IS undefined - leave width unchanged'); 181 | } 182 | if(rotate_wp_debug) { 183 | console.log('- rt_max_width: ' + rt_max_width); 184 | }; 185 | /* Go through the tweets - and set the minimum width */ 186 | jQuery(rt_children_id).width(rt_max_width); 187 | /* Go through the tweets - and set the minimum width */ 188 | jQuery(rt_children_meta_id).width(rt_max_width); 189 | }; 190 | // Now the responsiveness code 191 | // First get the measures we will use to track change 192 | var rt_resize_width_old_parent = rt_parent.innerWidth(), 193 | rt_resize_width_old_grandparent = rt_grandparent.innerWidth(), 194 | rt_resize_width_new_parent = rt_resize_width_old_parent, 195 | rt_resize_width_new_grandparent = rt_resize_width_old_grandparent, 196 | rt_resize_parent_change = 0, 197 | rt_resize_grandparent_change = 0; 198 | // Now get the starting measures 199 | var rt_resize_target_width = jQuery(rotate_id).width(), 200 | rt_resize_target_main = jQuery(rotate_id + ' .rtw_main').width(), 201 | rt_resize_target_tweet = jQuery(rotate_id + ' .rotatingtweet').width(), 202 | rt_resize_target_meta = jQuery(rotate_id + ' .rtw_meta').width(); 203 | jQuery(window).resize(function() { 204 | if(rotate_wp_debug) { 205 | console.log("== Window Resize Detected =="); 206 | } 207 | rt_parent = jQuery(rotate_id).parent(); 208 | rt_grandparent = rt_parent.parent(); 209 | rt_resize_width_new_parent = rt_parent.innerWidth(); 210 | rt_resize_width_new_grandparent = rt_grandparent.innerWidth(); 211 | 212 | // Now calculate the largest and smallest change in size 213 | rt_resize_parent_change = rt_resize_width_new_parent - rt_resize_width_old_parent; 214 | rt_resize_grandparent_change = rt_resize_width_new_grandparent - rt_resize_width_old_grandparent; 215 | 216 | // Now decide how much to change things 217 | rt_resize_change = rt_resize_parent_change; 218 | if(rt_resize_change == 0) { 219 | rt_resize_change = rt_resize_grandparent_change; 220 | } 221 | if(rotate_wp_debug) { 222 | console.log('Parent change: '+rt_resize_parent_change); 223 | console.log('Grandparent change: '+rt_resize_grandparent_change); 224 | console.log('Old box width: '+rt_resize_target_width); 225 | console.log('New target width: '+ (rt_resize_target_width + rt_resize_change)); 226 | console.log('rt_max_width: '+ (rt_resize_target_width + rt_resize_change)); 227 | } 228 | if(rt_max_width == null) { 229 | rt_max_width = rt_resize_target_tweet; 230 | } 231 | if(rt_resize_change != 0) { 232 | var rt_oldheight = 0; 233 | var rt_oldcontainerheight = jQuery(rotate_id).height(); 234 | jQuery(rotate_id + ' .rotatingtweet').height('auto'); 235 | jQuery(rotate_id + ' .rotatingtweet').each( function() { 236 | var rt_test_height = jQuery(this).height(); 237 | if(rotate_wp_debug) { 238 | console.log('Old tweet height: '+ rt_test_height); 239 | } 240 | if(rt_test_height > rt_oldheight ) { 241 | rt_oldheight = rt_test_height; 242 | }; 243 | }); 244 | if(rotate_wp_debug) { 245 | console.log('Old container height: '+ rt_oldcontainerheight); 246 | console.log('Old height: '+ rt_oldheight); 247 | } 248 | var rt_old_box_height = jQuery(rotate_id).height(); 249 | if(rotate_wp_debug) { 250 | console.log('Old container height' + rt_old_box_height ) 251 | } 252 | jQuery(rt_children_id).width(rt_max_width + rt_resize_change ); 253 | jQuery(rt_children_meta_id).width(rt_max_width + rt_resize_change ); 254 | jQuery(rotate_id + ' .rtw_main').width(rt_resize_target_main + rt_resize_change ); 255 | jQuery(rotate_id + ' .rotatingtweet').width(rt_resize_target_tweet + rt_resize_change ); 256 | jQuery(rotate_id + ' .rtw_meta').width(rt_resize_target_meta + rt_resize_change ); 257 | jQuery(rotate_id).width(rt_resize_target_width + rt_resize_change ); 258 | // Now update the variables 259 | rt_resize_target_width = rt_resize_target_width + rt_resize_change; 260 | rt_resize_target_main = rt_resize_target_main + rt_resize_change; 261 | rt_resize_target_tweet = rt_resize_target_tweet + rt_resize_change; 262 | rt_max_width = rt_max_width + rt_resize_change; 263 | rt_resize_target_meta = rt_resize_target_meta + rt_resize_change; 264 | rt_resize_width_old_parent = rt_parent.innerWidth(); 265 | rt_resize_width_old_grandparent = rt_grandparent.innerWidth(); 266 | // Now we need to fix the heights 267 | var rt_newheight = 0; 268 | jQuery(rotate_id + ' .rotatingtweet').height('auto'); 269 | jQuery(rotate_id + ' .rotatingtweet').each( function() { 270 | var rt_test_height = jQuery(this).height(); 271 | if(rotate_wp_debug) { 272 | console.log('New tweet height: '+ rt_test_height); 273 | } 274 | if(rt_test_height > rt_newheight ) { 275 | rt_newheight = rt_test_height; 276 | }; 277 | }); 278 | if(rotate_wp_debug) { 279 | console.log('New height: '+ rt_newheight); 280 | } 281 | if(rt_newheight > 0) { 282 | jQuery(rotate_id).height( Math.max( rt_oldcontainerheight + rt_newheight - rt_oldheight,rt_newheight) ); 283 | } 284 | } 285 | }); 286 | }); 287 | // Script to show mouseover effects when going over the Twitter intents 288 | jQuery('.rtw_intents a').hover(function() { 289 | var rtw_src = jQuery(this).find('img').attr('src'); 290 | var clearOutHovers = /_hover.png$/; 291 | jQuery(this).find('img').attr('src',rtw_src.replace(clearOutHovers,".png")); 292 | var rtw_src = jQuery(this).find('img').attr('src'); 293 | var srcReplacePattern = /.png$/; 294 | jQuery(this).find('img').attr('src',rtw_src.replace(srcReplacePattern,"_hover.png")); 295 | },function() { 296 | var rtw_src = jQuery(this).find('img').attr('src'); 297 | var clearOutHovers = /_hover.png/; 298 | jQuery(this).find('img').attr('src',rtw_src.replace(clearOutHovers,".png")); 299 | }); 300 | jQuery('.rtw_wide .rtw_intents').hide(); 301 | jQuery('.rtw_expand').show(); 302 | jQuery('.rotatingtweets').has('.rtw_wide').hover(function() { 303 | jQuery(this).find('.rtw_intents').show(); 304 | },function() { 305 | jQuery(this).find('.rtw_intents').hide(); 306 | }); 307 | }); 308 | /* And call the Twitter script while we're at it! */ 309 | /* Standard script to call Twitter */ 310 | !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs"); -------------------------------------------------------------------------------- /js/rotating_tweet.min.js: -------------------------------------------------------------------------------- 1 | jQuery(document).ready(function(){jQuery(".rotatingtweets").each(function(){var e="#"+this.id,t="."+this.id,r=jQuery(this).data("cycle-timeout"),i=jQuery(this).data("cycle-fx"),n=jQuery(this).data("cycle-speed"),o=jQuery(this).data("cycle-pager"),a=jQuery(this).data("cycle-pager-template"),s=jQuery(this).hasClass("wp_debug");("undefined"==typeof console||"undefined"==typeof console.log)&&(s=!1),null==i&&(i="scrollUp");var h="auto",g=jQuery(e).parent(),c=jQuery(e).parent().parent(),l=Math.min(g.innerWidth()-parseFloat(g.css("padding-left"))-parseFloat(g.css("padding-right")),c.innerWidth()-parseFloat(c.css("padding-left"))-parseFloat(c.css("padding-right"))-parseFloat(g.css("padding-left"))-parseFloat(g.css("padding-right"))-parseFloat(g.css("margin-left"))-parseFloat(g.css("margin-right"))),d=l-parseFloat(jQuery(this).css("padding-left"))-parseFloat(jQuery(this).css("padding-right"))-parseFloat(jQuery(this).css("margin-left"))-parseFloat(jQuery(this).css("margin-right"))-parseFloat(jQuery(this).css("border-left"))-parseFloat(jQuery(this).css("border-right")),u=1;null==d&&(u=0),s&&(console.log("============================"),console.log("self_width = "+jQuery(e).innerWidth()),console.log("parent_width = "+g.innerWidth()),console.log("grandparent_width = "+c.innerWidth()),console.log("rt_target_container_width = "+l),console.log("rt_target_width = "+d),console.log("rotate_timeout = "+r),console.log("rotate_speed = "+n),console.log("rotate_fx = "+i),console.log("rotate_pager = "+o),console.log("rotate_pager_template = "+a));var y={pause:1,height:h,timeout:r,cleartypeNoBg:!0,width:d,prev:t+"_rtw_prev",next:t+"_rtw_next",fx:i,fit:u,speed:n};r>0?y.timeout=r:(y.continuous=!0,y.easing="linear"),"undefined"!=typeof o&&(y.pager=e+"_rtw_pager","undefined"!=typeof a&&(y.pagerAnchorBuilder=function(){return a})),s&&console.log(y),jQuery(e).cycle(y);var _=jQuery(e).height();if(s&&console.log("Initial height: "+_),1>_){var p=e+" .rotatingtweet",_=0;jQuery(p).each(function(){var e=jQuery(this).height();e>_&&(_=e)}),_+=20;var h=_+"px";y.rt_height_px=h,s&&console.log("Resetting height to rt_height_px "+h),jQuery(e).cycle("destroy"),jQuery(e).cycle(y)}var p=e+" .rtw_info",w=e+" .rtw_wide_icon a img",j=e+" .rtw_wide_block",Q=jQuery(p).length,f=e+" .rtw_meta";if(Q>0){if(jQuery(w).length>0){s&&(console.log("Adjusting widths for 'Official Twitter Version 2'"),console.log("- Width of Rotating Tweets container: "+jQuery(this).width()),console.log("- Width of the icon container: "+jQuery(w).show().width()));var m=0;jQuery(w).each(function(){newiconsize=jQuery(this).width(),newiconsize>m&&(m=newiconsize)}),s&&console.log("- Width of the icon: "+m),m>0&&jQuery(j).css("padding-left",m+10+"px")}s&&(console.log("Now check for 'padding-left'"),console.log("- leftpadding - text : "+jQuery(j).css("padding-left")+" and value: "+parseFloat(jQuery(j).css("padding-left"))));var v=jQuery(e).width();"undefined"!=typeof jQuery(j).css("padding-left")?(v=v-parseFloat(jQuery(j).css("padding-left"))-1,s&&console.log("- Padding is not undefined")):s&&console.log("- Padding IS undefined - leave width unchanged"),s&&console.log("- rt_max_width: "+v),jQuery(p).width(v),jQuery(f).width(v)}var z=g.innerWidth(),F=c.innerWidth(),x=z,W=F,N=0,O=0,b=jQuery(e).width(),B=jQuery(e+" .rtw_main").width(),E=jQuery(e+" .rotatingtweet").width(),I=jQuery(e+" .rtw_meta").width();jQuery(window).resize(function(){if(g=jQuery(e).parent(),c=g.parent(),x=g.innerWidth(),W=c.innerWidth(),N=x-z,O=W-F,rt_resize_change=N,0==rt_resize_change&&(rt_resize_change=O),s&&(console.log("Parent change: "+N),console.log("Grandparent change: "+O),console.log("Old box width: "+b),console.log("New target width: "+(b+rt_resize_change)),console.log("rt_max_width: "+(b+rt_resize_change))),null==v&&(v=E),0!=rt_resize_change){var t=0,r=jQuery(e).height();jQuery(e+" .rotatingtweet").height("auto"),jQuery(e+" .rotatingtweet").each(function(){var e=jQuery(this).height();s&&console.log("Old tweet height: "+e),e>t&&(t=e)}),s&&(console.log("Old container height: "+r),console.log("Old height: "+t));var i=jQuery(e).height();s&&console.log("Old container height"+i),jQuery(p).width(v+rt_resize_change),jQuery(f).width(v+rt_resize_change),jQuery(e+" .rtw_main").width(B+rt_resize_change),jQuery(e+" .rotatingtweet").width(E+rt_resize_change),jQuery(e+" .rtw_meta").width(I+rt_resize_change),jQuery(e).width(b+rt_resize_change),b+=rt_resize_change,B+=rt_resize_change,E+=rt_resize_change,v+=rt_resize_change,I+=rt_resize_change,z=g.innerWidth(),F=c.innerWidth();var n=0;jQuery(e+" .rotatingtweet").height("auto"),jQuery(e+" .rotatingtweet").each(function(){var e=jQuery(this).height();s&&console.log("New tweet height: "+e),e>n&&(n=e)}),s&&console.log("New height: "+n),n>0&&jQuery(e).height(r+n-t)}})}),jQuery(".rtw_intents a").hover(function(){var e=jQuery(this).find("img").attr("src"),t=/_hover.png$/;jQuery(this).find("img").attr("src",e.replace(t,".png"));var e=jQuery(this).find("img").attr("src"),r=/.png$/;jQuery(this).find("img").attr("src",e.replace(r,"_hover.png"))},function(){var e=jQuery(this).find("img").attr("src"),t=/_hover.png/;jQuery(this).find("img").attr("src",e.replace(t,".png"))}),jQuery(".rtw_wide .rtw_intents").hide(),jQuery(".rtw_expand").show(),jQuery(".rotatingtweets").has(".rtw_wide").hover(function(){jQuery(this).find(".rtw_intents").show()},function(){jQuery(this).find(".rtw_intents").hide()})}),!function(e,t,r){var i,n=e.getElementsByTagName(t)[0];e.getElementById(r)||(i=e.createElement(t),i.id=r,i.src="https://platform.twitter.com/widgets.js",n.parentNode.insertBefore(i,n))}(document,"script","twitter-wjs"); -------------------------------------------------------------------------------- /js/rotating_tweet_admin.js: -------------------------------------------------------------------------------- 1 | /* 2 | Script to cycle the rotating tweets 3 | */ 4 | 5 | jQuery(document).ready(function() { 6 | function rotatingtweets_runselect() { 7 | // Script to show or hide display options on start up 8 | jQuery('input.rtw_ad_official:checked').each(function() { 9 | var response = jQuery(this).attr('value'); 10 | if( response == 0) { 11 | jQuery(this).parent().find('.rtw_ad_tw_det').show('fast'); 12 | } else { 13 | jQuery(this).parent().find('.rtw_ad_tw_det').hide('fast'); 14 | } 15 | }); 16 | // Script to show or hide display options when box is checked 17 | jQuery('.rtw_ad_official').change(function() { 18 | var response = jQuery(this).attr('value'); 19 | if( response == 0) { 20 | jQuery(this).parent().find('.rtw_ad_tw_det').show('fast'); 21 | } else { 22 | jQuery(this).parent().find('.rtw_ad_tw_det').hide('fast'); 23 | } 24 | }); 25 | // Script to show or hide display options on start up 26 | jQuery('input.rtw_ad_type:checked').each(function() { 27 | var response = jQuery(this).attr('value'); 28 | if( response == 3) { 29 | jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_list_tag').show('fast'); 30 | } else { 31 | jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_list_tag').hide('fast'); 32 | } 33 | }); 34 | // Script to show or hide display options when box is checked 35 | jQuery('.rtw_ad_type').change(function() { 36 | var response = jQuery(this).attr('value'); 37 | if( response == 3) { 38 | jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_list_tag').show('fast'); 39 | } else { 40 | jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_list_tag').hide('fast'); 41 | } 42 | if( response == 2) { 43 | jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_search').show(); 44 | jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_not_search').hide(); 45 | // jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_sf').hide('fast'); 46 | } else { 47 | jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_search').hide(); 48 | jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_not_search').show(); 49 | // jQuery(this).closest('.widget-content,.panel-dialog').find('.rtw_ad_sf').show('fast'); 50 | } 51 | }); 52 | } 53 | rotatingtweets_runselect(); 54 | 55 | jQuery(document).on('widget-updated widget-added', function(){ 56 | rotatingtweets_runselect(); 57 | }); 58 | jQuery(document).on('panelsopen', function() { 59 | rotatingtweets_runselect(); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /js/rotatingtweets_v2.js: -------------------------------------------------------------------------------- 1 | /* 2 | Add some transitions 3 | */ 4 | 5 | (function($) { 6 | "use strict"; 7 | 8 | $.fn.cycle2.transitions.scrollDown = { 9 | before: function( opts, curr, next, fwd ) { 10 | opts.API.stackSlides( opts, curr, next, fwd ); 11 | var width = opts.container.css('overflow','visible').width(); 12 | var height = opts.container.css('overflow','hidden').height(); 13 | opts.cssBefore = { top: fwd ? -height : height, left: 0, visibility: 'visible', opacity: 1, display: 'block' ,width:width }; 14 | opts.animIn = { top: 0 }; 15 | opts.animOut = { top: fwd ? height : -height }; 16 | } 17 | }; 18 | $.fn.cycle2.transitions.scrollUp = { 19 | before: function( opts, curr, next, fwd ) { 20 | opts.API.stackSlides( opts, curr, next, fwd ); 21 | var width = opts.container.css('overflow','visible').width(); 22 | var height = opts.container.css('overflow','hidden').height(); 23 | opts.cssBefore = { top: fwd ? height : -height, left: 0, visibility: 'visible', opacity: 1, display: 'block' ,width:width }; 24 | opts.animIn = { top: 0 }; 25 | opts.animOut = { top: fwd ? -height : height }; 26 | } 27 | }; 28 | $.fn.cycle2.transitions.scrollLeft = { 29 | before: function( opts, curr, next, fwd ) { 30 | opts.API.stackSlides( opts, curr, next, fwd ); 31 | var width = opts.container.css('overflow','hidden').width(); 32 | opts.cssBefore = { width: width, left : width+20, top: 0, visibility: 'visible', opacity: 1, display: 'block' }; 33 | opts.animIn = { left: 0 }; 34 | opts.animOut = { left : -width-20,width:width }; 35 | } 36 | }; 37 | 38 | $.fn.cycle2.transitions.scrollRight = { 39 | before: function( opts, curr, next, fwd ) { 40 | opts.API.stackSlides( opts, curr, next, fwd ); 41 | var width = opts.container.css('overflow','hidden').width(); 42 | opts.cssBefore = { width: width, left : -width-20, top: 0, visibility: 'visible', opacity: 1, display: 'block' }; 43 | opts.animIn = { left: 0 }; 44 | opts.animOut = { left : width+20 }; 45 | } 46 | }; 47 | 48 | $.fn.cycle2.transitions.toss = { 49 | before: function( opts, curr, next, fwd ) { 50 | opts.API.stackSlides( opts, curr, next, fwd ); 51 | var width = opts.container.css('overflow','visible').width(); 52 | var height = opts.container.css('overflow','visible').height(); 53 | opts.cssBefore = { left: 0, top: 0, opacity: 1, visibility: 'visible', display: 'block',width:width }; 54 | opts.animIn = { left: 0 }; 55 | opts.animOut = { left : width*2, top:-height/2 , opacity:0, width:width, display:'block' }; 56 | } 57 | }; 58 | 59 | $.fn.cycle2.transitions.scrollLeftGap = { 60 | before: function( opts, curr, next, fwd ) { 61 | opts.API.stackSlides( opts, curr, next, fwd ); 62 | var width = opts.container.css('overflow','hidden').width(); 63 | opts.cssBefore = { width: width, left : width+100, top: 0, visibility: 'visible', opacity: 1, display: 'block' }; 64 | opts.animIn = { left: 0 }; 65 | opts.animOut = { left : -width-100,width:width }; 66 | } 67 | }; 68 | 69 | })(jQuery); 70 | /* 71 | Script to cycle the rotating tweets 72 | */ 73 | jQuery(document).ready(function() { 74 | // Script to show mouseover effects when going over the Twitter intents 75 | var rtw_src, 76 | clearOutHovers = /_hover.png$/, 77 | srcReplacePattern = /.png$/; 78 | jQuery('.rtw_intents a').hover(function() { 79 | rtw_src = jQuery(this).find('img').attr('src'); 80 | jQuery(this).find('img').attr('src',rtw_src.replace(clearOutHovers,".png")); 81 | rtw_src = jQuery(this).find('img').attr('src'); 82 | jQuery(this).find('img').attr('src',rtw_src.replace(srcReplacePattern,"_hover.png")); 83 | },function() { 84 | rtw_src = jQuery(this).find('img').attr('src'); 85 | jQuery(this).find('img').attr('src',rtw_src.replace(clearOutHovers,".png")); 86 | }); 87 | jQuery('.rotatingtweets').children().not('.cycle-carousel-wrap').has('.rtw_wide').find('.rtw_wide .rtw_intents').hide(); 88 | jQuery('.rotatingtweets').children().not('.cycle-carousel-wrap').has('.rtw_wide').find('.rtw_expand').show(); 89 | jQuery('.rotatingtweets').children().not('.cycle-carousel-wrap').has('.rtw_wide').hover(function() { 90 | jQuery(this).find('.rtw_intents').show(); 91 | },function() { 92 | jQuery(this).find('.rtw_intents').hide(); 93 | }); 94 | }); 95 | /* And call the Twitter script while we're at it! */ 96 | /* Standard script to call Twitter */ 97 | !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs"); -------------------------------------------------------------------------------- /js/rotatingtweets_v2_cyclone.js: -------------------------------------------------------------------------------- 1 | /* 2 | Add some transitions 3 | */ 4 | (function($) { 5 | "use strict"; 6 | 7 | $.fn.cycle.transitions.scrollDown = { 8 | before: function( opts, curr, next, fwd ) { 9 | opts.API.stackSlides( opts, curr, next, fwd ); 10 | var width = opts.container.css('overflow','visible').width(); 11 | var height = opts.container.css('overflow','hidden').height(); 12 | opts.cssBefore = { top: fwd ? -height : height, left: 0, visibility: 'visible', opacity: 1, display: 'block' ,width:width }; 13 | opts.animIn = { top: 0 }; 14 | opts.animOut = { top: fwd ? height : -height }; 15 | } 16 | }; 17 | $.fn.cycle.transitions.scrollUp = { 18 | before: function( opts, curr, next, fwd ) { 19 | opts.API.stackSlides( opts, curr, next, fwd ); 20 | var width = opts.container.css('overflow','visible').width(); 21 | var height = opts.container.css('overflow','hidden').height(); 22 | opts.cssBefore = { top: fwd ? height : -height, left: 0, visibility: 'visible', opacity: 1, display: 'block' ,width:width }; 23 | opts.animIn = { top: 0 }; 24 | opts.animOut = { top: fwd ? -height : height }; 25 | } 26 | }; 27 | $.fn.cycle.transitions.scrollLeft = { 28 | before: function( opts, curr, next, fwd ) { 29 | opts.API.stackSlides( opts, curr, next, fwd ); 30 | var width = opts.container.css('overflow','hidden').width(); 31 | opts.cssBefore = { width: width, left : width+20, top: 0, visibility: 'visible', opacity: 1, display: 'block' }; 32 | opts.animIn = { left: 0 }; 33 | opts.animOut = { left : -width-20,width:width }; 34 | } 35 | }; 36 | 37 | $.fn.cycle.transitions.scrollRight = { 38 | before: function( opts, curr, next, fwd ) { 39 | opts.API.stackSlides( opts, curr, next, fwd ); 40 | var width = opts.container.css('overflow','hidden').width(); 41 | opts.cssBefore = { width: width, left : -width-20, top: 0, visibility: 'visible', opacity: 1, display: 'block' }; 42 | opts.animIn = { left: 0 }; 43 | opts.animOut = { left : width+20 }; 44 | } 45 | }; 46 | 47 | $.fn.cycle.transitions.toss = { 48 | before: function( opts, curr, next, fwd ) { 49 | opts.API.stackSlides( opts, curr, next, fwd ); 50 | var width = opts.container.css('overflow','visible').width(); 51 | var height = opts.container.css('overflow','visible').height(); 52 | opts.cssBefore = { left: 0, top: 0, opacity: 1, display: 'block', visibility: 'visible', width:width }; 53 | opts.animIn = { left: 0 }; 54 | opts.animOut = { left : width*2, top:-height/2 , opacity:0, width:width, display:'block' }; 55 | } 56 | }; 57 | 58 | $.fn.cycle.transitions.scrollLeftGap = { 59 | before: function( opts, curr, next, fwd ) { 60 | opts.API.stackSlides( opts, curr, next, fwd ); 61 | var width = opts.container.css('overflow','hidden').width(); 62 | opts.cssBefore = { width: width, left : width+100, top: 0, visibility: 'visible', opacity: 1, display: 'block' }; 63 | opts.animIn = { left: 0 }; 64 | opts.animOut = { left : -width-100,width:width }; 65 | } 66 | }; 67 | 68 | })(jQuery); 69 | /* 70 | Script to cycle the rotating tweets 71 | */ 72 | jQuery(document).ready(function() { 73 | // Not at all sure we need this 74 | jQuery('.rotatingtweets').cycle(); 75 | // Script to show mouseover effects when going over the Twitter intents 76 | var rtw_src, 77 | clearOutHovers = /_hover.png$/, 78 | srcReplacePattern = /.png$/; 79 | jQuery('.rtw_intents a').hover(function() { 80 | rtw_src = jQuery(this).find('img').attr('src'); 81 | jQuery(this).find('img').attr('src',rtw_src.replace(clearOutHovers,".png")); 82 | rtw_src = jQuery(this).find('img').attr('src'); 83 | jQuery(this).find('img').attr('src',rtw_src.replace(srcReplacePattern,"_hover.png")); 84 | },function() { 85 | rtw_src = jQuery(this).find('img').attr('src'); 86 | jQuery(this).find('img').attr('src',rtw_src.replace(clearOutHovers,".png")); 87 | }); 88 | jQuery('.rotatingtweets').children().not('.cycle-carousel-wrap').has('.rtw_wide').find('.rtw_wide .rtw_intents').hide(); 89 | jQuery('.rotatingtweets').children().not('.cycle-carousel-wrap').has('.rtw_wide').find('.rtw_expand').show(); 90 | jQuery('.rotatingtweets').children().not('.cycle-carousel-wrap').has('.rtw_wide').hover(function() { 91 | jQuery(this).find('.rtw_intents').show(); 92 | },function() { 93 | jQuery(this).find('.rtw_intents').hide(); 94 | }); 95 | }); 96 | /* And call the Twitter script while we're at it! */ 97 | /* Standard script to call Twitter */ 98 | !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs"); -------------------------------------------------------------------------------- /languages/rotatingtweets-de_DE.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/languages/rotatingtweets-de_DE.mo -------------------------------------------------------------------------------- /languages/rotatingtweets-fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/languages/rotatingtweets-fr_FR.mo -------------------------------------------------------------------------------- /languages/rotatingtweets-it_IT.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/languages/rotatingtweets-it_IT.mo -------------------------------------------------------------------------------- /languages/rotatingtweets-nl_NL.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/languages/rotatingtweets-nl_NL.mo -------------------------------------------------------------------------------- /languages/rotatingtweets-pt_BR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/languages/rotatingtweets-pt_BR.mo -------------------------------------------------------------------------------- /languages/rotatingtweets-sr_RS.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/languages/rotatingtweets-sr_RS.mo -------------------------------------------------------------------------------- /lib/WP_OAuth.php: -------------------------------------------------------------------------------- 1 | key = $key; 16 | $this->secret = $secret; 17 | $this->callback_url = $callback_url; 18 | } 19 | 20 | function __toString() { 21 | return "WP_OAuthConsumer[key=$this->key,secret=$this->secret]"; 22 | } 23 | } 24 | 25 | class WP_OAuthToken { 26 | // access tokens and request tokens 27 | public $key; 28 | public $secret; 29 | 30 | /** 31 | * key = the token 32 | * secret = the token secret 33 | */ 34 | function __construct($key, $secret) { 35 | $this->key = $key; 36 | $this->secret = $secret; 37 | } 38 | 39 | /** 40 | * generates the basic string serialization of a token that a server 41 | * would respond to request_token and access_token calls with 42 | */ 43 | function to_string() { 44 | return "oauth_token=" . 45 | WP_OAuthUtil::urlencode_rfc3986($this->key) . 46 | "&oauth_token_secret=" . 47 | WP_OAuthUtil::urlencode_rfc3986($this->secret); 48 | } 49 | 50 | function __toString() { 51 | return $this->to_string(); 52 | } 53 | } 54 | 55 | /** 56 | * A class for implementing a Signature Method 57 | * See section 9 ("Signing Requests") in the spec 58 | */ 59 | abstract class WP_OAuthSignatureMethod { 60 | /** 61 | * Needs to return the name of the Signature Method (ie HMAC-SHA1) 62 | * @return string 63 | */ 64 | abstract public function get_name(); 65 | 66 | /** 67 | * Build up the signature 68 | * NOTE: The output of this function MUST NOT be urlencoded. 69 | * the encoding is handled in WP_OAuthRequest when the final 70 | * request is serialized 71 | * @param WP_OAuthRequest $request 72 | * @param WP_OAuthConsumer $consumer 73 | * @param WP_OAuthToken $token 74 | * @return string 75 | */ 76 | abstract public function build_signature($request, $consumer, $token); 77 | 78 | /** 79 | * Verifies that a given signature is correct 80 | * @param WP_OAuthRequest $request 81 | * @param WP_OAuthConsumer $consumer 82 | * @param WP_OAuthToken $token 83 | * @param string $signature 84 | * @return bool 85 | */ 86 | public function check_signature($request, $consumer, $token, $signature) { 87 | $built = $this->build_signature($request, $consumer, $token); 88 | return $built == $signature; 89 | } 90 | } 91 | 92 | /** 93 | * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104] 94 | * where the Signature Base String is the text and the key is the concatenated values (each first 95 | * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&' 96 | * character (ASCII code 38) even if empty. 97 | * - Chapter 9.2 ("HMAC-SHA1") 98 | */ 99 | class WP_OAuthSignatureMethod_HMAC_SHA1 extends WP_OAuthSignatureMethod { 100 | function get_name() { 101 | return "HMAC-SHA1"; 102 | } 103 | 104 | public function build_signature($request, $consumer, $token) { 105 | $base_string = $request->get_signature_base_string(); 106 | $request->base_string = $base_string; 107 | 108 | $key_parts = array( 109 | $consumer->secret, 110 | ($token) ? $token->secret : "" 111 | ); 112 | 113 | $key_parts = WP_OAuthUtil::urlencode_rfc3986($key_parts); 114 | $key = implode('&', $key_parts); 115 | 116 | return base64_encode(hash_hmac('sha1', $base_string, $key, true)); 117 | } 118 | } 119 | 120 | /** 121 | * The PLAINTEXT method does not provide any security protection and SHOULD only be used 122 | * over a secure channel such as HTTPS. It does not use the Signature Base String. 123 | * - Chapter 9.4 ("PLAINTEXT") 124 | */ 125 | class WP_OAuthSignatureMethod_PLAINTEXT extends WP_OAuthSignatureMethod { 126 | public function get_name() { 127 | return "PLAINTEXT"; 128 | } 129 | 130 | /** 131 | * oauth_signature is set to the concatenated encoded values of the Consumer Secret and 132 | * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is 133 | * empty. The result MUST be encoded again. 134 | * - Chapter 9.4.1 ("Generating Signatures") 135 | * 136 | * Please note that the second encoding MUST NOT happen in the SignatureMethod, as 137 | * WP_OAuthRequest handles this! 138 | */ 139 | public function build_signature($request, $consumer, $token) { 140 | $key_parts = array( 141 | $consumer->secret, 142 | ($token) ? $token->secret : "" 143 | ); 144 | 145 | $key_parts = WP_OAuthUtil::urlencode_rfc3986($key_parts); 146 | $key = implode('&', $key_parts); 147 | $request->base_string = $key; 148 | 149 | return $key; 150 | } 151 | } 152 | 153 | /** 154 | * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in 155 | * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for 156 | * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a 157 | * verified way to the Service Provider, in a manner which is beyond the scope of this 158 | * specification. 159 | * - Chapter 9.3 ("RSA-SHA1") 160 | */ 161 | abstract class WP_OAuthSignatureMethod_RSA_SHA1 extends WP_OAuthSignatureMethod { 162 | public function get_name() { 163 | return "RSA-SHA1"; 164 | } 165 | 166 | // Up to the SP to implement this lookup of keys. Possible ideas are: 167 | // (1) do a lookup in a table of trusted certs keyed off of consumer 168 | // (2) fetch via http using a url provided by the requester 169 | // (3) some sort of specific discovery code based on request 170 | // 171 | // Either way should return a string representation of the certificate 172 | protected abstract function fetch_public_cert(&$request); 173 | 174 | // Up to the SP to implement this lookup of keys. Possible ideas are: 175 | // (1) do a lookup in a table of trusted certs keyed off of consumer 176 | // 177 | // Either way should return a string representation of the certificate 178 | protected abstract function fetch_private_cert(&$request); 179 | 180 | public function build_signature($request, $consumer, $token) { 181 | $base_string = $request->get_signature_base_string(); 182 | $request->base_string = $base_string; 183 | 184 | // Fetch the private key cert based on the request 185 | $cert = $this->fetch_private_cert($request); 186 | 187 | // Pull the private key ID from the certificate 188 | $privatekeyid = openssl_get_privatekey($cert); 189 | 190 | // Sign using the key 191 | $ok = openssl_sign($base_string, $signature, $privatekeyid); 192 | 193 | // Release the key resource 194 | openssl_free_key($privatekeyid); 195 | 196 | return base64_encode($signature); 197 | } 198 | 199 | public function check_signature($request, $consumer, $token, $signature) { 200 | $decoded_sig = base64_decode($signature); 201 | 202 | $base_string = $request->get_signature_base_string(); 203 | 204 | // Fetch the public key cert based on the request 205 | $cert = $this->fetch_public_cert($request); 206 | 207 | // Pull the public key ID from the certificate 208 | $publickeyid = openssl_get_publickey($cert); 209 | 210 | // Check the computed signature against the one passed in the query 211 | $ok = openssl_verify($base_string, $decoded_sig, $publickeyid); 212 | 213 | // Release the key resource 214 | openssl_free_key($publickeyid); 215 | 216 | return $ok == 1; 217 | } 218 | } 219 | 220 | class WP_OAuthRequest { 221 | private $parameters; 222 | private $http_method; 223 | private $http_url; 224 | // for debug purposes 225 | public $base_string; 226 | public static $version = '1.0'; 227 | public static $POST_INPUT = 'php://input'; 228 | 229 | function __construct($http_method, $http_url, $parameters=NULL) { 230 | @$parameters or $parameters = array(); 231 | $parameters = array_merge( WP_OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters); 232 | $this->parameters = $parameters; 233 | $this->http_method = $http_method; 234 | $this->http_url = $http_url; 235 | } 236 | 237 | 238 | /** 239 | * attempt to build up a request from what was passed to the server 240 | */ 241 | public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) { 242 | $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") 243 | ? 'http' 244 | : 'https'; 245 | @$http_url or $http_url = $scheme . 246 | '://' . $_SERVER['HTTP_HOST'] . 247 | ':' . 248 | $_SERVER['SERVER_PORT'] . 249 | $_SERVER['REQUEST_URI']; 250 | @$http_method or $http_method = $_SERVER['REQUEST_METHOD']; 251 | 252 | // We weren't handed any parameters, so let's find the ones relevant to 253 | // this request. 254 | // If you run XML-RPC or similar you should use this to provide your own 255 | // parsed parameter-list 256 | if (!$parameters) { 257 | // Find request headers 258 | $request_headers = WP_OAuthUtil::get_headers(); 259 | 260 | // Parse the query-string to find GET parameters 261 | $parameters = WP_OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); 262 | 263 | // It's a POST request of the proper content-type, so parse POST 264 | // parameters and add those overriding any duplicates from GET 265 | if ($http_method == "POST" 266 | && @strstr($request_headers["Content-Type"], 267 | "application/x-www-form-urlencoded") 268 | ) { 269 | $post_data = WP_OAuthUtil::parse_parameters( 270 | file_get_contents(self::$POST_INPUT) 271 | ); 272 | $parameters = array_merge($parameters, $post_data); 273 | } 274 | 275 | // We have a Authorization-header with WP_OAuth data. Parse the header 276 | // and add those overriding any duplicates from GET or POST 277 | if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") { 278 | $header_parameters = WP_OAuthUtil::split_header( 279 | $request_headers['Authorization'] 280 | ); 281 | $parameters = array_merge($parameters, $header_parameters); 282 | } 283 | 284 | } 285 | 286 | return new WP_OAuthRequest($http_method, $http_url, $parameters); 287 | } 288 | 289 | /** 290 | * pretty much a helper function to set up the request 291 | */ 292 | public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) { 293 | @$parameters or $parameters = array(); 294 | $defaults = array("oauth_version" => WP_OAuthRequest::$version, 295 | "oauth_nonce" => WP_OAuthRequest::generate_nonce(), 296 | "oauth_timestamp" => WP_OAuthRequest::generate_timestamp(), 297 | "oauth_consumer_key" => $consumer->key); 298 | if ($token) 299 | $defaults['oauth_token'] = $token->key; 300 | 301 | $parameters = array_merge($defaults, $parameters); 302 | 303 | return new WP_OAuthRequest($http_method, $http_url, $parameters); 304 | } 305 | 306 | public function set_parameter($name, $value, $allow_duplicates = true) { 307 | if ($allow_duplicates && isset($this->parameters[$name])) { 308 | // We have already added parameter(s) with this name, so add to the list 309 | if (is_scalar($this->parameters[$name])) { 310 | // This is the first duplicate, so transform scalar (string) 311 | // into an array so we can add the duplicates 312 | $this->parameters[$name] = array($this->parameters[$name]); 313 | } 314 | 315 | $this->parameters[$name][] = $value; 316 | } else { 317 | $this->parameters[$name] = $value; 318 | } 319 | } 320 | 321 | public function get_parameter($name) { 322 | return isset($this->parameters[$name]) ? $this->parameters[$name] : null; 323 | } 324 | 325 | public function get_parameters() { 326 | return $this->parameters; 327 | } 328 | 329 | public function unset_parameter($name) { 330 | unset($this->parameters[$name]); 331 | } 332 | 333 | /** 334 | * The request parameters, sorted and concatenated into a normalized string. 335 | * @return string 336 | */ 337 | public function get_signable_parameters() { 338 | // Grab all parameters 339 | $params = $this->parameters; 340 | 341 | // Remove oauth_signature if present 342 | // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") 343 | if (isset($params['oauth_signature'])) { 344 | unset($params['oauth_signature']); 345 | } 346 | 347 | return WP_OAuthUtil::build_http_query($params); 348 | } 349 | 350 | /** 351 | * Returns the base string of this request 352 | * 353 | * The base string defined as the method, the url 354 | * and the parameters (normalized), each urlencoded 355 | * and the concated with &. 356 | */ 357 | public function get_signature_base_string() { 358 | $parts = array( 359 | $this->get_normalized_http_method(), 360 | $this->get_normalized_http_url(), 361 | $this->get_signable_parameters() 362 | ); 363 | 364 | $parts = WP_OAuthUtil::urlencode_rfc3986($parts); 365 | 366 | return implode('&', $parts); 367 | } 368 | 369 | /** 370 | * just uppercases the http method 371 | */ 372 | public function get_normalized_http_method() { 373 | return strtoupper($this->http_method); 374 | } 375 | 376 | /** 377 | * parses the url and rebuilds it to be 378 | * scheme://host/path 379 | */ 380 | public function get_normalized_http_url() { 381 | $parts = parse_url($this->http_url); 382 | 383 | if(isset($parts['port'])): 384 | $port = @$parts['port']; 385 | else: 386 | $port = 0; 387 | endif; 388 | $scheme = $parts['scheme']; 389 | $host = $parts['host']; 390 | $path = @$parts['path']; 391 | 392 | $port or $port = ($scheme == 'https') ? '443' : '80'; 393 | 394 | if (($scheme == 'https' && $port != '443') 395 | || ($scheme == 'http' && $port != '80')) { 396 | $host = "$host:$port"; 397 | } 398 | return "$scheme://$host$path"; 399 | } 400 | 401 | /** 402 | * builds a url usable for a GET request 403 | */ 404 | public function to_url() { 405 | $post_data = $this->to_postdata(); 406 | $out = $this->get_normalized_http_url(); 407 | if ($post_data) { 408 | $out .= '?'.$post_data; 409 | } 410 | return $out; 411 | } 412 | 413 | /** 414 | * builds the data one would send in a POST request 415 | */ 416 | public function to_postdata() { 417 | return WP_OAuthUtil::build_http_query($this->parameters); 418 | } 419 | 420 | /** 421 | * builds the Authorization: header 422 | */ 423 | public function to_header($realm=null) { 424 | $first = true; 425 | if($realm) { 426 | $out = 'Authorization: OAuth realm="' . WP_OAuthUtil::urlencode_rfc3986($realm) . '"'; 427 | $first = false; 428 | } else 429 | $out = 'Authorization: OAuth'; 430 | 431 | $total = array(); 432 | foreach ($this->parameters as $k => $v) { 433 | if (substr($k, 0, 5) != "oauth") continue; 434 | if (is_array($v)) { 435 | throw new WP_OAuthException('Arrays not supported in headers'); 436 | } 437 | $out .= ($first) ? ' ' : ','; 438 | $out .= WP_OAuthUtil::urlencode_rfc3986($k) . 439 | '="' . 440 | WP_OAuthUtil::urlencode_rfc3986($v) . 441 | '"'; 442 | $first = false; 443 | } 444 | return $out; 445 | } 446 | 447 | public function __toString() { 448 | return $this->to_url(); 449 | } 450 | 451 | 452 | public function sign_request($signature_method, $consumer, $token) { 453 | $this->set_parameter( 454 | "oauth_signature_method", 455 | $signature_method->get_name(), 456 | false 457 | ); 458 | $signature = $this->build_signature($signature_method, $consumer, $token); 459 | $this->set_parameter("oauth_signature", $signature, false); 460 | } 461 | 462 | public function build_signature($signature_method, $consumer, $token) { 463 | $signature = $signature_method->build_signature($this, $consumer, $token); 464 | return $signature; 465 | } 466 | 467 | /** 468 | * util function: current timestamp 469 | */ 470 | private static function generate_timestamp() { 471 | return time(); 472 | } 473 | 474 | /** 475 | * util function: current nonce 476 | */ 477 | private static function generate_nonce() { 478 | $mt = microtime(); 479 | $rand = mt_rand(); 480 | 481 | return md5($mt . $rand); // md5s look nicer than numbers 482 | } 483 | } 484 | 485 | class WP_OAuthServer { 486 | protected $timestamp_threshold = 300; // in seconds, five minutes 487 | protected $version = '1.0'; // hi blaine 488 | protected $signature_methods = array(); 489 | 490 | protected $data_store; 491 | 492 | function __construct($data_store) { 493 | $this->data_store = $data_store; 494 | } 495 | 496 | public function add_signature_method($signature_method) { 497 | $this->signature_methods[$signature_method->get_name()] = 498 | $signature_method; 499 | } 500 | 501 | // high level functions 502 | 503 | /** 504 | * process a request_token request 505 | * returns the request token on success 506 | */ 507 | public function fetch_request_token(&$request) { 508 | $this->get_version($request); 509 | 510 | $consumer = $this->get_consumer($request); 511 | 512 | // no token required for the initial token request 513 | $token = NULL; 514 | 515 | $this->check_signature($request, $consumer, $token); 516 | 517 | // Rev A change 518 | $callback = $request->get_parameter('oauth_callback'); 519 | $new_token = $this->data_store->new_request_token($consumer, $callback); 520 | 521 | return $new_token; 522 | } 523 | 524 | /** 525 | * process an access_token request 526 | * returns the access token on success 527 | */ 528 | public function fetch_access_token(&$request) { 529 | $this->get_version($request); 530 | 531 | $consumer = $this->get_consumer($request); 532 | 533 | // requires authorized request token 534 | $token = $this->get_token($request, $consumer, "request"); 535 | 536 | $this->check_signature($request, $consumer, $token); 537 | 538 | // Rev A change 539 | $verifier = $request->get_parameter('oauth_verifier'); 540 | $new_token = $this->data_store->new_access_token($token, $consumer, $verifier); 541 | 542 | return $new_token; 543 | } 544 | 545 | /** 546 | * verify an api call, checks all the parameters 547 | */ 548 | public function verify_request(&$request) { 549 | $this->get_version($request); 550 | $consumer = $this->get_consumer($request); 551 | $token = $this->get_token($request, $consumer, "access"); 552 | $this->check_signature($request, $consumer, $token); 553 | return array($consumer, $token); 554 | } 555 | 556 | // Internals from here 557 | /** 558 | * version 1 559 | */ 560 | private function get_version(&$request) { 561 | $version = $request->get_parameter("oauth_version"); 562 | if (!$version) { 563 | // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. 564 | // Chapter 7.0 ("Accessing Protected Ressources") 565 | $version = '1.0'; 566 | } 567 | if ($version !== $this->version) { 568 | throw new WP_OAuthException("OAuth version '$version' not supported"); 569 | } 570 | return $version; 571 | } 572 | 573 | /** 574 | * figure out the signature with some defaults 575 | */ 576 | private function get_signature_method(&$request) { 577 | $signature_method = 578 | @$request->get_parameter("oauth_signature_method"); 579 | 580 | if (!$signature_method) { 581 | // According to chapter 7 ("Accessing Protected Ressources") the signature-method 582 | // parameter is required, and we can't just fallback to PLAINTEXT 583 | throw new WP_OAuthException('No signature method parameter. This parameter is required'); 584 | } 585 | 586 | if (!in_array($signature_method, 587 | array_keys($this->signature_methods))) { 588 | throw new WP_OAuthException( 589 | "Signature method '$signature_method' not supported " . 590 | "try one of the following: " . 591 | implode(", ", array_keys($this->signature_methods)) 592 | ); 593 | } 594 | return $this->signature_methods[$signature_method]; 595 | } 596 | 597 | /** 598 | * try to find the consumer for the provided request's consumer key 599 | */ 600 | private function get_consumer(&$request) { 601 | $consumer_key = @$request->get_parameter("oauth_consumer_key"); 602 | if (!$consumer_key) { 603 | throw new WP_OAuthException("Invalid consumer key"); 604 | } 605 | 606 | $consumer = $this->data_store->lookup_consumer($consumer_key); 607 | if (!$consumer) { 608 | throw new WP_OAuthException("Invalid consumer"); 609 | } 610 | 611 | return $consumer; 612 | } 613 | 614 | /** 615 | * try to find the token for the provided request's token key 616 | */ 617 | private function get_token(&$request, $consumer, $token_type="access") { 618 | $token_field = @$request->get_parameter('oauth_token'); 619 | $token = $this->data_store->lookup_token( 620 | $consumer, $token_type, $token_field 621 | ); 622 | if (!$token) { 623 | throw new WP_OAuthException("Invalid $token_type token: $token_field"); 624 | } 625 | return $token; 626 | } 627 | 628 | /** 629 | * all-in-one function to check the signature on a request 630 | * should guess the signature method appropriately 631 | */ 632 | private function check_signature(&$request, $consumer, $token) { 633 | // this should probably be in a different method 634 | $timestamp = @$request->get_parameter('oauth_timestamp'); 635 | $nonce = @$request->get_parameter('oauth_nonce'); 636 | 637 | $this->check_timestamp($timestamp); 638 | $this->check_nonce($consumer, $token, $nonce, $timestamp); 639 | 640 | $signature_method = $this->get_signature_method($request); 641 | 642 | $signature = $request->get_parameter('oauth_signature'); 643 | $valid_sig = $signature_method->check_signature( 644 | $request, 645 | $consumer, 646 | $token, 647 | $signature 648 | ); 649 | 650 | if (!$valid_sig) { 651 | throw new WP_OAuthException("Invalid signature"); 652 | } 653 | } 654 | 655 | /** 656 | * check that the timestamp is new enough 657 | */ 658 | private function check_timestamp($timestamp) { 659 | if( ! $timestamp ) 660 | throw new WP_OAuthException( 661 | 'Missing timestamp parameter. The parameter is required' 662 | ); 663 | 664 | // verify that timestamp is recentish 665 | $now = time(); 666 | if (abs($now - $timestamp) > $this->timestamp_threshold) { 667 | throw new WP_OAuthException( 668 | "Expired timestamp, yours $timestamp, ours $now" 669 | ); 670 | } 671 | } 672 | 673 | /** 674 | * check that the nonce is not repeated 675 | */ 676 | private function check_nonce($consumer, $token, $nonce, $timestamp) { 677 | if( ! $nonce ) 678 | throw new WP_OAuthException( 679 | 'Missing nonce parameter. The parameter is required' 680 | ); 681 | 682 | // verify that the nonce is uniqueish 683 | $found = $this->data_store->lookup_nonce( 684 | $consumer, 685 | $token, 686 | $nonce, 687 | $timestamp 688 | ); 689 | if ($found) { 690 | throw new WP_OAuthException("Nonce already used: $nonce"); 691 | } 692 | } 693 | 694 | } 695 | 696 | class WP_OAuthDataStore { 697 | function lookup_consumer($consumer_key) { 698 | // implement me 699 | } 700 | 701 | function lookup_token($consumer, $token_type, $token) { 702 | // implement me 703 | } 704 | 705 | function lookup_nonce($consumer, $token, $nonce, $timestamp) { 706 | // implement me 707 | } 708 | 709 | function new_request_token($consumer, $callback = null) { 710 | // return a new token attached to this consumer 711 | } 712 | 713 | function new_access_token($token, $consumer, $verifier = null) { 714 | // return a new access token attached to this consumer 715 | // for the user associated with this token if the request token 716 | // is authorized 717 | // should also invalidate the request token 718 | } 719 | 720 | } 721 | 722 | class WP_OAuthUtil { 723 | public static function urlencode_rfc3986($input) { 724 | if (is_array($input)) { 725 | return array_map(array('WP_OAuthUtil', 'urlencode_rfc3986'), $input); 726 | } else if (is_scalar($input)) { 727 | return str_replace( 728 | '+', 729 | ' ', 730 | str_replace('%7E', '~', rawurlencode($input)) 731 | ); 732 | } else { 733 | return ''; 734 | } 735 | } 736 | 737 | 738 | // This decode function isn't taking into consideration the above 739 | // modifications to the encoding process. However, this method doesn't 740 | // seem to be used anywhere so leaving it as is. 741 | public static function urldecode_rfc3986($string) { 742 | return urldecode($string); 743 | } 744 | 745 | // Utility function for turning the Authorization: header into 746 | // parameters, has to do some unescaping 747 | // Can filter out any non-oauth parameters if needed (default behaviour) 748 | public static function split_header($header, $only_allow_oauth_parameters = true) { 749 | $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/'; 750 | $offset = 0; 751 | $params = array(); 752 | while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) { 753 | $match = $matches[0]; 754 | $header_name = $matches[2][0]; 755 | $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0]; 756 | if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) { 757 | $params[$header_name] = WP_OAuthUtil::urldecode_rfc3986($header_content); 758 | } 759 | $offset = $match[1] + strlen($match[0]); 760 | } 761 | 762 | if (isset($params['realm'])) { 763 | unset($params['realm']); 764 | } 765 | 766 | return $params; 767 | } 768 | 769 | // helper to try to sort out headers for people who aren't running apache 770 | public static function get_headers() { 771 | if (function_exists('apache_request_headers')) { 772 | // we need this to get the actual Authorization: header 773 | // because apache tends to tell us it doesn't exist 774 | $headers = apache_request_headers(); 775 | 776 | // sanitize the output of apache_request_headers because 777 | // we always want the keys to be Cased-Like-This and arh() 778 | // returns the headers in the same case as they are in the 779 | // request 780 | $out = array(); 781 | foreach( $headers AS $key => $value ) { 782 | $key = str_replace( 783 | " ", 784 | "-", 785 | ucwords(strtolower(str_replace("-", " ", $key))) 786 | ); 787 | $out[$key] = $value; 788 | } 789 | } else { 790 | // otherwise we don't have apache and are just going to have to hope 791 | // that $_SERVER actually contains what we need 792 | $out = array(); 793 | if( isset($_SERVER['CONTENT_TYPE']) ) 794 | $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; 795 | if( isset($_ENV['CONTENT_TYPE']) ) 796 | $out['Content-Type'] = $_ENV['CONTENT_TYPE']; 797 | 798 | foreach ($_SERVER as $key => $value) { 799 | if (substr($key, 0, 5) == "HTTP_") { 800 | // this is chaos, basically it is just there to capitalize the first 801 | // letter of every word that is not an initial HTTP and strip HTTP 802 | // code from przemek 803 | $key = str_replace( 804 | " ", 805 | "-", 806 | ucwords(strtolower(str_replace("_", " ", substr($key, 5)))) 807 | ); 808 | $out[$key] = $value; 809 | } 810 | } 811 | } 812 | return $out; 813 | } 814 | 815 | // This function takes a input like a=b&a=c&d=e and returns the parsed 816 | // parameters like this 817 | // array('a' => array('b','c'), 'd' => 'e') 818 | public static function parse_parameters( $input ) { 819 | if (!isset($input) || !$input) return array(); 820 | 821 | $pairs = explode('&', $input); 822 | 823 | $parsed_parameters = array(); 824 | foreach ($pairs as $pair) { 825 | $split = explode('=', $pair, 2); 826 | $parameter = WP_OAuthUtil::urldecode_rfc3986($split[0]); 827 | $value = isset($split[1]) ? WP_OAuthUtil::urldecode_rfc3986($split[1]) : ''; 828 | 829 | if (isset($parsed_parameters[$parameter])) { 830 | // We have already recieved parameter(s) with this name, so add to the list 831 | // of parameters with this name 832 | 833 | if (is_scalar($parsed_parameters[$parameter])) { 834 | // This is the first duplicate, so transform scalar (string) into an array 835 | // so we can add the duplicates 836 | $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]); 837 | } 838 | 839 | $parsed_parameters[$parameter][] = $value; 840 | } else { 841 | $parsed_parameters[$parameter] = $value; 842 | } 843 | } 844 | return $parsed_parameters; 845 | } 846 | 847 | public static function build_http_query($params) { 848 | if (!$params) return ''; 849 | 850 | // Urlencode both keys and values 851 | $keys = WP_OAuthUtil::urlencode_rfc3986(array_keys($params)); 852 | $values = WP_OAuthUtil::urlencode_rfc3986(array_values($params)); 853 | $params = array_combine($keys, $values); 854 | 855 | // Parameters are sorted by name, using lexicographical byte value ordering. 856 | // Ref: Spec: 9.1.1 (1) 857 | uksort($params, 'strcmp'); 858 | 859 | $pairs = array(); 860 | foreach ($params as $parameter => $value) { 861 | if (is_array($value)) { 862 | // If two or more parameters share the same name, they are sorted by their value 863 | // Ref: Spec: 9.1.1 (1) 864 | natsort($value); 865 | foreach ($value as $duplicate_value) { 866 | $pairs[] = $parameter . '=' . $duplicate_value; 867 | } 868 | } else { 869 | $pairs[] = $parameter . '=' . $value; 870 | } 871 | } 872 | // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) 873 | // Each name-value pair is separated by an '&' character (ASCII code 38) 874 | return implode('&', $pairs); 875 | } 876 | } 877 | 878 | ?> -------------------------------------------------------------------------------- /lib/wp_twitteroauth.php: -------------------------------------------------------------------------------- 1 | http_status; } 59 | function lastAPICall() { return $this->last_api_call; } 60 | 61 | /** 62 | * construct TwitterOAuth object 63 | */ 64 | function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) { 65 | $this->sha1_method = new WP_OAuthSignatureMethod_HMAC_SHA1(); 66 | $this->consumer = new WP_OAuthConsumer($consumer_key, $consumer_secret); 67 | if (!empty($oauth_token) && !empty($oauth_token_secret)) { 68 | $this->token = new WP_OAuthConsumer($oauth_token, $oauth_token_secret); 69 | } else { 70 | $this->token = NULL; 71 | } 72 | } 73 | 74 | 75 | /** 76 | * Get a request_token from Twitter 77 | * 78 | * @returns a key/value array containing oauth_token and oauth_token_secret 79 | */ 80 | function getRequestToken($oauth_callback = NULL) { 81 | $parameters = array(); 82 | if (!empty($oauth_callback)) { 83 | $parameters['oauth_callback'] = $oauth_callback; 84 | } 85 | $request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters); 86 | $token = WP_OAuthUtil::parse_parameters($request); 87 | $this->token = new WP_OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); 88 | return $token; 89 | } 90 | 91 | /** 92 | * Get the authorize URL 93 | * 94 | * @returns a string 95 | */ 96 | function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) { 97 | if (is_array($token)) { 98 | $token = $token['oauth_token']; 99 | } 100 | if (empty($sign_in_with_twitter)) { 101 | return $this->authorizeURL() . "?oauth_token={$token}"; 102 | } else { 103 | return $this->authenticateURL() . "?oauth_token={$token}"; 104 | } 105 | } 106 | 107 | /** 108 | * Exchange request token and secret for an access token and 109 | * secret, to sign API calls. 110 | * 111 | * @returns array("oauth_token" => "the-access-token", 112 | * "oauth_token_secret" => "the-access-secret", 113 | * "user_id" => "9436992", 114 | * "screen_name" => "abraham") 115 | */ 116 | function getAccessToken($oauth_verifier = FALSE) { 117 | $parameters = array(); 118 | if (!empty($oauth_verifier)) { 119 | $parameters['oauth_verifier'] = $oauth_verifier; 120 | } 121 | $request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters); 122 | $token = WP_OAuthUtil::parse_parameters($request); 123 | $this->token = new WP_OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); 124 | return $token; 125 | } 126 | 127 | /** 128 | * One time exchange of username and password for access token and secret. 129 | * 130 | * @returns array("oauth_token" => "the-access-token", 131 | * "oauth_token_secret" => "the-access-secret", 132 | * "user_id" => "9436992", 133 | * "screen_name" => "abraham", 134 | * "x_auth_expires" => "0") 135 | */ 136 | function getXAuthToken($username, $password) { 137 | $parameters = array(); 138 | $parameters['x_auth_username'] = $username; 139 | $parameters['x_auth_password'] = $password; 140 | $parameters['x_auth_mode'] = 'client_auth'; 141 | $request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters); 142 | $token = WP_OAuthUtil::parse_parameters($request); 143 | $this->token = new WP_OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); 144 | return $token; 145 | } 146 | 147 | /** 148 | * GET wrapper for oAuthRequest. 149 | */ 150 | function get($url, $parameters = array()) { 151 | $response = $this->oAuthRequest($url, 'GET', $parameters); 152 | if ($this->format === 'json' && $this->decode_json) { 153 | return json_decode($response,true); 154 | } 155 | return $response; 156 | } 157 | 158 | /** 159 | * POST wrapper for oAuthRequest. 160 | */ 161 | function post($url, $parameters = array()) { 162 | $response = $this->oAuthRequest($url, 'POST', $parameters); 163 | if ($this->format === 'json' && $this->decode_json) { 164 | return json_decode($response,true); 165 | } 166 | return $response; 167 | } 168 | 169 | /** 170 | * DELETE wrapper for oAuthReqeust. 171 | */ 172 | function delete($url, $parameters = array()) { 173 | $response = $this->oAuthRequest($url, 'DELETE', $parameters); 174 | if ($this->format === 'json' && $this->decode_json) { 175 | return json_decode($response,true); 176 | } 177 | return $response; 178 | } 179 | 180 | /** 181 | * Format and sign an WP_OAuth / API request 182 | */ 183 | function oAuthRequest($url, $method, $parameters) { 184 | if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) { 185 | $url = "{$this->host}{$url}.{$this->format}"; 186 | } 187 | $request = WP_OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters); 188 | $request->sign_request($this->sha1_method, $this->consumer, $this->token); 189 | switch ($method) { 190 | case 'GET': 191 | return $this->http($request->to_url(), 'GET'); 192 | default: 193 | return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata()); 194 | } 195 | } 196 | 197 | /** 198 | * Make an HTTP request 199 | * 200 | * @return API results 201 | */ 202 | function http($url, $method, $postfields = NULL) { 203 | 204 | if(WP_DEBUG && ! is_admin()) echo "\n"; 222 | endif; 223 | $startwrrtime = microtime(true); 224 | $response = wp_remote_request($url,$args); 225 | if(WP_DEBUG && ! is_admin()) echo "\n"; 226 | return($response); 227 | 228 | /* 229 | if(WP_DEBUG && ! is_admin()) echo ""; 230 | $this->http_info = array(); 231 | $ci = curl_init(); 232 | # Curl settings 233 | curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); 234 | curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); 235 | curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout); 236 | curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); 237 | curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:')); 238 | curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer); 239 | curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader')); 240 | curl_setopt($ci, CURLOPT_HEADER, FALSE); 241 | 242 | switch ($method) { 243 | case 'POST': 244 | curl_setopt($ci, CURLOPT_POST, TRUE); 245 | if (!empty($postfields)) { 246 | curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); 247 | } 248 | break; 249 | case 'DELETE': 250 | curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE'); 251 | if (!empty($postfields)) { 252 | $url = "{$url}?{$postfields}"; 253 | } 254 | } 255 | 256 | curl_setopt($ci, CURLOPT_URL, $url); 257 | $response = curl_exec($ci); 258 | $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); 259 | $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); 260 | $this->url = $url; 261 | curl_close ($ci); 262 | $return = array('body' => $response); 263 | return $return; 264 | */ 265 | } 266 | 267 | /** 268 | * Get the header info to store. 269 | */ 270 | function getHeader($ch, $header) { 271 | $i = strpos($header, ':'); 272 | if (!empty($i)) { 273 | $key = str_replace('-', '_', strtolower(substr($header, 0, $i))); 274 | $value = trim(substr($header, $i + 2)); 275 | $this->http_header[$key] = $value; 276 | } 277 | return strlen($header); 278 | } 279 | } 280 | endif; -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | === Rotating Tweets (Twitter widget and shortcode) === 2 | 3 | Contributors: mpntod 4 | Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9XCNM4QSVHYT8 5 | Tags: shortcode,widget,twitter,rotating,rotate,rotator,tweet,tweets,animation,jquery,jquery cycle,cycle,multilingual,responsive,page builder 6 | Requires at least: 3.2 7 | Tested up to: 4.3 8 | Stable tag: 1.7.18 9 | License: GPLv2 or later 10 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 11 | 12 | Twitter widget and shortcode to show your latest tweets one at a time an animated rotation 13 | 14 | == Description == 15 | 16 | * **Replaces a [shortcode](http://codex.wordpress.org/Shortcode) such as `[rotatingtweets screen_name='your_twitter']`, or a [widget](http://codex.wordpress.org/WordPress_Widgets), with a rotating display of your most recent tweets** 17 | * **Supports v 1.1 of the Twitter API** ([i.e. it still works](https://blog.twitter.com/2013/api-v1-is-retired)) 18 | * **Space efficient** - instead of showing all your tweets at once, shows one at a time and then smoothly replaces it with the next one. After showing all your tweets, loops back to the beginning again. 19 | * **Reliable** - keeps showing your latest Tweets even if the Twitter website is down. 20 | * **Customisable** - you decide whose tweets to show, how many to show, whether to include retweets and replies, and whether to show a follow button. You can also decide how quickly the tweets rotate and what type of animation to use. 21 | * **Responsive** - resizes as your page resizes 22 | * Gives you the option to show a fully customisable Twitter 'follow' button 23 | * Replaces [t.co](http://t.co) links with the original link 24 | * Caches the most recent data from Twitter to avoid problems with rate limiting 25 | * Uses [jQuery](http://jquery.com/), [jQuery.Cycle](http://jquery.malsup.com/cycle/) and [jQuery.Cycle2](http://jquery.malsup.com/cycle2/) to produce a nice smooth result. 26 | * Compatible with [W3 Total Cache](https://wordpress.org/plugins/w3-total-cache/). 27 | * **Multi-lingual** - now set up to be multi-lingual. The Twitter 'follow' button is automatically translated to match your site's language setting [if Twitter has made the appropriate language available](https://dev.twitter.com/docs/api/1.1/get/help/languages). Also uses [Wordpress's multi-lingual capability](http://codex.wordpress.org/I18n_for_WordPress_Developers) to enable translation of all the other text used by the plug-in via [language packs](https://translate.wordpress.org/projects/wp-plugins/rotatingtweets). 28 | 29 | If you'd like to see what the plug-in looks like in action, you can [see the plug-in working here](http://www.martintod.org.uk/2012/05/29/new-twitter-plugin-to-show-tweets-in-rotation/). 30 | 31 | == Installation == 32 | 33 | = Installation = 34 | 35 | 1. Upload the contents of `rotatingtweets.zip` to the `/wp-content/plugins/` directory or use the Wordpress installer 36 | 1. Activate the plugin through the 'Plugins' menu in WordPress 37 | 1. Go to the [My applications page](https://dev.twitter.com/apps) on the Twitter website to set up your website as a new Twitter 'application'. You may need to log-in using your Twitter user name and password. 38 | 1. If you don't already have a suitable 'application' to use for your website, set one up on the [Create an Application page](https://dev.twitter.com/apps/new). It's normally best to use the name, description and website URL of the website where you plan to use Rotating Tweets. You don't need a Callback URL. 39 | 1. After clicking **Create your Twitter application**, on the following page, click on **Create my access token**. 40 | 1. Copy the **Consumer key**, **Consumer secret**, **Access token** and **Access token secret** from your Twitter application page into the Rotating Tweets settings page. Hit save. If there is a problem, you will see an error message. 41 | 1. Place a shortcode such `[rotatingtweets screen_name='mpntod']` in your post or page, or use a widget 42 | 43 | = Set-up = 44 | 45 | Options include: 46 | 47 | 1. Going to the Widgets menu on the admin page and adding the Rotating Tweets widget. Options include the name of the Twitter account to show, whether to show retweets and the speed of rotation. 48 | 1. Using the basic Rotating Tweets shortcode, for example `[rotatingtweets screen_name='mpntod']` 49 | 1. Using a more complicated Rotating Tweets shortcode, for example `[rotatingtweets screen_name='mpntod' include_rts='1' tweet_count='7' timeout='3000']` 50 | 51 | = Shortcode variables = 52 | 53 | Possible variables for the shortcode include: 54 | 55 | * **Required settings** - at least one of the following three settings is required for the short-code to function: 56 | * `screen_name` = one or more Twitter user names e.g. `[rotatingtweets screen_name="mpntod"]` or `[rotatingtweets screen_name="mpntod twitter"]` 57 | * `url` = Twitter user URL. If `screen_name` is empty and this link is valid, `screen_name` will be set to the user name included in `url` 58 | * `search` = a term to search for. There's a useful guide to using Twitter's search function at https://support.twitter.com/articles/71577-using-advanced-search 59 | * **Twitter options** 60 | * `include_rts` = `'0'` or `'1'` - include retweets - default is `'0'` 61 | * `only_rts` = `'0'` or `'1'` - only include retweets - default is `'0'` 62 | * `exclude_replies` = `'0'` or `'1'` - exclude replies - default is `'0'` 63 | * `tweet_count` = number of tweets to show - default is `5` 64 | * `get_favorites` = `'0'` or `'1'` - show someone's favorites rather than their timeline - default is `'0'` 65 | * `list` = `'list-slug'` - the 'slug' used by someone's list (something like `my-list`) 66 | * `offset` = ''number'' - default is `'0'` - enables you to start on a later tweet - `'1'` starts on the 2nd tweet, `'2'` starts on the 3rd tweet, etc. 67 | * **Display options** 68 | * `official_format` = `'1'`, `'2'` or `'custom'` - show one of the two official formats or a custom format if you have written your own `rotatingtweets_display_override()` function - default is `'0'` 69 | * `rtw_display_order`=`'info,main,media,meta'` - change the order that the main elements of the tweet are shown - `info`, `main`, `media` and `meta` - via a string using the four keywords separated by commas - default is `'info,main,media,meta'` 70 | * `timeout` = time that each tweet is shown in milliseconds - default is `'4000'` (i.e. 4 seconds). `timeout=0` allows for continuous scrolling. 71 | * `speed` = time it takes to change from one tweet to the next in milliseconds - default is `'1000'` (i.e. 1 second) 72 | * `links_in_new_window` = `'0'` or `'1'` - show links in a new tab or window - default is `'0'` 73 | * `rotation_type` = If you are using version 1 of the JavaScript, you can use any of the options listed on the [jQuery.cycle website](http://jquery.malsup.com/cycle/browser.html) - default is `'scrollUp'.` If you are using version 2 of the JavaScript, then the options are `'scrollUp'`,`'scrollDown'`,`'scrollHorz'`,`'scrollLeft'`,`'scrollRight'`,`'toss'`,`'scrollVert'`,`'fade'` and `'carousel'` 74 | * `carousel_horizontal` = `0` or `1` - if you've chosen 'carousel' as a rotation type, allow horizontal scrolling - default is `0` 75 | * `carousel_count` = ''number'' - if you've chosen 'carousel' as a rotation type, set the number of slides to appear in the carousel - default is 3 for vertical carousel and enough to fill the width of the page for horizontal carousel 76 | * `carousel_responsive` = `0` or `1` - if you've chosen a 'horizontal carousel' as a rotation type, makes the carousel responsive to the size of the page - default is `0` 77 | * `url_length` = sets the length that the URL of links should be trimmed to... - optional 78 | * `show_tco_link` = `'0'` or `'1'` allows you to show Twitter's t.co link instead of the original link - optional 79 | * `show_meta_timestamp` = `'0'` or `'1'` - show the time and date of each tweet - default is `'1'` 80 | * `show_meta_screen_name` = `'0'` or `'1'` - show who posted each tweet - default is `'1'` 81 | * `show_meta_via` = `'0'` or `'1'` - show how each tweet was posted - default is `'1'` 82 | * `show_meta_reply_retweet_favorite` = `'0'` or `'1'` - show 'reply', 'retweet' and 'favorite' buttons - default is `'0'` 83 | * `no_rotate` = `'0'` or `'1'` - switch off rotation - default is `'0'` 84 | * `show_meta_prev_next` = `'0'` or `'1'` - show 'next', 'prev' links - default is `'0'` 85 | * `prev` = content for the prev button (default `'prev'`) 86 | * `next` = content for the next button (default `'next'`) 87 | * `middot` = content for the space between the buttons (default `' · '`) 88 | * `np_pos` = position for 'next' and 'prev' buttons - `'top'`, `'bottom'`, `'insidebottom'`, `'beforeafter'` or `'tweets'` (default `'top'`) 89 | * `show_meta_pager` = `'0'` or `'1'` - show pager blobs below the tweets - default is `'0'` 90 | * `show_meta_pager_blob` = content for your pager blob - default is `''` 91 | * `show_media` = `'0'` or `'1'` - experimental option that shows images with the tweet - default is `'0'` 92 | * `screen_name_plural` = `'0'` or `'1'` - experimental option that allows you to have a plural possessive in the default display format (e.g. *British Lions' Twitter*) - default is `'0'` 93 | * `tweet_length` = maximum number of characters to show in tweet - default is `'0'` which allows whole tweet to be shown 94 | * `no_emoji` = `'0'` or `'1'` - experimental option that removes emoji from the feed - default is `'0'` 95 | * `official_format_override` = `'0'` or `'1'` - enables you to change the settings for `show_meta_reply_retweet_favorite` and `show_meta_timestamp` on the 'official formats'. 96 | * `profile_image_size` = `'normal'`, `'bigger'`, `'mini'` or `'original'` - lets you change the size of profile images - default is `'normal'` 97 | * `shuffle` = `'0'` or `'1'` - shuffle the order that Tweets display - default is `'0'` 98 | * `merge_cache` = `'0'` or `'1'` - switches cacheing of searches on or off - default is `'1'` (i.e. on) 99 | 100 | * **Caching** 101 | * `w3tc_render_to` = 'your_choice_of_random_string' - used to support 'fragment caching' by [W3 Total Cache](https://wordpress.org/plugins/w3-total-cache/). For this to work, you also need to ensure that `W3TC_DYNAMIC_SECURITY` is defined in your `wp-config.php` file and that you not using 'HTTP Compression' on the W3 Total Cache 'Browser Cache' settings page or 'Enhanced Disk caching' on the W3 Total Cache 'Page Cache' settings page. 102 | 103 | * **Twitter follow button** 104 | * `show_follow` = `'0'` or `'1'` - show follow button - default is `'0'` 105 | * `no_show_count` = `'0'` or `'1'` - remove the follower count from the Twitter follow button - default is `'0'` 106 | * `no_show_screen_name` = `'0'` or `'1'` - remove the screen name from the Twitter follow button - default is `'0'` 107 | 108 | == Credits == 109 | 110 | Most of this is my own work, but special thanks are owed to: 111 | 112 | * The [jQuery](http://jquery.com/) team 113 | * [Mike Alsup](http://jquery.malsup.com/cycle/) for [jQuery.Cycle](http://jquery.malsup.com/cycle/) and [jQuery.Cycle2](http://jquery.malsup.com/cycle2/) 114 | * [Syd Lawrence](http://sydlawrence.com/) for introducing me to jQuery and jQuery.Cycle 115 | * [Abraham Williams](http://abrah.am) for [TwitterOAuth](https://github.com/abraham/twitteroauth) 116 | * [Liam Gaddy](http://profiles.wordpress.org/lgladdy/) at [Storm Consultancy](http://www.stormconsultancy.co.uk/) for [his work](http://www.stormconsultancy.co.uk/blog/development/tools-plugins/oauth-twitter-feed-for-developers-library-and-wordpress-plugin/) on [oAuth Twitter Feed for Developers](http://wordpress.org/extend/plugins/oauth-twitter-feed-for-developers/) (although I ended up using it for inspiration rather than plugging it in directly). 117 | * All the people who have given advice and suggested improvements 118 | 119 | Thank you to the people who did the original translation work for the following packs: 120 | 121 | * Wilmerson Felipe for his work on Brazilian Portuguese 122 | * Nils Kroneberg for his work on German 123 | * Alberto Lario for his work on Spanish 124 | * [Mattia Migliorini](https://profiles.wordpress.org/deshack/) at [deshack](http://deshack.net/) for his work on Italian 125 | * Natasja Weijer for her work on Dutch 126 | * [Alexandre Trudel](http://wordpress.org/support/profile/alexandretrudel) for his help on French 127 | * Borisa Djuraskovic at [Web Hosting Hub](http://www.webhostinghub.com/) for his help on Serbian 128 | 129 | == Frequently Asked Questions == 130 | 131 | = What options can I use for the shortcode? = 132 | 133 | All the options are listed on the [Rotating Tweets installation page](http://wordpress.org/extend/plugins/rotatingtweets/installation/). 134 | 135 | = How can I include Rotating Tweets in my template? = 136 | 137 | Try something like: 138 | `` 139 | A common mistake with `do_shortcode` shortcodes is to use single-quotes or double-quotes all the way through without 'escaping' them. This will normally break your site! It's best to use double-quotes to enclose the shortcode string and single-quotes inside the shortcode string (or vice-versa!). 140 | 141 | = How can I pull information from two accounts into one widget = 142 | 143 | The easiest way is to list more than one account in the 'Twitter name' box in the widget or use something like `screen_name='account1 account2'` in the shortcode. 144 | 145 | = How often does the plug-in call Twitter = 146 | 147 | In most cases, each use (or "instance") of this plug-in gets data from Twitter every 2 minutes. The exception is when two or more instances share the same settings (screen name etc.), in which case they share the same data rather than each calling it separately. 148 | 149 | = My Rotating Tweets are not updating. What can I do? = 150 | 151 | This normally happens if there is an SSL problem. Try going to the settings page and switching off SSL validation. 152 | 153 | If this doesn't solve the problem, check your Twitter API key settings. 154 | 155 | If neither of these approaches work, Rotating Tweets will normally be reporting the error as a comment in the HTML of your page. This should give you an idea of how to solve the problem. 156 | 157 | = The Rotating Tweets are not rotating. What can I do? = 158 | 159 | This normally happens if there is more than one copy of `jQuery` installed on a page - or more than one copy of `jQuery.cycle`. 160 | 161 | To see if this is the case, search the HTML on your website to see if either script is called more than once. To do this: 162 | 163 | 1. Open the page. 164 | 1. Right click and select 'View Page Source' or 'View Source' 165 | 1. Hit `[CTRL]+F` and search for `jquery` 166 | 1. Look out for lines that contain `jquery.min.js` or `jquery.cycle.all.min.js`. Neither script should appear more than once. 167 | 168 | The problem is that the second (or third) copy of the script overwrites all previous versions and the scripts that go with them. This is particularly likely to happen with old templates or plug-ins. 169 | 170 | If this is the case: 171 | 172 | 1. Check is that you have upgraded your template or your plug-in to the latest version. 173 | 1. If this still doesn't work, please let me know which plug-in or template is causing the problem and I'll see if I can build a fix into the next version of Rotating Tweets. 174 | 175 | If there is only one copy of `jquery` and of `jquery.cycle` on your page, the best way to look for the problem is to open the 'console'. To do this: 176 | 177 | 1. Press `[F12]` (in Chrome or IE) or `[CTRL]+[SHIFT]+K` (in Firefox) 178 | 1. Load the page where you have a problem 179 | 1. In Chrome or IE, select the tab marked 'console'. 180 | 1. Read the diagnostics and look for any problems that relate to JavaScript. This will normally tell you which JavaScript (if any) is having problems. 181 | 182 | = What can I do if I get the WordPress error code: `http_request_failed - name lookup timed out`? = 183 | Try installing the [Core Control plug-in](http://wordpress.org/extend/plugins/core-control/) and disabling cURL. You can read more about the problem via [this support page](http://wordpress.org/support/topic/wp-351-wordpress-error-code-http_request_failed-name-lookup-timed-out). 184 | 185 | Thank you to [darkiko](http://wordpress.org/support/profile/darkiko) for sharing their solution to this problem. 186 | 187 | = My widget is too wide! = 188 | 189 | Try putting: 190 | ``` 191 | div.widget_rotatingtweets_widget, div.rotatingtweet, div.widget_rotatingtweets_widget div.widget-title { 192 | max-width: 123px; 193 | } 194 | ``` 195 | into your CSS - changing `123px;` to the width you're aiming at - either via putting `rotatingtweets.css` into `wp-content/uploads` or by editing your own template files. 196 | 197 | = How can I add a Twitter bird to the left of my tweets? = 198 | 199 | You can do this by going to the `rotatingtweets/css` directory and renaming `rotatingtweets-sample.css` to `rotatingtweets.css` and putting it in the `wp-content/uploads/` directory. This displays a Twitter bird to the left of your tweets. Any CSS you put into `rotatingtweets.css` won't be overwritten when the plug-in is upgraded to the latest version. 200 | 201 | == Upgrade notice == 202 | 203 | = 1.7.18 = 204 | * Reinstalling translation packs. 205 | 206 | == Changelog == 207 | = 1.7.18 = 208 | * Reinstalling translation packs. Turns out that incomplete packs aren't loaded - which breaks some of the available translations. 209 | 210 | = 1.7.17 = 211 | * Move to [Wordpress-hosted translation packs](https://translate.wordpress.org/projects/wp-plugins/rotatingtweets). 212 | 213 | = 1.7.16 = 214 | * Fixed undefined variable error for `show_media` in `WP_DEBUG` mode 215 | * Fix for caching bug 216 | 217 | = 1.7.15 = 218 | * Fixing bug on displaying meta content 219 | * Enabling sorting of display elements via `rtw_display_order` shortcode 220 | 221 | = 1.7.14 = 222 | * Works with [Page Builder by SiteOrigin](https://wordpress.org/plugins/siteorigin-panels/). 223 | * Adds new shortcode variable `only_rts` 224 | 225 | = 1.7.13 = 226 | * Adds `profile_image_size`, `shuffle` and `merge_cache` shortcode variables 227 | * Lowers chance of clashes with other installations of cycle2 - by defaulting `autoSelector` to `.rotatingtweets` instead of `.cycle-slideshow` 228 | * Handles old versions of jQuery that don't fully support `.data()` better 229 | * Fixes bug with merge functionality 230 | * Fixes bug with admin page JavaScript (thanks to this [very helpful article on StackExchange.com](http://wordpress.stackexchange.com/questions/130084/executing-javascript-when-a-widget-is-added-in-the-backend)) 231 | 232 | = 1.7.12 = 233 | * Updated version 2 of JavaScript - updated jQuery.cycle2 and removal of bug 234 | * Fixing height bug 235 | * Fixing Carousel defaults 236 | * Updating `.pot` file 237 | 238 | = 1.7.11 = 239 | * Completion of Spanish translation - many thanks to Alberto Lario for his help on this 240 | * Fixing tweet height JavaScript bug 241 | * CSS tidying for TwentyFifteen template 242 | * Experimental function combining historical and current tweets 243 | 244 | = 1.7.10 = 245 | * Move to using HTML5 custom data attributes and `data()` functions to transfer variable values to version 1 of JavaScript - including 'speed' variable 246 | * Addition of 'pager' via `show_meta_pager` and `show_meta_pager_blob` variables 247 | * Addition of `rtw_hashtag_link` class to hashtag links 248 | * `timeout=0` now allows continuous scrolling 249 | * Updating object code for the widget 250 | 251 | = 1.7.9 = 252 | * Fixing Tweet timezone display problem 253 | * Restoring Tweet time display by default for 'Official Twitter Guidelines (wide)' 254 | * Extra CSS added to enable people to hide links (should they want to) 255 | * Option to switch off JavaScript (for advanced users only) 256 | 257 | = 1.7.8 = 258 | * Solves bug when Base64 tries to decode an array 259 | 260 | = 1.7.7 = 261 | * Better handling transients on transition from old version to new 262 | 263 | = 1.7.6 = 264 | * Addition of Italian language 265 | * Fixes transient-based caching - many thanks to to [jensnilsson](https://wordpress.org/support/profile/jensnilsson) and [Moondrop](https://wordpress.org/support/profile/moondrop) for highlighting the solution [here](https://wordpress.org/support/topic/no-tweets-available-mostly?replies=30). 266 | 267 | = 1.7.5 = 268 | * Much faster and more reliable caching. 269 | * Compatibility with W3 Total Cache. 270 | * New `scrollLeftGap` transition 271 | * Ability to put 'prev' and 'next' buttons before and after the main rotating tweets 272 | 273 | = 1.7.4 = 274 | * Ensures all images use `https://` link for compatibility with SSL-secured sites 275 | 276 | = 1.7.3 = 277 | * Adds `show_tco_link` shortcode variable to allow people to show t.co.links. 278 | * Support for Newswire template 279 | * Restores the caching of Tweet co-ordinates 280 | 281 | = 1.7.2 = 282 | * Switches off JavaScript expansion of 'expand' to 'reply retweet favorite' for carousel rotation. 283 | * Adds new `insidebottom` option for `np_pos` shortcode variable 284 | 285 | = 1.7.1 = 286 | * Improved CSS support for horizontal carousel scrolling 287 | 288 | = 1.7.0 = 289 | * Adding `offset`, `speed`, `tweet_length`, `no_emoji` and `show_media` options to the shortcode 290 | * Solves clash with [Cyclone Slider 2](http://wordpress.org/plugins/cyclone-slider-2/) 291 | * Adds script version details to the JavaScript 292 | * Removal of excess spaces from `middot` shortcode option 293 | * Adds option for 'custom' display layoot with user-defined display function `rotatingtweets_display_override()` 294 | 295 | = 1.6.11 = 296 | * Fixing cache bug with 'user_mentions' 297 | 298 | = 1.6.10 = 299 | * New code to shrink size of cache by about 70% 300 | 301 | = 1.6.9 = 302 | * Bug fix. 303 | 304 | = 1.6.8 = 305 | * Shrinking cache size to reduce memory problems. 306 | * Improved diagnostics. 307 | * Clarified instructions. 308 | 309 | = 1.6.7 = 310 | * Fix next/prev buttons for v. 2 of Javascript. 311 | * Add next/prev `np_pos='tweets'` option to documentation. 312 | * Fix bug on admin page when `WP_DEBUG` is set. 313 | 314 | = 1.6.6 = 315 | * Corrected the 16x16 icon to the latest Twitter logo. 316 | 317 | = 1.6.5 = 318 | * Language update including new Serbian translation. Solved an unusual styling problem. 319 | 320 | = 1.6.4 = 321 | * Bug fix when user name not recognised. 322 | 323 | = 1.6.3 = 324 | * Add option to shorten default link length to 20 characters 325 | * Language update including new German translation from Nils Kroneberg 326 | * Updated Brazilian Portuguese translation from Wilmerson Felipe 327 | 328 | = 1.6.2 = 329 | * Fixing bug for PHP installations that don't support the 'u' modifier 330 | * Renaming v2 JavaScript to avoid clash with other plug-ins. 331 | * Extra diagnostics put in to solve regular expression problem 332 | 333 | = 1.6.1 = 334 | * Move to a more unique class name to avoid clashes with another template. 335 | 336 | = 1.6.0 = 337 | * New support for reading from multiple accounts 338 | * Improved clean-up on uninstallation or deactivation 339 | * Addition of settings page option for timeout of connection to Twitter 340 | * Addition of settings page option for placement of JavaScript at the bottom of the page 341 | * Addition of settings page option for duration of cache 342 | * Fixed problem with hashtags and accents 343 | * Improved error messages for connection problems 344 | * Tidying up settings page text 345 | 346 | = 1.5.1 = 347 | * Enforce rules on replies and retweets even if the Twitter API doesn't 348 | * Fixed problem with [Magazino template](http://wordpress.org/themes/magazino) 349 | * Fixed incorrect message on settings page 350 | 351 | = 1.5.0 = 352 | * Added `Carousel` rotation option and beta support for [version 2 of JQuery Cycle](http://jquery.malsup.com/cycle2/) 353 | * Added `link_all_text` shortcode tag and functionality 354 | * Added richer debug information 355 | * Corrected API expiry date 356 | * Added missing `alt` tag 357 | * Kept CSS permanently in the header to maintain HTML capability 358 | * Public facing Dutch translation complete - many thanks to Natasja Weijer for her help on this 359 | * Attempt to fix clash with [Avada](http://themeforest.net/item/avada-responsive-multipurpose-theme/2833226) and [Gleam](http://www.elegantthemes.com/gallery/gleam/) themes 360 | 361 | = 1.4.7 = 362 | * HTML5 compliance 363 | * Improved rate-limiting 364 | 365 | = 1.4.6 = 366 | * Addition of Brazilian Portuguese translation 367 | * Addition of new display format 6 368 | 369 | = 1.4.5 = 370 | * Deletes old cache entries if unused for more than 30 days 371 | * Fixes a jQuery cycle clash with the [Oxygen theme](http://wordpress.org/extend/themes/oxygen/). 372 | * Added `readme.txt` instructions for dealing with the WordPress error code: `http_request_failed - name lookup timed out`. 373 | 374 | = 1.4.4 = 375 | * Adds an option to switch off verification of SSL connections to Twitter 376 | * Adds a short code option (`no_rotate`) to switch off rotation 377 | 378 | = 1.4.3 = 379 | * Removes two lines of CSS causing formatting problems 380 | * Improves responsiveness going from narrow to wider layouts 381 | 382 | = 1.4.2 = 383 | * Corrected minor error with resizing of `.rtw_meta` div 384 | 385 | = 1.4.1 = 386 | * Now works with responsive formats 387 | * Adjusted width overflow issues 388 | * Added [instructions on how to deal with width issues](http://wordpress.org/extend/plugins/rotatingtweets/faq/) 389 | 390 | = 1.4.0 = 391 | * Support for search, favorites and lists via Rotating Tweets widgets. 392 | 393 | = 1.3.18 = 394 | * Improved and clearer error messages. 395 | * Removed search bug. 396 | * 'Next' and 'Prev' buttons for shortcodes. 397 | 398 | = 1.3.17 = 399 | * Adds the opportunity to show lists. 400 | * Tackles a very odd box height problem that has just appeared in Chrome (but not Firefox or IE). 401 | 402 | = 1.3.16 = 403 | * Making sure hashtags have a space or the start of a line before them. 404 | * Tidying up errors found when running plug-in with `wp_debug` set to `true` 405 | 406 | = 1.3.15 = 407 | * Minor correction to hashtag code 408 | 409 | = 1.3.14 = 410 | * Fixes accents in hashtags (hopefully). 411 | * Adds beta of search to the shortcode API. 412 | * Adds new format of Tweet display. 413 | 414 | = 1.3.13 = 415 | * Strips `@` from screen names to avoid API problems. 416 | 417 | = 1.3.12 = 418 | * Removes accents from screen names (and otherwise cleans them up). 419 | * Add test option (currently for shortcodes only) to access favorites. 420 | * Solves clash between PECL OAuth library and the Rotating Tweets OAuth library. 421 | 422 | = 1.3.11 = 423 | * Supports cyrillic hashtags! 424 | 425 | = 1.3.10 = 426 | * Fixed hashtag links 427 | 428 | = 1.3.9 = 429 | * Moved to [Semantic Versioning](http://semver.org/) 430 | 431 | = 0.712 (1.3.8) = 432 | * Fixed bug with `console.log` javascript on IE. 433 | 434 | = 0.711 (1.3.7) = 435 | * Fixed up a significant problem with cacheing. 436 | 437 | = 0.709 (1.3.6) = 438 | * Tidying up error reporting. 439 | 440 | = 0.707 (1.3.5) = 441 | * Fixes major bug resulting from upgrade to handle Twitter API v 1.1 442 | 443 | = 0.706 (1.3.4) = 444 | * Change to JavaScript to improve width handling for tweets. 445 | 446 | = 0.703 (1.3.3) = 447 | * Minor code tidying to improve debugging and increase speed! 448 | 449 | = 0.702 (1.3.2) = 450 | * Adjustment to javascript and CSS to cope with long links or long words 451 | 452 | = 0.701 (1.3.1) = 453 | * Very minor mistake in rendering code 454 | 455 | = 0.700 (1.3.0) = 456 | * Important upgrade needed for Rotating Tweets to keep working after March 2013. Supports version 1.1 of the Twitter API. 457 | 458 | = 0.625 (1.2.4) = 459 | * Enabled users to make all links open in a new tab or window 460 | 461 | = 0.623 (1.2.3) = 462 | * Fixed a problem where a short name fitted inside a long one - e.g. @rotary and @rotarycrocus 463 | 464 | = 0.622 (1.2.2) = 465 | * Escaped title tags 466 | 467 | = 0.621 (1.2.1) = 468 | * Fixed timezone problem. 469 | 470 | = 0.620 (1.2.0) = 471 | * Added option to show links in a new window 472 | * Fix problem with selection of 20 second rotating speed. 473 | 474 | = 0.613 (1.1.6) = 475 | * Fixed instructions in plug-ins list. 476 | 477 | = 0.612 (1.1.5) = 478 | * Fixed error message caused by last fix causing tweets to repeat. 479 | 480 | = 0.611 (1.1.4) = 481 | * Finally ran with debug and removed all the error messages. 482 | 483 | = 0.610 (1.1.3) = 484 | * Starts to add options to allow for different length URLs 485 | 486 | = 0.602 (1.1.2) = 487 | * Fixes bug with Javascript 488 | 489 | = 0.601 (1.1.1) = 490 | * Fixes problem with stylesheet 491 | 492 | = 0.600 (1.1.0) = 493 | *Now includes options consistent with Twitter display options 494 | * Tidied up code. 495 | 496 | = 0.505 (1.0.0) = 497 | * Minimised Javascript. 498 | * Set-up for I18n. 499 | 500 | = 0.502 (0.4.1) = 501 | * Javascript fix for zero height tweets problem 502 | 503 | = 0.500 (0.4.0) = 504 | * Adds options for how tweet information is displayed and how the tweet rotates. 505 | 506 | = 0.492 (0.3.1) = 507 | * Solves `Cannot use string offset as an array` error on line 232 508 | 509 | = 0.491 (0.3.0) = 510 | * Lets you customise the Twitter 'follow' button. 511 | * Fixes problem with media links. 512 | * Sorts problem of overlong links reshaping widgets. 513 | 514 | = 0.48 (0.2.6) = 515 | * More detailed error messages for Wordpress installations unable to access Twitter. 516 | * Fixes problem on the zeeBizzCard template and sets up fix for other templates that use their own install of the `jquery-cycle` javascript. 517 | 518 | = 0.471 (0.2.5) = 519 | * Making sure that cache never gets overwritten unless new, valid twitter data has been downloaded. 520 | * Dealing with the problem that someone in a long conversation may not get enough valid tweets to show by asking for only 20 tweets from Twitter. 521 | 522 | = 0.46 (0.2.4) = 523 | * Properly handles rate-limiting by Twitter 524 | 525 | = 0.44 (0.2.3) = 526 | * Removes follow button if Twitter has returned an empty value 527 | 528 | = 0.43 (0.2.2) = 529 | * Improved error checking if Twitter has returned an empty value 530 | 531 | = 0.42 (0.2.1) = 532 | * Fixed major bug causing crashes when Twitter goes down 533 | 534 | = 0.40 (0.2.0) = 535 | * Added ability to alter speed of rotation 536 | 537 | = 0.30 (0.1.8) = 538 | * Fixes bug - problem with `get_object_vars()` on line 193 539 | 540 | = 0.29 (0.1.7) = 541 | * Better handling of retweets. No longer cuts off the end of the text on longer RTs. 542 | 543 | = 0.28 (0.1.6) = 544 | * Properly fixes flaw in how flags are handled. 545 | 546 | = 0.27 (0.1.5) = 547 | * Fixed flaw in how flags are handled. 548 | 549 | = 0.26 (0.1.4) = 550 | * Stops display and cacheing of non-existent twitter feeds 551 | 552 | = 0.25 (0.1.3) = 553 | * Stops display and cacheing of faulty twitter feeds 554 | 555 | = 0.21 (0.1.2) = 556 | * Replaced a missing `` in the follow-button code (with thanks to [jacobp](http://wordpress.org/support/profile/jacobp) for spotting it and suggesting a fix) 557 | 558 | = 0.2 (0.1.1) = 559 | * Fixed a problem with cacheing 560 | 561 | = 0.1 (0.1.0) = 562 | * First published version 563 | 564 | == Screenshots == 565 | 566 | 1. This animation shows rotating tweets inserted into a blog-post via a short code. It is slightly faster than the default setting, but gives a sense of what you get. 567 | 568 | ![Tweet Widget](./screenshot-1.gif) 569 | 570 | 2. You can add rotating tweets via a Widget: 571 | 572 | ![Rotating tweets](./screenshot-2.png) 573 | 574 | 3. Or by using a shortcode: 575 | 576 | ![Shortcode](./screenshot-3.png) -------------------------------------------------------------------------------- /screenshot-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/screenshot-1.gif -------------------------------------------------------------------------------- /screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/screenshot-2.png -------------------------------------------------------------------------------- /screenshot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/wp-rotatingtweets/2f2515a5d54bd01e23a1889deab8e0d2bda09986/screenshot-3.png --------------------------------------------------------------------------------