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 callback(imageUrl, width, height); | |
not at google - send to devlin
2014/11/18 16:09:37
You might want to verify imageUrl, and catch width
robwu
2014/11/18 16:13:15
In principle I agree with verifying external data,
not at google - send to devlin
2014/11/18 16:15:20
Frozen APIs are well and good, but bugs and issues
robwu
2014/11/26 17:51:04
Done.
| |
81 }; | |
82 x.onerror = function() { | |
83 errorCallback('Network error.'); | |
84 }; | |
85 x.send(); | |
86 } | |
12 | 87 |
13 var kittenGenerator = { | 88 function renderStatus(statusText) { |
14 /** | 89 document.getElementById('status').textContent = statusText; |
15 * Flickr URL that will give us lots and lots of whatever we're looking for. | 90 } |
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 | 91 |
32 /** | 92 document.addEventListener('DOMContentLoaded', function() { |
33 * Sends an XHR GET request to grab photos of lots and lots of kittens. The | 93 getCurrentTabUrl(function(url) { |
34 * XHR's 'onload' event is hooks up to the 'showPhotos_' method. | 94 // Put the image URL in Google search. |
35 * | 95 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 | 96 |
45 /** | 97 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 | 98 |
63 /** | 99 renderStatus('Search term: ' + url + '\n' + |
64 * Given a photo, construct a URL using the method outlined at | 100 'Google image search result: ' + imageUrl); |
65 * http://www.flickr.com/services/api/misc.urlKittenl | 101 var imageResult = document.getElementById('image-result'); |
66 * | 102 // Explicitly set the width/height to minimize the number of reflows. For |
67 * @param {DOMElement} A kitten. | 103 // a single image, this does not matter, but if you're going to embed |
68 * @return {string} The kitten's URL. | 104 // multiple external images in your page, then the absence of width/height |
69 * @private | 105 // attributes causes the popup to resize multiple times. |
70 */ | 106 imageResult.width = width; |
71 constructKittenURL_: function (photo) { | 107 imageResult.height = height; |
72 return "http://farm" + photo.getAttribute("farm") + | 108 imageResult.src = imageUrl; |
73 ".static.flickr.com/" + photo.getAttribute("server") + | 109 imageResult.hidden = false; |
74 "/" + photo.getAttribute("id") + | |
75 "_" + photo.getAttribute("secret") + | |
76 "_s.jpg"; | |
77 } | |
78 }; | |
79 | 110 |
80 // Run our kitten generation script as soon as the document's DOM is ready. | 111 }, function(errorMessage) { |
81 document.addEventListener('DOMContentLoaded', function () { | 112 renderStatus('Cannot display image. ' + errorMessage); |
82 kittenGenerator.requestKittens(); | 113 }); |
114 }); | |
83 }); | 115 }); |
OLD | NEW |