home *** CD-ROM | disk | FTP | other *** search
Wrap
var API_CLIENT_ID = "ffext"; var API_CLIENT_KEY = '34daab8d9da7f58420098ce7d7f740c8'; var MAX_LINKS_TO_CHECK = 30; var VS_LOGGING_ACTIVE = null; var VS_AJAX_URL_ROOT = null; var VS_SUMMARY_TILE_WIDTH = 57; var URL_CHANGE_WATCH_TIMEOUT = 500; var CONTENT_CHANGE_WATCH_TIMEOUT = 500; function enhanceGoogleSearch() { vs_log("Enhancing google search/home page"); if($(VS_ACTIVE_SITE['link_selector']+':first').length > 0) { //This is a regular search page, no need for the ajax checks enhanceSearchPage(); } else { //We're most likely on the xhr version of their page (so annoying!) if(location.hash) { watchForPageContentChange(enhanceSearchPage); } else { watchForUrlChange(enhanceSearchPage); } } } /** * Twitter has a bunch of variations, ajax, no ajax, url change, no url change... This should handle them all **/ function enhanceTwitter() { vs_log("Twitter enhancer initializing"); if($(VS_ACTIVE_SITE['link_selector']).length > 0) { enhanceTwitterPage(); } else { watchForPageContentChange(enhanceTwitterPage); } watchForUrlChange(enhanceTwitterPage); } function enhanceTwitterPage() { vs_log("Actually enhancing a twitter page"); var probablyShortUrls = getEnhanceableUrlsOnPage(); if(probablyShortUrls.length > MAX_LINKS_TO_CHECK) { probablyShortUrls.length = MAX_LINKS_TO_CHECK; } var ajaxUrl = VS_AJAX_URL_ROOT+"/api/ext/services/longUrlService.php?urls="+encodeURIComponent(probablyShortUrls.join(","))+"&client_id="+API_CLIENT_ID+"&client_key="+API_CLIENT_KEY; ajaxCall(ajaxUrl, twitterUrlExpandAjaxCallback); } function twitterUrlExpandAjaxCallback(json) { var url_expansion_active = VS_getPref("expose_longer_twitter_urls"); $(VS_ACTIVE_SITE['link_selector']+":not(.vs_enhanced)").each(function() { if(json[this.href]) { var longVersion = json[this.href]; if(url_expansion_active && this.href != longVersion) { this.innerHTML = (longVersion.length > 25) ? longVersion.substr(0, 25)+"..." : longVersion; } this.href = longVersion; } }); enhanceSearchPage(false, enhanceTwitterPage); //The Refresh and More actions do not change the url, we have to explicitly watch for them $('#pagination .more:not(.vs_enhanced)').bind('click', function() { previousPageSignature = getPageSignature(); watchForPageContentChange(enhanceTwitterPage); }).addClass("vs_enhanced"); var refresh_link = $('#res-update:not(.vs_enhanced)'); if(refresh_link.length == 0) { refresh_link = $('#results_update:not(.vs_enhanced)'); } refresh_link.bind('mouseout', function() { watchForPageContentChange(enhanceTwitterPage); }); refresh_link.addClass("vs_enhanced"); } /** * Analyze the links on the page to generate a "signature" for it. * When this signature changes, we need to re-enhance the page **/ function getPageSignature() { var urls = []; var selector = VS_ACTIVE_SITE['link_selector']; $(selector).each(function() { urls[urls.length] = (this.original_href) ? this.original_href : this.href; }); return urls.join(""); } function getEnhanceableUrlsOnPage() { var urls = []; var selector = VS_ACTIVE_SITE['link_selector']+":not(.vs_enhanced)"; $(selector).each(function() { urls[urls.length] = (this.original_href) ? this.original_href : this.href; }); return urls; } /** * After the url changes, we periodically check to see if the videos on the page have changed. Once they have, * this means the xhr request has completed. This is a relatively heavy check so we only do it after we detect * that the url has changed. It should only persist for the duration of the site's xhr call and then we revert * to the light url check. **/ function watchForPageContentChange(run_fn) { var sig = getPageSignature(); if(sig && sig != previousPageSignature) { vs_log("Urls on page changed! Re-enhancing"); previousPageSignature = sig; run_fn(); } else { pccTimeout = setTimeout(function() { watchForPageContentChange(run_fn); }, CONTENT_CHANGE_WATCH_TIMEOUT); } } /** * Watch to see if the url changes. This indicates an xhr request has begun for a refinement. * This is an extremely light weight check, so we can do it fairly often **/ var previousHref; var pguTimeout; var pccTimeout; var previousPageSignature; var previousAutoPagerLength; function watchForUrlChange(run_fn) { //ap = $('.autoPagerS'); if((previousHref != null && location.href != previousHref)) { // || (ap.length > 0 && ap.length != previousAutoPagerLength)) { vs_log("URL changed!"); previousHref = location.href; //previousAutoPagerLength = ap.length; watchForPageContentChange(run_fn); } else { previousHref = location.href; pguTimeout = setTimeout(function() { watchForUrlChange(run_fn) }, URL_CHANGE_WATCH_TIMEOUT); } } function enhanceYoutubeVideoAjaxCallback(json) { vs_log("Inside enhanceYoutubeVideoAjaxCallback "); if(!json.videos || json.videos.length == 0) { return; } var video = json.videos[0]; if(video.visual_video_summary.frames.length) { var n = getSummaryReadyToInsert(video, true, 0); $('#watch-this-vid-info').prepend(n); attachSummaryEventHandlers(); bindSeekClickHandlers($('#watch-this-vid-info'), unsafeWindow.document.getElementById('movie_player')); } //Add related topics var topics = video.related_entities; if(topics && topics.length > 0) { var topicHtml = '<h2 id="videosurf-topics-heading" class="yt-uix-expander-head">' + ' <button class="yt-uix-expander-arrow master-sprite" title=""/>' + ' <span>Related VideoSurf Topics</span>' + '</h2>'; topicHtml += "<div class='watch-discoverbox-body mini-list-view yt-uix-expander-body'>"; topicHtml += "<ul>"; var count = 0; for(i = 0 ; i < topics.length ; i++) { var topic = topics[i]; if(count >= 6) { break; } if(topic['thumbnail']) { var title = topic['title']; var escapedTitle = title.replace("'", "\'"); if(title.length > 12) { title = title.substring(0, 9).replace(" ", " ")+"..."; } topicHtml += "<li><a href='"+topic['url']+"' title='"+escapedTitle+"'><img src='"+topic['thumbnail']+"'></a><a class='topic-title' title='"+escapedTitle+"' href='"+topic['url']+"'>"+title+"</a></li>"; count++; } } topicHtml += "</ul></div>"; var expandedClass = VS_getPref('youtube_related_expanded') ? "" : "yt-uix-expander-collapsed"; n = $('<div>').attr('id', 'videosurf-topics').html(topicHtml).addClass('videosurf-topics watch-discoverbox-wrapper expand-panel yt-uix-expander '+expandedClass); if(count) n.insertBefore('#watch-channel-videos-panel'); $('#videosurf-topics').click(function(event) { event.stopPropagation(); if($(this).hasClass('yt-uix-expander-collapsed')) { $(this).removeClass('yt-uix-expander-collapsed'); VS_setPref("youtube_related_expanded", true); } else { $(this).addClass('yt-uix-expander-collapsed'); VS_setPref("youtube_related_expanded", false); } }); } } function handleYoutubeSeekClick(e, embed_id) { e.preventDefault(); var re = new RegExp("t=([0-9]+)", "i"); var matches = e.target.parentNode.href.match(re); if(matches && matches.length > 0) { vs_log("seeking in "+embed_id+" to "+matches[1]); //var embed = unsafeWindow.document.getElementById('movie_player'); //Only the unsafeWindow document seems to have access to the api functions var embed = unsafeWindow.document.getElementById(embed_id); if(embed.getPlayerState() == 0) { embed.playVideo(); //their player has a bug about seeking after it's "ended", so we restart it } embed.seekTo(parseInt(matches[1]), true); } return false; } function bindSeekClickHandlers(summary, embed, source_id) { if(VS_ACTIVE_SITE['slug'] == "youtube_video" || VS_ACTIVE_SITE['slug'] == "embedded_video_summaries") { if(!embed.id) { embed.id = "vs_embed_"+source_id; } $(summary).find('.summaryThumbnailFrame').attr('title', 'Click to jump to this moment in the video!').bind('click', function(e) { handleYoutubeSeekClick(e, embed.id); }); } } /** * Gets info for just one video and inserts the summary **/ function enhanceYoutubeVideo() { vs_log("Enhancing youtube video page - Summaries ("+VS_ACTIVE_SITE_SUMMARIES_ENABLED+") Related ("+VS_ACTIVE_SITE_RELATED_ENABLED+")"); if(VS_ACTIVE_SITE_SUMMARIES_ENABLED) { var url = document.location.href; if(url.indexOf("#") == url.length - 1) { //strip off trailing # url = url.substring(0, url.length - 1); } summarySize = 11; ajaxUrl = VS_AJAX_URL_ROOT+"/video_lookup/v1.2/?urls="+encodeURIComponent(url)+"&visual_summary_size="+summarySize+"&client_id="+API_CLIENT_ID+"&client_key="+API_CLIENT_KEY+"&vss="+VS_ACTIVE_SITE['slug']; ajaxCall(ajaxUrl, enhanceYoutubeVideoAjaxCallback); } } /** * Takes search results from videosurf's search api and inserts them into the page as related videos **/ function enhanceSearchPageRelatedAjaxCallback(json) { vs_log("In Related Ajax Callback"); vs_log(json, true); if(!json.videos || json.videos.length == 0) { return; } var container = null; switch(VS_ACTIVE_SITE['slug']) { case "google_search": containerId = "mbEnd"; if(!document.getElementById(containerId)) { $('#res').before('<table id='+containerId+'></table>'); vs_log("adding the related container"); } container = $('#'+containerId); container.prepend("<tr><td colspan='100' id='vs-related-container'></td></tr>"); container = $("#vs-related-container"); break; case "yahoo": containerId = 'east'; if(!document.getElementById(containerId)) { $('#right').append($('<div>').attr('id', containerId)); vs_log("adding the related container"); } container = $('#'+containerId); break; case "youtube": container = $('#search-pva'); break; case "twitter_search": containerId = "vs-twitter-related-container"; if(!document.getElementById("vs-twitter-related-container")) { $('#mainContent').append($('<div>').attr('id', containerId).addClass("module")); vs_log("adding the related container"); } container = $('#'+containerId); break; case "bing": container = $('#sidebar'); break; case "riot": container = $('#secondaryContent'); if(!container.length) { $('body .wrapper').animate({width:975}); container = $('<div id="videosurfContainer" style="float: right"></div>'); $('#OneRiotWebSearch').before(container); } break; default: return; } var related_container_template = VS_getUrlContents("chrome://videosurf_enhanced/content/templates/related_container.tmpl"); var related_video_template = VS_getUrlContents("chrome://videosurf_enhanced/content/templates/related_video.tmpl"); relatedHtml = ""; for(i = 0 ; i < json.videos.length; i++) { v = json.videos[i]; v.img_width = 119; //needed for sprite hover animation v.img_height = 73; relatedHtml += getVideoHtml(v, false, i); } var query = getCurrentSearchQuery(); var more_url = "http://www.videosurf.com/videos/"+cleanQuery(query)+"?vlt=ffext"; relatedHtml = fillTemplate(related_container_template, { 'videos' : relatedHtml, 'more_url' : more_url, 'matching_results' : addCommas(json.matching_results), 'more_display' : (json.matching_results > VS_getPref("related_search_num_results")) ? "block" : "none" }); if(document.getElementById('vs-related-uber-container')) { //because of ajax, only inject the related once $('vs-related-uber-container').html(relatedHtml); } else { if(container && relatedHtml) { var related_css = VS_getUrlContents("chrome://videosurf_enhanced/content/css/relatedVideos.css"); related_css += VS_getUrlContents("chrome://videosurf_enhanced/content/css/related_custom_"+VS_ACTIVE_SITE['slug']+".css"); VS_addStyle(related_css); vs_log("Injecting the related videos"); container.prepend("<span id='vs-related-uber-container'>"+relatedHtml+"</span>"); } } $('body').append($('<iframe style="position: absolute; top: -1000px; left: -1000px; height: 1px; width: 1px;" src="http://network.videosurf.com/beacon/serp/' + VS_ACTIVE_SITE['slug'] + '"></iframe>')); attachSummaryEventHandlers(); } /** * Uses the link selector for the active type of page to get a list of video urls * It fetches the video info for these urls and then injects the summaries along with some custom css for this search engine **/ function enhanceSearchPageAjaxCallback(json, idsToCheck) { vs_log("Running search page ajax callback"); //dedupe videos to get rid of js conflicts later on //There's gotta be a better way to do this var seenVideos = ""; for(i = 0 ; i < json.videos.length; i++) { if(seenVideos.indexOf(json.videos[i].url) != -1) { Array.remove(json.videos, i); } else { seenVideos += json.videos[i].url; } } var parents = []; var prev = null; var index = 0; $(VS_ACTIVE_SITE['link_selector']+":not(.vs_enhanced)").each( function() { $(this).addClass("vs_enhanced"); for(i = 0 ; i < json.videos.length; i++) { var item = json.videos[i]; if(VS_ACTIVE_SITE['slug'] == "youtube" && VS_getPref("links_on_youtube_stay_there")) { item.url = item.source_url; } var searchStr = (idsToCheck && idsToCheck.indexOf(item.video_id) != -1) ? item.video_id : item.source_video_id; if(this.href.indexOf(searchStr) != -1) { var n = getSummaryReadyToInsert(item, true, index); switch(VS_ACTIVE_SITE['slug']) { case "google_search": var p = $(this).parents('li:first'); p.addClass("vs"); n.insertAfter(p); var pa = $(this).parents('table.ts:first'); parents[parents.length] = (pa && pa.length > 0) ? pa : p; //If it's in the videos module (Table case), do something else break; case "yahoo": if($(this).parents('div.res.indent:first')[0]) { n.addClass('indent'); } var p = $(this).parents('li:first'); parents[parents.length] = p; n.insertAfter(p); break; case "youtube": var p = $(this).parents('.video-entry:first'); p.find('.hd-video-logo').parent().remove(); n.find('.views').show().find('b').text(p.find('.video-view-count').text().split(' ')[0]); parents[parents.length] = p; n.insertAfter(p); break; case "friendfeed": $(this).parents('.title:first').append(n); break; case "twitter_pages": var p = $(this).parents(".entry-content:first"); if(!p || p.length == 0) { p = $(this).parents(".msgtxt:first"); } if($('#me_name').length == 1) { $(n).find('.summaryThumbnails').css({top:56,left:175,height:60}); } p.append(n); break; case "twitter_search": $(this).parents(".msgtxt:first").append(n); break; case "riot": $(this).parents('.searchResultBlock').html('').append(n); break; case "reddit": var sourceLink = $(this).attr('href'); $(this).parent().html(n).find('a').attr('href', sourceLink).end().parents('.thing').find('.thumbnail').remove(); break; case "digg": $(this).parent().html(n).parents('.news-body').css({ 'padding-left' : 60 }); break; } prev = n; index++; } } } ); for(i = 0 ; i < parents.length ; i++) { parents[i].hide(); } previousPageSignature = getPageSignature(); attachSummaryEventHandlers(); } /** * Take the json for a video from the server and generate the html for it **/ function getVideoHtml(item, needsSummary, index) { var video_with_summary_template = VS_getUrlContents("chrome://videosurf_enhanced/content/templates/video_with_summary.tmpl"); var summary_tile_template = VS_getUrlContents("chrome://videosurf_enhanced/content/templates/video_with_summary_tile.tmpl"); var title_length = 45; var desc_length = 60; switch(VS_ACTIVE_SITE['slug']) { case "twitter_pages": title_length = 30; desc_length = 50; break; case "twitter_search": title_length = 30; desc_length = 50; break; } context = { 'video_id': item.video_id, 'url': item.url, 'source_url': item.source_url, 'title': (item.title.length > title_length) ? item.title.substr(0, title_length)+"..." : item.title, 'description': (item.description.length > desc_length) ? item.description.substr(0, desc_length)+"..." : item.description, 'thumbnail': item.thumbnail, 'source': item.source, 'date_added_display': item.date_added_display || "—", 'length_display': item.length_display || "—", 'img_width': item.img_width, 'img_height': item.img_height, 'small_sprite_url': item.visual_video_summary.sprites['64x48'], 'large_sprite_url': item.visual_video_summary.sprites['160x120'], 'type': (needsSummary) ? "full" : "related", 'index': index } var frames = item.visual_video_summary.frames; item.sprite_order = []; item.summary_tiles = []; for(j = 0 ; j < frames.length ; j++) { //DO NOT use i, trust me item.sprite_order[item.sprite_order.length] = item.visual_video_summary.frames[j].sprite_position; if(needsSummary) { //Use a custom, smaller context to reduce number of regexp replacements in this inner loop if(VS_ACTIVE_SITE['slug'] == "youtube_video" && frames[j].url.indexOf("?t=") == -1) { frames[j].url += "&t="+frames[j].time; } frame_context = { 'video_id': item.video_id, 'url': frames[j].url, 'time_display': frames[j].time_display, 'small_sprite_url': item.visual_video_summary.sprites['64x48'], 'sprite_position': frames[j].sprite_position, 'img_width': 119, 'img_height': 73, 'type': (needsSummary) ? "full" : "related", 'index': index } item.summary_tiles[item.summary_tiles.length] = fillTemplate(summary_tile_template, frame_context); } } context.sprite_order = item.sprite_order.join(","); context.summary_tiles = item.summary_tiles.join(" "); context.content_type_class = ""; if(item.content_type && item.content_type.id == 4) { context.content_type_class = "fullepisode"; } if(item.content_type && item.content_type.id == 5) { context.content_type_class = "fullmovie"; } item_html = fillTemplate(video_with_summary_template, context); return item_html; } function getSummaryReadyToInsert(item, needsSummary, index) { item.img_width = 160; item.img_height = 120; item_html = getVideoHtml(item, needsSummary, index); var el = $("<div>").addClass('top-results').addClass("index_"+index).html(item_html); return el; } /** * Uses the link selector for the active type of page to get a list of video urls * It fetches the video info for these urls and then injects the summaries along with some custom css for this search engine **/ function enhanceSearchPage(relatedOnly, post_fn) { vs_log("Enhancing search page: Summaries ("+VS_ACTIVE_SITE_SUMMARIES_ENABLED+") - Related ("+VS_ACTIVE_SITE_RELATED_ENABLED+")"); //Inject the summaries if(VS_ACTIVE_SITE_SUMMARIES_ENABLED && !relatedOnly) { linkCount = 0; linksToCheck = ""; idsToCheck = ""; $(VS_ACTIVE_SITE['link_selector']+":not(.vs_enhanced)").each(function() { var videoSource = this.href; //To patch some bad assumptions if(VS_ACTIVE_SITE['slug'] == 'riot') { videoSource = 'http://' + $(this).find('img').attr('alt') } if(videoSource.indexOf("videosurf.com/video/") != -1) { var id = extractVideoSurfIdFromUrl(videoSource); if(idsToCheck.indexOf(id) == -1) { idsToCheck += id+","; } } else { if(linksToCheck.indexOf(videoSource) == -1 && linkCount <= MAX_LINKS_TO_CHECK && VS_isVideoPageUrl(videoSource)) { //dedupe linksToCheck += videoSource + "||"; linkCount++; } } }); var summarySize = 8; switch(VS_ACTIVE_SITE['slug']) { case "youtube" : summarySize = 7; break; case "twitter_pages" : summarySize = 5; break; case "twitter_search" : summarySize = 5; break; case "yahoo" : summarySize = 5; break; case "google_search" : summarySize = 7; break; case "riot" : summarySize = 8; break; case "reddit" : summarySize = 12; break; case "digg" : summarySize = 10; break; } if(linksToCheck || idsToCheck) { ajaxCallPost({ url : VS_AJAX_URL_ROOT + '/video_lookup/v1.2/', get : { client_id : API_CLIENT_ID, client_key : API_CLIENT_KEY, visual_summary_size : summarySize, vss : VS_ACTIVE_SITE['slug'] }, post : { urls : linksToCheck, ids : idsToCheck } }, function(json) { enhanceSearchPageAjaxCallback(json, idsToCheck); }); } } //Do the related videos if(VS_ACTIVE_SITE_RELATED_ENABLED) { var query = getCurrentSearchQuery(); if(query) { var safe_level = VS_getPref("safe_search_enabled") ? "1" : "2"; var num_per_page = VS_getPref("related_search_num_results"); ajaxUrl = VS_AJAX_URL_ROOT+"/video_search/v1.2/?query="+encodeURIComponent(query)+"&num_per_page="+num_per_page+"&safe_level="+safe_level+"&client_id="+API_CLIENT_ID+"&client_key="+API_CLIENT_KEY+"&vss="+VS_ACTIVE_SITE['slug']; if(VS_ACTIVE_SITE['slug'] == "youtube" && VS_getPref("exclude_youtube_results_on_youtube_search")) { ajaxUrl += "&refinement_providers=-2"; //exclude youtube results on youtube's search page } ajaxCall(ajaxUrl, enhanceSearchPageRelatedAjaxCallback); } } watchForUrlChange((post_fn) ? post_fn : enhanceSearchPage); } //enhanceSearchPage function attachSummaryEventHandlers() { index_AttachEventHandlers(); } //Used to power related videos function getCurrentSearchQuery() { var query = null; switch(VS_ACTIVE_SITE['slug']) { case "google_search": var input = $('input[name=q]:first'); if(input && input.length > 0) { query = input.get(0).value; } break; case "yahoo": if($('#yschsp') && $('#yschsp').length > 0) { query = $('#yschsp').get(0).value; } break; case "youtube": if(document.getElementById('masthead-search-term')) { query = $('#masthead-search-term').get(0).value; } break; case "twitter_search": if(document.getElementById('searchBox')) { query = document.getElementById('searchBox').value; } break; case "bing": if(document.getElementById('sb_form_q')) { query = document.getElementById('sb_form_q').value; } break; case "riot": if(document.getElementById('searchQueryInput')) { query = document.getElementById('searchQueryInput').value; } break; } vs_log("Current page search query is: "+query); return query; } //getCurrentSearchQuery function vs_LoadCSS() { if(VS_IS_VIDEO_PAGE || VS_IS_SPECIAL_PAGE) { VS_addStyle( VS_getUrlContents("chrome://videosurf_enhanced/content/css/reset-min.css") + VS_getUrlContents("chrome://videosurf_enhanced/content/css/relatedTab.css") + VS_getUrlContents("chrome://videosurf_enhanced/content/css/genericVideoSummary.css") + VS_getUrlContents("chrome://videosurf_enhanced/content/css/genericVideoSummary_NonVisuallyIndexed.css") + VS_getUrlContents("chrome://videosurf_enhanced/content/css/genericVideoSummary_Sprite.css") + VS_getUrlContents("chrome://videosurf_enhanced/content/css/genericVideoSummary_Tile.css") + VS_getUrlContents("chrome://videosurf_enhanced/content/css/genericVideoSummary_SmallTile.css") + VS_getUrlContents("chrome://videosurf_enhanced/content/css/genericVideoSummary_Vertical.css") ); vs_log('Loaded Generic CSS'); } if(VS_IS_SPECIAL_PAGE) { VS_addStyle( VS_getUrlContents("chrome://videosurf_enhanced/content/css/"+VS_ACTIVE_SITE['slug']+"_custom.css") + VS_getUrlContents("chrome://videosurf_enhanced/content/css/post.css") ); vs_log('Special CSS'); } } function vs_init() { if(!VS_getPref('extension_enabled')) { //If the extension was turned off via the icon, don't do anything return; } VS_LOGGING_ACTIVE = VS_getPref('logging_active'); VS_AJAX_URL_ROOT = VS_getPref('ajax_url_root'); jQuery.each($('embed'), function(index, element) { if($(element).attr('wmode') != 'transparent') { var embedHTML = $(element).attr('wmode', 'transparent').parent().html(); vs_log(embedHTML, true); $(element).replaceWith($(embedHTML)); } }); if(VS_IS_VIDEO_PAGE) { vs_log("Is video page: " + VS_IS_VIDEO_PAGE, true); vs_log("Page location: " + document.location.href, true); if(!VS_IS_SPECIAL_PAGE) { VS_ACTIVE_SITE = []; } ajaxUrl = VS_AJAX_URL_ROOT + "/video_lookup/v1.2/?include_videos_without_summaries=true&visual_summary_size=11&client_id=" + API_CLIENT_ID + "&client_key=" + API_CLIENT_KEY + "&vss=generic_video&urls=" + encodeURIComponent(document.location.href); ajaxCall(ajaxUrl, function(json) { if(json.videos.length > 0 && json.videos[0].video_id) { vs_log(json.videos[0], true); vs_log('Found Videosurf ID: ' + json.videos[0].video_id); vs_log('Create tab with Videosurf ID and call getVideoPageRelatedVideos'); videosurftab_InitializeTab(json); if(VS_ACTIVE_SITE['slug'] == "youtube_video") { enhanceYoutubeVideoAjaxCallback(json); } } }); } if(VS_IS_SPECIAL_PAGE) { vs_log("Is special page - " + VS_ACTIVE_SITE + " - " + VS_AJAX_URL_ROOT); VS_ACTIVE_SITE = VS_ACTIVE_SITE.split("||"); //This string is defined in compiler.js VS_ACTIVE_SITE['slug'] = VS_ACTIVE_SITE[0]; VS_ACTIVE_SITE['title'] = VS_ACTIVE_SITE[1]; VS_ACTIVE_SITE['regexp'] = VS_ACTIVE_SITE[2]; VS_ACTIVE_SITE['link_selector'] = VS_ACTIVE_SITE[3]; switch(VS_ACTIVE_SITE['slug']) { case "google_search" : enhanceGoogleSearch(); break; case "twitter_pages" : enhanceTwitter(); break; case "twitter_search" : enhanceTwitter(); break; case "youtube_video" : /*enhanceYoutubeVideo();*/ break; //handled by the ajax call from the tab lookup now default : enhanceSearchPage(); break; } } vs_LoadCSS(); } /**************************************************************************************************************************/ var videosurf_Tab_TabHeight = 156; var videosurf_Container_Width = 338; var videosurf_Container_Padding = 11; function videosurftab_InitializeTab(json) { var videoID = json.videos[0].video_id; //Create related tab, attach click handler, and append tab to the body of the current page $('body').append($( '<div id="videosurfRelated" class="videosurfRelated">' + ' <div id="videosurfRelatedContainer">' + ' <div id="videosurfRelatedContainerHeader">' + ' <div id="videosurfRelatedContainerHeaderClose"></div>' + ' </div>' + ' <div id="videosurfRelatedContainerVideos">' + ' <div id="videosurfRelatedContainerTextHeader">VideoSurf Related Videos</div>' + ' <a id="videosurfRelatedContainerWatchOnVideosurf">Watch This Video on VideoSurf</a>' + ' <div id="videosurfRelatedVideosContainerPeople">' + ' <div id="videosurfRelatedVideosContainerPeopleHeader">People Who Liked This Also Liked...</div>' + ' <div id="videosurfRelatedVideosContainerPeopleVideos" class="vertical"></div>' + ' <div id="videosurfRelatedVideosContainerPeopleMore">Show More</div>' + ' </div>' + ' <div id="videosurfRelatedVideosContainerRelated">' + ' <div id="videosurfRelatedVideosContainerRelatedHeader">Related Videos</div>' + ' <div id="videosurfRelatedVideosContainerRelatedVideos" class="vertical"></div>' + ' </div>' + ' <div id="videosurfRelatedVideosContainerRelatedNoneFoundError">' + ' Sorry, no related videos were found. <br>Please try again later. <br><br><img id="videosurfRelatedVideosContainerRelatedNoneFoundErrorImg"> ' + ' </div>' + ' </div>' + ' </div>' + '</div>' + '<div id="videosurfRelatedTab" class="videosurfRelatedTabClosed">' + ' <div id="videosurfRelatedTabContainer">' + ' <img id="videosurfRelatedContainerLoading" width="20" height="20" />' + ' </div>' + '</div>' )); //Apply page specific styling to above template and load in cached images $('#videosurfRelated').css({ background : 'url(' + VS_LOCAL_IMAGES['container-background'] + ')', left : -videosurf_Container_Width, width : videosurf_Container_Width }); $('#videosurfRelatedContainer').css({ background : 'url(' + VS_LOCAL_IMAGES['container-background'] + ')', width : videosurf_Container_Width - videosurf_Container_Padding }); $('#videosurfRelatedContainerHeader').css({ background : 'url(' + VS_LOCAL_IMAGES['container-header'] + ')', width : videosurf_Container_Width - videosurf_Container_Padding }); $('#videosurfRelatedVideosContainerRelatedNoneFoundErrorImg').attr({ src : "http://rexee-00.vo.llnwd.net/d1/application/images/error_bear.gif" }); $('#videosurfRelatedContainerHeaderClose').click(function() { videosurftab_HideRelated(); }); $('#videosurfRelatedContainerVideos').css({ width : videosurf_Container_Width - videosurf_Container_Padding, height : videosurftab_RelatedVideoContainerHeight() }); if(!json.videos[0].should_open_externally) { $('#videosurfRelatedContainerWatchOnVideosurf').attr( 'href', json.videos[0].url ).css({ display : 'block', background : 'url(' + VS_LOCAL_IMAGES['arrow-right'] + ') no-repeat center right', }); } $('#videosurfRelatedVideosContainerPeopleMore').css({ background : 'url(' + VS_LOCAL_IMAGES['arrow-down'] + ') no-repeat center right', }); $('#videosurfRelatedTab').css({ background : 'url(' + VS_LOCAL_IMAGES['tab-closed'] + ')', height : videosurf_Tab_TabHeight, top : videosurftab_GetTabLocation() }).addClass('closed'); $('#videosurfRelatedTabContainer').css({ height : videosurf_Tab_TabHeight }); $('#videosurfRelatedContainerLoading').attr({ src : VS_LOCAL_IMAGES['tab-loading-feedback'] }); //Attach an event handler to adjust tab tab location on window resize $(window).resize(function() { $('#videosurfRelatedTab').css({ top : videosurftab_GetTabLocation() }); $('#videosurfRelatedContainerVideos').css({ height : videosurftab_RelatedVideoContainerHeight() }); }); //Show tab $('#videosurfRelatedTab').click(function() { if($('#videosurfRelatedTab').hasClass('videosurfRelatedTabClosed')) { $('#videosurfRelatedTab').css({ background : 'url(' + VS_LOCAL_IMAGES['tab-loading'] + ')' }); if(!VS_CACHED_RELATED_VIDEOS[videoID]) { videosurftab_GetRelatedVideos(videoID); } else { videosurftab_ProcessRelatedVideos(videoID); } } else { videosurftab_HideRelated(); } }).fadeIn(); } function videosurftab_GetTabLocation() { var newTop = ($(window).height() - videosurf_Tab_TabHeight) / 2; return newTop <= 0 ? 0 : newTop; } function videosurftab_RelatedVideoContainerHeight() { return $(window).height() - $('#videosurfRelatedContainerHeader').height(); } function videosurftab_ShowRelated() { $('#videosurfRelatedTab').removeClass('videosurfRelatedTabClosed').addClass('videosurfRelatedTabOpen'); $('#videosurfRelatedTab').animate({ left : videosurf_Container_Width - videosurf_Container_Padding }); $('#videosurfRelated').animate({ left : 0 }); } function videosurftab_HideRelated() { $('#videosurfRelatedTab').removeClass('videosurfRelatedTabOpen').addClass('videosurfRelatedTabClosed'); $('#videosurfRelatedTab').animate({ left : 0 }); $('#videosurfRelated').animate( { left : -videosurf_Container_Width }, { complete : function() { $('#videosurfRelatedTab').css({background : 'url(' + VS_LOCAL_IMAGES['tab-closed'] + ')'}) } } ); } function videosurftab_GetRelatedVideos(videoID) { $('#videosurfRelatedContainerLoading').show(); ajaxUrl = VS_AJAX_URL_ROOT + "/related_videos/v1.2/?visual_summary_size=10&client_id=" + API_CLIENT_ID + "&client_key=" + API_CLIENT_KEY + "&vss=generic_video&id=" + videoID; ajaxCall(ajaxUrl, function(json) { vs_log(json, true); VS_CACHED_RELATED_VIDEOS[videoID] = json; $('body').append($('<iframe style="position: absolute; top: -1000px; left: -1000px; height: 1px; width: 1px;" src="http://network.videosurf.com/beacon/video"></iframe>')); videosurftab_ProcessRelatedVideos(videoID); }); } function videosurftab_ProcessRelatedVideos(videoID) { var behavioralRelated = VS_CACHED_RELATED_VIDEOS[videoID]['People who liked this video also liked']; var regularRelated = VS_CACHED_RELATED_VIDEOS[videoID]['Related Videos']; if(behavioralRelated) { var relatedVideoHTML = jQuery.map(behavioralRelated, function(video, index) { video.img_width = 119; video.img_height = 73; return getVideoHtml(video, false, index); }).join(''); if(relatedVideoHTML) { $('#videosurfRelatedVideosContainerPeople').show(); var videosToHide = $('#videosurfRelatedVideosContainerPeopleVideos').html( relatedVideoHTML ).find( '.summaryContainer:gt(3)' ); if(videosToHide.length > 0) { videosToHide.hide(); $('#videosurfRelatedVideosContainerPeopleMore').show().toggle( function() { videosToHide.show(); $(this).css({ background : 'url(' + VS_LOCAL_IMAGES['arrow-up'] + ') no-repeat center right', }).text( 'Show Less' ); }, function() { videosToHide.hide(); $(this).css({ background : 'url(' + VS_LOCAL_IMAGES['arrow-down'] + ') no-repeat center right', }).text( 'Show More' ); } ); } } } if(regularRelated) { var relatedVideoHTML = jQuery.map(regularRelated, function(video, index) { video.img_width = 119; video.img_height = 73; return getVideoHtml(video, false, index); }).join(''); if(relatedVideoHTML) { $('#videosurfRelatedVideosContainerRelated').show(); $('#videosurfRelatedVideosContainerRelatedVideos').html(relatedVideoHTML); } } if(!behavioralRelated && !regularRelated) { $('#videosurfRelatedVideosContainerRelatedNoneFoundError').show(); } attachSummaryEventHandlers(); $('#videosurfRelatedContainerLoading').hide(); videosurftab_ShowRelated(); } /**************************************************************************************************************************/ /** * Take a template string that has variables inside with a {variable} format and substitutes all the items * in the context dictionary into the string, returning the result * s = '<a href="{url}">{title}</a>'; fillTemplate(s, {'url': 'http://whatever.com', 'title': 'this is the link title'}); **/ function fillTemplate(templateString, context) { for(key in context) { s = "{"+key+"}"; templateString = templateString.replace(new RegExp(s,"g"), context[key]); } return templateString; } /** * Utility function to make ajax calls. Assumes json response. **/ function ajaxCall(url, callback, additionalVar) { vs_log("Doing GET ajax call to: "+url); VS_xmlhttpRequest({ method: 'GET', url: url, headers: { 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey - VSFFEXT', 'Accept': 'application/atom+xml,application/xml,text/json,text/html,application/javascript' }, onload: function(resp) { var json = evalJson(resp.responseText); json.original_ajax_url = url; callback(json, additionalVar); } }); } function ajaxCallPost(parameters, callback, additionalVar) { vs_log("Doing POST ajax call to: "+ parameters.url + '?' + jQuery.param(parameters.get) + ' POST: ' + jQuery.param(parameters.post)); VS_xmlhttpRequest({ method : 'POST', url : parameters.url + '?' + jQuery.param(parameters.get), headers : { 'User-Agent' : 'Mozilla/4.0 (compatible) Greasemonkey - VSFFEXT', 'Accept' : 'application/atom+xml,application/xml,text/json,text/html,application/javascript', 'Content-Type' : 'application/x-www-form-urlencoded' }, data : jQuery.param(parameters.post), onload : function(resp) { var json = evalJson(resp.responseText); json.original_ajax_url = parameters.url + '?' + jQuery.param(parameters.get); callback(json, additionalVar); } }); } function evalJson(jsonString) { try { return JSON.parse(jsonString); } catch(e) { vs_log('Whoops, there was an error evaluating the json from the server:'+txt) } } /** * Log something to the Firebug console if it's present and logging is active in preferences (off by default, hidden option) **/ function vs_log(item, clean) { if(VS_LOGGING_ACTIVE) { if(!clean) { item = "VS FFEXT:"+item; } //Pass true in for clean if you want to log an object or html element that needs further inspection and not a regular string try { unsafeWindow.console.log(item); } catch(e) { } } } // Array Remove - By John Resig (MIT Licensed) Array.remove = function(array, from, to) { var rest = array.slice((to || from) + 1 || array.length); array.length = from < 0 ? array.length + from : from; return array.push.apply(array, rest); }; function addCommas(nStr) { nStr += ''; x = nStr.split('.'); x1 = x[0]; x2 = x.length > 1 ? '.' + x[1] : ''; var rgx = /(\d+)(\d{3})/; while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ',' + '$2'); } return x1 + x2; } function cleanQuery(str) { return encodeURIComponent(str.replace(/^ +/, '').replace(/ +$/, '')).replace(/%20/g, "+"); //special case spaces to be + instead of the super ugly %20 } function extractVideoSurfIdFromUrl(url) { var re = new RegExp("videosurf.com\/video\/(.*)-([0-9]*)", "i"); var matches = url.match(re); if(matches && matches.length > 1) { return matches[2]; } return null; } //GO! vs_init();