Initial commit
[snf-cloudcms] / cloudcms / static / cloudcms / js / twitter / jquery.twitter.js
1 /*
2  * Twitter Search Plugin jquery.twitter.js
3  * http://code.bocoup.com/jquery-twitter-plugin/
4  *
5  * Copyright (c) 2010 Bocoup, LLC
6  * Authors: Boaz Sender, Rick Waldron, Nick Cammarata
7  * Dual licensed under the MIT and GPL licenses.
8  * http://code.bocoup.com/license/
9  *
10  */
11 var linkify = linkify || function() {};
12 ;(function($, linkify) {
13
14   var
15   mention = function( str ) {
16     return str.replace("/[@]+[A-Za-z0-9-_]+/ig", function( username ) {
17       return username.link("http://twitter.com/"+ username.replace("@","") );
18     });
19   },
20   hashtags = function( str ) {
21     return str.replace("/[#]+[A-Za-z0-9-_]+/ig", function( tag ) {
22       return tag.link("http://search.twitter.com/search?q="+tag.replace("#","%23"));
23     });
24   };
25
26   $.twitter = function (options, callback) {
27     // Fail if the options arg is not set
28     if ( !options ) {
29       return false;
30     }
31
32     // Set a temporary default query object
33     var query,
34         // Set up a string to be used later in the case that exclusions have been set
35         exclusionsStr = "",
36         // Set up a regex to be used later in the case that exclusions have been set
37         exclusionsExp = new RegExp(false);
38
39     // If options is a string use it as standalone query
40     if ( typeof options === "string" ) {
41       query = $.extend({}, $.twitter.opts, {
42         q: options
43       });
44     // Else prepare the options object to be serialized
45     } else {
46       // If a limit is set, add it to the query object
47       options.rpp = options.limit ? options.limit : options.rpp;
48
49       // If no limit is set, make the limit the rpp
50       options.limit = options.limit ? options.limit : options.rpp;
51
52       // If there are exlusions, turn them into a regex string
53       exclusionsStr = options.exclusions ? options.exclusions.replace(" ", "|") : false;
54
55       // If there are exlusions, turn the regex string we just made into a RegExp
56       exclusionsExp = exclusionsStr ? new RegExp( exclusionsStr ) : false;
57
58       // Make a new object that is a merger of the options passed in with the default $.twitter.opts object
59       // and assign it to the query variable
60       query = $.extend({}, $.twitter.opts, options);
61
62       // If there are exclusions, or replies or retweets are set to false, multiply the results to ask for from twitter by ten
63       // We need to do this so that we have some meat to work with if the exclusions are common
64       query.rpp = query.exclusions || !query.replies || !query.retweets  ? (query.rpp * 10) : query.rpp;
65
66     }
67
68
69     // Call Twitter JSONP
70     $.getJSON("http://search.twitter.com/search.json?callback=?", query, function(tweets){
71       callback(tweets, query, exclusionsExp);
72     });
73   };
74
75   $.fn.twitter = function( options ) {
76     // Fail gracefully if the options arg is not set
77     // return the jQuery obj so that chaining does not break
78     if ( !options ) {
79       return this;
80     }
81
82     // Begin to iterate over the jQuery collection that the method was called on
83     return this.each(function () {
84       // Cache `this`
85       var $this = $(this);
86
87       $.twitter(options, function( tweets, query, exclusionsExp ) {
88         //Create and cache a new UL
89         var $tweets = $("<ul>"),
90             // Create a counter variable to count up how many tweets we have rendered
91             // unfortunately we have to do this, because exclusions, retweet booleans and replies booleans
92             // are not supported by the Twitter Search API
93             limitInt = 0,
94             i;
95
96         // If there are results to work with
97         if ( tweets.results && tweets.results.length ) {
98
99           //  Iterate over returned tweets
100           for ( i in tweets.results ) {
101
102             // Cache tweet content
103             var tweet = tweets.results[i],
104                 // Set a variable to determine weather replies are set to false, and if so, weather the tweet starts with a reply
105                 allowReply = !query.replies && tweet.to_user_id ? false : true,
106                 // Set a variable to determine weather retweets are set to false, and if so, weather the tweet starts with a retweet
107                 allowRetweet = !query.retweets && tweet.text.slice(0,2) === "RT" ? false : true;
108
109             // Only proceed if allow reply is false
110             if ( !allowReply ) {
111               continue;
112             }
113
114             // Only proceed if allow retweet is false
115             if ( !allowRetweet ) {
116               continue;
117             }
118
119             // If exlusions set and none of the exlusions is found in the tweet then add it to the DOM
120             if ( exclusionsExp && exclusionsExp.test(tweet.text) ) {
121               continue;
122             }
123
124             // Create and cache new LI
125             var $tweet = $("<li/>", {
126               "class": "tweet"
127             });
128
129             // Make the avatar, and append it to the $tweet
130             if ( query.avatar === true ) {
131               $tweet.append($("<a/>", {
132                 href: "http://twitter.com/" + tweet.from_user,
133                 html: "<img src='" + tweet.profile_image_url + "'/>"
134               }));
135             }
136
137             // Make the tweet text, and append it to the $tweet, then to the parent
138             $tweet.append($("<span>", {
139               "class": "content",
140               html: "<a href='http://twitter.com/" + tweet.from_user + "'>@" + tweet.from_user + "</a>: " + mention(hashtags(linkify(tweet.text)))
141             }))
142             // Append tweet to the $tweets ul
143             .appendTo($tweets);
144
145             // Count up our counter variable
146             limitInt++;
147
148             // If the counter is equal to the limit, stop rendering tweets
149             if ( limitInt === query.limit ) {
150               break;
151             }
152           }
153
154           // Inject the $tweets into the DOM
155           $this.html($tweets);
156
157         // Else there are no results to work with
158         } else {
159           // Update the DOM to reflect that no results were found
160           $this.html($("<h3/>", {
161             "class": "twitter-notFound",
162             text: query.notFoundText
163           }));
164         }
165       });
166     });
167   };
168
169   $.twitter.opts = {
170     // Number of tweets to get
171     // not in twitter search api, maps to and supersedes rpp (results per page)
172     limit: 7,
173     // Space delimited list of strings to exclude  (eg: "_ s gr @b")
174     // not in twitter search api, done in plugin
175     exclusions: "",
176     // Text to display if no results are found
177     // not in twitter search api, done in plugin
178     notFoundText: "No results found on twitter",
179     // Include replies?
180     // not in twitter search api, done in plugin
181     replies: true,
182     // Include replies?
183     // not in twitter search api, done in plugin
184     retweets: true,
185     // All of these words
186     ands: "",
187     // This exact phrase
188     phrase: "",
189     // Any of these words
190     ors : "",
191     // None of these words
192     nots: "",
193     // This hashtag
194     tag : "",
195     // Written in language
196     lang: "",
197     // From this person
198     from: "",
199     // To this person
200     to: "",
201     // Referencing this person
202     ref: "",
203     // Near this place
204     near: "",
205     // Within this distance
206     within: "",
207     // Distance unit (miles or kilometers)
208     units: "",
209     // Since this date
210     since: "",
211     // Until this date
212     until: "",
213     // Attitude: "?" or :)" or ":)"
214     tude: "",
215     // Containing: "links"
216     filter: "",
217     // Include retweet?: "retweets"
218     include: "",
219     // Results per page
220     rpp: 5,
221     // Default query
222     q: "",
223     // Add an avatar image of the user
224     avatar: true
225   };
226 }(jQuery, linkify));