diff options
6 files changed, 342 insertions, 0 deletions
diff --git a/chrome/test/data/extensions/samples/youtube_popular/latest_yt_popular_video.html b/chrome/test/data/extensions/samples/youtube_popular/latest_yt_popular_video.html new file mode 100644 index 0000000..8299f15 --- /dev/null +++ b/chrome/test/data/extensions/samples/youtube_popular/latest_yt_popular_video.html @@ -0,0 +1,14 @@ +<html> +<head> +<link rel="stylesheet" type="text/css" href="styles.css"> +<script type="text/javascript" src="map.js"></script> +<script type="text/javascript" src="manage_video.js"></script> +</head> +<body onload="start()" onclick="showYTLatest()"> + <div> + <img src="youtube.png" style="width:24; height:24"> + <span>Popular on YouTube<span style="display: inline-block;" + id="newCount"></span> + </div> +</body> +</html> diff --git a/chrome/test/data/extensions/samples/youtube_popular/manage_video.js b/chrome/test/data/extensions/samples/youtube_popular/manage_video.js new file mode 100644 index 0000000..3129cc4 --- /dev/null +++ b/chrome/test/data/extensions/samples/youtube_popular/manage_video.js @@ -0,0 +1,176 @@ +// Copyright 2009 Google Inc. All Rights Reserved. + +/** + * @fileoverview This file contains js that continues collect Popular video + * from YouTube and displays them when needed. + * @author lzheng@chromium.com (Lei Zheng) + */ + +const YT_POLL_INTERVAL = 1000 * 600; // 10 minute +var json_url_popular = 'http://gdata.youtube.com/feeds/api/standardfeeds/' + + 'most_popular?time=today&alt=json-in-script&format=5&max-results=50&' + + 'callback=processVideos'; + +// This holds all videos when browser starts. +var YT_existing_video_map = new Map(); +// This holds all popular videos after browser starts. +var YT_latest_video_map = new Map(); + +var YT_reqCount = 0; + +const YT_MAX_VIDEOS = 500; + +var YT_start_time = Date(); + +/** + * Class that holds video information that will be displayed. + * @param {string} video_url Video Url from Gdata for a given video. + * @param {string} thumb_url The url to access thumbnails. + * @param {string} title Title of the video. + * @param {string} description The description of the video. + */ +function videoEntry(video_url, thumb_url, title, description) { + this.video_url = video_url; + this.thumb_url = thumb_url; + this.title = title; + this.description = description; + this.time = Date(); +} + +/** + * Dump what's in the video_map to html. + * @param {Map} video_map The Map that contains video information. + * @return {string} The html output. + */ +function outputMap(video_map) { + var keys = video_map.keys() || []; + var output = '<table>'; + for (var i = 0; i < keys.length; ++i) { + console.log(keys[i]); + var title = video_map.get(keys[i]).title; + var playerUrl = video_map.get(keys[i]).video_url; + var thumbnailUrl = video_map.get(keys[i]).thumb_url; + var time = video_map.get(keys[i]).time; + var description = video_map.get(keys[i]).description; + if (i % 3 == 0) { + if (i != 0) { + output += '</tr>'; + } + output += '<tr>'; + } + output += '<td><a href = \' ' + playerUrl + '\' target=\'_black\'\'>' + + '<img src="'+ thumbnailUrl + '" width="130" height="97"/><br />' + + '<span class="titlec">' + title + '...</span><br /></a><br />' + + '<font size=2>' + description + '... </font></td>'; + } + output += '</tr></table>'; + return output; +} + +/** + * Display popular videos when and after browser started. + */ +function showYTLatest() { + var new_win = window.open(); + var html = ['<html><head><title>New Popular YouTube Videos</title><style>', + '.titlec { font-size: small;}ul.videos li { float: left; ', + 'width: 10em; margin-bottom: 1em;}ul.videos{ ', + 'margin-bottom: 1em; padding-left : 0em; margin-left: 0em; ', + 'list-style: none;}</style></head><body>']; + console.log('show my videos total: ' + YT_latest_video_map.size()); + html.push('<div id="videos"><font size="5" color="green">', + YT_latest_video_map.size(), + '</font> new popular videos after you start', + ' your browser at: <font size="1">', YT_start_time, + '</font><ul>'); + + html.push(outputMap(YT_latest_video_map)); + html.push('</ul></div>'); + + html.push('<div id="videos"><font size="5" color="green">', + YT_existing_video_map.size(), + '</font> popular videos when you start your browser at: ', + '<font size="1">', YT_start_time, '</font><ul>'); + html.push(outputMap(YT_existing_video_map)); + html.push('</ul></div>'); + html.push('</body></html>'); + console.log('html: ' + html.join('')); + new_win.document.write(html.join('')); +} + +/** + * Callback function for GDataJson and schedule the next gdata call. + * Extract data from Gdata and store them if needed. + * @param {Gdata} gdata Gdata from YouTube. + */ +function processVideos(gdata) { + var feed = gdata.feed; + var entries = feed.entry || []; + console.log('process videos total: ' + entries.length + + 'reqCount=' + YT_reqCount); + var first_run = false; + + if (YT_existing_video_map.size() == 0) { + first_run = true; + } + for (var i = 0; i < entries.length; i++) { + var title = entries[i].title.$t.substr(0,20); + var thumb_url = entries[i].media$group.media$thumbnail[0].url; + var video_url = entries[i].media$group.media$player[0].url; + var description = + entries[i].media$group.media$description.$t.substr(0, 100); + if (first_run == true) { + YT_existing_video_map.insert( + title, + new videoEntry(video_url, thumb_url, title, description)); + console.log(title); + } else { + if (YT_existing_video_map.get(title) == null) { + // This is new, keep it + if (YT_latest_video_map.size() < YT_MAX_VIDEOS) { + YT_latest_video_map.insert( + title, + new videoEntry(video_url, thumb_url, title, description)); + } else { + console.log('Too many new videos'); + } + } + } + } + + // Schedule the next call + document.getElementById('newCount').innerHTML = '(was ' + + YT_existing_video_map.size() + ', new ' + + YT_latest_video_map.size() + ')'; + var gdata_json = document.getElementById('gdata_json'); + + // cleanup the json script inserted in fetchJSON + document.getElementsByTagName('body')[0].removeChild(gdata_json); + scheduleRequest(); +} + +/** + * Fetch gdata via JSON. + */ +function fetchJSON() { + var scr = document.createElement('script'); + scr.setAttribute('language', 'JavaScript'); + scr.setAttribute('src', json_url_popular + '&reqCount=' + YT_reqCount); + scr.setAttribute('id', 'gdata_json'); + ++YT_reqCount; + document.getElementsByTagName('body')[0].appendChild(scr); +} + +/** + * Where the extension starts. + */ +function start() { + window.setTimeout(fetchJSON, 0); +} + +/** + * Schedule the fetchJSON call. + */ +function scheduleRequest() { + window.setTimeout(fetchJSON, YT_POLL_INTERVAL); +} diff --git a/chrome/test/data/extensions/samples/youtube_popular/manifest.json b/chrome/test/data/extensions/samples/youtube_popular/manifest.json new file mode 100644 index 0000000..1f2783d --- /dev/null +++ b/chrome/test/data/extensions/samples/youtube_popular/manifest.json @@ -0,0 +1,11 @@ +{ + "name": "What's new?", + "version": "0.2", + "description": "Track latest YouTube Videos", + "permissions": [ + "http://www.youtube.com/*" + ], + "toolstrips": [ + "latest_yt_popular_video.html" + ] +} diff --git a/chrome/test/data/extensions/samples/youtube_popular/map.js b/chrome/test/data/extensions/samples/youtube_popular/map.js new file mode 100644 index 0000000..bfaaa1c --- /dev/null +++ b/chrome/test/data/extensions/samples/youtube_popular/map.js @@ -0,0 +1,126 @@ +/** + * @fileoverview This file contains js create a helper Map object + * @author lzheng@chromium.com (Lei Zheng) + */ + +/** + * A Map class that implemeted using two arrays. + */ +Map = function() { + /** + * Array that hold all Keys. + * @private + */ + this.keysArray = []; // Keys + /** + * Array that hold all values. + * @private + */ + this.valsArray = []; // Values + + /** + * Index of where to insert new entries in key and value array. + * @private + */ + this.mapIndex_ = 0; +}; + +/** + * Insert a key, value pair to map. + * @param {object} key An object that supports "==". + * @param {object} value The entry in map. + */ +Map.prototype.insert = function(key, value) { + var index = this.findIndex(key); + if (index == -1) { + this.keysArray[this.mapIndex_] = key; + this.valsArray[this.mapIndex_] = value; + ++this.mapIndex_; + } + else { + this.valsArray[index] = value; + } +}; + +/** + * Get the entry associated with a key. + * @param {object} key for the entry. + * @return {object} The entry in map. + */ +Map.prototype.keys = function() { + return this.keysArray; +}; + +/** + * Get the entry associated with a key. + * @param {object} key for the entry. + * @return {object} The entry in map. + */ +Map.prototype.get = function(key) { + var index = this.findIndex(key); + if (index != -1) { + return this.valsArray[index]; + } + return null; +}; + + + +/** + * Remove an entry associated with a key. + * @param {object} key for the entry. + */ +Map.prototype.remove = function(key) { + var index = this.findIndex(key); + if (index != -1) { + this.keysArray = this.removeFromArray(keysArray, index); + this.valsArray = this.removeFromAarry(valsArray, index); + --this.mapIndex_; + } + return; +}; + +/** + * Get the total entries in the map. + * @return {int} The total number of entries. + */ +Map.prototype.size = function() { + return this.mapIndex_; +}; + +/** + * Clear up everything in the map. + */ +Map.clear = function() { + this.mapIndex_ = 0; + this.keysArray = []; + this.valsArray = []; +}; + +/** + * Find the index associated with a key. + * @private + * @param {object} key for the entry. + * @return {int} The index of this entry. + */ +Map.prototype.findIndex = function(key) { + var result = -1; + for (var i = 0; i < this.keysArray.length; i++) { + if (this.keysArray[i] == key) { + result = i; + break; + } + } + return result; +}; + +/** + * @private + * Remove an entry from the map. + * @param {int} index The index of the entry. + */ +Map.prototype.removeAt = function(array, index) { + var first_half = array.slice(0, index); + var second_half = array.slice(index + 1); + return first_half.concat(second_half); +} diff --git a/chrome/test/data/extensions/samples/youtube_popular/styles.css b/chrome/test/data/extensions/samples/youtube_popular/styles.css new file mode 100644 index 0000000..d84c626 --- /dev/null +++ b/chrome/test/data/extensions/samples/youtube_popular/styles.css @@ -0,0 +1,15 @@ +.titlec { + font-size: small; +} +ul.videos li { + float: left; + width: 10em; + margin-bottom: 1em; +} +ul.videos +{ + margin-bottom: 1em; + padding-left : 0em; + margin-left: 0em; + list-style: none; +} diff --git a/chrome/test/data/extensions/samples/youtube_popular/youtube.png b/chrome/test/data/extensions/samples/youtube_popular/youtube.png Binary files differnew file mode 100644 index 0000000..c7d988a --- /dev/null +++ b/chrome/test/data/extensions/samples/youtube_popular/youtube.png |