/HotelSpaWP/wp-includes/js/media-views.js

https://bitbucket.org/Trulsh/personal-bootstrap-projects · JavaScript · 8542 lines · 5137 code · 1223 blank · 2182 comment · 606 complexity · b44bc57736b0f9071a8d5b4e1a1c38c0 MD5 · raw file

Large files are truncated click here to view the full file

  1. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. /**
  3. * wp.media.controller.CollectionAdd
  4. *
  5. * A state for adding attachments to a collection (e.g. video playlist).
  6. *
  7. * @class
  8. * @augments wp.media.controller.Library
  9. * @augments wp.media.controller.State
  10. * @augments Backbone.Model
  11. *
  12. * @param {object} [attributes] The attributes hash passed to the state.
  13. * @param {string} [attributes.id=library] Unique identifier.
  14. * @param {string} attributes.title Title for the state. Displays in the frame's title region.
  15. * @param {boolean} [attributes.multiple=add] Whether multi-select is enabled. @todo 'add' doesn't seem do anything special, and gets used as a boolean.
  16. * @param {wp.media.model.Attachments} [attributes.library] The attachments collection to browse.
  17. * If one is not supplied, a collection of attachments of the specified type will be created.
  18. * @param {boolean|string} [attributes.filterable=uploaded] Whether the library is filterable, and if so what filters should be shown.
  19. * Accepts 'all', 'uploaded', or 'unattached'.
  20. * @param {string} [attributes.menu=gallery] Initial mode for the menu region.
  21. * @param {string} [attributes.content=upload] Initial mode for the content region.
  22. * Overridden by persistent user setting if 'contentUserSetting' is true.
  23. * @param {string} [attributes.router=browse] Initial mode for the router region.
  24. * @param {string} [attributes.toolbar=gallery-add] Initial mode for the toolbar region.
  25. * @param {boolean} [attributes.searchable=true] Whether the library is searchable.
  26. * @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
  27. * @param {boolean} [attributes.autoSelect=true] Whether an uploaded attachment should be automatically added to the selection.
  28. * @param {boolean} [attributes.contentUserSetting=true] Whether the content region's mode should be set and persisted per user.
  29. * @param {int} [attributes.priority=100] The priority for the state link in the media menu.
  30. * @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
  31. * Defaults to false because for this state, because the library of the Edit Gallery state is the selection.
  32. * @param {string} attributes.type The collection's media type. (e.g. 'video').
  33. * @param {string} attributes.collectionType The collection type. (e.g. 'playlist').
  34. */
  35. var Selection = wp.media.model.Selection,
  36. Library = wp.media.controller.Library,
  37. CollectionAdd;
  38. CollectionAdd = Library.extend({
  39. defaults: _.defaults( {
  40. // Selection defaults. @see media.model.Selection
  41. multiple: 'add',
  42. // Attachments browser defaults. @see media.view.AttachmentsBrowser
  43. filterable: 'uploaded',
  44. priority: 100,
  45. syncSelection: false
  46. }, Library.prototype.defaults ),
  47. /**
  48. * @since 3.9.0
  49. */
  50. initialize: function() {
  51. var collectionType = this.get('collectionType');
  52. if ( 'video' === this.get( 'type' ) ) {
  53. collectionType = 'video-' + collectionType;
  54. }
  55. this.set( 'id', collectionType + '-library' );
  56. this.set( 'toolbar', collectionType + '-add' );
  57. this.set( 'menu', collectionType );
  58. // If we haven't been provided a `library`, create a `Selection`.
  59. if ( ! this.get('library') ) {
  60. this.set( 'library', wp.media.query({ type: this.get('type') }) );
  61. }
  62. Library.prototype.initialize.apply( this, arguments );
  63. },
  64. /**
  65. * @since 3.9.0
  66. */
  67. activate: function() {
  68. var library = this.get('library'),
  69. editLibrary = this.get('editLibrary'),
  70. edit = this.frame.state( this.get('collectionType') + '-edit' ).get('library');
  71. if ( editLibrary && editLibrary !== edit ) {
  72. library.unobserve( editLibrary );
  73. }
  74. // Accepts attachments that exist in the original library and
  75. // that do not exist in gallery's library.
  76. library.validator = function( attachment ) {
  77. return !! this.mirroring.get( attachment.cid ) && ! edit.get( attachment.cid ) && Selection.prototype.validator.apply( this, arguments );
  78. };
  79. // Reset the library to ensure that all attachments are re-added
  80. // to the collection. Do so silently, as calling `observe` will
  81. // trigger the `reset` event.
  82. library.reset( library.mirroring.models, { silent: true });
  83. library.observe( edit );
  84. this.set('editLibrary', edit);
  85. Library.prototype.activate.apply( this, arguments );
  86. }
  87. });
  88. module.exports = CollectionAdd;
  89. },{}],2:[function(require,module,exports){
  90. /**
  91. * wp.media.controller.CollectionEdit
  92. *
  93. * A state for editing a collection, which is used by audio and video playlists,
  94. * and can be used for other collections.
  95. *
  96. * @class
  97. * @augments wp.media.controller.Library
  98. * @augments wp.media.controller.State
  99. * @augments Backbone.Model
  100. *
  101. * @param {object} [attributes] The attributes hash passed to the state.
  102. * @param {string} attributes.title Title for the state. Displays in the media menu and the frame's title region.
  103. * @param {wp.media.model.Attachments} [attributes.library] The attachments collection to edit.
  104. * If one is not supplied, an empty media.model.Selection collection is created.
  105. * @param {boolean} [attributes.multiple=false] Whether multi-select is enabled.
  106. * @param {string} [attributes.content=browse] Initial mode for the content region.
  107. * @param {string} attributes.menu Initial mode for the menu region. @todo this needs a better explanation.
  108. * @param {boolean} [attributes.searchable=false] Whether the library is searchable.
  109. * @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
  110. * @param {boolean} [attributes.date=true] Whether to show the date filter in the browser's toolbar.
  111. * @param {boolean} [attributes.describe=true] Whether to offer UI to describe the attachments - e.g. captioning images in a gallery.
  112. * @param {boolean} [attributes.dragInfo=true] Whether to show instructional text about the attachments being sortable.
  113. * @param {boolean} [attributes.dragInfoText] Instructional text about the attachments being sortable.
  114. * @param {int} [attributes.idealColumnWidth=170] The ideal column width in pixels for attachments.
  115. * @param {boolean} [attributes.editing=false] Whether the gallery is being created, or editing an existing instance.
  116. * @param {int} [attributes.priority=60] The priority for the state link in the media menu.
  117. * @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
  118. * Defaults to false for this state, because the library passed in *is* the selection.
  119. * @param {view} [attributes.SettingsView] The view to edit the collection instance settings (e.g. Playlist settings with "Show tracklist" checkbox).
  120. * @param {view} [attributes.AttachmentView] The single `Attachment` view to be used in the `Attachments`.
  121. * If none supplied, defaults to wp.media.view.Attachment.EditLibrary.
  122. * @param {string} attributes.type The collection's media type. (e.g. 'video').
  123. * @param {string} attributes.collectionType The collection type. (e.g. 'playlist').
  124. */
  125. var Library = wp.media.controller.Library,
  126. l10n = wp.media.view.l10n,
  127. $ = jQuery,
  128. CollectionEdit;
  129. CollectionEdit = Library.extend({
  130. defaults: {
  131. multiple: false,
  132. sortable: true,
  133. date: false,
  134. searchable: false,
  135. content: 'browse',
  136. describe: true,
  137. dragInfo: true,
  138. idealColumnWidth: 170,
  139. editing: false,
  140. priority: 60,
  141. SettingsView: false,
  142. syncSelection: false
  143. },
  144. /**
  145. * @since 3.9.0
  146. */
  147. initialize: function() {
  148. var collectionType = this.get('collectionType');
  149. if ( 'video' === this.get( 'type' ) ) {
  150. collectionType = 'video-' + collectionType;
  151. }
  152. this.set( 'id', collectionType + '-edit' );
  153. this.set( 'toolbar', collectionType + '-edit' );
  154. // If we haven't been provided a `library`, create a `Selection`.
  155. if ( ! this.get('library') ) {
  156. this.set( 'library', new wp.media.model.Selection() );
  157. }
  158. // The single `Attachment` view to be used in the `Attachments` view.
  159. if ( ! this.get('AttachmentView') ) {
  160. this.set( 'AttachmentView', wp.media.view.Attachment.EditLibrary );
  161. }
  162. Library.prototype.initialize.apply( this, arguments );
  163. },
  164. /**
  165. * @since 3.9.0
  166. */
  167. activate: function() {
  168. var library = this.get('library');
  169. // Limit the library to images only.
  170. library.props.set( 'type', this.get( 'type' ) );
  171. // Watch for uploaded attachments.
  172. this.get('library').observe( wp.Uploader.queue );
  173. this.frame.on( 'content:render:browse', this.renderSettings, this );
  174. Library.prototype.activate.apply( this, arguments );
  175. },
  176. /**
  177. * @since 3.9.0
  178. */
  179. deactivate: function() {
  180. // Stop watching for uploaded attachments.
  181. this.get('library').unobserve( wp.Uploader.queue );
  182. this.frame.off( 'content:render:browse', this.renderSettings, this );
  183. Library.prototype.deactivate.apply( this, arguments );
  184. },
  185. /**
  186. * Render the collection embed settings view in the browser sidebar.
  187. *
  188. * @todo This is against the pattern elsewhere in media. Typically the frame
  189. * is responsible for adding region mode callbacks. Explain.
  190. *
  191. * @since 3.9.0
  192. *
  193. * @param {wp.media.view.attachmentsBrowser} The attachments browser view.
  194. */
  195. renderSettings: function( attachmentsBrowserView ) {
  196. var library = this.get('library'),
  197. collectionType = this.get('collectionType'),
  198. dragInfoText = this.get('dragInfoText'),
  199. SettingsView = this.get('SettingsView'),
  200. obj = {};
  201. if ( ! library || ! attachmentsBrowserView ) {
  202. return;
  203. }
  204. library[ collectionType ] = library[ collectionType ] || new Backbone.Model();
  205. obj[ collectionType ] = new SettingsView({
  206. controller: this,
  207. model: library[ collectionType ],
  208. priority: 40
  209. });
  210. attachmentsBrowserView.sidebar.set( obj );
  211. if ( dragInfoText ) {
  212. attachmentsBrowserView.toolbar.set( 'dragInfo', new wp.media.View({
  213. el: $( '<div class="instructions">' + dragInfoText + '</div>' )[0],
  214. priority: -40
  215. }) );
  216. }
  217. // Add the 'Reverse order' button to the toolbar.
  218. attachmentsBrowserView.toolbar.set( 'reverse', {
  219. text: l10n.reverseOrder,
  220. priority: 80,
  221. click: function() {
  222. library.reset( library.toArray().reverse() );
  223. }
  224. });
  225. }
  226. });
  227. module.exports = CollectionEdit;
  228. },{}],3:[function(require,module,exports){
  229. /**
  230. * wp.media.controller.Cropper
  231. *
  232. * A state for cropping an image.
  233. *
  234. * @class
  235. * @augments wp.media.controller.State
  236. * @augments Backbone.Model
  237. */
  238. var l10n = wp.media.view.l10n,
  239. Cropper;
  240. Cropper = wp.media.controller.State.extend({
  241. defaults: {
  242. id: 'cropper',
  243. title: l10n.cropImage,
  244. // Region mode defaults.
  245. toolbar: 'crop',
  246. content: 'crop',
  247. router: false,
  248. canSkipCrop: false,
  249. // Default doCrop Ajax arguments to allow the Customizer (for example) to inject state.
  250. doCropArgs: {}
  251. },
  252. activate: function() {
  253. this.frame.on( 'content:create:crop', this.createCropContent, this );
  254. this.frame.on( 'close', this.removeCropper, this );
  255. this.set('selection', new Backbone.Collection(this.frame._selection.single));
  256. },
  257. deactivate: function() {
  258. this.frame.toolbar.mode('browse');
  259. },
  260. createCropContent: function() {
  261. this.cropperView = new wp.media.view.Cropper({
  262. controller: this,
  263. attachment: this.get('selection').first()
  264. });
  265. this.cropperView.on('image-loaded', this.createCropToolbar, this);
  266. this.frame.content.set(this.cropperView);
  267. },
  268. removeCropper: function() {
  269. this.imgSelect.cancelSelection();
  270. this.imgSelect.setOptions({remove: true});
  271. this.imgSelect.update();
  272. this.cropperView.remove();
  273. },
  274. createCropToolbar: function() {
  275. var canSkipCrop, toolbarOptions;
  276. canSkipCrop = this.get('canSkipCrop') || false;
  277. toolbarOptions = {
  278. controller: this.frame,
  279. items: {
  280. insert: {
  281. style: 'primary',
  282. text: l10n.cropImage,
  283. priority: 80,
  284. requires: { library: false, selection: false },
  285. click: function() {
  286. var controller = this.controller,
  287. selection;
  288. selection = controller.state().get('selection').first();
  289. selection.set({cropDetails: controller.state().imgSelect.getSelection()});
  290. this.$el.text(l10n.cropping);
  291. this.$el.attr('disabled', true);
  292. controller.state().doCrop( selection ).done( function( croppedImage ) {
  293. controller.trigger('cropped', croppedImage );
  294. controller.close();
  295. }).fail( function() {
  296. controller.trigger('content:error:crop');
  297. });
  298. }
  299. }
  300. }
  301. };
  302. if ( canSkipCrop ) {
  303. _.extend( toolbarOptions.items, {
  304. skip: {
  305. style: 'secondary',
  306. text: l10n.skipCropping,
  307. priority: 70,
  308. requires: { library: false, selection: false },
  309. click: function() {
  310. var selection = this.controller.state().get('selection').first();
  311. this.controller.state().cropperView.remove();
  312. this.controller.trigger('skippedcrop', selection);
  313. this.controller.close();
  314. }
  315. }
  316. });
  317. }
  318. this.frame.toolbar.set( new wp.media.view.Toolbar(toolbarOptions) );
  319. },
  320. doCrop: function( attachment ) {
  321. return wp.ajax.post( 'custom-header-crop', _.extend(
  322. {},
  323. this.defaults.doCropArgs,
  324. {
  325. nonce: attachment.get( 'nonces' ).edit,
  326. id: attachment.get( 'id' ),
  327. cropDetails: attachment.get( 'cropDetails' )
  328. }
  329. ) );
  330. }
  331. });
  332. module.exports = Cropper;
  333. },{}],4:[function(require,module,exports){
  334. /**
  335. * wp.media.controller.CustomizeImageCropper
  336. *
  337. * A state for cropping an image.
  338. *
  339. * @class
  340. * @augments wp.media.controller.Cropper
  341. * @augments wp.media.controller.State
  342. * @augments Backbone.Model
  343. */
  344. var Controller = wp.media.controller,
  345. CustomizeImageCropper;
  346. CustomizeImageCropper = Controller.Cropper.extend({
  347. doCrop: function( attachment ) {
  348. var cropDetails = attachment.get( 'cropDetails' ),
  349. control = this.get( 'control' ),
  350. ratio = cropDetails.width / cropDetails.height;
  351. // Use crop measurements when flexible in both directions.
  352. if ( control.params.flex_width && control.params.flex_height ) {
  353. cropDetails.dst_width = cropDetails.width;
  354. cropDetails.dst_height = cropDetails.height;
  355. // Constrain flexible side based on image ratio and size of the fixed side.
  356. } else {
  357. cropDetails.dst_width = control.params.flex_width ? control.params.height * ratio : control.params.width;
  358. cropDetails.dst_height = control.params.flex_height ? control.params.width / ratio : control.params.height;
  359. }
  360. return wp.ajax.post( 'crop-image', {
  361. wp_customize: 'on',
  362. nonce: attachment.get( 'nonces' ).edit,
  363. id: attachment.get( 'id' ),
  364. context: control.id,
  365. cropDetails: cropDetails
  366. } );
  367. }
  368. });
  369. module.exports = CustomizeImageCropper;
  370. },{}],5:[function(require,module,exports){
  371. /**
  372. * wp.media.controller.EditImage
  373. *
  374. * A state for editing (cropping, etc.) an image.
  375. *
  376. * @class
  377. * @augments wp.media.controller.State
  378. * @augments Backbone.Model
  379. *
  380. * @param {object} attributes The attributes hash passed to the state.
  381. * @param {wp.media.model.Attachment} attributes.model The attachment.
  382. * @param {string} [attributes.id=edit-image] Unique identifier.
  383. * @param {string} [attributes.title=Edit Image] Title for the state. Displays in the media menu and the frame's title region.
  384. * @param {string} [attributes.content=edit-image] Initial mode for the content region.
  385. * @param {string} [attributes.toolbar=edit-image] Initial mode for the toolbar region.
  386. * @param {string} [attributes.menu=false] Initial mode for the menu region.
  387. * @param {string} [attributes.url] Unused. @todo Consider removal.
  388. */
  389. var l10n = wp.media.view.l10n,
  390. EditImage;
  391. EditImage = wp.media.controller.State.extend({
  392. defaults: {
  393. id: 'edit-image',
  394. title: l10n.editImage,
  395. menu: false,
  396. toolbar: 'edit-image',
  397. content: 'edit-image',
  398. url: ''
  399. },
  400. /**
  401. * @since 3.9.0
  402. */
  403. activate: function() {
  404. this.frame.on( 'toolbar:render:edit-image', _.bind( this.toolbar, this ) );
  405. },
  406. /**
  407. * @since 3.9.0
  408. */
  409. deactivate: function() {
  410. this.frame.off( 'toolbar:render:edit-image' );
  411. },
  412. /**
  413. * @since 3.9.0
  414. */
  415. toolbar: function() {
  416. var frame = this.frame,
  417. lastState = frame.lastState(),
  418. previous = lastState && lastState.id;
  419. frame.toolbar.set( new wp.media.view.Toolbar({
  420. controller: frame,
  421. items: {
  422. back: {
  423. style: 'primary',
  424. text: l10n.back,
  425. priority: 20,
  426. click: function() {
  427. if ( previous ) {
  428. frame.setState( previous );
  429. } else {
  430. frame.close();
  431. }
  432. }
  433. }
  434. }
  435. }) );
  436. }
  437. });
  438. module.exports = EditImage;
  439. },{}],6:[function(require,module,exports){
  440. /**
  441. * wp.media.controller.Embed
  442. *
  443. * A state for embedding media from a URL.
  444. *
  445. * @class
  446. * @augments wp.media.controller.State
  447. * @augments Backbone.Model
  448. *
  449. * @param {object} attributes The attributes hash passed to the state.
  450. * @param {string} [attributes.id=embed] Unique identifier.
  451. * @param {string} [attributes.title=Insert From URL] Title for the state. Displays in the media menu and the frame's title region.
  452. * @param {string} [attributes.content=embed] Initial mode for the content region.
  453. * @param {string} [attributes.menu=default] Initial mode for the menu region.
  454. * @param {string} [attributes.toolbar=main-embed] Initial mode for the toolbar region.
  455. * @param {string} [attributes.menu=false] Initial mode for the menu region.
  456. * @param {int} [attributes.priority=120] The priority for the state link in the media menu.
  457. * @param {string} [attributes.type=link] The type of embed. Currently only link is supported.
  458. * @param {string} [attributes.url] The embed URL.
  459. * @param {object} [attributes.metadata={}] Properties of the embed, which will override attributes.url if set.
  460. */
  461. var l10n = wp.media.view.l10n,
  462. $ = Backbone.$,
  463. Embed;
  464. Embed = wp.media.controller.State.extend({
  465. defaults: {
  466. id: 'embed',
  467. title: l10n.insertFromUrlTitle,
  468. content: 'embed',
  469. menu: 'default',
  470. toolbar: 'main-embed',
  471. priority: 120,
  472. type: 'link',
  473. url: '',
  474. metadata: {}
  475. },
  476. // The amount of time used when debouncing the scan.
  477. sensitivity: 400,
  478. initialize: function(options) {
  479. this.metadata = options.metadata;
  480. this.debouncedScan = _.debounce( _.bind( this.scan, this ), this.sensitivity );
  481. this.props = new Backbone.Model( this.metadata || { url: '' });
  482. this.props.on( 'change:url', this.debouncedScan, this );
  483. this.props.on( 'change:url', this.refresh, this );
  484. this.on( 'scan', this.scanImage, this );
  485. },
  486. /**
  487. * Trigger a scan of the embedded URL's content for metadata required to embed.
  488. *
  489. * @fires wp.media.controller.Embed#scan
  490. */
  491. scan: function() {
  492. var scanners,
  493. embed = this,
  494. attributes = {
  495. type: 'link',
  496. scanners: []
  497. };
  498. // Scan is triggered with the list of `attributes` to set on the
  499. // state, useful for the 'type' attribute and 'scanners' attribute,
  500. // an array of promise objects for asynchronous scan operations.
  501. if ( this.props.get('url') ) {
  502. this.trigger( 'scan', attributes );
  503. }
  504. if ( attributes.scanners.length ) {
  505. scanners = attributes.scanners = $.when.apply( $, attributes.scanners );
  506. scanners.always( function() {
  507. if ( embed.get('scanners') === scanners ) {
  508. embed.set( 'loading', false );
  509. }
  510. });
  511. } else {
  512. attributes.scanners = null;
  513. }
  514. attributes.loading = !! attributes.scanners;
  515. this.set( attributes );
  516. },
  517. /**
  518. * Try scanning the embed as an image to discover its dimensions.
  519. *
  520. * @param {Object} attributes
  521. */
  522. scanImage: function( attributes ) {
  523. var frame = this.frame,
  524. state = this,
  525. url = this.props.get('url'),
  526. image = new Image(),
  527. deferred = $.Deferred();
  528. attributes.scanners.push( deferred.promise() );
  529. // Try to load the image and find its width/height.
  530. image.onload = function() {
  531. deferred.resolve();
  532. if ( state !== frame.state() || url !== state.props.get('url') ) {
  533. return;
  534. }
  535. state.set({
  536. type: 'image'
  537. });
  538. state.props.set({
  539. width: image.width,
  540. height: image.height
  541. });
  542. };
  543. image.onerror = deferred.reject;
  544. image.src = url;
  545. },
  546. refresh: function() {
  547. this.frame.toolbar.get().refresh();
  548. },
  549. reset: function() {
  550. this.props.clear().set({ url: '' });
  551. if ( this.active ) {
  552. this.refresh();
  553. }
  554. }
  555. });
  556. module.exports = Embed;
  557. },{}],7:[function(require,module,exports){
  558. /**
  559. * wp.media.controller.FeaturedImage
  560. *
  561. * A state for selecting a featured image for a post.
  562. *
  563. * @class
  564. * @augments wp.media.controller.Library
  565. * @augments wp.media.controller.State
  566. * @augments Backbone.Model
  567. *
  568. * @param {object} [attributes] The attributes hash passed to the state.
  569. * @param {string} [attributes.id=featured-image] Unique identifier.
  570. * @param {string} [attributes.title=Set Featured Image] Title for the state. Displays in the media menu and the frame's title region.
  571. * @param {wp.media.model.Attachments} [attributes.library] The attachments collection to browse.
  572. * If one is not supplied, a collection of all images will be created.
  573. * @param {boolean} [attributes.multiple=false] Whether multi-select is enabled.
  574. * @param {string} [attributes.content=upload] Initial mode for the content region.
  575. * Overridden by persistent user setting if 'contentUserSetting' is true.
  576. * @param {string} [attributes.menu=default] Initial mode for the menu region.
  577. * @param {string} [attributes.router=browse] Initial mode for the router region.
  578. * @param {string} [attributes.toolbar=featured-image] Initial mode for the toolbar region.
  579. * @param {int} [attributes.priority=60] The priority for the state link in the media menu.
  580. * @param {boolean} [attributes.searchable=true] Whether the library is searchable.
  581. * @param {boolean|string} [attributes.filterable=false] Whether the library is filterable, and if so what filters should be shown.
  582. * Accepts 'all', 'uploaded', or 'unattached'.
  583. * @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
  584. * @param {boolean} [attributes.autoSelect=true] Whether an uploaded attachment should be automatically added to the selection.
  585. * @param {boolean} [attributes.describe=false] Whether to offer UI to describe attachments - e.g. captioning images in a gallery.
  586. * @param {boolean} [attributes.contentUserSetting=true] Whether the content region's mode should be set and persisted per user.
  587. * @param {boolean} [attributes.syncSelection=true] Whether the Attachments selection should be persisted from the last state.
  588. */
  589. var Attachment = wp.media.model.Attachment,
  590. Library = wp.media.controller.Library,
  591. l10n = wp.media.view.l10n,
  592. FeaturedImage;
  593. FeaturedImage = Library.extend({
  594. defaults: _.defaults({
  595. id: 'featured-image',
  596. title: l10n.setFeaturedImageTitle,
  597. multiple: false,
  598. filterable: 'uploaded',
  599. toolbar: 'featured-image',
  600. priority: 60,
  601. syncSelection: true
  602. }, Library.prototype.defaults ),
  603. /**
  604. * @since 3.5.0
  605. */
  606. initialize: function() {
  607. var library, comparator;
  608. // If we haven't been provided a `library`, create a `Selection`.
  609. if ( ! this.get('library') ) {
  610. this.set( 'library', wp.media.query({ type: 'image' }) );
  611. }
  612. Library.prototype.initialize.apply( this, arguments );
  613. library = this.get('library');
  614. comparator = library.comparator;
  615. // Overload the library's comparator to push items that are not in
  616. // the mirrored query to the front of the aggregate collection.
  617. library.comparator = function( a, b ) {
  618. var aInQuery = !! this.mirroring.get( a.cid ),
  619. bInQuery = !! this.mirroring.get( b.cid );
  620. if ( ! aInQuery && bInQuery ) {
  621. return -1;
  622. } else if ( aInQuery && ! bInQuery ) {
  623. return 1;
  624. } else {
  625. return comparator.apply( this, arguments );
  626. }
  627. };
  628. // Add all items in the selection to the library, so any featured
  629. // images that are not initially loaded still appear.
  630. library.observe( this.get('selection') );
  631. },
  632. /**
  633. * @since 3.5.0
  634. */
  635. activate: function() {
  636. this.updateSelection();
  637. this.frame.on( 'open', this.updateSelection, this );
  638. Library.prototype.activate.apply( this, arguments );
  639. },
  640. /**
  641. * @since 3.5.0
  642. */
  643. deactivate: function() {
  644. this.frame.off( 'open', this.updateSelection, this );
  645. Library.prototype.deactivate.apply( this, arguments );
  646. },
  647. /**
  648. * @since 3.5.0
  649. */
  650. updateSelection: function() {
  651. var selection = this.get('selection'),
  652. id = wp.media.view.settings.post.featuredImageId,
  653. attachment;
  654. if ( '' !== id && -1 !== id ) {
  655. attachment = Attachment.get( id );
  656. attachment.fetch();
  657. }
  658. selection.reset( attachment ? [ attachment ] : [] );
  659. }
  660. });
  661. module.exports = FeaturedImage;
  662. },{}],8:[function(require,module,exports){
  663. /**
  664. * wp.media.controller.GalleryAdd
  665. *
  666. * A state for selecting more images to add to a gallery.
  667. *
  668. * @class
  669. * @augments wp.media.controller.Library
  670. * @augments wp.media.controller.State
  671. * @augments Backbone.Model
  672. *
  673. * @param {object} [attributes] The attributes hash passed to the state.
  674. * @param {string} [attributes.id=gallery-library] Unique identifier.
  675. * @param {string} [attributes.title=Add to Gallery] Title for the state. Displays in the frame's title region.
  676. * @param {boolean} [attributes.multiple=add] Whether multi-select is enabled. @todo 'add' doesn't seem do anything special, and gets used as a boolean.
  677. * @param {wp.media.model.Attachments} [attributes.library] The attachments collection to browse.
  678. * If one is not supplied, a collection of all images will be created.
  679. * @param {boolean|string} [attributes.filterable=uploaded] Whether the library is filterable, and if so what filters should be shown.
  680. * Accepts 'all', 'uploaded', or 'unattached'.
  681. * @param {string} [attributes.menu=gallery] Initial mode for the menu region.
  682. * @param {string} [attributes.content=upload] Initial mode for the content region.
  683. * Overridden by persistent user setting if 'contentUserSetting' is true.
  684. * @param {string} [attributes.router=browse] Initial mode for the router region.
  685. * @param {string} [attributes.toolbar=gallery-add] Initial mode for the toolbar region.
  686. * @param {boolean} [attributes.searchable=true] Whether the library is searchable.
  687. * @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
  688. * @param {boolean} [attributes.autoSelect=true] Whether an uploaded attachment should be automatically added to the selection.
  689. * @param {boolean} [attributes.contentUserSetting=true] Whether the content region's mode should be set and persisted per user.
  690. * @param {int} [attributes.priority=100] The priority for the state link in the media menu.
  691. * @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
  692. * Defaults to false because for this state, because the library of the Edit Gallery state is the selection.
  693. */
  694. var Selection = wp.media.model.Selection,
  695. Library = wp.media.controller.Library,
  696. l10n = wp.media.view.l10n,
  697. GalleryAdd;
  698. GalleryAdd = Library.extend({
  699. defaults: _.defaults({
  700. id: 'gallery-library',
  701. title: l10n.addToGalleryTitle,
  702. multiple: 'add',
  703. filterable: 'uploaded',
  704. menu: 'gallery',
  705. toolbar: 'gallery-add',
  706. priority: 100,
  707. syncSelection: false
  708. }, Library.prototype.defaults ),
  709. /**
  710. * @since 3.5.0
  711. */
  712. initialize: function() {
  713. // If a library wasn't supplied, create a library of images.
  714. if ( ! this.get('library') ) {
  715. this.set( 'library', wp.media.query({ type: 'image' }) );
  716. }
  717. Library.prototype.initialize.apply( this, arguments );
  718. },
  719. /**
  720. * @since 3.5.0
  721. */
  722. activate: function() {
  723. var library = this.get('library'),
  724. edit = this.frame.state('gallery-edit').get('library');
  725. if ( this.editLibrary && this.editLibrary !== edit ) {
  726. library.unobserve( this.editLibrary );
  727. }
  728. // Accepts attachments that exist in the original library and
  729. // that do not exist in gallery's library.
  730. library.validator = function( attachment ) {
  731. return !! this.mirroring.get( attachment.cid ) && ! edit.get( attachment.cid ) && Selection.prototype.validator.apply( this, arguments );
  732. };
  733. // Reset the library to ensure that all attachments are re-added
  734. // to the collection. Do so silently, as calling `observe` will
  735. // trigger the `reset` event.
  736. library.reset( library.mirroring.models, { silent: true });
  737. library.observe( edit );
  738. this.editLibrary = edit;
  739. Library.prototype.activate.apply( this, arguments );
  740. }
  741. });
  742. module.exports = GalleryAdd;
  743. },{}],9:[function(require,module,exports){
  744. /**
  745. * wp.media.controller.GalleryEdit
  746. *
  747. * A state for editing a gallery's images and settings.
  748. *
  749. * @class
  750. * @augments wp.media.controller.Library
  751. * @augments wp.media.controller.State
  752. * @augments Backbone.Model
  753. *
  754. * @param {object} [attributes] The attributes hash passed to the state.
  755. * @param {string} [attributes.id=gallery-edit] Unique identifier.
  756. * @param {string} [attributes.title=Edit Gallery] Title for the state. Displays in the frame's title region.
  757. * @param {wp.media.model.Attachments} [attributes.library] The collection of attachments in the gallery.
  758. * If one is not supplied, an empty media.model.Selection collection is created.
  759. * @param {boolean} [attributes.multiple=false] Whether multi-select is enabled.
  760. * @param {boolean} [attributes.searchable=false] Whether the library is searchable.
  761. * @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
  762. * @param {boolean} [attributes.date=true] Whether to show the date filter in the browser's toolbar.
  763. * @param {string|false} [attributes.content=browse] Initial mode for the content region.
  764. * @param {string|false} [attributes.toolbar=image-details] Initial mode for the toolbar region.
  765. * @param {boolean} [attributes.describe=true] Whether to offer UI to describe attachments - e.g. captioning images in a gallery.
  766. * @param {boolean} [attributes.displaySettings=true] Whether to show the attachment display settings interface.
  767. * @param {boolean} [attributes.dragInfo=true] Whether to show instructional text about the attachments being sortable.
  768. * @param {int} [attributes.idealColumnWidth=170] The ideal column width in pixels for attachments.
  769. * @param {boolean} [attributes.editing=false] Whether the gallery is being created, or editing an existing instance.
  770. * @param {int} [attributes.priority=60] The priority for the state link in the media menu.
  771. * @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
  772. * Defaults to false for this state, because the library passed in *is* the selection.
  773. * @param {view} [attributes.AttachmentView] The single `Attachment` view to be used in the `Attachments`.
  774. * If none supplied, defaults to wp.media.view.Attachment.EditLibrary.
  775. */
  776. var Library = wp.media.controller.Library,
  777. l10n = wp.media.view.l10n,
  778. GalleryEdit;
  779. GalleryEdit = Library.extend({
  780. defaults: {
  781. id: 'gallery-edit',
  782. title: l10n.editGalleryTitle,
  783. multiple: false,
  784. searchable: false,
  785. sortable: true,
  786. date: false,
  787. display: false,
  788. content: 'browse',
  789. toolbar: 'gallery-edit',
  790. describe: true,
  791. displaySettings: true,
  792. dragInfo: true,
  793. idealColumnWidth: 170,
  794. editing: false,
  795. priority: 60,
  796. syncSelection: false
  797. },
  798. /**
  799. * @since 3.5.0
  800. */
  801. initialize: function() {
  802. // If we haven't been provided a `library`, create a `Selection`.
  803. if ( ! this.get('library') ) {
  804. this.set( 'library', new wp.media.model.Selection() );
  805. }
  806. // The single `Attachment` view to be used in the `Attachments` view.
  807. if ( ! this.get('AttachmentView') ) {
  808. this.set( 'AttachmentView', wp.media.view.Attachment.EditLibrary );
  809. }
  810. Library.prototype.initialize.apply( this, arguments );
  811. },
  812. /**
  813. * @since 3.5.0
  814. */
  815. activate: function() {
  816. var library = this.get('library');
  817. // Limit the library to images only.
  818. library.props.set( 'type', 'image' );
  819. // Watch for uploaded attachments.
  820. this.get('library').observe( wp.Uploader.queue );
  821. this.frame.on( 'content:render:browse', this.gallerySettings, this );
  822. Library.prototype.activate.apply( this, arguments );
  823. },
  824. /**
  825. * @since 3.5.0
  826. */
  827. deactivate: function() {
  828. // Stop watching for uploaded attachments.
  829. this.get('library').unobserve( wp.Uploader.queue );
  830. this.frame.off( 'content:render:browse', this.gallerySettings, this );
  831. Library.prototype.deactivate.apply( this, arguments );
  832. },
  833. /**
  834. * @since 3.5.0
  835. *
  836. * @param browser
  837. */
  838. gallerySettings: function( browser ) {
  839. if ( ! this.get('displaySettings') ) {
  840. return;
  841. }
  842. var library = this.get('library');
  843. if ( ! library || ! browser ) {
  844. return;
  845. }
  846. library.gallery = library.gallery || new Backbone.Model();
  847. browser.sidebar.set({
  848. gallery: new wp.media.view.Settings.Gallery({
  849. controller: this,
  850. model: library.gallery,
  851. priority: 40
  852. })
  853. });
  854. browser.toolbar.set( 'reverse', {
  855. text: l10n.reverseOrder,
  856. priority: 80,
  857. click: function() {
  858. library.reset( library.toArray().reverse() );
  859. }
  860. });
  861. }
  862. });
  863. module.exports = GalleryEdit;
  864. },{}],10:[function(require,module,exports){
  865. /**
  866. * wp.media.controller.ImageDetails
  867. *
  868. * A state for editing the attachment display settings of an image that's been
  869. * inserted into the editor.
  870. *
  871. * @class
  872. * @augments wp.media.controller.State
  873. * @augments Backbone.Model
  874. *
  875. * @param {object} [attributes] The attributes hash passed to the state.
  876. * @param {string} [attributes.id=image-details] Unique identifier.
  877. * @param {string} [attributes.title=Image Details] Title for the state. Displays in the frame's title region.
  878. * @param {wp.media.model.Attachment} attributes.image The image's model.
  879. * @param {string|false} [attributes.content=image-details] Initial mode for the content region.
  880. * @param {string|false} [attributes.menu=false] Initial mode for the menu region.
  881. * @param {string|false} [attributes.router=false] Initial mode for the router region.
  882. * @param {string|false} [attributes.toolbar=image-details] Initial mode for the toolbar region.
  883. * @param {boolean} [attributes.editing=false] Unused.
  884. * @param {int} [attributes.priority=60] Unused.
  885. *
  886. * @todo This state inherits some defaults from media.controller.Library.prototype.defaults,
  887. * however this may not do anything.
  888. */
  889. var State = wp.media.controller.State,
  890. Library = wp.media.controller.Library,
  891. l10n = wp.media.view.l10n,
  892. ImageDetails;
  893. ImageDetails = State.extend({
  894. defaults: _.defaults({
  895. id: 'image-details',
  896. title: l10n.imageDetailsTitle,
  897. content: 'image-details',
  898. menu: false,
  899. router: false,
  900. toolbar: 'image-details',
  901. editing: false,
  902. priority: 60
  903. }, Library.prototype.defaults ),
  904. /**
  905. * @since 3.9.0
  906. *
  907. * @param options Attributes
  908. */
  909. initialize: function( options ) {
  910. this.image = options.image;
  911. State.prototype.initialize.apply( this, arguments );
  912. },
  913. /**
  914. * @since 3.9.0
  915. */
  916. activate: function() {
  917. this.frame.modal.$el.addClass('image-details');
  918. }
  919. });
  920. module.exports = ImageDetails;
  921. },{}],11:[function(require,module,exports){
  922. /**
  923. * wp.media.controller.Library
  924. *
  925. * A state for choosing an attachment or group of attachments from the media library.
  926. *
  927. * @class
  928. * @augments wp.media.controller.State
  929. * @augments Backbone.Model
  930. * @mixes media.selectionSync
  931. *
  932. * @param {object} [attributes] The attributes hash passed to the state.
  933. * @param {string} [attributes.id=library] Unique identifier.
  934. * @param {string} [attributes.title=Media library] Title for the state. Displays in the media menu and the frame's title region.
  935. * @param {wp.media.model.Attachments} [attributes.library] The attachments collection to browse.
  936. * If one is not supplied, a collection of all attachments will be created.
  937. * @param {wp.media.model.Selection|object} [attributes.selection] A collection to contain attachment selections within the state.
  938. * If the 'selection' attribute is a plain JS object,
  939. * a Selection will be created using its values as the selection instance's `props` model.
  940. * Otherwise, it will copy the library's `props` model.
  941. * @param {boolean} [attributes.multiple=false] Whether multi-select is enabled.
  942. * @param {string} [attributes.content=upload] Initial mode for the content region.
  943. * Overridden by persistent user setting if 'contentUserSetting' is true.
  944. * @param {string} [attributes.menu=default] Initial mode for the menu region.
  945. * @param {string} [attributes.router=browse] Initial mode for the router region.
  946. * @param {string} [attributes.toolbar=select] Initial mode for the toolbar region.
  947. * @param {boolean} [attributes.searchable=true] Whether the library is searchable.
  948. * @param {boolean|string} [attributes.filterable=false] Whether the library is filterable, and if so what filters should be shown.
  949. * Accepts 'all', 'uploaded', or 'unattached'.
  950. * @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
  951. * @param {boolean} [attributes.autoSelect=true] Whether an uploaded attachment should be automatically added to the selection.
  952. * @param {boolean} [attributes.describe=false] Whether to offer UI to describe attachments - e.g. captioning images in a gallery.
  953. * @param {boolean} [attributes.contentUserSetting=true] Whether the content region's mode should be set and persisted per user.
  954. * @param {boolean} [attributes.syncSelection=true] Whether the Attachments selection should be persisted from the last state.
  955. */
  956. var l10n = wp.media.view.l10n,
  957. getUserSetting = window.getUserSetting,
  958. setUserSetting = window.setUserSetting,
  959. Library;
  960. Library = wp.media.controller.State.extend({
  961. defaults: {
  962. id: 'library',
  963. title: l10n.mediaLibraryTitle,
  964. multiple: false,
  965. content: 'upload',
  966. menu: 'default',
  967. router: 'browse',
  968. toolbar: 'select',
  969. searchable: true,
  970. filterable: false,
  971. sortable: true,
  972. autoSelect: true,
  973. describe: false,
  974. contentUserSetting: true,
  975. syncSelection: true
  976. },
  977. /**
  978. * If a library isn't provided, query all media items.
  979. * If a selection instance isn't provided, create one.
  980. *
  981. * @since 3.5.0
  982. */
  983. initialize: function() {
  984. var selection = this.get('selection'),
  985. props;
  986. if ( ! this.get('library') ) {
  987. this.set( 'library', wp.media.query() );
  988. }
  989. if ( ! ( selection instanceof wp.media.model.Selection ) ) {
  990. props = selection;
  991. if ( ! props ) {
  992. props = this.get('library').props.toJSON();
  993. props = _.omit( props, 'orderby', 'query' );
  994. }
  995. this.set( 'selection', new wp.media.model.Selection( null, {
  996. multiple: this.get('multiple'),
  997. props: props
  998. }) );
  999. }
  1000. this.resetDisplays();
  1001. },
  1002. /**
  1003. * @since 3.5.0
  1004. */
  1005. activate: function() {
  1006. this.syncSelection();
  1007. wp.Uploader.queue.on( 'add', this.uploading, this );
  1008. this.get('selection').on( 'add remove reset', this.refreshContent, this );
  1009. if ( this.get( 'router' ) && this.get('contentUserSetting') ) {
  1010. this.frame.on( 'content:activate', this.saveContentMode, this );
  1011. this.set( 'content', getUserSetting( 'libraryContent', this.get('content') ) );
  1012. }
  1013. },
  1014. /**
  1015. * @since 3.5.0
  1016. */
  1017. deactivate: function() {
  1018. this.recordSelection();
  1019. this.frame.off( 'content:activate', this.saveContentMode, this );
  1020. // Unbind all event handlers that use this state as the context
  1021. // from the selection.
  1022. this.get('selection').off( null, null, this );
  1023. wp.Uploader.queue.off( null, null, this );
  1024. },
  1025. /**
  1026. * Reset the library to its initial state.
  1027. *
  1028. * @since 3.5.0
  1029. */
  1030. reset: function() {
  1031. this.get('selection').reset();
  1032. this.resetDisplays();
  1033. this.refreshContent();
  1034. },
  1035. /**
  1036. * Reset the attachment display settings defaults to the site options.
  1037. *
  1038. * If site options don't define them, fall back to a persistent user setting.
  1039. *
  1040. * @since 3.5.0
  1041. */
  1042. resetDisplays: function() {
  1043. var defaultProps = wp.media.view.settings.defaultProps;
  1044. this._displays = [];
  1045. this._defaultDisplaySettings = {
  1046. align: getUserSetting( 'align', defaultProps.align ) || 'none',
  1047. size: getUserSetting( 'imgsize', defaultProps.size ) || 'medium',
  1048. link: getUserSetting( 'urlbutton', defaultProps.link ) || 'none'
  1049. };
  1050. },
  1051. /**
  1052. * Create a model to represent display settings (alignment, etc.) for an attachment.
  1053. *
  1054. * @since 3.5.0
  1055. *
  1056. * @param {wp.media.model.Attachment} attachment
  1057. * @returns {Backbone.Model}
  1058. */
  1059. display: function( attachment ) {
  1060. var displays = this._displays;
  1061. if ( ! displays[ attachment.cid ] ) {
  1062. displays[ attachment.cid ] = new Backbone.Model( this.defaultDisplaySettings( attachment ) );
  1063. }
  1064. return displays[ attachment.cid ];
  1065. },
  1066. /**
  1067. * Given an attachment, create attachment display settings properties.
  1068. *
  1069. * @since 3.6.0
  1070. *
  1071. * @param {wp.media.model.Attachment} attachment
  1072. * @returns {Object}
  1073. */
  1074. defaultDisplaySettings: function( attachment ) {
  1075. var settings = _.clone( this._defaultDisplaySettings );
  1076. if ( settings.canEmbed = this.canEmbed( attachment ) ) {
  1077. settings.link = 'embed';
  1078. } else if ( ! this.isImageAttachment( attachment ) && settings.link === 'none' ) {
  1079. settings.link = 'file';
  1080. }
  1081. return settings;
  1082. },
  1083. /**
  1084. * Whether an attachment is image.
  1085. *
  1086. * @since 4.4.1
  1087. *
  1088. * @param {wp.media.model.Attachment} attachment
  1089. * @returns {Boolean}
  1090. */
  1091. isImageAttachment: function( attachment ) {
  1092. // If uploading, we know the filename but not the mime type.
  1093. if ( attachment.get('uploading') ) {
  1094. return /\.(jpe?g|png|gif)$/i.test( attachment.get('filename') );
  1095. }
  1096. return attachment.get('type') === 'image';
  1097. },
  1098. /**
  1099. * Whether an attachment can be embedded (audio or video).
  1100. *
  1101. * @since 3.6.0
  1102. *
  1103. * @param {wp.media.model.Attachment} attachment
  1104. * @returns {Boolean}
  1105. */
  1106. canEmbed: function( attachment ) {
  1107. // If uploading, we know the filename but not the mime type.
  1108. if ( ! attachment.get('uploading') ) {
  1109. var type = attachment.get('type');
  1110. if ( type !== 'audio' && type !== 'video' ) {
  1111. return false;
  1112. }
  1113. }
  1114. return _.contains( wp.media.view.settings.embedExts, attachment.get('filename').split('.').pop() );
  1115. },
  1116. /**
  1117. * If the state is active, no items are selected, and the current
  1118. * content mode is not an option in the state's router (provided
  1119. * the state has a router), reset the content mode to the default.
  1120. *
  1121. * @since 3.5.0
  1122. */
  1123. refreshContent: function() {
  1124. var selection = this.get('selection'),
  1125. frame = this.frame,
  1126. router = frame.router.get(),
  1127. mode = frame.content.mode();
  1128. if ( this.active && ! selection.length && router && ! router.get( mode ) ) {
  1129. this.frame.content.render( this.get('content') );
  1130. }
  1131. },
  1132. /**
  1133. * Callback handler when an attachment is uploaded.
  1134. *
  1135. * Switch to the Media Library if uploaded from the 'Upload Files' tab.
  1136. *
  1137. * Adds any uploading attachments to the selection.
  1138. *
  1139. * If the state only supports one attachment to be selected and multiple
  1140. * attachments are uploaded, the last attachment in the upload queue will
  1141. * be selected.
  1142. *
  1143. * @since 3.5.0
  1144. *
  1145. * @param {wp.media.model.Attachment} attachment
  1146. */
  1147. uploading: function( attachment ) {
  1148. var content = this.frame.content;
  1149. if ( 'upload' === content.mode() ) {
  1150. this.frame.content.mode('browse');
  1151. }
  1152. if ( this.get( 'autoSelect' ) ) {
  1153. this.get('selection').add( attachment );
  1154. this.frame.trigger( 'library:selection:add' );
  1155. }
  1156. },
  1157. /**
  1158. * Persist the mode of the content region as a user setting.
  1159. *
  1160. * @since 3.5.0
  1161. */
  1162. saveContentMode: function() {
  1163. if ( 'browse' !== this.get('router') ) {
  1164. return;
  1165. }
  1166. var mode = this.frame.content.mode(),
  1167. view = this.frame.router.get();
  1168. if ( view && view.get( mode ) ) {
  1169. setUserSetting( 'libraryContent', mode );