PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/menu-icons/js/admin.js

https://gitlab.com/hop23typhu/list-theme
JavaScript | 1055 lines | 809 code | 201 blank | 45 comment | 47 complexity | ba181c766ebf01748ea592df17f47987 MD5 | raw file
  1. /* global jQuery, wp, window: false, Backbone: false, _: false */
  2. /**
  3. * Menu Icons
  4. *
  5. * @author Dzikri Aziz <kvcrvt@gmail.com>
  6. * @version 0.1.0
  7. *
  8. */
  9. (function($) {
  10. 'use strict';
  11. $.inputDependencies({
  12. selector : 'select.hasdep',
  13. disable : false
  14. });
  15. /**
  16. * Settings box tabs
  17. *
  18. * We can't use core's tabs script here because it will clear the
  19. * checkboxes upon tab switching
  20. */
  21. $('#menu-icons-settings-tabs')
  22. .on('click', 'a.mi-settings-nav-tab', function(e) {
  23. e.preventDefault();
  24. e.stopPropagation();
  25. var $el = $(this).blur();
  26. var $target = $( '#'+$el.data('type') );
  27. $el.parent().addClass('tabs').siblings().removeClass('tabs');
  28. $target
  29. .removeClass('tabs-panel-inactive')
  30. .addClass('tabs-panel-active')
  31. .show()
  32. .siblings('div.tabs-panel')
  33. .hide()
  34. .addClass('tabs-panel-inactive')
  35. .removeClass('tabs-panel-active');
  36. })
  37. .find('a.mi-settings-nav-tab').first().click();
  38. if ( 'undefined' === typeof window.menuIcons ) {
  39. return;
  40. }
  41. if ( undefined === window.menuIcons.iconTypes ) {
  42. return;
  43. }
  44. window.menuIcons = _.defaults({
  45. frame : '',
  46. currentItem : {},
  47. toggleSelect : function(e) {
  48. var $type = $(e.currentTarget);
  49. var $wrapr = $type.closest('div.menu-icons-wrap');
  50. var $select = $wrapr.find('a._select');
  51. var $remove = $wrapr.find('a._remove');
  52. if ( '' !== $type.val() ) {
  53. $remove.show();
  54. }
  55. else {
  56. $select.text( $select.data('text') );
  57. $remove.hide();
  58. }
  59. },
  60. selectIcon : function(e) {
  61. e.preventDefault();
  62. e.stopPropagation();
  63. var $el = $(this);
  64. var id = media.view.settings.post.id = $el.data('id');
  65. var attrs = {
  66. id : id,
  67. title : $('#edit-menu-item-title-'+id).val()
  68. };
  69. $el.closest('div.menu-icons-wrap').find(':input').each(function(i, input) {
  70. var key = $(input).data('key');
  71. attrs[ key ] = input.value;
  72. });
  73. window.menuIcons.currentItem = attrs;
  74. if ( ! ( window.menuIcons.frame instanceof media.view.MediaFrame.menuIcons ) ) {
  75. window.menuIcons.frame = new media.view.MediaFrame.menuIcons();
  76. }
  77. window.menuIcons.frame.open();
  78. },
  79. removeIcon : function(e) {
  80. e.preventDefault();
  81. e.stopPropagation();
  82. var id = $(this).data('id');
  83. $('#menu-icons-'+ id +'-type').val('').trigger('mi:update');
  84. }
  85. }, window.menuIcons);
  86. // WP Media
  87. var media = wp.media;
  88. var Attachment = media.model.Attachment;
  89. // Models
  90. media.model.mi = {};
  91. // Model: Menu Items
  92. media.model.mi.MenuItems = Backbone.Collection.extend({
  93. props : new Backbone.Model({ item : '' }),
  94. model : Backbone.Model.extend({
  95. defaults : {
  96. type : '',
  97. group : 'all',
  98. icon : ''
  99. },
  100. })
  101. });
  102. // Model: Settings fields
  103. media.model.mi.MenuItems.Settings = Backbone.Collection.extend({
  104. model : Backbone.Model.extend({
  105. defaults : {
  106. id : '',
  107. label : '',
  108. value : '',
  109. type : 'text'
  110. }
  111. })
  112. });
  113. // All: Sidebar
  114. media.view.miSidebar = media.view.Sidebar.extend({
  115. initialize : function() {
  116. var title = new media.View({
  117. tagName : 'h3',
  118. priority : -10
  119. });
  120. var info = new media.View({
  121. tagName : 'p',
  122. className : '_info',
  123. priority : 1000
  124. });
  125. media.view.Sidebar.prototype.initialize.apply( this, arguments );
  126. title.$el.text( window.menuIcons.text.preview );
  127. this.set( 'title', title );
  128. info.$el.html( window.menuIcons.text.settingsInfo );
  129. this.set( 'info', info );
  130. }
  131. });
  132. // View: Settings wrapper
  133. media.view.miSidebar.Settings = media.view.PriorityList.extend({
  134. className : 'mi-settings attachment-info',
  135. prepare : function() {
  136. _.each( this.collection.map( this.createField, this ), function( view ) {
  137. this.set( view.model.id, view );
  138. }, this );
  139. },
  140. createField : function( model ) {
  141. var field = new media.view.miSidebar.Settings.Field({
  142. item : this.model,
  143. model : model,
  144. collection : this.collection
  145. });
  146. return field;
  147. }
  148. });
  149. // View: Settings field
  150. media.view.miSidebar.Settings.Field = media.View.extend({
  151. tagName : 'label',
  152. className : 'setting',
  153. events : {
  154. 'change :input' : '_update'
  155. },
  156. initialize : function() {
  157. media.View.prototype.initialize.apply( this, arguments );
  158. this.template = media.template( 'menu-icons-settings-field-'+this.model.get('type') );
  159. this.model.on( 'change', this.render, this );
  160. },
  161. prepare : function() {
  162. return this.model.toJSON();
  163. },
  164. _update : function(e) {
  165. var item = this.options.item;
  166. var $input = $(e.currentTarget);
  167. var value = $input.val();
  168. var $field = $('#menu-icons-'+ item.id +'-'+ this.model.id +'._setting');
  169. this.model.set( 'value', value );
  170. item.set( this.model.id, value );
  171. $field.val( value ).trigger('mi:update');
  172. }
  173. });
  174. // View: Item preview on the sidebar
  175. media.view.miPreview = media.View.extend({
  176. tagName : 'p',
  177. className : 'mi-preview menu-item attachment-info',
  178. events : {
  179. 'click a' : 'preventDefault'
  180. },
  181. initialize : function() {
  182. media.View.prototype.initialize.apply( this, arguments );
  183. this.model.on( 'change', this.render, this );
  184. },
  185. render : function() {
  186. var data = _.extend( this.model.toJSON(), this.options.data );
  187. var template = 'menu-icons-' + data.type + '-preview-';
  188. if ( data.hide_label ) {
  189. template += 'hide_label';
  190. }
  191. else {
  192. template += data.position;
  193. }
  194. this.template = media.template( template );
  195. this.$el.html( this.template( data ) );
  196. return this;
  197. },
  198. preventDefault: function(e) {
  199. e.preventDefault();
  200. }
  201. });
  202. // Methods for the browser view
  203. media.view.miBrowser = {
  204. createSidebar : function() {
  205. var options = this.options;
  206. var selection = options.selection;
  207. var sidebar = this.sidebar = new media.view.miSidebar({
  208. controller : this.controller,
  209. type : options.type
  210. });
  211. this.views.add( sidebar );
  212. selection.on( 'selection:single', this.createSingle, this );
  213. selection.on( 'selection:unsingle', this.disposeSingle, this );
  214. if ( selection.single() ) {
  215. this.createSingle();
  216. }
  217. },
  218. createSingle : function() {
  219. this.createPreview();
  220. },
  221. createSettings : function() {
  222. var item = this.controller.miGetCurrentItem();
  223. var fields = this.model.get('settings');
  224. if ( ! fields.length ) {
  225. return;
  226. }
  227. _.each( fields, function( field ) {
  228. field.value = item.get( field.id );
  229. } );
  230. this.sidebar.set( 'settings', new media.view.miSidebar.Settings({
  231. controller : this.controller,
  232. collection : new media.model.mi.MenuItems.Settings( fields ),
  233. model : item,
  234. type : this.options.type,
  235. priority : 120
  236. }) );
  237. }
  238. };
  239. // View: Font icon: Browser
  240. media.view.miFont = media.View.extend({
  241. className : 'attachments-browser mi-items-wrap',
  242. initialize : function() {
  243. this.createToolbar();
  244. this.createLibrary();
  245. this.createSidebar();
  246. },
  247. createLibrary : function() {
  248. this.items = new media.view.miFont.Library({
  249. controller : this.controller,
  250. collection : this.collection,
  251. selection : this.options.selection,
  252. type : this.options.type,
  253. data : this.options.data
  254. });
  255. this.views.add( this.items );
  256. },
  257. createToolbar : function() {
  258. var library = this.collection;
  259. var group = library.props.get('group');
  260. this.toolbar = new media.view.Toolbar({
  261. controller : this.controller
  262. });
  263. this.views.add( this.toolbar );
  264. // Dropdown filter
  265. this.toolbar.set( 'filters', new media.view.miFont.Filters({
  266. controller : this.controller,
  267. model : this.collection.props,
  268. priority : -80
  269. }).render() );
  270. // Search field
  271. this.toolbar.set( 'search', new media.view.Search({
  272. controller : this.controller,
  273. model : this.collection.props,
  274. priority : 60
  275. }).render() );
  276. },
  277. createPreview : function() {
  278. var controller = this.controller;
  279. var menuItem = controller.miGetCurrentItem();
  280. var selected = this.model.get('selection').single();
  281. this.createSettings();
  282. this.sidebar.set( 'preview', new media.view.miPreview({
  283. controller : controller,
  284. model : menuItem,
  285. data : {
  286. type : selected.get('type'),
  287. icon : selected.id
  288. },
  289. priority : 80
  290. }) );
  291. },
  292. disposeSingle : function() {
  293. var sidebar = this.sidebar;
  294. sidebar.unset('preview');
  295. sidebar.unset('settings');
  296. }
  297. });
  298. _.extend( media.view.miFont.prototype, media.view.miBrowser );
  299. // View: Font icon: Library
  300. media.view.miFont.Library = media.View.extend({
  301. tagName : 'ul',
  302. className : 'attachments mi-items clearfix',
  303. initialize : function() {
  304. this._viewsByCid = {};
  305. this.collection.on( 'reset', this.refresh, this );
  306. this.controller.on( 'open', this.scrollToSelected, this );
  307. },
  308. render : function() {
  309. this.collection.each( function( model ) {
  310. this.views.add( this.renderItem( model ), {
  311. at : this.collection.indexOf( model )
  312. } );
  313. }, this );
  314. return this;
  315. },
  316. renderItem : function( model ) {
  317. var view = new media.view.miFont.Icon({
  318. controller : this.controller,
  319. model : model,
  320. collection : this.collection,
  321. selection : this.options.selection,
  322. type : this.options.type,
  323. data : this.options.data
  324. });
  325. return this._viewsByCid[ view.cid ] = view;
  326. },
  327. clearItems : function() {
  328. _.each( this._viewsByCid, function( view ) {
  329. delete this._viewsByCid[ view.cid ];
  330. view.remove();
  331. }, this );
  332. },
  333. refresh : function() {
  334. this.clearItems();
  335. this.render();
  336. },
  337. ready : function() {
  338. this.scrollToSelected();
  339. },
  340. scrollToSelected : function() {
  341. var single = this.options.selection.single();
  342. var singleView;
  343. if ( ! single ) {
  344. return;
  345. }
  346. singleView = this.getView( single );
  347. if ( singleView && ! this.isInView( singleView.$el ) ) {
  348. this.$el.scrollTop( singleView.$el.offset().top - this.$el.offset().top + this.$el.scrollTop() - parseInt( this.$el.css('paddingTop') ) );
  349. }
  350. },
  351. getView : function( model ) {
  352. return _.findWhere( this._viewsByCid, { model : model } );
  353. },
  354. isInView: function( $elem ) {
  355. var $window = $(window);
  356. var docViewTop = $window.scrollTop();
  357. var docViewBottom = docViewTop + $window.height();
  358. var elemTop = $elem.offset().top;
  359. var elemBottom = elemTop + $elem.height();
  360. return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
  361. }
  362. });
  363. // View: Font icon: Dropdown filter
  364. media.view.miFont.Filters = media.view.AttachmentFilters.extend({
  365. createFilters : function() {
  366. this.filters = {
  367. all : {
  368. text : window.menuIcons.text.all,
  369. props : {
  370. group : 'all'
  371. }
  372. }
  373. };
  374. var groups = this.controller.state().get('data').groups;
  375. _.each( groups, function( text, id ) {
  376. this.filters[ id ] = {
  377. text : text,
  378. props : {
  379. group : id
  380. }
  381. };
  382. }, this );
  383. },
  384. change : function() {
  385. var filter = this.filters[ this.el.value ];
  386. if ( filter ) {
  387. this.model.set( 'group', filter.props.group );
  388. }
  389. }
  390. });
  391. // View: Font icon: Item
  392. media.view.miFont.Icon = media.view.Attachment.extend({
  393. className : 'attachment mi-item',
  394. events : {
  395. 'click .attachment-preview' : 'toggleSelectionHandler',
  396. 'click a' : 'preventDefault'
  397. },
  398. initialize : function() {
  399. this.template = media.template( 'menu-icons-' + this.options.type + '-item' );
  400. media.view.Attachment.prototype.initialize.apply( this, arguments );
  401. },
  402. render: function() {
  403. this.$el.html( this.template( this.model.toJSON() ) );
  404. this.updateSelect();
  405. return this;
  406. }
  407. });
  408. // Font icon state
  409. media.controller.miFont = media.controller.State.extend({
  410. defaults : {
  411. id : 'mi-font',
  412. menu : 'default',
  413. toolbar : 'mi-select',
  414. type : '',
  415. settings : [ 'hide_label', 'position', 'font_size', 'vertical_align' ]
  416. },
  417. initialize : function() {
  418. var icons = this.get('data').items;
  419. var library = this.get('library');
  420. var selection = this.get('selection');
  421. var fieldIds = this.get('settings');
  422. var fields;
  423. if ( ! ( library instanceof media.controller.miFont.Library ) ) {
  424. library = new media.controller.miFont.Library( icons );
  425. library.props.on( 'change', this.miResetLibrary, this );
  426. this.set( 'library', library );
  427. }
  428. if ( ! ( selection instanceof media.model.Selection ) ) {
  429. this.set( 'selection', new media.model.Selection( selection, {
  430. multiple : false
  431. }) );
  432. }
  433. fields = _.filter( window.menuIcons.settingsFields, function( field ) {
  434. return ( -1 !== $.inArray( field.id, fieldIds ) );
  435. });
  436. this.set( 'settings', fields );
  437. },
  438. activate : function() {
  439. this.frame.on( 'open', this.refresh, this );
  440. this.miUpdateSelection();
  441. },
  442. deactivate : function() {
  443. media.controller.State.prototype.deactivate.apply( this, arguments );
  444. this.frame.off( 'open', this.refresh, this );
  445. },
  446. refresh : function() {
  447. this.miResetFilter();
  448. this.miUpdateSelection();
  449. },
  450. miGetContent : function() {
  451. this.miResetFilter();
  452. return new media.view.miFont({
  453. controller : this.frame,
  454. model : this,
  455. collection : this.get('library'),
  456. selection : this.get('selection'),
  457. type : this.get('type')
  458. });
  459. },
  460. miResetLibrary : function() {
  461. var library = this.get('library');
  462. var group = library.props.get('group');
  463. var item = this.frame.miGetCurrentItem();
  464. item.set( 'group', group );
  465. library.reInitialize();
  466. this.set( 'library', library );
  467. this.miUpdateSelection();
  468. },
  469. miResetFilter : function() {
  470. var library = this.get('library');
  471. var item = this.frame.miGetCurrentItem();
  472. var groups = this.get('data').groups;
  473. var group = item.get('group');
  474. if ( _.isUndefined( groups[ group ] ) ) {
  475. group = 'all';
  476. }
  477. library.props.set( 'group', group );
  478. },
  479. miUpdateSelection : function() {
  480. var selection = this.get('selection');
  481. var type = this.get('type');
  482. var key = type+'-icon';
  483. var item = this.frame.miGetCurrentItem();
  484. var icon = item.get(key);
  485. var selected;
  486. if ( type === item.get('type') && icon ) {
  487. selected = this.get('library').findWhere({id: icon});
  488. }
  489. selection.reset( selected ? selected : [] );
  490. }
  491. });
  492. // Font icon collection
  493. media.controller.miFont.Library = Backbone.Collection.extend({
  494. props : new Backbone.Model({
  495. group : 'all',
  496. search : ''
  497. }),
  498. initialize : function( models ) {
  499. this.icons = new Backbone.Collection( models );
  500. },
  501. reInitialize : function() {
  502. var library = this;
  503. var icons = this.icons.toJSON();
  504. var props = this.props.toJSON();
  505. _.each( props, function( val, filter ) {
  506. if ( library.filters[ filter ] ) {
  507. icons = _.filter( icons, library.filters[ filter ], val );
  508. }
  509. }, this);
  510. this.reset( icons );
  511. },
  512. filters : {
  513. group : function( icon ) {
  514. var group = this;
  515. return ( 'all' === group || icon.group === group || '' === icon.group );
  516. },
  517. search : function( icon ) {
  518. var term = this;
  519. var result;
  520. if ( '' === term ) {
  521. result = true;
  522. }
  523. else {
  524. result = _.any(['id','label'], function( key ) {
  525. var value = icon[key];
  526. return value && -1 !== value.search( this );
  527. }, term );
  528. }
  529. return result;
  530. }
  531. }
  532. });
  533. // Image icon state
  534. media.controller.miImage = media.controller.Library.extend({
  535. defaults : _.defaults({
  536. id : 'browse',
  537. menu : 'default',
  538. router : 'browse',
  539. toolbar : 'mi-select',
  540. filterable : 'uploaded',
  541. settings : [ 'hide_label', 'position', 'image_size', 'vertical_align' ],
  542. syncSelection : false
  543. }, media.controller.Library.prototype.defaults),
  544. initialize : function() {
  545. var selection = this.get('selection');
  546. var fieldIds = this.get('settings');
  547. var fields;
  548. this.set( 'library', media.query({ type: 'image' }) );
  549. this.routers = {
  550. upload : {
  551. text: media.view.l10n.uploadFilesTitle,
  552. priority: 20
  553. },
  554. browse : {
  555. text: media.view.l10n.mediaLibraryTitle,
  556. priority: 40
  557. }
  558. };
  559. if ( ! ( selection instanceof media.model.Selection ) ) {
  560. this.set( 'selection', new media.model.Selection( selection, {
  561. multiple : false
  562. }) );
  563. }
  564. fields = _.filter( window.menuIcons.settingsFields, function( field ) {
  565. return ( -1 !== $.inArray( field.id, fieldIds ) );
  566. });
  567. this.set( 'settings', fields );
  568. media.controller.Library.prototype.initialize.apply( this, arguments );
  569. },
  570. activate : function() {
  571. media.controller.Library.prototype.activate.apply( this, arguments );
  572. this.frame.on( 'open', this.miUpdateSelection, this );
  573. this.miUpdateSelection();
  574. },
  575. deactivate : function() {
  576. media.controller.Library.prototype.deactivate.apply( this, arguments );
  577. this.frame.off( 'open', this.miUpdateSelection, this );
  578. },
  579. miUpdateSelection : function() {
  580. var selection = this.get('selection');
  581. var type = this.get('type');
  582. var key = type+'-icon';
  583. var item = this.frame.miGetCurrentItem();
  584. var icon = item.get(key);
  585. var attachment;
  586. if ( type === item.get('type') && icon ) {
  587. attachment = Attachment.get( icon );
  588. this.dfd = attachment.fetch();
  589. }
  590. selection.reset( attachment ? attachment : [] );
  591. },
  592. miGetContent : function( mode ) {
  593. var content = ( 'upload' === mode ) ? this.uploadContent() : this.browseContent();
  594. this.frame.$el.removeClass('hide-toolbar');
  595. return content;
  596. },
  597. browseContent: function() {
  598. var state = this;
  599. // Browse our library of attachments.
  600. return new media.view.AttachmentsBrowser.miImage({
  601. type : state.get('type'),
  602. controller : state.frame,
  603. collection : state.get('library'),
  604. selection : state.get('selection'),
  605. model : state,
  606. sortable : state.get('sortable'),
  607. search : state.get('searchable'),
  608. filters : state.get('filterable'),
  609. display : state.get('displaySettings'),
  610. dragInfo : state.get('dragInfo')
  611. });
  612. },
  613. /**
  614. * Render callback for the content region in the `upload` mode.
  615. */
  616. uploadContent: function() {
  617. return new media.view.UploaderInline({
  618. controller: this.frame
  619. });
  620. }
  621. });
  622. // View: Image Icon: Browser
  623. media.view.AttachmentsBrowser.miImage = media.view.AttachmentsBrowser.extend({
  624. disposeSingle : function() {
  625. media.view.AttachmentsBrowser.prototype.disposeSingle.apply( this, arguments );
  626. this.sidebar.unset('preview');
  627. this.sidebar.unset('settings');
  628. },
  629. createPreview : function() {
  630. var self = this;
  631. var state = this.model;
  632. var selected, controller, menuItem;
  633. if ( state.dfd && 'pending' === state.dfd.state() ) {
  634. state.dfd.done( function() {
  635. self.createPreview();
  636. } );
  637. return;
  638. }
  639. selected = state.get('selection').single();
  640. // Disallow anything but image
  641. if ( 'image' !== selected.get('type') ) {
  642. state.get('selection').reset();
  643. return;
  644. }
  645. // Wait for the upload process to finish
  646. if ( selected.get('uploading') ) {
  647. selected.on( 'change:uploading', self.createPreview, this );
  648. return;
  649. }
  650. controller = this.controller;
  651. menuItem = controller.miGetCurrentItem();
  652. this.createSettings();
  653. this.sidebar.set( 'preview', new media.view.miPreview.miImage({
  654. controller : controller,
  655. settings : this.sidebar.get('settings'),
  656. model : menuItem,
  657. data : {
  658. type : state.get('type'),
  659. alt : selected.get('alt'),
  660. sizes : selected.get('sizes')
  661. },
  662. priority : 80
  663. }) );
  664. }
  665. });
  666. _.extend( media.view.AttachmentsBrowser.miImage.prototype, media.view.miBrowser );
  667. // View: Image Icon: Preview on the sidebar
  668. media.view.miPreview.miImage = media.view.miPreview.extend({
  669. render : function() {
  670. var size = this.options.model.get('image_size');
  671. var imageSizes = this.options.data.sizes;
  672. var sizeField = this.options.settings.get('image_size');
  673. var newChoices = [];
  674. if ( ! imageSizes.hasOwnProperty( size ) ) {
  675. size = 'full';
  676. }
  677. _.each( sizeField.model.get('choices'), function( choice ) {
  678. if ( imageSizes.hasOwnProperty( choice.value ) ) {
  679. newChoices.push( choice );
  680. }
  681. } );
  682. sizeField.model.set( 'choices', newChoices );
  683. this.options.model.set( 'image_size', size, { silent: true } );
  684. this.options.data.url = imageSizes[ size ].url;
  685. return media.view.miPreview.prototype.render.apply( this, arguments );
  686. }
  687. });
  688. // Frame
  689. media.view.MediaFrame.menuIcons = media.view.MediaFrame.extend({
  690. initialize : function() {
  691. media.view.MediaFrame.prototype.initialize.apply( this, arguments );
  692. _.defaults( this.options, {
  693. selection : [],
  694. multiple : false,
  695. editing : false,
  696. toolbar : 'mi-select',
  697. });
  698. this.miMenuItems = new media.model.mi.MenuItems();
  699. this.createStates();
  700. this.bindHandlers();
  701. },
  702. createStates : function() {
  703. var options = this.options;
  704. var Controller;
  705. if ( options.states ) {
  706. return;
  707. }
  708. _.each( window.menuIcons.iconTypes, function( props, type ) {
  709. if ( ! media.controller.hasOwnProperty( props.data.controller ) ) {
  710. delete window.menuIcons.iconTypes[ type ];
  711. return;
  712. }
  713. Controller = media.controller[ props.data.controller ];
  714. _.defaults( props, {
  715. content : props.id,
  716. selection : options.selection
  717. } );
  718. // States
  719. this.states.add( new Controller( props ) );
  720. }, this );
  721. },
  722. bindHandlers : function() {
  723. this.on( 'router:create:browse', this.createRouter, this );
  724. this.on( 'router:render:browse', this.browseRouter, this );
  725. this.on( 'content:render', this.miRenderContent, this );
  726. this.on( 'toolbar:create:mi-select', this.createToolbar, this );
  727. this.on( 'toolbar:render:mi-select', this.miSelectToolbar, this );
  728. this.on( 'open', this.miInitialize, this );
  729. },
  730. browseRouter : function( routerView ) {
  731. var routers = this.state().routers;
  732. if ( routers ) {
  733. routerView.set( routers );
  734. }
  735. },
  736. miRenderContent : function() {
  737. var state = this.state();
  738. var mode = this.content.mode();
  739. var content = state.miGetContent( mode );
  740. this.content.set( content );
  741. },
  742. // Toolbars
  743. miSelectToolbar : function( view ) {
  744. var frame = this;
  745. var state = frame.state();
  746. var type = state.get('type');
  747. view.set( state.id, {
  748. style : 'primary',
  749. priority : 80,
  750. text : window.menuIcons.text.select,
  751. requires : {
  752. selection : true
  753. },
  754. click : function() {
  755. frame.close();
  756. frame.miUpdateItemProps();
  757. frame.miUpdateItem();
  758. }
  759. });
  760. },
  761. // Content
  762. miContentRender : function() {
  763. var state = this.state();
  764. var content = state.miGetContent();
  765. this.content.set( content );
  766. },
  767. miGetState : function() {
  768. var item = window.menuIcons.currentItem;
  769. var type;
  770. if ( ! _.isUndefined( item.type ) && '' !== item.type && window.menuIcons.iconTypes.hasOwnProperty( item.type ) ) {
  771. type = item.type;
  772. }
  773. else {
  774. type = window.menuIcons.typeNames[0];
  775. }
  776. return 'mi-'+type;
  777. },
  778. miGetCurrentItem : function() {
  779. return this.miMenuItems.get( window.menuIcons.currentItem.id );
  780. },
  781. miUpdateMenuItems : function() {
  782. var item = this.miGetCurrentItem();
  783. if ( _.isUndefined( item ) ) {
  784. this.miMenuItems.add( window.menuIcons.currentItem );
  785. }
  786. else {
  787. item.set( window.menuIcons.currentItem );
  788. }
  789. this.miMenuItems.props.set( 'item', window.menuIcons.currentItem.id );
  790. },
  791. miInitialize : function() {
  792. this.miUpdateMenuItems();
  793. this.setState( this.miGetState() );
  794. },
  795. miUpdateItemProps : function() {
  796. var state = this.state();
  797. var type = state.get('type');
  798. var selection = state.get('selection');
  799. var single = selection.single();
  800. var icon = single ? single.id : '';
  801. var item = this.miGetCurrentItem();
  802. item.set( 'type', type );
  803. item.set( type+'-icon', icon );
  804. item.set( 'icon', icon );
  805. },
  806. miUpdateItem : function() {
  807. var attrs = this.miGetCurrentItem().toJSON();
  808. var id = attrs.id;
  809. var state = this.state();
  810. var selected = state.get('selection').single();
  811. var template = media.template( 'menu-icons-'+ attrs.type +'-field' );
  812. var data = selected.toJSON();
  813. var $el;
  814. data._settings = attrs;
  815. delete attrs.id;
  816. delete attrs.title;
  817. _.each( attrs, function( value, key ) {
  818. $el = $('#menu-icons-'+ id +'-'+ key).not('._setting');
  819. if ( $el.length ) {
  820. $el.val( value ).trigger('mi:update');
  821. }
  822. });
  823. $('#menu-icons-'+ id +'-select').html( template( data ) );
  824. }
  825. });
  826. $('body')
  827. .on( 'click', 'div.menu-icons-wrap a._select', window.menuIcons.selectIcon )
  828. .on( 'click', 'div.menu-icons-wrap a._remove', window.menuIcons.removeIcon )
  829. .on( 'mi:update', 'div.menu-icons-wrap select._type', window.menuIcons.toggleSelect );
  830. $('div.menu-icons-wrap select._type').trigger('mi:update');
  831. // Settings meta box
  832. $('#menu-item-settings-save').on('click', function(e) {
  833. var $button = $(this).prop( 'disabled', true );
  834. var $spinner = $button.siblings('span.spinner');
  835. e.preventDefault();
  836. $spinner.css( 'display', 'inline-block' );
  837. $.ajax({
  838. type : 'POST',
  839. url : window.menuIcons.ajaxUrls.update,
  840. data : $('#menu-icons-settings :input').serialize(),
  841. success : function( response, xhr ) {
  842. if ( true === response.success && response.data.redirectUrl ) {
  843. window.location = response.data.redirectUrl;
  844. }
  845. else {
  846. $button.prop( 'disabled', false );
  847. }
  848. },
  849. always : function() {
  850. $spinner.hide();
  851. }
  852. });
  853. });
  854. }(jQuery));