PageRenderTime 35ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 1ms

/t/upfront/scripts/upfront/upfront-media.js

https://bitbucket.org/matthewselby/wpdev
JavaScript | 2868 lines | 2558 code | 158 blank | 152 comment | 275 complexity | 8799fe65b60e14287bb765d5bd21c8a9 MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0, LGPL-3.0, LGPL-2.1, AGPL-1.0, BSD-3-Clause, MIT, GPL-3.0, MPL-2.0-no-copyleft-exception

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

  1. (function ($, undefined) {
  2. define([
  3. 'scripts/upfront/upfront-media/insert-options-item-control',
  4. 'scripts/perfect-scrollbar/perfect-scrollbar'
  5. ], function(InsertOptions, perfectScrollbar) {
  6. var MEDIA_SIZES = {
  7. FULL: "full",
  8. to_size: function (size) {
  9. return size.width + 'x' + size.height;
  10. }
  11. };
  12. var l10n = Upfront.Settings.l10n.media;
  13. var INSERT_OPTIONS = InsertOptions.INSERT_OPTIONS;
  14. // ----- Models -----
  15. var MediaItem_Model = Backbone.Model.extend({
  16. defaults: {
  17. thumbnail: "<span class='upfront-image-upload-placeholder'></span>",
  18. insert_option: "image_insert"
  19. }
  20. });
  21. var MediaCollection_Model = Backbone.Collection.extend({
  22. defaults:{
  23. thumbnail: '',
  24. title: ''
  25. }
  26. });
  27. var MediaCollection_Selection = Backbone.Collection.extend({
  28. model: MediaItem_Model,
  29. initialize: function () {
  30. this.listenTo(Upfront.Events, "media_manager:media:labels_loaded", this.global_labels_loaded);
  31. },
  32. get_shared_labels: function () {
  33. var known_labels = ActiveFilters.get("label"),
  34. selected_labels = [],
  35. shared_labels = [],
  36. tmp_shared = {}
  37. ;
  38. this.each(function (item) {
  39. var labels = item.get("labels") || [];
  40. labels = _.map(labels, function(each){ return parseInt(each, 10); });
  41. tmp_shared[item.get("ID")] = labels;
  42. });
  43. selected_labels = _.intersection.apply(this, _(tmp_shared).values());
  44. known_labels.each(function (label) {
  45. if (
  46. selected_labels.indexOf(label.get("value")) >= 0
  47. ||
  48. selected_labels.indexOf(parseInt(label.get("value"), 10)) >= 0
  49. ) shared_labels.push(label);
  50. });
  51. return shared_labels;
  52. },
  53. get_additional_sizes: function () {
  54. if (!ActiveFilters.multiple_sizes) return false; // Do not use multiple sizes if we're told not to
  55. var all_item_sizes = this.invoke("get", "additional_sizes"),
  56. item_sizes = []
  57. ;
  58. _(all_item_sizes).each(function (item, idx) {
  59. var tmp_sizes = [];
  60. if (!idx) item_sizes = _(item).map(function (size) { return MEDIA_SIZES.to_size(size);});
  61. _(item).each(function (size) {
  62. tmp_sizes.push(MEDIA_SIZES.to_size(size));
  63. });
  64. item_sizes = _.intersection(item_sizes, tmp_sizes);
  65. });
  66. item_sizes.push(MEDIA_SIZES.FULL);
  67. return item_sizes;
  68. },
  69. is_used_label: function (label) {
  70. return (_(this.get_shared_labels()).invoke("get", "value").indexOf(label.get("value")) >= 0);
  71. },
  72. update_label_state: function (label) {
  73. return this.is_used_label(label)
  74. ? this.disassociate_label(label)
  75. : this.associate_label(label)
  76. ;
  77. },
  78. associate_label: function (label) {
  79. this._update_label('', label);
  80. },
  81. disassociate_label: function (label) {
  82. this._update_label('dis', label);
  83. },
  84. _update_label: function (pfx, label) {
  85. pfx = pfx || '';
  86. var me = this,
  87. idx = label.get("value"),
  88. data = {
  89. action: "upfront-media-" + pfx + "associate_label",
  90. term: idx,
  91. post_ids: this.invoke("get", "ID")
  92. }
  93. ;
  94. Upfront.Util.post(data)
  95. .success(function (response) {
  96. me.each(function (model) {
  97. var labels = response.data[model.get("ID")];
  98. if (labels) model.set({labels: labels}, {silent: true});
  99. });
  100. me.trigger("change");
  101. })
  102. ;
  103. },
  104. add_new_label: function (label) {
  105. var me = this,
  106. data = {
  107. "action": "upfront-media-add_label",
  108. "term": label,
  109. "post_ids": this.invoke("get", "ID")
  110. }
  111. ;
  112. return Upfront.Util.post(data)
  113. .success(function (response) {
  114. me.each(function (model) {
  115. var labels = response.data[model.get("ID")];
  116. if (labels) model.set({labels: labels}, {silent: true});
  117. });
  118. Upfront.Events.trigger("media_manager:media:labels_updated");
  119. me.trigger("change");
  120. })
  121. ;
  122. },
  123. delete_media_items: function () {
  124. var me = this,
  125. data = {
  126. "action": "upfront-media-remove_item",
  127. "post_ids": this.invoke("get", "ID")
  128. }
  129. ;
  130. Upfront.Util.post(data)
  131. .success(function (response) {
  132. me.reset([]);
  133. Upfront.Events.trigger("media_manager:media:list", ActiveFilters);
  134. })
  135. ;
  136. },
  137. // Same as delete_media_items except for theme/UI images.
  138. delete_theme_items: function () {
  139. var me = this,
  140. data = {
  141. "action": "upfront-media-remove_theme_item",
  142. // Theme images use file names rather than post IDs.
  143. "post_ids": this.invoke("get", "post_title")
  144. }
  145. ;
  146. Upfront.Util.post(data)
  147. .success(function (response) {
  148. me.reset([]);
  149. Upfront.Events.trigger("media_manager:media:list", ActiveFilters);
  150. })
  151. ;
  152. },
  153. global_labels_loaded: function () {
  154. this.trigger("change");
  155. }
  156. });
  157. var MediaFilter_Item = Backbone.Model.extend({
  158. });
  159. var MediaFilter_Collection = Backbone.Collection.extend({
  160. model: MediaFilter_Item
  161. });
  162. var ActiveMediaFilter_Collection = Backbone.Model.extend({
  163. CONST: {
  164. CUTOFF_SIZE: 8,
  165. CUTOFF_BIT: 3
  166. },
  167. labels_cache: false,
  168. default_media_types: ['images', 'videos', 'audios', 'other'],
  169. allowed_media_types: [],
  170. image_sizes: true,
  171. showing_titles: true,
  172. current_keys: [],
  173. current_models: [],
  174. current_page: 1,
  175. max_pages: 1,
  176. max_items: 1,
  177. media_limit: 60,
  178. current_filter_control: 0,
  179. initialize: function () {
  180. this.to_defaults();
  181. this.listenTo(Upfront.Events, "media_manager:media:filters_updated", this.update_active_filters);
  182. this.listenTo(Upfront.Events, "media_manager:media:labels_updated", this.reload_labels);
  183. this.listenTo(Upfront.Events, "media_manager:media:toggle_titles", this.toggle_titles);
  184. },
  185. to_defaults: function () {
  186. var types = new MediaFilter_Collection([]),
  187. has_all = (this.allowed_media_types.indexOf('other') >= 0)
  188. ;
  189. if (!this.allowed_media_types.length) this.allowed_media_types = this.default_media_types;
  190. if (this.allowed_media_types.indexOf('images') >= 0) types.add(new MediaFilter_Item({filter: l10n.filter.images, value: 'images', state: !has_all}), {silent: true});
  191. if (this.allowed_media_types.indexOf('videos') >= 0) types.add(new MediaFilter_Item({filter: l10n.filter.videos, value: 'videos', state: !has_all}), {silent: true});
  192. if (this.allowed_media_types.indexOf('audios') >= 0) types.add(new MediaFilter_Item({filter: l10n.filter.audios, value: 'audios', state: !has_all}), {silent: true});
  193. if (this.allowed_media_types.indexOf('other') >= 0) types.add(new MediaFilter_Item({filter: l10n.filter.all, value: 'other', state: has_all}), {silent: true});
  194. this.set("type", types, {silent: true});
  195. this.set("recent", new MediaFilter_Collection([
  196. new MediaFilter_Item({filter: "5", value: 5, state: false}),
  197. new MediaFilter_Item({filter: "10", value: 10, state: false}),
  198. new MediaFilter_Item({filter: "20", value: 20, state: false}),
  199. new MediaFilter_Item({filter: "40", value: 40, state: false}),
  200. new MediaFilter_Item({filter: "100", value: 100, state: false})
  201. ]), {silent: true});
  202. this.set("order", new MediaFilter_Collection([
  203. new MediaFilter_Item({filter: l10n.filter.newest, value: 'date_desc', state: true}),
  204. new MediaFilter_Item({filter: l10n.filter.oldest, value: 'date_asc', state: false}),
  205. new MediaFilter_Item({filter: l10n.filter.a_z, value: 'title_asc', state: false}),
  206. new MediaFilter_Item({filter: l10n.filter.z_a, value: 'title_desc', state: false})
  207. ]), {silent: true});
  208. this.set({"search": new MediaFilter_Collection([])}, {silent: true});
  209. this.themeImages =false;
  210. this.current_page = 1;
  211. this.current_filter_control = 0;
  212. this.set_labels_to_defaults();
  213. },
  214. set_max_pages: function (max) {
  215. this.max_pages = !_.isUndefined(max) ? max : 1;
  216. },
  217. set_max_items: function (max) {
  218. this.max_items = !_.isUndefined(max) ? max : 1;
  219. },
  220. prev_page: function () {
  221. if (this.current_page > 1) return this.set_page(this.current_page-1);
  222. },
  223. next_page: function () {
  224. if (this.current_page < this.max_pages) return this.set_page(this.current_page+1);
  225. },
  226. set_page: function (page) {
  227. if (!page) return false;
  228. if (page >= 1 && page < this.max_pages) {
  229. if (page == this.current_page) return false; // Already here.
  230. this.current_page = page;
  231. return true;
  232. } else return false;
  233. },
  234. toggle_titles: function () {
  235. this.showing_titles = !this.showing_titles;
  236. },
  237. set_labels_to_defaults: function () {
  238. if (this.labels_cache) {
  239. var arr = [];
  240. _(this.labels_cache).each(function (item) {
  241. arr.push(new MediaFilter_Item({filter: item.name, value: item.term_id, state: false}));
  242. });
  243. this.set("label", new MediaFilter_Collection(arr), {silent: true});
  244. Upfront.Events.trigger("media_manager:media:labels_loaded");
  245. } else this.reload_labels();
  246. },
  247. reload_labels: function () {
  248. var me = this;
  249. Upfront.Util.post({action: "upfront-media-get_labels"})
  250. .success(function (response) {
  251. var arr = [];
  252. if (response.data) {
  253. me.labels_cache = response.data;
  254. me.set_labels_to_defaults();
  255. }
  256. })
  257. ;
  258. },
  259. update_active_filters: function (filter, data) {
  260. if (!filter || !this.get(filter)) {
  261. this.to_defaults();
  262. Upfront.Events.trigger("media_manager:media:filters_reset");
  263. } else {
  264. var collection = data && data.get ? data.get(filter).toArray() : data,
  265. me = this.get(filter)
  266. ;
  267. _(collection).each(function (item) {
  268. if (item.get("state")) {
  269. var has = me.where({filter: item.get("filter")});
  270. if (has.length) {
  271. has[0].set({state: item.get("state")}, {silent: true});
  272. }
  273. }
  274. });
  275. // Reset page to 1
  276. this.set_page(1);
  277. }
  278. Upfront.Events.trigger("media_manager:media:list", this);
  279. },
  280. to_request_json: function () {
  281. var data = {},
  282. me = this
  283. ;
  284. _(this.attributes).each(function (collection, idx) {
  285. var active = me.get(idx).where({state:true});
  286. data[idx] = _(active).invoke("get", "value");
  287. });
  288. data.page = this.current_page;
  289. return data;
  290. },
  291. to_list: function () {
  292. var data = {},
  293. me = this
  294. ;
  295. _(this.attributes).each(function (collection, idx) {
  296. var active = me.get(idx).where({state:true}),
  297. active_non_defaults = []
  298. ;
  299. active_non_defaults = _(active).filter(function (filter) {
  300. var value = filter.get("value");
  301. return "other" !== value && "date_desc" !== value;
  302. });
  303. data[idx] = _(active_non_defaults).invoke("get", "filter");
  304. });
  305. return data;
  306. },
  307. has_upload: function () {
  308. if ( Upfront.Settings.Application.PERMS.UPLOAD ) {
  309. if (!this.themeImages) return true; // Allow when not looking into theme images
  310. return true === Upfront.plugins.isRequiredByPlugin('media filter upload');
  311. } else {
  312. return false; // disabling upload when user role has no permission
  313. }
  314. }
  315. });
  316. var ActiveFilters = new ActiveMediaFilter_Collection();
  317. // ----- Views -----
  318. var MediaManager_Controls_View = Backbone.View.extend({
  319. className: "upfront-media-controls",
  320. is_search_active: false,
  321. initialize: function (args) {
  322. this.listenTo(Upfront.Events, "media:item:selection_changed", this.switch_controls);
  323. this.listenTo(Upfront.Events, "media:search:requested", this.switch_to_search);
  324. this.listenTo(Upfront.Events, "media_manager:load:done", this.render_filters);
  325. this.options = args.options;
  326. },
  327. render: function () {
  328. if (!this.options.show_insert) {
  329. this.$el.addClass('upfront-media-controls-no-insert');
  330. }
  331. this.render_filters();
  332. },
  333. render_filters: function () {
  334. if (this.search) this.search.remove();
  335. this.search = new MediaManager_SearchControl();
  336. if (this.control) this.control.remove();
  337. this.control = this.is_search_active ? new MediaManager_SearchFiltersControl() : new MediaManager_FiltersControl();
  338. this.search.render();
  339. this.control.render();
  340. this.$el.empty().append(this.search.$el).append(this.control.$el);
  341. if ( this.is_search_active ) this.$el.removeClass('upfront-media-controls-search-selected').addClass('upfront-media-controls-search');
  342. else this.$el.removeClass('upfront-media-controls-search');
  343. },
  344. render_media: function (selected) {
  345. var item_control = new MediaManager_ItemControl({model: new MediaCollection_Selection(selected), options: this.options});
  346. item_control.render();
  347. this.$el.empty();
  348. if (this.is_search_active) {
  349. this.control = new MediaManager_SearchFiltersControl();
  350. this.control.render();
  351. this.$el.append(this.control.$el);
  352. this.$el.removeClass('upfront-media-controls-search').addClass('upfront-media-controls-search-selected');
  353. }
  354. else
  355. this.$el.removeClass('upfront-media-controls-search-selected');
  356. this.$el.append(item_control.$el);
  357. },
  358. switch_controls: function (media_collection) {
  359. var positive = media_collection.where({selected: true});
  360. if (positive.length) this.render_media(positive);
  361. else this.render_filters();
  362. },
  363. switch_to_search: function (search) {
  364. this.is_search_active = search && search.get("state");
  365. //this.render_filters(); // This will be rendered later in another event to prevent double rendering in a row
  366. },
  367. remove: function() {
  368. if (this.control) this.control.remove();
  369. Backbone.View.prototype.remove.call(this);
  370. }
  371. });
  372. var MediaManager_AuxControls_View = Backbone.View.extend({
  373. className: "upfront-media-aux_controls",
  374. initialize: function () {
  375. this.listenTo(Upfront.Events, "media:item:selection_changed", this.switch_controls);
  376. },
  377. render: function () {
  378. //this.render_selection();
  379. },
  380. /*render_selection: function () {
  381. var selection_control = new MediaManager_SelectionControl({model: this.model});
  382. selection_control.render();
  383. this.$el.empty().append(selection_control.$el);
  384. this.$el.removeClass('upfront-media-aux_controls-has-select');
  385. },*/
  386. render_delete: function (selected) {
  387. var delete_control = new MediaManager_DeleteControl({model: new MediaCollection_Selection(selected)});
  388. delete_control.render();
  389. //this.render_selection();
  390. this.$el.empty().append(delete_control.$el);
  391. this.$el.addClass('upfront-media-aux_controls-has-select');
  392. },
  393. switch_controls: function (media_collection) {
  394. var positive = media_collection && media_collection.where ? media_collection.where({selected: true}) : [];
  395. if (positive.length) this.render_delete(positive);
  396. //else this.render_selection();
  397. }
  398. });
  399. var MediaManager_SelectionControl = Backbone.View.extend({
  400. className: "select_control_container",
  401. events: {
  402. "click a.none": "select_none",
  403. "click a.all": "select_all"
  404. },
  405. initialize: function () {
  406. this.display_values = [
  407. {label: '20', value: 20},
  408. {label: '40', value: 40},
  409. {label: '60', value: 60},
  410. {label: '80', value: 80},
  411. {label: '100', value: 100}
  412. ];
  413. },
  414. render: function () {
  415. var me = this;
  416. me.$el.empty().append(l10n.select + ' <a href="#all" class="all">' + l10n.all + '</a>&nbsp;|&nbsp;<a href="#none" class="none">' + l10n.none + '</a>');
  417. me.select_display_field = new Upfront.Views.Editor.Field.Select({
  418. label: l10n.display+":",
  419. className: "upfront-field-wrap upfront-field-wrap-select upfront-filter_display_control",
  420. name: "display-selection",
  421. width: '70px',
  422. values: me.display_values,
  423. multiple: false,
  424. default_value: ActiveFilters.media_limit,
  425. change: function(){
  426. me.select_display(this.get_value());
  427. }
  428. });
  429. me.select_display_field.render();
  430. me.$el.append(me.select_display_field.$el);
  431. },
  432. select_display: function (limit) {
  433. ActiveFilters.media_limit = limit;
  434. Upfront.Events.trigger("media_manager:media:list", ActiveFilters);
  435. },
  436. select_none: function (e) {
  437. e.preventDefault();
  438. e.stopPropagation();
  439. var positive = this.model.where({selected: true});
  440. if ( positive.length ) {
  441. this.model.each(function (item) {
  442. item.set({selected: false}, {silent: true});
  443. });
  444. this.model.trigger("change");
  445. Upfront.Events.trigger("media:item:selection_changed", this.model);
  446. // run again to apply the new list
  447. var selected_model = new MediaCollection_Selection(ActiveFilters.current_models);
  448. Upfront.Events.trigger("media:item:selection_changed", selected_model);
  449. }
  450. },
  451. select_all: function (e) {
  452. e.preventDefault();
  453. e.stopPropagation();
  454. var all = [];
  455. this.model.each(function (item) {
  456. item.set({selected: true}, {silent: true});
  457. all.push(item);
  458. });
  459. this.model.trigger("change");
  460. Upfront.Events.trigger("media:item:selection_changed", this.model);
  461. // run again to apply the new list
  462. var selected_model = new MediaCollection_Selection(ActiveFilters.current_models);
  463. Upfront.Events.trigger("media:item:selection_changed", selected_model);
  464. }
  465. });
  466. var MediaManager_DeleteControl = Backbone.View.extend({
  467. className: "delete_control_container upfront-icon upfront-icon-trash",
  468. events: {
  469. click: "delete_selection"
  470. },
  471. render: function () {
  472. this.$el.empty().append('<a href="#delete">' + l10n.del_command + '</a>');
  473. },
  474. delete_selection: function (e) {
  475. e.preventDefault();
  476. e.stopPropagation();
  477. if ( confirm(l10n.confirm_delete_items) ) {
  478. var show_nag = false;
  479. this.model.each(function (item) {
  480. if (item.get("parent")) show_nag = true;
  481. });
  482. if (!show_nag || (show_nag && confirm(l10n.item_in_use_nag))) {
  483. ActiveFilters.current_keys = [];
  484. ActiveFilters.current_models = [];
  485. // If theme image, delete via proper deletion method.
  486. if (ActiveFilters.themeImages) {
  487. return this.model.delete_theme_items();
  488. }
  489. // Otherwise delete media item.
  490. return this.model.delete_media_items();
  491. }
  492. }
  493. }
  494. });
  495. var MediaManager_ItemControl = Backbone.View.extend({
  496. className: "upfront-item-control",
  497. options: {
  498. insert_options: false,
  499. hide_sizes: false
  500. },
  501. templates: {
  502. caption: _.template('<label class="upfront-field-label upfront-field-label-block">{{title}}</label>'),
  503. shared_label: _.template('<a href="#remove" class="upfront-icon upfront-icon-media-label-delete" data-idx="{{value}}">{{filter}}</a>'),
  504. additional_size: _.template('<option value="{{size}}">{{size}}</option>')
  505. },
  506. events: {
  507. //"change .change_title :text": "change_title",
  508. "click .existing_labels a": "drop_label"//,
  509. //"change .additional_sizes select": "select_size"
  510. },
  511. initialize: function ( opts ) {
  512. this.listenTo(this.model, "change", this.render);
  513. this.options = _.extend( this.options, opts.options );
  514. },
  515. render: function () {
  516. var self = this,
  517. sections = _([
  518. 'size_hints',
  519. 'change_title',
  520. 'change_alt',
  521. 'copy_url',
  522. //'existing_labels',
  523. 'add_labels',
  524. 'insert_options',
  525. 'additional_sizes'
  526. ]),
  527. renderers = _([
  528. 'render_size_hint',
  529. 'render_title',
  530. 'render_alt',
  531. 'render_copy_url',
  532. //'render_shared_labels',
  533. 'render_labels_adding',
  534. 'render_insert_options',
  535. 'render_additional_sizes'
  536. ]);
  537. // remove prev sections
  538. this.$el.empty();
  539. // if insert_options is false remove insert options section
  540. if( !this.options.insert_options ){
  541. sections = _( sections.reject(function(section){
  542. return section === "insert_options";
  543. }) );
  544. renderers = _( renderers.reject(function(renderer){
  545. return renderer === "render_insert_options";
  546. }) );
  547. }
  548. if (_.indexOf(this.options.media_type, 'videos') !== -1) {
  549. sections = _( sections.reject(function(section){
  550. return section === "additional_sizes";
  551. }) );
  552. renderers = _( renderers.reject(function(renderer){
  553. return renderer === "render_additional_sizes";
  554. }) );
  555. }
  556. // add sections
  557. sections.each(function(section){
  558. self.$el.append( '<div class="' + section + '" />' );
  559. });
  560. // render sections
  561. renderers.each(function(renderer){
  562. self[renderer]();
  563. });
  564. },
  565. _find_gcd: function (a, b) {
  566. return (b == 0) ? a : this._find_gcd(b, a%b);
  567. },
  568. render_size_hint: function() {
  569. var me = this,
  570. $hub = this.$el.find('.size_hints'),
  571. sizeWidth,
  572. sizeHeight;
  573. $hub.empty();
  574. if(this.model.length === 1) {
  575. var image = this.model.at(0).get('image'),
  576. $container = $('<div class="upfront-size-hints upfront-field-wrap upfront-field-wrap-text"><label class="upfront-field-label upfront-field-label-block">'+ l10n.information +'</label></div>')
  577. ;
  578. if ( image !== undefined ) {
  579. var iwidth = parseInt((image || {}).width, 10),
  580. iheight = parseInt((image || {}).height, 10),
  581. gcd = me._find_gcd(iwidth, iheight)
  582. ;
  583. // Only render size hint if we're actually able to
  584. if (iwidth && iheight) {
  585. $container.append(
  586. '<span class="upfront-size-hint-ratio">' +
  587. (iwidth/gcd) +
  588. ':' +
  589. (iheight/gcd) +
  590. '</span>'
  591. );
  592. $container.append(
  593. '<span class="upfront-size-hint-width">' +
  594. l10n.width_label +
  595. ': <span>' +
  596. image.width + l10n.px_label +
  597. '</span></span>'
  598. );
  599. $container.append(
  600. '<span class="upfront-size-hint-height">' +
  601. l10n.height_label +
  602. ': <span>' +
  603. image.height + l10n.px_label +
  604. '</span></span>'
  605. );
  606. $hub.append($container);
  607. }
  608. }
  609. }
  610. },
  611. render_alt: function () {
  612. var me = this,
  613. $hub = this.$el.find(".change_alt"),
  614. image = this.model.at(0).get('image');
  615. $hub.empty();
  616. if (this.model.length === 1) {
  617. this.alt_field = new Upfront.Views.Editor.Field.Text({
  618. model: this.model.at(0),
  619. label: l10n.media_alt,
  620. name: 'alt',
  621. change: function(){
  622. me.change_alt();
  623. }
  624. });
  625. this.alt_field.render();
  626. $hub.append(this.alt_field.$el);
  627. }
  628. },
  629. render_title: function () {
  630. var me = this,
  631. $hub = this.$el.find(".change_title")
  632. ;
  633. $hub.empty();
  634. if (this.model.length > 1) {
  635. var files = '<span class="selected_files">' + l10n.files.replace(/%d/, this.model.length) + '</span>',
  636. shared_labels = this.model.get_shared_labels()
  637. ;
  638. $hub.append('<label class="upfront-field-label upfront-field-label-block">'+ l10n.information +'</label>');
  639. $hub.append('<span class="selected_length">' + ( shared_labels.length > 0 ? l10n.selected.replace(/%s/, files) : l10n.selected_no_label.replace(/%s/, files) ) + '</span>');
  640. } else {
  641. this.title_field = new Upfront.Views.Editor.Field.Text({
  642. model: this.model.at(0),
  643. label: l10n.media_title,
  644. compact: true,
  645. name: 'post_title',
  646. change: function(){
  647. me.change_title();
  648. }
  649. });
  650. this.title_field.render();
  651. $hub.append(this.title_field.$el);
  652. }
  653. },
  654. render_copy_url: function () {
  655. var $hub = this.$el.find(".copy_url");
  656. if (this.model.length > 1) return false;
  657. this.copy_url = new Upfront.Views.Editor.Field.Button({
  658. model: this.model.at(0),
  659. label: l10n.copy_url,
  660. compact: true,
  661. name: "document_url",
  662. on_click: function () {
  663. Upfront.Util.add_to_clipboard(this.model.get('document_url'));
  664. }
  665. });
  666. this.copy_url.render();
  667. $hub.append(this.copy_url.$el);
  668. },
  669. render_labels_adding: function () {
  670. var me = this,
  671. $hub = this.$el.find(".add_labels"),
  672. container = new MediaManager_ItemControl_LabelsContainer({model: this.model})
  673. ;
  674. $hub.empty().append(this.templates.caption({title: l10n.media_labels}));
  675. container.render();
  676. $hub.append(container.$el);
  677. this.$el.on("click", function (e) {
  678. e.stopPropagation();
  679. container.trigger("filters:selection:click");
  680. });
  681. },
  682. render_shared_labels: function () {
  683. var me = this,
  684. $hub = this.$el.find(".existing_labels"),
  685. shared_labels = this.model.get_shared_labels(),
  686. title = (shared_labels.length > 1 ? l10n.current_labels : '')
  687. ;
  688. $hub.empty()
  689. .append(this.templates.caption({title: title}))
  690. ;
  691. _(shared_labels).each(function (label) {
  692. $hub.append(me.templates.shared_label(label.toJSON()));
  693. });
  694. },
  695. render_additional_sizes: function () {
  696. var me = this,
  697. $hub = this.$el.find(".additional_sizes"),
  698. additional_sizes = this.model.get_additional_sizes(),
  699. title = l10n.additional_sizes,
  700. sizes = []
  701. ;
  702. $hub.empty();
  703. if( ( this.options.insert_options && this.model.at(0).get("insert_option") === INSERT_OPTIONS.wp_insert) || ( !this.options.hide_sizes && !this.options.insert_options ) ) {
  704. if (!additional_sizes.length) return false;
  705. _(additional_sizes).each(function (size) {
  706. if (size === MEDIA_SIZES.FULL) return;
  707. sizes.push({ label: size, value: size });
  708. });
  709. this.size_field = new Upfront.Views.Editor.Field.Radios({
  710. model: this.model.at(0),
  711. name: 'selected_size',
  712. width: '100%',
  713. values: sizes,
  714. default_value: additional_sizes[0],
  715. change: function(){
  716. me.select_size();
  717. }
  718. });
  719. this.size_field.render();
  720. $hub.append(this.size_field.$el);
  721. this.size_field.$el.on("click", function (e) {
  722. e.stopPropagation();
  723. });
  724. }
  725. },
  726. select_size: function (e) {
  727. //e.stopPropagation();
  728. var size = this.size_field.get_value() || MEDIA_SIZES.FULL;
  729. this.model.each(function (model) {
  730. model.set({selected_size: size}, {silent: true});
  731. });
  732. },
  733. change_title: function (e) {
  734. //e.stopPropagation();
  735. var model = this.model.at(0);
  736. model.set({post_title: this.title_field.get_value()});
  737. var me = this,
  738. data = {
  739. action: "upfront-media-update_media_item",
  740. data: model.toJSON()
  741. }
  742. ;
  743. Upfront.Util.post(data)
  744. .done(function () {
  745. model.trigger("change");
  746. })
  747. ;
  748. model.trigger("appearance:update");
  749. },
  750. change_alt: function (e) {
  751. //e.stopPropagation();
  752. var model = this.model.at(0);
  753. model.set({alt: this.alt_field.get_value()});
  754. var me = this,
  755. data = {
  756. action: "upfront-media-update_media_item",
  757. data: model.toJSON()
  758. }
  759. ;
  760. Upfront.Util.post(data)
  761. .done(function () {
  762. model.trigger("change");
  763. })
  764. ;
  765. model.trigger("appearance:update");
  766. },
  767. drop_label: function (e) {
  768. e.preventDefault();
  769. e.stopPropagation();
  770. var $label = $(e.target),
  771. idx = $label.attr("data-idx"),
  772. shared = this.model.get_shared_labels(),
  773. label_idx = _(shared).invoke("get", "value").indexOf(idx),
  774. label = label_idx >= 0 && shared[label_idx] ? shared[label_idx] : false
  775. ;
  776. if (label) this.model.update_label_state(label);
  777. },
  778. render_insert_options: function(){
  779. var $this_section = this.$(".insert_options"),
  780. view = new InsertOptions.Options_Control( {model: this.model} );
  781. view.render();
  782. $this_section.html(view.el);
  783. }
  784. });
  785. var MediaManager_ItemControl_LabelsContainer = Backbone.View.extend({
  786. className: "upfront-additive_multiselection",
  787. selection: '',
  788. events: {
  789. "click .labels_filter": "stop_prop",
  790. "keyup .labels_filter :text.filter": "update_selection",
  791. "click .new_labels .toggle-add-label": "show_add_label",
  792. "click .new_labels .submit-label": "add_new_labels",
  793. "focus :text.filter": "add_focus_state",
  794. "blur :text.filter": "remove_focus_state",
  795. "keyup .new_labels :text.add-label": "enter_new_labels"
  796. },
  797. initialize: function () {
  798. this.listenTo(Upfront.Events, "media_manager:media:labels_updated", this.render);
  799. this._adding_label = false;
  800. },
  801. stop_prop: function (e) {
  802. e.stopPropagation();
  803. // Also let's focus the text field
  804. this.$el.find(":text.filter").focus();
  805. },
  806. add_focus_state: function (e) {
  807. this.$el.addClass('focus');
  808. },
  809. remove_focus_state: function (e) {
  810. this.$el.removeClass('focus');
  811. },
  812. render: function () {
  813. var sel = this.selection || '';
  814. this.$el.empty()
  815. .append('<div class="title">' + l10n.assigned_labels + '</div>')
  816. .append('<div class="labels_filter"><ul></ul><input type="text" class="filter upfront-field upfront-field-text" value="' + sel + '" placeholder="' + l10n.type_labels_pick + '" /></div>')
  817. .append('<div class="labels_list"><ul></ul></div>')
  818. .append('<div class="title">' + l10n.create_new_label + '</div>')
  819. .append('<div class="new_labels"><a class="toggle-add-label upfront-icon-control upfront-icon-label-add"></a><input type="text" class="add-label upfront-field upfront-field-text" placeholder="' + l10n.type_labels_add + '" /><a class="submit-label upfront-icon-control upfront-icon-label-add-alt"></a></div>')
  820. ;
  821. this.render_existing_labels();
  822. this.render_labels();
  823. },
  824. render_existing_labels: function () {
  825. var me = this,
  826. $hub = this.$el.find("div.labels_filter ul"),
  827. count = 0
  828. ;
  829. $hub.empty();
  830. _.each(this.model.get_shared_labels(), function (label) {
  831. var item = new MediaManager_ItemControl_LabelItem({model: label});
  832. item.media_items = me.model;
  833. item.render();
  834. $hub.append(item.$el);
  835. count++;
  836. });
  837. if (count > 0) {
  838. // Remove placeholder
  839. this.$el.find(".labels_filter :text.filter").attr('placeholder', '');
  840. }
  841. },
  842. render_labels: function () {
  843. var me = this,
  844. $hub = this.$el.find(".labels_list ul"),
  845. known_labels = ActiveFilters.get("label"),
  846. shared_labels = this.model.get_shared_labels(),
  847. has_selection = false,
  848. match = 0
  849. ;
  850. $hub.empty();
  851. if (!this.selection) return false;
  852. known_labels.each(function (label) {
  853. if (me.model.is_used_label(label)) return;
  854. var item = new MediaManager_ItemControl_LabelItem({model: label});
  855. item.shared = shared_labels;
  856. item.media_items = me.model;
  857. item.selection = me.selection;
  858. item.render();
  859. if (item.matched) {
  860. $hub.append(item.$el);
  861. match++;
  862. }
  863. });
  864. if (match > 0) this.$el.addClass('has_match');
  865. else this.$el.removeClass('has_match');
  866. },
  867. update_selection: function (e) {
  868. e.preventDefault();
  869. e.stopPropagation();
  870. var $text = this.$el.find(".labels_filter :text.filter"),
  871. selection = $text.val()
  872. ;
  873. this.selection = selection;
  874. this.render_labels();
  875. },
  876. show_add_label: function (e) {
  877. e.preventDefault();
  878. e.stopPropagation();
  879. var $hub = this.$el.find(".new_labels"),
  880. $text = this.$el.find(".new_labels :text.add-label")
  881. ;
  882. $hub.addClass('active');
  883. $text.focus();
  884. },
  885. enter_new_labels: function (e) {
  886. if (e.which == 13) {
  887. this.add_new_labels();
  888. }
  889. },
  890. add_new_labels: function (e) {
  891. if (e) {
  892. e.preventDefault();
  893. e.stopPropagation();
  894. }
  895. if (this._adding_label) return;
  896. var me = this,
  897. $hub = this.$el.find(".new_labels"),
  898. $text = this.$el.find(".new_labels :text.add-label"),
  899. selection = $text.val()
  900. ;
  901. this._adding_label = true;
  902. $text.attr('disabled', true);
  903. this.model.add_new_label(selection)
  904. .always(function(){
  905. me._adding_label = false;
  906. $text.val('').attr('disabled', false);
  907. })
  908. .fail(function(jqxhr){
  909. var response = jqxhr.responseJSON;
  910. if (response && response.error) {
  911. Upfront.Views.Editor.notify(response.error, 'error');
  912. }
  913. });
  914. }
  915. });
  916. var MediaManager_ItemControl_LabelItem = Backbone.View.extend({
  917. tagName: 'li',
  918. events: {
  919. click: "toggle_label_assignment"
  920. },
  921. render: function () {
  922. var me = this,
  923. is_used = this.media_items.is_used_label(this.model),
  924. used = _.template('<input type="checkbox" id="{{id}}" class="upfront-field-checkbox" value="{{value}}" checked />'),
  925. free = _.template('<input type="checkbox" id="{{id}}" class="upfront-field-checkbox" value="{{value}}" />'),
  926. label = _.template('<label for="{{id}}">{{name}}</label>'),
  927. name = this.model.get("filter") || '',
  928. match_rx = this.selection ? new RegExp('(' + this.selection + ')', 'i') : false,
  929. obj = this.model.toJSON()
  930. ;
  931. this.matched = false;
  932. this.$el.empty();
  933. if (match_rx && !name.match(match_rx)) return false;
  934. this.matched = true;
  935. obj.id = this.cid;
  936. obj.name = name.replace(match_rx, '<span class="selection">$1</span>');
  937. this.$el
  938. .append(label(obj))
  939. .append((is_used ? used : free)(obj))
  940. ;
  941. },
  942. toggle_label_assignment: function (e) {
  943. e.preventDefault();
  944. e.stopPropagation();
  945. this.media_items.update_label_state(this.model);
  946. }
  947. });
  948. var MediaManager_SearchFiltersControl = Backbone.View.extend({
  949. className: "upfront-search_filter-control",
  950. events: {
  951. "click a": "clear_search"
  952. },
  953. render: function () {
  954. var search = ActiveFilters.get("search").first(),
  955. obj = search.toJSON();
  956. obj.total = ActiveFilters.max_items;
  957. this.$el.empty().append(
  958. _.template(l10n.showing_total_results + ' <b class="search-text">{{value}}</b> <a href="#clear" class="clear_search">' + l10n.clear_search + '</a>', obj)
  959. );
  960. },
  961. clear_search: function (e) {
  962. e.preventDefault();
  963. e.stopPropagation();
  964. var search = new MediaFilter_Item({filter: false, value: false, state: false});
  965. ActiveFilters.set({search: new MediaFilter_Collection([search])});
  966. Upfront.Events.trigger("media_manager:media:list", ActiveFilters);
  967. Upfront.Events.trigger("media:search:requested", search);
  968. }
  969. });
  970. var MediaManager_FiltersControl = Backbone.View.extend({
  971. className: "upfront-filter-control",
  972. events: {
  973. "click": "stop_prop"
  974. },
  975. stop_prop: function (e) {
  976. e.stopPropagation();
  977. if (this.filter_selection) this.filter_selection.trigger("filters:outside_click");
  978. },
  979. initialize: function () {
  980. this.filter_selection = new MediaManager_FiltersSelectionControl();
  981. //this.filters_selected = new MediaManager_FiltersSelectedControl({model: ActiveFilters});
  982. },
  983. render: function () {
  984. this.filter_selection.render();
  985. //this.filters_selected.render();
  986. this.$el.empty()
  987. .append(this.filter_selection.$el)
  988. //.append(this.filters_selected.$el)
  989. ;
  990. },
  991. toggle_titles: function (e) {
  992. e.stopPropagation();
  993. Upfront.Events.trigger("media_manager:media:toggle_titles");
  994. },
  995. remove: function() {
  996. this.filter_selection.remove();
  997. //this.filters_selected.remove();
  998. Backbone.View.prototype.remove.call(this);
  999. }
  1000. });
  1001. var MediaManager_FiltersSelectedControl = Backbone.View.extend({
  1002. className: "upfront-filter_selected-control",
  1003. events: {
  1004. "click a.filter": "drop_filter",
  1005. "click a.all_filters": "drop_all"
  1006. },
  1007. initialize: function () {
  1008. this.listenTo(Upfront.Events, "media_manager:media:list", this.set_filters);
  1009. },
  1010. render: function () {
  1011. this.$el.empty();
  1012. var me = this,
  1013. _list = _(this.model.to_list()),
  1014. _to_render = _([]),
  1015. tpl = _.template(' <a href="#" class="filter upfront-icon upfront-icon-media-label-delete" data-type="{{type}}" data-filter="{{filter}}">{{filter}}</a>')
  1016. ;
  1017. _list.each(function (filters, type) {
  1018. _(filters).each(function (filter) {
  1019. _to_render.push({filter: filter, type: type});
  1020. });
  1021. });
  1022. if (!_to_render.size()) return false; // Do not render the empty filter array (ie. only defaults)
  1023. this.$el.append('<label class="upfront-field-label upfront-field-label-block">' + l10n.active_filters + '</label>');
  1024. _to_render.each(function (item) {
  1025. me.$el.append(tpl(item));
  1026. });
  1027. this.$el.append(" <a href='#' class='all_filters'>" + l10n.clear_all_filters + "</a>");
  1028. },
  1029. set_filters: function (filters) {
  1030. this.model = filters;
  1031. this.render();
  1032. },
  1033. drop_filter: function (e) {
  1034. e.preventDefault();
  1035. e.stopPropagation();
  1036. var $el = $(e.target),
  1037. all = this.model,
  1038. type = $el.attr("data-type"),
  1039. filter = $el.attr("data-filter")
  1040. ;
  1041. if (type && all.get(type)) {
  1042. var has = all.get(type).where({filter: filter});
  1043. if (has && has.length) _(has).invoke("set", {state: false}, {silent: true});
  1044. } else {
  1045. _(this.model.attributes).each(function (collection, idx) {
  1046. var has = all.get(idx).where({filter: filter});
  1047. if (has.length) {
  1048. type = idx;
  1049. _(has).invoke("set", {state: false}, {silent: true});
  1050. }
  1051. });
  1052. }
  1053. Upfront.Events.trigger("media_manager:media:filters_updated", type, this.model);
  1054. },
  1055. drop_all: function (e) {
  1056. e.preventDefault();
  1057. e.stopPropagation();
  1058. Upfront.Events.trigger("media_manager:media:filters_updated", false, false);
  1059. }
  1060. });
  1061. var MediaManager_FiltersSelectionControl = Backbone.View.extend({
  1062. className: "upfront-filter_selection-control clearfix",
  1063. initialize: function () {
  1064. this.controls = _([
  1065. new Control_MediaType(),
  1066. //new Control_MediaDate(),
  1067. //new Control_MediaFileName(),
  1068. //new Control_MediaRecent(),
  1069. new Control_MediaLabels()
  1070. ]);
  1071. this.on("filters:outside_click", function () {
  1072. this.controls.each(function (ctrl) {
  1073. ctrl.trigger("filters:selection:click");
  1074. });
  1075. }, this);
  1076. },
  1077. render: function () {
  1078. var me = this,
  1079. tpl = _.template("<li style='display:none'><a href='#' data-idx='{{idx}}'>{{name}}</a></li>"),
  1080. values = []
  1081. ;
  1082. this.controls.each(function (ctl, idx) {
  1083. values.push({label: ctl.get_name(), value: idx});
  1084. });
  1085. this.$el.empty();
  1086. this.$el.append('<div class="upfront-filter_control" />');
  1087. this.$control = this.$el.find("div.upfront-filter_control");
  1088. this.control_field = new Upfront.Views.Editor.Field.Radios({
  1089. label: l10n.filter_label,
  1090. name: "filter-selection",
  1091. className: "upfront-field-wrap upfront-field-wrap-multiple upfront-field-wrap-radios upfront-filter_selection-tab",
  1092. values: values,
  1093. multiple: false,
  1094. default_value: ActiveFilters.current_filter_control,
  1095. change: function(){
  1096. me.select_control(this.get_value());
  1097. }
  1098. });
  1099. this.control_field.render();
  1100. this.$el.prepend(this.control_field.$el);
  1101. this.control_field.trigger('changed');
  1102. },
  1103. select_control: function (idx) {
  1104. this.$control.empty();
  1105. if ('false' === idx) return false;
  1106. ActiveFilters.current_filter_control = idx;
  1107. var control = this.controls.toArray()[idx];
  1108. control.render();
  1109. this.$control.append(control.$el);
  1110. return false;
  1111. },
  1112. remove: function () {
  1113. this.controls.each(function (ctrl) {
  1114. ctrl.remove();
  1115. });
  1116. Backbone.View.prototype.remove.call(this);
  1117. }
  1118. });
  1119. var Media_FilterSelection_Multiselection = Backbone.View.extend({
  1120. tagName: "ul",
  1121. get_name: function () {
  1122. return this.filter_name;
  1123. },
  1124. initialize_model: function () {
  1125. this.model = ActiveFilters.get(this.filter_type);
  1126. this.listenTo(this.model, "change", this.apply_changes);
  1127. },
  1128. render: function () {
  1129. var me = this;
  1130. this.$el.empty();
  1131. this.model.each(function (model) {
  1132. if (me.allowed_values && me.allowed_values.indexOf(model.get("value")) < 0) return false;
  1133. var item = new Media_FilterSelection_Multiselection_Item({model: model});
  1134. item.render();
  1135. me.$el.append(item.$el);
  1136. });
  1137. },
  1138. apply_changes: function () {
  1139. var data = {},
  1140. values = []
  1141. ;
  1142. data = this.model.where({state:true});
  1143. Upfront.Events.trigger("media_manager:media:filters_updated", this.filter_type, data);
  1144. },
  1145. update_selection: function () {
  1146. var active = ActiveFilters.get(this.filter_type);
  1147. if (!active) {
  1148. this.model.invoke("set", {state: false});
  1149. } else {
  1150. this.model.each(function (model) {
  1151. var has = active.where({filter: model.get("filter"), state: true});
  1152. model.set({state: !!has.length});
  1153. });
  1154. }
  1155. this.render();
  1156. return false;
  1157. }
  1158. });
  1159. var Media_FilterSelection_AdditiveMultiselection = Media_FilterSelection_Multiselection.extend({
  1160. tagName: "div",
  1161. className: "upfront-additive_multiselection",
  1162. events: {
  1163. click: "stop_prop",
  1164. "keyup :text.filter": "show_matching_labels",
  1165. "focus :text.filter": "add_focus_state",
  1166. "blur :text.filter": "remove_focus_state"
  1167. },
  1168. stop_prop: function (e) {
  1169. e.stopPropagation();
  1170. // Also let's focus the text field
  1171. this.$el.find(":text.filter").focus();
  1172. },
  1173. add_focus_state: function (e) {
  1174. this.$el.addClass('focus');
  1175. },
  1176. remove_focus_state: function (e) {
  1177. this.$el.removeClass('focus');
  1178. },
  1179. render: function () {
  1180. var me = this,
  1181. sel = this.selection || ''
  1182. ;
  1183. this.$el
  1184. .empty()
  1185. .append('<div class="title">' + l10n.filter_by_labels + '</div>')
  1186. .append('<div class="labels_filter"><ul></ul><input type="text" class="filter upfront-field upfront-field-text" value="' + sel + '" placeholder="' + l10n.type_labels + '" /></div>')
  1187. .append('<div class="labels_list"><ul></ul></div>')
  1188. ;
  1189. this.render_filtered_items();
  1190. this.render_items();
  1191. },
  1192. render_filtered_items: function () {
  1193. var me = this,
  1194. $hub = this.$el.find("div.labels_filter ul"),
  1195. count = 0
  1196. ;
  1197. $hub.empty();
  1198. this.model.each(function (model) {
  1199. if (me.allowed_values && me.allowed_values.indexOf(model.get("value")) < 0) return false;
  1200. if (!model.get("state")) return false;
  1201. var item = new Media_FilterSelection_AdditiveMultiselection_Item({model: model});
  1202. item.render();
  1203. $hub.append(item.$el);
  1204. count++;
  1205. });
  1206. if (count > 0) {
  1207. // Remove placeholder
  1208. this.$el.find(":text.filter").attr('placeholder', '');
  1209. }
  1210. },
  1211. render_items: function () {
  1212. var me = this,
  1213. $hub = this.$el.find("div.labels_list ul"),
  1214. match = 0
  1215. ;
  1216. $hub.empty();
  1217. if (!this.selection) {
  1218. this.$el.removeClass('has_match');
  1219. return false;
  1220. }
  1221. //if (!this.$el.is(".active")) return false; // Only actually render this if we can see it - it takes *a while* to do so
  1222. this.model.each(function (model) {
  1223. if (me.allowed_values && me.allowed_values.indexOf(model.get("value")) < 0) return false;
  1224. if (model.get("state")) return false;
  1225. var item = new Media_FilterSelection_AdditiveMultiselection_Item({model: model});
  1226. item.selection = me.selection;
  1227. item.render();
  1228. if (item.matched) {
  1229. $hub.append(item.$el);
  1230. match++;
  1231. }
  1232. });
  1233. if (match > 0) this.$el.addClass('has_match');
  1234. else this.$el.removeClass('has_match');
  1235. },
  1236. show_matching_labels: function (e) {
  1237. var $text = this.$el.find(":text.filter"),
  1238. selection = $text.val()
  1239. ;
  1240. this.selection = selection;
  1241. this.render_items();
  1242. }
  1243. });
  1244. var Media_FilterSelection_Uniqueselection = Media_FilterSelection_Multiselection.extend({
  1245. render: function () {
  1246. var me = this;
  1247. this.$el.empty();
  1248. this.model.each(function (model) {
  1249. if (me.allowed_values && me.allowed_values.indexOf(model.get("value")) < 0) return false;
  1250. var item = new Media_FilterSelection_Uniqueselection_Item({model: model});
  1251. item.render();
  1252. me.$el.append(item.$el);
  1253. me.listenTo(item, "model:unique_state:change", me.change_state);
  1254. });
  1255. },
  1256. change_state: function (model) {
  1257. this.model.each(function (item) {
  1258. if (item.get("value") != model.get("value")) item.set({state: false}, {silent: true});
  1259. });
  1260. model.set({state: true}, {silent: true});
  1261. this.apply_changes(model);
  1262. this.render();
  1263. }
  1264. });
  1265. var Media_FilterSelection_Multiselection_Item = Backbone.View.extend({
  1266. tagName: "li",
  1267. events: {
  1268. "click": "on_click"
  1269. },
  1270. initialize: function () {
  1271. this.listenTo(this.model, "change", this.render);
  1272. },
  1273. render: function () {
  1274. var name = this.model.get("filter");
  1275. if ("other" === this.model.get("value")) return false; // DO NOT RENDER "ALL", special case
  1276. if (this.model.get("state")) name = '<b>' + name + '</b>';
  1277. this.$el.empty().append(name);
  1278. },
  1279. on_click: function (e) {
  1280. e.preventDefault();
  1281. e.stopPropagation();
  1282. this.model.set({state: !this.model.get("state")});
  1283. }
  1284. });
  1285. var Media_FilterSelection_Uniqueselection_Item = Media_FilterSelection_Multiselection_Item.extend({
  1286. on_click: function (e) {
  1287. e.preventDefault();
  1288. e.stopPropagation();
  1289. this.model.set({state: !this.model.get("state")}, {silent: true});
  1290. this.trigger("model:unique_state:change", this.model);
  1291. }
  1292. });
  1293. var Media_FilterSelection_AdditiveMultiselection_Item = Media_FilterSelection_Multiselection_Item.extend({
  1294. render: function () {
  1295. var checked = _.template('<input type="checkbox" for="{{id}}" class="upfront-field-checkbox" name="{{filter}}" value="{{value}}" checked />'),
  1296. unchecked = _.template('<input type="checkbox" for="{{id}}" class="upfront-field-checkbox" name="{{filter}}" value="{{value}}" />'),
  1297. label = _.template('<label for="{{id}}">{{name}}</label>'),
  1298. name = this.model.get("filter") || '',
  1299. match_rx = this.selection ? new RegExp('(' + this.selection + ')', 'i') : false,
  1300. obj = this.model.toJSON()
  1301. ;
  1302. this.matched = false;
  1303. this.$el.empty();
  1304. if (match_rx && !name.match(match_rx)) return false;
  1305. this.matched = true;
  1306. obj.id = this.cid;
  1307. obj.name = name.replace(match_rx, '<span class="selection">$1</span>');
  1308. this.$el
  1309. .append(label(obj))
  1310. .append((this.model.get("state") ? checked : unchecked)(obj))
  1311. ;
  1312. }
  1313. });
  1314. var Media_FilterCollection = Backbone.View.extend({
  1315. render: function () {
  1316. var me = this;
  1317. this.$el.empty();
  1318. this.model.each(function (model) {
  1319. var item = new Media_FilterItem({model: model});
  1320. item.render();
  1321. me.$el.append(item.$el);
  1322. });
  1323. }
  1324. });
  1325. var Media_FilterItem = Backbone.View.extend({
  1326. render: function () {
  1327. this.$el.empty().append(this.model.get("filter"));
  1328. }
  1329. });
  1330. var Control_MediaType = Media_FilterSelection_Uniqueselection.extend({
  1331. initialize: function () {
  1332. this.filter_name = l10n.by_type;
  1333. this.filter_type = "type";
  1334. this.initialize_model();
  1335. this.listenTo(Upfront.Events, "media_manager:media:filters_updated", this.update_selection);
  1336. this.listenTo(Upfront.Events, "media_manager:media:filters_reset", this.initialize_model);
  1337. },
  1338. render: function () {
  1339. var me = this,
  1340. values = [],
  1341. has_all = (this.model.indexOf("other") >= 0)
  1342. ;
  1343. this.$el.empty();
  1344. this.model.each(function (model) {
  1345. if (me.allowed_values && me.allowed_values.indexOf(model.get("value")) < 0) return false;
  1346. values.push({label: model.get("filter"), value: model.get("value")});
  1347. });
  1348. this.select_field = new Upfront.Views.Editor.Field.Select({
  1349. name: "filter-type",
  1350. values: values,
  1351. multiple: false,
  1352. default_value: has_all ? "other" : this.model.findWhere({state: true}).get("value"),
  1353. change: function(){
  1354. var model = me.model.findWhere({value: this.get_value()});
  1355. model.set({state: !model.get("state")}, {silent: true});
  1356. me.change_state(model);
  1357. }
  1358. });
  1359. this.select_field.render();
  1360. this.$el.append(this.select_field.$el);
  1361. },
  1362. /*apply_changes: function (model) {
  1363. return;
  1364. var all = this.model.where({state: true}),
  1365. other = this.model.where({value: 'other'}),
  1366. edited = model.previousAttributes()
  1367. ;
  1368. if (other.length) other = other[0]; // Do the model
  1369. else return;
  1370. if (edited && edited.value && "other" === edited.value) {
  1371. var no_other = !!edited.state;
  1372. this.model.each(function (mod) {
  1373. mod.set({state: no_other}, {silent: true});
  1374. });
  1375. other.set({state: !no_other}, {silent: true});
  1376. } else if (other.get("state")) other.set({state: false}, {silent: true});
  1377. Media_FilterSelection_Uniqueselection.prototype.apply_changes.call(this);
  1378. }*/
  1379. });
  1380. var Control_MediaFileName = Media_FilterSelection_Uniqueselection.extend({
  1381. allowed_values: ['title_desc', 'title_asc'],
  1382. initialize: function () {
  1383. this.filter_name = l10n.file_name;
  1384. this.filter_type = "order";
  1385. this.initialize_model();
  1386. this.listenTo(Upfront.Events, "media_manager:media:filters_updated", this.update_selection);
  1387. this.listenTo(Upfront.Events, "media_manager:media:filters_reset", this.initialize_model);
  1388. }
  1389. });
  1390. var Control_MediaLabels = Media_FilterSelection_AdditiveMultiselection.extend({
  1391. initialize: func

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