diff --git a/www/static/common/jquery/jTweetsAnywhere/jquery.jtweetsanywhere-1.2.1.css b/www/static/common/jquery/jTweetsAnywhere/jquery.jtweetsanywhere-1.2.1.css deleted file mode 100755 index 3f3e8d4ee1..0000000000 --- a/www/static/common/jquery/jTweetsAnywhere/jquery.jtweetsanywhere-1.2.1.css +++ /dev/null @@ -1,295 +0,0 @@ -/* - * jTweetsAnywhere V1.2.1 - * http://thomasbillenstein.com/jTweetsAnywhere/ - * - * Copyright 2010, Thomas Billenstein - * Licensed under the MIT license. - * http://thomasbillenstein.com/jTweetsAnywhere/license.txt - */ - -.jta-tweet-list -{ - padding: 0; - list-style: none; -} - -.jta-tweet-list-item -{ - background: #fafafa; - border-bottom: 1px solid #e4e4e4; - padding: 8px 0px 8px 0px; - overflow: hidden; -} - -.jta-tweet-list-item:first-child -{ - border-top: 1px solid #e4e4e4; -} - -.jta-tweet-profile-image -{ - width: 48px; - display: inline; - float: left; -} - -.jta-tweet-profile-image-link -{ -} - -.jta-tweet-profile-image img -{ - width: 48px; - height: 48px; -} - -.jta-tweet-body -{ -} - -.jta-tweet-body-list-profile-image-present -{ - margin-left: 58px; -} - -.jta-tweet-user-name -{ - font-weight: bold; -} - -.jta-tweet-user-screen-name -{ -} - -.jta-tweet-user-full-name -{ - color: #900; -} - -.jta-tweet-text -{ -} - -.jta-tweet-user-screen-name-link, -.jta-tweet-user-full-name-link, -.jta-tweet-a, -.twitter-anywhere-user -{ - color: #900; - text-decoration: none; -} - -.jta-tweet-user-screen-name-link:hover, -.jta-tweet-user-full-name-link:hover, -.jta-tweet-a:hover, -.twitter-anywhere-user:hover -{ - color: #900; - text-decoration: underline; -} - -.jta-tweet-link -{ -} - -.jta-tweet-link:hover -{ -} - -.jta-tweet-hashtag -{ -} - -.jta-tweet-hashtag:hover -{ -} - -.jta-tweet-attributes -{ - display: block; - color: #999; - font-size: 11px; - margin-top: 3px; -} - -.jta-tweet-timestamp -{ -} - -.jta-tweet-source -{ -} - -.jta-tweet-inreplyto -{ -} - -.jta-tweet-location -{ -} - -.jta-tweet-retweeter -{ -} - -.jta-tweet-timestamp-link, -.jta-tweet-source-link a, -.jta-tweet-inreplyto-link, -.jta-tweet-location-link, -.jta-tweet-retweeter-link -{ - color: #999; - text-decoration: none; -} - -.jta-tweet-timestamp-link:hover, -.jta-tweet-source-link a:hover, -.jta-tweet-inreplyto-link:hover, -.jta-tweet-location-link:hover, -.jta-tweet-retweeter-link:hover -{ - color: #999; - text-decoration: underline; -} - -.jta-tweet-list-controls -{ - margin-top: 20px; -} - -.jta-tweet-list-controls-button -{ - padding: 5px; - padding-left: 20px; - padding-right: 20px; - text-align: center; - border: 1px solid #999; -} - -.jta-tweet-list-controls-button:hover -{ - color: black; - background-color: #999; - cursor: pointer; -} - -.jta-tweet-list-controls-button-more -{ -} - -.jta-tweet-list-controls-button-prev -{ -} - -.jta-tweet-list-controls-button-next -{ - margin-left: 10px; -} - -.jta-tweet-list-autorefresh-trigger -{ - padding: 8px 0px 8px 0px; - margin-bottom: 10px; - text-align: center; - border: 1px solid #999; -} - -.jta-tweet-list-autorefresh-trigger:hover -{ - color: black; - background-color: #999; - cursor: pointer; -} - -.jta-tweet-list-autorefresh-trigger-content -{ -} - -.jta-follow-button -{ -} - - -.jta-tweet-box -{ -} - - -.jta-connect-button -{ -} - - -.jta-login-info -{ -} - -.jta-login-info-profile-image -{ - width: 48px; - display: inline; - float: left; -} - -.jta-login-info-profile-image img -{ - width: 48px; - height: 48px; -} - -.jta-login-info-block -{ - margin-left: 58px; -} - -.jta-login-info-screen-name -{ -} - -.jta-login-info-sign-out -{ - width: 97px; - margin-top: 2px; - padding: 1px; - text-align: center; - border: 1px solid #999; -} - -.jta-login-info-sign-out:hover -{ - color: black; - background-color: #999; - cursor: pointer; -} - - -.jta-loading -{ - margin: 0; - padding: 8px 0px 8px 0px; -} - -.jta-error -{ - margin: 0; - padding: 8px; - color: #000; - background-color: #f00 -} - -.jta-nodata -{ - margin: 0; - padding-top: 8px; - padding-bottom: 8px; -} - -.jta-clear -{ - clear: both; - display: block; - overflow: hidden; - visibility: hidden; - width: 0; - height: 0; -} diff --git a/www/static/common/jquery/jTweetsAnywhere/jquery.jtweetsanywhere-1.2.1.js b/www/static/common/jquery/jTweetsAnywhere/jquery.jtweetsanywhere-1.2.1.js deleted file mode 100755 index 32903d65bc..0000000000 --- a/www/static/common/jquery/jTweetsAnywhere/jquery.jtweetsanywhere-1.2.1.js +++ /dev/null @@ -1,1807 +0,0 @@ -/* - * jTweetsAnywhere V1.2.1 - * http://thomasbillenstein.com/jTweetsAnywhere/ - * - * Copyright 2010, Thomas Billenstein - * Licensed under the MIT license. - * http://thomasbillenstein.com/jTweetsAnywhere/license.txt - */ -(function($) -{ - $.fn.jTweetsAnywhere = function(options) - { - // setup the default options - var options = $.extend( - { - /** - * The user's name who's tweet feed or list feed is displayed. This - * param is also used when a Twitter "Follow Button" is displayed. Usually - * this param is a string, but can also be an array of strings. If an array - * is supplied (and the params 'list' and 'searchParams' are null), a - * combined feed of all users is displayed. - * - * Sample: 'tbillenstein' or ['twitterapi', '...', '...'] - */ - username: 'tbillenstein', - - /** - * The name of a user's list where the tweet feed is generated from - */ - list: null, - - /** - * A single search param string or an array of search params, to be used in - * a Twitter search call. All Twitter Search Params are supported - * See here for the details: - * http://apiwiki.twitter.com/Twitter-Search-API-Method%3A-search - * - * Sample: 'q=twitter' or ['q=twitter', 'geocode=48.856667,2.350833,30km'] - */ - searchParams: null, - - /** - * The number of tweets shown in the tweet feed. If this param is 0, no feed - * is displayed. For user or list feeds the maximum count is 20, for search - * results the maximum count is 100. - * - * Unlike in previous releases, since 1.2.0 jTweetsAnywhere is based on a - * tweets caching algorithm that will always deliver the requested count of - * tweets accepting that this request can only be fullfilled by calling Twitter - * more than once. - * - * IMPORTANT: Please always keep in mind, that the use of the Twitter API is - * rate limited. Non-authenticated users are rated IP-based and you have only - * 150 calls per hour available. Every retrieval of tweets counts and so does - * for example hovering over a profile image to show the hovercard. - * jTweetsAnywhere will always check the remaining count of free API calls before - * actually calling Twitter to avoid black listing your visitor's IP. - */ - count: 0, - - /** - * A flag (true/false) that specifies whether to display a profile image in - * tweets. If the param is set to null (the default value), a profile image - * is displayed only if the feed represents a user's list or the result of a - * Twitter search. - * - * THIS OPTION IS DEPRECATED. You should use showTweetFeed.showProfileImages - * instead. - */ - tweetProfileImagePresent: null, - - /** - * Each tweet that is loaded from Twitter will pass the tweetFilter. if - * the filter returns true, the tweet will be added to the tweets cache - * otherwise it is ignored. The defaultTweetFilter alsways retruns true - * but you can supply your own tweet filter to customize the tweet feed. - */ - tweetFilter: defaultTweetFilter, - - /** - * A flag (true/false) that specifies whether to display a Tweet Feed - * or an object literal representing the configuration options for the - * Tweet Feed. This flag works in conjunction with the count parameter: - * - if count equals 0, no feed is displayed, ignoring showTweetFeed - * - if count not equals 0 and showTweetFeed equals false, no feed - * is displayed - * { - * expandHovercards: false, // Boolean - Show Hovercards in expanded mode. - * - * showTimestamp: true, // A flag (true/false) that specifies whether to display a tweet's timestamp - * // or an object literal representing the configuration options for the - * // timestamp. - * // { - * // refreshInterval: 0, // Time in seconds to be waited until the - * // // timestamps of the displayed tweets get refreshed - * // // 0 means no refreshing. - * // } - * - * showSource: false, // Boolean - Show info about the source of the tweet. - * - * showGeoLocation: true, // Boolean - Show geolocation info and link to Google maps. - * - * showInReplyTo: true, // Boolean - Show link to the "replied to" tweet (if available). - * - * showProfileImages: null, // A flag (true/false) that specifies whether to display a profile image in - * // tweets. If the param is set to null (the default value), a profile image - * // is displayed only if the feed represents a user's list or the result of a - * // Twitter search. - * - * showUserScreenNames: null, // A flag (true/false/null) that specifies whether to display a username in - * // tweets. If the param is set to null (the default value), a username - * // is displayed only if the feed represents a user's list or the result of a - * // Twitter search. - * - * showUserFullNames: false, // A flag (true/false/null) that specifies whether to display a user's full name - * // in tweets. If the param is set to null, a user's full name - * // is displayed only if the feed represents a user's list or the result of a - * // Twitter search. - * - * includeRetweets: true, // Boolean - Include native retweets in a user's tweet feed - * - * paging: // An object literal representing the configuration options for the - * { // paging support, that specifies how more/earlier tweets can be loaded - * mode: "none" // by using the supplied UI controls (more/next buttons, scrollbar). - * }, // Accepted values for mode are: "none" | "more" | "prev-next" | "endless-scroll" - * // if mode equals "endless-scroll" you have to set the height of the tweet feed - * // element (.jta-tweet-list) in your CSS to get a scrollbar! You should also set - * // the "overflow" attribute to "auto". - * - * autorefresh: // An object literal representing the configuration options for the - * { // autorefresh behaviour. - * - * // IMPORTANT: Please always keep in mind, that using the Twitter API is rate - * // limited. Non-authenticated users are rated IP-based and you have only 150 - * // calls per hour available. Every retrieval of tweets counts and so does for - * // example hovering over a profile image to show the hovercard. jTweetsAnywhere will - * // always check the remaining count of free API calls before actually calling - * // Twitter to avoid black listing your visitor's IP. - * - * // However - choose your settings wisely to keep your visitors happy. An update - * // interval of 30 seconds on a feed that is updated averaged once per hour - * // does not make sense and is a total waste of remaining API calls! - * - * mode: "none", // Accepted values for mode are: "none" | "auto-insert" | "trigger-insert" - * // "none" (the default value) - disables the autorefresh feature - * // "auto-insert" - automatically insert the new tweets on top of the tweet feed - * // "trigger-insert" - if new tweets arrived, show or update a button that displays - * // the number of new tweets. These new tweets are inserted on top of the tweet - * // feed, if the user clicks on the button. - * - * interval: 60, // Time in seconds to be waited until the next request for new tweets. Minimum - * // value is 30. - * - * duration: 3600 // Time in seconds for how long the autorefresh will be active. After - * // this period of time, autorefreshing will stop. A value of -1 means - * // autorefresh for ever. - * } - * } - */ - showTweetFeed: true, - - /** - * A flag (true/false) that specifies whether to display a Twitter "Follow - * Button". - */ - showFollowButton: false, - - /** - * A flag (true/false) that specifies whether to display a Twitter "Connect - * Button" or an object literal representing the configuration options for - * the "Tweet Box". - * { - * size: 'medium' // String - The size of the Connect Button. Valid values are: small, medium, large, xlarge - * } - */ - showConnectButton: false, - - /** - * A flag (true/false) that specifies whether to display Login Infos. - */ - showLoginInfo: false, - - /** - * A flag (true/false) that specifies whether to display a Twitter "Tweet - * Box" or an object literal representing the configuration options for - * the "Tweet Box". - * { - * counter: true, // Boolean - Display a counter in the Tweet Box for counting characters - * width: 515, // Number - The width of the Tweet Box in pixels - * height: 65, // Number - The height of the Tweet Box in pixels - * label: "What's happening", // String - The text above the Tweet Box, a call to action - * defaultContent: , // String - Pre-populated text in the Tweet Box. Useful for an @mention, a #hashtag, a link, etc. - * onTweet: // Function - Specify a listener for when a tweet is sent from the Tweet Box. The listener receives two arguments: a plaintext tweet and an HTML tweet - * } - */ - showTweetBox: false, - - /** - * A decorator is a function that is responsible for constructing a certain - * element of the widget. Most of the decorators return a HTML string. - * Exceptions are the mainDecorator, which defines the basic sequence of - * the widget's components, plus the linkDecorator, the usernameDecorator - * and the hashtagDecorator which return the string that is supplied as a - * function param, enriched with the HTML tags. - * - * For details, see the implementations of the default decorators. Each - * default decorator can be overwritten by your own implementation. - */ - mainDecorator: defaultMainDecorator, - - tweetFeedDecorator: defaultTweetFeedDecorator, - - tweetDecorator: defaultTweetDecorator, - tweetProfileImageDecorator: defaultTweetProfileImageDecorator, - tweetBodyDecorator: defaultTweetBodyDecorator, - tweetUsernameDecorator: defaultTweetUsernameDecorator, - tweetTextDecorator: defaultTweetTextDecorator, - tweetAttributesDecorator: defaultTweetAttributesDecorator, - tweetTimestampDecorator: defaultTweetTimestampDecorator, - tweetSourceDecorator: defaultTweetSourceDecorator, - tweetGeoLocationDecorator: defaultTweetGeoLocationDecorator, - tweetInReplyToDecorator: defaultTweetInReplyToDecorator, - tweetRetweeterDecorator: defaultTweetRetweeterDecorator, - - tweetFeedControlsDecorator: defaultTweetFeedControlsDecorator, - tweetFeedControlsMoreBtnDecorator: defaultTweetFeedControlsMoreBtnDecorator, - tweetFeedControlsPrevBtnDecorator: defaultTweetFeedControlsPrevBtnDecorator, - tweetFeedControlsNextBtnDecorator: defaultTweetFeedControlsNextBtnDecorator, - - tweetFeedAutorefreshTriggerDecorator: defaultTweetFeedAutorefreshTriggerDecorator, - tweetFeedAutorefreshTriggerContentDecorator: defaultTweetFeedAutorefreshTriggerContentDecorator, - - connectButtonDecorator: defaultConnectButtonDecorator, - - loginInfoDecorator: defaultLoginInfoDecorator, - loginInfoContentDecorator: defaultLoginInfoContentDecorator, - - followButtonDecorator: defaultFollowButtonDecorator, - - tweetBoxDecorator: defaultTweetBoxDecorator, - - linkDecorator: defaultLinkDecorator, - usernameDecorator: defaultUsernameDecorator, - hashtagDecorator: defaultHashtagDecorator, - - loadingDecorator: defaultLoadingDecorator, - errorDecorator: defaultErrorDecorator, - noDataDecorator: defaultNoDataDecorator, - - /** - * Formatters are currently used for date format processing only. - * - * The tweetTimestampFormatter formats the tweet's timestamp to be shown - * in the tweet attributes section - * - * For details, see the implementation of the defaultTweetTimestampFormatter. - */ - tweetTimestampFormatter : defaultTweetTimestampFormatter, - - /** - * The tweetTimestampTooltipFormatter formats the tweet's timestamp to be shown - * in the tooltip when hovering over the timestamp link. - */ - tweetTimestampTooltipFormatter : defaultTweetTimestampTooltipFormatter, - - /** - * A visualizer is a function that is responsible for adding one or more - * elements to the DOM and thereby making them visible to the user. - * A visualizer might also be responsible to do the opposite effect: - * To remove one or more elements from the DOM. - * - * The tweetVisualizer gets called each time a tweet element should be - * appended or prepended to the tweet feed element. - * - * For details, see the implementation of the defaultTweetVisualizer. - * - * Each default visualizer can be overwritten by your own implementation. - */ - tweetVisualizer: defaultTweetVisualizer, - - /** - * The loadingIndicatorVisualizer gets called each time data is retrieved - * from Twitter to visualize the loading indicator. This visualizer is also - * used to hide the loading indicator. - * - * For details, see the implementation of the defaultLoadingIndicatorVisualizer. - */ - loadingIndicatorVisualizer: defaultLoadingIndicatorVisualizer, - - /** - * The autorefreshTriggerVisualizer will be called if the autorefresh - * trigger should be visualized or hidden. - * - * For details, see the implementation of the autorefreshTriggerVisualizer. - */ - autorefreshTriggerVisualizer: defaultAutorefreshTriggerVisualizer, - - /** - * An event handler is a function that gets called whenever the event you - * are interested in, occurs. - * - * The onDataRequest event handler will be called immediatly before calling - * Twitter to retrieve new data and gives you the opportunity to deny - * the call by returning false from the function. - * - * This feature might be used in conjunction with the paging feature, - * especially when using the "endless-scroll" paging mode, to avoid the - * exhaustion of remaining Twitter API calls, before the rate limit is - * reached. The stats parameter contains statistical infos and counters - * that you can examine to base your decision whether to return true or - * false. - */ - onDataRequestHandler: defaultOnDataRequestHandler, - - /** - * The onRateLimitData event handler is called each time - * jTweetsAnywhere retrieved the rate limit data from Twitter. The actual - * rate limit data is contained in the stats object. - */ - onRateLimitDataHandler: defaultOnRateLimitDataHandler, - - _tweetFeedConfig: - { - expandHovercards: false, - showTimestamp: - { - refreshInterval: 0 - }, - showSource: false, - showGeoLocation: true, - showInReplyTo: true, - showProfileImages: null, - showUserScreenNames: null, - showUserFullNames: false, - includeRetweets: true, - paging: - { - mode: "none", - _limit: 0, - _offset: 0 - }, - autorefresh: - { - mode: "none", - interval: 60, - duration: 3600, - _startTime: null, - _triggerElement: null - }, - _pageParam: 0, - _maxId: null, - _recLevel: 0, - _noData: false, - _clearBeforePopulate: false - }, - _tweetBoxConfig: - { - counter: true, - width: 515, - height: 65, - label: "What's happening?", - defaultContent: '', - onTweet: function(textTweet, htmlTweet) {} - }, - _connectButtonConfig: - { - size: "medium" - }, - _baseSelector: null, - _baseElement: null, - _tweetFeedElement: null, - _tweetFeedControlsElement: null, - _followButtonElement: null, - _loginInfoElement: null, - _connectButtonElement: null, - _tweetBoxElement: null, - _loadingIndicatorElement: null, - _noDataElement: null, - _tweetsCache: [], - _autorefreshTweetsCache: [], - _stats: - { - dataRequestCount: 0, - rateLimitPreventionCount: 0, - rateLimit: - { - remaining_hits: 150, - hourly_limit: 150 - } - } - }, options); - - // no main decorator? nothing to do! - if (!options.mainDecorator) - { - return; - } - - options._baseSelector = this.selector; - - // if username is an array, create the search query and flatten username - if (typeof(options.username) != 'string') - { - if (!options.searchParams) - { - options.searchParams = ['q=from:' + options.username.join(" OR from:")]; - } - - options.username = options.username[0]; - } - - // if showTweetFeed is not set to a boolean value, we expect the configuration of - // the tweet feed - if (typeof(options.showTweetFeed) == 'object') - { - $.extend(true, options._tweetFeedConfig, options.showTweetFeed); - } - - // if showTweetBox is not set to a boolean value, we expect the configuration of - // the TweetBox - if (typeof(options.showTweetBox) == 'object') - { - options._tweetBoxConfig = options.showTweetBox; - options.showTweetBox = true; - } - - // if showConnectButton is not set to a boolean value, we expect the - // configuration of the Connect Button - if (typeof(options.showConnectButton) == 'object') - { - options._connectButtonConfig = options.showConnectButton; - options.showConnectButton = true; - } - - // to be compatible, check the deprecated option 'tweetProfileImagePresent' - if (options._tweetFeedConfig.showProfileImages == null) - { - options._tweetFeedConfig.showProfileImages = options.tweetProfileImagePresent; - } - - // if _tweetFeedConfig.showProfileImages is not set to a boolean value, - // we decide to show a profile image if the feed represents a user's - // list or the results of a Twitter search - if (options._tweetFeedConfig.showProfileImages == null) - { - options._tweetFeedConfig.showProfileImages = (options.list || options.searchParams) && options.tweetProfileImageDecorator; - } - - // if _tweetFeedConfig.showUserScreenNames is not set to a boolean value, - // we decide to show a username if the feed represents a user's - // list or the results of a Twitter search or a tweet is a native retweet - if (options._tweetFeedConfig.showUserScreenNames == null) - { - if (options.list || options.searchParams) - { - options._tweetFeedConfig.showUserScreenNames = true; - } - - if (!options.tweetUsernameDecorator) - { - options._tweetFeedConfig.showUserScreenNames = false; - } - } - - // if _tweetFeedConfig.showUserFullNames is not set to a boolean value, - // we decide to show a user's full name if the feed represents a user's - // list or the results of a Twitter search or a tweet is a native retweet - if (options._tweetFeedConfig.showUserFullNames == null) - { - if (options.list || options.searchParams) - { - options._tweetFeedConfig.showUserFullNames = true; - } - - if (!options.tweetUsernameDecorator) - { - options._tweetFeedConfig.showUserFullNames = false; - } - } - - options.count = validateRange(options.count, 0, options.searchParams ? 100 : 20); - - options._tweetFeedConfig.autorefresh.interval = Math.max(30, options._tweetFeedConfig.autorefresh.interval); - - options._tweetFeedConfig.paging._offset = 0; - options._tweetFeedConfig.paging._limit = options.count; - - // internally, the decision of what parts of a widget are to be - // displayed is based on the existence of the decorators - if (options.count == 0 || !options.showTweetFeed) - { - options.tweetFeedDecorator = null; - options.tweetFeedControlsDecorator = null; - } - - if (options._tweetFeedConfig.paging.mode == 'none') - { - options.tweetFeedControlsDecorator = null; - } - - if (!options.showFollowButton) - { - options.followButtonDecorator = null; - } - - if (!options.showTweetBox) - { - options.tweetBoxDecorator = null; - } - - if (!options.showConnectButton) - { - options.connectButtonDecorator = null; - } - - if (!options.showLoginInfo) - { - options.loginInfoDecorator = null; - } - - if (!options._tweetFeedConfig.showTimestamp) - { - options.tweetTimestampDecorator = null; - } - - if (!options._tweetFeedConfig.showSource) - { - options.tweetSourceDecorator = null; - } - - if (!options._tweetFeedConfig.showGeoLocation) - { - options.tweetGeoLocationDecorator = null; - } - - if (!options._tweetFeedConfig.showInReplyTo) - { - options.tweetInReplyToDecorator = null; - } - - // setup ajax - $.ajaxSetup({ cache: true }); - - return this.each(function() - { - // the DOM element, where to display the widget - options._baseElement = $(this); - - // create the widget's necessary sub DOM elements - options._tweetFeedElement = options.tweetFeedDecorator ? $(options.tweetFeedDecorator(options)) : null; - options._tweetFeedControlsElement = options.tweetFeedControlsDecorator ? $(options.tweetFeedControlsDecorator(options)) : null; - options._followButtonElement = options.followButtonDecorator ? $(options.followButtonDecorator(options)) : null; - options._tweetBoxElement = options.tweetBoxDecorator ? $(options.tweetBoxDecorator(options)) : null; - options._connectButtonElement = options.connectButtonDecorator ? $(options.connectButtonDecorator(options)): null; - options._loginInfoElement = options.loginInfoDecorator ? $(options.loginInfoDecorator(options)) : null; - - // add the widget to the DOM - options.mainDecorator(options); - - populateTweetFeed(options); - populateAnywhereControls(options); - - // bind event handlers to support paging - bindEventHandlers(options); - - // install autorefresh support - options._tweetFeedConfig.autorefresh._startTime = new Date().getTime(); - startAutorefresh(options); - startTimestampRefresh(options); - }); - }; - defaultMainDecorator = function(options) - { - // defines the default sequence of the widget's elements - if (options._tweetFeedElement) - { - options._baseElement.append(options._tweetFeedElement); - } - - if (options._tweetFeedControlsElement) - { - options._baseElement.append(options._tweetFeedControlsElement); - } - - if (options._connectButtonElement) - { - options._baseElement.append(options._connectButtonElement); - } - - if (options._loginInfoElement) - { - options._baseElement.append(options._loginInfoElement); - } - - if (options._followButtonElement) - { - options._baseElement.append(options._followButtonElement); - } - - if (options._tweetBoxElement) - { - options._baseElement.append(options._tweetBoxElement); - } - }; - defaultTweetFeedControlsDecorator = function(options) - { - // the default tweet feed's paging controls - var html = ''; - - if (options._tweetFeedConfig.paging.mode == 'prev-next') - { - if (options.tweetFeedControlsPrevBtnDecorator) - { - html += options.tweetFeedControlsPrevBtnDecorator(options); - } - - if (options.tweetFeedControlsNextBtnDecorator) - { - html += options.tweetFeedControlsNextBtnDecorator(options); - } - } - else if (options._tweetFeedConfig.paging.mode == 'endless-scroll') - { - // nothing to do here atm - } - else - { - if (options.tweetFeedControlsMoreBtnDecorator) - { - html += options.tweetFeedControlsMoreBtnDecorator(options); - } - } - - return '
' + html + '
'; - }; - defaultTweetFeedControlsMoreBtnDecorator = function(options) - { - return '' + 'More' + ''; - }; - defaultTweetFeedControlsPrevBtnDecorator = function(options) - { - return '' + 'Prev' + ''; - }; - defaultTweetFeedControlsNextBtnDecorator = function(options) - { - return '' + 'Next' + ''; - }; - defaultTweetFeedAutorefreshTriggerDecorator = function(count, options) - { - var html = ''; - - if (options.tweetFeedAutorefreshTriggerContentDecorator) - { - html = options.tweetFeedAutorefreshTriggerContentDecorator(count, options); - } - - return '
  • ' + html + '
  • '; - }; - defaultTweetFeedAutorefreshTriggerContentDecorator = function(count, options) - { - var content = '' + count + ' new ' + (count > 1 ? ' tweets' : ' tweet'); - - return '' + content + ''; - }; - defaultTweetFeedDecorator = function(options) - { - // the default placeholder for the tweet feed is an unordered list - return ''; - }; - defaultTweetDecorator = function(tweet, options) - { - // the default tweet is made of the optional user's profile image and the - // tweet body inside a list item element - var html = ''; - - if (options._tweetFeedConfig.showProfileImages) - { - html += options.tweetProfileImageDecorator(tweet, options); - } - - if (options.tweetBodyDecorator) - { - html += options.tweetBodyDecorator(tweet, options); - } - - html += '
     
    '; - - return '
  • ' + html + '
  • '; - }; - defaultTweetProfileImageDecorator = function(tweet, options) - { - // if tweet is a native retweet, use the retweet's profile - var t = tweet.retweeted_status || tweet; - - // the default profile image decorator simply adds a link to the user's Twitter profile - var screenName = t.user ? t.user.screen_name : false || t.from_user; - var imageUrl = t.user ? t.user.profile_image_url : false || t.profile_image_url; - - var html = - '' + - '' + screenName + '' + - ''; - - return '
    ' + html + '
    '; - }; - defaultTweetBodyDecorator = function(tweet, options) - { - // the default tweet body contains the tweet text and the tweet's creation date - var html = ''; - - if (options.tweetTextDecorator) - { - html += options.tweetTextDecorator(tweet, options); - } - - if (options.tweetAttributesDecorator) - { - html += options.tweetAttributesDecorator(tweet, options); - } - - return '
    ' + html + '
    '; - }; - defaultTweetTextDecorator = function(tweet, options) - { - var tweetText = tweet.text; - - // if usernames should be visible and tweet is a native retweet, use - // the original tweet text - if (tweet.retweeted_status && - ( - options._tweetFeedConfig.showUserScreenNames || - options._tweetFeedConfig.showUserScreenNames == null || - options._tweetFeedConfig.showUserFullNames || - options._tweetFeedConfig.showUserFullNames == null - ) - ) - { - tweetText = tweet.retweeted_status.text; - } - - // the default tweet text decorator optionally marks links, @usernames, - // and #hashtags - if (options.linkDecorator) - { - tweetText = options.linkDecorator(tweetText, options); - } - - if (options.usernameDecorator) - { - tweetText = options.usernameDecorator(tweetText, options); - } - - if (options.hashtagDecorator) - { - tweetText = options.hashtagDecorator(tweetText, options); - } - - if (options._tweetFeedConfig.showUserScreenNames || - options._tweetFeedConfig.showUserFullNames || - tweet.retweeted_status && - ( - options._tweetFeedConfig.showUserScreenNames == null || - options._tweetFeedConfig.showUserFullNames == null - ) - ) - { - tweetText = options.tweetUsernameDecorator(tweet, options) + ' ' + tweetText; - } - - return '' + tweetText + ''; - }; - defaultTweetUsernameDecorator = function(tweet, options) - { - // if tweet is a native retweet, use the retweet's profile - var t = tweet.retweeted_status || tweet; - var screenName = t.user ? t.user.screen_name : false || t.from_user; - var fullName = t.user ? t.user.name : null; - - var htmlScreenName; - if (screenName && (options._tweetFeedConfig.showUserScreenNames || (options._tweetFeedConfig.showUserScreenNames == null && tweet.retweeted_status))) - { - htmlScreenName = - '' + - '' + - screenName + - '' + - ''; - } - - var htmlFullName; - if (fullName && (options._tweetFeedConfig.showUserFullNames || (options._tweetFeedConfig.showUserFullNames == null && tweet.retweeted_status))) - { - htmlFullName = - '' + - (htmlScreenName ? ' (' : '') + - '' + - fullName + - '' + - (htmlScreenName ? ')' : '') + - ''; - } - - var html = ""; - - if (htmlScreenName) - { - html += htmlScreenName; - } - - if (htmlFullName) - { - if (htmlScreenName) - { - html += ' '; - } - - html += htmlFullName; - } - - if (htmlScreenName || htmlFullName) - { - html = - '' + - (tweet.retweeted_status ? 'RT ' : '') + - html + - ''; - } - - return html; - }; - defaultTweetAttributesDecorator = function(tweet, options) - { - var html = ''; - - if (options.tweetTimestampDecorator || - options.tweetSourceDecorator || - options.tweetGeoLocationDecorator || - options.tweetInReplyToDecorator || - (tweet.retweeted_status && options.tweetRetweeterDecorator) - ) - { - html += ''; - - if (options.tweetTimestampDecorator) - { - html += options.tweetTimestampDecorator(tweet, options); - } - - if (options.tweetSourceDecorator) - { - html += options.tweetSourceDecorator(tweet, options); - } - - if (options.tweetGeoLocationDecorator) - { - html += options.tweetGeoLocationDecorator(tweet, options); - } - - if (options.tweetInReplyToDecorator) - { - html += options.tweetInReplyToDecorator(tweet, options); - } - - if (tweet.retweeted_status && options.tweetRetweeterDecorator) - { - html += options.tweetRetweeterDecorator(tweet, options); - } - - html += ''; - } - - return html; - }; - defaultTweetTimestampDecorator = function(tweet, options) - { - // the default tweet timestamp decorator does a little bit of Twitter like formatting. - - // if tweet is a native retweet, use the retweet's timestamp - var tw = tweet.retweeted_status || tweet; - - // reformat timestamp from Twitter, so IE is happy - var createdAt = formatDate(tw.created_at); - - // format the timestamp by the tweetTimestampFormatter - var tweetTimestamp = options.tweetTimestampFormatter(createdAt); - var tweetTimestampTooltip = options.tweetTimestampTooltipFormatter(createdAt); - - var screenName = tw.user ? tw.user.screen_name : false || tw.from_user; - var html = - '' + - '' + - tweetTimestamp + - '' + - ''; - - return html; - }; - defaultTweetTimestampTooltipFormatter = function(timeStamp) - { - var d = new Date(timeStamp); - - return d.toLocaleString(); - }; - defaultTweetTimestampFormatter = function(timeStamp) - { - var now = new Date(); - - var diff = parseInt((now.getTime() - Date.parse(timeStamp)) / 1000); - - var tweetTimestamp = ''; - if (diff < 60) - { - tweetTimestamp += diff + ' second' + (diff == 1 ? '' : 's') + ' ago'; - } - else if (diff < 3600) - { - var t = parseInt((diff + 30) / 60); - tweetTimestamp += t + ' minute' + (t == 1 ? '' : 's') + ' ago'; - } - else if (diff < 86400) - { - var t = parseInt((diff + 1800) / 3600); - tweetTimestamp += t + ' hour' + (t == 1 ? '' : 's') + ' ago'; - } - else - { - var d = new Date(timeStamp); - var period = 'AM'; - - var hours = d.getHours(); - if (hours > 12) - { - hours -= 12; - period = 'PM'; - } - - var mins = d.getMinutes(); - var minutes = (mins < 10 ? '0' : '') + mins; - - var monthName = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; - - tweetTimestamp += monthName[d.getMonth()] + ' ' + d.getDate(); - - if (d.getFullYear() < now.getFullYear()) - { - tweetTimestamp += ', ' + d.getFullYear(); - } - - var t = parseInt((diff + 43200) / 86400); - tweetTimestamp += ' (' + t + ' day' + (t == 1 ? '' : 's') + ' ago)'; - } - - return tweetTimestamp; - }; - exTimestampFormatter = function(timeStamp) - { - var diff = parseInt((new Date().getTime() - Date.parse(timeStamp)) / 1000); - - var tweetTimestamp = ''; - if (diff < 60) - { - tweetTimestamp += 'less than a minute ago'; - } - else if (diff < 3600) - { - var t = parseInt((diff + 30) / 60); - tweetTimestamp += t + ' minute' + (t == 1 ? '' : 's') + ' ago'; - } - else if (diff < 86400) - { - var t = parseInt((diff + 1800) / 3600); - tweetTimestamp += 'about ' + t + ' hour' + (t == 1 ? '' : 's') + ' ago'; - } - else - { - var t = parseInt((diff + 43200) / 86400); - tweetTimestamp += 'about ' + t + ' day' + (t == 1 ? '' : 's') + ' ago'; - - var d = new Date(timeStamp); - var period = 'AM'; - - var hours = d.getHours(); - if (hours > 12) - { - hours -= 12; - period = 'PM'; - } - - var mins = d.getMinutes(); - var minutes = (mins < 10 ? '0' : '') + mins; - - tweetTimestamp += ' (' + hours + ':' + minutes + ' ' + period + ' ' + (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear() + ')'; - } - - return tweetTimestamp; - }; - defaultTweetSourceDecorator = function(tweet, options) - { - // if tweet is a native retweet, use the retweet's source - var tw = tweet.retweeted_status || tweet; - - var source = tw.source.replace(/\<\;/gi,'<').replace(/\>\;/gi,'>').replace(/\"\;/gi,'"'); - var html = - '' + - ' via ' + - '' + - source + - '' + - ''; - - return html; - }; - defaultTweetGeoLocationDecorator = function(tweet, options) - { - var html = ''; - - // if tweet is a native retweet, use the retweet's source - var tw = tweet.retweeted_status || tweet; - - var q; - if (tw.geo && tw.geo.coordinates) - { - q = tw.geo.coordinates.join(); - } - else if (tw.place && tw.place.full_name) - { - q = tw.place.full_name; - } - - if (q) - { - var location = 'here'; - if (tw.place && tw.place.full_name) - { - location = tw.place.full_name; - } - - var link = 'http://maps.google.com/maps?q=' + q; - - html = - '' + - ' from ' + - '' + - location + - '' + - ''; - } - - return html; - }; - defaultTweetInReplyToDecorator = function(tweet, options) - { - // if tweet is a native retweet, use the retweet's source - var tw = tweet.retweeted_status || tweet; - - var html = ''; - if (tw.in_reply_to_status_id && tw.in_reply_to_screen_name) - { - html = - '' + - ' ' + - '' + - 'in reply to ' + tw.in_reply_to_screen_name + - '' + - ''; - } - - return html; - }; - defaultTweetRetweeterDecorator = function(tweet, options) - { - var html = ''; - - if (tweet.retweeted_status) - { - var screenName = tweet.user ? tweet.user.screen_name : false || tweet.from_user; - var rtc = (tweet.retweeted_status.retweet_count || 0) - 1; - - var link = - '' + - screenName + - ''; - var rtcount = ' and ' + rtc + (rtc > 1 ? ' others' : ' other'); - html = - '
    ' + - '' + - 'Retweeted by ' + link + - (rtc > 0 ? rtcount : '') + - ''; - } - - return html; - }; - defaultConnectButtonDecorator = function(options) - { - // the default placeholder for the @Anywhere ConnectButton - return '
    '; - }; - defaultLoginInfoDecorator = function(options) - { - // the default placeholder for the LoginInfo - return ''; - }; - defaultLoginInfoContentDecorator = function(options, T) - { - // the default markup of the LoginInfo content: the user's profile image, the - // user's screen_name and a "button" to sign out - var html = ''; - - if (T.isConnected()) - { - var screenName = T.currentUser.data('screen_name'); - var imageUrl = T.currentUser.data('profile_image_url'); - - html = - '' + - '' + - '
     
    ' - ; - } - - return html; - }; - defaultFollowButtonDecorator = function(options) - { - // the default placeholder for the @Anywhere FollowButton - return '
    '; - }; - defaultTweetBoxDecorator = function(options) - { - // the default placeholder for the @Anywhere TweetBox - return '
    '; - }; - defaultLinkDecorator = function(text, options) - { - // the regex to markup links - return text.replace(/((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi,'$1<\/a>'); - }; - defaultUsernameDecorator = function(text, options) - { - // the regex to markup @usernames. if @Anywhere is present the task is left to - // them - return isAnywherePresent() ? text : text.replace(/@([a-zA-Z0-9_]+)/gi,'@#$1<\/a>'); - }; - defaultLoadingDecorator = function(options) - { - // the default loading decorator simply says: loading ... - return '
  • loading ...
  • '; - }; - defaultErrorDecorator = function(errorText, options) - { - // the default error decorator shows the error message - return '
  • ERROR: ' + errorText + '
  • '; - }; - defaultNoDataDecorator = function(options) - { - // the default no-data decorator simply says: No more data - return '
  • No more data
  • '; - }; - - defaultTweetFilter = function(tweet, options) - { - return true; - }; - - defaultTweetVisualizer = function(tweetFeedElement, tweetElement, inserter, options) - { - // insert (append/prepend) the tweetElement to the tweetFeedElement - tweetFeedElement[inserter](tweetElement); - }; - defaultLoadingIndicatorVisualizer = function(tweetFeedElement, loadingIndicatorElement, options, callback) - { - defaultVisualizer(tweetFeedElement, loadingIndicatorElement, 'append', 'fadeIn', 600, 'fadeOut', 200, callback); - }; - defaultAutorefreshTriggerVisualizer = function(tweetFeedElement, triggerElement, options, callback) - { - defaultVisualizer(tweetFeedElement, triggerElement, 'prepend', 'slideDown', 600, 'fadeOut', 200, callback); - }; - defaultVisualizer = function(container, element, inserter, effectIn, durationIn, effectOut, durationOut, callback) - { - // if param container is null element has to be removed from - // the DOM, else element has to be inserted in container - - // if param callback is not null, the callback function must be called - // in any case, if the visualizer is done - - var cb = function() - { - if (callback) - { - callback(); - } - }; - - if (container) - { - element.hide(); - container[inserter](element); - element[effectIn](durationIn, cb); - } - else - { - element[effectOut](durationOut, function() - { - element.remove(); - cb(); - }); - } - }; - - defaultOnDataRequestHandler = function(stats, options) - { - return true; - }; - defaultOnRateLimitDataHandler = function(stats, options) - { - }; - - updateLoginInfoElement = function(options, T) - { - // update the content of the LoginInfo element - if (options._loginInfoElement && options.loginInfoContentDecorator) - { - options._loginInfoElement.children().remove(); - options._loginInfoElement.append(options.loginInfoContentDecorator(options, T)); - $(options._baseSelector + ' .jta-login-info-sign-out').bind('click', function() - { - twttr.anywhere.signOut(); - }); - } - }; - getFeedUrl = function(options, flPaging) - { - // create the Twitter API URL based on the configuration options - var url = ('https:' == document.location.protocol ? 'https:' : 'http:'); - - if (options.searchParams) - { - url += '//search.twitter.com/search.json?' + - ((options.searchParams instanceof Array) ? options.searchParams.join('&') : options.searchParams) + - '&rpp=100'; - } - else if (options.list) - { - url += '//api.twitter.com/1/' + options.username + '/lists/' + options.list + '/statuses.json?per_page=20'; - } - else - { - url += '//api.twitter.com/1/statuses/user_timeline.json?screen_name=' + options.username + '&count=20'; - if (options._tweetFeedConfig.includeRetweets) - url += '&include_rts=true'; - } - - if (flPaging) - { - url += - (options._tweetFeedConfig._maxId ? '&max_id=' + options._tweetFeedConfig._maxId : '') + - '&page=' + options._tweetFeedConfig._pageParam; - } - - url += '&callback=?'; - - return url; - }; - isAnywherePresent = function() - { - // check, if @Anywhere is present - return typeof(twttr) != 'undefined'; - }; - clearTweetFeed = function(options) - { - if (options._tweetFeedElement) - { - options._tweetFeedElement.empty(); - } - }; - populateTweetFeed = function(options) - { - // if a tweet feed is to be displayed, get the tweets and show them - if (options.tweetDecorator && options._tweetFeedElement) - { - getPagedTweets(options, function(tweets, options) - { - if (options._tweetFeedConfig._clearBeforePopulate) - { - clearTweetFeed(options); - } - - hideLoadingIndicator(options, function() - { - // process the tweets - $.each(tweets, function(idx, tweet) - { - // decorate the tweet and give it to the tweet visualizer - options.tweetVisualizer( - options._tweetFeedElement, - $(options.tweetDecorator(tweet, options)), - 'append', - options - ); - }); - - if (options._tweetFeedConfig._noData && options.noDataDecorator && !options._tweetFeedConfig._noDataElement) - { - options._tweetFeedConfig._noDataElement = $(options.noDataDecorator(options)); - options._tweetFeedElement.append(options._tweetFeedConfig._noDataElement); - } - - if (options._tweetFeedConfig._clearBeforePopulate) - { - options._tweetFeedElement.scrollTop(0); - } - - addHovercards(options); - }); - }); - } - }; - populateTweetFeed2 = function(options) - { - if (options._tweetFeedElement && options._autorefreshTweetsCache.length > 0) - { - if (options._tweetFeedConfig.autorefresh.mode == 'trigger-insert') - { - if (options._tweetFeedConfig.autorefresh._triggerElement) - { - if (options.tweetFeedAutorefreshTriggerContentDecorator) - { - options._tweetFeedConfig.autorefresh._triggerElement.html( - options.tweetFeedAutorefreshTriggerContentDecorator(options._autorefreshTweetsCache.length, options) - ); - } - } - else - { - if (options.tweetFeedAutorefreshTriggerDecorator) - { - options._tweetFeedConfig.autorefresh._triggerElement = - $(options.tweetFeedAutorefreshTriggerDecorator(options._autorefreshTweetsCache.length, options)); - options._tweetFeedConfig.autorefresh._triggerElement.bind('click', function() - { - options.autorefreshTriggerVisualizer( - null, - options._tweetFeedConfig.autorefresh._triggerElement, - options, - function() - { - insertTriggerTweets(options); - } - ); - options._tweetFeedConfig.autorefresh._triggerElement = null; - }); - - options.autorefreshTriggerVisualizer(options._tweetFeedElement, options._tweetFeedConfig.autorefresh._triggerElement, options); - } - } - } - else - { - insertTriggerTweets(options); - } - } - }; - insertTriggerTweets = function(options) - { - // populate the tweet feed with tweets from the autorefresh cache - if (options.tweetDecorator && options._autorefreshTweetsCache.length > 0) - { - // process the autorefresh cache - while (options._autorefreshTweetsCache.length > 0) - { - // get the last tweet and remove it from the autorefresh cache - var tweet = options._autorefreshTweetsCache.pop(); - - // put that tweet on top of the tweets cache - options._tweetsCache.unshift(tweet); - - // adjust paging offset - options._tweetFeedConfig.paging._offset++; - - // decorate the tweet and give it to the tweet visualizer - options.tweetVisualizer( - options._tweetFeedElement, - $(options.tweetDecorator(tweet, options)), - 'prepend', - options - ); - } - - addHovercards(options); - } - }; - addHovercards = function(options) - { - if (isAnywherePresent()) - { - // if @Anywhere is present, append Hovercards to @username and - // profile images - twttr.anywhere(function(T) - { - T(options._baseSelector + ' .jta-tweet-list').hovercards({expanded: options._tweetFeedConfig.expandHovercards}); - T(options._baseSelector + ' .jta-tweet-profile-image img').hovercards( - { - expanded: options._tweetFeedConfig.expandHovercards, - username: function(node) { return node.alt; } - }); - T(options._baseSelector + ' .jta-tweet-retweeter-link').hovercards( - { - expanded: options._tweetFeedConfig.expandHovercards, - username: function(node) { return node.text; } - }); - T(options._baseSelector + ' .jta-tweet-user-screen-name-link').hovercards( - { - expanded: options._tweetFeedConfig.expandHovercards, - username: function(node) { return node.text; } - }); - T(options._baseSelector + ' .jta-tweet-user-full-name-link').hovercards( - { - expanded: options._tweetFeedConfig.expandHovercards, - username: function(node) { return node.name; } - }); - }); - } - }; - populateAnywhereControls = function(options) - { - if (isAnywherePresent()) - { - twttr.anywhere(function(T) - { - // optionally add an @Anywhere TweetBox - if (options.tweetBoxDecorator) - { - T(options._baseSelector + ' .jta-tweet-box').tweetBox(options._tweetBoxConfig); - } - - // optionally add an @Anywhere FollowButton - if (options.followButtonDecorator) - { - T(options._baseSelector + ' .jta-follow-button').followButton(options.username); - } - - // optionally add an @Anywhere ConnectButton - if (options.connectButtonDecorator) - { - var o = $.extend( - { - authComplete: function(user) - { - // display/update login infos on connect/signin event - updateLoginInfoElement(options, T); - }, - signOut: function() - { - // display/update login infos on signout event - updateLoginInfoElement(options, T); - } - }, options._connectButtonConfig); - - T(options._baseSelector + ' .jta-connect-button').connectButton(o); - - // display/update login infos - updateLoginInfoElement(options, T); - } - }); - } - }; - bindEventHandlers = function(options) - { - if (options.tweetFeedControlsDecorator) - { - if (options._tweetFeedConfig.paging.mode == 'prev-next') - { - $(options._baseSelector + ' .jta-tweet-list-controls-button-prev').bind('click', function() - { - if (!isLoading(options) && options._tweetFeedConfig.paging._offset > 0) - { - prevPage(options, true); - } - }); - $(options._baseSelector + ' .jta-tweet-list-controls-button-next').bind('click', function() - { - if (!isLoading(options)) - { - nextPage(options, true); - } - }); - } - else if (options._tweetFeedConfig.paging.mode == 'endless-scroll') - { - options._tweetFeedElement.bind("scroll", function() - { - if (!isLoading(options) && ($(this)[0].scrollHeight - $(this).scrollTop() == $(this).outerHeight())) - { - nextPage(options, false); - } - }); - } - else - { - $(options._baseSelector + ' .jta-tweet-list-controls-button-more').bind('click', function() - { - if (!isLoading(options)) - { - nextPage(options, false); - } - }); - } - } - }; - nextPage = function(options, flClear) - { - doPage(options, flClear, Math.min(options._tweetFeedConfig.paging._offset + options._tweetFeedConfig.paging._limit, options._tweetsCache.length)); - }; - prevPage = function(options, flClear) - { - doPage(options, flClear, Math.max(0, options._tweetFeedConfig.paging._offset - options._tweetFeedConfig.paging._limit)); - }; - doPage = function(options, flClear, newOffset) - { - options._tweetFeedConfig.paging._offset = newOffset; - options._tweetFeedConfig._clearBeforePopulate = flClear; - - populateTweetFeed(options); - }; - startAutorefresh = function(options) - { - if (options._tweetFeedConfig.autorefresh.mode != 'none' && - options._tweetFeedConfig.paging.mode != 'prev-next' && - options._tweetFeedConfig.autorefresh.duration != 0 && - ( - options._tweetFeedConfig.autorefresh.duration < 0 || - (new Date().getTime() - options._tweetFeedConfig.autorefresh._startTime) <= options._tweetFeedConfig.autorefresh.duration * 1000 - ) - ) - { - window.setTimeout(function() { processAutorefresh(options); }, options._tweetFeedConfig.autorefresh.interval * 1000); - } - }; - stopAutorefresh = function(options) - { - options._tweetFeedConfig.autorefresh.duration = 0; - }; - processAutorefresh = function(options) - { - if (options._tweetFeedConfig.autorefresh.duration != 0) - { - // load the data ... - getRateLimitedData(options, true, getFeedUrl(options, false), function(data, options) - { - // reverse the sequence of the autorefresh tweets ... - var tweets = (data.results || data).slice(0); - tweets.reverse(); - - // ...then process them - $.each(tweets, function(idx, tweet) - { - // if this tweet is already in the standard tweets cache, ignore - if (!isTweetInCache(tweet, options)) - { - // optionally filter tweet ... - if (options.tweetFilter(tweet, options)) - { - // ... then put it to the top of the autorefresh cache - options._autorefreshTweetsCache.unshift(tweet); - } - } - }); - - populateTweetFeed2(options); - }); - - // restart autorefresh - startAutorefresh(options); - } - }; - startTimestampRefresh = function(options) - { - if ( - options.tweetTimestampDecorator && - typeof(options._tweetFeedConfig.showTimestamp) == 'object' && - options._tweetFeedConfig.showTimestamp.refreshInterval > 0 - ) - { - window.setTimeout(function() { processTimestampRefresh(options); }, options._tweetFeedConfig.showTimestamp.refreshInterval * 1000); - } - }; - processTimestampRefresh = function(options) - { - $.each(options._tweetFeedElement.find('.jta-tweet-timestamp-link'), function(idx, element) - { - var dataTimestamp = $(element).attr('data-timestamp'); - - $(element).html(options.tweetTimestampFormatter(dataTimestamp)); - }); - - startTimestampRefresh(options); - }; - isTweetInCache = function(tweet, options) - { - var l = options._tweetsCache.length; - - for (var i = 0; i < l; i++) - { - if (tweet.id == options._tweetsCache[i].id) - { - return true; - } - } - - return false; - }; - showLoadingIndicator = function(options) - { - if (options._tweetFeedElement && options.loadingDecorator && !options._loadingIndicatorElement) - { - options._loadingIndicatorElement = $(options.loadingDecorator(options)); - options.loadingIndicatorVisualizer(options._tweetFeedElement, options._loadingIndicatorElement, options, null); - options._tweetFeedElement.scrollTop(1000000); - } - }; - hideLoadingIndicator = function(options, callback) - { - if (options._loadingIndicatorElement) - { - options.loadingIndicatorVisualizer(null, options._loadingIndicatorElement, options, callback); - options._loadingIndicatorElement = null; - } - else - { - if (callback) - { - callback(); - } - } - }; - isLoading = function(options) - { - return options._loadingIndicatorElement != null; - }; - formatDate = function(dateStr) - { - return dateStr.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, '$1,$2$4$3'); - }; - validateRange = function(num, lo, hi) - { - if (num < lo) - num = lo; - - if (num > hi) - num = hi; - - return num; - }; - showError = function(options, errorText) - { - if (options.errorDecorator && options._tweetFeedElement) - { - options._tweetFeedElement.append(options.errorDecorator(errorText, options)); - } - }; - getPagedTweets = function(options, callback) - { - options._tweetFeedConfig._recLevel = 0; - - getRecPagedTweets(options, options._tweetFeedConfig.paging._offset, options._tweetFeedConfig.paging._limit, callback); - }; - getRecPagedTweets = function(options, offset, limit, callback) - { - ++options._tweetFeedConfig._recLevel; - - if (offset + limit <= options._tweetsCache.length || - options._tweetFeedConfig._recLevel > 3 || - options._tweetFeedConfig._noData - ) - { - // if the requested data is already cached or the max. no. of - // consecutive API calls is reached, use the records - - if (offset + limit > options._tweetsCache.length) - { - limit = Math.max(0, options._tweetsCache.length - offset); - } - - var tweets = []; - - for (var i = 0; i < limit; i++) - { - tweets[i] = options._tweetsCache[offset + i]; - } - - callback(tweets, options); - } - else - { - // ... if not, load the data, fill the cache and try again - ++options._tweetFeedConfig._pageParam; - - getRateLimitedData(options, false, getFeedUrl(options, true), function(data, options) - { - var tweets = data.results || data; - - if (tweets.length == 0) - { - options._tweetFeedConfig._noData = true; - } - else - { - $.each(tweets, function(idx, tweet) - { - // Snowflake support: just update ids that are currently used - if (tweet.id_str) { tweet.id = tweet.id_str; } - if (tweet.in_reply_to_status_id_str) { tweet.in_reply_to_status_id = tweet.in_reply_to_status_id_str; } - - // save the first tweet id for subsequent paging requests - if (!options._tweetFeedConfig._maxId) - { - options._tweetFeedConfig._maxId = tweet.id; - } - - // optionally filter tweet ... - if (options.tweetFilter(tweet, options)) - { - // then put it into the cache - options._tweetsCache.push(tweet); - } - }); - } - - getRecPagedTweets(options, offset, limit, callback); - }); - } - }; - getRateLimitedData = function(options, flAutorefresh, url, callback) - { - getRateLimit(options, function(rateLimit) - { - if (rateLimit && rateLimit.remaining_hits <= 0) - { - options._stats.rateLimitPreventionCount++; - hideLoadingIndicator(options, null); - return; - } - - getData(options, flAutorefresh, url, callback); - }); - }; - getData = function(options, flAutorefresh, url, callback) - { - options._stats.dataRequestCount++; - - if (!options.onDataRequestHandler(options._stats, options)) - { - hideLoadingIndicator(options, null); - return; - } - - if (!flAutorefresh) - { - showLoadingIndicator(options); - } - - $.getJSON(url, function(data) - { - if (data.error) - { - // in case of an error, display the error message - showError(options, data.error); - } - else - { - callback(data, options); - } - }); - }; - getRateLimit = function(options, callback) - { - $.getJSON("http://api.twitter.com/1/account/rate_limit_status.json?callback=?", function(rateLimit) - { - options._stats.rateLimit = rateLimit; - - options.onRateLimitDataHandler(options._stats, options); - - callback(rateLimit); - }); - }; -})(jQuery); \ No newline at end of file diff --git a/www/static/common/jquery/jTweetsAnywhere/jquery.jtweetsanywhere-1.2.1.min.js b/www/static/common/jquery/jTweetsAnywhere/jquery.jtweetsanywhere-1.2.1.min.js deleted file mode 100755 index 6bfd41b13b..0000000000 --- a/www/static/common/jquery/jTweetsAnywhere/jquery.jtweetsanywhere-1.2.1.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(e){e.fn.jTweetsAnywhere=function(a){a=e.extend({username:"tbillenstein",list:null,searchParams:null,count:0,tweetProfileImagePresent:null,tweetFilter:defaultTweetFilter,showTweetFeed:true,showFollowButton:false,showConnectButton:false,showLoginInfo:false,showTweetBox:false,mainDecorator:defaultMainDecorator,tweetFeedDecorator:defaultTweetFeedDecorator,tweetDecorator:defaultTweetDecorator,tweetProfileImageDecorator:defaultTweetProfileImageDecorator,tweetBodyDecorator:defaultTweetBodyDecorator, tweetUsernameDecorator:defaultTweetUsernameDecorator,tweetTextDecorator:defaultTweetTextDecorator,tweetAttributesDecorator:defaultTweetAttributesDecorator,tweetTimestampDecorator:defaultTweetTimestampDecorator,tweetSourceDecorator:defaultTweetSourceDecorator,tweetGeoLocationDecorator:defaultTweetGeoLocationDecorator,tweetInReplyToDecorator:defaultTweetInReplyToDecorator,tweetRetweeterDecorator:defaultTweetRetweeterDecorator,tweetFeedControlsDecorator:defaultTweetFeedControlsDecorator,tweetFeedControlsMoreBtnDecorator:defaultTweetFeedControlsMoreBtnDecorator, tweetFeedControlsPrevBtnDecorator:defaultTweetFeedControlsPrevBtnDecorator,tweetFeedControlsNextBtnDecorator:defaultTweetFeedControlsNextBtnDecorator,tweetFeedAutorefreshTriggerDecorator:defaultTweetFeedAutorefreshTriggerDecorator,tweetFeedAutorefreshTriggerContentDecorator:defaultTweetFeedAutorefreshTriggerContentDecorator,connectButtonDecorator:defaultConnectButtonDecorator,loginInfoDecorator:defaultLoginInfoDecorator,loginInfoContentDecorator:defaultLoginInfoContentDecorator,followButtonDecorator:defaultFollowButtonDecorator, tweetBoxDecorator:defaultTweetBoxDecorator,linkDecorator:defaultLinkDecorator,usernameDecorator:defaultUsernameDecorator,hashtagDecorator:defaultHashtagDecorator,loadingDecorator:defaultLoadingDecorator,errorDecorator:defaultErrorDecorator,noDataDecorator:defaultNoDataDecorator,tweetTimestampFormatter:defaultTweetTimestampFormatter,tweetTimestampTooltipFormatter:defaultTweetTimestampTooltipFormatter,tweetVisualizer:defaultTweetVisualizer,loadingIndicatorVisualizer:defaultLoadingIndicatorVisualizer, autorefreshTriggerVisualizer:defaultAutorefreshTriggerVisualizer,onDataRequestHandler:defaultOnDataRequestHandler,onRateLimitDataHandler:defaultOnRateLimitDataHandler,_tweetFeedConfig:{expandHovercards:false,showTimestamp:{refreshInterval:0},showSource:false,showGeoLocation:true,showInReplyTo:true,showProfileImages:null,showUserScreenNames:null,showUserFullNames:false,includeRetweets:true,paging:{mode:"none",_limit:0,_offset:0},autorefresh:{mode:"none",interval:60,duration:3600,_startTime:null,_triggerElement:null}, _pageParam:0,_maxId:null,_recLevel:0,_noData:false,_clearBeforePopulate:false},_tweetBoxConfig:{counter:true,width:515,height:65,label:"What's happening?",defaultContent:"",onTweet:function(){}},_connectButtonConfig:{size:"medium"},_baseSelector:null,_baseElement:null,_tweetFeedElement:null,_tweetFeedControlsElement:null,_followButtonElement:null,_loginInfoElement:null,_connectButtonElement:null,_tweetBoxElement:null,_loadingIndicatorElement:null,_noDataElement:null,_tweetsCache:[],_autorefreshTweetsCache:[], _stats:{dataRequestCount:0,rateLimitPreventionCount:0,rateLimit:{remaining_hits:150,hourly_limit:150}}},a);if(a.mainDecorator){a._baseSelector=this.selector;if(typeof a.username!="string"){if(!a.searchParams)a.searchParams=["q=from:"+a.username.join(" OR from:")];a.username=a.username[0]}typeof a.showTweetFeed=="object"&&e.extend(true,a._tweetFeedConfig,a.showTweetFeed);if(typeof a.showTweetBox=="object"){a._tweetBoxConfig=a.showTweetBox;a.showTweetBox=true}if(typeof a.showConnectButton=="object"){a._connectButtonConfig= a.showConnectButton;a.showConnectButton=true}if(a._tweetFeedConfig.showProfileImages==null)a._tweetFeedConfig.showProfileImages=a.tweetProfileImagePresent;if(a._tweetFeedConfig.showProfileImages==null)a._tweetFeedConfig.showProfileImages=(a.list||a.searchParams)&&a.tweetProfileImageDecorator;if(a._tweetFeedConfig.showUserScreenNames==null){if(a.list||a.searchParams)a._tweetFeedConfig.showUserScreenNames=true;if(!a.tweetUsernameDecorator)a._tweetFeedConfig.showUserScreenNames=false}if(a._tweetFeedConfig.showUserFullNames== null){if(a.list||a.searchParams)a._tweetFeedConfig.showUserFullNames=true;if(!a.tweetUsernameDecorator)a._tweetFeedConfig.showUserFullNames=false}a.count=validateRange(a.count,0,a.searchParams?100:20);a._tweetFeedConfig.autorefresh.interval=Math.max(30,a._tweetFeedConfig.autorefresh.interval);a._tweetFeedConfig.paging._offset=0;a._tweetFeedConfig.paging._limit=a.count;if(a.count==0||!a.showTweetFeed){a.tweetFeedDecorator=null;a.tweetFeedControlsDecorator=null}if(a._tweetFeedConfig.paging.mode=="none")a.tweetFeedControlsDecorator= null;if(!a.showFollowButton)a.followButtonDecorator=null;if(!a.showTweetBox)a.tweetBoxDecorator=null;if(!a.showConnectButton)a.connectButtonDecorator=null;if(!a.showLoginInfo)a.loginInfoDecorator=null;if(!a._tweetFeedConfig.showTimestamp)a.tweetTimestampDecorator=null;if(!a._tweetFeedConfig.showSource)a.tweetSourceDecorator=null;if(!a._tweetFeedConfig.showGeoLocation)a.tweetGeoLocationDecorator=null;if(!a._tweetFeedConfig.showInReplyTo)a.tweetInReplyToDecorator=null;e.ajaxSetup({cache:true});return this.each(function(){a._baseElement= e(this);a._tweetFeedElement=a.tweetFeedDecorator?e(a.tweetFeedDecorator(a)):null;a._tweetFeedControlsElement=a.tweetFeedControlsDecorator?e(a.tweetFeedControlsDecorator(a)):null;a._followButtonElement=a.followButtonDecorator?e(a.followButtonDecorator(a)):null;a._tweetBoxElement=a.tweetBoxDecorator?e(a.tweetBoxDecorator(a)):null;a._connectButtonElement=a.connectButtonDecorator?e(a.connectButtonDecorator(a)):null;a._loginInfoElement=a.loginInfoDecorator?e(a.loginInfoDecorator(a)):null;a.mainDecorator(a); populateTweetFeed(a);populateAnywhereControls(a);bindEventHandlers(a);a._tweetFeedConfig.autorefresh._startTime=(new Date).getTime();startAutorefresh(a);startTimestampRefresh(a)})}};defaultMainDecorator=function(a){a._tweetFeedElement&&a._baseElement.append(a._tweetFeedElement);a._tweetFeedControlsElement&&a._baseElement.append(a._tweetFeedControlsElement);a._connectButtonElement&&a._baseElement.append(a._connectButtonElement);a._loginInfoElement&&a._baseElement.append(a._loginInfoElement);a._followButtonElement&& a._baseElement.append(a._followButtonElement);a._tweetBoxElement&&a._baseElement.append(a._tweetBoxElement)};defaultTweetFeedControlsDecorator=function(a){var b="";if(a._tweetFeedConfig.paging.mode=="prev-next"){if(a.tweetFeedControlsPrevBtnDecorator)b+=a.tweetFeedControlsPrevBtnDecorator(a);if(a.tweetFeedControlsNextBtnDecorator)b+=a.tweetFeedControlsNextBtnDecorator(a)}else if(a._tweetFeedConfig.paging.mode!="endless-scroll")if(a.tweetFeedControlsMoreBtnDecorator)b+=a.tweetFeedControlsMoreBtnDecorator(a); return'
    '+b+"
    "};defaultTweetFeedControlsMoreBtnDecorator=function(){return'More'};defaultTweetFeedControlsPrevBtnDecorator=function(){return'Prev'};defaultTweetFeedControlsNextBtnDecorator=function(){return'Next'}; defaultTweetFeedAutorefreshTriggerDecorator=function(a,b){var c="";if(b.tweetFeedAutorefreshTriggerContentDecorator)c=b.tweetFeedAutorefreshTriggerContentDecorator(a,b);return'
  • '+c+"
  • "};defaultTweetFeedAutorefreshTriggerContentDecorator=function(a){return''+(""+a+" new "+(a>1?" tweets":" tweet"))+""};defaultTweetFeedDecorator=function(){return'
      '};defaultTweetDecorator= function(a,b){var c="";if(b._tweetFeedConfig.showProfileImages)c+=b.tweetProfileImageDecorator(a,b);if(b.tweetBodyDecorator)c+=b.tweetBodyDecorator(a,b);c+='
       
      ';return'
    • '+c+"
    • "};defaultTweetProfileImageDecorator=function(a){a=a.retweeted_status||a;var b=a.user?a.user.screen_name:a.from_user;return'
      '+(''+b+'")+"
      "};defaultTweetBodyDecorator=function(a,b){var c="";if(b.tweetTextDecorator)c+=b.tweetTextDecorator(a,b);if(b.tweetAttributesDecorator)c+=b.tweetAttributesDecorator(a,b);return'
      '+c+"
      "};defaultTweetTextDecorator=function(a,b){var c=a.text;if(a.retweeted_status&& (b._tweetFeedConfig.showUserScreenNames||b._tweetFeedConfig.showUserScreenNames==null||b._tweetFeedConfig.showUserFullNames||b._tweetFeedConfig.showUserFullNames==null))c=a.retweeted_status.text;if(b.linkDecorator)c=b.linkDecorator(c,b);if(b.usernameDecorator)c=b.usernameDecorator(c,b);if(b.hashtagDecorator)c=b.hashtagDecorator(c,b);if(b._tweetFeedConfig.showUserScreenNames||b._tweetFeedConfig.showUserFullNames||a.retweeted_status&&(b._tweetFeedConfig.showUserScreenNames==null||b._tweetFeedConfig.showUserFullNames== null))c=b.tweetUsernameDecorator(a,b)+" "+c;return''+c+""};defaultTweetUsernameDecorator=function(a,b){var c=a.retweeted_status||a,d=c.user?c.user.screen_name:c.from_user;c=c.user?c.user.name:null;var f;if(d&&(b._tweetFeedConfig.showUserScreenNames||b._tweetFeedConfig.showUserScreenNames==null&&a.retweeted_status))f=''+d+""; var g;if(c&&(b._tweetFeedConfig.showUserFullNames||b._tweetFeedConfig.showUserFullNames==null&&a.retweeted_status))g=''+(f?" (":"")+''+c+""+(f?")":"")+"";d="";if(f)d+=f;if(g){if(f)d+=" ";d+=g}if(f||g)d=''+(a.retweeted_status?"RT ":"")+d+"";return d};defaultTweetAttributesDecorator=function(a,b){var c="";if(b.tweetTimestampDecorator|| b.tweetSourceDecorator||b.tweetGeoLocationDecorator||b.tweetInReplyToDecorator||a.retweeted_status&&b.tweetRetweeterDecorator){c+='';if(b.tweetTimestampDecorator)c+=b.tweetTimestampDecorator(a,b);if(b.tweetSourceDecorator)c+=b.tweetSourceDecorator(a,b);if(b.tweetGeoLocationDecorator)c+=b.tweetGeoLocationDecorator(a,b);if(b.tweetInReplyToDecorator)c+=b.tweetInReplyToDecorator(a,b);if(a.retweeted_status&&b.tweetRetweeterDecorator)c+=b.tweetRetweeterDecorator(a,b); c+=""}return c};defaultTweetTimestampDecorator=function(a,b){var c=a.retweeted_status||a,d=formatDate(c.created_at),f=b.tweetTimestampFormatter(d),g=b.tweetTimestampTooltipFormatter(d);return''+f+""};defaultTweetTimestampTooltipFormatter=function(a){return(new Date(a)).toLocaleString()}; defaultTweetTimestampFormatter=function(a){var b=new Date,c=parseInt((b.getTime()-Date.parse(a))/1E3),d="";if(c<60)d+=c+" second"+(c==1?"":"s")+" ago";else if(c<3600){b=parseInt((c+30)/60);d+=b+" minute"+(b==1?"":"s")+" ago"}else if(c<86400){b=parseInt((c+1800)/3600);d+=b+" hour"+(b==1?"":"s")+" ago"}else{a=new Date(a);a.getHours();a.getMinutes();d+=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][a.getMonth()]+" "+a.getDate();if(a.getFullYear()12){d-=12;b="PM"}var f= a.getMinutes();c+=" ("+d+":"+((f<10?"0":"")+f)+" "+b+" "+(a.getMonth()+1)+"/"+a.getDate()+"/"+a.getFullYear()+")"}return c};defaultTweetSourceDecorator=function(a){return' via '+(a.retweeted_status||a).source.replace(/\<\;/gi,"<").replace(/\>\;/gi,">").replace(/\"\;/gi,'"')+""};defaultTweetGeoLocationDecorator=function(a){var b="";a=a.retweeted_status||a;var c;if(a.geo&&a.geo.coordinates)c=a.geo.coordinates.join(); else if(a.place&&a.place.full_name)c=a.place.full_name;if(c){b="here";if(a.place&&a.place.full_name)b=a.place.full_name;b=' from '+b+""}return b};defaultTweetInReplyToDecorator=function(a){a=a.retweeted_status||a;var b="";if(a.in_reply_to_status_id&&a.in_reply_to_screen_name)b=' in reply to '+a.in_reply_to_screen_name+"";return b};defaultTweetRetweeterDecorator=function(a){var b="";if(a.retweeted_status){b=a.user?a.user.screen_name:a.from_user;a=(a.retweeted_status.retweet_count||0)-1;var c=" and "+a+(a>1?" others":" other");b='
      Retweeted by '+(''+b+"")+(a>0? c:"")+""}return b};defaultConnectButtonDecorator=function(){return'
      '};defaultLoginInfoDecorator=function(){return''};defaultLoginInfoContentDecorator=function(a,b){var c="";if(b.isConnected()){c=b.currentUser.data("screen_name");var d=b.currentUser.data("profile_image_url");c='
       
      '}return c};defaultFollowButtonDecorator=function(){return'
      '};defaultTweetBoxDecorator=function(){return'
      '};defaultLinkDecorator=function(a){return a.replace(/((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi,'$1')}; defaultUsernameDecorator=function(a){return isAnywherePresent()?a:a.replace(/@([a-zA-Z0-9_]+)/gi,'@')};defaultHashtagDecorator=function(a){return a.replace(/#([a-zA-Z0-9_]+)/gi,'#$1')};defaultLoadingDecorator=function(){return'
    • loading ...
    • '}; defaultErrorDecorator=function(a){return'
    • ERROR: '+a+"
    • "};defaultNoDataDecorator=function(){return'
    • No more data
    • '};defaultTweetFilter=function(){return true};defaultTweetVisualizer=function(a,b,c){a[c](b)};defaultLoadingIndicatorVisualizer=function(a,b,c,d){defaultVisualizer(a,b,"append","fadeIn",600,"fadeOut",200,d)};defaultAutorefreshTriggerVisualizer=function(a,b,c,d){defaultVisualizer(a,b,"prepend","slideDown",600,"fadeOut",200,d)};defaultVisualizer= function(a,b,c,d,f,g,k,h){var j=function(){h&&h()};if(a){b.hide();a[c](b);b[d](f,j)}else b[g](k,function(){b.remove();j()})};defaultOnDataRequestHandler=function(){return true};defaultOnRateLimitDataHandler=function(){};updateLoginInfoElement=function(a,b){if(a._loginInfoElement&&a.loginInfoContentDecorator){a._loginInfoElement.children().remove();a._loginInfoElement.append(a.loginInfoContentDecorator(a,b));e(a._baseSelector+" .jta-login-info-sign-out").bind("click",function(){twttr.anywhere.signOut()})}}; getFeedUrl=function(a,b){var c="https:"==document.location.protocol?"https:":"http:";if(a.searchParams)c+="//search.twitter.com/search.json?"+(a.searchParams instanceof Array?a.searchParams.join("&"):a.searchParams)+"&rpp=100";else if(a.list)c+="//api.twitter.com/1/"+a.username+"/lists/"+a.list+"/statuses.json?per_page=20";else{c+="//api.twitter.com/1/statuses/user_timeline.json?screen_name="+a.username+"&count=20";if(a._tweetFeedConfig.includeRetweets)c+="&include_rts=true"}if(b)c+=(a._tweetFeedConfig._maxId? "&max_id="+a._tweetFeedConfig._maxId:"")+"&page="+a._tweetFeedConfig._pageParam;c+="&callback=?";return c};isAnywherePresent=function(){return typeof twttr!="undefined"};clearTweetFeed=function(a){a._tweetFeedElement&&a._tweetFeedElement.empty()};populateTweetFeed=function(a){a.tweetDecorator&&a._tweetFeedElement&&getPagedTweets(a,function(b,c){c._tweetFeedConfig._clearBeforePopulate&&clearTweetFeed(c);hideLoadingIndicator(c,function(){e.each(b,function(d,f){c.tweetVisualizer(c._tweetFeedElement, e(c.tweetDecorator(f,c)),"append",c)});if(c._tweetFeedConfig._noData&&c.noDataDecorator&&!c._tweetFeedConfig._noDataElement){c._tweetFeedConfig._noDataElement=e(c.noDataDecorator(c));c._tweetFeedElement.append(c._tweetFeedConfig._noDataElement)}c._tweetFeedConfig._clearBeforePopulate&&c._tweetFeedElement.scrollTop(0);addHovercards(c)})})};populateTweetFeed2=function(a){if(a._tweetFeedElement&&a._autorefreshTweetsCache.length>0)if(a._tweetFeedConfig.autorefresh.mode=="trigger-insert")if(a._tweetFeedConfig.autorefresh._triggerElement)a.tweetFeedAutorefreshTriggerContentDecorator&& a._tweetFeedConfig.autorefresh._triggerElement.html(a.tweetFeedAutorefreshTriggerContentDecorator(a._autorefreshTweetsCache.length,a));else{if(a.tweetFeedAutorefreshTriggerDecorator){a._tweetFeedConfig.autorefresh._triggerElement=e(a.tweetFeedAutorefreshTriggerDecorator(a._autorefreshTweetsCache.length,a));a._tweetFeedConfig.autorefresh._triggerElement.bind("click",function(){a.autorefreshTriggerVisualizer(null,a._tweetFeedConfig.autorefresh._triggerElement,a,function(){insertTriggerTweets(a)});a._tweetFeedConfig.autorefresh._triggerElement= null});a.autorefreshTriggerVisualizer(a._tweetFeedElement,a._tweetFeedConfig.autorefresh._triggerElement,a)}}else insertTriggerTweets(a)};insertTriggerTweets=function(a){if(a.tweetDecorator&&a._autorefreshTweetsCache.length>0){for(;a._autorefreshTweetsCache.length>0;){var b=a._autorefreshTweetsCache.pop();a._tweetsCache.unshift(b);a._tweetFeedConfig.paging._offset++;a.tweetVisualizer(a._tweetFeedElement,e(a.tweetDecorator(b,a)),"prepend",a)}addHovercards(a)}};addHovercards=function(a){isAnywherePresent()&& twttr.anywhere(function(b){b(a._baseSelector+" .jta-tweet-list").hovercards({expanded:a._tweetFeedConfig.expandHovercards});b(a._baseSelector+" .jta-tweet-profile-image img").hovercards({expanded:a._tweetFeedConfig.expandHovercards,username:function(c){return c.alt}});b(a._baseSelector+" .jta-tweet-retweeter-link").hovercards({expanded:a._tweetFeedConfig.expandHovercards,username:function(c){return c.text}});b(a._baseSelector+" .jta-tweet-user-screen-name-link").hovercards({expanded:a._tweetFeedConfig.expandHovercards, username:function(c){return c.text}});b(a._baseSelector+" .jta-tweet-user-full-name-link").hovercards({expanded:a._tweetFeedConfig.expandHovercards,username:function(c){return c.name}})})};populateAnywhereControls=function(a){isAnywherePresent()&&twttr.anywhere(function(b){a.tweetBoxDecorator&&b(a._baseSelector+" .jta-tweet-box").tweetBox(a._tweetBoxConfig);a.followButtonDecorator&&b(a._baseSelector+" .jta-follow-button").followButton(a.username);if(a.connectButtonDecorator){var c=e.extend({authComplete:function(){updateLoginInfoElement(a, b)},signOut:function(){updateLoginInfoElement(a,b)}},a._connectButtonConfig);b(a._baseSelector+" .jta-connect-button").connectButton(c);updateLoginInfoElement(a,b)}})};bindEventHandlers=function(a){if(a.tweetFeedControlsDecorator)if(a._tweetFeedConfig.paging.mode=="prev-next"){e(a._baseSelector+" .jta-tweet-list-controls-button-prev").bind("click",function(){!isLoading(a)&&a._tweetFeedConfig.paging._offset>0&&prevPage(a,true)});e(a._baseSelector+" .jta-tweet-list-controls-button-next").bind("click", function(){isLoading(a)||nextPage(a,true)})}else a._tweetFeedConfig.paging.mode=="endless-scroll"?a._tweetFeedElement.bind("scroll",function(){!isLoading(a)&&e(this)[0].scrollHeight-e(this).scrollTop()==e(this).outerHeight()&&nextPage(a,false)}):e(a._baseSelector+" .jta-tweet-list-controls-button-more").bind("click",function(){isLoading(a)||nextPage(a,false)})};nextPage=function(a,b){doPage(a,b,Math.min(a._tweetFeedConfig.paging._offset+a._tweetFeedConfig.paging._limit,a._tweetsCache.length))};prevPage= function(a,b){doPage(a,b,Math.max(0,a._tweetFeedConfig.paging._offset-a._tweetFeedConfig.paging._limit))};doPage=function(a,b,c){a._tweetFeedConfig.paging._offset=c;a._tweetFeedConfig._clearBeforePopulate=b;populateTweetFeed(a)};startAutorefresh=function(a){if(a._tweetFeedConfig.autorefresh.mode!="none"&&a._tweetFeedConfig.paging.mode!="prev-next"&&a._tweetFeedConfig.autorefresh.duration!=0&&(a._tweetFeedConfig.autorefresh.duration<0||(new Date).getTime()-a._tweetFeedConfig.autorefresh._startTime<= a._tweetFeedConfig.autorefresh.duration*1E3))window.setTimeout(function(){processAutorefresh(a)},a._tweetFeedConfig.autorefresh.interval*1E3)};stopAutorefresh=function(a){a._tweetFeedConfig.autorefresh.duration=0};processAutorefresh=function(a){if(a._tweetFeedConfig.autorefresh.duration!=0){getRateLimitedData(a,true,getFeedUrl(a,false),function(b,c){var d=(b.results||b).slice(0);d.reverse();e.each(d,function(f,g){isTweetInCache(g,c)||c.tweetFilter(g,c)&&c._autorefreshTweetsCache.unshift(g)});populateTweetFeed2(c)}); startAutorefresh(a)}};startTimestampRefresh=function(a){a.tweetTimestampDecorator&&typeof a._tweetFeedConfig.showTimestamp=="object"&&a._tweetFeedConfig.showTimestamp.refreshInterval>0&&window.setTimeout(function(){processTimestampRefresh(a)},a._tweetFeedConfig.showTimestamp.refreshInterval*1E3)};processTimestampRefresh=function(a){e.each(a._tweetFeedElement.find(".jta-tweet-timestamp-link"),function(b,c){var d=e(c).attr("data-timestamp");e(c).html(a.tweetTimestampFormatter(d))});startTimestampRefresh(a)}; isTweetInCache=function(a,b){for(var c=b._tweetsCache.length,d=0;dc)a=c;return a};showError=function(a,b){a.errorDecorator&&a._tweetFeedElement&&a._tweetFeedElement.append(a.errorDecorator(b,a))};getPagedTweets=function(a,b){a._tweetFeedConfig._recLevel=0;getRecPagedTweets(a,a._tweetFeedConfig.paging._offset, a._tweetFeedConfig.paging._limit,b)};getRecPagedTweets=function(a,b,c,d){++a._tweetFeedConfig._recLevel;if(b+c<=a._tweetsCache.length||a._tweetFeedConfig._recLevel>3||a._tweetFeedConfig._noData){if(b+c>a._tweetsCache.length)c=Math.max(0,a._tweetsCache.length-b);for(var f=[],g=0;g