PageRenderTime 50ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 1ms

/dist/media-chooser.js

https://github.com/shinebig/media-chooser
JavaScript | 2009 lines | 1464 code | 287 blank | 258 comment | 424 complexity | 6e488b89dfdf3dcbfa5588ec498116bb MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*! Chute.MediaChooser - v0.1.4 - 2013-05-17
  2. * http://getchute.com/
  3. * Copyright (c) 2013 Chute Corporation; Licensed MIT */
  4. if (!window.Chute) {
  5. window.Chute = (function() {
  6. function Chute() {}
  7. Chute.setApp = function(app) {
  8. this.app = app;
  9. };
  10. Chute.fill = function(width, height, url) {
  11. return "" + url + "/" + width + "x" + height;
  12. };
  13. Chute.fit = function(width, height, url) {
  14. return "" + url + "/fit/" + width + "x" + height;
  15. };
  16. Chute.width = function(width, url) {
  17. return "" + url + "/w/" + width;
  18. };
  19. Chute.height = function(height, url) {
  20. return "" + url + "/h/" + height;
  21. };
  22. return Chute;
  23. })();
  24. }
  25. window.Chute.MediaChooser = (function() {
  26. function MediaChooser() {}
  27. MediaChooser.validateNumber = function(value, rule) {
  28. var max, maxEqual, min, minEqual, result;
  29. min = -Infinity;
  30. minEqual = false;
  31. max = Infinity;
  32. maxEqual = false;
  33. result = />=\s?([0-9.]+)/.exec(rule);
  34. if (result) {
  35. min = parseFloat(result[1]);
  36. minEqual = true;
  37. }
  38. result = />\s?([0-9.]+)/.exec(rule);
  39. if (result) {
  40. min = parseFloat(result[1]);
  41. minEqual = false;
  42. }
  43. result = /<=\s?([0-9.]+)/.exec(rule);
  44. if (result) {
  45. max = parseFloat(result[1]);
  46. maxEqual = true;
  47. }
  48. result = /<\s?([0-9.]+)/.exec(rule);
  49. if (result) {
  50. max = parseFloat(result[1]);
  51. maxEqual = false;
  52. }
  53. result = /^\=\s?([0-9.]+)$/.exec(rule);
  54. if (result) {
  55. min = max = parseFloat(result[1]);
  56. minEqual = maxEqual = true;
  57. }
  58. if (min !== -Infinity) {
  59. if (minEqual) {
  60. if (!(value >= min)) {
  61. return false;
  62. }
  63. } else {
  64. if (!(value > min)) {
  65. return false;
  66. }
  67. }
  68. }
  69. if (max !== Infinity) {
  70. if (maxEqual) {
  71. if (!(value <= max)) {
  72. return false;
  73. }
  74. } else {
  75. if (!(value < max)) {
  76. return false;
  77. }
  78. }
  79. }
  80. return true;
  81. };
  82. MediaChooser.defaults = {};
  83. MediaChooser.setDefaults = function(defaults) {
  84. this.defaults = defaults != null ? defaults : {};
  85. };
  86. MediaChooser.choose = function(params, callback) {
  87. var constraintsLength, id, key, widget,
  88. _this = this;
  89. if ('function' === typeof params) {
  90. callback = params;
  91. params = {};
  92. }
  93. params.app = Chute.app || params.app || this.defaults.app;
  94. params.chute_id = params.album || this.defaults.album;
  95. if (!params.app) {
  96. throw new Error('Chute.MediaChooser requires app parameter');
  97. }
  98. if (params.chute_id) {
  99. params.identifier = "chute-identifier-" + params.chute_id;
  100. }
  101. if (!(params.mode != null)) {
  102. params.mode = 'collector' || this.defaults.mode;
  103. }
  104. if (!(params.popup != null)) {
  105. params.popup = false || this.defaults.popup;
  106. }
  107. params.file_types = (function() {
  108. switch (params.mediaTypes || this.defaults.mediaTypes) {
  109. case 'images':
  110. case 'image':
  111. case 'picture':
  112. case 'pictures':
  113. return 1;
  114. case 'video':
  115. case 'videos':
  116. return 2;
  117. default:
  118. return 0;
  119. }
  120. }).call(this);
  121. params.inclusions = (params.services || this.defaults.services || ['upload', 'facebook', 'picasa', 'instagram', 'flickr']).join(',');
  122. params.file_limit = params.limit || this.defaults.limit || 0;
  123. if (params.version || this.defaults.version) {
  124. params.picker_version = "v" + (params.version || this.defaults.version);
  125. } else {
  126. params.picker_version = 'v2';
  127. }
  128. constraintsLength = 0;
  129. if (this.defaults.constraints && !params.constraints) {
  130. params.constraints = this.defaults.constraints;
  131. }
  132. if (params.constraints) {
  133. for (key in params.constraints) {
  134. if (params.constraints.hasOwnProperty(key)) {
  135. constraintsLength++;
  136. }
  137. }
  138. }
  139. params.onSelectionComplete = function(element, data) {
  140. var asset, filteredData, urls, valid, _i, _len, _ref;
  141. urls = [];
  142. filteredData = {};
  143. for (key in data) {
  144. if (data.hasOwnProperty(key)) {
  145. filteredData[key] = data[key];
  146. }
  147. }
  148. filteredData.assets = [];
  149. _ref = data.assets;
  150. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  151. asset = _ref[_i];
  152. if (constraintsLength > 0) {
  153. valid = true;
  154. for (key in params.constraints) {
  155. if (params.constraints.hasOwnProperty(key) && !_this.validateNumber(asset[key], params.constraints[key])) {
  156. valid = false;
  157. }
  158. }
  159. if (valid) {
  160. filteredData.assets.push(asset);
  161. urls.push(asset.url);
  162. }
  163. } else {
  164. filteredData.assets.push(asset);
  165. urls.push(asset.url);
  166. }
  167. }
  168. if (callback) {
  169. return callback(urls, filteredData);
  170. }
  171. };
  172. id = parseInt(Math.random() * 1000);
  173. widget = jQuery("<div id=\"chute-" + id + "\"></div>");
  174. widget.appendTo('body');
  175. params.widget_id = id;
  176. params.onComplete = function() {
  177. var browseButton;
  178. browseButton = widget.find('a.chute-browseButton');
  179. if (!params.popup && params.mode === 'collector') {
  180. browseButton.hide();
  181. }
  182. return browseButton.click();
  183. };
  184. return __chute("#chute-" + id, params);
  185. };
  186. return MediaChooser;
  187. })();
  188. function chutelog(what) {
  189. try {
  190. console.log(what);
  191. }
  192. catch (e) {}
  193. finally {
  194. return;
  195. }
  196. }
  197. /*
  198. * jQuery SlideChute Plugin 1.0.0
  199. * www.slidechute.com
  200. * Copyright 2012, Chute Corporation
  201. * Free to use under the MIT license.
  202. * http://www.opensource.org/licenses/mit-license.php
  203. */
  204. var currentWidget = null;
  205. var $chuteWidget;
  206. function chuteGetScript(url, success) {
  207. var script = document.createElement('script');
  208. script.src = url;
  209. var head = document.getElementsByTagName('head')[0],
  210. done = false;
  211. script.onload = script.onreadystatechange = function() {
  212. if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
  213. done = true;
  214. success();
  215. script.onload = script.onreadystatechange = null;
  216. head.removeChild(script);
  217. }
  218. };
  219. head.appendChild(script);
  220. }
  221. var __chute = function(element, data){
  222. function _loader(element, data){
  223. __chuteFunctions()
  224. jQuery(element).chute(data);
  225. }
  226. if (typeof(jQuery) != 'undefined') {
  227. _loader(element, data);
  228. }
  229. var _readyCallback = function(){
  230. if (typeof(jQuery) == 'undefined'){
  231. chuteGetScript('//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js', function(){
  232. setTimeout(function(){
  233. _loader(element, data);
  234. }, 10);
  235. });
  236. } else {
  237. _loader(element, data);
  238. }
  239. }
  240. var _loadCallback = function(){
  241. if (document.readyState == 'complete'){
  242. _readyCallback();
  243. }
  244. };
  245. if (typeof(jQuery) == 'undefined'){
  246. if (document.readyState == 'complete'){
  247. _readyCallback();
  248. } else if (document.addEventListener){
  249. document.addEventListener("readystatechange", _loadCallback);
  250. } else {
  251. document.attachEvent("onreadystatechange", _loadCallback);
  252. }
  253. }
  254. }
  255. var __chuteFunctions = function(){
  256. (function($) {
  257. var CHUTE = {
  258. popupHtml: "<style type='text/css'>.chute-reveal-modal { visibility:hidden }</style><div class='chute-popup chute-reveal-modal'>\
  259. <iframe width='100%' height='100%' marginWidth='0' marginHeight='0' frameBorder='0' scrolling='no' title='' src='//s3.amazonaws.com/cdn.getchute.com/html/v1/loading.html'>IFrame not supported</iframe>\
  260. <a class='close-chute-reveal-modal'>&#215;</a>\
  261. </div>\
  262. <div class='chute-thanks chute-reveal-modal'>\
  263. <div class='chute-thanks-header'>SUCCESS_MESSAGE</div>\
  264. <div class='chute-thanks-footer'>\
  265. <a href='mailto:info@getchute.com'>info@getchute.com</a>\
  266. </div>\
  267. <a class='close-chute-reveal-modal'>&nbsp;</a>\
  268. </div>",
  269. defaultDisplayTemplateHtml: "<style type='text/css'>.chute-thumbnails a{margin: 5px} .chute-thumbnails img{width:100px;height:100px;} .chute-thumbnail-reveal-modal {visibility: hidden;top: 0;left: 50%;margin-left: -250px;width: 500px;max-height: 800px;position: fixed;z-index: 10001;background-color:#fff;-moz-box-shadow: 0 0 10px rgba(0,0,0,.4);-webkit-box-shadow: 0 0 10px rgba(0,0,0,.4);-box-shadow: 0 0 10px rgba(0,0,0,.4);overflow:hidden;} .chute-thumbnail-reveal-modal img{width: 100%;float: left;} .chute-thumbnail-reveal-modal .close-chute-thumbnail-reveal-modal {font-size: 22px;line-height: .5;position: absolute;top: 15px;right: 11px;color: #aaa;text-shadow: 0 -1px 1px rbga(0,0,0,.6);font-weight: bold;cursor: pointer;} .chute-thumbnail-reveal-modal .chute-thumbnail-source{position:absolute;left: 0;bottom: 30px;background-color: #000;background-color: rgba(0,0,0, 0.6);color: #fff;padding: 5px;text-decoration: none;-moz-box-shadow: 0 0 5px #888;-webkit-box-shadow: 0 0 5px#888;box-shadow: 0 0 5px #888;} .chute-reveal-modal-bg {position: fixed;height: 100%;width: 100%;background: #000;background: rgba(150,150,150,.8);z-index: 10000;display: none;top: 0;left: 0;}</style><div class='chute-thumbnails'>{{#images}}<a href='{{url}}' data-source-url='{{source_url}}' data-url='{{url}}'><img src='{{url}}/100x100'></a>{{/images}}</div>",
  270. defaultCollectTemplateHtml: "<a href='#' class='chute-browseButton'><img src='//s3.amazonaws.com/cdn.getchute.com/v1/images/add-photos.png' style='border:0'></a>",
  271. // Paths
  272. paths: {
  273. assets : '/assets/:id', // Path to assets data
  274. gallery : '/chutes/:id.js', // Path to gallery data
  275. collection : '/collection/:id' // Path to collection data
  276. },
  277. // Defaults
  278. defaults: {
  279. uploadServer : '//upload.getchute.com', // Path to Upload Server
  280. apiServer : '//api.getchute.com', // Path to API
  281. cdnRoot : '//s3.amazonaws.com/cdn.getchute.com/v1',
  282. popup : false,
  283. app : null, // ID of the app
  284. disable_auto_identifier : false,
  285. display_template_name : null, // required only with an external url based template
  286. display_template : null, // jQuery Object or HTML template
  287. collector_template_name : null, // collector theme name
  288. collector_template : null, // collector theme path
  289. collector_width : '635px', // collector template width
  290. collector_height : '435px', // collector template height
  291. template_options : {},
  292. // Data Sources
  293. assets : null, // ID of Asset(s) to render as comma-delimited list
  294. gallery : null, // ID of the Gallery to render
  295. collection : null, // ID of the Collection to render
  296. // Externals
  297. css : '', // Comma-delimited list of css externals to load
  298. css_loaded : false, // Boolean indicating if all required css is loaded
  299. scripts : '', // Comma-delimited list of js externals to load
  300. scripts_lodaed : false, // Boolean indicating if all required js is loaded,
  301. exclusions : "",
  302. file_types : 1, // 0 = all, 1 = image, 2 = video
  303. file_limit : 0, // 0 = unlimited
  304. is_display : true,
  305. success_message : "<h3>Thanks!</h3><p>Your photos will be online as soon as they're approved</p>",
  306. // Plugin Events
  307. onComplete : function() {}, // Fired when the the plugin has completely initialized
  308. // Display Events
  309. onTemplateLoaded : function() {}, // Fired when template loaded
  310. onDependenciesLoaded : function() {}, // Fired when template dependencies loaded
  311. onAssetsLoading : function() {}, // Fired when assets are starting to load
  312. onAssetsLoaded : function() {}, // Fired when assets are loaded
  313. onAssetsRendered : null, // Fired when assets are rendered
  314. onAssetsReRendered : function() {}, // Fired when assets are re-rendered
  315. // Collection Events
  316. onDrop : function() {}, // Fired when assets are dropped on the plugin
  317. onAlbumList : function() {}, // Fired when the listing of albums is loaded
  318. onAlbumLoad : function() {}, // Fired when an external album loads
  319. onAdd : function() {}, // Fired when assets are selection for inclusion
  320. onRemove : function() {}, // Fired when assets are removed from inclusion
  321. onSelection : function() {}, // Fired when selection of photos has been completed
  322. onConfirmation : function() {}, // Fired when rights are confirmed
  323. onProfileComplete : function() {}, // Fired when custom profile is completed
  324. onSelectionComplete : function() {} // Fired when widget has completed the process
  325. },
  326. // Initializer
  327. init: function(element, options) {
  328. // Save values
  329. this.$element = $(element);
  330. this.$element.addClass('chute-loaded');
  331. // pull in options specified by html5 tags
  332. var _htmlOptions = {
  333. app : this.$element.attr('data-app-id'),
  334. identifier : this.$element.attr('data-identifier') == undefined || this.$element.attr('data-identifier') == '' ? null : this.$element.attr('data-identifier'),
  335. disable_auto_identifier : this.$element.attr('data-disable-auto-identifier') == undefined ? this.defaults.disable_auto_identifier : true,
  336. id : this.$element.attr('data-id') == undefined ? null : this.$element.attr('data-id'),
  337. bundle_id : this.$element.attr('data-bundle-id') == undefined ? '' : this.$element.attr('data-bundle-id'),
  338. custom_id : this.$element.attr('data-custom_id') == undefined ? '' : this.$element.attr('data-custom_id'),
  339. assets : this.$element.attr('data-assets') == undefined ? this.defaults.assets : this.$element.attr('data-assets').split(','),
  340. name : this.$element.attr('data-name'),
  341. url : this.$element.attr('data-url') == undefined ? document.location.href : this.$element.attr('data-url'),
  342. tags : this.$element.attr('data-tags') == undefined ? '' : this.$element.attr('data-tags'),
  343. css : this.$element.attr('data-css') == undefined ? '' : this.$element.attr('data-css'),
  344. screens : this.$element.attr('data-screens') == undefined ? '' : this.$element.attr('data-screens'),
  345. display_template_name : this.$element.attr('data-display-template-name') == undefined ? this.defaults.display_template_name : this.$element.attr('data-display-template-name'),
  346. display_template : this.$element.attr('data-display-template') == undefined ? this.defaults.display_template : this.$element.attr('data-display-template'),
  347. collector_template_name : this.$element.attr('data-collector-template-name') == undefined ? this.defaults.collector_template_name : this.$element.attr('data-collector-template-name'),
  348. collector_template : this.$element.attr('data-collector-template') == undefined ? this.defaults.collector_template : this.$element.attr('data-collector-template'),
  349. collector_width : this.$element.attr('data-collector-width') == undefined ? this.defaults.collector_width : this.$element.attr('data-collector-width'),
  350. collector_height : this.$element.attr('data-collector-height') == undefined ? this.defaults.collector_height : this.$element.attr('data-collector-height'),
  351. template_options : this.$element.attr('data-template-options') == undefined ? this.defaults.template_options : $.parseJSON(this.$element.attr('data-template-options')),
  352. captions : this.$element.attr('data-captions') == undefined ? 'hide' : this.$element.attr('data-captions'),
  353. exclusions : this.$element.attr('data-services-exclude') == undefined ? this.defaults.exclusions : this.$element.attr('data-services-exclude'),
  354. inclusions : this.$element.attr('data-services-include') == undefined ? '' : this.$element.attr('data-services-include'),
  355. dialogTitle : this.$element.attr('data-chooser-button-text') == undefined ? 'Choose Photos' : this.$element.attr('data-chooser-button-text'),
  356. mode : this.$element.attr('data-mode') == undefined ? 'thumbnails' : this.$element.attr('data-mode'),
  357. uploadServer : this.$element.attr('data-uploadServer') == undefined ? this.defaults.uploadServer : this.$element.attr('data-uploadServer'),
  358. apiServer : this.$element.attr('data-apiServer') == undefined ? this.defaults.apiServer : this.$element.attr('data-apiServer'),
  359. cdnRoot : this.$element.attr('data-cdnRoot') == undefined ? this.defaults.cdnRoot : this.$element.attr('data-cdnRoot'),
  360. file_types : this.$element.attr('data-file-types') == undefined ? this.defaults.file_types : this.$element.attr('data-file-types'),
  361. file_limit : this.$element.attr('data-file-limit') == undefined ? this.defaults.file_limit : this.$element.attr('data-file-limit'),
  362. share_text : this.$element.attr('data-share-text') == undefined ? '' : this.$element.attr('data-share-text'),
  363. awesm_key : this.$element.attr('data-awesm-key') == undefined ? '' : this.$element.attr('data-awesm-key'),
  364. popup : this.$element.attr('data-popup') == 'popup',
  365. success_message : this.$element.attr('data-success_message') == undefined ? this.defaults.success_message : this.$element.attr('data-success_message')
  366. }
  367. // Set the options
  368. this.options = $.extend({}, this.defaults, _htmlOptions);
  369. this.options = $.extend({}, this.options, options);
  370. this.options.is_display = !(this.options.mode == 'collector' || this.options.mode == 'chooser');
  371. this.popupHtml = this.popupHtml.replace('SUCCESS_MESSAGE', this.options.success_message);
  372. if (this.options.identifier == null && !this.options.disable_auto_identifier){
  373. this.options.identifier = '';
  374. this.options.id = '';
  375. }
  376. // use popup window when in an iframe hosted by us, or on a mobile
  377. // browser, unless already specified
  378. if ((!this.options.popup && window!=window.top && (document.location.host.indexOf("chute.com") == 0 || document.location.host.indexOf("slidechute.com") == 0))
  379. || navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry/i)) {
  380. this.options.popup = true;
  381. }
  382. var me = this;
  383. me.$element.addClass('chute-base-widget').css('position', 'relative');
  384. me.$element.data('options', this.options);
  385. me.$element.data('instanceReference', this);
  386. if (me.options.is_display){
  387. if (this.options.display_template == null && this.options.display_template_name != null){
  388. this.options.display_template = this.options.cdnRoot + "/templates/display/" + this.options.display_template_name + "/template.js";
  389. }
  390. if (me.options.display_template && me.options.display_template.indexOf('#') == 0){
  391. me.options.display_template = $(me.options.display_template).html();
  392. me.renderData();
  393. } else if (this.options.display_template != undefined && (this.options.display_template.indexOf('http') == 0 || this.options.display_template.indexOf('//') == 0)){
  394. $.getScript(me.options.display_template, function() {
  395. me.loadTemplateData(function(){
  396. me.options.onDependenciesLoaded(me.$element);
  397. me.renderData();
  398. });
  399. });
  400. } else if (this.options.display_template_name == undefined || this.options.display_template_name == 'default' || this.options.display_template_name == ''){
  401. this.options.display_template = this.defaultDisplayTemplateHtml;
  402. this.options.onAssetsRendered = this.assetsRendered;
  403. me.renderData();
  404. }
  405. }
  406. else {
  407. if (this.options.collector_template == null && this.options.collector_template_name == null){
  408. this.options.collector_template = this.defaultCollectTemplateHtml;
  409. }
  410. else if (this.options.collector_template == null){
  411. this.options.collector_template = this.options.cdnRoot + "/templates/collector/" + this.options.collector_template_name + "/template.js";
  412. }
  413. me.renderData();
  414. }
  415. me.options.onComplete();
  416. return me;
  417. },
  418. renderData: function(page_url){
  419. var me = this;
  420. me.resetTimestamp();
  421. if (me.options.is_display){
  422. if (me.options.id == null && me.options.identifier == null){
  423. me.$element.addClass('chute-disabled').css('opacity', '0.5');
  424. return;
  425. }
  426. me.options.onAssetsLoading(me.$element);
  427. var defaultUrl = me.options.imagesUrl;
  428. // if assets already given then get the ids
  429. if (me.options.assets){
  430. var staticAssets = "";
  431. if (typeof me.options.assets == 'string')
  432. me.options.assets = me.options.assets.split(',');
  433. if (me.options.assets[0].indexOf('http') == 0) {
  434. staticAssets = "assets=" + $.map(me.options.assets, function(asset_url){
  435. var match = asset_url.match("\/m\/([^\/]+)/");
  436. return match.pop();
  437. }).join(',');
  438. } else {
  439. staticAssets = "assets=" + me.options.assets.join(',');
  440. }
  441. defaultUrl += "&" + staticAssets;
  442. }
  443. if (this.options.template_options.per_page)
  444. defaultUrl += "&per_page=" + this.options.template_options.per_page;
  445. var loadState = page_url == undefined ? -1 : (page_url == me.options.nextImagesUrl ? 0 : 1);
  446. var _url = page_url ? page_url : defaultUrl;
  447. // if there is a hash in the document, then it could point to an asset
  448. // make sure its there in the page
  449. if (loadState == -1 && document.location.hash != "" && document.location.hash != "#"){
  450. var _extraAssetId = document.location.hash.replace('#', '');
  451. _url = _url + "&extra_assets=" + _extraAssetId;
  452. }
  453. me.loadPath(_url, function(data){
  454. // new data link
  455. // don't update when requesting next and previous pages
  456. if (data.data.next_url && loadState != 1){
  457. me.options.nextImagesUrl = data.data.next_url;
  458. }
  459. // paginations link
  460. // don't update when requesting new data
  461. if (loadState != 0){
  462. me.options.nextPageUrl = data.data.next_page_url;
  463. me.options.previousPageUrl = data.data.previous_page_url;
  464. }
  465. if (data.data.assets.length > 0){
  466. if (me.options.onAssetsLoaded(me.$element, data) != false){
  467. // writeout template html in page
  468. me.displayRender(data, loadState);
  469. }
  470. }
  471. });
  472. } else {
  473. me.setupCollectorModal();
  474. me.collectorRender(function(){
  475. me.$element.find('.chute-popup').css({
  476. width: me.options.collector_width,
  477. height: me.options.collector_height,
  478. 'margin-left' : '-' + parseInt(me.options.collector_width)/2 + 'px'
  479. });
  480. if (me.options.id == null && me.options.identifier == null){
  481. me.$element.addClass('chute-disabled').css('opacity', '0.5');
  482. return;
  483. }
  484. me.makeDroppable(me.$element.find('.chutedrop'));
  485. });
  486. }
  487. },
  488. hasNextPage: function(){
  489. return (this.options.nextPageUrl != undefined);
  490. },
  491. hasPreviousPage: function(){
  492. return (this.options.previousPageUrl != undefined);
  493. },
  494. hasNewPage: function(){
  495. return (this.options.nextImagesUrl != undefined);
  496. },
  497. renderNextPage: function(){
  498. if (this.hasNextPage()){
  499. this.renderData(this.options.nextPageUrl)
  500. }
  501. },
  502. renderPreviousPage: function(){
  503. if (this.hasPreviousPage())
  504. this.renderData(this.options.previousPageUrl)
  505. },
  506. renderNewData: function(){
  507. if (this.hasNewPage()){
  508. this.renderData(this.options.nextImagesUrl)
  509. }
  510. },
  511. //////////////////////////////////////////////////////////
  512. // Loaders
  513. //////////////////////////////////////////////////////////
  514. // Load CSS dependencies
  515. loadCSS: function(url) {
  516. if(!url) return;
  517. if (typeof(url) == 'string') {
  518. if (url.indexOf('http') != 0)
  519. url = document.location.protocol + url;
  520. $('head').append( '<link rel="stylesheet" type="text/css" href="' + url + '" />' );
  521. }
  522. else {
  523. $.each(url, function(i, _url){
  524. if (_url.indexOf('http') != 0)
  525. _url = document.location.protocol + _url;
  526. $('head').append( '<link rel="stylesheet" type="text/css" href="' + _url + '" />' );
  527. });
  528. }
  529. },
  530. // Load JS dependencies
  531. loadJS: function(url, callback) {
  532. if(!url) {
  533. callback();
  534. return;
  535. }
  536. if (typeof(url) == 'string') {
  537. $.getScript(url, callback);
  538. }
  539. else if (url.length == 0) {
  540. callback();
  541. }
  542. else if (url.length == 1) {
  543. $.getScript(url[0], callback);
  544. }
  545. else {
  546. // http://www.jquery4u.com/ajax/getscript-mutiple-scripts/
  547. var // reference declaration & localization
  548. length = url.length,
  549. deferreds = [],
  550. counter = 0,
  551. idx = 0;
  552. var handler = function(){
  553. counter++;
  554. if (counter == length) {
  555. callback();
  556. }
  557. }
  558. for ( ; idx < length; idx++ ) {
  559. deferreds.push(
  560. $.getScript( url[ idx ], handler )
  561. );
  562. }
  563. }
  564. },
  565. // Load the data based on the passed data sources
  566. // Data order: Collection > Gallery > Asset
  567. loadData: function(callback) {
  568. var path = '';
  569. // Collection
  570. if (this.options.collection != null) {
  571. path = this.paths.collection.replace(':id',this.options.collection);
  572. // Gallery
  573. } else if (this.options.gallery != null) {
  574. path = this.paths.gallery.replace(':id',this.options.gallery);
  575. // Asset
  576. } else if (this.options.assets != null) {
  577. path = this.paths.asset.replace(':id',this.options.asset);
  578. }
  579. // If we have found a data call to make, complete it
  580. if (path.length) {
  581. var url = this.paths.api + path;
  582. /*this.loadJS(this.paths.api + path, function(data, status) {
  583. console.log(data)
  584. console.log(status)
  585. });*/
  586. //$.get(url, function(data, status) { console.log(data); console.log(status);}, "json");
  587. $.ajax({
  588. url : this.paths.api + path,
  589. dataType : 'jsonp',
  590. success : function(data, textStatus, jqXHR) {
  591. // console.log(data);
  592. },
  593. error : function(e) {
  594. // console.log(e);
  595. }
  596. });
  597. }
  598. },
  599. loadPath: function(path, callback){
  600. $.ajax({
  601. url : path,
  602. dataType : 'jsonp',
  603. success : function(data, textStatus, jqXHR) {
  604. callback(data);
  605. },
  606. error : function(e) {
  607. // console.log(e);
  608. }
  609. });
  610. },
  611. //////////////////////////////////////////////////////////
  612. // Load Template Data
  613. //////////////////////////////////////////////////////////
  614. loadTemplateData : function(callback){
  615. var me = this;
  616. if (this.options.is_display){
  617. this.options.display_template = eval(this.options.display_template_name + '_template_definition');
  618. if (typeof(this.options.display_template) != 'string'){
  619. this.options = $.extend({}, this.options, this.options.display_template.bindings);
  620. this.options.onTemplateLoaded(me.$element);
  621. me.loadCSS(this.options.display_template.requires.css);
  622. me.loadJS(this.options.display_template.requires.js, function(){
  623. callback();
  624. });
  625. } else {
  626. callback();
  627. }
  628. }
  629. },
  630. //////////////////////////////////////////////////////////
  631. // Collectors
  632. //////////////////////////////////////////////////////////
  633. // Load dependencies for collection mode
  634. setupCollectorModal: function() {
  635. if (!$('#chute-collector-modal').length) {
  636. // Load Reveal External
  637. this.loadCSS(this.options.cdnRoot + '/css/c.css');
  638. }
  639. },
  640. // Render Collector
  641. collectorRender: function(callback) {
  642. var me = this;
  643. if (me.options.collector_template.indexOf('http') == 0) {
  644. $.getScript(me.options.collector_template, function() {
  645. me.$element.html(me.popupHtml + eval(me.options.collector_template_name + '_template_html'));
  646. callback();
  647. });
  648. } else {
  649. me.$element.html(me.popupHtml + me.options.collector_template);
  650. callback();
  651. }
  652. },
  653. // Collector Modal
  654. collectorModal: function() {
  655. this.setupCollectorModal();
  656. // Attach the behavior
  657. this.$element.click(function(event) {
  658. event.preventDefault();
  659. })
  660. },
  661. makeDroppable: function(element) {
  662. var me = this;
  663. me.$element.find('.chute-browseButton, .chute-dropBox').click(function(event){
  664. event.preventDefault();
  665. me.openChuteBrowser();
  666. });
  667. me.openChuteBrowser = function(){
  668. if (me.options.popup){
  669. var width = 700;
  670. var height = 450
  671. var left = parseInt((screen.availWidth/2) - (width/2));
  672. var top = parseInt((screen.availHeight/2) - (height/2));
  673. var windowFeatures = "width=" + width + ",height=" + height + ",status,resizable,scrollbars=0,left=" + left + ",top=" + top + "screenX=" + left + ",screenY=" + top;
  674. window.open(me.options.browsePath, "chute_browse_popup", windowFeatures);
  675. } else if (me.options.embed) {
  676. var element = jQuery(me.options.embed).append(me.$element.find('.chute-popup iframe').clone().attr('src', me.options.browsePath));
  677. element.css({
  678. width: 600,
  679. height: 400
  680. });
  681. } else {
  682. me.$element.find(".chute-popup iframe").attr('src', me.options.browsePath);
  683. me.$element.find(".chute-popup").chuteReveal();
  684. }
  685. this.resetTimestamp();
  686. currentWidget = me;
  687. }
  688. me.$element.find('.chute-popup .close-chute-reveal-modal').click(function(){
  689. me.resetIframe();
  690. });
  691. if(element.length == 0) return;
  692. var totalImagesCount = 0;
  693. var uploadedImagesCount = 0;
  694. var totalUploadPercentDone = 0;
  695. var maxFileSize = '';
  696. var extensions = '';
  697. var browseTitle = '';
  698. if (me.options.file_types == 0) {
  699. maxFileSize = '50MB';
  700. extensions = 'jpg,gif,png,jpeg,mov,mp4,mpeg,mpeg,avi';
  701. browseTitle = 'Media Files';
  702. } else if (me.options.file_types == 1) {
  703. maxFileSize = '5MB';
  704. extensions = 'jpg,gif,png,jpeg';
  705. browseTitle = 'Image Files';
  706. } else {
  707. maxFileSize = '50MB';
  708. extensions = 'mov,mp4,mpeg,mpeg,avi';
  709. browseTitle = 'Video Files';
  710. }
  711. element.attr('id', me.options.timestamp);
  712. // upload code - start
  713. var ChuteUploader = new plupload.Uploader({
  714. runtimes : 'html5,flash,silverlight',
  715. browse_button : '',
  716. container : me.options.timestamp,
  717. max_file_size : maxFileSize,
  718. resize : { quality : 90 },
  719. url : me.options.uploadPath,
  720. flash_swf_url : '//s3.amazonaws.com/cdn.getchute.com/objects/v1/plupload.flash.swf',
  721. silverlight_xap_url : '//s3.amazonaws.com/cdn.getchute.com/objects/v1/plupload.silverlight.xap',
  722. filters : [{
  723. title : browseTitle,
  724. extensions : extensions
  725. }],
  726. drop_element : me.options.timestamp
  727. });
  728. ChuteUploader.bind('Init', function(up, params) {
  729. // ready
  730. setTimeout(function(){
  731. me.$element.find('.plupload.html5 input').attr('size', 300);
  732. }, 100);
  733. me.$element.find('.chute-select-button').click(function(event){
  734. event.preventDefault();
  735. me.openChuteBrowser();
  736. });
  737. });
  738. $('#uploadfiles').click(function(e) {
  739. ChuteUploader.start();
  740. e.preventDefault();
  741. });
  742. ChuteUploader.init();
  743. ChuteUploader.bind('FilesAdded', function(up, files) {
  744. me.options.onDrop(me.$element, files);
  745. me.setChuteFileProgress(0);
  746. $.each(files, function(i, file) {
  747. totalImagesCount++;
  748. });
  749. up.refresh(); // Reposition Flash/Silverlight
  750. // automatically start upload, no need to click a button
  751. ChuteUploader.start();
  752. });
  753. ChuteUploader.bind('UploadProgress', function(up, file) {
  754. totalUploadPercentDone = (file.percent + uploadedImagesCount*100)/totalImagesCount;
  755. me.setChuteFileProgress(totalUploadPercentDone);
  756. });
  757. ChuteUploader.bind('Error', function(up, err) {
  758. alert('Files cannot be larger than ' + maxFileSize);
  759. up.refresh(); // Reposition Flash/Silverlight
  760. });
  761. ChuteUploader.bind('FileUploaded', function(up, file) {
  762. uploadedImagesCount ++;
  763. totalUploadPercentDone = (uploadedImagesCount*100)/totalImagesCount;
  764. me.setChuteFileProgress(totalUploadPercentDone);
  765. });
  766. ChuteUploader.bind('UploadComplete', function(up, file) {
  767. totalUploadPercentDone = 100;
  768. me.setChuteFileProgress(totalUploadPercentDone);
  769. me.openChuteBrowser();
  770. });
  771. me.setChuteFileProgress = function(progress){
  772. if (progress < 100) {
  773. me.$element.find('.chute-collector').addClass('chute-uploading');
  774. } else {
  775. me.$element.find('.chute-collector').removeClass('chute-uploading');
  776. }
  777. me.$element.find('.chute-uploadProgress .chute-bar').css('width', progress + "%");
  778. }
  779. // upload code - end
  780. },
  781. resetTimestamp: function(){
  782. var d = new Date();
  783. var timestamp = ("" + (d.getTime()-d.getMilliseconds())/1000 + "-" + Math.random()).replace("0.", "");
  784. this.options.timestamp = timestamp;
  785. var toURIParams = function(obj) {
  786. var val, params=[];
  787. for (var key in obj) {
  788. val = obj[key];
  789. if (val && typeof val != 'undefined' && (val.length > 0 || typeof val === 'number')) {
  790. params.push(key + "=" + encodeURIComponent(val));
  791. }
  792. }
  793. return params.join('&');
  794. };
  795. this.options.uploadPath = this.options.uploadServer + '/upload?' + toURIParams({
  796. timestamp : this.options.timestamp,
  797. app_id : this.options.app,
  798. id : this.options.id,
  799. identifier : this.options.identifier,
  800. title : this.options.name,
  801. url : this.options.url,
  802. tags : this.options.tags,
  803. screens : this.options.screens,
  804. css : this.options.css,
  805. captions : this.options.captions,
  806. exclusions : this.options.exclusions,
  807. inclusions : this.options.inclusions
  808. });
  809. this.options.browsePath = this.options.uploadServer + '/payload/' + this.options.timestamp + "?" + toURIParams({
  810. app_id : this.options.app,
  811. id : this.options.id,
  812. identifier : this.options.identifier,
  813. custom_id : this.options.custom_id,
  814. title : this.options.name,
  815. url : this.options.url,
  816. tags : this.options.tags,
  817. host : document.location.host,
  818. page : document.location.href,
  819. screens : this.options.screens,
  820. css : this.options.css,
  821. scripts : this.options.scripts,
  822. iframe : this.options.iframe,
  823. iframe_position : this.options.iframe_position,
  824. iframe_title : this.options.iframe_title,
  825. captions : this.options.captions,
  826. exclusions : this.options.exclusions,
  827. inclusions : this.options.inclusions,
  828. dialog_title : this.options.dialogTitle,
  829. popup : this.options.popup.toString(),
  830. picker_version : this.options.picker_version,
  831. limit : this.options.limit,
  832. config : this.options.config
  833. });
  834. this.options.imagesUrl = this.options.apiServer + '/widget/data?' + toURIParams({
  835. app_id : this.options.app,
  836. id : this.options.id,
  837. identifier : this.options.identifier,
  838. origin : document.location.host
  839. });
  840. },
  841. resetIframe: function(){
  842. this.$element.find(".chute-popup iframe").attr('src', "//s3.amazonaws.com/cdn.getchute.com/html/v1/loading.html");
  843. },
  844. uploadComplete: function(data){
  845. if (data.moderated && !this.options.popup){
  846. if (data.success_message && typeof data.success_message === 'string' && data.success_message.length > 0) {
  847. this.$element.find('.chute-thanks .chute-thanks-header').html(data.success_message);
  848. }
  849. this.$element.find('.chute-thanks').chuteReveal();
  850. }
  851. this.options.onSelectionComplete(this.$element, data);
  852. if (typeof(chuteSelectionComplete) == 'function'){
  853. chuteSelectionComplete(this.$element, data);
  854. }
  855. },
  856. //////////////////////////////////////////////////////////
  857. // Presenters
  858. //////////////////////////////////////////////////////////
  859. assetsRendered: function(element, data){
  860. var chuteThumbnailReveal = jQuery('#chute-thumbnail-reveal');
  861. if (chuteThumbnailReveal.length == 0){
  862. jQuery('body').append('<div class="chute-thumbnail-reveal-modal" id="chute-thumbnail-reveal"><img src=""><a class="chute-thumbnail-source" href="" target="_blank">source</a><a class="close-chute-thumbnail-reveal-modal">&#215;</a></div>');
  863. chuteThumbnailReveal = jQuery('#chute-thumbnail-reveal');
  864. }
  865. element.find('.chute-thumbnails a').live('click', function(event){
  866. event.preventDefault();
  867. chuteThumbnailReveal.find('img').attr('src', $(this).attr('data-url'));
  868. chuteThumbnailReveal.find('.chute-thumbnail-source').attr('href', $(this).attr('data-source-url'));
  869. chuteThumbnailReveal.chuteReveal({
  870. dismissmodalclass: 'close-chute-thumbnail-reveal-modal',
  871. top: "50px"
  872. });
  873. });
  874. },
  875. // Render Display Template
  876. displayRender: function(data, loadState) {
  877. var _templateDefinition = typeof(this.options.display_template) == 'string' ? this.options.display_template : this.options.display_template.template;
  878. var _templateContainer = typeof(this.options.display_template) == 'string' ? null : this.options.display_template.templateContainer;
  879. for (var key in this.options.template_options){
  880. if (this.options.display_template.options[key]){
  881. this.options.display_template.options[key].value = this.options.template_options[key];
  882. }
  883. }
  884. if (typeof(this.options.display_template.options) != 'undefined') {
  885. this.options.display_template.options.share_text = this.options.share_text;
  886. this.options.display_template.options.awesm_key = this.options.awesm_key;
  887. this.options.display_template.options.chute_id = this.options.chute_id;
  888. this.options.display_template.options.widget_id = this.options.widget_id;
  889. }
  890. for (var i in data.data.assets) {
  891. data.data.assets[i].serialized = encodeURIComponent($.serializeJSON(data.data.assets[i]).replace(/(\r\n|\n|\r|\t)/gm, ""));
  892. }
  893. var _html = ChuteMustache.to_html(_templateDefinition, { images: data.data.assets, options : this.options.display_template.options });
  894. if (_templateContainer){
  895. _html = _templateContainer.replace("{{yield}}", _html);
  896. }
  897. var appendContent = false;
  898. if (this.options.display_template.systemOptions && this.options.display_template.systemOptions.appendContent)
  899. appendContent = true;
  900. if (loadState > -1){
  901. if (_templateContainer){
  902. // new data
  903. if (loadState == 0)
  904. this.options.templateContainer.prepend(_html);
  905. // paginated data
  906. else if (appendContent)
  907. this.options.templateContainer.append(_html);
  908. else
  909. this.options.templateContainer.html(_html);
  910. } else {
  911. // new data
  912. if (loadState == 0)
  913. this.$element.prepend(_html);
  914. // paginted data
  915. else if (appendContent)
  916. this.$element.append(_html);
  917. else
  918. this.$element.html(_html);
  919. }
  920. this.options.onAssetsReRendered(this.$element, data, this.options.display_template.options, loadState);
  921. } else {
  922. this.options.templateContainer = this.$element.html(_html);
  923. if (typeof(this.options.onAssetsRendered) == 'function')
  924. this.options.onAssetsRendered(this.$element, data, this.options.display_template.options);
  925. }
  926. }
  927. };
  928. var methods = {
  929. init : function(options){
  930. if (options == undefined) options = {};
  931. return this.each(function () {
  932. var chute = $.extend({}, CHUTE);
  933. chute.init(this, options);
  934. chute.$element.data('callback', function(){
  935. if(chute.options.popup) {
  936. // do something
  937. } else {
  938. chute.$element.find(".close-chute-reveal-modal").click();
  939. }
  940. });
  941. if (options != undefined && typeof(options.success) == "function"){
  942. chute.$element.data('success-callback', options.success);
  943. }
  944. });
  945. },
  946. chooser : function(callback){
  947. var me = $(this);
  948. if (callback != undefined)
  949. me.data('success-callback', callback);
  950. me.find('.chute-browseButton').click();
  951. return me;
  952. },
  953. close : function(){
  954. var me = $(this);
  955. me.find('.close-chute-reveal-modal').click();
  956. return me;
  957. },
  958. success : function(files){
  959. var me = $(this);
  960. if (typeof(me.data('callback')) == 'function')
  961. me.data('callback')();
  962. if (typeof(me.data('success-callback')) == 'function')
  963. me.data('success-callback')(files);
  964. return me;
  965. },
  966. widget : function(){
  967. return $(this).find('.chute-popup iframe');
  968. }
  969. }
  970. $.fn.chute = function(method, callback){
  971. if (method == undefined || typeof(method) == 'object'){
  972. return methods.init.apply( this, arguments );
  973. } else if ( methods[method] ) {
  974. return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
  975. } else {
  976. $.error( 'Method ' + method + ' does not exist on jQuery.chute' );
  977. }
  978. };
  979. })(jQuery);
  980. (function($) {
  981. if ($chuteWidget != undefined){
  982. // add listsners just once
  983. $('.chute-widget:not(.chute-loaded)').chute();
  984. return;
  985. }
  986. $chuteWidget = 'chute';
  987. if (document.addEventListener){
  988. window.addEventListener('message', receiveMessage, false);
  989. } else {
  990. window.attachEvent('onmessage', receiveMessage);
  991. }
  992. function receiveMessage(event){
  993. receiveData(event.data);
  994. }
  995. function parseJSON(data){
  996. if (typeof(JSON) != 'undefined'){
  997. return JSON.parse(data);
  998. } else {
  999. return $.parseJSON(data);
  1000. }
  1001. }
  1002. function receiveData(data){
  1003. try {
  1004. data = parseJSON(data);
  1005. } catch(ex){
  1006. data = data;
  1007. }
  1008. if (currentWidget && data.moderated != undefined){
  1009. currentWidget.$element.chute('success', data);
  1010. currentWidget.uploadComplete(data);
  1011. }
  1012. }
  1013. chuteImageLoaded = function(image){
  1014. $(image).chuteScaleImage({fade: Math.floor(Math.random()*1000)});
  1015. }
  1016. })(jQuery);
  1017. /*********************************************
  1018. mustache
  1019. **********************************************/
  1020. /*
  1021. mustache.js — Logic-less templates in JavaScript
  1022. See http://mustache.github.com/ for more info.
  1023. */
  1024. ChuteMustache = function() {
  1025. var regexCache = {};
  1026. var Renderer = function() {};
  1027. Renderer.prototype = {
  1028. otag: "{{",
  1029. ctag: "}}",
  1030. pragmas: {},
  1031. buffer: [],
  1032. pragmas_implemented: {
  1033. "IMPLICIT-ITERATOR": true
  1034. },
  1035. context: {},
  1036. render: function(template, context, partials, in_recursion) {
  1037. // reset buffer & set context
  1038. if(!in_recursion) {
  1039. this.context = context;
  1040. this.buffer = []; // TODO: make this non-lazy
  1041. }
  1042. // fail fast
  1043. if(!this.includes("", template)) {
  1044. if(in_recursion) {
  1045. return template;
  1046. } else {
  1047. this.send(template);
  1048. return;
  1049. }
  1050. }
  1051. // get the pragmas together
  1052. template = this.render_pragmas(template);
  1053. // render the template
  1054. var html = this.render_section(template, context, partials);
  1055. // render_section did not find any sections, we still need to render the tags
  1056. if (html === false) {
  1057. html = this.render_tags(template, context, partials, in_recursion);
  1058. }
  1059. if (in_recursion) {
  1060. return html;
  1061. } else {
  1062. this.sendLines(html);
  1063. }
  1064. },
  1065. /*
  1066. Sends parsed lines
  1067. */
  1068. send: function(line) {
  1069. if(line !== "") {
  1070. this.buffer.push(line);
  1071. }
  1072. },
  1073. sendLines: function(text) {
  1074. if (text) {
  1075. var lines = text.split("\n");
  1076. for (var i = 0; i < lines.length; i++) {
  1077. this.send(lines[i]);
  1078. }
  1079. }
  1080. },
  1081. /*
  1082. Looks for %PRAGMAS
  1083. */
  1084. render_pragmas: function(template) {
  1085. // no pragmas
  1086. if(!this.includes("%", template)) {
  1087. return template;
  1088. }
  1089. var that = this;
  1090. var regex = this.getCachedRegex("render_pragmas", function(otag, ctag) {
  1091. return new RegExp(otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + ctag, "g");
  1092. });
  1093. return template.replace(regex, function(match, pragma, options) {
  1094. if(!that.pragmas_implemented[pragma]) {
  1095. throw({message:
  1096. "This implementation of mustache doesn't understand the '" +
  1097. pragma + "' pragma"});
  1098. }
  1099. that.pragmas[pragma] = {};
  1100. if(options) {
  1101. var opts = options.split("=");
  1102. that.pragmas[pragma][opts[0]] = opts[1];
  1103. }
  1104. return "";
  1105. // ignore unknown pragmas silently
  1106. });
  1107. },
  1108. /*
  1109. Tries to find a partial in the curent scope and render it
  1110. */
  1111. render_partial: function(name, context, partials) {
  1112. name = this.trim(name);
  1113. if(!partials || partials[name] === undefined) {
  1114. throw({message: "unknown_partial '" + name + "'"});
  1115. }
  1116. if(typeof(context[name]) != "object") {
  1117. return this.render(partials[name], context, partials, true);
  1118. }
  1119. return this.render(partials[name], context[name], partials, true);
  1120. },
  1121. /*
  1122. Renders inverted (^) and normal (#) sections
  1123. */
  1124. render_section: function(template, context, partials) {
  1125. if(!this.includes("#", template) && !this.includes("^", template)) {
  1126. // did not render anything, there were no sections
  1127. return false;
  1128. }
  1129. var that = this;
  1130. var regex = this.getCachedRegex("render_section", function(otag, ctag) {
  1131. // This regex matches _the first_ section ({{#foo}}{{/foo}}), and captures the remainder
  1132. return new RegExp(
  1133. "^([\\s\\S]*?)" + // all the crap at the beginning that is not {{*}} ($1)
  1134. otag + // {{
  1135. "(\\^|\\#)\\s*(.+)\\s*" + // #foo (# == $2, foo == $3)
  1136. ctag + // }}
  1137. "\n*([\\s\\S]*?)" + // between the tag ($2). leading newlines are dropped
  1138. otag + // {{
  1139. "\\/\\s*\\3\\s*" + // /foo (backreference to the opening tag).
  1140. ctag + // }}
  1141. "\\s*([\\s\\S]*)$", // everything else in the string ($4).…

Large files files are truncated, but you can click here to view the full file