OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Global variable containing the query we'd like to pass to Flickr. In this | 6 * Get the current URL. |
7 * case, kittens! | |
8 * | 7 * |
9 * @type {string} | 8 * @param {function(string)} callback - called when the URL of the current tab |
| 9 * is found. |
| 10 **/ |
| 11 function getCurrentTabUrl(callback) { |
| 12 // Query filter to be passed to chrome.tabs.query - see |
| 13 // https://developer.chrome.com/extensions/tabs#method-query |
| 14 var queryInfo = { |
| 15 active: true, |
| 16 currentWindow: true |
| 17 }; |
| 18 |
| 19 chrome.tabs.query(queryInfo, function(tabs) { |
| 20 // chrome.tabs.query invokes the callback with a list of tabs that match the |
| 21 // query. When the popup is opened, there is certainly a window and at least |
| 22 // one tab, so we can safely assume that |tabs| is a non-empty array. |
| 23 // A window can only have one active tab at a time, so the array consists of |
| 24 // exactly one tab. |
| 25 var tab = tabs[0]; |
| 26 |
| 27 // A tab is a plain object that provides information about the tab. |
| 28 // See https://developer.chrome.com/extensions/tabs#type-Tab |
| 29 var url = tab.url; |
| 30 |
| 31 // tab.url is only available if the "activeTab" permission is declared. |
| 32 // If you want to see the URL of other tabs (e.g. after removing active:true |
| 33 // from |queryInfo|), then the "tabs" permission is required to see their |
| 34 // "url" properties. |
| 35 console.assert(typeof url == 'string', 'tab.url should be a string'); |
| 36 |
| 37 callback(url); |
| 38 }); |
| 39 |
| 40 // Most methods of the Chrome extension APIs are asynchronous. This means that |
| 41 // you CANNOT do something like this: |
| 42 // |
| 43 // var url; |
| 44 // chrome.tabs.query(queryInfo, function(tabs) { |
| 45 // url = tabs[0].url; |
| 46 // }); |
| 47 // alert(url); // Shows "undefined", because chrome.tabs.query is async. |
| 48 } |
| 49 |
| 50 /** |
| 51 * @param {string} searchTerm - Search term for Google Image search. |
| 52 * @param {function(string,number,number)} callback - Called when an image has |
| 53 * been found. The callback gets the URL, width and height of the image. |
| 54 * @param {function(string)} errorCallback - Called when the image is not found. |
| 55 * The callback gets a string that describes the failure reason. |
10 */ | 56 */ |
11 var QUERY = 'kittens'; | 57 function getImageUrl(searchTerm, callback, errorCallback) { |
| 58 // Google image search - 100 searches per day. |
| 59 // https://developers.google.com/image-search/ |
| 60 var searchUrl = 'https://ajax.googleapis.com/ajax/services/search/images' + |
| 61 '?v=1.0&q=' + encodeURIComponent(searchTerm); |
| 62 var x = new XMLHttpRequest(); |
| 63 x.open('GET', searchUrl); |
| 64 // The Google image search API responds with JSON, so let Chrome parse it. |
| 65 x.responseType = 'json'; |
| 66 x.onload = function() { |
| 67 // Parse and process the response from Google Image Search. |
| 68 var response = x.response; |
| 69 if (!response || !response.responseData || !response.responseData.results || |
| 70 response.responseData.results.length === 0) { |
| 71 errorCallback('No response from Google Image search!'); |
| 72 return; |
| 73 } |
| 74 var firstResult = response.responseData.results[0]; |
| 75 // Take the thumbnail instead of the full image to get an approximately |
| 76 // consistent image size. |
| 77 var imageUrl = firstResult.tbUrl; |
| 78 var width = parseInt(firstResult.tbWidth); |
| 79 var height = parseInt(firstResult.tbHeight); |
| 80 console.assert( |
| 81 typeof imageUrl == 'string' && !isNaN(width) && !isNaN(height), |
| 82 'Unexpected respose from the Google Image Search API!'); |
| 83 callback(imageUrl, width, height); |
| 84 }; |
| 85 x.onerror = function() { |
| 86 errorCallback('Network error.'); |
| 87 }; |
| 88 x.send(); |
| 89 } |
12 | 90 |
13 var kittenGenerator = { | 91 function renderStatus(statusText) { |
14 /** | 92 document.getElementById('status').textContent = statusText; |
15 * Flickr URL that will give us lots and lots of whatever we're looking for. | 93 } |
16 * | |
17 * See http://www.flickr.com/services/api/flickr.photos.search.html for | |
18 * details about the construction of this URL. | |
19 * | |
20 * @type {string} | |
21 * @private | |
22 */ | |
23 searchOnFlickr_: 'https://secure.flickr.com/services/rest/?' + | |
24 'method=flickr.photos.search&' + | |
25 'api_key=90485e931f687a9b9c2a66bf58a3861a&' + | |
26 'text=' + encodeURIComponent(QUERY) + '&' + | |
27 'safe_search=1&' + | |
28 'content_type=1&' + | |
29 'sort=interestingness-desc&' + | |
30 'per_page=20', | |
31 | 94 |
32 /** | 95 document.addEventListener('DOMContentLoaded', function() { |
33 * Sends an XHR GET request to grab photos of lots and lots of kittens. The | 96 getCurrentTabUrl(function(url) { |
34 * XHR's 'onload' event is hooks up to the 'showPhotos_' method. | 97 // Put the image URL in Google search. |
35 * | 98 renderStatus('Performing Google Image search for ' + url); |
36 * @public | |
37 */ | |
38 requestKittens: function() { | |
39 var req = new XMLHttpRequest(); | |
40 req.open("GET", this.searchOnFlickr_, true); | |
41 req.onload = this.showPhotos_.bind(this); | |
42 req.send(null); | |
43 }, | |
44 | 99 |
45 /** | 100 getImageUrl(url, function(imageUrl, width, height) { |
46 * Handle the 'onload' event of our kitten XHR request, generated in | |
47 * 'requestKittens', by generating 'img' elements, and stuffing them into | |
48 * the document for display. | |
49 * | |
50 * @param {ProgressEvent} e The XHR ProgressEvent. | |
51 * @private | |
52 */ | |
53 showPhotos_: function (e) { | |
54 var kittens = e.target.responseXML.querySelectorAll('photo'); | |
55 for (var i = 0; i < kittens.length; i++) { | |
56 var img = document.createElement('img'); | |
57 img.src = this.constructKittenURL_(kittens[i]); | |
58 img.setAttribute('alt', kittens[i].getAttribute('title')); | |
59 document.body.appendChild(img); | |
60 } | |
61 }, | |
62 | 101 |
63 /** | 102 renderStatus('Search term: ' + url + '\n' + |
64 * Given a photo, construct a URL using the method outlined at | 103 'Google image search result: ' + imageUrl); |
65 * http://www.flickr.com/services/api/misc.urlKittenl | 104 var imageResult = document.getElementById('image-result'); |
66 * | 105 // Explicitly set the width/height to minimize the number of reflows. For |
67 * @param {DOMElement} A kitten. | 106 // a single image, this does not matter, but if you're going to embed |
68 * @return {string} The kitten's URL. | 107 // multiple external images in your page, then the absence of width/height |
69 * @private | 108 // attributes causes the popup to resize multiple times. |
70 */ | 109 imageResult.width = width; |
71 constructKittenURL_: function (photo) { | 110 imageResult.height = height; |
72 return "http://farm" + photo.getAttribute("farm") + | 111 imageResult.src = imageUrl; |
73 ".static.flickr.com/" + photo.getAttribute("server") + | 112 imageResult.hidden = false; |
74 "/" + photo.getAttribute("id") + | |
75 "_" + photo.getAttribute("secret") + | |
76 "_s.jpg"; | |
77 } | |
78 }; | |
79 | 113 |
80 // Run our kitten generation script as soon as the document's DOM is ready. | 114 }, function(errorMessage) { |
81 document.addEventListener('DOMContentLoaded', function () { | 115 renderStatus('Cannot display image. ' + errorMessage); |
82 kittenGenerator.requestKittens(); | 116 }); |
| 117 }); |
83 }); | 118 }); |
OLD | NEW |