picasa.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. // Copyright 2009 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview provides a reusable picasa album UI component given a public
  16. * picasa album URL.
  17. *
  18. * TODO(user): implement the javascript viewer, for users without flash. Get it
  19. * from the Gmail Picasa gadget.
  20. *
  21. * goog.ui.media.PicasaAlbum is actually a {@link goog.ui.ControlRenderer}, a
  22. * stateless class - that could/should be used as a Singleton with the static
  23. * method {@code goog.ui.media.PicasaAlbum.getInstance} -, that knows how to
  24. * render picasa albums. It is designed to be used with a
  25. * {@link goog.ui.Control}, which will actually control the media renderer and
  26. * provide the {@link goog.ui.Component} base. This design guarantees that all
  27. * different types of medias will behave alike but will look different.
  28. *
  29. * goog.ui.media.PicasaAlbum expects {@code goog.ui.media.PicasaAlbumModel}s on
  30. * {@code goog.ui.Control.getModel} as data models, and render a flash object
  31. * that will show a slideshow with the contents of that album URL.
  32. *
  33. * Example of usage:
  34. *
  35. * <pre>
  36. * var album = goog.ui.media.PicasaAlbumModel.newInstance(
  37. * 'http://picasaweb.google.com/username/SanFranciscoCalifornia');
  38. * goog.ui.media.PicasaAlbum.newControl(album).render();
  39. * </pre>
  40. *
  41. * picasa medias currently support the following states:
  42. *
  43. * <ul>
  44. * <li> {@link goog.ui.Component.State.DISABLED}: shows 'flash not available'
  45. * <li> {@link goog.ui.Component.State.HOVER}: mouse cursor is over the album
  46. * <li> {@link goog.ui.Component.State.SELECTED}: flash album is shown
  47. * </ul>
  48. *
  49. * Which can be accessed by
  50. *
  51. * <pre>
  52. * picasa.setEnabled(true);
  53. * picasa.setHighlighted(true);
  54. * picasa.setSelected(true);
  55. * </pre>
  56. *
  57. * Requires flash to actually work.
  58. */
  59. goog.provide('goog.ui.media.PicasaAlbum');
  60. goog.provide('goog.ui.media.PicasaAlbumModel');
  61. goog.require('goog.html.TrustedResourceUrl');
  62. goog.require('goog.string.Const');
  63. goog.require('goog.ui.media.FlashObject');
  64. goog.require('goog.ui.media.Media');
  65. goog.require('goog.ui.media.MediaModel');
  66. goog.require('goog.ui.media.MediaRenderer');
  67. /**
  68. * Subclasses a goog.ui.media.MediaRenderer to provide a Picasa specific media
  69. * renderer.
  70. *
  71. * This class knows how to parse picasa URLs, and render the DOM structure
  72. * of picasa album players and previews. This class is meant to be used as a
  73. * singleton static stateless class, that takes {@code goog.ui.media.Media}
  74. * instances and renders it. It expects {@code goog.ui.media.Media.getModel} to
  75. * return a well formed, previously constructed, object with a user and album
  76. * fields {@see goog.ui.media.PicasaAlbum.parseUrl}, which is the data model
  77. * this renderer will use to construct the DOM structure.
  78. * {@see goog.ui.media.PicasaAlbum.newControl} for a example of constructing a
  79. * control with this renderer.
  80. *
  81. * goog.ui.media.PicasaAlbum currently displays a picasa-made flash slideshow
  82. * with the photos, but could possibly display a handwritten js photo viewer,
  83. * in case flash is not available.
  84. *
  85. * This design is patterned after http://go/closure_control_subclassing
  86. *
  87. * It uses {@link goog.ui.media.FlashObject} to embed the flash object.
  88. *
  89. * @constructor
  90. * @extends {goog.ui.media.MediaRenderer}
  91. * @final
  92. */
  93. goog.ui.media.PicasaAlbum = function() {
  94. goog.ui.media.MediaRenderer.call(this);
  95. };
  96. goog.inherits(goog.ui.media.PicasaAlbum, goog.ui.media.MediaRenderer);
  97. goog.addSingletonGetter(goog.ui.media.PicasaAlbum);
  98. /**
  99. * Default CSS class to be applied to the root element of components rendered
  100. * by this renderer.
  101. *
  102. * @type {string}
  103. */
  104. goog.ui.media.PicasaAlbum.CSS_CLASS = goog.getCssName('goog-ui-media-picasa');
  105. /**
  106. * A static convenient method to construct a goog.ui.media.Media control out of
  107. * a picasa data model. It sets it as the data model goog.ui.media.PicasaAlbum
  108. * renderer uses, sets the states supported by the renderer, and returns a
  109. * Control that binds everything together. This is what you should be using for
  110. * constructing Picasa albums, except if you need finer control over the
  111. * configuration.
  112. *
  113. * @param {goog.ui.media.PicasaAlbumModel} dataModel A picasa album data model.
  114. * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper, used for
  115. * document interaction.
  116. * @return {!goog.ui.media.Media} A Control instance binded to the Picasa
  117. * renderer.
  118. */
  119. goog.ui.media.PicasaAlbum.newControl = function(dataModel, opt_domHelper) {
  120. var control = new goog.ui.media.Media(
  121. dataModel, goog.ui.media.PicasaAlbum.getInstance(), opt_domHelper);
  122. control.setSelected(true);
  123. return control;
  124. };
  125. /**
  126. * Creates the initial DOM structure of the picasa album, which is basically a
  127. * the flash object pointing to a flash picasa album player.
  128. *
  129. * @param {goog.ui.Control} c The media control.
  130. * @return {!Element} The DOM structure that represents the control.
  131. * @override
  132. */
  133. goog.ui.media.PicasaAlbum.prototype.createDom = function(c) {
  134. var control = /** @type {goog.ui.media.Media} */ (c);
  135. var div = goog.ui.media.PicasaAlbum.superClass_.createDom.call(this, control);
  136. var picasaAlbum =
  137. /** @type {goog.ui.media.PicasaAlbumModel} */ (control.getDataModel());
  138. var flash = new goog.ui.media.FlashObject(
  139. picasaAlbum.getPlayer().getTrustedResourceUrl(), control.getDomHelper());
  140. flash.addFlashVars(picasaAlbum.getPlayer().getVars());
  141. flash.render(div);
  142. return div;
  143. };
  144. /**
  145. * Returns the CSS class to be applied to the root element of components
  146. * rendered using this renderer.
  147. * @return {string} Renderer-specific CSS class.
  148. * @override
  149. */
  150. goog.ui.media.PicasaAlbum.prototype.getCssClass = function() {
  151. return goog.ui.media.PicasaAlbum.CSS_CLASS;
  152. };
  153. /**
  154. * The {@code goog.ui.media.PicasaAlbum} media data model. It stores a required
  155. * {@code userId} and {@code albumId} fields, sets the picasa album URL, and
  156. * allows a few optional parameters.
  157. *
  158. * @param {string} userId The picasa userId associated with this album.
  159. * @param {string} albumId The picasa albumId associated with this album.
  160. * @param {string=} opt_authKey An optional authentication key, used on private
  161. * albums.
  162. * @param {string=} opt_caption An optional caption of the picasa album.
  163. * @param {string=} opt_description An optional description of the picasa album.
  164. * @param {boolean=} opt_autoplay Whether to autoplay the slideshow.
  165. * @constructor
  166. * @extends {goog.ui.media.MediaModel}
  167. * @final
  168. */
  169. goog.ui.media.PicasaAlbumModel = function(
  170. userId, albumId, opt_authKey, opt_caption, opt_description, opt_autoplay) {
  171. goog.ui.media.MediaModel.call(
  172. this, goog.ui.media.PicasaAlbumModel.buildUrl(userId, albumId),
  173. opt_caption, opt_description, goog.ui.media.MediaModel.MimeType.FLASH);
  174. /**
  175. * The Picasa user id.
  176. * @type {string}
  177. * @private
  178. */
  179. this.userId_ = userId;
  180. /**
  181. * The Picasa album id.
  182. * @type {string}
  183. * @private
  184. */
  185. this.albumId_ = albumId;
  186. /**
  187. * The Picasa authentication key, used on private albums.
  188. * @type {?string}
  189. * @private
  190. */
  191. this.authKey_ = opt_authKey || null;
  192. var authParam = opt_authKey ? ('&authkey=' + opt_authKey) : '';
  193. var flashVars = {
  194. 'host': 'picasaweb.google.com',
  195. 'RGB': '0x000000',
  196. 'feed': 'http://picasaweb.google.com/data/feed/api/user/' + userId +
  197. '/album/' + albumId + '?kind=photo&alt=rss' + authParam
  198. };
  199. flashVars[opt_autoplay ? 'autoplay' : 'noautoplay'] = '1';
  200. var flashUrl = goog.html.TrustedResourceUrl.fromConstant(
  201. goog.string.Const.from(
  202. 'http://picasaweb.google.com/s/c/bin/slideshow.swf'));
  203. var player = new goog.ui.media.MediaModel.Player(flashUrl, flashVars);
  204. this.setPlayer(player);
  205. };
  206. goog.inherits(goog.ui.media.PicasaAlbumModel, goog.ui.media.MediaModel);
  207. /**
  208. * Regular expression used to extract the picasa username and albumid out of
  209. * picasa URLs.
  210. *
  211. * Copied from http://go/markdownlite.js,
  212. * and {@link PicasaWebExtractor.xml}.
  213. *
  214. * @type {RegExp}
  215. * @private
  216. * @const
  217. */
  218. goog.ui.media.PicasaAlbumModel.MATCHER_ =
  219. /https?:\/\/(?:www\.)?picasaweb\.(?:google\.)?com\/([\d\w\.]+)\/([\d\w_\-\.]+)(?:\?[\w\d\-_=&amp;;\.]*&?authKey=([\w\d\-_=;\.]+))?(?:#([\d]+)?)?/im;
  220. /**
  221. * Gets a {@code picasaUrl} and extracts the user and album id.
  222. *
  223. * @param {string} picasaUrl A picasa album URL.
  224. * @param {string=} opt_caption An optional caption of the picasa album.
  225. * @param {string=} opt_description An optional description of the picasa album.
  226. * @param {boolean=} opt_autoplay Whether to autoplay the slideshow.
  227. * @return {!goog.ui.media.PicasaAlbumModel} The picasa album data model that
  228. * represents the picasa URL.
  229. * @throws exception in case the parsing fails
  230. */
  231. goog.ui.media.PicasaAlbumModel.newInstance = function(
  232. picasaUrl, opt_caption, opt_description, opt_autoplay) {
  233. if (goog.ui.media.PicasaAlbumModel.MATCHER_.test(picasaUrl)) {
  234. var data = goog.ui.media.PicasaAlbumModel.MATCHER_.exec(picasaUrl);
  235. return new goog.ui.media.PicasaAlbumModel(
  236. data[1], data[2], data[3], opt_caption, opt_description, opt_autoplay);
  237. }
  238. throw Error('failed to parse user and album from picasa url: ' + picasaUrl);
  239. };
  240. /**
  241. * The opposite of {@code newInstance}: takes an {@code userId} and an
  242. * {@code albumId} and builds a URL.
  243. *
  244. * @param {string} userId The user that owns the album.
  245. * @param {string} albumId The album id.
  246. * @return {string} The URL of the album.
  247. */
  248. goog.ui.media.PicasaAlbumModel.buildUrl = function(userId, albumId) {
  249. return 'http://picasaweb.google.com/' + userId + '/' + albumId;
  250. };
  251. /**
  252. * Gets the Picasa user id.
  253. * @return {string} The Picasa user id.
  254. */
  255. goog.ui.media.PicasaAlbumModel.prototype.getUserId = function() {
  256. return this.userId_;
  257. };
  258. /**
  259. * Gets the Picasa album id.
  260. * @return {string} The Picasa album id.
  261. */
  262. goog.ui.media.PicasaAlbumModel.prototype.getAlbumId = function() {
  263. return this.albumId_;
  264. };
  265. /**
  266. * Gets the Picasa album authentication key.
  267. * @return {?string} The Picasa album authentication key.
  268. */
  269. goog.ui.media.PicasaAlbumModel.prototype.getAuthKey = function() {
  270. return this.authKey_;
  271. };