fl-builder-ui-main-menu.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. (function($, FLBuilder) {
  2. /**
  3. * Base prototype for views in the menu
  4. */
  5. var PanelView = FLExtendableObject.create({
  6. templateName: "fl-main-menu-panel-view",
  7. name: "Untitled View",
  8. isShowing: false,
  9. isRootView: false,
  10. items: {},
  11. /**
  12. * Initialize the view
  13. *
  14. * @return void
  15. */
  16. init: function() {
  17. this.template = wp.template(this.templateName);
  18. },
  19. /**
  20. * Render the view
  21. *
  22. * @return String
  23. */
  24. render: function() {
  25. return this.template(this);
  26. },
  27. /**
  28. * Setup Events
  29. *
  30. * @return void
  31. */
  32. bindEvents: function() {
  33. this.$items = this.$el.find('.fl-builder--menu-item');
  34. },
  35. /**
  36. * Make this the current view
  37. *
  38. * @return void
  39. */
  40. show: function() {
  41. this.$el.addClass('is-showing');
  42. },
  43. /**
  44. * Resign the active view
  45. *
  46. * @return void
  47. */
  48. hide: function() {
  49. this.$el.removeClass('is-showing');
  50. },
  51. /**
  52. * Handle transitioning the view in
  53. *
  54. * @return void
  55. */
  56. transitionIn: function(reverse) {
  57. requestAnimationFrame( this.show.bind(this) );
  58. },
  59. /**
  60. * Handle transition away from the view
  61. *
  62. * @return void
  63. */
  64. transitionOut: function(reverse) {
  65. this.hide();
  66. },
  67. });
  68. /**
  69. * Menu Panel
  70. */
  71. var MainMenuPanel = FLExtendableObject.create({
  72. templateName: 'fl-main-menu-panel',
  73. template: null,
  74. menu: null,
  75. views: {},
  76. viewNavigationStack: [],
  77. isShowing: false,
  78. shouldShowTabs: false,
  79. /**
  80. * Setup and render the menu
  81. *
  82. * @return void
  83. */
  84. init: function() {
  85. // Render Panel
  86. this.template = wp.template(this.templateName);
  87. $('body').prepend( this.template(this) );
  88. this.$el = $('.fl-builder--main-menu-panel');
  89. this.$el.find('.fl-builder--main-menu-panel-views').html('');
  90. // Render Views
  91. for (var key in FLBuilderConfig.mainMenu) {
  92. this.renderPanel( key );
  93. var hook = 'render' + key.charAt(0).toUpperCase() + key.slice(1) + 'Panel';
  94. FLBuilder.addHook( hook, $.proxy( function(){
  95. this.renderPanel( key );
  96. }, this ) );
  97. }
  98. // Event Listeners
  99. $('body').on('click', '.fl-builder--main-menu-panel .pop-view', this.goToPreviousView.bind(this));
  100. this.$tabs = this.$el.find('.fl-builder--tabs > span'); /* on purpose */
  101. this.$tabs.on('click', this.onItemClick.bind(this));
  102. this.$barTitle = $('.fl-builder-bar-title'); /* on purpose */
  103. $('body').on('click', '.fl-builder-bar-title', this.toggle.bind(this));
  104. var hide = this.hide.bind(this);
  105. FLBuilder.addHook('didShowPublishActions', hide);
  106. FLBuilder.addHook('didBeginSearch', hide);
  107. FLBuilder.addHook('didBeginPreview', hide);
  108. FLBuilder.addHook('didShowContentPanel', hide);
  109. FLBuilder.addHook('endEditingSession', hide);
  110. FLBuilder.addHook('didFocusSearchBox', hide);
  111. FLBuilder.addHook('didEnterRevisionPreview', hide);
  112. FLBuilder.addHook('didFailSettingsSave', hide);
  113. FLBuilder.addHook('showKeyboardShortcuts', hide);
  114. this.$mask = $('.fl-builder--main-menu-panel-mask');
  115. this.$mask.on('click', hide);
  116. Tools.init();
  117. Help.init();
  118. },
  119. /**
  120. * Render the panel
  121. *
  122. * @param String key
  123. * @return void
  124. */
  125. renderPanel: function( key ) {
  126. var data, view, $html;
  127. $( 'fl-builder--main-menu-panel-view[data-name="' + key + '"]' ).remove();
  128. data = FLBuilderConfig.mainMenu[ key ];
  129. data.handle = key;
  130. view = PanelView.create( data );
  131. view.init();
  132. $html = $( view.render() );
  133. view.$el = $html;
  134. $( '.fl-builder--main-menu-panel-views' ).append( $html );
  135. view.bindEvents();
  136. view.$el.find( '.fl-builder--menu-item' ).on( 'click', this.onItemClick.bind( this ) );
  137. if ( view.isRootView ) {
  138. this.rootView = view;
  139. this.currentView = view;
  140. }
  141. this.views[ key ] = view;
  142. },
  143. /**
  144. * Show the menu
  145. *
  146. * @return void
  147. */
  148. show: function() {
  149. if (this.isShowing) return;
  150. this.$el.addClass('is-showing');
  151. this.$barTitle.addClass('is-showing-menu');
  152. this.currentView.transitionIn();
  153. this.isShowing = true;
  154. this.$mask.show();
  155. FLBuilder.triggerHook('didOpenMainMenu');
  156. },
  157. /**
  158. * Hide the menu
  159. *
  160. * @return void
  161. */
  162. hide: function() {
  163. if (!this.isShowing) return;
  164. this.$el.removeClass('is-showing');
  165. this.$barTitle.removeClass('is-showing-menu');
  166. this.isShowing = false;
  167. this.resetViews();
  168. this.$mask.hide();
  169. },
  170. /**
  171. * Toggle show/hide the menu
  172. *
  173. * @return void
  174. */
  175. toggle: function() {
  176. if (this.isShowing) {
  177. this.hide();
  178. } else {
  179. this.show();
  180. }
  181. },
  182. /**
  183. * Handle item click
  184. *
  185. * @param {Event} e
  186. * @return void
  187. */
  188. onItemClick: function(e) {
  189. var $item = $(e.currentTarget),
  190. type = $item.data('type');
  191. switch (type) {
  192. case "view":
  193. var name = $item.data('view');
  194. this.goToView(name);
  195. break;
  196. case "event":
  197. var hook = $item.data('event');
  198. FLBuilder.triggerHook(hook, $item);
  199. break;
  200. case "link":
  201. // follow link
  202. break;
  203. }
  204. },
  205. /**
  206. * Display a specific view
  207. *
  208. * @param String name
  209. * @return void
  210. */
  211. goToView: function(name) {
  212. var currentView = this.currentView;
  213. var newView = this.views[name];
  214. currentView.transitionOut();
  215. newView.transitionIn();
  216. this.currentView = newView;
  217. this.viewNavigationStack.push(currentView);
  218. },
  219. /**
  220. * Pop a view off the stack
  221. *
  222. * @return void
  223. */
  224. goToPreviousView: function() {
  225. var currentView = this.currentView;
  226. var newView = this.viewNavigationStack.pop();
  227. currentView.transitionOut(true);
  228. newView.transitionIn(true);
  229. this.currentView = newView;
  230. //var item = newView.$el.find('.fl-builder--menu-item:first-child').eq(0).trigger('focus');
  231. $('.fl-builder-bar-title-caret').focus();
  232. },
  233. /**
  234. * Reset to root view
  235. *
  236. * @return void
  237. */
  238. resetViews: function() {
  239. if (this.currentView != this.rootView ) {
  240. this.currentView.hide();
  241. this.rootView.show();
  242. this.currentView = this.rootView;
  243. this.viewNavigationStack = [];
  244. }
  245. },
  246. });
  247. FLBuilder.MainMenu = MainMenuPanel;
  248. /**
  249. * Handle tools menu actions
  250. */
  251. var Tools = {
  252. /**
  253. * Setup listeners for tools actions
  254. * @return void
  255. */
  256. init: function() {
  257. FLBuilder.addHook('saveTemplate', this.saveTemplate.bind(this));
  258. FLBuilder.addHook('saveCoreTemplate', this.saveCoreTemplate.bind(this));
  259. FLBuilder.addHook('duplicateLayout', this.duplicateLayout.bind(this));
  260. FLBuilder.addHook('showLayoutSettings', this.showLayoutSettings.bind(this));
  261. FLBuilder.addHook('showGlobalSettings', this.showGlobalSettings.bind(this));
  262. FLBuilder.addHook('toggleUISkin', this.toggleUISkin.bind(this));
  263. FLBuilder.addHook('clearLayoutCache', this.clearLayoutCache.bind(this));
  264. },
  265. /**
  266. * Show the save template lightbox
  267. * @return void
  268. */
  269. saveTemplate: function() {
  270. FLBuilder._saveUserTemplateClicked();
  271. MainMenuPanel.hide();
  272. },
  273. /**
  274. * Show save core template lightbox
  275. * @return void
  276. */
  277. saveCoreTemplate: function() {
  278. FLBuilderCoreTemplatesAdmin._saveClicked();
  279. MainMenuPanel.hide();
  280. },
  281. /**
  282. * Trigger duplicate layout
  283. * @return void
  284. */
  285. duplicateLayout: function() {
  286. FLBuilder._duplicateLayoutClicked();
  287. MainMenuPanel.hide();
  288. },
  289. /**
  290. * Show the global settings lightbox
  291. * @return void
  292. */
  293. showGlobalSettings: function() {
  294. FLBuilder._globalSettingsClicked();
  295. MainMenuPanel.hide();
  296. },
  297. /**
  298. * Show the layout js/css lightbox
  299. * @return void
  300. */
  301. showLayoutSettings: function() {
  302. FLBuilder._layoutSettingsClicked();
  303. MainMenuPanel.hide();
  304. },
  305. /**
  306. * Clear cache for this layout
  307. * @return void
  308. */
  309. clearLayoutCache: function() {
  310. FLBuilder.ajax({
  311. action: 'clear_cache'
  312. }, function() {
  313. location.href = FLBuilderConfig.editUrl;
  314. });
  315. FLBuilder.showAjaxLoader();
  316. MainMenuPanel.hide();
  317. },
  318. /**
  319. * Toggle between the UI Skins
  320. * @var Event
  321. * @return void
  322. */
  323. toggleUISkin: function(e) {
  324. var $item = $('a[data-event="toggleUISkin"]');
  325. if ($('body').hasClass('fl-builder-ui-skin--light')) {
  326. var fromSkin = 'light';
  327. var toSkin = 'dark';
  328. }
  329. if ($('body').hasClass('fl-builder-ui-skin--dark')) {
  330. var fromSkin = 'dark';
  331. var toSkin = 'light';
  332. }
  333. $('body').removeClass('fl-builder-ui-skin--' + fromSkin ).addClass('fl-builder-ui-skin--' + toSkin);
  334. // ajax save
  335. FLBuilder.ajax({
  336. action: 'save_ui_skin',
  337. skin_name: toSkin,
  338. });
  339. },
  340. }
  341. var Help = {
  342. /**
  343. * Init the help controller
  344. * @return void
  345. */
  346. init: function() {
  347. FLBuilder.addHook('beginTour', this.onStartTourClicked.bind(this));
  348. },
  349. /**
  350. * Handle tour item click
  351. *
  352. * @return void
  353. */
  354. onStartTourClicked: function() {
  355. FLBuilderTour.start();
  356. MainMenuPanel.hide();
  357. },
  358. }
  359. })(jQuery, FLBuilder);