Dotclear

Changeset 3060


Ignore:
Timestamp:
06/16/11 02:01:25 (12 years ago)
Author:
noe
Message:

mise à jour du script tweet! pour la version 0.9

File:
1 edited

Legend:

Unmodified
Added
Removed
  • plugins/tweet/js/jquery.tweet.js

    r2391 r3060  
    11(function($) { 
    2   
     2 
    33  $.fn.tweet = function(o){ 
    4     var s = { 
    5       username: ["seaofclouds"],              // [string]   required, unless you want to display our tweets. :) it can be an array, just do ["username1","username2","etc"] 
    6       list: null,                              //[string]   optional name of list belonging to username 
    7       avatar_size: null,                      // [integer]  height and width of avatar if displayed (48px max) 
    8       count: 3,                               // [integer]  how many tweets to display? 
    9       intro_text: null,                       // [string]   do you want text BEFORE your your tweets? 
    10       outro_text: null,                       // [string]   do you want text AFTER your tweets? 
    11       join_text:  null,                       // [string]   optional text in between date and tweet, try setting to "auto" 
    12       auto_join_text_default: "i said,",      // [string]   auto text for non verb: "i said" bullocks 
    13       auto_join_text_ed: "i",                 // [string]   auto text for past tense: "i" surfed 
    14       auto_join_text_ing: "i am",             // [string]   auto tense for present tense: "i was" surfing 
    15       auto_join_text_reply: "i replied to",   // [string]   auto tense for replies: "i replied to" @someone "with" 
    16       auto_join_text_url: "i was looking at", // [string]   auto tense for urls: "i was looking at" http:... 
    17       loading_text: null,                     // [string]   optional loading text, displayed while tweets load 
    18       query: null,                            // [string]   optional search query 
    19       text_less_min: "less than a minute ago",// [string]   text for tweets less than a minute old 
    20       text_one_min: "about a minute ago",     // [string]   text for tweets between one and two minutes old 
    21       text_n_mins: "%t minutes ago",    // [string]   text for tweets less than an hour old 
    22       text_one_hour: "about an hour ago",     // [string]   text for tweets between 60 and 90 minutes old 
    23       text_n_hours: "about %t hours ago",    // [string]   text for tweets less than a day old 
    24       text_one_day: "1 day ago",     // [string]   text for tweets between 24 and 48 hours old 
    25       text_n_days: "%t days ago"    // [string]   text for tweets more than two days old 
    26    }; 
    27     
    28     if(o) $.extend(s, o); 
     4    var s = $.extend({ 
     5      username: null,                           // [string or array] required unless using the 'query' option; one or more twitter screen names 
     6      list: null,                               // [string]   optional name of list belonging to username 
     7      favorites: false,                         // [boolean]  display the user's favorites instead of his tweets 
     8      query: null,                              // [string]   optional search query 
     9      avatar_size: null,                        // [integer]  height and width of avatar if displayed (48px max) 
     10      count: 3,                                 // [integer]  how many tweets to display? 
     11      fetch: null,                              // [integer]  how many tweets to fetch via the API (set this higher than 'count' if using the 'filter' option) 
     12      retweets: true,                           // [boolean]  whether to fetch (official) retweets (not supported in all display modes) 
     13      intro_text: null,                         // [string]   do you want text BEFORE your your tweets? 
     14      outro_text: null,                         // [string]   do you want text AFTER your tweets? 
     15      join_text:  null,                         // [string]   optional text in between date and tweet, try setting to "auto" 
     16      auto_join_text_default: "i said,",        // [string]   auto text for non verb: "i said" bullocks 
     17      auto_join_text_ed: "i",                   // [string]   auto text for past tense: "i" surfed 
     18      auto_join_text_ing: "i am",               // [string]   auto tense for present tense: "i was" surfing 
     19      auto_join_text_reply: "i replied to",     // [string]   auto tense for replies: "i replied to" @someone "with" 
     20      auto_join_text_url: "i was looking at",   // [string]   auto tense for urls: "i was looking at" http:... 
     21      loading_text: null,                       // [string]   optional loading text, displayed while tweets load 
     22      refresh_interval: null ,                  // [integer]  optional number of seconds after which to reload tweets 
     23      twitter_url: "twitter.com",               // [string]   custom twitter url, if any (apigee, etc.) 
     24      twitter_api_url: "api.twitter.com",       // [string]   custom twitter api url, if any (apigee, etc.) 
     25      twitter_search_url: "search.twitter.com", // [string]   custom twitter search url, if any (apigee, etc.) 
     26      template: "{avatar}{time}{join}{text}",   // [string or function] template used to construct each tweet <li> - see code for available vars 
     27      comparator: function(tweet1, tweet2) {    // [function] comparator used to sort tweets (see Array.sort) 
     28        return tweet2["tweet_time"] - tweet1["tweet_time"]; 
     29      }, 
     30      filter: function(tweet) {                 // [function] whether or not to include a particular tweet (be sure to also set 'fetch') 
     31        return true; 
     32      }, 
     33      text_less_min: "less than a minute ago",  // [string]   text for tweets less than a minute old 
     34      text_one_min: "about a minute ago",       // [string]   text for tweets between one and two minutes old 
     35      text_n_mins: "%t minutes ago",            // [string]   text for tweets less than an hour old 
     36      text_one_hour: "about an hour ago",       // [string]   text for tweets between 60 and 90 minutes old 
     37      text_n_hours: "about %t hours ago",       // [string]   text for tweets less than a day old 
     38      text_one_day: "1 day ago",                // [string]   text for tweets between 24 and 48 hours old 
     39      text_n_days: "%t days ago"                // [string]   text for tweets more than two days old 
     40    }, o); 
    2941 
    3042    $.fn.extend({ 
    3143      linkUrl: function() { 
    3244        var returning = []; 
    33         var regexp = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi; 
    34         this.each(function() { 
    35           returning.push(this.replace(regexp,"<a href=\"$1\">$1</a>")); 
     45        // See http://daringfireball.net/2010/07/improved_regex_for_matching_urls 
     46        var regexp = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/gi; 
     47        this.each(function() { 
     48          returning.push(this.replace(regexp, 
     49                                      function(match) { 
     50                                        var url = (/^[a-z]+:/i).test(match) ? match : "http://"+match; 
     51                                        return "<a href=\""+url+"\">"+match+"</a>"; 
     52                                      })); 
    3653        }); 
    3754        return $(returning); 
     
    3956      linkUser: function() { 
    4057        var returning = []; 
    41         var regexp = /[\@]+([A-Za-z0-9-_]+)/gi; 
    42         this.each(function() { 
    43           returning.push(this.replace(regexp,"<a href=\"http://twitter.com/$1\">@$1</a>")); 
     58        var regexp = /[\@]+(\w+)/gi; 
     59        this.each(function() { 
     60          returning.push(this.replace(regexp,"@<a href=\"http://"+s.twitter_url+"/$1\">$1</a>")); 
    4461        }); 
    4562        return $(returning); 
     
    4764      linkHash: function() { 
    4865        var returning = []; 
    49      var regexp = /(?:^| )[\#]+([A-Za-z0-9-_]+)/gi; 
    50         this.each(function() { 
    51           returning.push(this.replace(regexp, ' <a href="http://search.twitter.com/search?q=&tag=$1&lang=all&from='+s.username.join("%2BOR%2B")+'">#$1</a>')); 
     66        // Support various latin1 (\u00**) and arabic (\u06**) alphanumeric chars 
     67        var regexp = /(?:^| )[\#]+([\w\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0600-\u06ff]+)/gi; 
     68        var usercond = (s.username && s.username.length == 1) ? '&from='+s.username.join("%2BOR%2B") : ''; 
     69        this.each(function() { 
     70          returning.push(this.replace(regexp, ' <a href="http://'+s.twitter_search_url+'/search?q=&tag=$1&lang=all'+usercond+'">#$1</a>')); 
    5271        }); 
    5372        return $(returning); 
     
    7089        var returning = []; 
    7190        this.each(function() { 
    72           returning.push(this.replace(/(&lt;)+[3]/gi, '<span class="heart">♥</span>')) 
     91          returning.push(this.replace(/(&lt;)+[3]/gi, "<tt class='heart'>&#x2665;</tt>")); 
    7392        }); 
    7493        return $(returning); 
     
    83102    } 
    84103 
    85     function relative_time(time_value) { 
    86       var parsed_date = parse_date(time_value); 
     104    function relative_time(date) { 
    87105      var relative_to = (arguments.length > 1) ? arguments[1] : new Date(); 
    88       var delta = parseInt((relative_to.getTime() - parsed_date) / 1000); 
     106      var delta = parseInt((relative_to.getTime() - date) / 1000, 10); 
    89107      if(delta < 60) { 
    90108      return s.text_less_min; 
    91109      } else if(delta < 120) { 
    92110      return s.text_one_min; 
    93       } else if(delta < (60*60)) { 
     111      } else if(delta < (45*60)) { 
    94112      return s.text_n_mins.replace('%t', parseInt(delta / 60).toString()); 
    95       //return (parseInt(delta / 60)).toString() + s.text_n_mins; 
    96113      } else if(delta < (120*60)) { 
    97114      return s.text_one_hour; 
    98115      } else if(delta < (24*60*60)) { 
    99116      return s.text_n_hours.replace('%t', parseInt(delta / 3600).toString()); 
    100 //      return (parseInt(delta / 3600)).toString() + s.text_n_hours; 
    101117      } else if(delta < (48*60*60)) { 
    102118      return s.text_one_day; 
    103119      } else { 
    104120      return s.text_n_days.replace('%t', parseInt(delta / 86400).toString()); 
    105 //      return (parseInt(delta / 86400)).toString() + s.text_n_days; 
    106121      } 
    107122    } 
     
    109124    function build_url() { 
    110125      var proto = ('https:' == document.location.protocol ? 'https:' : 'http:'); 
     126      var count = (s.fetch === null) ? s.count : s.fetch; 
    111127      if (s.list) { 
    112         return proto+"//api.twitter.com/1/"+s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+s.count+"&callback=?"; 
    113      var from_user_full_name = item.user.name; 
    114       } else if (s.query == null && s.username.length == 1) { 
    115         return proto+'//api.twitter.com/1/statuses/user_timeline.json?screen_name='+s.username[0]+'&count='+s.count+'&callback=?'; 
    116       
     128        return proto+"//"+s.twitter_api_url+"/1/"+s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+count+"&callback=?"; 
     129      } else if (s.favorites) { 
     130        return proto+"//"+s.twitter_api_url+"/favorites/"+s.username[0]+".json?count="+s.count+"&callback=?"; 
     131      } else if (s.query === null && s.username.length == 1) { 
     132        return proto+'//'+s.twitter_api_url+'/1/statuses/user_timeline.json?screen_name='+s.username[0]+'&count='+count+(s.retweets ? '&include_rts=1' : '')+'&callback=?'; 
    117133      } else { 
    118134        var query = (s.query || 'from:'+s.username.join(' OR from:')); 
    119         return proto+'//search.twitter.com/search.json?&q='+escape(query)+'&rpp='+s.count+'&callback=?'; 
     135        return proto+'//'+s.twitter_search_url+'/search.json?&q='+encodeURIComponent(query)+'&rpp='+count+'&callback=?'; 
    120136      } 
    121137    } 
     
    127143      var loading = $('<p class="loading">'+s.loading_text+'</p>'); 
    128144 
    129       if(typeof(s.username) == "string"){ 
     145      if(s.username && typeof(s.username) == "string"){ 
    130146        s.username = [s.username]; 
    131147      } 
    132148 
     149      var expand_template = function(info) { 
     150        if (typeof s.template === "string") { 
     151          var result = s.template; 
     152          for(var key in info) { 
     153            var val = info[key]; 
     154            result = result.replace(new RegExp('{'+key+'}','g'), val === null ? '' : val); 
     155          } 
     156          return result; 
     157        } else return s.template(info); 
     158      }; 
     159 
    133160      if (s.loading_text) $(widget).append(loading); 
    134       $.getJSON(build_url(), function(data){ 
    135         if (s.loading_text) loading.remove(); 
    136         if (s.intro_text) list.before(intro); 
    137         var tweets = (data.results || data); 
    138         $.each(tweets, function(i,item){ 
     161      $(widget).bind("load", function(){ 
     162        $.getJSON(build_url(), function(data){ 
     163          if (s.loading_text) loading.remove(); 
     164          if (s.intro_text) list.before(intro); 
     165          list.empty(); 
     166 
     167          var tweets = $.map(data.results || data, function(item){ 
     168            var join_text = s.join_text; 
    139169       var from_user = item.from_user || item.user.screen_name; 
    140170       if (s.list || (s.query == null && s.username.length == 1)) {var from_user_full_name = item.user.name} 
    141171       else var from_user_full_name = from_user; 
     172 
    142173          // auto join text based on verb tense and content 
    143           if (s.join_text == "auto") { 
    144             if (item.text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) { 
    145               var join_text = s.auto_join_text_reply.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
    146               var join_text = s.auto_join_text_reply.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
    147             } else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) { 
    148               var join_text = s.auto_join_text_url.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
    149               var join_text = s.auto_join_text_url.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
    150             } else if (item.text.match(/^((\w+ed)|just) .*/im)) { 
    151               var join_text = s.auto_join_text_ed.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
    152               var join_text = s.auto_join_text_ed.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
    153             } else if (item.text.match(/^(\w*ing) .*/i)) { 
    154               var join_text = s.auto_join_text_ing.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
    155               var join_text = s.auto_join_text_ing.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
    156             } else { 
    157               var join_text = s.auto_join_text_default.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
    158               var join_text = s.auto_join_text_default.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
     174            if (s.join_text == "auto") { 
     175              if (item.text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) { 
     176                join_text = s.auto_join_text_reply.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
     177          join_text = join_text.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
     178           } else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) { 
     179                join_text = s.auto_join_text_url.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
     180          join_text = join_text.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
     181              } else if (item.text.match(/^((\w+ed)|just) .*/im)) { 
     182                join_text = s.auto_join_text_ed.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
     183          join_text = join_text.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
     184              } else if (item.text.match(/^(\w*ing) .*/i)) { 
     185                join_text = s.auto_join_text_ing.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
     186          join_text = join_text.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
     187              } else { 
     188                join_text = s.auto_join_text_default.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
     189          join_text = join_text.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
     190              } 
    159191            } 
    160           } else { 
    161             var join_text = s.join_text.replace('%u','<a href="http://twitter.com/'+from_user+'">'+from_user+'</a>'); 
    162             var join_text = s.join_text.replace('%U','<a href="http://twitter.com/'+from_user+'">'+from_user_full_name+'</a>'); 
    163           }; 
    164  
    165           var profile_image_url = item.profile_image_url || item.user.profile_image_url; 
    166           var join_template = '<span class="tweet_join"> '+join_text+' </span>'; 
    167           var join = ((s.join_text) ? join_template : ' '); 
    168           var avatar_template = '<a class="tweet_avatar" href="http://twitter.com/'+from_user+'"><img src="'+profile_image_url+'" height="'+s.avatar_size+'" width="'+s.avatar_size+'"'+((s.avatar_alt) ? 'alt="'+s.avatar_alt.replace('%u', from_user)+'" title="'+s.avatar_alt.replace('%u', from_user)+'"' : '')+' /></a>'; 
    169           var avatar = (s.avatar_size ? avatar_template : ''); 
    170           var date = '<a class="tweet_date" href="http://twitter.com/'+from_user+'/statuses/'+item.id+'" title="view tweet on twitter">'+relative_time(item.created_at)+'</a>'; 
    171           var text = '<span class="tweet_text">' +$([item.text]).linkUrl().linkUser().linkHash().makeHeart().capAwesome().capEpic()[0]+ '</span>'; 
    172  
    173           // until we create a template option, arrange the items below to alter a tweet's display. 
    174        if (s.date_after) {  
    175           list.append('<li>' + avatar + '<span class="tweet_content">' + join + text + date + '</span></li>'); 
    176        } else { 
    177           list.append('<li>' + avatar + date + '<span class="tweet_content">' + join + text + '</span></li>'); 
    178        }; 
    179  
    180           list.children('li:first').addClass('tweet_first'); 
    181           list.children('li:odd').addClass('tweet_even'); 
    182           list.children('li:even').addClass('tweet_odd'); 
    183         }); 
    184         if (s.outro_text) list.after(outro); 
    185         $(widget).trigger("loaded").trigger((tweets.length == 0 ? "empty" : "full")); 
    186       }); 
    187  
     192 
     193            // Basic building blocks for constructing tweet <li> using a template 
     194            var screen_name = item.from_user || item.user.screen_name; 
     195            var source = item.source; 
     196            var user_url = "http://"+s.twitter_url+"/"+screen_name; 
     197            var avatar_size = s.avatar_size; 
     198            var avatar_url = item.profile_image_url || item.user.profile_image_url; 
     199            var tweet_url = "http://"+s.twitter_url+"/"+screen_name+"/status/"+item.id_str; 
     200            var retweet = (typeof(item.retweeted_status) != 'undefined'); 
     201            var retweeted_screen_name = retweet ? item.retweeted_status.user.screen_name : null; 
     202            var tweet_time = parse_date(item.created_at); 
     203            var tweet_relative_time = relative_time(tweet_time); 
     204            var tweet_raw_text = retweet ? ('RT @'+retweeted_screen_name+' '+item.retweeted_status.text) : item.text; // avoid '...' in long retweets 
     205            var tweet_text = $([tweet_raw_text]).linkUrl().linkUser().linkHash()[0]; 
     206 
     207            // Default spans, and pre-formatted blocks for common layouts 
     208            var user = '<a class="tweet_user" href="'+user_url+'">'+screen_name+'</a>'; 
     209            var join = ((s.join_text) ? ('<span class="tweet_join"> '+join_text+' </span>') : ' '); 
     210            var avatar = (avatar_size ? 
     211                          ('<a class="tweet_avatar" href="'+user_url+'"><img src="'+avatar_url+ 
     212                           '" height="'+avatar_size+'" width="'+avatar_size+ 
     213                           '" alt="'+screen_name+'\'s avatar" /></a>') : ''); 
     214            var time = '<span class="tweet_time"><a href="'+tweet_url+'" title="view tweet on twitter">'+tweet_relative_time+'</a></span>'; 
     215            var text = '<span class="tweet_text">'+$([tweet_text]).makeHeart().capAwesome().capEpic()[0]+ '</span>'; 
     216 
     217            return { item: item, // For advanced users who want to dig out other info 
     218                     screen_name: screen_name, 
     219                     user_url: user_url, 
     220                     avatar_size: avatar_size, 
     221                     avatar_url: avatar_url, 
     222                     source: source, 
     223                     tweet_url: tweet_url, 
     224                     tweet_time: tweet_time, 
     225                     tweet_relative_time: tweet_relative_time, 
     226                     tweet_raw_text: tweet_raw_text, 
     227                     tweet_text: tweet_text, 
     228                     retweet: retweet, 
     229                     retweeted_screen_name: retweeted_screen_name, 
     230                     user: user, 
     231                     join: join, 
     232                     avatar: avatar, 
     233                     time: time, 
     234                     text: text 
     235                   }; 
     236          }); 
     237 
     238          tweets = $.grep(tweets, s.filter).sort(s.comparator).slice(0, s.count); 
     239          list.append($.map(tweets, 
     240                            function(t) { return "<li>" + expand_template(t) + "</li>"; }).join('')). 
     241              children('li:first').addClass('tweet_first').end(). 
     242              children('li:odd').addClass('tweet_even').end(). 
     243              children('li:even').addClass('tweet_odd'); 
     244 
     245          if (s.outro_text) list.after(outro); 
     246          $(widget).trigger("loaded").trigger((tweets.length === 0 ? "empty" : "full")); 
     247          if (s.refresh_interval) { 
     248            window.setTimeout(function() { $(widget).trigger("load"); }, 1000 * s.refresh_interval); 
     249          } 
     250        }); 
     251      }).trigger("load"); 
    188252    }); 
    189253  }; 
Note: See TracChangeset for help on using the changeset viewer.

Sites map