Index: chrome/common/extensions/docs/examples/tutorials/getstarted/popup.js |
diff --git a/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.js b/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.js |
index bdbe548d457cf40f2945c1af0ab8ae61a6b4e2cf..669f4ccff44578a5a76055821b991f476237f0f2 100644 |
--- a/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.js |
+++ b/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.js |
@@ -1,83 +1,115 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2014 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
/** |
- * Global variable containing the query we'd like to pass to Flickr. In this |
- * case, kittens! |
+ * Get the current URL. |
* |
- * @type {string} |
- */ |
-var QUERY = 'kittens'; |
+ * @param {function(string)} callback - called when the URL of the current tab |
+ * is found. |
+ **/ |
+function getCurrentTabUrl(callback) { |
+ // Query filter to be passed to chrome.tabs.query - see |
+ // https://developer.chrome.com/extensions/tabs#method-query |
+ var queryInfo = { |
+ active: true, |
+ currentWindow: true |
+ }; |
+ |
+ chrome.tabs.query(queryInfo, function(tabs) { |
+ // chrome.tabs.query invokes the callback with a list of tabs that match the |
+ // query. When the popup is opened, there is certainly a window and at least |
+ // one tab, so we can safely assume that |tabs| is a non-empty array. |
+ // A window can only have one active tab at a time, so the array consists of |
+ // exactly one tab. |
+ var tab = tabs[0]; |
+ |
+ // A tab is a plain object that provides information about the tab. |
+ // See https://developer.chrome.com/extensions/tabs#type-Tab |
+ var url = tab.url; |
-var kittenGenerator = { |
- /** |
- * Flickr URL that will give us lots and lots of whatever we're looking for. |
- * |
- * See http://www.flickr.com/services/api/flickr.photos.search.html for |
- * details about the construction of this URL. |
- * |
- * @type {string} |
- * @private |
- */ |
- searchOnFlickr_: 'https://secure.flickr.com/services/rest/?' + |
- 'method=flickr.photos.search&' + |
- 'api_key=90485e931f687a9b9c2a66bf58a3861a&' + |
- 'text=' + encodeURIComponent(QUERY) + '&' + |
- 'safe_search=1&' + |
- 'content_type=1&' + |
- 'sort=interestingness-desc&' + |
- 'per_page=20', |
+ // tab.url is only available if the "activeTab" permission is declared. |
+ // If you want to see the URL of other tabs (e.g. after removing active:true |
+ // from |queryInfo|), then the "tabs" permission is required to see their |
+ // "url" properties. |
+ console.assert(typeof url == 'string', 'tab.url should be a string'); |
- /** |
- * Sends an XHR GET request to grab photos of lots and lots of kittens. The |
- * XHR's 'onload' event is hooks up to the 'showPhotos_' method. |
- * |
- * @public |
- */ |
- requestKittens: function() { |
- var req = new XMLHttpRequest(); |
- req.open("GET", this.searchOnFlickr_, true); |
- req.onload = this.showPhotos_.bind(this); |
- req.send(null); |
- }, |
+ callback(url); |
+ }); |
- /** |
- * Handle the 'onload' event of our kitten XHR request, generated in |
- * 'requestKittens', by generating 'img' elements, and stuffing them into |
- * the document for display. |
- * |
- * @param {ProgressEvent} e The XHR ProgressEvent. |
- * @private |
- */ |
- showPhotos_: function (e) { |
- var kittens = e.target.responseXML.querySelectorAll('photo'); |
- for (var i = 0; i < kittens.length; i++) { |
- var img = document.createElement('img'); |
- img.src = this.constructKittenURL_(kittens[i]); |
- img.setAttribute('alt', kittens[i].getAttribute('title')); |
- document.body.appendChild(img); |
+ // Most methods of the Chrome extension APIs are asynchronous. This means that |
+ // you CANNOT do something like this: |
+ // |
+ // var url; |
+ // chrome.tabs.query(queryInfo, function(tabs) { |
+ // url = tabs[0].url; |
+ // }); |
+ // alert(url); // Shows "undefined", because chrome.tabs.query is async. |
+} |
+ |
+/** |
+ * @param {string} searchTerm - Search term for Google Image search. |
+ * @param {function(string,number,number)} callback - Called when an image has |
+ * been found. The callback gets the URL, width and height of the image. |
+ * @param {function(string)} errorCallback - Called when the image is not found. |
+ * The callback gets a string that describes the failure reason. |
+ */ |
+function getImageUrl(searchTerm, callback, errorCallback) { |
+ // Google image search - 100 searches per day. |
+ // https://developers.google.com/image-search/ |
+ var searchUrl = 'https://ajax.googleapis.com/ajax/services/search/images' + |
+ '?v=1.0&q=' + encodeURIComponent(searchTerm); |
+ var x = new XMLHttpRequest(); |
+ x.open('GET', searchUrl); |
+ // The Google image search API responds with JSON, so let Chrome parse it. |
+ x.responseType = 'json'; |
+ x.onload = function() { |
+ // Parse and process the response from Google Image Search. |
+ var response = x.response; |
+ if (!response || !response.responseData || !response.responseData.results || |
+ response.responseData.results.length === 0) { |
+ errorCallback('No response from Google Image search!'); |
+ return; |
} |
- }, |
+ var firstResult = response.responseData.results[0]; |
+ // Take the thumbnail instead of the full image to get an approximately |
+ // consistent image size. |
+ var imageUrl = firstResult.tbUrl; |
+ var width = parseInt(firstResult.tbWidth); |
+ var height = parseInt(firstResult.tbHeight); |
+ 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.
|
+ }; |
+ x.onerror = function() { |
+ errorCallback('Network error.'); |
+ }; |
+ x.send(); |
+} |
+ |
+function renderStatus(statusText) { |
+ document.getElementById('status').textContent = statusText; |
+} |
+ |
+document.addEventListener('DOMContentLoaded', function() { |
+ getCurrentTabUrl(function(url) { |
+ // Put the image URL in Google search. |
+ renderStatus('Performing Google Image search for ' + url); |
+ |
+ getImageUrl(url, function(imageUrl, width, height) { |
- /** |
- * Given a photo, construct a URL using the method outlined at |
- * http://www.flickr.com/services/api/misc.urlKittenl |
- * |
- * @param {DOMElement} A kitten. |
- * @return {string} The kitten's URL. |
- * @private |
- */ |
- constructKittenURL_: function (photo) { |
- return "http://farm" + photo.getAttribute("farm") + |
- ".static.flickr.com/" + photo.getAttribute("server") + |
- "/" + photo.getAttribute("id") + |
- "_" + photo.getAttribute("secret") + |
- "_s.jpg"; |
- } |
-}; |
+ renderStatus('Search term: ' + url + '\n' + |
+ 'Google image search result: ' + imageUrl); |
+ var imageResult = document.getElementById('image-result'); |
+ // Explicitly set the width/height to minimize the number of reflows. For |
+ // a single image, this does not matter, but if you're going to embed |
+ // multiple external images in your page, then the absence of width/height |
+ // attributes causes the popup to resize multiple times. |
+ imageResult.width = width; |
+ imageResult.height = height; |
+ imageResult.src = imageUrl; |
+ imageResult.hidden = false; |
-// Run our kitten generation script as soon as the document's DOM is ready. |
-document.addEventListener('DOMContentLoaded', function () { |
- kittenGenerator.requestKittens(); |
+ }, function(errorMessage) { |
+ renderStatus('Cannot display image. ' + errorMessage); |
+ }); |
+ }); |
}); |