1if (typeof Object.create !== 'function') { 2 Object.create = function(obj) { 3 function F() {} 4 F.prototype = obj; 5 return new F(); 6 }; 7} 8 9(function($, window, document, undefined) { 10 $.fn.socialfeed = function(_options) { 11 12 13 var defaults = { 14 plugin_folder: '', // a folder in which the plugin is located (with a slash in the end) 15 template: 'template.html', // a path to the template file 16 show_media: false, // show images of attachments if available 17 media_min_width: 300, 18 length: 500, // maximum length of post message shown 19 date_format: 'll', 20 date_locale: 'en' 21 }; 22 //--------------------------------------------------------------------------------- 23 var options = $.extend(defaults, _options), 24 container = $(this), 25 template, 26 social_networks = ['facebook', 'instagram', 'vk', 'google', 'blogspot', 'twitter', 'pinterest', 'rss'], 27 posts_to_load_count = 0, 28 loaded_post_count = 0; 29 // container.empty().css('display', 'block'); 30 //--------------------------------------------------------------------------------- 31 32 //--------------------------------------------------------------------------------- 33 // This function performs consequent data loading from all of the sources by calling corresponding functions 34 function calculatePostsToLoadCount() { 35 social_networks.forEach(function(network) { 36 if (options[network]) { 37 if (options[network].accounts) { 38 posts_to_load_count += options[network].limit * options[network].accounts.length; 39 } else if (options[network].urls ){ 40 posts_to_load_count += options[network].limit * options[network].urls.length; 41 } else { 42 posts_to_load_count += options[network].limit; 43 } 44 } 45 }); 46 } 47 48 calculatePostsToLoadCount(); 49 50 function fireCallback() { 51 var fire = true; 52 /*$.each(Object.keys(loaded), function() { 53 if (loaded[this] > 0) 54 fire = false; 55 });*/ 56 if (fire && options.callback) { 57 options.callback(); 58 } 59 } 60 61 var Utility = { 62 request: function(url, callback) { 63 $.ajax({ 64 url: url, 65 dataType: 'jsonp', 66 success: callback 67 }); 68 }, 69 get_request: function(url, callback) { 70 $.get(url, callback, 'json'); 71 }, 72 wrapLinks: function(string, social_network) { 73 var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; 74 if (social_network === 'google-plus') { 75 string = string.replace(/(@|#)([a-z0-9_]+['])/ig, Utility.wrapGoogleplusTagTemplate); 76 } else { 77 string = string.replace(exp, Utility.wrapLinkTemplate); 78 } 79 return string; 80 }, 81 wrapLinkTemplate: function(string) { 82 return '<a target="_blank" href="' + string + '">' + string + '<\/a>'; 83 }, 84 wrapGoogleplusTagTemplate: function(string) { 85 return '<a target="_blank" href="https://plus.google.com/s/' + string + '" >' + string + '<\/a>'; 86 }, 87 shorten: function(string) { 88 string = $.trim(string); 89 if (string.length > options.length) { 90 return jQuery.trim(string).substring(0, options.length).split(" ").slice(0, -1).join(" ") + "..."; 91 } else { 92 return string; 93 } 94 }, 95 stripHTML: function(string) { 96 if (typeof string === "undefined" || string === null) { 97 return ''; 98 } 99 return string.replace(/(<([^>]+)>)|nbsp;|\s{2,}|/ig, ""); 100 } 101 }; 102 103 function SocialFeedPost(social_network, data) { 104 this.content = data; 105 this.content.social_network = social_network; 106 this.content.attachment = (this.content.attachment === undefined) ? '' : this.content.attachment; 107 this.content.time_ago = data.dt_create.locale(options.date_locale).fromNow(); 108 this.content.date = data.dt_create.locale(options.date_locale).format(
108options.date_format); 109 this.content.dt_create = this.content.dt_create.valueOf(); 110 this.content.text = Utility.wrapLinks(Utility.shorten(data.message + ' ' + data.description), data.social_network); 111 this.content.moderation_passed = (options.moderation) ? options.moderation(this.content) : true; 112 113 Feed[social_network].posts.push(this); 114 } 115 SocialFeedPost.prototype = { 116 render: function() { 117 var rendered_html = Feed.template(this.content); 118 var data = this.content; 119 120 if ($(container).children('[social-feed-id=' + data.id + ']').length !== 0) { 121 return false; 122 } 123 if ($(container).children().length === 0) { 124 $(container).append(rendered_html); 125 } else { 126 var i = 0, 127 insert_index = -1; 128 $.each($(container).children(), function() { 129 if ($(this).attr('dt-create') < data.dt_create) { 130 insert_index = i; 131 return false; 132 } 133 i++; 134 }); 135 $(container).append(rendered_html); 136 if (insert_index >= 0) { 137 insert_index++; 138 var before = $(container).children('div:nth-child(' + insert_index + ')'), 139 current = $(container).children('div:last-child'); 140 $(current).insertBefore(before); 141 } 142 143 } 144 if (options.media_min_width) { 145 146 var query = '[social-feed-id=' + data.id + '] img.attachment'; 147 var image = $(query); 148 149 // preload the image 150 var height, width = ''; 151 var img = new Image(); 152 var imgSrc = image.attr("src"); 153 154 $(img).load(function() { 155 156 if (img.width < options.media_min_width) { 157 image.hide(); 158 } 159 // garbage collect img 160 delete img; 161 162 }).error(function() { 163 // image couldnt be loaded 164 image.hide(); 165 166 }).attr({ 167 src: imgSrc 168 }); 169 170 } 171 172 loaded_post_count++; 173 if (loaded_post_count == posts_to_load_count) { 174 fireCallback(); 175 } 176 177 } 178 179 }; 180 181 var Feed = { 182 template: false, 183 init: function() { 184 Feed.getTemplate(function() { 185 social_networks.forEach(function(network) { 186 if (options[network]) { 187 if ( options[network].accounts ) { 188 //loaded[network] = 0; 189 options[network].accounts.forEach(function(account) { 190 //loaded[network]++; 191 Feed[network].getData(account); 192 }); 193 } else if ( options[network].urls ) { 194 options[network].urls.forEach(function(url) { 195 Feed[network].getData(url); 196 }); 197 } else { 198 Feed[network].getData(); 199 } 200 } 201 }); 202 }); 203 }, 204 getTemplate: function(callback) { 205 if (Feed.template) 206 return callback(); 207 else { 208 if (options.template_html) { 209 Feed.template = doT.template(options.template_html); 210 return callback(); 211 } else { 212 $.get(options.template, function(template_html) { 213 Feed.template = doT.template(template_html); 214 return callback(); 215 }); 216 } 217 } 218 }, 219 twitter: { 220 posts: [], 221 loaded: false,
222 api: 'http://api.tweecool.com/', 223 224 getData: function(account) { 225 226 var cb = new Codebird(); 227 cb.setConsumerKey(options.twitter.consumer_key, options.twitter.consumer_secret); 228 229 // Allow setting your own proxy with Codebird 230 if (options.twitter.proxy !== undefined) { 231 cb.setProxy(options.twitter.proxy); 232 } 233 234 switch (account[0]) { 235 case '@': 236 var userid = account.substr(1); 237 cb.__call( 238 "statuses_userTimeline", 239 "id=" + userid + "&count=" + options.twitter.limit, 240 Feed.twitter.utility.getPosts, 241 true // this parameter required 242 ); 243 break; 244 case '#': 245 var hashtag = account.substr(1); 246 cb.__call( 247 "search_tweets", 248 "q=" + hashtag + "&count=" + options.twitter.limit, 249 function(reply) { 250 Feed.twitter.utility.getPosts(reply.statuses); 251 }, 252 true // this parameter required 253 ); 254 break; 255 default: 256 } 257 }, 258 utility: { 259 getPosts: function(json) { 260 if (json) { 261 $.each(json, function() { 262 var element = this; 263 var post = new SocialFeedPost('twitter', Feed.twitter.utility.unifyPostData(element)); 264 post.render(); 265 }); 266 } 267 }, 268 unifyPostData: function(element) { 269 var post = {}; 270 if (element.id) { 271 post.id = element.id_str; 272 //prevent a moment.js console warning due to Twitter's poor date format. 273 post.dt_create = moment(element.created_at, 'dd MMM DD HH:mm:ss ZZ YYYY'); 274 post.author_link = 'http://twitter.com/' + element.user.screen_name; 275 post.author_picture = element.user.profile_image_url_https; 276 post.post_url = post.author_link + '/status/' + element.id_str; 277 post.author_name = element.user.name; 278 post.message = element.text; 279 post.description = ''; 280 post.link = 'http://twitter.com/' + element.user.screen_name + '/status/' + element.id_str; 281 282 if (options.show_media === true) { 283 if (element.entities.media && element.entities.media.length > 0) { 284 var image_url = element.entities.media[0].media_url_https; 285 if (image_url) { 286 post.attachment = '<img class="attachment" src="' + image_url + '" />'; 287 } 288 } 289 } 290 } 291 return post; 292 } 293 } 294 }, 295 facebook: { 296 posts: [], 297 graph: 'https://graph.facebook.com/', 298 loaded: false, 299 getData: function(account) { 300 var proceed = function(request_url){ 301 Utility.request(request_url, Feed.facebook.utility.getPosts); 302 }; 303 var fields = '?fields=id,from,name,message,created_time,story,description,link'; 304 fields += (options.show_media === true)?',picture,object_id':''; 305 var request_url, limit = '&limit=' + options.facebook.limit,
306 query_extention = '&access_token=' + options.facebook.access_token + '&callback=?'; 307 switch (account[0]) { 308 case '@': 309 var username = account.substr(1); 310 Feed.facebook.utility.getUserId(username, function(userdata) { 311 if (userdata.id !== '') { 312 request_url = Feed.facebook.graph + 'v2.4/' + userdata.id + '/posts'+ fields + limit + query_extention; 313 proceed(request_url); 314 } 315 }); 316 break; 317 case '!': 318 var page = account.substr(1); 319 request_url = Feed.facebook.graph + 'v2.4/' + page + '/feed'+ fields + limit + query_extention; 320 proceed(request_url); 321 break; 322 default: 323 proceed(request_url); 324 } 325 }, 326 utility: { 327 getUserId: function(username, callback) {
328 var query_extention = '&access_token=' + options.facebook.access_token + '&callback=?'; 329 var url = 'https://graph.facebook.com/' + username + '?' + query_extention; 330 var result = ''; 331 $.get(url, callback, 'json'); 332 }, 333 prepareAttachment: function(element) { 334 var image_url = element.picture; 335 if (image_url.indexOf('_b.') !== -1) { 336 //do nothing it is already big 337 } else if (image_url.indexOf('safe_image.php') !== -1) { 338 image_url = Feed.facebook.utility.getExternalImageURL(image_url, 'url'); 339 340 } else if (image_url.indexOf('app_full_proxy.php') !== -1) { 341 image_url = Feed.facebook.utility.getExternalImageURL(image_url, 'src'); 342 343 } else if (element.object_id) { 344 image_url = Feed.facebook.graph + element.object_id + '/picture/?type=normal'; 345 } 346 return '<img class="attachment" src="' + image_url + '" />'; 347 }, 348 getExternalImageURL: function(image_url, parameter) { 349 image_url = decodeURIComponent(image_url).split(parameter + '=')[1]; 350 if (image_url.indexOf('fbcdn-sphotos') === -1) { 351 return image_url.split('&')[0]; 352 } else { 353 return image_url; 354 } 355 356 }, 357 getPosts: function(json) { 358 if (json['data']) { 359 json['data'].forEach(function(element) { 360 var post = new SocialFeedPost('facebook', Feed.facebook.utility.unifyPostData(element)); 361 post.render(); 362 }); 363 } 364 }, 365 unifyPostData: function(element) { 366 var post = {}, 367 text = (element.message) ? element.message : element.story; 368 369 post.id = element.id; 370 post.dt_create = moment(element.created_time); 371 post.author_link = 'http://facebook.com/' + element.from.id; 372 post.author_picture = Feed.facebook.graph + element.from.id + '/picture'; 373 post.author_name = element.from.name; 374 post.name = element.name || ""; 375 post.message = (text) ? text : ''; 376 post.description = (element.description) ? element.description : ''; 377 post.link = (element.link) ? element.link : 'http://facebook.com/' + element.from.id; 378 379 if (options.show_media === true) { 380 if (element.picture) { 381 var attachment = Feed.facebook.utility.prepareAttachment(element); 382 if (attachment) { 383 post.attachment = attachment; 384 } 385 } 386 } 387 return post; 388 } 389 } 390 }, 391 google: { 392 posts: [], 393 loaded: false, 394 api: 'https://www.googleapis.com/plus/v1/', 395 getData: function(account) { 396 var request_url; 397 switch (account[0]) { 398 case '#': 399 var hashtag = account.substr(1); 400 request_url = Feed.google.api + 'activities?query=' + hashtag + '&key=' + options.google.access_token + '&maxResults=' + options.google.limit; 401 Utility.get_request(request_url, Feed.google.utility.getPosts); 402 break; 403 case '@': 404 var username = account.substr(1); 405 request_url = Feed.google.api + 'people/' + username + '/activities/public?key=' + options.google.access_token + '&maxResults=' + options.google.limit; 406 Utility.get_request(request_url, Feed.google.utility.getPosts); 407 break; 408 default: 409 } 410 }, 411 utility: { 412 getPosts: function(json) { 413 if (json.items) { 414 $.each(json.items, function(i) { 415 var post = new SocialFeedPost('google', Feed.google.utility.unifyPostData(json.items[i])); 416 post.render(); 417 }); 418 } 419 }, 420 unifyPostData: function(element) { 421 var post = {}; 422
423 post.id = element.id; 424 post.attachment = ''; 425 post.description = ''; 426 post.dt_create = moment(element.published); 427 post.author_link = element.actor.url; 428 post.author_picture = element.actor.image.url; 429 post.author_name = element.actor.displayName; 430 431 if (options.show_media === true) { 432 if (element.object.attachments) { 433 $.each(element.object.attachments, function() { 434 var image = ''; 435 if (this.fullImage) { 436 image = this.fullImage.url; 437 } else { 438 if (this.objectType === 'album') { 439 if (this.thumbnails && this.thumbnails.length > 0) { 440 if (this.thumbnails[0].image) { 441 image = this.thumbnails[0].image.url; 442 } 443 } 444 } 445 } 446 post.attachment = '<img class="attachment" src="' + image
446+ '"/>'; 447 }); 448 } 449 } 450 post.message = element.title; 451 post.link = element.url; 452 453 return post; 454 } 455 } 456 }, 457 instagram: { 458 posts: [], 459 api: 'https://api.instagram.com/v1/', 460 loaded: false, 461 accessType: function() { 462 // If we have both the client_id and access_token set in options, 463 // use access_token for authentication. If client_id is not set 464 // then use access_token. If neither are set, log an error to console. 465 if (typeof options.instagram.access_token === 'undefined' && typeof options.instagram.client_id === 'undefined') { 466 console.log('You need to define a client_id or access_token to authenticate with Instagram\'s API.'); 467 return undefined; 468 } 469 if (options.instagram.access_token) { options.instagram.client_id = undefined; } 470 options.instagram.access_type = (typeof options.instagram.client_id === 'undefined' ? 'access_token' : 'client_id'); 471 return options.instagram.access_type; 472 }, 473 getData: function(account) { 474 var url; 475 476 // API endpoint URL depends on which authentication type we're using. 477 if (this.accessType() !== 'undefined') { 478 var authTokenParams = options.instagram.access_type + '=' + options.instagram[options.instagram.access_type]; 479 } 480 481 switch (account[0]) { 482 case '@': 483 var username = account.substr(1); 484 url = Feed.instagram.api + 'users/search/?q=' + username + '&' + authTokenParams + '&count=1' + '&callback=?'; 485 Utility.request(url, Feed.instagram.utility.getUsers); 486 break; 487 case '#': 488 var hashtag = account.substr(1); 489 url = Feed.instagram.api + 'tags/' + hashtag + '/media/recent/?' + authTokenParams + '&' + 'count=' + options.instagram.limit + '&callback=?'; 490 Utility.request(url, Feed.instagram.utility.getImages); 491 break; 492 case '&': 493 var id = account.substr(1); 494 url = Feed.instagram.api + 'users/' + id + '/?' + authTokenParams + '&' + 'count=' + options.instagram.limit + '&callback=?'; 495 Utility.request(url, Feed.instagram.utility.getUsers); 496 default: 497 } 498 }, 499 utility: { 500 getImages: function(json) { 501 if (json.data) { 502 json.data.forEach(function(element) { 503 var post = new SocialFeedPost('instagram', Feed.instagram.utility.unifyPostData(element)); 504 post.render(); 505 }); 506 } 507 }, 508 getUsers: function(json) { 509 // API endpoint URL depends on which authentication type we're using. 510 if (options.instagram.access_type !== 'undefined') { 511 var authTokenParams = options.instagram.access_type + '=' + options.instagram[options.instagram.access_type]; 512 } 513 514 if (!jQuery.isArray(json.data)) json.data = [json.data] 515 json.data.forEach(function(user) { 516 var url = Feed.instagram.api + 'users/' + user.id + '/media/recent/?' + authTokenParams + '&' + 'count=' + options.instagram.limit + '&callback=?'; 517 Utility.request(url, Feed.instagram.utility.getImages); 518 }); 519 }, 520 unifyPostData: function(element) { 521 var post = {}; 522
523 post.id = element.id; 524 post.dt_create = moment(element.created_time * 1000); 525 post.author_link = 'http://instagram.com/' + element.user.username; 526 post.author_picture = element.user.profile_picture; 527 post.author_name = element.user.full_name || element.user.username; 528 post.message = (element.caption && element.caption) ? element.caption.text : ''; 529 post.description = ''; 530 post.link = element.link; 531 if (options.show_media) { 532 post.attachment = '<img class="attachment" src="' + element.images.standard_resolution.url + '' + '" />'; 533 } 534 return post; 535 } 536 } 537 }, 538 vk: { 539 posts: [], 540 loaded: false, 541 base: 'http://vk.com/', 542 api: 'https://api.vk.com/method/', 543 user_json_template: 'https://api.vk.com/method/' + 'users.get?fields=first_name,%20last_name,%20screen_name,%20photo&uid=', 544 group_json_template: 'https://api.vk.com/method/' + 'groups.getById?fields=first_name,%20last_name,%20screen_name,%20photo&gid=', 545 getData: function(account) { 546 var request_url; 547 548 switch (account[0]) { 549 case '@': 550 var username = account.substr(1); 551 request_url = Feed.vk.api + 'wall.get?owner_id=' + username + '&filter=' + options.vk.source + '&count=' + options.vk.limit + '&callback=?'; 552 Utility.get_request(request_url, Feed.vk.utility.getPosts); 553 break; 554 case '#': 555 var hashtag = account.substr(1); 556 request_url = Feed.vk.api + 'newsfeed.search?q=' + hashtag + '&count=' + options.vk.limit + '&callback=?'; 557 Utility.get_request(request_url, Feed.vk.utility.getPosts); 558 break; 559 default: 560 } 561 }, 562 utility: { 563 getPosts: function(json) { 564 if (json.response) { 565 $.each(json.response, function() { 566 if (this != parseInt(this) && this.post_type === 'post') { 567 var owner_id = (this.owner_id) ? this.owner_id : this.from_id, 568 vk_wall_owner_url = (owner_id > 0) ? (Feed.vk.user_json_template + owner_id + '&callback=?') : (Feed.vk.group_json_template + (-1) * owner_id + '&callback=?'), 569 element = this; 570 Utility.get_request(vk_wall_owner_url, function(wall_owner) { 571 Feed.vk.utility.unifyPostData(wall_owner, element, json); 572 }); 573 } 574 }); 575 } 576 }, 577 unifyPostData: function(wall_owner, element, json) { 578 var post = {}; 579 580 post.id = element.id; 581 post.dt_create = moment.unix(element.date); 582 post.description = ' '; 583 post.message = Utility.stripHTML(element.text); 584 if (options.show_media) { 585 if (element.attachment) { 586 if (element.attachment.type === 'link') 587 post.attachment = '<img class="attachment" src="' + element.attachment.link.image_src + '" />'; 588 if (element.attachment.type === 'video') 589 post.attachment = '<img class="attachment" src="' + element.attachment.video.image_big + '" />'; 590 if (element.attachment.type === 'photo') 591 post.attachment = '<img class="attachment" src="' + element.attachment.photo.src_big + '" />'; 592 } 593 } 594 595 if (element.from_id > 0) { 596 var vk_user_json = Feed.vk.user_json_template + element.from_id + '&callback=?'; 597 Utility.get_request(vk_user_json, function(user_json) { 598 var vk_post = new SocialFeedPost('vk', Feed.vk.utility.getUser(user_json, post, element, json)); 599 vk_post.render(); 600 }); 601 602 } else { 603 var vk_group_json = Feed.vk.group_json_template + (-1) * element.from_id + '&callback=?'; 604 Utility.get_request(vk_group_json, function(user_json) { 605 var vk_post = new SocialFeedPost('vk', Feed.vk.utility.getGroup(user_json, post, element, json)); 606 vk_post.render(); 607 }); 608 } 609 }, 610 getUser: function(user_json, post, element, json) { 611 post.author_name = user_json.response[0].first_name + ' ' + user_json.response[0].last_name; 612 post.author_picture = user_json.response[0].photo; 613 post.author_link = Feed.vk.base + user_json.response[0].screen_name; 614 post.link = Feed.vk.base + user_json.response[0].screen_name + '?w=wall' + element.from_id + '_' + element.i
614d; 615 616 return post; 617 }, 618 getGroup: function(user_json, post, element, json) { 619 post.author_name = user_json.response[0].name; 620 post.author_picture = user_json.response[0].photo; 621 post.author_link = Feed.vk.base + user_json.response[0].screen_name; 622 post.link = Feed.vk.base + user_json.response[0].screen_name + '?w=wall-' + user_json.response[0].gid + '_' + element.id; 623 624 return post; 625 } 626 } 627 }, 628 blogspot: { 629 loaded: false, 630 getData: function(account) { 631 var url; 632 633 switch (account[0]) { 634 case '@': 635 var username = account.substr(1); 636 url = 'http://' + username + '.blogspot.com/feeds/posts/default?alt=json-in-script&callback=?'; 637 request(url, getPosts); 638 break; 639 default: 640 } 641 }, 642 utility: { 643 getPosts: function(json) { 644 $.each(json.feed.entry, function() { 645 var post = {}, 646 element = this; 647 post.id = element.id['$t'].replace(/[^a-z0-9]/gi, ''); 648 post.dt_create = moment((element.published['$t'])); 649 post.author_link = element.author[0]['uri']['$t']; 650 post.author_picture = 'http:' + element.author[0]['gd$image']['src']; 651 post.author_name = element.author[0]['name']['$t']; 652 post.message = element.title['$t'] + '</br></br>' + stripHTML(element.content['$t']); 653 post.description = ''; 654 post.link = element.link.pop().href; 655 656 if (options.show_media) { 657 if (element['media$thumbnail']) { 658 post.attachment = '<img class="attachment" src="' + element['media$thumbnail']['url'] + '" />'; 659 } 660 } 661 662 post.render(); 663 664 }); 665 } 666 } 667 }, 668 pinterest: { 669 posts: [], 670 loaded: false, 671 apiv1: 'https://api.pinterest.com/v1/', 672 673 getData: function(account) { 674 var request_url, 675 limit = 'limit=' + options.pinterest.limit, 676 fields = 'fields=id,created_at,link,note,creator(url,first_name,last_name,image),image', 677 query_extention = fields + '&access_token='
677+ options.pinterest.access_token + '&' + limit + '&callback=?'; 678 switch (account[0]) { 679 case '@': 680 var username = account.substr(1); 681 if (username === 'me') { 682 request_url = Feed.pinterest.apiv1 + 'me/pins/?' + query_extention; 683 } else { 684 request_url = Feed.pinterest.apiv1 + 'boards/' + username + '/pins?' + query_extention; 685 } 686 break; 687 default: 688 } 689 Utility.request(request_url, Feed.pinterest.utility.getPosts); 690 }, 691 utility: { 692 693 getPosts: function(json) { 694 json.data.forEach(function(element) { 695 var post = new SocialFeedPost('pinterest', Feed.pinterest.utility.unifyPostData(element)); 696 post.render(); 697 }); 698 }, 699 700 unifyPostData: function(element){ 701 var post = {}; 702 703 post.id = element.id; 704 post.dt_create= moment(element.created_at); 705 post.author_link = element.creator.url; 706 post.author_picture = element.creator.image['60x60' ].url; 707 post.author_name = element.creator.first_name + element.creator.last_name; 708 post.message = element.note; 709 post.description = ''; 710 post.social_network = 'pinterest'; 711 post.link = element.link ? element.link : 'https://www.pinterest.com/pin/' + element.id; 712 if (options.show_media) { 713 post.attachment = '<img class="attachment" src="' + element.image['original'].url + '" />'; 714 } 715 return post; 716 } 717 } 718 }, 719 rss : { 720 posts: [], 721 loaded: false, 722 api : 'https://query.yahooapis.com/v1/public/yql?q=', 723 datatype: 'json', 724 725 getData: function(url) { 726 var limit = options.rss.limit, 727 yql = encodeURIComponent('select entry FROM feednormalizer where url=\'' + url + '\' AND output=\'atom_1.0\' | truncate(count=' + limit + ')' ), 728 request_url = Feed.rss.api + yql + '&format=json&callback=?'; 729 730 Utility.request(request_url, Feed.rss.utility.getPosts, Feed.rss.datatype); 731 }, 732 utility: { 733 734 getPosts: function(json) { 735 console.log(json); 736 if (json.query.count > 0 ){ 737 $.each(json.query.results.feed, function(index, element) { 738 var post = new SocialFeedPost('rss', Feed.rss.utility.unifyPostData(index, element)); 739 post.render(); 740 }); 741 } 742 }, 743 744 unifyPostData: function(index, element){ 745 746 var item = element; 747 748 if ( element.entry !== undefined ){ 749 item = element.entry; 750 } 751 var post = {}; 752 753 post.id = '"' + item.id + '"'; 754 post.dt_create= moment(item.published, 'YYYY-MM-DDTHH:mm:ssZ', 'en'); 755 756 post.author_link = ''; 757 post.author_picture = ''; 758 post.author_name = ''; 759 if( item.creator !== undefined ){ 760 post.author_name = item.creator; 761 } 762 post.message = item.title; 763 post.description = ''; 764 if( item.summary !== undefined ){ 765 post.description = Utility.stripHTML(item.summary.content); 766 } 767 post.social_network = 'rss'; 768 post.link = item.link.href; 769 if (options.show_media && item.thumbnail !== undefined ) { 770 post.attachment = '<img class="attachment" src="' + item.thumbnail.url + '" />'; 771 } 772 return post; 773 } 774 } 775 } 776 }; 777 778 //make the plugin chainable 779 return this.each(function() { 780 // Initialization 781 Feed.init(); 782 if (options.update_period) { 783 setInterval(function() { 784 return Feed.init(); 785 }, options.update_period); 786 } 787 }) 788 }; 789 790})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.