fl-icon-selector.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. (function($){
  2. /**
  3. * Helper class for the icon selector lightbox.
  4. *
  5. * @class FLIconSelector
  6. * @since 1.0
  7. */
  8. FLIconSelector = {
  9. /**
  10. * A reference to the lightbox HTML content that is
  11. * loaded via AJAX.
  12. *
  13. * @since 1.0
  14. * @access private
  15. * @property {String} _content
  16. */
  17. _content : null,
  18. /**
  19. * A reference to a FLLightbox object.
  20. *
  21. * @since 1.0
  22. * @access private
  23. * @property {FLLightbox} _lightbox
  24. */
  25. _lightbox : null,
  26. /**
  27. * A flag for whether the content has already
  28. * been rendered or not.
  29. *
  30. * @since 1.0
  31. * @access private
  32. * @property {Boolean} _rendered
  33. */
  34. _rendered : false,
  35. /**
  36. * The text that is used to filter the selection
  37. * of visible icons.
  38. *
  39. * @since 1.0
  40. * @access private
  41. * @property {String} _filterText
  42. */
  43. _filterText : '',
  44. _liveFilterText: '',
  45. /**
  46. * Opens the icon selector lightbox.
  47. *
  48. * @since 1.0
  49. * @method open
  50. * @param {Function} callback A callback that fires when an icon is selected.
  51. */
  52. open: function(callback)
  53. {
  54. if(!FLIconSelector._rendered) {
  55. FLIconSelector._render();
  56. }
  57. if(FLIconSelector._content === null) {
  58. FLIconSelector._lightbox.open('<div class="fl-builder-lightbox-loading"></div>');
  59. FLBuilder.ajax({
  60. action: 'render_icon_selector'
  61. }, FLIconSelector._getContentComplete);
  62. }
  63. else {
  64. FLIconSelector._lightbox.open();
  65. $('.fl-icons-filter-text-live', window.parent.document).focus();
  66. }
  67. FLIconSelector._lightbox.on('icon-selected', function(event, icon){
  68. FLIconSelector._lightbox.off('icon-selected');
  69. FLIconSelector._lightbox.close();
  70. callback(icon);
  71. });
  72. },
  73. /**
  74. * Renders a new instance of FLLightbox.
  75. *
  76. * @since 1.0
  77. * @access private
  78. * @method _render
  79. */
  80. _render: function()
  81. {
  82. FLIconSelector._lightbox = new FLLightbox({
  83. className: 'fl-icon-selector'
  84. });
  85. FLIconSelector._rendered = true;
  86. FLBuilder.addHook( 'endEditingSession', function() {
  87. FLIconSelector._lightbox.close()
  88. } );
  89. },
  90. /**
  91. * Callback for when the lightbox content
  92. * has been returned via AJAX.
  93. *
  94. * @since 1.0
  95. * @access private
  96. * @method _getContentComplete
  97. * @param {String} response The JSON with the HTML lightbox content.
  98. */
  99. _getContentComplete: function(response)
  100. {
  101. var data = FLBuilder._jsonParse(response);
  102. FLIconSelector._content = data.html;
  103. FLIconSelector._lightbox.setContent(data.html);
  104. $('.fl-icons-filter-text-live', window.parent.document).on('keyup', $.debounce( 1000, FLIconSelector.livefilter ));
  105. $('.fl-icons-filter-text-live', window.parent.document).focus();
  106. $('.fl-icons-list i', window.parent.document).on('click', FLIconSelector._select);
  107. $('.fl-icon-selector-cancel', window.parent.document).on('click', $.proxy(FLIconSelector._lightbox.close, FLIconSelector._lightbox));
  108. FLIconSelector.renderRecent();
  109. },
  110. renderRecent: function() {
  111. var recent = FLBuilderConfig.recentIcons;
  112. if ( recent.length < 1 ) {
  113. $('.fl-icons-section.recent h2.recent', window.parent.document).hide();
  114. return false;
  115. }
  116. $('.fl-icons-section.recent h2.recent', window.parent.document).show();
  117. $('.fl-icons-section.recent', window.parent.document).show()
  118. $('.recent-icons', window.parent.document).html('');
  119. $.each(recent, function( i, icon ) {
  120. $('.recent-icons', window.parent.document).append( '<i class="' + icon + '"></i>');
  121. });
  122. $('.recent-icons', window.parent.document).show();
  123. $('.recent-icons i', window.parent.document).on('click', FLIconSelector._select);
  124. // check if recent icons have ::before, if they dont the css for set is missing, so hide icon
  125. var recents = $('.recent-icons i', window.parent.document);
  126. $.each( recents, function( i,icon ) {
  127. var str = window.parent.getComputedStyle($(icon)[0], ':before').getPropertyValue('content');
  128. if ( 'none' == str ) {
  129. $(icon).hide();
  130. }
  131. });
  132. },
  133. livefilter: function() {
  134. var text = $( '.fl-icons-filter-text-live', window.parent.document ).val();
  135. if ( text === FLIconSelector._liveFilterText ) {
  136. return false;
  137. }
  138. $( '.fl-icons-section.results', window.parent.document ).html('')
  139. if ( '' === text ) {
  140. FLIconSelector._liveFilterText = '';
  141. $( '.fl-icons-section', window.parent.document ).show();
  142. FLIconSelector.renderRecent();
  143. } else {
  144. $('.fl-icons-section.recent', window.parent.document).hide();
  145. $('.fl-icons-section.all-icons', window.parent.document).hide()
  146. $('.fl-icons-section.results', window.parent.document).html('<i class="fas fa-spinner fa-spin"></i>')
  147. FLIconSelector._liveFilterText = text;
  148. FLBuilder.ajax({
  149. action: 'query_icons',
  150. text: text
  151. }, FLIconSelector._query_result);
  152. }
  153. },
  154. _query_result: function(result) {
  155. var results = $('.fl-icons-section.results', window.parent.document),
  156. html = '';
  157. if ( ! result || '[]' === result ) {
  158. html = '<h2>No Icons Found</h2>'
  159. FLIconSelector.renderRecent();
  160. results.html(html);
  161. results.show();
  162. return false;
  163. }
  164. var data = FLBuilder._jsonParse( result ),
  165. prefix = '';
  166. $.each(data, function(i,section) {
  167. html += '<h2>' + section.name + '</h2>';
  168. $.each(section.data, function( i, icon ) {
  169. $.each(icon.styles, function( i,style) {
  170. prefix = '';
  171. switch( style ) {
  172. case 'solid':
  173. prefix = 'fas';
  174. break;
  175. case 'regular':
  176. prefix = 'far';
  177. break;
  178. case 'light':
  179. prefix = 'fal';
  180. break;
  181. case 'duotone':
  182. prefix = 'fad';
  183. break;
  184. case 'thin':
  185. prefix = 'fa-thin' // fa6
  186. break;
  187. case 'brands':
  188. prefix = 'fa-brands fab' // fa6 + fa5
  189. break;
  190. case 'legacy':
  191. prefix = section.prefix;
  192. }
  193. if ( prefix.length > 0 ) {
  194. prefix += ' ';
  195. }
  196. html += '<i class="' + prefix + icon.tag + '" title="' + icon.label + '"></i>';
  197. })
  198. });
  199. })
  200. results.html(html);
  201. results.show();
  202. $('.fl-icons-section.results i', window.parent.document).on('click', FLIconSelector._select);
  203. },
  204. /**
  205. * Filters the selection of visible icons based on
  206. * the library select and search input text.
  207. *
  208. * @since 1.0
  209. * @access private
  210. * @method _filter
  211. */
  212. _filter: function()
  213. {
  214. var section = $( '.fl-icons-filter-select', window.parent.document ).val(),
  215. text = $( '.fl-icons-filter-text', window.parent.document ).val() || '';
  216. // Filter sections.
  217. if ( 'all' == section ) {
  218. $( '.fl-icons-section', window.parent.document ).show();
  219. }
  220. else {
  221. $( '.fl-icons-section', window.parent.document ).hide();
  222. $( '.fl-' + section, window.parent.document ).show();
  223. }
  224. // Filter icons.
  225. FLIconSelector._filterText = text;
  226. if ( '' !== text ) {
  227. $( '.fl-icons-list i', window.parent.document ).each( FLIconSelector._filterIcon );
  228. }
  229. else {
  230. $( '.fl-icons-list i', window.parent.document ).show();
  231. }
  232. },
  233. /**
  234. * Shows or hides an icon based on the filter text.
  235. *
  236. * @since 1.0
  237. * @access private
  238. * @method _filterIcon
  239. */
  240. _filterIcon: function()
  241. {
  242. var icon = $( this );
  243. if ( -1 == icon.attr( 'class' ).indexOf( FLIconSelector._filterText ) ) {
  244. icon.hide();
  245. }
  246. else {
  247. icon.show();
  248. }
  249. },
  250. /**
  251. * Called when an icon is selected and fires the
  252. * icon-selected event on the lightbox.
  253. *
  254. * @since 1.0
  255. * @access private
  256. * @method _select
  257. */
  258. _select: function()
  259. {
  260. var icon = $(this).attr('class');
  261. FLBuilder.ajax({
  262. action: 'recent_icons',
  263. icon: icon
  264. }, FLIconSelector._updateRecents);
  265. FLIconSelector._lightbox.trigger('icon-selected', icon);
  266. },
  267. _updateRecents: function(result) {
  268. FLBuilderConfig.recentIcons = FLBuilder._jsonParse(result);
  269. }
  270. };
  271. })(jQuery);