WordPress Page Builder – Beaver Builder - Version 2.0.3.2

Version Description

Download this release

Release Info

Developer pross
Plugin Icon 128x128 WordPress Page Builder – Beaver Builder
Version 2.0.3.2
Comparing to
See all releases

Code changes from version 1.11 to 2.0.3.2

Files changed (150) hide show
  1. changelog.txt +221 -1
  2. classes/class-fl-builder-admin-settings.php +1 -0
  3. classes/class-fl-builder-ajax-layout.php +57 -11
  4. classes/class-fl-builder-ajax.php +17 -11
  5. classes/class-fl-builder-auto-suggest.php +17 -0
  6. classes/class-fl-builder-fonts.php +6 -8
  7. classes/class-fl-builder-icons.php +7 -5
  8. classes/class-fl-builder-loader.php +6 -2
  9. classes/class-fl-builder-loop.php +66 -23
  10. classes/class-fl-builder-model.php +859 -242
  11. classes/class-fl-builder-module.php +82 -1
  12. classes/class-fl-builder-revisions.php +139 -0
  13. classes/class-fl-builder-service-activecampaign.php +6 -2
  14. classes/class-fl-builder-services.php +10 -0
  15. classes/class-fl-builder-ui-content-panel.php +312 -0
  16. classes/class-fl-builder-ui-settings-forms.php +737 -0
  17. classes/class-fl-builder-user-settings.php +93 -0
  18. classes/class-fl-builder-utils.php +12 -0
  19. classes/class-fl-builder-wpcli-command.php +1 -0
  20. classes/class-fl-builder.php +605 -424
  21. css/fl-builder-layout.css +9 -0
  22. css/fl-builder-ui-skin-dark.css +392 -0
  23. css/fl-builder.css +3020 -409
  24. css/fl-builder.min.css +1 -1
  25. css/fl-color-picker.css +97 -46
  26. css/fl-icon-selector.css +38 -9
  27. css/fl-lightbox.css +136 -48
  28. css/jquery.nanoscroller.css +4 -5
  29. css/jquery.tiptip.css +7 -26
  30. fl-builder.php +1 -1
  31. img/svg/button.svg +1 -0
  32. img/svg/chart-bar.svg +1 -0
  33. img/svg/clock.svg +1 -0
  34. img/svg/editor-code.svg +1 -0
  35. img/svg/editor-table.svg +1 -0
  36. img/svg/format-audio.svg +1 -0
  37. img/svg/format-gallery.svg +1 -0
  38. img/svg/format-image.svg +1 -0
  39. img/svg/format-quote.svg +1 -0
  40. img/svg/format-video.svg +1 -0
  41. img/svg/insert.svg +1 -0
  42. img/svg/layout.svg +1 -0
  43. img/svg/location.svg +1 -0
  44. img/svg/megaphone.svg +1 -0
  45. img/svg/minus.svg +1 -0
  46. img/svg/plus-alt.svg +1 -0
  47. img/svg/schedule.svg +1 -0
  48. img/svg/select-arrow-down-alt2-light.svg +1 -0
  49. img/svg/select-arrow-down-alt2.svg +1 -0
  50. img/svg/share-alt2.svg +1 -0
  51. img/svg/slides.svg +1 -0
  52. img/svg/star-filled.svg +1 -0
  53. img/svg/text.svg +1 -0
  54. img/svg/wordpress-alt.svg +1 -0
  55. includes/admin-settings-welcome.php +10 -8
  56. includes/column-settings.php +14 -128
  57. includes/compatibility.php +11 -0
  58. includes/field-button.php +0 -1
  59. includes/field-code.php +0 -57
  60. includes/field-color.php +0 -8
  61. includes/field-editor.php +0 -70
  62. includes/field-font.php +0 -9
  63. includes/field-form.php +0 -38
  64. includes/field-icon.php +0 -12
  65. includes/field-layout.php +0 -9
  66. includes/field-link.php +0 -9
  67. includes/field-multiple-audios.php +0 -27
  68. includes/field-multiple-photos.php +0 -26
  69. includes/field-ordering.php +0 -26
  70. includes/field-photo-sizes.php +0 -12
  71. includes/field-photo.php +0 -22
  72. includes/field-post-type.php +0 -5
  73. includes/field-select.php +0 -152
  74. includes/field-suggest.php +0 -12
  75. includes/field-text.php +0 -76
  76. includes/field-textarea.php +0 -3
  77. includes/field-time.php +0 -28
  78. includes/field-timezone.php +0 -6
  79. includes/field-unit.php +0 -6
  80. includes/field-video.php +0 -22
  81. includes/global-settings.php +6 -0
  82. includes/icon-selector.php +1 -1
  83. includes/jquery.php +2 -2
  84. includes/loop-settings-matching.php +5 -2
  85. includes/module-settings.php +4 -49
  86. includes/row-css.php +18 -0
  87. includes/row-js.php +1 -0
  88. includes/row-settings.php +23 -158
  89. includes/service-settings.php +0 -46
  90. includes/settings.php +0 -84
  91. includes/template-selector.php +0 -67
  92. includes/ui-bar-title-area.php +20 -0
  93. includes/ui-bar.php +26 -0
  94. includes/{ui-fields.php → ui-extras.php} +2 -4
  95. includes/ui-field-button.php +5 -0
  96. includes/ui-field-code.php +22 -0
  97. includes/ui-field-color.php +14 -0
  98. includes/ui-field-dimension.php +59 -0
  99. includes/ui-field-editor.php +20 -0
  100. includes/ui-field-font.php +9 -0
  101. includes/ui-field-form.php +53 -0
  102. includes/ui-field-icon.php +11 -0
  103. includes/ui-field-layout.php +9 -0
  104. includes/ui-field-link.php +11 -0
  105. includes/ui-field-multiple-audios.php +38 -0
  106. includes/ui-field-multiple-photos.php +32 -0
  107. includes/ui-field-ordering.php +33 -0
  108. includes/ui-field-photo-sizes.php +9 -0
  109. includes/ui-field-photo.php +53 -0
  110. includes/ui-field-post-type.php +5 -0
  111. includes/ui-field-select.php +153 -0
  112. includes/ui-field-suggest.php +11 -0
  113. includes/ui-field-text.php +9 -0
  114. includes/ui-field-textarea.php +6 -0
  115. includes/ui-field-time.php +28 -0
  116. includes/ui-field-timezone.php +9 -0
  117. includes/ui-field-unit.php +6 -0
  118. includes/ui-field-video.php +41 -0
  119. includes/ui-field.php +83 -0
  120. includes/ui-js-config.php +65 -0
  121. includes/ui-js-templates.php +733 -4
  122. includes/{field.php → ui-legacy-custom-field.php} +11 -9
  123. includes/ui-legacy-field.php +37 -0
  124. includes/ui-legacy-settings.php +24 -0
  125. includes/{loop-settings.php → ui-loop-settings.php} +6 -2
  126. includes/ui-panel-module-templates.php +0 -20
  127. includes/ui-panel-row-templates.php +0 -20
  128. includes/ui-panel.php +0 -72
  129. includes/ui-service-settings.php +49 -0
  130. includes/ui-settings-config.php +4 -0
  131. includes/ui-settings-form-row.php +40 -0
  132. includes/ui-settings-form.php +116 -0
  133. includes/updater-config.php +1 -1
  134. includes/updater/classes/class-fl-updater.php +1 -1
  135. js/fl-builder-ajax-layout.js +89 -74
  136. js/fl-builder-layout.js +1 -2
  137. js/fl-builder-preview.js +397 -318
  138. js/fl-builder-responsive-editing.js +78 -75
  139. js/fl-builder-revisions.js +243 -0
  140. js/fl-builder-save-manager.js +246 -0
  141. js/fl-builder-search.js +422 -0
  142. js/fl-builder-services.js +65 -65
  143. js/fl-builder-simulate-media-query.js +103 -104
  144. js/fl-builder-tour.js +31 -62
  145. js/fl-builder-ui-main-menu.js +418 -0
  146. js/fl-builder-ui-panel-content-library.js +1008 -0
  147. js/fl-builder-ui-pinned.js +702 -0
  148. js/fl-builder-ui-settings-forms.js +864 -0
  149. js/fl-builder-ui.js +1185 -0
  150. js/fl-builder.js +1140 -738
changelog.txt CHANGED
@@ -1,3 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <h4>1.11 11/28/17</h4>
2
  <p><strong>This will be the final 1.x release before 2.x is made available to all customers via remote update.</strong></p>
3
  <p><strong>Enhancements</strong></p>
@@ -2122,5 +2342,5 @@
2122
  <h4>0.8.2</h4>
2123
  <p>Responsive module margins now only reset if negative or greater than the default.</p>
2124
 
2125
- <h4>0.8.1</h4>
2126
  <p>Initial beta release.</p>
1
+ <h4>2.0.3.2 - 12/20/2017</h4>
2
+ <p><strong>Hotfix</strong></p>
3
+ <ul>
4
+ <li>Removed the next/prev settings tab shortcuts as they interfere with text editing.</li>
5
+ <li>Fixed module settings reverting to defaults when duplicating a module that isn't saved yet.</li>
6
+ <li>Fixed contact form errors when global or using the reCAPTCHA.</li>
7
+ </ul>
8
+
9
+ <h4>2.0.3.1 - 12/13/2017</h4>
10
+ <p><strong>Hotfix</strong></p>
11
+ <ul>
12
+ <li>Fixed a bug in multisite where subsite settings were being loaded from main site.</li>
13
+ <li>Fixed an issue with content slider only showing two slides.</li>
14
+ <li>Fixed javascript error shown when trying to edit a saved module.</li>
15
+ </ul>
16
+
17
+ <h4>2.0.3 - 12/11/2017</h4>
18
+ <p><strong>Enhancements</strong></p>
19
+ <ul>
20
+ <li>Enable Rest API support for builder template post type.</li>
21
+ <li>Pass <code>$settings</code> in available args in <code>fl_builder_loop_query_args</code> filter.</li>
22
+ <li>Insert Layout Shortcode will now render non BB content which was a fallback in 1.x.</li>
23
+ <li>New filter <code>fl_builder_photo_sizes_select</code>.</li>
24
+ </ul>
25
+ <p><strong>Bug Fixes</strong></p>
26
+ <ul>
27
+ <li>Fixed various UI scrollbar issues on Windows.</li>
28
+ <li>Fixed group name HTML entities issue.</li>
29
+ <li>Fixed duplicate audio issue in content slider when video is set to autoplay.</li>
30
+ <li>Fixed a multisite icon issue, network settings were being ignored on primary site.</li>
31
+ <li>Fixed issue with WordPress widgets being available in Builder UI when disabled in admin settings.</li>
32
+ <li>Fixed Active Campaign re-subscribe issue in Subscribe Module.</li>
33
+ <li>Fixed issue in form field settings <code>preview_text</code> now works with <code>select</code> field type.</li>
34
+ <li>Fixed PHP 7.2 warning thrown in <code>get_settings_form_fields</code></li>
35
+ <li>Fixed form fields issue: Duplicate item button missing until you add a second item.</li>
36
+ <li>Updated bxslider library, fixes 40px margin issue with content slider.</li>
37
+ <li>Remove Core WP Gallery Widget from list of available widgets in the builder.</li>
38
+ <li>Disabled swipe on row background videos.</li>
39
+ <li>Fixed GeneratePress Premium plugin Blog option overrules the Post modules excerpt setting.</li>
40
+ </ul>
41
+
42
+ <h4>2.0.2.2 - 12/06/2017</h4>
43
+ <p>Beaver Builder 2.0 is now available for remote update!</p>
44
+
45
+ <h4>2.0.2.1 - 11/27/2017</h4>
46
+ <p><strong>Bug Fixes</strong></p>
47
+ <ul>
48
+ <li>Fixed responsive editing mode not working correctly.</li>
49
+ <li>Fixed white labeling not working correctly on the updates page.</li>
50
+ </ul>
51
+
52
+ <h4>2.0.2 - 11/16/2017</h4>
53
+ <p><strong>Enhancements</strong></p>
54
+ <ul>
55
+ <li>Added <code>fl_builder_cache_cleared</code> action.</li>
56
+ </ul>
57
+ <p><strong>Bug Fixes</strong></p>
58
+ <ul>
59
+ <li>Fixed settings config not loading when query strings are removed from script URLs.</li>
60
+ <li>Fixed widgets not showing when site language is not in English.</li>
61
+ <li>Fixed error when using namespaced widgets.</li>
62
+ <li>Fixed JS errors in IE.</li>
63
+ <li>Fixed keyboard shortcut formatting in IE.</li>
64
+ <li>Fixed capitalization issues with translations.</li>
65
+ <li>Fixed character encoding issues with strtolower.</li>
66
+ </ul>
67
+
68
+ <h4>2.0.1.1 - 11/07/2017</h4>
69
+ <p><strong>Bug Fixes</strong></p>
70
+ <ul>
71
+ <li>Hotfix for a change in 2.0.1 that broke loading of the settings for the Subscribe Form module.</li>
72
+ </ul>
73
+
74
+ <h4>2.0.1 - 11/06/2017</h4>
75
+ <p><strong>Bug Fixes</strong></p>
76
+ <ul>
77
+ <li>Fixed errors caused by settings config not completely loading on certain server setups.</li>
78
+ <li>Fixed PHP warnings when attachment meta doesn't have a width or height set.</li>
79
+ </ul>
80
+
81
+ <h4>2.0 - 11/01/2017</h4>
82
+ <p><strong>Beaver Builder 2.0 is here!</strong></p>
83
+ <p>Please note that 2.0 is currently only available from your My Account page or via remote update if you already have 2.0 installed. We'll be releasing remote updates for older versions of Beaver Builder within the next few weeks.</p>
84
+
85
+ <h4>2.0-beta.3 - 10/31/2017</h4>
86
+ <p><strong>Enhancements</strong></p>
87
+ <ul>
88
+ <li>Updated the help video for 2.0.</li>
89
+ <li>Added fl_row_resize_settings filter.</li>
90
+ </ul>
91
+ <p><strong>Bug Fixes</strong></p>
92
+ <ul>
93
+ <li>Fixed various UI styling issues.</li>
94
+ <li>Fixed editing global rows not working properly.</li>
95
+ <li>Fixed template override settings not working on multisite.</li>
96
+ <li>Fixed repeater fields in nested forms not working.</li>
97
+ <li>Fixed stylesheets in the body tag not being parsed for responsive preview.</li>
98
+ <li>Fixed content panel showing during preview or unpinning during preview when not expected.</li>
99
+ <li>Fixed anchor links in the layout causing the builder to launch again after publish.</li>
100
+ </ul>
101
+
102
+ <h4>2.0-beta.2 - 10/12/2017</h4>
103
+ <p><strong>Enhancements</strong></p>
104
+ <ul>
105
+ <li>Publish button now says 'Submit for Review' if a user doesn't have permission to publish.</li>
106
+ <li>Pinned settings are now responsive for smaller devices.</li>
107
+ <li>Moved WordPress widgets into their own group.</li>
108
+ <li>Moved Themer modules into their own group (coming in Themer 1.0.3).</li>
109
+ </ul>
110
+ <p><strong>Bug Fixes</strong></p>
111
+ <ul>
112
+ <li>Fixed row actions being covered by modules when the row has no padding.</li>
113
+ <li>Fixed values in text inputs not being escaped which breaks the markup.</li>
114
+ <li>Fixed settings being dragged or resized so you can't access the drag handle anymore.</li>
115
+ <li>Fixed browser zoom triggering the action overflow menu when it shouldn't.</li>
116
+ <li>Fixed multiple issues with saving new templates.</li>
117
+ <li>Fixed styling issues with dark mode.</li>
118
+ <li>Fixed module aliases not showing in the content panel.</li>
119
+ <li>Fixed widgets not showing in the content panel.</li>
120
+ </ul>
121
+
122
+ <h4>2.0-beta.1 - 10/04/2017</h4>
123
+ <p><strong>Enhancements</strong></p>
124
+ <ul>
125
+ <li>Added keyboard shortcut UI to the builder menu.</li>
126
+ <li>Reworked keyboard shortcut system to support displaying shortcuts with labels and modifier key symbols.</li>
127
+ </ul>
128
+ <p><strong>Bug Fixes</strong></p>
129
+ <ul>
130
+ <li>Fixed various styling issues.</li>
131
+ <li>Fixed photo and video fields that aren't in node settings not showing saved data when opened again after the page is refreshed.</li>
132
+ <li>Fixed error when saving a template with no category set.</li>
133
+ <li>Fixed saved values for medium and responsive in dimension fields not showing when going back to edit a node.</li>
134
+ <li>Fixed module templates not showing in the content panel.</li>
135
+ <li>Fixed issue with module hover in the content panel being covered by siblings.</li>
136
+ <li>Fixed a major issue with secondary loops triggering the builder's content filter when they shouldn't. This caused a number of issues including an infinite loop in Themer and the incorrect posts being displayed on standard builder pages.</li>
137
+ <li>Fixed FLBuilder::render_query so it doesn't have to override $wp_query which was causing incorrect connection data for Themer layouts.</li>
138
+ </ul>
139
+
140
+ <h4>2.0-alpha.7 - 09/21/2017</h4>
141
+ <p><strong>Enhancements</strong></p>
142
+ <ul>
143
+ <li>Added the ability to match posts in the loop settings by related taxonomy terms.</li>
144
+ </ul>
145
+ <p><strong>Bug Fixes</strong></p>
146
+ <ul>
147
+ <li>Fixed page scrolling breaking when opening the main menu.</li>
148
+ <li>Fixed field connections not rendering in nested settings forms.</li>
149
+ </ul>
150
+
151
+ <h4>2.0-alpha.6.1 - 09/19/2017</h4>
152
+ <p><strong>Bug Fixes</strong></p>
153
+ <ul>
154
+ <li>Fixed a bug with the option labels in select option groups not showing.</li>
155
+ </ul>
156
+
157
+ <h4>2.0-alpha.6 - 09/19/2017</h4>
158
+ <p><strong>Bug Fixes</strong></p>
159
+ <ul>
160
+ <li>Fixed a bug breaking the Pods integration.</li>
161
+ <li>Fixed an issue causing the builder UI to break on SiteGround servers.</li>
162
+ </ul>
163
+
164
+ <h4>2.0-alpha.5 - 09/06/2017</h4>
165
+ <p><strong>Enhancements</strong></p>
166
+ <ul>
167
+ <li>Settings panel tabs no longer become a drop-down menu when slim. Tabs that cannot fit into the available space are pushed into a menu.</li>
168
+ <li>You can now move between settings tabs with the keyboard shortcuts "CMD + Left Arrow" or "CMD + Right Arrow" (CTRL on Windows).</li>
169
+ <li>You can now reset row or column widths from the module overlay.</li>
170
+ <li>"CMD + i" (CTRL on Windows) shortcut will take you directly to module search.</li>
171
+ <li>Module search is now case-insensitive.</li>
172
+ <li>Duplicated items that appear off screen will now scroll into view.</li>
173
+ </ul>
174
+ <p><strong>Bug Fixes</strong></p>
175
+ <ul>
176
+ <li>Fixed scrolling not working when hovering over the content panel and then back into the layout.</li>
177
+ <li>Hovering over the content panel should no longer cause screen jitter in Windows browsers.</li>
178
+ <li>Icon selector search/filter has been restored.</li>
179
+ <li>J, K, L, and ; keys now show content panel tabs even when the panel has been collapsed.</li>
180
+ <li>Dropping a row template into the layout immediately loads fonts.</li>
181
+ <li>Overriding core templates now works again when applying a template.<li>
182
+ <li>Fixed ACE editor resize causing incorrect cursor position.</li>
183
+ <li>Fixed multiple issues with pinning in Safari and Firefox.</li>
184
+ </ul>
185
+
186
+ <h4>2.0-alpha.4 - 08/29/2017</h4>
187
+ <ul>
188
+ <li>A new slimmer version of the settings panels now opens when clicking to edit content.</li>
189
+ <li>Settings panels can now be resized to any size that you desire.</li>
190
+ <li>We'll remember the size and position you set for the settings panels even after reloading the page.</li>
191
+ <li>The content panel and settings can now be pinned together on either the left or right side of the screen. You can resize the pinned sidebar when you need a little more room.</li>
192
+ <li>You can now work with the toolbar or in the layout even when settings are open.</li>
193
+ <li>If settings are open and you take action anywhere else in the builder, we'll save and close them for you. This means you can edit one module and click to edit another without ever needing to click save in between.</li>
194
+ <li>Module search has been moved into the modules tab for more intuitive access.</li>
195
+ </ul>
196
+
197
+ <h4>2.0-alpha.3 - 08/07/2017</h4>
198
+ <ul>
199
+ <li>Settings forms now load instantly! We've completely rewritten the settings forms in JavaScript so they don’t need to be loaded from the server anymore. The only time something needs to load is if you’re using a third party add-on that introduces legacy PHP fields. We’ll have docs on the new JavaScript settings APIs when 2.0 is released and hope that all major add-on authors will convert their fields to JavaScript so everything loads instantly! :)</li>
200
+ <li>Added an initial set of core row templates.</li>
201
+ <li>Various bug fixes and style tweaks.</li>
202
+ </ul>
203
+
204
+ <h4>2.0-alpha.2 - 07/24/2017</h4>
205
+ <ul>
206
+ <li>Added the ability to duplicate columns.</li>
207
+ <li>Increased contrast to light and dark UI modes.</li>
208
+ <li>Added module icons.</li>
209
+ <li>Restyled content group selector.</li>
210
+ <li>Reworked how group labels are displayed in search results.</li>
211
+ <li>Style hardening for GeneratePress theme.</li>
212
+ <li>Publishing out of the builder now moves the history state and updates the url. Re-entering will move back.</li>
213
+ </ul>
214
+
215
+ <h4>1.11.1 11/29/17</h4>
216
+ <p><strong>Hot Fix</strong></p>
217
+ <ul>
218
+ <li>Fixed issue with ScrollTo links.</li>
219
+ </ul>
220
+
221
  <h4>1.11 11/28/17</h4>
222
  <p><strong>This will be the final 1.x release before 2.x is made available to all customers via remote update.</strong></p>
223
  <p><strong>Enhancements</strong></p>
2342
  <h4>0.8.2</h4>
2343
  <p>Responsive module margins now only reset if negative or greater than the default.</p>
2344
 
2345
+ <h4>0.8.1</h4>
2346
  <p>Initial beta release.</p>
classes/class-fl-builder-admin-settings.php CHANGED
@@ -559,6 +559,7 @@ final class FLBuilderAdminSettings {
559
  FLCustomizer::clear_all_css_cache();
560
  }
561
  }
 
562
  }
563
  }
564
 
559
  FLCustomizer::clear_all_css_cache();
560
  }
561
  }
562
+ do_action( 'fl_builder_cache_cleared' );
563
  }
564
  }
565
 
classes/class-fl-builder-ajax-layout.php CHANGED
@@ -87,7 +87,10 @@ final class FLBuilderAJAXLayout {
87
  }
88
 
89
  // Return the response.
90
- return self::render( $row->node );
 
 
 
91
  } // End if().
92
  else {
93
 
@@ -118,10 +121,12 @@ final class FLBuilderAJAXLayout {
118
  *
119
  * @since 1.7
120
  * @param string $node_id The ID of a row to copy.
 
 
121
  * @return array
122
  */
123
- static public function copy_row( $node_id ) {
124
- $row = FLBuilderModel::copy_row( $node_id );
125
 
126
  return self::render( $row->node );
127
  }
@@ -175,6 +180,21 @@ final class FLBuilderAJAXLayout {
175
  return self::render( $group->node );
176
  }
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  /**
179
  * Renders the layout data for a new module.
180
  *
@@ -203,9 +223,6 @@ final class FLBuilderAJAXLayout {
203
  $module = FLBuilderModel::add_default_module( $parent_id, $type, $position, $defaults );
204
  }
205
 
206
- // Render the new module's settings.
207
- $settings = FLBuilder::render_module_settings( $module->node, $module->settings->type, $module->parent, false );
208
-
209
  // Maybe render the module's parent for a partial refresh?
210
  if ( $module->partial_refresh ) {
211
 
@@ -230,8 +247,13 @@ final class FLBuilderAJAXLayout {
230
 
231
  // Return the response.
232
  return array(
233
- 'layout' => self::render( $render_id ),
234
- 'settings' => $settings['settings'],
 
 
 
 
 
235
  );
236
  }
237
 
@@ -240,10 +262,11 @@ final class FLBuilderAJAXLayout {
240
  *
241
  * @since 1.7
242
  * @param string $node_id The ID of a module to copy.
 
243
  * @return array
244
  */
245
- static public function copy_module( $node_id ) {
246
- $module = FLBuilderModel::copy_module( $node_id );
247
 
248
  return self::render( $module->node );
249
  }
@@ -531,7 +554,30 @@ final class FLBuilderAJAXLayout {
531
  global $wp_scripts;
532
  global $wp_styles;
533
 
534
- $scripts_styles = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
 
536
  // Start the output buffer.
537
  ob_start();
87
  }
88
 
89
  // Return the response.
90
+ return array(
91
+ 'layout' => self::render( $row->node ),
92
+ 'config' => FLBuilderUISettingsForms::get_node_js_config(),
93
+ );
94
  } // End if().
95
  else {
96
 
121
  *
122
  * @since 1.7
123
  * @param string $node_id The ID of a row to copy.
124
+ * @param object $settings These settings will be used for the copy if present.
125
+ * @param string $settings_id The ID of the node who's settings were passed.
126
  * @return array
127
  */
128
+ static public function copy_row( $node_id, $settings = null, $settings_id = null ) {
129
+ $row = FLBuilderModel::copy_row( $node_id, $settings, $settings_id );
130
 
131
  return self::render( $row->node );
132
  }
180
  return self::render( $group->node );
181
  }
182
 
183
+ /**
184
+ * Renders the layout data for a copied column.
185
+ *
186
+ * @since 2.0
187
+ * @param string $node_id The ID of a column to copy.
188
+ * @param object $settings These settings will be used for the copy if present.
189
+ * @param string $settings_id The ID of the node who's settings were passed.
190
+ * @return array
191
+ */
192
+ static public function copy_col( $node_id, $settings = null, $settings_id = null ) {
193
+ $col = FLBuilderModel::copy_col( $node_id, $settings, $settings_id );
194
+
195
+ return self::render( $col->node );
196
+ }
197
+
198
  /**
199
  * Renders the layout data for a new module.
200
  *
223
  $module = FLBuilderModel::add_default_module( $parent_id, $type, $position, $defaults );
224
  }
225
 
 
 
 
226
  // Maybe render the module's parent for a partial refresh?
227
  if ( $module->partial_refresh ) {
228
 
247
 
248
  // Return the response.
249
  return array(
250
+ 'type' => $module->settings->type,
251
+ 'nodeId' => $module->node,
252
+ 'parentId' => $module->parent,
253
+ 'global' => FLBuilderModel::is_node_global( $module ),
254
+ 'layout' => self::render( $render_id ),
255
+ 'settings' => null === $template_id ? null : $module->settings,
256
+ 'legacy' => FLBuilderUISettingsForms::pre_render_legacy_module_settings( $module->settings->type, $module->settings ),
257
  );
258
  }
259
 
262
  *
263
  * @since 1.7
264
  * @param string $node_id The ID of a module to copy.
265
+ * @param object $settings These settings will be used for the copy if present.
266
  * @return array
267
  */
268
+ static public function copy_module( $node_id, $settings = null ) {
269
+ $module = FLBuilderModel::copy_module( $node_id, $settings );
270
 
271
  return self::render( $module->node );
272
  }
554
  global $wp_scripts;
555
  global $wp_styles;
556
 
557
+ $partial_refresh_data = self::get_partial_refresh_data();
558
+ $modules = array();
559
+ $scripts_styles = '';
560
+
561
+ // Enqueue module font styles.
562
+ if ( ! $partial_refresh_data['is_partial_refresh'] ) {
563
+ $modules = FLBuilderModel::get_all_modules();
564
+ } elseif ( 'module' !== $partial_refresh_data['node']->type ) {
565
+ $nodes = FLBuilderModel::get_nested_nodes( $partial_refresh_data['node'] );
566
+ foreach ( $nodes as $node ) {
567
+ if ( 'module' === $node->type && isset( FLBuilderModel::$modules[ $node->settings->type ] ) ) {
568
+ $node->form = FLBuilderModel::$modules[ $node->settings->type ]->form;
569
+ $modules[] = $node;
570
+ }
571
+ }
572
+ } else {
573
+ $modules = array( $partial_refresh_data['node'] );
574
+ }
575
+
576
+ foreach ( $modules as $module ) {
577
+ FLBuilderFonts::add_fonts_for_module( $module );
578
+ }
579
+
580
+ FLBuilderFonts::enqueue_styles();
581
 
582
  // Start the output buffer.
583
  ob_start();
classes/class-fl-builder-ajax.php CHANGED
@@ -80,15 +80,6 @@ final class FLBuilderAJAX {
80
  * @return void
81
  */
82
  static private function add_actions() {
83
- // FLBuilder
84
- self::add_action( 'render_settings_form', 'FLBuilder::render_settings_form', array( 'type', 'settings' ) );
85
- self::add_action( 'render_row_settings', 'FLBuilder::render_row_settings', array( 'node_id' ) );
86
- self::add_action( 'render_column_settings', 'FLBuilder::render_column_settings', array( 'node_id' ) );
87
- self::add_action( 'render_module_settings', 'FLBuilder::render_module_settings', array( 'node_id', 'type', 'parent_id' ) );
88
- self::add_action( 'render_layout_settings', 'FLBuilder::render_layout_settings' );
89
- self::add_action( 'render_global_settings', 'FLBuilder::render_global_settings' );
90
- self::add_action( 'render_template_selector', 'FLBuilder::render_template_selector' );
91
- self::add_action( 'render_icon_selector', 'FLBuilder::render_icon_selector' );
92
 
93
  // FLBuilderModel
94
  self::add_action( 'delete_node', 'FLBuilderModel::delete_node', array( 'node_id' ) );
@@ -99,6 +90,7 @@ final class FLBuilderAJAX {
99
  self::add_action( 'move_col', 'FLBuilderModel::move_col', array( 'node_id', 'new_parent', 'position', 'resize' ) );
100
  self::add_action( 'resize_cols', 'FLBuilderModel::resize_cols', array( 'col_id', 'col_width', 'sibling_id', 'sibling_width' ) );
101
  self::add_action( 'reset_col_widths', 'FLBuilderModel::reset_col_widths', array( 'group_id' ) );
 
102
  self::add_action( 'save_settings', 'FLBuilderModel::save_settings', array( 'node_id', 'settings' ) );
103
  self::add_action( 'save_layout_settings', 'FLBuilderModel::save_layout_settings', array( 'settings' ) );
104
  self::add_action( 'save_global_settings', 'FLBuilderModel::save_global_settings', array( 'settings' ) );
@@ -111,15 +103,28 @@ final class FLBuilderAJAX {
111
  self::add_action( 'save_draft', 'FLBuilderModel::save_draft' );
112
  self::add_action( 'clear_draft_layout', 'FLBuilderModel::clear_draft_layout' );
113
  self::add_action( 'disable_builder', 'FLBuilderModel::disable' );
 
114
 
115
  // FLBuilderAJAXLayout
116
  self::add_action( 'render_layout', 'FLBuilderAJAXLayout::render' );
 
117
  self::add_action( 'render_new_row', 'FLBuilderAJAXLayout::render_new_row', array( 'cols', 'position', 'template_id', 'template_type' ) );
118
- self::add_action( 'copy_row', 'FLBuilderAJAXLayout::copy_row', array( 'node_id' ) );
119
  self::add_action( 'render_new_column_group', 'FLBuilderAJAXLayout::render_new_column_group', array( 'node_id', 'cols', 'position' ) );
120
  self::add_action( 'render_new_columns', 'FLBuilderAJAXLayout::render_new_columns', array( 'node_id', 'insert', 'type', 'nested' ) );
 
121
  self::add_action( 'render_new_module', 'FLBuilderAJAXLayout::render_new_module', array( 'parent_id', 'position', 'type', 'alias', 'template_id', 'template_type' ) );
122
- self::add_action( 'copy_module', 'FLBuilderAJAXLayout::copy_module', array( 'node_id' ) );
 
 
 
 
 
 
 
 
 
 
123
 
124
  // FLBuilderServices
125
  self::add_action( 'render_service_settings', 'FLBuilderServices::render_settings' );
@@ -130,6 +135,7 @@ final class FLBuilderAJAX {
130
 
131
  // FLBuilderAutoSuggest
132
  self::add_action( 'fl_builder_autosuggest', 'FLBuilderAutoSuggest::init' );
 
133
  }
134
 
135
  /**
80
  * @return void
81
  */
82
  static private function add_actions() {
 
 
 
 
 
 
 
 
 
83
 
84
  // FLBuilderModel
85
  self::add_action( 'delete_node', 'FLBuilderModel::delete_node', array( 'node_id' ) );
90
  self::add_action( 'move_col', 'FLBuilderModel::move_col', array( 'node_id', 'new_parent', 'position', 'resize' ) );
91
  self::add_action( 'resize_cols', 'FLBuilderModel::resize_cols', array( 'col_id', 'col_width', 'sibling_id', 'sibling_width' ) );
92
  self::add_action( 'reset_col_widths', 'FLBuilderModel::reset_col_widths', array( 'group_id' ) );
93
+ self::add_action( 'resize_row_content', 'FLBuilderModel::resize_row_content', array( 'node', 'width' ) );
94
  self::add_action( 'save_settings', 'FLBuilderModel::save_settings', array( 'node_id', 'settings' ) );
95
  self::add_action( 'save_layout_settings', 'FLBuilderModel::save_layout_settings', array( 'settings' ) );
96
  self::add_action( 'save_global_settings', 'FLBuilderModel::save_global_settings', array( 'settings' ) );
103
  self::add_action( 'save_draft', 'FLBuilderModel::save_draft' );
104
  self::add_action( 'clear_draft_layout', 'FLBuilderModel::clear_draft_layout' );
105
  self::add_action( 'disable_builder', 'FLBuilderModel::disable' );
106
+ self::add_action( 'clear_cache', 'FLBuilderModel::delete_all_asset_cache' );
107
 
108
  // FLBuilderAJAXLayout
109
  self::add_action( 'render_layout', 'FLBuilderAJAXLayout::render' );
110
+ self::add_action( 'render_node', 'FLBuilderAJAXLayout::render', array( 'node_id' ) );
111
  self::add_action( 'render_new_row', 'FLBuilderAJAXLayout::render_new_row', array( 'cols', 'position', 'template_id', 'template_type' ) );
112
+ self::add_action( 'copy_row', 'FLBuilderAJAXLayout::copy_row', array( 'node_id', 'settings', 'settings_id' ) );
113
  self::add_action( 'render_new_column_group', 'FLBuilderAJAXLayout::render_new_column_group', array( 'node_id', 'cols', 'position' ) );
114
  self::add_action( 'render_new_columns', 'FLBuilderAJAXLayout::render_new_columns', array( 'node_id', 'insert', 'type', 'nested' ) );
115
+ self::add_action( 'copy_col', 'FLBuilderAJAXLayout::copy_col', array( 'node_id', 'settings', 'settings_id' ) );
116
  self::add_action( 'render_new_module', 'FLBuilderAJAXLayout::render_new_module', array( 'parent_id', 'position', 'type', 'alias', 'template_id', 'template_type' ) );
117
+ self::add_action( 'copy_module', 'FLBuilderAJAXLayout::copy_module', array( 'node_id', 'settings' ) );
118
+
119
+ // FLBuilderUISettingsForms
120
+ self::add_action( 'render_legacy_settings', 'FLBuilderUISettingsForms::render_legacy_settings', array( 'data', 'form', 'group', 'lightbox' ) );
121
+ self::add_action( 'render_settings_form', 'FLBuilderUISettingsForms::render_settings_form', array( 'type', 'settings' ) );
122
+ self::add_action( 'render_icon_selector', 'FLBuilderUISettingsForms::render_icon_selector' );
123
+
124
+ // FLBuilderRevisions
125
+ self::add_action( 'render_revision_preview', 'FLBuilderRevisions::render_preview', array( 'revision_id' ) );
126
+ self::add_action( 'restore_revision', 'FLBuilderRevisions::restore', array( 'revision_id' ) );
127
+ self::add_action( 'refresh_revision_items', 'FLBuilderRevisions::get_config', array( 'post_id' ) );
128
 
129
  // FLBuilderServices
130
  self::add_action( 'render_service_settings', 'FLBuilderServices::render_settings' );
135
 
136
  // FLBuilderAutoSuggest
137
  self::add_action( 'fl_builder_autosuggest', 'FLBuilderAutoSuggest::init' );
138
+ self::add_action( 'get_autosuggest_values', 'FLBuilderAutoSuggest::get_values', array( 'fields' ) );
139
  }
140
 
141
  /**
classes/class-fl-builder-auto-suggest.php CHANGED
@@ -78,6 +78,23 @@ final class FLBuilderAutoSuggest {
78
  return isset( $data ) ? str_replace( "'", '&#39;', json_encode( $data ) ) : '';
79
  }
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  /**
82
  * Returns the SQL escaped like value for auto suggest queries.
83
  *
78
  return isset( $data ) ? str_replace( "'", '&#39;', json_encode( $data ) ) : '';
79
  }
80
 
81
+ /**
82
+ * Returns the values for all suggest fields in a settings form.
83
+ *
84
+ * @since 2.0
85
+ * @param array $fields
86
+ * @return array
87
+ */
88
+ static public function get_values( $fields ) {
89
+ $values = array();
90
+
91
+ foreach ( $fields as $field ) {
92
+ $values[ $field['name'] ] = self::get_value( $field['action'], $field['value'], $field['data'] );
93
+ }
94
+
95
+ return $values;
96
+ }
97
+
98
  /**
99
  * Returns the SQL escaped like value for auto suggest queries.
100
  *
classes/class-fl-builder-fonts.php CHANGED
@@ -47,17 +47,17 @@ final class FLBuilderFonts {
47
  $system_fonts = apply_filters( 'fl_builder_font_families_system', FLBuilderFontFamilies::$system );
48
  $google_fonts = apply_filters( 'fl_builder_font_families_google', FLBuilderFontFamilies::google() );
49
 
50
- echo '<option value="Default" ' . selected( 'Default', $font ) . '>' . __( 'Default', 'fl-builder' ) . '</option>';
51
  echo '<optgroup label="System">';
52
 
53
  foreach ( $system_fonts as $name => $variants ) {
54
- echo '<option value="' . $name . '" ' . selected( $name, $font ) . '>' . $name . '</option>';
55
  }
56
 
57
  echo '<optgroup label="Google">';
58
 
59
  foreach ( $google_fonts as $name => $variants ) {
60
- echo '<option value="' . $name . '" ' . selected( $name, $font ) . '>' . $name . '</option>';
61
  }
62
  }
63
 
@@ -71,19 +71,18 @@ final class FLBuilderFonts {
71
  */
72
  static public function display_select_weight( $font, $weight ) {
73
  if ( 'Default' == $font ) {
74
- echo '<option value="default">' . __( 'Default', 'fl-builder' ) . '</option>';
75
  } else {
76
  $system_fonts = apply_filters( 'fl_builder_font_families_system', FLBuilderFontFamilies::$system );
77
  $google_fonts = apply_filters( 'fl_builder_font_families_google', FLBuilderFontFamilies::google() );
78
 
79
  if ( array_key_exists( $font, $system_fonts ) ) {
80
  foreach ( $system_fonts[ $font ]['weights'] as $variant ) {
81
- echo '<option value="' . $variant . '" ' . selected( $variant, $weight ) . '>' . FLBuilderFonts::get_weight_string( $variant ) . '</option>';
82
  }
83
  } else {
84
  foreach ( $google_fonts[ $font ] as $variant ) {
85
-
86
- echo '<option value="' . $variant . '" ' . selected( $variant, $weight ) . '>' . FLBuilderFonts::get_weight_string( $variant ) . '</option>';
87
  }
88
  }
89
  }
@@ -459,5 +458,4 @@ final class FLBuilderFontFamilies {
459
  ),
460
  ),
461
  );
462
-
463
  }
47
  $system_fonts = apply_filters( 'fl_builder_font_families_system', FLBuilderFontFamilies::$system );
48
  $google_fonts = apply_filters( 'fl_builder_font_families_google', FLBuilderFontFamilies::google() );
49
 
50
+ echo '<option value="Default" ' . selected( 'Default', $font, false ) . '>' . __( 'Default', 'fl-builder' ) . '</option>';
51
  echo '<optgroup label="System">';
52
 
53
  foreach ( $system_fonts as $name => $variants ) {
54
+ echo '<option value="' . $name . '" ' . selected( $name, $font, false ) . '>' . $name . '</option>';
55
  }
56
 
57
  echo '<optgroup label="Google">';
58
 
59
  foreach ( $google_fonts as $name => $variants ) {
60
+ echo '<option value="' . $name . '" ' . selected( $name, $font, false ) . '>' . $name . '</option>';
61
  }
62
  }
63
 
71
  */
72
  static public function display_select_weight( $font, $weight ) {
73
  if ( 'Default' == $font ) {
74
+ echo '<option value="default" selected="selected">' . __( 'Default', 'fl-builder' ) . '</option>';
75
  } else {
76
  $system_fonts = apply_filters( 'fl_builder_font_families_system', FLBuilderFontFamilies::$system );
77
  $google_fonts = apply_filters( 'fl_builder_font_families_google', FLBuilderFontFamilies::google() );
78
 
79
  if ( array_key_exists( $font, $system_fonts ) ) {
80
  foreach ( $system_fonts[ $font ]['weights'] as $variant ) {
81
+ echo '<option value="' . $variant . '" ' . selected( $variant, $weight, false ) . '>' . FLBuilderFonts::get_weight_string( $variant ) . '</option>';
82
  }
83
  } else {
84
  foreach ( $google_fonts[ $font ] as $variant ) {
85
+ echo '<option value="' . $variant . '" ' . selected( $variant, $weight, false ) . '>' . FLBuilderFonts::get_weight_string( $variant ) . '</option>';
 
86
  }
87
  }
88
  }
458
  ),
459
  ),
460
  );
 
461
  }
classes/class-fl-builder-icons.php CHANGED
@@ -24,19 +24,21 @@ final class FLBuilderIcons {
24
  * @return array An array of data for each icon set.
25
  */
26
  static public function get_sets() {
 
27
  // Return the sets if already registered.
28
  if ( self::$sets ) {
29
  return self::$sets;
30
  }
31
-
32
  // Check to see if we should pull sets from the main site.
33
  if ( is_multisite() ) {
34
 
35
- $blog_id = defined( 'BLOG_ID_CURRENT_SITE' ) ? BLOG_ID_CURRENT_SITE : 1;
36
  $enabled_icons = get_option( '_fl_builder_enabled_icons' );
37
 
38
- if ( empty( $enabled_icons ) ) {
39
- switch_to_blog( $blog_id );
 
40
  }
41
  }
42
 
@@ -45,7 +47,7 @@ final class FLBuilderIcons {
45
  self::register_core_sets();
46
 
47
  // Revert to the current site if we pulled from the main site.
48
- if ( is_multisite() && empty( $enabled_icons ) ) {
49
  restore_current_blog();
50
  }
51
 
24
  * @return array An array of data for each icon set.
25
  */
26
  static public function get_sets() {
27
+ $switched = false;
28
  // Return the sets if already registered.
29
  if ( self::$sets ) {
30
  return self::$sets;
31
  }
32
+ global $blog_id;
33
  // Check to see if we should pull sets from the main site.
34
  if ( is_multisite() ) {
35
 
36
+ $id = defined( 'BLOG_ID_CURRENT_SITE' ) ? BLOG_ID_CURRENT_SITE : 1;
37
  $enabled_icons = get_option( '_fl_builder_enabled_icons' );
38
 
39
+ if ( ( $id != $blog_id ) || empty( $enabled_icons ) ) {
40
+ switch_to_blog( $id );
41
+ $switched = true;
42
  }
43
  }
44
 
47
  self::register_core_sets();
48
 
49
  // Revert to the current site if we pulled from the main site.
50
+ if ( is_multisite() && $switched ) {
51
  restore_current_blog();
52
  }
53
 
classes/class-fl-builder-loader.php CHANGED
@@ -43,7 +43,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
43
  * @return void
44
  */
45
  static private function define_constants() {
46
- define( 'FL_BUILDER_VERSION', '1.11' );
47
  define( 'FL_BUILDER_FILE', trailingslashit( dirname( dirname( __FILE__ ) ) ) . 'fl-builder.php' );
48
  define( 'FL_BUILDER_DIR', plugin_dir_path( FL_BUILDER_FILE ) );
49
  define( 'FL_BUILDER_URL', plugins_url( '/', FL_BUILDER_FILE ) );
@@ -82,11 +82,15 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
82
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-model.php';
83
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-module.php';
84
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-photo.php';
 
85
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-services.php';
86
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-shortcodes.php';
87
- require_once FL_BUILDER_DIR . 'classes/class-fl-builder-update.php';
88
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-timezones.php';
 
 
 
89
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-user-access.php';
 
90
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-utils.php';
91
 
92
  /* WP CLI Commands */
43
  * @return void
44
  */
45
  static private function define_constants() {
46
+ define( 'FL_BUILDER_VERSION', '2.0.3.2' );
47
  define( 'FL_BUILDER_FILE', trailingslashit( dirname( dirname( __FILE__ ) ) ) . 'fl-builder.php' );
48
  define( 'FL_BUILDER_DIR', plugin_dir_path( FL_BUILDER_FILE ) );
49
  define( 'FL_BUILDER_URL', plugins_url( '/', FL_BUILDER_FILE ) );
82
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-model.php';
83
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-module.php';
84
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-photo.php';
85
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-revisions.php';
86
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-services.php';
87
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-shortcodes.php';
 
88
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-timezones.php';
89
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-ui-content-panel.php';
90
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-ui-settings-forms.php';
91
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-update.php';
92
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-user-access.php';
93
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-user-settings.php';
94
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-utils.php';
95
 
96
  /* WP CLI Commands */
classes/class-fl-builder-loop.php CHANGED
@@ -85,6 +85,7 @@ final class FLBuilderLoop {
85
  */
86
  static public function query( $settings ) {
87
  $settings = apply_filters( 'fl_builder_loop_before_query_settings', $settings );
 
88
  do_action( 'fl_builder_loop_before_query', $settings );
89
 
90
  // Count how many times this method has been called
@@ -164,19 +165,20 @@ final class FLBuilderLoop {
164
 
165
  // Build the query args.
166
  $args = apply_filters( 'fl_builder_loop_query_args', array(
167
- 'paged' => $paged,
168
- 'posts_per_page' => $posts_per_page,
169
- 'post_type' => $post_type,
170
- 'orderby' => $order_by,
171
- 'order' => $order,
172
- 'tax_query' => array(
173
  'relation' => 'AND',
174
  ),
175
- 'ignore_sticky_posts' => true,
176
- 'offset' => $paged_offset,
177
- 'fl_original_offset' => $offset,
178
- 'fl_builder_loop' => true,
179
- 'fields' => $fields,
 
180
  ) );
181
 
182
  // Order by meta value arg.
@@ -207,33 +209,72 @@ final class FLBuilderLoop {
207
  foreach ( $taxonomies as $tax_slug => $tax ) {
208
 
209
  $tax_value = '';
 
210
  $operator = 'IN';
211
 
212
- // Set to NOT IN if matching is present and set to 0.
213
- if ( isset( $settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'} ) ) {
214
- if ( ! $settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'} ) {
215
- $operator = 'NOT IN';
216
- }
217
- }
218
-
219
- // New settings slug.
220
  if ( isset( $settings->{'tax_' . $post_type . '_' . $tax_slug} ) ) {
 
221
  $tax_value = $settings->{'tax_' . $post_type . '_' . $tax_slug};
222
- } // End if().
223
- elseif ( isset( $settings->{'tax_' . $tax_slug} ) ) {
224
  $tax_value = $settings->{'tax_' . $tax_slug};
225
  }
226
 
 
227
  if ( ! empty( $tax_value ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
 
229
  $args['tax_query'][] = array(
230
  'taxonomy' => $tax_slug,
231
  'field' => 'id',
232
- 'terms' => explode( ',', $tax_value ),
233
  'operator' => $operator,
234
  );
235
  }
236
- }
237
 
238
  // Post in/not in query.
239
  if ( isset( $settings->{'posts_' . $post_type} ) ) {
@@ -960,6 +1001,8 @@ final class FLBuilderLoop {
960
  return;
961
  }
962
 
 
 
963
  if ( ! isset( $settings->{ $name . '_matching' } ) ) {
964
  $settings->{ $name . '_matching' } = '1';
965
  }
85
  */
86
  static public function query( $settings ) {
87
  $settings = apply_filters( 'fl_builder_loop_before_query_settings', $settings );
88
+
89
  do_action( 'fl_builder_loop_before_query', $settings );
90
 
91
  // Count how many times this method has been called
165
 
166
  // Build the query args.
167
  $args = apply_filters( 'fl_builder_loop_query_args', array(
168
+ 'paged' => $paged,
169
+ 'posts_per_page' => $posts_per_page,
170
+ 'post_type' => $post_type,
171
+ 'orderby' => $order_by,
172
+ 'order' => $order,
173
+ 'tax_query' => array(
174
  'relation' => 'AND',
175
  ),
176
+ 'ignore_sticky_posts' => true,
177
+ 'offset' => $paged_offset,
178
+ 'fl_original_offset' => $offset,
179
+ 'fl_builder_loop' => true,
180
+ 'fields' => $fields,
181
+ 'settings' => $settings,
182
  ) );
183
 
184
  // Order by meta value arg.
209
  foreach ( $taxonomies as $tax_slug => $tax ) {
210
 
211
  $tax_value = '';
212
+ $term_ids = array();
213
  $operator = 'IN';
214
 
215
+ // Get the value of the suggest field.
 
 
 
 
 
 
 
216
  if ( isset( $settings->{'tax_' . $post_type . '_' . $tax_slug} ) ) {
217
+ // New style slug.
218
  $tax_value = $settings->{'tax_' . $post_type . '_' . $tax_slug};
219
+ } elseif ( isset( $settings->{'tax_' . $tax_slug} ) ) {
220
+ // Old style slug for backwards compat.
221
  $tax_value = $settings->{'tax_' . $tax_slug};
222
  }
223
 
224
+ // Get the term IDs array.
225
  if ( ! empty( $tax_value ) ) {
226
+ $term_ids = explode( ',', $tax_value );
227
+ }
228
+
229
+ // Handle matching settings.
230
+ if ( isset( $settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'} ) ) {
231
+
232
+ $tax_matching = $settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'};
233
+
234
+ if ( ! $tax_matching ) {
235
+ // Do not match these terms.
236
+ $operator = 'NOT IN';
237
+ } elseif ( 'related' === $tax_matching ) {
238
+ // Match posts by related terms from the global post.
239
+ global $post;
240
+ $terms = wp_get_post_terms( $post->ID, $tax_slug );
241
+ $related = array();
242
+
243
+ foreach ( $terms as $term ) {
244
+ if ( ! in_array( $term->term_id, $term_ids ) ) {
245
+ $related[] = $term->term_id;
246
+ }
247
+ }
248
+
249
+ if ( empty( $related ) ) {
250
+ // If no related terms, match all except those in the suggest field.
251
+ $operator = 'NOT IN';
252
+ } else {
253
+
254
+ // Don't include posts with terms selected in the suggest field.
255
+ $args['tax_query'][] = array(
256
+ 'taxonomy' => $tax_slug,
257
+ 'field' => 'id',
258
+ 'terms' => $term_ids,
259
+ 'operator' => 'NOT IN',
260
+ );
261
+
262
+ // Set the term IDs to the related terms.
263
+ $term_ids = $related;
264
+ }
265
+ }
266
+ }// End if().
267
+
268
+ if ( ! empty( $term_ids ) ) {
269
 
270
  $args['tax_query'][] = array(
271
  'taxonomy' => $tax_slug,
272
  'field' => 'id',
273
+ 'terms' => $term_ids,
274
  'operator' => $operator,
275
  );
276
  }
277
+ }// End foreach().
278
 
279
  // Post in/not in query.
280
  if ( isset( $settings->{'posts_' . $post_type} ) ) {
1001
  return;
1002
  }
1003
 
1004
+ $label = FLBuilderUtils::strtolower( $field['label'] );
1005
+
1006
  if ( ! isset( $settings->{ $name . '_matching' } ) ) {
1007
  $settings->{ $name . '_matching' } = '1';
1008
  }
classes/class-fl-builder-model.php CHANGED
@@ -188,6 +188,7 @@ final class FLBuilderModel {
188
 
189
  /* Filters */
190
  add_filter( 'heartbeat_received', __CLASS__ . '::lock_post', 10, 2 );
 
191
 
192
  /* Core Templates */
193
  self::register_core_templates();
@@ -263,7 +264,7 @@ final class FLBuilderModel {
263
  $_POST['fl_builder_data']['node_settings'] = FLBuilderUtils::modsec_fix_decode( $_POST['fl_builder_data']['node_settings'] );
264
  }
265
 
266
- $data = FLBuilderUtils::json_decode_deep( wp_unslash( $_POST['fl_builder_data'] ) );
267
 
268
  foreach ( $data as $key => $val ) {
269
  self::$post_data[ $key ] = $val;
@@ -354,30 +355,39 @@ final class FLBuilderModel {
354
  * is being displayed or worked on.
355
  *
356
  * @since 1.0
 
357
  * @return int|bool The post id or false.
358
  */
359
- static public function get_post_id() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
  global $wp_the_query;
361
  global $post;
362
 
363
- $post_data = self::get_post_data();
364
-
365
- // Get a post ID from the internal $post_id array if not empty.
366
- if ( ! empty( self::$post_id ) ) {
367
- return self::$post_id[0];
368
- } // End if().
369
- elseif ( isset( $post_data['post_id'] ) ) {
370
- return $post_data['post_id'];
371
- } // Get a post ID from the main query.
372
- elseif ( in_the_loop() && is_main_query() && isset( $wp_the_query->post ) ) {
373
  return $wp_the_query->post->ID;
374
- } // Get a post ID in a query outside of the main loop.
375
- elseif ( isset( $post ) ) {
376
  return $post->ID;
377
- } // No post ID found.
378
- else {
379
- return false;
380
  }
 
 
 
381
  }
382
 
383
  /**
@@ -456,17 +466,20 @@ final class FLBuilderModel {
456
  * for the current post.
457
  *
458
  * @since 1.0
 
459
  * @return bool
460
  */
461
- static public function is_builder_enabled() {
462
- $post_id = self::get_post_id();
 
 
 
463
 
464
  if ( ! is_admin() && post_password_required( $post_id ) ) {
465
  return false;
466
- } elseif ( self::is_builder_active() ) {
467
  return true;
468
  } else {
469
-
470
  $post_types = self::get_post_types();
471
  $post = get_post( $post_id );
472
 
@@ -496,6 +509,8 @@ final class FLBuilderModel {
496
  return self::$active;
497
  } elseif ( ! is_admin() && is_singular() && $query_id != $post_id ) {
498
  self::$active = false;
 
 
499
  } elseif ( self::is_post_editable() && ! is_admin() && ! post_password_required() ) {
500
  $post_data = self::get_post_data();
501
  self::$active = isset( $_GET['fl_builder'] ) || isset( $post_data['fl_builder'] );
@@ -580,11 +595,10 @@ final class FLBuilderModel {
580
  $cols = self::get_nodes( 'column' );
581
  $col = array_shift( $cols );
582
  $settings = self::get_module_defaults( 'rich-text' );
583
- $settings->text = wpautop( $post->post_content );
584
 
585
  self::add_module( 'rich-text', $settings, $col->node );
586
- } // End if().
587
- elseif ( empty( $draft ) ) {
588
  self::update_layout_data( $published, 'draft', $post->ID );
589
  self::update_layout_settings( self::get_layout_settings( 'published' ), 'draft', $post->ID );
590
  }
@@ -922,8 +936,7 @@ final class FLBuilderModel {
922
  // Return all nodes?
923
  if ( ! $type ) {
924
  $nodes = $data;
925
- } // End if().
926
- else {
927
 
928
  foreach ( $data as $node_id => $node ) {
929
 
@@ -1083,15 +1096,18 @@ final class FLBuilderModel {
1083
  * @return array
1084
  */
1085
  static public function get_child_nodes( $parent_id, $status = null ) {
1086
- $parent = is_object( $parent_id ) ? $parent_id : self::get_node( $parent_id );
1087
- $template_post_id = self::is_node_global( $parent );
1088
- $status = $template_post_id && ! self::is_post_node_template() ? 'published' : $status;
1089
- $data = self::get_layout_data( $status, $template_post_id );
1090
- $nodes = array();
1091
 
1092
- foreach ( $data as $node_id => $node ) {
1093
- if ( $node->parent == $parent->node || ( $template_post_id && $parent->template_node_id == $node->parent ) ) {
1094
- $nodes[ $node_id ] = $node;
 
 
 
1095
  }
1096
  }
1097
 
@@ -1251,14 +1267,18 @@ final class FLBuilderModel {
1251
  * @return object
1252
  */
1253
  static public function process_node_settings( $node, $new_settings ) {
 
1254
  if ( 'row' == $node->type ) {
1255
  $new_settings = self::process_row_settings( $node, $new_settings );
 
1256
  }
1257
  if ( 'column' == $node->type ) {
1258
  $new_settings = self::process_col_settings( $node, $new_settings );
 
1259
  }
1260
  if ( 'module' == $node->type ) {
1261
  $new_settings = self::process_module_settings( $node, $new_settings );
 
1262
  }
1263
 
1264
  return $new_settings;
@@ -1534,9 +1554,11 @@ final class FLBuilderModel {
1534
  *
1535
  * @since 1.0
1536
  * @param string $node_id Node ID of the row to copy.
 
 
1537
  * @return void
1538
  */
1539
- static public function copy_row( $node_id = null ) {
1540
  $layout_data = self::get_layout_data();
1541
  $row = self::get_node( $node_id );
1542
  $new_row_id = self::generate_node_id();
@@ -1593,6 +1615,15 @@ final class FLBuilderModel {
1593
  }
1594
  }// End foreach().
1595
 
 
 
 
 
 
 
 
 
 
1596
  // Generate new child ids.
1597
  $new_nodes = self::generate_new_node_ids( $new_nodes );
1598
 
@@ -1718,7 +1749,7 @@ final class FLBuilderModel {
1718
  }
1719
 
1720
  // Cache background slideshow data.
1721
- if ( 'slideshow' == $new_settings->bg_type && 'wordpress' == $new_settings->ss_source ) {
1722
 
1723
  // Make sure we have a photo data object.
1724
  if ( ! isset( $row->settings->ss_photo_data ) ) {
@@ -1761,8 +1792,7 @@ final class FLBuilderModel {
1761
 
1762
  $data['webm'] = $row->settings->bg_video_webm_data;
1763
  }
1764
- } // End if().
1765
- elseif ( 'slideshow' == $row->settings->bg_type && isset( $row->settings->ss_photo_data ) ) {
1766
  $data = $row->settings->ss_photo_data;
1767
  }
1768
 
@@ -1794,6 +1824,22 @@ final class FLBuilderModel {
1794
  return $ss->get_source();
1795
  }
1796
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1797
  /**
1798
  * Adds a column group to a row in the current layout.
1799
  *
@@ -1842,8 +1888,7 @@ final class FLBuilderModel {
1842
  $data[ $col_node_id ]->template_node_id = $col_node_id;
1843
  }
1844
  }
1845
- } // End if().
1846
- else {
1847
 
1848
  $old_group = $data[ $cols ]->parent;
1849
  $siblings = self::get_nodes( 'column', $old_group );
@@ -1867,7 +1912,7 @@ final class FLBuilderModel {
1867
  $data[ $sibling->node ]->position = $sibling_pos;
1868
  $sibling_pos++;
1869
  }
1870
- }
1871
 
1872
  // Update the layout data.
1873
  self::update_layout_data( $data );
@@ -1982,8 +2027,7 @@ final class FLBuilderModel {
1982
  // Delete the group if empty.
1983
  if ( count( $cols ) === 0 ) {
1984
  self::delete_node( $group->node );
1985
- } // End if().
1986
- else {
1987
 
1988
  // Get the layout data.
1989
  $data = self::get_layout_data();
@@ -2297,6 +2341,98 @@ final class FLBuilderModel {
2297
  return $parent;
2298
  }
2299
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2300
  /**
2301
  * Returns the default settings for column nodes.
2302
  *
@@ -2318,7 +2454,7 @@ final class FLBuilderModel {
2318
  $dir = dir( $path );
2319
  $module_path = '';
2320
 
2321
- while ( false !== ($entry = $dir->read()) ) { // @codingStandardsIgnoreLine
2322
 
2323
  if ( ! is_dir( $path . $entry ) || '.' == $entry || '..' == $entry ) {
2324
  continue;
@@ -2333,14 +2469,14 @@ final class FLBuilderModel {
2333
  // Check for the module class in a child theme.
2334
  if ( is_child_theme() && file_exists( $child_path ) ) {
2335
  require_once $child_path;
2336
- } // End if().
2337
- elseif ( file_exists( $theme_path ) ) {
2338
  require_once $theme_path;
2339
- } // Check for the module class in the builder directory.
2340
- elseif ( file_exists( $builder_path ) ) {
2341
  require_once $builder_path;
2342
  }
2343
  }
 
 
2344
  }
2345
 
2346
  /**
@@ -2396,8 +2532,10 @@ final class FLBuilderModel {
2396
  $instance->name = isset( $config['name'] ) ? $config['name'] : $slug;
2397
  $instance->description = isset( $config['description'] ) ? $config['description'] : '';
2398
  $instance->category = isset( $config['category'] ) ? $config['category'] : null;
 
2399
  $instance->settings = isset( $config['settings'] ) ? $config['settings'] : array();
2400
  $instance->enabled = isset( $config['enabled'] ) ? $config['enabled'] : true;
 
2401
 
2402
  self::$module_aliases[ $alias ] = $instance;
2403
  }
@@ -2452,32 +2590,86 @@ final class FLBuilderModel {
2452
  }
2453
 
2454
  /**
2455
- * Returns an array of categorized modules.
2456
  *
2457
- * @since 1.0
2458
- * @param bool $show_disabled Whether to include disabled modules in the result.
2459
  * @return array
2460
  */
2461
- static public function get_categorized_modules( $show_disabled = false ) {
2462
- $enabled_modules = self::get_enabled_modules();
2463
- $widgets = null;
2464
- $categories = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2465
 
2466
  // Add any predefined custom categories.
2467
  foreach ( apply_filters( 'fl_builder_module_categories', array() ) as $custom_category ) {
2468
  $categories[ $custom_category ] = array();
2469
  }
2470
 
2471
- // Get the core category keys.
2472
- $basic_key = __( 'Basic Modules', 'fl-builder' );
2473
- $advanced_key = __( 'Advanced Modules', 'fl-builder' );
2474
- $other_key = __( 'Other Modules', 'fl-builder' );
2475
- $widgets_key = __( 'WordPress Widgets', 'fl-builder' );
2476
-
2477
  // Build the default category arrays.
2478
- $categories[ $basic_key ] = array();
2479
- $categories[ $advanced_key ] = array();
2480
- $categories[ $other_key ] = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2481
 
2482
  // Build the categories array.
2483
  foreach ( self::$modules as $module ) {
@@ -2532,33 +2724,96 @@ final class FLBuilderModel {
2532
  }
2533
 
2534
  /**
2535
- * Returns the slug for a module category.
2536
  *
2537
- * @since 1.0
2538
- * @param string $name The category name.
2539
- * @return string
2540
  */
2541
- static public function get_module_category_slug( $name ) {
2542
- // Get the core category keys.
2543
- $basic_key = __( 'Basic Modules', 'fl-builder' );
2544
- $advanced_key = __( 'Advanced Modules', 'fl-builder' );
2545
- $other_key = __( 'Other Modules', 'fl-builder' );
2546
- $widgets_key = __( 'WordPress Widgets', 'fl-builder' );
2547
 
2548
- if ( $name == $basic_key ) {
2549
- return 'basic';
2550
- }
2551
- if ( $name == $advanced_key ) {
2552
- return 'advanced';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2553
  }
2554
- if ( $name == $other_key ) {
2555
- return 'other';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2556
  }
2557
- if ( $name == $widgets_key ) {
2558
- return 'widgets';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2559
  }
2560
 
2561
- return sanitize_html_class( $name );
2562
  }
2563
 
2564
  /**
@@ -2581,6 +2836,7 @@ final class FLBuilderModel {
2581
  $instance->settings = $module->settings;
2582
  $instance->type = 'module';
2583
  $instance->form = self::$modules[ $module->settings->type ]->form;
 
2584
 
2585
  if ( isset( $module->template_id ) ) {
2586
  $instance->template_id = $module->template_id;
@@ -2621,6 +2877,7 @@ final class FLBuilderModel {
2621
  $instances[ $i ]->position = $module->position;
2622
  $instances[ $i ]->settings = $module->settings;
2623
  $instances[ $i ]->type = 'module';
 
2624
  $instances[ $i ]->form = self::$modules[ $module->settings->type ]->form;
2625
 
2626
  if ( isset( $module->template_id ) ) {
@@ -2672,16 +2929,16 @@ final class FLBuilderModel {
2672
  $settings = $instance->update( $settings );
2673
 
2674
  // Save the module.
2675
- $data[ $module_node_id ] = new StdClass();
2676
- $data[ $module_node_id ]->node = $module_node_id;
2677
- $data[ $module_node_id ]->type = 'module';
2678
- $data[ $module_node_id ]->parent = $parent_id;
2679
  $data[ $module_node_id ]->position = self::next_node_position( 'module', $parent_id );
2680
  $data[ $module_node_id ]->settings = $settings;
2681
 
2682
  // Add node template data.
2683
  if ( self::is_node_global( $parent ) ) {
2684
- $data[ $module_node_id ]->template_id = $parent->template_id;
2685
  $data[ $module_node_id ]->template_node_id = $module_node_id;
2686
  }
2687
 
@@ -2709,22 +2966,22 @@ final class FLBuilderModel {
2709
  static public function add_module_parent( $parent_id = null, $position = null ) {
2710
  $parent = ! $parent_id ? null : self::get_node( $parent_id );
2711
 
2712
- // Add a new row if we don't have a parent.
2713
  if ( ! $parent ) {
 
2714
  $row = self::add_row( '1-col', $position );
2715
  $col_groups = self::get_nodes( 'column-group', $row->node );
2716
  $col_group = array_shift( $col_groups );
2717
  $cols = self::get_nodes( 'column', $col_group->node );
2718
  $parent = array_shift( $cols );
2719
  $parent_id = $parent->node;
2720
- } // End if().
2721
- elseif ( 'row' == $parent->type ) {
2722
  $col_group = self::add_col_group( $parent->node, '1-col', $position );
2723
  $cols = self::get_nodes( 'column', $col_group->node );
2724
  $parent = array_shift( $cols );
2725
  $parent_id = $parent->node;
2726
- } // Add a new column if the parent is a column group.
2727
- elseif ( 'column-group' == $parent->type ) {
2728
  $parent = self::add_col( $parent->node, $position );
2729
  $parent_id = $parent->node;
2730
  }
@@ -2786,7 +3043,7 @@ final class FLBuilderModel {
2786
  * @return array $defaults Default settings for the module.
2787
  */
2788
  static public function add_default_module( $parent_id = null, $type = null, $position = null, $defaults = null ) {
2789
- $parent = 0 == $parent_id ? null : self::get_node( $parent_id );
2790
  $settings = self::get_module_defaults( $type );
2791
  $module_node_id = self::generate_node_id();
2792
 
@@ -2810,11 +3067,11 @@ final class FLBuilderModel {
2810
  $settings = $instance->update( $settings );
2811
 
2812
  // Save the module.
2813
- $data = self::get_layout_data();
2814
- $data[ $module_node_id ] = new StdClass();
2815
- $data[ $module_node_id ]->node = $module_node_id;
2816
- $data[ $module_node_id ]->type = 'module';
2817
- $data[ $module_node_id ]->parent = $parent_id;
2818
  $data[ $module_node_id ]->position = self::next_node_position( 'module', $parent_id );
2819
  $data[ $module_node_id ]->settings = $settings;
2820
 
@@ -2841,11 +3098,16 @@ final class FLBuilderModel {
2841
  *
2842
  * @since 1.0
2843
  * @param string $node_id Node ID of the module to copy.
 
2844
  * @return object The new module object.
2845
  */
2846
- static public function copy_module( $node_id = null ) {
2847
  $module = self::get_module( $node_id );
2848
 
 
 
 
 
2849
  return self::add_module( $module->settings->type, $module->settings, $module->parent, $module->position + 1 );
2850
  }
2851
 
@@ -2893,18 +3155,31 @@ final class FLBuilderModel {
2893
  }
2894
 
2895
  /**
2896
- * Returns the default settings for a module.
 
2897
  *
2898
  * @since 1.0
2899
  * @param string $type The type of module.
2900
- * @return object
2901
  */
2902
- static public function get_module_defaults( $type ) {
2903
- $defaults = new StdClass();
2904
 
2905
- if ( isset( self::$modules[ $type ]->form ) ) {
2906
- $defaults = self::get_settings_form_defaults( $type );
2907
- $defaults->type = $type;
 
 
 
 
 
 
 
 
 
 
 
 
 
2908
  }
2909
 
2910
  return $defaults;
@@ -2938,6 +3213,7 @@ final class FLBuilderModel {
2938
  'WP_Widget_Media_Audio',
2939
  'WP_Widget_Media_Image',
2940
  'WP_Widget_Media_Video',
 
2941
  'WP_Widget_Text',
2942
  'WP_Widget_Custom_HTML',
2943
  ) );
@@ -2946,7 +3222,9 @@ final class FLBuilderModel {
2946
  if ( in_array( $class, $exclude ) ) {
2947
  continue;
2948
  }
2949
- $widget->class = get_class( $widget );
 
 
2950
  $widgets[ $widget->name ] = $widget;
2951
  }
2952
 
@@ -2975,6 +3253,64 @@ final class FLBuilderModel {
2975
  return $sidebars;
2976
  }
2977
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2978
  /**
2979
  * Loads the files for all core builder settings.
2980
  *
@@ -2999,6 +3335,16 @@ final class FLBuilderModel {
2999
  */
3000
  static public function register_settings_form( $id, $form ) {
3001
  self::$settings_forms[ $id ] = apply_filters( 'fl_builder_register_settings_form', $form, $id );
 
 
 
 
 
 
 
 
 
 
3002
  }
3003
 
3004
  /**
@@ -3016,13 +3362,24 @@ final class FLBuilderModel {
3016
  * Returns an array of fields in a settings form.
3017
  *
3018
  * @since 1.0
3019
- * @param array $form The form data array.
 
3020
  * @return array
3021
  */
3022
- static public function get_settings_form_fields( $form ) {
3023
  $fields = array();
3024
 
3025
- foreach ( $form as $tab ) {
 
 
 
 
 
 
 
 
 
 
3026
  if ( isset( $tab['sections'] ) ) {
3027
  foreach ( $tab['sections'] as $section ) {
3028
  if ( isset( $section['fields'] ) ) {
@@ -3057,18 +3414,28 @@ final class FLBuilderModel {
3057
  if ( isset( self::$settings_forms[ $type ] ) ) {
3058
  $form_type = $type;
3059
  $tabs = self::$settings_forms[ $type ]['tabs'];
3060
- } // End if().
3061
- elseif ( isset( self::$modules[ $type ] ) ) {
3062
  $form_type = $type . '-module';
3063
  $tabs = self::$modules[ $type ]->form;
3064
- } // The form can't be found.
3065
- else {
3066
  return $defaults;
3067
  }
3068
 
3069
  // Get the fields.
3070
  $fields = self::get_settings_form_fields( $tabs );
3071
 
 
 
 
 
 
 
 
 
 
 
 
 
3072
  // Loop through the fields and get the defaults.
3073
  foreach ( $fields as $name => $field ) {
3074
 
@@ -3192,8 +3559,35 @@ final class FLBuilderModel {
3192
  self::delete_node_template_asset_cache( $template_post_id );
3193
  }
3194
 
3195
- // Return the new layout.
3196
- return FLBuilderAJAXLayout::render();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3197
  }
3198
 
3199
  /**
@@ -3464,15 +3858,14 @@ final class FLBuilderModel {
3464
  $status = ! $status ? self::get_node_status() : $status;
3465
 
3466
  // Get published data?
3467
- if ( 'published' == $status ) {
3468
  if ( isset( self::$published_layout_data[ $post_id ] ) ) {
3469
  $data = self::$published_layout_data[ $post_id ];
3470
  } else {
3471
  $data = get_metadata( 'post', $post_id, '_fl_builder_data', true );
3472
  self::$published_layout_data[ $post_id ] = self::clean_layout_data( $data );
3473
  }
3474
- } // End if().
3475
- elseif ( 'draft' == $status ) {
3476
  if ( isset( self::$draft_layout_data[ $post_id ] ) ) {
3477
  $data = self::$draft_layout_data[ $post_id ];
3478
  } else {
@@ -3594,6 +3987,24 @@ final class FLBuilderModel {
3594
  return $cleaned;
3595
  }
3596
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3597
  /**
3598
  * Get the builder settings for a layout.
3599
  *
@@ -3903,22 +4314,51 @@ final class FLBuilderModel {
3903
  // Set the template type.
3904
  wp_set_post_terms( $post_id, 'layout', 'fl-builder-template-type' );
3905
 
 
 
 
 
 
 
 
3906
  // Get the layout data and settings to copy.
3907
- $data = self::get_layout_data();
3908
- $settings = self::get_layout_settings();
3909
 
3910
  // Generate new node ids.
3911
  $data = self::generate_new_node_ids( $data );
3912
 
3913
  // Save the template layout data and settings.
3914
  self::update_layout_data( $data, 'published', $post_id );
3915
- self::update_layout_settings( $settings, 'published', $post_id );
3916
 
3917
  // Enable the builder for this template.
3918
  update_post_meta( $post_id, '_fl_builder_enabled', true );
3919
 
3920
  // Allow extensions to hook into saving a user template.
3921
  do_action( 'fl_builder_after_save_user_template', $post_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3922
  }
3923
 
3924
  /**
@@ -3957,41 +4397,54 @@ final class FLBuilderModel {
3957
  foreach ( $posts as $post ) {
3958
 
3959
  if ( has_post_thumbnail( $post->ID ) ) {
3960
- $image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'medium' );
3961
  $image = $image_data[0];
3962
  } else {
3963
  $image = FL_BUILDER_URL . 'img/templates/blank.jpg';
3964
  }
3965
 
3966
  $templates[] = array(
3967
- 'id' => $post->ID,
 
3968
  'name' => $post->post_title,
3969
  'image' => $image,
 
3970
  'type' => 'user',
 
 
 
 
3971
  );
3972
  }
3973
 
3974
  // Loop through templates and build the categorized array.
3975
- foreach ( $templates as $template ) {
3976
 
3977
- $cats = wp_get_post_terms( $template['id'], 'fl-builder-template-category' );
3978
 
3979
  if ( 0 === count( $cats ) || is_wp_error( $cats ) ) {
 
 
 
3980
  $categorized['uncategorized']['templates'][] = $template;
3981
  } else {
3982
 
3983
  foreach ( $cats as $cat ) {
 
 
3984
 
 
3985
  if ( ! isset( $categorized[ $cat->slug ] ) ) {
3986
  $categorized[ $cat->slug ] = array(
3987
  'name' => $cat->name,
3988
  'templates' => array(),
3989
  );
3990
  }
3991
-
3992
  $categorized[ $cat->slug ]['templates'][] = $template;
3993
  }
3994
  }
 
 
3995
  }
3996
 
3997
  // Unset the uncategorized cat if no templates.
@@ -4055,7 +4508,7 @@ final class FLBuilderModel {
4055
  * @since 1.1.3
4056
  * @param int|object $template The post ID of the template to apply or a template data object.
4057
  * @param bool $append Whether to append the new template or replacing the existing layout.
4058
- * @return void
4059
  */
4060
  static public function apply_user_template( $template = null, $append = false ) {
4061
  if ( $template ) {
@@ -4108,11 +4561,15 @@ final class FLBuilderModel {
4108
  // Delete old asset cache.
4109
  self::delete_asset_cache();
4110
 
4111
- return array(
4112
- 'layout_css' => $settings->css,
4113
- );
4114
  }// End if().
4115
  }// End if().
 
 
 
 
 
 
 
4116
  }
4117
 
4118
  /**
@@ -4218,8 +4675,7 @@ final class FLBuilderModel {
4218
  // For logged out users
4219
  if ( 'logged_out' == $node->settings->visibility_display && ! is_user_logged_in() ) {
4220
  $is_visible = true;
4221
- } // End if().
4222
- elseif ( 'logged_in' == $node->settings->visibility_display && is_user_logged_in() ) {
4223
  $is_visible = true;
4224
 
4225
  // User capability setting
@@ -4230,7 +4686,7 @@ final class FLBuilderModel {
4230
  $is_visible = false;
4231
  }
4232
  }
4233
- } // Never
4234
  elseif ( 0 == $node->settings->visibility_display ) {
4235
  $is_visible = false;
4236
  } else {
@@ -4442,8 +4898,7 @@ final class FLBuilderModel {
4442
  unset( $nodes[ $node_id ]->template_root_node );
4443
  }
4444
  }
4445
- } // End if().
4446
- else {
4447
 
4448
  foreach ( $nodes as $node_id => $node ) {
4449
 
@@ -4492,6 +4947,8 @@ final class FLBuilderModel {
4492
  'name' => $settings['name'],
4493
  'type' => $root_node->type,
4494
  'layout' => $settings['global'] ? FLBuilderAJAXLayout::render( $root_node->node, $template_node_id ) : null,
 
 
4495
  );
4496
  }
4497
 
@@ -4633,7 +5090,7 @@ final class FLBuilderModel {
4633
  // Remove template info from the layout data.
4634
  foreach ( $layout_data as $node_id => $node ) {
4635
  unset( $layout_data[ $node_id ]->template_id );
4636
- unset( $layout_data[ $node_id ]->template_post_id );
4637
  unset( $layout_data[ $node_id ]->template_root_node );
4638
  }
4639
 
@@ -4727,8 +5184,8 @@ final class FLBuilderModel {
4727
  * @return void
4728
  */
4729
  static public function apply_node_template( $template_id = null, $parent_id = null, $position = 0, $template = null ) {
4730
- $parent = 0 == $parent_id ? null : self::get_node( $parent_id );
4731
- $template_post_id = self::get_node_template_post_id( $template_id );
4732
 
4733
  // Allow extensions to hook into applying a node template.
4734
  $override = apply_filters( 'fl_builder_override_apply_node_template', false, array(
@@ -4750,8 +5207,7 @@ final class FLBuilderModel {
4750
  $template_settings = $template->settings;
4751
  $type = $template->type;
4752
  $global = $template->global;
4753
- } // End if().
4754
- else {
4755
  $template_data = self::get_layout_data( 'published', $template_post_id );
4756
  $template_settings = self::get_layout_settings( 'published', $template_post_id );
4757
  $type = self::get_user_template_type( $template_post_id );
@@ -4764,10 +5220,23 @@ final class FLBuilderModel {
4764
  // Get the root node from the template data.
4765
  $root_node = self::get_node_template_root( $type, $template_data );
4766
 
4767
- // Add a new parent for module node templates if needed.
4768
- if ( 'module' == $root_node->type && ( ! $parent || 'row' == $parent->type || 'column-group' == $parent->type ) ) {
4769
- $parent_id = self::add_module_parent( $parent_id, $position );
4770
- $position = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
4771
  }
4772
 
4773
  // Update the root node's parent.
@@ -4780,13 +5249,12 @@ final class FLBuilderModel {
4780
  // Only merge the root node for global templates.
4781
  if ( $global ) {
4782
  $layout_data[ $root_node->node ] = $template_data[ $root_node->node ];
4783
- } // End if().
4784
- else {
4785
 
4786
  // Merge template data.
4787
  foreach ( $template_data as $node_id => $node ) {
4788
  unset( $template_data[ $node_id ]->template_id );
4789
- unset( $template_data[ $node_id ]->template_post_id );
4790
  unset( $template_data[ $node_id ]->template_root_node );
4791
  }
4792
 
@@ -4820,13 +5288,37 @@ final class FLBuilderModel {
4820
  * Registers a template data file with the builder.
4821
  *
4822
  * @since 1.8
4823
- * @param sting $path The directory path to the template data file.
 
4824
  * @return void
4825
  */
4826
- static public function register_templates( $path = false ) {
4827
- if ( $path && file_exists( $path ) ) {
4828
- self::$templates[] = $path;
 
4829
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4830
  }
4831
 
4832
  /**
@@ -4837,6 +5329,7 @@ final class FLBuilderModel {
4837
  */
4838
  static private function register_core_templates() {
4839
  $templates = glob( FL_BUILDER_DIR . 'data/*' );
 
4840
 
4841
  // glob() will return false on error so cast as an array() just in case.
4842
  foreach ( (array) $templates as $template ) {
@@ -4845,8 +5338,10 @@ final class FLBuilderModel {
4845
  continue;
4846
  }
4847
 
4848
- self::register_templates( $template );
4849
  }
 
 
4850
  }
4851
 
4852
  /**
@@ -4870,11 +5365,11 @@ final class FLBuilderModel {
4870
 
4871
  // Return if we have an override from the filter.
4872
  if ( $override ) {
4873
- return;
4874
  }
4875
 
4876
  // Apply a core template.
4877
- self::apply_core_template( $index, $append, $type );
4878
  }
4879
 
4880
  /**
@@ -4884,7 +5379,7 @@ final class FLBuilderModel {
4884
  * @param int $index The index of the template to apply.
4885
  * @param bool $append Whether to append the new template or replacing the existing layout.
4886
  * @param string $type The type of template to apply.
4887
- * @return void
4888
  */
4889
  static public function apply_core_template( $index = 0, $append = false, $type = 'layout' ) {
4890
  $template = self::get_template( $index, $type );
@@ -4930,6 +5425,12 @@ final class FLBuilderModel {
4930
 
4931
  // Delete old asset cache.
4932
  self::delete_asset_cache();
 
 
 
 
 
 
4933
  }
4934
 
4935
  /**
@@ -4965,43 +5466,50 @@ final class FLBuilderModel {
4965
 
4966
  self::$template_data = array();
4967
 
4968
- foreach ( self::$templates as $path ) {
4969
 
4970
- // Make sure the template file exists.
4971
- if ( ! file_exists( $path ) ) {
4972
- continue;
4973
- }
4974
-
4975
- // Get the unserialized template data.
4976
- if ( stristr( $path, '.php' ) ) {
4977
- ob_start();
4978
- include $path;
4979
- $unserialized = unserialize( ob_get_clean() );
4980
- } else {
4981
- $unserialized = fl_maybe_fix_unserialize( file_get_contents( $path ) );
4982
- }
4983
 
4984
- // Make sure we have an unserialized array.
4985
- if ( ! is_array( $unserialized ) ) {
4986
- continue;
4987
- }
4988
 
4989
- // Group and cache the template data.
4990
- foreach ( $unserialized as $template_type => $template_data ) {
 
 
 
 
 
 
4991
 
4992
- if ( ! isset( self::$template_data[ $template_type ] ) ) {
4993
- self::$template_data[ $template_type ] = array();
 
4994
  }
4995
 
4996
- // Reserialize the node data as it's expensive to store in memory.
4997
- foreach ( $template_data as $key => $template ) {
4998
- if ( isset( $template->nodes ) ) {
4999
- $template_data[ $key ]->nodes = serialize( $template_data[ $key ]->nodes );
 
5000
  }
5001
- }
5002
 
5003
- self::$template_data[ $template_type ] = array_merge( self::$template_data[ $template_type ], $template_data );
5004
- }
 
 
 
 
 
 
 
 
 
 
 
 
5005
  }// End foreach().
5006
  }// End if().
5007
 
@@ -5038,16 +5546,17 @@ final class FLBuilderModel {
5038
  'landing' => __( 'Landing Pages', 'fl-builder' ),
5039
  'company' => __( 'Content Pages', 'fl-builder' ),
5040
  );
 
5041
 
5042
  // Build the the templates array.
5043
  foreach ( self::get_templates( $type ) as $key => $template ) {
5044
 
5045
- if ( 'module' == $type ) {
5046
 
5047
  $nodes = maybe_unserialize( $template->nodes );
5048
  $node = array_shift( $nodes );
5049
 
5050
- if ( ! isset( self::$modules[ $node->settings->type ] ) ) {
5051
  continue;
5052
  }
5053
  }
@@ -5058,76 +5567,100 @@ final class FLBuilderModel {
5058
  $image = FL_BUILDER_URL . 'img/templates/' . ( empty( $template->image ) ? 'blank.jpg' : $template->image );
5059
  }
5060
 
5061
- $template_data = array(
5062
  'id' => $key,
5063
  'name' => $template->name,
5064
  'image' => $image,
 
5065
  'category' => isset( $template->category ) ? $template->category : $template->categories,
 
 
5066
  'type' => 'core',
5067
- );
5068
-
5069
- $template_data = apply_filters( 'fl_builder_template_selector_data', $template_data, $template );
5070
-
5071
- $templates[] = $template_data;
5072
  }
5073
 
5074
- // Build the categorized templates array.
5075
- foreach ( $templates as $template ) {
5076
 
 
5077
  if ( ! isset( $template['category'] ) ) {
5078
- continue;
 
 
 
 
 
 
5079
  }
5080
 
5081
- if ( is_array( $template['category'] ) ) {
 
5082
 
5083
- foreach ( $template['category'] as $cat_key => $cat_label ) {
 
 
 
 
 
 
 
 
5084
 
5085
- if ( ! isset( $categorized[ $cat_key ] ) ) {
5086
- $categorized[ $cat_key ] = array(
5087
- 'name' => $cat_label,
5088
- 'templates' => array(),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5089
  );
5090
  }
5091
-
5092
- $categorized[ $cat_key ]['templates'][] = $template;
5093
  }
5094
- } else {
 
 
 
 
5095
 
5096
- if ( ! isset( $categorized[ $template['category'] ] ) ) {
5097
- $categorized[ $template['category'] ] = array(
5098
- 'name' => $core_categories[ $template['category'] ],
 
5099
  'templates' => array(),
5100
  );
5101
  }
5102
 
5103
- $categorized[ $template['category'] ]['templates'][] = $template;
5104
  }
5105
- }
 
 
5106
 
5107
  // Return both the templates and categorized templates array.
5108
  return apply_filters( 'fl_builder_template_selector_data', array(
5109
  'templates' => $templates,
5110
  'categorized' => $categorized,
 
5111
  ), $type );
5112
  }
5113
 
5114
- /**
5115
- * Returns data needed for the template selector's category filter.
5116
- *
5117
- * @since 1.8
5118
- * @return array
5119
- */
5120
- static public function get_template_selector_filter_data() {
5121
- $templates = self::get_template_selector_data();
5122
- $data = array();
5123
-
5124
- foreach ( $templates['categorized'] as $slug => $category ) {
5125
- $data[ $slug ] = $category['name'];
5126
- }
5127
-
5128
- return apply_filters( 'fl_builder_template_selector_filter_data', $data );
5129
- }
5130
-
5131
  /**
5132
  * Returns data for row templates to be shown in the UI panel.
5133
  *
@@ -5245,7 +5778,7 @@ final class FLBuilderModel {
5245
  'enabled' => true,
5246
  'tour' => true,
5247
  'video' => true,
5248
- 'video_embed' => '<iframe src="https://player.vimeo.com/video/124230072?autoplay=1" width="420" height="315" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
5249
  'knowledge_base' => true,
5250
  'knowledge_base_url' => self::get_store_url( 'knowledge-base', array(
5251
  'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ),
@@ -5277,6 +5810,70 @@ final class FLBuilderModel {
5277
  return self::get_help_button_defaults();
5278
  }
5279
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5280
  /**
5281
  * Returns an array of account data for all integrated services.
5282
  *
@@ -5340,18 +5937,18 @@ final class FLBuilderModel {
5340
  * @return mixed
5341
  */
5342
  static public function get_admin_settings_option( $key, $network_override = true ) {
5343
- // Get the site-wide option if we're in the network admin.
5344
  if ( is_network_admin() ) {
 
5345
  $value = get_site_option( $key );
5346
- } // End if().
5347
- elseif ( ! $network_override && class_exists( 'FLBuilderMultisiteSettings' ) ) {
5348
  $value = get_site_option( $key );
5349
- } // Network overrides are allowed. Return the subsite option if it exists.
5350
- elseif ( class_exists( 'FLBuilderMultisiteSettings' ) ) {
5351
  $value = get_option( $key );
5352
  $value = false === $value ? get_site_option( $key ) : $value;
5353
- } // This must be a single site install. Get the single site option.
5354
- else {
5355
  $value = get_option( $key );
5356
  }
5357
 
@@ -5368,14 +5965,14 @@ final class FLBuilderModel {
5368
  * @return mixed
5369
  */
5370
  static public function update_admin_settings_option( $key, $value, $network_override = true ) {
5371
- // Update the site-wide option since we're in the network admin.
5372
  if ( is_network_admin() ) {
 
5373
  update_site_option( $key, $value );
5374
- } // End if().
5375
- elseif ( $network_override && FLBuilderAdminSettings::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
5376
  delete_option( $key );
5377
- } // Update the option for single install or subsite.
5378
- else {
5379
  update_option( $key, $value );
5380
  }
5381
  }
@@ -5538,6 +6135,26 @@ final class FLBuilderModel {
5538
 
5539
  return FLBuilderUserAccess::current_user_can( 'builder_admin' );
5540
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5541
  }
5542
 
5543
  FLBuilderModel::init();
188
 
189
  /* Filters */
190
  add_filter( 'heartbeat_received', __CLASS__ . '::lock_post', 10, 2 );
191
+ add_filter( 'fl_builder_register_settings_form', __CLASS__ . '::filter_row_settings_for_resize', 10, 2 );
192
 
193
  /* Core Templates */
194
  self::register_core_templates();
264
  $_POST['fl_builder_data']['node_settings'] = FLBuilderUtils::modsec_fix_decode( $_POST['fl_builder_data']['node_settings'] );
265
  }
266
 
267
+ $data = FLBuilderUtils::json_decode_deep( wp_unslash( $_POST['fl_builder_data'] ) );
268
 
269
  foreach ( $data as $key => $val ) {
270
  self::$post_data[ $key ] = $val;
355
  * is being displayed or worked on.
356
  *
357
  * @since 1.0
358
+ * @param bool $force_globals Force the use of WP globals instead of checking our internal post ID.
359
  * @return int|bool The post id or false.
360
  */
361
+ static public function get_post_id( $force_globals = false ) {
362
+
363
+ // Check our internal post IDs first if we're not forced to use WP globals.
364
+ if ( ! $force_globals ) {
365
+
366
+ $post_data = self::get_post_data();
367
+
368
+ if ( ! empty( self::$post_id ) ) {
369
+ // Get a post ID from the internal $post_id array if not empty.
370
+ return self::$post_id[0];
371
+ } elseif ( isset( $post_data['post_id'] ) ) {
372
+ // Get a post ID from an AJAX request.
373
+ return $post_data['post_id'];
374
+ }
375
+ }
376
+
377
+ // Check WP globals.
378
  global $wp_the_query;
379
  global $post;
380
 
381
+ if ( in_the_loop() && is_main_query() && isset( $wp_the_query->post ) ) {
382
+ // Get a post ID from the main query.
 
 
 
 
 
 
 
 
383
  return $wp_the_query->post->ID;
384
+ } elseif ( isset( $post ) ) {
385
+ // Get a post ID in a query outside of the main loop.
386
  return $post->ID;
 
 
 
387
  }
388
+
389
+ // No post ID found.
390
+ return false;
391
  }
392
 
393
  /**
466
  * for the current post.
467
  *
468
  * @since 1.0
469
+ * @param int $post_id A post ID to check otherwise, self::get_post_id will be used.
470
  * @return bool
471
  */
472
+ static public function is_builder_enabled( $post_id = null ) {
473
+ global $wp_the_query;
474
+
475
+ $query_id = ( isset( $wp_the_query->post->ID ) ) ? $wp_the_query->post->ID : false;
476
+ $post_id = $post_id ? $post_id : self::get_post_id();
477
 
478
  if ( ! is_admin() && post_password_required( $post_id ) ) {
479
  return false;
480
+ } elseif ( self::is_builder_active() && $query_id === $post_id ) {
481
  return true;
482
  } else {
 
483
  $post_types = self::get_post_types();
484
  $post = get_post( $post_id );
485
 
509
  return self::$active;
510
  } elseif ( ! is_admin() && is_singular() && $query_id != $post_id ) {
511
  self::$active = false;
512
+ } elseif ( is_customize_preview() ) {
513
+ self::$active = false;
514
  } elseif ( self::is_post_editable() && ! is_admin() && ! post_password_required() ) {
515
  $post_data = self::get_post_data();
516
  self::$active = isset( $_GET['fl_builder'] ) || isset( $post_data['fl_builder'] );
595
  $cols = self::get_nodes( 'column' );
596
  $col = array_shift( $cols );
597
  $settings = self::get_module_defaults( 'rich-text' );
598
+ $settings->text = apply_filters( 'fl_builder_migrated_post_content', wpautop( $post->post_content ) );
599
 
600
  self::add_module( 'rich-text', $settings, $col->node );
601
+ } elseif ( empty( $draft ) ) {
 
602
  self::update_layout_data( $published, 'draft', $post->ID );
603
  self::update_layout_settings( self::get_layout_settings( 'published' ), 'draft', $post->ID );
604
  }
936
  // Return all nodes?
937
  if ( ! $type ) {
938
  $nodes = $data;
939
+ } else {
 
940
 
941
  foreach ( $data as $node_id => $node ) {
942
 
1096
  * @return array
1097
  */
1098
  static public function get_child_nodes( $parent_id, $status = null ) {
1099
+ $parent = is_object( $parent_id ) ? $parent_id : self::get_node( $parent_id );
1100
+ $template_post_id = self::is_node_global( $parent );
1101
+ $status = $template_post_id && ! self::is_post_node_template() ? 'published' : $status;
1102
+ $data = self::get_layout_data( $status, $template_post_id );
1103
+ $nodes = array();
1104
 
1105
+ if ( is_object( $parent ) ) {
1106
+ foreach ( $data as $node_id => $node ) {
1107
+ if ( ( isset( $node->parent ) && $node->parent == $parent->node )
1108
+ || ( $template_post_id && $parent->template_node_id == $node->parent ) ) {
1109
+ $nodes[ $node_id ] = $node;
1110
+ }
1111
  }
1112
  }
1113
 
1267
  * @return object
1268
  */
1269
  static public function process_node_settings( $node, $new_settings ) {
1270
+
1271
  if ( 'row' == $node->type ) {
1272
  $new_settings = self::process_row_settings( $node, $new_settings );
1273
+ $new_settings = self::sanitize_settings( $new_settings, 'row', 'general' );
1274
  }
1275
  if ( 'column' == $node->type ) {
1276
  $new_settings = self::process_col_settings( $node, $new_settings );
1277
+ $new_settings = self::sanitize_settings( $new_settings, 'col', 'general' );
1278
  }
1279
  if ( 'module' == $node->type ) {
1280
  $new_settings = self::process_module_settings( $node, $new_settings );
1281
+ $new_settings = self::sanitize_settings( $new_settings, $node->settings->type, 'module' );
1282
  }
1283
 
1284
  return $new_settings;
1554
  *
1555
  * @since 1.0
1556
  * @param string $node_id Node ID of the row to copy.
1557
+ * @param object $settings These settings will be used for the copy if present.
1558
+ * @param string $settings_id The ID of the node who's settings were passed.
1559
  * @return void
1560
  */
1561
+ static public function copy_row( $node_id = null, $settings = null, $settings_id = null ) {
1562
  $layout_data = self::get_layout_data();
1563
  $row = self::get_node( $node_id );
1564
  $new_row_id = self::generate_node_id();
1615
  }
1616
  }// End foreach().
1617
 
1618
+ // Apply settings that were passed if we have them.
1619
+ if ( $settings && $settings_id ) {
1620
+ if ( $settings_id === $row->node ) {
1621
+ $layout_data[ $new_row_id ]->settings = (object) array_merge( (array) $row->settings, (array) $settings );
1622
+ } else {
1623
+ $new_nodes[ $settings_id ]->settings = (object) array_merge( (array) $new_nodes[ $settings_id ]->settings, (array) $settings );
1624
+ }
1625
+ }
1626
+
1627
  // Generate new child ids.
1628
  $new_nodes = self::generate_new_node_ids( $new_nodes );
1629
 
1749
  }
1750
 
1751
  // Cache background slideshow data.
1752
+ if ( 'slideshow' == $new_settings->bg_type && 'wordpress' == $new_settings->ss_source ) {
1753
 
1754
  // Make sure we have a photo data object.
1755
  if ( ! isset( $row->settings->ss_photo_data ) ) {
1792
 
1793
  $data['webm'] = $row->settings->bg_video_webm_data;
1794
  }
1795
+ } elseif ( 'slideshow' == $row->settings->bg_type && isset( $row->settings->ss_photo_data ) ) {
 
1796
  $data = $row->settings->ss_photo_data;
1797
  }
1798
 
1824
  return $ss->get_source();
1825
  }
1826
 
1827
+ /**
1828
+ * Set the max-width of a specific row.
1829
+ *
1830
+ * @since 2.0
1831
+ * @param int Row node id
1832
+ * @param int Width
1833
+ * @return void
1834
+ */
1835
+ static public function resize_row_content( $node_id, $width ) {
1836
+ $data = self::get_layout_data();
1837
+ $row = self::get_node( $node_id );
1838
+ $row->settings->max_content_width = $width;
1839
+ $data[ $node_id ] = $row;
1840
+ self::update_layout_data( $data );
1841
+ }
1842
+
1843
  /**
1844
  * Adds a column group to a row in the current layout.
1845
  *
1888
  $data[ $col_node_id ]->template_node_id = $col_node_id;
1889
  }
1890
  }
1891
+ } else {
 
1892
 
1893
  $old_group = $data[ $cols ]->parent;
1894
  $siblings = self::get_nodes( 'column', $old_group );
1912
  $data[ $sibling->node ]->position = $sibling_pos;
1913
  $sibling_pos++;
1914
  }
1915
+ }// End if().
1916
 
1917
  // Update the layout data.
1918
  self::update_layout_data( $data );
2027
  // Delete the group if empty.
2028
  if ( count( $cols ) === 0 ) {
2029
  self::delete_node( $group->node );
2030
+ } else {
 
2031
 
2032
  // Get the layout data.
2033
  $data = self::get_layout_data();
2341
  return $parent;
2342
  }
2343
 
2344
+ /**
2345
+ * Copys a column and adds it to the current layout.
2346
+ *
2347
+ * @since 2.0
2348
+ * @param string $node_id Node ID of the column to copy.
2349
+ * @param object $settings These settings will be used for the copy if present.
2350
+ * @param string $settings_id The ID of the node who's settings were passed.
2351
+ * @return void
2352
+ */
2353
+ static public function copy_col( $node_id = null, $settings = null, $settings_id = null ) {
2354
+ $layout_data = self::get_layout_data();
2355
+ $col = self::get_node( $node_id );
2356
+ $new_col_id = self::generate_node_id();
2357
+ $nodes = self::get_nodes( null, $col );
2358
+ $new_nodes = array();
2359
+
2360
+ // Add the new column.
2361
+ $layout_data[ $new_col_id ] = clone $col;
2362
+ $layout_data[ $new_col_id ]->settings = clone $col->settings;
2363
+ $layout_data[ $new_col_id ]->node = $new_col_id;
2364
+
2365
+ // Unset column template data.
2366
+ if ( isset( $layout_data[ $new_col_id ]->template_id ) ) {
2367
+ unset( $layout_data[ $new_col_id ]->template_id );
2368
+ unset( $layout_data[ $new_col_id ]->template_node_id );
2369
+ unset( $layout_data[ $new_col_id ]->template_root_node );
2370
+ }
2371
+
2372
+ // Get the new child nodes.
2373
+ foreach ( $nodes as $node ) {
2374
+
2375
+ $new_nodes[ $node->node ] = clone $node;
2376
+
2377
+ if ( 'module' == $node->type ) {
2378
+ $new_nodes[ $node->node ]->settings = self::clone_module_settings( $node->settings );
2379
+ } elseif ( 'column-group' == $node->type ) {
2380
+
2381
+ $nested_cols = self::get_nodes( 'column', $node );
2382
+
2383
+ foreach ( $nested_cols as $nested_col ) {
2384
+
2385
+ $new_nodes[ $nested_col->node ] = clone $nested_col;
2386
+ $new_nodes[ $nested_col->node ]->settings = clone $nested_col->settings;
2387
+ $modules = self::get_nodes( 'module', $nested_col );
2388
+
2389
+ foreach ( $modules as $module ) {
2390
+ $new_nodes[ $module->node ] = clone $module;
2391
+ $new_nodes[ $module->node ]->settings = self::clone_module_settings( $module->settings );
2392
+ }
2393
+ }
2394
+ }
2395
+ }
2396
+
2397
+ // Apply settings that were passed if we have them.
2398
+ if ( $settings && $settings_id ) {
2399
+ if ( $settings_id === $col->node ) {
2400
+ $layout_data[ $new_col_id ]->settings = (object) array_merge( (array) $col->settings, (array) $settings );
2401
+ } else {
2402
+ $new_nodes[ $settings_id ]->settings = (object) array_merge( (array) $new_nodes[ $settings_id ]->settings, (array) $settings );
2403
+ }
2404
+ }
2405
+
2406
+ // Generate new child ids.
2407
+ $new_nodes = self::generate_new_node_ids( $new_nodes );
2408
+
2409
+ // Set child parent ids to the new column id and unset template data.
2410
+ foreach ( $new_nodes as $child_node_id => $child ) {
2411
+ if ( $child->parent == $col->node || ( isset( $col->template_node_id ) && $child->parent == $col->template_node_id ) ) {
2412
+ $new_nodes[ $child_node_id ]->parent = $new_col_id;
2413
+ }
2414
+ if ( isset( $new_nodes[ $child_node_id ]->template_id ) ) {
2415
+ unset( $new_nodes[ $child_node_id ]->template_id );
2416
+ unset( $new_nodes[ $child_node_id ]->template_node_id );
2417
+ }
2418
+ }
2419
+
2420
+ // Merge the child data.
2421
+ $layout_data = array_merge( $layout_data, $new_nodes );
2422
+
2423
+ // Update the layout data.
2424
+ self::update_layout_data( $layout_data );
2425
+
2426
+ // Position the new column.
2427
+ self::reorder_node( $new_col_id, $col->position + 1 );
2428
+
2429
+ // Reset the column widths.
2430
+ self::reset_col_widths( $col->parent );
2431
+
2432
+ // Return the new column.
2433
+ return self::get_node( $new_col_id );
2434
+ }
2435
+
2436
  /**
2437
  * Returns the default settings for column nodes.
2438
  *
2454
  $dir = dir( $path );
2455
  $module_path = '';
2456
 
2457
+ while ( false !== ( $entry = $dir->read() ) ) { // @codingStandardsIgnoreLine
2458
 
2459
  if ( ! is_dir( $path . $entry ) || '.' == $entry || '..' == $entry ) {
2460
  continue;
2469
  // Check for the module class in a child theme.
2470
  if ( is_child_theme() && file_exists( $child_path ) ) {
2471
  require_once $child_path;
2472
+ } elseif ( file_exists( $theme_path ) ) {
 
2473
  require_once $theme_path;
2474
+ } elseif ( file_exists( $builder_path ) ) {
 
2475
  require_once $builder_path;
2476
  }
2477
  }
2478
+
2479
+ do_action( 'fl_builder_register_extensions' );
2480
  }
2481
 
2482
  /**
2532
  $instance->name = isset( $config['name'] ) ? $config['name'] : $slug;
2533
  $instance->description = isset( $config['description'] ) ? $config['description'] : '';
2534
  $instance->category = isset( $config['category'] ) ? $config['category'] : null;
2535
+ $instance->group = isset( $config['group'] ) ? $config['group'] : null;
2536
  $instance->settings = isset( $config['settings'] ) ? $config['settings'] : array();
2537
  $instance->enabled = isset( $config['enabled'] ) ? $config['enabled'] : true;
2538
+ $instance->icon = isset( $config['icon'] ) ? $config['icon'] : FLBuilderModule::get_default_icon();
2539
 
2540
  self::$module_aliases[ $alias ] = $instance;
2541
  }
2590
  }
2591
 
2592
  /**
2593
+ * Returns an array of module group slugs and names.
2594
  *
2595
+ * @since 2.0
 
2596
  * @return array
2597
  */
2598
+ static public function get_module_groups() {
2599
+ $groups = array();
2600
+ $templates = FLBuilderModel::get_module_templates_data();
2601
+
2602
+ // Add module groups.
2603
+ foreach ( self::$modules as $module ) {
2604
+
2605
+ if ( ! $module->group || ! $module->enabled ) {
2606
+ continue;
2607
+ }
2608
+
2609
+ // Check if widgets are enabled
2610
+ if ( 'widget' == $module->slug && ! in_array( 'widget', self::get_enabled_modules() ) ) {
2611
+ continue;
2612
+ }
2613
+
2614
+ $slug = sanitize_key( $module->group );
2615
+
2616
+ if ( ! isset( $groups[ $slug ] ) ) {
2617
+ $groups[ $slug ] = $module->group;
2618
+ }
2619
+ }
2620
+
2621
+ // Add module template groups.
2622
+ if ( isset( $templates['groups'] ) ) {
2623
+ foreach ( $templates['groups'] as $slug => $data ) {
2624
+ if ( ! isset( $groups[ $slug ] ) ) {
2625
+ $groups[ $slug ] = $data['name'];
2626
+ }
2627
+ }
2628
+ }
2629
+
2630
+ return $groups;
2631
+ }
2632
+
2633
+ /**
2634
+ * Returns an array of module category slugs => names
2635
+ *
2636
+ * @since 2.0
2637
+ * @return array
2638
+ */
2639
+ static public function get_module_categories() {
2640
+ $categories = array();
2641
 
2642
  // Add any predefined custom categories.
2643
  foreach ( apply_filters( 'fl_builder_module_categories', array() ) as $custom_category ) {
2644
  $categories[ $custom_category ] = array();
2645
  }
2646
 
 
 
 
 
 
 
2647
  // Build the default category arrays.
2648
+ $categories[ __( 'Basic', 'fl-builder' ) ] = array();
2649
+ $categories[ __( 'Media', 'fl-builder' ) ] = array();
2650
+ $categories[ __( 'Actions', 'fl-builder' ) ] = array();
2651
+ $categories[ __( 'Layout', 'fl-builder' ) ] = array();
2652
+ $categories[ __( 'Info', 'fl-builder' ) ] = array();
2653
+ $categories[ __( 'Posts', 'fl-builder' ) ] = array();
2654
+ $categories[ __( 'Advanced', 'fl-builder' ) ] = array();
2655
+ $categories[ __( 'Other', 'fl-builder' ) ] = array();
2656
+
2657
+ return $categories;
2658
+ }
2659
+
2660
+ /**
2661
+ * Returns an array of categorized modules.
2662
+ *
2663
+ * @since 1.0
2664
+ * @param bool $show_disabled Whether to include disabled modules in the result.
2665
+ * @return array
2666
+ */
2667
+ static public function get_categorized_modules( $show_disabled = false ) {
2668
+ $enabled_modules = self::get_enabled_modules();
2669
+ $widgets = null;
2670
+ $categories = self::get_module_categories();
2671
+ $other_key = __( 'Other', 'fl-builder' );
2672
+ $widgets_key = __( 'WordPress Widgets', 'fl-builder' );
2673
 
2674
  // Build the categories array.
2675
  foreach ( self::$modules as $module ) {
2724
  }
2725
 
2726
  /**
2727
+ * Similar to get_categorized_modules() but creates a flat list.
2728
  *
2729
+ * @since 2.0
2730
+ * @param bool $show_disabled Should show disabled?
2731
+ * @return array
2732
  */
2733
+ static public function get_uncategorized_modules( $show_disabled = false ) {
2734
+ $enabled_modules = self::get_enabled_modules();
2735
+ $modules = array();
2736
+ $aliases = self::$module_aliases;
2737
+ $widgets = FLBuilderModel::get_wp_widgets();
 
2738
 
2739
+ foreach ( self::$modules as $module ) {
2740
+
2741
+ if ( ! $module->enabled ) {
2742
+ continue;
2743
+ } elseif ( ! in_array( $module->slug, $enabled_modules ) && ! $show_disabled ) {
2744
+ continue;
2745
+ } elseif ( 'widget' === $module->slug ) {
2746
+ continue;
2747
+ }
2748
+
2749
+ $module = (object) $module;
2750
+ $module->kind = 'module';
2751
+ $module->isWidget = false; // @codingStandardsIgnoreLine
2752
+ $module->isAlias = false; // @codingStandardsIgnoreLine
2753
+ $module->group = $module->group ? array( sanitize_key( $module->group ) ) : array( 'standard' );
2754
+
2755
+ if ( ! isset( $module->icon ) || '' == $module->icon ) {
2756
+ $module->icon = FLBuilderModule::get_default_icon();
2757
+ }
2758
+
2759
+ // Remove backend-only & instance properties.
2760
+ unset( $module->css );
2761
+ unset( $module->js );
2762
+ unset( $module->editor_export );
2763
+ unset( $module->node );
2764
+ unset( $module->parent );
2765
+ unset( $module->partial_refresh );
2766
+ unset( $module->position );
2767
+ unset( $module->settings );
2768
+ unset( $module->form );
2769
+ unset( $module->dir );
2770
+
2771
+ $modules[] = $module;
2772
  }
2773
+
2774
+ // Add module aliases.
2775
+ foreach ( $aliases as $alias => $config ) {
2776
+
2777
+ if ( ! $config->enabled || ! $config->slug || ! $config->category ) {
2778
+ continue;
2779
+ }
2780
+ if ( ! isset( $categories[ $config->category ] ) ) {
2781
+ $categories[ $config->category ] = array();
2782
+ }
2783
+
2784
+ $config->kind = 'module';
2785
+ $config->isWidget = false; // @codingStandardsIgnoreLine
2786
+ $config->isAlias = true; // @codingStandardsIgnoreLine
2787
+ $config->group = $config->group ? array( sanitize_key( $config->group ) ) : array( 'standard' );
2788
+
2789
+ $modules[] = $config;
2790
  }
2791
+
2792
+ // Add WordPress widgets.
2793
+ if ( in_array( 'widget', $enabled_modules ) ) {
2794
+ foreach ( $widgets as $widget ) {
2795
+
2796
+ $data = new stdClass;
2797
+ $widget = (object) $widget;
2798
+ $data->id = $widget->id;
2799
+ $data->name = $widget->name;
2800
+ $data->class = $widget->class;
2801
+ $data->category = $widget->category;
2802
+ $data->kind = 'module';
2803
+ $data->isWidget = true; // @codingStandardsIgnoreLine
2804
+ $data->isAlias = false; // @codingStandardsIgnoreLine
2805
+ $data->description = isset( $widget->widget_options['description'] ) ? $widget->widget_options['description'] : '';
2806
+
2807
+ $data->group = array( sanitize_key( __( 'WordPress Widgets', 'fl-builder' ) ) );
2808
+
2809
+ if ( ! isset( $widget->icon ) ) {
2810
+ $data->icon = FLBuilderModule::get_widget_icon();
2811
+ }
2812
+ $modules[] = $data;
2813
+ }
2814
  }
2815
 
2816
+ return $modules;
2817
  }
2818
 
2819
  /**
2836
  $instance->settings = $module->settings;
2837
  $instance->type = 'module';
2838
  $instance->form = self::$modules[ $module->settings->type ]->form;
2839
+ $instance->icon = isset( $module->icon ) ? $module->icon : FLBuilderModule::get_default_icon();
2840
 
2841
  if ( isset( $module->template_id ) ) {
2842
  $instance->template_id = $module->template_id;
2877
  $instances[ $i ]->position = $module->position;
2878
  $instances[ $i ]->settings = $module->settings;
2879
  $instances[ $i ]->type = 'module';
2880
+ $instances[ $i ]->icon = isset( $module->icon ) ? $module->icon : FLBuilderModule::get_default_icon();
2881
  $instances[ $i ]->form = self::$modules[ $module->settings->type ]->form;
2882
 
2883
  if ( isset( $module->template_id ) ) {
2929
  $settings = $instance->update( $settings );
2930
 
2931
  // Save the module.
2932
+ $data[ $module_node_id ] = new StdClass();
2933
+ $data[ $module_node_id ]->node = $module_node_id;
2934
+ $data[ $module_node_id ]->type = 'module';
2935
+ $data[ $module_node_id ]->parent = $parent_id;
2936
  $data[ $module_node_id ]->position = self::next_node_position( 'module', $parent_id );
2937
  $data[ $module_node_id ]->settings = $settings;
2938
 
2939
  // Add node template data.
2940
  if ( self::is_node_global( $parent ) ) {
2941
+ $data[ $module_node_id ]->template_id = $parent->template_id;
2942
  $data[ $module_node_id ]->template_node_id = $module_node_id;
2943
  }
2944
 
2966
  static public function add_module_parent( $parent_id = null, $position = null ) {
2967
  $parent = ! $parent_id ? null : self::get_node( $parent_id );
2968
 
 
2969
  if ( ! $parent ) {
2970
+ // Add a new row if we don't have a parent.
2971
  $row = self::add_row( '1-col', $position );
2972
  $col_groups = self::get_nodes( 'column-group', $row->node );
2973
  $col_group = array_shift( $col_groups );
2974
  $cols = self::get_nodes( 'column', $col_group->node );
2975
  $parent = array_shift( $cols );
2976
  $parent_id = $parent->node;
2977
+ } elseif ( 'row' == $parent->type ) {
2978
+ // Add a new column group if the parent is a row.
2979
  $col_group = self::add_col_group( $parent->node, '1-col', $position );
2980
  $cols = self::get_nodes( 'column', $col_group->node );
2981
  $parent = array_shift( $cols );
2982
  $parent_id = $parent->node;
2983
+ } elseif ( 'column-group' == $parent->type ) {
2984
+ // Add a new column if the parent is a column group.
2985
  $parent = self::add_col( $parent->node, $position );
2986
  $parent_id = $parent->node;
2987
  }
3043
  * @return array $defaults Default settings for the module.
3044
  */
3045
  static public function add_default_module( $parent_id = null, $type = null, $position = null, $defaults = null ) {
3046
+ $parent = ( 0 == $parent_id ) ? null : self::get_node( $parent_id );
3047
  $settings = self::get_module_defaults( $type );
3048
  $module_node_id = self::generate_node_id();
3049
 
3067
  $settings = $instance->update( $settings );
3068
 
3069
  // Save the module.
3070
+ $data = self::get_layout_data();
3071
+ $data[ $module_node_id ] = new StdClass();
3072
+ $data[ $module_node_id ]->node = $module_node_id;
3073
+ $data[ $module_node_id ]->type = 'module';
3074
+ $data[ $module_node_id ]->parent = $parent_id;
3075
  $data[ $module_node_id ]->position = self::next_node_position( 'module', $parent_id );
3076
  $data[ $module_node_id ]->settings = $settings;
3077
 
3098
  *
3099
  * @since 1.0
3100
  * @param string $node_id Node ID of the module to copy.
3101
+ * @param object $settings These settings will be used for the copy if present.
3102
  * @return object The new module object.
3103
  */
3104
+ static public function copy_module( $node_id = null, $settings = null ) {
3105
  $module = self::get_module( $node_id );
3106
 
3107
+ if ( $settings ) {
3108
+ $module->settings = (object) array_merge( (array) $module->settings, (array) $settings );
3109
+ }
3110
+
3111
  return self::add_module( $module->settings->type, $module->settings, $module->parent, $module->position + 1 );
3112
  }
3113
 
3155
  }
3156
 
3157
  /**
3158
+ * Returns the default settings for a module or
3159
+ * all modules if type is null.
3160
  *
3161
  * @since 1.0
3162
  * @param string $type The type of module.
3163
+ * @return object|array
3164
  */
3165
+ static public function get_module_defaults( $type = null ) {
 
3166
 
3167
+ if ( $type ) {
3168
+
3169
+ $defaults = new StdClass();
3170
+
3171
+ if ( isset( self::$modules[ $type ]->form ) ) {
3172
+ $defaults = self::get_settings_form_defaults( $type );
3173
+ $defaults = self::merge_nested_module_defaults( $type, $defaults );
3174
+ $defaults->type = $type;
3175
+ }
3176
+ } else {
3177
+
3178
+ $defaults = array();
3179
+
3180
+ foreach ( self::$modules as $module ) {
3181
+ $defaults[ $module->slug ] = self::get_module_defaults( $module->slug );
3182
+ }
3183
  }
3184
 
3185
  return $defaults;
3213
  'WP_Widget_Media_Audio',
3214
  'WP_Widget_Media_Image',
3215
  'WP_Widget_Media_Video',
3216
+ 'WP_Widget_Media_Gallery',
3217
  'WP_Widget_Text',
3218
  'WP_Widget_Custom_HTML',
3219
  ) );
3222
  if ( in_array( $class, $exclude ) ) {
3223
  continue;
3224
  }
3225
+ $widget->class = $class;
3226
+ $widget->isWidget = true; // @codingStandardsIgnoreLine
3227
+ $widget->category = __( 'WordPress Widgets', 'fl-builder' );
3228
  $widgets[ $widget->name ] = $widget;
3229
  }
3230
 
3253
  return $sidebars;
3254
  }
3255
 
3256
+ /**
3257
+ * Returns an array of column group data.
3258
+ *
3259
+ * @since 2.0
3260
+ * @return array
3261
+ */
3262
+ static public function get_column_groups() {
3263
+ $cols = array(
3264
+ array(
3265
+ 'name' => __( '1 Column', 'fl-builder' ),
3266
+ 'id' => '1-col',
3267
+ 'count' => 1,
3268
+ ),
3269
+ array(
3270
+ 'name' => __( '2 Columns', 'fl-builder' ),
3271
+ 'id' => '2-cols',
3272
+ 'count' => 2,
3273
+ ),
3274
+ array(
3275
+ 'name' => __( '3 Columns', 'fl-builder' ),
3276
+ 'id' => '3-cols',
3277
+ 'count' => 3,
3278
+ ),
3279
+ array(
3280
+ 'name' => __( '4 Columns', 'fl-builder' ),
3281
+ 'id' => '4-cols',
3282
+ 'count' => 4,
3283
+ ),
3284
+ array(
3285
+ 'name' => __( '5 Columns', 'fl-builder' ),
3286
+ 'id' => '5-cols',
3287
+ 'count' => 5,
3288
+ ),
3289
+ array(
3290
+ 'name' => __( '6 Columns', 'fl-builder' ),
3291
+ 'id' => '6-cols',
3292
+ 'count' => 6,
3293
+ ),
3294
+ array(
3295
+ 'name' => __( 'Left Sidebar', 'fl-builder' ),
3296
+ 'id' => 'left-sidebar',
3297
+ 'count' => 2,
3298
+ ),
3299
+ array(
3300
+ 'name' => __( 'Right Sidebar', 'fl-builder' ),
3301
+ 'id' => 'right-sidebar',
3302
+ 'count' => 2,
3303
+ ),
3304
+ array(
3305
+ 'name' => __( 'Left & Right Sidebar', 'fl-builder' ),
3306
+ 'id' => 'left-right-sidebar',
3307
+ 'count' => 3,
3308
+ ),
3309
+ );
3310
+
3311
+ return $cols;
3312
+ }
3313
+
3314
  /**
3315
  * Loads the files for all core builder settings.
3316
  *
3335
  */
3336
  static public function register_settings_form( $id, $form ) {
3337
  self::$settings_forms[ $id ] = apply_filters( 'fl_builder_register_settings_form', $form, $id );
3338
+
3339
+ // Since 2.0 we need to store the form ID on each tab to ensure that
3340
+ // it's always available for rendering forms in JS on the frontend.
3341
+ if ( isset( self::$settings_forms[ $id ]['tabs'] ) ) {
3342
+ foreach ( self::$settings_forms[ $id ]['tabs'] as $tab_id => $tab ) {
3343
+ self::$settings_forms[ $id ]['tabs'][ $tab_id ]['form_id'] = $id;
3344
+ }
3345
+ } else {
3346
+ self::$settings_forms[ $id ]['form_id'] = $id;
3347
+ }
3348
  }
3349
 
3350
  /**
3362
  * Returns an array of fields in a settings form.
3363
  *
3364
  * @since 1.0
3365
+ * @param array|string $form The form data array or the form key. If key, group must be set as well.
3366
+ * @param string The form group. Either general or module.
3367
  * @return array
3368
  */
3369
+ static public function get_settings_form_fields( $form, $group = null ) {
3370
  $fields = array();
3371
 
3372
+ if ( 'string' === gettype( $form ) ) {
3373
+ if ( 'general' === $group ) {
3374
+ $form = FLBuilderModel::$settings_forms[ $form ]['tabs'];
3375
+ } elseif ( 'module' === $group ) {
3376
+ $form = FLBuilderModel::$modules[ $form ]->form;
3377
+ } else {
3378
+ return $fields;
3379
+ }
3380
+ }
3381
+
3382
+ foreach ( (array) $form as $tab ) {
3383
  if ( isset( $tab['sections'] ) ) {
3384
  foreach ( $tab['sections'] as $section ) {
3385
  if ( isset( $section['fields'] ) ) {
3414
  if ( isset( self::$settings_forms[ $type ] ) ) {
3415
  $form_type = $type;
3416
  $tabs = self::$settings_forms[ $type ]['tabs'];
3417
+ } elseif ( isset( self::$modules[ $type ] ) ) {
 
3418
  $form_type = $type . '-module';
3419
  $tabs = self::$modules[ $type ]->form;
3420
+ } else {
 
3421
  return $defaults;
3422
  }
3423
 
3424
  // Get the fields.
3425
  $fields = self::get_settings_form_fields( $tabs );
3426
 
3427
+ // Handle dimension fields. We have to do it this way for backwards compat
3428
+ // with old margin, padding, and border fields as the settings expect margin_top
3429
+ // or margin_bottom to exist instead of just the margin key.
3430
+ foreach ( $fields as $name => $field ) {
3431
+ if ( 'dimension' == $field['type'] ) {
3432
+ foreach ( array( 'top', 'right', 'bottom', 'left' ) as $position ) {
3433
+ $fields[ $name . '_' . $position ] = $field;
3434
+ }
3435
+ unset( $fields[ $name ] );
3436
+ }
3437
+ }
3438
+
3439
  // Loop through the fields and get the defaults.
3440
  foreach ( $fields as $name => $field ) {
3441
 
3559
  self::delete_node_template_asset_cache( $template_post_id );
3560
  }
3561
 
3562
+ // Return the processed settings and new layout.
3563
+ return array(
3564
+ 'node_id' => $node->node,
3565
+ 'settings' => $new_settings,
3566
+ 'layout' => FLBuilderAJAXLayout::render(),
3567
+ );
3568
+ }
3569
+
3570
+ /**
3571
+ * Sanitizes settings for a form.
3572
+ *
3573
+ * @since 2.0
3574
+ * @param string $form
3575
+ * @param string $group
3576
+ * @param object $settings
3577
+ * @return object
3578
+ */
3579
+ static public function sanitize_settings( $settings, $form, $group ) {
3580
+ $fields = FLBuilderModel::get_settings_form_fields( $form, $group );
3581
+
3582
+ foreach ( $settings as $name => $value ) {
3583
+ if ( ! isset( $fields[ $name ] ) ) {
3584
+ continue;
3585
+ } elseif ( isset( $fields[ $name ]['sanitize'] ) ) {
3586
+ $settings->$name = call_user_func_array( $fields[ $name ]['sanitize'], array( $value ) );
3587
+ }
3588
+ }
3589
+
3590
+ return $settings;
3591
  }
3592
 
3593
  /**
3858
  $status = ! $status ? self::get_node_status() : $status;
3859
 
3860
  // Get published data?
3861
+ if ( 'published' == $status || 'revision' == get_post_type( $post_id ) ) {
3862
  if ( isset( self::$published_layout_data[ $post_id ] ) ) {
3863
  $data = self::$published_layout_data[ $post_id ];
3864
  } else {
3865
  $data = get_metadata( 'post', $post_id, '_fl_builder_data', true );
3866
  self::$published_layout_data[ $post_id ] = self::clean_layout_data( $data );
3867
  }
3868
+ } elseif ( 'draft' == $status ) {
 
3869
  if ( isset( self::$draft_layout_data[ $post_id ] ) ) {
3870
  $data = self::$draft_layout_data[ $post_id ];
3871
  } else {
3987
  return $cleaned;
3988
  }
3989
 
3990
+ /**
3991
+ * Detect if the current layout has previously drafted changes.
3992
+ *
3993
+ * @since 2.0
3994
+ * @return bool
3995
+ */
3996
+ static public function layout_has_drafted_changes() {
3997
+ $post_id = FLBuilderModel::get_post_id();
3998
+ $published = serialize( self::get_layout_data( 'published', $post_id ) );
3999
+ $draft = serialize( self::get_layout_data( 'draft', $post_id ) );
4000
+
4001
+ if ( $published != $draft ) {
4002
+ return true;
4003
+ }
4004
+
4005
+ return false;
4006
+ }
4007
+
4008
  /**
4009
  * Get the builder settings for a layout.
4010
  *
4314
  // Set the template type.
4315
  wp_set_post_terms( $post_id, 'layout', 'fl-builder-template-type' );
4316
 
4317
+ // Add category
4318
+ $cat = isset( $settings['category'] ) ? $settings['category'] : '';
4319
+ $cat_added = '';
4320
+ if ( __( 'Uncategorized', 'fl-builder' ) !== $cat && 'uncategorized' !== $cat ) {
4321
+ $cat_added = wp_set_object_terms( $post_id, $cat, 'fl-builder-template-category' );
4322
+ }
4323
+
4324
  // Get the layout data and settings to copy.
4325
+ $data = self::get_layout_data();
4326
+ $layout_settings = self::get_layout_settings();
4327
 
4328
  // Generate new node ids.
4329
  $data = self::generate_new_node_ids( $data );
4330
 
4331
  // Save the template layout data and settings.
4332
  self::update_layout_data( $data, 'published', $post_id );
4333
+ self::update_layout_settings( $layout_settings, 'published', $post_id );
4334
 
4335
  // Enable the builder for this template.
4336
  update_post_meta( $post_id, '_fl_builder_enabled', true );
4337
 
4338
  // Allow extensions to hook into saving a user template.
4339
  do_action( 'fl_builder_after_save_user_template', $post_id );
4340
+
4341
+ $response = array(
4342
+ 'name' => $settings['name'],
4343
+ 'id' => get_post_meta( $post_id, '_fl_builder_template_id', true ),
4344
+ 'postId' => $post_id,
4345
+ 'image' => FL_BUILDER_URL . 'img/templates/blank.jpg',
4346
+ 'kind' => 'template',
4347
+ 'content' => 'layout',
4348
+ 'type' => 'user',
4349
+ 'isGlobal' => false,
4350
+ 'link' => add_query_arg( 'fl_builder', '', get_permalink( $post_id ) ),
4351
+ 'category' => array(),
4352
+ );
4353
+
4354
+ if ( is_array( $cat_added ) && ! empty( $cat_added ) ) {
4355
+ $term = get_term( $cat_added[0] );
4356
+ $response['category'][ $term->slug ] = $term->name;
4357
+ } else {
4358
+ $response['category']['uncategorized'] = __( 'Uncategorized', 'fl-builder' );
4359
+ }
4360
+
4361
+ return $response;
4362
  }
4363
 
4364
  /**
4397
  foreach ( $posts as $post ) {
4398
 
4399
  if ( has_post_thumbnail( $post->ID ) ) {
4400
+ $image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'medium_large' );
4401
  $image = $image_data[0];
4402
  } else {
4403
  $image = FL_BUILDER_URL . 'img/templates/blank.jpg';
4404
  }
4405
 
4406
  $templates[] = array(
4407
+ 'id' => get_post_meta( $post->ID, '_fl_builder_template_id', true ),
4408
+ 'postId' => $post->ID,
4409
  'name' => $post->post_title,
4410
  'image' => $image,
4411
+ 'kind' => 'template',
4412
  'type' => 'user',
4413
+ 'content' => FLBuilderModel::get_user_template_type( $post->ID ),
4414
+ 'isGlobal' => FLBuilderModel::is_post_global_node_template( $post->ID ),
4415
+ 'link' => add_query_arg( 'fl_builder', '', get_permalink( $post->ID ) ),
4416
+ 'category' => array(),
4417
  );
4418
  }
4419
 
4420
  // Loop through templates and build the categorized array.
4421
+ foreach ( $templates as $i => $template ) {
4422
 
4423
+ $cats = wp_get_post_terms( $template['postId'], 'fl-builder-template-category' );
4424
 
4425
  if ( 0 === count( $cats ) || is_wp_error( $cats ) ) {
4426
+ $template['category'] = array(
4427
+ 'uncategorized' => __( 'Uncategorized', 'fl-builder' ),
4428
+ );
4429
  $categorized['uncategorized']['templates'][] = $template;
4430
  } else {
4431
 
4432
  foreach ( $cats as $cat ) {
4433
+ $template['category'][ $cat->slug ] = $cat->name;
4434
+ }
4435
 
4436
+ foreach ( $cats as $cat ) {
4437
  if ( ! isset( $categorized[ $cat->slug ] ) ) {
4438
  $categorized[ $cat->slug ] = array(
4439
  'name' => $cat->name,
4440
  'templates' => array(),
4441
  );
4442
  }
 
4443
  $categorized[ $cat->slug ]['templates'][] = $template;
4444
  }
4445
  }
4446
+
4447
+ $templates[ $i ] = $template;
4448
  }
4449
 
4450
  // Unset the uncategorized cat if no templates.
4508
  * @since 1.1.3
4509
  * @param int|object $template The post ID of the template to apply or a template data object.
4510
  * @param bool $append Whether to append the new template or replacing the existing layout.
4511
+ * @return array
4512
  */
4513
  static public function apply_user_template( $template = null, $append = false ) {
4514
  if ( $template ) {
4561
  // Delete old asset cache.
4562
  self::delete_asset_cache();
4563
 
 
 
 
4564
  }// End if().
4565
  }// End if().
4566
+
4567
+ // Return the layout.
4568
+ return array(
4569
+ 'layout_css' => isset( $settings ) ? $settings->css : null,
4570
+ 'layout' => FLBuilderAJAXLayout::render(),
4571
+ 'config' => FLBuilderUISettingsForms::get_node_js_config(),
4572
+ );
4573
  }
4574
 
4575
  /**
4675
  // For logged out users
4676
  if ( 'logged_out' == $node->settings->visibility_display && ! is_user_logged_in() ) {
4677
  $is_visible = true;
4678
+ } elseif ( 'logged_in' == $node->settings->visibility_display && is_user_logged_in() ) {
 
4679
  $is_visible = true;
4680
 
4681
  // User capability setting
4686
  $is_visible = false;
4687
  }
4688
  }
4689
+ } // End if().
4690
  elseif ( 0 == $node->settings->visibility_display ) {
4691
  $is_visible = false;
4692
  } else {
4898
  unset( $nodes[ $node_id ]->template_root_node );
4899
  }
4900
  }
4901
+ } else {
 
4902
 
4903
  foreach ( $nodes as $node_id => $node ) {
4904
 
4947
  'name' => $settings['name'],
4948
  'type' => $root_node->type,
4949
  'layout' => $settings['global'] ? FLBuilderAJAXLayout::render( $root_node->node, $template_node_id ) : null,
4950
+ 'config' => $settings['global'] ? FLBuilderUISettingsForms::get_node_js_config() : null,
4951
+ 'postID' => $post_id,
4952
  );
4953
  }
4954
 
5090
  // Remove template info from the layout data.
5091
  foreach ( $layout_data as $node_id => $node ) {
5092
  unset( $layout_data[ $node_id ]->template_id );
5093
+ unset( $layout_data[ $node_id ]->template_node_id );
5094
  unset( $layout_data[ $node_id ]->template_root_node );
5095
  }
5096
 
5184
  * @return void
5185
  */
5186
  static public function apply_node_template( $template_id = null, $parent_id = null, $position = 0, $template = null ) {
5187
+ $parent = ( 0 == $parent_id ) ? null : self::get_node( $parent_id );
5188
+ $template_post_id = self::get_node_template_post_id( $template_id );
5189
 
5190
  // Allow extensions to hook into applying a node template.
5191
  $override = apply_filters( 'fl_builder_override_apply_node_template', false, array(
5207
  $template_settings = $template->settings;
5208
  $type = $template->type;
5209
  $global = $template->global;
5210
+ } else {
 
5211
  $template_data = self::get_layout_data( 'published', $template_post_id );
5212
  $template_settings = self::get_layout_settings( 'published', $template_post_id );
5213
  $type = self::get_user_template_type( $template_post_id );
5220
  // Get the root node from the template data.
5221
  $root_node = self::get_node_template_root( $type, $template_data );
5222
 
5223
+ // Handle module templates.
5224
+ if ( 'module' == $root_node->type ) {
5225
+
5226
+ // Add a new parent for module node templates if needed.
5227
+ if ( ! $parent || 'row' == $parent->type || 'column-group' == $parent->type ) {
5228
+ $parent_id = self::add_module_parent( $parent_id, $position );
5229
+ $parent = self::get_node( $parent_id );
5230
+ $position = null;
5231
+ }
5232
+
5233
+ // Set the module's template data if the parent is a global node.
5234
+ if ( self::is_node_global( $parent ) ) {
5235
+ $template_data[ $root_node->node ]->template_id = $parent->template_id;
5236
+ $template_data[ $root_node->node ]->template_node_id = $root_node->node;
5237
+ unset( $template_data[ $root_node->node ]->template_root_node );
5238
+ $global = true;
5239
+ }
5240
  }
5241
 
5242
  // Update the root node's parent.
5249
  // Only merge the root node for global templates.
5250
  if ( $global ) {
5251
  $layout_data[ $root_node->node ] = $template_data[ $root_node->node ];
5252
+ } else {
 
5253
 
5254
  // Merge template data.
5255
  foreach ( $template_data as $node_id => $node ) {
5256
  unset( $template_data[ $node_id ]->template_id );
5257
+ unset( $template_data[ $node_id ]->template_node_id );
5258
  unset( $template_data[ $node_id ]->template_root_node );
5259
  }
5260
 
5288
  * Registers a template data file with the builder.
5289
  *
5290
  * @since 1.8
5291
+ * @param string|array $path The directory path to the template data file.
5292
+ * @param array $meta The collection information for this template file.
5293
  * @return void
5294
  */
5295
+ static public function register_templates( $path = false, $args = array() ) {
5296
+ // Check if the file exists if path is a string.
5297
+ if ( is_string( $path ) && ! file_exists( $path ) ) {
5298
+ return;
5299
  }
5300
+
5301
+ // Make sure one file exists if path is an array.
5302
+ if ( is_array( $path ) ) {
5303
+
5304
+ $exists = false;
5305
+
5306
+ foreach ( $path as $file ) {
5307
+ if ( file_exists( $file ) ) {
5308
+ $exists = true;
5309
+ }
5310
+ }
5311
+
5312
+ if ( ! $exists ) {
5313
+ return;
5314
+ }
5315
+ }
5316
+
5317
+ // Store the template data.
5318
+ self::$templates[] = array(
5319
+ 'group' => isset( $args['group'] ) ? $args['group'] : false,
5320
+ 'path' => is_string( $path ) ? array( $path ) : $path,
5321
+ );
5322
  }
5323
 
5324
  /**
5329
  */
5330
  static private function register_core_templates() {
5331
  $templates = glob( FL_BUILDER_DIR . 'data/*' );
5332
+ $paths = array();
5333
 
5334
  // glob() will return false on error so cast as an array() just in case.
5335
  foreach ( (array) $templates as $template ) {
5338
  continue;
5339
  }
5340
 
5341
+ $paths[] = $template;
5342
  }
5343
+
5344
+ self::register_templates( $paths );
5345
  }
5346
 
5347
  /**
5365
 
5366
  // Return if we have an override from the filter.
5367
  if ( $override ) {
5368
+ return $override;
5369
  }
5370
 
5371
  // Apply a core template.
5372
+ return self::apply_core_template( $index, $append, $type );
5373
  }
5374
 
5375
  /**
5379
  * @param int $index The index of the template to apply.
5380
  * @param bool $append Whether to append the new template or replacing the existing layout.
5381
  * @param string $type The type of template to apply.
5382
+ * @return array
5383
  */
5384
  static public function apply_core_template( $index = 0, $append = false, $type = 'layout' ) {
5385
  $template = self::get_template( $index, $type );
5425
 
5426
  // Delete old asset cache.
5427
  self::delete_asset_cache();
5428
+
5429
+ // Return the layout.
5430
+ return array(
5431
+ 'layout' => FLBuilderAJAXLayout::render(),
5432
+ 'config' => FLBuilderUISettingsForms::get_node_js_config(),
5433
+ );
5434
  }
5435
 
5436
  /**
5466
 
5467
  self::$template_data = array();
5468
 
5469
+ foreach ( self::$templates as $args ) {
5470
 
5471
+ foreach ( $args['path'] as $path ) {
 
 
 
 
 
 
 
 
 
 
 
 
5472
 
5473
+ // Make sure the template file exists.
5474
+ if ( ! file_exists( $path ) ) {
5475
+ continue;
5476
+ }
5477
 
5478
+ // Get the unserialized template data.
5479
+ if ( stristr( $path, '.php' ) ) {
5480
+ ob_start();
5481
+ include $path;
5482
+ $unserialized = unserialize( ob_get_clean() );
5483
+ } else {
5484
+ $unserialized = fl_maybe_fix_unserialize( file_get_contents( $path ) );
5485
+ }
5486
 
5487
+ // Make sure we have an unserialized array.
5488
+ if ( ! is_array( $unserialized ) ) {
5489
+ continue;
5490
  }
5491
 
5492
+ // Group and cache the template data.
5493
+ foreach ( $unserialized as $template_type => $template_data ) {
5494
+
5495
+ if ( ! isset( self::$template_data[ $template_type ] ) ) {
5496
+ self::$template_data[ $template_type ] = array();
5497
  }
 
5498
 
5499
+ foreach ( $template_data as $key => $template ) {
5500
+
5501
+ // Add the main group to each template.
5502
+ $template_data[ $key ]->group = $args['group'];
5503
+
5504
+ // Reserialize the node data as it's expensive to store in memory.
5505
+ if ( isset( $template->nodes ) ) {
5506
+ $template_data[ $key ]->nodes = serialize( $template_data[ $key ]->nodes );
5507
+ }
5508
+ }
5509
+
5510
+ self::$template_data[ $template_type ] = array_merge( self::$template_data[ $template_type ], $template_data );
5511
+ }
5512
+ }// End foreach().
5513
  }// End foreach().
5514
  }// End if().
5515
 
5546
  'landing' => __( 'Landing Pages', 'fl-builder' ),
5547
  'company' => __( 'Content Pages', 'fl-builder' ),
5548
  );
5549
+ $groups = array();
5550
 
5551
  // Build the the templates array.
5552
  foreach ( self::get_templates( $type ) as $key => $template ) {
5553
 
5554
+ if ( 'module' == $type && isset( $template->nodes ) ) {
5555
 
5556
  $nodes = maybe_unserialize( $template->nodes );
5557
  $node = array_shift( $nodes );
5558
 
5559
+ if ( ! isset( $node->settings ) || ! isset( self::$modules[ $node->settings->type ] ) ) {
5560
  continue;
5561
  }
5562
  }
5567
  $image = FL_BUILDER_URL . 'img/templates/' . ( empty( $template->image ) ? 'blank.jpg' : $template->image );
5568
  }
5569
 
5570
+ $templates[] = apply_filters( 'fl_builder_template_details', array(
5571
  'id' => $key,
5572
  'name' => $template->name,
5573
  'image' => $image,
5574
+ 'author' => '',
5575
  'category' => isset( $template->category ) ? $template->category : $template->categories,
5576
+ 'tags' => array(),
5577
+ 'group' => $template->group,
5578
  'type' => 'core',
5579
+ 'kind' => 'template',
5580
+ 'content' => ! in_array( $type, array( 'row', 'module' ) ) ? 'layout' : $type,
5581
+ ), $template );
 
 
5582
  }
5583
 
5584
+ // Build the categorized templates array and groups array.
5585
+ foreach ( $templates as $i => $template ) {
5586
 
5587
+ // Make sure we have a template category and it's an array.
5588
  if ( ! isset( $template['category'] ) ) {
5589
+ $template['category'] = array(
5590
+ 'uncategorized' => __( 'Uncategorized', 'fl-builder' ),
5591
+ );
5592
+ } elseif ( is_string( $template['category'] ) ) {
5593
+ $template['category'] = array(
5594
+ $template['category'] => $core_categories[ $template['category'] ],
5595
+ );
5596
  }
5597
 
5598
+ // Get template group data.
5599
+ $template_groups = array();
5600
 
5601
+ if ( ! $template['group'] ) {
5602
+ // If we don't have a group, use categories as groups.
5603
+ foreach ( $template['category'] as $cat_name ) {
5604
+ $template_groups[] = $cat_name;
5605
+ }
5606
+ // Clear the categories since we're using groups instead.
5607
+ $template['category'] = array(
5608
+ 'none' => '',
5609
+ );
5610
 
5611
+ } elseif ( is_string( $template['group'] ) ) {
5612
+ // Make sure template group is an array.
5613
+ $template_groups = array( $template['group'] );
5614
+ } else {
5615
+ $template_groups = $template['group'];
5616
+ }
5617
+
5618
+ // Add to the groups array.
5619
+ $template['group'] = array();
5620
+
5621
+ foreach ( $template_groups as $group_name ) {
5622
+ $group_key = sanitize_key( $group_name );
5623
+ if ( ! isset( $groups[ $group_key ] ) ) {
5624
+ $groups[ $group_key ] = array(
5625
+ 'name' => $group_name,
5626
+ 'categories' => array(),
5627
+ );
5628
+ }
5629
+ foreach ( $template['category'] as $cat_key => $cat_name ) {
5630
+ if ( ! isset( $groups[ $group_key ]['categories'][ $cat_key ] ) ) {
5631
+ $groups[ $group_key ]['categories'][ $cat_key ] = array(
5632
+ 'name' => $cat_name,
5633
  );
5634
  }
 
 
5635
  }
5636
+ $template['group'][] = $group_key;
5637
+ }
5638
+
5639
+ // Add to the categorized array.
5640
+ foreach ( $template['category'] as $cat_key => $cat_name ) {
5641
 
5642
+ // Add the category if we don't have it yet.
5643
+ if ( ! isset( $categorized[ $cat_key ] ) ) {
5644
+ $categorized[ $cat_key ] = array(
5645
+ 'name' => $cat_name,
5646
  'templates' => array(),
5647
  );
5648
  }
5649
 
5650
+ $categorized[ $cat_key ]['templates'][] = $template;
5651
  }
5652
+
5653
+ $templates[ $i ] = $template;
5654
+ }// End foreach().
5655
 
5656
  // Return both the templates and categorized templates array.
5657
  return apply_filters( 'fl_builder_template_selector_data', array(
5658
  'templates' => $templates,
5659
  'categorized' => $categorized,
5660
+ 'groups' => $groups,
5661
  ), $type );
5662
  }
5663
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5664
  /**
5665
  * Returns data for row templates to be shown in the UI panel.
5666
  *
5778
  'enabled' => true,
5779
  'tour' => true,
5780
  'video' => true,
5781
+ 'video_embed' => '<iframe src="https://player.vimeo.com/video/240550556?autoplay=1" width="420" height="315" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
5782
  'knowledge_base' => true,
5783
  'knowledge_base_url' => self::get_store_url( 'knowledge-base', array(
5784
  'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ),
5810
  return self::get_help_button_defaults();
5811
  }
5812
 
5813
+ /**
5814
+ * Get row resize settings
5815
+ *
5816
+ * @since 2.0
5817
+ * @return array
5818
+ */
5819
+ static public function get_row_resize_settings() {
5820
+ $defaults = array(
5821
+ 'userCanResizeRows' => true,
5822
+ 'minAllowedWidth' => 300,
5823
+ 'maxAllowedWidth' => false,
5824
+ );
5825
+
5826
+ $settings = apply_filters( 'fl_row_resize_settings', $defaults );
5827
+
5828
+ // Ensure everything is still defined after filter
5829
+ $settings = wp_parse_args( $settings, $defaults );
5830
+
5831
+ // Min width can't go lower than 100px
5832
+ if ( false == $settings['minAllowedWidth'] || $settings['minAllowedWidth'] < 100 ) {
5833
+ $settings['minAllowedWidth'] = 100;
5834
+ }
5835
+
5836
+ // Convert string numbers to int
5837
+ if ( is_string( $settings['minAllowedWidth'] ) ) {
5838
+ $settings['minAllowedWidth'] = intval( $settings['minAllowedWidth'] );
5839
+ }
5840
+ if ( is_string( $settings['maxAllowedWidth'] ) ) {
5841
+ $settings['maxAllowedWidth'] = intval( $settings['maxAllowedWidth'] );
5842
+ }
5843
+
5844
+ // Check user capability
5845
+ if ( ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' ) ) {
5846
+ $settings['userCanResizeRows'] = false;
5847
+ }
5848
+
5849
+ return $settings;
5850
+ }
5851
+
5852
+ /**
5853
+ * Filter the row settings to remove max width field
5854
+ *
5855
+ * @since 2.0
5856
+ * @return array
5857
+ */
5858
+ static public function filter_row_settings_for_resize( $form, $id ) {
5859
+
5860
+ if ( 'row' == $id && ! FLBuilderModel::user_can_resize_rows() ) {
5861
+ unset( $form['tabs']['style']['sections']['general']['fields']['max_content_width'] );
5862
+ }
5863
+ return $form;
5864
+ }
5865
+
5866
+ /**
5867
+ * Check if user has the ability to resize rows
5868
+ *
5869
+ * @since 2.0
5870
+ * @return bool
5871
+ */
5872
+ static public function user_can_resize_rows() {
5873
+ $args = self::get_row_resize_settings();
5874
+ return $args['userCanResizeRows'];
5875
+ }
5876
+
5877
  /**
5878
  * Returns an array of account data for all integrated services.
5879
  *
5937
  * @return mixed
5938
  */
5939
  static public function get_admin_settings_option( $key, $network_override = true ) {
 
5940
  if ( is_network_admin() ) {
5941
+ // Get the site-wide option if we're in the network admin.
5942
  $value = get_site_option( $key );
5943
+ } elseif ( ! $network_override && class_exists( 'FLBuilderMultisiteSettings' ) ) {
5944
+ // Get the site-wide option if there's no network override.
5945
  $value = get_site_option( $key );
5946
+ } elseif ( class_exists( 'FLBuilderMultisiteSettings' ) ) {
5947
+ // Network overrides are allowed. Return the subsite option if it exists.
5948
  $value = get_option( $key );
5949
  $value = false === $value ? get_site_option( $key ) : $value;
5950
+ } else {
5951
+ // This must be a single site install. Get the single site option.
5952
  $value = get_option( $key );
5953
  }
5954
 
5965
  * @return mixed
5966
  */
5967
  static public function update_admin_settings_option( $key, $value, $network_override = true ) {
 
5968
  if ( is_network_admin() ) {
5969
+ // Update the site-wide option since we're in the network admin.
5970
  update_site_option( $key, $value );
5971
+ } elseif ( $network_override && FLBuilderAdminSettings::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
5972
+ // Delete the option if we don't have a network override.
5973
  delete_option( $key );
5974
+ } else {
5975
+ // Update the option for single install or subsite.
5976
  update_option( $key, $value );
5977
  }
5978
  }
6135
 
6136
  return FLBuilderUserAccess::current_user_can( 'builder_admin' );
6137
  }
6138
+
6139
+ /**
6140
+ * @since 1.0
6141
+ * @deprecated 2.0
6142
+ */
6143
+ static public function get_module_category_slug( $name ) {
6144
+ _deprecated_function( __METHOD__, '2.0' );
6145
+
6146
+ return sanitize_html_class( $name );
6147
+ }
6148
+
6149
+ /**
6150
+ * @since 1.8
6151
+ * @deprecated 2.0
6152
+ */
6153
+ static public function get_template_selector_filter_data() {
6154
+ _deprecated_function( __METHOD__, '2.0' );
6155
+
6156
+ return array();
6157
+ }
6158
  }
6159
 
6160
  FLBuilderModel::init();
classes/class-fl-builder-module.php CHANGED
@@ -138,6 +138,13 @@ class FLBuilderModule {
138
  */
139
  public $js = array();
140
 
 
 
 
 
 
 
 
141
  /**
142
  * Module constructor.
143
  *
@@ -152,15 +159,22 @@ class FLBuilderModule {
152
  $this->editor_export = isset( $params['editor_export'] ) ? $params['editor_export'] : true;
153
  $this->partial_refresh = isset( $params['partial_refresh'] ) ? $params['partial_refresh'] : false;
154
 
 
 
 
155
  $details = apply_filters( 'fl_builder_module_details', array(
156
  'name' => $params['name'],
157
  'description' => $params['description'],
158
- 'category' => $params['category'],
 
 
159
  ), $this->slug );
160
 
161
  $this->name = $details['name'];
162
  $this->description = $details['description'];
163
  $this->category = $details['category'];
 
 
164
 
165
  // We need to normalize the paths here since path comparisons
166
  // break on Windows because they use backslashes.
@@ -296,4 +310,71 @@ class FLBuilderModule {
296
  public function remove() {
297
 
298
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  }
138
  */
139
  public $js = array();
140
 
141
+ /**
142
+ * The class of the font icon for this module.
143
+ *
144
+ * @since 2.0
145
+ */
146
+ public $icon = '';
147
+
148
  /**
149
  * Module constructor.
150
  *
159
  $this->editor_export = isset( $params['editor_export'] ) ? $params['editor_export'] : true;
160
  $this->partial_refresh = isset( $params['partial_refresh'] ) ? $params['partial_refresh'] : false;
161
 
162
+ // Icon requires dir be defined before calling get_icon()
163
+ $this->icon = isset( $params['icon'] ) ? $this->get_icon( $params['icon'] ) : $this->get_icon();
164
+
165
  $details = apply_filters( 'fl_builder_module_details', array(
166
  'name' => $params['name'],
167
  'description' => $params['description'],
168
+ 'category' => $this->normalize_category_name( $params['category'] ),
169
+ 'group' => isset( $params['group'] ) ? $params['group'] : false,
170
+ 'icon' => $this->icon,
171
  ), $this->slug );
172
 
173
  $this->name = $details['name'];
174
  $this->description = $details['description'];
175
  $this->category = $details['category'];
176
+ $this->group = $details['group'];
177
+ $this->icon = $details['icon'];
178
 
179
  // We need to normalize the paths here since path comparisons
180
  // break on Windows because they use backslashes.
310
  public function remove() {
311
 
312
  }
313
+
314
+ /**
315
+ * Get svg icon string
316
+ *
317
+ * @since 2.0
318
+ * @return String
319
+ */
320
+ public function get_icon( $icon = '' ) {
321
+
322
+ // check if $icon is referencing an included icon.
323
+ if ( '' != $icon && file_exists( FL_BUILDER_DIR . 'img/svg/' . $icon ) ) {
324
+ $path = FL_BUILDER_DIR . 'img/svg/' . $icon;
325
+
326
+ // check if module directory includes an icon.svg file
327
+ } elseif ( file_exists( $this->dir . 'icon.svg' ) ) {
328
+ $path = $this->dir . 'icon.svg';
329
+
330
+ // default to included icon
331
+ } else {
332
+ $path = FL_BUILDER_DIR . 'img/svg/insert.svg';
333
+ }
334
+ if ( file_exists( $path ) ) {
335
+ return file_get_contents( $path );
336
+ } else {
337
+ return '';
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Normalizes category names to support 2.0 since the default
343
+ * category names changed.
344
+ *
345
+ * @since 2.0
346
+ * @access private
347
+ * @param string $cat
348
+ * @return string
349
+ */
350
+ private function normalize_category_name( $cat ) {
351
+ if ( __( 'Basic Modules', 'fl-builder' ) === $cat ) {
352
+ $cat = __( 'Basic', 'fl-builder' );
353
+ } elseif ( __( 'Advanced Modules', 'fl-builder' ) === $cat ) {
354
+ $cat = __( 'Advanced', 'fl-builder' );
355
+ }
356
+ return $cat;
357
+ }
358
+
359
+ /**
360
+ * Get the default svg icon
361
+ *
362
+ * @since 2.0
363
+ * @return String
364
+ */
365
+ static public function get_default_icon() {
366
+ $path = FL_BUILDER_DIR . 'img/svg/insert.svg';
367
+ return file_get_contents( $path );
368
+ }
369
+
370
+ /**
371
+ * Get the widget icon
372
+ *
373
+ * @since 2.0
374
+ * @return String
375
+ */
376
+ static public function get_widget_icon() {
377
+ $path = FL_BUILDER_DIR . 'img/svg/wordpress-alt.svg';
378
+ return file_get_contents( $path );
379
+ }
380
  }
classes/class-fl-builder-revisions.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Handles the revisions UI for the builder.
5
+ *
6
+ * @since 2.0
7
+ */
8
+ final class FLBuilderRevisions {
9
+
10
+ /**
11
+ * Initialize hooks.
12
+ *
13
+ * @since 2.0
14
+ * @return void
15
+ */
16
+ static public function init() {
17
+ add_filter( 'fl_builder_ui_js_config', __CLASS__ . '::ui_js_config' );
18
+ add_filter( 'fl_builder_main_menu', __CLASS__ . '::main_menu_config' );
19
+ }
20
+
21
+ /**
22
+ * Adds revision data to the UI JS config.
23
+ *
24
+ * @since 2.0
25
+ * @param array $config
26
+ * @return array
27
+ */
28
+ static public function ui_js_config( $config ) {
29
+ $config['revisions'] = self::get_config( $config['postId'] );
30
+
31
+ return $config;
32
+ }
33
+
34
+ /**
35
+ * Gets the revision config for a post.
36
+ *
37
+ * @since 2.0
38
+ * @param int $post_id
39
+ * @return array
40
+ */
41
+ static public function get_config( $post_id ) {
42
+ $revisions = wp_get_post_revisions( $post_id );
43
+ $current_time = current_time( 'timestamp' );
44
+ $config = array(
45
+ 'posts' => array(),
46
+ 'authors' => array(),
47
+ );
48
+
49
+ if ( count( $revisions ) > 1 ) {
50
+
51
+ foreach ( $revisions as $revision ) {
52
+
53
+ if ( ! current_user_can( 'read_post', $revision->ID ) ) {
54
+ continue;
55
+ }
56
+ if ( wp_is_post_autosave( $revision ) ) {
57
+ continue;
58
+ }
59
+
60
+ $timestamp = strtotime( $revision->post_date );
61
+
62
+ $config['posts'][] = array(
63
+ 'id' => $revision->ID,
64
+ 'author' => $revision->post_author,
65
+ 'date' => array(
66
+ 'published' => date( 'F j', $timestamp ),
67
+ 'diff' => human_time_diff( $timestamp, $current_time ),
68
+ ),
69
+ );
70
+
71
+ if ( ! isset( $config['authors'][ $revision->post_author ] ) ) {
72
+ $config['authors'][ $revision->post_author ] = array(
73
+ 'name' => get_the_author_meta( 'display_name', $revision->post_author ),
74
+ 'avatar' => get_avatar( $revision->post_author, 30 ),
75
+ );
76
+ }
77
+ }
78
+ }
79
+
80
+ return $config;
81
+ }
82
+
83
+ /**
84
+ * Adds revision data to the main menu config.
85
+ *
86
+ * @since 2.0
87
+ * @param array $config
88
+ * @return array
89
+ */
90
+ static public function main_menu_config( $config ) {
91
+ $config['main']['items'][35] = array(
92
+ 'label' => __( 'Revisions', 'fl-builder' ),
93
+ 'type' => 'view',
94
+ 'view' => 'revisions',
95
+ );
96
+
97
+ $config['revisions'] = array(
98
+ 'name' => __( 'Revisions', 'fl-builder' ),
99
+ 'isShowing' => false,
100
+ 'isRootView' => false,
101
+ 'items' => array(),
102
+ );
103
+
104
+ return $config;
105
+ }
106
+
107
+ /**
108
+ * Renders the layout for a revision preview in the builder.
109
+ *
110
+ * @since 2.0
111
+ * @param int $revision_id
112
+ * @return array
113
+ */
114
+ static public function render_preview( $revision_id ) {
115
+ FLBuilderModel::set_post_id( $revision_id );
116
+
117
+ return FLBuilderAJAXLayout::render();
118
+ }
119
+
120
+ /**
121
+ * Restores the current layout to a revision with the specified ID.
122
+ *
123
+ * @since 2.0
124
+ * @param int $revision_id
125
+ * @return array
126
+ */
127
+ static public function restore( $revision_id ) {
128
+ $data = FLBuilderModel::get_layout_data( 'published', $revision_id );
129
+
130
+ FLBuilderModel::update_layout_data( $data );
131
+
132
+ return array(
133
+ 'layout' => FLBuilderAJAXLayout::render(),
134
+ 'config' => FLBuilderUISettingsForms::get_node_js_config(),
135
+ );
136
+ }
137
+ }
138
+
139
+ FLBuilderRevisions::init();
classes/class-fl-builder-service-activecampaign.php CHANGED
@@ -316,8 +316,12 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
316
  $data['form'] = $settings->form_id;
317
  } else {
318
  $data['p'] = array( $settings->list_id );
319
- $data['status'] = 1;
320
- $data['instantresponders'] = array( 1 );
 
 
 
 
321
  }
322
 
323
  // Name
316
  $data['form'] = $settings->form_id;
317
  } else {
318
  $data['p'] = array( $settings->list_id );
319
+ $data['status'] = array(
320
+ $settings->list_id => 1,
321
+ );
322
+ $data['instantresponders'] = array(
323
+ $settings->list_id => 1,
324
+ );
325
  }
326
 
327
  // Name
classes/class-fl-builder-services.php CHANGED
@@ -152,11 +152,21 @@ final class FLBuilderServices {
152
  }
153
  }
154
 
 
155
  foreach ( $services as $key => $service ) {
156
  if ( isset( $service['namespace'] ) && ! version_compare( phpversion(), '5.3', '>=' ) ) {
157
  unset( $services[ $key ] );
158
  }
159
  }
 
 
 
 
 
 
 
 
 
160
  return $services;
161
  }
162
 
152
  }
153
  }
154
 
155
+ // Remove services that use namespaces if we're not on a supported PHP version.
156
  foreach ( $services as $key => $service ) {
157
  if ( isset( $service['namespace'] ) && ! version_compare( phpversion(), '5.3', '>=' ) ) {
158
  unset( $services[ $key ] );
159
  }
160
  }
161
+
162
+ // Remove services that don't meet the requirements.
163
+ if ( isset( $services['mailpoet'] )
164
+ && ! class_exists( 'WYSIJA' )
165
+ && ( ! defined( 'MAILPOET_INITIALIZED' ) || ( defined( 'MAILPOET_INITIALIZED' ) && false === MAILPOET_INITIALIZED ) )
166
+ ) {
167
+ unset( $services['mailpoet'] );
168
+ }
169
+
170
  return $services;
171
  }
172
 
classes/class-fl-builder-ui-content-panel.php ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Handles logic for the builder's content panel UI.
5
+ *
6
+ * @since 2.0
7
+ */
8
+ class FLBuilderUIContentPanel {
9
+
10
+ /**
11
+ * Get data structure required by the content panel.
12
+ *
13
+ * @since 2.0
14
+ * @access public
15
+ * @return array
16
+ */
17
+ public static function get_panel_data() {
18
+
19
+ // Don't load the panel for module templates.
20
+ if ( FLBuilderModel::is_post_user_template( 'module' ) ) {
21
+ return array();
22
+ }
23
+
24
+ $data = array(
25
+ 'tabs' => array(),
26
+ );
27
+
28
+ $modules_data = self::get_modules_tab_data();
29
+ if ( $modules_data['should_display'] ) {
30
+ $modules_tab = array(
31
+ 'handle' => 'modules',
32
+ 'name' => __( 'Modules', 'fl-builder' ),
33
+ 'views' => $modules_data['views'],
34
+ 'isSearchEnabled' => true,
35
+ );
36
+ $data['tabs']['modules'] = $modules_tab;
37
+ }
38
+
39
+ $rows_data = self::get_rows_tab_data();
40
+ if ( $rows_data['should_display'] ) {
41
+ $rows_tab = array(
42
+ 'handle' => 'rows',
43
+ 'name' => __( 'Rows', 'fl-builder' ),
44
+ 'views' => $rows_data['views'],
45
+ );
46
+ $data['tabs']['rows'] = $rows_tab;
47
+ }
48
+
49
+ $templates_data = self::get_templates_tab_data();
50
+ if ( $templates_data['should_display'] ) {
51
+ $templates_tab = array(
52
+ 'handle' => 'templates',
53
+ 'name' => __( 'Templates', 'fl-builder' ),
54
+ 'views' => $templates_data['views'],
55
+ );
56
+ $data['tabs']['templates'] = $templates_tab;
57
+ }
58
+
59
+ /**
60
+ * Filter the tabs/views structure
61
+ *
62
+ * @since 2.0
63
+ * @param Array $data the initial tab data
64
+ */
65
+ return apply_filters( 'fl_builder_content_panel_data', $data );
66
+ }
67
+
68
+ /**
69
+ * Get module views for panel.
70
+ *
71
+ * @since 2.0
72
+ * @access private
73
+ * @return array
74
+ */
75
+ private static function get_modules_tab_data() {
76
+
77
+ $data = array(
78
+ 'should_display' => ! FLBuilderModel::is_post_user_template( 'module' ),
79
+ 'views' => array(),
80
+ );
81
+
82
+ // Standard Modules View
83
+ $data['views'][] = array(
84
+ 'handle' => 'standard',
85
+ 'name' => __( 'Standard Modules', 'fl-builder' ),
86
+ 'query' => array(
87
+ 'kind' => 'module',
88
+ 'categorized' => true,
89
+ 'group' => 'standard',
90
+ ),
91
+ 'orderedSectionNames' => array_keys( FLBuilderModel::get_module_categories() ),
92
+ );
93
+
94
+ // Third Party Module Groups
95
+ $groups = FLBuilderModel::get_module_groups();
96
+ if ( ! empty( $groups ) ) {
97
+
98
+ $data['views'][] = array(
99
+ 'type' => 'separator',
100
+ );
101
+
102
+ foreach ( $groups as $slug => $name ) {
103
+ $data['views'][] = array(
104
+ 'handle' => $slug,
105
+ 'name' => $name,
106
+ 'query' => array(
107
+ 'kind' => array( 'module', 'template' ),
108
+ 'content' => 'module',
109
+ 'type' => 'core',
110
+ 'categorized' => true,
111
+ 'group' => $slug,
112
+ ),
113
+ 'templateName' => 'fl-content-panel-modules-view',
114
+ );
115
+ }
116
+ }
117
+
118
+ return $data;
119
+ }
120
+
121
+ /**
122
+ * Get data for the rows tab.
123
+ *
124
+ * @since 2.0
125
+ * @access private
126
+ * @return array
127
+ */
128
+ private static function get_rows_tab_data() {
129
+
130
+ $data = array(
131
+ 'should_display' => true, /* rows tab shows even if row template */
132
+ 'views' => array(),
133
+ );
134
+
135
+ // Columns View
136
+ $data['views'][] = array(
137
+ 'handle' => 'columns',
138
+ 'name' => __( 'Columns', 'fl-builder' ),
139
+ 'query' => array(
140
+ 'kind' => 'colGroup',
141
+ ),
142
+ 'templateName' => 'fl-content-panel-col-groups-view',
143
+ );
144
+
145
+ // Row Templates View
146
+ $templates = FLBuilderModel::get_row_templates_data();
147
+ $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
148
+
149
+ if ( ! $is_row_template && isset( $templates['groups'] ) && ! empty( $templates['groups'] ) ) {
150
+
151
+ $data['views'][] = array(
152
+ 'type' => 'separator',
153
+ );
154
+
155
+ foreach ( $templates['groups'] as $slug => $group ) {
156
+
157
+ $data['views'][] = array(
158
+ 'handle' => $slug,
159
+ 'name' => $group['name'],
160
+ 'query' => array(
161
+ 'kind' => 'template',
162
+ 'type' => 'core',
163
+ 'group' => $slug,
164
+ 'content' => 'row',
165
+ 'categorized' => true,
166
+ ),
167
+ );
168
+
169
+ if ( count( $group['categories'] ) < 2 ) {
170
+ continue;
171
+ }
172
+
173
+ foreach ( $group['categories'] as $cat_slug => $category ) {
174
+ $data['views'][] = array(
175
+ 'handle' => $cat_slug,
176
+ 'name' => $category['name'],
177
+ 'isSubItem' => true,
178
+ 'query' => array(
179
+ 'kind' => 'template',
180
+ 'type' => 'core',
181
+ 'content' => 'row',
182
+ 'group' => $slug,
183
+ 'category' => $cat_slug,
184
+ 'categorized' => true,
185
+ ),
186
+ );
187
+ }
188
+ }
189
+ }// End if().
190
+
191
+ return $data;
192
+ }
193
+
194
+ /**
195
+ * Get data for the templates tab.
196
+ *
197
+ * @since 2.0
198
+ * @access private
199
+ * @return array
200
+ */
201
+ private static function get_templates_tab_data() {
202
+ $enabled = FLBuilderModel::get_enabled_templates();
203
+ $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
204
+ $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
205
+ $data = array(
206
+ 'should_display' => ( ! $is_module_template && ! $is_row_template && 'disabled' !== $enabled ),
207
+ 'views' => array(),
208
+ );
209
+
210
+ $templates = FLBuilderModel::get_template_selector_data();
211
+
212
+ if ( ! isset( $templates['groups'] ) || empty( $templates['groups'] ) ) {
213
+
214
+ if ( true === FL_BUILDER_LITE ) {
215
+ $data['views'][] = array(
216
+ 'handle' => 'standard',
217
+ 'name' => __( 'Upgrade', 'fl-builder' ),
218
+ 'templateName' => 'fl-content-lite-templates-upgrade-view',
219
+ );
220
+ }
221
+
222
+ return $data;
223
+ }
224
+
225
+ foreach ( $templates['groups'] as $slug => $group ) {
226
+
227
+ $data['views'][] = array(
228
+ 'handle' => $slug,
229
+ 'name' => $group['name'],
230
+ 'query' => array(
231
+ 'kind' => 'template',
232
+ 'type' => 'core',
233
+ 'content' => 'layout',
234
+ 'group' => $slug,
235
+ 'categorized' => true,
236
+ ),
237
+ );
238
+
239
+ if ( count( $group['categories'] ) < 2 ) {
240
+ continue;
241
+ }
242
+
243
+ foreach ( $group['categories'] as $cat_slug => $category ) {
244
+ $data['views'][] = array(
245
+ 'handle' => $cat_slug,
246
+ 'name' => $category['name'],
247
+ 'isSubItem' => true,
248
+ 'query' => array(
249
+ 'kind' => 'template',
250
+ 'type' => 'core',
251
+ 'content' => 'layout',
252
+ 'group' => $slug,
253
+ 'category' => $cat_slug,
254
+ 'categorized' => true,
255
+ ),
256
+ );
257
+ }
258
+ }
259
+
260
+ return $data;
261
+ }
262
+
263
+ /**
264
+ * Get all the insertable content elements that make up the content library.
265
+ *
266
+ * @since 2.0
267
+ * @access public
268
+ * @return array
269
+ */
270
+ public static function get_content_elements() {
271
+
272
+ $data = array(
273
+
274
+ /* Get all modules */
275
+ 'module' => FLBuilderModel::get_uncategorized_modules(),
276
+
277
+ /* Get all column groups */
278
+ 'colGroup' => FLBuilderModel::get_column_groups(),
279
+
280
+ 'template' => array(),
281
+ );
282
+
283
+ $static_modules = FLBuilderModel::get_module_templates_data();
284
+ $module_templates = $static_modules['templates'];
285
+
286
+ foreach ( $module_templates as $template ) {
287
+ $data['template'][] = $template;
288
+ }
289
+
290
+ $static_rows = FLBuilderModel::get_row_templates_data();
291
+ $row_templates = $static_rows['templates'];
292
+
293
+ foreach ( $row_templates as $template ) {
294
+ $data['template'][] = $template;
295
+ }
296
+
297
+ $static_templates = FLBuilderModel::get_template_selector_data();
298
+ $layout_templates = $static_templates['templates'];
299
+
300
+ foreach ( $layout_templates as $template ) {
301
+ $data['template'][] = $template;
302
+ }
303
+
304
+ /**
305
+ * Filter the available content elements
306
+ *
307
+ * @since 2.0
308
+ * @param Array $data the initial content elements
309
+ */
310
+ return apply_filters( 'fl_builder_content_elements_data', $data );
311
+ }
312
+ }
classes/class-fl-builder-ui-settings-forms.php ADDED
@@ -0,0 +1,737 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Handles logic for UI settings forms.
5
+ *
6
+ * @since 2.0
7
+ */
8
+ class FLBuilderUISettingsForms {
9
+
10
+ /**
11
+ * An array of JS templates for custom form tabs and
12
+ * sections that need to be loaded.
13
+ *
14
+ * @since 2.0
15
+ * @var int $form_templates
16
+ */
17
+ static private $form_templates = array();
18
+
19
+ /**
20
+ * @since 2.0
21
+ * @return void
22
+ */
23
+ static public function init() {
24
+ add_action( 'wp_footer', __CLASS__ . '::init_js_config', 1 );
25
+ add_action( 'wp_footer', __CLASS__ . '::render_js_templates', 11 );
26
+ }
27
+
28
+ /**
29
+ * Initializes the JS config by calling the get method early on
30
+ * wp_footer (before the UI renders). This needs to be done so
31
+ * changes to the builder's form config arrays are made before the
32
+ * JS templates are printed.
33
+ *
34
+ *
35
+ * @since 2.0.1.1
36
+ * @return void
37
+ */
38
+ static public function init_js_config() {
39
+ self::get_js_config();
40
+ }
41
+
42
+ /**
43
+ * Returns _all_ JS config for settings forms.
44
+ *
45
+ * @since 2.0
46
+ * @return array
47
+ */
48
+ static public function get_js_config() {
49
+ return array(
50
+ 'forms' => self::prep_forms_for_js_config( FLBuilderModel::$settings_forms ),
51
+ 'modules' => self::prep_module_forms_for_js_config(),
52
+ 'nodes' => self::prep_node_settings_for_js_config(),
53
+ 'attachments' => self::prep_attachments_for_js_config(),
54
+ 'settings' => array(
55
+ 'global' => FLBuilderModel::get_global_settings(),
56
+ 'layout' => FLBuilderModel::get_layout_settings(),
57
+ ),
58
+ 'defaults' => array(
59
+ 'row' => FLBuilderModel::get_row_defaults(),
60
+ 'column' => FLBuilderModel::get_col_defaults(),
61
+ 'modules' => FLBuilderModel::get_module_defaults(),
62
+ 'forms' => self::prep_form_defaults_for_js_config( FLBuilderModel::$settings_forms ),
63
+ ),
64
+ );
65
+ }
66
+
67
+ /**
68
+ * Returns only the node JS config for settings forms.
69
+ *
70
+ * @since 2.0
71
+ * @return array
72
+ */
73
+ static public function get_node_js_config() {
74
+ return array(
75
+ 'nodes' => self::prep_node_settings_for_js_config(),
76
+ 'attachments' => self::prep_attachments_for_js_config(),
77
+ );
78
+ }
79
+
80
+ /**
81
+ * Prepares form defaults for the JS config.
82
+ *
83
+ * @since 2.0
84
+ * @param array $forms
85
+ * @return array
86
+ */
87
+ static private function prep_form_defaults_for_js_config( $forms ) {
88
+ $defaults = array();
89
+
90
+ foreach ( $forms as $form_key => $form ) {
91
+ if ( isset( $form['tabs'] ) ) {
92
+ $defaults[ $form_key ] = FLBuilderModel::get_settings_form_defaults( $form_key );
93
+ }
94
+ }
95
+
96
+ return $defaults;
97
+ }
98
+
99
+
100
+ /**
101
+ * Prepares forms for the JS config.
102
+ *
103
+ * @since 2.0
104
+ * @param array $forms
105
+ * @return array
106
+ */
107
+ static private function prep_forms_for_js_config( $forms ) {
108
+
109
+ foreach ( $forms as $form_key => &$form ) {
110
+
111
+ if ( ! isset( $form['tabs'] ) ) {
112
+ continue;
113
+ }
114
+
115
+ foreach ( $form['tabs'] as $tab_key => &$tab ) {
116
+
117
+ if ( isset( $tab['template'] ) ) {
118
+ self::$form_templates[ $tab['template']['id'] ] = $tab['template']['file'];
119
+ }
120
+
121
+ if ( ! isset( $tab['sections'] ) ) {
122
+ continue;
123
+ }
124
+
125
+ foreach ( $tab['sections'] as $section_key => &$section ) {
126
+
127
+ if ( isset( $section['file'] ) && FL_BUILDER_DIR . 'includes/service-settings.php' === $section['file'] ) {
128
+ $section['template'] = array(
129
+ 'id' => 'fl-builder-service-settings',
130
+ 'file' => FL_BUILDER_DIR . 'includes/ui-service-settings.php',
131
+ );
132
+ unset( $section['file'] );
133
+ }
134
+
135
+ if ( isset( $section['template'] ) ) {
136
+ self::$form_templates[ $section['template']['id'] ] = $section['template']['file'];
137
+ }
138
+
139
+ if ( ! isset( $section['fields'] ) ) {
140
+ continue;
141
+ }
142
+
143
+ foreach ( $section['fields'] as $field_key => &$field ) {
144
+ self::prep_field_for_js_config( $field );
145
+ }
146
+ }
147
+ }
148
+ }// End foreach().
149
+
150
+ return $forms;
151
+ }
152
+
153
+ /**
154
+ * Prepares a field for the JS config.
155
+ *
156
+ * @since 2.0
157
+ * @param array $field
158
+ * @return void
159
+ */
160
+ static private function prep_field_for_js_config( &$field ) {
161
+
162
+ // Convert class to className for JS compat.
163
+ if ( isset( $field['class'] ) ) {
164
+ $field['className'] = $field['class'];
165
+ }
166
+
167
+ // Select fields
168
+ if ( 'select' === $field['type'] ) {
169
+
170
+ if ( is_string( $field['options'] ) && is_callable( $field['options'] ) ) {
171
+ $field['options'] = call_user_func( $field['options'] );
172
+ } else {
173
+ $field['options'] = (array) $field['options'];
174
+ }
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Gathers and prepares module forms for the JS config.
180
+ *
181
+ * @since 2.0
182
+ * @return array
183
+ */
184
+ static public function prep_module_forms_for_js_config() {
185
+ $module_forms = array();
186
+
187
+ foreach ( FLBuilderModel::$modules as $module ) {
188
+
189
+ $css = '';
190
+ $js = '';
191
+
192
+ if ( file_exists( $module->dir . 'css/settings.css' ) ) {
193
+ $css .= '<link class="fl-builder-settings-css" rel="stylesheet" href="' . $module->url . 'css/settings.css" />';
194
+ }
195
+ if ( file_exists( $module->dir . 'js/settings.js' ) ) {
196
+ $js .= '<script class="fl-builder-settings-js" src="' . $module->url . 'js/settings.js"></script>';
197
+ }
198
+
199
+ $module_forms[ $module->slug ] = array(
200
+ 'title' => $module->name,
201
+ 'tabs' => $module->form,
202
+ 'assets' => array(
203
+ 'css' => $css,
204
+ 'js' => $js,
205
+ ),
206
+ );
207
+ }
208
+
209
+ return self::prep_forms_for_js_config( $module_forms );
210
+ }
211
+
212
+ /**
213
+ * Gathers and prepares node settings for the JS config.
214
+ *
215
+ * @since 2.0
216
+ * @return array
217
+ */
218
+ static public function prep_node_settings_for_js_config() {
219
+ $layout_data = FLBuilderModel::get_layout_data();
220
+ $node_settings = array();
221
+
222
+ foreach ( $layout_data as $node_id => $node ) {
223
+ if ( ! is_object( $node ) || ! isset( $node->settings ) || ! is_object( $node->settings ) ) {
224
+ continue;
225
+ }
226
+ $node_settings[ $node_id ] = $node->settings;
227
+ }
228
+
229
+ return $node_settings;
230
+ }
231
+
232
+ /**
233
+ * Gathers and prepares attachments for the JS config.
234
+ *
235
+ * @since 2.0
236
+ * @return array
237
+ */
238
+ static private function prep_attachments_for_js_config() {
239
+
240
+ $layout_data = FLBuilderModel::get_layout_data();
241
+ $attachments = array();
242
+
243
+ foreach ( $layout_data as $node ) {
244
+
245
+ if ( ! isset( $node->settings ) || ! is_object( $node->settings ) ) {
246
+ continue;
247
+ }
248
+
249
+ if ( 'row' === $node->type ) {
250
+ $fields = FLBuilderModel::get_settings_form_fields( FLBuilderModel::$settings_forms['row']['tabs'] );
251
+ } elseif ( 'column' === $node->type ) {
252
+ $fields = FLBuilderModel::get_settings_form_fields( FLBuilderModel::$settings_forms['col']['tabs'] );
253
+ } elseif ( 'module' === $node->type && isset( FLBuilderModel::$modules[ $node->settings->type ] ) ) {
254
+ $fields = FLBuilderModel::get_settings_form_fields( FLBuilderModel::$modules[ $node->settings->type ]->form );
255
+ } else {
256
+ continue;
257
+ }
258
+
259
+ foreach ( $node->settings as $key => $value ) {
260
+
261
+ // Look for image attachments.
262
+ if ( strstr( $key, '_src' ) ) {
263
+
264
+ $base = str_replace( '_src', '', $key );
265
+
266
+ if ( isset( $node->settings->$base ) && is_numeric( $node->settings->$base ) ) {
267
+
268
+ $id = $node->settings->$base;
269
+ $data = self::prep_attachment_for_js_config( $id );
270
+
271
+ if ( $data ) {
272
+ $attachments[ $id ] = $data;
273
+ }
274
+ }
275
+ }
276
+
277
+ // Look for video attachments.
278
+ if ( isset( $fields[ $key ] ) && 'video' === $fields[ $key ]['type'] ) {
279
+
280
+ if ( is_numeric( $value ) ) {
281
+
282
+ $id = $value;
283
+ $data = self::prep_attachment_for_js_config( $id );
284
+
285
+ if ( $data ) {
286
+ $attachments[ $id ] = $data;
287
+ }
288
+ }
289
+ }
290
+ }
291
+ }// End foreach().
292
+
293
+ return $attachments;
294
+ }
295
+
296
+ /**
297
+ * Prepares a single attachment for the JS config.
298
+ *
299
+ * @since 2.0
300
+ * @param int $id
301
+ * @return array|bool
302
+ */
303
+ static private function prep_attachment_for_js_config( $id ) {
304
+
305
+ $url = wp_get_attachment_url( $id );
306
+
307
+ if ( ! $url ) {
308
+ return false;
309
+ }
310
+
311
+ $filename = wp_basename( $url );
312
+ $base_url = str_replace( $filename, '', $url );
313
+ $meta = wp_get_attachment_metadata( $id );
314
+ $sizes = array();
315
+ $possible_sizes = apply_filters( 'image_size_names_choose', array(
316
+ 'thumbnail' => __( 'Thumbnail' ),
317
+ 'medium' => __( 'Medium' ),
318
+ 'large' => __( 'Large' ),
319
+ 'full' => __( 'Full Size' ),
320
+ ) );
321
+
322
+ if ( isset( $meta['sizes'] ) ) {
323
+ foreach ( $meta['sizes'] as $size_key => $size ) {
324
+ if ( ! isset( $possible_sizes[ $size_key ] ) ) {
325
+ continue;
326
+ }
327
+ $sizes[ $size_key ] = array(
328
+ 'url' => $base_url . $size['file'],
329
+ 'filename' => $size['file'],
330
+ 'width' => $size['width'],
331
+ 'height' => $size['height'],
332
+ );
333
+ }
334
+ }
335
+
336
+ if ( ! isset( $sizes['full'] ) ) {
337
+ $sizes['full'] = array(
338
+ 'url' => $url,
339
+ 'filename' => isset( $meta['file'] ) ? $meta['file'] : $filename,
340
+ 'width' => isset( $meta['width'] ) ? $meta['width'] : '',
341
+ 'height' => isset( $meta['height'] ) ? $meta['height'] : '',
342
+ );
343
+ }
344
+
345
+ return array(
346
+ 'id' => $id,
347
+ 'url' => $url,
348
+ 'filename' => $filename,
349
+ 'sizes' => apply_filters( 'fl_builder_photo_sizes_select', $sizes ),
350
+ );
351
+ }
352
+
353
+ /**
354
+ * Renders the JS templates for settings forms.
355
+ *
356
+ * @since 2.0
357
+ * @return void
358
+ */
359
+ static public function render_js_templates() {
360
+ if ( ! FLBuilderModel::is_builder_active() ) {
361
+ return;
362
+ }
363
+
364
+ include FL_BUILDER_DIR . 'includes/ui-settings-form.php';
365
+ include FL_BUILDER_DIR . 'includes/ui-settings-form-row.php';
366
+ include FL_BUILDER_DIR . 'includes/ui-field.php';
367
+
368
+ $fields = glob( FL_BUILDER_DIR . 'includes/ui-field-*.php' );
369
+ $custom = apply_filters( 'fl_builder_custom_fields', array() );
370
+
371
+ foreach ( $fields as $path ) {
372
+ $slug = str_replace( array( 'ui-field-', '.php' ), '', basename( $path ) );
373
+ echo '<script type="text/html" id="tmpl-fl-builder-field-' . $slug . '">';
374
+ include $path;
375
+ echo '</script>';
376
+ }
377
+
378
+ foreach ( $custom as $type => $path ) {
379
+ echo '<script type="text/html" id="tmpl-fl-builder-field-' . $type . '">';
380
+ include $path;
381
+ echo '</script>';
382
+ }
383
+
384
+ foreach ( self::$form_templates as $id => $path ) {
385
+ if ( file_exists( $path ) ) {
386
+ echo '<script type="text/html" id="tmpl-' . $id . '">';
387
+ include $path;
388
+ echo '</script>';
389
+ }
390
+ }
391
+ }
392
+
393
+ /**
394
+ * Pre-renders legacy settings tabs, sections and fields for
395
+ * new modules that are currently being sent to the frontend.
396
+ *
397
+ * @since 2.0
398
+ * @param string $type
399
+ * @param object $settings
400
+ * @return array
401
+ */
402
+ static public function pre_render_legacy_module_settings( $type, $settings ) {
403
+ $data = array(
404
+ 'tabs' => array(),
405
+ 'sections' => array(),
406
+ 'fields' => array(),
407
+ 'settings' => $settings,
408
+ 'node_id' => null,
409
+ );
410
+ $custom = apply_filters( 'fl_builder_custom_fields', array() );
411
+
412
+ foreach ( FLBuilderModel::$modules[ $type ]->form as $tab_id => $tab ) {
413
+
414
+ if ( isset( $tab['file'] ) ) {
415
+ $data['tabs'][] = $tab_id;
416
+ }
417
+ if ( ! isset( $tab['sections'] ) ) {
418
+ continue;
419
+ }
420
+
421
+ foreach ( $tab['sections'] as $section_id => $section ) {
422
+
423
+ if ( isset( $section['file'] ) ) {
424
+ $data['sections'][] = array(
425
+ 'tab' => $tab_id,
426
+ 'section' => $section_id,
427
+ );
428
+ }
429
+ if ( ! isset( $section['fields'] ) ) {
430
+ continue;
431
+ }
432
+
433
+ foreach ( $section['fields'] as $field_id => $field ) {
434
+
435
+ $is_core = file_exists( FL_BUILDER_DIR . 'includes/ui-field-' . $field['type'] . '.php' );
436
+ $is_custom = isset( $custom[ $field['type'] ] );
437
+
438
+ if ( ! $is_core && ! $is_custom ) {
439
+ $data['fields'][] = $field_id;
440
+ }
441
+ }
442
+ }
443
+ }
444
+
445
+ return self::render_legacy_settings( $data, $type, 'module', null );
446
+ }
447
+
448
+ /**
449
+ * Renders legacy settings tabs, sections and fields.
450
+ *
451
+ * @since 2.0
452
+ * @param array $data
453
+ * @param string $form
454
+ * @param string $group
455
+ * @param string $lightbox
456
+ * @return array
457
+ */
458
+ static public function render_legacy_settings( $data, $form, $group, $lightbox ) {
459
+ $response = array(
460
+ 'lightbox' => $lightbox,
461
+ 'tabs' => array(),
462
+ 'sections' => array(),
463
+ 'fields' => array(),
464
+ 'extras' => array(),
465
+ );
466
+
467
+ // Get the form tabs.
468
+ if ( 'general' === $group ) {
469
+ $tabs = FLBuilderModel::$settings_forms[ $form ]['tabs'];
470
+ } elseif ( 'module' === $group ) {
471
+ $tabs = FLBuilderModel::$modules[ $form ]->form;
472
+ }
473
+
474
+ // Get the form fields.
475
+ $fields = FLBuilderModel::get_settings_form_fields( $tabs );
476
+
477
+ // Get the settings.
478
+ if ( $data['node_id'] ) {
479
+ $layout_data = FLBuilderModel::get_layout_data();
480
+ $settings = $layout_data[ $data['node_id'] ]->settings;
481
+ } else {
482
+ $settings = isset( $data['settings'] ) ? (object) $data['settings'] : new stdClass();
483
+ }
484
+
485
+ // Render legacy custom fields.
486
+ if ( isset( $data['fields'] ) ) {
487
+ foreach ( $data['fields'] as $name ) {
488
+ ob_start();
489
+ self::render_settings_field( $name, (array) $fields[ $name ], $settings );
490
+ $response['fields'][ $name ] = ob_get_clean();
491
+ }
492
+ }
493
+
494
+ // Render legacy field extras with the before and after actions.
495
+ foreach ( $fields as $name => $field ) {
496
+
497
+ if ( in_array( $name, $response['fields'] ) ) {
498
+ continue;
499
+ }
500
+
501
+ $value = isset( $settings->$name ) ? $settings->$name : '';
502
+
503
+ ob_start();
504
+ do_action( 'fl_builder_before_control', $name, $value, $field, $settings );
505
+ do_action( 'fl_builder_before_control_' . $field['type'], $name, $value, $field, $settings );
506
+ $before = ob_get_clean();
507
+
508
+ ob_start();
509
+ do_action( 'fl_builder_after_control_' . $field['type'], $name, $value, $field, $settings );
510
+ do_action( 'fl_builder_after_control', $name, $value, $field, $settings );
511
+ $after = ob_get_clean();
512
+
513
+ if ( ! empty( $before ) || ! empty( $after ) ) {
514
+ $response['extras'][ $name ] = array(
515
+ 'before' => $before,
516
+ 'after' => $after,
517
+ );
518
+ }
519
+ }
520
+
521
+ // Render legacy custom sections.
522
+ if ( isset( $data['sections'] ) ) {
523
+ foreach ( $data['sections'] as $section_data ) {
524
+ $tab = $section_data['tab'];
525
+ $name = $section_data['section'];
526
+ $section = $tabs[ $tab ]['sections'][ $name ];
527
+ if ( file_exists( $section['file'] ) ) {
528
+ if ( ! isset( $response['sections'][ $tab ] ) ) {
529
+ $response['sections'][ $tab ] = array();
530
+ }
531
+ ob_start();
532
+ include $section['file'];
533
+ $response['sections'][ $tab ][ $name ] = ob_get_clean();
534
+ }
535
+ }
536
+ }
537
+
538
+ // Render legacy custom tabs.
539
+ if ( isset( $data['tabs'] ) ) {
540
+ foreach ( $data['tabs'] as $name ) {
541
+ $tab = $tabs[ $name ];
542
+ if ( FL_BUILDER_DIR . 'includes/loop-settings.php' === $tab['file'] ) {
543
+ $tab['file'] = FL_BUILDER_DIR . 'includes/ui-loop-settings.php';
544
+ }
545
+ if ( file_exists( $tab['file'] ) ) {
546
+ ob_start();
547
+ include $tab['file'];
548
+ $response['tabs'][ $name ] = ob_get_clean();
549
+ }
550
+ }
551
+ }
552
+
553
+ return $response;
554
+ }
555
+
556
+ /**
557
+ * Renders a settings via PHP. This method is only around for
558
+ * backwards compatibility with third party settings forms that are
559
+ * still being rendered via AJAX. Going forward, all settings forms
560
+ * should be rendered on the frontend using FLBuilderSettingsForms.render.
561
+ *
562
+ * @since 2.0
563
+ * @param array $form The form data.
564
+ * @param object $settings The settings data.
565
+ * @return array
566
+ */
567
+ static public function render_settings( $form = array(), $settings ) {
568
+ $defaults = array(
569
+ 'class' => '',
570
+ 'attrs' => '',
571
+ 'title' => '',
572
+ 'badges' => array(),
573
+ 'tabs' => array(),
574
+ 'buttons' => array(),
575
+ 'settings' => $settings,
576
+ );
577
+
578
+ // Legacy filter for the config.
579
+ $form = apply_filters( 'fl_builder_settings_form_config', array_merge( $defaults, $form ) );
580
+
581
+ // Setup the class var to be safe in JS.
582
+ $form['className'] = $form['class'];
583
+ unset( $form['class'] );
584
+
585
+ // Get the form ID.
586
+ foreach ( $form['tabs'] as $tab ) {
587
+ $form['id'] = $tab['form_id'];
588
+ break;
589
+ }
590
+
591
+ // We don't need to send tab data back.
592
+ unset( $form['tabs'] );
593
+
594
+ // Render and return!
595
+ ob_start();
596
+ include FL_BUILDER_DIR . 'includes/ui-legacy-settings.php';
597
+ $html = ob_get_clean();
598
+
599
+ return array(
600
+ 'html' => $html,
601
+ );
602
+ }
603
+
604
+ /**
605
+ * Renders a settings form via PHP. This method is only around for
606
+ * backwards compatibility with third party settings forms that are
607
+ * still being rendered via AJAX. Going forward, all settings forms
608
+ * should be rendered on the frontend using FLBuilderSettingsForms.render.
609
+ *
610
+ * @since 2.0
611
+ * @param string $type The type of form to render.
612
+ * @param object $settings The settings data.
613
+ * @return array
614
+ */
615
+ static public function render_settings_form( $type = null, $settings = null ) {
616
+ $form = FLBuilderModel::get_settings_form( $type );
617
+
618
+ if ( isset( $settings ) && ! empty( $settings ) ) {
619
+ $defaults = FLBuilderModel::get_settings_form_defaults( $type );
620
+ $settings = (object) array_merge( (array) $defaults, (array) $settings );
621
+ } else {
622
+ $settings = FLBuilderModel::get_settings_form_defaults( $type );
623
+ }
624
+
625
+ return self::render_settings(array(
626
+ 'title' => $form['title'],
627
+ 'tabs' => $form['tabs'],
628
+ ), $settings);
629
+ }
630
+
631
+ /**
632
+ * Renders a settings field via PHP. This method is only around for
633
+ * backwards compatibility with third party settings forms that are
634
+ * still being rendered via AJAX. Going forward, all settings forms
635
+ * should be rendered on the frontend using FLBuilderSettingsForms.render.
636
+ *
637
+ * @since 2.0
638
+ * @param string $name The field name.
639
+ * @param array $field An array of setup data for the field.
640
+ * @param object $settings Form settings data object.
641
+ * @return void
642
+ */
643
+ static public function render_settings_field( $name, $field, $settings = null ) {
644
+
645
+ $field = apply_filters( 'fl_builder_render_settings_field', $field, $name, $settings ); // Allow field settings filtering first
646
+ $i = null;
647
+ $is_multiple = isset( $field['multiple'] ) && true === (bool) $field['multiple'];
648
+ $supports_multiple = 'editor' != $field['type'] && 'photo' != $field['type'] && 'service' != $field['type'];
649
+ $settings = ! $settings ? new stdClass() : $settings;
650
+ $preview = isset( $field['preview'] ) ? json_encode( $field['preview'] ) : json_encode( array(
651
+ 'type' => 'refresh',
652
+ ) );
653
+ $row_class = isset( $field['row_class'] ) ? ' ' . $field['row_class'] : '';
654
+ $responsive = false;
655
+ $responsive_fields = array( 'unit' );
656
+ $root_name = $name;
657
+ $global_settings = FLBuilderModel::get_global_settings();
658
+ $value = isset( $settings->$name ) ? $settings->$name : '';
659
+
660
+ // Use a default value if not set in the settings.
661
+ if ( ! isset( $settings->$name ) && isset( $field['default'] ) ) {
662
+ $value = $field['default'];
663
+ }
664
+
665
+ // Check to see if responsive is enabled for this field.
666
+ if ( $global_settings->responsive_enabled && isset( $field['responsive'] ) && ! $is_multiple && in_array( $field['type'], $responsive_fields ) ) {
667
+ $responsive = $field['responsive'];
668
+ }
669
+
670
+ if ( file_exists( FL_BUILDER_DIR . 'includes/ui-field-' . $field['type'] . '.php' ) ) {
671
+
672
+ // Render old calls to *core* fields with JS.
673
+ include FL_BUILDER_DIR . 'includes/ui-legacy-field.php';
674
+
675
+ } else {
676
+
677
+ // Render old calls to *custom* fields with PHP.
678
+ if ( $is_multiple && $supports_multiple ) {
679
+
680
+ $values = $value;
681
+ $arr_name = $name;
682
+ $name .= '[]';
683
+
684
+ echo '<tbody id="fl-field-' . $root_name . '" class="fl-field fl-builder-field-multiples" data-type="form" data-preview=\'' . $preview . '\'>';
685
+
686
+ for ( $i = 0; $i < count( $values ); $i++ ) {
687
+ $value = $values[ $i ];
688
+ echo '<tr class="fl-builder-field-multiple" data-field="' . $arr_name . '">';
689
+ include FL_BUILDER_DIR . 'includes/ui-legacy-custom-field.php';
690
+ echo '<td class="fl-builder-field-actions">';
691
+ echo '<i class="fl-builder-field-move fa fa-arrows"></i>';
692
+ echo '<i class="fl-builder-field-copy fa fa-copy"></i>';
693
+ echo '<i class="fl-builder-field-delete fa fa-times"></i>';
694
+ echo '</td>';
695
+ echo '</tr>';
696
+ }
697
+
698
+ echo '<tr>';
699
+
700
+ if ( empty( $field['label'] ) ) {
701
+ echo '<td colspan="2">';
702
+ } else {
703
+ echo '<td>&nbsp;</td><td>';
704
+ }
705
+
706
+ echo '<a href="javascript:void(0);" onclick="return false;" class="fl-builder-field-add fl-builder-button" data-field="' . $arr_name . '">' . sprintf( _x( 'Add %s', 'Field name to add.', 'fl-builder' ), $field['label'] ) . '</a>';
707
+ echo '</td>';
708
+ echo '</tr>';
709
+ echo '</tbody>';
710
+ } else {
711
+ echo '<tr id="fl-field-' . $name . '" class="fl-field' . $row_class . '" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
712
+ include FL_BUILDER_DIR . 'includes/ui-legacy-custom-field.php';
713
+ echo '</tr>';
714
+ }// End if().
715
+ }// End if().
716
+ }// End if().
717
+
718
+ /**
719
+ * Renders the markup for the icon selector.
720
+ *
721
+ * @since 2.0
722
+ * @return array
723
+ */
724
+ static public function render_icon_selector() {
725
+ $icon_sets = FLBuilderIcons::get_sets();
726
+
727
+ ob_start();
728
+ include FL_BUILDER_DIR . 'includes/icon-selector.php';
729
+ $html = ob_get_clean();
730
+
731
+ return array(
732
+ 'html' => $html,
733
+ );
734
+ }
735
+ }
736
+
737
+ FLBuilderUISettingsForms::init();
classes/class-fl-builder-user-settings.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Handles logic for user specific settings.
5
+ *
6
+ * @since 2.0
7
+ */
8
+ class FLBuilderUserSettings {
9
+
10
+ /**
11
+ * @since 2.0
12
+ * @return void
13
+ */
14
+ static public function init() {
15
+ FLBuilderAJAX::add_action( 'save_ui_skin', __CLASS__ . '::save_ui_skin', array( 'skin_name' ) );
16
+ FLBuilderAJAX::add_action( 'save_lightbox_position', __CLASS__ . '::save_lightbox_position', array( 'data' ) );
17
+ FLBuilderAJAX::add_action( 'save_pinned_ui_position', __CLASS__ . '::save_pinned_ui_position', array( 'data' ) );
18
+ }
19
+
20
+ /**
21
+ * @since 2.0
22
+ * @return array
23
+ */
24
+ static public function get() {
25
+ $meta = get_user_meta( get_current_user_id(), 'fl_builder_user_settings', true );
26
+ $defaults = array(
27
+ 'skin' => 'light',
28
+ 'lightbox' => null,
29
+ );
30
+
31
+ if ( ! $meta ) {
32
+ $meta = array();
33
+ }
34
+
35
+ return array_merge( $defaults, $meta );
36
+ }
37
+
38
+ /**
39
+ * @since 2.0
40
+ * @param array $data
41
+ * @return mixed
42
+ */
43
+ static public function update( $data ) {
44
+ return update_user_meta( get_current_user_id(), 'fl_builder_user_settings', $data );
45
+ }
46
+
47
+ /**
48
+ * Handle saving UI Skin type.
49
+ *
50
+ * @since 2.0
51
+ * @param string $name
52
+ * @return array
53
+ */
54
+ static public function save_ui_skin( $name ) {
55
+ $settings = self::get();
56
+ $settings['skin'] = $name;
57
+
58
+ return array(
59
+ 'saved' => self::update( $settings ),
60
+ 'name' => $name,
61
+ );
62
+ }
63
+
64
+ /**
65
+ * Handle saving the lightbox position.
66
+ *
67
+ * @since 2.0
68
+ * @param array $data
69
+ * @return array
70
+ */
71
+ static public function save_lightbox_position( $data ) {
72
+ $settings = self::get();
73
+ $settings['lightbox'] = $data;
74
+
75
+ return self::update( $settings );
76
+ }
77
+
78
+ /**
79
+ * Handle saving the lightbox position.
80
+ *
81
+ * @since 2.0
82
+ * @param array $data
83
+ * @return array
84
+ */
85
+ static public function save_pinned_ui_position( $data ) {
86
+ $settings = self::get();
87
+ $settings = array_merge( $settings, $data );
88
+
89
+ return self::update( $settings );
90
+ }
91
+ }
92
+
93
+ FLBuilderUserSettings::init();
classes/class-fl-builder-utils.php CHANGED
@@ -194,4 +194,16 @@ final class FLBuilderUtils {
194
  return $video_data;
195
  }
196
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  }
194
  return $video_data;
195
  }
196
 
197
+ /**
198
+ * Use mb_strtolower() if available.s
199
+ * @since 2.0.2
200
+ */
201
+ static public function strtolower( $text, $encoding = 'UTF-8' ) {
202
+
203
+ if ( function_exists( 'mb_strtolower' ) ) {
204
+ return mb_strtolower( $text, $encoding );
205
+ }
206
+ return strtolower( $text );
207
+ }
208
+
209
  }
classes/class-fl-builder-wpcli-command.php CHANGED
@@ -77,6 +77,7 @@ class FLbuilder_WPCLI_Command extends WP_CLI_Command {
77
  WP_CLI::success( __( 'Rebuilt the theme cache', 'fl-builder' ) );
78
  }
79
  }
 
80
  }// End if().
81
  }
82
  }
77
  WP_CLI::success( __( 'Rebuilt the theme cache', 'fl-builder' ) );
78
  }
79
  }
80
+ do_action( 'fl_builder_cache_cleared' );
81
  }// End if().
82
  }
83
  }
classes/class-fl-builder.php CHANGED
@@ -58,7 +58,9 @@ final class FLBuilder {
58
  /* Actions */
59
  add_action( 'plugins_loaded', __CLASS__ . '::load_plugin_textdomain' );
60
  add_action( 'send_headers', __CLASS__ . '::no_cache_headers' );
 
61
  add_action( 'wp', __CLASS__ . '::init_ui', 11 );
 
62
  add_action( 'wp_enqueue_scripts', __CLASS__ . '::register_layout_styles_scripts' );
63
  add_action( 'wp_enqueue_scripts', __CLASS__ . '::enqueue_ui_styles_scripts', 11 );
64
  add_action( 'wp_enqueue_scripts', __CLASS__ . '::enqueue_all_layouts_styles_scripts' );
@@ -66,8 +68,6 @@ final class FLBuilder {
66
  add_action( 'admin_bar_menu', __CLASS__ . '::admin_bar_menu', 999 );
67
  add_action( 'wp_footer', __CLASS__ . '::include_jquery' );
68
  add_action( 'wp_footer', __CLASS__ . '::render_ui' );
69
- add_action( 'fl_builder_ui_panel_after_rows', __CLASS__ . '::render_ui_panel_row_templates' );
70
- add_action( 'fl_builder_ui_panel_after_modules', __CLASS__ . '::render_ui_panel_modules_templates' );
71
 
72
  /* Filters */
73
  add_filter( 'fl_builder_render_css', __CLASS__ . '::rewrite_css_cache_urls', 9999 );
@@ -116,6 +116,12 @@ final class FLBuilder {
116
  return false;
117
  }
118
 
 
 
 
 
 
 
119
  /**
120
  * Alias method for registering a template data file with the builder.
121
  *
@@ -123,8 +129,8 @@ final class FLBuilder {
123
  * @param sting $path The directory path to the template data file.
124
  * @return void
125
  */
126
- static public function register_templates( $path ) {
127
- FLBuilderModel::register_templates( $path );
128
  }
129
 
130
  /**
@@ -179,6 +185,24 @@ final class FLBuilder {
179
  }
180
  }
181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  /**
183
  * Set the default text editor to tinymce when the builder is active.
184
  *
@@ -351,19 +375,19 @@ final class FLBuilder {
351
  // Register additional JS
352
  wp_register_script( 'fl-slideshow', $js_url . 'fl-slideshow' . $min . '.js', array( 'yui3' ), $ver, true );
353
  wp_register_script( 'fl-gallery-grid', $js_url . 'fl-gallery-grid.js', array( 'jquery' ), $ver, true );
354
- wp_register_script( 'jquery-bxslider', $js_url . 'jquery.bxslider.min.js', array( 'jquery-easing', 'jquery-fitvids' ), $ver, true );
355
- wp_register_script( 'jquery-easing', $js_url . 'jquery.easing.1.3.js', array( 'jquery' ), '1.3', true );
356
- wp_register_script( 'jquery-fitvids', $js_url . 'jquery.fitvids.js', array( 'jquery' ), $ver, true );
357
- wp_register_script( 'jquery-imagesloaded', $js_url . 'jquery.imagesloaded.js', array( 'jquery' ), $ver, true );
358
- wp_register_script( 'jquery-infinitescroll', $js_url . 'jquery.infinitescroll.js', array( 'jquery' ), $ver, true );
359
  wp_register_script( 'jquery-magnificpopup', $js_url . 'jquery.magnificpopup.min.js', array( 'jquery' ), $ver, true );
360
  wp_register_script( 'jquery-mosaicflow', $js_url . 'jquery.mosaicflow.min.js', array( 'jquery' ), $ver, true );
361
  wp_register_script( 'jquery-waypoints', $js_url . 'jquery.waypoints.min.js', array( 'jquery' ), $ver, true );
362
  wp_register_script( 'jquery-wookmark', $js_url . 'jquery.wookmark.min.js', array( 'jquery' ), $ver, true );
363
- wp_register_script( 'yui3', $js_url . 'yui3.js', array(), $ver, true );
364
 
365
- wp_register_script( 'youtube-player', 'https://www.youtube.com/iframe_api', array(), $ver, true );
366
- wp_register_script( 'vimeo-player', 'https://player.vimeo.com/api/player.js', array(), $ver, true );
367
  }
368
 
369
  /**
@@ -549,6 +573,10 @@ final class FLBuilder {
549
  */
550
  static public function enqueue_ui_styles_scripts() {
551
  if ( FLBuilderModel::is_builder_active() ) {
 
 
 
 
552
 
553
  $ver = FL_BUILDER_VERSION;
554
  $css_url = plugins_url( '/css/', FL_BUILDER_FILE );
@@ -569,6 +597,9 @@ final class FLBuilder {
569
  wp_enqueue_style( 'fl-lightbox', $css_url . 'fl-lightbox.css', array(), $ver );
570
  wp_enqueue_style( 'fl-icon-selector', $css_url . 'fl-icon-selector.css', array(), $ver );
571
  wp_enqueue_style( 'fl-builder', $css_url . 'fl-builder.css', array(), $ver );
 
 
 
572
  } else {
573
  wp_enqueue_style( 'fl-builder-min', $css_url . 'fl-builder.min.css', array(), $ver );
574
  }
@@ -605,11 +636,13 @@ final class FLBuilder {
605
  wp_enqueue_script( 'jquery-nanoscroller', $js_url . 'jquery.nanoscroller.min.js', array(), $ver );
606
  wp_enqueue_script( 'jquery-autosuggest', $js_url . 'jquery.autoSuggest.min.js', array(), $ver );
607
  wp_enqueue_script( 'jquery-tiptip', $js_url . 'jquery.tiptip.min.js', array(), $ver );
 
608
  wp_enqueue_script( 'jquery-simulate', $js_url . 'jquery.simulate.js', array(), $ver );
609
  wp_enqueue_script( 'jquery-validate', $js_url . 'jquery.validate.min.js', array(), $ver );
610
  wp_enqueue_script( 'bootstrap-tour', $js_url . 'bootstrap-tour-standalone.min.js', array(), $ver );
611
  wp_enqueue_script( 'ace', $js_url . 'ace/ace.js', array(), $ver );
612
  wp_enqueue_script( 'ace-language-tools', $js_url . 'ace/ext-language_tools.js', array(), $ver );
 
613
 
614
  // Enqueue individual builder scripts if WP_DEBUG is on.
615
  if ( self::is_debug() ) {
@@ -621,13 +654,29 @@ final class FLBuilder {
621
  wp_enqueue_script( 'fl-builder-ajax-layout', $js_url . 'fl-builder-ajax-layout.js', array(), $ver );
622
  wp_enqueue_script( 'fl-builder-preview', $js_url . 'fl-builder-preview.js', array(), $ver );
623
  wp_enqueue_script( 'fl-builder-simulate-media-query', $js_url . 'fl-builder-simulate-media-query.js', array(), $ver );
624
- wp_enqueue_script( 'fl-builder-responsive-editing', $js_url . 'fl-builder-responsive-editing.js', array(), $ver );
625
  wp_enqueue_script( 'fl-builder-services', $js_url . 'fl-builder-services.js', array(), $ver );
626
  wp_enqueue_script( 'fl-builder-tour', $js_url . 'fl-builder-tour.js', array(), $ver );
 
 
 
 
 
 
 
 
627
  } else {
628
- wp_enqueue_script( 'fl-builder-min', $js_url . 'fl-builder.min.js', array(), $ver );
629
  }
630
 
 
 
 
 
 
 
 
 
631
  /* Additional module styles and scripts */
632
  foreach ( FLBuilderModel::$modules as $module ) {
633
 
@@ -643,6 +692,21 @@ final class FLBuilder {
643
  }// End if().
644
  }
645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
646
  /**
647
  * Include a jQuery fallback script when the builder is
648
  * enabled for a page.
@@ -672,9 +736,20 @@ final class FLBuilder {
672
  if ( FLBuilderModel::is_builder_active() ) {
673
  $classes[] = 'fl-builder-edit';
674
 
 
 
 
 
675
  if ( ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' ) ) {
676
  $classes[] = 'fl-builder-simple';
677
  }
 
 
 
 
 
 
 
678
  }
679
 
680
  return $classes;
@@ -693,7 +768,7 @@ final class FLBuilder {
693
  if ( FLBuilderModel::is_post_editable() && is_object( $wp_the_query->post ) ) {
694
 
695
  $enabled = get_post_meta( $wp_the_query->post->ID, '_fl_builder_enabled', true );
696
- $dot = ' <span style="color:' . ( $enabled ? '#6bc373' : '#d9d9d9' ) . '; font-size:18px;">&bull;</span>';
697
 
698
  $wp_admin_bar->add_node( array(
699
  'id' => 'fl-builder-frontend-edit-link',
@@ -749,6 +824,11 @@ final class FLBuilder {
749
  remove_all_actions( 'media_buttons', 999999 );
750
  remove_all_actions( 'media_buttons_context', 999999 );
751
 
 
 
 
 
 
752
  // Get the post.
753
  require_once ABSPATH . 'wp-admin/includes/post.php';
754
  $post_id = FLBuilderModel::get_post_id();
@@ -777,20 +857,352 @@ final class FLBuilder {
777
  $unrestricted = FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
778
  $simple_ui = ! $unrestricted;
779
  $global_settings = FLBuilderModel::get_global_settings();
780
- $categories = FLBuilderModel::get_categorized_modules();
781
- $render_panel = apply_filters( 'fl_builder_render_ui_panel', $unrestricted );
782
-
783
- if ( $render_panel ) {
784
- include FL_BUILDER_DIR . 'includes/ui-panel.php';
785
- }
786
 
787
- include FL_BUILDER_DIR . 'includes/ui-bar.php';
788
- include FL_BUILDER_DIR . 'includes/ui-fields.php';
789
  include FL_BUILDER_DIR . 'includes/ui-js-templates.php';
790
  include FL_BUILDER_DIR . 'includes/ui-js-config.php';
791
  }
792
  }
793
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
794
  /**
795
  * Renders the markup for the title in the builder's bar.
796
  *
@@ -798,24 +1210,24 @@ final class FLBuilder {
798
  * @return void
799
  */
800
  static public function render_ui_bar_title() {
801
- // Get the bar title.
802
- $title = apply_filters( 'fl_builder_ui_bar_title', FLBuilderModel::get_branding() );
803
 
804
- // Render the bar title.
805
- if ( '' == FLBuilderModel::get_branding_icon() ) {
806
- echo '<div class="fl-builder-bar-title fl-builder-bar-title-no-icon">';
807
- do_action( 'fl_builder_before_ui_bar_title' );
808
- echo $title;
809
- do_action( 'fl_builder_after_ui_bar_title' );
810
- echo '</div>';
811
- } else {
812
- echo '<div class="fl-builder-bar-title">';
813
- do_action( 'fl_builder_before_ui_bar_title' );
814
- echo '<img src="' . FLBuilderModel::get_branding_icon() . '" /> ';
815
- echo '<span>' . $title . '</span>';
816
- do_action( 'fl_builder_after_ui_bar_title' );
817
- echo '</div>';
818
  }
 
 
 
 
 
 
 
819
  }
820
 
821
  /**
@@ -825,14 +1237,13 @@ final class FLBuilder {
825
  * @return void
826
  */
827
  static public function render_ui_bar_buttons() {
828
- $help_button = FLBuilderModel::get_help_button_settings();
829
- $simple_ui = ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
 
 
 
830
 
831
  $buttons = apply_filters( 'fl_builder_ui_bar_buttons', array(
832
- 'help' => array(
833
- 'label' => '<i class="fa fa-question-circle"></i>',
834
- 'show' => $help_button['enabled'] && ! $simple_ui,
835
- ),
836
  'upgrade' => array(
837
  'label' => __( 'Upgrade Today <i class="fa fa-external-link-square"></i>', 'fl-builder' ),
838
  'show' => true === FL_BUILDER_LITE,
@@ -843,73 +1254,53 @@ final class FLBuilder {
843
  ),
844
  'done' => array(
845
  'label' => __( 'Done', 'fl-builder' ),
846
- 'class' => 'fl-builder-button-primary',
847
  ),
848
- 'tools' => array(
849
- 'label' => __( 'Tools', 'fl-builder' ),
850
  'show' => ! $simple_ui,
851
  ),
852
- 'templates' => array(
853
- 'label' => __( 'Templates', 'fl-builder' ),
854
- 'show' => ! $simple_ui,
855
- ),
856
- 'add-content' => array(
857
- 'label' => __( 'Add Content', 'fl-builder' ),
858
  'show' => ! $simple_ui,
859
  ),
860
  ) );
861
 
862
  echo '<div class="fl-builder-bar-actions">';
863
 
 
 
864
  foreach ( $buttons as $slug => $button ) {
865
 
 
 
 
 
866
  if ( isset( $button['show'] ) && ! $button['show'] ) {
867
  continue;
868
  }
869
 
870
- echo '<span class="fl-builder-' . $slug . '-button fl-builder-button';
871
 
872
  if ( isset( $button['class'] ) ) {
873
  echo ' ' . $button['class'];
874
  }
875
 
876
- echo '">' . $button['label'] . '</span>';
877
- }
878
-
879
- echo '<div class="fl-clear"></div></div>';
880
- }
881
-
882
- /**
883
- * Renders categorized row templates in the UI panel.
884
- *
885
- * @since 1.8
886
- * @return void
887
- */
888
- static public function render_ui_panel_row_templates() {
889
- $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
890
- $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
891
- $has_editing_cap = FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
892
- $row_templates = FLBuilderModel::get_row_templates_data();
893
 
894
- if ( ! $is_row_template && ! $is_module_template && $has_editing_cap ) {
895
- include FL_BUILDER_DIR . 'includes/ui-panel-row-templates.php';
896
  }
897
- }
898
 
899
- /**
900
- * Renders categorized module templates in the UI panel.
901
- *
902
- * @since 1.8
903
- * @return void
904
- */
905
- static public function render_ui_panel_modules_templates() {
906
- $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
907
- $has_editing_cap = FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
908
- $module_templates = FLBuilderModel::get_module_templates_data();
909
 
910
- if ( ! $is_module_template && $has_editing_cap ) {
911
- include FL_BUILDER_DIR . 'includes/ui-panel-module-templates.php';
 
 
912
  }
 
 
 
913
  }
914
 
915
  /**
@@ -927,7 +1318,6 @@ final class FLBuilder {
927
  */
928
  static public function render_query( $args, $site_id = null ) {
929
  global $post;
930
- global $wp_query;
931
  $switched = false;
932
 
933
  // Pull from a site on the network?
@@ -936,47 +1326,34 @@ final class FLBuilder {
936
  $switched = true;
937
  }
938
 
939
- // Get the post and query.
940
- $original_post = $post;
941
- $wp_query = new WP_Query( $args );
942
- $post_data = FLBuilderModel::get_post_data();
943
-
944
- // Make sure the builder's render content filter is present.
945
- add_filter( 'the_content', 'FLBuilder::render_content' );
946
 
947
  // Loop through the posts.
948
- while ( $wp_query->have_posts() ) {
949
-
950
- // Set the global post.
951
- $wp_query->the_post();
952
 
953
  // Make sure this isn't the same post as the original post to prevent infinite loops.
954
- if ( is_object( $original_post ) && $original_post->ID === $post->ID && ! $switched ) {
955
  continue;
956
  }
957
 
958
- // Enqueue styles and scripts for this post.
959
- self::enqueue_layout_styles_scripts_by_id( $post->ID );
960
 
961
- // Print the styles since we are outside of the head tag.
962
- ob_start();
963
- wp_print_styles();
964
- echo ob_get_clean();
965
 
966
- // Backup the main query in case it is overwritten in the_content().
967
- $backup_query = $wp_query;
968
 
969
- // Render the content.
970
- FLBuilderModel::set_post_id( $post->ID );
971
- the_content();
972
- FLBuilderModel::reset_post_id();
973
 
974
- // Restore the main query in case it was overwritten.
975
- $wp_query = $backup_query;
976
- }
977
 
978
- // Reset the global query.
979
- wp_reset_query();
 
 
980
 
981
  // Reset the site data?
982
  if ( $site_id && is_multisite() ) {
@@ -1026,7 +1403,11 @@ final class FLBuilder {
1026
 
1027
  // Process shortcodes.
1028
  if ( apply_filters( 'fl_builder_render_shortcodes', true ) ) {
 
1029
  $content = apply_filters( 'fl_builder_before_render_shortcodes', $content );
 
 
 
1030
  $content = do_shortcode( $content );
1031
  }
1032
 
@@ -1056,8 +1437,8 @@ final class FLBuilder {
1056
  * @return string
1057
  */
1058
  static public function render_content( $content ) {
1059
- $post_id = FLBuilderModel::get_post_id();
1060
- $enabled = FLBuilderModel::is_builder_enabled();
1061
  $rendering = $post_id === self::$post_rendering;
1062
  $do_render = apply_filters( 'fl_builder_do_render_content', true, $post_id );
1063
  $in_loop = in_the_loop();
@@ -1068,45 +1449,14 @@ final class FLBuilder {
1068
  // Set the post rendering ID.
1069
  self::$post_rendering = $post_id;
1070
 
1071
- // Remove the builder's render_content filter so it's not called again.
1072
- remove_filter( 'the_content', 'FLBuilder::render_content' );
1073
-
1074
- // Fire the render content start action.
1075
- do_action( 'fl_builder_render_content_start' );
1076
-
1077
  // Render the content.
1078
  ob_start();
1079
- do_action( 'fl_builder_before_render_content' );
1080
- echo '<div class="' . self::render_content_classes() . '" data-post-id="' . $post_id . '">';
1081
- self::render_nodes();
1082
- echo '</div>';
1083
- do_action( 'fl_builder_after_render_content' );
1084
- $content = apply_filters( 'fl_builder_rendered_content', ob_get_clean() );
1085
-
1086
- // Reapply the builder's render_content filter.
1087
- add_filter( 'the_content', 'FLBuilder::render_content' );
1088
-
1089
- // Do shortcodes here since letting the WP filter run can cause an infinite loop.
1090
- if ( apply_filters( 'fl_builder_render_shortcodes', true ) ) {
1091
- global $wp_embed;
1092
- $content = apply_filters( 'fl_builder_before_render_shortcodes', $content );
1093
- $pattern = get_shortcode_regex();
1094
- $content = preg_replace_callback( "/$pattern/s", 'FLBuilder::double_escape_shortcodes', $content );
1095
- $content = $wp_embed->run_shortcode( $content );
1096
- $content = do_shortcode( $content );
1097
- }
1098
-
1099
- // Add srcset attrs to images with the class wp-image-<ID>.
1100
- if ( function_exists( 'wp_make_content_images_responsive' ) ) {
1101
- $content = wp_make_content_images_responsive( $content );
1102
- }
1103
-
1104
- // Fire the render content complete action.
1105
- do_action( 'fl_builder_render_content_complete' );
1106
 
1107
  // Clear the post rendering ID.
1108
  self::$post_rendering = null;
1109
- }// End if().
1110
 
1111
  return $content;
1112
  }
@@ -1285,11 +1635,14 @@ final class FLBuilder {
1285
  // Remove empty lines.
1286
  $content = preg_replace( '/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $content );
1287
 
1288
- return $content;
1289
  }
1290
 
1291
  /**
1292
- * Renders a settings form.
 
 
 
1293
  *
1294
  * @since 1.0
1295
  * @param array $form The form data.
@@ -1297,104 +1650,14 @@ final class FLBuilder {
1297
  * @return array
1298
  */
1299
  static public function render_settings( $form = array(), $settings ) {
1300
- $defaults = array(
1301
- 'class' => '',
1302
- 'attrs' => '',
1303
- 'title' => '',
1304
- 'badges' => array(),
1305
- 'tabs' => array(),
1306
- 'buttons' => array(),
1307
- 'resizable' => false,
1308
- );
1309
-
1310
- $form = apply_filters( 'fl_builder_settings_form_config', array_merge( $defaults, $form ) );
1311
-
1312
- ob_start();
1313
- include FL_BUILDER_DIR . 'includes/settings.php';
1314
- $html = ob_get_clean();
1315
-
1316
- return array(
1317
- 'html' => $html,
1318
- );
1319
  }
1320
 
1321
  /**
1322
- * Renders a settings form field.
1323
- *
1324
- * @since 1.0
1325
- * @param string $name The field name.
1326
- * @param array $field An array of setup data for the field.
1327
- * @param object $settings Form settings data object.
1328
- * @return void
1329
- */
1330
- static public function render_settings_field( $name, $field, $settings = null ) {
1331
- $field = apply_filters( 'fl_builder_render_settings_field', $field, $name, $settings ); // Allow field settings filtering first
1332
- $i = null;
1333
- $is_multiple = isset( $field['multiple'] ) && true === $field['multiple'];
1334
- $supports_multiple = 'editor' != $field['type'] && 'photo' != $field['type'] && 'service' != $field['type'];
1335
- $settings = ! $settings ? new stdClass() : $settings;
1336
- $preview = isset( $field['preview'] ) ? json_encode( $field['preview'] ) : json_encode( array(
1337
- 'type' => 'refresh',
1338
- ) );
1339
- $row_class = isset( $field['row_class'] ) ? ' ' . $field['row_class'] : '';
1340
- $responsive = false;
1341
- $responsive_fields = array( 'unit' );
1342
- $root_name = $name;
1343
- $global_settings = FLBuilderModel::get_global_settings();
1344
- $value = isset( $settings->$name ) ? $settings->$name : '';
1345
-
1346
- // Use a default value if not set in the settings.
1347
- if ( ! isset( $settings->$name ) && isset( $field['default'] ) ) {
1348
- $value = $field['default'];
1349
- }
1350
-
1351
- // Check to see if responsive is enabled for this field.
1352
- if ( $global_settings->responsive_enabled && isset( $field['responsive'] ) && ! $is_multiple && in_array( $field['type'], $responsive_fields ) ) {
1353
- $responsive = $field['responsive'];
1354
- }
1355
-
1356
- // Render the field.
1357
- if ( $is_multiple && $supports_multiple ) {
1358
-
1359
- $values = $value;
1360
- $arr_name = $name;
1361
- $name .= '[]';
1362
-
1363
- echo '<tbody class="fl-field fl-builder-field-multiples" data-type="form" data-preview=\'' . $preview . '\'>';
1364
-
1365
- for ( $i = 0; $i < count( $values ); $i++ ) {
1366
- $value = $values[ $i ];
1367
- echo '<tr class="fl-builder-field-multiple" data-field="' . $arr_name . '">';
1368
- include FL_BUILDER_DIR . 'includes/field.php';
1369
- echo '<td class="fl-builder-field-actions">';
1370
- echo '<i class="fl-builder-field-move fa fa-arrows"></i>';
1371
- echo '<i class="fl-builder-field-copy fa fa-copy"></i>';
1372
- echo '<i class="fl-builder-field-delete fa fa-times"></i>';
1373
- echo '</td>';
1374
- echo '</tr>';
1375
- }
1376
-
1377
- echo '<tr>';
1378
-
1379
- if ( empty( $field['label'] ) ) {
1380
- echo '<td colspan="2">';
1381
- } else {
1382
- echo '<td>&nbsp;</td><td>';
1383
- }
1384
-
1385
- echo '<a href="javascript:void(0);" onclick="return false;" class="fl-builder-field-add fl-builder-button" data-field="' . $arr_name . '">' . sprintf( _x( 'Add %s', 'Field name to add.', 'fl-builder' ), $field['label'] ) . '</a>';
1386
- echo '</td>';
1387
- echo '</tr>';
1388
- echo '</tbody>';
1389
- } else {
1390
- echo '<tr id="fl-field-' . $name . '" class="fl-field' . $row_class . '" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
1391
- include FL_BUILDER_DIR . 'includes/field.php';
1392
- echo '</tr>';
1393
- }// End if().
1394
- }
1395
-
1396
- /**
1397
- * Renders a settings form.
1398
  *
1399
  * @since 1.0
1400
  * @param string $type The type of form to render.
@@ -1402,75 +1665,23 @@ final class FLBuilder {
1402
  * @return array
1403
  */
1404
  static public function render_settings_form( $type = null, $settings = null ) {
1405
- $form = FLBuilderModel::get_settings_form( $type );
1406
-
1407
- if ( isset( $settings ) && ! empty( $settings ) ) {
1408
- $defaults = FLBuilderModel::get_settings_form_defaults( $type );
1409
- $settings = (object) array_merge( (array) $defaults, (array) $settings );
1410
- } else {
1411
- $settings = FLBuilderModel::get_settings_form_defaults( $type );
1412
- }
1413
-
1414
- return self::render_settings(array(
1415
- 'title' => $form['title'],
1416
- 'tabs' => $form['tabs'],
1417
- 'resizable' => true,
1418
- ), $settings);
1419
- }
1420
-
1421
- /**
1422
- * Renders the markup for the layout settings form.
1423
- *
1424
- * @since 1.8
1425
- * @return array
1426
- */
1427
- static public function render_layout_settings() {
1428
- $settings = FLBuilderModel::get_layout_settings();
1429
- $form = FLBuilderModel::$settings_forms['layout'];
1430
-
1431
- return self::render_settings( array(
1432
- 'class' => 'fl-builder-layout-settings',
1433
- 'title' => $form['title'],
1434
- 'tabs' => $form['tabs'],
1435
- 'resizable' => true,
1436
- ), $settings );
1437
- }
1438
-
1439
- /**
1440
- * Renders the markup for the global settings form.
1441
- *
1442
- * @since 1.0
1443
- * @return array
1444
- */
1445
- static public function render_global_settings() {
1446
- $settings = FLBuilderModel::get_global_settings();
1447
- $form = FLBuilderModel::$settings_forms['global'];
1448
-
1449
- return self::render_settings(array(
1450
- 'class' => 'fl-builder-global-settings',
1451
- 'title' => $form['title'],
1452
- 'tabs' => $form['tabs'],
1453
- 'resizable' => true,
1454
- ), $settings);
1455
  }
1456
 
1457
  /**
1458
- * Renders the markup for the template selector.
 
 
 
1459
  *
1460
  * @since 1.0
1461
- * @return array
 
 
 
1462
  */
1463
- static public function render_template_selector() {
1464
- $filter_data = FLBuilderModel::get_template_selector_filter_data();
1465
- $templates = FLBuilderModel::get_template_selector_data();
1466
-
1467
- ob_start();
1468
- include FL_BUILDER_DIR . 'includes/template-selector.php';
1469
- $html = ob_get_clean();
1470
-
1471
- return array(
1472
- 'html' => $html,
1473
- );
1474
  }
1475
 
1476
  /**
@@ -1480,15 +1691,7 @@ final class FLBuilder {
1480
  * @return array
1481
  */
1482
  static public function render_icon_selector() {
1483
- $icon_sets = FLBuilderIcons::get_sets();
1484
-
1485
- ob_start();
1486
- include FL_BUILDER_DIR . 'includes/icon-selector.php';
1487
- $html = ob_get_clean();
1488
-
1489
- return array(
1490
- 'html' => $html,
1491
- );
1492
  }
1493
 
1494
  /**
@@ -1626,32 +1829,6 @@ final class FLBuilder {
1626
  echo ' fl-node-content';
1627
  }
1628
 
1629
- /**
1630
- * Renders the settings lightbox for a row.
1631
- *
1632
- * @since 1.0
1633
- * @param string $node_id A row node ID.
1634
- * @return array
1635
- */
1636
- static public function render_row_settings( $node_id = null ) {
1637
- $node = FLBuilderModel::get_node( $node_id );
1638
- $settings = $node->settings;
1639
- $form = FLBuilderModel::$settings_forms['row'];
1640
-
1641
- $rendered_settings = self::render_settings(array(
1642
- 'class' => 'fl-builder-row-settings',
1643
- 'attrs' => 'data-node="' . $node->node . '"',
1644
- 'title' => $form['title'],
1645
- 'tabs' => $form['tabs'],
1646
- 'resizable' => true,
1647
- ), $settings);
1648
-
1649
- return array(
1650
- 'settings' => $rendered_settings['html'],
1651
- 'state' => FLBuilderAJAXLayout::render( $node_id ),
1652
- );
1653
- }
1654
-
1655
  /**
1656
  * Renders the markup for a column group.
1657
  *
@@ -1740,32 +1917,6 @@ final class FLBuilder {
1740
  }
1741
  }
1742
 
1743
- /**
1744
- * Renders the markup for the column settings lightbox.
1745
- *
1746
- * @since 1.0
1747
- * @param string $node_id A column node ID.
1748
- * @return array
1749
- */
1750
- static public function render_column_settings( $node_id = null ) {
1751
- $node = FLBuilderModel::get_node( $node_id );
1752
- $settings = $node->settings;
1753
- $form = FLBuilderModel::$settings_forms['col'];
1754
-
1755
- $rendered_settings = self::render_settings(array(
1756
- 'class' => 'fl-builder-col-settings',
1757
- 'attrs' => 'data-node="' . $node->node . '"',
1758
- 'title' => $form['title'],
1759
- 'tabs' => $form['tabs'],
1760
- 'resizable' => true,
1761
- ), $settings);
1762
-
1763
- return array(
1764
- 'settings' => $rendered_settings['html'],
1765
- 'state' => FLBuilderAJAXLayout::render( $node->parent ),
1766
- );
1767
- }
1768
-
1769
  /**
1770
  * Renders the HTML attributes for a single column.
1771
  *
@@ -1863,55 +2014,6 @@ final class FLBuilder {
1863
  do_action( 'fl_builder_after_render_module', $module );
1864
  }
1865
 
1866
- /**
1867
- * Renders the settings lightbox for a module.
1868
- *
1869
- * @since 1.0
1870
- * @param string $node_id The module node ID.
1871
- * @param string $type The type of module.
1872
- * @param string $parent_id The parent column node ID.
1873
- * @param bool $render_state Whether to render the preview state or not.
1874
- * @return array
1875
- */
1876
- static public function render_module_settings( $node_id = null, $type = null, $parent_id = null, $render_state = true ) {
1877
- $assets = '';
1878
-
1879
- // Get the module and settings.
1880
- if ( $node_id ) {
1881
- $module = FLBuilderModel::get_module( $node_id );
1882
- $settings = $module->settings;
1883
- } else {
1884
- $module = FLBuilderModel::$modules[ $type ];
1885
- $settings = FLBuilderModel::get_module_defaults( $type );
1886
- }
1887
-
1888
- // Render the settings CSS/JS assets.
1889
- if ( file_exists( $module->dir . 'css/settings.css' ) ) {
1890
- $assets .= '<link class="fl-builder-settings-css" rel="stylesheet" href="' . $module->url . 'css/settings.css" />';
1891
- }
1892
- if ( file_exists( $module->dir . 'js/settings.js' ) ) {
1893
- $assets .= '<script class="fl-builder-settings-js" src="' . $module->url . 'js/settings.js"></script>';
1894
- }
1895
-
1896
- // Allow developers to hook in from a plugin and add further assets
1897
- $assets = apply_filters( 'fl_builder_render_module_settings_assets', $assets, $module );
1898
-
1899
- // Render the form.
1900
- $rendered_settings = self::render_settings(array(
1901
- 'class' => 'fl-builder-module-settings fl-builder-' . $type . '-settings',
1902
- 'attrs' => 'data-node="' . $node_id . '" data-parent="' . $parent_id . '" data-type="' . $type . '"',
1903
- 'title' => sprintf( __( '%s Settings', 'fl-builder' ), $module->name ),
1904
- 'tabs' => apply_filters( 'fl_builder_render_module_settings', $module->form, $module ),
1905
- 'resizable' => true,
1906
- ), $settings);
1907
-
1908
- // Return the HTML.
1909
- return array(
1910
- 'settings' => $assets . $rendered_settings['html'],
1911
- 'state' => $render_state ? FLBuilderAJAXLayout::render( $node_id ) : null,
1912
- );
1913
- }
1914
-
1915
  /**
1916
  * Renders the markup for a single module. This can be used to render
1917
  * the markup of a module within another module by passing the type
@@ -2580,7 +2682,7 @@ final class FLBuilder {
2580
 
2581
  // Add the layout settings JS.
2582
  $js .= self::render_global_nodes_custom_code( 'js' );
2583
- $js .= is_array( $layout_settings->js ) ? json_encode( $layout_settings->js ) : $layout_settings->js;
2584
 
2585
  // Call the FLBuilder._renderLayoutComplete method if we're currently editing.
2586
  if ( stristr( $asset_info['js'], '-draft.js' ) || stristr( $asset_info['js'], '-preview.js' ) ) {
@@ -2784,6 +2886,17 @@ final class FLBuilder {
2784
  return $code;
2785
  }
2786
 
 
 
 
 
 
 
 
 
 
 
 
2787
  /**
2788
  * Custom logging function that handles objects and arrays.
2789
  *
@@ -2930,6 +3043,74 @@ final class FLBuilder {
2930
  FLBuilderUserTemplates::render_node_settings( $node_id );
2931
  }
2932
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2933
  }
2934
 
2935
  FLBuilder::init();
58
  /* Actions */
59
  add_action( 'plugins_loaded', __CLASS__ . '::load_plugin_textdomain' );
60
  add_action( 'send_headers', __CLASS__ . '::no_cache_headers' );
61
+ add_action( 'wp', __CLASS__ . '::render_settings_config', 11 );
62
  add_action( 'wp', __CLASS__ . '::init_ui', 11 );
63
+ add_action( 'wp', __CLASS__ . '::rich_edit' );
64
  add_action( 'wp_enqueue_scripts', __CLASS__ . '::register_layout_styles_scripts' );
65
  add_action( 'wp_enqueue_scripts', __CLASS__ . '::enqueue_ui_styles_scripts', 11 );
66
  add_action( 'wp_enqueue_scripts', __CLASS__ . '::enqueue_all_layouts_styles_scripts' );
68
  add_action( 'admin_bar_menu', __CLASS__ . '::admin_bar_menu', 999 );
69
  add_action( 'wp_footer', __CLASS__ . '::include_jquery' );
70
  add_action( 'wp_footer', __CLASS__ . '::render_ui' );
 
 
71
 
72
  /* Filters */
73
  add_filter( 'fl_builder_render_css', __CLASS__ . '::rewrite_css_cache_urls', 9999 );
116
  return false;
117
  }
118
 
119
+ static public function rich_edit() {
120
+ if ( FLBuilderModel::is_builder_active() ) {
121
+ add_filter( 'get_user_option_rich_editing', '__return_true' );
122
+ }
123
+ }
124
+
125
  /**
126
  * Alias method for registering a template data file with the builder.
127
  *
129
  * @param sting $path The directory path to the template data file.
130
  * @return void
131
  */
132
+ static public function register_templates( $path, $args = array() ) {
133
+ FLBuilderModel::register_templates( $path, $args );
134
  }
135
 
136
  /**
185
  }
186
  }
187
 
188
+ /**
189
+ * Returns the markup for creating new WP editors in the builder.
190
+ *
191
+ * @since 2.0
192
+ * @return string
193
+ */
194
+ static public function get_wp_editor() {
195
+ ob_start();
196
+
197
+ wp_editor( '{FL_EDITOR_CONTENT}', 'flbuildereditor', array(
198
+ 'media_buttons' => true,
199
+ 'wpautop' => true,
200
+ 'textarea_rows' => 16,
201
+ ) );
202
+
203
+ return ob_get_clean();
204
+ }
205
+
206
  /**
207
  * Set the default text editor to tinymce when the builder is active.
208
  *
375
  // Register additional JS
376
  wp_register_script( 'fl-slideshow', $js_url . 'fl-slideshow' . $min . '.js', array( 'yui3' ), $ver, true );
377
  wp_register_script( 'fl-gallery-grid', $js_url . 'fl-gallery-grid.js', array( 'jquery' ), $ver, true );
378
+ wp_register_script( 'jquery-bxslider', $js_url . 'jquery.bxslider.js', array( 'jquery-easing', 'jquery-fitvids' ), $ver, true );
379
+ wp_register_script( 'jquery-easing', $js_url . 'jquery.easing.min.js', array( 'jquery' ), '1.4', true );
380
+ wp_register_script( 'jquery-fitvids', $js_url . 'jquery.fitvids.min.js', array( 'jquery' ), '1.2', true );
381
+ wp_register_script( 'jquery-imagesloaded', $js_url . 'jquery.imagesloaded.min.js', array( 'jquery' ), $ver, true );
382
+ wp_register_script( 'jquery-infinitescroll', $js_url . 'jquery.infinitescroll.min.js', array( 'jquery' ), $ver, true );
383
  wp_register_script( 'jquery-magnificpopup', $js_url . 'jquery.magnificpopup.min.js', array( 'jquery' ), $ver, true );
384
  wp_register_script( 'jquery-mosaicflow', $js_url . 'jquery.mosaicflow.min.js', array( 'jquery' ), $ver, true );
385
  wp_register_script( 'jquery-waypoints', $js_url . 'jquery.waypoints.min.js', array( 'jquery' ), $ver, true );
386
  wp_register_script( 'jquery-wookmark', $js_url . 'jquery.wookmark.min.js', array( 'jquery' ), $ver, true );
387
+ wp_register_script( 'yui3', $js_url . 'yui3.min.js', array(), $ver, true );
388
 
389
+ wp_register_script( 'youtube-player', 'https://www.youtube.com/iframe_api', array(), $ver, true );
390
+ wp_register_script( 'vimeo-player', 'https://player.vimeo.com/api/player.js', array(), $ver, true );
391
  }
392
 
393
  /**
573
  */
574
  static public function enqueue_ui_styles_scripts() {
575
  if ( FLBuilderModel::is_builder_active() ) {
576
+ global $wp_the_query;
577
+
578
+ // Remove wp admin bar top margin
579
+ remove_action( 'wp_head', '_admin_bar_bump_cb' );
580
 
581
  $ver = FL_BUILDER_VERSION;
582
  $css_url = plugins_url( '/css/', FL_BUILDER_FILE );
597
  wp_enqueue_style( 'fl-lightbox', $css_url . 'fl-lightbox.css', array(), $ver );
598
  wp_enqueue_style( 'fl-icon-selector', $css_url . 'fl-icon-selector.css', array(), $ver );
599
  wp_enqueue_style( 'fl-builder', $css_url . 'fl-builder.css', array(), $ver );
600
+
601
+ // skins need to come after default ui styles
602
+ wp_enqueue_style( 'fl-builder-ui-skin-dark', $css_url . 'fl-builder-ui-skin-dark.css', array(), $ver );
603
  } else {
604
  wp_enqueue_style( 'fl-builder-min', $css_url . 'fl-builder.min.css', array(), $ver );
605
  }
636
  wp_enqueue_script( 'jquery-nanoscroller', $js_url . 'jquery.nanoscroller.min.js', array(), $ver );
637
  wp_enqueue_script( 'jquery-autosuggest', $js_url . 'jquery.autoSuggest.min.js', array(), $ver );
638
  wp_enqueue_script( 'jquery-tiptip', $js_url . 'jquery.tiptip.min.js', array(), $ver );
639
+ wp_enqueue_script( 'jquery-showhideevents', $js_url . 'jquery.showhideevents.js', array(), $ver );
640
  wp_enqueue_script( 'jquery-simulate', $js_url . 'jquery.simulate.js', array(), $ver );
641
  wp_enqueue_script( 'jquery-validate', $js_url . 'jquery.validate.min.js', array(), $ver );
642
  wp_enqueue_script( 'bootstrap-tour', $js_url . 'bootstrap-tour-standalone.min.js', array(), $ver );
643
  wp_enqueue_script( 'ace', $js_url . 'ace/ace.js', array(), $ver );
644
  wp_enqueue_script( 'ace-language-tools', $js_url . 'ace/ext-language_tools.js', array(), $ver );
645
+ wp_enqueue_script( 'mousetrap', $js_url . 'mousetrap-custom.js', array(), $ver );
646
 
647
  // Enqueue individual builder scripts if WP_DEBUG is on.
648
  if ( self::is_debug() ) {
654
  wp_enqueue_script( 'fl-builder-ajax-layout', $js_url . 'fl-builder-ajax-layout.js', array(), $ver );
655
  wp_enqueue_script( 'fl-builder-preview', $js_url . 'fl-builder-preview.js', array(), $ver );
656
  wp_enqueue_script( 'fl-builder-simulate-media-query', $js_url . 'fl-builder-simulate-media-query.js', array(), $ver );
657
+ wp_enqueue_script( 'fl-builder-responsive-editing', $js_url . 'fl-builder-responsive-editing.js', array(), $ver );
658
  wp_enqueue_script( 'fl-builder-services', $js_url . 'fl-builder-services.js', array(), $ver );
659
  wp_enqueue_script( 'fl-builder-tour', $js_url . 'fl-builder-tour.js', array(), $ver );
660
+ wp_enqueue_script( 'fl-builder-ui', $js_url . 'fl-builder-ui.js', array( 'fl-builder', 'mousetrap' ), $ver );
661
+ wp_enqueue_script( 'fl-builder-ui-main-menu', $js_url . 'fl-builder-ui-main-menu.js', array( 'fl-builder-ui' ), $ver );
662
+ wp_enqueue_script( 'fl-builder-ui-panel-content', $js_url . 'fl-builder-ui-panel-content-library.js', array( 'fl-builder-ui' ), $ver );
663
+ wp_enqueue_script( 'fl-builder-ui-settings-forms', $js_url . 'fl-builder-ui-settings-forms.js', array(), $ver );
664
+ wp_enqueue_script( 'fl-builder-ui-pinned', $js_url . 'fl-builder-ui-pinned.js', array(), $ver );
665
+ wp_enqueue_script( 'fl-builder-revisions', $js_url . 'fl-builder-revisions.js', array(), $ver );
666
+ wp_enqueue_script( 'fl-builder-search', $js_url . 'fl-builder-search.js', array( 'jquery' ), $ver );
667
+ wp_enqueue_script( 'fl-builder-save-manager', $js_url . 'fl-builder-save-manager.js', array( 'jquery' ), $ver );
668
  } else {
669
+ wp_enqueue_script( 'fl-builder-min', $js_url . 'fl-builder.min.js', array( 'jquery', 'mousetrap' ), $ver );
670
  }
671
 
672
+ // Dynamically generated settings config for the current page.
673
+ // Add to <head> via js.
674
+ $url = FLBuilderModel::get_edit_url( $wp_the_query->post->ID ) . '&fl_builder_load_settings_config';
675
+ $script = sprintf( 'var s = document.createElement("script");s.type = "text/javascript";s.src = "%s";document.head.appendChild(s);', $url );
676
+
677
+ wp_add_inline_script( 'fl-builder', $script );
678
+ wp_add_inline_script( 'fl-builder-min', $script );
679
+
680
  /* Additional module styles and scripts */
681
  foreach ( FLBuilderModel::$modules as $module ) {
682
 
692
  }// End if().
693
  }
694
 
695
+ /**
696
+ * Renders the JS config for settings forms for the current page if requested
697
+ * and dies early so it can be loaded from a script tag.
698
+ *
699
+ * @since 2.0.1
700
+ * @return void
701
+ */
702
+ static public function render_settings_config() {
703
+ if ( FLBuilderModel::is_builder_active() && isset( $_GET['fl_builder_load_settings_config'] ) ) {
704
+ header( 'Content-Type: application/javascript' );
705
+ include FL_BUILDER_DIR . 'includes/ui-settings-config.php';
706
+ die();
707
+ }
708
+ }
709
+
710
  /**
711
  * Include a jQuery fallback script when the builder is
712
  * enabled for a page.
736
  if ( FLBuilderModel::is_builder_active() ) {
737
  $classes[] = 'fl-builder-edit';
738
 
739
+ if ( true === FL_BUILDER_LITE ) {
740
+ $classes[] = 'fl-builder-lite';
741
+ }
742
+
743
  if ( ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' ) ) {
744
  $classes[] = 'fl-builder-simple';
745
  }
746
+
747
+ $user_settings = FLBuilderUserSettings::get();
748
+ $classes[] = 'fl-builder-ui-skin--' . $user_settings['skin'];
749
+
750
+ if ( FLBuilderModel::layout_has_drafted_changes() ) {
751
+ $classes[] = 'fl-builder--layout-has-drafted-changes';
752
+ }
753
  }
754
 
755
  return $classes;
768
  if ( FLBuilderModel::is_post_editable() && is_object( $wp_the_query->post ) ) {
769
 
770
  $enabled = get_post_meta( $wp_the_query->post->ID, '_fl_builder_enabled', true );
771
+ $dot = ' <span class="fl-builder-admin-bar-status-dot" style="color:' . ( $enabled ? '#6bc373' : '#d9d9d9' ) . '; font-size:18px; line-height:1;">&bull;</span>';
772
 
773
  $wp_admin_bar->add_node( array(
774
  'id' => 'fl-builder-frontend-edit-link',
824
  remove_all_actions( 'media_buttons', 999999 );
825
  remove_all_actions( 'media_buttons_context', 999999 );
826
 
827
+ // Increase available memory.
828
+ if ( function_exists( 'wp_raise_memory_limit' ) ) {
829
+ wp_raise_memory_limit( 'bb-plugin' );
830
+ }
831
+
832
  // Get the post.
833
  require_once ABSPATH . 'wp-admin/includes/post.php';
834
  $post_id = FLBuilderModel::get_post_id();
857
  $unrestricted = FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
858
  $simple_ui = ! $unrestricted;
859
  $global_settings = FLBuilderModel::get_global_settings();
 
 
 
 
 
 
860
 
861
+ include FL_BUILDER_DIR . 'includes/ui-extras.php';
 
862
  include FL_BUILDER_DIR . 'includes/ui-js-templates.php';
863
  include FL_BUILDER_DIR . 'includes/ui-js-config.php';
864
  }
865
  }
866
 
867
+ /**
868
+ * Get data structure for main builder menu.
869
+ *
870
+ * @since 2.0
871
+ * @return array
872
+ */
873
+ static function get_main_menu_data() {
874
+ global $post;
875
+
876
+ $views = array();
877
+ $is_lite = true === FL_BUILDER_LITE; // @codingStandardsIgnoreLine
878
+ $is_user_template = FLBuilderModel::is_post_user_template();
879
+ $enabled_templates = FLBuilderModel::get_enabled_templates();
880
+ $is_simple_ui = ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
881
+ $key_shortcuts = self::get_keyboard_shortcuts();
882
+ $help = FLBuilderModel::get_help_button_settings();
883
+ $default_view = array(
884
+ 'name' => __( 'Unnamed Menu', 'fl-builder' ),
885
+ 'isShowing' => false,
886
+ 'isRootView' => false,
887
+ 'items' => array(),
888
+ );
889
+
890
+ // Tools
891
+ $tools_view = array(
892
+ 'name' => __( 'Tools', 'fl-builder' ),
893
+ 'isShowing' => true,
894
+ 'isRootView' => true,
895
+ 'items' => array(),
896
+ );
897
+
898
+ if ( ! $is_lite && ! $is_user_template && ( 'enabled' == $enabled_templates || 'user' == $enabled_templates ) ) {
899
+ $tools_view['items'][10] = array(
900
+ 'label' => __( 'Save Template', 'fl-builder' ),
901
+ 'type' => 'event',
902
+ 'eventName' => 'saveTemplate',
903
+ 'accessory' => $key_shortcuts['saveTemplate']['keyLabel'],
904
+ );
905
+ }
906
+
907
+ $tools_view['items'][20] = array(
908
+ 'label' => __( 'Duplicate Layout', 'fl-builder' ),
909
+ 'type' => 'event',
910
+ 'eventName' => 'duplicateLayout',
911
+ );
912
+
913
+ $tools_view['items'][30] = array(
914
+ 'label' => __( 'Preview Layout', 'fl-builder' ),
915
+ 'type' => 'event',
916
+ 'eventName' => 'previewLayout',
917
+ 'accessory' => $key_shortcuts['previewLayout']['keyLabel'],
918
+ );
919
+
920
+ $tools_view['items'][40] = array(
921
+ 'type' => 'separator',
922
+ );
923
+
924
+ $tools_view['items'][50] = array(
925
+ 'label' => __( 'Layout CSS & Javascript', 'fl-builder' ),
926
+ 'type' => 'event',
927
+ 'eventName' => 'showLayoutSettings',
928
+ 'accessory' => $key_shortcuts['showLayoutSettings']['keyLabel'],
929
+ );
930
+
931
+ $tools_view['items'][60] = array(
932
+ 'label' => __( 'Global Settings', 'fl-builder' ),
933
+ 'type' => 'event',
934
+ 'eventName' => 'showGlobalSettings',
935
+ 'accessory' => $key_shortcuts['showGlobalSettings']['keyLabel'],
936
+ );
937
+
938
+ $tools_view['items'][70] = array(
939
+ 'type' => 'separator',
940
+ );
941
+
942
+ $tools_view['items'][80] = array(
943
+ 'label' => __( 'Change UI Brightness', 'fl-builder' ),
944
+ 'type' => 'event',
945
+ 'eventName' => 'toggleUISkin',
946
+ 'accessory' => $key_shortcuts['toggleUISkin']['keyLabel'],
947
+ );
948
+
949
+ $tools_view['items'][100] = array(
950
+ 'label' => __( 'WordPress Admin', 'fl-builder' ),
951
+ 'type' => 'view',
952
+ 'view' => 'admin',
953
+ );
954
+
955
+ if ( $help['enabled'] && ! $is_simple_ui ) {
956
+ $tools_view['items'][110] = array(
957
+ 'label' => __( 'Help', 'fl-builder' ),
958
+ 'type' => 'view',
959
+ 'view' => 'help',
960
+ );
961
+ }
962
+
963
+ $tools_view['items'][120] = array(
964
+ 'label' => __( 'Keyboard Shortcuts', 'fl-builder' ),
965
+ 'type' => 'event',
966
+ 'eventName' => 'showKeyboardShortcuts',
967
+ );
968
+
969
+ $views['main'] = wp_parse_args( $tools_view, $default_view );
970
+
971
+ // Admin
972
+ $admin_view = array(
973
+ 'name' => __( 'WordPress Admin', 'fl-builder' ),
974
+ 'items' => array(),
975
+ );
976
+
977
+ // Edit current post/page/cpt
978
+ if ( is_single( $post->ID ) || is_page( $post->ID ) ) {
979
+ $edit_label = get_post_type_object( $post->post_type )->labels->edit_item;
980
+ $admin_view['items'][10] = array(
981
+ 'label' => $edit_label,
982
+ 'type' => 'link',
983
+ 'url' => get_edit_post_link( $post->ID ),
984
+ );
985
+ }
986
+
987
+ $admin_view['items'][15] = array(
988
+ 'type' => 'separator',
989
+ );
990
+
991
+ // Dashboard
992
+ $admin_view['items'][17] = array(
993
+ 'label' => _x( 'Dashboard', 'label for the WordPress Dashboard link', 'fl-builder' ),
994
+ 'type' => 'link',
995
+ 'url' => admin_url( 'index.php' ),
996
+ );
997
+
998
+ $templates_enabled = FLBuilderUserAccess::current_user_can( 'builder_admin' );
999
+
1000
+ if ( $templates_enabled ) {
1001
+ $admin_view['items'][20] = array(
1002
+ 'label' => __( 'Manage Templates', 'fl-builder' ),
1003
+ 'type' => 'link',
1004
+ 'url' => admin_url( 'edit.php?post_type=fl-builder-template' ),
1005
+ );
1006
+ }
1007
+
1008
+ if ( current_user_can( 'customize' ) ) {
1009
+ $post_url = get_permalink( $post->ID );
1010
+ if ( $post_url ) {
1011
+ $url = admin_url( 'customize.php?url=' . $post_url );
1012
+ } else {
1013
+ $url = admin_url( 'customize.php' );
1014
+ }
1015
+ $admin_view['items'][30] = array(
1016
+ 'label' => __( 'Customize Theme', 'fl-builder' ),
1017
+ 'type' => 'link',
1018
+ 'url' => $url,
1019
+ );
1020
+ }
1021
+
1022
+ $views['admin'] = wp_parse_args( $admin_view, $default_view );
1023
+
1024
+ // Help
1025
+ if ( $help['enabled'] && ! $is_simple_ui ) {
1026
+ $help_view = array(
1027
+ 'name' => __( 'Help', 'fl-builder' ),
1028
+ 'items' => array(),
1029
+ );
1030
+
1031
+ if ( $help['video'] && isset( $help['video_embed'] ) ) {
1032
+ // Disable Auto Play
1033
+ $help['video_embed'] = str_replace( 'autoplay=1', 'autoplay=0', $help['video_embed'] );
1034
+
1035
+ // Remove Height from iframe
1036
+ $help['video_embed'] = str_replace( 'height="315"', 'height="173"', $help['video_embed'] );
1037
+
1038
+ $help_view['items'][10] = array(
1039
+ 'type' => 'video',
1040
+ 'embed' => $help['video_embed'],
1041
+ );
1042
+ }
1043
+
1044
+ if ( $help['tour'] ) {
1045
+ $help_view['items'][20] = array(
1046
+ 'label' => __( 'Take A Tour', 'fl-builder' ),
1047
+ 'type' => 'event',
1048
+ 'eventName' => 'beginTour',
1049
+ );
1050
+ }
1051
+
1052
+ if ( $help['knowledge_base'] && isset( $help['knowledge_base_url'] ) ) {
1053
+ $help_view['items'][30] = array(
1054
+ 'label' => __( 'View Knowledge Base', 'fl-builder' ),
1055
+ 'type' => 'link',
1056
+ 'url' => $help['knowledge_base_url'],
1057
+ );
1058
+ }
1059
+
1060
+ if ( $help['forums'] && isset( $help['forums_url'] ) ) {
1061
+ $help_view['items'][40] = array(
1062
+ 'label' => __( 'Contact Support', 'fl-builder' ),
1063
+ 'type' => 'link',
1064
+ 'url' => $help['forums_url'],
1065
+ );
1066
+ }
1067
+
1068
+ $views['help'] = wp_parse_args( $help_view, $default_view );
1069
+ }// End if().
1070
+
1071
+ return apply_filters( 'fl_builder_main_menu', $views );
1072
+ }
1073
+
1074
+ /**
1075
+ * Get array of registered keyboard shortcuts. The key corresponds to
1076
+ * an event to be triggered by FLbuilder.triggerHook()
1077
+ *
1078
+ * @since 2.0
1079
+ * @return array
1080
+ */
1081
+ static function get_keyboard_shortcuts() {
1082
+ $default_action = array(
1083
+ 'label' => _x( 'Untitled Shortcut', 'A keyboard shortcut with no label given', 'fl-builder' ),
1084
+ 'keyCode' => '',
1085
+ 'keyLabel' => '',
1086
+ 'isGlobal' => false,
1087
+ 'enabled' => true,
1088
+ );
1089
+ $data = array(
1090
+ 'showModules' => array(
1091
+ 'label' => _x( 'Open Modules Tab', 'Keyboard action to show modules tab', 'fl-builder' ),
1092
+ 'keyCode' => 'j',
1093
+ ),
1094
+ 'showRows' => array(
1095
+ 'label' => _x( 'Open Rows Tab', 'Keyboard action to show rows tab', 'fl-builder' ),
1096
+ 'keyCode' => 'k',
1097
+ ),
1098
+ 'showTemplates' => array(
1099
+ 'label' => _x( 'Open Templates Tab', 'Keyboard action to show templates tab', 'fl-builder' ),
1100
+ 'keyCode' => 'l',
1101
+ ),
1102
+ 'showSaved' => array(
1103
+ 'label' => _x( 'Open Saved Tab', 'Keyboard action to show saved tab', 'fl-builder' ),
1104
+ 'keyCode' => ';',
1105
+ 'enabled' => true !== FL_BUILDER_LITE,
1106
+ ),
1107
+ 'saveTemplate' => array(
1108
+ 'label' => _x( 'Save New Template', 'Keyboard action to open save template form', 'fl-builder' ),
1109
+ 'keyCode' => 'mod+j',
1110
+ 'enabled' => true !== FL_BUILDER_LITE,
1111
+ ),
1112
+ 'previewLayout' => array(
1113
+ 'label' => _x( 'Toggle Preview Mode', 'Keyboard action to toggle preview mode', 'fl-builder' ),
1114
+ 'keyCode' => 'p',
1115
+ ),
1116
+ 'showGlobalSettings' => array(
1117
+ 'label' => _x( 'Open Global Settings', 'Keyboard action to open the global settings panel', 'fl-builder' ),
1118
+ 'keyCode' => 'mod+u',
1119
+ ),
1120
+ 'showLayoutSettings' => array(
1121
+ 'label' => _x( 'Open Layout Settings', 'Keyboard action to open the layout settings panel', 'fl-builder' ),
1122
+ 'keyCode' => 'mod+y',
1123
+ ),
1124
+ 'toggleUISkin' => array(
1125
+ 'label' => _x( 'Change UI Brightness', 'Keyboard action to switch between light and dark UI brightness', 'fl-builder' ),
1126
+ 'keyCode' => 'o',
1127
+ ),
1128
+ 'showSearch' => array(
1129
+ 'label' => _x( 'Display Module Search', 'Keyboard action to open the module search panel', 'fl-builder' ),
1130
+ 'keyCode' => 'mod+i',
1131
+ 'enabled' => true !== FL_BUILDER_LITE,
1132
+ ),
1133
+ 'showSavedMessage' => array(
1134
+ 'label' => _x( 'Save Layout', 'Keyboard action to save changes', 'fl-builder' ),
1135
+ 'keyCode' => 'mod+s',
1136
+ 'isGlobal' => true,
1137
+ ),
1138
+ 'publishAndRemain' => array(
1139
+ 'label' => _x( 'Publish changes without leaving builder', 'Keyboard action to publish any pending changes', 'fl-builder' ),
1140
+ 'keyCode' => 'mod+p',
1141
+ 'isGlobal' => true,
1142
+ ),
1143
+ 'cancelTask' => array(
1144
+ 'label' => _x( 'Dismiss Active Panel', 'Keyboard action to dismiss the current task or panel', 'fl-builder' ),
1145
+ 'keyCode' => 'esc',
1146
+ 'isGlobal' => true,
1147
+ ),
1148
+ );
1149
+
1150
+ $data = apply_filters( 'fl_builder_keyboard_shortcuts', $data );
1151
+
1152
+ foreach ( $data as $hook => $args ) {
1153
+
1154
+ // Check for old (alpha) format and normalize
1155
+ if ( is_string( $args ) ) {
1156
+ $args = array(
1157
+ 'label' => ucwords( preg_replace( '/([^A-Z])([A-Z])/', '$1 $2', $hook ) ),
1158
+ 'keyCode' => $args,
1159
+ );
1160
+ }
1161
+
1162
+ $args = wp_parse_args( $args, $default_action );
1163
+
1164
+ // Unset this shortcut if it's not enabled.
1165
+ if ( ! $args['enabled'] ) {
1166
+ unset( $data[ $hook ] );
1167
+ continue;
1168
+ }
1169
+
1170
+ // Map 'mod' to mac or pc equivalent
1171
+ $code = $args['keyCode'];
1172
+ $code = str_replace( '+', '', $code );
1173
+
1174
+ if ( false !== strpos( $code, 'mod' ) ) {
1175
+ $is_mac = strpos( $_SERVER['HTTP_USER_AGENT'], 'Macintosh' ) ? true : false;
1176
+
1177
+ if ( $is_mac ) {
1178
+ $code = str_replace( 'mod', 'command', $code );
1179
+ } else {
1180
+ $code = str_replace( 'mod', 'Ctrl+', $code );
1181
+ }
1182
+ }
1183
+
1184
+ // Replace 'command'
1185
+ $code = str_replace( 'command', '&#8984;', $code );
1186
+
1187
+ // Replace 'shift'
1188
+ $code = str_replace( 'shift', '&#x21E7;', $code );
1189
+
1190
+ // Replace 'delete'
1191
+ $code = str_replace( 'delete', '&#x232b;', $code );
1192
+
1193
+ // Replace 'left' arrow
1194
+ $code = str_replace( 'left', '&larr;', $code );
1195
+
1196
+ // Replace 'right' arrow
1197
+ $code = str_replace( 'right', '&rarr;', $code );
1198
+
1199
+ $args['keyLabel'] = $code;
1200
+ $data[ $hook ] = $args;
1201
+ } // End foreach().
1202
+
1203
+ return $data;
1204
+ }
1205
+
1206
  /**
1207
  * Renders the markup for the title in the builder's bar.
1208
  *
1210
  * @return void
1211
  */
1212
  static public function render_ui_bar_title() {
 
 
1213
 
1214
+ global $post;
1215
+ $simple_ui = ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
1216
+
1217
+ $title = apply_filters( 'fl_builder_ui_bar_title', get_the_title( $post->ID ) );
1218
+ $icon_url = FLBuilderModel::get_branding_icon();
1219
+ $wrapper_classes = array( 'fl-builder-bar-title' );
1220
+
1221
+ if ( '' == $icon_url ) {
1222
+ $wrapper_classes[] = 'fl-builder-bar-title-no-icon';
 
 
 
 
 
1223
  }
1224
+
1225
+ $edited_object_label = get_post_type_object( $post->post_type )->labels->singular_name;
1226
+ $pretitle = sprintf( _x( 'Currently Editing %s', 'Currently editing message', 'fl-builder' ), $edited_object_label );
1227
+ $pretitle = apply_filters( 'fl_builder_ui_bar_pretitle', $pretitle );
1228
+
1229
+ // Render the bar title.
1230
+ include FL_BUILDER_DIR . 'includes/ui-bar-title-area.php';
1231
  }
1232
 
1233
  /**
1237
  * @return void
1238
  */
1239
  static public function render_ui_bar_buttons() {
1240
+ $help_button = FLBuilderModel::get_help_button_settings();
1241
+ $simple_ui = ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
1242
+ $should_display_search = ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui;
1243
+
1244
+ $add_btn_svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="24" height="24"><rect x="0" fill="none" width="24" height="24" /><g><path d="M17 9v2h-6v6H9v-6H3V9h6V3h2v6h6z"/></g></svg>';
1245
 
1246
  $buttons = apply_filters( 'fl_builder_ui_bar_buttons', array(
 
 
 
 
1247
  'upgrade' => array(
1248
  'label' => __( 'Upgrade Today <i class="fa fa-external-link-square"></i>', 'fl-builder' ),
1249
  'show' => true === FL_BUILDER_LITE,
1254
  ),
1255
  'done' => array(
1256
  'label' => __( 'Done', 'fl-builder' ),
 
1257
  ),
1258
+ 'content-panel' => array(
1259
+ 'label' => $add_btn_svg,
1260
  'show' => ! $simple_ui,
1261
  ),
1262
+ 'add-content' => array( // Only added here for backwards compat.
1263
+ 'label' => $add_btn_svg,
 
 
 
 
1264
  'show' => ! $simple_ui,
1265
  ),
1266
  ) );
1267
 
1268
  echo '<div class="fl-builder-bar-actions">';
1269
 
1270
+ $i = 0;
1271
+
1272
  foreach ( $buttons as $slug => $button ) {
1273
 
1274
+ if ( 'add-content' == $slug ) {
1275
+ continue; // The old add content button is no longer supported.
1276
+ }
1277
+
1278
  if ( isset( $button['show'] ) && ! $button['show'] ) {
1279
  continue;
1280
  }
1281
 
1282
+ echo '<button class="fl-builder-' . $slug . '-button fl-builder-button';
1283
 
1284
  if ( isset( $button['class'] ) ) {
1285
  echo ' ' . $button['class'];
1286
  }
1287
 
1288
+ echo '">' . $button['label'] . '</button>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1289
 
1290
+ $i++;
 
1291
  }
 
1292
 
1293
+ /*
1294
+ if ( $should_display_search ) {
 
 
 
 
 
 
 
 
1295
 
1296
+ echo '<span class="fl-builder--search fl-builder-button">';
1297
+ echo '<input type="text" id="fl-builder-search-input" placeholder="' . __( 'Search', 'fl-builder' ) . '">';
1298
+ echo '<span class="search-clear">' . __( 'Clear', 'fl-builder' ) . '</span>';
1299
+ echo '</span>';
1300
  }
1301
+ */
1302
+ echo '<span class="fl-builder--saving-indicator"></span>';
1303
+ echo '</div>';
1304
  }
1305
 
1306
  /**
1318
  */
1319
  static public function render_query( $args, $site_id = null ) {
1320
  global $post;
 
1321
  $switched = false;
1322
 
1323
  // Pull from a site on the network?
1326
  $switched = true;
1327
  }
1328
 
1329
+ // Get the query.
1330
+ $query = new WP_Query( $args );
 
 
 
 
 
1331
 
1332
  // Loop through the posts.
1333
+ foreach ( $query->posts as $query_post ) {
 
 
 
1334
 
1335
  // Make sure this isn't the same post as the original post to prevent infinite loops.
1336
+ if ( is_object( $post ) && $post->ID === $query_post->ID && ! $switched ) {
1337
  continue;
1338
  }
1339
 
1340
+ if ( FLBuilderModel::is_builder_enabled( $query_post->ID ) ) {
 
1341
 
1342
+ // Enqueue styles and scripts for this post.
1343
+ self::enqueue_layout_styles_scripts_by_id( $query_post->ID );
 
 
1344
 
1345
+ // Print the styles since we are outside of the head tag.
1346
+ wp_print_styles();
1347
 
1348
+ // Render the builder content.
1349
+ FLBuilder::render_content_by_id( $query_post->ID );
 
 
1350
 
1351
+ } else {
 
 
1352
 
1353
+ // Render the WP editor content if the builder isn't enabled.
1354
+ echo apply_filters( 'the_content', $query_post->post_content );
1355
+ }
1356
+ }
1357
 
1358
  // Reset the site data?
1359
  if ( $site_id && is_multisite() ) {
1403
 
1404
  // Process shortcodes.
1405
  if ( apply_filters( 'fl_builder_render_shortcodes', true ) ) {
1406
+ global $wp_embed;
1407
  $content = apply_filters( 'fl_builder_before_render_shortcodes', $content );
1408
+ $pattern = get_shortcode_regex();
1409
+ $content = preg_replace_callback( "/$pattern/s", 'FLBuilder::double_escape_shortcodes', $content );
1410
+ $content = $wp_embed->run_shortcode( $content );
1411
  $content = do_shortcode( $content );
1412
  }
1413
 
1437
  * @return string
1438
  */
1439
  static public function render_content( $content ) {
1440
+ $post_id = FLBuilderModel::get_post_id( true );
1441
+ $enabled = FLBuilderModel::is_builder_enabled( $post_id );
1442
  $rendering = $post_id === self::$post_rendering;
1443
  $do_render = apply_filters( 'fl_builder_do_render_content', true, $post_id );
1444
  $in_loop = in_the_loop();
1449
  // Set the post rendering ID.
1450
  self::$post_rendering = $post_id;
1451
 
 
 
 
 
 
 
1452
  // Render the content.
1453
  ob_start();
1454
+ self::render_content_by_id( $post_id );
1455
+ $content = ob_get_clean();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1456
 
1457
  // Clear the post rendering ID.
1458
  self::$post_rendering = null;
1459
+ }
1460
 
1461
  return $content;
1462
  }
1635
  // Remove empty lines.
1636
  $content = preg_replace( '/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $content );
1637
 
1638
+ return apply_filters( 'fl_builder_editor_content', $content );
1639
  }
1640
 
1641
  /**
1642
+ * Renders a settings via PHP. This method is only around for
1643
+ * backwards compatibility with third party settings forms that are
1644
+ * still being rendered via AJAX. Going forward, all settings forms
1645
+ * should be rendered on the frontend using FLBuilderSettingsForms.render.
1646
  *
1647
  * @since 1.0
1648
  * @param array $form The form data.
1650
  * @return array
1651
  */
1652
  static public function render_settings( $form = array(), $settings ) {
1653
+ return FLBuilderUISettingsForms::render_settings( $form, $settings );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1654
  }
1655
 
1656
  /**
1657
+ * Renders a settings form via PHP. This method is only around for
1658
+ * backwards compatibility with third party settings forms that are
1659
+ * still being rendered via AJAX. Going forward, all settings forms
1660
+ * should be rendered on the frontend using FLBuilderSettingsForms.render.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1661
  *
1662
  * @since 1.0
1663
  * @param string $type The type of form to render.
1665
  * @return array
1666
  */
1667
  static public function render_settings_form( $type = null, $settings = null ) {
1668
+ return FLBuilderUISettingsForms::render_settings_form( $type, $settings );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1669
  }
1670
 
1671
  /**
1672
+ * Renders a settings field via PHP. This method is only around for
1673
+ * backwards compatibility with third party settings forms that are
1674
+ * still being rendered via AJAX. Going forward, all settings forms
1675
+ * should be rendered on the frontend using FLBuilderSettingsForms.render.
1676
  *
1677
  * @since 1.0
1678
+ * @param string $name The field name.
1679
+ * @param array $field An array of setup data for the field.
1680
+ * @param object $settings Form settings data object.
1681
+ * @return void
1682
  */
1683
+ static public function render_settings_field( $name, $field, $settings = null ) {
1684
+ return FLBuilderUISettingsForms::render_settings_field( $name, $field, $settings );
 
 
 
 
 
 
 
 
 
1685
  }
1686
 
1687
  /**
1691
  * @return array
1692
  */
1693
  static public function render_icon_selector() {
1694
+ return FLBuilderUISettingsForms::render_icon_selector();
 
 
 
 
 
 
 
 
1695
  }
1696
 
1697
  /**
1829
  echo ' fl-node-content';
1830
  }
1831
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1832
  /**
1833
  * Renders the markup for a column group.
1834
  *
1917
  }
1918
  }
1919
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1920
  /**
1921
  * Renders the HTML attributes for a single column.
1922
  *
2014
  do_action( 'fl_builder_after_render_module', $module );
2015
  }
2016
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2017
  /**
2018
  * Renders the markup for a single module. This can be used to render
2019
  * the markup of a module within another module by passing the type
2682
 
2683
  // Add the layout settings JS.
2684
  $js .= self::render_global_nodes_custom_code( 'js' );
2685
+ $js .= ( is_array( $layout_settings->js ) || is_object( $layout_settings->js ) ) ? json_encode( $layout_settings->js ) : $layout_settings->js;
2686
 
2687
  // Call the FLBuilder._renderLayoutComplete method if we're currently editing.
2688
  if ( stristr( $asset_info['js'], '-draft.js' ) || stristr( $asset_info['js'], '-preview.js' ) ) {
2886
  return $code;
2887
  }
2888
 
2889
+ /**
2890
+ * Check if publish should require page to refresh.
2891
+ *
2892
+ * @since 2.0
2893
+ * @return void
2894
+ */
2895
+ static public function should_refresh_on_publish() {
2896
+ $refresh = ! is_admin_bar_showing();
2897
+ return apply_filters( 'fl_builder_should_refresh_on_publish', $refresh );
2898
+ }
2899
+
2900
  /**
2901
  * Custom logging function that handles objects and arrays.
2902
  *
3043
  FLBuilderUserTemplates::render_node_settings( $node_id );
3044
  }
3045
  }
3046
+
3047
+ /**
3048
+ * @since 1.0
3049
+ * @deprecated 2.0
3050
+ */
3051
+ static public function render_template_selector() {
3052
+ _deprecated_function( __METHOD__, '2.0' );
3053
+
3054
+ return array(
3055
+ 'html' => '',
3056
+ );
3057
+ }
3058
+
3059
+ /**
3060
+ * @since 1.8
3061
+ * @deprecated 2.0
3062
+ */
3063
+ static public function render_ui_panel_row_templates() {
3064
+ _deprecated_function( __METHOD__, '2.0' );
3065
+ }
3066
+
3067
+ /**
3068
+ * @since 1.8
3069
+ * @deprecated 2.0
3070
+ */
3071
+ static public function render_ui_panel_modules_templates() {
3072
+ _deprecated_function( __METHOD__, '2.0' );
3073
+ }
3074
+
3075
+ /**
3076
+ * @since 1.8
3077
+ * @deprecated 2.0
3078
+ */
3079
+ static public function render_layout_settings() {
3080
+ _deprecated_function( __METHOD__, '2.0' );
3081
+ }
3082
+
3083
+ /**
3084
+ * @since 1.0
3085
+ * @deprecated 2.0
3086
+ */
3087
+ static public function render_global_settings() {
3088
+ _deprecated_function( __METHOD__, '2.0' );
3089
+ }
3090
+
3091
+ /**
3092
+ * @since 1.0
3093
+ * @deprecated 2.0
3094
+ */
3095
+ static public function render_row_settings( $node_id = null ) {
3096
+ _deprecated_function( __METHOD__, '2.0' );
3097
+ }
3098
+
3099
+ /**
3100
+ * @since 1.0
3101
+ * @deprecated 2.0
3102
+ */
3103
+ static public function render_column_settings( $node_id = null ) {
3104
+ _deprecated_function( __METHOD__, '2.0' );
3105
+ }
3106
+
3107
+ /**
3108
+ * @since 1.0
3109
+ * @deprecated 2.0
3110
+ */
3111
+ static public function render_module_settings( $node_id = null, $type = null, $parent_id = null, $render_state = true ) {
3112
+ _deprecated_function( __METHOD__, '2.0' );
3113
+ }
3114
  }
3115
 
3116
  FLBuilder::init();
css/fl-builder-layout.css CHANGED
@@ -178,6 +178,9 @@
178
  min-height: 100vh;
179
 
180
  }
 
 
 
181
  .fl-row-full-height .fl-row-content {
182
  -webkit-box-flex: 1 1 auto;
183
  -moz-box-flex: 1 1 auto;
@@ -292,6 +295,11 @@
292
  -ms-flex-wrap: wrap;
293
  flex-wrap: wrap;
294
  }
 
 
 
 
 
295
  .fl-col-group-equal-height .fl-col,
296
  .fl-col-group-equal-height .fl-col-content{
297
  -webkit-box-flex: 1 1 auto;
@@ -688,6 +696,7 @@ img.mfp-img {
688
  }
689
  .fl-builder-mobile .fl-animation,
690
  .fl-builder-edit .fl-animation,
 
691
  .fl-animated {
692
  opacity: 1;
693
  }
178
  min-height: 100vh;
179
 
180
  }
181
+ .fl-builder-edit .fl-row-full-height .fl-row-content-wrap {
182
+ min-height: calc( 100vh - 48px );
183
+ }
184
  .fl-row-full-height .fl-row-content {
185
  -webkit-box-flex: 1 1 auto;
186
  -moz-box-flex: 1 1 auto;
295
  -ms-flex-wrap: wrap;
296
  flex-wrap: wrap;
297
  }
298
+ .fl-col-group-equal-height.fl-col-group-has-child-loading {
299
+ -webkit-flex-wrap: nowrap;
300
+ -ms-flex-wrap: nowrap;
301
+ flex-wrap: nowrap;
302
+ }
303
  .fl-col-group-equal-height .fl-col,
304
  .fl-col-group-equal-height .fl-col-content{
305
  -webkit-box-flex: 1 1 auto;
696
  }
697
  .fl-builder-mobile .fl-animation,
698
  .fl-builder-edit .fl-animation,
699
+ .fl-builder-preview .fl-animation,
700
  .fl-animated {
701
  opacity: 1;
702
  }
css/fl-builder-ui-skin-dark.css ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body.fl-builder-ui-skin--dark .fl-builder-bar .fl-builder-bar-content,
2
+ .fl-builder-ui-skin--dark .fl-lightbox,
3
+ .fl-builder-ui-skin--dark .fl-builder-panel,
4
+ .fl-builder-ui-skin--dark .fl-builder--main-menu-panel,
5
+ .fl-builder-ui-skin--dark .fl-builder--search-results-panel,
6
+ .fl-builder-ui-skin--dark .fl-builder--preview-actions {
7
+ background:#23282d;
8
+ color:#b4b9be;
9
+ border-color: #1d1d1d;
10
+ }
11
+ .fl-builder-ui-skin--dark .fl-builder--panel-header {
12
+ background:#1d2227;
13
+ color:#b4b9be;
14
+ border-bottom-color: #1d1d1d;
15
+ border-top-color: #1d1d1d;
16
+ }
17
+ .fl-builder-ui-skin--dark .fl-builder-panel.fl-builder-ui-pinned .fl-builder--panel-header {
18
+ border-top-color: #1d2227;
19
+ }
20
+ /* Panel arrows */
21
+ .fl-builder-ui-skin--dark .fl-builder--main-menu-panel:before {
22
+ border-bottom-color:#1d1d1d;
23
+ }
24
+ .fl-builder-ui-skin--dark .fl-builder--panel-arrow polygon {
25
+ fill: #1d1d1d;
26
+ }
27
+ .fl-builder-ui-skin--dark .fl-builder-panel-search .fl-builder-panel-search-input {
28
+ background: #1e2228;
29
+ }
30
+ .fl-builder-ui-skin--dark .fl-responsive-preview-content {
31
+ background:#131619;
32
+ }
33
+ .fl-builder-ui-skin--dark .fl-form-table th {
34
+ background:#23282d !important;
35
+ color:#7d8690;
36
+ }
37
+ .fl-builder-ui-skin--dark .fl-builder-button,
38
+ .fl-builder-ui-skin--dark .fl-builder--preview-actions .device-icons {
39
+ background: #383f46;
40
+ }
41
+ .fl-builder-ui-skin--dark .fl-builder-button:focus {
42
+ background: #131a22;
43
+ }
44
+ .fl-builder-ui-skin--dark .fl-builder-button.fl-builder-button-primary {
45
+ color: white !important;
46
+ fill: white !important;
47
+ background: #00A0D2;
48
+ }
49
+ .fl-builder-ui-skin--dark .fl-builder-button.fl-builder-button-silent:focus {
50
+ border: 2px solid #00a0d2 !important;
51
+ }
52
+ .fl-builder-ui-skin--dark .fl-builder-content-panel-button,
53
+ .fl-builder-ui-skin--dark .fl-builder-content-panel--button:hover {
54
+ color: #00A0D2 !important;
55
+ }
56
+ .fl-builder-ui-skin--dark .fl-builder--menu > a:hover,
57
+ .fl-builder-ui-skin--dark .fl-builder--menu > button:hover {
58
+ background: #101215 !important;
59
+ }
60
+ .fl-builder-ui-skin--dark .fl-builder--menu > a:focus,
61
+ .fl-builder-ui-skin--dark .fl-builder--menu > button:focus {
62
+ background: #101215 !important;
63
+ color: #ffffff !important;
64
+ }
65
+ .fl-builder-ui-skin--dark .fl-builder-bar-title {
66
+ border-color: #101215;
67
+ }
68
+ .fl-builder-ui-skin--dark .fl-builder-bar-title:hover {
69
+ background-color:#181b1f;
70
+ }
71
+ .fl-builder-simple.fl-builder-ui-skin--dark .fl-builder-bar-title:hover {
72
+ background-color:transparent;
73
+ }
74
+ .fl-builder-ui-skin--dark .fl-builder-layout-title {
75
+ color: #c6cdd6;
76
+ }
77
+ .fl-builder-ui-skin--dark .fl-builder-layout-pretitle,
78
+ .fl-builder-ui-skin--dark .fl-builder-bar-title-caret i,
79
+ .fl-builder-ui-skin--dark .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title {
80
+ color: #7d8690;
81
+ }
82
+ .fl-builder-ui-skin--dark button.fl-builder-button.fl-builder-bar-title-caret:focus {
83
+ background-color: #101215 !important;
84
+ }
85
+ .fl-builder-ui-skin--dark .fl-builder--search:before {
86
+ color: rgba(162, 173, 184, 0.73);
87
+ }
88
+ .fl-builder-ui-skin--dark .fl-builder--search input:focus::-webkit-input-placeholder {
89
+ color: rgba(162, 173, 184, 0.73) !important;
90
+ }
91
+ .fl-builder-ui-skin--dark .fl-builder--search .search-clear {
92
+ color: rgba(162, 173, 184, 0.5);
93
+ background-color: #e4e4e4;
94
+ background: linear-gradient(to left, #383f46, #383f46 75%, rgba(56, 63, 70, 0) );
95
+ }
96
+
97
+ .fl-builder-ui-skin--dark .fl-builder--menu hr {
98
+ background-color: #23282d !important;
99
+ border:none;
100
+ }
101
+ .fl-builder-ui-skin--dark .fl-builder--tabs {
102
+ border-color: #383f46 !important;
103
+ }
104
+ .fl-builder-ui-skin--dark .fl-builder--tabs > *.is-showing,
105
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs a.fl-active,
106
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs-more.fl-contains-active {
107
+ color: #ffffff !important;
108
+ fill: #ffffff !important;
109
+ background: #383f46;
110
+ }
111
+ .fl-builder-ui-skin--dark .fl-builder--tabs > *:focus {
112
+ background-color: #101215 !important;
113
+ color: #ffffff !important;
114
+ }
115
+ .fl-builder-ui-skin--dark .fl-builder--tabs > *.is-showing:focus {
116
+ color: #00a0d2 !important;
117
+ }
118
+
119
+ .fl-builder-ui-skin--dark .fl-builder--menu-item:hover {
120
+ background: #383f46;
121
+ color: #a8b3bf;
122
+ }
123
+ .fl-builder-ui-skin--dark .fl-builder--menu * .fl-builder--menu-item-accessory {
124
+ color:#7d8690;
125
+ }
126
+ .fl-builder-ui-skin--dark .fl-builder-blocks-section-group-name {
127
+ color: #7d8690;
128
+ }
129
+ .fl-builder-ui-skin--dark .fl-builder--category-select{
130
+ background: #171b1f;
131
+ }
132
+ .fl-builder-ui-skin--dark .fl-builder--selector-display {
133
+ color: #c6cdd6;
134
+ background: #171b1f url(../img/svg/select-arrow-down-alt2-light.svg) no-repeat center right 10px !important
135
+ }
136
+ .fl-builder-ui-skin--dark .fl-builder--selector-display-label,
137
+ .fl-builder-ui-skin--dark .fl-builder-panel-search-input input {
138
+ border-color: #5b656f;
139
+ color: #b5becb;
140
+ }
141
+ .fl-builder-ui-skin--dark .fl-builder-panel-search-input input {
142
+ background: #171b1f !important;
143
+ }
144
+ .fl-builder-ui-skin--dark .fl-builder--selector-display-label:focus,
145
+ .fl-builder-ui-skin--dark .fl-builder-panel-search-input input:focus {
146
+ border-color: #00a0d2;
147
+ }
148
+ .fl-builder-ui-skin--dark .fl-builder--group-label {
149
+ color: #171b1f !important;
150
+ background: #5b656f;
151
+ }
152
+ .fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu {
153
+ border-color: #101215 !important;
154
+ color: #7c858e;
155
+ background-color: #101215;
156
+ }
157
+ .fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu:before {
158
+ border-bottom-color: #101215;
159
+ }
160
+ .fl-builder-ui-skin--dark .fl-builder--menu > span,
161
+ .fl-builder-ui-skin--dark .fl-builder--menu > a,
162
+ .fl-builder-ui-skin--dark .fl-builder--menu > button {
163
+ color: #a1adb9;
164
+ }
165
+ .fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu .fl-builder--menu-item:hover {
166
+ background: #23282d !important;
167
+ color: #a1adb9;
168
+ }
169
+ .fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu .fl-builder--menu-item:focus {
170
+ background: #23282d !important;
171
+ color: #00a0d2 !important;
172
+ }
173
+
174
+ .fl-builder-ui-skin--dark .fl-builder-panel-drag-handle {
175
+ fill: #5b656f;
176
+ }
177
+
178
+ .fl-builder-ui-skin--dark .fl-builder-blocks-section .fl-builder-blocks-section-title,
179
+ .fl-builder-ui-skin--dark .fl-builder--template-collection-section-name,
180
+ .fl-builder-ui-skin--dark .fl-builder--user-templates-section-name {
181
+ color: #969ea7;
182
+ background: #171b1f;
183
+ }
184
+
185
+ .fl-builder-ui-skin--dark .fl-builder-blocks-section-content .fl-builder-block,
186
+ .fl-builder-ui-skin--dark .fl-user-template {
187
+ color: #b8c2ce;
188
+ }
189
+ .fl-builder-ui-skin--dark .fl-builder-block:hover .fl-builder-block-content,
190
+ .fl-builder-ui-skin--dark .fl-user-template:hover {
191
+ background: #171b1f;
192
+ color: #ffffff;
193
+ }
194
+ .fl-builder-ui-skin--dark .fl-builder-block:hover i,
195
+ .fl-builder-ui-skin--dark .fl-user-template:hover i {
196
+ color: #6d7782 !important;
197
+ }
198
+ .fl-builder-ui-skin--dark .fl-builder-block:hover a:hover i,
199
+ .fl-builder-ui-skin--dark .fl-user-template:hover a:hover i {
200
+ color: #9eacbb !important;
201
+ }
202
+
203
+ .fl-builder-ui-skin--dark .fl-builder-block .fl-builder-block-icon {
204
+ fill: #b5becb;
205
+ }
206
+
207
+ .fl-builder-ui-skin--dark .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col,
208
+ .fl-builder-ui-skin--dark .fl-builder-block:hover .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col {
209
+ background: #7d8690;
210
+ }
211
+
212
+ .fl-builder-ui-skin--dark .fl-builder-settings-section,
213
+ .fl-builder-ui-skin--dark .fl-builder-blocks-section {
214
+ border-top: 2px solid #171b1f;
215
+ }
216
+ .fl-builder-ui-skin--dark .fl-user-templates {
217
+ border-color: #101215;
218
+ }
219
+ .fl-builder-ui-skin--dark .fl-builder--template-thumbnail {
220
+ border-color: #393f44;
221
+ }
222
+ .fl-builder-ui-skin--dark .fl-builder--menu a.fl-template-collection {
223
+ color: #a8b3bf;
224
+ }
225
+ .fl-builder-ui-skin--dark .fl-lightbox-header-wrap {
226
+ background: #1d2227;
227
+ border-bottom-color: #131a22;
228
+ }
229
+ .fl-builder-ui-skin--dark .fl-lightbox .fl-lightbox-header h1 {
230
+ color: white !important
231
+ }
232
+ .fl-builder-ui-skin--dark .fl-form-table th label {
233
+ color: #a8b3bf !important;
234
+ }
235
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs {
236
+ border-color: #383f46 !important;
237
+ }
238
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields h3.fl-builder-settings-title {
239
+ background: #1b2025;
240
+ }
241
+ .fl-builder-ui-skin--dark h3.fl-builder-settings-title .fl-builder-settings-title-text-wrap {
242
+ color: #a8b3bf;
243
+ background-color: #1b2025;
244
+ }
245
+ .fl-builder-ui-skin--dark .fl-lightbox *:not(i) {
246
+ color: #7d8690 !important;
247
+ }
248
+ .fl-builder-ui-skin--dark .fl-builder-button {
249
+ color: #c6cdd6 !important;
250
+ fill: #c6cdd6 !important;
251
+ }
252
+ .fl-builder-ui-skin--dark .fl-builder-content-panel-button,
253
+ .fl-builder-ui-skin--dark .fl-builder-content-panel--button:hover {
254
+ color: #00A0D2 !important;
255
+ fill: #00A0D2 !important;
256
+ }
257
+ .fl-builder-ui-skin--dark .fl-lightbox .fl-builder-button.fl-builder-button-primary {
258
+ color: #ffffff !important;
259
+ }
260
+ .fl-builder-ui-skin--dark .fl-color-picker {
261
+ background: #131a22;
262
+ }
263
+ .fl-color-picker-color.fl-color-picker-empty .fl-color-picker-icon {
264
+ fill:#6f7881;
265
+ }
266
+ .fl-builder-ui-skin--dark .fl-color-picker-clear {
267
+ background-color: #191d21;
268
+ }
269
+ .fl-builder-ui-skin--dark .fl-color-picker-clear:hover {
270
+ background-color: #373f46;
271
+ }
272
+ .fl-builder-ui-skin--dark span.fl-builder-block-no-node-templates:hover {
273
+ background: #1d2025;
274
+ }
275
+
276
+ .fl-builder-ui-skin--dark .fl-builder-settings-tab-description {
277
+ background: #1d2227;
278
+ }
279
+ .fl-builder-ui-skin--dark .fl-builder-panel-search button svg .filled-shape {
280
+ fill: #b5becb;
281
+ }
282
+
283
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields textarea,
284
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=text],
285
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=password],
286
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=file],
287
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=email],
288
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=number],
289
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=search],
290
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=tel],
291
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=url],
292
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields select,
293
+ .fl-builder-ui-skin--dark .fl-builder-custom-field {
294
+ background-color: #131a22 !important;
295
+ }
296
+
297
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields textarea:focus,
298
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=text]:focus,
299
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=password]:focus,
300
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=file]:focus,
301
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=email]:focus,
302
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=number]:focus,
303
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=search]:focus,
304
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=tel]:focus,
305
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=url]:focus,
306
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields select:focus {
307
+ border-color: #00a0d2 !important;
308
+ color: white !important;
309
+ }
310
+
311
+ .fl-builder-ui-skin--dark .fl-builder-settings-fields select {
312
+ background-image: url(../img/svg/select-arrow-down-alt2-light.svg) !important;
313
+ }
314
+
315
+ .fl-builder-ui-skin--dark .fl-photo-field select,
316
+ .fl-builder-ui-skin--dark .fl-builder-custom-field select {
317
+ border-color: #7d8690 !important;
318
+ }
319
+
320
+ .fl-builder-ui-skin--dark .fl-field i.fl-field-responsive-toggle {
321
+ color: #6b747d;
322
+ }
323
+ .fl-builder-ui-skin--dark .fl-field i.fl-field-responsive-toggle:hover {
324
+ color: #a8b3bf;
325
+ }
326
+
327
+ .fl-builder-ui-skin--dark .fl-builder--main-menu-panel-view-title {
328
+ color: #a8b3bf;
329
+ }
330
+ .fl-builder-ui-skin--dark .fl-builder--saving-indicator {
331
+ color: #858f99;
332
+ }
333
+
334
+ .fl-builder-ui-skin--dark .fl-icons-list i:hover {
335
+ background-color: #16191d;
336
+ color:white;
337
+ }
338
+
339
+ .fl-builder-ui-skin--dark .fl-color-picker-clear .fl-color-picker-icon-remove:before,
340
+ .fl-builder-ui-skin--dark .fl-color-picker-clear .fl-color-picker-icon-remove:after{
341
+ background:#6f7881;
342
+ }
343
+
344
+ .fl-builder-ui-skin--dark .fl-builder--user-templates-section-content {
345
+ border-color: #1d1d1d;
346
+ }
347
+
348
+ .fl-builder-ui-skin--dark .fl-theme-builder-preview-select.fl-builder-button {
349
+ background:transparent;
350
+ border-right-color: #101215 !important;
351
+ }
352
+ .fl-builder-ui-skin--dark .fl-theme-builder-preview-select.fl-builder-button:hover {
353
+ background:#181b1f;
354
+ }
355
+ .fl-builder-ui-skin--dark .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span {
356
+ color:#c6cdd6;
357
+ }
358
+
359
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu {
360
+ background: #131a22;
361
+ border-color: #131a22;
362
+ border-top-color: #353c43;
363
+ }
364
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu:before {
365
+ border-bottom-color: #353c43;
366
+ }
367
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu > a:hover,
368
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu > a:focus,
369
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu > a:active {
370
+ background: #383f46;
371
+ }
372
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu > a.fl-active,
373
+ .fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu > a:hover.fl-active {
374
+ color:white !important;
375
+ background: #383f46;
376
+ }
377
+
378
+ .fl-builder-ui-skin--dark ul.as-selections {
379
+ background-color: #121a23;
380
+ }
381
+ .fl-builder-ui-skin--dark .fl-custom-query .fl-builder-settings-section {
382
+ border-top: 2px solid #1b2026 !important;
383
+ }
384
+
385
+ /* Powerpack fix */
386
+ .fl-builder-ui-skin--dark .pp-preview-button {
387
+ background: #23282d;
388
+ border: 2px solid #101215;
389
+ }
390
+ .fl-builder-ui-skin--dark .pp-preview-button .pp-preview-button-wrap .fa {
391
+ color: #b8bfc7;
392
+ }
css/fl-builder.css CHANGED
@@ -1,21 +1,60 @@
1
- /* General
2
  ------------------------------------------------------ */
3
 
4
- html.fl-builder-edit {
5
- margin-top: 43px !important;
 
 
 
 
6
  }
7
  .fl-builder-edit body {
8
  position: static !important;
9
  }
10
- .fl-builder-edit #wpadminbar {
11
- display: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  }
 
 
 
 
 
 
 
 
 
 
 
 
13
  .fl-clear {
14
  clear: both;
15
  }
16
- .fl-builder-hidden-editor {
17
- display: none;
18
- }
19
  .screen-reader-text {
20
  position: absolute;
21
  left: -1000em;
@@ -25,7 +64,9 @@ html.fl-builder-edit {
25
  overflow: hidden;
26
  }
27
 
28
- /* Loading
 
 
29
  ------------------------------------------------------ */
30
 
31
  .fl-builder-loading {
@@ -37,13 +78,17 @@ html.fl-builder-edit {
37
  right: 0;
38
  text-align: center;
39
  top: 0;
40
- z-index: 200000;
41
  }
42
  .fl-builder-settings .fl-builder-loading {
43
  background: rgba(255, 255, 255, 0.8) url(../img/ajax-loader.svg) center center no-repeat;
44
  display: block;
45
  position: absolute;
46
  }
 
 
 
 
47
  .fl-builder-node-loading {
48
  opacity: 0.35;
49
  }
@@ -60,8 +105,9 @@ html.fl-builder-edit {
60
  .fl-col-group-has-child-loading > .fl-builder-node-loading-placeholder {
61
  width: 50px;
62
  }
 
63
 
64
- /* Responsive Utilities
65
  ------------------------------------------------------ */
66
 
67
  .fl-builder-content-editing .fl-visible-desktop,
@@ -71,8 +117,9 @@ html.fl-builder-edit {
71
  .fl-builder-content-editing .fl-visible-mobile {
72
  display: block !important;
73
  }
 
74
 
75
- /* Responsive Editing
76
  ------------------------------------------------------ */
77
 
78
  .fl-responsive-preview-mask {
@@ -89,12 +136,15 @@ html.fl-builder-edit {
89
  left: 0;
90
  position: absolute;
91
  right: 0;
92
- top: 43px;
93
  z-index: 100000;
94
  }
 
 
 
95
  .fl-responsive-preview-content {
96
- background: #F7F7F7;
97
- padding: 20px;
98
  }
99
  .fl-responsive-preview-message {
100
  color: #b3b3b3;
@@ -114,64 +164,92 @@ html.fl-builder-edit {
114
  margin-right: auto;
115
  max-width: 100%;
116
  }
 
117
 
118
- /* Builder Buttons
119
  ------------------------------------------------------ */
120
 
121
  .fl-builder-button {
122
- color: #555;
123
- border-color: #ccc;
124
- background: #f7f7f7;
125
- -webkit-box-shadow: inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);
126
- box-shadow: inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);
127
- vertical-align: top;
128
- display: inline-block;
129
  text-decoration: none;
130
- font-size: 13px !important;
131
- line-height: 13px !important;
132
- height: 28px;
 
133
  margin: 0;
134
- padding: 7px 10px;
135
  cursor: pointer;
136
- border-width: 1px;
137
- border-style: solid;
138
  -webkit-border-radius: 3px;
139
  -webkit-appearance: none;
 
140
  border-radius: 3px;
 
141
  white-space: nowrap;
 
142
  -webkit-box-sizing: border-box !important;
143
  -moz-box-sizing: border-box !important;
144
  box-sizing: border-box !important;
 
 
 
 
 
 
 
 
 
 
145
  }
146
  .fl-builder-button:hover {
147
- background: #fafafa;
148
- border-color: #999;
149
  color: #222;
 
150
  }
151
- .fl-builder-button-primary {
152
- background: #2ea2cc;
153
- border-color: #0074a2;
154
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);
155
- box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);
 
 
 
 
 
 
 
 
 
 
 
156
  color: #fff !important;
157
  text-decoration: none;
 
 
 
 
 
 
158
  }
159
- .fl-builder-button-primary:hover {
160
- background: #1e8cbe;
161
- border-color: #0074a2;
162
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.6);
163
- box-shadow: inset 0 1px 0 rgba(120,200,230,.6);
164
  color: #fff !important;
165
  }
 
 
 
 
 
166
  .fl-builder-button-large {
167
  height: 30px;
168
- line-height: 30px !important;
169
- padding: 0 12px 2px;
170
  }
171
  .fl-builder-button-small {
172
  font-size: 11px !important;
173
- line-height: 11px !important;
174
- height: 24px;
175
  }
176
  .fl-builder-help-button {
177
  color: #b3b3b3;
@@ -185,11 +263,38 @@ html.fl-builder-edit {
185
  color: #666;
186
  }
187
  .fl-builder-publish-button {
188
- height: 45px;
189
  line-height: 45px !important;
190
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
- /* Builder Badges
 
 
 
 
 
 
 
 
 
193
  ------------------------------------------------------ */
194
 
195
  .fl-builder-badge {
@@ -202,13 +307,31 @@ html.fl-builder-edit {
202
  letter-spacing: 1px;
203
  margin-left: 2px;
204
  padding: 2px 4px;
205
- vertical-align: top;
206
  }
207
  .fl-builder-badge-global {
208
  background: #ff9600;
209
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
 
211
- /* Builder Bar
212
  ------------------------------------------------------ */
213
 
214
  .fl-builder-bar {
@@ -216,114 +339,653 @@ html.fl-builder-edit {
216
  position: fixed;
217
  right: 0;
218
  top: 0;
219
- z-index: 100008;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  }
221
- .fl-builder-bar-content {
222
- background: #f4f4f4;
223
- border-bottom: 1px solid #ccc;
224
- box-shadow: 0 0 8px rgba(0,0,0,0.2);
225
- -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
226
- -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
 
 
 
 
 
227
  color: #999999;
228
- font-family: Helvetica, Arial, Verdana, sans-serif;
229
- font-size: 14px;
230
- height: 43px;
 
 
 
 
 
 
 
 
 
 
 
231
  }
232
  .fl-builder-bar-title {
 
233
  color: #333;
234
- display: block;
235
- float: left;
236
- font-size: 20px;
237
- font-weight: 300;
238
- line-height: 20px;
239
- padding: 7px 10px;
 
 
 
 
 
 
 
 
 
 
 
 
240
  }
241
  .fl-builder-bar-title img {
242
- display: inline-block!important;
243
- height: 30px !important;
244
- margin: 0 1px 0 0 !important;
245
  vertical-align: middle !important;
 
246
  }
247
  .fl-builder-bar-title span {
248
  vertical-align: middle;
249
  }
 
 
 
 
 
 
 
 
 
 
 
 
250
  .fl-builder-bar-title.fl-builder-bar-title-no-icon {
251
- padding: 12px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  .fl-builder-bar-actions {
254
- float: right;
255
- padding: 7px;
 
 
256
  }
257
  .fl-builder-bar .fl-builder-button {
258
- float: right;
259
- margin: 0 0 0 6px;
260
  }
261
- .fl-builder-bar .fl-builder-add-content-button {
262
- display: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  }
264
 
265
  /* Buy/Upgrade button */
266
  .fl-builder-buy-button,
267
  .fl-builder-upgrade-button {
268
- background: #f7951e;
269
- border-color: #de7c04;
270
- -webkit-box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
271
- box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
272
  color: #fff !important;
273
  text-decoration: none;
274
  }
275
  .fl-builder-buy-button i.fa-external-link-square,
276
  .fl-builder-upgrade-button i.fa-external-link-square {
277
- color: #f4d1a7;
278
  margin: 0 0 0 6px;
279
  }
280
  .fl-builder-buy-button:hover,
281
  .fl-builder-upgrade-button:hover {
282
- background: #de861b;
283
- border-color: #c46e04;
284
- -webkit-box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
285
- box-shadow: inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);
286
  color: #fff !important;
287
  }
288
 
289
  /* Responsive Bar */
290
- @media (max-width: 768px) {
291
- .fl-builder-bar-title span {
292
- display: none;
 
 
 
 
293
  }
294
- }
295
- @media (max-width: 420px) {
296
  .fl-builder-bar-title,
297
- .fl-builder-help-button {
298
- display: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  }
300
  }
301
 
302
- /* Builder Panel
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  ------------------------------------------------------ */
304
 
305
- .fl-builder-panel {
306
- background: #f0f0f0;
307
- border-left: 1px solid #ccc;
308
- bottom: 0;
309
- box-shadow: 0 0 8px rgba(0,0,0,0.2);
310
- -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
311
- -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
312
- color: #999999;
313
- font-family: Helvetica, Arial, Verdana, sans-serif;
314
- font-size: 14px;
315
  opacity: 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  position: fixed;
 
 
 
 
 
 
 
 
 
 
317
  right: 0;
318
- top: 43px;
319
- width: 300px;
320
- z-index: 100007;
321
- -webkit-transform: translateZ(0);
322
- transition: opacity 0.2s;
323
- -webkit-transition: opacity 0.2s;
324
- -moz-transition: opacity 0.2s;
325
- -o-transition: opacity 0.2s;
326
- -ms-transition: opacity 0.2s;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  -webkit-touch-callout: none;
328
  -webkit-user-select: none;
329
  -khtml-user-select: none;
@@ -331,31 +993,151 @@ html.fl-builder-edit {
331
  -ms-user-select: none;
332
  user-select: none;
333
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
  /* Builder Panel Actions
336
  ------------------------------------------------------ */
337
 
338
- .fl-builder-panel-actions {
339
- background: #f4f4f4;
340
- border-bottom: 1px solid #dbdbdb;
341
- height: 43px;
342
- left: 0;
 
 
 
 
 
 
343
  position: absolute;
344
- right: 0;
345
- top: 0;
346
- text-align: right;
347
- z-index: 100009;
348
  }
349
- .fl-builder-panel-actions .fl-builder-panel-close {
350
- color: #bfbfbf;
351
- cursor: pointer;
352
- float: left;
353
- font-size: 18px;
354
- margin: 12px 18px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  }
356
- .fl-builder-panel-actions .fl-builder-panel-close:hover {
 
 
 
 
 
 
 
 
 
 
 
357
  color: #333;
358
  }
 
 
 
 
 
 
 
359
 
360
  /* Builder Panel Content
361
  ------------------------------------------------------ */
@@ -372,50 +1154,238 @@ html.fl-builder-edit {
372
  .fl-builder-panel-content {
373
  padding-bottom: 60px;
374
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  .fl-builder-blocks-section .fl-builder-blocks-section-title,
376
  .fl-builder-blocks-section .fl-builder-block {
377
- cursor: pointer;
378
  display: block;
379
- line-height: 14px;
380
  padding: 15px 20px;
381
  }
382
- .fl-builder-blocks-section .fl-builder-blocks-section-title {
383
- border-bottom: 1px solid #dfdfdf;
384
- color: #333;
385
- font-weight: normal;
 
 
 
 
 
 
 
 
 
 
 
 
386
  }
387
  .fl-builder-blocks-section .fl-builder-blocks-section-title i {
388
  color: #bfbfbf;
389
  float: right;
390
  }
391
- .fl-builder-blocks-section .fl-builder-blocks-section-title:hover,
392
- .fl-builder-blocks-section .fl-builder-blocks-section-title:hover i {
393
- background: #e5e5e5;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394
  }
395
- .fl-builder-blocks-section-content {
396
- background: #fff;
397
- display: none;
 
 
 
398
  }
399
- .fl-builder-blocks-section.fl-active .fl-builder-blocks-section-content {
400
- display: block;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  }
402
  .fl-builder-blocks-section-content .fl-builder-block {
403
- border-bottom: 1px solid #ebebeb;
404
- overflow: hidden;
405
- text-overflow: ellipsis;
406
- white-space: nowrap;
407
  }
408
- .fl-builder-blocks-section-content .fl-builder-block i {
409
- color: #d9d9d9;
 
410
  margin-right: 10px;
411
  }
412
- .fl-builder-blocks-section-content .fl-builder-block:hover {
413
- background: #0074a1;
414
- color: #fff;
415
- cursor: move;
416
  }
417
  .fl-builder-blocks-separator {
418
- background: #dfdfdf;
419
  height: 6px;
420
  }
421
  .fl-builder-block:hover .fl-builder-badge {
@@ -448,6 +1418,28 @@ html.fl-builder-edit {
448
  margin: 3px 0px 0 9px !important;
449
  }
450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  /* Builder Panel Templates
452
  ------------------------------------------------------ */
453
 
@@ -456,40 +1448,110 @@ html.fl-builder-edit {
456
  max-width: 100%;
457
  border: 1px solid #dfdfdf;
458
  }
459
- .fl-builder-block-template .fl-builder-block-title {
460
- display: block;
461
  overflow: hidden;
462
  text-overflow: ellipsis;
 
 
463
  }
464
  .ui-sortable-helper .fl-builder-block-template-image {
465
  display: none !important;
466
  }
467
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
468
  /* Builder Panel Node Templates
469
  ------------------------------------------------------ */
470
 
471
  span.fl-builder-block-no-node-templates {
472
  display: block;
473
  padding: 15px 20px;
 
474
  }
475
  span.fl-builder-block-no-node-templates:hover {
476
  cursor: default;
477
- background: #fff;
478
  }
479
  .fl-builder-blocks-node-template .fl-builder-block {
480
  position: relative;
481
  }
482
- .fl-builder-blocks-node-template .fl-builder-badge-global {
483
- position: absolute;
484
- right: 20px;
485
- top: 13px;
486
- }
487
- .fl-builder-blocks-node-template .fl-builder-block:hover .fl-builder-badge-global {
488
- display: none;
489
- }
490
- .fl-builder-blocks-node-template .fl-builder-block-global.fl-builder-block {
491
- padding-right: 85px;
492
- }
493
  .fl-builder-blocks-section-content .fl-builder-node-template-actions {
494
  bottom: 0;
495
  cursor: default;
@@ -497,25 +1559,19 @@ span.fl-builder-block-no-node-templates:hover {
497
  position: absolute;
498
  right: 0;
499
  top: 0;
500
- width: 72px;
501
  }
502
  .fl-builder-blocks-section-content .fl-builder-node-template-edit,
503
  .fl-builder-blocks-section-content .fl-builder-node-template-delete {
504
- bottom: 0;
505
  cursor: pointer;
506
  margin: 0;
507
- padding: 15px 0;
508
- position: absolute;
509
- right: 0;
510
  text-align: center;
511
- top: 0;
512
  width: 30px;
513
  }
514
- .fl-builder-blocks-section-content .fl-builder-node-template-delete {
515
- right: 12px;
516
- }
517
- .fl-builder-blocks-section-content .fl-builder-node-template-edit {
518
- right: 42px;
519
  }
520
  .fl-builder-blocks-section-content .fl-builder-node-template-edit i,
521
  .fl-builder-blocks-section-content .fl-builder-node-template-delete i {
@@ -523,10 +1579,7 @@ span.fl-builder-block-no-node-templates:hover {
523
  }
524
  .fl-builder-blocks-section-content .fl-builder-node-template-edit:hover i,
525
  .fl-builder-blocks-section-content .fl-builder-node-template-delete:hover i {
526
- color: #fff;
527
- }
528
- .fl-builder-blocks-node-template .fl-builder-block:hover {
529
- padding-right: 85px;
530
  }
531
  .fl-builder-blocks-node-template .fl-builder-block:hover .fl-builder-node-template-actions {
532
  display: block;
@@ -535,50 +1588,412 @@ span.fl-builder-block-no-node-templates:hover {
535
  .ui-sortable-helper .fl-builder-node-template-delete {
536
  display: none !important;
537
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
538
 
539
- /* Drag and Drop
540
  ------------------------------------------------------ */
541
 
542
  .fl-builder-dragging .fl-builder-content:not(.fl-builder-empty) {
543
  padding: 16px 0;
544
  }
545
  .fl-builder-empty {
546
- border: 1px dashed #3ba0ff;
547
- color: #3ba0ff;
548
- font-family: Helvetica, Verdana, sans-serif !important;
549
- font-size: 14px;
 
 
 
550
  margin: 10px;
551
- padding: 100px 20px;
552
  position: relative;
553
  text-align: center;
554
  text-transform: uppercase;
555
  }
 
 
 
556
  .fl-builder-block.ui-draggable-dragging,
557
  .fl-builder-block-drag-helper {
558
- background: rgba( 255, 255, 255, 0.85 ) !important;
559
- border: 1px solid #ccc;
 
560
  box-shadow: 0 0 8px rgba(0,0,0,0.2);
561
  -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
562
  -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
563
- color: #999999 !important;
564
- font-family: Helvetica, Verdana, sans-serif !important;
565
  font-size: 13px !important;
566
- height: 40px !important;
567
  line-height: 40px !important;
568
  overflow: hidden;
569
- padding: 0 15px;
570
  position: fixed !important;
571
  text-overflow: ellipsis;
572
  white-space: nowrap;
573
- width: 120px !important;
574
  z-index: 100010 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
575
  }
576
  .fl-builder-drop-zone {
577
- animation: fl-builder-drop-zone-pulse 3s infinite;
578
- background: #3ba0ff;
 
579
  color: #fff !important;
580
  display: block;
581
- font-family: Helvetica, Verdana, sans-serif !important;
582
  font-weight: normal;
583
  font-size: 12px;
584
  letter-spacing: 1px;
@@ -596,17 +2011,17 @@ span.fl-builder-block-no-node-templates:hover {
596
  }
597
  @keyframes fl-builder-drop-zone-pulse {
598
  0% {
599
- background-color: #7ABFFF;
600
  }
601
  50% {
602
- background-color: #3ba0ff;
603
  }
604
  100% {
605
- background-color: #7ABFFF;
606
  }
607
  }
608
  .fl-builder-drop-zone-global {
609
- animation: fl-builder-drop-zone-global-pulse 3s infinite;
610
  background: #ff9600;
611
  }
612
  @keyframes fl-builder-drop-zone-global-pulse {
@@ -641,8 +2056,9 @@ span.fl-builder-block-no-node-templates:hover {
641
  padding: 16px 0;
642
  }
643
  .fl-row-highlight .fl-row-content {
644
- border: 1px dashed #3ba0ff;
645
  padding: 8px;
 
646
  }
647
  .fl-row-highlight.fl-node-global .fl-row-content {
648
  border-color: #ff9600;
@@ -658,11 +2074,12 @@ span.fl-builder-block-no-node-templates:hover {
658
  }
659
  .fl-col-highlight .fl-col-content {
660
  border-style: dashed !important;
661
- border-color: #3ba0ff !important;
662
- border-top-width: 1px !important;
663
- border-bottom-width: 1px !important;
664
- border-left-width: 1px !important;
665
- border-right-width: 1px !important;
 
666
  min-height: 100px;
667
  overflow-x: hidden;
668
  width: 100%;
@@ -682,8 +2099,9 @@ span.fl-builder-block-no-node-templates:hover {
682
  position: relative;
683
  }
684
  .fl-col-highlight-guide {
685
- background: rgba(59, 160, 255, 0.15);
686
- border: 1px solid #3ba0ff;
 
687
  bottom: 4px;
688
  left: 4px;
689
  position: absolute;
@@ -691,6 +2109,10 @@ span.fl-builder-block-no-node-templates:hover {
691
  top: 4px;
692
  z-index: 1;
693
  }
 
 
 
 
694
  .fl-col-has-highlight-guide .fl-block-overlay {
695
  background: none;
696
  border-color: transparent;
@@ -808,6 +2230,14 @@ span.fl-builder-block-no-node-templates:hover {
808
  margin-top: 0;
809
  }
810
 
 
 
 
 
 
 
 
 
811
  /* Sortable Proxies */
812
  .fl-sortable-proxy {
813
  display: none;
@@ -819,18 +2249,28 @@ span.fl-builder-block-no-node-templates:hover {
819
  .fl-block-overlay,
820
  .fl-block-overlay * {
821
  text-shadow: none;
 
822
  }
823
  .fl-block-overlay-active {
824
  position: relative;
825
  }
826
  .fl-block-overlay-actions {
827
- background: #3ba0ff;
828
  float: left;
829
- height: 28px;
830
  margin: -1px -1px 0;
 
831
  text-shadow: none;
 
 
 
 
 
 
 
832
  }
833
- .fl-builder-col-resizing .fl-block-overlay-actions {
 
834
  overflow: hidden;
835
  }
836
  .fl-block-overlay-actions > span {
@@ -842,15 +2282,16 @@ span.fl-builder-block-no-node-templates:hover {
842
  cursor: pointer;
843
  display: block !important;
844
  float: left;
845
- font-size: 14px !important;
846
  height: 28px !important;
847
  font-weight: 100 !important;
848
  line-height: 28px !important;
849
  opacity: 0.8;
850
  filter: alpha(opacity = 80);
851
  text-align: center;
852
- width: 28px !important;
853
  }
 
854
  .fl-block-overlay-actions i:hover {
855
  opacity: 1;
856
  filter: alpha(opacity = 100);
@@ -865,21 +2306,21 @@ span.fl-builder-block-no-node-templates:hover {
865
  cursor: move;
866
  }
867
  .fl-block-overlay-title {
868
- border-right: 1px solid #5eb1ff;
869
  color: #fff !important;
870
  float: left;
871
- font-family: Helvetica, Arial, Verdana, sans-serif;
872
- font-size: 13px;
873
  height: 30px;
874
  line-height: 29px;
875
  margin-right: 2px;
876
- padding: 0 8px;
877
  }
878
 
879
  /* Row Overlays */
880
  .fl-row-overlay {
881
- background: rgba(59, 160, 255, 0.15);
882
- border: 1px solid #3ba0ff;
 
883
  bottom: 0;
884
  box-sizing: border-box !important;
885
  -moz-box-sizing: border-box !important;
@@ -887,12 +2328,17 @@ span.fl-builder-block-no-node-templates:hover {
887
  color: #fff;
888
  left: 0;
889
  position: absolute;
890
- top: -30px;
891
- width: 100%;
892
  z-index: 100006;
893
  }
 
 
 
 
 
894
  .fl-row-overlay-header-bottom {
895
- bottom: -30px;
896
  top: 0;
897
  }
898
  .fl-row-overlay-header-bottom .fl-block-overlay-header {
@@ -907,10 +2353,17 @@ span.fl-builder-block-no-node-templates:hover {
907
  z-index: 100007 !important;
908
  }
909
 
 
 
 
 
 
 
910
  /* Column Overlays */
911
  .fl-col-overlay {
912
- background: rgba(59, 160, 255, 0.15);
913
- border: 1px solid #3ba0ff;
 
914
  bottom: 8px;
915
  cursor: pointer;
916
  color: #fff;
@@ -918,13 +2371,14 @@ span.fl-builder-block-no-node-templates:hover {
918
  position: absolute;
919
  right: 8px;
920
  top: 8px;
921
- z-index: 100007;
922
  }
923
 
924
  /* Module Overlays */
925
  .fl-module-overlay {
926
- background: rgba(59, 160, 255, 0.15);
927
- border: 1px solid #3ba0ff;
 
928
  bottom: 4px;
929
  cursor: pointer;
930
  color: #fff;
@@ -945,18 +2399,15 @@ span.fl-builder-block-no-node-templates:hover {
945
 
946
  /* Global Overlays */
947
  .fl-block-overlay-global {
948
- background: rgba(255, 150, 0, 0.1);
949
- border: 1px solid #ff9600;
 
950
  }
951
  .fl-block-overlay-global .fl-block-overlay-actions {
952
- background: #ff9600;
953
- }
954
- .fl-block-overlay-global .fl-block-overlay-title {
955
- border-right: 1px solid #ffcf66;
956
  }
957
  .fl-block-overlay-title-global {
958
  background: #fff;
959
- border-radius: 2px;
960
  color: #ff9600 !important;
961
  font-size: 11px;
962
  letter-spacing: 1px;
@@ -967,7 +2418,7 @@ span.fl-builder-block-no-node-templates:hover {
967
 
968
  /* Global Row Overlays */
969
  .fl-block-overlay-global.fl-row-overlay {
970
- background: rgba(255, 150, 0, 0.30);
971
  cursor: pointer;
972
  z-index: 100007;
973
  }
@@ -975,21 +2426,24 @@ span.fl-builder-block-no-node-templates:hover {
975
  cursor: default;
976
  }
977
  .fl-builder-row-template .fl-block-overlay-global.fl-row-overlay {
978
- background: rgba(255, 150, 0, 0.1);
979
  cursor: default;
980
  z-index: 100006;
981
  }
 
 
 
982
 
983
  /* Muted Overlays */
984
  .fl-block-overlay-muted .fl-row-overlay {
985
- background: rgba(153, 153, 153, 0.1);
986
- border: 1px solid #8c8c8c;
987
  }
988
  .fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-actions {
989
- background: #8c8c8c;
990
  }
991
- .fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-title {
992
- border-right: 1px solid #a6a6a6;
993
  }
994
 
995
  /* Disabled Overlays */
@@ -1007,11 +2461,11 @@ span.fl-builder-block-no-node-templates:hover {
1007
  .fl-block-col-resize-e {
1008
  cursor: ew-resize;
1009
  left: auto !important;
1010
- right: -4px !important;
1011
  }
1012
  .fl-block-col-resize-w {
1013
  cursor: ew-resize;
1014
- left: -4px !important;
1015
  }
1016
  .fl-block-col-resize-handle-wrap {
1017
  margin: -4px 0 0 -5px;
@@ -1024,9 +2478,10 @@ span.fl-builder-block-no-node-templates:hover {
1024
  }
1025
  .fl-block-col-resize-handle {
1026
  background: #fff;
1027
- border: 1px solid #259aff;
1028
- height: 7px;
1029
- width: 7px;
 
1030
  }
1031
  .fl-node-global .fl-block-col-resize-handle {
1032
  border-color: #ff9600;
@@ -1034,7 +2489,7 @@ span.fl-builder-block-no-node-templates:hover {
1034
  .fl-block-col-resize-feedback {
1035
  color: #333 !important;
1036
  display: none;
1037
- font-family: Helvetica, Verdana, sans-serif !important;
1038
  font-size: 11px !important;
1039
  position: absolute;
1040
  }
@@ -1060,8 +2515,10 @@ span.fl-builder-block-no-node-templates:hover {
1060
  position: relative;
1061
  }
1062
  .fl-builder-has-submenu > ul.fl-builder-submenu {
1063
- background: #3ba0ff;
1064
  box-shadow: 0 0 20px rgba(0,0,0,0.20);
 
 
1065
  display: none;
1066
  left: 0;
1067
  list-style: none;
@@ -1070,7 +2527,7 @@ span.fl-builder-block-no-node-templates:hover {
1070
  position: absolute;
1071
  text-align: left;
1072
  top: 100%;
1073
- width: 155px;
1074
  z-index: 100008;
1075
  }
1076
  .fl-builder-has-submenu > ul.fl-builder-submenu li {
@@ -1082,7 +2539,7 @@ span.fl-builder-block-no-node-templates:hover {
1082
  left: auto;
1083
  right: 0;
1084
  }
1085
- .fl-builder-submenu-open ul.fl-builder-submenu {
1086
  display: block;
1087
  }
1088
  .fl-builder-has-submenu > ul.fl-builder-submenu li a {
@@ -1094,7 +2551,7 @@ span.fl-builder-block-no-node-templates:hover {
1094
  display: block;
1095
  line-height: 13px;
1096
  font-size: 13px;
1097
- font-family: Helvetica, Arial, Verdana, sans-serif;
1098
  font-weight: normal;
1099
  opacity: 0.8;
1100
  filter: alpha(opacity = 80);
@@ -1105,7 +2562,7 @@ span.fl-builder-block-no-node-templates:hover {
1105
  white-space: nowrap;
1106
  }
1107
  .fl-builder-has-submenu > ul.fl-builder-submenu li a:hover {
1108
- background: #54acff;
1109
  color: #fff;
1110
  opacity: 1;
1111
  filter: alpha(opacity = 100);
@@ -1165,50 +2622,77 @@ span.fl-builder-block-no-node-templates:hover {
1165
  .fl-block-overlay-global ul.fl-builder-submenu li a:hover {
1166
  background: #ffaa33;
1167
  }
 
1168
 
1169
- /* Actions Lightbox
1170
  ------------------------------------------------------ */
1171
 
1172
  .fl-builder-actions-lightbox .fl-lightbox {
 
1173
  width: 300px;
 
1174
  }
1175
- .fl-builder-actions-lightbox .fl-builder-actions {
1176
  display: block;
 
 
 
 
1177
  padding: 25px;
1178
  text-align: center;
1179
  }
1180
  .fl-builder-actions-title {
1181
  color: #333 !important;
1182
  display: block;
1183
- font-family: Helvetica, Verdana, sans-serif !important;
1184
  font-size: 16px !important;
1185
  margin-bottom: 20px;
1186
  }
1187
  .fl-builder-actions .fl-builder-button {
1188
- display: block;
 
1189
  margin-bottom: 7px;
 
1190
  }
 
1191
 
1192
- /* Alert Lightbox
1193
  ------------------------------------------------------ */
1194
 
1195
  .fl-builder-alert-lightbox {
1196
- z-index: 200001;
 
 
 
1197
  }
1198
  .fl-builder-alert-lightbox .fl-lightbox {
1199
- width: 440px !important;
 
 
 
 
1200
  }
1201
  .fl-builder-alert-lightbox .fl-lightbox-message {
1202
  color: #333 !important;
1203
- font-family: Helvetica, Verdana, sans-serif !important;
1204
  font-size: 16px !important;
1205
  line-height: 24px;
1206
  padding: 30px;
1207
  }
 
1208
 
1209
- /* Template Selector
1210
  ------------------------------------------------------ */
1211
-
 
 
 
 
 
 
 
 
 
1212
  .fl-template-category-select {
1213
  width: 180px !important;
1214
  }
@@ -1263,43 +2747,168 @@ span.fl-builder-block-no-node-templates:hover {
1263
  padding: 8px 15px;
1264
  }
1265
  .fl-user-templates {
1266
- border-top: 1px solid #dfdfdf;
1267
- margin-bottom: 20px;
1268
- margin-right: 8px;
1269
- }
1270
- .fl-user-template {
1271
  border-bottom: 1px solid #dfdfdf;
1272
- padding: 15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1273
  position: relative;
 
 
 
 
 
 
 
 
 
 
 
 
1274
  }
1275
  .fl-user-template:hover {
1276
- background: #0074a1;
1277
- color: #fff !important;
1278
  cursor: pointer;
 
 
 
 
 
1279
  }
1280
- .fl-user-template:hover * {
1281
- color: #fff !important;
 
 
1282
  }
1283
  .fl-user-template-actions {
 
1284
  bottom: 0;
1285
  position: absolute;
1286
  right: 0;
1287
  top: 0;
1288
  }
 
 
 
 
 
1289
  .fl-user-template-actions a {
1290
- color: #bfbfbf !important;
1291
  display: inline-block;
1292
- padding: 15px;
1293
- }
1294
- .fl-user-template:hover a {
1295
- color: #99c7d9 !important;
1296
  }
1297
- .fl-user-template:hover a:hover {
1298
- color: #fff !important;
1299
  }
1300
  .fl-user-templates-message {
1301
  display: none;
1302
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1303
 
1304
  /* Lite version templates CTA */
1305
  .fl-builder-templates-cta {
@@ -1320,38 +2929,25 @@ span.fl-builder-block-no-node-templates:hover {
1320
  left: 15px;
1321
  padding: 1px 12px;
1322
  }
 
1323
 
1324
- /* User Template Settings
1325
- ------------------------------------------------------ */
1326
-
1327
- .fl-builder-user-template-settings .fl-builder-settings-fields {
1328
- height: 150px;
1329
- }
1330
-
1331
-
1332
- /* User Template Editing
1333
  ------------------------------------------------------ */
1334
 
1335
  .single-fl-builder-template .fl-content {
1336
  width: 100% !important;
1337
  }
 
1338
 
1339
- /* Node Template Settings
1340
- ------------------------------------------------------ */
1341
-
1342
- .fl-builder-node-template-settings .fl-builder-settings-fields {
1343
- height: 150px;
1344
- }
1345
-
1346
- /* Settings
1347
  ------------------------------------------------------ */
1348
 
1349
- .fl-builder-lightbox .fl-lightbox {
1350
- width: 600px;
1351
- }
1352
  form.fl-builder-settings {
 
1353
  margin: 0;
1354
  padding: 0;
 
 
1355
  }
1356
  .fl-builder-settings-message {
1357
  font-size: 15px !important;
@@ -1365,7 +2961,7 @@ form.fl-builder-settings {
1365
  }
1366
  .fl-builder-preview-loader {
1367
  position: relative;
1368
- top: -1px;
1369
  margin-left: 3px;
1370
  }
1371
  .fl-lightbox-header .fl-builder-preview-loader {
@@ -1375,41 +2971,227 @@ form.fl-builder-settings {
1375
  top: 15px;
1376
  }
1377
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1378
  /* Settings Tabs
1379
  ------------------------------------------------------ */
1380
 
1381
  .fl-builder-settings-tabs {
1382
- background: #f5f5f5;
1383
- border-bottom: 1px solid #dfdfdf;
1384
- padding: 15px 20px 0 20px;
 
 
 
1385
  }
1386
- .fl-builder-settings-tabs a {
1387
- color: #999 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1388
  display: inline-block;
1389
  margin: 0;
1390
  outline: none;
1391
- padding: 10px 20px;
1392
  text-decoration: none !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1393
  }
1394
- .fl-builder-settings-tabs a:hover {
 
 
1395
  color: #333;
 
 
1396
  }
1397
- .fl-builder-settings-tabs a:focus {
 
1398
  outline: none;
1399
- }
1400
- .fl-builder-settings-tabs a.fl-active {
1401
- background: #fff;
1402
- border: 1px solid #dfdfdf;
1403
- border-bottom: none;
1404
- color: #333 !important;
 
 
 
 
1405
  position: relative;
1406
- top: 1px;
1407
  }
1408
- .fl-builder-settings-tabs a.error {
 
 
 
 
1409
  color: #d03436;
1410
  padding-right: 10px;
1411
  }
1412
- .fl-builder-settings-tabs a.error .fl-error-icon {
 
1413
  background: url('../img/sprite.png') -148px -5px no-repeat;
1414
  display: inline-block;
1415
  height: 16px;
@@ -1418,16 +3200,21 @@ form.fl-builder-settings {
1418
  top: 3px;
1419
  width: 16px;
1420
  }
 
 
 
1421
  .fl-builder-settings-tab {
1422
  display: none;
1423
- width: 550px;
1424
  }
1425
  .fl-builder-settings-tab.fl-active {
1426
  display: block;
1427
  }
1428
  .fl-builder-settings-tab-description {
1429
- background: #f5f5f5;
1430
  padding: 10px 15px;
 
 
1431
  }
1432
  .fl-builder-settings-tab-description a {
1433
  text-decoration: underline !important;
@@ -1435,6 +3222,58 @@ form.fl-builder-settings {
1435
  .fl-builder-settings-tab-description a:hover {
1436
  color: #333;
1437
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1438
 
1439
  /* Settings Tables
1440
  ------------------------------------------------------ */
@@ -1442,7 +3281,7 @@ form.fl-builder-settings {
1442
  .fl-form-table {
1443
  background: none transparent;
1444
  border: none;
1445
- width: 100%;
1446
  }
1447
  .fl-form-table tbody {
1448
  border: none;
@@ -1453,33 +3292,42 @@ form.fl-builder-settings {
1453
  }
1454
  .fl-form-table th {
1455
  border: none !important;
1456
- background: #fff !important;
1457
  font-weight: normal !important;
1458
  padding: 10px !important;
 
1459
  text-align: left !important;
1460
  vertical-align: top !important;
1461
  width: 200px !important;
 
 
 
 
1462
  }
1463
  .fl-form-table th label {
1464
  color: #333;
 
 
1465
  }
1466
  .fl-form-table td {
1467
- background: #fff !important;
1468
  border: none !important;
1469
  font-weight: normal !important;
1470
  padding: 8px 10px;
1471
  text-align: left !important;
1472
- width: auto !important;
 
 
1473
  }
1474
 
1475
  /* Settings Fields
1476
  ------------------------------------------------------ */
1477
 
1478
  .fl-builder-settings-fields {
1479
- height: 410px;
1480
- margin: 5px 0 0 0;
1481
  overflow: hidden;
1482
  position: relative;
 
 
1483
  }
1484
  .fl-lightbox-header .fl-builder-settings-fields {
1485
  height: auto;
@@ -1489,11 +3337,15 @@ form.fl-builder-settings {
1489
  top: 10px;
1490
  }
1491
  .fl-builder-settings-fields .fl-nanoscroller-content {
1492
- padding: 15px 20px;
1493
  }
1494
  .fl-builder-settings-fields .fl-field-control-wrapper {
1495
  position: relative;
1496
  }
 
 
 
 
1497
  .fl-builder-settings-fields textarea,
1498
  .fl-builder-settings-fields input[type=text],
1499
  .fl-builder-settings-fields input[type=password],
@@ -1505,43 +3357,50 @@ form.fl-builder-settings {
1505
  .fl-builder-settings-fields input[type=url],
1506
  .fl-builder-settings-fields select {
1507
  background: #fff !important;
1508
- border-color: #dfdfdf !important;
1509
  border-style: solid;
1510
- border-width: 1px;
1511
- border-radius: 3px;
1512
- -moz-border-radius: 3px;
1513
- -webkit-border-radius: 3px;
1514
- box-shadow: none;
1515
- -moz-box-shadow: none;
1516
- -webkit-box-shadow: none;
1517
  color: #333 !important;
1518
  display: inline;
1519
- font-size: 12px;
1520
  height: auto;
1521
  line-height: 15px;
1522
  margin: 1px;
1523
  outline: none;
1524
- padding: 3px;
1525
  width: auto;
 
1526
  }
1527
- .fl-builder-settings-fields input[type=number] {
1528
- width: 50px;
1529
- }
1530
- .fl-builder-settings-fields textarea:focus,
1531
- .fl-builder-settings-fields input[type=text]:focus,
1532
- .fl-builder-settings-fields input[type=password]:focus,
1533
- .fl-builder-settings-fields input[type=file]:focus,
1534
- .fl-builder-settings-fields input[type=email]:focus,
1535
- .fl-builder-settings-fields input[type=number]:focus,
1536
- .fl-builder-settings-fields input[type=search]:focus,
1537
- .fl-builder-settings-fields input[type=tel]:focus,
1538
- .fl-builder-settings-fields input[type=url]:focus,
1539
- .fl-builder-settings-fields select:focus {
1540
- background: transparent;
1541
- border-color: #dfdfdf;
1542
  }
1543
- .fl-builder-settings-fields select[multiple] {
1544
- height: 60px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1545
  }
1546
  .fl-builder-settings-fields ::-webkit-input-placeholder { /* WebKit browsers */
1547
  color: #999 !important;
@@ -1560,14 +3419,93 @@ form.fl-builder-settings {
1560
  font-size: 12px;
1561
  }
1562
  .fl-builder-settings-fields label {
 
1563
  font-weight: normal;
 
 
1564
  }
1565
  .fl-builder-settings-fields select {
 
 
 
1566
  box-sizing: border-box;
1567
- height: 2em;
1568
  color: #000;
1569
  margin: 0;
1570
- padding: 2px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1571
  }
1572
  .fl-builder-settings-description {
1573
  padding: 10px;
@@ -1577,21 +3515,19 @@ form.fl-builder-settings {
1577
  opacity: .75;
1578
  }
1579
  .fl-builder-settings-fields table {
1580
- margin: 0;
1581
- }
1582
- .fl-builder-settings-fields h3.fl-builder-settings-title {
1583
- border-bottom: 1px solid #dfdfdf;
1584
- color: #333;
1585
- font-size: 14px;
1586
- font-weight: bold;
1587
- margin: 0 0 20px !important;
1588
- padding: 10px;
1589
- }
1590
- .fl-builder-settings-section {
1591
- margin-bottom: 15px;
1592
  }
1593
- .fl-builder-settings-section:last-child {
1594
- margin-bottom: 0;
 
 
 
 
 
 
 
 
 
1595
  }
1596
 
1597
  /* Core WordPress UI */
@@ -1608,7 +3544,6 @@ form.fl-builder-settings {
1608
  }
1609
  .wp-core-ui button {
1610
  font-weight: normal;
1611
- text-transform: capitalize;
1612
  }
1613
  .wp-core-ui textarea,
1614
  .wp-core-ui input[type=text],
@@ -1665,7 +3600,7 @@ i.fl-field-responsive-toggle {
1665
  display: inline-block;
1666
  font-size: 15px !important;
1667
  height: auto;
1668
- line-height: 15px !important;
1669
  text-align: left;
1670
  vertical-align: middle;
1671
  width: 20px;
@@ -1676,21 +3611,25 @@ i.fl-field-responsive-toggle:hover {
1676
 
1677
  /* Text Field */
1678
  .fl-builder-settings-fields input.text-full {
1679
- width: 97%;
1680
  }
1681
 
1682
  /* Textarea */
1683
  .fl-builder-settings-fields textarea {
1684
- width: 97%;
1685
  }
1686
 
1687
  /* Color Picker */
1688
  .fl-color-picker {
1689
  cursor: pointer;
1690
  }
 
 
 
1691
  .fl-color-picker .fl-color-picker-clear:hover {
1692
  background-color: #ededed;
1693
  }
 
1694
  .colorpicker input {
1695
  padding: 0 !important;
1696
  font-size: 11px !important;
@@ -1706,9 +3645,16 @@ i.fl-field-responsive-toggle:hover {
1706
 
1707
  /* Custom Fields */
1708
  .fl-builder-custom-field {
1709
- border: 1px solid #dfdfdf;
1710
- border-radius: 3px;
1711
- padding: 5px 10px;
 
 
 
 
 
 
 
1712
  }
1713
  .fl-builder-custom-field a {
1714
  color: #21759b !important;
@@ -1722,6 +3668,9 @@ i.fl-field-responsive-toggle:hover {
1722
  }
1723
 
1724
  /* Photo Fields */
 
 
 
1725
  .fl-photo-field .fl-photo-select,
1726
  .fl-photo-field.fl-photo-empty .fl-photo-preview {
1727
  display: none;
@@ -1730,7 +3679,6 @@ i.fl-field-responsive-toggle:hover {
1730
  display: block;
1731
  }
1732
  .fl-photo-field .fl-photo-preview-img {
1733
- float: left;
1734
  line-height: 0;
1735
  margin: 5px 0;
1736
  }
@@ -1741,15 +3689,37 @@ i.fl-field-responsive-toggle:hover {
1741
  margin: 8px 0 8px 10px;
1742
  width: 200px;
1743
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
1744
  .fl-photo-field .fl-photo-edit {
1745
  margin: 0 0 0 11px;
1746
  }
 
 
 
1747
  .fl-photo-field .fl-photo-replace,
1748
  .fl-photo-field .fl-photo-remove {
1749
  margin: 0 0 0 8px;
1750
  }
1751
 
1752
  /* Media Uploader */
 
 
 
 
 
 
1753
  .fl-builder-edit .media-frame {
1754
  -webkit-backface-visibility: hidden;
1755
  }
@@ -1804,11 +3774,18 @@ i.fl-field-responsive-toggle:hover {
1804
  .fl-video-field .fl-video-preview-img img {
1805
  max-width: 60px;
1806
  }
 
 
 
 
 
 
 
1807
  .fl-video-field .fl-video-preview-filename {
1808
  display: inline-block;
1809
  font-size: 14px;
1810
  font-weight: bold;
1811
- margin: 7px 0 0 11px;
1812
  }
1813
  .fl-video-field .fl-video-replace {
1814
  margin: 0 0 0 11px;
@@ -1839,7 +3816,7 @@ i.fl-field-responsive-toggle:hover {
1839
  .fl-icon-field .fl-icon-preview i {
1840
  display: inline-block;
1841
  font-size: 28px;
1842
- margin: 10px 10px 9px 2px;
1843
  vertical-align: middle;
1844
  }
1845
  .fl-icon-field .fl-icon-remove {
@@ -1847,6 +3824,9 @@ i.fl-field-responsive-toggle:hover {
1847
  }
1848
 
1849
  /* Text Editors */
 
 
 
1850
  .fl-builder-settings .wp-switch-editor {
1851
  background: #ebebeb;
1852
  border: 1px solid #e5e5e5;
@@ -1892,7 +3872,7 @@ i.fl-field-responsive-toggle:hover {
1892
  /* Editor Link Modal */
1893
  .fl-builder-edit form#wp-link {
1894
  color: #000;
1895
- font-family: Helvetica, Arial, Verdana, sans-serif;
1896
  font-size: 13px;
1897
  }
1898
  .fl-builder-edit form#wp-link #link-options label {
@@ -1951,12 +3931,23 @@ i.fl-field-responsive-toggle:hover {
1951
  }
1952
 
1953
  /* Link Field */
 
 
 
 
1954
  .fl-link-field-input {
1955
- width: 244px !important;
 
 
 
 
 
1956
  }
 
 
1957
  .fl-link-field-search {
1958
  display: none;
1959
- border: 1px solid #dfdfdf;
1960
  border-radius: 3px;
1961
  -moz-border-radius: 3px;
1962
  -webkit-border-radius: 3px;
@@ -1998,15 +3989,22 @@ i.fl-field-responsive-toggle:hover {
1998
  top: -6px;
1999
  width: 250px;
2000
  z-index: 1000;
 
 
 
 
 
2001
  }
2002
 
2003
  /* Multiples */
2004
  .fl-field-control .fl-form-field {
2005
  margin-bottom: 0;
2006
  }
2007
- .fl-form-field-preview-text .fa {
 
2008
  font-size: 18px;
2009
  line-height: 22px;
 
2010
  }
2011
  .fl-builder-field-actions {
2012
  padding-left: 0 !important;
@@ -2019,7 +4017,7 @@ i.fl-field-responsive-toggle:hover {
2019
  cursor: pointer;
2020
  font-size: 13px !important;
2021
  line-height: 29px !important;
2022
- width: 24px;
2023
  }
2024
  .fl-builder-field-actions i:hover {
2025
  color: #000 !important;
@@ -2041,11 +4039,32 @@ i.fl-field-responsive-toggle:hover {
2041
  border: 1px dashed #cccccc;
2042
  height: 30px;
2043
  }
2044
- .fl-builder-field-actions-single {
2045
- width: auto;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2046
  }
2047
- .fl-builder-field-actions-single i.fl-builder-field-delete,
2048
- .fl-builder-field-actions-single i.fl-builder-field-move {
 
 
 
 
2049
  display: none;
2050
  }
2051
 
@@ -2062,7 +4081,7 @@ i.fl-field-responsive-toggle:hover {
2062
  }
2063
  .fl-builder-settings .error,
2064
  .fl-builder-settings input.error {
2065
- border-color: #d03436;
2066
  }
2067
  .fl-builder-settings label.error,
2068
  .fl-builder-settings p.error {
@@ -2071,22 +4090,28 @@ i.fl-field-responsive-toggle:hover {
2071
  margin-top: 5px;
2072
  }
2073
  .fl-builder-settings .fl-form-table .fl-field-description {
2074
- color: #999;
2075
  font-style: normal;
 
 
 
 
 
 
 
 
 
 
 
 
2076
  }
2077
 
2078
  /* Auto Suggest */
2079
  ul.as-selections {
2080
  background-color: #fff;
2081
- border-color: #dfdfdf;
2082
- border-style: solid;
2083
- border-width: 1px;
2084
- border-radius: 3px;
2085
- -moz-border-radius: 3px;
2086
- -webkit-border-radius: 3px;
2087
  box-shadow: none;
2088
- -moz-box-shadow: none;
2089
- -webkit-box-shadow: none;
2090
  color: #333;
2091
  font-size: 12px;
2092
  height: auto;
@@ -2109,9 +4134,9 @@ ul.as-selections li.as-selection-item {
2109
  border-radius: 0;
2110
  font-size: 11px;
2111
  line-height: 14px;
2112
- margin-bottom: 4px;
2113
- padding-bottom: 0;
2114
- padding-top: 0;
2115
  }
2116
  ul.as-selections li.as-selection-item.blur {
2117
  background: #f4f4f4;
@@ -2127,12 +4152,13 @@ ul.as-selections li.as-original input {
2127
  font-size: 12px;
2128
  margin: 0;
2129
  padding: 0;
 
2130
  }
2131
  ul.as-list {
2132
  margin: 0;
2133
  font-size: 13px;
2134
  color: #000;
2135
- font-family: Helvetica, Arial, Verdana, sans-serif;
2136
  background-color: #fff;
2137
  background-color: rgba(255,255,255,.95);
2138
  z-index: 2;
@@ -2170,6 +4196,7 @@ li.as-result-item em {
2170
  color: #333 !important;
2171
  font-size: 12px;
2172
  padding: 0 !important;
 
2173
  }
2174
 
2175
  /* Loop Settings */
@@ -2229,16 +4256,27 @@ li.as-result-item em {
2229
  ------------------------------------------------------ */
2230
 
2231
  #tiptip_holder {
2232
- z-index: 200000;
 
 
 
 
 
 
 
 
 
2233
  }
2234
- #tiptip_arrow_inner {
2235
- border-top-color: #333 !important;
2236
  }
2237
  #tiptip_content {
2238
  background: #333;
2239
  box-shadow: none;
2240
  }
 
2241
 
 
2242
  /* Getting Started Video
2243
  ------------------------------------------------------ */
2244
 
@@ -2288,7 +4326,7 @@ body > .fl-builder-tour-dimmed {
2288
  box-shadow: 0 0 40px rgba(0,0,0,.3);
2289
  color: #666;
2290
  font-size: 13px;
2291
- font-family: Helvetica, Arial, Verdana, sans-serif;
2292
  font-weight: normal;
2293
  line-height: 18px;
2294
  max-width: none;
@@ -2329,8 +4367,12 @@ body > .fl-builder-tour-dimmed {
2329
  float: none;
2330
  width: 100%;
2331
  }
 
 
 
 
2332
 
2333
- /* Shortcodes
2334
  ------------------------------------------------------ */
2335
 
2336
  .fl-builder-shortcode-mask-wrap {
@@ -2344,8 +4386,319 @@ body > .fl-builder-tour-dimmed {
2344
  top: -1px;
2345
  z-index: 1;
2346
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2347
 
2348
- /* Modules
 
 
2349
  ------------------------------------------------------ */
2350
 
2351
  .fl-builder-module-placeholder-message {
@@ -2356,3 +4709,261 @@ body > .fl-builder-tour-dimmed {
2356
  text-overflow: ellipsis;
2357
  white-space: nowrap;
2358
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* @group General
2
  ------------------------------------------------------ */
3
 
4
+ html {
5
+ transition-property: margin;
6
+ transition-duration: .35s;
7
+ }
8
+ html.fl-builder-is-showing-toolbar {
9
+ margin-top: 46px !important;
10
  }
11
  .fl-builder-edit body {
12
  position: static !important;
13
  }
14
+ /* fix for twentysixteen */
15
+ .fl-builder-edit:before,
16
+ .fl-builder-edit:after {
17
+ z-index: 0 !important;
18
+ }
19
+ .fl-builder-edit .fl-builder-content {
20
+ -webkit-user-select: none;
21
+ -moz-user-select: none;
22
+ -ms-user-select: none;
23
+ user-select: none;
24
+ -webkit-touch-callout: none;
25
+ }
26
+
27
+ #wpadminbar {
28
+ transition-property: transform, opacity;
29
+ transition-duration: .35s;
30
+
31
+ transform-origin: bottom;
32
+ transform-style: preserve-3d;
33
+ transform: rotateX(89deg) translateY(46px);
34
+ opacity:0;
35
+
36
+ pointer-events: none;
37
+ will-change: transform;
38
+ }
39
+
40
+ html.fl-builder-show-admin-bar {
41
+ margin-top: 32px;
42
  }
43
+ html.fl-builder-show-admin-bar #wpadminbar {
44
+ transform: rotateX(0deg) translateY(0px);
45
+ pointer-events: auto;
46
+ opacity:1;
47
+ }
48
+
49
+ @media screen and ( max-width: 782px ) {
50
+ html.fl-builder-show-admin-bar {
51
+ margin-top: 46px;
52
+ }
53
+ }
54
+
55
  .fl-clear {
56
  clear: both;
57
  }
 
 
 
58
  .screen-reader-text {
59
  position: absolute;
60
  left: -1000em;
64
  overflow: hidden;
65
  }
66
 
67
+ /* @endgroup General */
68
+
69
+ /* @group Loading
70
  ------------------------------------------------------ */
71
 
72
  .fl-builder-loading {
78
  right: 0;
79
  text-align: center;
80
  top: 0;
81
+ z-index: 12000000;
82
  }
83
  .fl-builder-settings .fl-builder-loading {
84
  background: rgba(255, 255, 255, 0.8) url(../img/ajax-loader.svg) center center no-repeat;
85
  display: block;
86
  position: absolute;
87
  }
88
+ .fl-field-loader {
89
+ color: #B3B3B3 !important;
90
+ font-style: italic;
91
+ }
92
  .fl-builder-node-loading {
93
  opacity: 0.35;
94
  }
105
  .fl-col-group-has-child-loading > .fl-builder-node-loading-placeholder {
106
  width: 50px;
107
  }
108
+ /* @endgroup Loading */
109
 
110
+ /* @group Responsive Utilities
111
  ------------------------------------------------------ */
112
 
113
  .fl-builder-content-editing .fl-visible-desktop,
117
  .fl-builder-content-editing .fl-visible-mobile {
118
  display: block !important;
119
  }
120
+ /* @endgroup Responsive Utilities */
121
 
122
+ /* @group Responsive Editing
123
  ------------------------------------------------------ */
124
 
125
  .fl-responsive-preview-mask {
136
  left: 0;
137
  position: absolute;
138
  right: 0;
139
+ top: 0;
140
  z-index: 100000;
141
  }
142
+ .fl-builder-preview .fl-responsive-preview {
143
+ margin: 0 !important;
144
+ }
145
  .fl-responsive-preview-content {
146
+ background: #F5F7F9;
147
+ padding: 20px 20px 45px;
148
  }
149
  .fl-responsive-preview-message {
150
  color: #b3b3b3;
164
  margin-right: auto;
165
  max-width: 100%;
166
  }
167
+ /* @endgroup Responsive Editing */
168
 
169
+ /* @group Buttons
170
  ------------------------------------------------------ */
171
 
172
  .fl-builder-button {
173
+ color: #676F7A !important;
174
+ fill: #676F7A !important;
175
+ background: #E4E7EA;
176
+ align-items: center;
177
+ display: flex;
 
 
178
  text-decoration: none;
179
+ font-size: 14px !important;
180
+ font-weight: 500 !important;
181
+ line-height: 1 !important;
182
+ height: 33px;
183
  margin: 0;
184
+ padding: 0px 12px;
185
  cursor: pointer;
 
 
186
  -webkit-border-radius: 3px;
187
  -webkit-appearance: none;
188
+ border:2px solid transparent;
189
  border-radius: 3px;
190
+ letter-spacing: normal !important;
191
  white-space: nowrap;
192
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
193
  -webkit-box-sizing: border-box !important;
194
  -moz-box-sizing: border-box !important;
195
  box-sizing: border-box !important;
196
+ transition-property: background-color, width;
197
+ transition-duration: .2s;
198
+
199
+ /* Prevent select */
200
+ -webkit-touch-callout: none; /* iOS Safari */
201
+ -webkit-user-select: none; /* Chrome/Safari/Opera */
202
+ -khtml-user-select: none; /* Konqueror */
203
+ -moz-user-select: none; /* Firefox */
204
+ -ms-user-select: none; /* Internet Explorer/Edge */
205
+ user-select: none;
206
  }
207
  .fl-builder-button:hover {
208
+ background: #dadfe5;
 
209
  color: #222;
210
+ border: 2px solid transparent !important;
211
  }
212
+ .fl-builder-button:active {
213
+ background: #DCDCDC;
214
+ }
215
+ button.fl-builder-button:focus {
216
+ position: static;
217
+ top:auto;
218
+ outline:none;
219
+ background: #E4E7EA;
220
+ border:2px solid #00A0D0 !important;
221
+ }
222
+ .fl-builder-bar .fl-builder-button {
223
+ height: auto;
224
+ }
225
+ .fl-builder-button-primary,
226
+ body.fl-builder--layout-has-drafted-changes .fl-builder-done-button {
227
+ background: #00A0D2;
228
  color: #fff !important;
229
  text-decoration: none;
230
+ border:2px solid transparent !important;
231
+ }
232
+ .fl-builder-button.fl-builder-button-primary:focus,
233
+ body.fl-builder--layout-has-drafted-changes .fl-builder-button.fl-builder-done-button:focus {
234
+ background: #00A0D2;
235
+ border:2px solid #ffc217 !important;
236
  }
237
+ .fl-builder-button-primary:hover,
238
+ body.fl-builder--layout-has-drafted-changes .fl-builder-done-button:hover {
239
+ background: #0197C6;
 
 
240
  color: #fff !important;
241
  }
242
+ .fl-builder-button-primary:active,
243
+ body.fl-builder--layout-has-drafted-changes .fl-builder-done-button:active {
244
+ background: #0484AC;
245
+ }
246
+
247
  .fl-builder-button-large {
248
  height: 30px;
 
 
249
  }
250
  .fl-builder-button-small {
251
  font-size: 11px !important;
252
+ line-height: 1 !important;
 
253
  }
254
  .fl-builder-help-button {
255
  color: #b3b3b3;
263
  color: #666;
264
  }
265
  .fl-builder-publish-button {
 
266
  line-height: 45px !important;
267
  }
268
+ .fl-builder-content-panel-button,
269
+ .fl-builder-content-panel-button:hover {
270
+ fill: #00A0D2 !important;
271
+ font-size: 30px !important;
272
+ padding-bottom: 4px;
273
+ }
274
+ /* Silent buttons have the same dimensions but no background or "button" look. */
275
+ .fl-builder-button-silent,
276
+ .fl-builder-button-silent:hover {
277
+ padding:0 12px;
278
+ background:none !important;
279
+ border:2px solid transparent !important;
280
+ box-shadow:none !important;
281
+ }
282
+
283
+ .fl-builder-done-button,
284
+ .fl-builder-done-button:hover {
285
+ font-weight: 600;
286
+ }
287
 
288
+ .fl-field .fl-builder-button {
289
+ display: inline-block;
290
+ height: auto;
291
+ padding: 11px 12px;
292
+ vertical-align: middle;
293
+ box-shadow: 0 2px 4px 0 rgba(0,0,0,0.12);
294
+ }
295
+ /* @endgroup Buttons */
296
+
297
+ /* @group Badges
298
  ------------------------------------------------------ */
299
 
300
  .fl-builder-badge {
307
  letter-spacing: 1px;
308
  margin-left: 2px;
309
  padding: 2px 4px;
310
+ vertical-align: middle;
311
  }
312
  .fl-builder-badge-global {
313
  background: #ff9600;
314
  }
315
+ .fl-builder-blocks-node-template .fl-builder-badge-global {
316
+ position: absolute;
317
+ right: 0;
318
+ top: 0;
319
+ }
320
+ .fl-builder-badge-global {
321
+ transform: translateY(0px);
322
+ transition-duration: .25s;
323
+ transition-property: transform;
324
+ }
325
+ .fl-builder-block:hover .fl-builder-badge-global {
326
+ display:none;
327
+ }
328
+ .fl-builder-blocks-section-content .fl-builder-node-template-actions {
329
+ bottom: 0;
330
+ cursor: default;
331
+ }
332
+ /* @endgroup Badges */
333
 
334
+ /* @group Toolbar
335
  ------------------------------------------------------ */
336
 
337
  .fl-builder-bar {
339
  position: fixed;
340
  right: 0;
341
  top: 0;
342
+ z-index: 999999;
343
+ /* Prevent select */
344
+ -webkit-touch-callout: none; /* iOS Safari */
345
+ -webkit-user-select: none; /* Chrome/Safari/Opera */
346
+ -khtml-user-select: none; /* Konqueror */
347
+ -moz-user-select: none; /* Firefox */
348
+ -ms-user-select: none; /* Internet Explorer/Edge */
349
+ user-select: none; /* Non-prefixed version, currently
350
+ not supported by any browser */
351
+ transition-property: transform opacity;
352
+ transition-duration: .35s;
353
+ transform-style: preserve-3d;
354
+
355
+ -webkit-perspective: 1100px;
356
+ -moz-perspective: 1100px;
357
+ perspective: 1100px;
358
  }
359
+ .fl-builder-bar.is-hidden {
360
+ pointer-events: none;
361
+ }
362
+ .fl-builder-bar.is-hidden .fl-builder-bar-content {
363
+ transform: translateY(-100%) rotateX(90deg);
364
+ }
365
+ body .fl-builder-bar .fl-builder-bar-content {
366
+ display: flex;
367
+ box-sizing: border-box;
368
+ background: #ffffff;
369
+ border-bottom: 2px solid #D5DADD;
370
  color: #999999;
371
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
372
+ font-size: 14px !important;
373
+ height: 48px; /* include 2px border */
374
+ transition-property: background-color, opacity, transform;
375
+ transition-duration: .35s;
376
+ pointer-events: auto;
377
+ }
378
+ body .fl-builder-bar .fl-builder-bar-content.is-muted {
379
+ pointer-events: none;
380
+ }
381
+ body .fl-builder-bar .fl-builder-bar-content.is-muted > *:not(.fl-builder-publish-actions) {
382
+ -webkit-filter: saturate(20%) blur(1px);
383
+ filter: saturate(20%) blur(1px);
384
+ opacity: .4;
385
  }
386
  .fl-builder-bar-title {
387
+ box-sizing: border-box;
388
  color: #333;
389
+ display: flex;
390
+ flex: 0 0 380px;
391
+ max-width: 380px; /* required */
392
+ border-right: 2px solid #D5DADD;
393
+ cursor: pointer;
394
+ }
395
+ .fl-builder-bar-title:hover {
396
+ background: #ffffff;
397
+ }
398
+ .fl-builder-bar-title.is-showing-menu .fl-builder-bar-title-caret > svg {
399
+ transform: rotate(180deg);
400
+ }
401
+ .fl-builder-simple .fl-builder-bar-title {
402
+ cursor: auto;
403
+ }
404
+ .fl-builder-simple .fl-builder-bar-title:hover {
405
+ cursor: auto;
406
+ background: none;
407
  }
408
  .fl-builder-bar-title img {
409
+ /*
410
+ height: 33px !important;
411
+ margin: 2px 10px 0 0 !important;
412
  vertical-align: middle !important;
413
+ */
414
  }
415
  .fl-builder-bar-title span {
416
  vertical-align: middle;
417
  }
418
+ .fl-builder-bar-title-icon {
419
+ box-sizing: border-box;
420
+ background: transparent;
421
+ flex: 0 0 46px;
422
+ display: flex;
423
+ align-items: center;
424
+ padding: 4px;
425
+ }
426
+ .fl-builder-bar-title-icon img {
427
+ max-width: 100% !important;
428
+ height:auto !important
429
+ }
430
  .fl-builder-bar-title.fl-builder-bar-title-no-icon {
431
+ padding-left: 12px;
432
+ }
433
+ .fl-builder-bar-title-area {
434
+ box-sizing: border-box;
435
+ flex: 1 1 100%;
436
+ display: flex;
437
+ flex-direction: column;
438
+ overflow: hidden;
439
+ padding: 4px;
440
+ }
441
+ .fl-builder-layout-title,
442
+ .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span {
443
+ font-size: 17px;
444
+ font-weight: 400;
445
+ line-height: 1.3;
446
+ color: #161B20;
447
+ white-space: nowrap;
448
+ text-overflow: ellipsis;
449
+ overflow: hidden;
450
+ }
451
+ .fl-builder-layout-pretitle,
452
+ .fl-builder-bar-title-caret,
453
+ .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title {
454
+ font-size: 12px;
455
+ font-weight: 500;
456
+ line-height: 1.3;
457
+ color: #656d77;
458
+ white-space: nowrap;
459
+ text-overflow: ellipsis;
460
+ overflow: hidden;
461
+ }
462
+ .fl-builder-bar-title-caret i,
463
+ .fl-theme-builder-preview-select-title i {
464
+ color: inherit !important;
465
+ font-size:14px;
466
+ }
467
+ .fl-builder-bar-title-caret {
468
+ margin-left:auto;
469
+ margin-left: auto !important;
470
+ flex: 0 0 46px;
471
+ }
472
+ .fl-theme-builder-preview-select-title i {
473
+ padding:12px 12px;
474
+ }
475
+ .fl-theme-builder-preview-select-title i:before {
476
+ content: "\f078";
477
+ }
478
+
479
+ .fl-theme-builder-preview-select.fl-builder-button {
480
+ position: relative;
481
+ border-radius:0;
482
+ background:none;
483
+ max-width: none;
484
+ min-width: 0;
485
+ display: flex;
486
+ flex:0 0 360px;
487
+ max-width: 360px;
488
+ margin:0 !important;
489
+ padding:4px 10px;
490
+ border:none !important;
491
+ border-right: 2px solid #d5dadd !important;
492
+ box-shadow: none;
493
+ }
494
+ .fl-theme-builder-preview-select.fl-builder-button:hover {
495
+ border:none !important;
496
+ border-right: 2px solid #d5dadd !important;
497
+ }
498
+ .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title {
499
+ display: flex;
500
+ flex: 1;
501
+ justify-content: flex-end;
502
+ flex-direction: row-reverse;
503
+ }
504
+ .fl-theme-builder-preview-select-title div {
505
+ flex:1;
506
  }
507
+ .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span {
508
+ display: block;
509
+ }
510
+ .fl-theme-builder-preview-select-open .fl-theme-builder-preview-select-items {
511
+ position: absolute;
512
+ top: calc(48px + 10px);
513
+ left: 10px;
514
+ width: calc(100% - 20px) !important;
515
+ background:#ffffff;
516
+ border:none;
517
+ border-radius: 4px;
518
+ border: 2px solid #D5DADD;
519
+ border-top: 3px solid #00a0d2;
520
+ box-shadow: 0px 15px 45px 8px rgba(0, 0, 0, 0.04);
521
+ margin:0 !important;
522
+ padding:0;
523
+ z-index: -1;
524
+ font-size: 16px;
525
+ overflow: visible;
526
+ height: auto !important;
527
+ max-height: calc(100vh - 66px);
528
+ min-height: 300px;
529
+ display: flex !important;
530
+ flex-direction: column;
531
+ }
532
+ .fl-theme-builder-preview-select-open .fl-theme-builder-preview-select-items:before {
533
+ right: 18px;
534
+ }
535
+ .fl-theme-builder-preview-select-item {
536
+ padding: 4px 0 !important;
537
+ border-bottom: none !important;
538
+ display: flex;
539
+ flex-direction: column;
540
+ }
541
+ .fl-theme-builder-preview-select-item:hover {
542
+ text-decoration: none;
543
+ color: #111111;
544
+ background: transparent !important;
545
+ }
546
+ body .fl-theme-builder-preview-select .fa-caret-down {
547
+ float: none;
548
+ }
549
+ body .fl-theme-builder-preview-select-item-title {
550
+ padding:10px 15px;
551
+ color: #222222;
552
+ font-size:14px;
553
+ }
554
+ body .fl-theme-builder-preview-select .fa-caret-down i:before,
555
+ body .fl-theme-builder-preview-select-item-title i:before {
556
+ content: "\f078";
557
+ }
558
+ body .fl-theme-builder-preview-select-item-children {
559
+ overflow:auto;
560
+ }
561
+ body .fl-theme-builder-preview-select-item-child {
562
+ overflow: hidden;
563
+ text-overflow: ellipsis;
564
+ line-height: 1.1;
565
+ color: #6b6b6b;
566
+ margin: 0 10px;
567
+ border: 2px solid transparent;
568
+ border-radius:4px;
569
+ padding: 8px 10px 10px;
570
+ font-size:14px;
571
+ font-weight:normal;
572
+ color: #222222;
573
+ }
574
+ body .fl-theme-builder-preview-select-item-child:hover {
575
+ background: #e6eaed !important;
576
+ }
577
+ .fl-theme-builder-preview-select-item .fa-caret-down {
578
+ color: #606D77;
579
+ }
580
+
581
  .fl-builder-bar-actions {
582
+ display: flex;
583
+ flex-direction: row-reverse;
584
+ flex: 1 1 100%;
585
+ padding: 4px;
586
  }
587
  .fl-builder-bar .fl-builder-button {
588
+ margin: 0 0 0 4px;
 
589
  }
590
+ /* Actually the first button, but it's the last because it's inside a row-reverse container */
591
+ .fl-builder-bar-actions .fl-builder-button:last-child {
592
+ margin:0;
593
+ }
594
+ .fl-builder-bar-actions:after {
595
+ clear:both;
596
+ }
597
+ .fl-builder-bar .fl-builder-content-panel-button {
598
+ align-items: baseline !important;
599
+ padding-top:1px;
600
+ font-weight: 400;
601
+ }
602
+ .fl-builder-content-panel-button svg {
603
+ transition-property: transform;
604
+ transition-duration: .25s;
605
+ transform: rotate(0deg) scale(1);
606
+ transform-origin: center;
607
+ }
608
+ .fl-builder-content-panel-is-showing .fl-builder-content-panel-button svg {
609
+ transform: rotate(135deg) scale(1.1) translate(.5px, -.5px);
610
+ }
611
+ .fl-builder--saving-indicator {
612
+ cursor: pointer;
613
+ display: flex;
614
+ align-self: center;
615
+ padding: 0 16px;
616
+ font-size: 1em;
617
+ font-style:italic;
618
+ color: #676f7a;
619
+ }
620
+ .fl-builder--saving-indicator:hover {
621
+ color: #676f7a;
622
+ }
623
+ .fl-builder--saving-indicator .fa-question-circle {
624
+ font-size: 13px;
625
+ margin: 3px 0 3px 8px;
626
  }
627
 
628
  /* Buy/Upgrade button */
629
  .fl-builder-buy-button,
630
  .fl-builder-upgrade-button {
631
+ background: #F7A407;
 
 
 
632
  color: #fff !important;
633
  text-decoration: none;
634
  }
635
  .fl-builder-buy-button i.fa-external-link-square,
636
  .fl-builder-upgrade-button i.fa-external-link-square {
637
+ color: #FFC733;
638
  margin: 0 0 0 6px;
639
  }
640
  .fl-builder-buy-button:hover,
641
  .fl-builder-upgrade-button:hover {
642
+ background: #EE8E0D;
 
 
 
643
  color: #fff !important;
644
  }
645
 
646
  /* Responsive Bar */
647
+ @media (max-width: 980px) {
648
+ .fl-builder--main-menu-panel {
649
+ width: calc(100% - 20px) !important;
650
+ }
651
+ .fl-builder--main-menu-panel:before {
652
+ right:auto;
653
+ left: 20px;
654
  }
 
 
655
  .fl-builder-bar-title,
656
+ .fl-theme-builder-preview-select {
657
+ flex: 1 .5 380px !important;
658
+ }
659
+ }
660
+ @media (max-width:620px) {
661
+ .fl-theme-builder-preview-select.fl-builder-button {
662
+ display:none;
663
+ }
664
+ }
665
+ @media (max-width: 500px) {
666
+ .fl-builder-panel,
667
+ .fl-builder--main-menu-panel {
668
+ width: auto !important;
669
+ top:44px !important;
670
+ left: 0 !important;
671
+ right: 0 !important;
672
+ bottom: 0 !important;
673
+ border-radius:0 !important;
674
+ box-shadow: none !important;
675
+ }
676
+ .fl-builder--main-menu-panel {
677
+ border-left: transparent !important;
678
+ border-right: transparent !important;
679
+ border-bottom: transparent !important;
680
+ max-height: calc(100% - 44px) !important;
681
+ }
682
+ .fl-builder-bar-title {
683
+ flex: 0 0 100px !important;
684
+ }
685
+ .fl-builder-bar-title-area {
686
+ display:none;
687
+ }
688
+ .fl-builder--main-menu-panel:before {
689
+ display:none;
690
+ }
691
+ .fl-builder--panel-header {
692
+ border-radius: 0 !important;
693
+ cursor: default !important;
694
+ }
695
+ .fl-builder--panel-header .fl-builder--tabs {
696
+ cursor: default !important;
697
+ }
698
+ .fl-builder-panel:before {
699
+ display:none;
700
+ }
701
+ .fl-builder-panel-drag-handle {
702
+ display:none;
703
+ }
704
+ .fl-builder-publish-actions {
705
+ width:100% !important;
706
+ }
707
+ }
708
+ @media (max-width: 400px) {
709
+ .fl-builder-bar-actions .fl-builder-button {
710
+ padding: 0 8px;
711
  }
712
  }
713
 
714
+ .fl-builder--preview-actions {
715
+ display:none;
716
+ position: fixed;
717
+ top: 4px;
718
+ left: 4px;
719
+ z-index: 100008;
720
+ padding: 4px 4px 6px;
721
+ justify-content: center;
722
+ background:white;
723
+ border-radius: 4px;
724
+ }
725
+ .fl-builder-preview .fl-builder--preview-actions {
726
+ display: flex;
727
+ }
728
+ .fl-builder--preview-actions .device-icons {
729
+ color: #555;
730
+ background: #e4e4e4;
731
+ -webkit-box-shadow: 0 2px 0 #d6d6d6;
732
+ box-shadow: 0 2px 0 #d6d6d6;
733
+ border: none !important;
734
+ align-items: center;
735
+ display: flex;
736
+ text-decoration: none;
737
+ font-size: 14px !important;
738
+ line-height: 1 !important;
739
+ margin: 0;
740
+ margin-right:4px;
741
+ padding: 0 6px;
742
+ cursor: pointer;
743
+ -webkit-border-radius: 3px;
744
+ -webkit-appearance: none;
745
+ border-radius: 3px;
746
+ height: 33px;
747
+ }
748
+ .fl-builder--preview-actions .device-icons i {
749
+ margin: 0 6px;
750
+ }
751
+ /* @endgroup Toolbar */
752
+
753
+ /* @group Pinned UI
754
  ------------------------------------------------------ */
755
 
756
+ /* Pin Zones */
757
+ @keyframes fl-builder-ui-pin-zone-pulse {
758
+ 0% {
 
 
 
 
 
 
 
759
  opacity: 1;
760
+ filter: alpha( opacity = 1 );
761
+ }
762
+ 50% {
763
+ opacity: 0.5;
764
+ filter: alpha( opacity = 35 );
765
+ }
766
+ 100% {
767
+ opacity: 1;
768
+ filter: alpha( opacity = 1 );
769
+ }
770
+ }
771
+ .fl-builder-ui-pin-zone {
772
+ animation: fl-builder-ui-pin-zone-pulse 2s infinite;
773
+ transition: width 0.3s ease;
774
+ background: rgba(0, 160, 210, .5);
775
+ bottom: 0;
776
+ top: 0;
777
  position: fixed;
778
+ width: 35px;
779
+ z-index: 100001;
780
+ }
781
+ .fl-builder-ui-pin-zone-left {
782
+ left: 0;
783
+ }
784
+ .fl-builder-ui-show-pin-zone-left .fl-builder-ui-pin-zone-left {
785
+ width: 75px;
786
+ }
787
+ .fl-builder-ui-pin-zone-right {
788
  right: 0;
789
+ }
790
+ .fl-builder-ui-show-pin-zone-right .fl-builder-ui-pin-zone-right {
791
+ width: 75px;
792
+ }
793
+ .fl-builder-content-panel-pin-zone .fl-builder-content-panel-button {
794
+ display: flex !important;
795
+ background: rgba(0, 160, 210, .5) !important;
796
+ padding: 2px 4px;
797
+ width: 80px;
798
+ animation: fl-builder-ui-pin-zone-pulse 2s infinite;
799
+ }
800
+ .fl-builder-content-panel-pin-zone .fl-builder-content-panel-button svg {
801
+ display: none;
802
+ }
803
+ .fl-builder-content-panel-pin-zone-hover .fl-builder-content-panel-button {
804
+ width:120px;
805
+ }
806
+ .fl-builder-content-panel-pin-zone-hover .fl-builder-content-panel-button svg {
807
+ display: none !important;
808
+ width: 100%;
809
+ transform: none !important;
810
+ fill: #00A0D2 !important;
811
+ border-radius: 3px;
812
+ }
813
+ .fl-builder-content-panel-pin-zone .fl-builder-done-button {
814
+ filter: grayscale(100%);
815
+ }
816
+
817
+ /* Pinned - Panel State */
818
+ .fl-builder-ui-is-pinned .fl-builder-content-panel-button {
819
+ display: none;
820
+ }
821
+ .fl-builder-panel.fl-builder-ui-pinned {
822
+ top: 48px !important;
823
+ bottom: 0 !important;
824
+ height: auto !important;
825
+ border-radius: 0;
826
+ border:none;
827
+ box-shadow: none;
828
+ animation-duration: 0s;
829
+ -moz-animation-duration: 0s;
830
+ -webkit-animation-duration: 0s;
831
+ -o-animation-duration: 0s;
832
+ z-index: 9;
833
+ }
834
+ .fl-builder-panel.fl-builder-ui-pinned-right {
835
+ left: auto !important;
836
+ right: 0;
837
+ border-left: 2px solid #d5dadd;
838
+ }
839
+ .fl-builder-panel.fl-builder-ui-pinned-left {
840
+ left: 0;
841
+ right: auto;
842
+ border-right: 2px solid #d5dadd;
843
+ }
844
+ .fl-builder-panel.fl-builder-ui-pinned .fl-builder--panel-header {
845
+ border-radius: 0 !important;
846
+ }
847
+
848
+ /* Pinned - Lightbox State */
849
+ .fl-builder-ui-pinned-container .fl-lightbox-wrap {
850
+ position: absolute;
851
+ z-index: 9;
852
+ }
853
+ .fl-builder-ui-pinned-container .fl-lightbox {
854
+ position: absolute;
855
+ top: 0;
856
+ bottom: 0;
857
+ left: 0;
858
+ right: 0;
859
+ width: auto !important;
860
+ height: auto;
861
+ border-radius: 0;
862
+ box-shadow: none;
863
+ -moz-box-shadow: none;
864
+ -webkit-box-shadow: none;
865
+ animation-duration: 0s;
866
+ -moz-animation-duration: 0s;
867
+ -webkit-animation-duration: 0s;
868
+ -o-animation-duration: 0s;
869
+ }
870
+ .fl-builder-ui-pinned-container .fl-lightbox-header-wrap {
871
+ border-radius: 0;
872
+ }
873
+ .fl-builder-ui-pinned-container .fl-lightbox.ui-draggable .fl-lightbox-header {
874
+ cursor: auto;
875
+ }
876
+ .fl-builder-ui-pinned-container .fl-lightbox-header h1 {
877
+ padding: 12px 20px 10px !important;
878
+ }
879
+ .fl-builder-ui-pinned-container .fl-lightbox-controls {
880
+ display: none;
881
+ }
882
+
883
+ /* Pinned - Content Transform */
884
+ .fl-builder-ui-pinned-content-transform {
885
+ transform: scale(1);
886
+ transform-origin: center top 0px;
887
+ }
888
+
889
+ /* Pinned - Collapse Controls */
890
+ .fl-builder-ui-pinned-collapse {
891
+ cursor: pointer;
892
+ display: none;
893
+ position: absolute !important;
894
+ bottom: 2px;
895
+ padding: 5px;
896
+ border: 2px solid transparent;
897
+ background: transparent;
898
+ width: 36px;
899
+ height: 36px;
900
+ border-radius: 4px;
901
+ fill: #778794;
902
+ flex-direction: row;
903
+ justify-content: center;
904
+ }
905
+ .fl-builder-ui-pinned-collapse:hover,
906
+ .fl-builder-ui-pinned-collapse:focus {
907
+ top:auto !important;
908
+ background:transparent;
909
+ border: 2px solid transparent;
910
+ outline:none;
911
+ fill: #00A0D2;
912
+ }
913
+ .fl-builder-ui-pinned-collapse:focus {
914
+ background: #E4E7EA;
915
+ }
916
+ .fl-builder-ui-pinned-collapse > * {
917
+ margin:auto;
918
+ line-height: 1;
919
+ }
920
+ .fl-builder-ui-pinned-collapse svg g {
921
+ fill:inherit;
922
+ }
923
+ .fl-builder-ui-is-pinned-right .fl-builder-ui-pinned-right-collapse {
924
+ display: flex;
925
+ left: -40px;
926
+ }
927
+ .fl-builder-ui-is-pinned-left .fl-builder-ui-pinned-left-collapse {
928
+ display: flex;
929
+ right: -40px;
930
+ }
931
+ .fl-builder-ui-pinned-collapse i[data-toggle="show"],
932
+ .fl-builder-ui-pinned-is-collapsed i[data-toggle="hide"] {
933
+ display: none;
934
+ }
935
+ .fl-builder-ui-pinned-is-collapsed i[data-toggle="show"] {
936
+ display: block;
937
+ }
938
+ .fl-builder-ui-is-pinned-left [data-toggle="hide"],
939
+ .fl-builder-ui-is-pinned-right [data-toggle="show"] {
940
+ transform: rotateY(180deg);
941
+ }
942
+ .fl-builder-ui-pinned-is-collapsed .fl-lightbox {
943
+ box-shadow: none;
944
+ -moz-box-shadow: none;
945
+ -webkit-box-shadow: none;
946
+ }
947
+
948
+ .fl-builder-ui-pinned-is-collapsed .fl-builder--panel-header {
949
+ display:none; /* to take it out of tab order while collapsed */
950
+ }
951
+
952
+ /* Pinned - iFrame Fix */
953
+ .fl-builder-resizable-is-resizing .fl-builder-content,
954
+ .fl-builder-resizable-is-resizing .fl-builder-panel .fl-lightbox,
955
+ .fl-builder-draggable-is-dragging .fl-builder-panel .fl-lightbox,
956
+ .fl-builder-draggable-is-dragging .fl-builder-content {
957
+ pointer-events: none;
958
+ }
959
+
960
+ /* @endgroup Pinned UI */
961
+
962
+ /* @group Content Panel
963
+ ------------------------------------------------------ */
964
+ @keyframes fl-builder-show-panel {
965
+ from {
966
+ transform: scale(.8);
967
+ }
968
+ to {
969
+ transform: scale(1);
970
+ }
971
+ }
972
+ .fl-builder-panel,
973
+ .fl-builder--search-results-panel {
974
+ box-sizing: border-box;
975
+ position: fixed !important;
976
+ right: 20px;
977
+ top: calc(48px + 10px);
978
+ width: 380px;
979
+ bottom: 20px;
980
+ background: #F5F7F9;
981
+ color: #676F7A;
982
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
983
+ font-size: 14px;
984
+ border-radius: 4px;
985
+ box-shadow: 0px 8px 40px 4px rgba(0, 0, 0, 0.3);
986
+ z-index: 10000007;
987
+ will-change: transform;
988
+ display:none;
989
  -webkit-touch-callout: none;
990
  -webkit-user-select: none;
991
  -khtml-user-select: none;
993
  -ms-user-select: none;
994
  user-select: none;
995
  }
996
+ .fl-builder-panel {
997
+ transform-origin: top right;
998
+ animation-name: fl-builder-show-panel;
999
+ animation-duration: .15s;
1000
+ animation-fill-mode: both;
1001
+ }
1002
+ .fl-builder--search-results-panel {
1003
+ position: absolute;
1004
+ right: 0;
1005
+ top: 93px;
1006
+ left: 0;
1007
+ bottom:0;
1008
+ width: auto !important;
1009
+ border:none;
1010
+ border-radius:0;
1011
+ box-shadow:none;
1012
+ min-height: 100px;
1013
+ max-height: calc(100vh - 54px);
1014
+ overflow:auto;
1015
+ z-index:1;
1016
+ }
1017
+ .fl-builder-content-panel-is-showing .fl-builder-panel,
1018
+ .fl-builder-search-results-panel-is-showing .fl-builder--search-results-panel {
1019
+ display:block;
1020
+ }
1021
+ .fl-builder-content-panel-is-showing .fl-builder-panel.fl-builder--current-view-templates {
1022
+ width: 520px;
1023
+ }
1024
+ .fl-builder--search-results-panel .fl-builder--no-results {
1025
+ text-align: center;
1026
+ padding: 50px 20px;
1027
+ }
1028
+
1029
+ .fl-builder--panel-arrow {
1030
+ position: absolute;
1031
+ top: -13px;
1032
+ right: 10px;
1033
+ }
1034
+ .fl-builder-ui-is-pinned .fl-builder--panel-arrow,
1035
+ body.fl-builder-draggable-is-dragging .fl-builder--panel-arrow {
1036
+ display: none;
1037
+ }
1038
+ .fl-builder--panel-arrow polygon {
1039
+ fill: #00a0d2;
1040
+ }
1041
 
1042
  /* Builder Panel Actions
1043
  ------------------------------------------------------ */
1044
 
1045
+ .fl-builder--panel-header {
1046
+ background:white;
1047
+ border-top: 3px solid #00a0d2;
1048
+ border-bottom: 2px solid #e6eaed;
1049
+ border-top-right-radius: 4px;
1050
+ border-top-left-radius: 4px;
1051
+ }
1052
+ .fl-builder-ui-is-pinned .fl-builder--panel-header {
1053
+ border-top-color: transparent;
1054
+ }
1055
+ .fl-builder-panel-drag-handle {
1056
  position: absolute;
1057
+ top: 7px;
1058
+ left: 10px;
1059
+ fill: #ccd4da;
1060
+ width: 6px;
1061
  }
1062
+ .fl-builder-ui-is-pinned-left .fl-builder-panel-drag-handle {
1063
+ left: auto;
1064
+ right:10px;
1065
+ }
1066
+ .fl-builder-panel .fl-lightbox .fl-builder-panel-drag-handle,
1067
+ .fl-lightbox-width-full .fl-builder-panel-drag-handle {
1068
+ display: none;
1069
+ }
1070
+ .fl-builder--panel-header .fl-builder--panel-controls {
1071
+ display: flex;
1072
+ flex-direction: row;
1073
+ position: relative;
1074
+ }
1075
+ .fl-builder--panel-header .fl-builder--panel-controls .fl-builder-content-group-select {
1076
+ flex: 1 1;
1077
+ }
1078
+ .fl-builder--panel-header .fl-builder--panel-controls .fl-builder-panel-search {
1079
+ flex: 0 0;
1080
+ padding: 0 10px 6px;
1081
+ padding-left:0;
1082
+ margin-left: -4px; /* compensate for group select padding */
1083
+ }
1084
+ .fl-builder--panel-controls .fl-builder-panel-search button {
1085
+ width: 38px;
1086
+ background: transparent !important;
1087
+ border: 2px solid transparent !important;
1088
+ font-size: inherit;
1089
+ height: 38px;
1090
+ padding:0;
1091
+ }
1092
+ .fl-builder--panel-controls .fl-builder-panel-search button:focus,
1093
+ .fl-builder--panel-controls .fl-builder-panel-search button:active {
1094
+ top:0;
1095
+ outline: none;
1096
+ }
1097
+ .fl-builder-panel-search button svg {
1098
+ height:auto;
1099
+ width:20px;
1100
+ }
1101
+ .fl-builder-panel-search button.fl-builder-dismiss-panel-search svg {
1102
+ width: 16px;
1103
+ }
1104
+ .fl-builder-panel-search button svg .filled-shape {
1105
+ fill:black;
1106
+ }
1107
+ .fl-builder--panel-controls .fl-builder-panel-search button:focus svg .filled-shape,
1108
+ .fl-builder--panel-controls .fl-builder-panel-search button:active svg .filled-shape {
1109
+ fill: #00A0D2;
1110
+ }
1111
+ .fl-builder-panel-search .fl-builder-panel-search-input {
1112
+ display: none;
1113
+ position: absolute;
1114
+ top:0;
1115
+ left:0;
1116
+ right:0;
1117
+ bottom:0;
1118
+ background:white;
1119
  }
1120
+ .fl-builder-panel-search.is-showing-input .fl-builder-panel-search-input {
1121
+ display: flex;
1122
+ flex-direction: row;
1123
+ padding: 0 10px 6px;
1124
+ }
1125
+ .fl-builder-panel-search-input input {
1126
+ flex: 1 1 100%;
1127
+ border: 2px solid #e6eaed;
1128
+ background:white;
1129
+ border-radius: 4px;
1130
+ margin-right: 4px;
1131
+ padding: 10px;
1132
  color: #333;
1133
  }
1134
+ .fl-builder-panel-search-input input:focus {
1135
+ border-color: #0197C6;
1136
+ outline: none;
1137
+ }
1138
+ .fl-builder-panel-search-input button {
1139
+ flex: 0 0 38px;
1140
+ }
1141
 
1142
  /* Builder Panel Content
1143
  ------------------------------------------------------ */
1154
  .fl-builder-panel-content {
1155
  padding-bottom: 60px;
1156
  }
1157
+ .fl-builder-blocks-section {
1158
+ border-top: 2px solid #e6eaed;
1159
+ }
1160
+ .fl-builder--panel-view .fl-builder-blocks-section:first-child {
1161
+ border-top:none;
1162
+ }
1163
+ .fl-builder-blocks-group:first-child {
1164
+ padding: 20px 0 0;
1165
+ }
1166
+ .fl-builder-blocks-group .fl-builder-blocks-section-group-name {
1167
+ display: block;
1168
+ padding: 0 30px 15px;
1169
+ color: #000000;
1170
+ font-size: 20px;
1171
+ font-weight: 600;
1172
+ line-height: 1.4;
1173
+ }
1174
  .fl-builder-blocks-section .fl-builder-blocks-section-title,
1175
  .fl-builder-blocks-section .fl-builder-block {
 
1176
  display: block;
1177
+ line-height: 1.1;
1178
  padding: 15px 20px;
1179
  }
1180
+ .fl-builder-blocks-section .fl-builder-blocks-section-title,
1181
+ .fl-builder--template-collection-section-name {
1182
+ display: inline-block;
1183
+ font-weight: 700;
1184
+ font-size: 12px;
1185
+ line-height: 1.2;
1186
+ text-transform: uppercase;
1187
+ padding-top: 30px;
1188
+ color: #333333;
1189
+ padding: 4px 10px;
1190
+ padding-left: 15px;
1191
+ margin:0 !important;
1192
+ background: #e6eaed;
1193
+ border-bottom-right-radius: 4px;
1194
+ user-select: none;
1195
+ vertical-align: top;
1196
  }
1197
  .fl-builder-blocks-section .fl-builder-blocks-section-title i {
1198
  color: #bfbfbf;
1199
  float: right;
1200
  }
1201
+ .fl-builder-blocks-section-content {
1202
+ overflow: auto;
1203
+ padding: 10px 10px 20px;
1204
+ }
1205
+ .fl-builder-blocks-section-content:after {
1206
+ float:none;
1207
+ clear:both;
1208
+ }
1209
+ .fl-builder-blocks-section-content.fl-builder-modules,
1210
+ .fl-builder-blocks-section-content.fl-builder-widgets,
1211
+ .fl-builder-blocks-section-content.fl-builder-rows {
1212
+ display: flex;
1213
+ flex-wrap: wrap;
1214
+ }
1215
+ .fl-builder-blocks-section-content .fl-builder-block-module,
1216
+ .fl-builder-blocks-section-content .fl-builder-block-row {
1217
+ flex: 1 1 50%;
1218
+ width:50%;
1219
+ box-sizing: border-box;
1220
+ }
1221
+ .fl-builder--search-results-panel .fl-builder-blocks-section-content .fl-builder-block-module {
1222
+ flex: 1 1 100%;
1223
+ width: 100%;
1224
+ }
1225
+ .fl-builder-blocks-section.fl-active .fl-builder-blocks-section-content {
1226
+ display: block;
1227
+ }
1228
+ .fl-builder-blocks-section-content .fl-builder-block {
1229
+ box-sizing: border-box;
1230
+ overflow: hidden;
1231
+ text-overflow: ellipsis;
1232
+ white-space: nowrap;
1233
+ border-radius: 4px;
1234
+ font-size: 14px;
1235
+ line-height: 1.1;
1236
+ font-weight: 500;
1237
+ color: #727272;
1238
+ }
1239
+ .fl-builder-block {
1240
+ position: relative;
1241
+ height:47px;
1242
+ }
1243
+ .fl-builder-block.fl-builder-block-col-group {
1244
+ height:84px;
1245
+ }
1246
+ .fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail,
1247
+ .fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail,
1248
+ .fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail,
1249
+ .fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail {
1250
+ padding:10px;
1251
+ }
1252
+ .fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail,
1253
+ .fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail,
1254
+ .fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail,
1255
+ .fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail {
1256
+ height:auto;
1257
+ }
1258
+ .fl-builder-block:hover {
1259
+ overflow:visible;
1260
+ z-index: 1;
1261
+ }
1262
+ .fl-builder-block:hover .fl-builder-block-content {
1263
+ display: block;
1264
+ box-sizing: border-box;
1265
+ position: absolute;
1266
+ top:0;
1267
+ left:0;
1268
+ width: 100%;
1269
+ padding: 15px 20px;
1270
+ border-radius: 4px;
1271
+ background: #ffffff;
1272
+ box-shadow: 0 2px 4px 0 rgba(0,0,0,0.12);
1273
+ text-decoration: none;
1274
+ color: #111111;
1275
+ cursor: move;
1276
+ overflow:hidden;
1277
+ }
1278
+ .fl-builder-block-module:hover .fl-builder-block-content {
1279
+ width:auto; /* modules allow auto width to show long titles */
1280
+ min-width:100%;
1281
+ }
1282
+
1283
+ .fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail .fl-builder-block-content,
1284
+ .fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail .fl-builder-block-content,
1285
+ .fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail .fl-builder-block-content,
1286
+ .fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail .fl-builder-block-content {
1287
+ position: relative;
1288
+ }
1289
+
1290
+ .fl-builder-block .fl-builder-block-content .fl-builder-block-visual {
1291
+ display: block;
1292
+ margin-bottom: 7px;
1293
+ }
1294
+ .fl-builder-block-drag-helper .fl-builder-block-content .fl-builder-block-visual {
1295
+ display: none !important;
1296
+ }
1297
+ .fl-builder-block .fl-builder-block-content .fl-builder-block-visual.fl-cols-visual {
1298
+ display: flex;
1299
+ flex-direction: row;
1300
+ height: 30px;
1301
+ }
1302
+ .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col {
1303
+ flex: 1 100%;
1304
+ background: #464a4c;
1305
+ height: 30px;
1306
+ margin: 0 2px;
1307
+ border-radius: 2px;
1308
+ }
1309
+ .fl-builder-block:hover .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col {
1310
+ background: #000000;
1311
+ }
1312
+ .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col:first-child {
1313
+ margin-left: 0 !important;
1314
+ }
1315
+ .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col:last-child {
1316
+ margin-right: 0 !important;
1317
+ }
1318
+ .fl-cols-visual.left-sidebar .fl-cols-visual-col:first-child {
1319
+ flex-basis:60px;
1320
+ }
1321
+ .fl-cols-visual.right-sidebar .fl-cols-visual-col:last-child {
1322
+ flex-basis:60px;
1323
+ }
1324
+ .fl-cols-visual.left-right-sidebar .fl-cols-visual-col:first-child,
1325
+ .fl-cols-visual.left-right-sidebar .fl-cols-visual-col:last-child {
1326
+ flex-basis:60px;
1327
  }
1328
+
1329
+ .fl-builder-block-saved-module.fl-builder-block-global .fl-builder-block-title,
1330
+ .fl-builder-block-saved-module:hover .fl-builder-block-title,
1331
+ .fl-builder-block-saved-row.fl-builder-block-global .fl-builder-block-title,
1332
+ .fl-builder-block-saved-row:hover .fl-builder-block-title {
1333
+ margin-right: 70px;
1334
  }
1335
+
1336
+ .fl-builder-block-module:nth-child(even):hover .fl-builder-block-content {
1337
+ left:auto;
1338
+ right:0;
1339
+ }
1340
+ .fl-builder-block-thumbnail {
1341
+ border-radius: 4px;
1342
+ background-size: contain;
1343
+ background-repeat: no-repeat;
1344
+ background-position: center;
1345
+ background-color: rgba(0, 0, 0, 0.06);
1346
+ margin-bottom:10px;
1347
+ transform-origin: bottom;
1348
+ transition-property: transform, box-shadow;
1349
+ transition-duration: .15s;
1350
+ }
1351
+ .fl-builder-block:hover .fl-builder-block-thumbnail {
1352
+ transform:scale(1.05);
1353
+ box-shadow: 0px 20px 40px rgba(0, 0, 0, 0.08)
1354
+ }
1355
+ .fl-builder-block .fl-builder-block-icon {
1356
+ margin-right:7px;
1357
+ fill: #000000;
1358
+ display: inline-block;
1359
+ width:20px;
1360
+ height:20px;
1361
+ vertical-align: middle;
1362
+ }
1363
+ .fl-builder-block-thumbnail:before {
1364
+ content: "";
1365
+ display:block;
1366
+ padding-top:50%;
1367
+ }
1368
+ .fl-builder-block-thumbnail img {
1369
+ max-width: 100%;
1370
+ max-height: 160px;
1371
+ margin: 0;
1372
+ object-fit: cover;
1373
  }
1374
  .fl-builder-blocks-section-content .fl-builder-block {
1375
+ box-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
1376
+ transition-property: box-shadow;
1377
+ transition-duration: .15s;
 
1378
  }
1379
+ .fl-builder-blocks-section-content .fl-builder-block i,
1380
+ .fl-user-template-actions i {
1381
+ color: #000000;
1382
  margin-right: 10px;
1383
  }
1384
+ .fl-builder-blocks-section-content .fl-builder-block .fl-builder-block-details {
1385
+ position: relative;
 
 
1386
  }
1387
  .fl-builder-blocks-separator {
1388
+ background: #f1f1f1;
1389
  height: 6px;
1390
  }
1391
  .fl-builder-block:hover .fl-builder-badge {
1418
  margin: 3px 0px 0 9px !important;
1419
  }
1420
 
1421
+ .fl-builder--panel-message {
1422
+ text-align: center;
1423
+ padding:40px 20px;
1424
+ font-size: 16px;
1425
+ }
1426
+ .fl-builder--panel-message .fl-builder-button {
1427
+ display: inline-block;
1428
+ padding:10px;
1429
+ }
1430
+ .fl-builder--panel-cta {
1431
+ padding: 20px 30px;
1432
+ font-size:16px;
1433
+ text-align: center;
1434
+ }
1435
+ .fl-builder--panel-cta a {
1436
+ color:inherit;
1437
+ text-decoration: none;
1438
+ }
1439
+ .fl-builder--panel-cta a:hover {
1440
+ text-decoration: none;
1441
+ }
1442
+
1443
  /* Builder Panel Templates
1444
  ------------------------------------------------------ */
1445
 
1448
  max-width: 100%;
1449
  border: 1px solid #dfdfdf;
1450
  }
1451
+ .fl-builder-block .fl-builder-block-title {
 
1452
  overflow: hidden;
1453
  text-overflow: ellipsis;
1454
+ vertical-align: middle;
1455
+ line-height: 1.3;
1456
  }
1457
  .ui-sortable-helper .fl-builder-block-template-image {
1458
  display: none !important;
1459
  }
1460
 
1461
+ @keyframes fl-builder-template-item-enter {
1462
+ from {
1463
+ transform: translateY(100px) scale(.3);
1464
+ opacity:0;
1465
+ }
1466
+ to {
1467
+ transform: scale(1);
1468
+ opacity:1;
1469
+ }
1470
+ }
1471
+ .fl-builder--template-collection {
1472
+ clear:both;
1473
+ padding:10px 0;
1474
+ }
1475
+ .fl-builder--template-collection-section-content {
1476
+ padding: 0 10px;
1477
+ }
1478
+ .fl-builder--template-collection-item {
1479
+ box-sizing: border-box;
1480
+ width: 50%;
1481
+ float:left;
1482
+ padding:10px;
1483
+ cursor: pointer;
1484
+ font-size: 13px;
1485
+ transform-origin: center;
1486
+ opacity: 1;
1487
+ }
1488
+ .fl-builder--template-thumbnail {
1489
+ background-size: cover;
1490
+ background-clip: content-box;
1491
+ background-position: center top;
1492
+ background-color:white;
1493
+ border:2px solid transparent;
1494
+ transform-origin: bottom;
1495
+ transition-property: transform, box-shadow;
1496
+ transition-duration: .15s;
1497
+ }
1498
+ .fl-builder--template-collection-item[data-id="0"] .fl-builder--template-thumbnail {
1499
+ border-color: #e4e7ea;
1500
+ }
1501
+ .fl-user-template .fl-builder--template-thumbnail {
1502
+ border-color: #e4e7ea;
1503
+ }
1504
+
1505
+ .fl-builder--template-thumbnail:before {
1506
+ display:block;
1507
+ content: "";
1508
+ padding-top:120%;
1509
+ }
1510
+ .fl-builder--template-thumbnail:hover {
1511
+ transform: scale(1.05);
1512
+ box-shadow: 0px 20px 40px rgba(0, 0, 0, 0.08);
1513
+ }
1514
+ .fl-builder--template-name {
1515
+ text-align: center;
1516
+ padding:4px 0;
1517
+ overflow: hidden;
1518
+ white-space: nowrap;
1519
+ text-overflow: ellipsis;
1520
+ }
1521
+ .fl-builder--template-collection-section {
1522
+ padding-bottom: 10px;
1523
+ border-bottom: 1px solid #dfdfdf;
1524
+ }
1525
+ .fl-builder--template-collection-section:after,
1526
+ .fl-builder--template-collection-section:before {
1527
+ content: "";
1528
+ display: block;
1529
+ clear:both;
1530
+ }
1531
+ .fl-builder--template-collection-section-name {
1532
+ padding: 15px 10px 10px;
1533
+ }
1534
+ .fl-builder--template-collection-section-name:before,
1535
+ .fl-builder--template-collection-section-name:after,
1536
+ .fl-builder--template-collection-section-content:before,
1537
+ .fl-builder--template-collection-section-content:after {
1538
+
1539
+ }
1540
+
1541
  /* Builder Panel Node Templates
1542
  ------------------------------------------------------ */
1543
 
1544
  span.fl-builder-block-no-node-templates {
1545
  display: block;
1546
  padding: 15px 20px;
1547
+ text-align: center;
1548
  }
1549
  span.fl-builder-block-no-node-templates:hover {
1550
  cursor: default;
 
1551
  }
1552
  .fl-builder-blocks-node-template .fl-builder-block {
1553
  position: relative;
1554
  }
 
 
 
 
 
 
 
 
 
 
 
1555
  .fl-builder-blocks-section-content .fl-builder-node-template-actions {
1556
  bottom: 0;
1557
  cursor: default;
1559
  position: absolute;
1560
  right: 0;
1561
  top: 0;
 
1562
  }
1563
  .fl-builder-blocks-section-content .fl-builder-node-template-edit,
1564
  .fl-builder-blocks-section-content .fl-builder-node-template-delete {
1565
+ display: inline;
1566
  cursor: pointer;
1567
  margin: 0;
1568
+ padding: 15px 10px;
 
 
1569
  text-align: center;
 
1570
  width: 30px;
1571
  }
1572
+ .fl-builder-block-details .fl-builder-node-template-edit,
1573
+ .fl-builder-block-details .fl-builder-node-template-delete {
1574
+ padding-top: 0 !important;
 
 
1575
  }
1576
  .fl-builder-blocks-section-content .fl-builder-node-template-edit i,
1577
  .fl-builder-blocks-section-content .fl-builder-node-template-delete i {
1579
  }
1580
  .fl-builder-blocks-section-content .fl-builder-node-template-edit:hover i,
1581
  .fl-builder-blocks-section-content .fl-builder-node-template-delete:hover i {
1582
+ color: #444444;
 
 
 
1583
  }
1584
  .fl-builder-blocks-node-template .fl-builder-block:hover .fl-builder-node-template-actions {
1585
  display: block;
1588
  .ui-sortable-helper .fl-builder-node-template-delete {
1589
  display: none !important;
1590
  }
1591
+ /* @endgroup Content Panel */
1592
+
1593
+ /* @group Panel
1594
+ ------------------------------------------------------ */
1595
+
1596
+ .fl-builder--tabs {
1597
+ display: flex;
1598
+ flex-direction: row;
1599
+ position: relative;
1600
+ justify-content: flex-start;
1601
+ align-items: center;
1602
+ }
1603
+ .fl-builder-panel .fl-builder--panel-header {
1604
+ cursor:move;
1605
+ position: absolute;
1606
+ top: 0;
1607
+ left: 0;
1608
+ right: 0;
1609
+ z-index: 9;
1610
+ }
1611
+ .fl-builder-panel .fl-builder--tabs {
1612
+ justify-content: space-around;
1613
+ padding: 0 24px;
1614
+ min-height: 46px;
1615
+ cursor: pointer;
1616
+ }
1617
+ .fl-builder--tab-wrap {
1618
+ flex: 1 1 100%;
1619
+ display: flex;
1620
+ flex-direction: row;
1621
+ align-items: stretch;
1622
+ justify-content: space-between;
1623
+ }
1624
+ .fl-builder--tabs button,
1625
+ .fl-builder--tabs button:hover,
1626
+ .fl-builder--tabs button:focus,
1627
+ .fl-builder--tabs button:active {
1628
+ flex:1 1 100%;
1629
+ display: inline-block;
1630
+ text-decoration: none;
1631
+ color:inherit;
1632
+ text-align: center;
1633
+ letter-spacing: normal !important;
1634
+ padding:5px;
1635
+ cursor: pointer;
1636
+ font-size: 14px !important;
1637
+ font-weight: 600 !important;
1638
+ line-height: 1.4 !important;
1639
+ background: transparent !important;
1640
+ outline: none !important;
1641
+ border: 2px solid transparent;
1642
+ border-radius: 4px;
1643
+ margin: 7px 0px;
1644
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
1645
+ top:0; /* fix default button active */
1646
+ transition-property: background, color;
1647
+ transition-duration: .25s;
1648
+ }
1649
+ .fl-builder--tabs button:focus {
1650
+ background: #e6eaed !important;
1651
+ }
1652
+ .fl-builder--tabs button.is-showing { /* active tab */
1653
+ color: #0086b0;
1654
+ }
1655
+ .fl-builder--panel-view {
1656
+ display: none;
1657
+ overflow: hidden;
1658
+ }
1659
+ .fl-builder--panel-view.is-showing {
1660
+ display: block;
1661
+ }
1662
+ .fl-builder--content-library-panel .fl-builder--panel-view.is-showing {
1663
+ position: absolute;
1664
+ top: 96px;
1665
+ bottom:0;
1666
+ left:0;
1667
+ right:0;
1668
+ width: auto;
1669
+ height: auto;
1670
+ }
1671
+ .fl-builder--content-library-panel.single-view .fl-builder--panel-view.is-showing {
1672
+ top: 52px;
1673
+ }
1674
+
1675
+ .fl-builder--content-library-panel.ui-draggable-dragging {
1676
+ height: 500px !important;
1677
+ }
1678
+ .fl-builder--content-library-panel .fl-builder-drop-zone {
1679
+ display: none !important;
1680
+ }
1681
+
1682
+
1683
+ .fl-builder--panel-header .fl-builder--tabs {
1684
+ cursor: move;
1685
+ }
1686
+
1687
+ .fl-builder--category-select {
1688
+ display: flex;
1689
+ flex-direction: column;
1690
+ position: relative;
1691
+ }
1692
+ .fl-builder--selector-display {
1693
+ display: flex;
1694
+ flex-direction: row;
1695
+ position: relative;
1696
+ justify-content: space-between;
1697
+ align-items: center;
1698
+ color: #161B20;
1699
+ background: white url(../img/svg/select-arrow-down-alt2.svg) no-repeat center right 10px !important;
1700
+ cursor: pointer;
1701
+ font-size: 13px;
1702
+ font-weight: 700;
1703
+ line-height: 16px;
1704
+ border-radius: 4px;
1705
+ }
1706
+ .fl-builder--selector-display-label {
1707
+ display: flex;
1708
+ flex-direction: row;
1709
+ font-size: inherit;
1710
+ line-height: inherit;
1711
+ width: 100%;
1712
+ padding:0 !important;
1713
+ color: #6D6D6D;
1714
+ background: none;
1715
+ border: 2px solid #e4e7ea;
1716
+ border-radius: 4px;
1717
+ font-family: inherit;
1718
+ }
1719
+ .fl-builder--selector-display-label:hover,
1720
+ .fl-builder--selector-display-label:active {
1721
+ top:0;
1722
+ color: inherit;
1723
+ background: none;
1724
+ border: 2px solid #e4e7ea;
1725
+ border-radius: 4px;
1726
+ }
1727
+ .fl-builder--selector-display-label:focus {
1728
+ top:0;
1729
+ color: inherit;
1730
+ background:none;
1731
+ border: 2px solid #00A0D2;
1732
+ outline: none;
1733
+ }
1734
+ .fl-builder--group-label {
1735
+ color: inherit;
1736
+ flex: 0 0 0%;
1737
+ padding: 9px 10px;
1738
+ padding-right: 12px;
1739
+ background: #e6eaed;
1740
+ border-top-left-radius: 2px;
1741
+ border-bottom-left-radius: 2px;
1742
+ }
1743
+ .fl-builder--current-view-name {
1744
+ flex: 1 1 100%;
1745
+ color: inherit;
1746
+ overflow: hidden;
1747
+ text-overflow: ellipsis;
1748
+ white-space: nowrap;
1749
+ font-weight: 600;
1750
+ padding: 9px 10px;
1751
+ text-align: left;
1752
+ }
1753
+ .fl-builder--selector-menu {
1754
+ display: none;
1755
+ overflow:auto;
1756
+ color: #293138;
1757
+ position: absolute;
1758
+ top: 46px;
1759
+ left: 0;
1760
+ width: 100%;
1761
+ background: white;
1762
+ border-radius: 4px;
1763
+ box-shadow: 0px 0px 20px 2px rgba(0, 0, 0, 0.2);
1764
+ overflow: visible;
1765
+ }
1766
+ .fl-builder--selector-menu:before {
1767
+ bottom: 100%;
1768
+ right: 8px;
1769
+ content: " ";
1770
+ height: 0;
1771
+ width: 0;
1772
+ position: absolute;
1773
+ pointer-events: none;
1774
+ border: solid;
1775
+ border-color: rgba(255, 255, 255, 0);
1776
+ border-bottom-color: #ffffff;
1777
+ border-width: 10px;
1778
+ margin-left: -10px;
1779
+ }
1780
+ .fl-builder--category-select.is-showing .fl-builder--selector-menu {
1781
+ display: flex;
1782
+ max-height: calc(100vh - 150px);
1783
+ }
1784
+ .fl-builder--category-select.is-showing .fl-builder--selector-menu .fl-builder--menu {
1785
+ margin:10px 0;
1786
+ flex: 1 100%;
1787
+ overflow: auto;
1788
+ }
1789
+ button.fl-builder-button.fl-builder-bar-title-caret {
1790
+ margin:4px;
1791
+ }
1792
+ button.fl-builder-button.fl-builder-bar-title-caret:focus {
1793
+ background-color: #e6eaed !important;
1794
+ border-color: transparent !important;
1795
+ }
1796
+ .fl-builder--category-select.is-showing .fl-builder-bar-title-caret i {
1797
+ transform: rotate(180deg);
1798
+ }
1799
+
1800
+ .fl-builder--menu {
1801
+ padding:4px;
1802
+ margin-bottom:2px;
1803
+ }
1804
+ .fl-builder--menu > span,
1805
+ .fl-builder--menu > a,
1806
+ .fl-builder--menu > button {
1807
+ display: block;
1808
+ padding:8px 10px 10px;
1809
+ border-radius: 4px;
1810
+ color:inherit;
1811
+ text-decoration: none;
1812
+ background:transparent !important;
1813
+ border: 2px solid transparent !important;
1814
+ font-weight: normal;
1815
+ font-family: inherit;
1816
+ }
1817
+ .fl-builder--menu > a:hover,
1818
+ .fl-builder--menu > button:hover,
1819
+ .fl-builder--menu > a:active,
1820
+ .fl-builder--menu > button:active {
1821
+ top:0;
1822
+ background: #e6eaed !important;
1823
+ border: 2px solid transparent !important;
1824
+ }
1825
+ .fl-builder--menu > a:focus,
1826
+ .fl-builder--menu > button:focus {
1827
+ top:0;
1828
+ outline:none;
1829
+ color:inherit;
1830
+ background: #e6eaed !important;
1831
+ border: 2px solid transparent !important;
1832
+ text-decoration: none;
1833
+ }
1834
+ .fl-builder--menu .fl-inset {
1835
+ padding-left:35px;
1836
+ font-size: 14px;
1837
+ line-height: 1.25;
1838
+ }
1839
+ .fl-builder--menu a.fl-template-collection {
1840
+ color: #161B20;
1841
+ }
1842
+ .fl-builder--menu > *:after {
1843
+ clear:both;
1844
+ }
1845
+ .fl-builder--menu * .fl-builder--menu-item-accessory {
1846
+ float:right;
1847
+ color: #000000;
1848
+ text-transform: uppercase;
1849
+ text-align: center;
1850
+ min-width: 20px;
1851
+ letter-spacing: 2px;
1852
+ }
1853
+ .fl-builder--menu * .fl-builder--menu-item-accessory i {
1854
+ font-size:1em;
1855
+ margin-top:2px;
1856
+ }
1857
+ .fl-builder--menu hr {
1858
+ margin:4px 30px;
1859
+ }
1860
+ .fl-builder--menu .fl-builder-video-wrap iframe {
1861
+ display: block;
1862
+ margin:4px 0;
1863
+ width: 100%;
1864
+ }
1865
+ /* @endgroup Admin Panel */
1866
+
1867
+ /* @group Publish Actions */
1868
+ .fl-builder-publish-actions {
1869
+ display: flex;
1870
+ box-sizing: border-box;
1871
+ position: absolute;
1872
+ top:0;
1873
+ right:0;
1874
+ width: 380px;
1875
+ max-width: 100%;
1876
+ height:46px;
1877
+ padding: 4px;
1878
+ flex-direction: row;
1879
+ justify-content: flex-end;
1880
+ opacity:1;
1881
+ pointer-events: auto;
1882
+ transform: scaleX(1) translateX(0px);
1883
+ transform-origin: right;
1884
+ transition-property: transform, opacity;
1885
+ transition-duration: .15s;
1886
+ }
1887
+ .fl-builder-publish-actions.is-hidden {
1888
+ transform: scaleX(.23) translateX(68px);
1889
+ opacity:0;
1890
+ pointer-events: none;
1891
+ }
1892
+ .fl-builder-bar .fl-builder-button-group {
1893
+ display: flex;
1894
+ flex-basis: 100%;
1895
+ }
1896
+ .fl-builder-bar .fl-builder-button-group > .fl-builder-button {
1897
+ border-radius: 0;
1898
+ margin-left: 0px;
1899
+ flex-basis: 100%;
1900
+ text-align: center;
1901
+ justify-content: space-around;
1902
+ }
1903
+ .fl-builder-bar .fl-builder-button-group > .fl-builder-button {
1904
+ box-shadow:none;
1905
+ }
1906
+ .fl-builder-bar .fl-builder-button-group > .fl-builder-button:first-child {
1907
+ margin-left:0;
1908
+ border-top-left-radius: 3px;
1909
+ border-bottom-left-radius: 3px;
1910
+ }
1911
+ .fl-builder-bar .fl-builder-button-group > .fl-builder-button:last-child {
1912
+ border-top-right-radius: 3px;
1913
+ border-bottom-right-radius: 3px;
1914
+ }
1915
+ .fl-builder-publish-actions-click-away-mask {
1916
+ display: none;
1917
+ position: fixed;
1918
+ top:0;
1919
+ left:0;
1920
+ right:0;
1921
+ height:100vh;
1922
+ background: transparent;
1923
+ }
1924
+ /* @endgroup Publish Actions */
1925
 
1926
+ /* @group Drag and Drop
1927
  ------------------------------------------------------ */
1928
 
1929
  .fl-builder-dragging .fl-builder-content:not(.fl-builder-empty) {
1930
  padding: 16px 0;
1931
  }
1932
  .fl-builder-empty {
1933
+ display: none;
1934
+ border: 2px dashed #969696;
1935
+ border-radius: 8px;
1936
+ color: #909090;
1937
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
1938
+ font-size: 20px;
1939
+ font-weight: 700;
1940
  margin: 10px;
1941
+ padding: 250px 20px;
1942
  position: relative;
1943
  text-align: center;
1944
  text-transform: uppercase;
1945
  }
1946
+ .fl-builder-edit .fl-builder-empty {
1947
+ display: block;
1948
+ }
1949
  .fl-builder-block.ui-draggable-dragging,
1950
  .fl-builder-block-drag-helper {
1951
+ background: rgba( 255, 255, 255, 0.95 ) !important;
1952
+ border: 2px solid #000000;
1953
+ border-radius: 4px;
1954
  box-shadow: 0 0 8px rgba(0,0,0,0.2);
1955
  -moz-box-shadow: 0 0 8px rgba(0,0,0,0.2);
1956
  -webkit-box-shadow: 0 0 8px rgba(0,0,0,0.2);
1957
+ color: #333333 !important;
1958
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
1959
  font-size: 13px !important;
1960
+ height: 47px !important;
1961
  line-height: 40px !important;
1962
  overflow: hidden;
1963
+ padding: 0 20px;
1964
  position: fixed !important;
1965
  text-overflow: ellipsis;
1966
  white-space: nowrap;
1967
+ width: 180px !important;
1968
  z-index: 100010 !important;
1969
+ display:flex;
1970
+ flex-direction:row;
1971
+ align-content: center;
1972
+ justify-content: flex-start;
1973
+ }
1974
+ .fl-builder-block.fl-builder-block-drag-helper:hover {
1975
+ padding:0;
1976
+ box-shadow: none;
1977
+ }
1978
+ .fl-builder-block-drag-helper:hover .fl-builder-block-content {
1979
+ position: static;
1980
+ padding: 0 20px;
1981
+ }
1982
+ .fl-builder-block-saved-row.fl-builder-block-drag-helper:hover .fl-builder-block-content,
1983
+ .fl-builder-block-saved-module.fl-builder-block-drag-helper:hover .fl-builder-block-content {
1984
+ padding: 14px 20px;
1985
+ }
1986
+ .fl-builder-block-drag-helper .fl-builder-block-icon {
1987
+ fill: #000000;
1988
+ margin-top:-10px;
1989
  }
1990
  .fl-builder-drop-zone {
1991
+ animation: fl-builder-drop-zone-pulse 2s infinite;
1992
+ background: #00A2D7;
1993
+ border-radius: 4px;
1994
  color: #fff !important;
1995
  display: block;
1996
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
1997
  font-weight: normal;
1998
  font-size: 12px;
1999
  letter-spacing: 1px;
2011
  }
2012
  @keyframes fl-builder-drop-zone-pulse {
2013
  0% {
2014
+ background-color: #00A2D7;
2015
  }
2016
  50% {
2017
+ background-color: #79DEFF;
2018
  }
2019
  100% {
2020
+ background-color: #00A2D7;
2021
  }
2022
  }
2023
  .fl-builder-drop-zone-global {
2024
+ animation: fl-builder-drop-zone-global-pulse 2s infinite;
2025
  background: #ff9600;
2026
  }
2027
  @keyframes fl-builder-drop-zone-global-pulse {
2056
  padding: 16px 0;
2057
  }
2058
  .fl-row-highlight .fl-row-content {
2059
+ border:2px dashed rgba(203, 205, 206, .5);
2060
  padding: 8px;
2061
+ border-radius: 6px;
2062
  }
2063
  .fl-row-highlight.fl-node-global .fl-row-content {
2064
  border-color: #ff9600;
2074
  }
2075
  .fl-col-highlight .fl-col-content {
2076
  border-style: dashed !important;
2077
+ border-color: #00a0d2 !important;
2078
+ border-top-width: 2px !important;
2079
+ border-bottom-width: 2px !important;
2080
+ border-left-width: 2px !important;
2081
+ border-right-width: 2px !important;
2082
+ border-radius: 4px;
2083
  min-height: 100px;
2084
  overflow-x: hidden;
2085
  width: 100%;
2099
  position: relative;
2100
  }
2101
  .fl-col-highlight-guide {
2102
+ background: rgba(0, 160, 210, 0.05);
2103
+ border: 2px solid #00A0D2;
2104
+ border-radius: 4px;
2105
  bottom: 4px;
2106
  left: 4px;
2107
  position: absolute;
2109
  top: 4px;
2110
  z-index: 1;
2111
  }
2112
+ .fl-node-global .fl-col-highlight-guide {
2113
+ border-color: #ff9600 !important;
2114
+ background-color: rgba(255, 150, 0, 0.06) !important;
2115
+ }
2116
  .fl-col-has-highlight-guide .fl-block-overlay {
2117
  background: none;
2118
  border-color: transparent;
2230
  margin-top: 0;
2231
  }
2232
 
2233
+ /* Nodes */
2234
+ .fl-module:focus,
2235
+ .fl-row:focus,
2236
+ .fl-col-group:focus,
2237
+ .fl-col:focus {
2238
+ outline:none;
2239
+ }
2240
+
2241
  /* Sortable Proxies */
2242
  .fl-sortable-proxy {
2243
  display: none;
2249
  .fl-block-overlay,
2250
  .fl-block-overlay * {
2251
  text-shadow: none;
2252
+ -webkit-touch-callout: none;
2253
  }
2254
  .fl-block-overlay-active {
2255
  position: relative;
2256
  }
2257
  .fl-block-overlay-actions {
2258
+ background: #00A0D2;
2259
  float: left;
2260
+ height: 30px;
2261
  margin: -1px -1px 0;
2262
+ padding: 0 4px;
2263
  text-shadow: none;
2264
+ border-bottom-right-radius: 5px;
2265
+ border-top-left-radius: 3px;
2266
+ }
2267
+ .fl-row-overlay-header-bottom .fl-block-overlay-actions {
2268
+ border-radius: 0;
2269
+ border-top-right-radius: 5px;
2270
+ border-bottom-left-radius: 3px;
2271
  }
2272
+ .fl-builder-col-resizing .fl-block-overlay-actions,
2273
+ .fl-builder-row-resizing .fl-block-overlay-actions {
2274
  overflow: hidden;
2275
  }
2276
  .fl-block-overlay-actions > span {
2282
  cursor: pointer;
2283
  display: block !important;
2284
  float: left;
2285
+ font-size: 16px !important;
2286
  height: 28px !important;
2287
  font-weight: 100 !important;
2288
  line-height: 28px !important;
2289
  opacity: 0.8;
2290
  filter: alpha(opacity = 80);
2291
  text-align: center;
2292
+ width: 32px !important;
2293
  }
2294
+
2295
  .fl-block-overlay-actions i:hover {
2296
  opacity: 1;
2297
  filter: alpha(opacity = 100);
2306
  cursor: move;
2307
  }
2308
  .fl-block-overlay-title {
 
2309
  color: #fff !important;
2310
  float: left;
2311
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
2312
+ font-size: 14px;
2313
  height: 30px;
2314
  line-height: 29px;
2315
  margin-right: 2px;
2316
+ padding: 0 12px 0 8px;
2317
  }
2318
 
2319
  /* Row Overlays */
2320
  .fl-row-overlay {
2321
+ background: rgba(190, 239, 255, 0);
2322
+ border: 2px solid #00A0D2;
2323
+ border-radius: 4px;
2324
  bottom: 0;
2325
  box-sizing: border-box !important;
2326
  -moz-box-sizing: border-box !important;
2328
  color: #fff;
2329
  left: 0;
2330
  position: absolute;
2331
+ top: -33px;
2332
+ right: 0;
2333
  z-index: 100006;
2334
  }
2335
+ .fl-row-full-width .fl-row-overlay {
2336
+ left: 2px;
2337
+ right: 2px;
2338
+ bottom: 2px;
2339
+ }
2340
  .fl-row-overlay-header-bottom {
2341
+ bottom: -32px !important;
2342
  top: 0;
2343
  }
2344
  .fl-row-overlay-header-bottom .fl-block-overlay-header {
2353
  z-index: 100007 !important;
2354
  }
2355
 
2356
+ /* Row Resizing */
2357
+ .fl-builder-row-resizing .fl-col.fl-block-overlay-active,
2358
+ .fl-builder-row-resizing .fl-module.fl-block-overlay-active {
2359
+ position: static;
2360
+ }
2361
+
2362
  /* Column Overlays */
2363
  .fl-col-overlay {
2364
+ background: rgba(190, 239, 255, 0);
2365
+ border: 2px solid #00A0D2;
2366
+ border-radius: 4px;
2367
  bottom: 8px;
2368
  cursor: pointer;
2369
  color: #fff;
2371
  position: absolute;
2372
  right: 8px;
2373
  top: 8px;
2374
+ z-index: 100008;
2375
  }
2376
 
2377
  /* Module Overlays */
2378
  .fl-module-overlay {
2379
+ background: rgba(190, 239, 255, 0);
2380
+ border: 2px solid #00A0D2;
2381
+ border-radius: 4px;
2382
  bottom: 4px;
2383
  cursor: pointer;
2384
  color: #fff;
2399
 
2400
  /* Global Overlays */
2401
  .fl-block-overlay-global {
2402
+ background: rgba(255, 150, 0, 0);
2403
+ border: 2px solid #F7A407;
2404
+ border-radius: 4px;
2405
  }
2406
  .fl-block-overlay-global .fl-block-overlay-actions {
2407
+ background: #F7A407;
 
 
 
2408
  }
2409
  .fl-block-overlay-title-global {
2410
  background: #fff;
 
2411
  color: #ff9600 !important;
2412
  font-size: 11px;
2413
  letter-spacing: 1px;
2418
 
2419
  /* Global Row Overlays */
2420
  .fl-block-overlay-global.fl-row-overlay {
2421
+ background: rgba(255, 150, 0, 0);
2422
  cursor: pointer;
2423
  z-index: 100007;
2424
  }
2426
  cursor: default;
2427
  }
2428
  .fl-builder-row-template .fl-block-overlay-global.fl-row-overlay {
2429
+ background: rgba(255, 150, 0, 0);
2430
  cursor: default;
2431
  z-index: 100006;
2432
  }
2433
+ .fl-block-overlay-global.fl-row-overlay .fl-block-col-resize {
2434
+ display:none;
2435
+ }
2436
 
2437
  /* Muted Overlays */
2438
  .fl-block-overlay-muted .fl-row-overlay {
2439
+ background: rgba(85, 93, 102, 0);
2440
+ border: 2px solid #555D66;
2441
  }
2442
  .fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-actions {
2443
+ background: #555D66;
2444
  }
2445
+ .fl-block-overlay-muted .fl-row-overlay .fl-block-col-resize {
2446
+ display:none;
2447
  }
2448
 
2449
  /* Disabled Overlays */
2461
  .fl-block-col-resize-e {
2462
  cursor: ew-resize;
2463
  left: auto !important;
2464
+ right: -2px !important;
2465
  }
2466
  .fl-block-col-resize-w {
2467
  cursor: ew-resize;
2468
+ left: -7px !important;
2469
  }
2470
  .fl-block-col-resize-handle-wrap {
2471
  margin: -4px 0 0 -5px;
2478
  }
2479
  .fl-block-col-resize-handle {
2480
  background: #fff;
2481
+ border: 2px solid #00A0D2;
2482
+ border-radius: 50%;
2483
+ height: 12px;
2484
+ width: 12px;
2485
  }
2486
  .fl-node-global .fl-block-col-resize-handle {
2487
  border-color: #ff9600;
2489
  .fl-block-col-resize-feedback {
2490
  color: #333 !important;
2491
  display: none;
2492
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
2493
  font-size: 11px !important;
2494
  position: absolute;
2495
  }
2515
  position: relative;
2516
  }
2517
  .fl-builder-has-submenu > ul.fl-builder-submenu {
2518
+ background: #00A0D2;
2519
  box-shadow: 0 0 20px rgba(0,0,0,0.20);
2520
+ border-radius: 4px;
2521
+ border-top-left-radius: 0;
2522
  display: none;
2523
  left: 0;
2524
  list-style: none;
2527
  position: absolute;
2528
  text-align: left;
2529
  top: 100%;
2530
+ width: 165px;
2531
  z-index: 100008;
2532
  }
2533
  .fl-builder-has-submenu > ul.fl-builder-submenu li {
2539
  left: auto;
2540
  right: 0;
2541
  }
2542
+ .fl-builder-has-submenu.fl-builder-submenu-open > ul.fl-builder-submenu {
2543
  display: block;
2544
  }
2545
  .fl-builder-has-submenu > ul.fl-builder-submenu li a {
2551
  display: block;
2552
  line-height: 13px;
2553
  font-size: 13px;
2554
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
2555
  font-weight: normal;
2556
  opacity: 0.8;
2557
  filter: alpha(opacity = 80);
2562
  white-space: nowrap;
2563
  }
2564
  .fl-builder-has-submenu > ul.fl-builder-submenu li a:hover {
2565
+ background: #0197C6;
2566
  color: #fff;
2567
  opacity: 1;
2568
  filter: alpha(opacity = 100);
2622
  .fl-block-overlay-global ul.fl-builder-submenu li a:hover {
2623
  background: #ffaa33;
2624
  }
2625
+ /* @endgroup Drag and Drop */
2626
 
2627
+ /* @group Actions Lightbox
2628
  ------------------------------------------------------ */
2629
 
2630
  .fl-builder-actions-lightbox .fl-lightbox {
2631
+ display: block;
2632
  width: 300px;
2633
+ border-radius: 4px;
2634
  }
2635
+ .fl-builder-actions-lightbox .fl-lightbox-content-wrap {
2636
  display: block;
2637
+ }
2638
+ .fl-builder-actions-lightbox .fl-builder-actions {
2639
+ display: flex;
2640
+ flex-direction: column;
2641
  padding: 25px;
2642
  text-align: center;
2643
  }
2644
  .fl-builder-actions-title {
2645
  color: #333 !important;
2646
  display: block;
2647
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
2648
  font-size: 16px !important;
2649
  margin-bottom: 20px;
2650
  }
2651
  .fl-builder-actions .fl-builder-button {
2652
+ display: flex;
2653
+ justify-content: center;
2654
  margin-bottom: 7px;
2655
+ min-height: 36px;
2656
  }
2657
+ /* @endgroup Actions Lightbox */
2658
 
2659
+ /* @group Alert Lightbox
2660
  ------------------------------------------------------ */
2661
 
2662
  .fl-builder-alert-lightbox {
2663
+ padding: 20px;
2664
+ z-index: 30000000;
2665
+ top: 0;
2666
+ pointer-events: auto;
2667
  }
2668
  .fl-builder-alert-lightbox .fl-lightbox {
2669
+ max-width: 440px;
2670
+ width: auto;
2671
+ }
2672
+ .fl-builder-alert-lightbox .fl-lightbox-content-wrap {
2673
+ display: block;
2674
  }
2675
  .fl-builder-alert-lightbox .fl-lightbox-message {
2676
  color: #333 !important;
2677
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
2678
  font-size: 16px !important;
2679
  line-height: 24px;
2680
  padding: 30px;
2681
  }
2682
+ /* @endgroup Alert Lightbox */
2683
 
2684
+ /* @group Template Selector
2685
  ------------------------------------------------------ */
2686
+ @keyframes fl-builder-content-section-entry {
2687
+ from {
2688
+ transform: translateY(150px) translateX(100px) scale(.3);
2689
+ opacity:0;
2690
+ }
2691
+ to {
2692
+ transform: translateY(0px) translateX(0px) scale(1);
2693
+ opacity:1;
2694
+ }
2695
+ }
2696
  .fl-template-category-select {
2697
  width: 180px !important;
2698
  }
2747
  padding: 8px 15px;
2748
  }
2749
  .fl-user-templates {
 
 
 
 
 
2750
  border-bottom: 1px solid #dfdfdf;
2751
+ padding: 10px 0 20px;
2752
+ }
2753
+ .fl-builder--user-templates-section-content {
2754
+ padding-top: 10px;
2755
+ padding-left: 10px;
2756
+ padding-right: 10px;
2757
+ padding-bottom: 10px;
2758
+ border-bottom: 2px solid #e6eaed;
2759
+ }
2760
+ .fl-builder--user-templates-section-content:first-child {
2761
+ padding-top:0;
2762
+ }
2763
+ .fl-user-templates:last-child,
2764
+ .fl-builder--user-templates-section-content:last-child {
2765
+ border-bottom: none;
2766
+ }
2767
+ .fl-builder--user-templates-section-name {
2768
+ font-weight: bold;
2769
+ font-size: 16px;
2770
+ padding-top: 30px;
2771
+ color: #333333;
2772
+ z-index: 9999;
2773
+ padding: 15px 10px;
2774
+ margin: 0 10px;
2775
+ }
2776
+ @keyframes fl-list-item-entry {
2777
+ from {
2778
+ opacity:0;
2779
+ transform: scale(.5) translateY(100px);
2780
+ }
2781
+ to {
2782
+ opacity:1;
2783
+ transform: scale(1) translateY(0px);
2784
+ }
2785
+ }
2786
+ .fl-user-template,
2787
+ .fl-builder--save-new-user-template {
2788
  position: relative;
2789
+ display: flex;
2790
+ flex-direction: row;
2791
+ align-items: center;
2792
+ overflow: hidden;
2793
+ text-overflow: ellipsis;
2794
+ white-space: nowrap;
2795
+ border-radius: 4px;
2796
+ font-size: 16px;
2797
+ font-weight: 200;
2798
+ line-height: 1.1;
2799
+ padding: 10px 20px;
2800
+ color: #6d6d6d;
2801
  }
2802
  .fl-user-template:hover {
 
 
2803
  cursor: pointer;
2804
+ background: #ffffff;
2805
+ box-shadow: 0px 6px 20px rgba(0, 0, 0, 0.08);
2806
+ text-decoration: none;
2807
+ color: #111111;
2808
+ padding-right:68px;
2809
  }
2810
+ .fl-user-template-name {
2811
+ overflow: hidden;
2812
+ text-overflow: ellipsis;
2813
+ flex:1;
2814
  }
2815
  .fl-user-template-actions {
2816
+ display:none;
2817
  bottom: 0;
2818
  position: absolute;
2819
  right: 0;
2820
  top: 0;
2821
  }
2822
+ .fl-user-template:hover .fl-user-template-actions {
2823
+ display: flex;
2824
+ flex-direction: row;
2825
+ align-items: center;
2826
+ }
2827
  .fl-user-template-actions a {
 
2828
  display: inline-block;
2829
+ padding: 15px 0;
2830
+ width:30px;
 
 
2831
  }
2832
+ .fl-user-template:hover a:hover i {
2833
+ color: #444444 !important;
2834
  }
2835
  .fl-user-templates-message {
2836
  display: none;
2837
  }
2838
+ .fl-user-template-thumbnail {
2839
+ flex:0;
2840
+ margin-right:20px;
2841
+ }
2842
+ .fl-user-template-thumbnail .fl-builder--template-thumbnail {
2843
+ background-size: cover;
2844
+ background-position: center top;
2845
+ }
2846
+ .fl-user-template-thumbnail .fl-builder--template-thumbnail:hover {
2847
+ box-shadow: none;
2848
+ transform: scale(1);
2849
+ transition-property: none;
2850
+ }
2851
+ .fl-user-template-thumbnail .fl-builder--template-thumbnail {
2852
+ width:45px;
2853
+ }
2854
+ .fl-builder--save-new-user-template .fl-user-template-thumbnail .fl-builder--template-thumbnail {
2855
+ border-style: dashed;
2856
+ border-width: 2px;
2857
+ border-color: #ccd4da;
2858
+ }
2859
+ .fl-builder--save-new-user-template .fl-save-control {
2860
+ display: flex;
2861
+ flex-direction: row;
2862
+ flex:1;
2863
+ }
2864
+ .fl-builder--save-new-user-template .fl-save-control input {
2865
+ background:transparent;
2866
+ border:none !important;
2867
+ flex:1;
2868
+ font-size: 16px;
2869
+ margin-right:10px;
2870
+ margin-left: -12px;
2871
+ color: #000;
2872
+ }
2873
+ .fl-builder--save-new-user-template .fl-save-control input::-webkit-input-placeholder { /* Chrome/Opera/Safari */
2874
+ color: #777;
2875
+ }
2876
+ .fl-builder--save-new-user-template .fl-save-control input::-moz-placeholder { /* Firefox 19+ */
2877
+ color: #777;
2878
+ }
2879
+ .fl-builder--save-new-user-template .fl-save-control input:-ms-input-placeholder { /* IE 10+ */
2880
+ color: #777;
2881
+ }
2882
+ .fl-builder--save-new-user-template .fl-save-control input:-moz-placeholder { /* Firefox 18- */
2883
+ color: #777;
2884
+ }
2885
+ @keyframes fl-slide-in-right {
2886
+ from {
2887
+ transform: translateX(50px);
2888
+ }
2889
+ to {
2890
+ transform: translateX(0px);
2891
+ }
2892
+ }
2893
+ .fl-builder--save-new-user-template .fl-save-control button {
2894
+ display: none;
2895
+ animation-name: fl-slide-in-right;
2896
+ animation-duration: .25s;
2897
+ background-color: #00a0d2;
2898
+ border: none;
2899
+ padding: 0 15px;
2900
+ }
2901
+ .fl-save-control-mask {
2902
+ display:none;
2903
+ background: transparent;
2904
+ position: absolute;
2905
+ top: -50px;
2906
+ left: 0;
2907
+ bottom: 0;
2908
+ right: 0;
2909
+ z-index: -1;
2910
+ min-height: 80vh;
2911
+ }
2912
 
2913
  /* Lite version templates CTA */
2914
  .fl-builder-templates-cta {
2929
  left: 15px;
2930
  padding: 1px 12px;
2931
  }
2932
+ /* @endgroup Template Selector */
2933
 
2934
+ /* @group User Template Editing
 
 
 
 
 
 
 
 
2935
  ------------------------------------------------------ */
2936
 
2937
  .single-fl-builder-template .fl-content {
2938
  width: 100% !important;
2939
  }
2940
+ /* @endgroup User Template Editing */
2941
 
2942
+ /* @group Settings Lightboxes
 
 
 
 
 
 
 
2943
  ------------------------------------------------------ */
2944
 
 
 
 
2945
  form.fl-builder-settings {
2946
+ height: 100%;
2947
  margin: 0;
2948
  padding: 0;
2949
+ display: flex;
2950
+ flex-direction: column;
2951
  }
2952
  .fl-builder-settings-message {
2953
  font-size: 15px !important;
2961
  }
2962
  .fl-builder-preview-loader {
2963
  position: relative;
2964
+ top: -2px;
2965
  margin-left: 3px;
2966
  }
2967
  .fl-lightbox-header .fl-builder-preview-loader {
2971
  top: 15px;
2972
  }
2973
 
2974
+ @keyframes fl-grab-attention {
2975
+ 0% {
2976
+ transform: scale(1);
2977
+ }
2978
+ 50% {
2979
+ transform: scale(1.05);
2980
+ }
2981
+ 100% {
2982
+ transform: scale(1);
2983
+ }
2984
+ }
2985
+
2986
+ /* Slim Settings
2987
+ ------------------------------------------------------ */
2988
+
2989
+ .fl-lightbox-width-slim .fl-form-table {
2990
+ margin: 20px 25px 10px 15px !important;
2991
+ width: calc(100% - 60px);
2992
+ }
2993
+ .fl-lightbox-width-slim .fl-form-table th {
2994
+ display: block;
2995
+ padding: 10px 0 0 12px !important;
2996
+ }
2997
+ .fl-lightbox-width-slim .fl-form-table td {
2998
+ display: block;
2999
+ }
3000
+ .fl-lightbox-width-slim .fl-form-table td:first-child {
3001
+ padding-left: 10px !important;
3002
+ }
3003
+ .fl-lightbox-width-slim .fl-form-table .fl-field[data-type="editor"] td:first-child {
3004
+ padding-left: 0px !important;
3005
+ }
3006
+
3007
+ .fl-field-label .fl-field-responsive-toggle {
3008
+ display:none; /* Hide label icons on wide settings */
3009
+ }
3010
+ .fl-lightbox-width-slim .fl-field-control-wrapper .fl-field-responsive-toggle {
3011
+ display:none; /* Hide control icons on slim settings */
3012
+ }
3013
+ .fl-lightbox-width-slim .fl-field-label .fl-field-responsive-toggle {
3014
+ display: inline-block;
3015
+ padding: 0 5px !important;
3016
+ }
3017
+
3018
+ /* Slim - Selects */
3019
+ .fl-lightbox-width-slim .fl-builder-settings-fields select {
3020
+ width: 100%;
3021
+ }
3022
+
3023
+ /* Slim - Color Picker */
3024
+ .fl-lightbox-width-slim .fl-color-picker {
3025
+ display: flex;
3026
+ width:auto;
3027
+ }
3028
+ .fl-lightbox-width-slim .fl-color-picker-clear {
3029
+ flex: 0 0 50px;
3030
+ }
3031
+
3032
+ /* Slim - TinyMCE */
3033
+ .fl-lightbox-width-slim .mce-menubtn.mce-fixed-width button {
3034
+ width: 28px !important;
3035
+ }
3036
+ .fl-lightbox-width-slim .mce-btn[aria-label="Fullscreen"],
3037
+ .fl-lightbox-width-slim .mce-btn[aria-label="Blockquote"] {
3038
+ display: none;
3039
+ }
3040
+
3041
+ /* Slim - Repeaters */
3042
+ .fl-lightbox-width-slim .fl-builder-field-multiple {
3043
+ display: flex;
3044
+ flex-wrap: wrap;
3045
+ position: relative;
3046
+ }
3047
+ .fl-lightbox-width-slim .fl-builder-field-multiple .fl-field-label {
3048
+ width: 100% !important;
3049
+ }
3050
+ .fl-lightbox-width-slim .fl-builder-field-multiple .fl-field-control {
3051
+ width: 100% !important;
3052
+ }
3053
+ .fl-lightbox-width-slim .fl-builder-field-multiple .fl-builder-field-actions {
3054
+ position: absolute !important;
3055
+ top:0;
3056
+ right:0;
3057
+ width: 70px;
3058
+ }
3059
+
3060
+ /* Slim - Time */
3061
+ .fl-lightbox-width-slim .fl-field[data-type="time"] select {
3062
+ width: auto;
3063
+ }
3064
+
3065
  /* Settings Tabs
3066
  ------------------------------------------------------ */
3067
 
3068
  .fl-builder-settings-tabs {
3069
+ margin: 6px 6px 6px;
3070
+ border: 2px solid #e6eaed;
3071
+ border-radius: 4px;
3072
+ display: flex;
3073
+ flex-direction: row;
3074
+ overflow: hidden;
3075
  }
3076
+
3077
+ .fl-builder-content-group-select {
3078
+ padding: 0 10px 6px;
3079
+ }
3080
+ .fl-builder-content-group-select {
3081
+ display:none; /* Default to hidden */
3082
+ }
3083
+ .fl-builder-content-group-select select {
3084
+ display: block;
3085
+ width: 100%;
3086
+ -webkit-appearance: none;
3087
+ -moz-appearance: none;
3088
+ appearance: none;
3089
+ box-sizing: border-box;
3090
+ padding: 8px 10px;
3091
+ background: white url(../img/svg/select-arrow-down-alt2.svg) no-repeat center right 10px !important;
3092
+ border: 2px solid #e4e7ea;
3093
+ color: #161B20;
3094
+ }
3095
+ select:focus {
3096
+ border-width: 2px !important;
3097
+ border-style: solid !important;
3098
+ border-color: #00a0d2 !important;
3099
+ outline:none !important;
3100
+ }
3101
+ .fl-legacy-settings-tab {
3102
+ background: url(../img/ajax-loader.svg) center center no-repeat;
3103
+ height: 100px;
3104
+ }
3105
+ .fl-builder-settings-tab:first-child .fl-legacy-settings-tab {
3106
+ background: transparent;
3107
+ height: auto;
3108
+ }
3109
+ body .fl-builder-settings-tabs > * {
3110
+ box-sizing: border-box;
3111
+ color: #676F7A !important;
3112
+ fill: #676F7A !important;
3113
+ background: transparent;
3114
+ border: 2px solid transparent;
3115
+ border-radius:0;
3116
  display: inline-block;
3117
  margin: 0;
3118
  outline: none;
3119
+ padding: 6px 15px;
3120
  text-decoration: none !important;
3121
+ font-size: 14px;
3122
+ font-weight: normal !important;
3123
+ flex: 0 0 auto;
3124
+ white-space: nowrap;
3125
+ overflow: hidden;
3126
+ text-overflow: ellipsis;
3127
+ display:block;
3128
+ text-align: center;
3129
+ }
3130
+ body .fl-builder-settings-tabs > *:first-child {
3131
+ border-top-left-radius: 3px;
3132
+ border-bottom-left-radius: 3px;
3133
+ }
3134
+ body .fl-builder-settings-tabs > *:last-child {
3135
+ border-top-right-radius: 3px;
3136
+ border-bottom-right-radius: 3px;
3137
+ }
3138
+ body .fl-lightbox-width-slim .fl-builder-settings-tabs > * {
3139
+ flex: 1 1 auto;
3140
+ padding: 6px 8px;
3141
+ }
3142
+ body .fl-builder-settings-tabs > .fl-builder-settings-tabs-more {
3143
+ flex: 0 0 60px;
3144
+ display:none;
3145
+ margin-left:auto;
3146
+ justify-content: center;
3147
+ }
3148
+ .fl-builder-settings-tabs-more svg {
3149
+ width:16px;
3150
+ height:auto;
3151
+ fill:inherit;
3152
+ margin:auto; /* safari centering fix */
3153
+ }
3154
+ .fl-builder-settings-tabs-more svg,
3155
+ .fl-builder-settings-tabs-more g,
3156
+ .fl-builder-settings-tabs-more path {
3157
+ fill:inherit;
3158
+ }
3159
+ body .fl-lightbox-has-tab-overflow .fl-builder-settings-tabs-more {
3160
+ display: flex;
3161
  }
3162
+ .fl-builder-settings-tabs > *:hover,
3163
+ .fl-builder-settings-tabs > *:active {
3164
+ top:0;
3165
  color: #333;
3166
+ background: transparent;
3167
+ border: 2px solid transparent;
3168
  }
3169
+ .fl-builder-settings-tabs > *:focus {
3170
+ top:0;
3171
  outline: none;
3172
+ border: 2px solid transparent;
3173
+ background: transparent;
3174
+ color: #0086b0;
3175
+ fill: #0086b0;
3176
+ }
3177
+ .fl-builder-settings-tabs .fl-active,
3178
+ .fl-builder-settings-tabs-more.fl-contains-active,
3179
+ .fl-builder-settings-tabs-overflow-menu .fl-active {
3180
+ color: #0086b0 !important;
3181
+ fill: #0086b0 !important;
3182
  position: relative;
3183
+ background: #e6eaed;
3184
  }
3185
+ .fl-builder-settings-tabs .fl-overflowed,
3186
+ .fl-builder-settings-tabs .fl-active.fl-overflowed {
3187
+ display:none !important;
3188
+ }
3189
+ .fl-builder-settings-tabs .error {
3190
  color: #d03436;
3191
  padding-right: 10px;
3192
  }
3193
+ .fl-builder-settings-tabs .error .fl-error-icon,
3194
+ .fl-builder-settings-tabs-overflow-menu .error .fl-error-icon {
3195
  background: url('../img/sprite.png') -148px -5px no-repeat;
3196
  display: inline-block;
3197
  height: 16px;
3200
  top: 3px;
3201
  width: 16px;
3202
  }
3203
+ .fl-builder-settings-tabs-more.fl-contains-errors {
3204
+ fill: #d03436 !important;
3205
+ }
3206
  .fl-builder-settings-tab {
3207
  display: none;
3208
+ width: auto !important;
3209
  }
3210
  .fl-builder-settings-tab.fl-active {
3211
  display: block;
3212
  }
3213
  .fl-builder-settings-tab-description {
3214
+ background: #e4e7ea;
3215
  padding: 10px 15px;
3216
+ border-radius: 4px;
3217
+ margin: 20px 20px;
3218
  }
3219
  .fl-builder-settings-tab-description a {
3220
  text-decoration: underline !important;
3222
  .fl-builder-settings-tab-description a:hover {
3223
  color: #333;
3224
  }
3225
+ .fl-builder-settings-tabs-overflow-menu {
3226
+ display:none;
3227
+ position: absolute;
3228
+ left: 0;
3229
+ right: 0;
3230
+ border: 2px solid #e6eaed;
3231
+ border-top: 3px solid #00a0d2;
3232
+ border-radius: 4px;
3233
+ background: white;
3234
+ z-index: 9;
3235
+ margin: 0 6px;
3236
+ padding: 10px;
3237
+ flex-direction: column;
3238
+ box-shadow: 0px 0px 20px 2px rgba(0, 0, 0, 0.2);
3239
+ }
3240
+ .fl-builder-settings-tabs-overflow-menu:before {
3241
+ bottom: 100%;
3242
+ right: 20px;
3243
+ content: " ";
3244
+ height: 0;
3245
+ width: 0;
3246
+ position: absolute;
3247
+ pointer-events: none;
3248
+ border: solid;
3249
+ border-color: rgba(255, 255, 255, 0);
3250
+ border-bottom-color: #00a0d2;
3251
+ border-width: 10px;
3252
+ margin-left: -10px;
3253
+ }
3254
+ .fl-builder-settings-tabs-overflow-menu > a {
3255
+ display: block;
3256
+ padding: 10px 15px;
3257
+ font-size: 14px;
3258
+ font-weight: 600 !important;
3259
+ border:2px solid transparent;
3260
+ border-radius: 4px;
3261
+ outline:none;
3262
+ }
3263
+ .fl-builder-settings-tabs-overflow-menu > a:hover {
3264
+ background: #e6eaed;
3265
+ text-decoration: none;
3266
+ }
3267
+ .fl-builder-settings-tabs-overflow-click-mask {
3268
+ display: none;
3269
+ position: fixed;
3270
+ top:0;
3271
+ bottom:0;
3272
+ left:0;
3273
+ right:0;
3274
+ background:transparent;
3275
+ z-index: 9;
3276
+ }
3277
 
3278
  /* Settings Tables
3279
  ------------------------------------------------------ */
3281
  .fl-form-table {
3282
  background: none transparent;
3283
  border: none;
3284
+ width: calc(100% - 35px); /* extra 25px for field connections toggle) */
3285
  }
3286
  .fl-form-table tbody {
3287
  border: none;
3292
  }
3293
  .fl-form-table th {
3294
  border: none !important;
 
3295
  font-weight: normal !important;
3296
  padding: 10px !important;
3297
+ padding-left:30px !important;
3298
  text-align: left !important;
3299
  vertical-align: top !important;
3300
  width: 200px !important;
3301
+ background:transparent !important;
3302
+ }
3303
+ .fl-form-table td:first-child {
3304
+ padding-left:30px !important;
3305
  }
3306
  .fl-form-table th label {
3307
  color: #333;
3308
+ width: auto;
3309
+ max-width: 100%;
3310
  }
3311
  .fl-form-table td {
3312
+ background: transparent !important;
3313
  border: none !important;
3314
  font-weight: normal !important;
3315
  padding: 8px 10px;
3316
  text-align: left !important;
3317
+ }
3318
+ .fl-lightbox-width-slim .fl-form-table td {
3319
+ padding: 4px 0 10px;
3320
  }
3321
 
3322
  /* Settings Fields
3323
  ------------------------------------------------------ */
3324
 
3325
  .fl-builder-settings-fields {
3326
+ margin: 0;
 
3327
  overflow: hidden;
3328
  position: relative;
3329
+ flex: 1 100%;
3330
+ visibility: hidden;
3331
  }
3332
  .fl-lightbox-header .fl-builder-settings-fields {
3333
  height: auto;
3337
  top: 10px;
3338
  }
3339
  .fl-builder-settings-fields .fl-nanoscroller-content {
3340
+ padding: 0;
3341
  }
3342
  .fl-builder-settings-fields .fl-field-control-wrapper {
3343
  position: relative;
3344
  }
3345
+ .fl-field {
3346
+ animation-duration: .25s;
3347
+ animation-delay: .1s;
3348
+ }
3349
  .fl-builder-settings-fields textarea,
3350
  .fl-builder-settings-fields input[type=text],
3351
  .fl-builder-settings-fields input[type=password],
3357
  .fl-builder-settings-fields input[type=url],
3358
  .fl-builder-settings-fields select {
3359
  background: #fff !important;
3360
+ border-color: transparent !important;
3361
  border-style: solid;
3362
+ border-width: 2px;
3363
+ border-radius: 4px !important;
3364
+ box-shadow: 0 2px 4px 0 rgba(0,0,0,0.12);
 
 
 
 
3365
  color: #333 !important;
3366
  display: inline;
3367
+ font-size: 13px;
3368
  height: auto;
3369
  line-height: 15px;
3370
  margin: 1px;
3371
  outline: none;
3372
+ padding: 3px 9px;
3373
  width: auto;
3374
+ box-sizing: border-box;
3375
  }
3376
+ .fl-builder-settings-fields input[type=text],
3377
+ .fl-builder-settings-fields input[type=password],
3378
+ .fl-builder-settings-fields input[type=file],
3379
+ .fl-builder-settings-fields input[type=email],
3380
+ .fl-builder-settings-fields input[type=number],
3381
+ .fl-builder-settings-fields input[type=search],
3382
+ .fl-builder-settings-fields input[type=tel],
3383
+ .fl-builder-settings-fields input[type=url],
3384
+ .fl-builder-settings-fields select {
3385
+ height: 36px !important;
 
 
 
 
 
3386
  }
3387
+ .fl-builder-settings-fields input[type=number] {
3388
+ width: 70px;
3389
+ }
3390
+ .fl-builder-lightbox .fl-builder-settings-fields textarea:focus,
3391
+ .fl-builder-lightbox .fl-builder-settings-fields input[type=text]:focus,
3392
+ .fl-builder-lightbox .fl-builder-settings-fields input[type=password]:focus,
3393
+ .fl-builder-lightbox .fl-builder-settings-fields input[type=file]:focus,
3394
+ .fl-builder-lightbox .fl-builder-settings-fields input[type=email]:focus,
3395
+ .fl-builder-lightbox .fl-builder-settings-fields input[type=number]:focus,
3396
+ .fl-builder-lightbox .fl-builder-settings-fields input[type=search]:focus,
3397
+ .fl-builder-lightbox .fl-builder-settings-fields input[type=tel]:focus,
3398
+ .fl-builder-lightbox .fl-builder-settings-fields input[type=url]:focus,
3399
+ .fl-builder-lightbox .fl-builder-settings-fields select:focus {
3400
+ border-width: 2px !important;
3401
+ border-style: solid !important;
3402
+ border-color: #00a0d2 !important;
3403
+ box-shadow: 0 2px 4px 0 rgba(0,0,0,0.12) !important;
3404
  }
3405
  .fl-builder-settings-fields ::-webkit-input-placeholder { /* WebKit browsers */
3406
  color: #999 !important;
3419
  font-size: 12px;
3420
  }
3421
  .fl-builder-settings-fields label {
3422
+ display: inline-block;
3423
  font-weight: normal;
3424
+ user-select: none;
3425
+ margin-bottom:3px;
3426
  }
3427
  .fl-builder-settings-fields select {
3428
+ -webkit-appearance: none;
3429
+ -moz-appearance: none;
3430
+ appearance: none;
3431
  box-sizing: border-box;
 
3432
  color: #000;
3433
  margin: 0;
3434
+ margin-bottom: 2px;
3435
+ padding: 2px 10px;
3436
+ padding-right:30px !important;
3437
+ background: white url("../img/svg/select-arrow-down-alt2.svg") no-repeat center right 10px !important;
3438
+ }
3439
+ .fl-builder-settings-fields select[multiple] {
3440
+ height: 60px;
3441
+ background-image: none !important;
3442
+ }
3443
+ .fl-photo-field select,
3444
+ .fl-builder-custom-field select {
3445
+ -webkit-box-shadow: none;
3446
+ border-color: #e6eaed !important;
3447
+ }
3448
+ .fl-font-field .fl-font-field-font {
3449
+ margin-bottom:4px;
3450
+ width: calc( 70% - 5px ) !important;
3451
+ }
3452
+ .fl-font-field .fl-font-field-weight {
3453
+ width:30% !important;
3454
+ }
3455
+
3456
+ .fl-lightbox-width-slim input.text-full + .fl-field-description,
3457
+ .fl-lightbox-width-slim select + .fl-field-description {
3458
+ display: block;
3459
+ padding: 8px 10px;
3460
+ margin: 0;
3461
+ }
3462
+
3463
+ /* Dimension Field */
3464
+ .fl-field[data-type="dimension"] .fl-field-control-wrapper {
3465
+ display: flex;
3466
+ }
3467
+ .fl-field[data-type="dimension"] .fl-field-description {
3468
+ padding-top: 9px;
3469
+ }
3470
+ .fl-field[data-type="dimension"] .fl-field-responsive-toggle {
3471
+ padding: 9px 9px 0 0;
3472
+ }
3473
+ .fl-dimension-field-units {
3474
+ display: flex;
3475
+ }
3476
+ .fl-dimension-field-unit {
3477
+ padding-right: 5px;
3478
+ }
3479
+ .fl-dimension-field-unit input {
3480
+ max-width: 60px;
3481
+ width: auto !important;
3482
+ }
3483
+ .fl-dimension-field-unit label {
3484
+ padding: 5px 0 0;
3485
+ font-size: 12px;
3486
+ color: inherit !important;
3487
+ display: block;
3488
+ text-align: center;
3489
+ }
3490
+
3491
+ /* Link Field */
3492
+ .fl-link-field-search input {
3493
+ box-shadow: none !important;
3494
+ width: 100% !important;
3495
+ padding: 3px 9px !important;
3496
+ }
3497
+ .fl-link-field-search #as-original-link-search {
3498
+ width:100%;
3499
+ }
3500
+
3501
+ .fl-builder-settings-section {
3502
+ border-top: 2px solid #E6EAED;
3503
+ }
3504
+ .fl-builder-settings-section:first-child {
3505
+ border-top: none !important;
3506
+ }
3507
+ .fl-custom-query .fl-builder-settings-section {
3508
+ border-top: 2px solid #E6EAED !important; /* custom for posts module */
3509
  }
3510
  .fl-builder-settings-description {
3511
  padding: 10px;
3515
  opacity: .75;
3516
  }
3517
  .fl-builder-settings-fields table {
3518
+ margin: 20px 0 20px;
 
 
 
 
 
 
 
 
 
 
 
3519
  }
3520
+ .fl-builder-settings-fields h3.fl-builder-settings-title {
3521
+ display: inline-block;
3522
+ background: #E6EAED;
3523
+ padding:4px 10px;
3524
+ padding-left: 15px;
3525
+ margin:0;
3526
+ text-transform: uppercase !important;
3527
+ border-bottom-right-radius: 4px;
3528
+ font-size: 12px !important;
3529
+ font-weight: 700;
3530
+ user-select: none;
3531
  }
3532
 
3533
  /* Core WordPress UI */
3544
  }
3545
  .wp-core-ui button {
3546
  font-weight: normal;
 
3547
  }
3548
  .wp-core-ui textarea,
3549
  .wp-core-ui input[type=text],
3600
  display: inline-block;
3601
  font-size: 15px !important;
3602
  height: auto;
3603
+ line-height: 18px !important;
3604
  text-align: left;
3605
  vertical-align: middle;
3606
  width: 20px;
3611
 
3612
  /* Text Field */
3613
  .fl-builder-settings-fields input.text-full {
3614
+ width: 100%;
3615
  }
3616
 
3617
  /* Textarea */
3618
  .fl-builder-settings-fields textarea {
3619
+ width: 100%;
3620
  }
3621
 
3622
  /* Color Picker */
3623
  .fl-color-picker {
3624
  cursor: pointer;
3625
  }
3626
+ .fl-color-picker .fl-color-picker-clear {
3627
+ box-sizing: border-box;
3628
+ }
3629
  .fl-color-picker .fl-color-picker-clear:hover {
3630
  background-color: #ededed;
3631
  }
3632
+
3633
  .colorpicker input {
3634
  padding: 0 !important;
3635
  font-size: 11px !important;
3645
 
3646
  /* Custom Fields */
3647
  .fl-builder-custom-field {
3648
+ background:white;
3649
+ border: 2px solid transparent;
3650
+ border-radius: 4px;
3651
+ padding: 7px 10px;
3652
+ box-shadow: 0 2px 4px 0 rgba(0,0,0,0.12);
3653
+ min-height: 36px;
3654
+ box-sizing: border-box;
3655
+ }
3656
+ .fl-builder-field-multiple .fl-builder-custom-field {
3657
+ cursor: move;
3658
  }
3659
  .fl-builder-custom-field a {
3660
  color: #21759b !important;
3668
  }
3669
 
3670
  /* Photo Fields */
3671
+ .fl-photo-field .fl-photo-preview {
3672
+ display: flex;
3673
+ }
3674
  .fl-photo-field .fl-photo-select,
3675
  .fl-photo-field.fl-photo-empty .fl-photo-preview {
3676
  display: none;
3679
  display: block;
3680
  }
3681
  .fl-photo-field .fl-photo-preview-img {
 
3682
  line-height: 0;
3683
  margin: 5px 0;
3684
  }
3689
  margin: 8px 0 8px 10px;
3690
  width: 200px;
3691
  }
3692
+ .fl-photo-field.fl-photo-no-attachment .fl-photo-preview select {
3693
+ display: none;
3694
+ }
3695
+ .fl-photo-field .fl-photo-preview-filename {
3696
+ display: none;
3697
+ font-size: 14px;
3698
+ font-weight: bold;
3699
+ margin: 7px 0 5px 11px;
3700
+ }
3701
+ .fl-photo-field.fl-photo-no-attachment .fl-photo-preview-filename {
3702
+ display: inline-block;
3703
+ word-break: break-all;
3704
+ }
3705
  .fl-photo-field .fl-photo-edit {
3706
  margin: 0 0 0 11px;
3707
  }
3708
+ .fl-photo-field.fl-photo-no-attachment .fl-photo-edit {
3709
+ display: none;
3710
+ }
3711
  .fl-photo-field .fl-photo-replace,
3712
  .fl-photo-field .fl-photo-remove {
3713
  margin: 0 0 0 8px;
3714
  }
3715
 
3716
  /* Media Uploader */
3717
+ .fl-builder-edit .media-modal {
3718
+ z-index: 9999991;
3719
+ }
3720
+ .fl-builder-edit .media-modal-backdrop {
3721
+ z-index: 999999;
3722
+ }
3723
  .fl-builder-edit .media-frame {
3724
  -webkit-backface-visibility: hidden;
3725
  }
3774
  .fl-video-field .fl-video-preview-img img {
3775
  max-width: 60px;
3776
  }
3777
+ .fl-video-field .fl-video-preview-img .dashicons.dashicons-media-video {
3778
+ display: block;
3779
+ font-size: 60px;
3780
+ height: 60px;
3781
+ line-height: 60px;
3782
+ width: 60px;
3783
+ }
3784
  .fl-video-field .fl-video-preview-filename {
3785
  display: inline-block;
3786
  font-size: 14px;
3787
  font-weight: bold;
3788
+ margin: 7px 0 5px 11px;
3789
  }
3790
  .fl-video-field .fl-video-replace {
3791
  margin: 0 0 0 11px;
3816
  .fl-icon-field .fl-icon-preview i {
3817
  display: inline-block;
3818
  font-size: 28px;
3819
+ margin: 10px 10px 9px 10px;
3820
  vertical-align: middle;
3821
  }
3822
  .fl-icon-field .fl-icon-remove {
3824
  }
3825
 
3826
  /* Text Editors */
3827
+ .fl-builder-hidden-editor {
3828
+ display: none;
3829
+ }
3830
  .fl-builder-settings .wp-switch-editor {
3831
  background: #ebebeb;
3832
  border: 1px solid #e5e5e5;
3872
  /* Editor Link Modal */
3873
  .fl-builder-edit form#wp-link {
3874
  color: #000;
3875
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
3876
  font-size: 13px;
3877
  }
3878
  .fl-builder-edit form#wp-link #link-options label {
3931
  }
3932
 
3933
  /* Link Field */
3934
+ .fl-link-field .fl-link-field-input-wrap {
3935
+ display: flex;
3936
+ flex-direction: row;
3937
+ }
3938
  .fl-link-field-input {
3939
+ width: auto !important;
3940
+ flex: 1 1 100%;
3941
+ }
3942
+ .fl-link-field .fl-link-field-input-wrap button {
3943
+ flex: 0 0 0%;
3944
+ margin-left: 5px;
3945
  }
3946
+
3947
+ .fl-link-field-input {}
3948
  .fl-link-field-search {
3949
  display: none;
3950
+ border: 2px solid #e6eaed;
3951
  border-radius: 3px;
3952
  -moz-border-radius: 3px;
3953
  -webkit-border-radius: 3px;
3989
  top: -6px;
3990
  width: 250px;
3991
  z-index: 1000;
3992
+ border-radius: 4px;
3993
+ }
3994
+ .fl-lightbox-width-slim .fl-help-tooltip-text {
3995
+ top:26px;
3996
+ left:-30px;
3997
  }
3998
 
3999
  /* Multiples */
4000
  .fl-field-control .fl-form-field {
4001
  margin-bottom: 0;
4002
  }
4003
+ .fl-form-field-preview-text i {
4004
+ display: inline-block;
4005
  font-size: 18px;
4006
  line-height: 22px;
4007
+ margin-bottom: 5px;
4008
  }
4009
  .fl-builder-field-actions {
4010
  padding-left: 0 !important;
4017
  cursor: pointer;
4018
  font-size: 13px !important;
4019
  line-height: 29px !important;
4020
+ width: 16px;
4021
  }
4022
  .fl-builder-field-actions i:hover {
4023
  color: #000 !important;
4039
  border: 1px dashed #cccccc;
4040
  height: 30px;
4041
  }
4042
+ .fl-builder-field-actions-single .fl-builder-field-move,
4043
+ .fl-builder-field-actions-single .fl-builder-field-delete {
4044
+ display: none !important;
4045
+ }
4046
+ .fl-lightbox-width-slim .fl-builder-field-actions-single .fl-builder-field-copy {
4047
+ float: right !important;
4048
+ }
4049
+
4050
+ .fl-builder-field-multiple .fl-field-label,
4051
+ .fl-builder-field-multiple .fl-field-control,
4052
+ .fl-builder-field-multiple .fl-builder-field-actions {
4053
+ padding-top:2px !important;
4054
+ padding-bottom:2px !important;
4055
+ }
4056
+ .fl-builder-field-multiple .fl-builder-field-actions {
4057
+ min-width: 70px !important;
4058
+ }
4059
+ .fl-builder-field-multiple[data-field="icons"] .fl-builder-field-actions {
4060
+ width: 70px !important;
4061
  }
4062
+
4063
+ /* Multiple item during drag */
4064
+ .fl-builder-field-multiple.ui-sortable-helper .fl-field-control {
4065
+ width: 60%; /* loose number because calc() doesn't work on table cells */
4066
+ }
4067
+ .fl-builder-field-multiple.ui-sortable-helper .fl-builder-field-actions {
4068
  display: none;
4069
  }
4070
 
4081
  }
4082
  .fl-builder-settings .error,
4083
  .fl-builder-settings input.error {
4084
+ color: #d03436 !important;
4085
  }
4086
  .fl-builder-settings label.error,
4087
  .fl-builder-settings p.error {
4090
  margin-top: 5px;
4091
  }
4092
  .fl-builder-settings .fl-form-table .fl-field-description {
4093
+ color: #464646;
4094
  font-style: normal;
4095
+ margin-left:2px;
4096
+ }
4097
+
4098
+ .fl-lightbox .fl-field-connection {
4099
+ right: -1px;
4100
+ }
4101
+ .fl-lightbox .fl-field-connection-content {
4102
+ border: 2px solid transparent !important;
4103
+ background: #e4e7ea !important;
4104
+ }
4105
+ .fl-field-connection-content .fl-field-connection-label {
4106
+ color: #676f7a !important;
4107
  }
4108
 
4109
  /* Auto Suggest */
4110
  ul.as-selections {
4111
  background-color: #fff;
4112
+ border:none;
4113
+ border-radius: 4px;
 
 
 
 
4114
  box-shadow: none;
 
 
4115
  color: #333;
4116
  font-size: 12px;
4117
  height: auto;
4134
  border-radius: 0;
4135
  font-size: 11px;
4136
  line-height: 14px;
4137
+ padding: 8px 15px;
4138
+ border-radius: 4px;
4139
+ margin: 2px;
4140
  }
4141
  ul.as-selections li.as-selection-item.blur {
4142
  background: #f4f4f4;
4152
  font-size: 12px;
4153
  margin: 0;
4154
  padding: 0;
4155
+ box-shadow: none;
4156
  }
4157
  ul.as-list {
4158
  margin: 0;
4159
  font-size: 13px;
4160
  color: #000;
4161
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
4162
  background-color: #fff;
4163
  background-color: rgba(255,255,255,.95);
4164
  z-index: 2;
4196
  color: #333 !important;
4197
  font-size: 12px;
4198
  padding: 0 !important;
4199
+ font-weight: bold;
4200
  }
4201
 
4202
  /* Loop Settings */
4256
  ------------------------------------------------------ */
4257
 
4258
  #tiptip_holder {
4259
+ z-index: 1000000;
4260
+ }
4261
+ #tiptip_holder.tip_top #tiptip_arrow_inner {
4262
+ border-top-color: #333;
4263
+ }
4264
+ #tiptip_holder.tip_bottom #tiptip_arrow_inner {
4265
+ border-bottom-color: #333;
4266
+ }
4267
+ #tiptip_holder.tip_right #tiptip_arrow_inner {
4268
+ border-right-color: #333;
4269
  }
4270
+ #tiptip_holder.tip_left #tiptip_arrow_inner {
4271
+ border-left-color: #333;
4272
  }
4273
  #tiptip_content {
4274
  background: #333;
4275
  box-shadow: none;
4276
  }
4277
+ /* @endgroup Settings Lightboxes */
4278
 
4279
+ /* @group Help */
4280
  /* Getting Started Video
4281
  ------------------------------------------------------ */
4282
 
4326
  box-shadow: 0 0 40px rgba(0,0,0,.3);
4327
  color: #666;
4328
  font-size: 13px;
4329
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
4330
  font-weight: normal;
4331
  line-height: 18px;
4332
  max-width: none;
4367
  float: none;
4368
  width: 100%;
4369
  }
4370
+ .popover-navigation button {
4371
+ min-height: 36px;
4372
+ }
4373
+ /* @endgroup Help */
4374
 
4375
+ /* @group Shortcodes
4376
  ------------------------------------------------------ */
4377
 
4378
  .fl-builder-shortcode-mask-wrap {
4386
  top: -1px;
4387
  z-index: 1;
4388
  }
4389
+ /* @endgroup Shortcodes */
4390
+
4391
+ /* @group Search
4392
+ ------------------------------------------------------------ */
4393
+ .fl-builder--search {
4394
+ border: 2px solid transparent;
4395
+ position:relative;
4396
+ padding:0;
4397
+ width:54px;
4398
+ transition-property: width;
4399
+ transition-delay: .1s;
4400
+ transition-duration: .15s;
4401
+ }
4402
+ .fl-builder--search.is-expanded {
4403
+ border: 2px solid #00A0D0;
4404
+ }
4405
+ .fl-builder--search input[type="text"],
4406
+ .fl-builder--search input[type="text"]:focus {
4407
+ background-color:transparent;
4408
+ border: none !important;
4409
+ box-sizing: border-box;
4410
+ width:100%;
4411
+ font-size:16px;
4412
+ text-align: center;
4413
+ }
4414
+ .fl-builder--search:before {
4415
+ display: flex;
4416
+ position: absolute;
4417
+ top:0;
4418
+ left:0;
4419
+ align-items: center;
4420
+ justify-content: center;
4421
+ content: "\f002";
4422
+ font: normal normal normal 14px/1 FontAwesome;
4423
+ text-align: center;
4424
+ width: 100%;
4425
+ height:100%;
4426
+ position: absolute;
4427
+ pointer-events: none;
4428
+ color: rgba(128,128,128,0.6);
4429
+ font-size: 17px;
4430
+ opacity:1;
4431
+ transition-property: opacity;
4432
+ transition-duration: .15s;
4433
+ }
4434
+ .fl-builder--search.is-expanded:before,
4435
+ .fl-builder--search.has-text:before {
4436
+ opacity:0;
4437
+ }
4438
+
4439
+ .fl-builder--search input::-webkit-input-placeholder {
4440
+ color: rgba(128,128,128,0) !important;
4441
+ transition: color .25s;
4442
+ }
4443
+ .fl-builder--search input:focus::-webkit-input-placeholder {
4444
+ color: rgba(128,128,128,0.4) !important;
4445
+ }
4446
+ .fl-builder--search .search-label {
4447
+ cursor: text;
4448
+ }
4449
+ .fl-builder--search .search-clear {
4450
+ display: none;
4451
+ padding: 10px 10px 10px 30px;
4452
+ color: #a7a7a7;
4453
+ font-size: 12px;
4454
+ position: absolute;
4455
+ right: 0;
4456
+ top: 0;
4457
+ background-color: #eff1f2;
4458
+ background: linear-gradient(to left, #e4e7ea, #e4e7ea 75%, rgba(228, 231, 234, 0) );
4459
+ }
4460
+ .fl-builder--search:hover .search-clear {
4461
+ color: #888888;
4462
+ background-color: #eff1f2;
4463
+ background: linear-gradient(to left, #dadfe5, #dadfe5 75%, rgba(218, 223, 229, 0) );
4464
+ }
4465
+ .fl-builder--search.has-text .search-clear {
4466
+ display:inline-block;
4467
+ }
4468
+ .fl-builder--search.is-expanded {
4469
+ width: 246px;
4470
+ }
4471
+ .fl-builder--search.is-expanded input {
4472
+ display: inline-block;
4473
+ }
4474
+ /* @endgroup Search */
4475
+
4476
+ /* @group Main Menu
4477
+ ------------------------------------------------------ */
4478
+
4479
+ @keyframes fl-builder-show-menu-item {
4480
+ from {
4481
+ transform: translateY(10px) scale(.8);
4482
+ opacity:0;
4483
+ }
4484
+
4485
+ to {
4486
+ transform: translateX(0px) translateY(0px) scale(1);
4487
+ opacity:1;
4488
+ }
4489
+ }
4490
+
4491
+ .fl-builder--main-menu-panel {
4492
+ display:none;
4493
+ box-sizing: border-box;
4494
+ position: fixed;
4495
+ top:calc(48px + 10px);
4496
+ left: 10px;
4497
+ width: 360px;
4498
+ color: #222;
4499
+ max-height: calc(100% - 66px);
4500
+ border-radius: 4px;
4501
+ background: #ffffff;
4502
+ border: 2px solid #D5DADD;
4503
+ border-top: 3px solid #00a0d2;
4504
+ box-shadow: 0px 15px 45px 8px rgba(0, 0, 0, 0.04);
4505
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
4506
+ font-size: 14px !important;
4507
+
4508
+ /* Prevent select */
4509
+ -webkit-touch-callout: none; /* iOS Safari */
4510
+ -webkit-user-select: none; /* Chrome/Safari/Opera */
4511
+ -moz-user-select: none; /* Firefox */
4512
+ -ms-user-select: none; /* Internet Explorer/Edge */
4513
+ user-select: none; /* Non-prefixed version, currently
4514
+ not supported by any browser */
4515
+ z-index: 10000009;
4516
+ pointer-events: auto;
4517
+ }
4518
+ .fl-builder--main-menu-panel.is-showing {
4519
+ display:flex;
4520
+ }
4521
+ .fl-builder--main-menu-panel:before,
4522
+ .fl-theme-builder-preview-select-open .fl-theme-builder-preview-select-items:before {
4523
+ bottom: 100%;
4524
+ right: 6px;
4525
+ content: " ";
4526
+ height: 0;
4527
+ width: 0;
4528
+ position: absolute;
4529
+ pointer-events: none;
4530
+ border: solid;
4531
+ border-color: rgba(255, 255, 255, 0);
4532
+ border-bottom-color: #00a0d2;
4533
+ border-width: 13px;
4534
+ margin-left: -13px;
4535
+ }
4536
+ .fl-builder--main-menu-panel-views {
4537
+ flex: 1 1 100%;
4538
+ overflow: auto;
4539
+ }
4540
+ .fl-builder--main-menu-panel-mask {
4541
+ display:none;
4542
+ position: fixed;
4543
+ top:0;
4544
+ left:0;
4545
+ right:0;
4546
+ bottom:0;
4547
+ z-index: 1000119;
4548
+ }
4549
+ .fl-builder--main-menu-panel .fl-builder--tabs {
4550
+ padding-left:20px;
4551
+ padding-top: 15px;
4552
+ }
4553
+ .fl-builder--main-menu-panel-view {
4554
+ display:none;
4555
+ }
4556
+ .fl-builder--main-menu-panel-view.is-showing {
4557
+ display:block;
4558
+ }
4559
+ .fl-builder--main-menu-panel-view-title {
4560
+ font-size: 24px;
4561
+ font-weight: 600;
4562
+ padding: 25px 22px 0;
4563
+ line-height: 1;
4564
+ white-space: nowrap;
4565
+ }
4566
+ .fl-builder--main-menu-panel-view-title .title-accessory {
4567
+ float:right;
4568
+ color: #b1b1b1;
4569
+ }
4570
+ .fl-builder--main-menu-panel-view-title .title-accessory > i {
4571
+ font-size: 20px !important;
4572
+ width: 25px !important;
4573
+ }
4574
+ .fl-builder--main-menu-panel-view-title .title-accessory > i:hover {
4575
+ color: #222222;
4576
+ }
4577
+ .fl-builder--main-menu-panel-view-title .pop-view {
4578
+ padding: 10px;
4579
+ padding-right: 10px;
4580
+ margin-left: -10px;
4581
+ opacity: .5;
4582
+ font-size: 25px;
4583
+ font-weight: 400;
4584
+ cursor: pointer;
4585
+ background: transparent;
4586
+ outline: none;
4587
+ border: none;
4588
+ color: inherit;
4589
+ }
4590
+ .fl-builder--main-menu-panel-view-title .pop-view:focus {
4591
+ outline:none;
4592
+ top:0;
4593
+ background: #E5EAED !important;
4594
+ }
4595
+ .fl-builder--menu-item:before {
4596
+ display:block;
4597
+ content: "";
4598
+ float:none;
4599
+ clear:both;
4600
+ }
4601
+
4602
+ .fl-builder--menu-item {
4603
+ color: inherit;
4604
+ text-align: left;
4605
+ box-sizing: border-box;
4606
+ display: block;
4607
+ padding: 10px 15px;
4608
+ margin:0 10px;
4609
+ width: calc(100% - 20px);
4610
+ background: transparent;
4611
+ border: none;
4612
+ border-radius: 4px;
4613
+ font-size:14px;
4614
+ line-height: 1.1;
4615
+ cursor: pointer;
4616
+ opacity:1;
4617
+ }
4618
+ .fl-builder--menu-item:hover {
4619
+ background: #eaf1f8;
4620
+ border:none;
4621
+ text-decoration: none;
4622
+ color: #000000;
4623
+ }
4624
+ .fl-builder--selector-menu .fl-builder--menu-item:hover {
4625
+ background:white;
4626
+ }
4627
+ .fl-builder--menu-item-accessory {
4628
+ float:right;
4629
+ text-align: center;
4630
+ display: inline-block;
4631
+ min-width: 40px;
4632
+ font-size: 14px;
4633
+ }
4634
+ .fl-builder--menu-item-accessory.view-arrow {
4635
+ font-size: 18px;
4636
+ }
4637
+ .fl-builder--menu {
4638
+ padding:0;
4639
+ margin:20px 0;
4640
+ }
4641
+ .fl-builder--menu hr {
4642
+ margin: 8px 0;
4643
+ background-color: #e6eaed !important;
4644
+ height: 2px;
4645
+ border: none;
4646
+ }
4647
+ .fl-builder--menu .fl-builder-video-wrap {
4648
+ padding: 0px 10px 10px;
4649
+ }
4650
+ /* @endgroup Main Menu */
4651
+
4652
+ /* @group Revisions
4653
+ ------------------------------------------------------ */
4654
+
4655
+ /* Revisions items */
4656
+ .fl-revision-list-item {
4657
+ display: flex;
4658
+ }
4659
+ .fl-revision-list-item-text {
4660
+ padding-left: 15px;
4661
+ }
4662
+ .fl-revision-list-item-date {
4663
+ padding-bottom: 5px;
4664
+ }
4665
+
4666
+ /* Revision actions */
4667
+ .fl-builder--revision-actions {
4668
+ display:none;
4669
+ position: fixed;
4670
+ top: 4px;
4671
+ left: 4px;
4672
+ z-index: 100008;
4673
+ padding: 4px 4px 6px;
4674
+ justify-content: center;
4675
+ background:white;
4676
+ border-radius: 4px;
4677
+ }
4678
+ .fl-builder--revision-actions * {
4679
+ margin-right: 5px;
4680
+ }
4681
+ .fl-builder--revision-actions *:last-child {
4682
+ margin: 0;
4683
+ }
4684
+
4685
+ /* No revisions message */
4686
+ .fl-builder--menu-item[data-event="noRevisionsMessage"]:hover {
4687
+ background: transparent;
4688
+ box-shadow: none;
4689
+ cursor: default;
4690
+ }
4691
+ .fl-no-revisions-message-title {
4692
+ font-weight: bold;
4693
+ margin-bottom: 10px;
4694
+ }
4695
+ .fl-no-revisions-message-text {
4696
+ line-height: 22px;
4697
+ }
4698
 
4699
+ /* @endgroup Revisions */
4700
+
4701
+ /* @group Modules
4702
  ------------------------------------------------------ */
4703
 
4704
  .fl-builder-module-placeholder-message {
4709
  text-overflow: ellipsis;
4710
  white-space: nowrap;
4711
  }
4712
+ /* @endgroup Modules */
4713
+
4714
+ /* @group Misc
4715
+ ------------------------------------------------------ */
4716
+
4717
+ .fl-field-connections-menu {
4718
+ z-index: 999999;;
4719
+ }
4720
+ .fl-field-connections-toggle {
4721
+ right: -30px !important;
4722
+ }
4723
+ /* @endgroup Misc */
4724
+
4725
+ /* @group 2.0 Compat
4726
+ Rules to ensure compatibility with v2.0.
4727
+ ------------------------------------------------------ */
4728
+
4729
+ .uabb-live-preview-button,
4730
+ .pp-preview-button,
4731
+ .fl-builder-pp-add-template-button,
4732
+ .fl-builder-add-ultimate-rows-button,
4733
+ .fl-builder-add-ultimate-presets-button {
4734
+ display: none !important;
4735
+ }
4736
+ /* @endgroup 2.0 Compat */
4737
+
4738
+ /* @group jQuery UI */
4739
+
4740
+ /* Resizable
4741
+ ------------------------------------------------------ */
4742
+
4743
+ .ui-resizable {
4744
+ position: relative;
4745
+ }
4746
+ .ui-resizable-handle {
4747
+ position: absolute;
4748
+ font-size: 0.1px;
4749
+ display: block;
4750
+ -ms-touch-action: none;
4751
+ touch-action: none;
4752
+ background: transparent;
4753
+ transition-property: background;
4754
+ transition-duration: .15s;
4755
+ }
4756
+ .ui-resizable-disabled .ui-resizable-handle,
4757
+ .ui-resizable-autohide .ui-resizable-handle {
4758
+ display: none;
4759
+ }
4760
+ .ui-resizable-n {
4761
+ cursor: n-resize;
4762
+ height: 7px;
4763
+ width: 100%;
4764
+ top: -5px;
4765
+ left: 0;
4766
+ }
4767
+ .ui-resizable-s {
4768
+ cursor: s-resize;
4769
+ height: 7px;
4770
+ width: 100%;
4771
+ bottom: -5px;
4772
+ left: 0;
4773
+ }
4774
+ .ui-resizable-e {
4775
+ cursor: e-resize;
4776
+ width: 7px;
4777
+ right: -5px;
4778
+ top: 0;
4779
+ height: 100%;
4780
+ }
4781
+ .ui-resizable-w {
4782
+ cursor: w-resize;
4783
+ width: 7px;
4784
+ left: -5px;
4785
+ top: 0;
4786
+ height: 100%;
4787
+ }
4788
+ .ui-resizable-se {
4789
+ cursor: se-resize;
4790
+ width: 12px;
4791
+ height: 12px;
4792
+ right: -4px;
4793
+ bottom: -4px;
4794
+ }
4795
+ .ui-resizable-sw {
4796
+ cursor: sw-resize;
4797
+ width: 12px;
4798
+ height: 12px;
4799
+ left: -4px;
4800
+ bottom: -4px;
4801
+ }
4802
+ .ui-resizable-nw {
4803
+ cursor: nw-resize;
4804
+ width: 12px;
4805
+ height: 12px;
4806
+ left: -4px;
4807
+ top: -4px;
4808
+ }
4809
+ .ui-resizable-ne {
4810
+ cursor: ne-resize;
4811
+ width: 12px;
4812
+ height: 12px;
4813
+ right: -4px;
4814
+ top: -4px;
4815
+ }
4816
+ .fl-builder-resizable-iframe-fix {
4817
+ position: absolute;
4818
+ top: 0;
4819
+ right: 0;
4820
+ bottom: 0;
4821
+ left: 0;
4822
+ z-index: 100000000;
4823
+ }
4824
+
4825
+ .fl-lightbox .ui-resizable-handle:hover,
4826
+ .fl-lightbox .ui-resizable-handle:active,
4827
+ .fl-builder-panel .ui-resizable-handle:hover,
4828
+ .fl-builder-panel .ui-resizable-handle:active {
4829
+ background: #00a0d2;
4830
+ }
4831
+ .fl-lightbox .ui-resizable-n,
4832
+ .fl-lightbox .ui-resizable-s,
4833
+ .fl-builder-panel .ui-resizable-n,
4834
+ .fl-builder-panel .ui-resizable-s {
4835
+ height: 6px;
4836
+ }
4837
+ .fl-lightbox .ui-resizable-n,
4838
+ .fl-builder-panel .ui-resizable-n {
4839
+ top: -3px;
4840
+ }
4841
+ .fl-lightbox .ui-resizable-s,
4842
+ .fl-builder-panel .ui-resizable-s {
4843
+ bottom: -3px;
4844
+ }
4845
+
4846
+ .fl-lightbox .ui-resizable-e,
4847
+ .fl-lightbox .ui-resizable-w,
4848
+ .fl-builder-panel .ui-resizable-e,
4849
+ .fl-builder-panel .ui-resizable-w {
4850
+ width: 6px;
4851
+ }
4852
+ .fl-lightbox .ui-resizable-e,
4853
+ .fl-builder-panel .ui-resizable-e {
4854
+ right: -3px;
4855
+ }
4856
+ .fl-lightbox .ui-resizable-w,
4857
+ .fl-builder-panel .ui-resizable-w {
4858
+ left: -3px;
4859
+ }
4860
+ .fl-lightbox .ui-resizable-ne,
4861
+ .fl-lightbox .ui-resizable-nw,
4862
+ .fl-lightbox .ui-resizable-se,
4863
+ .fl-lightbox .ui-resizable-sw {
4864
+ background: transparent;
4865
+ border: 6px solid transparent;
4866
+ }
4867
+ .fl-lightbox .ui-resizable-ne:hover,
4868
+ .fl-lightbox .ui-resizable-nw:hover,
4869
+ .fl-lightbox .ui-resizable-se:hover,
4870
+ .fl-lightbox .ui-resizable-sw:hover,
4871
+ .fl-lightbox .ui-resizable-ne:active,
4872
+ .fl-lightbox .ui-resizable-nw:active,
4873
+ .fl-lightbox .ui-resizable-se:active,
4874
+ .fl-lightbox .ui-resizable-sw:active {
4875
+ background:transparent;
4876
+ border-color: #00a0d2;
4877
+ }
4878
+ .fl-lightbox .ui-resizable-ne {
4879
+ border-bottom:none;
4880
+ border-left:none;
4881
+ border-top-right-radius: 4px;
4882
+ }
4883
+ .fl-lightbox .ui-resizable-nw {
4884
+ border-bottom:none;
4885
+ border-right:none;
4886
+ border-top-left-radius: 4px;
4887
+ }
4888
+ .fl-lightbox .ui-resizable-se {
4889
+ border-top:none;
4890
+ border-left:none;
4891
+ border-bottom-right-radius: 4px;
4892
+ }
4893
+ .fl-lightbox .ui-resizable-sw {
4894
+ border-top:none;
4895
+ border-right:none;
4896
+ border-bottom-left-radius: 4px;
4897
+ }
4898
+
4899
+ /* @endgroup jQuery UI */
4900
+
4901
+
4902
+ .fl-builder-ui-keyboard-shortcuts {
4903
+ display:none;
4904
+ position: fixed;
4905
+ top:0;
4906
+ left:0;
4907
+ bottom:0;
4908
+ right:0;
4909
+ z-index: 999999;
4910
+ justify-content: center;
4911
+ align-items: center;
4912
+ background: rgba(50, 50, 50, 0.88);
4913
+ font-size: 15px;
4914
+ line-height: 1.3;
4915
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
4916
+ user-select: none;
4917
+ }
4918
+ .fl-builder-ui-keyboard-shortcuts.is-showing {
4919
+ display: flex;
4920
+ }
4921
+ .fl-builder-ui-keyboard-shortcuts-content {
4922
+ box-sizing: border-box;
4923
+ width: 500px;
4924
+ background: #f5f7f9;
4925
+ border-radius: 4px;
4926
+ padding: 30px 0 0;
4927
+ box-shadow: 0px 10px 30px rgba(0, 0, 0, 0.15);
4928
+ }
4929
+ .fl-builder-ui-keyboard-shortcut-item {
4930
+ display: flex;
4931
+ flex-direction: row;
4932
+ align-items: center;
4933
+ padding:12px 40px;
4934
+ }
4935
+ .fl-builder-ui-keyboard-shortcut-item:nth-child(even) {
4936
+ background: #eef2f5;
4937
+ }
4938
+ .fl-builder-ui-shortcut-keycode {
4939
+ margin-left: auto;
4940
+ text-transform:uppercase;
4941
+ letter-spacing: 2px;
4942
+ }
4943
+ .fl-builder-ui-keyboard-shortcust-footer {
4944
+ display: flex;
4945
+ flex-direction: row;
4946
+ justify-content: center;
4947
+ padding: 10px;
4948
+ }
4949
+ .dismiss-shortcut-ui {
4950
+ padding:10px;
4951
+ border-radius:4px;
4952
+ background:white;
4953
+ color: black;
4954
+ border:none;
4955
+ font-size: 14px;
4956
+ border: 2px solid white;
4957
+ }
4958
+ .dismiss-shortcut-ui:hover {
4959
+ top:0;
4960
+ color: black;
4961
+ background: #eef2f5;
4962
+ border: 2px solid #eef2f5;
4963
+ }
4964
+ .dismiss-shortcut-ui:focus {
4965
+ top:0;
4966
+ color: black;
4967
+ background: #eef2f5;
4968
+ border: 2px solid #eef2f5;
4969
+ }
css/fl-builder.min.css CHANGED
@@ -1 +1 @@
1
- .fl-builder-edit #wpadminbar,.fl-builder-hidden-editor{display:none}html.fl-builder-edit{margin-top:43px!important}.fl-builder-edit body{position:static!important}.fl-clear{clear:both}.screen-reader-text{position:absolute;left:-1000em;top:-1000em;height:1px;width:1px;overflow:hidden}.fl-builder-loading{background:url(../img/ajax-loader.svg) center center no-repeat rgba(240,240,240,.8);bottom:0;display:none;left:0;position:fixed;right:0;text-align:center;top:0;z-index:200000}.fl-builder-settings .fl-builder-loading{background:url(../img/ajax-loader.svg) center center no-repeat rgba(255,255,255,.8);display:block;position:absolute}.fl-builder-node-loading{opacity:.35}.fl-builder-node-loading-placeholder{background:url(../img/ajax-loader.svg) center center no-repeat;height:50px}.fl-col-group-has-child-loading{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.fl-col-group-has-child-loading>.fl-builder-node-loading-placeholder{width:50px}.fl-builder-content-editing .fl-visible-desktop,.fl-builder-content-editing .fl-visible-desktop-medium,.fl-builder-content-editing .fl-visible-medium,.fl-builder-content-editing .fl-visible-medium-mobile,.fl-builder-content-editing .fl-visible-mobile{display:block!important}.fl-responsive-preview-mask{background:#F7F7F7;bottom:0;left:0;position:fixed;right:0;top:0;z-index:99999}.fl-responsive-preview{bottom:0;left:0;position:absolute;right:0;top:43px;z-index:100000}.fl-responsive-preview-content{background:#F7F7F7;padding:20px}.fl-responsive-preview-message{color:#b3b3b3;font-family:Helvetica,Arial,Verdana,sans-serif;font-size:14px;font-weight:400;padding:0 20px 20px;text-align:center}.fl-responsive-preview-message i{cursor:pointer;margin-left:3px}.fl-responsive-preview .fl-builder-content{box-shadow:0 0 8px rgba(0,0,0,.2);margin-left:auto;margin-right:auto;max-width:100%}.fl-builder-button{color:#555;border-color:#ccc;background:#f7f7f7;-webkit-box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);vertical-align:top;display:inline-block;text-decoration:none;font-size:13px!important;line-height:13px!important;height:28px;margin:0;padding:7px 10px;cursor:pointer;border-width:1px;border-style:solid;-webkit-border-radius:3px;-webkit-appearance:none;border-radius:3px;white-space:nowrap;-webkit-box-sizing:border-box!important;-moz-box-sizing:border-box!important;box-sizing:border-box!important}.fl-builder-button:hover{background:#fafafa;border-color:#999;color:#222}.fl-builder-button-primary{background:#2ea2cc;border-color:#0074a2;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);color:#fff!important;text-decoration:none}.fl-builder-button-primary:hover{background:#1e8cbe;border-color:#0074a2;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.6);box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff!important}.fl-builder-bar-content,.fl-builder-panel{box-shadow:0 0 8px rgba(0,0,0,.2);font-family:Helvetica,Arial,Verdana,sans-serif}.fl-builder-button-large{height:30px;line-height:30px!important;padding:0 12px 2px}.fl-builder-button-small{font-size:11px!important;line-height:11px!important;height:24px}.fl-builder-help-button{color:#b3b3b3;font-size:16px!important}.fl-builder-help-button i{position:relative;top:-1px}.fl-builder-help-button:hover{color:#666}.fl-builder-publish-button{height:45px;line-height:45px!important}.fl-builder-badge{background:#333;border-radius:2px;color:#fff!important;display:inline;font-size:11px!important;font-weight:400;letter-spacing:1px;margin-left:2px;padding:2px 4px;vertical-align:top}.fl-builder-badge-global{background:#ff9600}.fl-builder-bar{left:0;position:fixed;right:0;top:0;z-index:100008}.fl-builder-bar-content{background:#f4f4f4;border-bottom:1px solid #ccc;-moz-box-shadow:0 0 8px rgba(0,0,0,.2);-webkit-box-shadow:0 0 8px rgba(0,0,0,.2);color:#999;font-size:14px;height:43px}.fl-builder-bar-title{color:#333;display:block;float:left;font-size:20px;font-weight:300;line-height:20px;padding:7px 10px}.fl-builder-bar-title img{display:inline-block!important;height:30px!important;margin:0 1px 0 0!important;vertical-align:middle!important}.fl-builder-bar-title span{vertical-align:middle}.fl-builder-bar-title.fl-builder-bar-title-no-icon{padding:12px}.fl-builder-bar-actions{float:right;padding:7px}.fl-builder-bar .fl-builder-button{float:right;margin:0 0 0 6px}.fl-builder-bar .fl-builder-add-content-button{display:none}.fl-builder-buy-button,.fl-builder-upgrade-button{background:#f7951e;border-color:#de7c04;-webkit-box-shadow:inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);color:#fff!important;text-decoration:none}.fl-builder-buy-button i.fa-external-link-square,.fl-builder-upgrade-button i.fa-external-link-square{color:#f4d1a7;margin:0 0 0 6px}.fl-builder-buy-button:hover,.fl-builder-upgrade-button:hover{background:#de861b;border-color:#c46e04;-webkit-box-shadow:inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(255,177,82,.5),0 1px 0 rgba(0,0,0,.15);color:#fff!important}@media (max-width:768px){.fl-builder-bar-title span{display:none}}@media (max-width:420px){.fl-builder-bar-title,.fl-builder-help-button{display:none}}.fl-builder-panel{background:#f0f0f0;border-left:1px solid #ccc;bottom:0;-moz-box-shadow:0 0 8px rgba(0,0,0,.2);-webkit-box-shadow:0 0 8px rgba(0,0,0,.2);color:#999;font-size:14px;opacity:1;position:fixed;right:0;top:43px;width:300px;z-index:100007;-webkit-transform:translateZ(0);transition:opacity .2s;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;-ms-transition:opacity .2s;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fl-builder-panel-actions{background:#f4f4f4;border-bottom:1px solid #dbdbdb;height:43px;left:0;position:absolute;right:0;top:0;text-align:right;z-index:100009}.fl-builder-panel-actions .fl-builder-panel-close{color:#bfbfbf;cursor:pointer;float:left;font-size:18px;margin:12px 18px}.fl-builder-panel-actions .fl-builder-panel-close:hover{color:#333}.fl-builder-panel-content-wrap{bottom:0;height:auto;left:0;overflow:hidden;position:absolute;right:0;top:43px}.fl-builder-panel-content{padding-bottom:60px}.fl-builder-blocks-section .fl-builder-block,.fl-builder-blocks-section .fl-builder-blocks-section-title{cursor:pointer;display:block;line-height:14px;padding:15px 20px}.fl-builder-blocks-section .fl-builder-blocks-section-title{border-bottom:1px solid #dfdfdf;color:#333;font-weight:400}.fl-builder-blocks-section .fl-builder-blocks-section-title i{color:#bfbfbf;float:right}.fl-builder-blocks-section .fl-builder-blocks-section-title:hover,.fl-builder-blocks-section .fl-builder-blocks-section-title:hover i{background:#e5e5e5}.fl-builder-blocks-section-content{background:#fff;display:none}.fl-builder-blocks-section.fl-active .fl-builder-blocks-section-content{display:block}.fl-builder-blocks-section-content .fl-builder-block{border-bottom:1px solid #ebebeb;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fl-builder-blocks-section-content .fl-builder-block i{color:#d9d9d9;margin-right:10px}.fl-builder-blocks-section-content .fl-builder-block:hover{background:#0074a1;color:#fff;cursor:move}.fl-builder-blocks-separator{background:#dfdfdf;height:6px}.fl-builder-block:hover .fl-builder-badge{background:#2ea2cc}.ui-sortable-helper .fl-builder-badge{display:none!important}.fl-builder-modules-cta a{color:#999!important;display:block!important;font-size:12px!important;font-style:italic!important;padding:15px 20px!important;line-height:16px!important}.fl-builder-modules-cta a:hover{background:#e5e5e5!important;color:#666!important;text-decoration:none!important}.fl-builder-modules-cta a:focus{text-decoration:none!important}.fl-builder-modules-cta .fa{float:right!important;font-size:14px!important;margin:3px 0 0 9px!important}.fl-builder-block-template-image{margin:5px 0 10px;max-width:100%;border:1px solid #dfdfdf}.fl-builder-block-template .fl-builder-block-title{display:block;overflow:hidden;text-overflow:ellipsis}.ui-sortable-helper .fl-builder-block-template-image{display:none!important}span.fl-builder-block-no-node-templates{display:block;padding:15px 20px}span.fl-builder-block-no-node-templates:hover{cursor:default;background:#fff}.fl-builder-blocks-node-template .fl-builder-block{position:relative}.fl-builder-blocks-node-template .fl-builder-badge-global{position:absolute;right:20px;top:13px}.fl-builder-blocks-node-template .fl-builder-block:hover .fl-builder-badge-global{display:none}.fl-builder-blocks-node-template .fl-builder-block-global.fl-builder-block{padding-right:85px}.fl-builder-blocks-section-content .fl-builder-node-template-actions{bottom:0;cursor:default;display:none;position:absolute;right:0;top:0;width:72px}.fl-builder-blocks-section-content .fl-builder-node-template-delete,.fl-builder-blocks-section-content .fl-builder-node-template-edit{bottom:0;cursor:pointer;margin:0;padding:15px 0;position:absolute;text-align:center;top:0;width:30px}.fl-builder-blocks-section-content .fl-builder-node-template-delete{right:12px}.fl-builder-blocks-section-content .fl-builder-node-template-edit{right:42px}.fl-builder-blocks-section-content .fl-builder-node-template-delete i,.fl-builder-blocks-section-content .fl-builder-node-template-edit i{margin:0}.fl-builder-drop-zone,.fl-builder-empty{font-family:Helvetica,Verdana,sans-serif!important;margin:10px}.fl-builder-blocks-section-content .fl-builder-node-template-delete:hover i,.fl-builder-blocks-section-content .fl-builder-node-template-edit:hover i{color:#fff}.fl-builder-blocks-node-template .fl-builder-block:hover{padding-right:85px}.fl-builder-blocks-node-template .fl-builder-block:hover .fl-builder-node-template-actions{display:block}.ui-sortable-helper .fl-builder-node-template-delete,.ui-sortable-helper .fl-builder-node-template-edit{display:none!important}.fl-builder-dragging .fl-builder-content:not(.fl-builder-empty){padding:16px 0}.fl-builder-empty{border:1px dashed #3ba0ff;color:#3ba0ff;font-size:14px;padding:100px 20px;position:relative;text-align:center;text-transform:uppercase}.fl-builder-block-drag-helper,.fl-builder-block.ui-draggable-dragging{background:rgba(255,255,255,.85)!important;border:1px solid #ccc;box-shadow:0 0 8px rgba(0,0,0,.2);-moz-box-shadow:0 0 8px rgba(0,0,0,.2);-webkit-box-shadow:0 0 8px rgba(0,0,0,.2);color:#999!important;font-family:Helvetica,Verdana,sans-serif!important;font-size:13px!important;height:40px!important;line-height:40px!important;overflow:hidden;padding:0 15px;position:fixed!important;text-overflow:ellipsis;white-space:nowrap;width:120px!important;z-index:100010!important}.fl-col-has-highlight-guide .fl-col-content,.fl-col-highlight,.fl-row-highlight .fl-col-group{position:relative}.fl-builder-drop-zone{animation:fl-builder-drop-zone-pulse 3s infinite;background:#3ba0ff;color:#fff!important;display:block;font-weight:400;font-size:12px;letter-spacing:1px;line-height:14px;padding:6px 8px 5px;position:relative;text-align:left;text-overflow:ellipsis;text-shadow:none;text-transform:none;white-space:nowrap;overflow:hidden;z-index:10}@keyframes fl-builder-drop-zone-pulse{0%,100%{background-color:#7ABFFF}50%{background-color:#3ba0ff}}.fl-builder-drop-zone-global{animation:fl-builder-drop-zone-global-pulse 3s infinite;background:#ff9600}@keyframes fl-builder-drop-zone-global-pulse{0%,100%{background-color:#FFBC5C}50%{background-color:#ff9600}}.fl-builder-content>.fl-builder-drop-zone{margin:10px 20px}.fl-row-content>.fl-builder-drop-zone{margin:3px 7px}.fl-col-has-cols>.fl-col-content>.fl-builder-drop-zone{margin:3px 10px}.fl-sortable-disabled>.fl-builder-drop-zone{display:none!important}.fl-col-group-equal-height.fl-col-group-align-center .fl-col-content>.fl-builder-drop-zone{width:100%}.fl-row-highlight{padding:16px 0}.fl-row-highlight .fl-row-content{border:1px dashed #3ba0ff;padding:8px}.fl-row-highlight.fl-node-global .fl-row-content{border-color:#ff9600}.fl-col-highlight{padding:8px}.fl-col-highlight .fl-col-content{border-style:dashed!important;border-color:#3ba0ff!important;min-height:100px;overflow-x:hidden;width:100%;border-width:1px!important}.fl-col-has-cols.fl-col-highlight>.fl-col-content{padding:8px}.fl-col-highlight.fl-node-global .fl-col-content{border-color:#ff9600!important}.fl-builder-simple .fl-col-highlight .fl-col-content{border:none!important}.fl-col-highlight-guide{background:rgba(59,160,255,.15);border:1px solid #3ba0ff;bottom:4px;left:4px;position:absolute;right:4px;top:4px;z-index:1}.fl-col-has-highlight-guide .fl-block-overlay{background:0 0;border-color:transparent}.fl-col-has-highlight-guide .fl-block-col-resize{display:none}.fl-col-has-highlight-guide .fl-col-highlight .fl-col-content{border-color:transparent!important}.fl-col-drop-target{bottom:8px;display:none;left:-9px;position:absolute;top:8px;width:18px;z-index:1}.fl-col-highlight .fl-col-drop-target{display:block}.fl-col-drop-target-last{left:auto;right:-9px}.fl-col-drop-target .fl-builder-drop-zone{bottom:0;left:2px;margin:0;padding:0;position:absolute;right:2px;top:0}.fl-col-group-drop-target{display:none;left:8px;height:18px;position:absolute;right:8px;top:-9px;z-index:1}.fl-row-highlight .fl-col-group-drop-target{display:block}.fl-col-group-drop-target-last{top:auto;bottom:-9px}.fl-col-group-drop-target .fl-builder-drop-zone{bottom:2px;left:0;margin:0;padding:0;position:absolute;right:0;top:2px}.fl-row-content>.fl-col-group-drop-target{position:static}.fl-row-content>.fl-col-group-drop-target .fl-builder-drop-zone{height:18px;position:static}.fl-row-drop-target{display:none;left:0;height:24px;margin-top:-28px;position:absolute;right:0;z-index:1}.fl-row-highlight .fl-row-drop-target{display:block}.fl-row-drop-target-last{margin-top:4px}.fl-row .fl-row-drop-target .fl-builder-drop-zone{bottom:0;left:4px;margin:0;position:absolute;right:4px;top:0}.fl-builder-content>.fl-row-drop-target{margin:0;position:static}.fl-builder-dragging .fl-builder-content.fl-builder-empty>.fl-row-drop-target{bottom:10px;display:block;height:auto;left:0;position:absolute;right:0;top:10px}.fl-builder-content .fl-row-drop-target .fl-builder-drop-zone{margin-bottom:0;margin-top:0}.fl-sortable-proxy{display:none}.fl-block-overlay,.fl-block-overlay *{text-shadow:none}.fl-block-overlay-active{position:relative}.fl-block-overlay-actions{background:#3ba0ff;float:left;height:28px;margin:-1px -1px 0;text-shadow:none}.fl-builder-col-resizing .fl-block-overlay-actions{overflow:hidden}.fl-block-overlay-actions>span{display:block;float:left}.fl-block-overlay-actions i{color:#fff!important;cursor:pointer;display:block!important;float:left;font-size:14px!important;height:28px!important;font-weight:100!important;line-height:28px!important;opacity:.8;filter:alpha(opacity=80);text-align:center;width:28px!important}.fl-block-overlay-actions i:hover{opacity:1;filter:alpha(opacity=100)}.fl-block-overlay-actions>i:first-child{padding-left:4px}.fl-block-overlay-actions>i:last-child{padding-right:2px}.fl-block-overlay-actions .fl-block-move{cursor:move}.fl-block-overlay-title{border-right:1px solid #5eb1ff;color:#fff!important;float:left;font-family:Helvetica,Arial,Verdana,sans-serif;font-size:13px;height:30px;line-height:29px;margin-right:2px;padding:0 8px}.fl-col-overlay,.fl-module-overlay,.fl-row-overlay{background:rgba(59,160,255,.15);border:1px solid #3ba0ff;color:#fff}.fl-row-overlay{bottom:0;box-sizing:border-box!important;-moz-box-sizing:border-box!important;-webkit-box-sizing:border-box!important;left:0;position:absolute;top:-30px;width:100%;z-index:100006}.fl-row-overlay-header-bottom{bottom:-30px;top:0}.fl-row-overlay-header-bottom .fl-block-overlay-header{position:absolute;bottom:0}.fl-block-overlay-active .fl-row-content-wrap{position:relative}.fl-block-overlay-active .fl-row-content{position:relative;z-index:100007!important}.fl-col-overlay{bottom:8px;cursor:pointer;left:8px;position:absolute;right:8px;top:8px;z-index:100007}.fl-module-overlay{bottom:4px;cursor:pointer;left:4px;min-height:32px;position:absolute;right:4px;top:4px;z-index:100007}.fl-builder-global-templates-locked .fl-block-overlay-global.fl-module-overlay{cursor:default}.fl-module-adjust-height{padding-bottom:15px;padding-top:15px}.fl-block-overlay-global{background:rgba(255,150,0,.1);border:1px solid #ff9600}.fl-block-overlay-global .fl-block-overlay-actions{background:#ff9600}.fl-block-overlay-global .fl-block-overlay-title{border-right:1px solid #ffcf66}.fl-block-overlay-title-global{background:#fff;border-radius:2px;color:#ff9600!important;font-size:11px;letter-spacing:1px;margin-left:4px;padding:2px 4px;vertical-align:top}.fl-block-overlay-global.fl-row-overlay{background:rgba(255,150,0,.3);cursor:pointer;z-index:100007}.fl-builder-global-templates-locked .fl-block-overlay-global.fl-row-overlay{cursor:default}.fl-builder-row-template .fl-block-overlay-global.fl-row-overlay{background:rgba(255,150,0,.1);cursor:default;z-index:100006}.fl-block-overlay-muted .fl-row-overlay{background:rgba(153,153,153,.1);border:1px solid #8c8c8c}.fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-actions{background:#8c8c8c}.fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-title{border-right:1px solid #a6a6a6}.fl-node-disabled .fl-row-content-wrap{opacity:.3}.fl-block-col-resize{bottom:0!important;position:absolute;top:0!important;width:6px}.fl-block-col-resize-e{cursor:ew-resize;left:auto!important;right:-4px!important}.fl-block-col-resize-w{cursor:ew-resize;left:-4px!important}.fl-block-col-resize-handle-wrap{margin:-4px 0 0 -5px;padding:0 5px;position:absolute;top:50%!important}.fl-block-col-resize-e .fl-block-col-resize-handle-wrap{margin-left:-6px}.fl-block-col-resize-handle{background:#fff;border:1px solid #259aff;height:7px;width:7px}.fl-node-global .fl-block-col-resize-handle{border-color:#ff9600}.fl-block-col-resize-feedback{color:#333!important;display:none;font-family:Helvetica,Verdana,sans-serif!important;font-size:11px!important;position:absolute}.fl-block-col-resize-feedback-left,.fl-block-col-resize-feedback-right{background:#fff;border:1px solid #3ba0ff;padding:2px 4px}.fl-block-col-resize-feedback-left{right:20px;top:-7px}.fl-block-col-resize-feedback-right{left:20px;top:-7px}.fl-builder-has-submenu{position:relative}.fl-builder-has-submenu>ul.fl-builder-submenu{background:#3ba0ff;box-shadow:0 0 20px rgba(0,0,0,.2);display:none;left:0;list-style:none;margin:0;padding:6px 0;position:absolute;text-align:left;top:100%;width:155px;z-index:100008}.fl-builder-has-submenu>ul.fl-builder-submenu li{list-style:none;margin:0;padding:0}.fl-builder-submenu-right ul.fl-builder-submenu{left:auto;right:0}.fl-builder-submenu-open ul.fl-builder-submenu{display:block}.fl-builder-has-submenu>ul.fl-builder-submenu li a{border-bottom:0 none;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#fff!important;display:block;line-height:13px;font-size:13px;font-family:Helvetica,Arial,Verdana,sans-serif;font-weight:400;opacity:.8;filter:alpha(opacity=80);overflow:hidden;padding:6px 12px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.fl-builder-has-submenu>ul.fl-builder-submenu li a:hover{background:#54acff;color:#fff;opacity:1;filter:alpha(opacity=100);text-decoration:none}.fl-builder-actions-title,.fl-builder-alert-lightbox .fl-lightbox-message{color:#333!important;font-size:16px!important;font-family:Helvetica,Verdana,sans-serif!important}.fl-builder-has-submenu .fl-builder-submenu .fa{float:right;height:12px!important;line-height:12px!important;position:relative;right:-5px;width:14px!important}.fl-builder-has-submenu .fl-builder-has-submenu .fl-builder-submenu{display:none;left:100%;top:0}.fl-builder-has-submenu .fl-builder-submenu-right.fl-builder-has-submenu .fl-builder-submenu{left:auto;right:100%}.fl-builder-has-submenu .fl-builder-has-submenu:hover .fl-builder-submenu{display:block}.fl-builder-submenu-sep{padding:7px 0!important}.fl-builder-submenu-sep div{border-bottom:1px solid rgba(255,255,255,.4)}.fl-block-col-move,.fl-block-col-move-parent{cursor:move;position:relative}.fl-builder-submenu .fa-arrows{cursor:move;display:none!important}.fl-builder-submenu a:hover .fa-arrows{display:block!important}.fl-block-overlay-global ul.fl-builder-submenu{background:#ff9600!important}.fl-block-overlay-global ul.fl-builder-submenu li a:hover{background:#fa3}.fl-builder-actions-lightbox .fl-lightbox{width:300px}.fl-builder-actions-lightbox .fl-builder-actions{display:block;padding:25px;text-align:center}.fl-builder-actions-title{display:block;margin-bottom:20px}.fl-builder-actions .fl-builder-button{display:block;margin-bottom:7px}.fl-builder-alert-lightbox{z-index:200001}.fl-builder-alert-lightbox .fl-lightbox{width:440px!important}.fl-builder-alert-lightbox .fl-lightbox-message{line-height:24px;padding:30px}.fl-template-category-select{width:180px!important}.fl-template-selector .fl-builder-settings-section{margin:0 0 10px}.fl-template-selector .fl-builder-settings-fields{height:470px}.fl-template-selector .fl-builder-settings-tab{width:560px}.fl-template-selector .fl-builder-settings-tab-description{font-size:15px!important;margin:0!important;padding:10px 0 25px;text-align:center}.fl-template-preview{float:left;margin:0 25px 30px 0;position:relative;text-align:center;width:170px}.fl-template-preview.fl-last{margin-right:0}.fl-template-image{border:1px solid #d9d9d9;cursor:pointer;margin-bottom:12px;height:164px;overflow:hidden}.fl-builder-templates-cta,.fl-user-templates{margin-bottom:20px}.fl-builder-node-template-settings .fl-builder-settings-fields,.fl-builder-user-template-settings .fl-builder-settings-fields{height:150px}.fl-template-image:hover{border-color:red}.fl-template-image img{max-height:none;width:100%}.fl-template-preview span{display:block;text-align:center}.fl-user-template-category-name{background:#f2f2f2;border-bottom:3px solid #dfdfdf;border-top:2px solid #dfdfdf;font-weight:700;padding:8px 15px}.fl-user-templates{border-top:1px solid #dfdfdf;margin-right:8px}.fl-user-template{border-bottom:1px solid #dfdfdf;padding:15px;position:relative}.fl-user-template:hover{background:#0074a1;color:#fff!important;cursor:pointer}.fl-user-template:hover *{color:#fff!important}.fl-user-template-actions{bottom:0;position:absolute;right:0;top:0}.fl-user-template-actions a{color:#bfbfbf!important;display:inline-block;padding:15px}.fl-user-template:hover a{color:#99c7d9!important}.fl-user-template:hover a:hover{color:#fff!important}.fl-user-templates-message{display:none}.fl-builder-templates-cta p{display:inline-block!important;width:75%!important;font-size:14px!important;line-height:1.5!important;margin-bottom:0!important}.fl-builder-templates-cta .fl-builder-upgrade-button{font-size:13px!important;line-height:13px!important;position:relative;top:8px;left:15px;padding:1px 12px}.fl-builder-settings-message,.fl-builder-settings-message *{font-size:15px!important;line-height:23px!important}.single-fl-builder-template .fl-content{width:100%!important}.fl-builder-lightbox .fl-lightbox{width:600px}form.fl-builder-settings{margin:0;padding:0}.fl-builder-settings-message{padding:20px 25px!important;background:#f2f2f2!important}.fl-builder-preview-loader{position:relative;top:-1px;margin-left:3px}.fl-lightbox-header .fl-builder-preview-loader{margin:0;position:absolute;right:40px;top:15px}.fl-builder-settings-tabs{background:#f5f5f5;border-bottom:1px solid #dfdfdf;padding:15px 20px 0}.fl-builder-settings-tabs a{color:#999!important;display:inline-block;margin:0;outline:0;padding:10px 20px;text-decoration:none!important}.fl-builder-custom-field a,.fl-builder-settings-tab-description a{text-decoration:underline!important}.fl-builder-settings-tabs a:hover{color:#333}.fl-builder-settings-tabs a:focus{outline:0}.fl-builder-settings-tabs a.fl-active{background:#fff;border:1px solid #dfdfdf;border-bottom:none;color:#333!important;position:relative;top:1px}.fl-builder-settings-tabs a.error{color:#d03436;padding-right:10px}.fl-builder-settings-tab-description a:hover,.fl-form-table th label{color:#333}.fl-builder-settings-tabs a.error .fl-error-icon{background:url(../img/sprite.png) -148px -5px no-repeat;display:inline-block;height:16px;margin-left:7px;position:relative;top:3px;width:16px}.fl-builder-settings-tab{display:none;width:550px}.fl-builder-settings-tab.fl-active{display:block}.fl-builder-settings-tab-description{background:#f5f5f5;padding:10px 15px}.fl-form-table{background:none;border:none;width:100%}.fl-form-table tbody{border:none}.fl-form-table td,.fl-form-table th{border:none!important;font-weight:400!important;text-align:left!important}.fl-form-table tr,.fl-form-table tr:nth-child(even){background:0 0}.fl-form-table th{background:#fff!important;padding:10px!important;vertical-align:top!important;width:200px!important}.fl-form-table td{background:#fff!important;padding:8px 10px;width:auto!important}.fl-builder-settings-fields{height:410px;margin:5px 0 0;overflow:hidden;position:relative}.fl-lightbox-header .fl-builder-settings-fields{height:auto;margin:0;position:absolute;right:10px;top:10px}.fl-builder-settings-fields .fl-nanoscroller-content{padding:15px 20px}.fl-builder-settings-fields .fl-field-control-wrapper{position:relative}.fl-builder-settings-fields input[type=email],.fl-builder-settings-fields input[type=file],.fl-builder-settings-fields input[type=number],.fl-builder-settings-fields input[type=password],.fl-builder-settings-fields input[type=search],.fl-builder-settings-fields input[type=tel],.fl-builder-settings-fields input[type=text],.fl-builder-settings-fields input[type=url],.fl-builder-settings-fields select,.fl-builder-settings-fields textarea{background:#fff!important;border-color:#dfdfdf!important;border-style:solid;border-width:1px;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#333!important;display:inline;font-size:12px;height:auto;line-height:15px;margin:1px;outline:0;padding:3px;width:auto}.fl-builder-settings-fields input[type=number]{width:50px}.fl-builder-settings-fields input[type=email]:focus,.fl-builder-settings-fields input[type=file]:focus,.fl-builder-settings-fields input[type=number]:focus,.fl-builder-settings-fields input[type=password]:focus,.fl-builder-settings-fields input[type=search]:focus,.fl-builder-settings-fields input[type=tel]:focus,.fl-builder-settings-fields input[type=text]:focus,.fl-builder-settings-fields input[type=url]:focus,.fl-builder-settings-fields select:focus,.fl-builder-settings-fields textarea:focus{background:0 0;border-color:#dfdfdf}.fl-builder-settings-fields select[multiple]{height:60px}.fl-builder-settings-fields ::-webkit-input-placeholder{color:#999!important;font-size:12px}.fl-builder-settings-fields input:-moz-placeholder{color:#999;font-size:12px}.fl-builder-settings-fields ::-moz-placeholder{color:#999!important;font-size:12px}.fl-builder-settings-fields input:-ms-input-placeholder{color:#999;font-size:12px}.fl-builder-settings-fields label{font-weight:400}.fl-builder-settings-fields select{box-sizing:border-box;height:2em;color:#000;margin:0;padding:2px}.fl-builder-settings-description{padding:0 10px 10px;margin:0;font-style:italic;opacity:.75}.fl-builder-settings-fields table{margin:0}.fl-builder-settings-fields h3.fl-builder-settings-title{border-bottom:1px solid #dfdfdf;color:#333;font-size:14px;font-weight:700;margin:0 0 20px!important;padding:10px}.fl-builder-settings-section{margin-bottom:15px}.fl-builder-settings-section:last-child{margin-bottom:0}.wp-core-ui h1,.wp-core-ui h2,.wp-core-ui h3,.wp-core-ui h4,.wp-core-ui h5,.wp-core-ui h6{color:#333}.wp-core-ui .submitbox .submitdelete{color:#a00}.wp-core-ui button{font-weight:400;text-transform:capitalize}.wp-core-ui input[type=email],.wp-core-ui input[type=file],.wp-core-ui input[type=number],.wp-core-ui input[type=password],.wp-core-ui input[type=search],.wp-core-ui input[type=tel],.wp-core-ui input[type=text],.wp-core-ui input[type=url],.wp-core-ui select,.wp-core-ui textarea{background-color:#fff;border-color:#dfdfdf;border-style:solid;border-width:1px;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#333;font-weight:400}.wp-core-ui input[type=email]:focus,.wp-core-ui input[type=file]:focus,.wp-core-ui input[type=number]:focus,.wp-core-ui input[type=password]:focus,.wp-core-ui input[type=search]:focus,.wp-core-ui input[type=tel]:focus,.wp-core-ui input[type=text]:focus,.wp-core-ui input[type=url]:focus,.wp-core-ui select:focus,.wp-core-ui textarea:focus{background:0 0;border-color:#aaa}.wp-core-ui input[type=search]{background-image:none;padding:6px}.fl-field-responsive-setting{display:inline-block}.fl-field-responsive-setting-medium,.fl-field-responsive-setting-responsive{display:none}i.fl-field-responsive-toggle{color:grey;cursor:pointer;display:inline-block;font-size:15px!important;height:auto;line-height:15px!important;text-align:left;vertical-align:middle;width:20px}i.fl-field-responsive-toggle:hover{color:#000}.fl-builder-settings-fields input.text-full,.fl-builder-settings-fields textarea{width:97%}.fl-color-picker{cursor:pointer}.fl-color-picker .fl-color-picker-clear:hover{background-color:#ededed}.colorpicker input{padding:0!important;font-size:11px!important;color:#fff!important;width:29px!important;height:auto!important;background:0 0!important;border:none!important}.colorpicker .colorpicker_hex input{width:45px!important}.fl-builder-custom-field{border:1px solid #dfdfdf;border-radius:3px;padding:5px 10px}.fl-builder-custom-field a{color:#21759b!important}.fl-builder-custom-field a:hover{color:#d54e21!important}.fl-builder-custom-field label.error{margin-top:5px}.fl-photo-field .fl-photo-select,.fl-photo-field.fl-photo-empty .fl-photo-preview{display:none}.fl-photo-field.fl-photo-empty .fl-photo-select{display:block}.fl-photo-field .fl-photo-preview-img{float:left;line-height:0;margin:5px 0}.fl-photo-field .fl-photo-preview-img img{max-width:60px}.fl-photo-field .fl-photo-preview select{margin:8px 0 8px 10px;width:200px}.fl-photo-field .fl-photo-edit{margin:0 0 0 11px}.fl-multiple-photos-field .fl-multiple-photos-add,.fl-photo-field .fl-photo-remove,.fl-photo-field .fl-photo-replace{margin:0 0 0 8px}.fl-builder-edit .media-frame{-webkit-backface-visibility:hidden}.fl-builder-edit .media-modal-content .thumbnail{padding:0;border:none;border-radius:0}.fl-builder-edit button.button-link.media-modal-close{position:absolute;box-shadow:none;-webkit-box-shadow:none}.fl-builder-edit .media-frame.hide-menu{visibility:visible}.fl-multiple-photos-field .fl-multiple-photos-select,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-add,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-count,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-edit,.fl-multiple-photos-lightbox .gallery-settings{display:none}.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-select{display:inline}.fl-multiple-photos-count{font-weight:700;margin-bottom:3px}.fl-video-field .fl-video-select,.fl-video-field.fl-video-empty .fl-video-preview{display:none}.fl-video-field.fl-video-empty .fl-video-select{display:block}.fl-video-field .fl-video-preview-img{float:left;line-height:0;margin:5px 0}.fl-video-field .fl-video-preview-img img{max-width:60px}.fl-video-field .fl-video-preview-filename{display:inline-block;font-size:14px;font-weight:700;margin:7px 0 0 11px}.fl-video-field .fl-video-replace{margin:0 0 0 11px}.fl-multiple-audios-field .fl-multiple-audios-select,.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-add,.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-edit{display:none}.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-select{display:block}.fl-multiple-audios-field .fl-multiple-audios-add{margin:0 0 0 8px}.fl-icon-field .fl-icon-select,.fl-icon-field.fl-icon-empty .fl-icon-preview{display:none}.fl-icon-field.fl-icon-empty .fl-icon-select{display:block}.fl-icon-field .fl-icon-preview i{display:inline-block;font-size:28px;margin:10px 10px 9px 2px;vertical-align:middle}.fl-icon-field .fl-icon-remove{margin:0 0 0 8px}.fl-builder-settings .wp-switch-editor{background:#ebebeb;border:1px solid #e5e5e5;border-radius:0;color:#333}.fl-builder-settings .wp-editor-container{border:1px solid #e5e5e5}.fl-builder-settings .mce-toolbar .mce-btn-group .mce-btn{margin:2px 0}.fl-builder-settings .mce-menubtn.mce-fixed-width button{width:100px}.mce-close:active,.mce-close:hover,.mce-toolbar .mce-btn button:active,.mce-toolbar .mce-btn button:hover,.mce-window .mce-btn button:active,.mce-window .mce-btn button:hover{background:0 0;border:none}.mce-ico{font-family:tinymce,Arial!important}.mce-toolbar i.mce-ico{font:400 20px/1 dashicons!important}.wp-core-ui .quicktags-toolbar input.button.button-small{margin:1px!important}.wp-editor-container textarea.wp-editor-area{background:0 0;border:none;padding:10px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.fl-builder-edit form#wp-link{color:#000;font-family:Helvetica,Arial,Verdana,sans-serif;font-size:13px}.fl-builder-edit form#wp-link #link-options label{display:block;margin-bottom:2px}.fl-builder-edit form#wp-link #link-options label span{padding-right:10px;vertical-align:middle}.fl-builder-edit form#wp-link #link-options input[type=text]{display:inline-block;height:auto;margin:5px 0 0;padding:3px 5px;width:80%}.fl-builder-edit form#wp-link .query-results{top:225px}.fl-code-field{border:1px solid #E6E6E6;border-left:none}.ace_editor,.ace_editor *{font-family:Monaco,Menlo,"Ubuntu Mono","Droid Sans Mono",Consolas,monospace!important;font-size:12px!important;font-weight:400!important;letter-spacing:0!important}.fl-layout-field-option{border:2px solid #d9d9d9;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-sizing:border-box!important;-moz-box-sizing:border-box!important;-webkit-box-sizing:border-box!important;cursor:pointer;float:left;line-height:0;max-width:23%;margin:0 1% 2%;padding:5px}.fl-layout-field-option-selected,.fl-layout-field-option:hover{border-color:red}.fl-layout-field-option img{max-width:100%}.fl-link-field-input{width:244px!important}.fl-link-field-search{display:none;border:1px solid #dfdfdf;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;margin:4px 0 0;padding:10px}.fl-link-field-search-title{display:block;margin:0 0 3px 2px}.fl-link-field-search-cancel{margin-top:6px}.fl-help-tooltip{display:inline-block;position:relative}.fl-help-tooltip-icon{color:#999!important;cursor:pointer;font-family:FontAwesome;font-size:15px!important;padding:5px;vertical-align:middle}.popover[class*=tour-],ul.as-list{font-family:Helvetica,Arial,Verdana,sans-serif}.fl-help-tooltip-text{background:#fff;border:1px solid #ccc;box-shadow:0 0 5px #ccc;-moz-box-shadow:0 0 5px #ccc;-webkit-box-shadow:0 0 5px #ccc;display:none;font-weight:400;left:23px;padding:10px 13px;position:absolute;top:-6px;width:250px;z-index:1000}.fl-field-control .fl-form-field{margin-bottom:0}.fl-form-field-preview-text .fa{font-size:18px;line-height:22px}.fl-builder-field-actions{padding-left:0!important;padding-right:0!important;text-align:center;width:85px}.fl-builder-field-actions i{color:#999!important;cursor:pointer;font-size:13px!important;line-height:29px!important;width:24px}.fl-builder-field-actions i:hover{color:#000!important}.fl-builder-field-actions i.fl-builder-field-copy,.fl-builder-field-actions i.fl-builder-field-delete{margin-left:5px}.fl-builder-field-actions i.fl-builder-field-move{cursor:move}.fl-builder-field-dd-helper{background:#ccc;height:30px!important;float:left;width:130px!important}.fl-builder-field-dd-zone{border:1px dashed #ccc;height:30px}.fl-builder-field-actions-single{width:auto}.fl-builder-field-actions-single i.fl-builder-field-delete,.fl-builder-field-actions-single i.fl-builder-field-move{display:none}.fl-builder-widget-settings input{display:inline-block!important;margin:5px 10px 8px!important}.fl-builder-lightbox-loading{background:url(../img/ajax-loader.svg) center center no-repeat;height:100px}.fl-builder-settings .error,.fl-builder-settings input.error{border-color:#d03436}.fl-builder-settings label.error,.fl-builder-settings p.error{color:#d03436;display:block;margin-top:5px}.fl-builder-settings .fl-form-table .fl-field-description{color:#999;font-style:normal}ul.as-selections{background-color:#fff;border-color:#dfdfdf;border-style:solid;border-width:1px;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#333;font-size:12px;height:auto;line-height:15px;margin:1px;outline:0;padding:3px;width:auto}ul.as-selections.loading{background:url(../img/ajax-loader-small.svg) 98% center no-repeat}ul.as-selections li.as-selection-item{background:#d4eaf6;border:none;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0;font-size:11px;line-height:14px;margin-bottom:4px;padding-bottom:0;padding-top:0}ul.as-selections li.as-selection-item.blur{background:#f4f4f4}ul.as-selections li.as-selection-item a.as-close{line-height:12px}ul.as-selections li.as-original{margin:0}ul.as-selections li.as-original input{height:auto;font-size:12px;margin:0;padding:0}ul.as-list{margin:0;font-size:13px;color:#000;background-color:#fff;background-color:rgba(255,255,255,.95);z-index:2;-webkit-box-shadow:0 0 10px rgba(0,0,0,.1);-moz-box-shadow:0 0 10px rgba(0,0,0,.1);box-shadow:0 0 10px rgba(0,0,0,.1);-ms-border-radius:0;-o-border-radius:0;border:none;border:1px solid #dfdfdf;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px}li.as-message,li.as-result-item{border:none}li.as-result-item.active{background:#e5e5e5;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0;color:#333;text-shadow:none}li.as-result-item em{background:0 0!important;color:#333!important;font-size:12px;padding:0!important}.fl-custom-query-filter{display:none}.fl-custom-query .fl-field[data-type=suggest] select{margin-bottom:5px;width:100%}.fl-builder-service-settings{position:relative}.fl-builder-service-error{color:red!important;padding:15px 0 0}.fl-builder-service-account-delete{color:red!important;margin-left:10px;position:relative;top:2px}#fl-field-visibility_user_capability .fl-field-description,.fl-builder-service-connect-row .fl-field-description{background:#f0f0f0;color:#333!important;display:block;float:none;margin:10px 0 0;padding:10px}#fl-field-visibility_user_capability .fl-field-description a,.fl-builder-service-connect-row .fl-field-description a{color:#21759b!important;text-decoration:underline!important}.fl-ordering-field-option{background:#fff;border:1px solid #dfdfdf;border-radius:3px;cursor:move;margin-bottom:5px;padding:5px 10px}.fl-ordering-field-option .fa{color:#ccc;float:right;line-height:16px}#tiptip_holder{z-index:200000}#tiptip_arrow_inner{border-top-color:#333!important}#tiptip_content{background:#333;box-shadow:none}.fl-builder-getting-started-video{line-height:0!important;padding:10px}.fl-builder-getting-started-video iframe{border:none;height:326px;width:100%}.fl-builder-tour-actions .fl-builder-actions-title{font-size:14px!important;line-height:19px}.fl-builder-tour-mask{bottom:0;left:0;position:fixed;right:0;top:0;z-index:100000000}.fl-builder-tour-dimmed{background:rgba(0,0,0,.7);bottom:0;left:0;position:absolute;right:0;top:0}body>.fl-builder-tour-dimmed{position:fixed}.tour-backdrop{z-index:110000}.popover[class*=tour-]{border:1px solid #ccc;border-radius:0;-webkit-box-shadow:0 0 30px rgba(0,0,0,.3);box-shadow:0 0 40px rgba(0,0,0,.3);color:#666;font-size:13px;font-weight:400;line-height:18px;max-width:none;padding:0;width:300px;z-index:100000001}.popover[class*=tour-].bottom>.arrow{border-bottom-color:#ccc}.popover[class*=tour-].bottom>.arrow:after{border-bottom-color:#f7f7f7}.popover[class*=tour-] .popover-title{border-radius:0;color:#333;letter-spacing:normal;text-transform:none}.popover[class*=tour-] .fa-times{color:#b3b3b3;cursor:pointer;font-size:16px;padding:5px;position:absolute;right:3px;top:2px}.popover[class*=tour-] .fa-times:hover{color:#666}.popover[class*=tour-] .popover-content{border-bottom:1px solid #d9d9d9;padding:13px 15px}.popover[class*=tour-] .fl-builder-tour-next{display:block;float:none;width:100%}.fl-builder-shortcode-mask-wrap{position:relative}.fl-builder-shortcode-mask{bottom:-1px;left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fl-builder-module-placeholder-message{border:1px dashed #ccc;overflow:hidden;padding:20px;text-align:center;text-overflow:ellipsis;white-space:nowrap}.fl-color-picker-ui{width:200px}.fl-color-picker-ui.fl-color-alpha-enabled{width:238px}.fl-color-picker-ui .iris-picker{float:left;width:240px;height:224px;display:block;position:relative;border-top:1px solid rgba(0,0,0,.1)}.fl-color-picker-ui .iris-picker .iris-square-inner,.fl-color-picker-ui .iris-picker-inner{position:absolute;left:0;top:0;bottom:0;right:0}.fl-color-picker-ui .iris-picker,.iris-picker *{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}.fl-color-picker-ui .iris-error{background-color:#ffafaf}.fl-color-picker-ui .iris-picker .iris-square{width:200px;height:200px}.fl-color-picker-ui .iris-picker .iris-palette,.fl-color-picker-ui .iris-picker .iris-slider,.fl-color-picker-ui .iris-picker .iris-square-inner{box-shadow:0 0 3px rgba(0,0,0,.1) inset;height:100%;width:12.5%}.fl-color-picker-ui .iris-picker .iris-placeholder,.fl-color-picker-ui .iris-picker .iris-square{position:relative}.fl-color-picker-ui .iris-picker .iris-square-inner{width:auto;margin:0}.fl-color-picker-ui .iris-ie-9 .iris-palette,.fl-color-picker-ui .iris-ie-9 .iris-slider,.fl-color-picker-ui .iris-ie-9 .iris-square,.fl-color-picker-ui .iris-ie-9 .iris-square-inner{box-shadow:none;border-radius:0}.fl-color-picker-ui .iris-ie-9 .iris-palette,.fl-color-picker-ui .iris-ie-9 .iris-slider,.fl-color-picker-ui .iris-ie-9 .iris-square{outline:rgba(0,0,0,.1) solid 1px}.fl-color-picker-ui .iris-ie-lt9 .iris-palette,.fl-color-picker-ui .iris-ie-lt9 .iris-slider,.fl-color-picker-ui .iris-ie-lt9 .iris-square,.fl-color-picker-ui .iris-ie-lt9 .iris-square-inner{outline:#999 solid 1px}.fl-color-picker-ui .iris-ie-lt9 .iris-square .ui-slider-handle{outline:#999 solid 1px;background-color:#fff;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"}.fl-color-picker-ui .iris-ie-lt9 .iris-square .iris-square-handle{background:0 0;border:3px solid #fff;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"}.fl-color-picker-ui .iris-picker .iris-strip{width:200px;margin-top:5px;position:relative;height:22px;-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fl-color-picker-ui .iris-picker .iris-strip .ui-slider-handle{width:6px;position:absolute;right:0;top:-2px;bottom:-2px;margin:0;border-radius:3px;background:#fff;box-shadow:0 0 2px rgba(0,0,0,.5);z-index:5;cursor:ew-resize}.fl-color-picker-ui .iris-picker .iris-slider-offset{position:absolute;top:0;left:6px;right:0;bottom:0;width:auto;height:auto;background:0 0;border:none;border-radius:0;-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fl-color-picker-ui .iris-picker .iris-square-handle{background:0 0;border:5px solid #999;border-radius:50%;border-color:rgba(128,128,128,.5);box-shadow:none;width:12px;height:12px;position:absolute;left:-10px;top:-10px;cursor:move;opacity:1;z-index:10}.fl-color-picker-ui .iris-picker .ui-state-focus .iris-square-handle{opacity:.8}.fl-color-picker-ui .iris-picker .iris-square-handle:hover{border-color:#999}.fl-color-picker-ui .iris-picker .iris-square-value:focus .iris-square-handle{box-shadow:0 0 2px rgba(0,0,0,.75);opacity:.8}.fl-color-picker-ui .iris-picker .iris-square-handle:hover::after{border-color:#fff}.fl-color-picker-ui .iris-picker .iris-square-handle::after{position:absolute;bottom:-4px;right:-4px;left:-4px;top:-4px;border:3px solid #f9f9f9;border-color:rgba(255,255,255,.8);border-radius:50%;content:" "}.fl-color-picker-clear,.fl-color-picker-color{float:left;border:1px solid rgba(0,0,0,.1);cursor:pointer}.fl-color-picker-ui .iris-picker .iris-square-value{width:8px;height:8px;position:absolute}.iris-ie-lt9 .iris-square-value,.iris-mozilla .iris-square-value{width:1px;height:1px}.fl-color-picker-wrapper{position:relative;width:48px;height:32px}.fl-color-picker-color{position:relative;width:30px;height:30px;background-color:transparent}.fl-color-picker-color.fl-color-picker-empty{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABG2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS4xLjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+MahxaQAAAAlwSFlzAAALEwAACxMBAJqcGAAACk9pQ0NQUGhvdG9zaG9wIElDQyBwcm9maWxlAAB42p1TZ1RT6RY99970QkuIgJRLb1IVCCBSQouAFJEmKiEJEEqIIaHZFVHBEUVFBBvIoIgDjo6AjBVRLAyKCtgH5CGijoOjiIrK++F7o2vWvPfmzf611z7nrPOds88HwAgMlkgzUTWADKlCHhHgg8fExuHkLkCBCiRwABAIs2Qhc/0jAQD4fjw8KyLAB74AAXjTCwgAwE2bwDAch/8P6kKZXAGAhAHAdJE4SwiAFABAeo5CpgBARgGAnZgmUwCgBABgy2Ni4wBQLQBgJ3/m0wCAnfiZewEAW5QhFQGgkQAgE2WIRABoOwCsz1aKRQBYMAAUZkvEOQDYLQAwSVdmSACwtwDAzhALsgAIDAAwUYiFKQAEewBgyCMjeACEmQAURvJXPPErrhDnKgAAeJmyPLkkOUWBWwgtcQdXVy4eKM5JFysUNmECYZpALsJ5mRkygTQP4PPMAACgkRUR4IPz/XjODq7OzjaOtg5fLeq/Bv8iYmLj/uXPq3BAAADhdH7R/iwvsxqAOwaAbf6iJe4EaF4LoHX3i2ayD0C1AKDp2lfzcPh+PDxFoZC52dnl5OTYSsRCW2HKV33+Z8JfwFf9bPl+PPz39eC+4iSBMl2BRwT44MLM9EylHM+SCYRi3OaPR/y3C//8HdMixEliuVgqFONREnGORJqM8zKlIolCkinFJdL/ZOLfLPsDPt81ALBqPgF7kS2oXWMD9ksnEFh0wOL3AADyu2/B1CgIA4Bog+HPd//vP/1HoCUAgGZJknEAAF5EJC5UyrM/xwgAAESggSqwQRv0wRgswAYcwQXcwQv8YDaEQiTEwkIQQgpkgBxyYCmsgkIohs2wHSpgL9RAHTTAUWiGk3AOLsJVuA49cA/6YQiewSi8gQkEQcgIE2Eh2ogBYopYI44IF5mF+CHBSAQSiyQgyYgUUSJLkTVIMVKKVCBVSB3yPXICOYdcRrqRO8gAMoL8hrxHMZSBslE91Ay1Q7moNxqERqIL0GR0MZqPFqCb0HK0Gj2MNqHn0KtoD9qPPkPHMMDoGAczxGwwLsbDQrE4LAmTY8uxIqwMq8YasFasA7uJ9WPPsXcEEoFFwAk2BHdCIGEeQUhYTFhO2EioIBwkNBHaCTcJA4RRwicik6hLtCa6EfnEGGIyMYdYSCwj1hKPEy8Qe4hDxDckEolDMie5kAJJsaRU0hLSRtJuUiPpLKmbNEgaI5PJ2mRrsgc5lCwgK8iF5J3kw+Qz5BvkIfJbCp1iQHGk+FPiKFLKakoZ5RDlNOUGZZgyQVWjmlLdqKFUETWPWkKtobZSr1GHqBM0dZo5zYMWSUulraKV0xpoF2j3aa/odLoR3ZUeTpfQV9LL6Ufol+gD9HcMDYYVg8eIZygZmxgHGGcZdxivmEymGdOLGcdUMDcx65jnmQ+Zb1VYKrYqfBWRygqVSpUmlRsqL1Spqqaq3qoLVfNVy1SPqV5Tfa5GVTNT46kJ1JarVaqdUOtTG1NnqTuoh6pnqG9UP6R+Wf2JBlnDTMNPQ6RRoLFf47zGIAtjGbN4LCFrDauGdYE1xCaxzdl8diq7mP0du4s9qqmhOUMzSjNXs1LzlGY/B+OYcficdE4J5yinl/N+it4U7yniKRumNEy5MWVca6qWl5ZYq0irUatH6702ru2nnaa9RbtZ+4EOQcdKJ1wnR2ePzgWd51PZU92nCqcWTT069a4uqmulG6G7RHe/bqfumJ6+XoCeTG+n3nm95/ocfS/9VP1t+qf1RwxYBrMMJAbbDM4YPMU1cW88HS/H2/FRQ13DQEOlYZVhl+GEkbnRPKPVRo1GD4xpxlzjJONtxm3GoyYGJiEmS03qTe6aUk25pimmO0w7TMfNzM2izdaZNZs9Mdcy55vnm9eb37dgWnhaLLaotrhlSbLkWqZZ7ra8boVaOVmlWFVaXbNGrZ2tJda7rbunEae5TpNOq57WZ8Ow8bbJtqm3GbDl2AbbrrZttn1hZ2IXZ7fFrsPuk72Tfbp9jf09Bw2H2Q6rHVodfnO0chQ6Vjrems6c7j99xfSW6S9nWM8Qz9gz47YTyynEaZ1Tm9NHZxdnuXOD84iLiUuCyy6XPi6bG8bdyL3kSnT1cV3hetL1nZuzm8LtqNuv7jbuae6H3J/MNJ8pnlkzc9DDyEPgUeXRPwuflTBr36x+T0NPgWe15yMvYy+RV63XsLeld6r3Ye8XPvY+cp/jPuM8N94y3llfzDfAt8i3y0/Db55fhd9DfyP/ZP96/9EAp4AlAWcDiYFBgVsC+/h6fCG/jj8622X2stntQYyguUEVQY+CrYLlwa0haMjskK0h9+eYzpHOaQ6FUH7o1tAHYeZhi8N+DCeFh4VXhj+OcIhYGtExlzV30dxDc99E+kSWRN6bZzFPOa8tSjUqPqouajzaN7o0uj/GLmZZzNVYnVhJbEscOS4qrjZubL7f/O3zh+Kd4gvjexeYL8hdcHmhzsL0hacWqS4SLDqWQEyITjiU8EEQKqgWjCXyE3cljgp5wh3CZyIv0TbRiNhDXCoeTvJIKk16kuyRvDV5JMUzpSzluYQnqZC8TA1M3Zs6nhaadiBtMj06vTGDkpGQcUKqIU2TtmfqZ+ZmdsusZYWy/sVui7cvHpUHyWuzkKwFWS0KtkKm6FRaKNcqB7JnZVdmv82JyjmWq54rze3Ms8rbkDec75//7RLCEuGStqWGS1ctHVjmvaxqObI8cXnbCuMVBSuGVgasPLiKtipt1U+r7VeXrn69JnpNa4FewcqCwbUBa+sLVQrlhX3r3NftXU9YL1nftWH6hp0bPhWJiq4U2xeXFX/YKNx45RuHb8q/mdyUtKmrxLlkz2bSZunm3i2eWw6Wqpfmlw5uDdnatA3fVrTt9fZF2y+XzSjbu4O2Q7mjvzy4vGWnyc7NOz9UpFT0VPpUNu7S3bVh1/hu0e4be7z2NOzV21u89/0+yb7bVQFVTdVm1WX7Sfuz9z+uiarp+Jb7bV2tTm1x7ccD0gP9ByMOtte51NUd0j1UUo/WK+tHDscfvv6d73ctDTYNVY2cxuIjcER55On3Cd/3Hg062naMe6zhB9Mfdh1nHS9qQprymkabU5r7W2Jbuk/MPtHW6t56/EfbHw+cNDxZeUrzVMlp2umC05Nn8s+MnZWdfX4u+dxg26K2e+djzt9qD2/vuhB04dJF/4vnO7w7zlzyuHTystvlE1e4V5qvOl9t6nTqPP6T00/Hu5y7mq65XGu57nq9tXtm9+kbnjfO3fS9efEW/9bVnjk93b3zem/3xff13xbdfnIn/c7Lu9l3J+6tvE+8X/RA7UHZQ92H1T9b/tzY79x/asB3oPPR3Ef3BoWDz/6R9Y8PQwWPmY/Lhg2G6544Pjk54j9y/en8p0PPZM8mnhf+ov7LrhcWL3741evXztGY0aGX8peTv218pf3qwOsZr9vGwsYevsl4MzFe9Fb77cF33Hcd76PfD0/kfCB/KP9o+bH1U9Cn+5MZk5P/BAOY8/xjMy3bAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAGbSURBVHjajNO/S1VxGMfx9+ebQ6FiImkOgatTDYlKXgfPgVAbHRpt6U/oH6jmHAPH2gOX2vx1URCaWoKGhhQ1hKsJLnqeT8sxTveeSz3bFx5ez/f58vkqyzL+pyQhiYhYsL0i6bIoiuf6B/AIENCUBPAUWAX6AGx/6wpIyoEPJTBhewxYk9Rz3RMRXYEeSevATHneB/qBgcqAi4hY6gAkYVvApKS3wP2aAYWk5Yh4rzzPKff7U7axfQP4LKkdOJb0zPZH23QAtpE0FBGbwLmkV7ZfV6AD29PAD6AWGLa9JSlJemj7l6THtj9VbnFuexHYbgcGbe+UjzgLHNq+DawBt4BeYBy4sj33FxARA8BeOblh+0jSsO0mcAk8sD0u6Q3w0vZGdYWhiGgCKaXUAH7aHikDFMAU0IqIzrzkeX6nsvOU7Zak0YjYklRImgZaZXBqgW3gXtl4aHsQ2AWSpAZwXEleJ5Bl2feU0rztr5WdQ9IMcFJt7naDL5JeAKcR8S6ldAVM2j5rD1g3YB24C9wEDiQ9AU7rPkgd8HsAv5vXzUui544AAAAASUVORK5CYII=) center center no-repeat}.fl-color-picker-clear{position:relative;display:block;width:17px;height:30px;border-left:none;background-color:#FAFAFA}.fl-color-picker-color.fl-color-picker-empty+.fl-color-picker-clear{display:none}.fl-color-picker-ui{display:inline-block;font-family:Helvetica,Verdana,sans-serif;z-index:999999;position:fixed;overflow:hidden;padding-bottom:45px;border:1px solid rgba(0,0,0,.1);color:#999;background-color:#FAFAFA;border-radius:3px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.1);box-shadow:0 1px 3px rgba(0,0,0,.1);-webkit-transition:opacity .2s,visibility .2s;-moz-transition:opacity .2s,visibility .2s;-ms-transition:opacity .2s,visibility .2s;-o-transition:opacity .2s,visibility .2s;transition:opacity .2s,visibility .2s;visibility:hidden;opacity:0;-webkit-transform:translate3d(0,0,0)}.fl-color-picker-ui.fl-color-picker-active{visibility:visible;opacity:1}.fl-color-picker-ui .fl-color-picker-input,.fl-color-picker-ui .fl-color-picker-input:focus{width:100%;height:30px;border:none!important;font-size:14px!important;padding:0 8px;vertical-align:middle;color:#999;background-color:#fff;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.fl-color-picker-ui .iris-square-value{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.fl-color-picker-preset-add{position:absolute;top:8px;right:8px;width:14px;height:14px;background-color:#999;border-radius:50%;cursor:pointer;-webkit-transition:all .2s;-moz-transition:all .2s;-ms-transition:all .2s;-o-transition:all .2s;transition:all .2s}.fl-color-picker-preset-add:hover{background-color:#333}.fl-color-picker-preset-add:after,.fl-color-picker-preset-add:before{content:'';display:block;position:relative;background-color:#fff}.fl-color-picker-preset-add:before{top:6px;left:3px;width:8px;height:2px}.fl-color-picker-preset-add:after{left:6px;top:1px;width:2px;height:8px}.fl-color-picker-presets{position:absolute;left:0;bottom:0;width:100%;z-index:15;overflow:auto;border-top:1px solid rgba(0,0,0,.1);background-color:#FAFAFA}.fl-color-picker-presets-list .fl-color-picker-preset:hover,.fl-color-picker-presets-toggle:hover{background-color:#EDEDED}.fl-color-picker-presets-toggle{position:relative;overflow:hidden;width:100%;height:35px;text-align:center;line-height:35px;font-size:12px;font-weight:700;cursor:pointer;-webkit-transition:all .1s;-moz-transition:all .1s;-ms-transition:all .1s;-o-transition:all .1s;transition:all .1s}.fl-color-picker-presets-close-label,.fl-color-picker-presets-open-label{position:absolute;top:50%;left:50%;visibility:hidden;color:#999;-webkit-transition:all .5s;-moz-transition:all .5s;-ms-transition:all .5s;-o-transition:all .5s;transition:all .5s;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;width:100%}.fl-color-picker-presets-close-label.fl-color-picker-active,.fl-color-picker-presets-open-label.fl-color-picker-active{color:#999;visibility:visible;opacity:1}.fl-color-picker-presets-list{width:100%;list-style:none;margin:0;padding:0;overflow:auto}.fl-color-picker-presets-list .fl-color-picker-no-preset,.fl-color-picker-presets-list .fl-color-picker-preset{position:relative;padding:5px;font-size:12px;border-top:1px solid rgba(0,0,0,.1);-webkit-transition:all .1s;-moz-transition:all .1s;-ms-transition:all .1s;-o-transition:all .1s;transition:all .1s}.fl-color-picker-presets-list .fl-color-picker-preset-color{display:inline-block;width:20px;height:20px;margin-right:3px;vertical-align:middle;border:1px solid rgba(0,0,0,.1);border-radius:2px;cursor:pointer}.fl-color-picker-presets-list .fl-color-picker-preset-label{vertical-align:middle;color:#999}.fl-color-picker-clear .fl-color-picker-icon-remove,.fl-color-picker-presets-list .fl-color-picker-preset-remove{position:absolute;top:50%;cursor:pointer;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%)}.fl-color-picker-clear .fl-color-picker-icon-remove{right:0}.fl-color-picker-presets-list .fl-color-picker-preset-remove{right:5px}.fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:after,.fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:before{background-color:#333}.fl-color-picker-added{position:absolute;width:100%;top:0;left:0;right:0;bottom:35px;z-index:10;color:#fff;text-align:center;background-color:rgba(0,0,0,.6)}.fl-color-picker-added-text{position:absolute;top:50%;left:50%;width:80%;font-size:14px;color:#fff!important;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.fl-color-picker-icon-check{position:relative;width:50px;height:50px;margin:5px auto}.fl-color-picker-icon-check:before{content:'';display:block;position:relative;width:15px;height:30px;margin-left:14px;border:7px solid #fff;border-left:none;border-top:none;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.fl-color-picker-icon-arrow-down,.fl-color-picker-icon-arrow-up{display:inline-block;position:relative;width:10px;height:10px;margin-left:5px}.fl-color-picker-icon-arrow-down:before,.fl-color-picker-icon-arrow-up:before{content:'';display:block;position:relative;width:6px;height:6px;border:2px solid #999;border-left:none;border-top:none;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.fl-color-picker-icon-arrow-up{top:2px;-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fl-color-picker-icon-remove{width:15px;height:15px}.fl-color-picker-icon-remove:after,.fl-color-picker-icon-remove:before{content:'';display:block;position:relative;background-color:#999}.fl-color-picker-icon-remove:before{left:6px;width:2px;height:10px;margin-top:3px;background:#999;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg)}.fl-color-picker-icon-remove:after{left:6px;width:2px;height:10px;margin-top:-10px;background:#999;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.fl-alpha-wrap{position:absolute;width:35px;height:215px;padding:0 5px;right:4px;border-top:none}.fl-alpha-slider{height:190px;position:absolute;top:12px;width:28px}.fl-alpha-slider .ui-slider-handle{background:rgba(0,0,0,0);border-color:#aaa;border-radius:4px;border-style:solid;border-width:4px;box-shadow:0 1px 2px rgba(0,0,0,.2);-moz-box-shadow:0 1px 2px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.2);cursor:ns-resize;height:12px;left:0;opacity:.9;position:absolute;right:0;width:30px;z-index:14}.fl-alpha-slider .ui-slider-handle:before{content:" ";position:absolute;left:-2px;right:-2px;top:-3px;bottom:-3px;border:2px solid #fff;border-radius:3px}.fl-alpha-slider-offset{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAASCAYAAAAe/ZHXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NkNEQUQ0ODM4RUE0MTFFNEExOEJFN0E5M0VFOTg0QUQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NkNEQUQ0ODQ4RUE0MTFFNEExOEJFN0E5M0VFOTg0QUQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2Q0RBRDQ4MThFQTQxMUU0QTE4QkU3QTkzRUU5ODRBRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2Q0RBRDQ4MjhFQTQxMUU0QTE4QkU3QTkzRUU5ODRBRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/r/N8AAAWYSURBVHjarFvvR3VBEN45JZGIPkREHyIiIhJJf3qUSERE9CGiDxERkcg9z9u92uucvTszz5z7xnHPj93Z2d359cxscn5+jpTS+EoiMr3/+51cZ2dn4+e29i2/u7y8RKf/pO3vc+o+n5ycoNK31+f6+jrfZ37yuG2mf3R01H3fa5N/b29vU6dP5qft0G4PDg5MGuPr/v4+jz1t27mfvN/b21P75+fHx8eZfiV/Ozs7rUJnSu/5+RlFv+m6ZJpbW1s1PnrvXl9fZ/qX89zY2LB4mfy+v7/nsdV1XltbK/dr5vnz87OcV5bJabuVlRVLBifjfX9/l/xkGtM+S0tLNXnu0szfU/P3IMn/k0678h6ddqjQFGccVL6hoCsVfsq+NZ5QtCv5rfFS41sq37W+UPhMyhxEWTetvce3NR8oewqD39qalXuGAK/WPltjajIC4x2c9Ye1f43SGcqGwRBeTZjhMNntL4pCWZMQYhE05RVl02EovRgC4RkCbUNSQAGhGB/GsKG4h6FQoigDa2i8fRBy3uLMXYIG3Vr3aZvRaCRdBYlYIMZywhBGCVhgzzOlgRuUSOvC0GMEWxOM/+EtQFh1OIIXtfwg1tRaayGjg5px0jyZKEaTle3e+AsLCygVRAh3FlEgKbReE3oYGj9EgIR00QiEgKw3ZBQbRGjBeAMtDETQmHiKDsezJNLgCTFGItZXlAgCSiQggblP+9c8SDI0lXWlFv5g3K63KZ51FOcZzthQ3LomoNHwJmKIQISI3vqzSpwIQ8liSjGMFQjDpoVgaQ6cWgvLhOC7qiAwiHrWbEg4JMSmeUrBuHoYwioOQNXmhmAcrs096s1gJCGi3hSEVU8DQxYElYHhKwUUGAa+NqOBMsSSAQJuhQhCAH4vxozExsxiihPuaIrjCVYKWlYEsjSM52G8Kxxryngl5j0j+EyGTIiED4s1Itm0ZGWxMFCLJaBAcEI6OBkmFgNBoc8Cait2ZnENE/6wQN8LJSJeSMNAjKVm+LUMAIt3PR5AQgIGp1Z5zxhE8PtXUYReYeXi4mKmOPNXBMzt2tPT07LIUtJqr66uusXEbkFnWiQ6Pj72ikrtzc1NKopuvbbj58PDwxqNHp27u7tuYWumUDV+v7+/Xyu6pc59+/DwUCsC9ujt7u6qRbt8//T01C3elbyN70fb29uZ/1FSincvLy/lPGb42tzc9IqJeHt7q61Pr2C6vr7u7tfHx8fMPhV0sLq6WhZtU0n36+uru8elPE7aLi8v1wqJPXn++fmZKYgX8ozFxcXJb0NaQTHClZT8+gBjsYdaFc+zWcUkGTCWENY66ta92oSVzo3WI6IZKGtukeyfBLFKBNAj6bUOBgaoe9wE4n04IBNkLMoC7+Skj630ZlTJMYdyMsU2T8AwpzALkVFilZgJcT2l9PCWDDSAMBSjVlJgZNk0lE1AIby0qCiCnBQNj6aBGQslZIZJ5hB6D/AzQHto5Z9Nk8tARdN4q2ExBnsyIJ311EymShyjan2rKk0zh1Ay1oQVWAZQRnkUA8RFw7TahjBnmNgMVMQrsCGZJezRtGlU0cUZ1zuaxGZPpbhApM+ZpFQqQ6xadoMtBrEKpBVo4GRXvNSxpaRixKiR+TChCYhsDwZkfFj8IkErjAHejcUI0XQrgwehhNSMHAz21E0wZ23FcCAmj8Sd/PXy2xLYLAuwRw4IMsqjFaWYOpMEhDySAPFCWyFkgAHrEcA+BNeJ4UE8HCzJPpCrerUmQIx1pWJkjqxJD8EikUo2c5aI8ZYgsAkM4WQtnHd0ns0ORgVTBghy5ISy928SGsbTMqYg523RUY8oNYG4FIYiyRyZCnFCJC87IoRAIMVOqQ7BKexxCS2hYVl9JhvlpYjnAe4MhmRPMWhhvLfXINaI9WKM0Zu0+SfAAFLE1EgfVSv7AAAAAElFTkSuQmCC) center;box-shadow:0 0 5px rgba(0,0,0,.4) inset;-moz-box-shadow:0 0 5px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 5px rgba(0,0,0,.4) inset;width:200px;height:22px;-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg);bottom:48%;left:-80px;position:absolute}.fl-alpha-text{width:30px;font-size:12px;text-align:center;color:#999;position:absolute;bottom:-5px}.fl-icons-filter input,.fl-icons-filter select{vertical-align:middle;width:160px}.fl-icon-selector .fl-lightbox{height:100%}.fl-icons-filter{height:auto!important;margin:0!important;position:absolute!important;right:10px;top:10px}.fl-icons-filter input{line-height:18px}.fl-icons-list{bottom:52px;left:0;overflow:auto;padding:20px;position:absolute;right:0;top:48px}.fl-icons-list::-webkit-scrollbar{background-color:#ccc;-webkit-appearance:none;width:10px}.fl-icons-list::-webkit-scrollbar-thumb{background-color:#666;border:1px solid #ccc}.fl-icons-section{text-align:center}.fl-icons-section h2{border-bottom:1px solid #dfdfdf;color:#333!important;font-family:Helvetica,Verdana,sans-serif!important;font-size:16px!important;font-weight:700!important;margin:0 0 20px!important;padding:0 0 10px!important;text-align:left}.fl-icons-list i,.fl-icons-list i:before{cursor:pointer;display:inline-block;font-size:32px;height:80px;line-height:80px;width:80px}.fl-icons-list i:hover{background:#e5e5e5}.fl-icon-selector-footer{bottom:0;left:0;position:absolute;right:0}.fl-lightbox-mask,.fl-lightbox-wrap{bottom:0;left:0;position:fixed;right:0;top:0}.fl-lightbox-wrap{display:none;overflow:auto;padding:30px;z-index:100010;-webkit-backface-visibility:hidden;-webkit-transform:translateZ(0)}.fl-lightbox-wrap.fl-icon-selector{z-index:100011}.fl-lightbox-mask{background:#000;opacity:.7;filter:alpha(opacity=70);z-index:100010}.fl-lightbox{background:#fff;box-shadow:rgba(0,0,0,1) 0 4px 30px;-moz-box-shadow:rgba(0,0,0,1) 0 4px 30px;-webkit-box-shadow:rgba(0,0,0,1) 0 4px 30px;position:relative;z-index:100011}.fl-lightbox :not(i){color:#333;font-family:Helvetica,Verdana,sans-serif;font-size:12px;line-height:16px;text-decoration:none;text-transform:none}.fl-lightbox *,.fl-lightbox :after,.fl-lightbox :before{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.fl-lightbox .fl-nanoscroller-pane{bottom:4px;right:4px;width:8px}.fl-lightbox .fa{font-family:FontAwesome}.fl-lightbox .dashicons{font-family:dashicons}.fl-lightbox-content-wrap{height:100%}.fl-lightbox.ui-draggable{box-shadow:rgba(0,0,0,.5) 0 4px 30px;-moz-box-shadow:rgba(0,0,0,.5) 0 4px 30px;-webkit-box-shadow:rgba(0,0,0,.5) 0 4px 30px}.fl-lightbox-controls{position:absolute;right:10px;top:10px;z-index:5}.fl-lightbox-controls .fa{color:#999;font-size:18px;padding:5px}.fl-lightbox-controls .fa:hover{color:#333;cursor:pointer}.fl-builder-lightbox .fl-lightbox-expanded{left:0!important;right:0!important;top:0!important;height:100%!important;width:100%!important}.fl-lightbox.ui-draggable.fl-lightbox-expanded .fl-lightbox-header{cursor:inherit}.fl-builder-lightbox .fl-lightbox-expanded .fl-builder-settings-tab{width:100%!important}.fl-lightbox-header{background:#fff;border-bottom:1px solid #dfdfdf;box-shadow:0 4px 4px -4px rgba(0,0,0,.1);-moz-box-shadow:0 4px 4px -4px rgba(0,0,0,.1);-webkit-box-shadow:0 4px 4px -4px rgba(0,0,0,.1);position:relative}.fl-lightbox-header h1{color:#333!important;font-size:18px!important;font-family:Helvetica,Verdana,sans-serif!important;font-weight:300!important;margin:0!important;padding:15px 20px!important;text-align:left!important}.fl-lightbox.ui-draggable .fl-lightbox-header{cursor:move}.fl-lightbox-footer{border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1);-moz-box-shadow:0 -4px 4px -4px rgba(0,0,0,.1);-webkit-box-shadow:0 -4px 4px -4px rgba(0,0,0,.1);padding:10px;text-align:right}.fl-lightbox-footer .fl-builder-button{margin-left:5px!important}
1
+ #wpadminbar,html{transition-duration:.35s}.fl-builder-button,.fl-builder-edit .fl-builder-content{-webkit-touch-callout:none;-webkit-user-select:none;-ms-user-select:none}.fl-builder-badge,.fl-builder-bar-title span{vertical-align:middle}.fl-theme-builder-preview-select-title i:before,body .fl-theme-builder-preview-select .fa-caret-down i:before,body .fl-theme-builder-preview-select-item-title i:before{content:"\f078"}.fl-builder-edit .media-frame,.fl-lightbox-wrap{-webkit-backface-visibility:hidden}html{transition-property:margin}html.fl-builder-is-showing-toolbar{margin-top:46px!important}.fl-builder-edit body{position:static!important}.fl-builder-edit:after,.fl-builder-edit:before{z-index:0!important}.fl-builder-edit .fl-builder-content{-moz-user-select:none;user-select:none}#wpadminbar{transition-property:opacity,-webkit-transform;transition-property:transform,opacity;transition-property:transform,opacity,-webkit-transform;-webkit-transform-origin:bottom;transform-origin:bottom;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:rotateX(89deg) translateY(46px);transform:rotateX(89deg) translateY(46px);opacity:0;pointer-events:none;will-change:transform}html.fl-builder-show-admin-bar{margin-top:32px}html.fl-builder-show-admin-bar #wpadminbar{-webkit-transform:rotateX(0) translateY(0);transform:rotateX(0) translateY(0);pointer-events:auto;opacity:1}@media screen and (max-width:782px){html.fl-builder-show-admin-bar{margin-top:46px}}.fl-clear{clear:both}.screen-reader-text{position:absolute;left:-1000em;top:-1000em;height:1px;width:1px;overflow:hidden}.fl-builder-loading{background:url(../img/ajax-loader.svg) center center no-repeat rgba(240,240,240,.8);bottom:0;display:none;left:0;position:fixed;right:0;text-align:center;top:0;z-index:12000000}.fl-builder-settings .fl-builder-loading{background:url(../img/ajax-loader.svg) center center no-repeat rgba(255,255,255,.8);display:block;position:absolute}.fl-field-loader{color:#B3B3B3!important;font-style:italic}.fl-builder-node-loading{opacity:.35}.fl-builder-node-loading-placeholder{background:url(../img/ajax-loader.svg) center center no-repeat;height:50px}.fl-col-group-has-child-loading{display:-webkit-box;display:-ms-flexbox;display:flex}.fl-col-group-has-child-loading>.fl-builder-node-loading-placeholder{width:50px}.fl-builder-content-editing .fl-visible-desktop,.fl-builder-content-editing .fl-visible-desktop-medium,.fl-builder-content-editing .fl-visible-medium,.fl-builder-content-editing .fl-visible-medium-mobile,.fl-builder-content-editing .fl-visible-mobile{display:block!important}.fl-responsive-preview-mask{background:#F7F7F7;bottom:0;left:0;position:fixed;right:0;top:0;z-index:99999}.fl-responsive-preview{bottom:0;left:0;position:absolute;right:0;top:0;z-index:100000}.fl-builder-preview .fl-responsive-preview{margin:0!important}.fl-responsive-preview-content{background:#F5F7F9;padding:20px 20px 45px}.fl-responsive-preview-message{color:#b3b3b3;font-family:Helvetica,Arial,Verdana,sans-serif;font-size:14px;font-weight:400;padding:0 20px 20px;text-align:center}.fl-builder-button,body .fl-builder-bar .fl-builder-bar-content{display:-webkit-box;display:-ms-flexbox;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important}.fl-responsive-preview-message i{cursor:pointer;margin-left:3px}.fl-responsive-preview .fl-builder-content{box-shadow:0 0 8px rgba(0,0,0,.2);margin-left:auto;margin-right:auto;max-width:100%}.fl-builder-button{color:#676F7A!important;fill:#676F7A!important;background:#E4E7EA;-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:flex;text-decoration:none;font-size:14px!important;font-weight:500!important;line-height:1!important;height:33px;margin:0;padding:0 12px;cursor:pointer;-webkit-border-radius:3px;-webkit-appearance:none;border:2px solid transparent;border-radius:3px;letter-spacing:normal!important;white-space:nowrap;box-sizing:border-box!important;transition-property:background-color,width;transition-duration:.2s;-moz-user-select:none;user-select:none}.fl-builder--search-results-panel,.fl-builder-bar,.fl-builder-panel{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-touch-callout:none}.fl-builder-button:hover{background:#dadfe5;color:#222;border:2px solid transparent!important}.fl-builder-button:active{background:#DCDCDC}button.fl-builder-button:focus{position:static;top:auto;outline:0;background:#E4E7EA;border:2px solid #00A0D0!important}.fl-builder-bar .fl-builder-button{height:auto}.fl-builder-button-primary,body.fl-builder--layout-has-drafted-changes .fl-builder-done-button{background:#00A0D2;color:#fff!important;text-decoration:none;border:2px solid transparent!important}.fl-builder-button.fl-builder-button-primary:focus,body.fl-builder--layout-has-drafted-changes .fl-builder-button.fl-builder-done-button:focus{background:#00A0D2;border:2px solid #ffc217!important}.fl-builder-button-primary:hover,body.fl-builder--layout-has-drafted-changes .fl-builder-done-button:hover{background:#0197C6;color:#fff!important}.fl-builder-button-primary:active,body.fl-builder--layout-has-drafted-changes .fl-builder-done-button:active{background:#0484AC}.fl-builder-button-large{height:30px}.fl-builder-button-small{font-size:11px!important;line-height:1!important}.fl-builder-help-button{color:#b3b3b3;font-size:16px!important}.fl-builder-help-button i{position:relative;top:-1px}.fl-builder-help-button:hover{color:#666}.fl-builder-publish-button{line-height:45px!important}.fl-builder-content-panel-button,.fl-builder-content-panel-button:hover{fill:#00A0D2!important;font-size:30px!important;padding-bottom:4px}.fl-builder-button-silent,.fl-builder-button-silent:hover{padding:0 12px;background:0 0!important;border:2px solid transparent!important;box-shadow:none!important}.fl-builder-done-button,.fl-builder-done-button:hover{font-weight:600}.fl-field .fl-builder-button{display:inline-block;height:auto;padding:11px 12px;vertical-align:middle;box-shadow:0 2px 4px 0 rgba(0,0,0,.12)}.fl-builder-badge{background:#333;border-radius:2px;color:#fff!important;display:inline;font-size:11px!important;font-weight:400;letter-spacing:1px;margin-left:2px;padding:2px 4px}.fl-builder-badge-global{background:#ff9600;-webkit-transform:translateY(0);transform:translateY(0);transition-duration:.25s;transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform}.fl-builder-blocks-node-template .fl-builder-badge-global{position:absolute;right:0;top:0}.fl-builder-block:hover .fl-builder-badge-global{display:none}.fl-builder-bar{left:0;position:fixed;right:0;top:0;z-index:999999;user-select:none;transition-property:-webkit-transform opacity;transition-property:transform opacity;transition-property:transform opacity,-webkit-transform opacity;transition-duration:.35s;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-perspective:1100px;perspective:1100px}.fl-builder-bar.is-hidden{pointer-events:none}.fl-builder-bar.is-hidden .fl-builder-bar-content{-webkit-transform:translateY(-100%) rotateX(90deg);transform:translateY(-100%) rotateX(90deg)}body .fl-builder-bar .fl-builder-bar-content{display:flex;box-sizing:border-box;background:#fff;border-bottom:2px solid #D5DADD;color:#999;font-size:14px!important;height:48px;transition-property:background-color,opacity,-webkit-transform;transition-property:background-color,opacity,transform;transition-property:background-color,opacity,transform,-webkit-transform;transition-duration:.35s;pointer-events:auto}.fl-builder-bar-title,.fl-builder-bar-title-icon{display:-webkit-box;display:-ms-flexbox;box-sizing:border-box}.fl-builder-draggable-is-dragging .fl-builder-content,.fl-builder-draggable-is-dragging .fl-builder-panel .fl-lightbox,.fl-builder-resizable-is-resizing .fl-builder-content,.fl-builder-resizable-is-resizing .fl-builder-panel .fl-lightbox,body .fl-builder-bar .fl-builder-bar-content.is-muted{pointer-events:none}body .fl-builder-bar .fl-builder-bar-content.is-muted>:not(.fl-builder-publish-actions){-webkit-filter:saturate(20%) blur(1px);filter:saturate(20%) blur(1px);opacity:.4}.fl-builder-bar-title{color:#333;display:flex;-webkit-box-flex:0;-ms-flex:0 0 380px;flex:0 0 380px;max-width:380px;border-right:2px solid #D5DADD;cursor:pointer}.fl-builder-bar-title:hover{background:#fff}.fl-builder-bar-title.is-showing-menu .fl-builder-bar-title-caret>svg{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fl-builder-simple .fl-builder-bar-title{cursor:auto}.fl-builder-simple .fl-builder-bar-title:hover{cursor:auto;background:0 0}.fl-builder-bar-title-icon{background:0 0;-webkit-box-flex:0;-ms-flex:0 0 46px;flex:0 0 46px;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:4px}.fl-builder-bar-title-icon img{max-width:100%!important;height:auto!important}.fl-builder-bar-title.fl-builder-bar-title-no-icon{padding-left:12px}.fl-builder-bar-title-area{box-sizing:border-box;-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;overflow:hidden;padding:4px}.fl-builder-layout-title,.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span{font-size:17px;font-weight:400;line-height:1.3;color:#161B20;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.fl-builder-bar-title-caret,.fl-builder-layout-pretitle,.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title{font-size:12px;font-weight:500;line-height:1.3;color:#656d77;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.fl-builder-bar-title-caret i,.fl-theme-builder-preview-select-title i{color:inherit!important;font-size:14px}.fl-builder-bar-title-caret{margin-left:auto!important;-webkit-box-flex:0;-ms-flex:0 0 46px;flex:0 0 46px}.fl-theme-builder-preview-select-title i{padding:12px}.fl-theme-builder-preview-select.fl-builder-button{position:relative;border-radius:0;background:0 0;min-width:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 0 360px;flex:0 0 360px;max-width:360px;margin:0!important;padding:4px 10px;border:none!important;border-right:2px solid #d5dadd!important;box-shadow:none}.fl-theme-builder-preview-select.fl-builder-button:hover{border:none!important;border-right:2px solid #d5dadd!important}.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.fl-theme-builder-preview-select-title div{-webkit-box-flex:1;-ms-flex:1;flex:1}.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span{display:block}.fl-theme-builder-preview-select-open .fl-theme-builder-preview-select-items{position:absolute;top:calc(48px + 10px);left:10px;width:calc(100% - 20px)!important;background:#fff;border-radius:4px;border:2px solid #D5DADD;border-top:3px solid #00a0d2;box-shadow:0 15px 45px 8px rgba(0,0,0,.04);margin:0!important;padding:0;z-index:-1;font-size:16px;overflow:visible;height:auto!important;max-height:calc(100vh - 66px);min-height:300px;display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.fl-theme-builder-preview-select-item{padding:4px 0!important;border-bottom:none!important;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.fl-theme-builder-preview-select-item:hover{text-decoration:none;color:#111;background:0 0!important}body .fl-theme-builder-preview-select .fa-caret-down{float:none}body .fl-theme-builder-preview-select-item-title{padding:10px 15px;color:#222;font-size:14px}body .fl-theme-builder-preview-select-item-children{overflow:auto}body .fl-theme-builder-preview-select-item-child{overflow:hidden;text-overflow:ellipsis;line-height:1.1;margin:0 10px;border:2px solid transparent;border-radius:4px;padding:8px 10px 10px;font-size:14px;font-weight:400;color:#222}body .fl-theme-builder-preview-select-item-child:hover{background:#e6eaed!important}.fl-theme-builder-preview-select-item .fa-caret-down{color:#606D77}.fl-builder-bar-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;padding:4px}.fl-builder-bar .fl-builder-button{margin:0 0 0 4px}.fl-builder-bar-actions .fl-builder-button:last-child{margin:0}.fl-builder-bar-actions:after{clear:both}.fl-builder-bar .fl-builder-content-panel-button{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important;padding-top:1px;font-weight:400}.fl-builder-content-panel-button svg{transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform;transition-duration:.25s;-webkit-transform:rotate(0) scale(1);transform:rotate(0) scale(1);-webkit-transform-origin:center;transform-origin:center}.fl-builder-content-panel-is-showing .fl-builder-content-panel-button svg{-webkit-transform:rotate(135deg) scale(1.1) translate(.5px,-.5px);transform:rotate(135deg) scale(1.1) translate(.5px,-.5px)}.fl-builder--saving-indicator{cursor:pointer;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-item-align:center;align-self:center;padding:0 16px;font-size:1em;font-style:italic;color:#676f7a}.fl-builder--saving-indicator:hover{color:#676f7a}.fl-builder--saving-indicator .fa-question-circle{font-size:13px;margin:3px 0 3px 8px}.fl-builder-buy-button,.fl-builder-upgrade-button{background:#F7A407;color:#fff!important;text-decoration:none}.fl-builder-buy-button i.fa-external-link-square,.fl-builder-upgrade-button i.fa-external-link-square{color:#FFC733;margin:0 0 0 6px}.fl-builder-buy-button:hover,.fl-builder-upgrade-button:hover{background:#EE8E0D;color:#fff!important}@media (max-width:980px){.fl-builder--main-menu-panel{width:calc(100% - 20px)!important}.fl-builder--main-menu-panel:before{right:auto;left:20px}.fl-builder-bar-title,.fl-theme-builder-preview-select{-webkit-box-flex:1!important;-ms-flex:1 .5 380px!important;flex:1 .5 380px!important}}@media (max-width:620px){.fl-theme-builder-preview-select.fl-builder-button{display:none}}@media (max-width:500px){.fl-builder--main-menu-panel:before,.fl-builder-bar-title-area,.fl-builder-panel-drag-handle,.fl-builder-panel:before{display:none}.fl-builder--main-menu-panel,.fl-builder-panel{width:auto!important;top:44px!important;left:0!important;right:0!important;bottom:0!important;border-radius:0!important;box-shadow:none!important}.fl-builder--main-menu-panel{border-left:transparent!important;border-right:transparent!important;border-bottom:transparent!important;max-height:calc(100% - 44px)!important}.fl-builder-bar-title{-webkit-box-flex:0!important;-ms-flex:0 0 100px!important;flex:0 0 100px!important}.fl-builder--panel-header{border-radius:0!important;cursor:default!important}.fl-builder--panel-header .fl-builder--tabs{cursor:default!important}.fl-builder-publish-actions{width:100%!important}}@media (max-width:400px){.fl-builder-bar-actions .fl-builder-button{padding:0 8px}}.fl-builder--preview-actions{display:none;position:fixed;top:4px;left:4px;z-index:100008;padding:4px 4px 6px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;background:#fff;border-radius:4px}.fl-builder-preview .fl-builder--preview-actions{display:-webkit-box;display:-ms-flexbox;display:flex}.fl-builder--preview-actions .device-icons{color:#555;background:#e4e4e4;box-shadow:0 2px 0 #d6d6d6;border:none!important;-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;text-decoration:none;font-size:14px!important;line-height:1!important;margin:0 4px 0 0;padding:0 6px;cursor:pointer;-webkit-border-radius:3px;-webkit-appearance:none;border-radius:3px;height:33px}.fl-builder--preview-actions .device-icons i{margin:0 6px}@-webkit-keyframes fl-builder-ui-pin-zone-pulse{0%,100%{opacity:1;filter:alpha( opacity=1 )}50%{opacity:.5;filter:alpha( opacity=35 )}}@keyframes fl-builder-ui-pin-zone-pulse{0%,100%{opacity:1;filter:alpha( opacity=1 )}50%{opacity:.5;filter:alpha( opacity=35 )}}.fl-builder-ui-pin-zone{-webkit-animation:fl-builder-ui-pin-zone-pulse 2s infinite;animation:fl-builder-ui-pin-zone-pulse 2s infinite;transition:width .3s ease;background:rgba(0,160,210,.5);bottom:0;top:0;position:fixed;width:35px;z-index:100001}.fl-builder-ui-show-pin-zone-left .fl-builder-ui-pin-zone-left,.fl-builder-ui-show-pin-zone-right .fl-builder-ui-pin-zone-right{width:75px}.fl-builder-ui-pin-zone-left{left:0}.fl-builder-ui-pin-zone-right{right:0}.fl-builder-content-panel-pin-zone .fl-builder-content-panel-button{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;background:rgba(0,160,210,.5)!important;padding:2px 4px;width:80px;-webkit-animation:fl-builder-ui-pin-zone-pulse 2s infinite;animation:fl-builder-ui-pin-zone-pulse 2s infinite}.fl-builder-content-panel-pin-zone .fl-builder-content-panel-button svg{display:none}.fl-builder-content-panel-pin-zone-hover .fl-builder-content-panel-button{width:120px}.fl-builder-content-panel-pin-zone-hover .fl-builder-content-panel-button svg{display:none!important;width:100%;-webkit-transform:none!important;transform:none!important;fill:#00A0D2!important;border-radius:3px}.fl-builder-ui-is-pinned .fl-builder-content-panel-button,.fl-builder-ui-pinned-container .fl-lightbox-controls{display:none}.fl-builder-content-panel-pin-zone .fl-builder-done-button{-webkit-filter:grayscale(100%);filter:grayscale(100%)}.fl-builder-panel.fl-builder-ui-pinned{top:48px!important;bottom:0!important;height:auto!important;border-radius:0;border:none;box-shadow:none;animation-duration:0s;-moz-animation-duration:0s;-webkit-animation-duration:0s;-o-animation-duration:0s;z-index:9}.fl-builder-panel.fl-builder-ui-pinned-right{left:auto!important;right:0;border-left:2px solid #d5dadd}.fl-builder-panel.fl-builder-ui-pinned-left{left:0;right:auto;border-right:2px solid #d5dadd}.fl-builder-panel.fl-builder-ui-pinned .fl-builder--panel-header{border-radius:0!important}.fl-builder-ui-pinned-container .fl-lightbox-wrap{position:absolute;z-index:9}.fl-builder-ui-pinned-container .fl-lightbox{position:absolute;top:0;bottom:0;left:0;right:0;width:auto!important;height:auto;border-radius:0;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;animation-duration:0s;-moz-animation-duration:0s;-webkit-animation-duration:0s;-o-animation-duration:0s}.fl-builder-ui-pinned-container .fl-lightbox-header-wrap{border-radius:0}.fl-builder-ui-pinned-container .fl-lightbox.ui-draggable .fl-lightbox-header{cursor:auto}.fl-builder-ui-pinned-container .fl-lightbox-header h1{padding:12px 20px 10px!important}.fl-builder-ui-pinned-content-transform{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:center top 0;transform-origin:center top 0}.fl-builder-ui-pinned-collapse{cursor:pointer;display:none;position:absolute!important;bottom:2px;padding:5px;border:2px solid transparent;background:0 0;width:36px;height:36px;border-radius:4px;fill:#778794;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.fl-builder-ui-pinned-collapse:focus,.fl-builder-ui-pinned-collapse:hover{top:auto!important;background:0 0;border:2px solid transparent;outline:0;fill:#00A0D2}.fl-builder-ui-pinned-collapse:focus{background:#E4E7EA}.fl-builder-ui-pinned-collapse>*{margin:auto;line-height:1}.fl-builder-ui-pinned-collapse svg g{fill:inherit}.fl-builder-ui-is-pinned-right .fl-builder-ui-pinned-right-collapse{display:-webkit-box;display:-ms-flexbox;display:flex;left:-40px}.fl-builder-ui-is-pinned-left .fl-builder-ui-pinned-left-collapse{display:-webkit-box;display:-ms-flexbox;display:flex;right:-40px}.fl-builder-ui-pinned-collapse i[data-toggle=show],.fl-builder-ui-pinned-is-collapsed i[data-toggle=hide]{display:none}.fl-builder-ui-pinned-is-collapsed i[data-toggle=show]{display:block}.fl-builder-ui-is-pinned-left [data-toggle=hide],.fl-builder-ui-is-pinned-right [data-toggle=show]{-webkit-transform:rotateY(180deg);transform:rotateY(180deg)}.fl-builder-ui-pinned-is-collapsed .fl-lightbox{box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}.fl-builder-ui-pinned-is-collapsed .fl-builder--panel-header{display:none}@-webkit-keyframes fl-builder-show-panel{from{-webkit-transform:scale(.8);transform:scale(.8)}to{-webkit-transform:scale(1);transform:scale(1)}}@keyframes fl-builder-show-panel{from{-webkit-transform:scale(.8);transform:scale(.8)}to{-webkit-transform:scale(1);transform:scale(1)}}.fl-builder--search-results-panel,.fl-builder-panel{box-sizing:border-box;position:fixed!important;right:20px;top:calc(48px + 10px);width:380px;bottom:20px;background:#F5F7F9;color:#676F7A;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:14px;border-radius:4px;box-shadow:0 8px 40px 4px rgba(0,0,0,.3);z-index:10000007;will-change:transform;display:none;user-select:none}.fl-builder-panel{-webkit-transform-origin:top right;transform-origin:top right;-webkit-animation-name:fl-builder-show-panel;animation-name:fl-builder-show-panel;-webkit-animation-duration:.15s;animation-duration:.15s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.fl-builder--search-results-panel{position:absolute;right:0;top:93px;left:0;bottom:0;width:auto!important;border:none;border-radius:0;box-shadow:none;min-height:100px;max-height:calc(100vh - 54px);overflow:auto;z-index:1}.fl-builder-content-panel-is-showing .fl-builder-panel,.fl-builder-search-results-panel-is-showing .fl-builder--search-results-panel{display:block}.fl-builder-panel .fl-lightbox .fl-builder-panel-drag-handle,.fl-builder-ui-is-pinned .fl-builder--panel-arrow,.fl-lightbox-width-full .fl-builder-panel-drag-handle,body.fl-builder-draggable-is-dragging .fl-builder--panel-arrow{display:none}.fl-builder-content-panel-is-showing .fl-builder-panel.fl-builder--current-view-templates{width:520px}.fl-builder--search-results-panel .fl-builder--no-results{text-align:center;padding:50px 20px}.fl-builder--panel-arrow{position:absolute;top:-13px;right:10px}.fl-builder--panel-arrow polygon{fill:#00a0d2}.fl-builder--panel-header{background:#fff;border-top:3px solid #00a0d2;border-bottom:2px solid #e6eaed;border-top-right-radius:4px;border-top-left-radius:4px}.fl-builder-ui-is-pinned .fl-builder--panel-header{border-top-color:transparent}.fl-builder-panel-drag-handle{position:absolute;top:7px;left:10px;fill:#ccd4da;width:6px}.fl-builder-ui-is-pinned-left .fl-builder-panel-drag-handle{left:auto;right:10px}.fl-builder--panel-header .fl-builder--panel-controls{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;position:relative}.fl-builder--panel-header .fl-builder--panel-controls .fl-builder-content-group-select{-webkit-box-flex:1;-ms-flex:1 1;flex:1 1}.fl-builder--panel-header .fl-builder--panel-controls .fl-builder-panel-search{-webkit-box-flex:0;-ms-flex:0 0;flex:0 0;padding:0 10px 6px 0;margin-left:-4px}.fl-builder--panel-controls .fl-builder-panel-search button{width:38px;background:0 0!important;border:2px solid transparent!important;font-size:inherit;height:38px;padding:0}.fl-builder--panel-controls .fl-builder-panel-search button:active,.fl-builder--panel-controls .fl-builder-panel-search button:focus{top:0;outline:0}.fl-builder-panel-search button svg{height:auto;width:20px}.fl-builder-panel-search button.fl-builder-dismiss-panel-search svg{width:16px}.fl-builder-panel-search button svg .filled-shape{fill:#000}.fl-builder--panel-controls .fl-builder-panel-search button:active svg .filled-shape,.fl-builder--panel-controls .fl-builder-panel-search button:focus svg .filled-shape{fill:#00A0D2}.fl-builder-panel-search .fl-builder-panel-search-input{display:none;position:absolute;top:0;left:0;right:0;bottom:0;background:#fff}.fl-builder-panel-search.is-showing-input .fl-builder-panel-search-input{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;padding:0 10px 6px}.fl-builder-panel-search-input input{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;border:2px solid #e6eaed;background:#fff;border-radius:4px;margin-right:4px;padding:10px;color:#333}.fl-builder-panel-search-input input:focus{border-color:#0197C6;outline:0}.fl-builder-panel-search-input button{-webkit-box-flex:0;-ms-flex:0 0 38px;flex:0 0 38px}.fl-builder-panel-content-wrap{bottom:0;height:auto;left:0;overflow:hidden;position:absolute;right:0;top:43px}.fl-builder-panel-content{padding-bottom:60px}.fl-builder-blocks-section{border-top:2px solid #e6eaed}.fl-builder--panel-view .fl-builder-blocks-section:first-child{border-top:none}.fl-builder-blocks-group:first-child{padding:20px 0 0}.fl-builder-blocks-group .fl-builder-blocks-section-group-name{display:block;padding:0 30px 15px;color:#000;font-size:20px;font-weight:600;line-height:1.4}.fl-builder-blocks-section .fl-builder-block,.fl-builder-blocks-section .fl-builder-blocks-section-title{display:block;line-height:1.1;padding:15px 20px}.fl-builder--template-collection-section-name,.fl-builder-blocks-section .fl-builder-blocks-section-title{display:inline-block;font-weight:700;font-size:12px;line-height:1.2;text-transform:uppercase;color:#333;padding:4px 10px 4px 15px;margin:0!important;background:#e6eaed;border-bottom-right-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top}.fl-builder-blocks-section .fl-builder-blocks-section-title i{color:#bfbfbf;float:right}.fl-builder-blocks-section-content{overflow:auto;padding:10px 10px 20px}.fl-builder-blocks-section-content:after{float:none;clear:both}.fl-builder-blocks-section-content.fl-builder-modules,.fl-builder-blocks-section-content.fl-builder-rows,.fl-builder-blocks-section-content.fl-builder-widgets{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.fl-builder-blocks-section-content .fl-builder-block-module,.fl-builder-blocks-section-content .fl-builder-block-row{-webkit-box-flex:1;-ms-flex:1 1 50%;flex:1 1 50%;width:50%;box-sizing:border-box}.fl-builder--search-results-panel .fl-builder-blocks-section-content .fl-builder-block-module{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;width:100%}.fl-builder-blocks-section.fl-active .fl-builder-blocks-section-content{display:block}.fl-builder-blocks-section-content .fl-builder-block{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;font-size:14px;line-height:1.1;font-weight:500;color:#727272}.fl-builder-block{position:relative;height:47px}.fl-builder-block.fl-builder-block-col-group{height:84px}.fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail{padding:10px;height:auto}.fl-builder-block:hover{overflow:visible;z-index:1}.fl-builder-block:hover .fl-builder-block-content{display:block;box-sizing:border-box;position:absolute;top:0;left:0;width:100%;padding:15px 20px;border-radius:4px;background:#fff;box-shadow:0 2px 4px 0 rgba(0,0,0,.12);text-decoration:none;color:#111;cursor:move;overflow:hidden}.fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-blocks-node-template .fl-builder-block,.fl-builder-blocks-section-content .fl-builder-block .fl-builder-block-details{position:relative}.fl-builder-block-module:hover .fl-builder-block-content{width:auto;min-width:100%}.fl-builder-block .fl-builder-block-content .fl-builder-block-visual{display:block;margin-bottom:7px}.fl-builder-block-drag-helper .fl-builder-block-content .fl-builder-block-visual{display:none!important}.fl-builder-block .fl-builder-block-content .fl-builder-block-visual.fl-cols-visual{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;height:30px}.fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col{-webkit-box-flex:1;-ms-flex:1 100%;flex:1 100%;background:#464a4c;height:30px;margin:0 2px;border-radius:2px}.fl-builder-block:hover .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col{background:#000}.fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col:first-child{margin-left:0!important}.fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col:last-child{margin-right:0!important}.fl-cols-visual.left-right-sidebar .fl-cols-visual-col:first-child,.fl-cols-visual.left-right-sidebar .fl-cols-visual-col:last-child,.fl-cols-visual.left-sidebar .fl-cols-visual-col:first-child,.fl-cols-visual.right-sidebar .fl-cols-visual-col:last-child{-ms-flex-preferred-size:60px;flex-basis:60px}.fl-builder-block-saved-module.fl-builder-block-global .fl-builder-block-title,.fl-builder-block-saved-module:hover .fl-builder-block-title,.fl-builder-block-saved-row.fl-builder-block-global .fl-builder-block-title,.fl-builder-block-saved-row:hover .fl-builder-block-title{margin-right:70px}.fl-builder-block-module:nth-child(even):hover .fl-builder-block-content{left:auto;right:0}.fl-builder-block-thumbnail{border-radius:4px;background-size:contain;background-repeat:no-repeat;background-position:center;background-color:rgba(0,0,0,.06);margin-bottom:10px;-webkit-transform-origin:bottom;transform-origin:bottom;transition-property:box-shadow,-webkit-transform;transition-property:transform,box-shadow;transition-property:transform,box-shadow,-webkit-transform;transition-duration:.15s}.fl-builder-block:hover .fl-builder-block-thumbnail{-webkit-transform:scale(1.05);transform:scale(1.05);box-shadow:0 20px 40px rgba(0,0,0,.08)}.fl-builder-block .fl-builder-block-icon{margin-right:7px;fill:#000;display:inline-block;width:20px;height:20px;vertical-align:middle}.fl-builder-block-thumbnail:before{content:"";display:block;padding-top:50%}.fl-builder-block-thumbnail img{max-width:100%;max-height:160px;margin:0;-o-object-fit:cover;object-fit:cover}.fl-builder-blocks-section-content .fl-builder-block{box-shadow:0 0 0 transparent;transition-property:box-shadow;transition-duration:.15s}.fl-builder-blocks-section-content .fl-builder-block i,.fl-user-template-actions i{color:#000;margin-right:10px}.fl-builder-blocks-separator{background:#f1f1f1;height:6px}.fl-builder-block:hover .fl-builder-badge{background:#2ea2cc}.ui-sortable-helper .fl-builder-badge{display:none!important}.fl-builder-modules-cta a{color:#999!important;display:block!important;font-size:12px!important;font-style:italic!important;padding:15px 20px!important;line-height:16px!important}.fl-builder-modules-cta a:hover{background:#e5e5e5!important;color:#666!important;text-decoration:none!important}.fl-builder-modules-cta a:focus{text-decoration:none!important}.fl-builder-modules-cta .fa{float:right!important;font-size:14px!important;margin:3px 0 0 9px!important}.fl-builder--panel-message{text-align:center;padding:40px 20px;font-size:16px}.fl-builder--panel-message .fl-builder-button{display:inline-block;padding:10px}.fl-builder--panel-cta{padding:20px 30px;font-size:16px;text-align:center}.fl-builder--panel-cta a{color:inherit;text-decoration:none}.fl-builder--panel-cta a:hover{text-decoration:none}.fl-builder-block-template-image{margin:5px 0 10px;max-width:100%;border:1px solid #dfdfdf}.fl-builder-block .fl-builder-block-title{overflow:hidden;text-overflow:ellipsis;vertical-align:middle;line-height:1.3}.ui-sortable-helper .fl-builder-block-template-image{display:none!important}@-webkit-keyframes fl-builder-template-item-enter{from{-webkit-transform:translateY(100px) scale(.3);transform:translateY(100px) scale(.3);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes fl-builder-template-item-enter{from{-webkit-transform:translateY(100px) scale(.3);transform:translateY(100px) scale(.3);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.fl-builder--template-collection{clear:both;padding:10px 0}.fl-builder--template-collection-section-content{padding:0 10px}.fl-builder--template-collection-item{box-sizing:border-box;width:50%;float:left;padding:10px;cursor:pointer;font-size:13px;-webkit-transform-origin:center;transform-origin:center;opacity:1}.fl-builder--template-thumbnail{background-size:cover;background-clip:content-box;background-position:center top;background-color:#fff;border:2px solid transparent;-webkit-transform-origin:bottom;transform-origin:bottom;transition-property:box-shadow,-webkit-transform;transition-property:transform,box-shadow;transition-property:transform,box-shadow,-webkit-transform;transition-duration:.15s}.fl-builder--template-collection-item[data-id="0"] .fl-builder--template-thumbnail,.fl-user-template .fl-builder--template-thumbnail{border-color:#e4e7ea}.fl-builder--template-thumbnail:before{display:block;content:"";padding-top:120%}.fl-builder--template-thumbnail:hover{-webkit-transform:scale(1.05);transform:scale(1.05);box-shadow:0 20px 40px rgba(0,0,0,.08)}.fl-builder--template-name{text-align:center;padding:4px 0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fl-builder--template-collection-section{padding-bottom:10px;border-bottom:1px solid #dfdfdf}.fl-builder--template-collection-section:after,.fl-builder--template-collection-section:before{content:"";display:block;clear:both}.fl-builder--template-collection-section-name{padding:15px 10px 10px}span.fl-builder-block-no-node-templates{display:block;padding:15px 20px;text-align:center}span.fl-builder-block-no-node-templates:hover{cursor:default}.fl-builder-blocks-section-content .fl-builder-node-template-actions{bottom:0;cursor:default;display:none;position:absolute;right:0;top:0}.fl-builder-blocks-section-content .fl-builder-node-template-delete,.fl-builder-blocks-section-content .fl-builder-node-template-edit{display:inline;cursor:pointer;margin:0;padding:15px 10px;text-align:center;width:30px}.fl-builder-block-details .fl-builder-node-template-delete,.fl-builder-block-details .fl-builder-node-template-edit{padding-top:0!important}.fl-builder-blocks-section-content .fl-builder-node-template-delete i,.fl-builder-blocks-section-content .fl-builder-node-template-edit i{margin:0}.fl-builder-blocks-section-content .fl-builder-node-template-delete:hover i,.fl-builder-blocks-section-content .fl-builder-node-template-edit:hover i{color:#444}.fl-builder-blocks-node-template .fl-builder-block:hover .fl-builder-node-template-actions{display:block}.ui-sortable-helper .fl-builder-node-template-delete,.ui-sortable-helper .fl-builder-node-template-edit{display:none!important}.fl-builder--tabs{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;position:relative;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.fl-builder-panel .fl-builder--panel-header{cursor:move;position:absolute;top:0;left:0;right:0;z-index:9}.fl-builder-panel .fl-builder--tabs{-ms-flex-pack:distribute;justify-content:space-around;padding:0 24px;min-height:46px;cursor:pointer}.fl-builder--tab-wrap{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.fl-builder--tabs button,.fl-builder--tabs button:active,.fl-builder--tabs button:focus,.fl-builder--tabs button:hover{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;display:inline-block;text-decoration:none;color:inherit;text-align:center;letter-spacing:normal!important;padding:5px;cursor:pointer;font-size:14px!important;font-weight:600!important;line-height:1.4!important;background:0 0!important;outline:0!important;border:2px solid transparent;border-radius:4px;margin:7px 0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important;top:0;transition-property:background,color;transition-duration:.25s}.fl-builder--tabs button:focus{background:#e6eaed!important}.fl-builder--tabs button.is-showing{color:#0086b0}.fl-builder--panel-view{display:none;overflow:hidden}.fl-builder--panel-view.is-showing{display:block}.fl-builder--content-library-panel .fl-builder--panel-view.is-showing{position:absolute;top:96px;bottom:0;left:0;right:0;width:auto;height:auto}.fl-builder--content-library-panel.single-view .fl-builder--panel-view.is-showing{top:52px}.fl-builder--content-library-panel.ui-draggable-dragging{height:500px!important}.fl-builder--content-library-panel .fl-builder-drop-zone{display:none!important}.fl-builder--panel-header .fl-builder--tabs{cursor:move}.fl-builder--category-select{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;position:relative}.fl-builder--selector-display,.fl-builder--selector-display-label,.fl-builder-publish-actions{-webkit-box-orient:horizontal;-webkit-box-direction:normal}.fl-builder--selector-display{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;position:relative;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#161B20;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important;cursor:pointer;font-size:13px;font-weight:700;line-height:16px;border-radius:4px}.fl-builder--selector-display-label{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;font-size:inherit;line-height:inherit;width:100%;padding:0!important;color:#6D6D6D;background:0 0;border:2px solid #e4e7ea;border-radius:4px;font-family:inherit}.fl-builder--selector-display-label:active,.fl-builder--selector-display-label:hover{top:0;color:inherit;background:0 0;border:2px solid #e4e7ea;border-radius:4px}.fl-builder--selector-display-label:focus{top:0;color:inherit;background:0 0;border:2px solid #00A0D2;outline:0}.fl-builder--group-label{color:inherit;-webkit-box-flex:0;-ms-flex:0 0 0%;flex:0 0 0%;padding:9px 12px 9px 10px;background:#e6eaed;border-top-left-radius:2px;border-bottom-left-radius:2px}.fl-builder--current-view-name{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;color:inherit;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;padding:9px 10px;text-align:left}.fl-builder--selector-menu{display:none;color:#293138;position:absolute;top:46px;left:0;width:100%;background:#fff;border-radius:4px;box-shadow:0 0 20px 2px rgba(0,0,0,.2);overflow:visible}.fl-builder--selector-menu:before{bottom:100%;right:8px;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:solid;border-color:rgba(255,255,255,0);border-bottom-color:#fff;border-width:10px;margin-left:-10px}.fl-builder--category-select.is-showing .fl-builder--selector-menu{display:-webkit-box;display:-ms-flexbox;display:flex;max-height:calc(100vh - 150px)}.fl-builder--category-select.is-showing .fl-builder--selector-menu .fl-builder--menu{margin:10px 0;-webkit-box-flex:1;-ms-flex:1 100%;flex:1 100%;overflow:auto}button.fl-builder-button.fl-builder-bar-title-caret{margin:4px}button.fl-builder-button.fl-builder-bar-title-caret:focus{background-color:#e6eaed!important;border-color:transparent!important}.fl-builder--category-select.is-showing .fl-builder-bar-title-caret i{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fl-builder--menu{margin-bottom:2px}.fl-builder--menu>a,.fl-builder--menu>button,.fl-builder--menu>span{display:block;padding:8px 10px 10px;border-radius:4px;color:inherit;text-decoration:none;background:0 0!important;border:2px solid transparent!important;font-weight:400;font-family:inherit}.fl-builder--menu>a:active,.fl-builder--menu>a:focus,.fl-builder--menu>a:hover,.fl-builder--menu>button:active,.fl-builder--menu>button:focus,.fl-builder--menu>button:hover{background:#e6eaed!important;border:2px solid transparent!important;top:0}.fl-block-col-resize-feedback,.fl-block-overlay-title,.fl-builder-block-drag-helper,.fl-builder-block.ui-draggable-dragging,.fl-builder-drop-zone,.fl-builder-empty,.fl-builder-has-submenu>ul.fl-builder-submenu li a{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}.fl-builder--menu>a:focus,.fl-builder--menu>button:focus{outline:0;color:inherit;text-decoration:none}.fl-builder--menu .fl-inset{padding-left:35px;font-size:14px;line-height:1.25}.fl-builder--menu a.fl-template-collection{color:#161B20}.fl-builder--menu>:after{clear:both}.fl-builder--menu * .fl-builder--menu-item-accessory{float:right;color:#000;text-transform:uppercase;text-align:center;min-width:20px;letter-spacing:2px}.fl-builder--menu * .fl-builder--menu-item-accessory i{font-size:1em;margin-top:2px}.fl-builder--menu .fl-builder-video-wrap iframe{display:block;margin:4px 0;width:100%}.fl-builder-publish-actions{display:-webkit-box;display:-ms-flexbox;display:flex;box-sizing:border-box;position:absolute;top:0;right:0;width:380px;max-width:100%;height:46px;padding:4px;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;opacity:1;pointer-events:auto;-webkit-transform:scaleX(1) translateX(0);transform:scaleX(1) translateX(0);-webkit-transform-origin:right;transform-origin:right;transition-property:opacity,-webkit-transform;transition-property:transform,opacity;transition-property:transform,opacity,-webkit-transform;transition-duration:.15s}.fl-builder-publish-actions.is-hidden{-webkit-transform:scaleX(.23) translateX(68px);transform:scaleX(.23) translateX(68px);opacity:0;pointer-events:none}.fl-builder-bar .fl-builder-button-group{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-preferred-size:100%;flex-basis:100%}.fl-builder-bar .fl-builder-button-group>.fl-builder-button{border-radius:0;margin-left:0;-ms-flex-preferred-size:100%;flex-basis:100%;text-align:center;-ms-flex-pack:distribute;justify-content:space-around;box-shadow:none}.fl-builder-bar .fl-builder-button-group>.fl-builder-button:first-child{margin-left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.fl-builder-bar .fl-builder-button-group>.fl-builder-button:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.fl-builder-publish-actions-click-away-mask{display:none;position:fixed;top:0;left:0;right:0;height:100vh;background:0 0}.fl-builder-dragging .fl-builder-content:not(.fl-builder-empty){padding:16px 0}.fl-builder-empty{display:none;border:2px dashed #969696;border-radius:8px;color:#909090;font-size:20px;font-weight:700;margin:10px;padding:250px 20px;position:relative;text-align:center;text-transform:uppercase}.fl-builder-edit .fl-builder-empty{display:block}.fl-builder-block-drag-helper,.fl-builder-block.ui-draggable-dragging{background:rgba(255,255,255,.95)!important;border:2px solid #000;border-radius:4px;box-shadow:0 0 8px rgba(0,0,0,.2);-moz-box-shadow:0 0 8px rgba(0,0,0,.2);-webkit-box-shadow:0 0 8px rgba(0,0,0,.2);color:#333!important;font-size:13px!important;height:47px!important;line-height:40px!important;overflow:hidden;padding:0 20px;position:fixed!important;text-overflow:ellipsis;white-space:nowrap;width:180px!important;z-index:100010!important;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-line-pack:center;align-content:center;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.fl-builder-block.fl-builder-block-drag-helper:hover{padding:0;box-shadow:none}.fl-builder-block-drag-helper:hover .fl-builder-block-content{position:static;padding:0 20px}.fl-col-has-highlight-guide .fl-col-content,.fl-col-highlight,.fl-row-highlight .fl-col-group{position:relative}.fl-builder-block-saved-module.fl-builder-block-drag-helper:hover .fl-builder-block-content,.fl-builder-block-saved-row.fl-builder-block-drag-helper:hover .fl-builder-block-content{padding:14px 20px}.fl-builder-block-drag-helper .fl-builder-block-icon{fill:#000;margin-top:-10px}.fl-builder-drop-zone{-webkit-animation:fl-builder-drop-zone-pulse 2s infinite;animation:fl-builder-drop-zone-pulse 2s infinite;background:#00A2D7;border-radius:4px;color:#fff!important;display:block;font-weight:400;font-size:12px;letter-spacing:1px;line-height:14px;margin:10px;padding:6px 8px 5px;position:relative;text-align:left;text-overflow:ellipsis;text-shadow:none;text-transform:none;white-space:nowrap;overflow:hidden;z-index:10}@-webkit-keyframes fl-builder-drop-zone-pulse{0%,100%{background-color:#00A2D7}50%{background-color:#79DEFF}}@keyframes fl-builder-drop-zone-pulse{0%,100%{background-color:#00A2D7}50%{background-color:#79DEFF}}.fl-builder-drop-zone-global{-webkit-animation:fl-builder-drop-zone-global-pulse 2s infinite;animation:fl-builder-drop-zone-global-pulse 2s infinite;background:#ff9600}@-webkit-keyframes fl-builder-drop-zone-global-pulse{0%,100%{background-color:#FFBC5C}50%{background-color:#ff9600}}@keyframes fl-builder-drop-zone-global-pulse{0%,100%{background-color:#FFBC5C}50%{background-color:#ff9600}}.fl-builder-content>.fl-builder-drop-zone{margin:10px 20px}.fl-row-content>.fl-builder-drop-zone{margin:3px 7px}.fl-col-has-cols>.fl-col-content>.fl-builder-drop-zone{margin:3px 10px}.fl-sortable-disabled>.fl-builder-drop-zone{display:none!important}.fl-col-group-equal-height.fl-col-group-align-center .fl-col-content>.fl-builder-drop-zone{width:100%}.fl-row-highlight{padding:16px 0}.fl-row-highlight .fl-row-content{border:2px dashed rgba(203,205,206,.5);padding:8px;border-radius:6px}.fl-row-highlight.fl-node-global .fl-row-content{border-color:#ff9600}.fl-col-highlight{padding:8px}.fl-col-highlight .fl-col-content{border-style:dashed!important;border-color:#00a0d2!important;border-radius:4px;min-height:100px;overflow-x:hidden;width:100%;border-width:2px!important}.fl-col-has-cols.fl-col-highlight>.fl-col-content{padding:8px}.fl-col-highlight.fl-node-global .fl-col-content{border-color:#ff9600!important}.fl-builder-simple .fl-col-highlight .fl-col-content{border:none!important}.fl-col-highlight-guide{background:rgba(0,160,210,.05);border:2px solid #00A0D2;border-radius:4px;bottom:4px;left:4px;position:absolute;right:4px;top:4px;z-index:1}.fl-node-global .fl-col-highlight-guide{border-color:#ff9600!important;background-color:rgba(255,150,0,.06)!important}.fl-col-has-highlight-guide .fl-block-overlay{background:0 0;border-color:transparent}.fl-col-has-highlight-guide .fl-block-col-resize{display:none}.fl-col-has-highlight-guide .fl-col-highlight .fl-col-content{border-color:transparent!important}.fl-col-drop-target{bottom:8px;display:none;left:-9px;position:absolute;top:8px;width:18px;z-index:1}.fl-col-highlight .fl-col-drop-target{display:block}.fl-col-drop-target-last{left:auto;right:-9px}.fl-col-drop-target .fl-builder-drop-zone{bottom:0;left:2px;margin:0;padding:0;position:absolute;right:2px;top:0}.fl-col-group-drop-target{display:none;left:8px;height:18px;position:absolute;right:8px;top:-9px;z-index:1}.fl-row-highlight .fl-col-group-drop-target{display:block}.fl-col-group-drop-target-last{top:auto;bottom:-9px}.fl-col-group-drop-target .fl-builder-drop-zone{bottom:2px;left:0;margin:0;padding:0;position:absolute;right:0;top:2px}.fl-row-content>.fl-col-group-drop-target{position:static}.fl-row-content>.fl-col-group-drop-target .fl-builder-drop-zone{height:18px;position:static}.fl-row-drop-target{display:none;left:0;height:24px;margin-top:-28px;position:absolute;right:0;z-index:1}.fl-row-highlight .fl-row-drop-target{display:block}.fl-row-drop-target-last{margin-top:4px}.fl-row .fl-row-drop-target .fl-builder-drop-zone{bottom:0;left:4px;margin:0;position:absolute;right:4px;top:0}.fl-builder-content>.fl-row-drop-target{margin:0;position:static}.fl-builder-dragging .fl-builder-content.fl-builder-empty>.fl-row-drop-target{bottom:10px;display:block;height:auto;left:0;position:absolute;right:0;top:10px}.fl-builder-content .fl-row-drop-target .fl-builder-drop-zone{margin-bottom:0;margin-top:0}.fl-col-group:focus,.fl-col:focus,.fl-module:focus,.fl-row:focus{outline:0}.fl-sortable-proxy{display:none}.fl-block-overlay,.fl-block-overlay *{text-shadow:none;-webkit-touch-callout:none}.fl-block-overlay-active{position:relative}.fl-block-overlay-actions{background:#00A0D2;float:left;height:30px;margin:-1px -1px 0;padding:0 4px;text-shadow:none;border-bottom-right-radius:5px;border-top-left-radius:3px}.fl-row-overlay-header-bottom .fl-block-overlay-actions{border-radius:0 5px 0 3px}.fl-builder-col-resizing .fl-block-overlay-actions,.fl-builder-row-resizing .fl-block-overlay-actions{overflow:hidden}.fl-block-overlay-actions>span{display:block;float:left}.fl-block-overlay-actions i{color:#fff!important;cursor:pointer;display:block!important;float:left;font-size:16px!important;height:28px!important;font-weight:100!important;line-height:28px!important;opacity:.8;filter:alpha(opacity=80);text-align:center;width:32px!important}.fl-block-overlay-actions i:hover{opacity:1;filter:alpha(opacity=100)}.fl-block-overlay-actions>i:first-child{padding-left:4px}.fl-block-overlay-actions>i:last-child{padding-right:2px}.fl-block-overlay-actions .fl-block-move{cursor:move}.fl-block-overlay-title{color:#fff!important;float:left;font-size:14px;height:30px;line-height:29px;margin-right:2px;padding:0 12px 0 8px}.fl-col-overlay,.fl-module-overlay,.fl-row-overlay{background:rgba(190,239,255,0);color:#fff}.fl-row-overlay{border:2px solid #00A0D2;border-radius:4px;bottom:0;box-sizing:border-box!important;-moz-box-sizing:border-box!important;-webkit-box-sizing:border-box!important;left:0;position:absolute;top:-33px;right:0;z-index:100006}.fl-row-full-width .fl-row-overlay{left:2px;right:2px;bottom:2px}.fl-row-overlay-header-bottom{bottom:-32px!important;top:0}.fl-row-overlay-header-bottom .fl-block-overlay-header{position:absolute;bottom:0}.fl-block-overlay-active .fl-row-content-wrap{position:relative}.fl-block-overlay-active .fl-row-content{position:relative;z-index:100007!important}.fl-builder-row-resizing .fl-col.fl-block-overlay-active,.fl-builder-row-resizing .fl-module.fl-block-overlay-active{position:static}.fl-col-overlay{border:2px solid #00A0D2;border-radius:4px;bottom:8px;cursor:pointer;left:8px;position:absolute;right:8px;top:8px;z-index:100008}.fl-module-overlay{border:2px solid #00A0D2;border-radius:4px;bottom:4px;cursor:pointer;left:4px;min-height:32px;position:absolute;right:4px;top:4px;z-index:100007}.fl-builder-global-templates-locked .fl-block-overlay-global.fl-module-overlay{cursor:default}.fl-module-adjust-height{padding-bottom:15px;padding-top:15px}.fl-block-overlay-global{background:rgba(255,150,0,0);border:2px solid #F7A407;border-radius:4px}.fl-block-overlay-global .fl-block-overlay-actions{background:#F7A407}.fl-block-overlay-title-global{background:#fff;color:#ff9600!important;font-size:11px;letter-spacing:1px;margin-left:4px;padding:2px 4px;vertical-align:top}.fl-block-overlay-global.fl-row-overlay{background:rgba(255,150,0,0);cursor:pointer;z-index:100007}.fl-builder-global-templates-locked .fl-block-overlay-global.fl-row-overlay{cursor:default}.fl-builder-row-template .fl-block-overlay-global.fl-row-overlay{background:rgba(255,150,0,0);cursor:default;z-index:100006}.fl-block-overlay-global.fl-row-overlay .fl-block-col-resize{display:none}.fl-block-overlay-muted .fl-row-overlay{background:rgba(85,93,102,0);border:2px solid #555D66}.fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-actions{background:#555D66}.fl-block-overlay-muted .fl-row-overlay .fl-block-col-resize{display:none}.fl-node-disabled .fl-row-content-wrap{opacity:.3}.fl-block-col-resize{bottom:0!important;position:absolute;top:0!important;width:6px}.fl-block-col-resize-e{cursor:ew-resize;left:auto!important;right:-2px!important}.fl-block-col-resize-w{cursor:ew-resize;left:-7px!important}.fl-block-col-resize-handle-wrap{margin:-4px 0 0 -5px;padding:0 5px;position:absolute;top:50%!important}.fl-block-col-resize-e .fl-block-col-resize-handle-wrap{margin-left:-6px}.fl-block-col-resize-handle{background:#fff;border:2px solid #00A0D2;border-radius:50%;height:12px;width:12px}.fl-node-global .fl-block-col-resize-handle{border-color:#ff9600}.fl-block-col-resize-feedback{color:#333!important;display:none;font-size:11px!important;position:absolute}.fl-block-col-resize-feedback-left,.fl-block-col-resize-feedback-right{background:#fff;border:1px solid #3ba0ff;padding:2px 4px}.fl-block-col-resize-feedback-left{right:20px;top:-7px}.fl-block-col-resize-feedback-right{left:20px;top:-7px}.fl-builder-has-submenu{position:relative}.fl-builder-has-submenu>ul.fl-builder-submenu{background:#00A0D2;box-shadow:0 0 20px rgba(0,0,0,.2);border-radius:0 4px 4px;display:none;left:0;list-style:none;margin:0;padding:6px 0;position:absolute;text-align:left;top:100%;width:165px;z-index:100008}.fl-builder-has-submenu>ul.fl-builder-submenu li{list-style:none;margin:0;padding:0}.fl-builder-submenu-right ul.fl-builder-submenu{left:auto;right:0}.fl-builder-has-submenu.fl-builder-submenu-open>ul.fl-builder-submenu{display:block}.fl-builder-has-submenu>ul.fl-builder-submenu li a{border-bottom:0 none;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#fff!important;display:block;line-height:13px;font-size:13px;font-weight:400;opacity:.8;filter:alpha(opacity=80);overflow:hidden;padding:6px 12px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.fl-builder-has-submenu>ul.fl-builder-submenu li a:hover{background:#0197C6;color:#fff;opacity:1;filter:alpha(opacity=100);text-decoration:none}.fl-builder-actions-title,.fl-builder-alert-lightbox .fl-lightbox-message{color:#333!important;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:16px!important}.fl-builder-has-submenu .fl-builder-submenu .fa{float:right;height:12px!important;line-height:12px!important;position:relative;right:-5px;width:14px!important}.fl-builder-has-submenu .fl-builder-has-submenu .fl-builder-submenu{display:none;left:100%;top:0}.fl-builder-has-submenu .fl-builder-submenu-right.fl-builder-has-submenu .fl-builder-submenu{left:auto;right:100%}.fl-builder-has-submenu .fl-builder-has-submenu:hover .fl-builder-submenu{display:block}.fl-builder-submenu-sep{padding:7px 0!important}.fl-builder-submenu-sep div{border-bottom:1px solid rgba(255,255,255,.4)}.fl-block-col-move,.fl-block-col-move-parent{cursor:move;position:relative}.fl-builder-submenu .fa-arrows{cursor:move;display:none!important}.fl-builder-submenu a:hover .fa-arrows{display:block!important}.fl-block-overlay-global ul.fl-builder-submenu{background:#ff9600!important}.fl-block-overlay-global ul.fl-builder-submenu li a:hover{background:#fa3}.fl-builder-actions-lightbox .fl-lightbox{display:block;width:300px;border-radius:4px}.fl-builder-actions-lightbox .fl-lightbox-content-wrap{display:block}.fl-builder-actions-lightbox .fl-builder-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:25px;text-align:center}.fl-builder-actions-title{display:block;margin-bottom:20px}.fl-builder-actions .fl-builder-button{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-bottom:7px;min-height:36px}.fl-builder-alert-lightbox{padding:20px;z-index:30000000;top:0;pointer-events:auto}.fl-builder-alert-lightbox .fl-lightbox{max-width:440px;width:auto}.fl-builder-alert-lightbox .fl-lightbox-content-wrap{display:block}.fl-builder-alert-lightbox .fl-lightbox-message{line-height:24px;padding:30px}@-webkit-keyframes fl-builder-content-section-entry{from{-webkit-transform:translateY(150px) translateX(100px) scale(.3);transform:translateY(150px) translateX(100px) scale(.3);opacity:0}to{-webkit-transform:translateY(0) translateX(0) scale(1);transform:translateY(0) translateX(0) scale(1);opacity:1}}@keyframes fl-builder-content-section-entry{from{-webkit-transform:translateY(150px) translateX(100px) scale(.3);transform:translateY(150px) translateX(100px) scale(.3);opacity:0}to{-webkit-transform:translateY(0) translateX(0) scale(1);transform:translateY(0) translateX(0) scale(1);opacity:1}}.fl-template-category-select{width:180px!important}.fl-template-selector .fl-builder-settings-section{margin:0 0 10px}.fl-template-selector .fl-builder-settings-fields{height:470px}.fl-template-selector .fl-builder-settings-tab{width:560px}.fl-template-selector .fl-builder-settings-tab-description{font-size:15px!important;margin:0!important;padding:10px 0 25px;text-align:center}.fl-template-preview{float:left;margin:0 25px 30px 0;position:relative;text-align:center;width:170px}.fl-template-preview.fl-last{margin-right:0}.fl-template-image{border:1px solid #d9d9d9;cursor:pointer;margin-bottom:12px;height:164px;overflow:hidden}.fl-template-image:hover{border-color:red}.fl-template-image img{max-height:none;width:100%}.fl-template-preview span{display:block;text-align:center}.fl-user-template-category-name{background:#f2f2f2;border-bottom:3px solid #dfdfdf;border-top:2px solid #dfdfdf;font-weight:700;padding:8px 15px}.fl-user-templates{border-bottom:1px solid #dfdfdf;padding:10px 0 20px}.fl-builder--user-templates-section-content{border-bottom:2px solid #e6eaed;padding:10px}.fl-builder--user-templates-section-content:first-child{padding-top:0}.fl-builder--user-templates-section-content:last-child,.fl-user-templates:last-child{border-bottom:none}.fl-builder--user-templates-section-name{font-weight:700;font-size:16px;color:#333;z-index:9999;padding:15px 10px;margin:0 10px}@-webkit-keyframes fl-list-item-entry{from{opacity:0;-webkit-transform:scale(.5) translateY(100px);transform:scale(.5) translateY(100px)}to{opacity:1;-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@keyframes fl-list-item-entry{from{opacity:0;-webkit-transform:scale(.5) translateY(100px);transform:scale(.5) translateY(100px)}to{opacity:1;-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}.fl-builder--save-new-user-template,.fl-user-template{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;font-size:16px;font-weight:200;line-height:1.1;padding:10px 20px;color:#6d6d6d}.fl-user-template:hover{cursor:pointer;background:#fff;box-shadow:0 6px 20px rgba(0,0,0,.08);text-decoration:none;color:#111;padding-right:68px}.fl-user-template-name{overflow:hidden;text-overflow:ellipsis;-webkit-box-flex:1;-ms-flex:1;flex:1}.fl-user-template-actions{display:none;bottom:0;position:absolute;right:0;top:0}.fl-user-template:hover .fl-user-template-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.fl-user-template-actions a{display:inline-block;padding:15px 0;width:30px}.fl-user-template:hover a:hover i{color:#444!important}.fl-user-templates-message{display:none}.fl-user-template-thumbnail{-webkit-box-flex:0;-ms-flex:0;flex:0;margin-right:20px}.fl-user-template-thumbnail .fl-builder--template-thumbnail{background-size:cover;background-position:center top;width:45px}.fl-user-template-thumbnail .fl-builder--template-thumbnail:hover{box-shadow:none;-webkit-transform:scale(1);transform:scale(1);transition-property:none}.fl-builder--save-new-user-template .fl-user-template-thumbnail .fl-builder--template-thumbnail{border-style:dashed;border-width:2px;border-color:#ccd4da}.fl-builder--save-new-user-template .fl-save-control{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-flex:1;-ms-flex:1;flex:1}.fl-builder--save-new-user-template .fl-save-control input{background:0 0;border:none!important;-webkit-box-flex:1;-ms-flex:1;flex:1;font-size:16px;margin-right:10px;margin-left:-12px;color:#000}.fl-builder--save-new-user-template .fl-save-control input::-webkit-input-placeholder{color:#777}.fl-builder--save-new-user-template .fl-save-control input::-moz-placeholder{color:#777}.fl-builder--save-new-user-template .fl-save-control input:-ms-input-placeholder{color:#777}.fl-builder--save-new-user-template .fl-save-control input:-moz-placeholder{color:#777}@-webkit-keyframes fl-slide-in-right{from{-webkit-transform:translateX(50px);transform:translateX(50px)}to{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fl-slide-in-right{from{-webkit-transform:translateX(50px);transform:translateX(50px)}to{-webkit-transform:translateX(0);transform:translateX(0)}}.fl-builder--save-new-user-template .fl-save-control button{display:none;-webkit-animation-name:fl-slide-in-right;animation-name:fl-slide-in-right;-webkit-animation-duration:.25s;animation-duration:.25s;background-color:#00a0d2;border:none;padding:0 15px}.fl-save-control-mask{display:none;background:0 0;position:absolute;top:-50px;left:0;bottom:0;right:0;z-index:-1;min-height:80vh}.fl-builder-templates-cta{margin-bottom:20px}.fl-builder-templates-cta p{display:inline-block!important;width:75%!important;font-size:14px!important;line-height:1.5!important;margin-bottom:0!important}.fl-builder-templates-cta .fl-builder-upgrade-button{font-size:13px!important;line-height:13px!important;position:relative;top:8px;left:15px;padding:1px 12px}.fl-builder-settings-message,.fl-builder-settings-message *{font-size:15px!important;line-height:23px!important}.single-fl-builder-template .fl-content{width:100%!important}form.fl-builder-settings{height:100%;margin:0;padding:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.fl-builder-settings-message{padding:20px 25px!important;background:#f2f2f2!important}.fl-builder-preview-loader{position:relative;top:-2px;margin-left:3px}.fl-lightbox-header .fl-builder-preview-loader{margin:0;position:absolute;right:40px;top:15px}@-webkit-keyframes fl-grab-attention{0%,100%{-webkit-transform:scale(1);transform:scale(1)}50%{-webkit-transform:scale(1.05);transform:scale(1.05)}}@keyframes fl-grab-attention{0%,100%{-webkit-transform:scale(1);transform:scale(1)}50%{-webkit-transform:scale(1.05);transform:scale(1.05)}}.fl-lightbox-width-slim .fl-form-table{margin:20px 25px 10px 15px!important;width:calc(100% - 60px)}.fl-lightbox-width-slim .fl-form-table th{display:block;padding:10px 0 0 12px!important}.fl-lightbox-width-slim .fl-form-table td{display:block}.fl-lightbox-width-slim .fl-form-table td:first-child{padding-left:10px!important}.fl-lightbox-width-slim .fl-form-table .fl-field[data-type=editor] td:first-child{padding-left:0!important}.fl-field-label .fl-field-responsive-toggle,.fl-lightbox-width-slim .fl-field-control-wrapper .fl-field-responsive-toggle{display:none}.fl-lightbox-width-slim .fl-field-label .fl-field-responsive-toggle{display:inline-block;padding:0 5px!important}.fl-lightbox-width-slim .fl-builder-settings-fields select{width:100%}.fl-lightbox-width-slim .fl-color-picker{display:-webkit-box;display:-ms-flexbox;display:flex;width:auto}.fl-lightbox-width-slim .fl-color-picker-clear{-webkit-box-flex:0;-ms-flex:0 0 50px;flex:0 0 50px}.fl-lightbox-width-slim .mce-menubtn.mce-fixed-width button{width:28px!important}.fl-lightbox-width-slim .mce-btn[aria-label=Blockquote],.fl-lightbox-width-slim .mce-btn[aria-label=Fullscreen]{display:none}.fl-lightbox-width-slim .fl-builder-field-multiple{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;position:relative}.fl-lightbox-width-slim .fl-builder-field-multiple .fl-field-control,.fl-lightbox-width-slim .fl-builder-field-multiple .fl-field-label{width:100%!important}.fl-lightbox-width-slim .fl-builder-field-multiple .fl-builder-field-actions{position:absolute!important;top:0;right:0;width:70px}.fl-lightbox-width-slim .fl-field[data-type=time] select{width:auto}.fl-builder-settings-tabs{margin:6px;border:2px solid #e6eaed;border-radius:4px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;overflow:hidden}.fl-builder-content-group-select{padding:0 10px 6px;display:none}.fl-builder-content-group-select select{display:block;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;padding:8px 10px;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important;border:2px solid #e4e7ea;color:#161B20}select:focus{border-width:2px!important;border-style:solid!important;border-color:#00a0d2!important;outline:0!important}.fl-legacy-settings-tab{background:url(../img/ajax-loader.svg) center center no-repeat;height:100px}.fl-builder-settings-tab:first-child .fl-legacy-settings-tab{background:0 0;height:auto}body .fl-builder-settings-tabs>*{box-sizing:border-box;color:#676F7A!important;fill:#676F7A!important;background:0 0;border:2px solid transparent;border-radius:0;margin:0;outline:0;padding:6px 15px;text-decoration:none!important;font-size:14px;font-weight:400!important;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;text-align:center}.fl-builder-settings-tabs-more g,.fl-builder-settings-tabs-more path,.fl-builder-settings-tabs-more svg,.fl-color-picker-color.fl-color-picker-empty svg.fl-color-picker-icon path{fill:inherit}body .fl-builder-settings-tabs>:first-child{border-top-left-radius:3px;border-bottom-left-radius:3px}body .fl-builder-settings-tabs>:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}body .fl-lightbox-width-slim .fl-builder-settings-tabs>*{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:6px 8px}body .fl-builder-settings-tabs>.fl-builder-settings-tabs-more{-webkit-box-flex:0;-ms-flex:0 0 60px;flex:0 0 60px;display:none;margin-left:auto;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.fl-builder-settings-tabs-more svg{width:16px;height:auto;margin:auto}body .fl-lightbox-has-tab-overflow .fl-builder-settings-tabs-more{display:-webkit-box;display:-ms-flexbox;display:flex}.fl-builder-settings-tabs>:active,.fl-builder-settings-tabs>:hover{top:0;color:#333;background:0 0;border:2px solid transparent}.fl-builder-settings-tabs>:focus{top:0;outline:0;border:2px solid transparent;background:0 0;color:#0086b0;fill:#0086b0}.fl-builder-settings-tabs .fl-active,.fl-builder-settings-tabs-more.fl-contains-active,.fl-builder-settings-tabs-overflow-menu .fl-active{color:#0086b0!important;fill:#0086b0!important;position:relative;background:#e6eaed}.fl-builder-settings-tabs .fl-active.fl-overflowed,.fl-builder-settings-tabs .fl-overflowed{display:none!important}.fl-builder-settings-tabs .error{color:#d03436;padding-right:10px}.fl-builder-settings-tabs .error .fl-error-icon,.fl-builder-settings-tabs-overflow-menu .error .fl-error-icon{background:url(../img/sprite.png) -148px -5px no-repeat;display:inline-block;height:16px;margin-left:7px;position:relative;top:3px;width:16px}.fl-builder-settings-tabs-more.fl-contains-errors{fill:#d03436!important}.fl-builder-settings-tab{display:none;width:auto!important}.fl-builder-settings-tab.fl-active{display:block}.fl-builder-settings-tab-description{background:#e4e7ea;padding:10px 15px;border-radius:4px;margin:20px}.fl-builder-settings-tab-description a{text-decoration:underline!important}.fl-builder-settings-tab-description a:hover{color:#333}.fl-builder-settings-tabs-overflow-menu{display:none;position:absolute;left:0;right:0;border:2px solid #e6eaed;border-top:3px solid #00a0d2;border-radius:4px;background:#fff;z-index:9;margin:0 6px;padding:10px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;box-shadow:0 0 20px 2px rgba(0,0,0,.2)}.fl-builder-settings-tabs-overflow-menu:before{bottom:100%;right:20px;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:solid;border-color:rgba(255,255,255,0);border-bottom-color:#00a0d2;border-width:10px;margin-left:-10px}.fl-builder-settings-tabs-overflow-menu>a{display:block;padding:10px 15px;font-size:14px;font-weight:600!important;border:2px solid transparent;border-radius:4px;outline:0}.fl-builder-settings-tabs-overflow-menu>a:hover{background:#e6eaed;text-decoration:none}.fl-builder-settings-tabs-overflow-click-mask{display:none;position:fixed;top:0;bottom:0;left:0;right:0;background:0 0;z-index:9}.fl-form-table{background:none;border:none;width:calc(100% - 35px)}.fl-form-table tbody{border:none}.fl-form-table tr,.fl-form-table tr:nth-child(even){background:0 0}.fl-form-table td,.fl-form-table th{background:0 0!important;border:none!important;font-weight:400!important;text-align:left!important}.fl-form-table th{padding:10px 10px 10px 30px!important;vertical-align:top!important;width:200px!important}.fl-form-table td:first-child{padding-left:30px!important}.fl-form-table th label{color:#333;width:auto;max-width:100%}.fl-photo-field .fl-photo-preview-img img,.fl-video-field .fl-video-preview-img img{max-width:60px}.fl-form-table td{padding:8px 10px}.fl-lightbox-width-slim .fl-form-table td{padding:4px 0 10px}.fl-builder-settings-fields{margin:0;overflow:hidden;position:relative;-webkit-box-flex:1;-ms-flex:1 100%;flex:1 100%;visibility:hidden}.fl-builder-ui-keyboard-shortcut-item,.fl-link-field .fl-link-field-input-wrap{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row}.fl-lightbox-header .fl-builder-settings-fields{height:auto;margin:0;position:absolute;right:10px;top:10px}.fl-builder-settings-fields .fl-nanoscroller-content{padding:0}.fl-builder-settings-fields .fl-field-control-wrapper{position:relative}.fl-field{-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-delay:.1s;animation-delay:.1s}.fl-builder-settings-fields input[type=email],.fl-builder-settings-fields input[type=file],.fl-builder-settings-fields input[type=number],.fl-builder-settings-fields input[type=password],.fl-builder-settings-fields input[type=search],.fl-builder-settings-fields input[type=tel],.fl-builder-settings-fields input[type=text],.fl-builder-settings-fields input[type=url],.fl-builder-settings-fields select,.fl-builder-settings-fields textarea{background:#fff!important;border-color:transparent!important;border-style:solid;border-width:2px;border-radius:4px!important;box-shadow:0 2px 4px 0 rgba(0,0,0,.12);color:#333!important;display:inline;font-size:13px;height:auto;line-height:15px;margin:1px;outline:0;padding:3px 9px;width:auto;box-sizing:border-box}.fl-builder-settings-fields input[type=email],.fl-builder-settings-fields input[type=file],.fl-builder-settings-fields input[type=number],.fl-builder-settings-fields input[type=password],.fl-builder-settings-fields input[type=search],.fl-builder-settings-fields input[type=tel],.fl-builder-settings-fields input[type=text],.fl-builder-settings-fields input[type=url],.fl-builder-settings-fields select{height:36px!important}.fl-builder-settings-fields input[type=number]{width:70px}.fl-builder-lightbox .fl-builder-settings-fields input[type=email]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=file]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=number]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=password]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=search]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=tel]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=text]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=url]:focus,.fl-builder-lightbox .fl-builder-settings-fields select:focus,.fl-builder-lightbox .fl-builder-settings-fields textarea:focus{border-width:2px!important;border-style:solid!important;border-color:#00a0d2!important;box-shadow:0 2px 4px 0 rgba(0,0,0,.12)!important}.fl-builder-settings-fields ::-webkit-input-placeholder{color:#999!important;font-size:12px}.fl-builder-settings-fields input:-moz-placeholder{color:#999;font-size:12px}.fl-builder-settings-fields ::-moz-placeholder{color:#999!important;font-size:12px}.fl-builder-settings-fields input:-ms-input-placeholder{color:#999;font-size:12px}.fl-builder-settings-fields label{display:inline-block;font-weight:400;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin-bottom:3px}.fl-builder-settings-fields select{-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;color:#000;margin:0 0 2px;padding:2px 10px;padding-right:30px!important;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important}.fl-builder-settings-fields select[multiple]{height:60px;background-image:none!important}.fl-builder-custom-field select,.fl-photo-field select{-webkit-box-shadow:none;border-color:#e6eaed!important}.fl-font-field .fl-font-field-font{margin-bottom:4px;width:calc(70% - 5px)!important}.fl-font-field .fl-font-field-weight{width:30%!important}.fl-lightbox-width-slim input.text-full+.fl-field-description,.fl-lightbox-width-slim select+.fl-field-description{display:block;padding:8px 10px;margin:0}.fl-field[data-type=dimension] .fl-field-control-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex}.fl-field[data-type=dimension] .fl-field-description{padding-top:9px}.fl-field[data-type=dimension] .fl-field-responsive-toggle{padding:9px 9px 0 0}.fl-dimension-field-units{display:-webkit-box;display:-ms-flexbox;display:flex}.fl-dimension-field-unit{padding-right:5px}.fl-dimension-field-unit input{max-width:60px;width:auto!important}.fl-dimension-field-unit label{padding:5px 0 0;font-size:12px;color:inherit!important;display:block;text-align:center}.fl-link-field-search input{box-shadow:none!important;width:100%!important;padding:3px 9px!important}.fl-link-field-search #as-original-link-search{width:100%}.fl-builder-settings-section{border-top:2px solid #E6EAED}.fl-builder-settings-section:first-child{border-top:none!important}.fl-custom-query .fl-builder-settings-section{border-top:2px solid #E6EAED!important}.fl-builder-settings-description{padding:0 10px 10px;margin:0;font-style:italic;opacity:.75}.fl-builder-settings-fields table{margin:20px 0}.fl-builder-settings-fields h3.fl-builder-settings-title{display:inline-block;background:#E6EAED;padding:4px 10px 4px 15px;margin:0;text-transform:uppercase!important;border-bottom-right-radius:4px;font-size:12px!important;font-weight:700;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.wp-core-ui h1,.wp-core-ui h2,.wp-core-ui h3,.wp-core-ui h4,.wp-core-ui h5,.wp-core-ui h6{color:#333}.wp-core-ui .submitbox .submitdelete{color:#a00}.wp-core-ui button{font-weight:400}.wp-core-ui input[type=email],.wp-core-ui input[type=file],.wp-core-ui input[type=number],.wp-core-ui input[type=password],.wp-core-ui input[type=search],.wp-core-ui input[type=tel],.wp-core-ui input[type=text],.wp-core-ui input[type=url],.wp-core-ui select,.wp-core-ui textarea{background-color:#fff;border-color:#dfdfdf;border-style:solid;border-width:1px;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#333;font-weight:400}.wp-core-ui input[type=email]:focus,.wp-core-ui input[type=file]:focus,.wp-core-ui input[type=number]:focus,.wp-core-ui input[type=password]:focus,.wp-core-ui input[type=search]:focus,.wp-core-ui input[type=tel]:focus,.wp-core-ui input[type=text]:focus,.wp-core-ui input[type=url]:focus,.wp-core-ui select:focus,.wp-core-ui textarea:focus{background:0 0;border-color:#aaa}.wp-core-ui input[type=search]{background-image:none;padding:6px}.fl-field-responsive-setting{display:inline-block}.fl-field-responsive-setting-medium,.fl-field-responsive-setting-responsive{display:none}i.fl-field-responsive-toggle{color:grey;cursor:pointer;display:inline-block;font-size:15px!important;height:auto;line-height:18px!important;text-align:left;vertical-align:middle;width:20px}i.fl-field-responsive-toggle:hover{color:#000}.fl-builder-settings-fields input.text-full,.fl-builder-settings-fields textarea{width:100%}.fl-color-picker{cursor:pointer}.fl-color-picker .fl-color-picker-clear{box-sizing:border-box}.fl-color-picker .fl-color-picker-clear:hover{background-color:#ededed}.colorpicker input{padding:0!important;font-size:11px!important;color:#fff!important;width:29px!important;height:auto!important;background:0 0!important;border:none!important}.colorpicker .colorpicker_hex input{width:45px!important}.fl-builder-custom-field{background:#fff;border:2px solid transparent;border-radius:4px;padding:7px 10px;box-shadow:0 2px 4px 0 rgba(0,0,0,.12);min-height:36px;box-sizing:border-box}.fl-builder-field-multiple .fl-builder-custom-field{cursor:move}.fl-builder-custom-field a{color:#21759b!important;text-decoration:underline!important}.fl-builder-custom-field a:hover{color:#d54e21!important}.fl-builder-custom-field label.error{margin-top:5px}.fl-photo-field .fl-photo-preview{display:-webkit-box;display:-ms-flexbox;display:flex}.fl-photo-field .fl-photo-select,.fl-photo-field.fl-photo-empty .fl-photo-preview{display:none}.fl-photo-field.fl-photo-empty .fl-photo-select{display:block}.fl-photo-field .fl-photo-preview-img{line-height:0;margin:5px 0}.fl-photo-field .fl-photo-preview select{margin:8px 0 8px 10px;width:200px}.fl-photo-field.fl-photo-no-attachment .fl-photo-preview select{display:none}.fl-photo-field .fl-photo-preview-filename{display:none;font-size:14px;font-weight:700;margin:7px 0 5px 11px}.fl-photo-field.fl-photo-no-attachment .fl-photo-preview-filename{display:inline-block;word-break:break-all}.fl-multiple-photos-field .fl-multiple-photos-select,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-add,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-count,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-edit,.fl-multiple-photos-lightbox .gallery-settings,.fl-photo-field.fl-photo-no-attachment .fl-photo-edit{display:none}.fl-photo-field .fl-photo-edit{margin:0 0 0 11px}.fl-multiple-photos-field .fl-multiple-photos-add,.fl-photo-field .fl-photo-remove,.fl-photo-field .fl-photo-replace{margin:0 0 0 8px}.fl-builder-edit .media-modal{z-index:9999991}.fl-builder-edit .media-modal-backdrop{z-index:999999}.fl-builder-edit .media-modal-content .thumbnail{padding:0;border:none;border-radius:0}.fl-builder-edit button.button-link.media-modal-close{position:absolute;box-shadow:none;-webkit-box-shadow:none}.fl-builder-edit .media-frame.hide-menu{visibility:visible}.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-select{display:inline}.fl-multiple-photos-count{font-weight:700;margin-bottom:3px}.fl-video-field .fl-video-select,.fl-video-field.fl-video-empty .fl-video-preview{display:none}.fl-video-field.fl-video-empty .fl-video-select{display:block}.fl-video-field .fl-video-preview-img{float:left;line-height:0;margin:5px 0}.fl-video-field .fl-video-preview-img .dashicons.dashicons-media-video{display:block;font-size:60px;height:60px;line-height:60px;width:60px}.fl-video-field .fl-video-preview-filename{display:inline-block;font-size:14px;font-weight:700;margin:7px 0 5px 11px}.fl-video-field .fl-video-replace{margin:0 0 0 11px}.fl-multiple-audios-field .fl-multiple-audios-select,.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-add,.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-edit{display:none}.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-select{display:block}.fl-multiple-audios-field .fl-multiple-audios-add{margin:0 0 0 8px}.fl-icon-field .fl-icon-select,.fl-icon-field.fl-icon-empty .fl-icon-preview{display:none}.fl-icon-field.fl-icon-empty .fl-icon-select{display:block}.fl-icon-field .fl-icon-preview i{display:inline-block;font-size:28px;margin:10px 10px 9px;vertical-align:middle}.fl-icon-field .fl-icon-remove{margin:0 0 0 8px}.fl-builder-hidden-editor{display:none}.fl-builder-settings .wp-switch-editor{background:#ebebeb;border:1px solid #e5e5e5;border-radius:0;color:#333}.fl-builder-settings .wp-editor-container{border:1px solid #e5e5e5}.fl-builder-settings .mce-toolbar .mce-btn-group .mce-btn{margin:2px 0}.fl-builder-settings .mce-menubtn.mce-fixed-width button{width:100px}.mce-close:active,.mce-close:hover,.mce-toolbar .mce-btn button:active,.mce-toolbar .mce-btn button:hover,.mce-window .mce-btn button:active,.mce-window .mce-btn button:hover{background:0 0;border:none}.mce-ico{font-family:tinymce,Arial!important}.mce-toolbar i.mce-ico{font:400 20px/1 dashicons!important}.fl-builder-edit form#wp-link,.popover[class*=tour-],ul.as-list{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}.wp-core-ui .quicktags-toolbar input.button.button-small{margin:1px!important}.wp-editor-container textarea.wp-editor-area{background:0 0;border:none;padding:10px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.fl-builder-edit form#wp-link{color:#000;font-size:13px}.fl-builder-edit form#wp-link #link-options label{display:block;margin-bottom:2px}.fl-builder-edit form#wp-link #link-options label span{padding-right:10px;vertical-align:middle}.fl-builder-edit form#wp-link #link-options input[type=text]{display:inline-block;height:auto;margin:5px 0 0;padding:3px 5px;width:80%}.fl-builder-edit form#wp-link .query-results{top:225px}.fl-code-field{border:1px solid #E6E6E6;border-left:none}.ace_editor,.ace_editor *{font-family:Monaco,Menlo,"Ubuntu Mono","Droid Sans Mono",Consolas,monospace!important;font-size:12px!important;font-weight:400!important;letter-spacing:0!important}.fl-layout-field-option{border:2px solid #d9d9d9;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-sizing:border-box!important;-moz-box-sizing:border-box!important;-webkit-box-sizing:border-box!important;cursor:pointer;float:left;line-height:0;max-width:23%;margin:0 1% 2%;padding:5px}.fl-layout-field-option-selected,.fl-layout-field-option:hover{border-color:red}.fl-layout-field-option img{max-width:100%}.fl-link-field .fl-link-field-input-wrap{display:-webkit-box;display:-ms-flexbox;display:flex;flex-direction:row}.fl-link-field-input{width:auto!important;-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%}.fl-link-field .fl-link-field-input-wrap button{-webkit-box-flex:0;-ms-flex:0 0 0%;flex:0 0 0%;margin-left:5px}.fl-link-field-search{display:none;border:2px solid #e6eaed;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;margin:4px 0 0;padding:10px}.fl-link-field-search-title{display:block;margin:0 0 3px 2px}.fl-link-field-search-cancel{margin-top:6px}.fl-help-tooltip{display:inline-block;position:relative}.fl-help-tooltip-icon{color:#999!important;cursor:pointer;font-family:FontAwesome;font-size:15px!important;padding:5px;vertical-align:middle}.fl-help-tooltip-text{background:#fff;border:1px solid #ccc;box-shadow:0 0 5px #ccc;-moz-box-shadow:0 0 5px #ccc;-webkit-box-shadow:0 0 5px #ccc;display:none;font-weight:400;left:23px;padding:10px 13px;position:absolute;top:-6px;width:250px;z-index:1000;border-radius:4px}.fl-lightbox-width-slim .fl-help-tooltip-text{top:26px;left:-30px}.fl-field-control .fl-form-field{margin-bottom:0}.fl-form-field-preview-text i{display:inline-block;font-size:18px;line-height:22px;margin-bottom:5px}.fl-builder-field-actions{padding-left:0!important;padding-right:0!important;text-align:center;width:85px}.fl-builder-field-actions i{color:#999!important;cursor:pointer;font-size:13px!important;line-height:29px!important;width:16px}.fl-builder-field-actions i:hover{color:#000!important}.fl-builder-field-actions i.fl-builder-field-copy,.fl-builder-field-actions i.fl-builder-field-delete{margin-left:5px}.fl-builder-field-actions i.fl-builder-field-move{cursor:move}.fl-builder-field-dd-helper{background:#ccc;height:30px!important;float:left;width:130px!important}.fl-builder-field-dd-zone{border:1px dashed #ccc;height:30px}.fl-builder-field-actions-single .fl-builder-field-delete,.fl-builder-field-actions-single .fl-builder-field-move{display:none!important}.fl-lightbox-width-slim .fl-builder-field-actions-single .fl-builder-field-copy{float:right!important}.fl-builder-field-multiple .fl-builder-field-actions,.fl-builder-field-multiple .fl-field-control,.fl-builder-field-multiple .fl-field-label{padding-top:2px!important;padding-bottom:2px!important}.fl-builder-field-multiple .fl-builder-field-actions{min-width:70px!important}.fl-builder-field-multiple[data-field=icons] .fl-builder-field-actions{width:70px!important}.fl-builder-field-multiple.ui-sortable-helper .fl-field-control{width:60%}.fl-builder-field-multiple.ui-sortable-helper .fl-builder-field-actions{display:none}.fl-builder-widget-settings input{display:inline-block!important;margin:5px 10px 8px!important}.fl-builder-lightbox-loading{background:url(../img/ajax-loader.svg) center center no-repeat;height:100px}.fl-builder-settings .error,.fl-builder-settings input.error{color:#d03436!important}.fl-builder-settings label.error,.fl-builder-settings p.error{color:#d03436;display:block;margin-top:5px}.fl-builder-settings .fl-form-table .fl-field-description{color:#464646;font-style:normal;margin-left:2px}.fl-lightbox .fl-field-connection{right:-1px}.fl-lightbox .fl-field-connection-content{border:2px solid transparent!important;background:#e4e7ea!important}.fl-field-connection-content .fl-field-connection-label{color:#676f7a!important}ul.as-selections{background-color:#fff;border:none;border-radius:4px;box-shadow:none;color:#333;font-size:12px;height:auto;line-height:15px;margin:1px;outline:0;padding:3px;width:auto}ul.as-selections.loading{background:url(../img/ajax-loader-small.svg) 98% center no-repeat}ul.as-selections li.as-selection-item{background:#d4eaf6;border:none;font-size:11px;line-height:14px;padding:8px 15px;border-radius:4px;margin:2px}ul.as-selections li.as-selection-item.blur{background:#f4f4f4}ul.as-selections li.as-selection-item a.as-close{line-height:12px}ul.as-selections li.as-original{margin:0}ul.as-selections li.as-original input{height:auto;font-size:12px;margin:0;padding:0;box-shadow:none}ul.as-list{margin:0;font-size:13px;color:#000;background-color:#fff;background-color:rgba(255,255,255,.95);z-index:2;box-shadow:0 0 10px rgba(0,0,0,.1);border:none;border:1px solid #dfdfdf;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px}li.as-message,li.as-result-item{border:none}li.as-result-item.active{background:#e5e5e5;border-radius:0;color:#333;text-shadow:none}li.as-result-item em{background:0 0!important;color:#333!important;font-size:12px;padding:0!important;font-weight:700}.fl-custom-query-filter{display:none}.fl-custom-query .fl-field[data-type=suggest] select{margin-bottom:5px;width:100%}.fl-builder-service-settings{position:relative}.fl-builder-service-error{color:red!important;padding:15px 0 0}.fl-builder-service-account-delete{color:red!important;margin-left:10px;position:relative;top:2px}#fl-field-visibility_user_capability .fl-field-description,.fl-builder-service-connect-row .fl-field-description{background:#f0f0f0;color:#333!important;display:block;float:none;margin:10px 0 0;padding:10px}#fl-field-visibility_user_capability .fl-field-description a,.fl-builder-service-connect-row .fl-field-description a{color:#21759b!important;text-decoration:underline!important}.fl-ordering-field-option{background:#fff;border:1px solid #dfdfdf;border-radius:3px;cursor:move;margin-bottom:5px;padding:5px 10px}.fl-ordering-field-option .fa{color:#ccc;float:right;line-height:16px}#tiptip_holder{z-index:1000000}#tiptip_holder.tip_top #tiptip_arrow_inner{border-top-color:#333}#tiptip_holder.tip_bottom #tiptip_arrow_inner{border-bottom-color:#333}#tiptip_holder.tip_right #tiptip_arrow_inner{border-right-color:#333}#tiptip_holder.tip_left #tiptip_arrow_inner{border-left-color:#333}#tiptip_content{background:#333;box-shadow:none}.fl-builder-getting-started-video{line-height:0!important;padding:10px}.fl-builder-getting-started-video iframe{border:none;height:326px;width:100%}.fl-builder-tour-actions .fl-builder-actions-title{font-size:14px!important;line-height:19px}.fl-builder-tour-mask{bottom:0;left:0;position:fixed;right:0;top:0;z-index:100000000}.fl-builder-tour-dimmed{background:rgba(0,0,0,.7);bottom:0;left:0;position:absolute;right:0;top:0}body>.fl-builder-tour-dimmed{position:fixed}.tour-backdrop{z-index:110000}.popover[class*=tour-]{border:1px solid #ccc;border-radius:0;box-shadow:0 0 40px rgba(0,0,0,.3);color:#666;font-size:13px;font-weight:400;line-height:18px;max-width:none;padding:0;width:300px;z-index:100000001}.popover[class*=tour-].bottom>.arrow{border-bottom-color:#ccc}.popover[class*=tour-].bottom>.arrow:after{border-bottom-color:#f7f7f7}.popover[class*=tour-] .popover-title{border-radius:0;color:#333;letter-spacing:normal;text-transform:none}.popover[class*=tour-] .fa-times{color:#b3b3b3;cursor:pointer;font-size:16px;padding:5px;position:absolute;right:3px;top:2px}.popover[class*=tour-] .fa-times:hover{color:#666}.popover[class*=tour-] .popover-content{border-bottom:1px solid #d9d9d9;padding:13px 15px}.popover[class*=tour-] .fl-builder-tour-next{display:block;float:none;width:100%}.popover-navigation button{min-height:36px}.fl-builder-shortcode-mask-wrap{position:relative}.fl-builder-shortcode-mask{bottom:-1px;left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fl-builder--search{border:2px solid transparent;position:relative;padding:0;width:54px;transition-property:width;transition-delay:.1s;transition-duration:.15s}.fl-builder--search.is-expanded{border:2px solid #00A0D0}.fl-builder--search input[type=text],.fl-builder--search input[type=text]:focus{background-color:transparent;border:none!important;box-sizing:border-box;width:100%;font-size:16px;text-align:center}.fl-builder--search:before{display:-webkit-box;display:-ms-flexbox;display:flex;top:0;left:0;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;content:"\f002";font:normal normal normal 14px/1 FontAwesome;text-align:center;width:100%;height:100%;position:absolute;pointer-events:none;color:rgba(128,128,128,.6);font-size:17px;opacity:1;transition-property:opacity;transition-duration:.15s}.fl-builder--main-menu-panel,.fl-builder-ui-keyboard-shortcuts{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important}.fl-builder--search.has-text:before,.fl-builder--search.is-expanded:before{opacity:0}.fl-builder--search input::-webkit-input-placeholder{color:rgba(128,128,128,0)!important;transition:color .25s}.fl-builder--search input:focus::-webkit-input-placeholder{color:rgba(128,128,128,.4)!important}.fl-builder--search .search-label{cursor:text}.fl-builder--search .search-clear{display:none;padding:10px 10px 10px 30px;color:#a7a7a7;font-size:12px;position:absolute;right:0;top:0;background-color:#eff1f2;background:linear-gradient(to left,#e4e7ea,#e4e7ea 75%,rgba(228,231,234,0))}.fl-builder--search.has-text .search-clear,.fl-builder--search.is-expanded input{display:inline-block}.fl-builder--search:hover .search-clear{color:#888;background-color:#eff1f2;background:linear-gradient(to left,#dadfe5,#dadfe5 75%,rgba(218,223,229,0))}.fl-builder--search.is-expanded{width:246px}@-webkit-keyframes fl-builder-show-menu-item{from{-webkit-transform:translateY(10px) scale(.8);transform:translateY(10px) scale(.8);opacity:0}to{-webkit-transform:translateX(0) translateY(0) scale(1);transform:translateX(0) translateY(0) scale(1);opacity:1}}@keyframes fl-builder-show-menu-item{from{-webkit-transform:translateY(10px) scale(.8);transform:translateY(10px) scale(.8);opacity:0}to{-webkit-transform:translateX(0) translateY(0) scale(1);transform:translateX(0) translateY(0) scale(1);opacity:1}}.fl-builder--main-menu-panel{display:none;box-sizing:border-box;position:fixed;top:calc(48px + 10px);left:10px;width:360px;color:#222;max-height:calc(100% - 66px);border-radius:4px;background:#fff;border:2px solid #D5DADD;border-top:3px solid #00a0d2;box-shadow:0 15px 45px 8px rgba(0,0,0,.04);font-size:14px!important;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:10000009;pointer-events:auto}.fl-builder--main-menu-panel.is-showing{display:-webkit-box;display:-ms-flexbox;display:flex}.fl-builder--main-menu-panel:before,.fl-theme-builder-preview-select-open .fl-theme-builder-preview-select-items:before{bottom:100%;right:6px;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:solid;border-color:rgba(255,255,255,0);border-bottom-color:#00a0d2;border-width:13px;margin-left:-13px}.fl-builder--main-menu-panel-views{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;overflow:auto}.fl-builder--main-menu-panel-mask{display:none;position:fixed;top:0;left:0;right:0;bottom:0;z-index:1000119}.fl-builder--main-menu-panel .fl-builder--tabs{padding-left:20px;padding-top:15px}.fl-builder--main-menu-panel-view{display:none}.fl-builder--main-menu-panel-view.is-showing{display:block}.fl-builder--main-menu-panel-view-title{font-size:24px;font-weight:600;padding:25px 22px 0;line-height:1;white-space:nowrap}.fl-builder--main-menu-panel-view-title .title-accessory{float:right;color:#b1b1b1}.fl-builder--main-menu-panel-view-title .title-accessory>i{font-size:20px!important;width:25px!important}.fl-builder--main-menu-panel-view-title .title-accessory>i:hover{color:#222}.fl-builder--main-menu-panel-view-title .pop-view{padding:10px;margin-left:-10px;opacity:.5;font-size:25px;font-weight:400;cursor:pointer;background:0 0;outline:0;border:none;color:inherit}.fl-builder--main-menu-panel-view-title .pop-view:focus{outline:0;top:0;background:#E5EAED!important}.fl-builder--menu-item:before{display:block;content:"";float:none;clear:both}.fl-builder--menu-item{color:inherit;text-align:left;box-sizing:border-box;display:block;padding:10px 15px;margin:0 10px;width:calc(100% - 20px);background:0 0;border:none;border-radius:4px;font-size:14px;line-height:1.1;cursor:pointer;opacity:1}.fl-builder--menu-item:hover{background:#eaf1f8;border:none;text-decoration:none;color:#000}.fl-builder--selector-menu .fl-builder--menu-item:hover{background:#fff}.fl-builder--menu-item-accessory{float:right;text-align:center;display:inline-block;min-width:40px;font-size:14px}.fl-builder--menu-item-accessory.view-arrow{font-size:18px}.fl-builder--menu{padding:0;margin:20px 0}.fl-builder--menu hr{margin:8px 0;background-color:#e6eaed!important;height:2px;border:none}.fl-builder--menu .fl-builder-video-wrap{padding:0 10px 10px}.fl-revision-list-item{display:-webkit-box;display:-ms-flexbox;display:flex}.fl-revision-list-item-text{padding-left:15px}.fl-revision-list-item-date{padding-bottom:5px}.fl-builder--revision-actions{display:none;position:fixed;top:4px;left:4px;z-index:100008;padding:4px 4px 6px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;background:#fff;border-radius:4px}.fl-builder--revision-actions *{margin-right:5px}.fl-builder--revision-actions :last-child{margin:0}.fl-builder--menu-item[data-event=noRevisionsMessage]:hover{background:0 0;box-shadow:none;cursor:default}.fl-no-revisions-message-title{font-weight:700;margin-bottom:10px}.fl-no-revisions-message-text{line-height:22px}.fl-builder-module-placeholder-message{border:1px dashed #ccc;overflow:hidden;padding:20px;text-align:center;text-overflow:ellipsis;white-space:nowrap}.fl-field-connections-menu{z-index:999999}.fl-field-connections-toggle{right:-30px!important}.fl-builder-add-ultimate-presets-button,.fl-builder-add-ultimate-rows-button,.fl-builder-pp-add-template-button,.pp-preview-button,.uabb-live-preview-button{display:none!important}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none;background:0 0;transition-property:background;transition-duration:.15s}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-ne,.ui-resizable-nw,.ui-resizable-se,.ui-resizable-sw{width:12px;height:12px}.ui-resizable-se{cursor:se-resize;right:-4px;bottom:-4px}.ui-resizable-sw{cursor:sw-resize;left:-4px;bottom:-4px}.ui-resizable-nw{cursor:nw-resize;left:-4px;top:-4px}.ui-resizable-ne{cursor:ne-resize;right:-4px;top:-4px}.fl-builder-resizable-iframe-fix{position:absolute;top:0;right:0;bottom:0;left:0;z-index:100000000}.fl-builder-panel .ui-resizable-handle:active,.fl-builder-panel .ui-resizable-handle:hover,.fl-lightbox .ui-resizable-handle:active,.fl-lightbox .ui-resizable-handle:hover{background:#00a0d2}.fl-builder-panel .ui-resizable-n,.fl-builder-panel .ui-resizable-s,.fl-lightbox .ui-resizable-n,.fl-lightbox .ui-resizable-s{height:6px}.fl-builder-panel .ui-resizable-n,.fl-lightbox .ui-resizable-n{top:-3px}.fl-builder-panel .ui-resizable-s,.fl-lightbox .ui-resizable-s{bottom:-3px}.fl-builder-panel .ui-resizable-e,.fl-builder-panel .ui-resizable-w,.fl-lightbox .ui-resizable-e,.fl-lightbox .ui-resizable-w{width:6px}.fl-builder-panel .ui-resizable-e,.fl-lightbox .ui-resizable-e{right:-3px}.fl-builder-panel .ui-resizable-w,.fl-lightbox .ui-resizable-w{left:-3px}.fl-lightbox .ui-resizable-ne,.fl-lightbox .ui-resizable-nw,.fl-lightbox .ui-resizable-se,.fl-lightbox .ui-resizable-sw{background:0 0;border:6px solid transparent}.fl-lightbox .ui-resizable-ne:active,.fl-lightbox .ui-resizable-ne:hover,.fl-lightbox .ui-resizable-nw:active,.fl-lightbox .ui-resizable-nw:hover,.fl-lightbox .ui-resizable-se:active,.fl-lightbox .ui-resizable-se:hover,.fl-lightbox .ui-resizable-sw:active,.fl-lightbox .ui-resizable-sw:hover{background:0 0;border-color:#00a0d2}.fl-lightbox .ui-resizable-ne{border-bottom:none;border-left:none;border-top-right-radius:4px}.fl-lightbox .ui-resizable-nw{border-bottom:none;border-right:none;border-top-left-radius:4px}.fl-lightbox .ui-resizable-se{border-top:none;border-left:none;border-bottom-right-radius:4px}.fl-lightbox .ui-resizable-sw{border-top:none;border-right:none;border-bottom-left-radius:4px}.fl-builder-ui-keyboard-shortcuts{display:none;position:fixed;top:0;left:0;bottom:0;right:0;z-index:999999;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgba(50,50,50,.88);font-size:15px;line-height:1.3;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fl-builder-ui-keyboard-shortcuts.is-showing{display:-webkit-box;display:-ms-flexbox;display:flex}.fl-builder-ui-keyboard-shortcuts-content{box-sizing:border-box;width:500px;background:#f5f7f9;border-radius:4px;padding:30px 0 0;box-shadow:0 10px 30px rgba(0,0,0,.15)}.fl-builder-ui-keyboard-shortcut-item{display:-webkit-box;display:-ms-flexbox;display:flex;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:12px 40px}.fl-builder-ui-keyboard-shortcust-footer,.fl-color-picker{display:-webkit-box;display:-ms-flexbox;-ms-flex-direction:row;-webkit-box-orient:horizontal;-webkit-box-direction:normal}.fl-builder-ui-keyboard-shortcut-item:nth-child(even){background:#eef2f5}.fl-builder-ui-shortcut-keycode{margin-left:auto;text-transform:uppercase;letter-spacing:2px}.fl-builder-ui-keyboard-shortcust-footer{display:flex;flex-direction:row;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:10px}.dismiss-shortcut-ui{padding:10px;border-radius:4px;background:#fff;color:#000;font-size:14px;border:2px solid #fff}.dismiss-shortcut-ui:focus,.dismiss-shortcut-ui:hover{top:0;color:#000;background:#eef2f5;border:2px solid #eef2f5}.fl-color-picker-ui{width:300px}.fl-color-picker-ui.fl-color-alpha-enabled{width:238px}.fl-color-picker-ui .iris-picker{float:left;width:100%;height:224px;display:block;position:relative;border-top:1px solid rgba(0,0,0,.1)}.fl-color-picker-ui .iris-picker .iris-square-inner,.fl-color-picker-ui .iris-picker-inner{position:absolute;left:0;top:0;bottom:0;right:0}.fl-color-picker-ui .iris-picker,.iris-picker *{box-sizing:content-box}.fl-color-picker-ui .iris-error{background-color:#ffafaf}.fl-color-picker-ui .iris-picker .iris-square{width:300px;height:200px}.fl-color-picker-ui .iris-picker .iris-palette,.fl-color-picker-ui .iris-picker .iris-slider,.fl-color-picker-ui .iris-picker .iris-square-inner{height:100%;width:12.5%}.fl-color-picker-ui .iris-picker .iris-placeholder,.fl-color-picker-ui .iris-picker .iris-square{position:relative}.fl-color-picker-ui .iris-picker .iris-square-inner{width:auto;margin:0}.fl-color-picker-ui .iris-ie-9 .iris-palette,.fl-color-picker-ui .iris-ie-9 .iris-slider,.fl-color-picker-ui .iris-ie-9 .iris-square,.fl-color-picker-ui .iris-ie-9 .iris-square-inner{box-shadow:none;border-radius:0}.fl-color-picker-ui .iris-ie-9 .iris-palette,.fl-color-picker-ui .iris-ie-9 .iris-slider,.fl-color-picker-ui .iris-ie-9 .iris-square{outline:rgba(0,0,0,.1) solid 1px}.fl-color-picker-ui .iris-ie-lt9 .iris-palette,.fl-color-picker-ui .iris-ie-lt9 .iris-slider,.fl-color-picker-ui .iris-ie-lt9 .iris-square,.fl-color-picker-ui .iris-ie-lt9 .iris-square-inner{outline:#999 solid 1px}.fl-color-picker-ui .iris-ie-lt9 .iris-square .ui-slider-handle{outline:#999 solid 1px;background-color:#fff;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"}.fl-color-picker-ui .iris-ie-lt9 .iris-square .iris-square-handle{background:0 0;border:3px solid #fff;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"}.fl-color-picker-ui .iris-picker .iris-strip{box-sizing:border-box;width:calc(300px - 12px);margin:5px 6px 6px;border-radius:4px;position:relative;height:22px;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fl-color-picker-ui .iris-picker .iris-strip .ui-slider-handle{width:6px;position:absolute;right:0;top:-2px;bottom:-2px;margin:0;border-radius:3px;background:#fff;box-shadow:0 0 2px rgba(0,0,0,.5);z-index:5;cursor:ew-resize}.fl-color-picker-ui .iris-picker .iris-strip .ui-slider-handle:focus{outline:#00a0d2 solid 2px}.fl-color-picker-ui .iris-picker .iris-slider-offset{position:absolute;top:0;left:6px;right:0;bottom:0;width:auto;height:auto;background:0 0;border:none;border-radius:0;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fl-color-picker-ui .iris-picker .iris-square-handle{background:0 0;border:5px solid #999;border-radius:50%;border-color:rgba(128,128,128,.5);box-shadow:none;width:12px;height:12px;position:absolute;left:-10px;top:-10px;cursor:move;opacity:1;z-index:10}.fl-color-picker-ui .iris-picker .ui-state-focus .iris-square-handle{opacity:.8}.fl-color-picker-ui .iris-picker .iris-square-handle:hover{border-color:#999}.fl-color-picker-ui .iris-picker .iris-square-value:focus .iris-square-handle{box-shadow:0 0 2px rgba(0,0,0,.75);opacity:.8}.fl-color-picker-ui .iris-picker .iris-square-handle:hover::after{border-color:#fff}.fl-color-picker-ui .iris-picker .iris-square-handle::after{position:absolute;bottom:-4px;right:-4px;left:-4px;top:-4px;border:3px solid #f9f9f9;border-color:rgba(255,255,255,.8);border-radius:50%;content:" "}.fl-color-picker-ui .iris-picker .iris-square-value{width:8px;height:8px;position:absolute}.iris-ie-lt9 .iris-square-value,.iris-mozilla .iris-square-value{width:1px;height:1px}.fl-color-picker-wrapper{position:relative;width:48px;height:32px}.fl-color-picker{box-shadow:0 2px 4px 0 rgba(0,0,0,.12);background:#fff;border-radius:4px;width:120px;height:36px;display:flex;flex-direction:row}.fl-color-picker-color{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;box-sizing:border-box!important;position:relative;border-radius:4px;background-color:transparent;cursor:pointer;border:2px solid transparent;border-right:2px solid rgba(0,0,0,.1);padding:0;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;display:-webkit-box;display:-ms-flexbox;display:flex}.fl-color-picker-clear:hover,.fl-color-picker-color:hover{background:0 0;border:2px solid transparent}.fl-color-picker-clear:focus,.fl-color-picker-color.fl-color-picker-empty:focus,.fl-color-picker-color:focus{outline:0;top:0;border:2px solid #00a0d2;background:0 0}.fl-color-picker.fl-color-picker-has-reset .fl-color-picker-color:not(.fl-color-picker-empty){border-top-right-radius:0;border-bottom-right-radius:0}.fl-color-picker-icon{display:none;margin:auto}.fl-color-picker-color.fl-color-picker-empty{border-color:transparent}.fl-color-picker-color.fl-color-picker-empty svg.fl-color-picker-icon{display:block}.fl-color-picker-clear{box-sizing:border-box;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 0 36px;flex:0 0 36px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:0;border:2px solid transparent;border-top-right-radius:4px;border-bottom-right-radius:4px;background-color:#fff;cursor:pointer}.fl-color-picker-color.fl-color-picker-empty+.fl-color-picker-clear{display:none}.fl-color-picker-ui{display:inline-block;font-family:Helvetica,Verdana,sans-serif;z-index:999999;position:fixed;overflow:hidden;padding-bottom:45px;border:1px solid rgba(0,0,0,.1);color:#999;background-color:#FAFAFA;border-radius:3px;box-shadow:0 9px 20px rgba(0,0,0,.17);transition:opacity .2s,visibility .2s;visibility:hidden;opacity:0;-webkit-transform:translate3d(0,0,0)}.fl-color-picker-ui.fl-color-picker-active{visibility:visible;opacity:1}.fl-color-picker-ui .fl-color-picker-input,.fl-color-picker-ui .fl-color-picker-input:focus{width:100%;height:30px;border:none!important;font-size:14px!important;padding:0 8px;vertical-align:middle;color:#656c6e;background-color:#fff;border-radius:0;box-shadow:none}.fl-color-picker-ui .iris-square-value{transition:none}.fl-color-picker-preset-add{position:absolute;top:8px;right:8px;width:14px;height:14px;background-color:#656c6e;border-radius:50%;cursor:pointer;transition:all .2s}.fl-color-picker-preset-add:hover{background-color:#333}.fl-color-picker-preset-add:after,.fl-color-picker-preset-add:before{content:'';display:block;position:relative;background-color:#fff}.fl-color-picker-preset-add:before{top:6px;left:3px;width:8px;height:2px}.fl-color-picker-preset-add:after{left:6px;top:1px;width:2px;height:8px}.fl-color-picker-presets{position:absolute;left:0;bottom:0;width:100%;z-index:15;overflow:auto;border-top:1px solid rgba(0,0,0,.1);background-color:#FAFAFA}.fl-color-picker-presets-list .fl-color-picker-preset:hover,.fl-color-picker-presets-toggle:hover{background-color:#EDEDED}.fl-color-picker-presets-toggle{position:relative;overflow:hidden;width:100%;height:35px;text-align:center;line-height:35px;font-size:12px;font-weight:700;cursor:pointer;transition:all .1s}.fl-color-picker-presets-close-label,.fl-color-picker-presets-open-label{position:absolute;top:50%;left:50%;visibility:hidden;color:#999;transition:all .5s;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;width:100%}.fl-color-picker-presets-close-label.fl-color-picker-active,.fl-color-picker-presets-open-label.fl-color-picker-active{color:#656c6e;visibility:visible;opacity:1}.fl-color-picker-presets-list{width:100%;list-style:none;margin:0;padding:0;overflow:auto}.fl-color-picker-presets-list .fl-color-picker-no-preset,.fl-color-picker-presets-list .fl-color-picker-preset{position:relative;padding:5px;font-size:12px;border-top:1px solid rgba(0,0,0,.1);transition:all .1s}.fl-color-picker-presets-list .fl-color-picker-no-preset{padding:18px 5px;text-align:center}.fl-color-picker-presets-list .fl-color-picker-preset-color{display:inline-block;width:40px;height:20px;margin-right:3px;vertical-align:middle;border:1px solid rgba(0,0,0,.1);border-radius:2px;cursor:pointer}.fl-color-picker-presets-list .fl-color-picker-preset-label{vertical-align:middle;color:#333;cursor:pointer}.fl-color-picker-presets-list .fl-color-picker-preset-remove{position:absolute;top:50%;cursor:pointer;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.fl-color-picker-clear .fl-color-picker-icon-remove{right:auto;top:auto;margin:auto}.fl-color-picker-presets-list .fl-color-picker-preset-remove{right:5px}.fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:after,.fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:before{background-color:#333}.fl-color-picker-added{position:absolute;width:100%;top:0;left:0;right:0;bottom:35px;z-index:10;color:#fff;text-align:center;background-color:rgba(0,0,0,.8)}.fl-color-picker-added-text{position:absolute;top:50%;left:50%;width:80%;font-size:14px;color:#fff!important;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.fl-color-picker-icon-check{position:relative;width:50px;height:50px;margin:5px auto}.fl-color-picker-icon-check:before{content:'';display:block;position:relative;width:15px;height:30px;margin-left:14px;border:7px solid #fff;border-left:none;border-top:none;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.fl-color-picker-icon-arrow-down,.fl-color-picker-icon-arrow-up{display:inline-block;position:relative;width:10px;height:10px;margin-left:5px}.fl-color-picker-icon-arrow-down:before,.fl-color-picker-icon-arrow-up:before{content:'';display:block;position:relative;width:6px;height:6px;border:2px solid #999;border-left:none;border-top:none;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.fl-color-picker-icon-arrow-up{top:2px;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fl-color-picker-icon-remove{width:15px;height:15px}.fl-color-picker-icon-remove:after,.fl-color-picker-icon-remove:before{content:'';display:block;position:relative;background-color:#6f7881}.fl-color-picker-icon-remove:before{left:6px;width:2px;height:10px;margin-top:3px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.fl-color-picker-icon-remove:after{left:6px;width:2px;height:10px;margin-top:-10px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.fl-alpha-wrap{position:absolute;width:35px;height:215px;padding:0 5px;right:4px;border-top:none}.fl-alpha-slider{height:190px;position:absolute;top:12px;width:28px}.fl-alpha-slider .ui-slider-handle{background:rgba(0,0,0,0);border-color:#aaa;border-radius:4px;border-style:solid;border-width:4px;box-shadow:0 1px 2px rgba(0,0,0,.2);-moz-box-shadow:0 1px 2px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.2);cursor:ns-resize;height:12px;left:0;opacity:.9;position:absolute;right:0;width:30px;z-index:14}.fl-alpha-slider .ui-slider-handle:before{content:" ";position:absolute;left:-2px;right:-2px;top:-3px;bottom:-3px;border:2px solid #fff;border-radius:3px}.fl-alpha-slider-offset{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAASCAYAAAAe/ZHXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NkNEQUQ0ODM4RUE0MTFFNEExOEJFN0E5M0VFOTg0QUQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NkNEQUQ0ODQ4RUE0MTFFNEExOEJFN0E5M0VFOTg0QUQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2Q0RBRDQ4MThFQTQxMUU0QTE4QkU3QTkzRUU5ODRBRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2Q0RBRDQ4MjhFQTQxMUU0QTE4QkU3QTkzRUU5ODRBRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/r/N8AAAWYSURBVHjarFvvR3VBEN45JZGIPkREHyIiIhJJf3qUSERE9CGiDxERkcg9z9u92uucvTszz5z7xnHPj93Z2d359cxscn5+jpTS+EoiMr3/+51cZ2dn4+e29i2/u7y8RKf/pO3vc+o+n5ycoNK31+f6+jrfZ37yuG2mf3R01H3fa5N/b29vU6dP5qft0G4PDg5MGuPr/v4+jz1t27mfvN/b21P75+fHx8eZfiV/Ozs7rUJnSu/5+RlFv+m6ZJpbW1s1PnrvXl9fZ/qX89zY2LB4mfy+v7/nsdV1XltbK/dr5vnz87OcV5bJabuVlRVLBifjfX9/l/xkGtM+S0tLNXnu0szfU/P3IMn/k0678h6ddqjQFGccVL6hoCsVfsq+NZ5QtCv5rfFS41sq37W+UPhMyhxEWTetvce3NR8oewqD39qalXuGAK/WPltjajIC4x2c9Ye1f43SGcqGwRBeTZjhMNntL4pCWZMQYhE05RVl02EovRgC4RkCbUNSQAGhGB/GsKG4h6FQoigDa2i8fRBy3uLMXYIG3Vr3aZvRaCRdBYlYIMZywhBGCVhgzzOlgRuUSOvC0GMEWxOM/+EtQFh1OIIXtfwg1tRaayGjg5px0jyZKEaTle3e+AsLCygVRAh3FlEgKbReE3oYGj9EgIR00QiEgKw3ZBQbRGjBeAMtDETQmHiKDsezJNLgCTFGItZXlAgCSiQggblP+9c8SDI0lXWlFv5g3K63KZ51FOcZzthQ3LomoNHwJmKIQISI3vqzSpwIQ8liSjGMFQjDpoVgaQ6cWgvLhOC7qiAwiHrWbEg4JMSmeUrBuHoYwioOQNXmhmAcrs096s1gJCGi3hSEVU8DQxYElYHhKwUUGAa+NqOBMsSSAQJuhQhCAH4vxozExsxiihPuaIrjCVYKWlYEsjSM52G8Kxxryngl5j0j+EyGTIiED4s1Itm0ZGWxMFCLJaBAcEI6OBkmFgNBoc8Cait2ZnENE/6wQN8LJSJeSMNAjKVm+LUMAIt3PR5AQgIGp1Z5zxhE8PtXUYReYeXi4mKmOPNXBMzt2tPT07LIUtJqr66uusXEbkFnWiQ6Pj72ikrtzc1NKopuvbbj58PDwxqNHp27u7tuYWumUDV+v7+/Xyu6pc59+/DwUCsC9ujt7u6qRbt8//T01C3elbyN70fb29uZ/1FSincvLy/lPGb42tzc9IqJeHt7q61Pr2C6vr7u7tfHx8fMPhV0sLq6WhZtU0n36+uru8elPE7aLi8v1wqJPXn++fmZKYgX8ozFxcXJb0NaQTHClZT8+gBjsYdaFc+zWcUkGTCWENY66ta92oSVzo3WI6IZKGtukeyfBLFKBNAj6bUOBgaoe9wE4n04IBNkLMoC7+Skj630ZlTJMYdyMsU2T8AwpzALkVFilZgJcT2l9PCWDDSAMBSjVlJgZNk0lE1AIby0qCiCnBQNj6aBGQslZIZJ5hB6D/AzQHto5Z9Nk8tARdN4q2ExBnsyIJ311EymShyjan2rKk0zh1Ay1oQVWAZQRnkUA8RFw7TahjBnmNgMVMQrsCGZJezRtGlU0cUZ1zuaxGZPpbhApM+ZpFQqQ6xadoMtBrEKpBVo4GRXvNSxpaRixKiR+TChCYhsDwZkfFj8IkErjAHejcUI0XQrgwehhNSMHAz21E0wZ23FcCAmj8Sd/PXy2xLYLAuwRw4IMsqjFaWYOpMEhDySAPFCWyFkgAHrEcA+BNeJ4UE8HCzJPpCrerUmQIx1pWJkjqxJD8EikUo2c5aI8ZYgsAkM4WQtnHd0ns0ORgVTBghy5ISy928SGsbTMqYg523RUY8oNYG4FIYiyRyZCnFCJC87IoRAIMVOqQ7BKexxCS2hYVl9JhvlpYjnAe4MhmRPMWhhvLfXINaI9WKM0Zu0+SfAAFLE1EgfVSv7AAAAAElFTkSuQmCC) center;box-shadow:0 0 5px rgba(0,0,0,.4) inset;-moz-box-shadow:0 0 5px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 5px rgba(0,0,0,.4) inset;width:200px;height:22px;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);bottom:48%;left:-80px;position:absolute}.fl-alpha-text{width:30px;font-size:12px;text-align:center;color:#999;position:absolute;bottom:-5px}.fl-lightbox-wrap.fl-icon-selector{z-index:1000111}.fl-icon-selector .fl-lightbox{height:100%}.fl-icons-filter{height:auto!important;margin:0!important;position:absolute!important;right:0;top:0;padding:10px 16px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.fl-icons-filter select{vertical-align:middle;width:160px;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;color:#000;border:2px solid #e4e7ea!important;border-right:none!important;margin:0;padding:2px 10px;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important;-webkit-box-flex:1;-ms-flex:1 1 160px;flex:1 1 160px;border-radius:0}.fl-icons-filter input[type=text]{line-height:18px;vertical-align:middle;width:160px;-webkit-box-flex:1;-ms-flex:1 1 160px;flex:1 1 160px;border:2px solid #e4e7ea!important;border-radius:0!important;padding:2px 10px!important}.fl-icons-filter input[type=text]:focus,.fl-icons-filter select:focus{border:2px solid #00A0D2!important}.fl-icons-list{bottom:52px;left:0;overflow:auto;padding:20px;position:absolute;right:0;top:48px}.fl-icons-list::-webkit-scrollbar{background-color:#ccc;-webkit-appearance:none;width:10px}.fl-icons-list::-webkit-scrollbar-thumb{background-color:#666;border:1px solid #ccc}.fl-icons-section{text-align:center}.fl-icons-section h2{border-bottom:1px solid #dfdfdf;color:#333!important;font-family:Helvetica,Verdana,sans-serif!important;font-size:16px!important;font-weight:700!important;margin:0 0 20px!important;padding:0 0 10px!important;text-align:left}.fl-icons-list i,.fl-icons-list i:before{cursor:pointer;display:inline-block;font-size:40px;height:100px;line-height:100px;width:100px;background:0 0}.fl-icons-list i:hover{background:#fff;box-shadow:0 10px 20px rgba(0,0,0,.15);border-radius:4px}.fl-icon-selector-footer{bottom:0;left:0;position:absolute;right:0}.fl-lightbox-mask,.fl-lightbox-wrap{bottom:0;left:0;position:fixed;right:0;z-index:100010}@-webkit-keyframes fl-lightbox-zoom{from{-webkit-transform:scale(.4);transform:scale(.4)}to{-webkit-transform:scale(1);transform:scale(1)}}@keyframes fl-lightbox-zoom{from{-webkit-transform:scale(.4);transform:scale(.4)}to{-webkit-transform:scale(1);transform:scale(1)}}.fl-lightbox-wrap{display:none;overflow:auto;padding:4px;top:46px;-webkit-transform:translateZ(0);pointer-events:none}.fl-builder-draggable-is-dragging .fl-lightbox-wrap,.fl-builder-resizable-is-resizing .fl-lightbox-wrap,.fl-lightbox,.fl-lightbox-mask{pointer-events:auto}.fl-lightbox-mask{background:#000;opacity:.7;filter:alpha(opacity=70);top:0}.fl-lightbox{background:#F5F7F9;border-radius:4px;box-shadow:rgba(0,0,0,1) 0 4px 30px;-moz-box-shadow:rgba(0,0,0,1) 0 4px 30px;-webkit-box-shadow:rgba(0,0,0,1) 0 4px 30px;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;z-index:100011;-webkit-transform-origin:center;transform-origin:center;-webkit-animation-name:fl-lightbox-zoom;animation-name:fl-lightbox-zoom;-webkit-animation-duration:.25s;animation-duration:.25s}.fl-lightbox.fl-lightbox-prevent-animation{animation-duration:0s;-moz-animation-duration:0s;-webkit-animation-duration:0s;-o-animation-duration:0s}.fl-lightbox :not(i){color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:13px;line-height:16px;text-decoration:none;text-transform:none}.fl-lightbox *,.fl-lightbox :after,.fl-lightbox :before{box-sizing:content-box}.fl-lightbox .fl-nanoscroller-pane{bottom:4px;right:4px;width:8px}.fl-lightbox .fa{font-family:FontAwesome}.fl-lightbox .dashicons{font-family:dashicons}.fl-lightbox.ui-draggable{box-shadow:rgba(0,0,0,.2) 0 7px 30px;-moz-box-shadow:rgba(0,0,0,.2) 0 7px 30px;-webkit-box-shadow:rgba(0,0,0,.2) 0 7px 30px}.fl-lightbox-resizable{height:500px;width:380px}@media (max-width:500px){.fl-lightbox-resizable{left:0!important;right:0!important;top:0!important;height:100%!important;width:100%!important}.fl-lightbox-resizable .ui-resizable-handle{display:none!important}.fl-lightbox.ui-draggable .fl-lightbox-header{cursor:default!important}.fl-lightbox-controls{display:none}}.fl-lightbox-width-full{left:0!important;right:0!important;top:0!important;height:100%!important;width:100%!important}.fl-lightbox-width-full .fl-lightbox-header{cursor:inherit!important}.fl-lightbox-controls{position:absolute;right:10px;top:10px;z-index:5}.fl-lightbox-controls .fa{color:#bdbdbd;font-size:14px;padding:5px}.fl-lightbox-controls .fa:hover{color:#aaa;cursor:pointer}.fl-lightbox-header-wrap{background:#fff;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:2px solid #eaeaea}.fl-lightbox-header{position:relative}.fl-lightbox-header h1{color:#333!important;font-size:20px!important;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important;font-weight:600!important;margin:0!important;padding:14px 34px 15px 28px!important;text-align:left!important;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;line-height:1.1}.fl-lightbox.ui-draggable .fl-lightbox-header{cursor:move}.fl-lightbox-header h1 .fl-builder-badge{margin-left:10px}.fl-lightbox-content,.fl-lightbox-content-wrap{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-flex:1;-ms-flex:1 100%;flex:1 100%;height:100%;max-width:100%}.fl-lightbox-footer{box-sizing:border-box;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-flex:0;-ms-flex:0 0;flex:0 0;-ms-flex-preferred-size:44px;flex-basis:44px;padding:4px;text-align:right}.fl-lightbox-footer .fl-builder-button{height:36px;margin-left:5px!important;-webkit-box-flex:0;-ms-flex:0 0 0%;flex:0 0 0%;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.fl-lightbox-width-slim .fl-lightbox-footer{-webkit-box-pack:stretch;-ms-flex-pack:stretch;justify-content:stretch;padding:4px 5px}.fl-lightbox-width-slim .fl-lightbox-footer .fl-builder-button{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;display:block;text-align:center}.fl-lightbox-width-slim .fl-lightbox-footer .fl-builder-button:first-child{margin-left:0!important}.fl-lightbox table,.fl-lightbox td,.fl-lightbox th,.fl-lightbox tr{border:none}.fl-builder-ui-skin--dark .fl-builder--main-menu-panel,.fl-builder-ui-skin--dark .fl-builder--preview-actions,.fl-builder-ui-skin--dark .fl-builder--search-results-panel,.fl-builder-ui-skin--dark .fl-builder-panel,.fl-builder-ui-skin--dark .fl-lightbox,body.fl-builder-ui-skin--dark .fl-builder-bar .fl-builder-bar-content{background:#23282d;color:#b4b9be;border-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder--panel-header{background:#1d2227;color:#b4b9be;border-bottom-color:#1d1d1d;border-top-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder-panel.fl-builder-ui-pinned .fl-builder--panel-header{border-top-color:#1d2227}.fl-builder-ui-skin--dark .fl-builder--main-menu-panel:before{border-bottom-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder--panel-arrow polygon{fill:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder-panel-search .fl-builder-panel-search-input{background:#1e2228}.fl-builder-ui-skin--dark .fl-responsive-preview-content{background:#131619}.fl-builder-ui-skin--dark .fl-form-table th{background:#23282d!important;color:#7d8690}.fl-builder-ui-skin--dark .fl-builder--preview-actions .device-icons,.fl-builder-ui-skin--dark .fl-builder-button{background:#383f46}.fl-builder-ui-skin--dark .fl-builder-button:focus{background:#131a22}.fl-builder-ui-skin--dark .fl-builder-button.fl-builder-button-primary{color:#fff!important;fill:#fff!important;background:#00A0D2}.fl-builder-ui-skin--dark .fl-builder-button.fl-builder-button-silent:focus{border:2px solid #00a0d2!important}.fl-builder-ui-skin--dark .fl-builder-content-panel--button:hover,.fl-builder-ui-skin--dark .fl-builder-content-panel-button{color:#00A0D2!important}.fl-builder-ui-skin--dark .fl-builder--menu>a:hover,.fl-builder-ui-skin--dark .fl-builder--menu>button:hover{background:#101215!important}.fl-builder-ui-skin--dark .fl-builder--menu>a:focus,.fl-builder-ui-skin--dark .fl-builder--menu>button:focus{background:#101215!important;color:#fff!important}.fl-builder-ui-skin--dark .fl-builder-bar-title{border-color:#101215}.fl-builder-ui-skin--dark .fl-builder-bar-title:hover{background-color:#181b1f}.fl-builder-simple.fl-builder-ui-skin--dark .fl-builder-bar-title:hover{background-color:transparent}.fl-builder-ui-skin--dark .fl-builder-layout-title{color:#c6cdd6}.fl-builder-ui-skin--dark .fl-builder-bar-title-caret i,.fl-builder-ui-skin--dark .fl-builder-layout-pretitle,.fl-builder-ui-skin--dark .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title{color:#7d8690}.fl-builder-ui-skin--dark button.fl-builder-button.fl-builder-bar-title-caret:focus{background-color:#101215!important}.fl-builder-ui-skin--dark .fl-builder--search:before{color:rgba(162,173,184,.73)}.fl-builder-ui-skin--dark .fl-builder--search input:focus::-webkit-input-placeholder{color:rgba(162,173,184,.73)!important}.fl-builder-ui-skin--dark .fl-builder--search .search-clear{color:rgba(162,173,184,.5);background-color:#e4e4e4;background:linear-gradient(to left,#383f46,#383f46 75%,rgba(56,63,70,0))}.fl-builder-ui-skin--dark .fl-builder--menu hr{background-color:#23282d!important;border:none}.fl-builder-ui-skin--dark .fl-builder--tabs{border-color:#383f46!important}.fl-builder-ui-skin--dark .fl-builder--tabs>.is-showing,.fl-builder-ui-skin--dark .fl-builder-settings-tabs a.fl-active,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-more.fl-contains-active{color:#fff!important;fill:#fff!important;background:#383f46}.fl-builder-ui-skin--dark .fl-builder--tabs>:focus{background-color:#101215!important;color:#fff!important}.fl-builder-ui-skin--dark .fl-builder--tabs>.is-showing:focus{color:#00a0d2!important}.fl-builder-ui-skin--dark .fl-builder--menu-item:hover{background:#383f46;color:#a8b3bf}.fl-builder-ui-skin--dark .fl-builder--menu * .fl-builder--menu-item-accessory,.fl-builder-ui-skin--dark .fl-builder-blocks-section-group-name{color:#7d8690}.fl-builder-ui-skin--dark .fl-builder--category-select{background:#171b1f}.fl-builder-ui-skin--dark .fl-builder--selector-display{color:#c6cdd6;background:url(../img/svg/select-arrow-down-alt2-light.svg) center right 10px no-repeat #171b1f!important}.fl-builder-ui-skin--dark .fl-builder--selector-display-label,.fl-builder-ui-skin--dark .fl-builder-panel-search-input input{border-color:#5b656f;color:#b5becb}.fl-builder-ui-skin--dark .fl-builder-panel-search-input input{background:#171b1f!important}.fl-builder-ui-skin--dark .fl-builder--selector-display-label:focus,.fl-builder-ui-skin--dark .fl-builder-panel-search-input input:focus{border-color:#00a0d2}.fl-builder-ui-skin--dark .fl-builder--group-label{color:#171b1f!important;background:#5b656f}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu{border-color:#101215!important;color:#7c858e;background-color:#101215}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu:before{border-bottom-color:#101215}.fl-builder-ui-skin--dark .fl-builder--menu>a,.fl-builder-ui-skin--dark .fl-builder--menu>button,.fl-builder-ui-skin--dark .fl-builder--menu>span{color:#a1adb9}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu .fl-builder--menu-item:hover{background:#23282d!important;color:#a1adb9}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu .fl-builder--menu-item:focus{background:#23282d!important;color:#00a0d2!important}.fl-builder-ui-skin--dark .fl-builder-panel-drag-handle{fill:#5b656f}.fl-builder-ui-skin--dark .fl-builder--template-collection-section-name,.fl-builder-ui-skin--dark .fl-builder--user-templates-section-name,.fl-builder-ui-skin--dark .fl-builder-blocks-section .fl-builder-blocks-section-title{color:#969ea7;background:#171b1f}.fl-builder-ui-skin--dark .fl-builder-blocks-section-content .fl-builder-block,.fl-builder-ui-skin--dark .fl-user-template{color:#b8c2ce}.fl-builder-ui-skin--dark .fl-builder-block:hover .fl-builder-block-content,.fl-builder-ui-skin--dark .fl-user-template:hover{background:#171b1f;color:#fff}.fl-builder-ui-skin--dark .fl-builder-block:hover i,.fl-builder-ui-skin--dark .fl-user-template:hover i{color:#6d7782!important}.fl-builder-ui-skin--dark .fl-builder-block:hover a:hover i,.fl-builder-ui-skin--dark .fl-user-template:hover a:hover i{color:#9eacbb!important}.fl-builder-ui-skin--dark .fl-builder-block .fl-builder-block-icon{fill:#b5becb}.fl-builder-ui-skin--dark .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col,.fl-builder-ui-skin--dark .fl-builder-block:hover .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col{background:#7d8690}.fl-builder-ui-skin--dark .fl-builder-blocks-section,.fl-builder-ui-skin--dark .fl-builder-settings-section{border-top:2px solid #171b1f}.fl-builder-ui-skin--dark .fl-user-templates{border-color:#101215}.fl-builder-ui-skin--dark .fl-builder--template-thumbnail{border-color:#393f44}.fl-builder-ui-skin--dark .fl-builder--menu a.fl-template-collection{color:#a8b3bf}.fl-builder-ui-skin--dark .fl-lightbox-header-wrap{background:#1d2227;border-bottom-color:#131a22}.fl-builder-ui-skin--dark .fl-lightbox .fl-lightbox-header h1{color:#fff!important}.fl-builder-ui-skin--dark .fl-form-table th label{color:#a8b3bf!important}.fl-builder-ui-skin--dark .fl-builder-settings-tabs{border-color:#383f46!important}.fl-builder-ui-skin--dark .fl-builder-settings-fields h3.fl-builder-settings-title{background:#1b2025}.fl-builder-ui-skin--dark h3.fl-builder-settings-title .fl-builder-settings-title-text-wrap{color:#a8b3bf;background-color:#1b2025}.fl-builder-ui-skin--dark .fl-lightbox :not(i){color:#7d8690!important}.fl-builder-ui-skin--dark .fl-builder-button{color:#c6cdd6!important;fill:#c6cdd6!important}.fl-builder-ui-skin--dark .fl-builder-content-panel--button:hover,.fl-builder-ui-skin--dark .fl-builder-content-panel-button{fill:#00A0D2!important}.fl-builder-ui-skin--dark .fl-lightbox .fl-builder-button.fl-builder-button-primary{color:#fff!important}.fl-builder-ui-skin--dark .fl-color-picker{background:#131a22}.fl-color-picker-color.fl-color-picker-empty .fl-color-picker-icon{fill:#6f7881}.fl-builder-ui-skin--dark .fl-color-picker-clear{background-color:#191d21}.fl-builder-ui-skin--dark .fl-color-picker-clear:hover{background-color:#373f46}.fl-builder-ui-skin--dark span.fl-builder-block-no-node-templates:hover{background:#1d2025}.fl-builder-ui-skin--dark .fl-builder-settings-tab-description{background:#1d2227}.fl-builder-ui-skin--dark .fl-builder-panel-search button svg .filled-shape{fill:#b5becb}.fl-builder-ui-skin--dark .fl-builder-custom-field,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=email],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=file],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=number],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=password],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=search],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=tel],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=text],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=url],.fl-builder-ui-skin--dark .fl-builder-settings-fields select,.fl-builder-ui-skin--dark .fl-builder-settings-fields textarea{background-color:#131a22!important}.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=email]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=file]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=number]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=password]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=search]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=tel]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=text]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=url]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields select:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields textarea:focus{border-color:#00a0d2!important;color:#fff!important}.fl-builder-ui-skin--dark .fl-builder-settings-fields select{background-image:url(../img/svg/select-arrow-down-alt2-light.svg)!important}.fl-builder-ui-skin--dark .fl-builder-custom-field select,.fl-builder-ui-skin--dark .fl-photo-field select{border-color:#7d8690!important}.fl-builder-ui-skin--dark .fl-field i.fl-field-responsive-toggle{color:#6b747d}.fl-builder-ui-skin--dark .fl-builder--main-menu-panel-view-title,.fl-builder-ui-skin--dark .fl-field i.fl-field-responsive-toggle:hover{color:#a8b3bf}.fl-builder-ui-skin--dark .fl-builder--saving-indicator{color:#858f99}.fl-builder-ui-skin--dark .fl-icons-list i:hover{background-color:#16191d;color:#fff}.fl-builder-ui-skin--dark .fl-color-picker-clear .fl-color-picker-icon-remove:after,.fl-builder-ui-skin--dark .fl-color-picker-clear .fl-color-picker-icon-remove:before{background:#6f7881}.fl-builder-ui-skin--dark .fl-builder--user-templates-section-content{border-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-theme-builder-preview-select.fl-builder-button{background:0 0;border-right-color:#101215!important}.fl-builder-ui-skin--dark .fl-theme-builder-preview-select.fl-builder-button:hover{background:#181b1f}.fl-builder-ui-skin--dark .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span{color:#c6cdd6}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu{background:#131a22;border-color:#353c43 #131a22 #131a22}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu:before{border-bottom-color:#353c43}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:active,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:focus,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:hover{background:#383f46}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a.fl-active,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:hover.fl-active{color:#fff!important;background:#383f46}.fl-builder-ui-skin--dark ul.as-selections{background-color:#121a23}.fl-builder-ui-skin--dark .fl-custom-query .fl-builder-settings-section{border-top:2px solid #1b2026!important}.fl-builder-ui-skin--dark .pp-preview-button{background:#23282d;border:2px solid #101215}.fl-builder-ui-skin--dark .pp-preview-button .pp-preview-button-wrap .fa{color:#b8bfc7}
css/fl-color-picker.css CHANGED
@@ -2,14 +2,14 @@
2
  ---------------------------------------------------- */
3
 
4
  .fl-color-picker-ui {
5
- width: 200px;
6
  }
7
  .fl-color-picker-ui.fl-color-alpha-enabled {
8
  width: 238px;
9
  }
10
  .fl-color-picker-ui .iris-picker {
11
  float: left;
12
- width: 240px;
13
  height: 224px;
14
  display: block;
15
  position: relative;
@@ -38,16 +38,14 @@
38
  top: 0;
39
  bottom: 0;
40
  }
41
- .fl-color-picker-ui .iris-picker .iris-square{
42
- /* float: left; */
43
- width: 200px;
44
- height: 200px;
45
  }
46
 
47
  .fl-color-picker-ui .iris-picker .iris-slider,
48
  .fl-color-picker-ui .iris-picker .iris-square-inner,
49
  .fl-color-picker-ui .iris-picker .iris-palette {
50
- box-shadow: 0 0 3px rgba(0, 0, 0, 0.1) inset;
51
  height: 100%;
52
  width: 12.5%;
53
  }
@@ -89,8 +87,11 @@
89
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
90
  }
91
  .fl-color-picker-ui .iris-picker .iris-strip {
92
- width: 200px;
 
 
93
  margin-top: 5px;
 
94
  position: relative;
95
  height: 22px;
96
  -webkit-transform: rotate(180deg);
@@ -111,6 +112,9 @@
111
  z-index: 5;
112
  cursor: ew-resize;
113
  }
 
 
 
114
  .fl-color-picker-ui .iris-picker .iris-slider-offset {
115
  position: absolute;
116
  top: 0;
@@ -176,7 +180,7 @@
176
  height: 1px;
177
  }
178
 
179
- /* Beaver Picker
180
  ---------------------------------------------------- */
181
 
182
  .fl-color-picker-wrapper {
@@ -184,34 +188,77 @@
184
  width: 48px;
185
  height: 32px;
186
  }
187
- .fl-color-picker-color{
 
 
 
 
 
 
 
 
 
 
 
188
  position: relative;
189
- float: left;
190
- width: 30px;
191
- height: 30px;
192
- border: 1px solid rgba(0,0,0,0.1);
193
  background-color: transparent;
194
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
196
- .fl-color-picker-color.fl-color-picker-empty{
197
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABG2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS4xLjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+MahxaQAAAAlwSFlzAAALEwAACxMBAJqcGAAACk9pQ0NQUGhvdG9zaG9wIElDQyBwcm9maWxlAAB42p1TZ1RT6RY99970QkuIgJRLb1IVCCBSQouAFJEmKiEJEEqIIaHZFVHBEUVFBBvIoIgDjo6AjBVRLAyKCtgH5CGijoOjiIrK++F7o2vWvPfmzf611z7nrPOds88HwAgMlkgzUTWADKlCHhHgg8fExuHkLkCBCiRwABAIs2Qhc/0jAQD4fjw8KyLAB74AAXjTCwgAwE2bwDAch/8P6kKZXAGAhAHAdJE4SwiAFABAeo5CpgBARgGAnZgmUwCgBABgy2Ni4wBQLQBgJ3/m0wCAnfiZewEAW5QhFQGgkQAgE2WIRABoOwCsz1aKRQBYMAAUZkvEOQDYLQAwSVdmSACwtwDAzhALsgAIDAAwUYiFKQAEewBgyCMjeACEmQAURvJXPPErrhDnKgAAeJmyPLkkOUWBWwgtcQdXVy4eKM5JFysUNmECYZpALsJ5mRkygTQP4PPMAACgkRUR4IPz/XjODq7OzjaOtg5fLeq/Bv8iYmLj/uXPq3BAAADhdH7R/iwvsxqAOwaAbf6iJe4EaF4LoHX3i2ayD0C1AKDp2lfzcPh+PDxFoZC52dnl5OTYSsRCW2HKV33+Z8JfwFf9bPl+PPz39eC+4iSBMl2BRwT44MLM9EylHM+SCYRi3OaPR/y3C//8HdMixEliuVgqFONREnGORJqM8zKlIolCkinFJdL/ZOLfLPsDPt81ALBqPgF7kS2oXWMD9ksnEFh0wOL3AADyu2/B1CgIA4Bog+HPd//vP/1HoCUAgGZJknEAAF5EJC5UyrM/xwgAAESggSqwQRv0wRgswAYcwQXcwQv8YDaEQiTEwkIQQgpkgBxyYCmsgkIohs2wHSpgL9RAHTTAUWiGk3AOLsJVuA49cA/6YQiewSi8gQkEQcgIE2Eh2ogBYopYI44IF5mF+CHBSAQSiyQgyYgUUSJLkTVIMVKKVCBVSB3yPXICOYdcRrqRO8gAMoL8hrxHMZSBslE91Ay1Q7moNxqERqIL0GR0MZqPFqCb0HK0Gj2MNqHn0KtoD9qPPkPHMMDoGAczxGwwLsbDQrE4LAmTY8uxIqwMq8YasFasA7uJ9WPPsXcEEoFFwAk2BHdCIGEeQUhYTFhO2EioIBwkNBHaCTcJA4RRwicik6hLtCa6EfnEGGIyMYdYSCwj1hKPEy8Qe4hDxDckEolDMie5kAJJsaRU0hLSRtJuUiPpLKmbNEgaI5PJ2mRrsgc5lCwgK8iF5J3kw+Qz5BvkIfJbCp1iQHGk+FPiKFLKakoZ5RDlNOUGZZgyQVWjmlLdqKFUETWPWkKtobZSr1GHqBM0dZo5zYMWSUulraKV0xpoF2j3aa/odLoR3ZUeTpfQV9LL6Ufol+gD9HcMDYYVg8eIZygZmxgHGGcZdxivmEymGdOLGcdUMDcx65jnmQ+Zb1VYKrYqfBWRygqVSpUmlRsqL1Spqqaq3qoLVfNVy1SPqV5Tfa5GVTNT46kJ1JarVaqdUOtTG1NnqTuoh6pnqG9UP6R+Wf2JBlnDTMNPQ6RRoLFf47zGIAtjGbN4LCFrDauGdYE1xCaxzdl8diq7mP0du4s9qqmhOUMzSjNXs1LzlGY/B+OYcficdE4J5yinl/N+it4U7yniKRumNEy5MWVca6qWl5ZYq0irUatH6702ru2nnaa9RbtZ+4EOQcdKJ1wnR2ePzgWd51PZU92nCqcWTT069a4uqmulG6G7RHe/bqfumJ6+XoCeTG+n3nm95/ocfS/9VP1t+qf1RwxYBrMMJAbbDM4YPMU1cW88HS/H2/FRQ13DQEOlYZVhl+GEkbnRPKPVRo1GD4xpxlzjJONtxm3GoyYGJiEmS03qTe6aUk25pimmO0w7TMfNzM2izdaZNZs9Mdcy55vnm9eb37dgWnhaLLaotrhlSbLkWqZZ7ra8boVaOVmlWFVaXbNGrZ2tJda7rbunEae5TpNOq57WZ8Ow8bbJtqm3GbDl2AbbrrZttn1hZ2IXZ7fFrsPuk72Tfbp9jf09Bw2H2Q6rHVodfnO0chQ6Vjrems6c7j99xfSW6S9nWM8Qz9gz47YTyynEaZ1Tm9NHZxdnuXOD84iLiUuCyy6XPi6bG8bdyL3kSnT1cV3hetL1nZuzm8LtqNuv7jbuae6H3J/MNJ8pnlkzc9DDyEPgUeXRPwuflTBr36x+T0NPgWe15yMvYy+RV63XsLeld6r3Ye8XPvY+cp/jPuM8N94y3llfzDfAt8i3y0/Db55fhd9DfyP/ZP96/9EAp4AlAWcDiYFBgVsC+/h6fCG/jj8622X2stntQYyguUEVQY+CrYLlwa0haMjskK0h9+eYzpHOaQ6FUH7o1tAHYeZhi8N+DCeFh4VXhj+OcIhYGtExlzV30dxDc99E+kSWRN6bZzFPOa8tSjUqPqouajzaN7o0uj/GLmZZzNVYnVhJbEscOS4qrjZubL7f/O3zh+Kd4gvjexeYL8hdcHmhzsL0hacWqS4SLDqWQEyITjiU8EEQKqgWjCXyE3cljgp5wh3CZyIv0TbRiNhDXCoeTvJIKk16kuyRvDV5JMUzpSzluYQnqZC8TA1M3Zs6nhaadiBtMj06vTGDkpGQcUKqIU2TtmfqZ+ZmdsusZYWy/sVui7cvHpUHyWuzkKwFWS0KtkKm6FRaKNcqB7JnZVdmv82JyjmWq54rze3Ms8rbkDec75//7RLCEuGStqWGS1ctHVjmvaxqObI8cXnbCuMVBSuGVgasPLiKtipt1U+r7VeXrn69JnpNa4FewcqCwbUBa+sLVQrlhX3r3NftXU9YL1nftWH6hp0bPhWJiq4U2xeXFX/YKNx45RuHb8q/mdyUtKmrxLlkz2bSZunm3i2eWw6Wqpfmlw5uDdnatA3fVrTt9fZF2y+XzSjbu4O2Q7mjvzy4vGWnyc7NOz9UpFT0VPpUNu7S3bVh1/hu0e4be7z2NOzV21u89/0+yb7bVQFVTdVm1WX7Sfuz9z+uiarp+Jb7bV2tTm1x7ccD0gP9ByMOtte51NUd0j1UUo/WK+tHDscfvv6d73ctDTYNVY2cxuIjcER55On3Cd/3Hg062naMe6zhB9Mfdh1nHS9qQprymkabU5r7W2Jbuk/MPtHW6t56/EfbHw+cNDxZeUrzVMlp2umC05Nn8s+MnZWdfX4u+dxg26K2e+djzt9qD2/vuhB04dJF/4vnO7w7zlzyuHTystvlE1e4V5qvOl9t6nTqPP6T00/Hu5y7mq65XGu57nq9tXtm9+kbnjfO3fS9efEW/9bVnjk93b3zem/3xff13xbdfnIn/c7Lu9l3J+6tvE+8X/RA7UHZQ92H1T9b/tzY79x/asB3oPPR3Ef3BoWDz/6R9Y8PQwWPmY/Lhg2G6544Pjk54j9y/en8p0PPZM8mnhf+ov7LrhcWL3741evXztGY0aGX8peTv218pf3qwOsZr9vGwsYevsl4MzFe9Fb77cF33Hcd76PfD0/kfCB/KP9o+bH1U9Cn+5MZk5P/BAOY8/xjMy3bAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAGbSURBVHjajNO/S1VxGMfx9+ebQ6FiImkOgatTDYlKXgfPgVAbHRpt6U/oH6jmHAPH2gOX2vx1URCaWoKGhhQ1hKsJLnqeT8sxTveeSz3bFx5ez/f58vkqyzL+pyQhiYhYsL0i6bIoiuf6B/AIENCUBPAUWAX6AGx/6wpIyoEPJTBhewxYk9Rz3RMRXYEeSevATHneB/qBgcqAi4hY6gAkYVvApKS3wP2aAYWk5Yh4rzzPKff7U7axfQP4LKkdOJb0zPZH23QAtpE0FBGbwLmkV7ZfV6AD29PAD6AWGLa9JSlJemj7l6THtj9VbnFuexHYbgcGbe+UjzgLHNq+DawBt4BeYBy4sj33FxARA8BeOblh+0jSsO0mcAk8sD0u6Q3w0vZGdYWhiGgCKaXUAH7aHikDFMAU0IqIzrzkeX6nsvOU7Zak0YjYklRImgZaZXBqgW3gXtl4aHsQ2AWSpAZwXEleJ5Bl2feU0rztr5WdQ9IMcFJt7naDL5JeAKcR8S6ldAVM2j5rD1g3YB24C9wEDiQ9AU7rPkgd8HsAv5vXzUui544AAAAASUVORK5CYII=) center center no-repeat;
 
198
  }
199
- .fl-color-picker-clear{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  position: relative;
201
- display: block;
202
- float: left;
203
- width: 17px;
204
- height: 30px;
205
- border: 1px solid rgba(0,0,0,0.1);
206
- border-left: none;
207
- background-color: #FAFAFA;
 
 
208
  cursor: pointer;
209
  }
210
  .fl-color-picker-color.fl-color-picker-empty + .fl-color-picker-clear {
211
  display: none;
212
  }
213
 
214
- .fl-color-picker-ui{
215
  display: inline-block;
216
  font-family: Helvetica, Verdana, sans-serif;
217
  z-index: 999999;
@@ -222,8 +269,8 @@
222
  color: #999;
223
  background-color: #FAFAFA;
224
  border-radius: 3px;
225
- -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1);
226
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
227
  -webkit-transition: opacity .2s, visibility .2s;
228
  -moz-transition: opacity .2s, visibility .2s;
229
  -ms-transition: opacity .2s, visibility .2s;
@@ -245,7 +292,7 @@
245
  font-size: 14px !important;
246
  padding: 0 8px;
247
  vertical-align: middle;
248
- color: #999;
249
  background-color: #fff;
250
  border-radius: 0;
251
  -webkit-box-shadow: none;
@@ -264,7 +311,7 @@
264
  right: 8px;
265
  width: 14px;
266
  height: 14px;
267
- background-color: #999;
268
  border-radius: 50%;
269
  cursor: pointer;
270
  -webkit-transition: all .2s;
@@ -340,13 +387,13 @@
340
  -webkit-transform: translate(-50%,-50%);
341
  -ms-transform: translate(-50%,-50%);
342
  -o-transform: translate(-50%,-50%);
343
- transform: translate(-50%,-50%);
344
  opacity: 0;
345
  width: 100%;
346
  }
347
  .fl-color-picker-presets-open-label.fl-color-picker-active,
348
  .fl-color-picker-presets-close-label.fl-color-picker-active{
349
- color: #999;
350
  visibility: visible;
351
  opacity: 1;
352
  }
@@ -372,13 +419,17 @@
372
  transition: all .1s;
373
 
374
  }
 
 
 
 
375
  .fl-color-picker-presets-list .fl-color-picker-preset:hover{
376
  background-color: #EDEDED;
377
  }
378
 
379
  .fl-color-picker-presets-list .fl-color-picker-preset-color{
380
  display: inline-block;
381
- width: 20px;
382
  height: 20px;
383
  margin-right: 3px;
384
  vertical-align: middle;
@@ -386,12 +437,12 @@
386
  border-radius: 2px;
387
  cursor: pointer;
388
  }
389
- .fl-color-picker-presets-list .fl-color-picker-preset-label{
390
  vertical-align: middle;
391
- color: #999;
 
392
  }
393
- .fl-color-picker-clear .fl-color-picker-icon-remove,
394
- .fl-color-picker-presets-list .fl-color-picker-preset-remove{
395
  position: absolute;
396
  top: 50%;
397
  cursor: pointer;
@@ -400,14 +451,16 @@
400
  -o-transform: translateY(-50%);
401
  transform: translateY(-50%);
402
  }
403
- .fl-color-picker-clear .fl-color-picker-icon-remove{
404
- right: 0;
 
 
405
  }
406
- .fl-color-picker-presets-list .fl-color-picker-preset-remove{
407
  right: 5px;
408
  }
409
  .fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:before,
410
- .fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:after{
411
  background-color: #333;
412
  }
413
 
@@ -421,7 +474,7 @@
421
  z-index: 10;
422
  color: #fff;
423
  text-align: center;
424
- background-color: rgba(0,0,0,.6);
425
  }
426
  .fl-color-picker-added-text{
427
  position: absolute;
@@ -505,14 +558,13 @@
505
  content: '';
506
  display: block;
507
  position: relative;
508
- background-color: #999;
509
  }
510
  .fl-color-picker-icon-remove:before{
511
  left: 6px;
512
  width: 2px;
513
  height: 10px;
514
  margin-top: 3px;
515
- background: #999;
516
  -webkit-transform: rotate(-45deg);
517
  -moz-transform: rotate(-45deg);
518
  -ms-transform: rotate(-45deg);
@@ -524,7 +576,6 @@
524
  width: 2px;
525
  height: 10px;
526
  margin-top: -10px;
527
- background: #999;
528
  -webkit-transform: rotate(45deg);
529
  -moz-transform: rotate(45deg);
530
  -ms-transform: rotate(45deg);
@@ -556,7 +607,7 @@
556
  border-radius: 4px;
557
  border-style: solid;
558
  border-width: 4px;
559
-
560
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
561
  -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
562
  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -608,4 +659,4 @@
608
  color: #999;
609
  position: absolute;
610
  bottom: -5px;
611
- }
2
  ---------------------------------------------------- */
3
 
4
  .fl-color-picker-ui {
5
+ width: 300px;
6
  }
7
  .fl-color-picker-ui.fl-color-alpha-enabled {
8
  width: 238px;
9
  }
10
  .fl-color-picker-ui .iris-picker {
11
  float: left;
12
+ width: 100%;
13
  height: 224px;
14
  display: block;
15
  position: relative;
38
  top: 0;
39
  bottom: 0;
40
  }
41
+ .fl-color-picker-ui .iris-picker .iris-square {
42
+ width: 300px;
43
+ height: 200px;
 
44
  }
45
 
46
  .fl-color-picker-ui .iris-picker .iris-slider,
47
  .fl-color-picker-ui .iris-picker .iris-square-inner,
48
  .fl-color-picker-ui .iris-picker .iris-palette {
 
49
  height: 100%;
50
  width: 12.5%;
51
  }
87
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
88
  }
89
  .fl-color-picker-ui .iris-picker .iris-strip {
90
+ box-sizing: border-box;
91
+ width: calc(300px - 12px);
92
+ margin: 6px 6px;
93
  margin-top: 5px;
94
+ border-radius: 4px;
95
  position: relative;
96
  height: 22px;
97
  -webkit-transform: rotate(180deg);
112
  z-index: 5;
113
  cursor: ew-resize;
114
  }
115
+ .fl-color-picker-ui .iris-picker .iris-strip .ui-slider-handle:focus {
116
+ outline: 2px solid #00a0d2;
117
+ }
118
  .fl-color-picker-ui .iris-picker .iris-slider-offset {
119
  position: absolute;
120
  top: 0;
180
  height: 1px;
181
  }
182
 
183
+ /* Beaver Picker
184
  ---------------------------------------------------- */
185
 
186
  .fl-color-picker-wrapper {
188
  width: 48px;
189
  height: 32px;
190
  }
191
+ .fl-color-picker {
192
+ box-shadow: 0 2px 4px 0 rgba(0,0,0,0.12);
193
+ background:white;
194
+ border-radius: 4px;
195
+ width: 120px;
196
+ height:36px;
197
+ display: flex;
198
+ flex-direction: row;
199
+ }
200
+ .fl-color-picker-color {
201
+ flex: 1 1 100%;
202
+ box-sizing: border-box !important;
203
  position: relative;
204
+ border-radius: 4px;
 
 
 
205
  background-color: transparent;
206
  cursor: pointer;
207
+ border: 2px solid transparent;
208
+ border-right: 2px solid rgba(0,0,0,0.1);
209
+ padding:0;
210
+ justify-content: center;
211
+ display: flex;
212
+ }
213
+ .fl-color-picker-color:hover,
214
+ .fl-color-picker-clear:hover {
215
+ background:transparent;
216
+ border: 2px solid transparent;
217
+ }
218
+ .fl-color-picker-color:focus,
219
+ .fl-color-picker-color.fl-color-picker-empty:focus,
220
+ .fl-color-picker-clear:focus {
221
+ outline:none;
222
+ top:0;
223
+ border: 2px solid #00a0d2;
224
+ background: transparent;
225
  }
226
+ .fl-color-picker.fl-color-picker-has-reset .fl-color-picker-color:not(.fl-color-picker-empty) {
227
+ border-top-right-radius: 0px;
228
+ border-bottom-right-radius: 0px;
229
  }
230
+ .fl-color-picker-icon {
231
+ display:none;
232
+ margin:auto;
233
+ }
234
+ .fl-color-picker-color.fl-color-picker-empty {
235
+ border-color: transparent;
236
+ }
237
+ .fl-color-picker-color.fl-color-picker-empty svg.fl-color-picker-icon {
238
+ display:block;
239
+ }
240
+ .fl-color-picker-color.fl-color-picker-empty svg.fl-color-picker-icon path {
241
+ fill:inherit;
242
+ }
243
+ .fl-color-picker-clear {
244
+ box-sizing: border-box;
245
  position: relative;
246
+ display: flex;
247
+ flex: 0 0 36px;
248
+ justify-content: center;
249
+ padding: 0;
250
+ border: 2px solid transparent;
251
+ border-top-right-radius: 4px;
252
+ border-bottom-right-radius: 4px;
253
+ background-color: #ffffff;
254
+ border-color:transparent;
255
  cursor: pointer;
256
  }
257
  .fl-color-picker-color.fl-color-picker-empty + .fl-color-picker-clear {
258
  display: none;
259
  }
260
 
261
+ .fl-color-picker-ui {
262
  display: inline-block;
263
  font-family: Helvetica, Verdana, sans-serif;
264
  z-index: 999999;
269
  color: #999;
270
  background-color: #FAFAFA;
271
  border-radius: 3px;
272
+ -webkit-box-shadow: 0 9px 20px rgba(0, 0, 0, 0.17);
273
+ box-shadow: 0 9px 20px rgba(0, 0, 0, 0.17);
274
  -webkit-transition: opacity .2s, visibility .2s;
275
  -moz-transition: opacity .2s, visibility .2s;
276
  -ms-transition: opacity .2s, visibility .2s;
292
  font-size: 14px !important;
293
  padding: 0 8px;
294
  vertical-align: middle;
295
+ color: #656c6e;
296
  background-color: #fff;
297
  border-radius: 0;
298
  -webkit-box-shadow: none;
311
  right: 8px;
312
  width: 14px;
313
  height: 14px;
314
+ background-color: #656c6e;
315
  border-radius: 50%;
316
  cursor: pointer;
317
  -webkit-transition: all .2s;
387
  -webkit-transform: translate(-50%,-50%);
388
  -ms-transform: translate(-50%,-50%);
389
  -o-transform: translate(-50%,-50%);
390
+ transform: translate(-50%,-50%);
391
  opacity: 0;
392
  width: 100%;
393
  }
394
  .fl-color-picker-presets-open-label.fl-color-picker-active,
395
  .fl-color-picker-presets-close-label.fl-color-picker-active{
396
+ color: #656c6e;
397
  visibility: visible;
398
  opacity: 1;
399
  }
419
  transition: all .1s;
420
 
421
  }
422
+ .fl-color-picker-presets-list .fl-color-picker-no-preset{
423
+ padding: 18px 5px;
424
+ text-align:center;
425
+ }
426
  .fl-color-picker-presets-list .fl-color-picker-preset:hover{
427
  background-color: #EDEDED;
428
  }
429
 
430
  .fl-color-picker-presets-list .fl-color-picker-preset-color{
431
  display: inline-block;
432
+ width: 40px;
433
  height: 20px;
434
  margin-right: 3px;
435
  vertical-align: middle;
437
  border-radius: 2px;
438
  cursor: pointer;
439
  }
440
+ .fl-color-picker-presets-list .fl-color-picker-preset-label {
441
  vertical-align: middle;
442
+ color: #333;
443
+ cursor: pointer;
444
  }
445
+ .fl-color-picker-presets-list .fl-color-picker-preset-remove {
 
446
  position: absolute;
447
  top: 50%;
448
  cursor: pointer;
451
  -o-transform: translateY(-50%);
452
  transform: translateY(-50%);
453
  }
454
+ .fl-color-picker-clear .fl-color-picker-icon-remove {
455
+ right: auto;
456
+ top: auto;
457
+ margin:auto;
458
  }
459
+ .fl-color-picker-presets-list .fl-color-picker-preset-remove {
460
  right: 5px;
461
  }
462
  .fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:before,
463
+ .fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:after {
464
  background-color: #333;
465
  }
466
 
474
  z-index: 10;
475
  color: #fff;
476
  text-align: center;
477
+ background-color: rgba(0,0,0,.8);
478
  }
479
  .fl-color-picker-added-text{
480
  position: absolute;
558
  content: '';
559
  display: block;
560
  position: relative;
561
+ background-color: #6f7881;
562
  }
563
  .fl-color-picker-icon-remove:before{
564
  left: 6px;
565
  width: 2px;
566
  height: 10px;
567
  margin-top: 3px;
 
568
  -webkit-transform: rotate(-45deg);
569
  -moz-transform: rotate(-45deg);
570
  -ms-transform: rotate(-45deg);
576
  width: 2px;
577
  height: 10px;
578
  margin-top: -10px;
 
579
  -webkit-transform: rotate(45deg);
580
  -moz-transform: rotate(45deg);
581
  -ms-transform: rotate(45deg);
607
  border-radius: 4px;
608
  border-style: solid;
609
  border-width: 4px;
610
+
611
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
612
  -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
613
  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
659
  color: #999;
660
  position: absolute;
661
  bottom: -5px;
662
+ }
css/fl-icon-selector.css CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
  .fl-icon-selector .fl-lightbox {
2
  height: 100%;
3
  }
@@ -5,17 +8,40 @@
5
  height: auto !important;
6
  margin: 0 !important;
7
  position: absolute !important;
8
- right: 10px;
9
- top: 10px;
 
 
 
10
  }
11
  .fl-icons-filter select {
12
  vertical-align: middle;
13
  width: 160px;
 
 
 
 
 
 
 
 
 
 
 
 
14
  }
15
- .fl-icons-filter input {
16
  line-height: 18px;
17
  vertical-align: middle;
18
  width: 160px;
 
 
 
 
 
 
 
 
19
  }
20
  .fl-icons-list {
21
  bottom: 52px;
@@ -52,17 +78,20 @@
52
  .fl-icons-list i:before {
53
  cursor: pointer;
54
  display: inline-block;
55
- font-size: 32px;
56
- height: 80px;
57
- line-height: 80px;
58
- width: 80px;
 
59
  }
60
  .fl-icons-list i:hover {
61
- background: #e5e5e5;
 
 
62
  }
63
  .fl-icon-selector-footer {
64
  bottom: 0;
65
  left: 0;
66
  position: absolute;
67
  right: 0;
68
- }
1
+ .fl-lightbox-wrap.fl-icon-selector {
2
+ z-index: 1000111;
3
+ }
4
  .fl-icon-selector .fl-lightbox {
5
  height: 100%;
6
  }
8
  height: auto !important;
9
  margin: 0 !important;
10
  position: absolute !important;
11
+ right: 0px;
12
+ top: 0px;
13
+ padding: 10px 16px;
14
+ display: flex;
15
+ flex-direction: row;
16
  }
17
  .fl-icons-filter select {
18
  vertical-align: middle;
19
  width: 160px;
20
+ -webkit-appearance: none;
21
+ -moz-appearance: none;
22
+ appearance: none;
23
+ box-sizing: border-box;
24
+ color: #000;
25
+ border: 2px solid #e4e7ea !important;
26
+ border-right: none !important;
27
+ margin: 0;
28
+ padding: 2px 10px;
29
+ background: white url("../img/svg/select-arrow-down-alt2.svg") no-repeat center right 10px !important;
30
+ flex: 1 1 160px;
31
+ border-radius:0px;
32
  }
33
+ .fl-icons-filter input[type="text"] {
34
  line-height: 18px;
35
  vertical-align: middle;
36
  width: 160px;
37
+ flex: 1 1 160px;
38
+ border: 2px solid #e4e7ea !important;
39
+ border-radius:0px !important;
40
+ padding:2px 10px !important;
41
+ }
42
+ .fl-icons-filter input[type="text"]:focus,
43
+ .fl-icons-filter select:focus {
44
+ border: 2px solid #00A0D2 !important;
45
  }
46
  .fl-icons-list {
47
  bottom: 52px;
78
  .fl-icons-list i:before {
79
  cursor: pointer;
80
  display: inline-block;
81
+ font-size: 40px;
82
+ height: 100px;
83
+ line-height: 100px;
84
+ width: 100px;
85
+ background: transparent;
86
  }
87
  .fl-icons-list i:hover {
88
+ background: white;
89
+ box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.15);
90
+ border-radius: 4px;
91
  }
92
  .fl-icon-selector-footer {
93
  bottom: 0;
94
  left: 0;
95
  position: absolute;
96
  right: 0;
97
+ }
css/fl-lightbox.css CHANGED
@@ -1,18 +1,24 @@
 
 
 
 
 
 
 
 
1
  .fl-lightbox-wrap {
2
  bottom: 0;
3
  display: none;
4
  left: 0;
5
  overflow: auto;
6
- padding: 30px;
7
  position: fixed;
8
  right: 0;
9
- top: 0;
10
- z-index: 100010;
11
  -webkit-backface-visibility: hidden;
12
  -webkit-transform: translateZ(0);
13
- }
14
- .fl-lightbox-wrap.fl-icon-selector {
15
- z-index: 100011;
16
  }
17
  .fl-lightbox-mask {
18
  background: #000;
@@ -24,25 +30,38 @@
24
  right: 0;
25
  top: 0;
26
  z-index: 100010;
 
27
  }
28
  .fl-lightbox {
29
- background: #fff;
 
30
  box-shadow: rgba(0,0,0,1) 0 4px 30px;
31
  -moz-box-shadow: rgba(0,0,0,1) 0 4px 30px;
32
  -webkit-box-shadow: rgba(0,0,0,1) 0 4px 30px;
33
  position: relative;
 
34
  z-index: 100011;
 
 
 
 
 
 
 
 
 
 
35
  }
36
  .fl-lightbox *:not(i) {
37
  color: #333;
38
- font-family: Helvetica, Verdana, sans-serif;
39
- font-size: 12px;
40
  line-height: 16px;
41
  text-decoration: none;
42
  text-transform: none;
43
  }
44
- .fl-lightbox *,
45
- .fl-lightbox *:before,
46
  .fl-lightbox *:after {
47
  -webkit-box-sizing: content-box;
48
  -moz-box-sizing: content-box;
@@ -59,13 +78,51 @@
59
  .fl-lightbox .dashicons {
60
  font-family: dashicons;
61
  }
62
- .fl-lightbox-content-wrap {
63
- height: 100%;
64
- }
65
  .fl-lightbox.ui-draggable {
66
- box-shadow: rgba(0,0,0,0.5) 0 4px 30px;
67
- -moz-box-shadow: rgba(0,0,0,0.5) 0 4px 30px;
68
- -webkit-box-shadow: rgba(0,0,0,0.5) 0 4px 30px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
 
71
  /* Lightbox Controls */
@@ -76,59 +133,90 @@
76
  z-index: 5;
77
  }
78
  .fl-lightbox-controls .fa {
79
- color: #999;
80
- font-size: 18px;
81
  padding: 5px;
82
  }
83
  .fl-lightbox-controls .fa:hover {
84
- color: #333;
85
  cursor: pointer;
86
  }
87
- .fl-builder-lightbox .fl-lightbox-expanded {
88
- left: 0!important;
89
- right: 0!important;
90
- top: 0!important;
91
- height: 100%!important;
92
- width: 100%!important;
93
- }
94
- .fl-lightbox.ui-draggable.fl-lightbox-expanded .fl-lightbox-header {
95
- cursor: inherit;
96
- }
97
- .fl-builder-lightbox .fl-lightbox-expanded .fl-builder-settings-tab {
98
- width: 100%!important;
99
- }
100
 
101
  /* Header */
 
 
 
 
 
 
102
  .fl-lightbox-header {
103
- background: #fff;
104
- border-bottom: 1px solid #dfdfdf;
105
- box-shadow: 0 4px 4px -4px rgba(0,0,0,0.1);
106
- -moz-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.1);
107
- -webkit-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.1);
108
  position: relative;
109
  }
110
  .fl-lightbox-header h1 {
111
  color: #333 !important;
112
- font-size: 18px !important;
113
- font-family: Helvetica, Verdana, sans-serif !important;
114
- font-weight: 300 !important;
115
  margin: 0 !important;
116
- padding: 15px 20px !important;
 
117
  text-align: left!important;
 
 
 
 
118
  }
119
  .fl-lightbox.ui-draggable .fl-lightbox-header {
120
  cursor: move;
121
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
  /* Footer */
124
  .fl-lightbox-footer {
125
- border-top: 1px solid #dfdfdf;
126
- box-shadow: 0 -4px 4px -4px rgba(0,0,0,0.1);
127
- -moz-box-shadow: 0 -4px 4px -4px rgba(0,0,0,0.1);
128
- -webkit-box-shadow: 0 -4px 4px -4px rgba(0,0,0,0.1);
129
- padding: 10px;
 
 
130
  text-align: right;
131
  }
132
  .fl-lightbox-footer .fl-builder-button {
 
133
  margin-left: 5px !important;
134
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @keyframes fl-lightbox-zoom {
2
+ from {
3
+ transform: scale(.4);
4
+ }
5
+ to {
6
+ transform: scale(1);
7
+ }
8
+ }
9
  .fl-lightbox-wrap {
10
  bottom: 0;
11
  display: none;
12
  left: 0;
13
  overflow: auto;
14
+ padding: 4px;
15
  position: fixed;
16
  right: 0;
17
+ top: 46px;
18
+ z-index: 100010;
19
  -webkit-backface-visibility: hidden;
20
  -webkit-transform: translateZ(0);
21
+ pointer-events: none;
 
 
22
  }
23
  .fl-lightbox-mask {
24
  background: #000;
30
  right: 0;
31
  top: 0;
32
  z-index: 100010;
33
+ pointer-events: auto;
34
  }
35
  .fl-lightbox {
36
+ background: #F5F7F9;
37
+ border-radius: 4px;
38
  box-shadow: rgba(0,0,0,1) 0 4px 30px;
39
  -moz-box-shadow: rgba(0,0,0,1) 0 4px 30px;
40
  -webkit-box-shadow: rgba(0,0,0,1) 0 4px 30px;
41
  position: relative;
42
+ display: flex;
43
  z-index: 100011;
44
+ transform-origin: center;
45
+ animation-name: fl-lightbox-zoom;
46
+ animation-duration: .25s;
47
+ pointer-events: auto;
48
+ }
49
+ .fl-lightbox.fl-lightbox-prevent-animation {
50
+ animation-duration: 0s;
51
+ -moz-animation-duration: 0s;
52
+ -webkit-animation-duration: 0s;
53
+ -o-animation-duration: 0s;
54
  }
55
  .fl-lightbox *:not(i) {
56
  color: #333;
57
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
58
+ font-size: 13px;
59
  line-height: 16px;
60
  text-decoration: none;
61
  text-transform: none;
62
  }
63
+ .fl-lightbox *,
64
+ .fl-lightbox *:before,
65
  .fl-lightbox *:after {
66
  -webkit-box-sizing: content-box;
67
  -moz-box-sizing: content-box;
78
  .fl-lightbox .dashicons {
79
  font-family: dashicons;
80
  }
 
 
 
81
  .fl-lightbox.ui-draggable {
82
+ box-shadow: rgba(0, 0, 0, 0.2) 0 7px 30px;
83
+ -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 7px 30px;
84
+ -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 7px 30px;
85
+ }
86
+
87
+ /* Resizable */
88
+ .fl-builder-resizable-is-resizing .fl-lightbox-wrap,
89
+ .fl-builder-draggable-is-dragging .fl-lightbox-wrap {
90
+ pointer-events: auto;
91
+ }
92
+ .fl-lightbox-resizable {
93
+ height: 500px;
94
+ width: 380px;
95
+ }
96
+
97
+ @media ( max-width: 500px ) {
98
+ .fl-lightbox-resizable {
99
+ left: 0 !important;
100
+ right: 0 !important;
101
+ top: 0 !important;
102
+ height: 100% !important;
103
+ width: 100% !important;
104
+ }
105
+ .fl-lightbox-resizable .ui-resizable-handle {
106
+ display: none !important;
107
+ }
108
+ .fl-lightbox.ui-draggable .fl-lightbox-header {
109
+ cursor: default !important;
110
+ }
111
+ .fl-lightbox-controls {
112
+ display: none;
113
+ }
114
+ }
115
+
116
+ /* Resizable - Full Style */
117
+ .fl-lightbox-width-full {
118
+ left: 0 !important;
119
+ right: 0 !important;
120
+ top: 0 !important;
121
+ height: 100% !important;
122
+ width: 100% !important;
123
+ }
124
+ .fl-lightbox-width-full .fl-lightbox-header {
125
+ cursor: inherit !important;
126
  }
127
 
128
  /* Lightbox Controls */
133
  z-index: 5;
134
  }
135
  .fl-lightbox-controls .fa {
136
+ color: #bdbdbd;
137
+ font-size: 14px;
138
  padding: 5px;
139
  }
140
  .fl-lightbox-controls .fa:hover {
141
+ color: #aaaaaa;
142
  cursor: pointer;
143
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
  /* Header */
146
+ .fl-lightbox-header-wrap {
147
+ background:white;
148
+ border-top-left-radius: 4px;
149
+ border-top-right-radius: 4px;
150
+ border-bottom: 2px solid #eaeaea;
151
+ }
152
  .fl-lightbox-header {
 
 
 
 
 
153
  position: relative;
154
  }
155
  .fl-lightbox-header h1 {
156
  color: #333 !important;
157
+ font-size: 20px !important;
158
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
159
+ font-weight: 600 !important;
160
  margin: 0 !important;
161
+ padding: 14px 28px 15px !important;
162
+ padding-right: 34px !important;
163
  text-align: left!important;
164
+ display: flex;
165
+ flex-direction: row;
166
+ align-items: center;
167
+ line-height: 1.1;
168
  }
169
  .fl-lightbox.ui-draggable .fl-lightbox-header {
170
  cursor: move;
171
  }
172
+ .fl-lightbox-header h1 .fl-builder-badge {
173
+ margin-left: 10px;
174
+ }
175
+
176
+ /* Content */
177
+ .fl-lightbox-content-wrap,
178
+ .fl-lightbox-content {
179
+ display: flex;
180
+ flex-direction: column;
181
+ flex: 1 100%;
182
+ height: 100%;
183
+ max-width: 100%;
184
+ }
185
 
186
  /* Footer */
187
  .fl-lightbox-footer {
188
+ box-sizing: border-box;
189
+ display: flex;
190
+ flex-direction: row;
191
+ justify-content: flex-end;
192
+ flex: 0 0;
193
+ flex-basis: 44px;
194
+ padding: 4px;
195
  text-align: right;
196
  }
197
  .fl-lightbox-footer .fl-builder-button {
198
+ height: 36px;
199
  margin-left: 5px !important;
200
+ flex: 0 0 0%;
201
+ justify-content: center;
202
+ }
203
+ .fl-lightbox-width-slim .fl-lightbox-footer {
204
+ justify-content: stretch;
205
+ padding: 4px 5px;
206
+ }
207
+ .fl-lightbox-width-slim .fl-lightbox-footer .fl-builder-button {
208
+ flex: 1 1 100%;
209
+ display: block;
210
+ text-align: center;
211
+ }
212
+ .fl-lightbox-width-slim .fl-lightbox-footer .fl-builder-button:first-child {
213
+ margin-left:0 !important;
214
+ }
215
+
216
+ /* Tables */
217
+ .fl-lightbox table,
218
+ .fl-lightbox tr,
219
+ .fl-lightbox th,
220
+ .fl-lightbox td {
221
+ border: none;
222
+ }
css/jquery.nanoscroller.css CHANGED
@@ -32,19 +32,18 @@
32
  top : 2px;
33
  bottom : 2px;
34
  visibility : hidden\9; /* Target only IE7 and IE8 with this hack */
35
- opacity : .01;
36
  -webkit-transition : .2s;
37
  -moz-transition : .2s;
38
  -o-transition : .2s;
39
  transition : .2s;
40
  }
41
  .fl-nanoscroller > .fl-nanoscroller-pane > .fl-nanoscroller-slider {
42
- background: #444;
43
  border-radius: 10px;
44
- background: rgba(0,0,0,.5);
45
- position : relative;
46
  }
47
  .fl-nanoscroller:hover > .fl-nanoscroller-pane, .fl-nanoscroller-pane.active, .fl-nanoscroller-pane.flashed {
48
  visibility : visible\9; /* Target only IE7 and IE8 with this hack */
49
  opacity : 0.99;
50
- }
32
  top : 2px;
33
  bottom : 2px;
34
  visibility : hidden\9; /* Target only IE7 and IE8 with this hack */
35
+ opacity : .01;
36
  -webkit-transition : .2s;
37
  -moz-transition : .2s;
38
  -o-transition : .2s;
39
  transition : .2s;
40
  }
41
  .fl-nanoscroller > .fl-nanoscroller-pane > .fl-nanoscroller-slider {
42
+ background: #c9ced3;
43
  border-radius: 10px;
44
+ position: relative;
 
45
  }
46
  .fl-nanoscroller:hover > .fl-nanoscroller-pane, .fl-nanoscroller-pane.active, .fl-nanoscroller-pane.flashed {
47
  visibility : visible\9; /* Target only IE7 and IE8 with this hack */
48
  opacity : 0.99;
49
+ }
css/jquery.tiptip.css CHANGED
@@ -22,6 +22,7 @@
22
 
23
  #tiptip_holder.tip_left {
24
  padding-right: 5px;
 
25
  }
26
 
27
  #tiptip_content {
@@ -50,26 +51,6 @@
50
  width: 0;
51
  }
52
 
53
- #tiptip_holder.tip_top #tiptip_arrow {
54
- border-top-color: #fff;
55
- border-top-color: rgba(255,255,255,0.35);
56
- }
57
-
58
- #tiptip_holder.tip_bottom #tiptip_arrow {
59
- border-bottom-color: #fff;
60
- border-bottom-color: rgba(255,255,255,0.35);
61
- }
62
-
63
- #tiptip_holder.tip_right #tiptip_arrow {
64
- border-right-color: #fff;
65
- border-right-color: rgba(255,255,255,0.35);
66
- }
67
-
68
- #tiptip_holder.tip_left #tiptip_arrow {
69
- border-left-color: #fff;
70
- border-left-color: rgba(255,255,255,0.35);
71
- }
72
-
73
  #tiptip_holder.tip_top #tiptip_arrow_inner {
74
  margin-top: -7px;
75
  margin-left: -6px;
@@ -78,7 +59,7 @@
78
  }
79
 
80
  #tiptip_holder.tip_bottom #tiptip_arrow_inner {
81
- margin-top: -5px;
82
  margin-left: -6px;
83
  border-bottom-color: rgb(25,25,25);
84
  border-bottom-color: rgba(25,25,25,0.92);
@@ -93,21 +74,21 @@
93
 
94
  #tiptip_holder.tip_left #tiptip_arrow_inner {
95
  margin-top: -6px;
96
- margin-left: -7px;
97
  border-left-color: rgb(25,25,25);
98
  border-left-color: rgba(25,25,25,0.92);
99
  }
100
 
101
  /* Webkit Hacks */
102
- @media screen and (-webkit-min-device-pixel-ratio:0) {
103
  #tiptip_content {
104
  padding: 4px 8px 5px 8px;
105
  background-color: rgba(45,45,45,0.88);
106
  }
107
- #tiptip_holder.tip_bottom #tiptip_arrow_inner {
108
  border-bottom-color: rgba(45,45,45,0.88);
109
  }
110
- #tiptip_holder.tip_top #tiptip_arrow_inner {
111
  border-top-color: rgba(20,20,20,0.92);
112
  }
113
- }
22
 
23
  #tiptip_holder.tip_left {
24
  padding-right: 5px;
25
+ transform: translateX(25px);
26
  }
27
 
28
  #tiptip_content {
51
  width: 0;
52
  }
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  #tiptip_holder.tip_top #tiptip_arrow_inner {
55
  margin-top: -7px;
56
  margin-left: -6px;
59
  }
60
 
61
  #tiptip_holder.tip_bottom #tiptip_arrow_inner {
62
+ margin-top: -17px;
63
  margin-left: -6px;
64
  border-bottom-color: rgb(25,25,25);
65
  border-bottom-color: rgba(25,25,25,0.92);
74
 
75
  #tiptip_holder.tip_left #tiptip_arrow_inner {
76
  margin-top: -6px;
77
+ margin-left: -11px;
78
  border-left-color: rgb(25,25,25);
79
  border-left-color: rgba(25,25,25,0.92);
80
  }
81
 
82
  /* Webkit Hacks */
83
+ @media screen and (-webkit-min-device-pixel-ratio:0) {
84
  #tiptip_content {
85
  padding: 4px 8px 5px 8px;
86
  background-color: rgba(45,45,45,0.88);
87
  }
88
+ #tiptip_holder.tip_bottom #tiptip_arrow_inner {
89
  border-bottom-color: rgba(45,45,45,0.88);
90
  }
91
+ #tiptip_holder.tip_top #tiptip_arrow_inner {
92
  border-top-color: rgba(20,20,20,0.92);
93
  }
94
+ }
fl-builder.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-uri
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
- * Version: 1.11
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-author
9
  * Copyright: (c) 2014 Beaver Builder
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-uri
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
+ * Version: 2.0.3.2
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-author
9
  * Copyright: (c) 2014 Beaver Builder
img/svg/button.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M17 5H3c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm1 7c0 .6-.4 1-1 1H3c-.6 0-1-.4-1-1V7c0-.6.4-1 1-1h14c.6 0 1 .4 1 1v5z"/></g></svg>
img/svg/chart-bar.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M18 18V2h-4v16h4zm-6 0V7H8v11h4zm-6 0v-8H2v8h4z"/></g></svg>
img/svg/clock.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M10 2c4.42 0 8 3.58 8 8s-3.58 8-8 8-8-3.58-8-8 3.58-8 8-8zm0 14c3.31 0 6-2.69 6-6s-2.69-6-6-6-6 2.69-6 6 2.69 6 6 6zm-.71-5.29c.07.05.14.1.23.15l-.02.02L14 13l-3.03-3.19L10 5l-.97 4.81h.01c0 .02-.01.05-.02.09S9 9.97 9 10c0 .28.1.52.29.71z"/></g></svg>
img/svg/editor-code.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M9 6l-4 4 4 4-1 2-6-6 6-6zm2 8l4-4-4-4 1-2 6 6-6 6z"/></g></svg>
img/svg/editor-table.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M18 17V3H2v14h16zM16 7H4V5h12v2zm-7 4H4V9h5v2zm7 0h-5V9h5v2zm-7 4H4v-2h5v2zm7 0h-5v-2h5v2z"/></g></svg>
img/svg/format-audio.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M6.99 3.08l11.02-2c.55-.08.99.45.99 1V14.5c0 1.94-1.57 3.5-3.5 3.5S12 16.44 12 14.5c0-1.93 1.57-3.5 3.5-3.5.54 0 1.04.14 1.5.35V5.08l-9 2V16c-.24 1.7-1.74 3-3.5 3C2.57 19 1 17.44 1 15.5 1 13.57 2.57 12 4.5 12c.54 0 1.04.14 1.5.35V4.08c0-.55.44-.91.99-1z"/></g></svg>
img/svg/format-gallery.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M16 4h1.96c.57 0 1.04.47 1.04 1.04v12.92c0 .57-.47 1.04-1.04 1.04H5.04C4.47 19 4 18.53 4 17.96V16H2.04C1.47 16 1 15.53 1 14.96V2.04C1 1.47 1.47 1 2.04 1h12.92c.57 0 1.04.47 1.04 1.04V4zM3 14h11V3H3v11zm5-8.5C8 4.67 7.33 4 6.5 4S5 4.67 5 5.5 5.67 7 6.5 7 8 6.33 8 5.5zm2 4.5s1-5 3-5v8H4V7c2 0 2 3 2 3s.33-2 2-2 2 2 2 2zm7 7V6h-1v8.96c0 .57-.47 1.04-1.04 1.04H6v1h11z"/></g></svg>
img/svg/format-image.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M2.25 1h15.5c.69 0 1.25.56 1.25 1.25v15.5c0 .69-.56 1.25-1.25 1.25H2.25C1.56 19 1 18.44 1 17.75V2.25C1 1.56 1.56 1 2.25 1zM17 17V3H3v14h14zM10 6c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm3 5s0-6 3-6v10c0 .55-.45 1-1 1H5c-.55 0-1-.45-1-1V8c2 0 3 4 3 4s1-3 3-3 3 2 3 2z"/></g></svg>
img/svg/format-quote.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M8.54 12.74c0-.87-.24-1.61-.72-2.22-.73-.92-2.14-1.03-2.96-.85-.34-1.93 1.3-4.39 3.42-5.45L6.65 1.94C3.45 3.46.31 6.96.85 11.37 1.19 14.16 2.8 16 5.08 16c1 0 1.83-.29 2.48-.88.66-.59.98-1.38.98-2.38zm9.43 0c0-.87-.24-1.61-.72-2.22-.73-.92-2.14-1.03-2.96-.85-.34-1.93 1.3-4.39 3.42-5.45l-1.63-2.28c-3.2 1.52-6.34 5.02-5.8 9.43.34 2.79 1.95 4.63 4.23 4.63 1 0 1.83-.29 2.48-.88.66-.59.98-1.38.98-2.38z"/></g></svg>
img/svg/format-video.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M2 1h16c.55 0 1 .45 1 1v16l-18-.02V2c0-.55.45-1 1-1zm4 1L4 5h1l2-3H6zm4 0H9L7 5h1zm3 0h-1l-2 3h1zm3 0h-1l-2 3h1zm1 14V6H3v10h14zM8 7l6 4-6 4V7z"/></g></svg>
img/svg/insert.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M10 1c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 16c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7zm1-11H9v3H6v2h3v3h2v-3h3V9h-3V6z"/></g></svg>
img/svg/layout.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M2 2h5v11H2V2zm6 0h5v5H8V2zm6 0h4v16h-4V2zM8 8h5v5H8V8zm-6 6h11v4H2v-4z"/></g></svg>
img/svg/location.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M10 2C6.69 2 4 4.69 4 8c0 2.02 1.17 3.71 2.53 4.89.43.37 1.18.96 1.85 1.83.74.97 1.41 2.01 1.62 2.71.21-.7.88-1.74 1.62-2.71.67-.87 1.42-1.46 1.85-1.83C14.83 11.71 16 10.02 16 8c0-3.31-2.69-6-6-6zm0 2.56c1.9 0 3.44 1.54 3.44 3.44S11.9 11.44 10 11.44 6.56 9.9 6.56 8 8.1 4.56 10 4.56z"/></g></svg>
img/svg/megaphone.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M18.15 5.94c.46 1.62.38 3.22-.02 4.48-.42 1.28-1.26 2.18-2.3 2.48-.16.06-.26.06-.4.06-.06.02-.12.02-.18.02-.06.02-.14.02-.22.02h-6.8l2.22 5.5c.02.14-.06.26-.14.34-.08.1-.24.16-.34.16H6.95c-.1 0-.26-.06-.34-.16-.08-.08-.16-.2-.14-.34l-1-5.5H4.25l-.02-.02c-.5.06-1.08-.18-1.54-.62s-.88-1.08-1.06-1.88c-.24-.8-.2-1.56-.02-2.2.18-.62.58-1.08 1.06-1.3l.02-.02 9-5.4c.1-.06.18-.1.24-.16.06-.04.14-.08.24-.12.16-.08.28-.12.5-.18 1.04-.3 2.24.1 3.22.98s1.84 2.24 2.26 3.86zm-2.58 5.98h-.02c.4-.1.74-.34 1.04-.7.58-.7.86-1.76.86-3.04 0-.64-.1-1.3-.28-1.98-.34-1.36-1.02-2.5-1.78-3.24s-1.68-1.1-2.46-.88c-.82.22-1.4.96-1.7 2-.32 1.04-.28 2.36.06 3.72.38 1.36 1 2.5 1.8 3.24.78.74 1.62 1.1 2.48.88zm-2.54-7.08c.22-.04.42-.02.62.04.38.16.76.48 1.02 1s.42 1.2.42 1.78c0 .3-.04.56-.12.8-.18.48-.44.84-.86.94-.34.1-.8-.06-1.14-.4s-.64-.86-.78-1.5c-.18-.62-.12-1.24.02-1.72s.48-.84.82-.94z"/></g></svg>
img/svg/minus.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M4 9h12v2H4V9z"/></g></svg>
img/svg/plus-alt.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M15.8 4.2c3.2 3.21 3.2 8.39 0 11.6-3.21 3.2-8.39 3.2-11.6 0C1 12.59 1 7.41 4.2 4.2 7.41 1 12.59 1 15.8 4.2zm-4.3 11.3v-4h4v-3h-4v-4h-3v4h-4v3h4v4h3z"/></g></svg>
img/svg/schedule.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M2 2h16v4H2V2zm0 10V8h4v4H2zm6-2V8h4v2H8zm6 3V8h4v5h-4zm-6 5v-6h4v6H8zm-6 0v-4h4v4H2zm12 0v-3h4v3h-4z"/></g></svg>
img/svg/select-arrow-down-alt2-light.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="16" height="16"><path fill="#7d8690" d="M5 6l5 5 5-5 2 1-7 7-7-7z"/></svg>
img/svg/select-arrow-down-alt2.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="16" height="16"><path fill="#000000" d="M5 6l5 5 5-5 2 1-7 7-7-7z"/></svg>
img/svg/share-alt2.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M18 8l-5 4V9.01c-2.58.06-4.88.45-7 2.99.29-3.57 2.66-5.66 7-5.94V3zM4 14h11v-2l2-1.6V16H2V5h9.43c-1.83.32-3.31 1-4.41 2H4v7z"/></g></svg>
img/svg/slides.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M5 14V6h10v8H5zm-3-1V7h2v6H2zm4-6v6h8V7H6zm10 0h2v6h-2V7zm-3 2V8H7v1h6zm0 3v-2H7v2h6z"/></g></svg>
img/svg/star-filled.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M10 1l3 6 6 .75-4.12 4.62L16 19l-6-3-6 3 1.13-6.63L1 7.75 7 7z"/></g></svg>
img/svg/text.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M18 3v2H2V3h16zm-6 4v2H2V7h10zm6 0v2h-4V7h4zM8 11v2H2v-2h6zm10 0v2h-8v-2h8zm-4 4v2H2v-2h12z"/></g></svg>
img/svg/wordpress-alt.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M20 10c0-5.51-4.49-10-10-10C4.48 0 0 4.49 0 10c0 5.52 4.48 10 10 10 5.51 0 10-4.48 10-10zM7.78 15.37L4.37 6.22c.55-.02 1.17-.08 1.17-.08.5-.06.44-1.13-.06-1.11 0 0-1.45.11-2.37.11-.18 0-.37 0-.58-.01C4.12 2.69 6.87 1.11 10 1.11c2.33 0 4.45.87 6.05 2.34-.68-.11-1.65.39-1.65 1.58 0 .74.45 1.36.9 2.1.35.61.55 1.36.55 2.46 0 1.49-1.4 5-1.4 5l-3.03-8.37c.54-.02.82-.17.82-.17.5-.05.44-1.25-.06-1.22 0 0-1.44.12-2.38.12-.87 0-2.33-.12-2.33-.12-.5-.03-.56 1.2-.06 1.22l.92.08 1.26 3.41zM17.41 10c.24-.64.74-1.87.43-4.25.7 1.29 1.05 2.71 1.05 4.25 0 3.29-1.73 6.24-4.4 7.78.97-2.59 1.94-5.2 2.92-7.78zM6.1 18.09C3.12 16.65 1.11 13.53 1.11 10c0-1.3.23-2.48.72-3.59C3.25 10.3 4.67 14.2 6.1 18.09zm4.03-6.63l2.58 6.98c-.86.29-1.76.45-2.71.45-.79 0-1.57-.11-2.29-.33.81-2.38 1.62-4.74 2.42-7.1z"/></g></svg>
includes/admin-settings-welcome.php CHANGED
@@ -8,13 +8,14 @@ function fl_welcome_utm( $campaign ) {
8
  );
9
  }
10
 
11
- $blog_post_url = FLBuilderModel::get_store_url( 'beaver-builder-1-9-shasta', fl_welcome_utm( 'settings-welcome-blog-post' ) );
12
  $change_logs_url = FLBuilderModel::get_store_url( 'change-logs', fl_welcome_utm( 'settings-welcome-change-logs' ) );
13
  $upgrade_url = FLBuilderModel::get_upgrade_url( fl_welcome_utm( 'settings-welcome-upgrade' ) );
14
  $support_url = FLBuilderModel::get_store_url( 'beaver-builder-support', fl_welcome_utm( 'settings-welcome-support' ) );
15
  $faqs_url = FLBuilderModel::get_store_url( 'frequently-asked-questions', fl_welcome_utm( 'settings-welcome-faqs' ) );
16
  $forums_url = FLBuilderModel::get_store_url( 'support', fl_welcome_utm( 'settings-welcome-forums' ) );
17
  $docs_url = 'http://kb.wpbeaverbuilder.com/';
 
18
 
19
  ?>
20
  <div id="fl-welcome-form" class="fl-settings-form">
@@ -68,15 +69,16 @@ $docs_url = 'http://kb.wpbeaverbuilder.com/';
68
 
69
  <div class="fl-welcome-col">
70
 
71
- <h4><?php _e( 'What\'s New in Beaver Builder 1.9 Shasta', 'fl-builder' ); ?></h4>
72
 
73
- <p><?php _e( 'Beaver Builder 1.9 is out and it has some epic new features:', 'fl-builder' ); ?></p>
74
 
75
  <ul>
76
- <li><?php _e( 'The ability to drag, drop and nest columns.', 'fl-builder' ); ?></li>
77
- <li><?php _e( 'A revamped editor with more accurate dragging and dropping.', 'fl-builder' ); ?></li>
78
- <li><?php _e( 'Responsive settings for margins, paddings and borders.', 'fl-builder' ); ?></li>
79
- <li><?php _e( 'New content page templates available in the template selector.', 'fl-builder' ); ?></li>
 
80
  </ul>
81
 
82
  <p><?php printf( __( 'There\'s a whole lot more, too! Read about everything else on our <a href="%1$s" target="_blank">update post</a> or <a href="%2$s" target="_blank">change logs</a>.', 'fl-builder' ), $blog_post_url, $change_logs_url ); ?></p>
@@ -91,7 +93,7 @@ $docs_url = 'http://kb.wpbeaverbuilder.com/';
91
 
92
  <p><?php _e( 'The fastest way to find an answer to a question is to see if someone\'s already answered it!', 'fl-builder' ); ?></p>
93
 
94
- <p><?php printf( __( 'For that, check our <a href="%1$s" target="_blank">Knowledge Base</a>, <a href="%2$s" target="_blank">FAQ page</a>, or search our legacy <a href="%3$s" target="_blank">support forum.</a>', 'fl-builder' ), $docs_url, $faqs_url, $forums_url ); ?></p>
95
 
96
  <?php if ( true === FL_BUILDER_LITE ) : ?>
97
  <p><?php printf( __( 'If you can\'t find an answer, consider upgrading to a premium version of Beaver Builder. Our expert support team is waiting to answer your questions and help you build your website. <a href="%s" target="_blank">Learn More</a>.', 'fl-builder' ), $upgrade_url ); ?></p>
8
  );
9
  }
10
 
11
+ $blog_post_url = FLBuilderModel::get_store_url( 'beaver-builder-2-0-hoover', fl_welcome_utm( 'settings-welcome-blog-post' ) );
12
  $change_logs_url = FLBuilderModel::get_store_url( 'change-logs', fl_welcome_utm( 'settings-welcome-change-logs' ) );
13
  $upgrade_url = FLBuilderModel::get_upgrade_url( fl_welcome_utm( 'settings-welcome-upgrade' ) );
14
  $support_url = FLBuilderModel::get_store_url( 'beaver-builder-support', fl_welcome_utm( 'settings-welcome-support' ) );
15
  $faqs_url = FLBuilderModel::get_store_url( 'frequently-asked-questions', fl_welcome_utm( 'settings-welcome-faqs' ) );
16
  $forums_url = FLBuilderModel::get_store_url( 'support', fl_welcome_utm( 'settings-welcome-forums' ) );
17
  $docs_url = 'http://kb.wpbeaverbuilder.com/';
18
+ $fb_url = 'https://www.facebook.com/groups/beaverbuilders/';
19
 
20
  ?>
21
  <div id="fl-welcome-form" class="fl-settings-form">
69
 
70
  <div class="fl-welcome-col">
71
 
72
+ <h4><?php _e( 'What\'s New in Beaver Builder 2.0 Hoover', 'fl-builder' ); ?></h4>
73
 
74
+ <p><?php _e( 'We’re thrilled to announce Beaver Builder 2.0, Hoover. Beaver Builder 2.0 looks better, feels better, it\'s faster, and we\'re introducing new customization options and tons of workflow improvements.', 'fl-builder' ); ?></p>
75
 
76
  <ul>
77
+ <li><?php _e( 'A sleek and modern visual refresh.', 'fl-builder' ); ?></li>
78
+ <li><?php _e( 'A centralized main menu.', 'fl-builder' ); ?></li>
79
+ <li><?php _e( 'Keyboard shortcuts.', 'fl-builder' ); ?></li>
80
+ <li><?php _e( 'Major performance improvements.', 'fl-builder' ); ?></li>
81
+ <li><?php _e( 'Customizable and dockable settings panels.', 'fl-builder' ); ?></li>
82
  </ul>
83
 
84
  <p><?php printf( __( 'There\'s a whole lot more, too! Read about everything else on our <a href="%1$s" target="_blank">update post</a> or <a href="%2$s" target="_blank">change logs</a>.', 'fl-builder' ), $blog_post_url, $change_logs_url ); ?></p>
93
 
94
  <p><?php _e( 'The fastest way to find an answer to a question is to see if someone\'s already answered it!', 'fl-builder' ); ?></p>
95
 
96
+ <p><?php printf( __( 'For that, check our <a href="%1$s" target="_blank">Knowledge Base</a> or try searching <a href="%2$s" target="_blank">the Beaver Builders Facebook group</a>.', 'fl-builder' ), $docs_url, $fb_url ); ?></p>
97
 
98
  <?php if ( true === FL_BUILDER_LITE ) : ?>
99
  <p><?php printf( __( 'If you can\'t find an answer, consider upgrading to a premium version of Beaver Builder. Our expert support team is waiting to answer your questions and help you build your website. <a href="%s" target="_blank">Learn More</a>.', 'fl-builder' ), $upgrade_url ); ?></p>
includes/column-settings.php CHANGED
@@ -259,16 +259,16 @@ FLBuilder::register_settings_form('col', array(
259
  'fields' => array(),
260
  ),
261
  'solid' => array(
262
- 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
263
  ),
264
  'dashed' => array(
265
- 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
266
  ),
267
  'dotted' => array(
268
- 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
269
  ),
270
  'double' => array(
271
- 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
272
  ),
273
  ),
274
  'preview' => array(
@@ -294,58 +294,9 @@ FLBuilder::register_settings_form('col', array(
294
  'type' => 'none',
295
  ),
296
  ),
297
- 'border_top' => array(
298
- 'type' => 'unit',
299
- 'label' => __( 'Top Width', 'fl-builder' ),
300
- 'default' => '1',
301
- 'description' => 'px',
302
- 'preview' => array(
303
- 'type' => 'none',
304
- ),
305
- 'responsive' => array(
306
- 'placeholder' => array(
307
- 'default' => '0',
308
- 'medium' => '',
309
- 'responsive' => '',
310
- ),
311
- ),
312
- ),
313
- 'border_bottom' => array(
314
- 'type' => 'unit',
315
- 'label' => __( 'Bottom Width', 'fl-builder' ),
316
- 'default' => '1',
317
- 'description' => 'px',
318
- 'preview' => array(
319
- 'type' => 'none',
320
- ),
321
- 'responsive' => array(
322
- 'placeholder' => array(
323
- 'default' => '0',
324
- 'medium' => '',
325
- 'responsive' => '',
326
- ),
327
- ),
328
- ),
329
- 'border_left' => array(
330
- 'type' => 'unit',
331
- 'label' => __( 'Left Width', 'fl-builder' ),
332
- 'default' => '1',
333
- 'description' => 'px',
334
- 'preview' => array(
335
- 'type' => 'none',
336
- ),
337
- 'responsive' => array(
338
- 'placeholder' => array(
339
- 'default' => '0',
340
- 'medium' => '',
341
- 'responsive' => '',
342
- ),
343
- ),
344
- ),
345
- 'border_right' => array(
346
- 'type' => 'unit',
347
- 'label' => __( 'Right Width', 'fl-builder' ),
348
- 'default' => '1',
349
  'description' => 'px',
350
  'preview' => array(
351
  'type' => 'none',
@@ -366,76 +317,11 @@ FLBuilder::register_settings_form('col', array(
366
  'title' => __( 'Advanced', 'fl-builder' ),
367
  'sections' => array(
368
  'margins' => array(
369
- 'title' => __( 'Margins', 'fl-builder' ),
370
  'fields' => array(
371
- 'margin_top' => array(
372
- 'type' => 'unit',
373
- 'label' => __( 'Top', 'fl-builder' ),
374
- 'description' => 'px',
375
- 'preview' => array(
376
- 'type' => 'none',
377
- ),
378
- 'placeholder' => '0',
379
- 'responsive' => true,
380
- ),
381
- 'margin_bottom' => array(
382
- 'type' => 'unit',
383
- 'label' => __( 'Bottom', 'fl-builder' ),
384
- 'description' => 'px',
385
- 'preview' => array(
386
- 'type' => 'none',
387
- ),
388
- 'placeholder' => '0',
389
- 'responsive' => true,
390
- ),
391
- 'margin_left' => array(
392
- 'type' => 'unit',
393
- 'label' => __( 'Left', 'fl-builder' ),
394
- 'description' => 'px',
395
- 'preview' => array(
396
- 'type' => 'none',
397
- ),
398
- 'placeholder' => '0',
399
- 'responsive' => true,
400
- ),
401
- 'margin_right' => array(
402
- 'type' => 'unit',
403
- 'label' => __( 'Right', 'fl-builder' ),
404
- 'description' => 'px',
405
- 'preview' => array(
406
- 'type' => 'none',
407
- ),
408
- 'placeholder' => '0',
409
- 'responsive' => true,
410
- ),
411
- ),
412
- ),
413
- 'padding' => array(
414
- 'title' => __( 'Padding', 'fl-builder' ),
415
- 'fields' => array(
416
- 'padding_top' => array(
417
- 'type' => 'unit',
418
- 'label' => __( 'Top', 'fl-builder' ),
419
- 'description' => 'px',
420
- 'preview' => array(
421
- 'type' => 'none',
422
- ),
423
- 'placeholder' => '0',
424
- 'responsive' => true,
425
- ),
426
- 'padding_bottom' => array(
427
- 'type' => 'unit',
428
- 'label' => __( 'Bottom', 'fl-builder' ),
429
- 'description' => 'px',
430
- 'preview' => array(
431
- 'type' => 'none',
432
- ),
433
- 'placeholder' => '0',
434
- 'responsive' => true,
435
- ),
436
- 'padding_left' => array(
437
- 'type' => 'unit',
438
- 'label' => __( 'Left', 'fl-builder' ),
439
  'description' => 'px',
440
  'preview' => array(
441
  'type' => 'none',
@@ -443,9 +329,9 @@ FLBuilder::register_settings_form('col', array(
443
  'placeholder' => '0',
444
  'responsive' => true,
445
  ),
446
- 'padding_right' => array(
447
- 'type' => 'unit',
448
- 'label' => __( 'Right', 'fl-builder' ),
449
  'description' => 'px',
450
  'preview' => array(
451
  'type' => 'none',
259
  'fields' => array(),
260
  ),
261
  'solid' => array(
262
+ 'fields' => array( 'border_color', 'border_opacity', 'border' ),
263
  ),
264
  'dashed' => array(
265
+ 'fields' => array( 'border_color', 'border_opacity', 'border' ),
266
  ),
267
  'dotted' => array(
268
+ 'fields' => array( 'border_color', 'border_opacity', 'border' ),
269
  ),
270
  'double' => array(
271
+ 'fields' => array( 'border_color', 'border_opacity', 'border' ),
272
  ),
273
  ),
274
  'preview' => array(
294
  'type' => 'none',
295
  ),
296
  ),
297
+ 'border' => array(
298
+ 'type' => 'dimension',
299
+ 'label' => __( 'Width', 'fl-builder' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  'description' => 'px',
301
  'preview' => array(
302
  'type' => 'none',
317
  'title' => __( 'Advanced', 'fl-builder' ),
318
  'sections' => array(
319
  'margins' => array(
320
+ 'title' => __( 'Spacing', 'fl-builder' ),
321
  'fields' => array(
322
+ 'margin' => array(
323
+ 'type' => 'dimension',
324
+ 'label' => __( 'Margins', 'fl-builder' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  'description' => 'px',
326
  'preview' => array(
327
  'type' => 'none',
329
  'placeholder' => '0',
330
  'responsive' => true,
331
  ),
332
+ 'padding' => array(
333
+ 'type' => 'dimension',
334
+ 'label' => __( 'Padding', 'fl-builder' ),
335
  'description' => 'px',
336
  'preview' => array(
337
  'type' => 'none',
includes/compatibility.php CHANGED
@@ -272,3 +272,14 @@ function fl_autoptimize_filter_noptimize_filter( $args ) {
272
  return $args;
273
  }
274
  add_filter( 'autoptimize_filter_noptimize', 'fl_autoptimize_filter_noptimize_filter' );
 
 
 
 
 
 
 
 
 
 
 
272
  return $args;
273
  }
274
  add_filter( 'autoptimize_filter_noptimize', 'fl_autoptimize_filter_noptimize_filter' );
275
+
276
+ /**
277
+ * Plugin Enjoy Instagram loads its js and css on all frontend pages breaking the builder.
278
+ * @since 2.0.1
279
+ */
280
+ add_action( 'template_redirect', 'fix_aggiungi_script_instafeed_owl', 1000 );
281
+ function fix_aggiungi_script_instafeed_owl() {
282
+ if ( FLBuilderModel::is_builder_active() ) {
283
+ remove_action( 'wp_enqueue_scripts', 'aggiungi_script_instafeed_owl' );
284
+ }
285
+ }
includes/field-button.php DELETED
@@ -1 +0,0 @@
1
- <span class="fl-builder-button<?php if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>" href="javascript:void(0);" onclick="return false;"><?php echo $field['label']; ?></span>
 
includes/field-code.php DELETED
@@ -1,57 +0,0 @@
1
- <div class="fl-code-field">
2
- <?php
3
-
4
- $editor_id = 'flcode' . time() . '_' . $name;
5
- $value = is_array( $value ) ? htmlspecialchars( json_encode( $value ) ) : htmlspecialchars( $value );
6
- $editor_defaults = array(
7
- 'enableBasicAutocompletion' => 'true',
8
- 'enableLiveAutocompletion' => 'true',
9
- 'enableSnippets' => 'false',
10
- 'showLineNumbers' => 'false',
11
- 'showFoldWidgets' => 'false',
12
- );
13
-
14
- $editor_opts = wp_parse_args( apply_filters( 'fl_builder_ace_options', $editor_defaults ), $editor_defaults );
15
-
16
- ?>
17
- <textarea id="<?php echo $editor_id; ?>" name="<?php echo $name; ?>" data-editor="<?php echo $field['editor']; ?>" <?php if ( isset( $field['class'] ) ) { echo ' class="' . $field['class'] . '"';
18
- } if ( isset( $field['rows'] ) ) { echo ' rows="' . $field['rows'] . '"';} ?>><?php echo $value; ?></textarea>
19
- <script>
20
-
21
- jQuery(function(){
22
-
23
- var textarea = jQuery('#<?php echo $editor_id; ?>'),
24
- mode = textarea.data('editor'),
25
- editDiv = jQuery('<div>', {
26
- position: 'absolute',
27
- height: parseInt(textarea.attr('rows'), 10) * 20
28
- }),
29
- editor = null;
30
-
31
- editDiv.insertBefore(textarea);
32
- textarea.css('display', 'none');
33
- ace.require('ace/ext/language_tools');
34
- editor = ace.edit(editDiv[0]);
35
- editor.$blockScrolling = Infinity;
36
- editor.getSession().setValue(textarea.val());
37
- editor.getSession().setMode('ace/mode/' + mode);
38
-
39
- <?php if ( isset( $field['wrap'] ) && true === $field['wrap'] ) : ?>
40
- editor.getSession().setUseWrapMode(true);
41
- <?php endif; ?>
42
-
43
- editor.setOptions( {
44
- <?php foreach ( $editor_opts as $opt => $val ) {
45
- printf( "%s:%s,\n", $opt, $val );
46
- } ?>
47
- } );
48
-
49
- editor.getSession().on('change', function(e) {
50
- textarea.val(editor.getSession().getValue()).trigger('change');
51
- });
52
-
53
- textarea.closest( '.fl-field' ).data( 'editor', editor );
54
- });
55
-
56
- </script>
57
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-color.php DELETED
@@ -1,8 +0,0 @@
1
- <div class="fl-color-picker<?php if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
2
- <div class="fl-color-picker-color<?php if ( empty( $value ) ) { echo ' fl-color-picker-empty'; } ?><?php if ( isset( $field['show_alpha'] ) && $field['show_alpha'] ) { echo ' fl-color-picker-alpha-enabled'; } ?>"></div>
3
- <?php if ( isset( $field['show_reset'] ) && $field['show_reset'] ) : ?>
4
- <div class="fl-color-picker-clear"><div class="fl-color-picker-icon-remove"></div></div>
5
- <?php endif; ?>
6
- <input name="<?php echo $name; ?>" type="hidden" value="<?php echo $value; ?>" class="fl-color-picker-value" />
7
- <div class="fl-clear"></div>
8
- </div>
 
 
 
 
 
 
 
 
includes/field-editor.php DELETED
@@ -1,70 +0,0 @@
1
- <?php
2
-
3
- if ( ! isset( $field['wpautop'] ) || $field['wpautop'] ) {
4
- $wpautop = ' data-wpautop="1"';
5
- } else {
6
- $wpautop = ' data-wpautop="0"';
7
- }
8
-
9
- ?>
10
- <div class="fl-editor-field" id="<?php echo $name; ?>"<?php echo $wpautop; ?>>
11
- <?php
12
-
13
- // Remove 3rd party editor buttons.
14
- remove_all_actions( 'media_buttons', 999999 );
15
- remove_all_actions( 'media_buttons_context', 999999 );
16
- remove_all_filters( 'mce_external_plugins', 999999 );
17
-
18
- global $wp_version;
19
-
20
- $editor_id = 'flrich' . time() . '_' . $name;
21
-
22
- wp_editor($value, $editor_id, array(
23
- 'media_buttons' => isset( $field['media_buttons'] ) ? $field['media_buttons'] : true,
24
- 'textarea_rows' => isset( $field['rows'] ) ? $field['rows'] : 16,
25
- 'wpautop' => true,
26
- ));
27
-
28
- ?>
29
- <script type="text/javascript">
30
-
31
- <?php if ( version_compare( $wp_version, '3.8.9', '<=' ) ) : // Pre 3.9 editor init. ?>
32
- jQuery(function()
33
- {
34
- var editorId = '<?php echo $editor_id; ?>';
35
-
36
- quicktags({id : editorId});
37
- QTags._buttonsInit();
38
-
39
- if(typeof tinymce != 'undefined') {
40
- tinymce.execCommand('mceAddControl', true, editorId);
41
- }
42
-
43
- FLBuilder.initEditorField(editorId);
44
- });
45
- <?php else : // 3.9 and above editor init. ?>
46
- jQuery(function()
47
- {
48
- var editorId = '<?php echo $editor_id; ?>',
49
- hiddenEditor = tinyMCEPreInit.mceInit['flhiddeneditor'],
50
- editorProps = null;
51
-
52
- if(typeof tinymce != 'undefined') {
53
- editorProps = tinymce.extend({}, hiddenEditor);
54
- editorProps.selector = '#' + editorId;
55
- editorProps.body_class = editorProps.body_class.replace('flhiddeneditor', editorId);
56
- tinyMCEPreInit.mceInit[editorId] = editorProps;
57
- tinymce.init(editorProps);
58
- tinymce.ui.FloatPanel.zIndex = 100100; // Fix z-index issue in wp 4.8.1
59
- }
60
- if(typeof quicktags != 'undefined') {
61
- quicktags({id : editorId, buttons : 'strong,em,link,block,del,ins,img,ul,ol,li,code,close'});
62
- QTags._buttonsInit();
63
- }
64
-
65
- window.wpActiveEditor = editorId;
66
- });
67
- <?php endif; ?>
68
-
69
- </script>
70
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-font.php DELETED
@@ -1,9 +0,0 @@
1
- <?php $value = (array) $value; // Make sure we have an array and not an object. ?>
2
- <div class="fl-font-field">
3
- <select name="<?php echo $name . '[][family]'; ?>" class="fl-font-field-font">
4
- <?php FLBuilderFonts::display_select_font( $value['family'] ) ?>
5
- </select>
6
- <select name="<?php echo $name . '[][weight]'; ?>" class="fl-font-field-weight">
7
- <?php FLBuilderFonts::display_select_weight( $value['family'], $value['weight'] ) ?>
8
- </select>
9
- </div>
 
 
 
 
 
 
 
 
 
includes/field-form.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
- // Allow filtering of preview text output of a field
3
- $preview_text = apply_filters( 'fl_builder_form_field_preview_text', $field['preview_text'], $name, $field, $i );
4
- ?>
5
- <div class="fl-form-field fl-builder-custom-field"<?php if ( isset( $preview_text ) ) { echo ' data-preview-text="' . $preview_text . '"';} ?>>
6
- <div class="fl-form-field-preview-text">
7
- <?php
8
-
9
- if ( isset( $preview_text ) && is_object( $value ) ) {
10
-
11
- $form = FLBuilderModel::get_settings_form( $field['form'] );
12
- $form_fields = FLBuilderModel::get_settings_form_fields( $form['tabs'] );
13
-
14
- if ( isset( $form_fields[ $preview_text ] ) ) {
15
-
16
- $preview_field = $form_fields[ $preview_text ];
17
-
18
- if ( 'icon' == $preview_field['type'] ) {
19
- echo '<i class="' . $value->$preview_text . '"></i>';
20
- } elseif ( 'select' == $preview_field['type'] ) {
21
- echo $preview_field['options'][ $value->$preview_text ];
22
- } elseif ( ! empty( $value->{$preview_text} ) ) {
23
- echo FLBuilderUtils::snippetwop( strip_tags( str_replace( '&#39;', "'", $value->{$preview_text} ) ), 35 );
24
- }
25
- }
26
- }
27
-
28
- // JSON encode the value and fix encoding conflicts.
29
- if ( ! empty( $value ) ) {
30
- $value = str_replace( "'", '&#39;', json_encode( $value ) );
31
- $value = str_replace( '<wbr \/>', '<wbr>', $value );
32
- }
33
-
34
- ?>
35
- </div>
36
- <a class="fl-form-field-edit" href="javascript:void(0);" onclick="return false;" data-type="<?php echo $field['form']; ?>"><?php printf( _x( 'Edit %s', '%s stands for form field label.', 'fl-builder' ), $field['label'] ); ?></a>
37
- <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
38
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-icon.php DELETED
@@ -1,12 +0,0 @@
1
- <div class="fl-icon-field fl-builder-custom-field<?php if ( empty( $value ) ) { echo ' fl-icon-empty';
2
- } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
3
- <a class="fl-icon-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Icon', 'fl-builder' ); ?></a>
4
- <div class="fl-icon-preview">
5
- <i class="<?php echo $value; ?>" data-icon="<?php echo $value; ?>"></i>
6
- <a class="fl-icon-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace', 'fl-builder' ); ?></a>
7
- <?php if ( isset( $field['show_remove'] ) && $field['show_remove'] ) : ?>
8
- <a class="fl-icon-remove" href="javascript:void(0);" onclick="return false;"><?php _e( 'Remove', 'fl-builder' ); ?></a>
9
- <?php endif; ?>
10
- </div>
11
- <input name="<?php echo $name; ?>" type="hidden" value="<?php echo $value; ?>" />
12
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-layout.php DELETED
@@ -1,9 +0,0 @@
1
- <div class="fl-layout-field">
2
- <?php foreach ( $field['options'] as $key => $img ) : ?>
3
- <div class="fl-layout-field-option <?php if ( $key == $value ) { echo 'fl-layout-field-option-selected';} ?>" data-value="<?php echo $key; ?>">
4
- <img src="<?php echo $img; ?>" />
5
- </div>
6
- <?php endforeach; ?>
7
- <div class="fl-clear"></div>
8
- <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
9
- </div>
 
 
 
 
 
 
 
 
 
includes/field-link.php DELETED
@@ -1,9 +0,0 @@
1
- <div class="fl-link-field">
2
- <input type="text" name="<?php echo $name; ?>" value="<?php echo $value; ?>" class="text fl-link-field-input" placeholder="<?php _ex( 'http://www.example.com', 'Link placeholder', 'fl-builder' ); ?>" />
3
- <span class="fl-link-field-select fl-builder-button fl-builder-button-small" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select', 'fl-builder' ); ?></span>
4
- <div class="fl-link-field-search">
5
- <span class="fl-link-field-search-title"><?php _e( 'Enter a post title to search.', 'fl-builder' ); ?></span>
6
- <input type="text" name="<?php echo $name; ?>-search" class="text text-full fl-link-field-search-input" placeholder="<?php esc_attr_e( 'Start typing...', 'fl-builder' ); ?>" />
7
- <span class="fl-link-field-search-cancel fl-builder-button fl-builder-button-small" href="javascript:void(0);" onclick="return false;"><?php _e( 'Cancel', 'fl-builder' ); ?></span>
8
- </div>
9
- </div>
 
 
 
 
 
 
 
 
 
includes/field-multiple-audios.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
-
3
- // Normalize the value so we have an array.
4
- if ( ! empty( $value ) && is_string( $value ) ) {
5
-
6
- $value = json_decode( $value );
7
- if ( is_string( $value ) ) {
8
- $value = json_decode( $value );
9
- }
10
- if ( is_int( $value ) ) {
11
- $value = (array) $value;
12
- }
13
- } elseif ( empty( $value ) ) {
14
- $value = array();
15
- }
16
-
17
- ?>
18
- <div class="fl-multiple-audios-field fl-builder-custom-field<?php if ( empty( $value ) ) { echo ' fl-multiple-audios-empty';
19
- } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>" <?php if ( isset( $field['toggle'] ) ) { echo "data-toggle='" . json_encode( $field['toggle'] ) . "'";}?>>
20
- <div class="fl-multiple-audios-count">
21
- <?php printf( _n( '%d Audio File Selected', '%d Audio Files Selected', count( $value ), 'fl-builder' ), count( $value ) ); ?>
22
- </div>
23
- <a class="fl-multiple-audios-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Audio', 'fl-builder' ); ?></a>
24
- <a class="fl-multiple-audios-edit" href="javascript:void(0);" onclick="return false;"><?php _e( 'Edit Playlist', 'fl-builder' ); ?></a>
25
- <a class="fl-multiple-audios-add" href="javascript:void(0);" onclick="return false;"><?php _e( 'Add Audio Files', 'fl-builder' ); ?></a>
26
- <input name="<?php echo $name; ?>" type="hidden" value='<?php if ( ! empty( $value ) ) { echo json_encode( $value );} ?>' />
27
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-multiple-photos.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- // Normalize the value so we have an array.
4
- if ( ! empty( $value ) && is_string( $value ) ) {
5
-
6
- $value = json_decode( $value );
7
-
8
- // Older versions might be double encoded.
9
- if ( is_string( $value ) ) {
10
- $value = json_decode( $value );
11
- }
12
- } elseif ( empty( $value ) ) {
13
- $value = array();
14
- }
15
-
16
- ?>
17
- <div class="fl-multiple-photos-field fl-builder-custom-field<?php if ( empty( $value ) ) { echo ' fl-multiple-photos-empty';
18
- } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
19
- <div class="fl-multiple-photos-count">
20
- <?php printf( _n( '%d Photo Selected', '%d Photos Selected', count( $value ), 'fl-builder' ), count( $value ) ); ?>
21
- </div>
22
- <a class="fl-multiple-photos-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Create Gallery', 'fl-builder' ); ?></a>
23
- <a class="fl-multiple-photos-edit" href="javascript:void(0);" onclick="return false;"><?php _e( 'Edit Gallery', 'fl-builder' ); ?></a>
24
- <a class="fl-multiple-photos-add" href="javascript:void(0);" onclick="return false;"><?php _e( 'Add Photos', 'fl-builder' ); ?></a>
25
- <input name="<?php echo $name; ?>" type="hidden" value='<?php if ( ! empty( $value ) ) { echo json_encode( $value );} ?>' />
26
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-ordering.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- // Make sure we have an options array.
4
- if ( empty( $field['options'] ) ) {
5
- $field['options'] = array();
6
- }
7
-
8
- // Set the default value if we don't have one.
9
- if ( empty( $value ) ) {
10
- $value = array_keys( $field['options'] );
11
- }
12
-
13
- // Make sure any new options are added to the value.
14
- foreach ( $field['options'] as $key => $label ) {
15
- if ( ! in_array( $key, $value ) ) {
16
- $value[] = $key;
17
- }
18
- }
19
-
20
- ?>
21
- <div class="fl-ordering-field-options<?php if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
22
- <?php foreach ( $value as $key ) : ?>
23
- <div class="fl-ordering-field-option" data-key="<?php echo $key; ?>"><?php echo $field['options'][ $key ]; ?><i class="fa fa-arrows"></i> </div>
24
- <?php endforeach; ?>
25
- </div>
26
- <input type="hidden" name="<?php echo $name; ?>" value='<?php echo json_encode( $value ); ?>' />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-photo-sizes.php DELETED
@@ -1,12 +0,0 @@
1
- <select name="<?php echo $name; ?>">
2
- <?php
3
-
4
- foreach ( FLBuilderPhoto::sizes() as $size => $atts ) :
5
-
6
- $label = ucwords( str_replace( array( '_', '-' ), ' ', $size ) ) . ' (' . implode( 'x', $atts ) . ')';
7
-
8
- ?>
9
- <option value="<?php echo $size; ?>" <?php selected( $value, $size ); ?>><?php echo $label; ?></option>
10
- <?php endforeach; ?>
11
- <option value="full" <?php selected( $value, 'full' ); ?>><?php _e( 'Full Size', 'fl-builder' ); ?></option>
12
- </select>
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-photo.php DELETED
@@ -1,22 +0,0 @@
1
- <?php $photo = FLBuilderPhoto::get_attachment_data( $value ); ?>
2
- <div class="fl-photo-field fl-builder-custom-field<?php if ( empty( $value ) || ! $photo ) { echo ' fl-photo-empty';
3
- } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
4
- <a class="fl-photo-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Photo', 'fl-builder' ); ?></a>
5
- <div class="fl-photo-preview">
6
- <div class="fl-photo-preview-img">
7
- <img src="<?php if ( $photo ) { echo FLBuilderPhoto::get_thumb( $photo );} ?>" />
8
- </div>
9
- <select name="<?php echo $name; ?>_src">
10
- <?php if ( $photo && isset( $settings->{$name . '_src'} ) ) { echo FLBuilderPhoto::get_src_options( $settings->{$name . '_src'}, $photo );} ?>
11
- </select>
12
- <br />
13
- <a class="fl-photo-edit" href="javascript:void(0);" onclick="return false;"><?php _e( 'Edit', 'fl-builder' ); ?></a>
14
- <?php if ( isset( $field['show_remove'] ) && $field['show_remove'] ) : ?>
15
- <a class="fl-photo-remove" href="javascript:void(0);" onclick="return false;"><?php _e( 'Remove', 'fl-builder' ); ?></a>
16
- <?php else : ?>
17
- <a class="fl-photo-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace', 'fl-builder' ); ?></a>
18
- <?php endif; ?>
19
- <div class="fl-clear"></div>
20
- </div>
21
- <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
22
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-post-type.php DELETED
@@ -1,5 +0,0 @@
1
- <select name="<?php echo $name; ?>"<?php if ( isset( $field['class'] ) ) { echo ' class="' . $field['class'] . '"';} ?>>
2
- <?php foreach ( FLBuilderLoop::post_types() as $slug => $type ) : ?>
3
- <option value="<?php echo $slug; ?>" <?php selected( $value, $slug ); ?>><?php echo $type->labels->name; ?></option>
4
- <?php endforeach; ?>
5
- </select>
 
 
 
 
 
includes/field-select.php DELETED
@@ -1,152 +0,0 @@
1
- <?php
2
- /**
3
- * Select field
4
- *
5
- * Setup attributes example:
6
- *
7
- * 'select_field_name' => array(
8
- * 'type' => 'select',
9
- * 'label' => esc_html__( 'Select Field', 'fl-builder' ),
10
- * 'default' => 'option-1',
11
- * 'class' => '',
12
- * 'multi-select' => false,
13
- * 'options' => array(
14
- * 'option-1' => esc_html__( 'Option 1', 'fl-builder' ),
15
- * 'option-2' => array(
16
- * 'label' => esc_html__( 'Premium Option 2', 'fl-builder' ),
17
- * 'premium' => true,
18
- * ),
19
- * 'optgroup-1' => array(
20
- * 'label' => esc_html__( 'Optgroup 1', 'fl-builder' ),
21
- * 'options' => array( *
22
- * 'option-3' => esc_html__( 'Option 3', 'fl-builder' ),
23
- * 'option-4' => array(
24
- * 'label' => esc_html__( 'Premium Option 4', 'fl-builder' ),
25
- * 'premium' => true,
26
- * ),
27
- * ),
28
- * 'premium' => false,
29
- * ),
30
- * ),
31
- * 'toggle' => array(
32
- * 'option-1' => array(
33
- * 'fields' => array( 'my_field_1', 'my_field_2' ),
34
- * 'sections' => array( 'my_section' ),
35
- * 'tabs' => array( 'my_tab' ),
36
- * ),
37
- * 'option-2' => array(),
38
- * ),
39
- * 'hide' => '', @todo Write example setup attribute value
40
- * 'trigger' => '', @todo Write example setup attribute value
41
- * );
42
- *
43
- */
44
-
45
-
46
-
47
- $atts = '';
48
-
49
- // Multiselect?
50
- if ( isset( $field['multi-select'] ) ) {
51
- $atts .= ' multiple';
52
- $name .= '[]';
53
- }
54
-
55
- // Class
56
- if ( isset( $field['class'] ) ) {
57
- $atts .= ' class="' . esc_attr( $field['class'] ) . '"';
58
- }
59
-
60
- // Toggle data
61
- if ( isset( $field['toggle'] ) ) {
62
- $atts .= ' data-toggle="' . esc_attr( json_encode( $field['toggle'] ) ) . '"';
63
- }
64
-
65
- // Hide data
66
- if ( isset( $field['hide'] ) ) {
67
- $atts .= ' data-hide="' . esc_attr( json_encode( $field['hide'] ) ) . '"';
68
- }
69
-
70
- // Trigger data
71
- if ( isset( $field['trigger'] ) ) {
72
- $atts .= ' data-trigger="' . esc_attr( json_encode( $field['trigger'] ) ) . '"';
73
- }
74
-
75
- ?>
76
-
77
- <select name="<?php echo esc_attr( $name ); ?>"<?php echo $atts; ?>>
78
-
79
- <?php
80
-
81
- // Get the options from a function?
82
- if ( is_string( $field['options'] ) ) {
83
- $field['options'] = call_user_func( $field['options'] );
84
- }
85
-
86
- // Loop through the options
87
- foreach ( (array) $field['options'] as $option_key => $option_val ) {
88
-
89
- // Don't display premium options if using lite plugin version
90
- if ( is_array( $option_val ) && isset( $option_val['premium'] ) && $option_val['premium'] && true === FL_BUILDER_LITE ) {
91
- continue;
92
- }
93
-
94
- if ( is_array( $option_val ) && isset( $option_val['label'] ) && isset( $option_val['options'] ) ) {
95
-
96
- echo '<optgroup label="' . esc_attr( $option_val['label'] ) . '">';
97
-
98
- foreach ( (array) $option_val['options'] as $optgroup_option_key => $optgroup_option_val ) {
99
-
100
- // Don't display premium optgroup options if using lite plugin version
101
- if ( is_array( $optgroup_option_val ) && isset( $optgroup_option_val['premium'] ) && $optgroup_option_val['premium'] && true === FL_BUILDER_LITE ) {
102
- continue;
103
- }
104
-
105
- // Is selected?
106
-
107
- $selected = '';
108
-
109
- if ( is_array( $value ) && in_array( $optgroup_option_key, $value ) ) {
110
- // Multi select
111
- $selected = ' selected="selected"';
112
- } elseif ( ! is_array( $value ) && selected( $value, $optgroup_option_key, false ) ) {
113
- // Single select
114
- $selected = ' selected="selected"';
115
- }
116
-
117
- // Option label
118
- $label = ( is_array( $optgroup_option_val ) ) ? ( $optgroup_option_val['label'] ) : ( $optgroup_option_val );
119
-
120
- // Output option
121
- echo '<option value="' . esc_attr( $optgroup_option_key ) . '"' . $selected . '>' . esc_html( $label ) . '</option>';
122
-
123
- } // End foreach().
124
-
125
- echo '</optgroup>';
126
-
127
- } else {
128
-
129
- // Is selected?
130
-
131
- $selected = '';
132
-
133
- if ( is_array( $value ) && in_array( $option_key, $value ) ) {
134
- // Multi select
135
- $selected = ' selected="selected"';
136
- } elseif ( ! is_array( $value ) && selected( $value, $option_key, false ) ) {
137
- // Single select
138
- $selected = ' selected="selected"';
139
- }
140
-
141
- // Option label
142
- $label = ( is_array( $option_val ) ) ? ( $option_val['label'] ) : ( $option_val );
143
-
144
- // Output option
145
- echo '<option value="' . esc_attr( $option_key ) . '"' . $selected . '>' . esc_html( $label ) . '</option>';
146
-
147
- }// End if().
148
- } // End foreach().
149
-
150
- ?>
151
-
152
- </select>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-suggest.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- $class = isset( $field['class'] ) ? ' ' . $field['class'] : '';
4
- $action = isset( $field['action'] ) ? $field['action'] : '';
5
- $data = isset( $field['data'] ) ? $field['data'] : '';
6
- $placeholder = isset( $field['placeholder'] ) ? esc_attr( $field['placeholder'] ) : esc_attr__( 'Start typing...', 'fl-builder' );
7
- $limit = isset( $field['limit'] ) ? $field['limit'] : 'false';
8
- $args = isset( $field['args'] ) && is_array( $field['args'] ) ? $field['args'] : array();
9
- $value = FLBuilderAutoSuggest::get_value( $action, $value, $data );
10
-
11
- ?>
12
- <input type="text" class="text text-full fl-suggest-field<?php echo $class; ?>" name="<?php echo $name; ?>" data-value='<?php echo $value; ?>' data-action="<?php echo $action; ?>" data-action-data="<?php echo $data; ?>" data-limit="<?php echo $limit; ?>" data-args='<?php echo json_encode( $args ); ?>' placeholder="<?php echo $placeholder; ?>" />
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-text.php DELETED
@@ -1,76 +0,0 @@
1
- <input type="text" name="<?php echo $name; ?>" value="<?php echo esc_attr( $value ); ?>" class="text<?php if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];
2
- } if ( ! isset( $field['size'] ) ) { echo ' text-full';} ?>" <?php if ( isset( $field['placeholder'] ) ) { echo ' placeholder="' . $field['placeholder'] . '"';
3
- } if ( isset( $field['maxlength'] ) ) { echo ' maxlength="' . $field['maxlength'] . '"';
4
- } if ( isset( $field['size'] ) ) { echo ' size="' . $field['size'] . '"';} ?> />
5
-
6
- <?php
7
-
8
- /**
9
- * Adding predefined values selector
10
- */
11
-
12
- if (
13
- isset( $field['options'] )
14
- && is_array( $field['options'] )
15
- && ! empty( $field['options'] )
16
- ) :
17
-
18
- // Adding empty value if missing
19
-
20
- if ( ! isset( $field['options'][''] ) ) {
21
- $field['options'][''] = esc_html_x( '- Add predefined -', 'Add predefined value.', 'fl-builder' );
22
- }
23
-
24
- // Moving the empty value to top
25
-
26
- $selector_value_empty = $field['options'][''];
27
-
28
- unset( $field['options'][''] );
29
-
30
- $field['options'] = array(
31
- '' => $selector_value_empty,
32
- ) + $field['options'];
33
-
34
- // Outputting select field
35
-
36
- ?>
37
-
38
- <select class="fl-select-add-value" data-target="<?php echo esc_attr( $name ); ?>">
39
- <?php
40
-
41
- foreach ( $field['options'] as $option_value => $option ) {
42
-
43
- if (
44
- is_array( $option )
45
- && isset( $option['label'] )
46
- && isset( $option['options'] )
47
- ) {
48
-
49
- // Optgroups
50
-
51
- echo '<optgroup label="' . esc_attr( $option['label'] ) . '">';
52
-
53
- foreach ( (array) $option['options'] as $optgroup_option_value => $optgroup_option ) {
54
- echo '<option value="' . esc_attr( $optgroup_option_value ) . '">' . esc_html( $optgroup_option ) . '</option>';
55
- }
56
-
57
- echo '</optgroup>';
58
-
59
-
60
- } else {
61
-
62
- // Standard options
63
-
64
- echo '<option value="' . esc_attr( $option_value ) . '">' . esc_html( $option ) . '</option>';
65
-
66
- }
67
- } // End foreach().
68
-
69
- ?>
70
- </select>
71
-
72
- <?php
73
-
74
- endif;
75
-
76
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-textarea.php DELETED
@@ -1,3 +0,0 @@
1
- <textarea name="<?php echo $name; ?>"<?php if ( isset( $field['class'] ) ) { echo ' class="' . $field['class'] . '"';
2
- } if ( isset( $field['placeholder'] ) ) { echo ' placeholder="' . $field['placeholder'] . '"';
3
- } if ( isset( $field['rows'] ) ) { echo ' rows="' . $field['rows'] . '"';} ?>><?php echo $value; ?></textarea>
 
 
 
includes/field-time.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
- $prepend = array( '01','02','03','04','05','06','07','08','09' );
3
- $hours = array_merge( $prepend, range( 10, 12 ) );
4
- $minutes = array_merge( array( '00' ), $prepend, range( 10, 59 ) );
5
- $day_period = array( 'am', 'pm' );
6
-
7
- if ( is_object( $value ) ) {
8
- $value = (array) $value;
9
- }
10
- ?>
11
- <select name="<?php echo $name . '[][hours]'; ?>" class="fl-time-field-hours">
12
- <?php foreach ( $hours as $hour ) : ?>
13
- <?php $selected = isset( $value['hours'] ) && $value['hours'] == $hour ? ' selected="selected"' : ''; ?>
14
- <option value="<?php echo $hour ?>"<?php echo $selected ?>><?php echo $hour ?></option>
15
- <?php endforeach; ?>
16
- </select>
17
- <select name="<?php echo $name . '[][minutes]'; ?>" class="fl-time-field-minutes">
18
- <?php foreach ( $minutes as $minute ) : ?>
19
- <?php $selected = isset( $value['minutes'] ) && $value['minutes'] == $minute ? ' selected="selected"' : ''; ?>
20
- <option value="<?php echo $minute ?>"<?php echo $selected ?>><?php echo $minute ?></option>
21
- <?php endforeach; ?>
22
- </select>
23
- <select name="<?php echo $name . '[][day_period]'; ?>" class="fl-time-field-day_period">
24
- <?php foreach ( $day_period as $period ) : ?>
25
- <?php $selected = isset( $value['day_period'] ) && $value['day_period'] == $period ? ' selected="selected"' : ''; ?>
26
- <option value="<?php echo $period ?>"<?php echo $selected ?>><?php echo $period ?></option>
27
- <?php endforeach; ?>
28
- </select>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/field-timezone.php DELETED
@@ -1,6 +0,0 @@
1
- <select name="<?php echo $name; ?>"<?php if ( isset( $field['class'] ) ) { echo ' class="' . $field['class'] . '"';
2
- } if ( isset( $field['toggle'] ) ) { echo "data-toggle='" . json_encode( $field['toggle'] ) . "'";
3
- } if ( isset( $field['hide'] ) ) { echo "data-hide='" . json_encode( $field['hide'] ) . "'";
4
- } if ( isset( $field['trigger'] ) ) { echo "data-trigger='" . json_encode( $field['trigger'] ) . "'";} ?>>
5
- <?php echo FLBuilderTimezones::build_timezones( $settings->time_zone ); ?>
6
- </select>
 
 
 
 
 
 
includes/field-unit.php DELETED
@@ -1,6 +0,0 @@
1
- <input
2
- type="number"
3
- name="<?php echo esc_attr( $name ); ?>"
4
- value="<?php echo esc_attr( $value ); ?>"
5
- placeholder="<?php if ( isset( $field['placeholder'] ) ) { echo esc_attr( $field['placeholder'] );} ?>"
6
- />
 
 
 
 
 
 
includes/field-video.php DELETED
@@ -1,22 +0,0 @@
1
- <?php $video = FLBuilderPhoto::get_attachment_data( $value ); ?>
2
- <div class="fl-video-field fl-builder-custom-field<?php if ( empty( $value ) || ! $video ) { echo ' fl-video-empty';
3
- } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
4
- <a class="fl-video-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Video', 'fl-builder' ); ?></a>
5
- <div class="fl-video-preview">
6
- <?php if ( ! empty( $value ) && $video ) : ?>
7
- <div class="fl-video-preview-img">
8
- <img src="<?php echo $video->icon; ?>" />
9
- </div>
10
- <span class="fl-video-preview-filename"><?php echo $video->filename; ?></span>
11
- <?php else : ?>
12
- <div class="fl-video-preview-img">
13
- <img src="<?php echo FL_BUILDER_URL; ?>img/spacer.png" />
14
- </div>
15
- <span class="fl-video-preview-filename"></span>
16
- <?php endif; ?>
17
- <br />
18
- <a class="fl-video-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace Video', 'fl-builder' ); ?></a>
19
- <div class="fl-clear"></div>
20
- </div>
21
- <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
22
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/global-settings.php CHANGED
@@ -43,6 +43,7 @@ FLBuilder::register_settings_form('global', array(
43
  'placeholder' => '0',
44
  'responsive' => true,
45
  'description' => 'px',
 
46
  ),
47
  'row_padding' => array(
48
  'type' => 'unit',
@@ -51,6 +52,7 @@ FLBuilder::register_settings_form('global', array(
51
  'placeholder' => '0',
52
  'responsive' => true,
53
  'description' => 'px',
 
54
  ),
55
  'row_width' => array(
56
  'type' => 'text',
@@ -59,6 +61,7 @@ FLBuilder::register_settings_form('global', array(
59
  'maxlength' => '4',
60
  'size' => '5',
61
  'description' => 'px',
 
62
  'help' => __( 'All rows will default to this width. You can override this and make a row full width in the settings for each row.', 'fl-builder' ),
63
  ),
64
  'row_width_default' => array(
@@ -96,6 +99,7 @@ FLBuilder::register_settings_form('global', array(
96
  'placeholder' => '0',
97
  'responsive' => true,
98
  'description' => 'px',
 
99
  ),
100
  ),
101
  ),
@@ -133,6 +137,7 @@ FLBuilder::register_settings_form('global', array(
133
  'maxlength' => '4',
134
  'size' => '5',
135
  'description' => 'px',
 
136
  'help' => __( 'The browser width at which the layout will adjust for medium devices such as tablets.', 'fl-builder' ),
137
  ),
138
  'responsive_breakpoint' => array(
@@ -142,6 +147,7 @@ FLBuilder::register_settings_form('global', array(
142
  'maxlength' => '4',
143
  'size' => '5',
144
  'description' => 'px',
 
145
  'help' => __( 'The browser width at which the layout will adjust for small devices such as phones.', 'fl-builder' ),
146
  ),
147
  ),
43
  'placeholder' => '0',
44
  'responsive' => true,
45
  'description' => 'px',
46
+ 'sanitize' => 'absint',
47
  ),
48
  'row_padding' => array(
49
  'type' => 'unit',
52
  'placeholder' => '0',
53
  'responsive' => true,
54
  'description' => 'px',
55
+ 'sanitize' => 'absint',
56
  ),
57
  'row_width' => array(
58
  'type' => 'text',
61
  'maxlength' => '4',
62
  'size' => '5',
63
  'description' => 'px',
64
+ 'sanitize' => 'absint',
65
  'help' => __( 'All rows will default to this width. You can override this and make a row full width in the settings for each row.', 'fl-builder' ),
66
  ),
67
  'row_width_default' => array(
99
  'placeholder' => '0',
100
  'responsive' => true,
101
  'description' => 'px',
102
+ 'sanitize' => 'absint',
103
  ),
104
  ),
105
  ),
137
  'maxlength' => '4',
138
  'size' => '5',
139
  'description' => 'px',
140
+ 'sanitize' => 'absint',
141
  'help' => __( 'The browser width at which the layout will adjust for medium devices such as tablets.', 'fl-builder' ),
142
  ),
143
  'responsive_breakpoint' => array(
147
  'maxlength' => '4',
148
  'size' => '5',
149
  'description' => 'px',
150
+ 'sanitize' => 'absint',
151
  'help' => __( 'The browser width at which the layout will adjust for small devices such as phones.', 'fl-builder' ),
152
  ),
153
  ),
includes/icon-selector.php CHANGED
@@ -1,6 +1,6 @@
1
  <div class="fl-lightbox-header">
2
  <h1><?php _e( 'Select Icon', 'fl-builder' ); ?></h1>
3
- <div class="fl-icons-filter fl-builder-settings-fields">
4
  <select class="fl-icons-filter-select">
5
  <option value="all"><?php _ex( 'All Libraries', 'Select option for showing all icon libraries.', 'fl-builder' ); ?></option>
6
  <?php foreach ( $icon_sets as $set_key => $set_data ) : ?>
1
  <div class="fl-lightbox-header">
2
  <h1><?php _e( 'Select Icon', 'fl-builder' ); ?></h1>
3
+ <div class="fl-icons-filter">
4
  <select class="fl-icons-filter-select">
5
  <option value="all"><?php _ex( 'All Libraries', 'Select option for showing all icon libraries.', 'fl-builder' ); ?></option>
6
  <?php foreach ( $icon_sets as $set_key => $set_data ) : ?>
includes/jquery.php CHANGED
@@ -1,8 +1,8 @@
1
  <script type="text/javascript">
2
 
3
  if(typeof jQuery == 'undefined' || typeof jQuery.fn.on == 'undefined') {
4
- document.write('<script src="<?php echo FL_BUILDER_URL ?>js/jquery.js"><\/script>');
5
- document.write('<script src="<?php echo FL_BUILDER_URL ?>js/jquery.migrate.min.js"><\/script>');
6
  }
7
 
8
  </script>
1
  <script type="text/javascript">
2
 
3
  if(typeof jQuery == 'undefined' || typeof jQuery.fn.on == 'undefined') {
4
+ document.write('<script src="<?php echo includes_url( 'js/jquery/jquery.js' ); ?>"><\/script>');
5
+ document.write('<script src="<?php echo includes_url( 'js/jquery/jquery-migrate.min.js' ); ?>"><\/script>');
6
  }
7
 
8
  </script>
includes/loop-settings-matching.php CHANGED
@@ -1,4 +1,7 @@
1
  <select name="<?php echo $name ?>_matching">
2
- <option value="1" <?php selected( $settings->{ $name . '_matching' }, '1' ); ?>><?php printf( _x( 'Match these %s', '%s is an object like posts or taxonomies.', 'fl-builder' ), $field['label'] ); ?></option>
3
- <option value="0" <?php selected( $settings->{ $name . '_matching' }, '0' ); ?>><?php printf( _x( 'Do not match these %s', '%s is an object like posts or taxonomies.', 'fl-builder' ), $field['label'] ); ?></option>
 
 
 
4
  </select>
1
  <select name="<?php echo $name ?>_matching">
2
+ <option value="1" <?php selected( $settings->{ $name . '_matching' }, '1' ); ?>><?php printf( _x( 'Match these %s...', '%s is an object like posts or taxonomies.', 'fl-builder' ), $label ); ?></option>
3
+ <option value="0" <?php selected( $settings->{ $name . '_matching' }, '0' ); ?>><?php printf( _x( 'Match all %s except...', '%s is an object like posts or taxonomies.', 'fl-builder' ), $label ); ?></option>
4
+ <?php if ( 'fl_as_terms' === $field['action'] ) : ?>
5
+ <option value="related" <?php selected( $settings->{ $name . '_matching' }, 'related' ); ?>><?php printf( _x( 'Match all related %s except...', '%s is an object like posts or taxonomies.', 'fl-builder' ), $label ); ?></option>
6
+ <?php endif; ?>
7
  </select>
includes/module-settings.php CHANGED
@@ -6,56 +6,11 @@ FLBuilder::register_settings_form('module_advanced', array(
6
  'title' => __( 'Advanced', 'fl-builder' ),
7
  'sections' => array(
8
  'margins' => array(
9
- 'title' => __( 'Margins', 'fl-builder' ),
10
  'fields' => array(
11
- 'margin_top' => array(
12
- 'type' => 'unit',
13
- 'label' => __( 'Top', 'fl-builder' ),
14
- 'description' => 'px',
15
- 'preview' => array(
16
- 'type' => 'none',
17
- ),
18
- 'responsive' => array(
19
- 'placeholder' => array(
20
- 'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
21
- 'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
22
- 'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
23
- ),
24
- ),
25
- ),
26
- 'margin_bottom' => array(
27
- 'type' => 'unit',
28
- 'label' => __( 'Bottom', 'fl-builder' ),
29
- 'description' => 'px',
30
- 'preview' => array(
31
- 'type' => 'none',
32
- ),
33
- 'responsive' => array(
34
- 'placeholder' => array(
35
- 'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
36
- 'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
37
- 'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
38
- ),
39
- ),
40
- ),
41
- 'margin_left' => array(
42
- 'type' => 'unit',
43
- 'label' => __( 'Left', 'fl-builder' ),
44
- 'description' => 'px',
45
- 'preview' => array(
46
- 'type' => 'none',
47
- ),
48
- 'responsive' => array(
49
- 'placeholder' => array(
50
- 'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
51
- 'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
52
- 'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
53
- ),
54
- ),
55
- ),
56
- 'margin_right' => array(
57
- 'type' => 'unit',
58
- 'label' => __( 'Right', 'fl-builder' ),
59
  'description' => 'px',
60
  'preview' => array(
61
  'type' => 'none',
6
  'title' => __( 'Advanced', 'fl-builder' ),
7
  'sections' => array(
8
  'margins' => array(
9
+ 'title' => __( 'Spacing', 'fl-builder' ),
10
  'fields' => array(
11
+ 'margin' => array(
12
+ 'type' => 'dimension',
13
+ 'label' => __( 'Margins', 'fl-builder' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  'description' => 'px',
15
  'preview' => array(
16
  'type' => 'none',
includes/row-css.php CHANGED
@@ -107,3 +107,21 @@
107
  <?php endif; ?>
108
  }
109
  <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  <?php endif; ?>
108
  }
109
  <?php endif; ?>
110
+
111
+ <?php
112
+ // Row resize support
113
+ $has_max_width = ! empty( $row->settings->max_content_width );
114
+ $is_row_fixed = ( 'fixed' === $row->settings->width );
115
+ $is_row_content_fixed = ( 'fixed' === $row->settings->content_width );
116
+ $are_both_full_width = ( ! $is_row_fixed && ! $is_row_content_fixed );
117
+
118
+ if ( $has_max_width && ! $are_both_full_width ) {
119
+ if ( $is_row_fixed ) {
120
+ print '.fl-node-' . $row->node . ".fl-row-fixed-width,\n .fl-node-" . $row->node . " .fl-row-fixed-width {\n";
121
+ } else {
122
+ print '.fl-node-' . $row->node . " .fl-row-content {\n";
123
+ }
124
+ print "\tmax-width: " . $row->settings->max_content_width . "px;\n";
125
+ print "}\n";
126
+ }
127
+ ?>
includes/row-js.php CHANGED
@@ -20,6 +20,7 @@ YUI({'logExclude': { 'yui': true } }).use('fl-slideshow', function(Y) {
20
  loadingImageEnabled : false,
21
  randomize : <?php echo $settings->ss_randomize; ?>,
22
  responsiveThreshold : 0,
 
23
  source : [{<?php echo $source; ?>}],
24
  speed : <?php echo $settings->ss_speed * 1000; ?>,
25
  stretchy : true,
20
  loadingImageEnabled : false,
21
  randomize : <?php echo $settings->ss_randomize; ?>,
22
  responsiveThreshold : 0,
23
+ touchSupport : false,
24
  source : [{<?php echo $source; ?>}],
25
  speed : <?php echo $settings->ss_speed * 1000; ?>,
26
  stretchy : true,
includes/row-settings.php CHANGED
@@ -43,6 +43,15 @@ FLBuilder::register_settings_form('row', array(
43
  'type' => 'none',
44
  ),
45
  ),
 
 
 
 
 
 
 
 
 
46
  'full_height' => array(
47
  'type' => 'select',
48
  'label' => __( 'Height', 'fl-builder' ),
@@ -515,16 +524,16 @@ FLBuilder::register_settings_form('row', array(
515
  'fields' => array(),
516
  ),
517
  'solid' => array(
518
- 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
519
  ),
520
  'dashed' => array(
521
- 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
522
  ),
523
  'dotted' => array(
524
- 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
525
  ),
526
  'double' => array(
527
- 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
528
  ),
529
  ),
530
  'preview' => array(
@@ -550,59 +559,10 @@ FLBuilder::register_settings_form('row', array(
550
  'type' => 'none',
551
  ),
552
  ),
553
- 'border_top' => array(
554
- 'type' => 'unit',
555
- 'label' => __( 'Top Width', 'fl-builder' ),
556
- 'description' => 'px',
557
- 'default' => '1',
558
- 'preview' => array(
559
- 'type' => 'none',
560
- ),
561
- 'responsive' => array(
562
- 'placeholder' => array(
563
- 'default' => '1',
564
- 'medium' => '',
565
- 'responsive' => '',
566
- ),
567
- ),
568
- ),
569
- 'border_bottom' => array(
570
- 'type' => 'unit',
571
- 'label' => __( 'Bottom Width', 'fl-builder' ),
572
- 'description' => 'px',
573
- 'default' => '1',
574
- 'preview' => array(
575
- 'type' => 'none',
576
- ),
577
- 'responsive' => array(
578
- 'placeholder' => array(
579
- 'default' => '1',
580
- 'medium' => '',
581
- 'responsive' => '',
582
- ),
583
- ),
584
- ),
585
- 'border_left' => array(
586
- 'type' => 'unit',
587
- 'label' => __( 'Left Width', 'fl-builder' ),
588
- 'description' => 'px',
589
- 'default' => '0',
590
- 'preview' => array(
591
- 'type' => 'none',
592
- ),
593
- 'responsive' => array(
594
- 'placeholder' => array(
595
- 'default' => '0',
596
- 'medium' => '',
597
- 'responsive' => '',
598
- ),
599
- ),
600
- ),
601
- 'border_right' => array(
602
- 'type' => 'unit',
603
- 'label' => __( 'Right Width', 'fl-builder' ),
604
  'description' => 'px',
605
- 'default' => '0',
606
  'preview' => array(
607
  'type' => 'none',
608
  ),
@@ -622,26 +582,11 @@ FLBuilder::register_settings_form('row', array(
622
  'title' => __( 'Advanced', 'fl-builder' ),
623
  'sections' => array(
624
  'margins' => array(
625
- 'title' => __( 'Margins', 'fl-builder' ),
626
  'fields' => array(
627
- 'margin_top' => array(
628
- 'type' => 'unit',
629
- 'label' => __( 'Top', 'fl-builder' ),
630
- 'description' => 'px',
631
- 'preview' => array(
632
- 'type' => 'none',
633
- ),
634
- 'responsive' => array(
635
- 'placeholder' => array(
636
- 'default' => $spacing_placeholders['row_margins'],
637
- 'medium' => $spacing_placeholders['row_margins_medium'],
638
- 'responsive' => $spacing_placeholders['row_margins_responsive'],
639
- ),
640
- ),
641
- ),
642
- 'margin_bottom' => array(
643
- 'type' => 'unit',
644
- 'label' => __( 'Bottom', 'fl-builder' ),
645
  'description' => 'px',
646
  'preview' => array(
647
  'type' => 'none',
@@ -654,44 +599,9 @@ FLBuilder::register_settings_form('row', array(
654
  ),
655
  ),
656
  ),
657
- 'margin_left' => array(
658
- 'type' => 'unit',
659
- 'label' => __( 'Left', 'fl-builder' ),
660
- 'description' => 'px',
661
- 'preview' => array(
662
- 'type' => 'none',
663
- ),
664
- 'responsive' => array(
665
- 'placeholder' => array(
666
- 'default' => $spacing_placeholders['row_margins'],
667
- 'medium' => $spacing_placeholders['row_margins_medium'],
668
- 'responsive' => $spacing_placeholders['row_margins_responsive'],
669
- ),
670
- ),
671
- ),
672
- 'margin_right' => array(
673
- 'type' => 'unit',
674
- 'label' => __( 'Right', 'fl-builder' ),
675
- 'description' => 'px',
676
- 'preview' => array(
677
- 'type' => 'none',
678
- ),
679
- 'responsive' => array(
680
- 'placeholder' => array(
681
- 'default' => $spacing_placeholders['row_margins'],
682
- 'medium' => $spacing_placeholders['row_margins_medium'],
683
- 'responsive' => $spacing_placeholders['row_margins_responsive'],
684
- ),
685
- ),
686
- ),
687
- ),
688
- ),
689
- 'padding' => array(
690
- 'title' => __( 'Padding', 'fl-builder' ),
691
- 'fields' => array(
692
- 'padding_top' => array(
693
- 'type' => 'unit',
694
- 'label' => __( 'Top', 'fl-builder' ),
695
  'description' => 'px',
696
  'preview' => array(
697
  'type' => 'none',
@@ -704,51 +614,6 @@ FLBuilder::register_settings_form('row', array(
704
  ),
705
  ),
706
  ),
707
- 'padding_bottom' => array(
708
- 'type' => 'unit',
709
- 'label' => __( 'Bottom', 'fl-builder' ),
710
- 'description' => 'px',
711
- 'preview' => array(
712
- 'type' => 'none',
713
- ),
714
- 'responsive' => array(
715
- 'placeholder' => array(
716
- 'default' => $spacing_placeholders['row_padding'],
717
- 'medium' => $spacing_placeholders['row_padding_medium'],
718
- 'responsive' => $spacing_placeholders['row_padding_tb_responsive'],
719
- ),
720
- ),
721
- ),
722
- 'padding_left' => array(
723
- 'type' => 'unit',
724
- 'label' => __( 'Left', 'fl-builder' ),
725
- 'description' => 'px',
726
- 'preview' => array(
727
- 'type' => 'none',
728
- ),
729
- 'responsive' => array(
730
- 'placeholder' => array(
731
- 'default' => $spacing_placeholders['row_padding'],
732
- 'medium' => $spacing_placeholders['row_padding_medium'],
733
- 'responsive' => $spacing_placeholders['row_padding_lr_responsive'],
734
- ),
735
- ),
736
- ),
737
- 'padding_right' => array(
738
- 'type' => 'unit',
739
- 'label' => __( 'Right', 'fl-builder' ),
740
- 'description' => 'px',
741
- 'preview' => array(
742
- 'type' => 'none',
743
- ),
744
- 'responsive' => array(
745
- 'placeholder' => array(
746
- 'default' => $spacing_placeholders['row_padding'],
747
- 'medium' => $spacing_placeholders['row_padding_medium'],
748
- 'responsive' => $spacing_placeholders['row_padding_lr_responsive'],
749
- ),
750
- ),
751
- ),
752
  ),
753
  ),
754
  'responsive' => array(
43
  'type' => 'none',
44
  ),
45
  ),
46
+ 'max_content_width' => array(
47
+ 'type' => 'unit',
48
+ 'label' => __( 'Fixed Width', 'fl-builder' ),
49
+ 'description' => 'px',
50
+ 'placeholder' => $global_settings->row_width,
51
+ 'preview' => array(
52
+ 'type' => 'none',
53
+ ),
54
+ ),
55
  'full_height' => array(
56
  'type' => 'select',
57
  'label' => __( 'Height', 'fl-builder' ),
524
  'fields' => array(),
525
  ),
526
  'solid' => array(
527
+ 'fields' => array( 'border_color', 'border_opacity', 'border' ),
528
  ),
529
  'dashed' => array(
530
+ 'fields' => array( 'border_color', 'border_opacity', 'border' ),
531
  ),
532
  'dotted' => array(
533
+ 'fields' => array( 'border_color', 'border_opacity', 'border' ),
534
  ),
535
  'double' => array(
536
+ 'fields' => array( 'border_color', 'border_opacity', 'border' ),
537
  ),
538
  ),
539
  'preview' => array(
559
  'type' => 'none',
560
  ),
561
  ),
562
+ 'border' => array(
563
+ 'type' => 'dimension',
564
+ 'label' => __( 'Border', 'fl-builder' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
565
  'description' => 'px',
 
566
  'preview' => array(
567
  'type' => 'none',
568
  ),
582
  'title' => __( 'Advanced', 'fl-builder' ),
583
  'sections' => array(
584
  'margins' => array(
585
+ 'title' => __( 'Spacing', 'fl-builder' ),
586
  'fields' => array(
587
+ 'margin' => array(
588
+ 'type' => 'dimension',
589
+ 'label' => __( 'Margins', 'fl-builder' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
590
  'description' => 'px',
591
  'preview' => array(
592
  'type' => 'none',
599
  ),
600
  ),
601
  ),
602
+ 'padding' => array(
603
+ 'type' => 'dimension',
604
+ 'label' => __( 'Padding', 'fl-builder' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605
  'description' => 'px',
606
  'preview' => array(
607
  'type' => 'none',
614
  ),
615
  ),
616
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
617
  ),
618
  ),
619
  'responsive' => array(
includes/service-settings.php DELETED
@@ -1,46 +0,0 @@
1
- <div class="fl-builder-service-settings">
2
- <table class="fl-form-table">
3
- <?php
4
-
5
- // Get the service type.
6
- $service_type = null;
7
-
8
- if ( isset( $section['services'] ) && 'all' != $section['services'] ) {
9
- $service_type = $section['services'];
10
- }
11
-
12
- // Get the service data.
13
- $services = FLBuilderServices::get_services_data( $service_type );
14
-
15
- // Remove services that don't meet the requirements.
16
- if ( isset( $services['mailpoet'] )
17
- && ! class_exists( 'WYSIJA' )
18
- && ( ! defined( 'MAILPOET_INITIALIZED' ) || ( defined( 'MAILPOET_INITIALIZED' ) && false === MAILPOET_INITIALIZED ) )
19
- ) {
20
- unset( $services['mailpoet'] );
21
- }
22
-
23
- // Build the select options.
24
- $options = array(
25
- '' => __( 'Choose...', 'fl-builder' ),
26
- );
27
-
28
- foreach ( $services as $key => $service ) {
29
- $options[ $key ] = $service['name'];
30
- }
31
-
32
- // Render the service select.
33
- FLBuilder::render_settings_field( 'service', array(
34
- 'row_class' => 'fl-builder-service-select-row',
35
- 'class' => 'fl-builder-service-select',
36
- 'type' => 'select',
37
- 'label' => __( 'Service', 'fl-builder' ),
38
- 'options' => $options,
39
- 'preview' => array(
40
- 'type' => 'none',
41
- ),
42
- ), $settings );
43
-
44
- ?>
45
- </table>
46
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/settings.php DELETED
@@ -1,84 +0,0 @@
1
- <form class="fl-builder-settings <?php echo $form['class']; ?>" <?php echo $form['attrs']; ?> onsubmit="return false;">
2
- <div class="fl-lightbox-header">
3
- <h1>
4
- <?php echo $form['title']; ?>
5
- <?php foreach ( $form['badges'] as $form_badge_slug => $form_badge_title ) : ?>
6
- <span class="fl-builder-badge fl-builder-badge-<?php echo $form_badge_slug; ?>"><?php echo $form_badge_title; ?></span>
7
- <?php endforeach; ?>
8
- </h1>
9
- <?php if ( isset( $form['resizable'] ) && true === $form['resizable'] ) : ?>
10
- <div class="fl-lightbox-controls"><i class="fa fa-expand"></i></div>
11
- <?php endif; ?>
12
- </div>
13
- <?php if ( isset( $form['tabs'] ) && count( $form['tabs'] ) > 1 ) : ?>
14
- <div class="fl-builder-settings-tabs">
15
- <?php $i = 0; foreach ( $form['tabs'] as $id => $tab ) : ?>
16
- <a href="#fl-builder-settings-tab-<?php echo $id; ?>"<?php if ( 0 == $i ) { echo ' class="fl-active"';} ?>><?php echo $tab['title']; ?></a>
17
- <?php $i++;
18
- endforeach; ?>
19
- </div>
20
- <?php endif; ?>
21
- <div class="fl-builder-settings-fields fl-nanoscroller">
22
- <div class="fl-nanoscroller-content">
23
- <?php if ( isset( $form['tabs'] ) && count( $form['tabs'] ) > 0 ) : ?>
24
- <?php $i = 0; foreach ( $form['tabs'] as $id => $tab ) : // Tabs ?>
25
- <div id="fl-builder-settings-tab-<?php echo $id; ?>" class="fl-builder-settings-tab <?php if ( 0 == $i ) { echo 'fl-active';} ?>">
26
-
27
- <?php if ( isset( $tab['file'] ) && file_exists( $tab['file'] ) ) : // Tab File ?>
28
-
29
- <?php include $tab['file']; ?>
30
-
31
- <?php else : ?>
32
-
33
- <?php if ( ! empty( $tab['description'] ) ) : // Tab Description ?>
34
- <p class="fl-builder-settings-tab-description"><?php echo $tab['description']; ?></p>
35
- <?php endif; ?>
36
-
37
- <?php foreach ( $tab['sections'] as $id => $section ) : // Tab Sections ?>
38
- <div id="fl-builder-settings-section-<?php echo $id; ?>" class="fl-builder-settings-section">
39
-
40
- <?php if ( isset( $section['file'] ) && file_exists( $section['file'] ) ) : // Section File ?>
41
-
42
- <?php include $section['file']; ?>
43
-
44
- <?php else : ?>
45
-
46
- <?php if ( ! empty( $section['title'] ) ) : // Section Title ?>
47
- <h3 class="fl-builder-settings-title"><?php echo $section['title']; ?></h3>
48
- <?php endif; ?>
49
-
50
- <?php if ( isset( $section['description'] ) && ! empty( $section['description'] ) ) : // Section description ?>
51
- <p class="fl-builder-settings-description"><?php echo $section['description']; ?></p>
52
- <?php endif; ?>
53
-
54
- <table class="fl-form-table">
55
- <?php
56
-
57
- foreach ( $section['fields'] as $name => $field ) { // Fields
58
- FLBuilder::render_settings_field( $name, $field, $settings );
59
- }
60
-
61
- ?>
62
- </table>
63
-
64
- <?php endif; ?>
65
-
66
- </div>
67
- <?php endforeach; ?>
68
-
69
- <?php endif; ?>
70
-
71
- </div>
72
- <?php $i++;
73
- endforeach;
74
- endif; ?>
75
- </div>
76
- </div>
77
- <div class="fl-lightbox-footer">
78
- <span class="fl-builder-settings-save fl-builder-button fl-builder-button-large fl-builder-button-primary" href="javascript:void(0);" onclick="return false;"><?php _e( 'Save', 'fl-builder' ); ?></span>
79
- <?php if ( in_array( 'save-as', $form['buttons'] ) ) : ?>
80
- <span class="fl-builder-settings-save-as fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e( 'Save As...', 'fl-builder' ); ?></span>
81
- <?php endif; ?>
82
- <span class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e( 'Cancel', 'fl-builder' ); ?></span>
83
- </div>
84
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/template-selector.php DELETED
@@ -1,67 +0,0 @@
1
- <form class="fl-builder-settings fl-template-selector">
2
- <div class="fl-lightbox-header">
3
-
4
- <h1><?php _e( 'Layout Templates', 'fl-builder' ); ?></h1>
5
-
6
- <?php if ( count( $filter_data ) > 1 ) : ?>
7
- <div class="fl-template-category-filter fl-builder-settings-fields">
8
- <select class="fl-template-category-select" name="fl-template-category-select">
9
- <?php foreach ( $filter_data as $slug => $category ) : ?>
10
- <option value="fl-builder-settings-tab-<?php echo $slug; ?>"><?php echo $category; ?></option>
11
- <?php endforeach; ?>
12
- </select>
13
- </div>
14
- <?php endif; ?>
15
-
16
- </div>
17
- <div class="fl-builder-settings-fields fl-nanoscroller">
18
- <div class="fl-nanoscroller-content">
19
-
20
- <?php if ( true === FL_BUILDER_LITE ) : ?>
21
- <?php if ( FLBuilderModel::has_templates() ) : ?>
22
- <div class="fl-builder-settings-message fl-builder-templates-cta">
23
- <p><?php _e( 'Save and reuse your layouts or kick-start your creativity with even more professionally designed templates.', 'fl-builder' ); ?></p>
24
- <a class="fl-builder-upgrade-button fl-builder-button" href="<?php echo FLBuilderModel::get_upgrade_url( array(
25
- 'utm_medium' => 'bb-lite',
26
- 'utm_source' => 'builder-ui',
27
- 'utm_campaign' => 'templates-cta',
28
- ) ); ?>" target="_blank"><?php _e( 'Learn More', 'fl-builder' ); ?> <i class="fa fa-external-link-square"></i></a>
29
- </div>
30
- <?php else : ?>
31
- <div class="fl-builder-settings-message fl-builder-templates-cta">
32
- <p><?php _e( 'Save and reuse your layouts or kick-start your creativity with dozens of professionally designed templates.', 'fl-builder' ); ?></p>
33
- <a class="fl-builder-upgrade-button fl-builder-button" href="<?php echo FLBuilderModel::get_upgrade_url( array(
34
- 'utm_medium' => 'bb-lite',
35
- 'utm_source' => 'builder-ui',
36
- 'utm_campaign' => 'templates-cta',
37
- ) ); ?>" target="_blank"><?php _e( 'Learn More', 'fl-builder' ); ?> <i class="fa fa-external-link-square"></i></a>
38
- </div>
39
- <img class="fl-builder-templates-cta-img" src="<?php echo FL_BUILDER_URL; ?>img/templates-preview.jpg" />
40
- <?php endif; ?>
41
- <?php endif; ?>
42
-
43
- <?php $i = 0; foreach ( $templates['categorized'] as $slug => $category ) : ?>
44
- <div id="fl-builder-settings-tab-<?php echo $slug; ?>" class="fl-builder-settings-tab<?php if ( 0 === $i ) { echo ' fl-active';} ?>">
45
- <div class="fl-builder-settings-section">
46
- <?php $k = 0; foreach ( $category['templates'] as $template ) : ?>
47
- <div class="fl-template-preview<?php if ( ($k + 1) % 3 === 0 ) { echo ' fl-last';} ?>" data-id="<?php echo $template['id']; ?>">
48
- <div class="fl-template-image">
49
- <img src="<?php echo $template['image']; ?>" />
50
- </div>
51
- <span><?php echo $template['name']; ?></span>
52
- </div>
53
- <?php $k++;
54
- endforeach; ?>
55
- </div>
56
- </div>
57
- <?php $i++;
58
- endforeach; ?>
59
-
60
- <?php do_action( 'fl_builder_template_selector_content' ); ?>
61
-
62
- </div>
63
- </div>
64
- <div class="fl-lightbox-footer">
65
- <span class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e( 'Cancel', 'fl-builder' ); ?></span>
66
- </div>
67
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/ui-bar-title-area.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php do_action( 'fl_builder_before_ui_bar_title' ) ?>
2
+ <span class="<?php echo implode( ' ', $wrapper_classes )?>">
3
+ <?php if ( '' != $icon_url ) { ?>
4
+ <div class="fl-builder-bar-title-icon">
5
+ <img src="<?php echo $icon_url ?>" />
6
+ </div>
7
+ <?php } ?>
8
+ <div class="fl-builder-bar-title-area">
9
+ <div class="fl-builder-layout-pretitle"><?php echo $pretitle ?></div>
10
+ <div class="fl-builder-layout-title" title="<?php echo $title ?>"><?php echo $title ?></div>
11
+ </div>
12
+ <?php if ( ! $simple_ui ) { ?>
13
+ <button class="fl-builder-button fl-builder-button-silent fl-builder-bar-title-caret" title="<?php _e( 'Toggle Main Menu', 'fl-builder' ) ?>">
14
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" heigh="30px" width="30px">
15
+ <path d="M5 6l5 5 5-5 2 1-7 7-7-7z"/>
16
+ </svg>
17
+ </button>
18
+ <?php } ?>
19
+ </span>
20
+ <?php do_action( 'fl_builder_after_ui_bar_title' ) ?>
includes/ui-bar.php CHANGED
@@ -3,5 +3,31 @@
3
  <?php FLBuilder::render_ui_bar_title(); ?>
4
  <?php FLBuilder::render_ui_bar_buttons(); ?>
5
  <div class="fl-clear"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  </div>
7
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  <?php FLBuilder::render_ui_bar_title(); ?>
4
  <?php FLBuilder::render_ui_bar_buttons(); ?>
5
  <div class="fl-clear"></div>
6
+ <div class="fl-builder-publish-actions-click-away-mask"></div>
7
+ <div class="fl-builder-publish-actions is-hidden">
8
+ <span class="fl-builder-button-group">
9
+ <span class="fl-builder-button fl-builder-button-primary" data-action="discard" title="<?php _e( 'Discard changes and exit', 'fl-builder' ) ?>"><?php _e( 'Discard', 'fl-builder' ) ?></span>
10
+ <span class="fl-builder-button fl-builder-button-primary" data-action="draft" title="<?php _e( 'Keep changes drafted and exit', 'fl-builder' ) ?>"><?php _e( 'Save Draft', 'fl-builder' ) ?></span>
11
+ <# if( 'publish' !== FLBuilderConfig.postStatus && ! FLBuilderConfig.userCanPublish ) { #>
12
+ <span class="fl-builder-button fl-builder-button-primary" data-action="publish" title="<?php _e( 'Submit changes for review and exit', 'fl-builder' ) ?>"><?php _e( 'Submit for Review', 'fl-builder' ) ?></span>
13
+ <# } else { #>
14
+ <span class="fl-builder-button fl-builder-button-primary" data-action="publish" title="<?php _e( 'Publish changes and exit', 'fl-builder' ) ?>"><?php _e( 'Publish', 'fl-builder' ) ?></span>
15
+ <# } #>
16
+ </span>
17
+ <span class="fl-builder-button" data-action="dismiss"><?php _e( 'Cancel', 'fl-builder' ) ?></span>
18
+ </div>
19
  </div>
20
  </div>
21
+ <div class="fl-builder--preview-actions">
22
+ <span class="title-accessory device-icons">
23
+ <i class="dashicons dashicons-smartphone" data-mode="responsive"></i>
24
+ <i class="dashicons dashicons-tablet" data-mode="medium"></i>
25
+ <i class="dashicons dashicons-desktop" data-mode="default"></i>
26
+ </span>
27
+ <button class="fl-builder-button fl-builder-button-primary end-preview-btn"><?php _e( 'Edit', 'fl-builder' ) ?></button>
28
+ </div>
29
+ <div class="fl-builder--revision-actions">
30
+ <select></select>
31
+ <button class="fl-builder-button fl-cancel-revision-preview"><?php _e( 'Cancel', 'fl-builder' ) ?></button>
32
+ <button class="fl-builder-button fl-builder-button-primary fl-apply-revision-preview"><?php _e( 'Apply', 'fl-builder' ) ?></button>
33
+ </div>
includes/{ui-fields.php → ui-extras.php} RENAMED
@@ -1,8 +1,6 @@
1
  <div class="fl-builder-loading"></div>
2
  <div class="fl-sortable-proxy fl-row-sortable-proxy"><div class="fl-row-sortable-proxy-item"></div></div>
3
  <div class="fl-sortable-proxy fl-col-sortable-proxy"><div class="fl-col-sortable-proxy-item"></div></div>
4
- <div class="fl-builder-hidden-editor">
5
- <?php wp_editor( ' ', 'flhiddeneditor', array(
6
- 'wpautop' => true,
7
- ) ); ?>
8
  </div>
1
  <div class="fl-builder-loading"></div>
2
  <div class="fl-sortable-proxy fl-row-sortable-proxy"><div class="fl-row-sortable-proxy-item"></div></div>
3
  <div class="fl-sortable-proxy fl-col-sortable-proxy"><div class="fl-col-sortable-proxy-item"></div></div>
4
+ <div class="fl-builder-hidden-editor fl-editor-field" data-name="text" data-wpautop="1" data-buttons="1" data-rows="16">
5
+ <textarea></textarea>
 
 
6
  </div>
includes/ui-field-button.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <span
2
+ class="fl-builder-button<# if ( data.field.className ) { #> {{data.field.className}}<# } #>"
3
+ href="javascript:void(0);"
4
+ onclick="return false;"
5
+ >{{data.field.label}}</span>
includes/ui-field-code.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="fl-code-field">
2
+ <#
3
+
4
+ var editorId = 'flcode' + new Date().getTime() + '_' + data.name,
5
+ value = 'object' === typeof data.value ? JSON.stringify( data.value ) : data.value;
6
+
7
+ value.replace( '&', '&amp;' )
8
+ .replace( '"', '&quot;' )
9
+ .replace( "'", '&#039;' )
10
+ .replace( '<', '&lt;' )
11
+ .replace( '>', '&gt;' );
12
+
13
+ #>
14
+ <textarea
15
+ id="{{editorId}}"
16
+ name="{{data.name}}"
17
+ data-editor="{{data.field.editor}}"
18
+ data-wrap="<# if ( data.field.wrap ) { #>1<# } else { #>0<# } #>"
19
+ <# if ( data.field.className ) { #>class="{{data.field.className}}" <# } #>
20
+ <# if ( data.field.rows ) { #>rows="{{data.field.rows}}" <# } #>
21
+ >{{{data.value}}}</textarea>
22
+ </div>
includes/ui-field-color.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="fl-color-picker<# if ( data.field.className ) { #> {{data.field.className}}<# } if ( data.field.show_reset ) { #> fl-color-picker-has-reset<# } #>">
2
+ <button class="fl-color-picker-color<# if ( '' === data.value ) { #> fl-color-picker-empty<# } #><# if ( data.field.show_alpha ) { #> fl-color-picker-alpha-enabled<# } #>">
3
+ <svg class="fl-color-picker-icon" width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
4
+ <g fill-rule="evenodd">
5
+ <path d="M17.7037706,2.62786498 L15.3689327,0.292540631 C14.9789598,-0.0975135435 14.3440039,-0.0975135435 13.954031,0.292540631 L10.829248,3.41797472 L8.91438095,1.49770802 L7.4994792,2.91290457 L8.9193806,4.33310182 L0,13.2493402 L0,18 L4.74967016,18 L13.6690508,9.07876094 L15.0839525,10.4989582 L16.4988542,9.08376163 L14.5789876,7.16349493 L17.7037706,4.03806084 C18.0987431,3.64800667 18.0987431,3.01791916 17.7037706,2.62786498 Z M3.92288433,16 L2,14.0771157 L10.0771157,6 L12,7.92288433 L3.92288433,16 Z"></path>
6
+ </g>
7
+ </svg>
8
+ </button>
9
+ <# if ( data.field.show_reset ) { #>
10
+ <button class="fl-color-picker-clear"><div class="fl-color-picker-icon-remove"></div></button>
11
+ <# } #>
12
+ <input name="{{data.name}}" type="hidden" value="{{{data.value}}}" class="fl-color-picker-value" />
13
+ <div class="fl-clear"></div>
14
+ </div>
includes/ui-field-dimension.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <#
2
+
3
+ var placeholder = data.field.placeholder;
4
+
5
+ if ( 'object' !== typeof placeholder ) {
6
+ placeholder = {
7
+ top : placeholder,
8
+ right : placeholder,
9
+ bottom : placeholder,
10
+ left : placeholder,
11
+ };
12
+ }
13
+
14
+ /**
15
+ * We need to handle responsive dimension fields like this for backwards
16
+ * compatibility with old margin, padding and border fields. If we did not do this
17
+ * the keys would be margin_medium_top instead of the existing margin_top_medium.
18
+ */
19
+ var responsive = data.name.replace( data.rootName, '' );
20
+
21
+ #>
22
+ <div class="fl-dimension-field-units">
23
+ <div class="fl-dimension-field-unit">
24
+ <input
25
+ type="number"
26
+ name="{{data.rootName}}_top{{responsive}}"
27
+ value="{{data.settings[ data.rootName + '_top' + responsive ]}}"
28
+ placeholder="{{placeholder.top}}"
29
+ />
30
+ <label><?php _e( 'Top', 'fl-builder' ); ?></label>
31
+ </div>
32
+ <div class="fl-dimension-field-unit">
33
+ <input
34
+ type="number"
35
+ name="{{data.rootName}}_right{{responsive}}"
36
+ value="{{data.settings[ data.rootName + '_right' + responsive ]}}"
37
+ placeholder="{{placeholder.right}}"
38
+ />
39
+ <label><?php _e( 'Right', 'fl-builder' ); ?></label>
40
+ </div>
41
+ <div class="fl-dimension-field-unit">
42
+ <input
43
+ type="number"
44
+ name="{{data.rootName}}_bottom{{responsive}}"
45
+ value="{{data.settings[ data.rootName + '_bottom' + responsive ]}}"
46
+ placeholder="{{placeholder.bottom}}"
47
+ />
48
+ <label><?php _e( 'Bottom', 'fl-builder' ); ?></label>
49
+ </div>
50
+ <div class="fl-dimension-field-unit">
51
+ <input
52
+ type="number"
53
+ name="{{data.rootName}}_left{{responsive}}"
54
+ value="{{data.settings[ data.rootName + '_left' + responsive ]}}"
55
+ placeholder="{{placeholder.left}}"
56
+ />
57
+ <label><?php _e( 'Left', 'fl-builder' ); ?></label>
58
+ </div>
59
+ </div>
includes/ui-field-editor.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <#
2
+
3
+ var wpautop = 0,
4
+ buttons = 1,
5
+ rows = 16;
6
+
7
+ if ( undefined === data.field.wpautop || true === data.field.wpautop ) {
8
+ wpautop = 1;
9
+ }
10
+ if ( false === data.field.media_buttons ) {
11
+ buttons = 0;
12
+ }
13
+ if ( data.field.rows ) {
14
+ rows = data.field.rows;
15
+ }
16
+
17
+ #>
18
+ <div class="fl-editor-field" data-name="{{data.name}}" data-wpautop="{{wpautop}}" data-buttons="{{buttons}}" data-rows="{{rows}}">
19
+ <textarea>{{{data.value}}}</textarea>
20
+ </div>
includes/ui-field-font.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <# data.value = JSON.stringify( data.value ); #>
2
+ <div class="fl-font-field" data-value='{{{data.value}}}'>
3
+ <select name="{{data.name}}[][family]" class="fl-font-field-font">
4
+ <?php FLBuilderFonts::display_select_font( 'Default' ) ?>
5
+ </select>
6
+ <select name="{{data.name}}[][weight]" class="fl-font-field-weight">
7
+ <?php FLBuilderFonts::display_select_weight( 'Default', '' ) ?>
8
+ </select>
9
+ </div>
includes/ui-field-form.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="fl-form-field fl-builder-custom-field"<# if ( data.field.preview_text ) { #> data-preview-text="{{{data.field.preview_text}}}"<# } #>>
2
+ <div class="fl-form-field-preview-text">
3
+ <#
4
+
5
+ if ( 'string' === typeof data.value && '' !== data.value ) {
6
+ data.value = JSON.parse( data.value );
7
+ }
8
+
9
+ if ( data.field.preview_text && 'object' === typeof data.value ) {
10
+
11
+ var form = FLBuilderSettingsConfig.forms[ data.field.form ],
12
+ text = '';
13
+
14
+ for ( var tab in form.tabs ) {
15
+
16
+ for ( var section in form.tabs[ tab ].sections ) {
17
+
18
+ var fields = form.tabs[ tab ].sections[ section ].fields;
19
+
20
+ if ( fields[ data.field.preview_text ] ) {
21
+
22
+ var field = fields[ data.field.preview_text ];
23
+
24
+ if ( 'icon' === field.type ) {
25
+ text = '<i class="' + data.value[ data.field.preview_text ] + '"></i>';
26
+ } else if ( 'select' === field.type ) {
27
+ text = field.options[ data.value[ data.field.preview_text ] ];
28
+ } else if ( '' !== data.value[ data.field.preview_text ] ) {
29
+ var tmp = document.createElement( 'div' );
30
+ text = data.value[ data.field.preview_text ].replace( /&#39;/g, "'" );
31
+ tmp.innerHTML = text;
32
+ text = ( tmp.textContent || tmp.innerText || '' ).replace( /^(.{35}[^\s]*).*/, "$1" ) + '...';
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ #>
40
+ {{{text}}}
41
+ </div>
42
+ <#
43
+
44
+ if ( 'object' === typeof data.value ) {
45
+ data.value = FLBuilder._getSettingsJSONForHTML( data.value );
46
+ }
47
+
48
+ var label = FLBuilderStrings.editFormField.replace( '%s', data.field.label );
49
+
50
+ #>
51
+ <a class="fl-form-field-edit" href="javascript:void(0);" onclick="return false;" data-type="{{data.field.form}}">{{{label}}}</a>
52
+ <input name="{{data.name}}" type="hidden" value='{{{data.value}}}' />
53
+ </div>
includes/ui-field-icon.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="fl-icon-field fl-builder-custom-field<# if ( '' === data.value ) { #> fl-icon-empty<# } #><# if ( data.field.className ) { #> {{data.field.className}}<# } #>">
2
+ <a class="fl-icon-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Icon', 'fl-builder' ); ?></a>
3
+ <div class="fl-icon-preview">
4
+ <i class="{{{data.value}}}" data-icon="{{{data.value}}}"></i>
5
+ <a class="fl-icon-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace', 'fl-builder' ); ?></a>
6
+ <# if ( data.field.show_remove ) { #>
7
+ <a class="fl-icon-remove" href="javascript:void(0);" onclick="return false;"><?php _e( 'Remove', 'fl-builder' ); ?></a>
8
+ <# } #>
9
+ </div>
10
+ <input name="{{data.name}}" type="hidden" value="{{{data.value}}}" />
11
+ </div>
includes/ui-field-layout.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <div class="fl-layout-field">
2
+ <# for ( var key in data.field.options ) { #>
3
+ <div class="fl-layout-field-option<# if ( key == data.value ) { #> fl-layout-field-option-selected<# } #>" data-value="{{key}}">
4
+ <img src="{{{data.field.options[ key ]}}}" />
5
+ </div>
6
+ <# } #>
7
+ <div class="fl-clear"></div>
8
+ <input name="{{data.name}}" type="hidden" value='{{{data.value}}}' />
9
+ </div>
includes/ui-field-link.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="fl-link-field">
2
+ <div class="fl-link-field-input-wrap">
3
+ <input type="text" name="{{data.name}}" value="{{{data.value}}}" class="text fl-link-field-input" placeholder="<?php _ex( 'http://www.example.com', 'Link placeholder', 'fl-builder' ); ?>" />
4
+ <button class="fl-link-field-select fl-builder-button fl-builder-button-small" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select', 'fl-builder' ); ?></button>
5
+ </div>
6
+ <div class="fl-link-field-search">
7
+ <span class="fl-link-field-search-title"><?php _e( 'Enter a post title to search.', 'fl-builder' ); ?></span>
8
+ <input type="text" name="{{data.name}}-search" class="text text-full fl-link-field-search-input" placeholder="<?php esc_attr_e( 'Start typing...', 'fl-builder' ); ?>" />
9
+ <button class="fl-link-field-search-cancel fl-builder-button fl-builder-button-small" href="javascript:void(0);" onclick="return false;"><?php _e( 'Cancel', 'fl-builder' ); ?></button>
10
+ </div>
11
+ </div>
includes/ui-field-multiple-audios.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <#
2
+
3
+ // Normalize the value so we have an array.
4
+ if ( '' !== data.value && 'string' === typeof data.value ) {
5
+
6
+ data.value = JSON.parse( data.value );
7
+
8
+ // Older versions might be double encoded.
9
+ if ( 'string' === typeof data.value ) {
10
+ data.value = JSON.parse( data.value );
11
+ }
12
+ if ( 'number' === typeof data.value ) {
13
+ data.value = [ data.value ];
14
+ }
15
+
16
+ } else if ( '' === data.value ) {
17
+ data.value = [];
18
+ }
19
+
20
+ if ( 1 === data.value.length ) {
21
+ var selectedText = FLBuilderStrings.audioSelectedNum.replace( '%d', 1 );
22
+ } else {
23
+ var selectedText = FLBuilderStrings.audiosSelectedNum.replace( '%d', data.value.length );
24
+ }
25
+
26
+ var encodedValue = '' !== data.value && data.value.length ? JSON.stringify( data.value ) : '';
27
+
28
+ #>
29
+ <div class="fl-multiple-audios-field fl-builder-custom-field
30
+ <# if ( '' === data.value ) { #> fl-multiple-audios-empty<# } #>
31
+ <# if ( data.field.className ) { #> {{data.field.className}}<# } #>"
32
+ <# if ( data.field.toggle ) { data.field.toggle = JSON.stringify( data.field.toggle ); #>data-toggle='{{{data.field.toggle}}}'<# } #>>
33
+ <div class="fl-multiple-audios-count">{{selectedText}}</div>
34
+ <a class="fl-multiple-audios-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Audio', 'fl-builder' ); ?></a>
35
+ <a class="fl-multiple-audios-edit" href="javascript:void(0);" onclick="return false;"><?php _e( 'Edit Playlist', 'fl-builder' ); ?></a>
36
+ <a class="fl-multiple-audios-add" href="javascript:void(0);" onclick="return false;"><?php _e( 'Add Audio Files', 'fl-builder' ); ?></a>
37
+ <input name="{{data.name}}" type="hidden" value='{{{encodedValue}}}' />
38
+ </div>
includes/ui-field-multiple-photos.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <#
2
+
3
+ // Normalize the value so we have an array.
4
+ if ( '' !== data.value && 'string' === typeof data.value ) {
5
+
6
+ data.value = JSON.parse( data.value );
7
+
8
+ // Older versions might be double encoded.
9
+ if ( 'string' === typeof data.value ) {
10
+ data.value = JSON.parse( data.value );
11
+ }
12
+
13
+ } else if ( '' === data.value ) {
14
+ data.value = [];
15
+ }
16
+
17
+ if ( 1 === data.value.length ) {
18
+ var selectedText = FLBuilderStrings.photoSelectedNum.replace( '%d', 1 );
19
+ } else {
20
+ var selectedText = FLBuilderStrings.photoSelectedNum.replace( '%d', data.value.length );
21
+ }
22
+
23
+ var encodedValue = '' !== data.value && data.value.length ? JSON.stringify( data.value ) : '';
24
+
25
+ #>
26
+ <div class="fl-multiple-photos-field fl-builder-custom-field<# if ( '' === data.value ) { #> fl-multiple-photos-empty<# } #><# if ( data.field.className ) { #> {{data.field.className}}<# } #>">
27
+ <div class="fl-multiple-photos-count">{{selectedText}}</div>
28
+ <a class="fl-multiple-photos-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Create Gallery', 'fl-builder' ); ?></a>
29
+ <a class="fl-multiple-photos-edit" href="javascript:void(0);" onclick="return false;"><?php _e( 'Edit Gallery', 'fl-builder' ); ?></a>
30
+ <a class="fl-multiple-photos-add" href="javascript:void(0);" onclick="return false;"><?php _e( 'Add Photos', 'fl-builder' ); ?></a>
31
+ <input name="{{data.name}}" type="hidden" value='{{encodedValue}}' />
32
+ </div>
includes/ui-field-ordering.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <#
2
+
3
+ // Make sure we have an options array.
4
+ if ( '' === data.field.options ) {
5
+ data.field.options = [];
6
+ }
7
+
8
+ // JSON parse if needed.
9
+ if ( '' !== data.value && 'string' === typeof data.value ) {
10
+ data.value = JSON.parse( data.value );
11
+ }
12
+
13
+ // Set the default value if we do not have one.
14
+ if ( '' === data.value ) {
15
+ data.value = Object.keys( data.field.options )[0];
16
+ }
17
+
18
+ // Make sure any new options are added to the value.
19
+ for ( var key in data.field.options ) {
20
+ if ( jQuery.inArray( key, data.value ) === -1 ) {
21
+ data.value.push( key );
22
+ }
23
+ }
24
+
25
+ var encodedValue = JSON.stringify( data.value );
26
+
27
+ #>
28
+ <div class="fl-ordering-field-options<# if ( data.field.className ) { #> {{data.field.className}}<# } #>">
29
+ <# for ( var i in data.value ) { #>
30
+ <div class="fl-ordering-field-option" data-key="{{data.value[ i ]}}">{{data.field.options[ data.value[ i ] ]}}<i class="fa fa-arrows"></i></div>
31
+ <# } #>
32
+ </div>
33
+ <input type="hidden" name="{{data.name}}" value='{{{encodedValue}}}' />
includes/ui-field-photo-sizes.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <select name="{{data.name}}">
2
+ <?php
3
+ foreach ( FLBuilderPhoto::sizes() as $size => $atts ) :
4
+ $label = ucwords( str_replace( array( '_', '-' ), ' ', $size ) ) . ' (' . implode( 'x', $atts ) . ')';
5
+ ?>
6
+ <option value="<?php echo $size; ?>"<# if ( data.value === '<?php echo $size; ?>' ) { #> selected="selected"<# } #>><?php echo $label; ?></option>
7
+ <?php endforeach; ?>
8
+ <option value="full"<# if ( data.value === 'full' ) { #> selected="selected"<# } #>><?php _e( 'Full Size', 'fl-builder' ); ?></option>
9
+ </select>
includes/ui-field-photo.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <#
2
+
3
+ var photo = null;
4
+
5
+ if ( FLBuilderSettingsConfig.attachments[ data.value ] ) {
6
+ photo = FLBuilderSettingsConfig.attachments[ data.value ];
7
+ photo.isAttachment = true;
8
+ } else if ( ! _.isEmpty( data.value ) ) {
9
+ photo = {
10
+ id: data.value,
11
+ url: data.settings[ data.name + '_src' ],
12
+ filename: data.settings[ data.name + '_src' ].split( '/' ).pop(),
13
+ isAttachment: false
14
+ };
15
+ }
16
+
17
+ var className = data.field.className ? ' ' + data.field.className : '';
18
+
19
+ if ( ! data.value || ! photo ) {
20
+ className += ' fl-photo-empty';
21
+ } else if ( photo ) {
22
+ className += photo.isAttachment ? ' fl-photo-has-attachment' : ' fl-photo-no-attachment';
23
+ }
24
+
25
+ #>
26
+ <div class="fl-photo-field fl-builder-custom-field{{className}}">
27
+ <a class="fl-photo-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Photo', 'fl-builder' ); ?></a>
28
+ <div class="fl-photo-preview">
29
+ <div class="fl-photo-preview-img">
30
+ <img src="<# if ( photo ) { var src = FLBuilder._getPhotoSrc( photo ); #>{{{src}}}<# } #>" />
31
+ </div>
32
+ <div class="fl-photo-preview-controls">
33
+ <select name="{{data.name}}_src">
34
+ <# if ( photo && data.settings[ data.name + '_src' ] ) {
35
+ var sizes = FLBuilder._getPhotoSizeOptions( photo, data.settings[ data.name + '_src' ] );
36
+ #>
37
+ {{{sizes}}}
38
+ <# } #>
39
+ </select>
40
+ <div class="fl-photo-preview-filename">
41
+ <# if ( photo ) { #>{{{photo.filename}}}<# } #>
42
+ </div>
43
+ <br />
44
+ <a class="fl-photo-edit" href="javascript:void(0);" onclick="return false;"><?php _e( 'Edit', 'fl-builder' ); ?></a>
45
+ <# if ( data.show_remove ) { #>
46
+ <a class="fl-photo-remove" href="javascript:void(0);" onclick="return false;"><?php _e( 'Remove', 'fl-builder' ); ?></a>
47
+ <# } else { #>
48
+ <a class="fl-photo-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace', 'fl-builder' ); ?></a>
49
+ <# } #>
50
+ </div>
51
+ </div>
52
+ <input name="{{data.name}}" type="hidden" value='{{data.value}}' />
53
+ </div>
includes/ui-field-post-type.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <select name="{{data.name}}"<# if ( data.field.className ) { #> {{data.field.className}}<# } #>>
2
+ <?php foreach ( FLBuilderLoop::post_types() as $slug => $type ) : ?>
3
+ <option value="<?php echo $slug; ?>"<# if ( data.value === '<?php echo $slug; ?>' ) { #> selected="selected"<# } #>><?php echo $type->labels->name; ?></option>
4
+ <?php endforeach; ?>
5
+ </select>
includes/ui-field-select.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Select field
4
+ *
5
+ * Setup attributes example:
6
+ *
7
+ * 'select_field_name' => array(
8
+ * 'type' => 'select',
9
+ * 'label' => esc_html__( 'Select Field', 'fl-builder' ),
10
+ * 'default' => 'option-1',
11
+ * 'className' => '',
12
+ * 'multi-select' => false,
13
+ * 'options' => array(
14
+ * 'option-1' => esc_html__( 'Option 1', 'fl-builder' ),
15
+ * 'option-2' => array(
16
+ * 'label' => esc_html__( 'Premium Option 2', 'fl-builder' ),
17
+ * 'premium' => true,
18
+ * ),
19
+ * 'optgroup-1' => array(
20
+ * 'label' => esc_html__( 'Optgroup 1', 'fl-builder' ),
21
+ * 'options' => array( *
22
+ * 'option-3' => esc_html__( 'Option 3', 'fl-builder' ),
23
+ * 'option-4' => array(
24
+ * 'label' => esc_html__( 'Premium Option 4', 'fl-builder' ),
25
+ * 'premium' => true,
26
+ * ),
27
+ * ),
28
+ * 'premium' => false,
29
+ * ),
30
+ * ),
31
+ * 'toggle' => array(
32
+ * 'option-1' => array(
33
+ * 'fields' => array( 'my_field_1', 'my_field_2' ),
34
+ * 'sections' => array( 'my_section' ),
35
+ * 'tabs' => array( 'my_tab' ),
36
+ * ),
37
+ * 'option-2' => array(),
38
+ * ),
39
+ * 'hide' => '', @todo Write example setup attribute value
40
+ * 'trigger' => '', @todo Write example setup attribute value
41
+ * );
42
+ *
43
+ */
44
+ ?>
45
+ <#
46
+
47
+ var atts = '',
48
+ field = data.field,
49
+ name = data.name,
50
+ value = data.value;
51
+
52
+ // Multiselect?
53
+ if ( field['multi-select'] ) {
54
+ atts += ' multiple';
55
+ name += '[]';
56
+ }
57
+
58
+ // Class
59
+ if ( field.className ) {
60
+ atts += ' class="' + field.className + '"';
61
+ }
62
+
63
+ // Toggle data
64
+ if ( field.toggle ) {
65
+ atts += " data-toggle='" + JSON.stringify( field.toggle ) + "'";
66
+ }
67
+
68
+ // Hide data
69
+ if ( field.hide ) {
70
+ atts += " data-hide='" + JSON.stringify( field.hide ) + "'";
71
+ }
72
+
73
+ // Trigger data
74
+ if ( field.trigger ) {
75
+ atts += " data-trigger='" + JSON.stringify( field.trigger ) + "'";
76
+ }
77
+
78
+ #>
79
+ <select name="{{name}}"{{{atts}}}>
80
+ <#
81
+
82
+ // Loop through the options
83
+ for ( var optionKey in field.options ) {
84
+
85
+ var optionVal = field.options[ optionKey ];
86
+
87
+ // Do not display premium options if using lite plugin version
88
+ if ( 'object' === typeof optionVal && optionVal.premium && true === FLBuilderConfig.lite ) {
89
+ continue;
90
+ }
91
+
92
+ if ( 'object' === typeof optionVal && optionVal.label && optionVal.options ) {
93
+
94
+ #>
95
+ <optgroup label="{{optionVal.label}}">
96
+ <#
97
+
98
+ for ( var groupKey in optionVal.options ) {
99
+
100
+ var groupVal = optionVal.options[ groupKey ],
101
+ selected = '';
102
+
103
+ // Do not display premium optgroup options if using lite plugin version
104
+ if ( 'object' === typeof groupVal && groupVal.premium && true === FLBuilderConfig.lite ) {
105
+ continue;
106
+ }
107
+
108
+ // Is selected?
109
+ if ( 'object' === typeof value && jQuery.inArray( groupKey, value ) != -1 ) {
110
+ // Multi select
111
+ selected = ' selected="selected"';
112
+ } else if ( 'string' === typeof value && groupKey == value ) {
113
+ // Single select
114
+ selected = ' selected="selected"';
115
+ }
116
+
117
+ // Option label
118
+ var label = 'object' === typeof groupVal ? groupVal.label : groupVal;
119
+
120
+ // Output option
121
+ #>
122
+ <option value="{{groupKey}}"{{{selected}}}>{{{label}}}</option>
123
+ <#
124
+ }
125
+ #>
126
+ </optgroup>
127
+ <#
128
+
129
+ } else {
130
+
131
+ // Is selected?
132
+ var selected = '';
133
+
134
+ if ( 'object' === typeof value && jQuery.inArray( optionKey, value ) != -1 ) {
135
+ // Multi select
136
+ selected = ' selected="selected"';
137
+ } else if ( 'string' === typeof value && optionKey == value ) {
138
+ // Single select
139
+ selected = ' selected="selected"';
140
+ }
141
+
142
+ // Option label
143
+ var label = 'object' === typeof optionVal ? optionVal.label : optionVal;
144
+
145
+ // Output option
146
+ #>
147
+ <option value="{{optionKey}}"{{{selected}}}>{{{label}}}</option>
148
+ <#
149
+ }
150
+ }
151
+
152
+ #>
153
+ </select>
includes/ui-field-suggest.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <input
2
+ type="text"
3
+ class="text text-full fl-suggest-field<# if ( data.field.className ) { #> {{data.field.className}}<# } #>"
4
+ name="{{data.name}}"
5
+ data-value='{{data.value}}'
6
+ data-action="<# if ( data.field.action ) { #>{{data.field.action}}<# } #>"
7
+ data-action-data="<# if ( data.field.data ) { #>{{data.field.data}}<# } #>"
8
+ data-limit="<# if ( data.field.limit ) { #>{{data.field.limit}}<# } else { #>false<# } #>"
9
+ data-args='<# if ( data.field.args ) { args = JSON.stringify( args ); #>{{{args}}}<# } #>'
10
+ placeholder="<# if ( data.field.placeholder ) { #>{{data.field.placeholder}}<# } else { #><?php esc_attr__( 'Start typing...', 'fl-builder' ) ?><# } #>"
11
+ />
includes/ui-field-text.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <input
2
+ type="text"
3
+ name="{{data.name}}"
4
+ value="{{data.value}}"
5
+ class="text <# if ( data.field.className ) { #> {{data.field.className}}<# } #><# if ( ! data.field.size ) { #> text-full<# } #>"
6
+ <# if ( data.field.placeholder ) { #>placeholder="{{data.field.placeholder}}" <# } #>
7
+ <# if ( data.field.maxlength ) { #>maxlength="{{data.field.maxlength}}" <# } #>
8
+ <# if ( data.field.size ) { #>size="{{data.field.size}}" <# } #>
9
+ />
includes/ui-field-textarea.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <textarea
2
+ name="{{data.name}}"
3
+ <# if ( data.field.className ) { #>class="{{data.field.className}}" <# } #>
4
+ <# if ( data.field.placeholder ) { #>placeholder="{{data.field.placeholder}}" <# } #>
5
+ <# if ( data.field.rows ) { #>rows="{{data.field.rows}}" <# } #>
6
+ >{{{data.value}}}</textarea>
includes/ui-field-time.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <#
2
+
3
+ var getOptions = function( start, end, saved ) {
4
+ var i, value, selected, options = '';
5
+
6
+ for ( i = start; i < end; i++ ) {
7
+ value = String( i );
8
+ value = 1 === value.length ? '0' + value : value;
9
+ selected = value == saved ? ' selected="selected"' : '';
10
+ options += '<option value="' + value + '"' + selected + '>' + value + '</option>';
11
+ }
12
+
13
+ return options;
14
+ }
15
+
16
+ #>
17
+ <select name="{{data.name}}[][hours]" class="fl-time-field-hours">
18
+ <# var hours = getOptions( 1, 13, data.value.hours ); #>
19
+ {{{hours}}}
20
+ </select>
21
+ <select name="{{data.name}}[][minutes]" class="fl-time-field-minutes">
22
+ <# var minutes = getOptions( 0, 60, data.value.minutes ); #>
23
+ {{{minutes}}}
24
+ </select>
25
+ <select name="{{data.name}}[][day_period]" class="fl-time-field-day_period">
26
+ <option value="am"<# if ( 'am' == data.value.day_period ) { #> selected="selected"<# } #>>am</option>
27
+ <option value="pm"<# if ( 'pm' == data.value.day_period ) { #> selected="selected"<# } #>>pm</option>
28
+ </select>
includes/ui-field-timezone.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <select
2
+ name="{{data.name}}"
3
+ data-value="{{{data.value}}}"
4
+ <# if ( data.field.className ) { #>class="{{data.field.className}}" <# } #>
5
+ <# if ( data.field.toggle ) { data.field.toggle = JSON.stringify( data.field.toggle ); #>data-toggle="{{{data.field.toggle}}}" <# } #>
6
+ <# if ( data.field.hide ) { data.field.hide = JSON.stringify( data.field.hide ); #>data-hide="{{{data.field.hide}}}" <# } #>
7
+ <# if ( data.field.trigger ) { data.field.trigger = JSON.stringify( data.field.trigger ); #>data-trigger="{{{data.field.trigger}}}" <# } #>>
8
+ <?php echo FLBuilderTimezones::build_timezones( '' ); ?>
9
+ </select>
includes/ui-field-unit.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <input
2
+ type="number"
3
+ name="{{data.name}}"
4
+ value="{{{data.value}}}"
5
+ placeholder="<# if ( data.field.placeholder ) { #>{{data.field.placeholder}}<# } #>"
6
+ />
includes/ui-field-video.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <#
2
+
3
+ var video = null;
4
+
5
+ if ( FLBuilderSettingsConfig.attachments[ data.value ] ) {
6
+ video = FLBuilderSettingsConfig.attachments[ data.value ];
7
+ } else if ( ! _.isEmpty( data.value ) ) {
8
+ video = {
9
+ id: data.value,
10
+ url: data.value,
11
+ filename: data.value
12
+ };
13
+ }
14
+
15
+ var className = data.field.className ? ' ' + data.field.className : '';
16
+
17
+ if ( ! data.value || ! video ) {
18
+ className += ' fl-video-empty';
19
+ }
20
+
21
+ #>
22
+ <div class="fl-video-field fl-builder-custom-field{{className}}">
23
+ <a class="fl-video-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Video', 'fl-builder' ); ?></a>
24
+ <div class="fl-video-preview">
25
+ <# if ( data.value && video ) { #>
26
+ <div class="fl-video-preview-img">
27
+ <span class="dashicons dashicons-media-video"></span>
28
+ </div>
29
+ <span class="fl-video-preview-filename">{{{video.filename}}}</span>
30
+ <# } else { #>
31
+ <div class="fl-video-preview-img">
32
+ <img src="<?php echo FL_BUILDER_URL; ?>img/spacer.png" />
33
+ </div>
34
+ <span class="fl-video-preview-filename"></span>
35
+ <# } #>
36
+ <br />
37
+ <a class="fl-video-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace Video', 'fl-builder' ); ?></a>
38
+ <div class="fl-clear"></div>
39
+ </div>
40
+ <input name="{{data.name}}" type="hidden" value='{{{data.value}}}' />
41
+ </div>
includes/ui-field.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/html" id="tmpl-fl-builder-field">
2
+ <# if ( ! data.field.label ) { #>
3
+ <td class="fl-field-control" colspan="2">
4
+ <# } else { #>
5
+ <th class="fl-field-label">
6
+ <label for="{{data.name}}">
7
+
8
+ <# if ( 'button' === data.field.type ) { #>
9
+ &nbsp;
10
+ <# } else { #>
11
+ {{{data.field.label}}}
12
+ <# if ( undefined !== data.index ) { #>
13
+ <# var index = data.index + 1; #>
14
+ <span class="fl-builder-field-index">{{index}}</span>
15
+ <# } #>
16
+ <# } #>
17
+
18
+ <# if ( data.responsive ) { #>
19
+ <i class="fl-field-responsive-toggle dashicons dashicons-desktop" data-mode="default"></i>
20
+ <# } #>
21
+
22
+ <# if ( data.field.help ) { #>
23
+ <span class="fl-help-tooltip">
24
+ <i class="fl-help-tooltip-icon fa fa-question-circle"></i>
25
+ <span class="fl-help-tooltip-text">{{{data.field.help}}}</span>
26
+ </span>
27
+ <# } #>
28
+
29
+ </label>
30
+ </th>
31
+ <td class="fl-field-control">
32
+ <# } #>
33
+ <div class="fl-field-control-wrapper">
34
+
35
+ <# if ( data.responsive ) { #>
36
+ <i class="fl-field-responsive-toggle dashicons dashicons-desktop" data-mode="default"></i>
37
+ <# } #>
38
+
39
+ <# var devices = [ 'default', 'medium', 'responsive' ]; #>
40
+ <# for ( var i = 0; i < devices.length; i++ ) { #>
41
+
42
+ <# if ( 'default' !== devices[ i ] && ! data.responsive ) {
43
+ continue;
44
+ } #>
45
+
46
+ <# if ( data.responsive ) {
47
+ data.name = 'default' === devices[ i ] ? data.rootName : data.rootName + '_' + devices[ i ];
48
+ data.value = data.settings[ data.name ] ? data.settings[ data.name ] : '';
49
+
50
+ if ( 'object' === typeof data.responsive ) {
51
+ for ( var key in data.responsive ) {
52
+ if ( 'object' === typeof data.responsive[ key ] && data.responsive[ key ][ devices[ i ] ] ) {
53
+ data.field[ key ] = data.responsive[ key ][ devices[ i ] ];
54
+ }
55
+ }
56
+ }
57
+ #>
58
+ <div class="fl-field-responsive-setting fl-field-responsive-setting-{{devices[ i ]}}" data-device="{{devices[ i ]}}">
59
+ <# } #>
60
+ <# if ( data.template.length ) {
61
+ var template = wp.template( 'fl-builder-field-' + data.field.type ),
62
+ field = template( data ),
63
+ before = data.field.html_before ? data.field.html_before : '',
64
+ after = data.field.html_after ? data.field.html_after : '';
65
+ #>
66
+ {{{before}}}{{{field}}}{{{after}}}
67
+ <# } else {
68
+ var name = data.name.replace( '[]', '' );
69
+ #>
70
+ <div class="fl-legacy-field" data-field="{{name}}" />
71
+ <# } #>
72
+
73
+ <# if ( data.responsive ) { #>
74
+ </div>
75
+ <# } #>
76
+
77
+ <# } #>
78
+ <# if ( data.field.description ) { #>
79
+ <span class="fl-field-description">{{{data.field.description}}}</span>
80
+ <# } #>
81
+ </div>
82
+ </td>
83
+ </script>
includes/ui-js-config.php CHANGED
@@ -16,12 +16,14 @@ echo 'FLBuilderConfig = ' . json_encode( apply_filters('fl_builder_ui_js_config'
16
  'isUserTemplate' => false,
17
  'lite' => true === FL_BUILDER_LITE,
18
  'modSecFix' => ( defined( 'FL_BUILDER_MODSEC_FIX' ) && FL_BUILDER_MODSEC_FIX ),
 
19
  'nestedColumns' => ( ! defined( 'FL_BUILDER_NESTED_COLUMNS' ) || FL_BUILDER_NESTED_COLUMNS ),
20
  'newUser' => FLBuilderModel::is_new_user(),
21
  'pluginUrl' => FL_BUILDER_URL,
22
  'postId' => $post_id,
23
  'postStatus' => get_post_status(),
24
  'postType' => get_post_type(),
 
25
  'simpleUi' => $simple_ui ? true : false,
26
  'upgradeUrl' => FLBuilderModel::get_upgrade_url( array(
27
  'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-demo' ),
@@ -30,15 +32,33 @@ echo 'FLBuilderConfig = ' . json_encode( apply_filters('fl_builder_ui_js_config'
30
  ) ),
31
  'userCanEditGlobalTemplates' => FLBuilderUserAccess::current_user_can( 'global_node_editing' ),
32
  'userCanPublish' => current_user_can( 'publish_posts' ),
 
33
  'userTemplateType' => FLBuilderModel::get_user_template_type(),
 
 
 
 
 
 
 
 
 
 
 
34
  'googleFontsUrl' => apply_filters( 'fl_builder_google_fonts_domain', '//fonts.googleapis.com/' ) . 'css?family=',
 
 
35
  ) ) ) . ';';
36
 
37
  echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_strings', array(
38
  'actionsLightboxTitle' => esc_attr__( 'What would you like to do?', 'fl-builder' ),
 
39
  'alreadySaved' => esc_attr_x( '%s is already a saved preset.', '%s is the preset hex color code.', 'fl-builder' ),
40
  'audioSelected' => esc_attr__( 'Audio File Selected', 'fl-builder' ),
 
41
  'audiosSelected' => esc_attr__( 'Audio Files Selected', 'fl-builder' ),
 
 
42
  'cancel' => esc_attr__( 'Cancel', 'fl-builder' ),
43
  'changeTemplate' => esc_attr__( 'Change Template', 'fl-builder' ),
44
  'changeTemplateMessage' => esc_attr__( 'Warning! Changing the template will replace your existing layout. Do you really want to do this?', 'fl-builder' ),
@@ -61,6 +81,7 @@ echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_string
61
  'draft' => esc_attr__( 'Save Changes and Exit', 'fl-builder' ),
62
  'duplicate' => esc_attr__( 'Duplicate', 'fl-builder' ),
63
  'duplicateLayout' => esc_attr_x( 'Duplicate Layout', 'Duplicate page/post action label.', 'fl-builder' ),
 
64
  'editGlobalSettings' => esc_attr__( 'Global Settings', 'fl-builder' ),
65
  'editLayoutSettings' => esc_attr__( 'Layout CSS / Javascript', 'fl-builder' ),
66
  'emptyMessage' => esc_attr__( 'Drop a row layout or module to get started!', 'fl-builder' ),
@@ -68,8 +89,10 @@ echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_string
68
  'enterValidMonth' => esc_attr__( 'Error! Please enter a valid month.', 'fl-builder' ),
69
  'enterValidYear' => esc_attr__( 'Error! Please enter a valid year.', 'fl-builder' ),
70
  'errorMessage' => esc_attr__( 'Beaver Builder caught the following JavaScript error. If Beaver Builder is not functioning as expected the cause is most likely this error. Please help us by disabling all plugins and testing Beaver Builder while reactivating each to determine if the issue is related to a third party plugin.', 'fl-builder' ),
 
71
  'fullSize' => esc_attr__( 'Full Size', 'fl-builder' ),
72
  'getHelp' => esc_attr__( 'Get Help', 'fl-builder' ),
 
73
  'globalErrorMessage' => __( '"{message}" on line {line} of {file}.', 'fl-builder' ),
74
  'insert' => esc_attr__( 'Insert', 'fl-builder' ),
75
  'large' => esc_attr__( 'Large', 'fl-builder' ),
@@ -88,22 +111,31 @@ echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_string
88
  'ok' => esc_attr__( 'OK', 'fl-builder' ),
89
  'photoPage' => esc_attr__( 'Photo Page', 'fl-builder' ),
90
  'photoSelected' => esc_attr__( 'Photo Selected', 'fl-builder' ),
 
91
  'photosSelected' => esc_attr__( 'Photos Selected', 'fl-builder' ),
 
92
  'placeholder' => esc_attr__( 'Paste color here...', 'fl-builder' ),
93
  'pleaseWait' => esc_attr__( 'Please Wait...', 'fl-builder' ),
94
  'presetAdded' => esc_attr_x( '%s added to presets!', '%s is the preset hex color code.', 'fl-builder' ),
95
  'publish' => esc_attr__( 'Publish Changes', 'fl-builder' ),
96
  'remove' => esc_attr__( 'Remove', 'fl-builder' ),
97
  'removePresetConfirm' => esc_attr__( 'Are you sure?', 'fl-builder' ),
 
 
98
  'row' => esc_attr__( 'Row', 'fl-builder' ),
99
  'rowSettings' => esc_attr__( 'Row Settings', 'fl-builder' ),
100
  'rowTemplateSaved' => esc_attr__( 'Row Saved!', 'fl-builder' ),
101
  'saveCoreTemplate' => esc_attr__( 'Save Core Template', 'fl-builder' ),
 
 
 
 
102
  'saveTemplate' => esc_attr__( 'Save Template', 'fl-builder' ),
103
  'selectAudio' => esc_attr__( 'Select Audio', 'fl-builder' ),
104
  'selectPhoto' => esc_attr__( 'Select Photo', 'fl-builder' ),
105
  'selectPhotos' => esc_attr__( 'Select Photos', 'fl-builder' ),
106
  'selectVideo' => esc_attr__( 'Select Video', 'fl-builder' ),
 
107
  'submitForReview' => esc_attr__( 'Submit for Review', 'fl-builder' ),
108
  'subscriptionModuleAccountError' => esc_attr__( 'Please select an account before saving.', 'fl-builder' ),
109
  'subscriptionModuleConnectError' => esc_attr__( 'Please connect an account before saving.', 'fl-builder' ),
@@ -141,7 +173,40 @@ echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_string
141
  'visitForums' => esc_attr__( 'Contact Support', 'fl-builder' ),
142
  'watchHelpVideo' => esc_attr__( 'Watch the Video', 'fl-builder' ),
143
  'welcomeMessage' => esc_attr__( 'Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder' ),
 
144
  'yesPlease' => esc_attr__( 'Yes Please!', 'fl-builder' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  ) ) ) . ';';
146
 
147
  FLBuilderFonts::js();
16
  'isUserTemplate' => false,
17
  'lite' => true === FL_BUILDER_LITE,
18
  'modSecFix' => ( defined( 'FL_BUILDER_MODSEC_FIX' ) && FL_BUILDER_MODSEC_FIX ),
19
+ 'moduleGroups' => FLBuilderModel::get_module_groups(),
20
  'nestedColumns' => ( ! defined( 'FL_BUILDER_NESTED_COLUMNS' ) || FL_BUILDER_NESTED_COLUMNS ),
21
  'newUser' => FLBuilderModel::is_new_user(),
22
  'pluginUrl' => FL_BUILDER_URL,
23
  'postId' => $post_id,
24
  'postStatus' => get_post_status(),
25
  'postType' => get_post_type(),
26
+ 'services' => FLBuilderServices::get_services_data(),
27
  'simpleUi' => $simple_ui ? true : false,
28
  'upgradeUrl' => FLBuilderModel::get_upgrade_url( array(
29
  'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-demo' ),
32
  ) ),
33
  'userCanEditGlobalTemplates' => FLBuilderUserAccess::current_user_can( 'global_node_editing' ),
34
  'userCanPublish' => current_user_can( 'publish_posts' ),
35
+ 'userSettings' => FLBuilderUserSettings::get(),
36
  'userTemplateType' => FLBuilderModel::get_user_template_type(),
37
+ 'brandingIcon' => FLBuilderModel::get_branding_icon(),
38
+ 'url' => get_permalink(),
39
+ 'editUrl' => add_query_arg( 'fl_builder', '', get_permalink() ),
40
+ 'layoutHasDraftedChanges' => FLBuilderModel::layout_has_drafted_changes(),
41
+ 'panelData' => FLBuilderUIContentPanel::get_panel_data(),
42
+ 'contentItems' => FLBuilderUIContentPanel::get_content_elements(),
43
+ 'mainMenu' => FLBuilder::get_main_menu_data(),
44
+ 'keyboardShortcuts' => FLBuilder::get_keyboard_shortcuts(),
45
+ 'isCustomizer' => is_customize_preview(),
46
+ 'showToolbar' => is_customize_preview() ? false : true,
47
+ 'shouldRefreshOnPublish' => FLBuilder::should_refresh_on_publish(),
48
  'googleFontsUrl' => apply_filters( 'fl_builder_google_fonts_domain', '//fonts.googleapis.com/' ) . 'css?family=',
49
+ 'wp_editor' => FLBuilder::get_wp_editor(),
50
+ 'rowResize' => FLBuilderModel::get_row_resize_settings(),
51
  ) ) ) . ';';
52
 
53
  echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_strings', array(
54
  'actionsLightboxTitle' => esc_attr__( 'What would you like to do?', 'fl-builder' ),
55
+ 'addField' => esc_attr_x( 'Add %s', 'Field name to add.', 'fl-builder' ),
56
  'alreadySaved' => esc_attr_x( '%s is already a saved preset.', '%s is the preset hex color code.', 'fl-builder' ),
57
  'audioSelected' => esc_attr__( 'Audio File Selected', 'fl-builder' ),
58
+ 'audioSelectedNum' => esc_attr__( '%d Audio File Selected', 'fl-builder' ),
59
  'audiosSelected' => esc_attr__( 'Audio Files Selected', 'fl-builder' ),
60
+ 'audiosSelectedNum' => esc_attr__( '%d Audio Files Selected', 'fl-builder' ),
61
+ 'blank' => esc_attr__( 'Blank', 'fl-builder' ),
62
  'cancel' => esc_attr__( 'Cancel', 'fl-builder' ),
63
  'changeTemplate' => esc_attr__( 'Change Template', 'fl-builder' ),
64
  'changeTemplateMessage' => esc_attr__( 'Warning! Changing the template will replace your existing layout. Do you really want to do this?', 'fl-builder' ),
81
  'draft' => esc_attr__( 'Save Changes and Exit', 'fl-builder' ),
82
  'duplicate' => esc_attr__( 'Duplicate', 'fl-builder' ),
83
  'duplicateLayout' => esc_attr_x( 'Duplicate Layout', 'Duplicate page/post action label.', 'fl-builder' ),
84
+ 'editFormField' => esc_attr_x( 'Edit %s', '%s stands for form field label.', 'fl-builder' ),
85
  'editGlobalSettings' => esc_attr__( 'Global Settings', 'fl-builder' ),
86
  'editLayoutSettings' => esc_attr__( 'Layout CSS / Javascript', 'fl-builder' ),
87
  'emptyMessage' => esc_attr__( 'Drop a row layout or module to get started!', 'fl-builder' ),
89
  'enterValidMonth' => esc_attr__( 'Error! Please enter a valid month.', 'fl-builder' ),
90
  'enterValidYear' => esc_attr__( 'Error! Please enter a valid year.', 'fl-builder' ),
91
  'errorMessage' => esc_attr__( 'Beaver Builder caught the following JavaScript error. If Beaver Builder is not functioning as expected the cause is most likely this error. Please help us by disabling all plugins and testing Beaver Builder while reactivating each to determine if the issue is related to a third party plugin.', 'fl-builder' ),
92
+ 'fieldLoading' => esc_attr__( 'Field Loading...', 'fl-builder' ),
93
  'fullSize' => esc_attr__( 'Full Size', 'fl-builder' ),
94
  'getHelp' => esc_attr__( 'Get Help', 'fl-builder' ),
95
+ 'global' => esc_attr_x( 'Global', 'Indicator for global node templates.', 'fl-builder' ),
96
  'globalErrorMessage' => __( '"{message}" on line {line} of {file}.', 'fl-builder' ),
97
  'insert' => esc_attr__( 'Insert', 'fl-builder' ),
98
  'large' => esc_attr__( 'Large', 'fl-builder' ),
111
  'ok' => esc_attr__( 'OK', 'fl-builder' ),
112
  'photoPage' => esc_attr__( 'Photo Page', 'fl-builder' ),
113
  'photoSelected' => esc_attr__( 'Photo Selected', 'fl-builder' ),
114
+ 'photoSelectedNum' => esc_attr__( '%d Photo Selected', 'fl-builder' ),
115
  'photosSelected' => esc_attr__( 'Photos Selected', 'fl-builder' ),
116
+ 'photosSelectedNum' => esc_attr__( '%d Photos Selected', 'fl-builder' ),
117
  'placeholder' => esc_attr__( 'Paste color here...', 'fl-builder' ),
118
  'pleaseWait' => esc_attr__( 'Please Wait...', 'fl-builder' ),
119
  'presetAdded' => esc_attr_x( '%s added to presets!', '%s is the preset hex color code.', 'fl-builder' ),
120
  'publish' => esc_attr__( 'Publish Changes', 'fl-builder' ),
121
  'remove' => esc_attr__( 'Remove', 'fl-builder' ),
122
  'removePresetConfirm' => esc_attr__( 'Are you sure?', 'fl-builder' ),
123
+ 'revisionDate' => esc_attr_x( '%s ago', '%s is a time diff such as 1 day or 2 weeks.', 'fl-builder' ),
124
+ 'revisionAuthor' => esc_attr_x( 'By %s', '%s is the author name.', 'fl-builder' ),
125
  'row' => esc_attr__( 'Row', 'fl-builder' ),
126
  'rowSettings' => esc_attr__( 'Row Settings', 'fl-builder' ),
127
  'rowTemplateSaved' => esc_attr__( 'Row Saved!', 'fl-builder' ),
128
  'saveCoreTemplate' => esc_attr__( 'Save Core Template', 'fl-builder' ),
129
+ 'save' => esc_attr__( 'Save', 'fl-builder' ),
130
+ 'saveAs' => esc_attr__( 'Save As...', 'fl-builder' ),
131
+ 'saveModule' => esc_attr__( 'Save Module', 'fl-builder' ),
132
+ 'saveRow' => esc_attr__( 'Save Row', 'fl-builder' ),
133
  'saveTemplate' => esc_attr__( 'Save Template', 'fl-builder' ),
134
  'selectAudio' => esc_attr__( 'Select Audio', 'fl-builder' ),
135
  'selectPhoto' => esc_attr__( 'Select Photo', 'fl-builder' ),
136
  'selectPhotos' => esc_attr__( 'Select Photos', 'fl-builder' ),
137
  'selectVideo' => esc_attr__( 'Select Video', 'fl-builder' ),
138
+ 'settingsHaveErrors' => esc_attr__( 'These settings have errors. Please correct them before continuing.', 'fl-builder' ),
139
  'submitForReview' => esc_attr__( 'Submit for Review', 'fl-builder' ),
140
  'subscriptionModuleAccountError' => esc_attr__( 'Please select an account before saving.', 'fl-builder' ),
141
  'subscriptionModuleConnectError' => esc_attr__( 'Please connect an account before saving.', 'fl-builder' ),
173
  'visitForums' => esc_attr__( 'Contact Support', 'fl-builder' ),
174
  'watchHelpVideo' => esc_attr__( 'Watch the Video', 'fl-builder' ),
175
  'welcomeMessage' => esc_attr__( 'Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder' ),
176
+ 'uncategorized' => esc_attr__( 'Uncategorized', 'fl-builder' ),
177
  'yesPlease' => esc_attr__( 'Yes Please!', 'fl-builder' ),
178
+ 'savedStatus' => array(
179
+ 'saving' => esc_attr__( 'Saving...', 'fl-builder' ),
180
+ 'savingTooltip' => esc_attr__( 'The layout is currently being saved', 'fl-builder' ),
181
+ 'saved' => esc_attr__( 'Saved', 'fl-builder' ),
182
+ 'savedTooltip' => esc_attr__( 'The layout is saved', 'fl-builder' ),
183
+ 'edited' => esc_attr__( 'Edited', 'fl-builder' ),
184
+ 'editedTooltip' => esc_attr__( 'This layout has unpublished changes', 'fl-builder' ),
185
+ 'editedWarning' => esc_attr__( 'This layout has unpublished changes. If you discard this draft all of your previously unpublished changes will be lost.', 'fl-builder' ),
186
+ 'editedWarningDismiss' => esc_attr__( 'Ok, got it!', 'fl-builder' ),
187
+ 'noChanges' => esc_attr__( 'Nothing new to publish', 'fl-builder' ),
188
+ 'publishing' => esc_attr__( 'Publishing Changes', 'fl-builder' ),
189
+ 'publishingTooltip' => esc_attr__( 'Changes being published', 'fl-builder' ),
190
+ 'nothingToSave' => esc_attr__( 'No new changes to save', 'fl-builder' ),
191
+ 'hasAlreadySaved' => esc_attr__( 'Your changes are saved', 'fl-builder' ),
192
+
193
+ ),
194
+ 'widgetsCategoryTitle' => esc_attr__( 'WordPress Widgets', 'fl-builder' ),
195
+ 'typeLabels' => array(
196
+ 'template' => esc_attr__( 'Template', 'fl-builder' ),
197
+ 'module' => esc_attr__( 'Module', 'fl-builder' ),
198
+ 'row' => esc_attr__( 'Row', 'fl-builder' ),
199
+ 'colGroup' => esc_attr__( 'Column Group', 'fl-builder' ),
200
+ 'widget' => esc_attr__( 'Widget', 'fl-builder' ),
201
+ ),
202
+ 'categoryMeta' => array(
203
+ 'landing' => array(
204
+ 'name' => esc_attr__( 'Landing Pages', 'fl-builder' ),
205
+ ),
206
+ 'company' => array(
207
+ 'name' => esc_attr__( 'Content Pages', 'fl-builder' ),
208
+ ),
209
+ ),
210
  ) ) ) . ';';
211
 
212
  FLBuilderFonts::js();
includes/ui-js-templates.php CHANGED
@@ -2,7 +2,6 @@
2
  <div class="fl-row-overlay fl-block-overlay<# if ( data.global ) { #> fl-block-overlay-global<# } #>">
3
  <div class="fl-block-overlay-header">
4
  <div class="fl-block-overlay-actions">
5
- <div class="fl-block-overlay-title"><?php _e( 'Row', 'fl-builder' ); ?></div>
6
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
7
  <i class="fa fa-lock fl-tip" title="<?php _e( 'Locked', 'fl-builder' ); ?>"></i>
8
  <# } else { #>
@@ -11,7 +10,20 @@
11
  <?php endif; ?>
12
  <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php _e( 'Row Settings', 'fl-builder' ); ?>"></i>
13
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
14
- <i class="fl-block-copy fa fa-copy fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  <i class="fl-block-remove fa fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
16
  <?php endif; ?>
17
  <# } #>
@@ -28,6 +40,9 @@
28
  <div class="fl-block-overlay-actions">
29
  <?php if ( ! $simple_ui ) : ?>
30
  <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
 
 
 
31
  <span class="fl-builder-has-submenu">
32
  <i class="fl-block-settings fa fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
33
  <ul class="fl-builder-submenu fl-block-col-submenu">
@@ -35,6 +50,9 @@
35
  <# if ( data.numCols > 1 || ( data.hasParentCol && data.numParentCols > 1 ) ) { #>
36
  <li><a class="fl-block-col-reset" href="javascript:void(0);"><?php _e( 'Reset Column Widths', 'fl-builder' ); ?></a></li>
37
  <# } #>
 
 
 
38
  <# if ( data.hasParentCol ) { #>
39
  <li class="fl-builder-submenu-sep"><div></div></li>
40
  <li><a class="fl-block-col-move-parent" href="javascript:void(0);"><?php _e( 'Move Parent', 'fl-builder' ); ?><i class="fa fa-arrows"></i></a></li>
@@ -68,6 +86,26 @@
68
  </div>
69
  <# } #>
70
  <# } #>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  <?php endif; ?>
72
  </div>
73
  </script>
@@ -85,16 +123,22 @@
85
  <?php endif; ?>
86
  <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php printf( __( '%s Settings', 'fl-builder' ), '{{data.moduleName}}' ); ?>"></i>
87
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
88
- <i class="fl-block-copy fa fa-copy fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
89
  <span class="fl-builder-has-submenu">
90
  <i class="fl-block-col-settings fa fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
91
  <ul class="fl-builder-submenu fl-block-col-submenu">
92
  <li><a class="fl-block-col-move" href="javascript:void(0);"><?php _e( 'Move Column', 'fl-builder' ); ?><i class="fa fa-arrows"></i></a></li>
93
  <li><a class="fl-block-col-edit" href="javascript:void(0);"><?php _e( 'Column Settings', 'fl-builder' ); ?></a></li>
 
 
 
94
  <li><a class="fl-block-col-delete" href="javascript:void(0);"><?php _e( 'Delete Column', 'fl-builder' ); ?></a></li>
95
  <# if ( data.numCols > 1 || ( data.hasParentCol && data.numParentCols > 1 ) ) { #>
96
  <li><a class="fl-block-col-reset" href="javascript:void(0);"><?php _e( 'Reset Column Widths', 'fl-builder' ); ?></a></li>
97
  <# } #>
 
 
 
98
  <# if ( data.hasParentCol ) { #>
99
  <li class="fl-builder-submenu-sep"><div></div></li>
100
  <li><a class="fl-block-col-move-parent" href="javascript:void(0);"><?php _e( 'Move Parent', 'fl-builder' ); ?><i class="fa fa-arrows"></i></a></li>
@@ -129,6 +173,26 @@
129
  </div>
130
  <# } #>
131
  <# } #>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  <?php endif; ?>
133
  </div>
134
  </script>
@@ -205,9 +269,674 @@
205
  <div class="fl-responsive-preview">
206
  <div class="fl-responsive-preview-content">
207
  <div class="fl-responsive-preview-message">
208
- <?php _e( 'Layout Preview', 'fl-builder' ); ?>
209
  </div>
210
  </div>
211
  </div>
212
  </script>
213
  <!-- #tmpl-fl-responsive-preview -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <div class="fl-row-overlay fl-block-overlay<# if ( data.global ) { #> fl-block-overlay-global<# } #>">
3
  <div class="fl-block-overlay-header">
4
  <div class="fl-block-overlay-actions">
 
5
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
6
  <i class="fa fa-lock fl-tip" title="<?php _e( 'Locked', 'fl-builder' ); ?>"></i>
7
  <# } else { #>
10
  <?php endif; ?>
11
  <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php _e( 'Row Settings', 'fl-builder' ); ?>"></i>
12
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
13
+ <i class="fl-block-copy fa fa-clone fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
14
+ <?php endif; ?>
15
+ <?php if ( ! $simple_ui ) : ?>
16
+ <# if ( ! data.global || ( data.global && 'row' == FLBuilderConfig.userTemplateType ) ) { #>
17
+ <span class="fl-builder-has-submenu">
18
+ <i class="fl-block-col-settings fa fa-bars fl-tip" title="<?php _e( 'Row Actions', 'fl-builder' ); ?>"></i>
19
+ <ul class="fl-builder-submenu fl-block-col-submenu">
20
+ <li><a class="fl-block-col-reset" href="javascript:void(0);"><?php _e( 'Reset Column Widths', 'fl-builder' ); ?></a></li>
21
+ <li><a class="fl-block-row-reset" href="javascript:void(0);"><?php _e( 'Reset Row Width', 'fl-builder' ); ?></a></li>
22
+ </ul>
23
+ </span>
24
+ <# } #>
25
+ <?php endif; ?>
26
+ <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
27
  <i class="fl-block-remove fa fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
28
  <?php endif; ?>
29
  <# } #>
40
  <div class="fl-block-overlay-actions">
41
  <?php if ( ! $simple_ui ) : ?>
42
  <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
43
+ <# if ( ( ! data.hasParentCol && data.numCols < 12 ) || ( data.hasParentCol && data.numCols < 4 ) ) { #>
44
+ <i class="fl-block-copy fl-block-col-copy fa fa-clone fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
45
+ <# } #>
46
  <span class="fl-builder-has-submenu">
47
  <i class="fl-block-settings fa fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
48
  <ul class="fl-builder-submenu fl-block-col-submenu">
50
  <# if ( data.numCols > 1 || ( data.hasParentCol && data.numParentCols > 1 ) ) { #>
51
  <li><a class="fl-block-col-reset" href="javascript:void(0);"><?php _e( 'Reset Column Widths', 'fl-builder' ); ?></a></li>
52
  <# } #>
53
+ <# if ( data.rowIsFixedWidth ) { #>
54
+ <li><a class="fl-block-row-reset" href="javascript:void(0);"><?php _e( 'Reset Row Width', 'fl-builder' ); ?></a></li>
55
+ <# } #>
56
  <# if ( data.hasParentCol ) { #>
57
  <li class="fl-builder-submenu-sep"><div></div></li>
58
  <li><a class="fl-block-col-move-parent" href="javascript:void(0);"><?php _e( 'Move Parent', 'fl-builder' ); ?><i class="fa fa-arrows"></i></a></li>
86
  </div>
87
  <# } #>
88
  <# } #>
89
+ <# if ( data.userCanResizeRows ) { #>
90
+ <# if ( ( ( data.first && ! data.hasParentCol ) || ( data.first && data.parentFirst ) ) && data.rowIsFixedWidth ) { #>
91
+ <div class="fl-block-row-resize fl-block-col-resize fl-block-col-resize-w">
92
+ <div class="fl-block-col-resize-handle-wrap">
93
+ <div class="fl-block-col-resize-feedback fl-block-col-resize-feedback-left"></div>
94
+ <div class="fl-block-col-resize-handle"></div>
95
+ <div class="fl-block-col-resize-feedback fl-block-col-resize-feedback-right"></div>
96
+ </div>
97
+ </div>
98
+ <# } #>
99
+ <# if ( ( ( data.last && ! data.hasParentCol ) || ( data.last && data.parentLast ) ) && data.rowIsFixedWidth ) { #>
100
+ <div class=" fl-block-row-resize fl-block-col-resize fl-block-col-resize-e">
101
+ <div class="fl-block-col-resize-handle-wrap">
102
+ <div class="fl-block-col-resize-feedback fl-block-col-resize-feedback-left"></div>
103
+ <div class="fl-block-col-resize-handle"></div>
104
+ <div class="fl-block-col-resize-feedback fl-block-col-resize-feedback-right"></div>
105
+ </div>
106
+ </div>
107
+ <# } #>
108
+ <# } #>
109
  <?php endif; ?>
110
  </div>
111
  </script>
123
  <?php endif; ?>
124
  <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php printf( __( '%s Settings', 'fl-builder' ), '{{data.moduleName}}' ); ?>"></i>
125
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
126
+ <i class="fl-block-copy fa fa-clone fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
127
  <span class="fl-builder-has-submenu">
128
  <i class="fl-block-col-settings fa fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
129
  <ul class="fl-builder-submenu fl-block-col-submenu">
130
  <li><a class="fl-block-col-move" href="javascript:void(0);"><?php _e( 'Move Column', 'fl-builder' ); ?><i class="fa fa-arrows"></i></a></li>
131
  <li><a class="fl-block-col-edit" href="javascript:void(0);"><?php _e( 'Column Settings', 'fl-builder' ); ?></a></li>
132
+ <# if ( ( ! data.hasParentCol && data.numCols < 12 ) || ( data.hasParentCol && data.numCols < 4 ) ) { #>
133
+ <li><a class="fl-block-col-copy" href="javascript:void(0);"><?php _e( 'Duplicate Column', 'fl-builder' ); ?></a></li>
134
+ <# } #>
135
  <li><a class="fl-block-col-delete" href="javascript:void(0);"><?php _e( 'Delete Column', 'fl-builder' ); ?></a></li>
136
  <# if ( data.numCols > 1 || ( data.hasParentCol && data.numParentCols > 1 ) ) { #>
137
  <li><a class="fl-block-col-reset" href="javascript:void(0);"><?php _e( 'Reset Column Widths', 'fl-builder' ); ?></a></li>
138
  <# } #>
139
+ <# if ( data.rowIsFixedWidth ) { #>
140
+ <li><a class="fl-block-row-reset" href="javascript:void(0);"><?php _e( 'Reset Row Width', 'fl-builder' ); ?></a></li>
141
+ <# } #>
142
  <# if ( data.hasParentCol ) { #>
143
  <li class="fl-builder-submenu-sep"><div></div></li>
144
  <li><a class="fl-block-col-move-parent" href="javascript:void(0);"><?php _e( 'Move Parent', 'fl-builder' ); ?><i class="fa fa-arrows"></i></a></li>
173
  </div>
174
  <# } #>
175
  <# } #>
176
+ <# if ( data.userCanResizeRows ) { #>
177
+ <# if ( ( ( data.colFirst && ! data.hasParentCol ) || ( data.colFirst && data.parentFirst ) ) && data.rowIsFixedWidth ) { #>
178
+ <div class="fl-block-row-resize fl-block-col-resize fl-block-col-resize-w">
179
+ <div class="fl-block-col-resize-handle-wrap">
180
+ <div class="fl-block-col-resize-feedback fl-block-col-resize-feedback-left"></div>
181
+ <div class="fl-block-col-resize-handle"></div>
182
+ <div class="fl-block-col-resize-feedback fl-block-col-resize-feedback-right"></div>
183
+ </div>
184
+ </div>
185
+ <# } #>
186
+ <# if ( ( ( data.colLast && ! data.hasParentCol ) || ( data.colLast && data.parentLast ) ) && data.rowIsFixedWidth ) { #>
187
+ <div class="fl-block-row-resize fl-block-col-resize fl-block-col-resize-e">
188
+ <div class="fl-block-col-resize-handle-wrap">
189
+ <div class="fl-block-col-resize-feedback fl-block-col-resize-feedback-left"></div>
190
+ <div class="fl-block-col-resize-handle"></div>
191
+ <div class="fl-block-col-resize-feedback fl-block-col-resize-feedback-right"></div>
192
+ </div>
193
+ </div>
194
+ <# } #>
195
+ <# } #>
196
  <?php endif; ?>
197
  </div>
198
  </script>
269
  <div class="fl-responsive-preview">
270
  <div class="fl-responsive-preview-content">
271
  <div class="fl-responsive-preview-message">
272
+ <?php _e( 'Layout Preview', 'fl-builder' ); ?>
273
  </div>
274
  </div>
275
  </div>
276
  </script>
277
  <!-- #tmpl-fl-responsive-preview -->
278
+
279
+ <script type="text/html" id="tmpl-fl-search-results-panel">
280
+ <div class="fl-builder--search-results">
281
+ <#
282
+ var grouped = data.grouped;
283
+ for( var groupSlug in grouped) {
284
+ var cats = grouped[groupSlug];
285
+ #>
286
+ <div class="fl-builder-blocks-group">
287
+ <# if ( _.isUndefined( FLBuilderConfig.moduleGroups[ groupSlug ] ) ) { #>
288
+ <span class="fl-builder-blocks-section-group-name"><?php _e( 'Standard Modules', 'fl-builder' ); ?></span>
289
+ <# } else { #>
290
+ <span class="fl-builder-blocks-section-group-name">{{FLBuilderConfig.moduleGroups[ groupSlug ]}}</span>
291
+ <# } #>
292
+ <#
293
+ for( var catName in cats) {
294
+ var modules = cats[catName];
295
+
296
+ modules.sort(function(a, b) {
297
+ if (a.name < b.name)
298
+ return -1;
299
+ if (a.name > b.name)
300
+ return 1;
301
+ return 0;
302
+ });
303
+ #>
304
+ <div class="fl-builder-blocks-section">
305
+ <span class="fl-builder-blocks-section-title">{{catName}}</span>
306
+ <div class="fl-builder-blocks-section-content fl-builder-modules">
307
+ <#
308
+ for( var i in modules ) {
309
+ var module = modules[i],
310
+ type = module.isWidget ? 'widget' : module.slug,
311
+ alias = module.isAlias ? ' data-alias="' + module.alias + '"' : '',
312
+ widget = module.isWidget ? ' data-widget="' + module.class + '"' : '',
313
+ name = module.name;
314
+ #>
315
+ <span class="fl-builder-block fl-builder-block-module" data-type="{{type}}"{{{alias}}}{{{widget}}}>
316
+ <span class="fl-builder-block-content">
317
+ <span class="fl-builder-block-icon">{{{module.icon}}}</span>
318
+ <span class="fl-builder-block-title" title="{{name}}">{{name}}</span>
319
+ </span>
320
+ </span>
321
+ <# } #>
322
+ </div>
323
+ </div>
324
+ <# } #>
325
+ </div>
326
+ <# } #>
327
+ </div>
328
+ </script>
329
+ <!-- #tmpl-fl-search-results-panel -->
330
+
331
+ <script type="text/html" id="tmpl-fl-search-no-results">
332
+ <div class="fl-builder--no-results"><?php _ex( 'No Results Found', 'No content panel search results found', 'fl-builder' ) ?></div>
333
+ </script>
334
+ <!-- #tmpl-fl-search-no-results -->
335
+
336
+ <script type="text/html" id="tmpl-fl-main-menu-panel">
337
+ <div class="fl-builder--main-menu-panel-mask"></div>
338
+ <div class="fl-builder--main-menu-panel">
339
+ <div class="fl-builder--main-menu-panel-views"></div>
340
+ </div>
341
+ </script>
342
+ <!-- #tmpl-fl-main-menu-panel -->
343
+
344
+ <script type="text/html" id="tmpl-fl-main-menu-panel-view">
345
+ <#
346
+ var viewClasses = [],
347
+ backItem;
348
+
349
+ if (data.isShowing) {
350
+ viewClasses.push('is-showing');
351
+ }
352
+ if (data.isRootView) {
353
+ viewClasses.push('is-root-view');
354
+ }
355
+
356
+ viewClasses = viewClasses.join(' ');
357
+
358
+ if (!data.isRootView) {
359
+ backItem = '<button class="pop-view">&larr;</button>';
360
+ }
361
+ #>
362
+ <div class="fl-builder--main-menu-panel-view {{viewClasses}}" data-name="{{data.handle}}">
363
+ <div class="fl-builder--main-menu-panel-view-title">{{{backItem}}}{{data.name}}</div>
364
+
365
+ <div class="fl-builder--menu">
366
+ <# for (var key in data.items) {
367
+ var item = data.items[key];
368
+
369
+ switch(item.type) {
370
+ case "separator":
371
+ #><hr><#
372
+ break;
373
+ case "event":
374
+ #>
375
+ <button class="fl-builder--menu-item" data-type="event" data-event="{{item.eventName}}">{{{item.label}}} <span class="fl-builder--menu-item-accessory">{{{item.accessory}}}</span></button>
376
+ <#
377
+ break;
378
+ case "link":
379
+ #>
380
+ <a class="fl-builder--menu-item" href="{{{item.url}}}" data-type="link" target="_blank">{{item.label}} <span class="fl-builder--menu-item-accessory"><i class="fa fa-external-link"></i></span></a>
381
+ <#
382
+ break;
383
+ case "view":
384
+ #>
385
+ <button class="fl-builder--menu-item" data-type="view" data-view="{{item.view}}">{{item.label}} <span class="fl-builder--menu-item-accessory">&rarr;</span></button>
386
+ <#
387
+ break;
388
+ case "video":
389
+ #>
390
+ <div class="fl-builder-video-wrap">
391
+ {{{item.embed}}}
392
+ </div>
393
+ <#
394
+ break;
395
+ default:
396
+ }
397
+ }
398
+ #>
399
+ </div>
400
+ </div>
401
+ </script>
402
+ <!-- #tmpl-fl-main-menu-panel-view -->
403
+
404
+ <script type="text/html" id="tmpl-fl-toolbar">
405
+ <?php include FL_BUILDER_DIR . 'includes/ui-bar.php' ?>
406
+ </script>
407
+ <!-- #tmpl-fl-toolbar -->
408
+
409
+ <script type="text/html" id="tmpl-fl-content-panel-base">
410
+ <div class="fl-builder--content-library-panel fl-builder-panel">
411
+ <div class="fl-builder--panel-arrow">
412
+ <svg width="29px" height="15px" viewBox="0 0 29 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
413
+ <g transform="translate(-260.000000, -14.000000)">
414
+ <polygon transform="translate(274.142136, 28.142136) rotate(-315.000000) translate(-274.142136, -28.142136) " points="264.142136 18.1421356 284.142136 18.1421356 264.142136 38.1421356"></polygon>
415
+ </g>
416
+ </svg>
417
+ </div>
418
+ <div class="fl-builder--panel-header">
419
+ <div class="fl-builder-panel-drag-handle">
420
+ <svg viewBox="0 0 6 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
421
+ <g fill-rule="nonzero" >
422
+ <polygon points="0 2 6 2 6 0 0 0"></polygon>
423
+ <polygon points="0 6 6 6 6 4 0 4"></polygon>
424
+ <polygon points="0 10 6 10 6 8 0 8"></polygon>
425
+ <polygon points="0 14 6 14 6 12 0 12"></polygon>
426
+ <polygon points="0 18 6 18 6 16 0 16"></polygon>
427
+ <polygon points="0 22 6 22 6 20 0 20"></polygon>
428
+ <polygon points="0 26 6 26 6 24 0 24"></polygon>
429
+ <polygon points="0 30 6 30 6 28 0 28"></polygon>
430
+ </g>
431
+ </svg>
432
+ </div>
433
+ <div class="fl-builder--tabs">
434
+ <div class="fl-builder--tab-wrap">
435
+ <# for (var handle in data.tabs) {
436
+ var tab = data.tabs[handle];
437
+ if (!tab.shouldShowTabItem || "" == tab.name ) {
438
+ continue;
439
+ }
440
+ var isShowingClass = (tab.isShowing) ? 'is-showing' : '' ;
441
+ #>
442
+ <button data-tab="{{tab.handle}}" class="{{isShowingClass}}">{{tab.name}}</button>
443
+ <#
444
+ }
445
+ #>
446
+ </div>
447
+ </div>
448
+ <div class="fl-builder--panel-controls">
449
+ <div class="fl-builder-content-group-select"></div>
450
+ <div class="fl-builder-panel-search">
451
+ <button class="fl-builder-toggle-panel-search">
452
+ <svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
453
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
454
+ <g class="filled-shape" transform="translate(-528.000000, -17.000000)">
455
+ <path d="M539.435106,27.0628931 L538.707833,27.0628931 L538.456261,26.8113208 C539.352773,25.7730132 539.89251,24.4236707 539.89251,22.946255 C539.89251,19.6620926 537.230417,17 533.946255,17 C530.662093,17 528,19.6620926 528,22.946255 C528,26.2304174 530.662093,28.89251 533.946255,28.89251 C535.423671,28.89251 536.773013,28.352773 537.811321,27.4608348 L538.062893,27.7124071 L538.062893,28.4351058 L542.636935,33 L544,31.6369354 L539.435106,27.0628931 Z M534,27 C531.791111,27 530,25.2088889 530,23 C530,20.7911111 531.791111,19 534,19 C536.208889,19 538,20.7911111 538,23 C538,25.2088889 536.208889,27 534,27 Z"></path>
456
+ </g>
457
+ </g>
458
+ </svg>
459
+ </button>
460
+ <div class="fl-builder-panel-search-input">
461
+ <input name="search-term" placeholder="<?php _e( 'Search Modules', 'fl-builder' ) ?>" />
462
+ <button class="fl-builder-dismiss-panel-search">
463
+ <svg viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
464
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
465
+ <polygon class="filled-shape" points="20 2.02142857 17.9785714 0 10 7.97857143 2.02142857 0 0 2.02142857 7.97857143 10 0 17.9785714 2.02142857 20 10 12.0214286 17.9785714 20 20 17.9785714 12.0214286 10"></polygon>
466
+ </g>
467
+ </svg>
468
+ </button>
469
+ </div>
470
+ </div>
471
+ </div>
472
+ </div>
473
+ <div class="fl-builder--panel-content">
474
+ <# for (var handle in data.tabs) {
475
+ var tab = data.tabs[handle];
476
+ if (!tab.shouldShowTabItem) {
477
+ continue;
478
+ }
479
+ var isShowingClass = (tab.isShowing) ? 'is-showing' : '' ;
480
+ #>
481
+ <div data-tab="{{tab.handle}}" class="fl-builder--panel-view fl-nanoscroller {{isShowingClass}}">
482
+ <div class="fl-nanoscroller-content"></div>
483
+ </div>
484
+ <# } #>
485
+ </div>
486
+ <div class="fl-builder--search-results-panel"></div>
487
+ <button class="fl-builder-ui-pinned-collapse fl-builder-ui-pinned-left-collapse">
488
+ <i data-toggle="show" data-position="left">
489
+ <svg width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
490
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
491
+ <g transform="translate(-150.000000, -812.000000)">
492
+ <path d="M150,813.7625 L156.194332,819.5 L150,825.2375 L151.902834,827 L160,819.5 L151.902834,812 L150,813.7625 Z M162,812 L165,812 L165,827 L162,827 L162,812 Z"></path>
493
+ </g>
494
+ </g>
495
+ </svg>
496
+ </i>
497
+ <i data-toggle="hide" data-position="left">
498
+ <svg width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
499
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
500
+ <g transform="translate(-150.000000, -812.000000)">
501
+ <path d="M150,813.7625 L156.194332,819.5 L150,825.2375 L151.902834,827 L160,819.5 L151.902834,812 L150,813.7625 Z M162,812 L165,812 L165,827 L162,827 L162,812 Z"></path>
502
+ </g>
503
+ </g>
504
+ </svg>
505
+ </i>
506
+ </button>
507
+ <button class="fl-builder-ui-pinned-collapse fl-builder-ui-pinned-right-collapse">
508
+ <i data-toggle="hide" data-position="right">
509
+ <svg width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
510
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
511
+ <g transform="translate(-150.000000, -812.000000)">
512
+ <path d="M150,813.7625 L156.194332,819.5 L150,825.2375 L151.902834,827 L160,819.5 L151.902834,812 L150,813.7625 Z M162,812 L165,812 L165,827 L162,827 L162,812 Z"></path>
513
+ </g>
514
+ </g>
515
+ </svg>
516
+ </i>
517
+ <i data-toggle="show" data-position="right">
518
+ <svg width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
519
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
520
+ <g transform="translate(-150.000000, -812.000000)">
521
+ <path d="M150,813.7625 L156.194332,819.5 L150,825.2375 L151.902834,827 L160,819.5 L151.902834,812 L150,813.7625 Z M162,812 L165,812 L165,827 L162,827 L162,812 Z"></path>
522
+ </g>
523
+ </g>
524
+ </svg>
525
+ </i>
526
+ </button>
527
+ </div>
528
+ </script>
529
+ <!-- #tmpl-fl-content-panel-base -->
530
+
531
+ <script type="text/html" id="tmpl-fl-content-panel-category-selector">
532
+ <#
533
+ var activeViewName = data.tab.activeView.name,
534
+ views = data.items;
535
+ #>
536
+ <div class="fl-builder--category-select">
537
+ <div class="fl-builder--selector-display">
538
+ <button class="fl-builder--selector-display-label">
539
+ <span class="fl-builder--group-label"><?php _e( 'Group', 'fl-builder' ) ?></span>
540
+ <span class="fl-builder--current-view-name">{{{activeViewName}}}</span>
541
+ </button>
542
+ </div>
543
+ <div class="fl-builder--selector-menu">
544
+ <div class="fl-builder--menu">
545
+ <# for(var i in views) {
546
+ var view = views[i];
547
+ if (view.type === 'separator') {
548
+ #><hr><#
549
+ } else {
550
+ var insetClass = view.isSubItem ? 'fl-inset' : '';
551
+ #>
552
+ <button data-view="{{view.handle}}" class="fl-builder--menu-item {{insetClass}}">{{{view.name}}}</button>
553
+ <# } } #>
554
+ </div>
555
+ </div>
556
+ </div>
557
+ </script>
558
+ <!-- #tmpl-fl-content-panel-category-selector -->
559
+
560
+ <script type="text/html" id="tmpl-fl-content-panel-modules-view">
561
+ <#
562
+ if (!_.isUndefined(data.queryResults)) {
563
+ var groupedModules = data.queryResults.library.module,
564
+ groupedTemplates = data.queryResults.library.template;
565
+ }
566
+
567
+ if (!_.isUndefined(groupedModules) && groupedModules.hasOwnProperty('categorized')) {
568
+
569
+ // Check if there are any ordered sections before looping over everything
570
+ if (!_.isUndefined(data.orderedSectionNames)) {
571
+
572
+ for( var i in data.orderedSectionNames ) {
573
+ var title = data.orderedSectionNames[i],
574
+ modules = groupedModules.categorized[title],
575
+ slug = title.replace(/\s+/g, '-').toLowerCase();
576
+
577
+ if ( _.isUndefined(modules) ) { continue; }
578
+ #>
579
+ <div id="fl-builder-blocks-{{slug}}" class="fl-builder-blocks-section">
580
+ <span class="fl-builder-blocks-section-title">{{title}}</span>
581
+ <div class="fl-builder-blocks-section-content fl-builder-modules">
582
+ <# for( var i in modules) {
583
+ var module = modules[i],
584
+ type = module.isWidget ? 'widget' : module.slug,
585
+ alias = module.isAlias ? ' data-alias="' + module.alias + '"' : '',
586
+ widget = module.isWidget ? ' data-widget="' + module.class + '"' : '';
587
+ #>
588
+ <span class="fl-builder-block fl-builder-block-module" data-type="{{type}}"{{{alias}}}{{{widget}}}>
589
+ <span class="fl-builder-block-content">
590
+ <span class="fl-builder-block-icon">{{{module.icon}}}</span>
591
+ <span class="fl-builder-block-title">{{module.name}}</span>
592
+ </span>
593
+ </span>
594
+ <# } #>
595
+ </div>
596
+ </div>
597
+ <#
598
+ delete groupedModules.categorized[title];
599
+ }
600
+ }
601
+
602
+ // Render any sections that were not already rendered in the ordered set
603
+ for( var title in groupedModules.categorized) {
604
+ var modules = groupedModules.categorized[title],
605
+ slug = title.replace(/\s+/g, '-').toLowerCase();
606
+ #>
607
+ <div id="fl-builder-blocks-{{slug}}" class="fl-builder-blocks-section">
608
+ <span class="fl-builder-blocks-section-title">{{title}}</span>
609
+ <div class="fl-builder-blocks-section-content fl-builder-modules">
610
+ <# for( var i in modules) {
611
+ var module = modules[i],
612
+ type = module.isWidget ? 'widget' : module.slug,
613
+ alias = module.isAlias ? ' data-alias="' + module.alias + '"' : '',
614
+ widget = module.isWidget ? ' data-widget="' + module.class + '"' : '';
615
+ #>
616
+ <span class="fl-builder-block fl-builder-block-module" data-type="{{type}}"{{{alias}}}{{{widget}}}>
617
+ <span class="fl-builder-block-content">
618
+ <span class="fl-builder-block-icon">{{{module.icon}}}</span>
619
+ <span class="fl-builder-block-title">{{module.name}}</span>
620
+ </span>
621
+ </span>
622
+ <# } #>
623
+ </div>
624
+ </div>
625
+ <#
626
+ }
627
+ }
628
+
629
+ if (!_.isUndefined(groupedTemplates) && groupedTemplates.hasOwnProperty('categorized')) {
630
+
631
+ var uncategorizedKey = FLBuilderStrings.uncategorized;
632
+ if (!_.isUndefined(groupedTemplates.categorized[uncategorizedKey])) {
633
+ var uncategorized = groupedTemplates.categorized[uncategorizedKey];
634
+ }
635
+ for( var title in groupedTemplates.categorized) {
636
+ var templates = groupedTemplates.categorized[title];
637
+ #>
638
+ <div class="fl-builder-blocks-section">
639
+ <# if (title !== '') { #>
640
+ <span class="fl-builder-blocks-section-title">{{title}}</span>
641
+ <# } #>
642
+ <div class="fl-builder-blocks-section-content fl-builder-module-templates">
643
+ <#
644
+ for( var i in templates) {
645
+ var template = templates[i],
646
+ image = template.image,
647
+ id = _.isNumber( template.postId ) ? template.postId : template.id,
648
+ hasImage = !_.isUndefined(image) && !image.endsWith('blank.jpg'),
649
+ hasImageClass = hasImage ? 'fl-builder-block-has-thumbnail' : '' ;
650
+ #>
651
+ <span class="fl-builder-block fl-builder-block-template fl-builder-block-module-template {{hasImageClass}}" data-id="{{id}}" data-type="{{template.type}}">
652
+ <span class="fl-builder-block-content">
653
+ <# if ( hasImage ) { #>
654
+ <div class="fl-builder-block-thumbnail" style="background-image:url({{image}})"></div>
655
+ <# } #>
656
+ <span class="fl-builder-block-title">{{template.name}}</span>
657
+ </span>
658
+ </span>
659
+ <# } #>
660
+ </div>
661
+ </div>
662
+ <#
663
+ }
664
+ }
665
+ if (FLBuilderConfig.lite) { #>
666
+ <div class="fl-builder--panel-cta"><a href="https://www.wpbeaverbuilder.com/?utm_medium=bb-lite&amp;utm_source=builder-ui&amp;utm_campaign=modules-panel-cta" target="_blank"><i class="fa fa-external-link-square"></i> <?php _e( 'Get more time-saving features, modules, and expert support.', 'fl-builder' ) ?></a></div>
667
+ <# } #>
668
+ </script>
669
+ <!-- #tmpl-fl-content-panel-modules-view -->
670
+
671
+ <script type="text/html" id="tmpl-fl-content-panel-col-groups-view">
672
+ <#
673
+ if (_.isUndefined(data.queryResults)) return;
674
+ var colGroups = data.queryResults.library.colGroup.items;
675
+ #>
676
+ <div id="fl-builder-blocks-rows" class="fl-builder-blocks-section">
677
+ <# if (typeof colGroups !== 'undefined') { #>
678
+ <div class="fl-builder-blocks-section-content fl-builder-rows">
679
+ <# for( var i in colGroups) {
680
+ var group = colGroups[i],
681
+ id = group.id,
682
+ name = group.name;
683
+ #>
684
+ <span class="fl-builder-block fl-builder-block-row fl-builder-block-col-group" data-cols="{{id}}" title="{{name}}">
685
+ <span class="fl-builder-block-content">
686
+ <span class="fl-builder-block-visual fl-cols-visual {{id}}">
687
+ <# for ( i = 0; i < group.count; i++ ) { #>
688
+ <span class="fl-cols-visual-col"></span>
689
+ <# } #>
690
+ </span>
691
+ <span class="fl-builder-block-title">{{name}}</span>
692
+ </span>
693
+ </span>
694
+ <# } #>
695
+ </div>
696
+ <# } #>
697
+
698
+ <# if (FLBuilderConfig.lite) { #>
699
+ <div class="fl-builder--panel-cta"><a href="https://www.wpbeaverbuilder.com/?utm_medium=bb-lite&amp;utm_source=builder-ui&amp;utm_campaign=modules-panel-cta" target="_blank"><i class="fa fa-external-link-square"></i> <?php _e( 'Get more time-saving features, modules, and expert support.', 'fl-builder' ) ?></a></div>
700
+ <# } #>
701
+ </div>
702
+ </script>
703
+ <!-- #tmpl-fl-content-panel-col-groups-view -->
704
+
705
+ <script type="text/html" id="tmpl-fl-content-panel-templates-view">
706
+ <# if (FLBuilderConfig.lite) { #>
707
+ <div class="fl-builder--panel-message">
708
+ <p><?php _ex( 'Save and reuse your layouts or kick-start your creativity with dozens of professionally designed templates.', 'Upgrade message that displays in the templates tab in lite installs.', 'fl-builder' ) ?></p>
709
+ <a class="fl-builder-upgrade-button fl-builder-button" href="{{FLBuilderConfig.upgradeUrl}}" target="_blank"><?php _ex( 'Learn More', 'Link to learn more about premium page builder', 'fl-builder' )?> <i class="fa fa-external-link-square"></i></a>
710
+ </div>
711
+ <# } #>
712
+ <#
713
+ var categories;
714
+ if (!_.isUndefined(data.queryResults)) {
715
+ categories = data.queryResults.library.template.categorized;
716
+ }
717
+ #>
718
+ <div class="fl-builder--template-collection">
719
+ <#
720
+ if (categories !== undefined) {
721
+ // treat as collection
722
+ for( var catHandle in categories) {
723
+ var templates = categories[catHandle];
724
+ var categoryName;
725
+ if (!_.isUndefined(FLBuilderStrings.categoryMeta[catHandle])) {
726
+ categoryName = FLBuilderStrings.categoryMeta[catHandle].name;
727
+ } else {
728
+ categoryName = catHandle;
729
+ }
730
+ #>
731
+ <div class="fl-builder--template-collection-section">
732
+ <# if (catHandle !== 'uncategorized' && catHandle !== FLBuilderStrings.undefined && Object.keys(categories).length > 1) { #>
733
+ <div class="fl-builder--template-collection-section-name">{{categoryName}}</div>
734
+ <# } #>
735
+ <div class="fl-builder--template-collection-section-content">
736
+ <#
737
+ for( var i in templates) {
738
+ var template = templates[i];
739
+ var background = template.image;
740
+ var id = _.isNumber( template.postId ) ? template.postId : template.id;
741
+ #>
742
+ <div class="fl-builder--template-collection-item" data-id="{{id}}" data-type="{{template.type}}">
743
+ <div class="fl-builder--template-thumbnail" style="background-image:url({{background}})"></div>
744
+ <div class="fl-builder--template-name">{{template.name}}</div>
745
+ </div>
746
+ <# } #>
747
+ </div>
748
+ </div>
749
+ <#
750
+ }
751
+ } else {
752
+ // treat as category
753
+ for( var i in data.templates) {
754
+ var template = data.templates[i];
755
+ var background = template.image;
756
+ #>
757
+ <div class="fl-builder--template-collection-item" data-id="{{template.id}}">
758
+ <div class="fl-builder--template-thumbnail" style="background-image:url({{background}})"></div>
759
+ <div class="fl-builder--template-name">{{template.name}}</div>
760
+ </div>
761
+ <#
762
+ }
763
+ }
764
+ #>
765
+ </div>
766
+ </script>
767
+ <!-- #tmpl-fl-content-panel-templates-view -->
768
+
769
+ <script type="text/html" id="tmpl-fl-content-panel-row-templates-view">
770
+ <#
771
+ var categories;
772
+ if (!_.isUndefined(data.queryResults)) {
773
+ categories = data.queryResults.library.template.categorized;
774
+ }
775
+ #>
776
+ <div>
777
+ <#
778
+ if (!_.isUndefined(categories)) {
779
+ for( var catHandle in categories) {
780
+ var templates = categories[catHandle];
781
+ var categoryName;
782
+ if (!_.isUndefined(FLBuilderStrings.categoryMeta[catHandle])) {
783
+ categoryName = FLBuilderStrings.categoryMeta[catHandle].name;
784
+ } else {
785
+ categoryName = catHandle;
786
+ }
787
+ #>
788
+ <div class="fl-builder-blocks-section">
789
+ <# if (catHandle !== 'uncategorized' && catHandle !== FLBuilderStrings.undefined && Object.keys(categories).length > 1) { #>
790
+ <span class="fl-builder-blocks-section-title">{{categoryName}}</span>
791
+ <# } #>
792
+ <div class="fl-builder-blocks-section-content fl-builder-row-templates">
793
+ <#
794
+ for( var i in templates) {
795
+ var template = templates[i],
796
+ image = template.image,
797
+ id = _.isNumber( template.postId ) ? template.postId : template.id,
798
+ hasImage = !_.isUndefined(image) && !image.endsWith('blank.jpg'),
799
+ hasImageClass = hasImage ? 'fl-builder-block-has-thumbnail' : '';
800
+ #>
801
+ <span class="fl-builder-block fl-builder-block-template fl-builder-block-row-template {{hasImageClass}}" data-id="{{id}}" data-type="{{template.type}}">
802
+ <span class="fl-builder-block-content">
803
+ <# if (hasImage) { #>
804
+ <div class="fl-builder-block-thumbnail" style="background-image:url({{image}})"></div>
805
+ <# } #>
806
+ <span class="fl-builder-block-title">{{template.name}}</span>
807
+ </span>
808
+ </span>
809
+ <# } #>
810
+ </div>
811
+ </div>
812
+ <#
813
+ }
814
+ }
815
+ #>
816
+ </div>
817
+ </script>
818
+ <!-- #tmpl-fl-content-panel-row-templates-view -->
819
+
820
+ <script type="text/html" id="tmpl-fl-content-panel-module-templates-view">
821
+ <#
822
+ var categories;
823
+ if (!_.isUndefined(data.queryResults)) {
824
+ categories = data.queryResults.library.template.categorized;
825
+ }
826
+ #>
827
+ <div class="fl-builder-module-templates-view">
828
+ <#
829
+ if (!_.isUndefined(categories)) {
830
+ for( var catHandle in categories) {
831
+ var templates = categories[catHandle],
832
+ categoryName;
833
+ if (!_.isUndefined(FLBuilderStrings.categoryMeta[catHandle])) {
834
+ categoryName = FLBuilderStrings.categoryMeta[catHandle].name;
835
+ } else {
836
+ categoryName = catHandle;
837
+ }
838
+ #>
839
+ <div class="fl-builder-blocks-section">
840
+ <# if (catHandle !== 'uncategorized' && catHandle !== FLBuilderStrings.undefined && Object.keys(categories).length > 1) { #>
841
+ <span class="fl-builder-blocks-section-title">{{categoryName}}</span>
842
+ <# } #>
843
+ <div class="fl-builder-blocks-section-content fl-builder-module-templates">
844
+ <#
845
+ for( var i in templates) {
846
+ var template = templates[i],
847
+ image = template.image,
848
+ id = _.isNumber( template.postId ) ? template.postId : template.id,
849
+ hasImage = !_.Undefined(image) && !image.endsWith('blank.jpg'),
850
+ hasImageClass = hasImage ? 'fl-builder-block-has-thumbnail' : '';
851
+ #>
852
+ <span class="fl-builder-block fl-builder-block-template fl-builder-block-module-template {{hasImageClass}}" data-id="{{id}}" data-type="{{template.type}}">
853
+ <span class="fl-builder-block-content">
854
+ <# if ( hasImage ) { #>
855
+ <img class="fl-builder-block-template-image" src="{{image}}" />
856
+ <# } #>
857
+ <span class="fl-builder-block-title">{{template.name}}</span>
858
+ </span>
859
+ </span>
860
+ <# } #>
861
+ </div>
862
+ </div><#
863
+ }
864
+ }
865
+ #>
866
+ </div>
867
+ </script>
868
+ <!-- #tmpl-fl-content-panel-module-templates-view -->
869
+
870
+ <script type="text/html" id="tmpl-fl-content-panel-no-view">
871
+ <div class="fl-builder--panel-message">
872
+ <?php _ex( 'Sorry, no content was found!', 'Message that displays when a panel tab has no view to display', 'fl-builder' ) ?>
873
+ </div>
874
+ </script>
875
+ <!-- #tmpl-fl-content-panel-no-view -->
876
+
877
+ <script type="text/html" id="tmpl-fl-content-panel-no-templates-view">
878
+ <div class="fl-builder--panel-message">
879
+ <?php _ex( 'Sorry, no templates were found!', 'Message that displays when there are no templates to display', 'fl-builder' ) ?>
880
+ </div>
881
+ </script>
882
+ <!-- #tmpl-fl-content-panel-no-templates-view -->
883
+
884
+ <script type="text/html" id="tmpl-fl-content-lite-templates-upgrade-view">
885
+ <div class="fl-builder--panel-message">
886
+ <p><?php _ex( 'Save and reuse your layouts or kick-start your creativity with dozens of professionally designed templates.', 'Upgrade message that displays in the templates tab in lite installs.', 'fl-builder' ) ?></p>
887
+ <a class="fl-builder-upgrade-button fl-builder-button" href="{{FLBuilderConfig.upgradeUrl}}" target="_blank"><?php _ex( 'Learn More', 'Link to learn more about premium page builder', 'fl-builder' )?> <i class="fa fa-external-link-square"></i></a>
888
+ </div>
889
+ </script>
890
+ <!-- #tmpl-fl-content-lite-templates-upgrade-view -->
891
+
892
+ <script type="text/html" id="tmpl-fl-revision-list-item">
893
+ <div class="fl-revision-list-item" data-revision-id="{{data.id}}">
894
+ <div class="fl-revision-list-item-avatar">
895
+ {{{data.avatar}}}
896
+ </div>
897
+ <div class="fl-revision-list-item-text">
898
+ <div class="fl-revision-list-item-date">
899
+ {{data.date}}
900
+ </div>
901
+ <div class="fl-revision-list-item-author">
902
+ {{data.author}}
903
+ </div>
904
+ </div>
905
+ </div>
906
+ </script>
907
+ <!-- #tmpl-fl-revision-list-item -->
908
+
909
+ <script type="text/html" id="tmpl-fl-no-revisions-message">
910
+ <div class="fl-no-revisions-message">
911
+ <div class="fl-no-revisions-message-title">
912
+ <?php _e( 'No Revisions Found', 'fl-builder' ); ?>
913
+ </div>
914
+ <?php if ( defined( 'WP_POST_REVISIONS' ) && ! WP_POST_REVISIONS ) : ?>
915
+ <div class="fl-no-revisions-message-text">
916
+ <?php _e( "Revisions are disabled for this site. Please contact your host if you aren't sure how to enable revisions.", 'fl-builder' ); ?>
917
+ </div>
918
+ <?php else : ?>
919
+ <div class="fl-no-revisions-message-text">
920
+ <?php _e( "You haven't saved any revisions yet. Each time you publish a new revision will be saved here.", 'fl-builder' ); ?>
921
+ </div>
922
+ <?php endif; ?>
923
+ </div>
924
+ </script>
925
+ <!-- #tmpl-fl-no-revisions-message -->
926
+
927
+ <script type="text/html" id="tmpl-fl-keyboard-shortcuts">
928
+ <div class="fl-builder-ui-keyboard-shortcuts">
929
+ <div class="fl-builder-ui-keyboard-shortcuts-content">
930
+ <# for( var i in data ) {
931
+ var item = data[i];
932
+ #>
933
+ <div class="fl-builder-ui-keyboard-shortcut-item">{{ item.label }} <span class="fl-builder-ui-shortcut-keycode">{{{ item.keyLabel }}}</span></div>
934
+ <# } #>
935
+
936
+ <div class="fl-builder-ui-keyboard-shortcust-footer">
937
+ <button class="dismiss-shortcut-ui"><?php _e( 'Close', 'fl-builder' ) ?></button>
938
+ </div>
939
+ </div>
940
+ </div>
941
+ </script>
942
+ <!-- #tmpl-fl-keyboard-shortcuts -->
includes/{field.php → ui-legacy-custom-field.php} RENAMED
@@ -1,3 +1,13 @@
 
 
 
 
 
 
 
 
 
 
1
  <?php if ( empty( $field['label'] ) ) : ?>
2
  <td class="fl-field-control" colspan="2">
3
  <?php else : ?>
@@ -57,15 +67,7 @@
57
 
58
  do_action( 'fl_builder_before_control', $name, $value, $field, $settings );
59
  do_action( 'fl_builder_before_control_' . $field['type'], $name, $value, $field, $settings );
60
-
61
- $field_file = FL_BUILDER_DIR . 'includes/field-' . $field['type'] . '.php';
62
-
63
- if ( file_exists( $field_file ) ) {
64
- include $field_file;
65
- } else {
66
- do_action( 'fl_builder_control_' . $field['type'], $name, $value, $field, $settings );
67
- }
68
-
69
  do_action( 'fl_builder_after_control_' . $field['type'], $name, $value, $field, $settings );
70
  do_action( 'fl_builder_after_control', $name, $value, $field, $settings );
71
 
1
+ <?php
2
+
3
+ /**
4
+ * PLEASE NOTE: This file is only around for backwards compatibility
5
+ * with third party settings forms that are still being rendered via
6
+ * AJAX. Going forward, all settings forms should be rendered on the
7
+ * frontend using FLBuilderSettingsForms.render.
8
+ */
9
+
10
+ ?>
11
  <?php if ( empty( $field['label'] ) ) : ?>
12
  <td class="fl-field-control" colspan="2">
13
  <?php else : ?>
67
 
68
  do_action( 'fl_builder_before_control', $name, $value, $field, $settings );
69
  do_action( 'fl_builder_before_control_' . $field['type'], $name, $value, $field, $settings );
70
+ do_action( 'fl_builder_control_' . $field['type'], $name, $value, $field, $settings );
 
 
 
 
 
 
 
 
71
  do_action( 'fl_builder_after_control_' . $field['type'], $name, $value, $field, $settings );
72
  do_action( 'fl_builder_after_control', $name, $value, $field, $settings );
73
 
includes/ui-legacy-field.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * PLEASE NOTE: This file is only around for backwards compatibility
5
+ * with third party settings forms that are still being rendered via
6
+ * AJAX. Going forward, all settings forms should be rendered on the
7
+ * frontend using FLBuilderSettingsForms.render.
8
+ */
9
+
10
+ if ( isset( $field['class'] ) ) {
11
+ $field['className'] = $field['class'];
12
+ }
13
+
14
+ ob_start();
15
+ do_action( 'fl_builder_before_control', $name, $value, $field, $settings );
16
+ do_action( 'fl_builder_before_control_' . $field['type'], $name, $value, $field, $settings );
17
+ $field['html_before'] = ob_get_clean();
18
+
19
+ ob_start();
20
+ do_action( 'fl_builder_after_control_' . $field['type'], $name, $value, $field, $settings );
21
+ do_action( 'fl_builder_after_control', $name, $value, $field, $settings );
22
+ $field['html_after'] = ob_get_clean();
23
+
24
+ ?>
25
+ <tr id="fl-field-<?php echo $name; ?>"></tr>
26
+ <script>
27
+
28
+ var html = null,
29
+ fields = {
30
+ '<?php echo $name; ?>' : <?php echo json_encode( $field ); ?>
31
+ };
32
+
33
+ html = FLBuilderSettingsForms.renderFields( fields );
34
+
35
+ jQuery( '#fl-field-<?php echo $name; ?>' ).after( html ).remove();
36
+
37
+ </script>
includes/ui-legacy-settings.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * PLEASE NOTE: This file is only around for backwards compatibility
5
+ * with third party settings forms that are still being rendered via
6
+ * AJAX. Going forward, all settings forms should be rendered on the
7
+ * frontend using FLBuilderSettingsForms.render.
8
+ */
9
+
10
+ $id = uniqid( 'fl-lightbox-content-placeholder' );
11
+
12
+ ?>
13
+ <div id="<?php echo $id; ?>"></div>
14
+ <script class="fl-legacy-settings">
15
+
16
+ var config = <?php echo json_encode( $form ); ?>,
17
+ wrap = jQuery( '#<?php echo $id; ?>' ).closest( '.fl-builder-lightbox' ),
18
+ id = wrap.attr( 'data-instance-id' );
19
+
20
+ config.lightbox = FLLightbox._instances[ id ];
21
+
22
+ FLBuilderSettingsForms.render( config );
23
+
24
+ </script>
includes/{loop-settings.php → ui-loop-settings.php} RENAMED
@@ -42,7 +42,9 @@ do_action( 'fl_builder_loop_settings_before_form', $settings ); // e.g Add custo
42
  </div>
43
  <div class="fl-custom-query fl-loop-data-source" data-source="custom_query">
44
  <div id="fl-builder-settings-section-general" class="fl-builder-settings-section">
45
- <h3 class="fl-builder-settings-title"><?php _e( 'Custom Query', 'fl-builder' ); ?></h3>
 
 
46
  <table class="fl-form-table">
47
  <?php
48
 
@@ -107,7 +109,9 @@ do_action( 'fl_builder_loop_settings_before_form', $settings ); // e.g Add custo
107
  </table>
108
  </div>
109
  <div id="fl-builder-settings-section-filter" class="fl-builder-settings-section">
110
- <h3 class="fl-builder-settings-title"><?php _e( 'Filter', 'fl-builder' ); ?></h3>
 
 
111
  <?php foreach ( FLBuilderLoop::post_types() as $slug => $type ) : ?>
112
  <table class="fl-form-table fl-custom-query-filter fl-custom-query-<?php echo $slug; ?>-filter" <?php if ( $slug == $settings->post_type ) { echo 'style="display:table;"';} ?>>
113
  <?php
42
  </div>
43
  <div class="fl-custom-query fl-loop-data-source" data-source="custom_query">
44
  <div id="fl-builder-settings-section-general" class="fl-builder-settings-section">
45
+ <h3 class="fl-builder-settings-title">
46
+ <span class="fl-builder-settings-title-text-wrap"><?php _e( 'Custom Query', 'fl-builder' ); ?></span>
47
+ </h3>
48
  <table class="fl-form-table">
49
  <?php
50
 
109
  </table>
110
  </div>
111
  <div id="fl-builder-settings-section-filter" class="fl-builder-settings-section">
112
+ <h3 class="fl-builder-settings-title">
113
+ <span class="fl-builder-settings-title-text-wrap"><?php _e( 'Filter', 'fl-builder' ); ?></span>
114
+ </h3>
115
  <?php foreach ( FLBuilderLoop::post_types() as $slug => $type ) : ?>
116
  <table class="fl-form-table fl-custom-query-filter fl-custom-query-<?php echo $slug; ?>-filter" <?php if ( $slug == $settings->post_type ) { echo 'style="display:table;"';} ?>>
117
  <?php
includes/ui-panel-module-templates.php DELETED
@@ -1,20 +0,0 @@
1
- <?php if ( count( $module_templates['categorized'] ) > 0 ) : ?>
2
- <?php foreach ( $module_templates['categorized'] as $cat ) : ?>
3
- <div class="fl-builder-blocks-section">
4
- <span class="fl-builder-blocks-section-title">
5
- <?php echo $cat['name']; ?>
6
- <i class="fa fa-chevron-down"></i>
7
- </span>
8
- <div class="fl-builder-blocks-section-content fl-builder-module-templates">
9
- <?php foreach ( $cat['templates'] as $template ) : ?>
10
- <span class="fl-builder-block fl-builder-block-template fl-builder-block-module-template" data-id="<?php echo $template['id']; ?>" data-type="<?php echo $template['type']; ?>">
11
- <?php if ( ! stristr( $template['image'], 'blank.jpg' ) ) : ?>
12
- <img class="fl-builder-block-template-image" src="<?php echo $template['image']; ?>" />
13
- <?php endif; ?>
14
- <span class="fl-builder-block-title"><?php echo $template['name']; ?></span>
15
- </span>
16
- <?php endforeach; ?>
17
- </div>
18
- </div>
19
- <?php endforeach; ?>
20
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/ui-panel-row-templates.php DELETED
@@ -1,20 +0,0 @@
1
- <?php if ( count( $row_templates['categorized'] ) > 0 ) : ?>
2
- <?php foreach ( $row_templates['categorized'] as $cat ) : ?>
3
- <div class="fl-builder-blocks-section">
4
- <span class="fl-builder-blocks-section-title">
5
- <?php echo $cat['name']; ?>
6
- <i class="fa fa-chevron-down"></i>
7
- </span>
8
- <div class="fl-builder-blocks-section-content fl-builder-row-templates">
9
- <?php foreach ( $cat['templates'] as $template ) : ?>
10
- <span class="fl-builder-block fl-builder-block-template fl-builder-block-row-template" data-id="<?php echo $template['id']; ?>" data-type="<?php echo $template['type']; ?>">
11
- <?php if ( ! stristr( $template['image'], 'blank.jpg' ) ) : ?>
12
- <img class="fl-builder-block-template-image" src="<?php echo $template['image']; ?>" />
13
- <?php endif; ?>
14
- <span class="fl-builder-block-title"><?php echo $template['name']; ?></span>
15
- </span>
16
- <?php endforeach; ?>
17
- </div>
18
- </div>
19
- <?php endforeach; ?>
20
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/ui-panel.php DELETED
@@ -1,72 +0,0 @@
1
- <div class="fl-builder-panel">
2
- <div class="fl-builder-panel-actions">
3
- <i class="fl-builder-panel-close fa fa-times"></i>
4
- </div>
5
- <div class="fl-builder-panel-content-wrap fl-nanoscroller">
6
- <div class="fl-builder-panel-content fl-nanoscroller-content">
7
- <div class="fl-builder-blocks">
8
-
9
- <?php do_action( 'fl_builder_ui_panel_before_rows' ); ?>
10
-
11
- <div id="fl-builder-blocks-rows" class="fl-builder-blocks-section">
12
- <span class="fl-builder-blocks-section-title">
13
- <?php _e( 'Row Layouts', 'fl-builder' ); ?>
14
- <i class="fa fa-chevron-down"></i>
15
- </span>
16
- <div class="fl-builder-blocks-section-content fl-builder-rows">
17
- <span class="fl-builder-block fl-builder-block-row" data-cols="1-col"><span class="fl-builder-block-title"><?php _e( '1 Column', 'fl-builder' ); ?></span></span>
18
- <span class="fl-builder-block fl-builder-block-row" data-cols="2-cols"><span class="fl-builder-block-title"><?php _e( '2 Columns', 'fl-builder' ); ?></span></span>
19
- <span class="fl-builder-block fl-builder-block-row" data-cols="3-cols"><span class="fl-builder-block-title"><?php _e( '3 Columns', 'fl-builder' ); ?></span></span>
20
- <span class="fl-builder-block fl-builder-block-row" data-cols="4-cols"><span class="fl-builder-block-title"><?php _e( '4 Columns', 'fl-builder' ); ?></span></span>
21
- <span class="fl-builder-block fl-builder-block-row" data-cols="5-cols"><span class="fl-builder-block-title"><?php _e( '5 Columns', 'fl-builder' ); ?></span></span>
22
- <span class="fl-builder-block fl-builder-block-row" data-cols="6-cols"><span class="fl-builder-block-title"><?php _e( '6 Columns', 'fl-builder' ); ?></span></span>
23
- <span class="fl-builder-block fl-builder-block-row" data-cols="left-sidebar"><span class="fl-builder-block-title"><?php _e( 'Left Sidebar', 'fl-builder' ); ?></span></span>
24
- <span class="fl-builder-block fl-builder-block-row" data-cols="right-sidebar"><span class="fl-builder-block-title"><?php _e( 'Right Sidebar', 'fl-builder' ); ?></span></span>
25
- <span class="fl-builder-block fl-builder-block-row" data-cols="left-right-sidebar"><span class="fl-builder-block-title"><?php _e( 'Left &amp; Right Sidebar', 'fl-builder' ); ?></span></span>
26
- </div>
27
- </div>
28
-
29
- <?php do_action( 'fl_builder_ui_panel_after_rows' ); ?>
30
-
31
- <div class="fl-builder-blocks-separator"></div>
32
-
33
- <?php do_action( 'fl_builder_ui_panel_before_modules' ); ?>
34
-
35
- <?php foreach ( $categories as $title => $modules ) : ?>
36
- <div id="fl-builder-blocks-<?php echo FLBuilderModel::get_module_category_slug( $title ); ?>" class="fl-builder-blocks-section">
37
- <span class="fl-builder-blocks-section-title">
38
- <?php echo $title; ?>
39
- <i class="fa fa-chevron-down"></i>
40
- </span>
41
- <?php if ( __( 'WordPress Widgets', 'fl-builder' ) == $title ) : ?>
42
- <div class="fl-builder-blocks-section-content fl-builder-widgets">
43
- <?php foreach ( $modules as $module ) : ?>
44
- <span class="fl-builder-block fl-builder-block-module" data-type="widget" data-widget="<?php echo $module->class; ?>"><span class="fl-builder-block-title" title="<?php echo esc_attr( $module->name ); ?>"><?php echo $module->name; ?></span></span>
45
- <?php endforeach; ?>
46
- </div>
47
- <?php else : ?>
48
- <div class="fl-builder-blocks-section-content fl-builder-modules">
49
- <?php foreach ( $modules as $module ) : ?>
50
- <span class="fl-builder-block fl-builder-block-module" data-type="<?php echo $module->slug; ?>"<?php if ( isset( $module->alias ) ) { echo ' data-alias="' . $module->alias . '"';} ?>><span class="fl-builder-block-title" title="<?php echo esc_attr( $module->name ); ?>"><?php echo $module->name; ?></span></span>
51
- <?php endforeach; ?>
52
- </div>
53
- <?php endif; ?>
54
- </div>
55
- <?php endforeach; ?>
56
-
57
- <?php do_action( 'fl_builder_ui_panel_after_modules' ); ?>
58
-
59
- <?php if ( true === FL_BUILDER_LITE ) : ?>
60
- <div class="fl-builder-modules-cta">
61
- <a href="#" onclick="window.open('<?php echo FLBuilderModel::get_upgrade_url( array(
62
- 'utm_medium' => 'bb-lite',
63
- 'utm_source' => 'builder-ui',
64
- 'utm_campaign' => 'modules-panel-cta',
65
- ) ); ?>');" target="_blank"><i class="fa fa-external-link-square"></i> <?php _e( 'Get more time-saving features, modules, and expert support.', 'fl-builder' ); ?></a>
66
- </div>
67
- <?php endif; ?>
68
-
69
- </div>
70
- </div>
71
- </div>
72
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/ui-service-settings.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="fl-builder-service-settings">
2
+ <table class="fl-form-table">
3
+ <#
4
+
5
+ var service_type = null,
6
+ services = {},
7
+ options = { '' : '<?php esc_html_e( 'Choose...', 'fl-builder' ); ?>' },
8
+ key = '',
9
+ fields = {},
10
+ html = '';
11
+
12
+ if ( data.section.services && 'all' !== data.section.services ) {
13
+ service_type = data.section.services;
14
+ }
15
+
16
+ if ( ! service_type ) {
17
+ services = FLBuilderConfig.services;
18
+ }
19
+ else {
20
+ for ( key in FLBuilderConfig.services ) {
21
+ if ( FLBuilderConfig.services[ key ].type == service_type ) {
22
+ services[ key ] = FLBuilderConfig.services[ key ];
23
+ }
24
+ }
25
+ }
26
+
27
+ for ( key in services ) {
28
+ options[ key ] = services[ key ].name;
29
+ }
30
+
31
+ var fields = {
32
+ service: {
33
+ row_class : 'fl-builder-service-select-row',
34
+ className : 'fl-builder-service-select',
35
+ type : 'select',
36
+ label : '<?php esc_html_e( 'Service', 'fl-builder' ); ?>',
37
+ options : options,
38
+ preview : {
39
+ type : 'none'
40
+ }
41
+ }
42
+ };
43
+
44
+ html = FLBuilderSettingsForms.renderFields( fields, data.settings );
45
+
46
+ #>
47
+ {{{html}}}
48
+ </table>
49
+ </div>
includes/ui-settings-config.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ ( function( $ ) {
2
+ FLBuilderSettingsConfig = 'undefined' === typeof FLBuilderSettingsConfig ? {} : FLBuilderSettingsConfig;
3
+ $.extend( FLBuilderSettingsConfig, <?php echo json_encode( FLBuilderUISettingsForms::get_js_config() ); ?> );
4
+ } )( jQuery );
includes/ui-settings-form-row.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/html" id="tmpl-fl-builder-settings-row">
2
+ <# if ( data.isMultiple && data.supportsMultiple && data.template.length ) {
3
+ var values = data.value,
4
+ button = FLBuilderStrings.addField.replace( '%s', data.field.label ),
5
+ i = 0;
6
+
7
+ data.name += '[]';
8
+ #>
9
+ <tbody id="fl-field-{{data.rootName}}" class="fl-field fl-builder-field-multiples" data-type="form" data-preview='{{{data.preview}}}'>
10
+ <# for( ; i < values.length; i++ ) {
11
+ data.index = i;
12
+ data.value = values[ i ];
13
+ #>
14
+ <tr class="fl-builder-field-multiple" data-field="{{data.rootName}}">
15
+ <# var field = FLBuilderSettingsForms.renderField( data ); #>
16
+ {{{field}}}
17
+ <td class="fl-builder-field-actions">
18
+ <i class="fl-builder-field-move fa fa-arrows"></i>
19
+ <i class="fl-builder-field-copy fa fa-copy"></i>
20
+ <i class="fl-builder-field-delete fa fa-times"></i>
21
+ </td>
22
+ </tr>
23
+ <# } #>
24
+ <tr>
25
+ <# if ( ! data.field.label ) { #>
26
+ <td colspan="2">
27
+ <# } else { #>
28
+ <td>&nbsp;</td><td>
29
+ <# } #>
30
+ <a href="javascript:void(0);" onclick="return false;" class="fl-builder-field-add fl-builder-button" data-field="{{data.rootName}}">{{button}}</a>
31
+ </td>
32
+ </tr>
33
+ </tbody>
34
+ <# } else { #>
35
+ <tr id="fl-field-{{data.name}}" class="fl-field{{data.rowClass}}" data-type="{{data.field.type}}" data-preview='{{{data.preview}}}'>
36
+ <# var field = FLBuilderSettingsForms.renderField( data ); #>
37
+ {{{field}}}
38
+ </tr>
39
+ <# } #>
40
+ </script>
includes/ui-settings-form.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/html" id="tmpl-fl-builder-settings">
2
+ <form class="fl-builder-settings {{data.className}}" {{{data.attrs}}} data-form-id="{{data.id}}" data-form-group="{{data.type}}" onsubmit="return false;">
3
+ <div class="fl-lightbox-header-wrap">
4
+ <div class="fl-builder-panel-drag-handle">
5
+ <svg viewBox="0 0 6 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
6
+ <g fill-rule="nonzero" >
7
+ <polygon points="0 2 6 2 6 0 0 0"></polygon>
8
+ <polygon points="0 6 6 6 6 4 0 4"></polygon>
9
+ <polygon points="0 10 6 10 6 8 0 8"></polygon>
10
+ <polygon points="0 14 6 14 6 12 0 12"></polygon>
11
+ <polygon points="0 18 6 18 6 16 0 16"></polygon>
12
+ <polygon points="0 22 6 22 6 20 0 20"></polygon>
13
+ <polygon points="0 26 6 26 6 24 0 24"></polygon>
14
+ <polygon points="0 30 6 30 6 28 0 28"></polygon>
15
+ </g>
16
+ </svg>
17
+ </div>
18
+ <div class="fl-lightbox-header">
19
+ <h1>
20
+ {{{data.title}}}
21
+ <# for ( var badge in data.badges ) { #>
22
+ <span class="fl-builder-badge fl-builder-badge-{{badge}}">{{data.badges[ badge ]}}</span>
23
+ <# } #>
24
+ </h1>
25
+ <div class="fl-lightbox-controls">
26
+ <i class="fl-lightbox-resize-toggle <# var className = FLLightbox.getResizableControlClass(); #>{{className}}"></i>
27
+ </div>
28
+ </div>
29
+ <# if ( data.tabs && Object.keys( data.tabs ).length > 1 ) { #>
30
+ <div class="fl-builder-settings-tabs">
31
+ <# var i = 0; for ( var tabId in data.tabs ) { #>
32
+ <# var tab = data.tabs[ tabId ]; #>
33
+ <a href="#fl-builder-settings-tab-{{tabId}}"<# if ( 0 === i ) { #> class="fl-active"<# } #>>{{{tab.title}}}</a>
34
+ <# i++; } #>
35
+ <button class="fl-builder-settings-tabs-more">
36
+ <svg viewBox="0 0 18 4" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
37
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
38
+ <g transform="translate(-520.000000, -108.000000)">
39
+ <path d="M524,110 C524,111.1 523.1,112 522,112 C520.9,112 520,111.1 520,110 C520,108.9 520.9,108 522,108 C523.1,108 524,108.9 524,110 Z M536,108 C534.9,108 534,108.9 534,110 C534,111.1 534.9,112 536,112 C537.1,112 538,111.1 538,110 C538,108.9 537.1,108 536,108 Z M529,108 C527.9,108 527,108.9 527,110 C527,111.1 527.9,112 529,112 C530.1,112 531,111.1 531,110 C531,108.9 530.1,108 529,108 Z"></path>
40
+ </g>
41
+ </g>
42
+ </svg>
43
+ </button>
44
+ </div>
45
+ <div class="fl-builder-settings-tabs-overflow-click-mask"></div>
46
+ <div class="fl-builder-settings-tabs-overflow-menu"></div>
47
+ <# } #>
48
+ </div>
49
+
50
+ <div class="fl-lightbox-content-wrap">
51
+ <div class="fl-builder-settings-fields fl-nanoscroller">
52
+ <div class="fl-nanoscroller-content">
53
+ <# if ( data.tabs && Object.keys( data.tabs ).length > 0 ) { #>
54
+ <# var i = 0; for ( var tabId in data.tabs ) { #>
55
+ <# var tab = data.tabs[ tabId ]; #>
56
+ <div id="fl-builder-settings-tab-{{tabId}}" class="fl-builder-settings-tab<# if ( 0 === i ) { #> fl-active<# } #>">
57
+
58
+ <# if ( tab.file ) { #>
59
+ <div class="fl-legacy-settings-tab" data-tab="{{tabId}}" />
60
+ <# } else if ( tab.template ) { #>
61
+ <# tab = FLBuilderSettingsForms.renderTabTemplate( tab, data.settings ); #>
62
+ {{{tab}}}
63
+ <# } else { #>
64
+
65
+ <# if ( tab.description ) { #>
66
+ <p class="fl-builder-settings-tab-description">{{{tab.description}}}</p>
67
+ <# } #>
68
+
69
+ <# for ( var sectionId in tab.sections ) { #>
70
+ <# var section = tab.sections[ sectionId ]; #>
71
+ <div id="fl-builder-settings-section-{{sectionId}}" class="fl-builder-settings-section">
72
+
73
+ <# if ( section.file ) { #>
74
+ <div class="fl-legacy-settings-section" data-section="{{sectionId}}" data-tab="{{tabId}}" />
75
+ <# } else if ( section.template ) { #>
76
+ <# section = FLBuilderSettingsForms.renderSectionTemplate( section, data.settings ); #>
77
+ {{{section}}}
78
+ <# } else { #>
79
+
80
+ <# if ( section.title ) { #>
81
+ <h3 class="fl-builder-settings-title">{{{section.title}}}</h3>
82
+ <# } #>
83
+
84
+ <# if ( section.description ) { #>
85
+ <p class="fl-builder-settings-description">{{{section.description}}}</p>
86
+ <# } #>
87
+
88
+ <table class="fl-form-table">
89
+ <# var fields = FLBuilderSettingsForms.renderFields( section.fields, data.settings ); #>
90
+ {{{fields}}}
91
+ </table>
92
+
93
+ <# } #>
94
+
95
+ </div>
96
+ <# } #>
97
+
98
+ <# } #>
99
+
100
+ </div>
101
+ <# i++; } #>
102
+ <# } #>
103
+ </div>
104
+ </div>
105
+ <div class="fl-lightbox-footer">
106
+ <button class="fl-builder-settings-save fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;">{{FLBuilderStrings.save}}</button>
107
+ <# if ( jQuery.inArray( 'save-as', data.buttons ) > -1 ) { #>
108
+ <button class="fl-builder-settings-save-as fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;">{{FLBuilderStrings.saveAs}}</button>
109
+ <# } #>
110
+ <button class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;">{{FLBuilderStrings.cancel}}</button>
111
+ </div>
112
+ </div>
113
+ <# var settings = FLBuilder._getSettingsJSONForHTML( data.settings ); #>
114
+ <input class="fl-builder-settings-json" type="hidden" value='{{{settings}}}' />
115
+ </form>
116
+ </script>
includes/updater-config.php CHANGED
@@ -3,7 +3,7 @@
3
  if ( class_exists( 'FLUpdater' ) ) {
4
  FLUpdater::add_product(array(
5
  'name' => 'Beaver Builder Plugin (Lite Version)',
6
- 'version' => '1.11',
7
  'slug' => 'bb-plugin',
8
  'type' => 'plugin',
9
  ));
3
  if ( class_exists( 'FLUpdater' ) ) {
4
  FLUpdater::add_product(array(
5
  'name' => 'Beaver Builder Plugin (Lite Version)',
6
+ 'version' => '2.0.3.2',
7
  'slug' => 'bb-plugin',
8
  'type' => 'plugin',
9
  ));
includes/updater/classes/class-fl-updater.php CHANGED
@@ -56,7 +56,7 @@ final class FLUpdater {
56
 
57
  if ( 'plugin' == $settings['type'] ) {
58
  add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_check' ) );
59
- add_filter( 'plugins_api', array( $this, 'plugin_info' ), 10, 3 );
60
  add_action( 'in_plugin_update_message-' . self::get_plugin_file( $settings['slug'] ), array( $this, 'update_message' ), 1, 2 );
61
  } elseif ( 'theme' == $settings['type'] ) {
62
  add_filter( 'pre_set_site_transient_update_themes', array( $this, 'update_check' ) );
56
 
57
  if ( 'plugin' == $settings['type'] ) {
58
  add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_check' ) );
59
+ add_filter( 'plugins_api', array( $this, 'plugin_info' ), 99, 3 );
60
  add_action( 'in_plugin_update_message-' . self::get_plugin_file( $settings['slug'] ), array( $this, 'update_message' ), 1, 2 );
61
  } elseif ( 'theme' == $settings['type'] ) {
62
  add_filter( 'pre_set_site_transient_update_themes', array( $this, 'update_check' ) );
js/fl-builder-ajax-layout.js CHANGED
@@ -13,15 +13,15 @@
13
  this._post = FLBuilderConfig.postId;
14
  this._head = $('head').eq(0);
15
  this._body = $('body').eq(0);
16
-
17
  // Setup the new CSS vars if we have new CSS.
18
  if ( this._data.css ) {
19
  this._loader = $('<img src="' + this._data.css + '" />');
20
  this._oldCss = $('link[href*="/cache/' + this._post + '"]');
21
  this._newCss = $('<link rel="stylesheet" id="fl-builder-layout-' + this._post + '-css" href="'+ this._data.css +'" />');
22
  }
23
-
24
- // Setup partial refresh vars.
25
  if ( this._data.partial ) {
26
  if ( this._data.js ) {
27
  this._oldJs = $('#fl-builder-partial-refresh-js');
@@ -45,7 +45,7 @@
45
  this._oldScriptsStyles = $( '.fl-builder-layout-scripts-styles' );
46
  this._content = $( FLBuilder._contentClass );
47
  }
48
-
49
  this._init();
50
  };
51
 
@@ -54,9 +54,9 @@
54
  *
55
  * @since 1.7.
56
  * @property {Object} prototype
57
- */
58
  FLBuilderAJAXLayout.prototype = {
59
-
60
  /**
61
  * Defaults for the data sent from the server.
62
  *
@@ -76,7 +76,7 @@
76
  css : null,
77
  js : null
78
  },
79
-
80
  /**
81
  * Data from the server for this render.
82
  *
@@ -85,7 +85,7 @@
85
  * @property {Object} _data
86
  */
87
  _data : null,
88
-
89
  /**
90
  * A function to call when the render is complete.
91
  *
@@ -94,7 +94,7 @@
94
  * @property {Function} _callback
95
  */
96
  _callback : function(){},
97
-
98
  /**
99
  * The ID of this post.
100
  *
@@ -103,7 +103,7 @@
103
  * @property {Number} _post
104
  */
105
  _post : null,
106
-
107
  /**
108
  * A jQuery reference to the head element.
109
  *
@@ -112,7 +112,7 @@
112
  * @property {Object} _head
113
  */
114
  _head : null,
115
-
116
  /**
117
  * A jQuery reference to the body element.
118
  *
@@ -121,7 +121,7 @@
121
  * @property {Object} _body
122
  */
123
  _body : null,
124
-
125
  /**
126
  * An jQuery reference to an image element that is used
127
  * to preload the new CSS file using the onerror hack.
@@ -131,7 +131,7 @@
131
  * @property {Object} _loader
132
  */
133
  _loader : null,
134
-
135
  /**
136
  * An jQuery reference to the old CSS element.
137
  *
@@ -140,7 +140,7 @@
140
  * @property {Object} _oldCss
141
  */
142
  _oldCss : null,
143
-
144
  /**
145
  * An jQuery reference to the new CSS element.
146
  *
@@ -149,7 +149,7 @@
149
  * @property {Object} _newCss
150
  */
151
  _newCss : null,
152
-
153
  /**
154
  * An jQuery reference to the old JS element.
155
  *
@@ -158,7 +158,7 @@
158
  * @property {Object} _oldJs
159
  */
160
  _oldJs : null,
161
-
162
  /**
163
  * An jQuery reference to the new JS element.
164
  *
@@ -167,9 +167,9 @@
167
  * @property {Object} _newJs
168
  */
169
  _newJs : null,
170
-
171
  /**
172
- * An jQuery reference to the old div that holds scripts
173
  * and styles generated by widgets and shortcodes.
174
  *
175
  * @since 1.7
@@ -177,7 +177,7 @@
177
  * @property {Object} _oldScriptsStyles
178
  */
179
  _oldScriptsStyles : null,
180
-
181
  /**
182
  * An jQuery reference to the content element.
183
  *
@@ -186,7 +186,7 @@
186
  * @property {Object} _content
187
  */
188
  _content : null,
189
-
190
  /**
191
  * Starts the render by loading the new CSS file.
192
  *
@@ -198,13 +198,13 @@
198
  {
199
  // Set the body height so the page doesn't scroll.
200
  this._body.height( this._body.height() );
201
-
202
  // Load the new CSS.
203
  if ( this._loader ) {
204
-
205
  // Set the loader's error event.
206
  this._loader.on( 'error', $.proxy( this._loadNewCSSComplete, this ) );
207
-
208
  // Add the loader to the body.
209
  this._body.append( this._loader );
210
  }
@@ -213,7 +213,7 @@
213
  this._finish();
214
  }
215
  },
216
-
217
  /**
218
  * Removes the loader, adds the new CSS once it has loaded,
219
  * and sets a quick timeout to finish the render.
@@ -226,19 +226,19 @@
226
  {
227
  // Remove the loader.
228
  this._loader.remove();
229
-
230
  // Add the new layout css.
231
  if ( this._oldCss.length > 0 ) {
232
  this._oldCss.after( this._newCss );
233
  }
234
  else {
235
- this._head.append( this._newCss );
236
  }
237
-
238
  // Set a quick timeout to ensure the css has taken effect.
239
  setTimeout( $.proxy( this._finish, this ), 250 );
240
  },
241
-
242
  /**
243
  * Finishes the render after the CSS has been loaded.
244
  *
@@ -250,34 +250,37 @@
250
  {
251
  // Remove the old content and assets.
252
  this._removeOldContentAndAssets();
253
-
254
  // Clean the new HTML.
255
  this._cleanNewHTML();
256
-
257
  // Clean up the new JS and CSS assets.
258
  this._cleanNewAssets();
259
-
260
  // Add the new HTML.
261
  this._addNewHTML();
262
-
263
  // Add widget/shortcode JS and CSS assets.
264
  this._addNewScriptsStyles();
265
-
266
  // Add the new layout JS.
267
  this._addNewJS();
268
 
269
  // Send the layout rendered event.
270
  $( FLBuilder._contentClass ).trigger( 'fl-builder.layout-rendered' );
271
-
272
  // Hide the loader.
273
  FLBuilder.hideAjaxLoader();
274
-
275
  // Run the callback.
276
  if ( typeof this._callback != 'undefined' ) {
277
  this._callback();
278
  }
 
 
 
279
  },
280
-
281
  /**
282
  * Removes old content and assets from the page.
283
  *
@@ -300,7 +303,7 @@
300
  this._oldScriptsStyles.remove();
301
  }
302
  },
303
-
304
  /**
305
  * Removes scripts and styles from _data.html that have been added by
306
  * widgets and shortcodes and adds them to _data.scriptsStyles.
@@ -315,13 +318,13 @@
315
  if ( ! this._data.scriptsStyles ) {
316
  return;
317
  }
318
-
319
  // Setup vars.
320
  var html = $( '<div>' + this._data.html + '</div>' ),
321
  nodeClass = 'fl-row',
322
  scriptsStyles = this._data.scriptsStyles,
323
  removed = '';
324
-
325
  // Get the class of the nodes that should be in data.html.
326
  if ( this._data.partial ) {
327
  if ( 'column-group' == this._data.nodeType ) {
@@ -334,7 +337,7 @@
334
  nodeClass = 'fl-' + this._data.nodeType;
335
  }
336
  }
337
-
338
  // Remove elements that shouldn't be in data.html.
339
  html.find( '> *, script' ).each( function() {
340
  if ( ! $( this ).hasClass( nodeClass ) ) {
@@ -342,7 +345,7 @@
342
  scriptsStyles += removed[0].outerHTML;
343
  }
344
  });
345
-
346
  // Wrap scriptsStyles if we have any content in it.
347
  if ( '' !== scriptsStyles ) {
348
  if ( this._data.partial ) {
@@ -352,12 +355,12 @@
352
  scriptsStyles = '<div class="fl-builder-node-scripts-styles">' + scriptsStyles + '<div>';
353
  }
354
  }
355
-
356
  // Update the data object.
357
  this._data.html = html.html();
358
  this._data.scriptsStyles = scriptsStyles;
359
  },
360
-
361
  /**
362
  * Adds the new HTML to the page.
363
  *
@@ -368,13 +371,13 @@
368
  _addNewHTML: function()
369
  {
370
  var siblings;
371
-
372
  // Add HTML for a partial refresh.
373
  if ( this._data.partial ) {
374
-
375
  // If data.nodeParent is present, we have a new node.
376
  if ( this._data.nodeParent ) {
377
-
378
  // Get sibling rows.
379
  if ( this._data.nodeParent.hasClass( 'fl-builder-content' ) ) {
380
  siblings = this._data.nodeParent.find( '.fl-row' );
@@ -383,14 +386,18 @@
383
  else if ( this._data.nodeParent.hasClass( 'fl-row-content' ) ) {
384
  siblings = this._data.nodeParent.find( ' > .fl-col-group' );
385
  }
 
 
 
 
386
  // Get sibling modules.
387
  else {
388
  siblings = this._data.nodeParent.find( ' > .fl-col-group, > .fl-module' );
389
  }
390
-
391
  // Filter out any clones created by duplicating.
392
  siblings = siblings.filter( ':not(.fl-builder-node-clone)' );
393
-
394
  // Add the new node.
395
  if ( 0 === siblings.length || siblings.length == this._data.nodePosition ) {
396
  this._data.nodeParent.append( this._data.html );
@@ -398,7 +405,7 @@
398
  else {
399
  siblings.eq( this._data.nodePosition ).before( this._data.html );
400
  }
401
-
402
  // Remove node loading placeholder in case we have one.
403
  if ( this._data.nodeId ) {
404
  FLBuilder._removeNodeLoadingPlaceholder( $( '.fl-node-' + this._data.nodeId ) );
@@ -414,8 +421,16 @@
414
  else {
415
  this._content.append( this._data.html );
416
  }
 
 
 
 
 
 
 
 
417
  },
418
-
419
  /**
420
  * Removes unnecessary JS and CSS assets from the layout.
421
  *
@@ -427,15 +442,15 @@
427
  {
428
  var nodeId = null,
429
  self = this;
430
-
431
  // Remove duplicate assets from _data.html.
432
  this._data.html = this._removeDuplicateAssets( this._data.html );
433
-
434
  // Remove duplicate assets from _data.scriptsStyles.
435
  if ( this._data.scriptsStyles && '' !== this._data.scriptsStyles ) {
436
  this._data.scriptsStyles = this._removeDuplicateAssets( this._data.scriptsStyles );
437
  }
438
-
439
  // Remove all partial JS and CSS if this is a full render.
440
  if ( ! this._data.partial ) {
441
  $( '#fl-builder-partial-refresh-js' ).remove();
@@ -443,7 +458,7 @@
443
  }
444
  // Else, remove assets that aren't needed.
445
  else {
446
-
447
  $( '.fl-builder-node-scripts-styles' ).each( function() {
448
  if ( self._data.html.indexOf( 'fl-node-' + $( this ).data( 'node' ) ) > -1 ) {
449
  $( this ).remove();
@@ -451,9 +466,9 @@
451
  } );
452
  }
453
  },
454
-
455
  /**
456
- * Removes JS and CSS that is already on the page
457
  * from the provided HTML content.
458
  *
459
  * @since 1.7
@@ -471,42 +486,42 @@
471
  link = null,
472
  loc = window.location,
473
  origin = loc.protocol + '//' + loc.hostname + ( loc.port ? ':' + loc.port : '' );
474
-
475
  // Remove duplicate scripts.
476
  cleaned.find( 'script' ).each( function() {
477
-
478
  src = $( this ).attr( 'src' );
479
-
480
  if ( 'undefined' != typeof src ) {
481
-
482
  src = src.replace( origin, '' );
483
  script = $( 'script[src*="' + src + '"]' );
484
-
485
  if ( script.length > 0 ) {
486
  $( this ).remove();
487
  }
488
  }
489
  });
490
-
491
  // Remove duplicate links.
492
  cleaned.find( 'link' ).each( function() {
493
-
494
  href = $( this ).attr( 'href' );
495
-
496
  if ( 'undefined' != typeof href ) {
497
-
498
  href = href.replace( origin, '' );
499
  link = $( 'link[href*="' + href + '"]' );
500
-
501
  if ( link.length > 0 ) {
502
  $( this ).remove();
503
  }
504
  }
505
  });
506
-
507
  return cleaned.html();
508
  },
509
-
510
  /**
511
  * Adds the new scripts and styles to the page.
512
  *
@@ -520,7 +535,7 @@
520
  this._body.append( this._data.scriptsStyles );
521
  }
522
  },
523
-
524
  /**
525
  * Adds the new layout JS to the page.
526
  *
@@ -531,14 +546,14 @@
531
  _addNewJS: function()
532
  {
533
  setTimeout( $.proxy( function() {
534
-
535
  if ( this._newJs ) {
536
  this._head.append( this._newJs );
537
  }
538
-
539
  }, this ), 50 );
540
  },
541
-
542
  /**
543
  * Called when the render has been completed.
544
  *
@@ -556,9 +571,9 @@
556
  FLBuilder._initMediaElements();
557
  FLBuilderLayout.init();
558
  FLBuilderResponsiveEditing.refreshPreview();
559
-
560
  this._body.height( 'auto' );
561
  }
562
  };
563
 
564
- })(jQuery);
13
  this._post = FLBuilderConfig.postId;
14
  this._head = $('head').eq(0);
15
  this._body = $('body').eq(0);
16
+
17
  // Setup the new CSS vars if we have new CSS.
18
  if ( this._data.css ) {
19
  this._loader = $('<img src="' + this._data.css + '" />');
20
  this._oldCss = $('link[href*="/cache/' + this._post + '"]');
21
  this._newCss = $('<link rel="stylesheet" id="fl-builder-layout-' + this._post + '-css" href="'+ this._data.css +'" />');
22
  }
23
+
24
+ // Setup partial refresh vars.
25
  if ( this._data.partial ) {
26
  if ( this._data.js ) {
27
  this._oldJs = $('#fl-builder-partial-refresh-js');
45
  this._oldScriptsStyles = $( '.fl-builder-layout-scripts-styles' );
46
  this._content = $( FLBuilder._contentClass );
47
  }
48
+
49
  this._init();
50
  };
51
 
54
  *
55
  * @since 1.7.
56
  * @property {Object} prototype
57
+ */
58
  FLBuilderAJAXLayout.prototype = {
59
+
60
  /**
61
  * Defaults for the data sent from the server.
62
  *
76
  css : null,
77
  js : null
78
  },
79
+
80
  /**
81
  * Data from the server for this render.
82
  *
85
  * @property {Object} _data
86
  */
87
  _data : null,
88
+
89
  /**
90
  * A function to call when the render is complete.
91
  *
94
  * @property {Function} _callback
95
  */
96
  _callback : function(){},
97
+
98
  /**
99
  * The ID of this post.
100
  *
103
  * @property {Number} _post
104
  */
105
  _post : null,
106
+
107
  /**
108
  * A jQuery reference to the head element.
109
  *
112
  * @property {Object} _head
113
  */
114
  _head : null,
115
+
116
  /**
117
  * A jQuery reference to the body element.
118
  *
121
  * @property {Object} _body
122
  */
123
  _body : null,
124
+
125
  /**
126
  * An jQuery reference to an image element that is used
127
  * to preload the new CSS file using the onerror hack.
131
  * @property {Object} _loader
132
  */
133
  _loader : null,
134
+
135
  /**
136
  * An jQuery reference to the old CSS element.
137
  *
140
  * @property {Object} _oldCss
141
  */
142
  _oldCss : null,
143
+
144
  /**
145
  * An jQuery reference to the new CSS element.
146
  *
149
  * @property {Object} _newCss
150
  */
151
  _newCss : null,
152
+
153
  /**
154
  * An jQuery reference to the old JS element.
155
  *
158
  * @property {Object} _oldJs
159
  */
160
  _oldJs : null,
161
+
162
  /**
163
  * An jQuery reference to the new JS element.
164
  *
167
  * @property {Object} _newJs
168
  */
169
  _newJs : null,
170
+
171
  /**
172
+ * An jQuery reference to the old div that holds scripts
173
  * and styles generated by widgets and shortcodes.
174
  *
175
  * @since 1.7
177
  * @property {Object} _oldScriptsStyles
178
  */
179
  _oldScriptsStyles : null,
180
+
181
  /**
182
  * An jQuery reference to the content element.
183
  *
186
  * @property {Object} _content
187
  */
188
  _content : null,
189
+
190
  /**
191
  * Starts the render by loading the new CSS file.
192
  *
198
  {
199
  // Set the body height so the page doesn't scroll.
200
  this._body.height( this._body.height() );
201
+
202
  // Load the new CSS.
203
  if ( this._loader ) {
204
+
205
  // Set the loader's error event.
206
  this._loader.on( 'error', $.proxy( this._loadNewCSSComplete, this ) );
207
+
208
  // Add the loader to the body.
209
  this._body.append( this._loader );
210
  }
213
  this._finish();
214
  }
215
  },
216
+
217
  /**
218
  * Removes the loader, adds the new CSS once it has loaded,
219
  * and sets a quick timeout to finish the render.
226
  {
227
  // Remove the loader.
228
  this._loader.remove();
229
+
230
  // Add the new layout css.
231
  if ( this._oldCss.length > 0 ) {
232
  this._oldCss.after( this._newCss );
233
  }
234
  else {
235
+ this._head.append( this._newCss );
236
  }
237
+
238
  // Set a quick timeout to ensure the css has taken effect.
239
  setTimeout( $.proxy( this._finish, this ), 250 );
240
  },
241
+
242
  /**
243
  * Finishes the render after the CSS has been loaded.
244
  *
250
  {
251
  // Remove the old content and assets.
252
  this._removeOldContentAndAssets();
253
+
254
  // Clean the new HTML.
255
  this._cleanNewHTML();
256
+
257
  // Clean up the new JS and CSS assets.
258
  this._cleanNewAssets();
259
+
260
  // Add the new HTML.
261
  this._addNewHTML();
262
+
263
  // Add widget/shortcode JS and CSS assets.
264
  this._addNewScriptsStyles();
265
+
266
  // Add the new layout JS.
267
  this._addNewJS();
268
 
269
  // Send the layout rendered event.
270
  $( FLBuilder._contentClass ).trigger( 'fl-builder.layout-rendered' );
271
+
272
  // Hide the loader.
273
  FLBuilder.hideAjaxLoader();
274
+
275
  // Run the callback.
276
  if ( typeof this._callback != 'undefined' ) {
277
  this._callback();
278
  }
279
+
280
+ // Fire the complete hook.
281
+ FLBuilder.triggerHook( 'didRenderLayoutComplete' );
282
  },
283
+
284
  /**
285
  * Removes old content and assets from the page.
286
  *
303
  this._oldScriptsStyles.remove();
304
  }
305
  },
306
+
307
  /**
308
  * Removes scripts and styles from _data.html that have been added by
309
  * widgets and shortcodes and adds them to _data.scriptsStyles.
318
  if ( ! this._data.scriptsStyles ) {
319
  return;
320
  }
321
+
322
  // Setup vars.
323
  var html = $( '<div>' + this._data.html + '</div>' ),
324
  nodeClass = 'fl-row',
325
  scriptsStyles = this._data.scriptsStyles,
326
  removed = '';
327
+
328
  // Get the class of the nodes that should be in data.html.
329
  if ( this._data.partial ) {
330
  if ( 'column-group' == this._data.nodeType ) {
337
  nodeClass = 'fl-' + this._data.nodeType;
338
  }
339
  }
340
+
341
  // Remove elements that shouldn't be in data.html.
342
  html.find( '> *, script' ).each( function() {
343
  if ( ! $( this ).hasClass( nodeClass ) ) {
345
  scriptsStyles += removed[0].outerHTML;
346
  }
347
  });
348
+
349
  // Wrap scriptsStyles if we have any content in it.
350
  if ( '' !== scriptsStyles ) {
351
  if ( this._data.partial ) {
355
  scriptsStyles = '<div class="fl-builder-node-scripts-styles">' + scriptsStyles + '<div>';
356
  }
357
  }
358
+
359
  // Update the data object.
360
  this._data.html = html.html();
361
  this._data.scriptsStyles = scriptsStyles;
362
  },
363
+
364
  /**
365
  * Adds the new HTML to the page.
366
  *
371
  _addNewHTML: function()
372
  {
373
  var siblings;
374
+
375
  // Add HTML for a partial refresh.
376
  if ( this._data.partial ) {
377
+
378
  // If data.nodeParent is present, we have a new node.
379
  if ( this._data.nodeParent ) {
380
+
381
  // Get sibling rows.
382
  if ( this._data.nodeParent.hasClass( 'fl-builder-content' ) ) {
383
  siblings = this._data.nodeParent.find( '.fl-row' );
386
  else if ( this._data.nodeParent.hasClass( 'fl-row-content' ) ) {
387
  siblings = this._data.nodeParent.find( ' > .fl-col-group' );
388
  }
389
+ // Get sibling columns.
390
+ else if ( this._data.nodeParent.hasClass( 'fl-col-group' ) ) {
391
+ siblings = this._data.nodeParent.find( ' > .fl-col' );
392
+ }
393
  // Get sibling modules.
394
  else {
395
  siblings = this._data.nodeParent.find( ' > .fl-col-group, > .fl-module' );
396
  }
397
+
398
  // Filter out any clones created by duplicating.
399
  siblings = siblings.filter( ':not(.fl-builder-node-clone)' );
400
+
401
  // Add the new node.
402
  if ( 0 === siblings.length || siblings.length == this._data.nodePosition ) {
403
  this._data.nodeParent.append( this._data.html );
405
  else {
406
  siblings.eq( this._data.nodePosition ).before( this._data.html );
407
  }
408
+
409
  // Remove node loading placeholder in case we have one.
410
  if ( this._data.nodeId ) {
411
  FLBuilder._removeNodeLoadingPlaceholder( $( '.fl-node-' + this._data.nodeId ) );
421
  else {
422
  this._content.append( this._data.html );
423
  }
424
+
425
+ // Refresh preview HTML of nodes within other nodes (such as modules in a row) to ensure
426
+ // any changes to the nested node are preserved after we've inserted the new HTML.
427
+ if ( FLBuilder.preview && this._data.nodeId && this._data.nodeId != FLBuilder.preview.nodeId ) {
428
+ if ( $( FLBuilder.preview.classes.node ).length ) {
429
+ $( FLBuilder.preview.classes.node ).html( FLBuilder.preview.elements.node.html() );
430
+ }
431
+ }
432
  },
433
+
434
  /**
435
  * Removes unnecessary JS and CSS assets from the layout.
436
  *
442
  {
443
  var nodeId = null,
444
  self = this;
445
+
446
  // Remove duplicate assets from _data.html.
447
  this._data.html = this._removeDuplicateAssets( this._data.html );
448
+
449
  // Remove duplicate assets from _data.scriptsStyles.
450
  if ( this._data.scriptsStyles && '' !== this._data.scriptsStyles ) {
451
  this._data.scriptsStyles = this._removeDuplicateAssets( this._data.scriptsStyles );
452
  }
453
+
454
  // Remove all partial JS and CSS if this is a full render.
455
  if ( ! this._data.partial ) {
456
  $( '#fl-builder-partial-refresh-js' ).remove();
458
  }
459
  // Else, remove assets that aren't needed.
460
  else {
461
+
462
  $( '.fl-builder-node-scripts-styles' ).each( function() {
463
  if ( self._data.html.indexOf( 'fl-node-' + $( this ).data( 'node' ) ) > -1 ) {
464
  $( this ).remove();
466
  } );
467
  }
468
  },
469
+
470
  /**
471
+ * Removes JS and CSS that is already on the page
472
  * from the provided HTML content.
473
  *
474
  * @since 1.7
486
  link = null,
487
  loc = window.location,
488
  origin = loc.protocol + '//' + loc.hostname + ( loc.port ? ':' + loc.port : '' );
489
+
490
  // Remove duplicate scripts.
491
  cleaned.find( 'script' ).each( function() {
492
+
493
  src = $( this ).attr( 'src' );
494
+
495
  if ( 'undefined' != typeof src ) {
496
+
497
  src = src.replace( origin, '' );
498
  script = $( 'script[src*="' + src + '"]' );
499
+
500
  if ( script.length > 0 ) {
501
  $( this ).remove();
502
  }
503
  }
504
  });
505
+
506
  // Remove duplicate links.
507
  cleaned.find( 'link' ).each( function() {
508
+
509
  href = $( this ).attr( 'href' );
510
+
511
  if ( 'undefined' != typeof href ) {
512
+
513
  href = href.replace( origin, '' );
514
  link = $( 'link[href*="' + href + '"]' );
515
+
516
  if ( link.length > 0 ) {
517
  $( this ).remove();
518
  }
519
  }
520
  });
521
+
522
  return cleaned.html();
523
  },
524
+
525
  /**
526
  * Adds the new scripts and styles to the page.
527
  *
535
  this._body.append( this._data.scriptsStyles );
536
  }
537
  },
538
+
539
  /**
540
  * Adds the new layout JS to the page.
541
  *
546
  _addNewJS: function()
547
  {
548
  setTimeout( $.proxy( function() {
549
+
550
  if ( this._newJs ) {
551
  this._head.append( this._newJs );
552
  }
553
+
554
  }, this ), 50 );
555
  },
556
+
557
  /**
558
  * Called when the render has been completed.
559
  *
571
  FLBuilder._initMediaElements();
572
  FLBuilderLayout.init();
573
  FLBuilderResponsiveEditing.refreshPreview();
574
+
575
  this._body.height( 'auto' );
576
  }
577
  };
578
 
579
+ })(jQuery);
js/fl-builder-layout.js CHANGED
@@ -899,8 +899,7 @@
899
  loc = window.location,
900
  id = null,
901
  element = null;
902
-
903
- if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg') < 1 ) {
904
 
905
  if ( loc.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && loc.hostname == this.hostname ) {
906
 
899
  loc = window.location,
900
  id = null,
901
  element = null;
902
+ if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg').length < 1 ) {
 
903
 
904
  if ( loc.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && loc.hostname == this.hostname ) {
905
 
js/fl-builder-preview.js CHANGED
@@ -5,37 +5,37 @@
5
  *
6
  * @class FLBuilderPreview
7
  * @since 1.3.3
 
8
  */
9
- FLBuilderPreview = function(o)
10
  {
11
- // Type
12
- this.type = o.type;
13
-
14
  // Save the current state.
15
- if(o.state != 'undefined' && o.state) {
16
- this.state = o.state;
17
- }
18
- else {
19
- this._saveState();
20
- }
21
-
22
- // Render an initial preview?
23
- if(o.layout != 'undefined' && o.layout) {
24
- FLBuilder._renderLayout(o.layout, $.proxy(this._init, this));
25
- }
26
- else {
27
  this._init();
28
  }
29
  };
30
 
31
  /**
32
- * Stores all the fonts and weights of all font fields.
33
  * This is used to render the stylesheet with Google Fonts.
34
  *
35
  * @since 1.6.3
36
  * @access private
37
  * @property {Array} _fontsList
38
- */
39
  FLBuilderPreview._fontsList = {};
40
 
41
  /**
@@ -43,7 +43,7 @@
43
  *
44
  * @since 1.3.3
45
  * @property {Object} prototype
46
- */
47
  FLBuilderPreview.prototype = {
48
 
49
  /**
@@ -59,7 +59,7 @@
59
  *
60
  * @since 1.3.3
61
  * @property {String} nodeId
62
- */
63
  nodeId : null,
64
 
65
  /**
@@ -68,98 +68,98 @@
68
  *
69
  * @since 1.3.3
70
  * @property {Object} classes
71
- */
72
  classes : {},
73
-
74
  /**
75
  * An object with references to each element
76
  * in the preview.
77
  *
78
  * @since 1.3.3
79
  * @property {Object} elements
80
- */
81
  elements : {},
82
-
83
  /**
84
  * An object that contains data for the current
85
  * state of a layout before changes are made.
86
  *
87
  * @since 1.3.3
88
  * @property {Object} state
89
- */
90
  state : null,
91
-
92
  /**
93
  * Node settings saved when the preview was initalized.
94
  *
95
  * @since 1.7
96
  * @access private
97
  * @property {Object} _savedSettings
98
- */
99
  _savedSettings : null,
100
-
101
  /**
102
  * An instance of FLStyleSheet for the current preview.
103
  *
104
  * @since 1.3.3
105
  * @access private
106
  * @property {FLStyleSheet} _styleSheet
107
- */
108
  _styleSheet : null,
109
-
110
  /**
111
  * An instance of FLStyleSheet for the medium device preview.
112
  *
113
  * @since 1.9
114
  * @access private
115
  * @property {FLStyleSheet} _styleSheetMedium
116
- */
117
  _styleSheetMedium : null,
118
-
119
  /**
120
  * An instance of FLStyleSheet for the responsive device preview.
121
  *
122
  * @since 1.9
123
  * @access private
124
  * @property {FLStyleSheet} _styleSheet
125
- */
126
  _styleSheetResponsive : null,
127
-
128
  /**
129
  * A timeout object for delaying the current preview refresh.
130
  *
131
  * @since 1.3.3
132
  * @access private
133
  * @property {Object} _timeout
134
- */
135
  _timeout : null,
136
-
137
  /**
138
- * A timeout object for delaying when we show the loading
139
  * graphic for refresh previews.
140
  *
141
  * @since 1.10
142
  * @access private
143
  * @property {Object} _loaderTimeout
144
- */
145
  _loaderTimeout : null,
146
-
147
  /**
148
  * Stores the last classname for a classname preview.
149
  *
150
  * @since 1.3.3
151
  * @access private
152
  * @property {String} _lastClassName
153
- */
154
  _lastClassName : null,
155
-
156
  /**
157
  * A reference to the AJAX object for a preview refresh.
158
  *
159
  * @since 1.3.3
160
  * @access private
161
- * @property {String} _xhr
162
- */
163
  _xhr : null,
164
 
165
  /**
@@ -173,33 +173,33 @@
173
  {
174
  // Node Id
175
  this.nodeId = $('.fl-builder-settings').data('node');
176
-
177
  // Save settings
178
  this._saveSettings();
179
-
180
  // Elements and Class Names
181
  this._initElementsAndClasses();
182
-
183
  // Create the preview stylesheets
184
  this._createSheets();
185
-
186
  // Responsive previews
187
  this._initResponsivePreviews();
188
-
189
  // Default field previews
190
  this._initDefaultFieldPreviews();
191
-
192
  // Init
193
  switch(this.type) {
194
-
195
  case 'row':
196
  this._initRow();
197
  break;
198
-
199
  case 'col':
200
  this._initColumn();
201
  break;
202
-
203
  case 'module':
204
  this._initModule();
205
  break;
@@ -217,7 +217,7 @@
217
  _saveSettings: function()
218
  {
219
  var form = $('.fl-builder-settings-lightbox .fl-builder-settings');
220
-
221
  this._savedSettings = FLBuilder._getSettings( form );
222
  },
223
 
@@ -233,10 +233,10 @@
233
  {
234
  var form = $('.fl-builder-settings-lightbox .fl-builder-settings'),
235
  settings = FLBuilder._getSettings( form );
236
-
237
  return JSON.stringify( this._savedSettings ) != JSON.stringify( settings );
238
  },
239
-
240
  /**
241
  * Initializes the classname and element references
242
  * for this preview.
@@ -248,7 +248,7 @@
248
  _initElementsAndClasses: function()
249
  {
250
  var contentClass;
251
-
252
  // Content Class
253
  if(this.type == 'row') {
254
  contentClass = '.fl-row-content-wrap';
@@ -256,7 +256,7 @@
256
  else {
257
  contentClass = '.fl-' + this.type + '-content';
258
  }
259
-
260
  // Class Names
261
  $.extend(this.classes, {
262
  settings : '.fl-builder-' + this.type + '-settings',
@@ -264,7 +264,7 @@
264
  node : FLBuilder._contentClass + ' .fl-node-' + this.nodeId,
265
  content : FLBuilder._contentClass + ' .fl-node-' + this.nodeId + ' > ' + contentClass
266
  });
267
-
268
  // Elements
269
  $.extend(this.elements, {
270
  settings : $(this.classes.settings),
@@ -273,9 +273,9 @@
273
  content : $(this.classes.content)
274
  });
275
  },
276
-
277
  /**
278
- * Creates the stylesheets for default, medium
279
  * and responsive previews.
280
  *
281
  * @since 1.9
@@ -283,17 +283,28 @@
283
  */
284
  _createSheets: function()
285
  {
 
 
286
  if ( ! this._styleSheet ) {
287
- this._styleSheet = new FLStyleSheet( { id : 'fl-builder-preview' } );
 
 
 
288
  }
289
  if ( ! this._styleSheetMedium ) {
290
- this._styleSheetMedium = new FLStyleSheet( { id : 'fl-builder-preview-medium' } );
 
 
 
291
  }
292
  if ( ! this._styleSheetResponsive ) {
293
- this._styleSheetResponsive = new FLStyleSheet( { id : 'fl-builder-preview-responsive' } );
 
 
 
294
  }
295
  },
296
-
297
  /**
298
  * Destroys all preview sheets.
299
  *
@@ -303,19 +314,19 @@
303
  _destroySheets: function()
304
  {
305
  if ( this._styleSheet ) {
306
- this._styleSheet.destroy();
307
  this._styleSheet = null;
308
  }
309
  if ( this._styleSheetMedium ) {
310
- this._styleSheetMedium.destroy();
311
- this._styleSheetMedium = null;
312
  }
313
  if ( this._styleSheetResponsive ) {
314
  this._styleSheetResponsive.destroy();
315
  this._styleSheetResponsive = null;
316
  }
317
  },
318
-
319
  /**
320
  * Updates a CSS rule for this preview.
321
  *
@@ -329,7 +340,7 @@
329
  {
330
  this._styleSheet.updateRule( selector, property, value );
331
  },
332
-
333
  /**
334
  * Runs a delay with a callback.
335
  *
@@ -343,7 +354,7 @@
343
  this._cancelDelay();
344
  this._timeout = setTimeout(callback, length);
345
  },
346
-
347
  /**
348
  * Cancels a preview refresh delay.
349
  *
@@ -357,7 +368,7 @@
357
  clearTimeout(this._timeout);
358
  }
359
  },
360
-
361
  /**
362
  * Converts a hex value to an array of RGB values.
363
  *
@@ -366,16 +377,16 @@
366
  * @param {String} hex
367
  * @return {Array}
368
  */
369
- hexToRgb: function(hex)
370
  {
371
  var bigInt = parseInt(hex, 16),
372
  r = (bigInt >> 16) & 255,
373
  g = (bigInt >> 8) & 255,
374
  b = bigInt & 255;
375
-
376
  return [r, g, b];
377
  },
378
-
379
  /**
380
  * Parses a float or returns 0 if we don't have a number.
381
  *
@@ -384,14 +395,14 @@
384
  * @param {Number} value
385
  * @return {Number}
386
  */
387
- parseFloat: function(value)
388
  {
389
  return isNaN(parseFloat(value)) ? 0 : parseFloat(value);
390
  },
391
-
392
  /* Responsive Previews
393
  ----------------------------------------------------------*/
394
-
395
  /**
396
  * Initializes logic for responsive previews.
397
  *
@@ -402,7 +413,7 @@
402
  {
403
  FLBuilder.addHook( 'responsive-editing-switched', $.proxy( this._responsiveEditingSwitched, this ) );
404
  },
405
-
406
  /**
407
  * Destroys responsive preview events.
408
  *
@@ -413,7 +424,7 @@
413
  {
414
  FLBuilder.removeHook( 'responsive-editing-switched' );
415
  },
416
-
417
  /**
418
  * Initializes logic for responsive previews.
419
  *
@@ -435,7 +446,7 @@
435
  this._styleSheetResponsive.enable();
436
  }
437
  },
438
-
439
  /**
440
  * Updates a CSS rule for responsive preview.
441
  *
@@ -449,13 +460,13 @@
449
  {
450
  var mode = FLBuilderResponsiveEditing._mode,
451
  sheetKey = 'default' == mode ? '' : mode.charAt(0).toUpperCase() + mode.slice(1);
452
-
453
  this[ '_styleSheet' + sheetKey ].updateRule( selector, property, value );
454
  },
455
-
456
  /* States
457
  ----------------------------------------------------------*/
458
-
459
  /**
460
  * Saves the current state of a layout.
461
  *
@@ -463,33 +474,36 @@
463
  * @access private
464
  * @method _saveState
465
  */
466
- _saveState: function()
467
  {
468
  var post = FLBuilderConfig.postId,
469
  css = $('link[href*="/cache/' + post + '"]').attr('href'),
470
  js = $('script[src*="/cache/' + post + '"]').attr('src'),
471
  html = $(FLBuilder._contentClass).html();
472
-
473
  this.state = {
474
  css : css,
475
  js : js,
476
  html : html
477
  };
478
  },
479
-
480
  /**
481
  * Runs a preview refresh for the current settings lightbox.
482
  *
483
  * @since 1.3.3
484
  * @method preview
485
  */
486
- preview: function()
487
  {
488
  var form = $('.fl-builder-settings-lightbox .fl-builder-settings'),
489
  nodeId = form.attr('data-node'),
490
  settings = FLBuilder._getSettings(form);
491
-
492
- // Abort an existing preview request.
 
 
 
493
  this._cancelPreview();
494
 
495
  // Make a new preview request.
@@ -499,7 +513,7 @@
499
  node_preview : settings
500
  }, $.proxy(this._renderPreview, this));
501
  },
502
-
503
  /**
504
  * Runs a preview refresh with a delay.
505
  *
@@ -513,13 +527,13 @@
513
  lightboxHeading = $('.fl-builder-settings .fl-lightbox-header'),
514
  loaderSrc = FLBuilderLayoutConfig.paths.pluginUrl + 'img/ajax-loader-small.svg',
515
  loader = $('<img class="fl-builder-preview-loader" src="' + loaderSrc + '" />');
516
-
517
  this.delay(1000, $.proxy(this.preview, this));
518
-
519
  this._loaderTimeout = setTimeout( function() {
520
-
521
  $('.fl-builder-preview-loader').remove();
522
-
523
  if(heading.length > 0) {
524
  heading.append(loader);
525
  }
@@ -529,10 +543,10 @@
529
  else if(lightboxHeading.length > 0) {
530
  lightboxHeading.append(loader);
531
  }
532
-
533
  }, 1500 );
534
  },
535
-
536
  /**
537
  * Cancels a preview refresh.
538
  *
@@ -540,14 +554,14 @@
540
  * @access private
541
  * @method _cancelPreview
542
  */
543
- _cancelPreview: function()
544
  {
545
  if(this._xhr) {
546
  this._xhr.abort();
547
  this._xhr = null;
548
  }
549
  },
550
-
551
  /**
552
  * Renders the response of a preview refresh.
553
  *
@@ -556,13 +570,13 @@
556
  * @method _renderPreview
557
  * @param {String} response The JSON encoded response.
558
  */
559
- _renderPreview: function(response)
560
  {
561
  this._xhr = null;
562
-
563
  FLBuilder._renderLayout(response, $.proxy(this._renderPreviewComplete, this));
564
  },
565
-
566
  /**
567
  * Fires when a preview refresh has finished rendering.
568
  *
@@ -570,27 +584,26 @@
570
  * @access private
571
  * @method _renderPreviewComplete
572
  */
573
- _renderPreviewComplete: function()
574
  {
575
  // Refresh the preview styles.
576
- this._destroySheets();
577
  this._createSheets();
578
-
579
  // Refresh the elements.
580
  this._initElementsAndClasses();
581
-
582
  // Clear the loader timeout.
583
  if(this._loaderTimeout !== null) {
584
  clearTimeout(this._loaderTimeout);
585
  }
586
-
587
  // Remove the loading graphic.
588
  $('.fl-builder-preview-loader').remove();
589
-
590
- // Fire the preview rendered event.
591
  $( FLBuilder._contentClass ).trigger( 'fl-builder.preview-rendered' );
592
  },
593
-
594
  /**
595
  * Reverts a preview to the state that was saved
596
  * before the preview was initialized.
@@ -598,38 +611,52 @@
598
  * @since 1.3.3
599
  * @method revert
600
  */
601
- revert: function()
602
  {
603
- // Clear the preview.
604
- this.clear();
605
-
606
- // Render the layout.
607
- FLBuilder._renderLayout( this.state );
 
 
 
608
  },
609
-
610
  /**
611
- * Cancels a preview refresh and removes
612
- * any stylesheet changes.
613
  *
614
  * @since 1.3.3
615
  * @method clear
616
  */
617
- clear: function()
618
  {
619
- // Canel any preview delays or requests.
620
  this._cancelDelay();
621
  this._cancelPreview();
622
-
 
 
 
 
 
 
 
 
 
 
 
 
 
623
  // Destroy the preview stylesheet.
624
  this._destroySheets();
625
-
626
  // Destroy responsive editing previews.
627
  this._destroyResponsivePreviews();
628
  },
629
 
630
  /* Node Text Color Settings
631
  ----------------------------------------------------------*/
632
-
633
  /**
634
  * Initializes node text color previews.
635
  *
@@ -646,14 +673,14 @@
646
  hoverColor : $(this.classes.settings + ' input[name=hover_color]'),
647
  headingColor : $(this.classes.settings + ' input[name=heading_color]')
648
  });
649
-
650
  // Events
651
  this.elements.textColor.on('change', $.proxy(this._textColorChange, this));
652
  this.elements.linkColor.on('change', $.proxy(this._textColorChange, this));
653
  this.elements.hoverColor.on('change', $.proxy(this._textColorChange, this));
654
  this.elements.headingColor.on('change', $.proxy(this._textColorChange, this));
655
  },
656
-
657
  /**
658
  * Fires when the text color field for a node
659
  * is changed.
@@ -669,13 +696,13 @@
669
  linkColor = this.elements.linkColor.val(),
670
  hoverColor = this.elements.hoverColor.val(),
671
  headingColor = this.elements.headingColor.val();
672
-
673
  linkColor = linkColor === '' ? textColor : linkColor;
674
  hoverColor = hoverColor === '' ? textColor : hoverColor;
675
  headingColor = headingColor === '' ? textColor : headingColor;
676
-
677
  this.delay(100, $.proxy(function(){
678
-
679
  // Update Text color.
680
  if(textColor === '') {
681
  this.updateCSSRule(this.classes.node, 'color', 'inherit');
@@ -683,7 +710,7 @@
683
  else {
684
  this.updateCSSRule(this.classes.node, 'color', '#' + textColor);
685
  }
686
-
687
  // Update Link Color
688
  if ( linkColor === '' ) {
689
  this.updateCSSRule(this.classes.node + ' a', 'color', 'inherit');
@@ -691,7 +718,7 @@
691
  else {
692
  this.updateCSSRule(this.classes.node + ' a', 'color', '#' + linkColor);
693
  }
694
-
695
  // Hover Color
696
  if(hoverColor === '') {
697
  this.updateCSSRule(this.classes.node + ' a:hover', 'color', 'inherit');
@@ -699,7 +726,7 @@
699
  else {
700
  this.updateCSSRule(this.classes.node + ' a:hover', 'color', '#' + hoverColor);
701
  }
702
-
703
  // Heading Color
704
  if(headingColor === '') {
705
  this.updateCSSRule(this.classes.node + ' h1', 'color', 'inherit');
@@ -729,13 +756,13 @@
729
  this.updateCSSRule(this.classes.node + ' h5 a', 'color', '#' + headingColor);
730
  this.updateCSSRule(this.classes.node + ' h6 a', 'color', '#' + headingColor);
731
  }
732
-
733
  }, this));
734
  },
735
-
736
  /* Node Bg Settings
737
  ----------------------------------------------------------*/
738
-
739
  /**
740
  * Initializes node background previews.
741
  *
@@ -770,7 +797,7 @@
770
  bgOverlayColor : $(this.classes.settings + ' input[name=bg_overlay_color]'),
771
  bgOverlayOpacity : $(this.classes.settings + ' input[name=bg_overlay_opacity]')
772
  });
773
-
774
  // Events
775
  this.elements.bgType.on( 'change', $.proxy(this._bgTypeChange, this));
776
  this.elements.bgColor.on( 'change', $.proxy(this._bgColorChange, this));
@@ -791,9 +818,9 @@
791
  this.elements.bgOverlayColor.on( 'change', $.proxy(this._bgOverlayChange, this));
792
  this.elements.bgOverlayOpacity.on( 'keyup', $.proxy(this._bgOverlayChange, this));
793
  },
794
-
795
  /**
796
- * Fires when the background type field of
797
  * a node changes.
798
  *
799
  * @since 1.3.3
@@ -804,7 +831,7 @@
804
  _bgTypeChange: function(e)
805
  {
806
  var val = this.elements.bgType.val();
807
-
808
  // Clear bg styles first.
809
  this.elements.node.removeClass('fl-row-bg-video');
810
  this.elements.node.removeClass('fl-row-bg-slideshow');
@@ -812,12 +839,12 @@
812
  this.elements.node.find('.fl-bg-video').remove();
813
  this.elements.node.find('.fl-bg-slideshow').remove();
814
  this.elements.content.css('background-image', '');
815
-
816
  this.updateCSSRule(this.classes.content, {
817
  'background-color' : 'transparent',
818
  'background-image' : 'none'
819
  });
820
-
821
  // None
822
  if(val == 'none') {
823
  this._bgOverlayClear();
@@ -828,34 +855,34 @@
828
  this.elements.bgColor.trigger('change');
829
  this._bgOverlayClear();
830
  }
831
-
832
  // Photo
833
  else if(val == 'photo') {
834
  this.elements.bgColor.trigger('change');
835
  this.elements.bgImageSrc.trigger('change');
836
  }
837
-
838
  // Video
839
  else if(val == 'video') {
840
  this.elements.bgColor.trigger('change');
841
- this._bgVideoChange();
842
  }
843
-
844
  // Slideshow
845
  else if(val == 'slideshow') {
846
  this.elements.bgColor.trigger('change');
847
  this._bgSlideshowChange();
848
  }
849
-
850
  // Parallax
851
  else if(val == 'parallax') {
852
  this.elements.bgColor.trigger('change');
853
  this.elements.bgParallaxImageSrc.trigger('change');
854
  }
855
  },
856
-
857
  /**
858
- * Fires when the background color field of
859
  * a node changes.
860
  *
861
  * @since 1.3.3
@@ -866,24 +893,24 @@
866
  _bgColorChange: function(e)
867
  {
868
  var rgb, alpha, value;
869
-
870
  if(this.elements.bgColor.val() === '' || isNaN(this.elements.bgOpacity.val())) {
871
- this.updateCSSRule(this.classes.content, 'background-color', 'transparent');
872
  }
873
  else {
874
-
875
  rgb = this.hexToRgb( this.elements.bgColor.val() );
876
  alpha = this.parseFloat(this.elements.bgOpacity.val())/100;
877
  value = 'rgba(' + rgb.join() + ', ' + alpha + ')';
878
-
879
  this.delay(100, $.proxy(function(){
880
  this.updateCSSRule(this.classes.content, 'background-color', value);
881
- }, this));
882
  }
883
  },
884
-
885
  /**
886
- * Fires when the background opacity field of
887
  * a node changes.
888
  *
889
  * @since 1.3.3
@@ -895,9 +922,9 @@
895
  {
896
  this.elements.bgColor.trigger('change');
897
  },
898
-
899
  /**
900
- * Fires when the background photo field of
901
  * a node changes.
902
  *
903
  * @since 1.3.3
@@ -925,7 +952,7 @@
925
  },
926
 
927
  /**
928
- * Fires when the background video field of
929
  * a node changes.
930
  *
931
  * @since 1.9.2
@@ -949,11 +976,11 @@
949
  && $( 'script[src*="youtube.com"' ).length < 1) {
950
  scriptTag.attr('src', youtubePlayer);
951
  }
952
- else if(/^(http\:\/\/|https\:\/\/)?(www\.)?(vimeo\.com\/)([0-9]+)$/.test(videoUrl)
953
  && $( 'script[src*="vimeo.com"' ).length < 1) {
954
  scriptTag.attr('src', vimeoPlayer);
955
  }
956
-
957
  scriptTag
958
  .attr('type', 'text/javascript')
959
  .appendTo('head');
@@ -964,9 +991,9 @@
964
  this.preview();
965
  }
966
  },
967
-
968
  /**
969
- * Fires when the background slideshow field of
970
  * a node changes.
971
  *
972
  * @since 1.3.3
@@ -982,7 +1009,7 @@
982
  feed = eles.bgSlideshowFeedUrl.val(),
983
  speed = eles.bgSlideshowSpeed.val(),
984
  transSpeed = eles.bgSlideshowTransSpeed.val();
985
-
986
  if(source == 'wordpress' && photos === '') {
987
  return;
988
  }
@@ -995,12 +1022,12 @@
995
  else if(isNaN(parseInt(transSpeed))) {
996
  return;
997
  }
998
-
999
  this.delay(500, $.proxy(this.preview, this));
1000
  },
1001
-
1002
  /**
1003
- * Fires when the background parallax field of
1004
  * a node changes.
1005
  *
1006
  * @since 1.3.3
@@ -1011,7 +1038,7 @@
1011
  _bgParallaxChange: function(e)
1012
  {
1013
  if(this.elements.bgParallaxImageSrc.val()) {
1014
-
1015
  this.updateCSSRule(this.classes.content, {
1016
  'background-image' : 'url(' + this.elements.bgParallaxImageSrc.val() + ')',
1017
  'background-repeat' : 'no-repeat',
@@ -1021,9 +1048,9 @@
1021
  });
1022
  }
1023
  },
1024
-
1025
  /**
1026
- * Fires when the background overlay field of
1027
  * a node changes.
1028
  *
1029
  * @since 1.3.3
@@ -1034,34 +1061,34 @@
1034
  _bgOverlayChange: function(e)
1035
  {
1036
  var rgb, alpha, value;
1037
-
1038
  if(this.elements.bgOverlayColor.val() === '' || isNaN(this.elements.bgOverlayOpacity.val())) {
1039
  this.elements.node.removeClass('fl-row-bg-overlay');
1040
  this.elements.node.removeClass('fl-col-bg-overlay');
1041
- this.updateCSSRule(this.classes.content + ':after', 'background-color', 'transparent');
1042
  }
1043
  else {
1044
-
1045
  rgb = this.hexToRgb(this.elements.bgOverlayColor.val());
1046
  alpha = this.parseFloat(this.elements.bgOverlayOpacity.val())/100;
1047
  value = 'rgba(' + rgb.join() + ', ' + alpha + ')';
1048
-
1049
  this.delay(100, $.proxy(function(){
1050
-
1051
  if ( this.elements.node.hasClass( 'fl-col' ) ) {
1052
  this.elements.node.addClass( 'fl-col-bg-overlay' );
1053
  }
1054
  else {
1055
  this.elements.node.addClass( 'fl-row-bg-overlay' );
1056
  }
1057
-
1058
  this.updateCSSRule( this.classes.content + ':after', 'background-color', value );
1059
-
1060
  }, this));
1061
-
1062
  }
1063
  },
1064
-
1065
  /**
1066
  * Fires when a background overlay color is cleared.
1067
  *
@@ -1077,7 +1104,7 @@
1077
 
1078
  /* Node Border Settings
1079
  ----------------------------------------------------------*/
1080
-
1081
  /**
1082
  * Initializes node border previews.
1083
  *
@@ -1094,15 +1121,15 @@
1094
  borderColorPicker : $(this.classes.settings + ' .fl-picker-border_color'),
1095
  borderOpacity : $(this.classes.settings + ' input[name=border_opacity]')
1096
  });
1097
-
1098
  // Events
1099
  this.elements.borderType.on( 'change', $.proxy(this._borderTypeChange, this));
1100
  this.elements.borderColor.on( 'change', $.proxy(this._borderColorChange, this));
1101
  this.elements.borderOpacity.on( 'keyup', $.proxy(this._borderOpacityChange, this));
1102
  },
1103
-
1104
  /**
1105
- * Fires when the border type field of
1106
  * a node changes.
1107
  *
1108
  * @since 1.3.3
@@ -1113,17 +1140,17 @@
1113
  _borderTypeChange: function(e)
1114
  {
1115
  var val = this.elements.borderType.val();
1116
-
1117
  this.updateCSSRule(this.classes.content, {
1118
  'border-style' : val === '' ? 'none' : val
1119
  });
1120
-
1121
  this.elements.borderColor.trigger('change');
1122
  this.elements.borderTop.trigger('keyup');
1123
  },
1124
-
1125
  /**
1126
- * Fires when the border color field of
1127
  * a node changes.
1128
  *
1129
  * @since 1.3.3
@@ -1134,24 +1161,24 @@
1134
  _borderColorChange: function(e)
1135
  {
1136
  var rgb, alpha, value;
1137
-
1138
  if(this.elements.borderColor.val() === '' || isNaN(this.elements.borderOpacity.val())) {
1139
- this.updateCSSRule(this.classes.content, 'border-color', 'transparent');
1140
  }
1141
  else {
1142
-
1143
  rgb = this.hexToRgb(this.elements.borderColor.val());
1144
  alpha = parseInt(this.elements.borderOpacity.val())/100;
1145
  value = 'rgba(' + rgb.join() + ', ' + alpha + ')';
1146
-
1147
  this.delay(100, $.proxy(function(){
1148
  this.updateCSSRule(this.classes.content, 'border-color', value);
1149
- }, this));
1150
  }
1151
  },
1152
-
1153
  /**
1154
- * Fires when the border opacity field of
1155
  * a node changes.
1156
  *
1157
  * @since 1.3.3
@@ -1163,10 +1190,10 @@
1163
  {
1164
  this.elements.borderColor.trigger('change');
1165
  },
1166
-
1167
  /* Node Class Name Settings
1168
  ----------------------------------------------------------*/
1169
-
1170
  /**
1171
  * Initializes node classname previews.
1172
  *
@@ -1180,12 +1207,12 @@
1180
  $.extend(this.elements, {
1181
  className : $(this.classes.settings + ' input[name=class]')
1182
  });
1183
-
1184
  // Events
1185
  this.elements.className.on('keyup', $.proxy(this._classNameChange, this));
1186
  this._lastClassName = this.elements.className.val();
1187
  },
1188
-
1189
  /**
1190
  * Fires when the classname of a node changes.
1191
  *
@@ -1197,18 +1224,18 @@
1197
  _classNameChange: function(e)
1198
  {
1199
  var className = this.elements.className.val();
1200
-
1201
  if(this._lastClassName !== null) {
1202
  this.elements.node.removeClass(this._lastClassName);
1203
  }
1204
-
1205
  this.elements.node.addClass(className);
1206
  this._lastClassName = className;
1207
  },
1208
-
1209
  /* Node Margin Settings
1210
  ----------------------------------------------------------*/
1211
-
1212
  /**
1213
  * Initializes node responsive dimension previews for things
1214
  * like margins, padding and borders.
@@ -1227,26 +1254,26 @@
1227
  inputName = '',
1228
  i = null,
1229
  k = null;
1230
-
1231
  for ( i = 0; i < dimensions.length; i++ ) {
1232
-
1233
  for ( k = 0; k < devices.length; k++ ) {
1234
-
1235
  elementKey = property + dimensions[ i ] + devices[ k ];
1236
  inputName = property + '_' + dimensions[ i ].toLowerCase();
1237
-
1238
  if ( '' != devices[ k ] ) {
1239
  inputName += '_' + devices[ k ].toLowerCase();
1240
  }
1241
-
1242
  elements[ elementKey ] = $( settingsClass + ' input[name=' + inputName + ']');
1243
  elements[ elementKey ].on( 'keyup', $.proxy( this._responsiveDimensionChange, this, property ) );
1244
  }
1245
  }
1246
-
1247
  $.extend( this.elements, elements );
1248
  },
1249
-
1250
  /**
1251
  * Get all dimensions from a node preview event.
1252
  *
@@ -1263,14 +1290,14 @@
1263
  device = 'default' == mode ? '' : mode.charAt(0).toUpperCase() + mode.slice(1),
1264
  values = {},
1265
  i = 0;
1266
-
1267
  for ( ; i < dimensions.length; i++ ) {
1268
  values[ dimensions[ i ].toLowerCase() ] = this.elements[ property + dimensions[ i ] + device ].val();
1269
  }
1270
 
1271
  return this._normalizeDimensionValues( values, property );
1272
  },
1273
-
1274
  /**
1275
  * Fires when a dimension field of a node changes.
1276
  *
@@ -1292,7 +1319,7 @@
1292
  this.updateResponsiveCSSRule( this.classes.content, newRules );
1293
  this._positionAbsoluteBgs();
1294
  },
1295
-
1296
  /**
1297
  * Normalize CSS dimension values.
1298
  *
@@ -1342,10 +1369,10 @@
1342
 
1343
  return values;
1344
  },
1345
-
1346
  /* Absolutely Positioned Backgrounds
1347
  ----------------------------------------------------------*/
1348
-
1349
  /**
1350
  * Positions the backgrounds of a node that need absolute
1351
  * positioning such as videos and slideshows.
@@ -1392,10 +1419,10 @@
1392
  }
1393
  }
1394
  },
1395
-
1396
  /* Row Settings
1397
  ----------------------------------------------------------*/
1398
-
1399
  /**
1400
  * Initializes a row preview.
1401
  *
@@ -1407,18 +1434,20 @@
1407
  {
1408
  // Elements
1409
  $.extend(this.elements, {
1410
- width : $(this.classes.settings + ' select[name=width]'),
1411
- contentWidth : $(this.classes.settings + ' select[name=content_width]'),
1412
- height : $(this.classes.settings + ' select[name=full_height]'),
1413
- align : $(this.classes.settings + ' select[name=content_alignment]')
 
1414
  });
1415
-
1416
  // Events
1417
- this.elements.width.on( 'change', $.proxy(this._rowWidthChange, this));
1418
- this.elements.contentWidth.on( 'change', $.proxy(this._rowContentWidthChange, this));
1419
- this.elements.height.on( 'change', $.proxy(this._rowHeightChange, this));
1420
- this.elements.align.on( 'change', $.proxy(this._rowHeightChange, this));
1421
-
 
1422
  // Common Elements
1423
  this._initNodeTextColor();
1424
  this._initNodeBg();
@@ -1428,7 +1457,7 @@
1428
  this._initResponsiveDimensions( 'margin' );
1429
  this._initResponsiveDimensions( 'padding' );
1430
  },
1431
-
1432
  /**
1433
  * Fires when the width field of a row changes.
1434
  *
@@ -1439,15 +1468,23 @@
1439
  */
1440
  _rowWidthChange: function(e)
1441
  {
1442
- var row = this.elements.node;
1443
-
 
1444
  if(this.elements.width.val() == 'full') {
 
1445
  row.removeClass('fl-row-fixed-width');
1446
  row.addClass('fl-row-full-width');
1447
  }
1448
  else {
1449
  row.removeClass('fl-row-full-width');
1450
  row.addClass('fl-row-fixed-width');
 
 
 
 
 
 
1451
  }
1452
  },
1453
 
@@ -1462,11 +1499,11 @@
1462
  _rowHeightChange: function(e)
1463
  {
1464
  var row = this.elements.node;
1465
-
1466
  row.removeClass('fl-row-align-top');
1467
  row.removeClass('fl-row-align-center');
1468
  row.removeClass('fl-row-align-bottom');
1469
-
1470
  if(this.elements.height.val() == 'full') {
1471
  row.addClass('fl-row-full-height');
1472
  row.addClass('fl-row-align-' + this.elements.align.val());
@@ -1475,7 +1512,7 @@
1475
  row.removeClass('fl-row-full-height');
1476
  }
1477
  },
1478
-
1479
  /**
1480
  * Fires when the content width field of a row changes.
1481
  *
@@ -1486,21 +1523,57 @@
1486
  */
1487
  _rowContentWidthChange: function(e)
1488
  {
1489
- var content = this.elements.content.find('.fl-row-content');
1490
-
 
1491
  if(this.elements.contentWidth.val() == 'full') {
 
1492
  content.removeClass('fl-row-fixed-width');
1493
  content.addClass('fl-row-full-width');
1494
  }
1495
  else {
1496
  content.removeClass('fl-row-full-width');
1497
  content.addClass('fl-row-fixed-width');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1498
  }
1499
  },
1500
-
1501
  /* Columns Settings
1502
  ----------------------------------------------------------*/
1503
-
1504
  /**
1505
  * Initializes a column preview.
1506
  *
@@ -1517,13 +1590,13 @@
1517
  columnAlign : $(this.classes.settings + ' select[name=content_alignment]'),
1518
  responsiveOrder : $(this.classes.settings + ' select[name=responsive_order]')
1519
  });
1520
-
1521
  // Events
1522
  this.elements.size.on( 'keyup', $.proxy( this._colSizeChange, this ) );
1523
  this.elements.columnHeight.on( 'change', $.proxy( this._colHeightChange, this ) );
1524
  this.elements.columnAlign.on( 'change', $.proxy( this._colHeightChange, this ) );
1525
  this.elements.responsiveOrder.on( 'change', $.proxy( this._colResponsiveOrder, this ) );
1526
-
1527
  // Common Elements
1528
  this._initNodeTextColor();
1529
  this._initNodeBg();
@@ -1533,7 +1606,7 @@
1533
  this._initResponsiveDimensions( 'margin' );
1534
  this._initResponsiveDimensions( 'padding' );
1535
  },
1536
-
1537
  /**
1538
  * Fires when the size field of a column changes.
1539
  *
@@ -1552,33 +1625,33 @@
1552
  sibling = next.length === 0 ? prev : next,
1553
  siblings = this.elements.node.siblings('.fl-col'),
1554
  siblingsWidth = 0;
1555
-
1556
  // Don't resize if we onlt have one column or no size.
1557
  if(siblings.length === 0 || isNaN(size)) {
1558
  return;
1559
  }
1560
-
1561
  // Adjust sizes based on other columns.
1562
  siblings.each(function() {
1563
-
1564
  if($(this).data('node') == sibling.data('node')) {
1565
  return;
1566
  }
1567
-
1568
  maxWidth -= parseFloat($(this)[0].style.width);
1569
  siblingsWidth += parseFloat($(this)[0].style.width);
1570
  });
1571
-
1572
  // Make sure the new width isn't too small.
1573
  if(size < minWidth) {
1574
  size = minWidth;
1575
  }
1576
-
1577
  // Make sure the new width isn't too big.
1578
  if(size > maxWidth) {
1579
  size = maxWidth;
1580
  }
1581
-
1582
  // Update the widths.
1583
  sibling.css('width', (100 - siblingsWidth - size) + '%');
1584
  this.elements.node.css('width', size + '%');
@@ -1594,11 +1667,11 @@
1594
  _colHeightChange: function()
1595
  {
1596
  var parent = this.elements.node.parent('.fl-col-group');
1597
-
1598
  parent.removeClass('fl-col-group-align-top');
1599
  parent.removeClass('fl-col-group-align-center');
1600
  parent.removeClass('fl-col-group-align-bottom');
1601
-
1602
  if(this.elements.columnHeight.val() == 'yes') {
1603
  parent.addClass('fl-col-group-equal-height');
1604
  parent.addClass('fl-col-group-align-' + this.elements.columnAlign.val());
@@ -1619,7 +1692,7 @@
1619
  {
1620
 
1621
  var parent = this.elements.node.parent('.fl-col-group');
1622
-
1623
  if(this.elements.responsiveOrder.val() == 'reversed') {
1624
  parent.addClass('fl-col-group-responsive-reversed');
1625
  }
@@ -1627,10 +1700,10 @@
1627
  parent.removeClass('fl-col-group-responsive-reversed');
1628
  }
1629
  },
1630
-
1631
  /* Module Settings
1632
  ----------------------------------------------------------*/
1633
-
1634
  /**
1635
  * Initializes a module preview.
1636
  *
@@ -1643,10 +1716,10 @@
1643
  this._initNodeClassName();
1644
  this._initResponsiveDimensions( 'margin' );
1645
  },
1646
-
1647
  /* Default Field Previews
1648
  ----------------------------------------------------------*/
1649
-
1650
  /**
1651
  * Initializes the default preview logic for each
1652
  * field in a settings form.
@@ -1654,20 +1727,21 @@
1654
  * @since 1.3.3
1655
  * @access private
1656
  * @method _initDefaultFieldPreviews
 
1657
  */
1658
- _initDefaultFieldPreviews: function()
1659
  {
1660
- var fields = this.elements.settings.find('.fl-field'),
1661
  field = null,
1662
  fieldType = null,
1663
  preview = null,
1664
  i = 0;
1665
-
1666
  for( ; i < fields.length; i++) {
1667
-
1668
  field = fields.eq(i);
1669
  preview = field.data('preview');
1670
-
1671
  if(preview.type == 'refresh') {
1672
  this._initFieldRefreshPreview(field);
1673
  }
@@ -1685,7 +1759,7 @@
1685
  }
1686
  }
1687
  },
1688
-
1689
  /**
1690
  * Initializes the refresh preview for a field.
1691
  *
@@ -1699,41 +1773,41 @@
1699
  var fieldType = field.data('type'),
1700
  preview = field.data('preview'),
1701
  callback = $.proxy(this.delayPreview, this);
1702
-
1703
  switch(fieldType) {
1704
-
1705
  case 'text':
1706
  field.find('input[type=text]').on('keyup', callback);
1707
  break;
1708
-
1709
  case 'textarea':
1710
  field.find('textarea').on('keyup', callback);
1711
  break;
1712
-
1713
  case 'select':
1714
  field.find('select').on('change', callback);
1715
  break;
1716
-
1717
  case 'color':
1718
  field.find('.fl-color-picker-value').on('change', callback);
1719
  break;
1720
-
1721
  case 'photo':
1722
  field.find('select').on('change', callback);
1723
  break;
1724
-
1725
  case 'multiple-photos':
1726
  field.find('input').on('change', callback);
1727
  break;
1728
-
1729
  case 'photo-sizes':
1730
  field.find('select').on('change', callback);
1731
  break;
1732
-
1733
  case 'video':
1734
  field.find('input').on('change', callback);
1735
  break;
1736
-
1737
  case 'multiple-audios':
1738
  field.find('input').on('change', callback);
1739
  break;
@@ -1741,39 +1815,39 @@
1741
  case 'icon':
1742
  field.find('input').on('change', callback);
1743
  break;
1744
-
1745
  case 'form':
1746
  field.delegate('input', 'change', callback);
1747
  break;
1748
-
1749
  case 'editor':
1750
  this._addTextEditorCallback(field, preview);
1751
  break;
1752
-
1753
  case 'code':
1754
  field.find('textarea').on('change', callback);
1755
  break;
1756
-
1757
  case 'post-type':
1758
  field.find('select').on('change', callback);
1759
  break;
1760
-
1761
  case 'suggest':
1762
  field.find('.as-values').on('change', callback);
1763
  field.find('select').on('change', callback);
1764
  break;
1765
-
1766
  case 'unit':
1767
  field.find('input[type=number]').on('keyup', callback);
1768
  break;
1769
-
1770
  case 'ordering':
1771
  field.find('input[type=hidden]').on('change', callback);
1772
  break;
1773
 
1774
  }
1775
  },
1776
-
1777
  /**
1778
  * Initializes a text preview for a field.
1779
  *
@@ -1787,25 +1861,25 @@
1787
  var fieldType = field.data('type'),
1788
  preview = field.data('preview'),
1789
  callback = $.proxy(this._previewText, this, preview);
1790
-
1791
  switch(fieldType) {
1792
-
1793
  case 'text':
1794
  field.find('input[type=text]').on('keyup', callback);
1795
  break;
1796
-
1797
  case 'unit':
1798
  field.find('input[type=number]').on('keyup', callback);
1799
  break;
1800
-
1801
  case 'textarea':
1802
  field.find('textarea').on('keyup', callback);
1803
  break;
1804
-
1805
  case 'code':
1806
  field.find('textarea').on('change', callback);
1807
  break;
1808
-
1809
  case 'editor':
1810
  this._addTextEditorCallback(field, preview);
1811
  break;
@@ -1825,13 +1899,13 @@
1825
  {
1826
  var element = this.elements.node.find(preview.selector),
1827
  text = $('<div>' + $(e.target).val() + '</div>');
1828
-
1829
  if(element.length > 0) {
1830
  text.find('script').remove();
1831
  element.html(text.html());
1832
  }
1833
  },
1834
-
1835
  /**
1836
  * Runs a real time preview for text editor fields.
1837
  *
@@ -1850,10 +1924,10 @@
1850
  text = '';
1851
 
1852
  if(element.length > 0) {
1853
-
1854
  if(editor && textarea.css('display') == 'none') {
1855
  text = $('<div>' + editor.getContent() + '</div>');
1856
- }
1857
  else {
1858
  if ( 'undefined' == typeof switchEditors || 'undefined' == typeof switchEditors.wpautop ) {
1859
  text = $('<div>' + textarea.val() + '</div>');
@@ -1862,12 +1936,12 @@
1862
  text = $('<div>' + switchEditors.wpautop( textarea.val() ) + '</div>');
1863
  }
1864
  }
1865
-
1866
  text.find('script').remove();
1867
  element.html(text.html());
1868
  }
1869
  },
1870
-
1871
  /**
1872
  * Callback for text editor previews.
1873
  *
@@ -1881,7 +1955,7 @@
1881
  {
1882
  var id = field.find('textarea.wp-editor-area').attr('id'),
1883
  callback = null;
1884
-
1885
  if(preview.type == 'refresh') {
1886
  callback = $.proxy(this.delayPreview, this);
1887
  }
@@ -1891,9 +1965,9 @@
1891
  else {
1892
  return;
1893
  }
1894
-
1895
  $('#' + id).on('keyup', callback);
1896
-
1897
  if(typeof tinyMCE != 'undefined') {
1898
  editor = tinyMCE.get(id);
1899
  editor.on('change', callback);
@@ -1918,7 +1992,7 @@
1918
  preview.id = field.attr( 'id' );
1919
 
1920
  var callback = $.proxy(this._previewFont, this, preview);
1921
-
1922
  if( fieldType == 'font' ){
1923
  field.find('.fl-font-field').on('change', 'select', callback);
1924
  }
@@ -1958,13 +2032,13 @@
1958
  } else {
1959
  // Updated CSS rules
1960
  this.updateCSSRule( selector, 'font-family', font.val() );
1961
- this.updateCSSRule( selector, 'font-weight', weight.val() );
1962
  }
1963
 
1964
  },
1965
 
1966
  /**
1967
- * Gets all fonts store insite FLBuilderPreview._fontsList and renders the respective
1968
  * link tag with Google Fonts.
1969
  *
1970
  * @since 1.6.3
@@ -1987,9 +2061,9 @@
1987
  // adds to the list of fonts for this font setting
1988
  FLBuilderPreview._fontsList[ id ] = fontObj;
1989
 
1990
- // iterate over the keys of the FLBuilderPreview._fontsList object
1991
  Object.keys( FLBuilderPreview._fontsList ).forEach( function( fieldFont ) {
1992
-
1993
  var field = FLBuilderPreview._fontsList[ fieldFont ];
1994
 
1995
  // iterate over the font / weight object
@@ -2004,8 +2078,8 @@
2004
  return fontArray[ key ].indexOf( weight ) < 0;
2005
  });
2006
 
2007
- fontArray[ key ] = fontArray[ key ].concat( weights );
2008
-
2009
  });
2010
 
2011
  });
@@ -2023,13 +2097,13 @@
2023
  .attr( 'type', 'text/css' )
2024
  .attr( 'rel', 'stylesheet' )
2025
  .attr( 'href', href )
2026
- .appendTo('head');
2027
  } else{
2028
  $( '#fl-builder-google-fonts-preview' ).attr( 'href', href );
2029
  }
2030
 
2031
  },
2032
-
2033
  /**
2034
  * Initializes CSS previews for a node.
2035
  *
@@ -2043,7 +2117,7 @@
2043
  {
2044
  var preview = field.data( 'preview' ),
2045
  i = null;
2046
-
2047
  if ( 'undefined' != typeof preview.rules ) {
2048
  for ( i in preview.rules ) {
2049
  this._initFieldCSSPreviewCallback( field, preview.rules[ i ] );
@@ -2053,7 +2127,7 @@
2053
  this._initFieldCSSPreviewCallback( field, preview );
2054
  }
2055
  },
2056
-
2057
  /**
2058
  * Initializes CSS preview callbacks for a field.
2059
  *
@@ -2066,25 +2140,25 @@
2066
  _initFieldCSSPreviewCallback: function( field, preview )
2067
  {
2068
  switch( field.data( 'type' ) ) {
2069
-
2070
  case 'text':
2071
  field.find( 'input[type=text]' ).on( 'keyup', $.proxy( this._previewCSS, this, preview ) );
2072
  break;
2073
-
2074
  case 'unit':
2075
  field.find( 'input[type=number]' ).on( 'keyup', $.proxy( this._previewCSS, this, preview ) );
2076
  break;
2077
-
2078
  case 'select':
2079
  field.find( 'select' ).on( 'change', $.proxy( this._previewCSS, this, preview ) );
2080
  break;
2081
-
2082
  case 'color':
2083
  field.find( '.fl-color-picker-value' ).on( 'change', $.proxy( this._previewColor, this, preview ) );
2084
  break;
2085
  }
2086
  },
2087
-
2088
  /**
2089
  * Updates the CSS rule for a preview.
2090
  *
@@ -2101,14 +2175,14 @@
2101
  unit = typeof preview.unit == 'undefined' ? '' : preview.unit,
2102
  input = $(e.target),
2103
  value = input.val();
2104
-
2105
  if(unit == '%') {
2106
  value = parseInt(value)/100;
2107
  }
2108
  else if ( '' !== value ) {
2109
  value += unit;
2110
  }
2111
-
2112
  if ( input.closest( '.fl-field-responsive-setting' ).length ) {
2113
  this.updateResponsiveCSSRule( selector, property, value );
2114
  }
@@ -2116,7 +2190,7 @@
2116
  this.updateCSSRule( selector, property, value );
2117
  }
2118
  },
2119
-
2120
  /**
2121
  * Updates the CSS rule for a color preview.
2122
  *
@@ -2132,7 +2206,7 @@
2132
  input = $(e.target),
2133
  val = input.val(),
2134
  color = val === '' ? 'inherit' : '#' + val;
2135
-
2136
  if ( /^rgb/.test( val.replace(/\s+/g, '') ) ) {
2137
  color = val;
2138
  }
@@ -2144,7 +2218,7 @@
2144
  this.updateCSSRule( selector, preview.property, color );
2145
  }
2146
  },
2147
-
2148
  /**
2149
  * Initializes the preview for a WordPress widget.
2150
  *
@@ -2156,13 +2230,13 @@
2156
  _initFieldWidgetPreview: function(field)
2157
  {
2158
  var callback = $.proxy(this.delayPreview, this);
2159
-
2160
  field.find('input').on('keyup', callback);
2161
  field.find('input[type=checkbox]').on('click', callback);
2162
  field.find('textarea').on('keyup', callback);
2163
  field.find('select').on('change', callback);
2164
  },
2165
-
2166
  /**
2167
  * Returns a formatted selector string for a preview.
2168
  *
@@ -2177,16 +2251,21 @@
2177
  var formatted = '',
2178
  parts = selector.split( ',' ),
2179
  i = 0;
2180
-
2181
  for ( ; i < parts.length; i++ ) {
2182
-
2183
- formatted += prefix + ' ' + parts[ i ];
2184
-
 
 
 
 
 
2185
  if ( i != parts.length - 1 ) {
2186
  formatted += ', ';
2187
  }
2188
  }
2189
-
2190
  return formatted;
2191
  }
2192
  };
5
  *
6
  * @class FLBuilderPreview
7
  * @since 1.3.3
8
+ * @param {Object} config
9
  */
10
+ FLBuilderPreview = function( config )
11
  {
12
+ // Set the type.
13
+ this.type = config.type;
14
+
15
  // Save the current state.
16
+ this._saveState();
17
+
18
+ // Initialize the preview.
19
+ if ( config.layout ) {
20
+ FLBuilder._renderLayout( config.layout, function() {
21
+ this._init();
22
+ if ( config.callback ) {
23
+ config.callback();
24
+ }
25
+ }.bind( this ) );
26
+ } else {
 
27
  this._init();
28
  }
29
  };
30
 
31
  /**
32
+ * Stores all the fonts and weights of all font fields.
33
  * This is used to render the stylesheet with Google Fonts.
34
  *
35
  * @since 1.6.3
36
  * @access private
37
  * @property {Array} _fontsList
38
+ */
39
  FLBuilderPreview._fontsList = {};
40
 
41
  /**
43
  *
44
  * @since 1.3.3
45
  * @property {Object} prototype
46
+ */
47
  FLBuilderPreview.prototype = {
48
 
49
  /**
59
  *
60
  * @since 1.3.3
61
  * @property {String} nodeId
62
+ */
63
  nodeId : null,
64
 
65
  /**
68
  *
69
  * @since 1.3.3
70
  * @property {Object} classes
71
+ */
72
  classes : {},
73
+
74
  /**
75
  * An object with references to each element
76
  * in the preview.
77
  *
78
  * @since 1.3.3
79
  * @property {Object} elements
80
+ */
81
  elements : {},
82
+
83
  /**
84
  * An object that contains data for the current
85
  * state of a layout before changes are made.
86
  *
87
  * @since 1.3.3
88
  * @property {Object} state
89
+ */
90
  state : null,
91
+
92
  /**
93
  * Node settings saved when the preview was initalized.
94
  *
95
  * @since 1.7
96
  * @access private
97
  * @property {Object} _savedSettings
98
+ */
99
  _savedSettings : null,
100
+
101
  /**
102
  * An instance of FLStyleSheet for the current preview.
103
  *
104
  * @since 1.3.3
105
  * @access private
106
  * @property {FLStyleSheet} _styleSheet
107
+ */
108
  _styleSheet : null,
109
+
110
  /**
111
  * An instance of FLStyleSheet for the medium device preview.
112
  *
113
  * @since 1.9
114
  * @access private
115
  * @property {FLStyleSheet} _styleSheetMedium
116
+ */
117
  _styleSheetMedium : null,
118
+
119
  /**
120
  * An instance of FLStyleSheet for the responsive device preview.
121
  *
122
  * @since 1.9
123
  * @access private
124
  * @property {FLStyleSheet} _styleSheet
125
+ */
126
  _styleSheetResponsive : null,
127
+
128
  /**
129
  * A timeout object for delaying the current preview refresh.
130
  *
131
  * @since 1.3.3
132
  * @access private
133
  * @property {Object} _timeout
134
+ */
135
  _timeout : null,
136
+
137
  /**
138
+ * A timeout object for delaying when we show the loading
139
  * graphic for refresh previews.
140
  *
141
  * @since 1.10
142
  * @access private
143
  * @property {Object} _loaderTimeout
144
+ */
145
  _loaderTimeout : null,
146
+
147
  /**
148
  * Stores the last classname for a classname preview.
149
  *
150
  * @since 1.3.3
151
  * @access private
152
  * @property {String} _lastClassName
153
+ */
154
  _lastClassName : null,
155
+
156
  /**
157
  * A reference to the AJAX object for a preview refresh.
158
  *
159
  * @since 1.3.3
160
  * @access private
161
+ * @property {Object} _xhr
162
+ */
163
  _xhr : null,
164
 
165
  /**
173
  {
174
  // Node Id
175
  this.nodeId = $('.fl-builder-settings').data('node');
176
+
177
  // Save settings
178
  this._saveSettings();
179
+
180
  // Elements and Class Names
181
  this._initElementsAndClasses();
182
+
183
  // Create the preview stylesheets
184
  this._createSheets();
185
+
186
  // Responsive previews
187
  this._initResponsivePreviews();
188
+
189
  // Default field previews
190
  this._initDefaultFieldPreviews();
191
+
192
  // Init
193
  switch(this.type) {
194
+
195
  case 'row':
196
  this._initRow();
197
  break;
198
+
199
  case 'col':
200
  this._initColumn();
201
  break;
202
+
203
  case 'module':
204
  this._initModule();
205
  break;
217
  _saveSettings: function()
218
  {
219
  var form = $('.fl-builder-settings-lightbox .fl-builder-settings');
220
+
221
  this._savedSettings = FLBuilder._getSettings( form );
222
  },
223
 
233
  {
234
  var form = $('.fl-builder-settings-lightbox .fl-builder-settings'),
235
  settings = FLBuilder._getSettings( form );
236
+
237
  return JSON.stringify( this._savedSettings ) != JSON.stringify( settings );
238
  },
239
+
240
  /**
241
  * Initializes the classname and element references
242
  * for this preview.
248
  _initElementsAndClasses: function()
249
  {
250
  var contentClass;
251
+
252
  // Content Class
253
  if(this.type == 'row') {
254
  contentClass = '.fl-row-content-wrap';
256
  else {
257
  contentClass = '.fl-' + this.type + '-content';
258
  }
259
+
260
  // Class Names
261
  $.extend(this.classes, {
262
  settings : '.fl-builder-' + this.type + '-settings',
264
  node : FLBuilder._contentClass + ' .fl-node-' + this.nodeId,
265
  content : FLBuilder._contentClass + ' .fl-node-' + this.nodeId + ' > ' + contentClass
266
  });
267
+
268
  // Elements
269
  $.extend(this.elements, {
270
  settings : $(this.classes.settings),
273
  content : $(this.classes.content)
274
  });
275
  },
276
+
277
  /**
278
+ * Creates the stylesheets for default, medium
279
  * and responsive previews.
280
  *
281
  * @since 1.9
283
  */
284
  _createSheets: function()
285
  {
286
+ this._destroySheets();
287
+
288
  if ( ! this._styleSheet ) {
289
+ this._styleSheet = new FLStyleSheet( {
290
+ id : 'fl-builder-preview',
291
+ className : 'fl-builder-preview-style'
292
+ } );
293
  }
294
  if ( ! this._styleSheetMedium ) {
295
+ this._styleSheetMedium = new FLStyleSheet( {
296
+ id : 'fl-builder-preview-medium',
297
+ className : 'fl-builder-preview-style'
298
+ } );
299
  }
300
  if ( ! this._styleSheetResponsive ) {
301
+ this._styleSheetResponsive = new FLStyleSheet( {
302
+ id : 'fl-builder-preview-responsive',
303
+ className : 'fl-builder-preview-style'
304
+ } );
305
  }
306
  },
307
+
308
  /**
309
  * Destroys all preview sheets.
310
  *
314
  _destroySheets: function()
315
  {
316
  if ( this._styleSheet ) {
317
+ this._styleSheet.destroy();
318
  this._styleSheet = null;
319
  }
320
  if ( this._styleSheetMedium ) {
321
+ this._styleSheetMedium.destroy();
322
+ this._styleSheetMedium = null;
323
  }
324
  if ( this._styleSheetResponsive ) {
325
  this._styleSheetResponsive.destroy();
326
  this._styleSheetResponsive = null;
327
  }
328
  },
329
+
330
  /**
331
  * Updates a CSS rule for this preview.
332
  *
340
  {
341
  this._styleSheet.updateRule( selector, property, value );
342
  },
343
+
344
  /**
345
  * Runs a delay with a callback.
346
  *
354
  this._cancelDelay();
355
  this._timeout = setTimeout(callback, length);
356
  },
357
+
358
  /**
359
  * Cancels a preview refresh delay.
360
  *
368
  clearTimeout(this._timeout);
369
  }
370
  },
371
+
372
  /**
373
  * Converts a hex value to an array of RGB values.
374
  *
377
  * @param {String} hex
378
  * @return {Array}
379
  */
380
+ hexToRgb: function(hex)
381
  {
382
  var bigInt = parseInt(hex, 16),
383
  r = (bigInt >> 16) & 255,
384
  g = (bigInt >> 8) & 255,
385
  b = bigInt & 255;
386
+
387
  return [r, g, b];
388
  },
389
+
390
  /**
391
  * Parses a float or returns 0 if we don't have a number.
392
  *
395
  * @param {Number} value
396
  * @return {Number}
397
  */
398
+ parseFloat: function(value)
399
  {
400
  return isNaN(parseFloat(value)) ? 0 : parseFloat(value);
401
  },
402
+
403
  /* Responsive Previews
404
  ----------------------------------------------------------*/
405
+
406
  /**
407
  * Initializes logic for responsive previews.
408
  *
413
  {
414
  FLBuilder.addHook( 'responsive-editing-switched', $.proxy( this._responsiveEditingSwitched, this ) );
415
  },
416
+
417
  /**
418
  * Destroys responsive preview events.
419
  *
424
  {
425
  FLBuilder.removeHook( 'responsive-editing-switched' );
426
  },
427
+
428
  /**
429
  * Initializes logic for responsive previews.
430
  *
446
  this._styleSheetResponsive.enable();
447
  }
448
  },
449
+
450
  /**
451
  * Updates a CSS rule for responsive preview.
452
  *
460
  {
461
  var mode = FLBuilderResponsiveEditing._mode,
462
  sheetKey = 'default' == mode ? '' : mode.charAt(0).toUpperCase() + mode.slice(1);
463
+
464
  this[ '_styleSheet' + sheetKey ].updateRule( selector, property, value );
465
  },
466
+
467
  /* States
468
  ----------------------------------------------------------*/
469
+
470
  /**
471
  * Saves the current state of a layout.
472
  *
474
  * @access private
475
  * @method _saveState
476
  */
477
+ _saveState: function()
478
  {
479
  var post = FLBuilderConfig.postId,
480
  css = $('link[href*="/cache/' + post + '"]').attr('href'),
481
  js = $('script[src*="/cache/' + post + '"]').attr('src'),
482
  html = $(FLBuilder._contentClass).html();
483
+
484
  this.state = {
485
  css : css,
486
  js : js,
487
  html : html
488
  };
489
  },
490
+
491
  /**
492
  * Runs a preview refresh for the current settings lightbox.
493
  *
494
  * @since 1.3.3
495
  * @method preview
496
  */
497
+ preview: function()
498
  {
499
  var form = $('.fl-builder-settings-lightbox .fl-builder-settings'),
500
  nodeId = form.attr('data-node'),
501
  settings = FLBuilder._getSettings(form);
502
+
503
+ // Show the node as loading.
504
+ FLBuilder._showNodeLoading( nodeId );
505
+
506
+ // Abort an existing preview request.
507
  this._cancelPreview();
508
 
509
  // Make a new preview request.
513
  node_preview : settings
514
  }, $.proxy(this._renderPreview, this));
515
  },
516
+
517
  /**
518
  * Runs a preview refresh with a delay.
519
  *
527
  lightboxHeading = $('.fl-builder-settings .fl-lightbox-header'),
528
  loaderSrc = FLBuilderLayoutConfig.paths.pluginUrl + 'img/ajax-loader-small.svg',
529
  loader = $('<img class="fl-builder-preview-loader" src="' + loaderSrc + '" />');
530
+
531
  this.delay(1000, $.proxy(this.preview, this));
532
+
533
  this._loaderTimeout = setTimeout( function() {
534
+
535
  $('.fl-builder-preview-loader').remove();
536
+
537
  if(heading.length > 0) {
538
  heading.append(loader);
539
  }
543
  else if(lightboxHeading.length > 0) {
544
  lightboxHeading.append(loader);
545
  }
546
+
547
  }, 1500 );
548
  },
549
+
550
  /**
551
  * Cancels a preview refresh.
552
  *
554
  * @access private
555
  * @method _cancelPreview
556
  */
557
+ _cancelPreview: function()
558
  {
559
  if(this._xhr) {
560
  this._xhr.abort();
561
  this._xhr = null;
562
  }
563
  },
564
+
565
  /**
566
  * Renders the response of a preview refresh.
567
  *
570
  * @method _renderPreview
571
  * @param {String} response The JSON encoded response.
572
  */
573
+ _renderPreview: function(response)
574
  {
575
  this._xhr = null;
576
+
577
  FLBuilder._renderLayout(response, $.proxy(this._renderPreviewComplete, this));
578
  },
579
+
580
  /**
581
  * Fires when a preview refresh has finished rendering.
582
  *
584
  * @access private
585
  * @method _renderPreviewComplete
586
  */
587
+ _renderPreviewComplete: function()
588
  {
589
  // Refresh the preview styles.
 
590
  this._createSheets();
591
+
592
  // Refresh the elements.
593
  this._initElementsAndClasses();
594
+
595
  // Clear the loader timeout.
596
  if(this._loaderTimeout !== null) {
597
  clearTimeout(this._loaderTimeout);
598
  }
599
+
600
  // Remove the loading graphic.
601
  $('.fl-builder-preview-loader').remove();
602
+
603
+ // Fire the preview rendered event.
604
  $( FLBuilder._contentClass ).trigger( 'fl-builder.preview-rendered' );
605
  },
606
+
607
  /**
608
  * Reverts a preview to the state that was saved
609
  * before the preview was initialized.
611
  * @since 1.3.3
612
  * @method revert
613
  */
614
+ revert: function()
615
  {
616
+ if ( ! this._settingsHaveChanged() ) {
617
+ this.clear();
618
+ return;
619
+ }
620
+
621
+ FLBuilder._updateNode( this.nodeId, function() {
622
+ this.clear();
623
+ }.bind( this ) );
624
  },
625
+
626
  /**
627
+ * Cancels a preview refresh.
 
628
  *
629
  * @since 1.3.3
630
  * @method clear
631
  */
632
+ cancel: function()
633
  {
 
634
  this._cancelDelay();
635
  this._cancelPreview();
636
+ },
637
+
638
+ /**
639
+ * Cancels a preview refresh and removes
640
+ * any stylesheet changes.
641
+ *
642
+ * @since 1.3.3
643
+ * @method clear
644
+ */
645
+ clear: function()
646
+ {
647
+ // Canel any preview delays or requests.
648
+ this.cancel();
649
+
650
  // Destroy the preview stylesheet.
651
  this._destroySheets();
652
+
653
  // Destroy responsive editing previews.
654
  this._destroyResponsivePreviews();
655
  },
656
 
657
  /* Node Text Color Settings
658
  ----------------------------------------------------------*/
659
+
660
  /**
661
  * Initializes node text color previews.
662
  *
673
  hoverColor : $(this.classes.settings + ' input[name=hover_color]'),
674
  headingColor : $(this.classes.settings + ' input[name=heading_color]')
675
  });
676
+
677
  // Events
678
  this.elements.textColor.on('change', $.proxy(this._textColorChange, this));
679
  this.elements.linkColor.on('change', $.proxy(this._textColorChange, this));
680
  this.elements.hoverColor.on('change', $.proxy(this._textColorChange, this));
681
  this.elements.headingColor.on('change', $.proxy(this._textColorChange, this));
682
  },
683
+
684
  /**
685
  * Fires when the text color field for a node
686
  * is changed.
696
  linkColor = this.elements.linkColor.val(),
697
  hoverColor = this.elements.hoverColor.val(),
698
  headingColor = this.elements.headingColor.val();
699
+
700
  linkColor = linkColor === '' ? textColor : linkColor;
701
  hoverColor = hoverColor === '' ? textColor : hoverColor;
702
  headingColor = headingColor === '' ? textColor : headingColor;
703
+
704
  this.delay(100, $.proxy(function(){
705
+
706
  // Update Text color.
707
  if(textColor === '') {
708
  this.updateCSSRule(this.classes.node, 'color', 'inherit');
710
  else {
711
  this.updateCSSRule(this.classes.node, 'color', '#' + textColor);
712
  }
713
+
714
  // Update Link Color
715
  if ( linkColor === '' ) {
716
  this.updateCSSRule(this.classes.node + ' a', 'color', 'inherit');
718
  else {
719
  this.updateCSSRule(this.classes.node + ' a', 'color', '#' + linkColor);
720
  }
721
+
722
  // Hover Color
723
  if(hoverColor === '') {
724
  this.updateCSSRule(this.classes.node + ' a:hover', 'color', 'inherit');
726
  else {
727
  this.updateCSSRule(this.classes.node + ' a:hover', 'color', '#' + hoverColor);
728
  }
729
+
730
  // Heading Color
731
  if(headingColor === '') {
732
  this.updateCSSRule(this.classes.node + ' h1', 'color', 'inherit');
756
  this.updateCSSRule(this.classes.node + ' h5 a', 'color', '#' + headingColor);
757
  this.updateCSSRule(this.classes.node + ' h6 a', 'color', '#' + headingColor);
758
  }
759
+
760
  }, this));
761
  },
762
+
763
  /* Node Bg Settings
764
  ----------------------------------------------------------*/
765
+
766
  /**
767
  * Initializes node background previews.
768
  *
797
  bgOverlayColor : $(this.classes.settings + ' input[name=bg_overlay_color]'),
798
  bgOverlayOpacity : $(this.classes.settings + ' input[name=bg_overlay_opacity]')
799
  });
800
+
801
  // Events
802
  this.elements.bgType.on( 'change', $.proxy(this._bgTypeChange, this));
803
  this.elements.bgColor.on( 'change', $.proxy(this._bgColorChange, this));
818
  this.elements.bgOverlayColor.on( 'change', $.proxy(this._bgOverlayChange, this));
819
  this.elements.bgOverlayOpacity.on( 'keyup', $.proxy(this._bgOverlayChange, this));
820
  },
821
+
822
  /**
823
+ * Fires when the background type field of
824
  * a node changes.
825
  *
826
  * @since 1.3.3
831
  _bgTypeChange: function(e)
832
  {
833
  var val = this.elements.bgType.val();
834
+
835
  // Clear bg styles first.
836
  this.elements.node.removeClass('fl-row-bg-video');
837
  this.elements.node.removeClass('fl-row-bg-slideshow');
839
  this.elements.node.find('.fl-bg-video').remove();
840
  this.elements.node.find('.fl-bg-slideshow').remove();
841
  this.elements.content.css('background-image', '');
842
+
843
  this.updateCSSRule(this.classes.content, {
844
  'background-color' : 'transparent',
845
  'background-image' : 'none'
846
  });
847
+
848
  // None
849
  if(val == 'none') {
850
  this._bgOverlayClear();
855
  this.elements.bgColor.trigger('change');
856
  this._bgOverlayClear();
857
  }
858
+
859
  // Photo
860
  else if(val == 'photo') {
861
  this.elements.bgColor.trigger('change');
862
  this.elements.bgImageSrc.trigger('change');
863
  }
864
+
865
  // Video
866
  else if(val == 'video') {
867
  this.elements.bgColor.trigger('change');
868
+ this._bgVideoChange();
869
  }
870
+
871
  // Slideshow
872
  else if(val == 'slideshow') {
873
  this.elements.bgColor.trigger('change');
874
  this._bgSlideshowChange();
875
  }
876
+
877
  // Parallax
878
  else if(val == 'parallax') {
879
  this.elements.bgColor.trigger('change');
880
  this.elements.bgParallaxImageSrc.trigger('change');
881
  }
882
  },
883
+
884
  /**
885
+ * Fires when the background color field of
886
  * a node changes.
887
  *
888
  * @since 1.3.3
893
  _bgColorChange: function(e)
894
  {
895
  var rgb, alpha, value;
896
+
897
  if(this.elements.bgColor.val() === '' || isNaN(this.elements.bgOpacity.val())) {
898
+ this.updateCSSRule(this.classes.content, 'background-color', 'transparent');
899
  }
900
  else {
901
+
902
  rgb = this.hexToRgb( this.elements.bgColor.val() );
903
  alpha = this.parseFloat(this.elements.bgOpacity.val())/100;
904
  value = 'rgba(' + rgb.join() + ', ' + alpha + ')';
905
+
906
  this.delay(100, $.proxy(function(){
907
  this.updateCSSRule(this.classes.content, 'background-color', value);
908
+ }, this));
909
  }
910
  },
911
+
912
  /**
913
+ * Fires when the background opacity field of
914
  * a node changes.
915
  *
916
  * @since 1.3.3
922
  {
923
  this.elements.bgColor.trigger('change');
924
  },
925
+
926
  /**
927
+ * Fires when the background photo field of
928
  * a node changes.
929
  *
930
  * @since 1.3.3
952
  },
953
 
954
  /**
955
+ * Fires when the background video field of
956
  * a node changes.
957
  *
958
  * @since 1.9.2
976
  && $( 'script[src*="youtube.com"' ).length < 1) {
977
  scriptTag.attr('src', youtubePlayer);
978
  }
979
+ else if(/^(http\:\/\/|https\:\/\/)?(www\.)?(vimeo\.com\/)([0-9]+)$/.test(videoUrl)
980
  && $( 'script[src*="vimeo.com"' ).length < 1) {
981
  scriptTag.attr('src', vimeoPlayer);
982
  }
983
+
984
  scriptTag
985
  .attr('type', 'text/javascript')
986
  .appendTo('head');
991
  this.preview();
992
  }
993
  },
994
+
995
  /**
996
+ * Fires when the background slideshow field of
997
  * a node changes.
998
  *
999
  * @since 1.3.3
1009
  feed = eles.bgSlideshowFeedUrl.val(),
1010
  speed = eles.bgSlideshowSpeed.val(),
1011
  transSpeed = eles.bgSlideshowTransSpeed.val();
1012
+
1013
  if(source == 'wordpress' && photos === '') {
1014
  return;
1015
  }
1022
  else if(isNaN(parseInt(transSpeed))) {
1023
  return;
1024
  }
1025
+
1026
  this.delay(500, $.proxy(this.preview, this));
1027
  },
1028
+
1029
  /**
1030
+ * Fires when the background parallax field of
1031
  * a node changes.
1032
  *
1033
  * @since 1.3.3
1038
  _bgParallaxChange: function(e)
1039
  {
1040
  if(this.elements.bgParallaxImageSrc.val()) {
1041
+
1042
  this.updateCSSRule(this.classes.content, {
1043
  'background-image' : 'url(' + this.elements.bgParallaxImageSrc.val() + ')',
1044
  'background-repeat' : 'no-repeat',
1048
  });
1049
  }
1050
  },
1051
+
1052
  /**
1053
+ * Fires when the background overlay field of
1054
  * a node changes.
1055
  *
1056
  * @since 1.3.3
1061
  _bgOverlayChange: function(e)
1062
  {
1063
  var rgb, alpha, value;
1064
+
1065
  if(this.elements.bgOverlayColor.val() === '' || isNaN(this.elements.bgOverlayOpacity.val())) {
1066
  this.elements.node.removeClass('fl-row-bg-overlay');
1067
  this.elements.node.removeClass('fl-col-bg-overlay');
1068
+ this.updateCSSRule(this.classes.content + ':after', 'background-color', 'transparent');
1069
  }
1070
  else {
1071
+
1072
  rgb = this.hexToRgb(this.elements.bgOverlayColor.val());
1073
  alpha = this.parseFloat(this.elements.bgOverlayOpacity.val())/100;
1074
  value = 'rgba(' + rgb.join() + ', ' + alpha + ')';
1075
+
1076
  this.delay(100, $.proxy(function(){
1077
+
1078
  if ( this.elements.node.hasClass( 'fl-col' ) ) {
1079
  this.elements.node.addClass( 'fl-col-bg-overlay' );
1080
  }
1081
  else {
1082
  this.elements.node.addClass( 'fl-row-bg-overlay' );
1083
  }
1084
+
1085
  this.updateCSSRule( this.classes.content + ':after', 'background-color', value );
1086
+
1087
  }, this));
1088
+
1089
  }
1090
  },
1091
+
1092
  /**
1093
  * Fires when a background overlay color is cleared.
1094
  *
1104
 
1105
  /* Node Border Settings
1106
  ----------------------------------------------------------*/
1107
+
1108
  /**
1109
  * Initializes node border previews.
1110
  *
1121
  borderColorPicker : $(this.classes.settings + ' .fl-picker-border_color'),
1122
  borderOpacity : $(this.classes.settings + ' input[name=border_opacity]')
1123
  });
1124
+
1125
  // Events
1126
  this.elements.borderType.on( 'change', $.proxy(this._borderTypeChange, this));
1127
  this.elements.borderColor.on( 'change', $.proxy(this._borderColorChange, this));
1128
  this.elements.borderOpacity.on( 'keyup', $.proxy(this._borderOpacityChange, this));
1129
  },
1130
+
1131
  /**
1132
+ * Fires when the border type field of
1133
  * a node changes.
1134
  *
1135
  * @since 1.3.3
1140
  _borderTypeChange: function(e)
1141
  {
1142
  var val = this.elements.borderType.val();
1143
+
1144
  this.updateCSSRule(this.classes.content, {
1145
  'border-style' : val === '' ? 'none' : val
1146
  });
1147
+
1148
  this.elements.borderColor.trigger('change');
1149
  this.elements.borderTop.trigger('keyup');
1150
  },
1151
+
1152
  /**
1153
+ * Fires when the border color field of
1154
  * a node changes.
1155
  *
1156
  * @since 1.3.3
1161
  _borderColorChange: function(e)
1162
  {
1163
  var rgb, alpha, value;
1164
+
1165
  if(this.elements.borderColor.val() === '' || isNaN(this.elements.borderOpacity.val())) {
1166
+ this.updateCSSRule(this.classes.content, 'border-color', 'transparent');
1167
  }
1168
  else {
1169
+
1170
  rgb = this.hexToRgb(this.elements.borderColor.val());
1171
  alpha = parseInt(this.elements.borderOpacity.val())/100;
1172
  value = 'rgba(' + rgb.join() + ', ' + alpha + ')';
1173
+
1174
  this.delay(100, $.proxy(function(){
1175
  this.updateCSSRule(this.classes.content, 'border-color', value);
1176
+ }, this));
1177
  }
1178
  },
1179
+
1180
  /**
1181
+ * Fires when the border opacity field of
1182
  * a node changes.
1183
  *
1184
  * @since 1.3.3
1190
  {
1191
  this.elements.borderColor.trigger('change');
1192
  },
1193
+
1194
  /* Node Class Name Settings
1195
  ----------------------------------------------------------*/
1196
+
1197
  /**
1198
  * Initializes node classname previews.
1199
  *
1207
  $.extend(this.elements, {
1208
  className : $(this.classes.settings + ' input[name=class]')
1209
  });
1210
+
1211
  // Events
1212
  this.elements.className.on('keyup', $.proxy(this._classNameChange, this));
1213
  this._lastClassName = this.elements.className.val();
1214
  },
1215
+
1216
  /**
1217
  * Fires when the classname of a node changes.
1218
  *
1224
  _classNameChange: function(e)
1225
  {
1226
  var className = this.elements.className.val();
1227
+
1228
  if(this._lastClassName !== null) {
1229
  this.elements.node.removeClass(this._lastClassName);
1230
  }
1231
+
1232
  this.elements.node.addClass(className);
1233
  this._lastClassName = className;
1234
  },
1235
+
1236
  /* Node Margin Settings
1237
  ----------------------------------------------------------*/
1238
+
1239
  /**
1240
  * Initializes node responsive dimension previews for things
1241
  * like margins, padding and borders.
1254
  inputName = '',
1255
  i = null,
1256
  k = null;
1257
+
1258
  for ( i = 0; i < dimensions.length; i++ ) {
1259
+
1260
  for ( k = 0; k < devices.length; k++ ) {
1261
+
1262
  elementKey = property + dimensions[ i ] + devices[ k ];
1263
  inputName = property + '_' + dimensions[ i ].toLowerCase();
1264
+
1265
  if ( '' != devices[ k ] ) {
1266
  inputName += '_' + devices[ k ].toLowerCase();
1267
  }
1268
+
1269
  elements[ elementKey ] = $( settingsClass + ' input[name=' + inputName + ']');
1270
  elements[ elementKey ].on( 'keyup', $.proxy( this._responsiveDimensionChange, this, property ) );
1271
  }
1272
  }
1273
+
1274
  $.extend( this.elements, elements );
1275
  },
1276
+
1277
  /**
1278
  * Get all dimensions from a node preview event.
1279
  *
1290
  device = 'default' == mode ? '' : mode.charAt(0).toUpperCase() + mode.slice(1),
1291
  values = {},
1292
  i = 0;
1293
+
1294
  for ( ; i < dimensions.length; i++ ) {
1295
  values[ dimensions[ i ].toLowerCase() ] = this.elements[ property + dimensions[ i ] + device ].val();
1296
  }
1297
 
1298
  return this._normalizeDimensionValues( values, property );
1299
  },
1300
+
1301
  /**
1302
  * Fires when a dimension field of a node changes.
1303
  *
1319
  this.updateResponsiveCSSRule( this.classes.content, newRules );
1320
  this._positionAbsoluteBgs();
1321
  },
1322
+
1323
  /**
1324
  * Normalize CSS dimension values.
1325
  *
1369
 
1370
  return values;
1371
  },
1372
+
1373
  /* Absolutely Positioned Backgrounds
1374
  ----------------------------------------------------------*/
1375
+
1376
  /**
1377
  * Positions the backgrounds of a node that need absolute
1378
  * positioning such as videos and slideshows.
1419
  }
1420
  }
1421
  },
1422
+
1423
  /* Row Settings
1424
  ----------------------------------------------------------*/
1425
+
1426
  /**
1427
  * Initializes a row preview.
1428
  *
1434
  {
1435
  // Elements
1436
  $.extend(this.elements, {
1437
+ width : $(this.classes.settings + ' select[name=width]'),
1438
+ contentWidth : $(this.classes.settings + ' select[name=content_width]'),
1439
+ maxContentWidth : $(this.classes.settings + ' input[name=max_content_width]'),
1440
+ height : $(this.classes.settings + ' select[name=full_height]'),
1441
+ align : $(this.classes.settings + ' select[name=content_alignment]')
1442
  });
1443
+
1444
  // Events
1445
+ this.elements.width.on( 'change', $.proxy(this._rowWidthChange, this));
1446
+ this.elements.contentWidth.on( 'change', $.proxy(this._rowContentWidthChange, this));
1447
+ this.elements.maxContentWidth.on( 'keyup', $.proxy(this._rowMaxContentWidthChange, this));
1448
+ this.elements.height.on( 'change', $.proxy(this._rowHeightChange, this));
1449
+ this.elements.align.on( 'change', $.proxy(this._rowHeightChange, this));
1450
+
1451
  // Common Elements
1452
  this._initNodeTextColor();
1453
  this._initNodeBg();
1457
  this._initResponsiveDimensions( 'margin' );
1458
  this._initResponsiveDimensions( 'padding' );
1459
  },
1460
+
1461
  /**
1462
  * Fires when the width field of a row changes.
1463
  *
1468
  */
1469
  _rowWidthChange: function(e)
1470
  {
1471
+ var row = this.elements.node,
1472
+ maxWidth = this.elements.maxContentWidth.val();
1473
+
1474
  if(this.elements.width.val() == 'full') {
1475
+ row.css( 'max-width', 'none' );
1476
  row.removeClass('fl-row-fixed-width');
1477
  row.addClass('fl-row-full-width');
1478
  }
1479
  else {
1480
  row.removeClass('fl-row-full-width');
1481
  row.addClass('fl-row-fixed-width');
1482
+
1483
+ if ( '' !== maxWidth ) {
1484
+ row.css( 'max-width', maxWidth + 'px' );
1485
+ } else {
1486
+ row.css( 'max-width', FLBuilderConfig.global.row_width + 'px' );
1487
+ }
1488
  }
1489
  },
1490
 
1499
  _rowHeightChange: function(e)
1500
  {
1501
  var row = this.elements.node;
1502
+
1503
  row.removeClass('fl-row-align-top');
1504
  row.removeClass('fl-row-align-center');
1505
  row.removeClass('fl-row-align-bottom');
1506
+
1507
  if(this.elements.height.val() == 'full') {
1508
  row.addClass('fl-row-full-height');
1509
  row.addClass('fl-row-align-' + this.elements.align.val());
1512
  row.removeClass('fl-row-full-height');
1513
  }
1514
  },
1515
+
1516
  /**
1517
  * Fires when the content width field of a row changes.
1518
  *
1523
  */
1524
  _rowContentWidthChange: function(e)
1525
  {
1526
+ var content = this.elements.content.find('.fl-row-content'),
1527
+ maxWidth = this.elements.maxContentWidth.val();
1528
+
1529
  if(this.elements.contentWidth.val() == 'full') {
1530
+ content.css( 'max-width', 'none' );
1531
  content.removeClass('fl-row-fixed-width');
1532
  content.addClass('fl-row-full-width');
1533
  }
1534
  else {
1535
  content.removeClass('fl-row-full-width');
1536
  content.addClass('fl-row-fixed-width');
1537
+
1538
+ if ( '' !== maxWidth ) {
1539
+ content.css( 'max-width', maxWidth + 'px' );
1540
+ } else {
1541
+ content.css( 'max-width', FLBuilderConfig.global.row_width + 'px' );
1542
+ }
1543
+ }
1544
+ },
1545
+
1546
+ /**
1547
+ * Fires when the content width field of a row changes.
1548
+ *
1549
+ * @since 1.3.3
1550
+ * @access private
1551
+ * @method _rowContentWidthChange
1552
+ * @param {Object} e An event object.
1553
+ */
1554
+ _rowMaxContentWidthChange: function(e)
1555
+ {
1556
+ var row = this.elements.node,
1557
+ content = this.elements.content.find('.fl-row-content'),
1558
+ width = this.elements.maxContentWidth.val();
1559
+
1560
+ if ( '' == width ) {
1561
+ width = FLBuilderConfig.global.row_width + 'px';
1562
+ } else {
1563
+ width += 'px';
1564
+ }
1565
+
1566
+ if ( 'fixed' == this.elements.width.val() ) {
1567
+ row.css( 'max-width', width );
1568
+ }
1569
+ if ( 'fixed' == this.elements.contentWidth.val() ) {
1570
+ content.css( 'max-width', width );
1571
  }
1572
  },
1573
+
1574
  /* Columns Settings
1575
  ----------------------------------------------------------*/
1576
+
1577
  /**
1578
  * Initializes a column preview.
1579
  *
1590
  columnAlign : $(this.classes.settings + ' select[name=content_alignment]'),
1591
  responsiveOrder : $(this.classes.settings + ' select[name=responsive_order]')
1592
  });
1593
+
1594
  // Events
1595
  this.elements.size.on( 'keyup', $.proxy( this._colSizeChange, this ) );
1596
  this.elements.columnHeight.on( 'change', $.proxy( this._colHeightChange, this ) );
1597
  this.elements.columnAlign.on( 'change', $.proxy( this._colHeightChange, this ) );
1598
  this.elements.responsiveOrder.on( 'change', $.proxy( this._colResponsiveOrder, this ) );
1599
+
1600
  // Common Elements
1601
  this._initNodeTextColor();
1602
  this._initNodeBg();
1606
  this._initResponsiveDimensions( 'margin' );
1607
  this._initResponsiveDimensions( 'padding' );
1608
  },
1609
+
1610
  /**
1611
  * Fires when the size field of a column changes.
1612
  *
1625
  sibling = next.length === 0 ? prev : next,
1626
  siblings = this.elements.node.siblings('.fl-col'),
1627
  siblingsWidth = 0;
1628
+
1629
  // Don't resize if we onlt have one column or no size.
1630
  if(siblings.length === 0 || isNaN(size)) {
1631
  return;
1632
  }
1633
+
1634
  // Adjust sizes based on other columns.
1635
  siblings.each(function() {
1636
+
1637
  if($(this).data('node') == sibling.data('node')) {
1638
  return;
1639
  }
1640
+
1641
  maxWidth -= parseFloat($(this)[0].style.width);
1642
  siblingsWidth += parseFloat($(this)[0].style.width);
1643
  });
1644
+
1645
  // Make sure the new width isn't too small.
1646
  if(size < minWidth) {
1647
  size = minWidth;
1648
  }
1649
+
1650
  // Make sure the new width isn't too big.
1651
  if(size > maxWidth) {
1652
  size = maxWidth;
1653
  }
1654
+
1655
  // Update the widths.
1656
  sibling.css('width', (100 - siblingsWidth - size) + '%');
1657
  this.elements.node.css('width', size + '%');
1667
  _colHeightChange: function()
1668
  {
1669
  var parent = this.elements.node.parent('.fl-col-group');
1670
+
1671
  parent.removeClass('fl-col-group-align-top');
1672
  parent.removeClass('fl-col-group-align-center');
1673
  parent.removeClass('fl-col-group-align-bottom');
1674
+
1675
  if(this.elements.columnHeight.val() == 'yes') {
1676
  parent.addClass('fl-col-group-equal-height');
1677
  parent.addClass('fl-col-group-align-' + this.elements.columnAlign.val());
1692
  {
1693
 
1694
  var parent = this.elements.node.parent('.fl-col-group');
1695
+
1696
  if(this.elements.responsiveOrder.val() == 'reversed') {
1697
  parent.addClass('fl-col-group-responsive-reversed');
1698
  }
1700
  parent.removeClass('fl-col-group-responsive-reversed');
1701
  }
1702
  },
1703
+
1704
  /* Module Settings
1705
  ----------------------------------------------------------*/
1706
+
1707
  /**
1708
  * Initializes a module preview.
1709
  *
1716
  this._initNodeClassName();
1717
  this._initResponsiveDimensions( 'margin' );
1718
  },
1719
+
1720
  /* Default Field Previews
1721
  ----------------------------------------------------------*/
1722
+
1723
  /**
1724
  * Initializes the default preview logic for each
1725
  * field in a settings form.
1727
  * @since 1.3.3
1728
  * @access private
1729
  * @method _initDefaultFieldPreviews
1730
+ * @param {Object} fields
1731
  */
1732
+ _initDefaultFieldPreviews: function( fields )
1733
  {
1734
+ var fields = ! _.isUndefined( fields ) ? fields : this.elements.settings.find('.fl-field'),
1735
  field = null,
1736
  fieldType = null,
1737
  preview = null,
1738
  i = 0;
1739
+
1740
  for( ; i < fields.length; i++) {
1741
+
1742
  field = fields.eq(i);
1743
  preview = field.data('preview');
1744
+
1745
  if(preview.type == 'refresh') {
1746
  this._initFieldRefreshPreview(field);
1747
  }
1759
  }
1760
  }
1761
  },
1762
+
1763
  /**
1764
  * Initializes the refresh preview for a field.
1765
  *
1773
  var fieldType = field.data('type'),
1774
  preview = field.data('preview'),
1775
  callback = $.proxy(this.delayPreview, this);
1776
+
1777
  switch(fieldType) {
1778
+
1779
  case 'text':
1780
  field.find('input[type=text]').on('keyup', callback);
1781
  break;
1782
+
1783
  case 'textarea':
1784
  field.find('textarea').on('keyup', callback);
1785
  break;
1786
+
1787
  case 'select':
1788
  field.find('select').on('change', callback);
1789
  break;
1790
+
1791
  case 'color':
1792
  field.find('.fl-color-picker-value').on('change', callback);
1793
  break;
1794
+
1795
  case 'photo':
1796
  field.find('select').on('change', callback);
1797
  break;
1798
+
1799
  case 'multiple-photos':
1800
  field.find('input').on('change', callback);
1801
  break;
1802
+
1803
  case 'photo-sizes':
1804
  field.find('select').on('change', callback);
1805
  break;
1806
+
1807
  case 'video':
1808
  field.find('input').on('change', callback);
1809
  break;
1810
+
1811
  case 'multiple-audios':
1812
  field.find('input').on('change', callback);
1813
  break;
1815
  case 'icon':
1816
  field.find('input').on('change', callback);
1817
  break;
1818
+
1819
  case 'form':
1820
  field.delegate('input', 'change', callback);
1821
  break;
1822
+
1823
  case 'editor':
1824
  this._addTextEditorCallback(field, preview);
1825
  break;
1826
+
1827
  case 'code':
1828
  field.find('textarea').on('change', callback);
1829
  break;
1830
+
1831
  case 'post-type':
1832
  field.find('select').on('change', callback);
1833
  break;
1834
+
1835
  case 'suggest':
1836
  field.find('.as-values').on('change', callback);
1837
  field.find('select').on('change', callback);
1838
  break;
1839
+
1840
  case 'unit':
1841
  field.find('input[type=number]').on('keyup', callback);
1842
  break;
1843
+
1844
  case 'ordering':
1845
  field.find('input[type=hidden]').on('change', callback);
1846
  break;
1847
 
1848
  }
1849
  },
1850
+
1851
  /**
1852
  * Initializes a text preview for a field.
1853
  *
1861
  var fieldType = field.data('type'),
1862
  preview = field.data('preview'),
1863
  callback = $.proxy(this._previewText, this, preview);
1864
+
1865
  switch(fieldType) {
1866
+
1867
  case 'text':
1868
  field.find('input[type=text]').on('keyup', callback);
1869
  break;
1870
+
1871
  case 'unit':
1872
  field.find('input[type=number]').on('keyup', callback);
1873
  break;
1874
+
1875
  case 'textarea':
1876
  field.find('textarea').on('keyup', callback);
1877
  break;
1878
+
1879
  case 'code':
1880
  field.find('textarea').on('change', callback);
1881
  break;
1882
+
1883
  case 'editor':
1884
  this._addTextEditorCallback(field, preview);
1885
  break;
1899
  {
1900
  var element = this.elements.node.find(preview.selector),
1901
  text = $('<div>' + $(e.target).val() + '</div>');
1902
+
1903
  if(element.length > 0) {
1904
  text.find('script').remove();
1905
  element.html(text.html());
1906
  }
1907
  },
1908
+
1909
  /**
1910
  * Runs a real time preview for text editor fields.
1911
  *
1924
  text = '';
1925
 
1926
  if(element.length > 0) {
1927
+
1928
  if(editor && textarea.css('display') == 'none') {
1929
  text = $('<div>' + editor.getContent() + '</div>');
1930
+ }
1931
  else {
1932
  if ( 'undefined' == typeof switchEditors || 'undefined' == typeof switchEditors.wpautop ) {
1933
  text = $('<div>' + textarea.val() + '</div>');
1936
  text = $('<div>' + switchEditors.wpautop( textarea.val() ) + '</div>');
1937
  }
1938
  }
1939
+
1940
  text.find('script').remove();
1941
  element.html(text.html());
1942
  }
1943
  },
1944
+
1945
  /**
1946
  * Callback for text editor previews.
1947
  *
1955
  {
1956
  var id = field.find('textarea.wp-editor-area').attr('id'),
1957
  callback = null;
1958
+
1959
  if(preview.type == 'refresh') {
1960
  callback = $.proxy(this.delayPreview, this);
1961
  }
1965
  else {
1966
  return;
1967
  }
1968
+
1969
  $('#' + id).on('keyup', callback);
1970
+
1971
  if(typeof tinyMCE != 'undefined') {
1972
  editor = tinyMCE.get(id);
1973
  editor.on('change', callback);
1992
  preview.id = field.attr( 'id' );
1993
 
1994
  var callback = $.proxy(this._previewFont, this, preview);
1995
+
1996
  if( fieldType == 'font' ){
1997
  field.find('.fl-font-field').on('change', 'select', callback);
1998
  }
2032
  } else {
2033
  // Updated CSS rules
2034
  this.updateCSSRule( selector, 'font-family', font.val() );
2035
+ this.updateCSSRule( selector, 'font-weight', weight.val() );
2036
  }
2037
 
2038
  },
2039
 
2040
  /**
2041
+ * Gets all fonts store insite FLBuilderPreview._fontsList and renders the respective
2042
  * link tag with Google Fonts.
2043
  *
2044
  * @since 1.6.3
2061
  // adds to the list of fonts for this font setting
2062
  FLBuilderPreview._fontsList[ id ] = fontObj;
2063
 
2064
+ // iterate over the keys of the FLBuilderPreview._fontsList object
2065
  Object.keys( FLBuilderPreview._fontsList ).forEach( function( fieldFont ) {
2066
+
2067
  var field = FLBuilderPreview._fontsList[ fieldFont ];
2068
 
2069
  // iterate over the font / weight object
2078
  return fontArray[ key ].indexOf( weight ) < 0;
2079
  });
2080
 
2081
+ fontArray[ key ] = fontArray[ key ].concat( weights );
2082
+
2083
  });
2084
 
2085
  });
2097
  .attr( 'type', 'text/css' )
2098
  .attr( 'rel', 'stylesheet' )
2099
  .attr( 'href', href )
2100
+ .appendTo('head');
2101
  } else{
2102
  $( '#fl-builder-google-fonts-preview' ).attr( 'href', href );
2103
  }
2104
 
2105
  },
2106
+
2107
  /**
2108
  * Initializes CSS previews for a node.
2109
  *
2117
  {
2118
  var preview = field.data( 'preview' ),
2119
  i = null;
2120
+
2121
  if ( 'undefined' != typeof preview.rules ) {
2122
  for ( i in preview.rules ) {
2123
  this._initFieldCSSPreviewCallback( field, preview.rules[ i ] );
2127
  this._initFieldCSSPreviewCallback( field, preview );
2128
  }
2129
  },
2130
+
2131
  /**
2132
  * Initializes CSS preview callbacks for a field.
2133
  *
2140
  _initFieldCSSPreviewCallback: function( field, preview )
2141
  {
2142
  switch( field.data( 'type' ) ) {
2143
+
2144
  case 'text':
2145
  field.find( 'input[type=text]' ).on( 'keyup', $.proxy( this._previewCSS, this, preview ) );
2146
  break;
2147
+
2148
  case 'unit':
2149
  field.find( 'input[type=number]' ).on( 'keyup', $.proxy( this._previewCSS, this, preview ) );
2150
  break;
2151
+
2152
  case 'select':
2153
  field.find( 'select' ).on( 'change', $.proxy( this._previewCSS, this, preview ) );
2154
  break;
2155
+
2156
  case 'color':
2157
  field.find( '.fl-color-picker-value' ).on( 'change', $.proxy( this._previewColor, this, preview ) );
2158
  break;
2159
  }
2160
  },
2161
+
2162
  /**
2163
  * Updates the CSS rule for a preview.
2164
  *
2175
  unit = typeof preview.unit == 'undefined' ? '' : preview.unit,
2176
  input = $(e.target),
2177
  value = input.val();
2178
+
2179
  if(unit == '%') {
2180
  value = parseInt(value)/100;
2181
  }
2182
  else if ( '' !== value ) {
2183
  value += unit;
2184
  }
2185
+
2186
  if ( input.closest( '.fl-field-responsive-setting' ).length ) {
2187
  this.updateResponsiveCSSRule( selector, property, value );
2188
  }
2190
  this.updateCSSRule( selector, property, value );
2191
  }
2192
  },
2193
+
2194
  /**
2195
  * Updates the CSS rule for a color preview.
2196
  *
2206
  input = $(e.target),
2207
  val = input.val(),
2208
  color = val === '' ? 'inherit' : '#' + val;
2209
+
2210
  if ( /^rgb/.test( val.replace(/\s+/g, '') ) ) {
2211
  color = val;
2212
  }
2218
  this.updateCSSRule( selector, preview.property, color );
2219
  }
2220
  },
2221
+
2222
  /**
2223
  * Initializes the preview for a WordPress widget.
2224
  *
2230
  _initFieldWidgetPreview: function(field)
2231
  {
2232
  var callback = $.proxy(this.delayPreview, this);
2233
+
2234
  field.find('input').on('keyup', callback);
2235
  field.find('input[type=checkbox]').on('click', callback);
2236
  field.find('textarea').on('keyup', callback);
2237
  field.find('select').on('change', callback);
2238
  },
2239
+
2240
  /**
2241
  * Returns a formatted selector string for a preview.
2242
  *
2251
  var formatted = '',
2252
  parts = selector.split( ',' ),
2253
  i = 0;
2254
+
2255
  for ( ; i < parts.length; i++ ) {
2256
+
2257
+ if ( parts[ i ].indexOf( '{node}' ) > -1 ) {
2258
+ formatted = parts[ i ].replace( '{node}', prefix );
2259
+ }
2260
+ else {
2261
+ formatted += prefix + ' ' + parts[ i ];
2262
+ }
2263
+
2264
  if ( i != parts.length - 1 ) {
2265
  formatted += ', ';
2266
  }
2267
  }
2268
+
2269
  return formatted;
2270
  }
2271
  };
js/fl-builder-responsive-editing.js CHANGED
@@ -13,7 +13,7 @@
13
  *
14
  * @since 1.9
15
  * @private
16
- * @property {FLBuilderPreview} _mode
17
  */
18
  _mode: 'default',
19
 
@@ -324,17 +324,12 @@
324
 
325
  if ( Number( FLBuilderConfig.global.responsive_enabled ) ) {
326
 
327
- self._initFields( 'unit', 'input', 'keyup', self._spacingFieldKeyup, [
328
- 'margin_top',
329
- 'margin_bottom',
330
- 'margin_left',
331
- 'margin_right',
332
- 'padding_top',
333
- 'padding_bottom',
334
- 'padding_left',
335
- 'padding_right'
336
  ] );
337
 
 
338
  self._initFields( 'unit', 'input', 'keyup', self._textFieldKeyup );
339
  }
340
 
@@ -415,26 +410,30 @@
415
  */
416
  _textFieldKeyup: function()
417
  {
418
- var fields = FLBuilderResponsiveEditing._getFields( this, 'input' ),
419
- defaultPlaceholder = fields.default.attr( 'placeholder' ),
420
- defaultValue = fields.default.val(),
421
- mediumValue = fields.medium.val();
422
-
423
- // Medium placeholder
424
- if ( '' == defaultValue ) {
425
- fields.medium.attr( 'placeholder', ( undefined === defaultPlaceholder ? '' : defaultPlaceholder ) );
426
- }
427
- else {
428
- fields.medium.attr( 'placeholder', defaultValue );
429
- }
430
 
431
- // Responsive placeholder
432
- if ( '' == mediumValue ) {
433
- fields.responsive.attr( 'placeholder', fields.medium.attr( 'placeholder' ) );
434
- }
435
- else {
436
- fields.responsive.attr( 'placeholder', mediumValue );
437
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
  },
439
 
440
  /**
@@ -448,20 +447,13 @@
448
  {
449
  var form = $( '.fl-builder-settings' ),
450
  type = 'row',
451
- parts = $( this ).closest( '.fl-field' ).attr( 'id' ).replace( 'fl-field-', '' ).split( '_' ),
452
- field = parts[0],
453
- dimension = parts[1],
454
  fields = FLBuilderResponsiveEditing._getFields( this, 'input' ),
455
  config = FLBuilderConfig.global,
456
  configPrefix = null,
457
- defaultVal = fields.default.val(),
458
  defaultGlobalVal = null,
459
- mediumVal = fields.medium.val(),
460
  mediumGlobalVal = null,
461
- responsiveVal = fields.responsive.val(),
462
- responsiveGlobalVal = null,
463
- moduleGlobalVal = null,
464
- moduleResponsiveVal = null;
465
 
466
  // Get the node type
467
  if ( form.hasClass( 'fl-builder-row-settings' ) ) {
@@ -474,7 +466,7 @@
474
  type = 'module';
475
  }
476
 
477
- // Spoof global column defaults.
478
  $.extend( config, {
479
  col_margins : 0,
480
  col_margins_medium : '',
@@ -485,56 +477,67 @@
485
  } );
486
 
487
  // Set the global values
488
- configPrefix = type + '_' + field + ( 'margin' == field ? 's' : '' );
489
  defaultGlobalVal = config[ configPrefix ];
490
  mediumGlobalVal = config[ configPrefix + '_medium' ];
491
  responsiveGlobalVal = config[ configPrefix + '_responsive' ];
492
 
493
- // Medium value
494
- if ( '' == mediumGlobalVal ) {
495
-
496
- if ( '' != defaultVal ) {
497
- fields.medium.attr( 'placeholder', defaultVal );
498
- }
499
- else if ( '' != defaultGlobalVal ) {
500
- fields.medium.attr( 'placeholder', defaultGlobalVal );
501
- }
502
- }
503
-
504
- // Responsive value
505
- if ( '' == responsiveGlobalVal ) {
506
 
507
- if ( 'module' == type && Number( config.auto_spacing ) ) {
 
 
 
 
 
508
 
509
- moduleGlobalVal = '' == mediumGlobalVal ? Number( defaultGlobalVal ) : mediumGlobalVal;
510
- moduleResponsiveVal = '' == mediumVal ? Number( defaultVal ) : mediumVal;
511
 
512
- if ( '' != moduleResponsiveVal && ( moduleResponsiveVal > moduleGlobalVal || moduleResponsiveVal < 0 ) ) {
513
- fields.responsive.attr( 'placeholder', moduleGlobalVal );
514
  }
515
- else if ( '' != moduleResponsiveVal ) {
516
- fields.responsive.attr( 'placeholder', moduleResponsiveVal );
517
- }
518
- else {
519
- fields.responsive.attr( 'placeholder', moduleGlobalVal );
520
  }
521
  }
522
- else if ( ! Number( config.auto_spacing ) || ( 'padding' == field && 'top|bottom'.indexOf( dimension ) > -1 ) ) {
523
 
524
- if ( '' != mediumVal ) {
525
- fields.responsive.attr( 'placeholder', mediumVal );
526
- }
527
- else if ( '' != mediumGlobalVal ) {
528
- fields.responsive.attr( 'placeholder', mediumGlobalVal );
529
- }
530
- else if ( '' != defaultVal ) {
531
- fields.responsive.attr( 'placeholder', defaultVal );
 
 
 
 
 
 
 
 
 
532
  }
533
- else if ( '' != defaultGlobalVal ) {
534
- fields.responsive.attr( 'placeholder', defaultGlobalVal );
 
 
 
 
 
 
 
 
 
 
 
 
535
  }
536
  }
537
- }
538
  },
539
 
540
  /**
13
  *
14
  * @since 1.9
15
  * @private
16
+ * @property {String} _mode
17
  */
18
  _mode: 'default',
19
 
324
 
325
  if ( Number( FLBuilderConfig.global.responsive_enabled ) ) {
326
 
327
+ self._initFields( 'dimension', 'input', 'keyup', self._spacingFieldKeyup, [
328
+ 'margin',
329
+ 'padding'
 
 
 
 
 
 
330
  ] );
331
 
332
+ self._initFields( 'dimension', 'input', 'keyup', self._textFieldKeyup );
333
  self._initFields( 'unit', 'input', 'keyup', self._textFieldKeyup );
334
  }
335
 
410
  */
411
  _textFieldKeyup: function()
412
  {
413
+ var fields = FLBuilderResponsiveEditing._getFields( this, 'input' );
 
 
 
 
 
 
 
 
 
 
 
414
 
415
+ fields.default.each( function( i ) {
416
+
417
+ var defaultPlaceholder = fields.default.eq( i ).attr( 'placeholder' ),
418
+ defaultValue = fields.default.eq( i ).val(),
419
+ mediumValue = fields.medium.eq( i ).val();
420
+
421
+ // Medium placeholder
422
+ if ( '' == defaultValue ) {
423
+ fields.medium.eq( i ).attr( 'placeholder', ( undefined === defaultPlaceholder ? '' : defaultPlaceholder ) );
424
+ }
425
+ else {
426
+ fields.medium.eq( i ).attr( 'placeholder', defaultValue );
427
+ }
428
+
429
+ // Responsive placeholder
430
+ if ( '' == mediumValue ) {
431
+ fields.responsive.eq( i ).attr( 'placeholder', fields.medium.eq( i ).attr( 'placeholder' ) );
432
+ }
433
+ else {
434
+ fields.responsive.eq( i ).attr( 'placeholder', mediumValue );
435
+ }
436
+ } );
437
  },
438
 
439
  /**
447
  {
448
  var form = $( '.fl-builder-settings' ),
449
  type = 'row',
450
+ name = $( this ).closest( '.fl-field' ).attr( 'id' ).replace( 'fl-field-', '' ),
 
 
451
  fields = FLBuilderResponsiveEditing._getFields( this, 'input' ),
452
  config = FLBuilderConfig.global,
453
  configPrefix = null,
 
454
  defaultGlobalVal = null,
 
455
  mediumGlobalVal = null,
456
+ responsiveGlobalVal = null;
 
 
 
457
 
458
  // Get the node type
459
  if ( form.hasClass( 'fl-builder-row-settings' ) ) {
466
  type = 'module';
467
  }
468
 
469
+ // Spoof global column defaults since we don't have a setting for those.
470
  $.extend( config, {
471
  col_margins : 0,
472
  col_margins_medium : '',
477
  } );
478
 
479
  // Set the global values
480
+ configPrefix = type + '_' + name + ( 'margin' == name ? 's' : '' );
481
  defaultGlobalVal = config[ configPrefix ];
482
  mediumGlobalVal = config[ configPrefix + '_medium' ];
483
  responsiveGlobalVal = config[ configPrefix + '_responsive' ];
484
 
485
+ // Loop through the fields.
486
+ fields.default.each( function( i ) {
 
 
 
 
 
 
 
 
 
 
 
487
 
488
+ var dimension = fields.default.eq( i ).attr( 'name' ).split( '_' ).pop(),
489
+ defaultVal = fields.default.eq( i ).val(),
490
+ mediumVal = fields.medium.eq( i ).val(),
491
+ responsiveVal = fields.responsive.eq( i ).val(),
492
+ moduleGlobalVal = null,
493
+ moduleResponsiveVal = null;
494
 
495
+ // Medium value
496
+ if ( '' == mediumGlobalVal ) {
497
 
498
+ if ( '' != defaultVal ) {
499
+ fields.medium.eq( i ).attr( 'placeholder', defaultVal );
500
  }
501
+ else if ( '' != defaultGlobalVal ) {
502
+ fields.medium.eq( i ).attr( 'placeholder', defaultGlobalVal );
 
 
 
503
  }
504
  }
 
505
 
506
+ // Responsive value
507
+ if ( '' == responsiveGlobalVal ) {
508
+
509
+ if ( 'module' == type && Number( config.auto_spacing ) ) {
510
+
511
+ moduleGlobalVal = '' == mediumGlobalVal ? Number( defaultGlobalVal ) : mediumGlobalVal;
512
+ moduleResponsiveVal = '' == mediumVal ? Number( defaultVal ) : mediumVal;
513
+
514
+ if ( '' != moduleResponsiveVal && ( moduleResponsiveVal > moduleGlobalVal || moduleResponsiveVal < 0 ) ) {
515
+ fields.responsive.eq( i ).attr( 'placeholder', moduleGlobalVal );
516
+ }
517
+ else if ( '' != moduleResponsiveVal ) {
518
+ fields.responsive.eq( i ).attr( 'placeholder', moduleResponsiveVal );
519
+ }
520
+ else {
521
+ fields.responsive.eq( i ).attr( 'placeholder', moduleGlobalVal );
522
+ }
523
  }
524
+ else if ( ! Number( config.auto_spacing ) || ( 'padding' == name && 'top|bottom'.indexOf( dimension ) > -1 ) ) {
525
+
526
+ if ( '' != mediumVal ) {
527
+ fields.responsive.eq( i ).attr( 'placeholder', mediumVal );
528
+ }
529
+ else if ( '' != mediumGlobalVal ) {
530
+ fields.responsive.eq( i ).attr( 'placeholder', mediumGlobalVal );
531
+ }
532
+ else if ( '' != defaultVal ) {
533
+ fields.responsive.eq( i ).attr( 'placeholder', defaultVal );
534
+ }
535
+ else if ( '' != defaultGlobalVal ) {
536
+ fields.responsive.eq( i ).attr( 'placeholder', defaultGlobalVal );
537
+ }
538
  }
539
  }
540
+ } );
541
  },
542
 
543
  /**
js/fl-builder-revisions.js ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function( $ ) {
2
+
3
+ /**
4
+ * Revisions manager for the builder.
5
+ *
6
+ * @since 2.0
7
+ * @class Revisions
8
+ */
9
+ var Revisions = {
10
+
11
+ /**
12
+ * Initialize builder revisions.
13
+ *
14
+ * @since 2.0
15
+ * @method init
16
+ */
17
+ init: function()
18
+ {
19
+ this.setupMainMenuData();
20
+
21
+ $( '.fl-builder--revision-actions select' ).on( 'change', this.selectChanged );
22
+ $( '.fl-cancel-revision-preview' ).on( 'click', this.exitPreview.bind( this ) );
23
+ $( '.fl-apply-revision-preview' ).on( 'click', this.applyClicked.bind( this ) );
24
+
25
+ FLBuilder.addHook( 'revisionItemClicked', this.itemClicked.bind( this ) );
26
+ FLBuilder.addHook( 'didPublishLayout', this.refreshItems.bind( this ) );
27
+ },
28
+
29
+ /**
30
+ * Adds the revision items to the main menu data.
31
+ *
32
+ * @since 2.0
33
+ * @method setupMainMenuData
34
+ */
35
+ setupMainMenuData: function()
36
+ {
37
+ var posts = FLBuilderConfig.revisions.posts,
38
+ authors = FLBuilderConfig.revisions.authors,
39
+ template = wp.template( 'fl-revision-list-item' ),
40
+ select = $( '.fl-builder--revision-actions select' ),
41
+ date = '',
42
+ author = '',
43
+ i = 0;
44
+
45
+ FLBuilderConfig.mainMenu.revisions.items = [];
46
+ select.html( '' );
47
+
48
+ if ( 0 === posts.length ) {
49
+
50
+ FLBuilderConfig.mainMenu.revisions.items.push( {
51
+ eventName : 'noRevisionsMessage',
52
+ type : 'event',
53
+ label : wp.template( 'fl-no-revisions-message' )()
54
+ } );
55
+
56
+ } else {
57
+
58
+ for ( i in posts ) {
59
+
60
+ date = FLBuilderStrings.revisionDate.replace( '%s', posts[ i ].date.diff );
61
+ date += ' (' + posts[ i ].date.published + ')';
62
+ author = FLBuilderStrings.revisionAuthor.replace( '%s', authors[ posts[ i ].author ].name );
63
+
64
+ FLBuilderConfig.mainMenu.revisions.items.push( {
65
+ eventName : 'revisionItemClicked',
66
+ type : 'event',
67
+ label : template( {
68
+ id : posts[ i ].id,
69
+ date : date,
70
+ author : author,
71
+ avatar : authors[ posts[ i ].author ].avatar
72
+ } )
73
+ } );
74
+
75
+ select.append( '<option value="' + posts[ i ].id + '">' + date + '</option>' );
76
+ }
77
+ }
78
+
79
+ FLBuilder.triggerHook( 'renderRevisionsPanel' );
80
+ },
81
+
82
+ /**
83
+ * Refreshes the items in the revisions menu.
84
+ *
85
+ * @since 2.0
86
+ * @method refreshItems
87
+ */
88
+ refreshItems: function()
89
+ {
90
+ FLBuilder.ajax( {
91
+ action: 'refresh_revision_items'
92
+ }, this.refreshItemsComplete.bind( this ) );
93
+ },
94
+
95
+ /**
96
+ * Re-renders the revision items when they have been refreshed.
97
+ *
98
+ * @since 2.0
99
+ * @method preview
100
+ * @param {Number} id
101
+ */
102
+ refreshItemsComplete: function( response )
103
+ {
104
+ FLBuilderConfig.revisions = JSON.parse( response );
105
+
106
+ this.setupMainMenuData();
107
+ },
108
+
109
+ /**
110
+ * Callback for when a revision item is clicked
111
+ * to preview a revision.
112
+ *
113
+ * @since 2.0
114
+ * @method itemClicked
115
+ * @param {Object} e
116
+ * @param {Object} item
117
+ */
118
+ itemClicked: function( e, item )
119
+ {
120
+ var id = $( item ).find( '.fl-revision-list-item' ).attr( 'data-revision-id' );
121
+
122
+ // Save existing settings first if any exist. Don't proceed if it fails.
123
+ if ( ! FLBuilder._triggerSettingsSave( false, true ) ) {
124
+ return;
125
+ }
126
+
127
+ $( '.fl-builder--revision-actions select' ).val( id );
128
+
129
+ this.preview( id );
130
+ },
131
+
132
+ /**
133
+ * Callback for when the revision select is changed.
134
+ *
135
+ * @since 2.0
136
+ * @method selectChanged
137
+ * @param {Object} e
138
+ */
139
+ selectChanged: function( e )
140
+ {
141
+ Revisions.preview( $( this ).val() );
142
+ },
143
+
144
+ /**
145
+ * Restores a revision when the apply button is clicked.
146
+ *
147
+ * @since 2.0
148
+ * @method applyClicked
149
+ * @param {Object} e
150
+ */
151
+ applyClicked: function( e )
152
+ {
153
+ var id = $( '.fl-builder--revision-actions select' ).val();
154
+
155
+ Revisions.restore( id );
156
+ },
157
+
158
+ /**
159
+ * Previews a revision with the specified ID.
160
+ *
161
+ * @since 2.0
162
+ * @method preview
163
+ * @param {Number} id
164
+ */
165
+ preview: function( id )
166
+ {
167
+ $( '.fl-builder--revision-actions' ).css( 'display', 'flex' );
168
+ FLBuilder.triggerHook( 'didEnterRevisionPreview' );
169
+ FLBuilder.showAjaxLoader();
170
+
171
+ FLBuilder.ajax( {
172
+ action : 'render_revision_preview',
173
+ revision_id : id
174
+ }, this.previewRenderComplete.bind( this ) );
175
+ },
176
+
177
+ /**
178
+ * Previews a revision with the specified ID.
179
+ *
180
+ * @since 2.0
181
+ * @method previewRenderComplete
182
+ * @param {String} response
183
+ */
184
+ previewRenderComplete: function( response )
185
+ {
186
+ FLBuilder._renderLayout( response, function() {
187
+ FLBuilder._destroyOverlayEvents();
188
+ FLBuilder._removeAllOverlays();
189
+ } );
190
+ },
191
+
192
+ /**
193
+ * Exits a revision preview and restores the original layout.
194
+ *
195
+ * @since 2.0
196
+ * @method exitPreview
197
+ */
198
+ exitPreview: function()
199
+ {
200
+ $( '.fl-builder--revision-actions' ).hide();
201
+ FLBuilder.triggerHook( 'didExitRevisionPreview' );
202
+ FLBuilder._bindOverlayEvents();
203
+ FLBuilder._updateLayout();
204
+ },
205
+
206
+ /**
207
+ * Restores the layout to a revision with the specified ID.
208
+ *
209
+ * @since 2.0
210
+ * @method restore
211
+ * @param {Number} id
212
+ */
213
+ restore: function( id )
214
+ {
215
+ $( '.fl-builder--revision-actions' ).hide();
216
+ FLBuilder.triggerHook( 'didExitRevisionPreview' );
217
+ FLBuilder.showAjaxLoader();
218
+ FLBuilder._bindOverlayEvents();
219
+
220
+ FLBuilder.ajax( {
221
+ action : 'restore_revision',
222
+ revision_id : id
223
+ }, Revisions.restoreComplete );
224
+ },
225
+
226
+ /**
227
+ * Callback for when a revision is restored.
228
+ *
229
+ * @since 2.0
230
+ * @method restoreComplete
231
+ * @param {String} response
232
+ */
233
+ restoreComplete: function( response ) {
234
+ var data = JSON.parse( response );
235
+
236
+ FLBuilder._renderLayout( data.layout );
237
+ FLBuilder.triggerHook( 'didRestoreRevisionComplete', data.config );
238
+ }
239
+ };
240
+
241
+ $( function() { Revisions.init(); } );
242
+
243
+ } )( jQuery );
js/fl-builder-save-manager.js ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($, FLBuilder) {
2
+
3
+ /**
4
+ * Save Manager Object
5
+ */
6
+ var SaveManager = {
7
+
8
+ /**
9
+ * Indicates whether or not the current layout is clean or has changes that require
10
+ * publish actions.
11
+ *
12
+ * @var bool
13
+ */
14
+ layoutNeedsPublish: false,
15
+
16
+ /**
17
+ * The message that is displayed whenever `resetStatusMessage()` is called.
18
+ *
19
+ * @var string
20
+ */
21
+ defaultIndicatorMessage: "",
22
+
23
+ /**
24
+ * The tooltip that is displayed whenever 'resetStatusMessage()' is called.
25
+ *
26
+ * @var string
27
+ */
28
+ defaultTooltipMessage: "",
29
+
30
+ /**
31
+ * Local reference to strings pertaining to saving states.
32
+ *
33
+ * @var object
34
+ */
35
+ messages: null,
36
+
37
+ /**
38
+ * Setup the Save Manager object.
39
+ *
40
+ * @return void
41
+ */
42
+ init: function() {
43
+ this.messages = FLBuilderStrings.savedStatus;
44
+ this.$savingIndicator = $('.fl-builder--saving-indicator');
45
+
46
+ FLBuilder.addHook('didBeginAJAX', this.onLayoutSaving.bind(this));
47
+ FLBuilder.addHook('didCompleteAJAX', this.onLayoutSaved.bind(this));
48
+ FLBuilder.addHook('didPublishLayout', this.onLayoutPublished.bind(this));
49
+ FLBuilder.addHook('publishAndRemain', this.onPublishAndRemain.bind(this));
50
+
51
+ // We have to set the layout as needing publish when settings are opened because
52
+ // we can't yet reliably set it to needing publish when settings are changed.
53
+ FLBuilder.addHook('didShowLightbox', this.setLayoutNeedsPublish.bind(this));
54
+
55
+ if (FLBuilderConfig.layoutHasDraftedChanges || ! FLBuilderConfig.builderEnabledd) {
56
+ this.setLayoutNeedsPublish();
57
+ this.resetStatusMessage();
58
+ }
59
+ },
60
+
61
+ /**
62
+ * Flag the layout as needing to be published.
63
+ *
64
+ * @return void
65
+ */
66
+ setLayoutNeedsPublish: function() {
67
+ if ( !this.layoutNeedsPublish ) {
68
+ this.layoutNeedsPublish = true;
69
+ $('body').addClass('fl-builder--layout-has-drafted-changes');
70
+ }
71
+ },
72
+
73
+ /**
74
+ * Fires when layout begins saving.
75
+ *
76
+ * @return void
77
+ */
78
+ onLayoutSaving: function(e, data) {;
79
+
80
+ if ( this.isPublishingLayout( data.action ) ) {
81
+ this.showStatusMessage( this.messages.publishing, this.messages.publishingTooltip );
82
+ }
83
+ else if ( this.isUpdatingLayout( data.action ) ) {
84
+ this.setLayoutNeedsPublish();
85
+ this.showStatusMessage( this.messages.saving, this.messages.savingTooltip );
86
+ }
87
+ },
88
+
89
+ /**
90
+ * Check if the current ajax action is publishing the layout
91
+ *
92
+ * @var String action
93
+ * @return bool
94
+ */
95
+ isPublishingLayout: function( action ) {
96
+
97
+ if ( 'save_layout' == action ) {
98
+ return true;
99
+ }
100
+ return false;
101
+ },
102
+
103
+ /**
104
+ * Checks if the current ajax action is updating the layout or some other part of the system.
105
+ *
106
+ * @var String action
107
+ * @return bool
108
+ */
109
+ isUpdatingLayout: function( action ) {
110
+
111
+ if ( action.startsWith('render') ) {
112
+ if ( action.startsWith('render_new') ) { return true; }
113
+ return false;
114
+ }
115
+ if ( action.startsWith('duplicate') ) { return false; }
116
+ if ( action.startsWith('refresh') ) { return false; } // Like refresh_revision_items
117
+ if ( 'save_ui_skin' == action ) { return false; }
118
+ if ( 'save_lightbox_position' == action ) { return false; }
119
+ if ( 'save_pinned_ui_position' == action ) { return false; }
120
+
121
+ return true;
122
+ },
123
+
124
+ /**
125
+ * Fires after layout has been successfully saved.
126
+ * Display the "Saved" message, wait a bit and reset to the default message.
127
+ *
128
+ * @return void
129
+ */
130
+ onLayoutSaved: function( e, data ) {
131
+ if ( this.isUpdatingLayout( data.fl_builder_data.action ) ) {
132
+ this.showStatusMessage(this.messages.saved, this.messages.savedTooltip);
133
+
134
+ var obj = this;
135
+ setTimeout(function() {
136
+ obj.resetStatusMessage();
137
+ }, 2000);
138
+ }
139
+ },
140
+
141
+ /**
142
+ * Handle layout published
143
+ *
144
+ * @return void
145
+ */
146
+ onLayoutPublished: function() {
147
+ this.layoutNeedsPublish = false;
148
+ $('body').removeClass('fl-builder--layout-has-drafted-changes');
149
+ this.resetStatusMessage();
150
+ },
151
+
152
+ /**
153
+ * Set the status message area to a string of text.
154
+ *
155
+ * @var string Message to display
156
+ * @return void
157
+ */
158
+ showStatusMessage: function(message, toolTip) {
159
+ this.$savingIndicator.html(message);
160
+ if (!_.isUndefined(toolTip)) {
161
+ this.$savingIndicator.attr('title', toolTip);
162
+ $('.fl-builder--saving-indicator').tipTip({
163
+ defaultPosition: 'bottom',
164
+ edgeOffset: 14
165
+ });
166
+ }
167
+ },
168
+
169
+ /**
170
+ * Set the status message back to it's default state.
171
+ *
172
+ * @return void
173
+ */
174
+ resetStatusMessage: function() {
175
+ if(this.layoutNeedsPublish) {
176
+ this.defaultIndicatorMessage = this.messages.edited + '<i class="fa fa-question-circle"></i>';
177
+ this.defaultTooltipMessage = this.messages.editedTooltip;
178
+ } else {
179
+ this.defaultIndicatorMessage = "";
180
+ this.defaultTooltipMessage = "";
181
+ }
182
+ this.showStatusMessage(this.defaultIndicatorMessage, this.defaultTooltipMessage );
183
+ },
184
+
185
+ /**
186
+ * Handle publish key command
187
+ *
188
+ * @return void
189
+ */
190
+ onPublishAndRemain: function() {
191
+ if (this.layoutNeedsPublish) {
192
+ FLBuilder._publishLayout(false);
193
+ } else {
194
+ this.showStatusMessage(this.messages.noChanges);
195
+
196
+ var manager = this;
197
+ setTimeout(function() {
198
+ manager.resetStatusMessage();
199
+ }, 2000);
200
+ }
201
+ }
202
+ };
203
+
204
+ /**
205
+ * Pubic Interface
206
+ */
207
+ FLBuilder.SaveManager = {
208
+
209
+ /**
210
+ * Check if the current layout has unpublished changes
211
+ *
212
+ * @return bool
213
+ */
214
+ layoutNeedsPublish: function() {
215
+ return SaveManager.layoutNeedsPublish;
216
+ },
217
+
218
+ /**
219
+ * Show a status message
220
+ *
221
+ * @var String message
222
+ * @var String toolTip
223
+ * @return void
224
+ */
225
+ showStatusMessage: function(message, toolTip) {
226
+ SaveManager.showStatusMessage(message, toolTip);
227
+ },
228
+
229
+ /**
230
+ * Reset status message to contextual default
231
+ *
232
+ * @return void
233
+ */
234
+ resetStatusMessage: function() {
235
+ SaveManager.resetStatusMessage();
236
+ }
237
+ }
238
+
239
+ /**
240
+ * Kick off init.
241
+ */
242
+ $(function() {
243
+ SaveManager.init();
244
+ });
245
+
246
+ })(jQuery, FLBuilder);
js/fl-builder-search.js ADDED
@@ -0,0 +1,422 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+
3
+ var Search = {
4
+
5
+ /**
6
+ * Kick-off the query
7
+ *
8
+ * @since 2.0
9
+ * @param {Object} query The query
10
+ * @return {Object} The response
11
+ */
12
+ query: function( query ) {
13
+
14
+ var data = {},
15
+ kind = null,
16
+ results = {
17
+ library: {}
18
+ },
19
+ foundItems = null;
20
+
21
+ query = this.normalizeQuery(query);
22
+
23
+ // Reduce data by kind
24
+ if ( !_.isNull( query.kind ) ) {
25
+ for( var i in query.kind ) {
26
+ kind = query.kind[ i ];
27
+ data[ kind ] = FLBuilderConfig.contentItems[ kind ];
28
+ }
29
+ } else {
30
+ data = FLBuilderConfig.contentItems;
31
+ }
32
+
33
+ foundItems = this.findMatches( query, data );
34
+ results.library = this.formatResults( foundItems, query );
35
+
36
+ return results;
37
+ },
38
+
39
+ /**
40
+ * Make sure the query object is well-formed.
41
+ *
42
+ * @since 2.0
43
+ * @param {Object} query The query
44
+ * @return {Object} The query
45
+ */
46
+ normalizeQuery: function( query ) {
47
+ var defaultQuery = {
48
+ kind: null,
49
+ type: null,
50
+ category: null,
51
+ group: null,
52
+ enabled: true, /* pertains only to modules */
53
+ global: null, /* pertains only to user row and module templates */
54
+ searchTerm: null,
55
+ categorized: false,
56
+ };
57
+
58
+ query = _.extend(defaultQuery, query);
59
+
60
+ if ( _.isString( query.kind ) ) {
61
+ query.kind = [ query.kind ];
62
+ }
63
+
64
+ return query;
65
+ },
66
+
67
+ /**
68
+ * Find the objects in the dataset that match query criteria.
69
+ *
70
+ * @since 2.0
71
+ * @param {Object} query
72
+ * @param {Object} data
73
+ * @return {Object}
74
+ */
75
+ findMatches: function( query, data ) {
76
+ var foundItems = {},
77
+ typeName = null,
78
+ objects = null,
79
+ object = null,
80
+ inArray = null,
81
+ matches = null,
82
+ i = null;
83
+
84
+ for ( typeName in data ) {
85
+
86
+ objects = data[ typeName ];
87
+
88
+ foundItems[ typeName ] = {
89
+ items: []
90
+ };
91
+
92
+ for ( i in objects ) {
93
+
94
+ object = objects[i];
95
+
96
+ // Test for category matches.
97
+ if ( ! _.isUndefined( query.category ) && ! _.isNull( query.category ) ) {
98
+ if ( ! this.matchesCategory( object.category, query.category ) ) {
99
+ continue;
100
+ }
101
+ }
102
+
103
+ switch ( typeName ) {
104
+ case 'template':
105
+
106
+ // Content type - module | row | layout
107
+ if ( ! _.isUndefined( query.content ) && ! _.isNull( query.content ) ) {
108
+
109
+ inArray = _.contains( query.content, object.content );
110
+ matches = query.content === object.content;
111
+
112
+ if ( ! inArray && ! matches) {
113
+ continue;
114
+ }
115
+ }
116
+
117
+ // Text type matches - core | user
118
+ if ( ! _.isUndefined( query.type ) && ! _.isNull( query.type ) ) {
119
+ if ( query.type !== object.type ) {
120
+ continue;
121
+ }
122
+ }
123
+
124
+ if ( !_.isNull( query.group ) ) {
125
+ var queryGroup = query.group,
126
+ objectGroup = object.group;
127
+
128
+ // Normalize group into arrays
129
+ if ( _.isString( queryGroup) ) {
130
+ queryGroup = [ queryGroup ];
131
+ }
132
+ if ( _.isString( objectGroup) ) {
133
+ objectGroup = [ objectGroup ];
134
+ }
135
+ if ( _.isEmpty( queryGroup ) || _.isEmpty( objectGroup ) ) {
136
+ continue;
137
+ }
138
+
139
+ var hasGroup = false;
140
+ for( i in queryGroup ) {
141
+ var group = queryGroup[i];
142
+ if ( _.contains( objectGroup, group ) ) {
143
+ hasGroup = true;
144
+ }
145
+ }
146
+ if ( !hasGroup ) {
147
+ continue;
148
+ }
149
+ }
150
+
151
+ break;
152
+ case 'module':
153
+
154
+ if ( ! _.isNull( query.group ) ) {
155
+ if ( query.group === false && object.group.length > 0 ) {
156
+ continue;
157
+ }
158
+ if ( query.group !== false && ! _.contains( object.group, query.group ) ) {
159
+ continue;
160
+ }
161
+ }
162
+
163
+ break;
164
+ }
165
+
166
+ if ( ! _.isUndefined( query.searchTerm ) && ! _.isNull( query.searchTerm ) ) {
167
+ if ( ! this.matchesSearchTerm( object, query.searchTerm ) ) {
168
+ continue;
169
+ }
170
+ }
171
+
172
+ foundItems[ typeName ].items.push( object );
173
+ }
174
+ }
175
+
176
+ return foundItems;
177
+ },
178
+
179
+ /**
180
+ * @since 2.0
181
+ * @param {Object} objectCat
182
+ * @param {Object} queryCats
183
+ * @return {Boolean}
184
+ */
185
+ matchesCategory: function( objectCat, queryCats ) {
186
+ var queryCat, i, j, cat, key, value;
187
+
188
+ if ( objectCat === queryCats ) {
189
+ return true;
190
+ }
191
+
192
+ if ( _.isString( queryCats ) ) {
193
+ queryCats = [queryCats];
194
+ }
195
+
196
+ // Loop over multipe query categories
197
+ for ( i in queryCats ) {
198
+ queryCat = queryCats[ i ];
199
+
200
+ if ( _.isString( objectCat ) && objectCat === queryCat ) {
201
+ return true;
202
+ }
203
+
204
+ if ( _.isArray( objectCat ) ) {
205
+ for ( j in objectCat ) {
206
+ cat = objectCat[ j ];
207
+ if ( cat === queryCat ) {
208
+ return true;
209
+ }
210
+ }
211
+ }
212
+
213
+ if ( _.isObject( objectCat ) ) {
214
+ for ( key in objectCat ) {
215
+ value = objectCat[ key ];
216
+ if ( value === queryCat || key === queryCat ) {
217
+ return true;
218
+ }
219
+ }
220
+ }
221
+ }
222
+
223
+ return false;
224
+ },
225
+
226
+ /**
227
+ * @since 2.0
228
+ * @param {Object} obj
229
+ * @param {String} term
230
+ * @return {Boolean}
231
+ */
232
+ matchesSearchTerm: function( obj, term ) {
233
+ var widgetLowercase,
234
+ moduleWordLowercase,
235
+ termLowercase = term.toLowerCase();
236
+
237
+ // Match Slug
238
+ if ( !_.isUndefined( obj.slug ) && obj.slug.toLowerCase().includes( termLowercase ) ) {
239
+ return true;
240
+ }
241
+
242
+ // Match Name
243
+ if ( !_.isUndefined( obj.name ) && obj.name.toLowerCase().includes( termLowercase ) ) {
244
+ return true;
245
+ }
246
+
247
+ // Match Category
248
+ if ( _.isString(obj.category) && obj.category.toLowerCase().includes( termLowercase ) ) {
249
+ return true;
250
+ }
251
+
252
+ // Match Description
253
+ if ( !_.isUndefined( obj.description ) && obj.description.toLowerCase().includes( termLowercase ) ) {
254
+ return true;
255
+ }
256
+
257
+ // Match Widget Base ID (slug equivalent)
258
+ if ( !_.isUndefined( obj.id_base ) && obj.id_base.includes(term)) {
259
+ return true;
260
+ }
261
+
262
+ // If term matches "Widget" or "widget"
263
+ if ( obj.isWidget ) {
264
+ widgetLowercase = "widget";
265
+ if ( widgetLowercase.includes( termLowercase ) ) {
266
+ return true;
267
+ }
268
+ }
269
+
270
+ // if term matches "Module" or "module"
271
+ if ( !_.isUndefined( obj.editor_export ) ) {
272
+ moduleWordLowercase = "module";
273
+ if ( moduleWordLowercase.includes( termLowercase ) ) {
274
+ return true;
275
+ }
276
+ }
277
+ return false;
278
+ },
279
+
280
+ /**
281
+ * @since 2.0
282
+ * @param {Object} foundItems
283
+ * @param {Object} query
284
+ * @return {Object}
285
+ */
286
+ formatResults: function(foundItems, query) {
287
+
288
+ if (query.categorized) {
289
+ for( type in foundItems) {
290
+ var items = foundItems[type].items;
291
+ foundItems[type].categorized = this.groupBy(items, 'category');
292
+ }
293
+ }
294
+ return foundItems;
295
+ },
296
+
297
+ /**
298
+ * @since 2.0
299
+ * @param {Object} items
300
+ * @param {String} propertyName
301
+ * @return {Object}
302
+ */
303
+ groupBy: function(items, propertyName) {
304
+ var groups = {}, propertyValue, propertyValues;
305
+
306
+ _.forEach(items, function(item, i, list) {
307
+
308
+ propertyValue = item[propertyName];
309
+
310
+ if ( _.isNull(propertyValue) || _.isUndefined(propertyValue) ) { return; }
311
+ if ( _.isString(propertyValue) && item[propertyValue] === "") { return; }
312
+
313
+ // Group item by single category
314
+ if (_.isString(propertyValue)) {
315
+ groups[propertyValue] = groups[propertyValue] || [];
316
+ groups[propertyValue].push(item);
317
+ }
318
+
319
+ // Group item into each category in an array
320
+ if (_.isArray(propertyValue)) {
321
+ propertyValues = propertyValue;
322
+ _.forEach(propertyValues, function(prop, j, list) {
323
+ groups[prop] = groups[prop] || [];
324
+ groups[prop].push(item);
325
+ });
326
+ }
327
+
328
+ // Group item into each value of a hash.
329
+ if (_.isObject(propertyValue)) {
330
+ propertyValues = propertyValue;
331
+ _.forEach(propertyValues, function(value, key, list) {
332
+ groups[value] = groups[value] || [];
333
+ groups[value].push(item);
334
+ });
335
+ }
336
+ });
337
+
338
+ // if any group only contains blank, lose it.
339
+ return groups;
340
+ },
341
+
342
+ /**
343
+ * @since 2.0
344
+ * @param String The search term
345
+ * @return {Object} The response
346
+ */
347
+ search: function(term) {
348
+ var query = {
349
+ searchTerm: term
350
+ }
351
+ var raw = this.query(query),
352
+ response = {
353
+ total: 0,
354
+ term: term,
355
+ sections: {}
356
+ };
357
+
358
+ if ( !_.isUndefined(raw.library.module.items) ) {
359
+ var categorized = {};
360
+ for(var i in raw.library.module.items) {
361
+ var item = raw.library.module.items[i],
362
+ group = item.group[0],
363
+ cat = item.category,
364
+ name = item.name;
365
+
366
+ if ( _.isUndefined(categorized[group]) ) {
367
+ categorized[group] = {};
368
+ }
369
+ if ( _.isUndefined(categorized[group][cat]) ) {
370
+ categorized[group][cat] = [];
371
+ }
372
+ categorized[group][cat].push(item);
373
+ }
374
+ response.grouped = categorized;
375
+ }
376
+
377
+ for( var i in raw.library) {
378
+ var type = raw.library[i];
379
+ if ( !_.isUndefined(type.items) && type.items.length > 0) {
380
+ response.sections[i] = {
381
+ name: FLBuilderStrings.typeLabels[i],
382
+ handle: i,
383
+ type: "",
384
+ items: type.items
385
+ };
386
+ response.total += type.items.length;
387
+ }
388
+ }
389
+ return response;
390
+ }
391
+ }
392
+
393
+ /**
394
+ * Public Interface
395
+ */
396
+ FLBuilder.Search = {
397
+
398
+ /**
399
+ * Find items that match query object
400
+ *
401
+ * @since 2.0
402
+ * @param {Object} query The query
403
+ * @return {Object} The response
404
+ */
405
+ byQuery: function(query) {
406
+ return Search.query(query);
407
+ },
408
+
409
+ /**
410
+ * Find items by search term
411
+ *
412
+ * @since 2.0
413
+ * @param String term
414
+ * @return {Object} The response
415
+ */
416
+ byTerm: function(term) {
417
+ var response = Search.search(term);
418
+ return response;
419
+ }
420
+ }
421
+
422
+ })(jQuery);
js/fl-builder-services.js CHANGED
@@ -1,12 +1,12 @@
1
  (function( $ ) {
2
-
3
  /**
4
  * JavaScript class for working with third party services.
5
  *
6
  * @since 1.5.4
7
  */
8
  var FLBuilderServices = {
9
-
10
  /**
11
  * Initializes the services logic.
12
  *
@@ -16,23 +16,23 @@
16
  init: function()
17
  {
18
  var body = $('body');
19
-
20
  // Standard Events
21
  body.delegate( '.fl-builder-service-select', 'change', this._serviceChange );
22
  body.delegate( '.fl-builder-service-connect-button', 'click', this._connectClicked );
23
  body.delegate( '.fl-builder-service-account-select', 'change', this._accountChange );
24
  body.delegate( '.fl-builder-service-account-delete', 'click', this._accountDeleteClicked );
25
-
26
  // Campaign Monitor Events
27
  body.delegate( '.fl-builder-campaign-monitor-client-select', 'change', this._campaignMonitorClientChange );
28
-
29
  // MailChimp Events
30
  body.delegate( '.fl-builder-mailchimp-list-select', 'change', this._mailChimpListChange );
31
 
32
  // ActiveCampaign Events
33
  body.delegate( '.fl-builder-activecampaign-list_type-select', 'change', this._activeCampaignChange );
34
  },
35
-
36
  /**
37
  * Show the lightbox loading graphic and remove errors.
38
  *
@@ -45,12 +45,12 @@
45
  var lightbox = $( '.fl-builder-settings' ),
46
  wrap = ele.closest( '.fl-builder-service-settings' ),
47
  error = $( '.fl-builder-service-error' );
48
-
49
  lightbox.append( '<div class="fl-builder-loading"></div>' );
50
  wrap.addClass( 'fl-builder-service-settings-loading' );
51
  error.remove();
52
  },
53
-
54
  /**
55
  * Remove the lightbox loading graphic.
56
  *
@@ -61,11 +61,11 @@
61
  {
62
  var lightbox = $( '.fl-builder-settings' ),
63
  wrap = $( '.fl-builder-service-settings-loading' );
64
-
65
  lightbox.find( '.fl-builder-loading' ).remove();
66
  wrap.removeClass( 'fl-builder-service-settings-loading' );
67
  },
68
-
69
  /**
70
  * Fires when the service select changes.
71
  *
@@ -78,25 +78,25 @@
78
  select = $( this ),
79
  selectRow = select.closest( 'tr' ),
80
  service = select.val();
81
-
82
  selectRow.siblings( 'tr.fl-builder-service-account-row' ).remove();
83
  selectRow.siblings( 'tr.fl-builder-service-connect-row' ).remove();
84
  selectRow.siblings( 'tr.fl-builder-service-field-row' ).remove();
85
  $( '.fl-builder-service-error' ).remove();
86
-
87
  if ( '' === service ) {
88
  return;
89
  }
90
-
91
  FLBuilderServices._startSettingsLoading( select );
92
-
93
  FLBuilder.ajax( {
94
  action : 'render_service_settings',
95
  node_id : nodeId,
96
  service : service
97
  }, FLBuilderServices._serviceChangeComplete );
98
  },
99
-
100
  /**
101
  * AJAX callback for when the service select changes.
102
  *
@@ -109,12 +109,12 @@
109
  var data = JSON.parse( response ),
110
  wrap = $( '.fl-builder-service-settings-loading' ),
111
  selectRow = wrap.find( '.fl-builder-service-select-row' );
112
-
113
  selectRow.after( data.html );
114
  FLBuilderServices._addAccountDelete( wrap );
115
  FLBuilderServices._finishSettingsLoading();
116
  },
117
-
118
  /**
119
  * Fires when the service connect button is clicked.
120
  *
@@ -137,18 +137,18 @@
137
  service : select.val(),
138
  fields : {}
139
  };
140
-
141
  for ( ; i < connectInputs.length; i++ ) {
142
  input = connectInputs.eq( i );
143
  name = input.attr( 'name' );
144
  data.fields[ name ] = input.val();
145
  }
146
-
147
  connectRows.hide();
148
  FLBuilderServices._startSettingsLoading( select );
149
  FLBuilder.ajax( data, FLBuilderServices._connectComplete );
150
  },
151
-
152
  /**
153
  * AJAX callback for when the service connect button is clicked.
154
  *
@@ -165,11 +165,11 @@
165
  accountRow = wrap.find( '.fl-builder-service-account-row' ),
166
  account = wrap.find( '.fl-builder-service-account-select' ),
167
  connectRows = wrap.find( '.fl-builder-service-connect-row' );
168
-
169
  if ( data.error ) {
170
-
171
  connectRows.show();
172
-
173
  if ( 0 === account.length ) {
174
  select.after( '<div class="fl-builder-service-error">' + data.error + '</div>' );
175
  }
@@ -182,11 +182,11 @@
182
  accountRow.remove();
183
  selectRow.after( data.html );
184
  }
185
-
186
  FLBuilderServices._addAccountDelete( wrap );
187
  FLBuilderServices._finishSettingsLoading();
188
  },
189
-
190
  /**
191
  * Fires when the service account select changes.
192
  *
@@ -204,11 +204,11 @@
204
  error = $( '.fl-builder-service-error' ),
205
  value = account.val(),
206
  data = null;
207
-
208
  connectRows.remove();
209
  fieldRows.remove();
210
  error.remove();
211
-
212
  if ( 'add_new_account' == value ) {
213
  data = {
214
  action : 'render_service_settings',
@@ -225,15 +225,15 @@
225
  account : value
226
  };
227
  }
228
-
229
  if ( data ) {
230
  FLBuilderServices._startSettingsLoading( select );
231
  FLBuilder.ajax( data, FLBuilderServices._accountChangeComplete );
232
  }
233
-
234
  FLBuilderServices._addAccountDelete( wrap );
235
  },
236
-
237
  /**
238
  * AJAX callback for when the service account select changes.
239
  *
@@ -246,11 +246,11 @@
246
  var data = JSON.parse( response ),
247
  wrap = $( '.fl-builder-service-settings-loading' ),
248
  accountRow = wrap.find( '.fl-builder-service-account-row' );
249
-
250
  accountRow.after( data.html );
251
  FLBuilderServices._finishSettingsLoading();
252
  },
253
-
254
  /**
255
  * Adds an account delete link.
256
  *
@@ -261,17 +261,17 @@
261
  _addAccountDelete: function( wrap )
262
  {
263
  var account = wrap.find( '.fl-builder-service-account-select' );
264
-
265
  if ( account.length > 0 ) {
266
-
267
  wrap.find( '.fl-builder-service-account-delete' ).remove();
268
-
269
  if ( '' !== account.val() && 'add_new_account' != account.val() ) {
270
  account.after( '<a href="javascript:void(0);" class="fl-builder-service-account-delete">' + FLBuilderStrings.deleteAccount + '</a>' );
271
  }
272
  }
273
  },
274
-
275
  /**
276
  * Fires when the account delete link is clicked.
277
  *
@@ -283,19 +283,19 @@
283
  var wrap = $( this ).closest( '.fl-builder-service-settings' ),
284
  select = wrap.find( '.fl-builder-service-select' ),
285
  account = wrap.find( '.fl-builder-service-account-select' );
286
-
287
  if ( confirm( FLBuilderStrings.deleteAccountWarning ) ) {
288
-
289
  FLBuilder.ajax( {
290
  action : 'delete_service_account',
291
  service : select.val(),
292
  account : account.val()
293
  }, FLBuilderServices._accountDeleteComplete );
294
-
295
  FLBuilderServices._startSettingsLoading( account );
296
  }
297
  },
298
-
299
  /**
300
  * AJAX callback for when the account delete link is clicked.
301
  *
@@ -306,15 +306,15 @@
306
  {
307
  var wrap = $( '.fl-builder-service-settings-loading' ),
308
  select = wrap.find( '.fl-builder-service-select' );
309
-
310
  FLBuilderServices._finishSettingsLoading();
311
-
312
  select.trigger( 'change' );
313
  },
314
-
315
  /* Campaign Monitor
316
  ----------------------------------------------------------*/
317
-
318
  /**
319
  * Fires when the Campaign Monitor client select is changed.
320
  *
@@ -330,16 +330,16 @@
330
  client = $( this ),
331
  list = wrap.find( '.fl-builder-service-list-select' ),
332
  value = client.val();
333
-
334
  if ( 0 !== list.length ) {
335
  list.closest( 'tr' ).remove();
336
  }
337
  if ( '' === value ) {
338
  return;
339
  }
340
-
341
  FLBuilderServices._startSettingsLoading( select );
342
-
343
  FLBuilder.ajax( {
344
  action : 'render_service_fields',
345
  node_id : nodeId,
@@ -348,7 +348,7 @@
348
  client : value
349
  }, FLBuilderServices._campaignMonitorClientChangeComplete );
350
  },
351
-
352
  /**
353
  * AJAX callback for when the Campaign Monitor client select is changed.
354
  *
@@ -361,14 +361,14 @@
361
  var data = JSON.parse( response ),
362
  wrap = $( '.fl-builder-service-settings-loading' ),
363
  client = wrap.find( '.fl-builder-campaign-monitor-client-select' );
364
-
365
  client.closest( 'tr' ).after( data.html );
366
  FLBuilderServices._finishSettingsLoading();
367
  },
368
-
369
  /* MailChimp
370
  ----------------------------------------------------------*/
371
-
372
  /**
373
  * Fires when the MailChimp list select is changed.
374
  *
@@ -382,15 +382,15 @@
382
  select = wrap.find( '.fl-builder-service-select' ),
383
  account = wrap.find( '.fl-builder-service-account-select' ),
384
  list = wrap.find( '.fl-builder-service-list-select' );
385
-
386
  $( '.fl-builder-mailchimp-group-select' ).closest( 'tr' ).remove();
387
-
388
  if ( '' === list.val() ) {
389
  return;
390
  }
391
-
392
  FLBuilderServices._startSettingsLoading( select );
393
-
394
  FLBuilder.ajax( {
395
  action : 'render_service_fields',
396
  node_id : nodeId,
@@ -399,7 +399,7 @@
399
  list_id : list.val()
400
  }, FLBuilderServices._mailChimpListChangeComplete );
401
  },
402
-
403
  /**
404
  * AJAX callback for when the MailChimp list select is changed.
405
  *
@@ -412,14 +412,14 @@
412
  var data = JSON.parse( response ),
413
  wrap = $( '.fl-builder-service-settings-loading' ),
414
  list = wrap.find( '.fl-builder-service-list-select' );
415
-
416
  list.closest( 'tr' ).after( data.html );
417
  FLBuilderServices._finishSettingsLoading();
418
  },
419
 
420
  /* ActiveCampaign
421
  ----------------------------------------------------------*/
422
-
423
  /**
424
  * Fires when the ActiveCampaign list type select is changed.
425
  *
@@ -434,17 +434,17 @@
434
  account = wrap.find( '.fl-builder-service-account-select' ),
435
  list = wrap.find( '.fl-builder-service-list-select' );
436
  list_type = wrap.find( 'select[name="list_type"]' );
437
-
438
  if ( 0 !== list.length ) {
439
  list.closest( 'tr' ).remove();
440
  }
441
-
442
  if ( '' === list_type.val() ) {
443
  return;
444
  }
445
-
446
  FLBuilderServices._startSettingsLoading( select );
447
-
448
  FLBuilder.ajax( {
449
  action : 'render_service_fields',
450
  node_id : nodeId,
@@ -453,7 +453,7 @@
453
  list_type : list_type.val()
454
  }, FLBuilderServices._activeCampaignTypeChangeComplete );
455
  },
456
-
457
  /**
458
  * AJAX callback for when the ActiveCampaign list select is changed.
459
  *
@@ -466,7 +466,7 @@
466
  var data = JSON.parse( response ),
467
  wrap = $( '.fl-builder-service-settings-loading' ),
468
  fieldRow = wrap.find( '.fl-builder-service-field-row' );
469
-
470
  fieldRow.after( data.html );
471
  FLBuilderServices._finishSettingsLoading();
472
  }
@@ -476,4 +476,4 @@
476
  FLBuilderServices.init();
477
  });
478
 
479
- })( jQuery );
1
  (function( $ ) {
2
+
3
  /**
4
  * JavaScript class for working with third party services.
5
  *
6
  * @since 1.5.4
7
  */
8
  var FLBuilderServices = {
9
+
10
  /**
11
  * Initializes the services logic.
12
  *
16
  init: function()
17
  {
18
  var body = $('body');
19
+
20
  // Standard Events
21
  body.delegate( '.fl-builder-service-select', 'change', this._serviceChange );
22
  body.delegate( '.fl-builder-service-connect-button', 'click', this._connectClicked );
23
  body.delegate( '.fl-builder-service-account-select', 'change', this._accountChange );
24
  body.delegate( '.fl-builder-service-account-delete', 'click', this._accountDeleteClicked );
25
+
26
  // Campaign Monitor Events
27
  body.delegate( '.fl-builder-campaign-monitor-client-select', 'change', this._campaignMonitorClientChange );
28
+
29
  // MailChimp Events
30
  body.delegate( '.fl-builder-mailchimp-list-select', 'change', this._mailChimpListChange );
31
 
32
  // ActiveCampaign Events
33
  body.delegate( '.fl-builder-activecampaign-list_type-select', 'change', this._activeCampaignChange );
34
  },
35
+
36
  /**
37
  * Show the lightbox loading graphic and remove errors.
38
  *
45
  var lightbox = $( '.fl-builder-settings' ),
46
  wrap = ele.closest( '.fl-builder-service-settings' ),
47
  error = $( '.fl-builder-service-error' );
48
+
49
  lightbox.append( '<div class="fl-builder-loading"></div>' );
50
  wrap.addClass( 'fl-builder-service-settings-loading' );
51
  error.remove();
52
  },
53
+
54
  /**
55
  * Remove the lightbox loading graphic.
56
  *
61
  {
62
  var lightbox = $( '.fl-builder-settings' ),
63
  wrap = $( '.fl-builder-service-settings-loading' );
64
+
65
  lightbox.find( '.fl-builder-loading' ).remove();
66
  wrap.removeClass( 'fl-builder-service-settings-loading' );
67
  },
68
+
69
  /**
70
  * Fires when the service select changes.
71
  *
78
  select = $( this ),
79
  selectRow = select.closest( 'tr' ),
80
  service = select.val();
81
+
82
  selectRow.siblings( 'tr.fl-builder-service-account-row' ).remove();
83
  selectRow.siblings( 'tr.fl-builder-service-connect-row' ).remove();
84
  selectRow.siblings( 'tr.fl-builder-service-field-row' ).remove();
85
  $( '.fl-builder-service-error' ).remove();
86
+
87
  if ( '' === service ) {
88
  return;
89
  }
90
+
91
  FLBuilderServices._startSettingsLoading( select );
92
+
93
  FLBuilder.ajax( {
94
  action : 'render_service_settings',
95
  node_id : nodeId,
96
  service : service
97
  }, FLBuilderServices._serviceChangeComplete );
98
  },
99
+
100
  /**
101
  * AJAX callback for when the service select changes.
102
  *
109
  var data = JSON.parse( response ),
110
  wrap = $( '.fl-builder-service-settings-loading' ),
111
  selectRow = wrap.find( '.fl-builder-service-select-row' );
112
+
113
  selectRow.after( data.html );
114
  FLBuilderServices._addAccountDelete( wrap );
115
  FLBuilderServices._finishSettingsLoading();
116
  },
117
+
118
  /**
119
  * Fires when the service connect button is clicked.
120
  *
137
  service : select.val(),
138
  fields : {}
139
  };
140
+
141
  for ( ; i < connectInputs.length; i++ ) {
142
  input = connectInputs.eq( i );
143
  name = input.attr( 'name' );
144
  data.fields[ name ] = input.val();
145
  }
146
+
147
  connectRows.hide();
148
  FLBuilderServices._startSettingsLoading( select );
149
  FLBuilder.ajax( data, FLBuilderServices._connectComplete );
150
  },
151
+
152
  /**
153
  * AJAX callback for when the service connect button is clicked.
154
  *
165
  accountRow = wrap.find( '.fl-builder-service-account-row' ),
166
  account = wrap.find( '.fl-builder-service-account-select' ),
167
  connectRows = wrap.find( '.fl-builder-service-connect-row' );
168
+
169
  if ( data.error ) {
170
+
171
  connectRows.show();
172
+
173
  if ( 0 === account.length ) {
174
  select.after( '<div class="fl-builder-service-error">' + data.error + '</div>' );
175
  }
182
  accountRow.remove();
183
  selectRow.after( data.html );
184
  }
185
+
186
  FLBuilderServices._addAccountDelete( wrap );
187
  FLBuilderServices._finishSettingsLoading();
188
  },
189
+
190
  /**
191
  * Fires when the service account select changes.
192
  *
204
  error = $( '.fl-builder-service-error' ),
205
  value = account.val(),
206
  data = null;
207
+
208
  connectRows.remove();
209
  fieldRows.remove();
210
  error.remove();
211
+
212
  if ( 'add_new_account' == value ) {
213
  data = {
214
  action : 'render_service_settings',
225
  account : value
226
  };
227
  }
228
+
229
  if ( data ) {
230
  FLBuilderServices._startSettingsLoading( select );
231
  FLBuilder.ajax( data, FLBuilderServices._accountChangeComplete );
232
  }
233
+
234
  FLBuilderServices._addAccountDelete( wrap );
235
  },
236
+
237
  /**
238
  * AJAX callback for when the service account select changes.
239
  *
246
  var data = JSON.parse( response ),
247
  wrap = $( '.fl-builder-service-settings-loading' ),
248
  accountRow = wrap.find( '.fl-builder-service-account-row' );
249
+
250
  accountRow.after( data.html );
251
  FLBuilderServices._finishSettingsLoading();
252
  },
253
+
254
  /**
255
  * Adds an account delete link.
256
  *
261
  _addAccountDelete: function( wrap )
262
  {
263
  var account = wrap.find( '.fl-builder-service-account-select' );
264
+
265
  if ( account.length > 0 ) {
266
+
267
  wrap.find( '.fl-builder-service-account-delete' ).remove();
268
+
269
  if ( '' !== account.val() && 'add_new_account' != account.val() ) {
270
  account.after( '<a href="javascript:void(0);" class="fl-builder-service-account-delete">' + FLBuilderStrings.deleteAccount + '</a>' );
271
  }
272
  }
273
  },
274
+
275
  /**
276
  * Fires when the account delete link is clicked.
277
  *
283
  var wrap = $( this ).closest( '.fl-builder-service-settings' ),
284
  select = wrap.find( '.fl-builder-service-select' ),
285
  account = wrap.find( '.fl-builder-service-account-select' );
286
+
287
  if ( confirm( FLBuilderStrings.deleteAccountWarning ) ) {
288
+
289
  FLBuilder.ajax( {
290
  action : 'delete_service_account',
291
  service : select.val(),
292
  account : account.val()
293
  }, FLBuilderServices._accountDeleteComplete );
294
+
295
  FLBuilderServices._startSettingsLoading( account );
296
  }
297
  },
298
+
299
  /**
300
  * AJAX callback for when the account delete link is clicked.
301
  *
306
  {
307
  var wrap = $( '.fl-builder-service-settings-loading' ),
308
  select = wrap.find( '.fl-builder-service-select' );
309
+
310
  FLBuilderServices._finishSettingsLoading();
311
+
312
  select.trigger( 'change' );
313
  },
314
+
315
  /* Campaign Monitor
316
  ----------------------------------------------------------*/
317
+
318
  /**
319
  * Fires when the Campaign Monitor client select is changed.
320
  *
330
  client = $( this ),
331
  list = wrap.find( '.fl-builder-service-list-select' ),
332
  value = client.val();
333
+
334
  if ( 0 !== list.length ) {
335
  list.closest( 'tr' ).remove();
336
  }
337
  if ( '' === value ) {
338
  return;
339
  }
340
+
341
  FLBuilderServices._startSettingsLoading( select );
342
+
343
  FLBuilder.ajax( {
344
  action : 'render_service_fields',
345
  node_id : nodeId,
348
  client : value
349
  }, FLBuilderServices._campaignMonitorClientChangeComplete );
350
  },
351
+
352
  /**
353
  * AJAX callback for when the Campaign Monitor client select is changed.
354
  *
361
  var data = JSON.parse( response ),
362
  wrap = $( '.fl-builder-service-settings-loading' ),
363
  client = wrap.find( '.fl-builder-campaign-monitor-client-select' );
364
+
365
  client.closest( 'tr' ).after( data.html );
366
  FLBuilderServices._finishSettingsLoading();
367
  },
368
+
369
  /* MailChimp
370
  ----------------------------------------------------------*/
371
+
372
  /**
373
  * Fires when the MailChimp list select is changed.
374
  *
382
  select = wrap.find( '.fl-builder-service-select' ),
383
  account = wrap.find( '.fl-builder-service-account-select' ),
384
  list = wrap.find( '.fl-builder-service-list-select' );
385
+
386
  $( '.fl-builder-mailchimp-group-select' ).closest( 'tr' ).remove();
387
+
388
  if ( '' === list.val() ) {
389
  return;
390
  }
391
+
392
  FLBuilderServices._startSettingsLoading( select );
393
+
394
  FLBuilder.ajax( {
395
  action : 'render_service_fields',
396
  node_id : nodeId,
399
  list_id : list.val()
400
  }, FLBuilderServices._mailChimpListChangeComplete );
401
  },
402
+
403
  /**
404
  * AJAX callback for when the MailChimp list select is changed.
405
  *
412
  var data = JSON.parse( response ),
413
  wrap = $( '.fl-builder-service-settings-loading' ),
414
  list = wrap.find( '.fl-builder-service-list-select' );
415
+
416
  list.closest( 'tr' ).after( data.html );
417
  FLBuilderServices._finishSettingsLoading();
418
  },
419
 
420
  /* ActiveCampaign
421
  ----------------------------------------------------------*/
422
+
423
  /**
424
  * Fires when the ActiveCampaign list type select is changed.
425
  *
434
  account = wrap.find( '.fl-builder-service-account-select' ),
435
  list = wrap.find( '.fl-builder-service-list-select' );
436
  list_type = wrap.find( 'select[name="list_type"]' );
437
+
438
  if ( 0 !== list.length ) {
439
  list.closest( 'tr' ).remove();
440
  }
441
+
442
  if ( '' === list_type.val() ) {
443
  return;
444
  }
445
+
446
  FLBuilderServices._startSettingsLoading( select );
447
+
448
  FLBuilder.ajax( {
449
  action : 'render_service_fields',
450
  node_id : nodeId,
453
  list_type : list_type.val()
454
  }, FLBuilderServices._activeCampaignTypeChangeComplete );
455
  },
456
+
457
  /**
458
  * AJAX callback for when the ActiveCampaign list select is changed.
459
  *
466
  var data = JSON.parse( response ),
467
  wrap = $( '.fl-builder-service-settings-loading' ),
468
  fieldRow = wrap.find( '.fl-builder-service-field-row' );
469
+
470
  fieldRow.after( data.html );
471
  FLBuilderServices._finishSettingsLoading();
472
  }
476
  FLBuilderServices.init();
477
  });
478
 
479
+ })( jQuery );
js/fl-builder-simulate-media-query.js CHANGED
@@ -1,44 +1,44 @@
1
  ( function( $ ) {
2
-
3
  /**
4
- * Helper for simulating media queries without resizing
5
  * the viewport.
6
  *
7
  * Parts based on Respond.js by Scott Jehl (https://github.com/scottjehl/Respond)
8
- *
9
  * @since 1.10
10
  * @class SimulateMediaQuery
11
  */
12
  var SimulateMediaQuery = {
13
-
14
  /**
15
- * Strings to look for in stylesheet URLs that are
16
- * going to be parsed. If a string matches, that
17
  * stylesheet won't be parsed.
18
- *
19
  * @since 1.10
20
  * @property {Array} ignored
21
  */
22
  ignored: [],
23
-
24
  /**
25
- * Strings to look for in stylesheet URLs. If a
26
  * string matches, that stylesheet will be reparsed
27
  * on each updated.
28
- *
29
  * @since 1.10
30
  * @property {Array} reparsed
31
  */
32
  reparsed: [],
33
-
34
  /**
35
  * The current viewport width to simulate.
36
- *
37
  * @since 1.10
38
  * @property {Number} width
39
  */
40
  width: null,
41
-
42
  /**
43
  * A callback to run when an update completes.
44
  *
@@ -46,15 +46,15 @@
46
  * @property {Function} callback
47
  */
48
  callback: null,
49
-
50
  /**
51
- * Cache of original stylesheets.
52
  *
53
  * @since 1.10
54
  * @property {Object} sheets
55
  */
56
  sheets: {},
57
-
58
  /**
59
  * Style tags used for rendering simulated
60
  * media query styles.
@@ -63,7 +63,7 @@
63
  * @property {Array} styles
64
  */
65
  styles: [],
66
-
67
  /**
68
  * AJAX queue for retrieving rules from a sheet.
69
  *
@@ -71,7 +71,7 @@
71
  * @property {Array} queue
72
  */
73
  queue: [],
74
-
75
  /**
76
  * The value of 1em in pixels.
77
  *
@@ -80,7 +80,7 @@
80
  * @property {Number} emPxValue
81
  */
82
  emPxValue: null,
83
-
84
  /**
85
  * Regex for parsing styles.
86
  *
@@ -99,7 +99,7 @@
99
  minmaxwh: /\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,
100
  other: /\([^\)]*\)/g
101
  },
102
-
103
  /**
104
  * Adds strings to look for in stylesheet URLs
105
  * that are going to be parsed. If a string matches,
@@ -109,24 +109,24 @@
109
  * @method ignore
110
  * @param {Array} strings
111
  */
112
- ignore: function( strings )
113
  {
114
  Array.prototype.push.apply( this.ignored, strings );
115
  },
116
-
117
  /**
118
- * Adds strings to look for in stylesheet URLs. If a
119
  * string matches, that stylesheet will be reparsed.
120
  *
121
  * @since 1.10
122
  * @method reparse
123
  * @param {Array} strings
124
  */
125
- reparse: function( strings )
126
  {
127
  Array.prototype.push.apply( this.reparsed, strings );
128
  },
129
-
130
  /**
131
  * Updates all simulated media query rules.
132
  *
@@ -135,13 +135,13 @@
135
  * @param {Number} width The viewport width to simulate.
136
  * @param {Function) callback
137
  */
138
- update: function( width, callback )
139
  {
140
  this.width = undefined === width ? null : width;
141
  this.callback = undefined === callback ? null : callback;
142
-
143
  ForceJQueryValues.update();
144
-
145
  if ( this.queueSheets() ) {
146
  this.runQueue();
147
  }
@@ -149,7 +149,7 @@
149
  this.applyStyles();
150
  }
151
  },
152
-
153
  /**
154
  * Adds all sheets that aren't already cached
155
  * to the AJAX queue.
@@ -158,10 +158,9 @@
158
  * @method queueSheets
159
  * @return {Boolean}
160
  */
161
- queueSheets: function()
162
  {
163
- var head = $( 'head' ),
164
- links = head.find( 'link' ),
165
  sheet = null,
166
  href = null,
167
  media = null,
@@ -169,48 +168,48 @@
169
  ignore = false,
170
  i = 0,
171
  k = 0;
172
-
173
  for ( ; i < links.length; i++ ) {
174
-
175
  sheet = links[ i ];
176
  href = sheet.href;
177
  media = sheet.media;
178
  isCSS = sheet.rel && sheet.rel.toLowerCase() === 'stylesheet';
179
  ignore = false;
180
-
181
  if ( !! href && isCSS ) {
182
-
183
  for ( k = 0; k < this.ignored.length; k++ ) {
184
  if ( href.indexOf( this.ignored[ k ] ) > -1 ) {
185
  ignore = true;
186
  break;
187
  }
188
  }
189
-
190
  if ( ignore ) {
191
  continue;
192
  }
193
-
194
  for ( k = 0; k < this.reparsed.length; k++ ) {
195
  if ( href.indexOf( this.reparsed[ k ] ) > -1 ) {
196
  this.sheets[ href ] = null;
197
  break;
198
  }
199
  }
200
-
201
  if ( undefined === this.sheets[ href ] || ! this.sheets[ href ] ) {
202
  this.queue.push( {
203
  link : links.eq( i ),
204
  href : href,
205
  media : media
206
- } );
207
  }
208
  }
209
  }
210
-
211
  return this.queue.length;
212
  },
213
-
214
  /**
215
  * Send AJAX requests to get styles from all
216
  * stylesheets in the queue.
@@ -218,14 +217,14 @@
218
  * @since 1.10
219
  * @method runQueue
220
  */
221
- runQueue: function()
222
  {
223
  var item;
224
-
225
  if ( this.queue.length ) {
226
-
227
  item = this.queue.shift();
228
-
229
  $.get( item.href, $.proxy( function( response ) {
230
  this.parse( response, item );
231
  this.runQueue();
@@ -235,7 +234,7 @@
235
  this.applyStyles();
236
  }
237
  },
238
-
239
  /**
240
  * Parse a stylesheet that has been returned
241
  * from an AJAX request.
@@ -245,7 +244,7 @@
245
  * @param {String} styles
246
  * @param {Array} item
247
  */
248
- parse: function( styles, item )
249
  {
250
  var re = this.regex,
251
  allQueries = styles.replace( re.comments, '' ).replace( re.keyframes, '' ).match( re.media ),
@@ -267,7 +266,7 @@
267
  else {
268
  all = styles;
269
  }
270
-
271
  this.sheets[ item.href ] = {
272
  link : item.link,
273
  href : item.href,
@@ -277,7 +276,7 @@
277
  };
278
 
279
  for ( i = 0; i < length; i++ ) {
280
-
281
  if ( useMedia ) {
282
  query = item.media;
283
  styles = this.convertURLs( styles, item.href );
@@ -286,11 +285,11 @@
286
  query = allQueries[ i ].match( re.findStyles ) && RegExp.$1;
287
  styles = RegExp.$2 && this.convertURLs( RegExp.$2, item.href );
288
  }
289
-
290
  queries = query.split( ',' );
291
 
292
  for ( k = 0; k < queries.length; k++ ) {
293
-
294
  query = queries[ k ];
295
  media = query.split( '(' )[ 0 ].match( re.only ) && RegExp.$2;
296
 
@@ -300,7 +299,7 @@
300
  if ( query.replace( re.minmaxwh, '' ).match( re.other ) ) {
301
  continue;
302
  }
303
-
304
  this.sheets[ item.href ].queries.push( {
305
  minw : query.match( re.minw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || '' ),
306
  maxw : query.match( re.maxw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || '' ),
@@ -309,14 +308,14 @@
309
  }
310
  }
311
  },
312
-
313
  /**
314
  * Applies simulated media queries to the page.
315
  *
316
  * @since 1.10
317
  * @method applyStyles
318
  */
319
- applyStyles: function()
320
  {
321
  var head = $( 'head' ),
322
  styles = null,
@@ -328,76 +327,76 @@
328
  min = null,
329
  max = null,
330
  added = false;
331
-
332
  this.clearStyles();
333
-
334
  for ( href in this.sheets ) {
335
-
336
  styles = '';
337
  style = $( '<style></style>' );
338
  sheet = this.sheets[ href ];
339
-
340
  if ( ! sheet.queries.length || ! this.width ) {
341
  continue;
342
  }
343
-
344
  styles += sheet.all;
345
-
346
  for ( i = 0; i < sheet.queries.length; i++ ) {
347
-
348
  query = sheet.queries[ i ];
349
  min = query.minw;
350
  max = query.maxw;
351
  added = false;
352
 
353
  if ( min ) {
354
-
355
  min = parseFloat( min ) * ( min.indexOf( 'em' ) > -1 ? this.getEmPxValue() : 1 );
356
-
357
  if ( this.width >= min ) {
358
  styles += query.styles;
359
  added = true;
360
  }
361
  }
362
-
363
  if ( max && ! added ) {
364
-
365
  max = parseFloat( max ) * ( max.indexOf( 'em' ) > -1 ? this.getEmPxValue() : 1 );
366
-
367
  if ( this.width <= max ) {
368
  styles += query.styles;
369
  }
370
  }
371
  }
372
-
373
  this.styles.push( style );
374
  head.append( style );
375
  style.html( styles );
376
  sheet.link.remove();
377
  }
378
  },
379
-
380
  /**
381
- * Clears all style tags used to render
382
  * simulated queries.
383
  *
384
  * @since 1.10
385
  * @method applyStyles
386
  */
387
- clearStyles: function()
388
  {
389
  var head = $( 'head' ),
390
  href = null,
391
  styles = this.styles.slice( 0 );
392
-
393
  this.styles = [];
394
-
395
  for ( href in this.sheets ) {
396
  if ( ! this.sheets[ href ].link.parent().length ) {
397
  head.append( this.sheets[ href ].link );
398
  }
399
  }
400
-
401
  setTimeout( function() {
402
  for ( var i = 0; i < styles.length; i++ ) {
403
  styles[ i ].empty();
@@ -405,7 +404,7 @@
405
  }
406
  }, 50 );
407
  },
408
-
409
  /**
410
  * Converts relative URLs to absolute URLs since the
411
  * styles will be added to a <style> tag.
@@ -415,17 +414,17 @@
415
  * @param {String} styles
416
  * @param {String} href
417
  */
418
- convertURLs: function( styles, href )
419
  {
420
  href = href.substring( 0, href.lastIndexOf( '/' ) );
421
 
422
- if ( href.length ) {
423
- href += '/';
424
  }
425
-
426
  return styles.replace( this.regex.urls, "$1" + href + "$2$3" );
427
  },
428
-
429
  /**
430
  * Returns the value of 1em in pixels.
431
  *
@@ -433,12 +432,12 @@
433
  * @method getEmPixelValue
434
  * @return {Number}
435
  */
436
- getEmPxValue: function()
437
  {
438
  if ( this.emPxValue ) {
439
  return this.emPxValue;
440
  }
441
-
442
  var value = null,
443
  doc = window.document,
444
  docElem = doc.documentElement,
@@ -479,7 +478,7 @@
479
 
480
  // Restore the original values.
481
  docElem.style.fontSize = originalHTMLFontSize;
482
-
483
  if ( originalBodyFontSize ) {
484
  body.style.fontSize = originalBodyFontSize;
485
  }
@@ -492,18 +491,18 @@
492
  return value;
493
  }
494
  };
495
-
496
  /**
497
  * Force jQuery functions to return certain values
498
- * based on the current simulated media query.
499
- *
500
  * @since 1.10
501
  * @class ForceJQueryValues
502
  */
503
  var ForceJQueryValues = {
504
-
505
  /**
506
- * jQuery functions that have been overwritten. Saved for
507
  * restoring them later.
508
  *
509
  * @since 1.10
@@ -511,7 +510,7 @@
511
  * @property {Object} _functions
512
  */
513
  _functions: null,
514
-
515
  /**
516
  * Updates forced jQuery methods.
517
  *
@@ -521,17 +520,17 @@
521
  update: function()
522
  {
523
  var fn;
524
-
525
  // Cache the original jQuery functions.
526
  if ( ! this._functions ) {
527
-
528
  this._functions = {};
529
-
530
  for ( fn in ForceJQueryFunctions ) {
531
  this._functions[ fn ] = jQuery.fn[ fn ];
532
  }
533
  }
534
-
535
  // Reset the jQuery functions if no width, otherwise, override them.
536
  if ( ! SimulateMediaQuery.width ) {
537
  for ( fn in this._functions ) {
@@ -545,16 +544,16 @@
545
  }
546
  }
547
  };
548
-
549
  /**
550
- * jQuery functions that get overwritten by
551
  * the ForceJQueryValues class.
552
- *
553
  * @since 1.10
554
  * @class ForceJQueryFunctions
555
  */
556
  var ForceJQueryFunctions = {
557
-
558
  /**
559
  * @since 1.10
560
  * @method width
@@ -562,17 +561,17 @@
562
  width: function( val )
563
  {
564
  if ( undefined != val ) {
565
- return ForceJQueryValues._functions['width'].call( this, val );
566
  }
567
-
568
  if ( $.isWindow( this[0] ) ) {
569
  return SimulateMediaQuery.width;
570
  }
571
-
572
- return ForceJQueryValues._functions['width'].call( this );
573
  }
574
  };
575
-
576
  /**
577
  * Public API
578
  */
@@ -587,5 +586,5 @@
587
  SimulateMediaQuery.update( width, callback );
588
  }
589
  };
590
-
591
- } )( jQuery );
1
  ( function( $ ) {
2
+
3
  /**
4
+ * Helper for simulating media queries without resizing
5
  * the viewport.
6
  *
7
  * Parts based on Respond.js by Scott Jehl (https://github.com/scottjehl/Respond)
8
+ *
9
  * @since 1.10
10
  * @class SimulateMediaQuery
11
  */
12
  var SimulateMediaQuery = {
13
+
14
  /**
15
+ * Strings to look for in stylesheet URLs that are
16
+ * going to be parsed. If a string matches, that
17
  * stylesheet won't be parsed.
18
+ *
19
  * @since 1.10
20
  * @property {Array} ignored
21
  */
22
  ignored: [],
23
+
24
  /**
25
+ * Strings to look for in stylesheet URLs. If a
26
  * string matches, that stylesheet will be reparsed
27
  * on each updated.
28
+ *
29
  * @since 1.10
30
  * @property {Array} reparsed
31
  */
32
  reparsed: [],
33
+
34
  /**
35
  * The current viewport width to simulate.
36
+ *
37
  * @since 1.10
38
  * @property {Number} width
39
  */
40
  width: null,
41
+
42
  /**
43
  * A callback to run when an update completes.
44
  *
46
  * @property {Function} callback
47
  */
48
  callback: null,
49
+
50
  /**
51
+ * Cache of original stylesheets.
52
  *
53
  * @since 1.10
54
  * @property {Object} sheets
55
  */
56
  sheets: {},
57
+
58
  /**
59
  * Style tags used for rendering simulated
60
  * media query styles.
63
  * @property {Array} styles
64
  */
65
  styles: [],
66
+
67
  /**
68
  * AJAX queue for retrieving rules from a sheet.
69
  *
71
  * @property {Array} queue
72
  */
73
  queue: [],
74
+
75
  /**
76
  * The value of 1em in pixels.
77
  *
80
  * @property {Number} emPxValue
81
  */
82
  emPxValue: null,
83
+
84
  /**
85
  * Regex for parsing styles.
86
  *
99
  minmaxwh: /\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,
100
  other: /\([^\)]*\)/g
101
  },
102
+
103
  /**
104
  * Adds strings to look for in stylesheet URLs
105
  * that are going to be parsed. If a string matches,
109
  * @method ignore
110
  * @param {Array} strings
111
  */
112
+ ignore: function( strings )
113
  {
114
  Array.prototype.push.apply( this.ignored, strings );
115
  },
116
+
117
  /**
118
+ * Adds strings to look for in stylesheet URLs. If a
119
  * string matches, that stylesheet will be reparsed.
120
  *
121
  * @since 1.10
122
  * @method reparse
123
  * @param {Array} strings
124
  */
125
+ reparse: function( strings )
126
  {
127
  Array.prototype.push.apply( this.reparsed, strings );
128
  },
129
+
130
  /**
131
  * Updates all simulated media query rules.
132
  *
135
  * @param {Number} width The viewport width to simulate.
136
  * @param {Function) callback
137
  */
138
+ update: function( width, callback )
139
  {
140
  this.width = undefined === width ? null : width;
141
  this.callback = undefined === callback ? null : callback;
142
+
143
  ForceJQueryValues.update();
144
+
145
  if ( this.queueSheets() ) {
146
  this.runQueue();
147
  }
149
  this.applyStyles();
150
  }
151
  },
152
+
153
  /**
154
  * Adds all sheets that aren't already cached
155
  * to the AJAX queue.
158
  * @method queueSheets
159
  * @return {Boolean}
160
  */
161
+ queueSheets: function()
162
  {
163
+ var links = $( 'link' ),
 
164
  sheet = null,
165
  href = null,
166
  media = null,
168
  ignore = false,
169
  i = 0,
170
  k = 0;
171
+
172
  for ( ; i < links.length; i++ ) {
173
+
174
  sheet = links[ i ];
175
  href = sheet.href;
176
  media = sheet.media;
177
  isCSS = sheet.rel && sheet.rel.toLowerCase() === 'stylesheet';
178
  ignore = false;
179
+
180
  if ( !! href && isCSS ) {
181
+
182
  for ( k = 0; k < this.ignored.length; k++ ) {
183
  if ( href.indexOf( this.ignored[ k ] ) > -1 ) {
184
  ignore = true;
185
  break;
186
  }
187
  }
188
+
189
  if ( ignore ) {
190
  continue;
191
  }
192
+
193
  for ( k = 0; k < this.reparsed.length; k++ ) {
194
  if ( href.indexOf( this.reparsed[ k ] ) > -1 ) {
195
  this.sheets[ href ] = null;
196
  break;
197
  }
198
  }
199
+
200
  if ( undefined === this.sheets[ href ] || ! this.sheets[ href ] ) {
201
  this.queue.push( {
202
  link : links.eq( i ),
203
  href : href,
204
  media : media
205
+ } );
206
  }
207
  }
208
  }
209
+
210
  return this.queue.length;
211
  },
212
+
213
  /**
214
  * Send AJAX requests to get styles from all
215
  * stylesheets in the queue.
217
  * @since 1.10
218
  * @method runQueue
219
  */
220
+ runQueue: function()
221
  {
222
  var item;
223
+
224
  if ( this.queue.length ) {
225
+
226
  item = this.queue.shift();
227
+
228
  $.get( item.href, $.proxy( function( response ) {
229
  this.parse( response, item );
230
  this.runQueue();
234
  this.applyStyles();
235
  }
236
  },
237
+
238
  /**
239
  * Parse a stylesheet that has been returned
240
  * from an AJAX request.
244
  * @param {String} styles
245
  * @param {Array} item
246
  */
247
+ parse: function( styles, item )
248
  {
249
  var re = this.regex,
250
  allQueries = styles.replace( re.comments, '' ).replace( re.keyframes, '' ).match( re.media ),
266
  else {
267
  all = styles;
268
  }
269
+
270
  this.sheets[ item.href ] = {
271
  link : item.link,
272
  href : item.href,
276
  };
277
 
278
  for ( i = 0; i < length; i++ ) {
279
+
280
  if ( useMedia ) {
281
  query = item.media;
282
  styles = this.convertURLs( styles, item.href );
285
  query = allQueries[ i ].match( re.findStyles ) && RegExp.$1;
286
  styles = RegExp.$2 && this.convertURLs( RegExp.$2, item.href );
287
  }
288
+
289
  queries = query.split( ',' );
290
 
291
  for ( k = 0; k < queries.length; k++ ) {
292
+
293
  query = queries[ k ];
294
  media = query.split( '(' )[ 0 ].match( re.only ) && RegExp.$2;
295
 
299
  if ( query.replace( re.minmaxwh, '' ).match( re.other ) ) {
300
  continue;
301
  }
302
+
303
  this.sheets[ item.href ].queries.push( {
304
  minw : query.match( re.minw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || '' ),
305
  maxw : query.match( re.maxw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || '' ),
308
  }
309
  }
310
  },
311
+
312
  /**
313
  * Applies simulated media queries to the page.
314
  *
315
  * @since 1.10
316
  * @method applyStyles
317
  */
318
+ applyStyles: function()
319
  {
320
  var head = $( 'head' ),
321
  styles = null,
327
  min = null,
328
  max = null,
329
  added = false;
330
+
331
  this.clearStyles();
332
+
333
  for ( href in this.sheets ) {
334
+
335
  styles = '';
336
  style = $( '<style></style>' );
337
  sheet = this.sheets[ href ];
338
+
339
  if ( ! sheet.queries.length || ! this.width ) {
340
  continue;
341
  }
342
+
343
  styles += sheet.all;
344
+
345
  for ( i = 0; i < sheet.queries.length; i++ ) {
346
+
347
  query = sheet.queries[ i ];
348
  min = query.minw;
349
  max = query.maxw;
350
  added = false;
351
 
352
  if ( min ) {
353
+
354
  min = parseFloat( min ) * ( min.indexOf( 'em' ) > -1 ? this.getEmPxValue() : 1 );
355
+
356
  if ( this.width >= min ) {
357
  styles += query.styles;
358
  added = true;
359
  }
360
  }
361
+
362
  if ( max && ! added ) {
363
+
364
  max = parseFloat( max ) * ( max.indexOf( 'em' ) > -1 ? this.getEmPxValue() : 1 );
365
+
366
  if ( this.width <= max ) {
367
  styles += query.styles;
368
  }
369
  }
370
  }
371
+
372
  this.styles.push( style );
373
  head.append( style );
374
  style.html( styles );
375
  sheet.link.remove();
376
  }
377
  },
378
+
379
  /**
380
+ * Clears all style tags used to render
381
  * simulated queries.
382
  *
383
  * @since 1.10
384
  * @method applyStyles
385
  */
386
+ clearStyles: function()
387
  {
388
  var head = $( 'head' ),
389
  href = null,
390
  styles = this.styles.slice( 0 );
391
+
392
  this.styles = [];
393
+
394
  for ( href in this.sheets ) {
395
  if ( ! this.sheets[ href ].link.parent().length ) {
396
  head.append( this.sheets[ href ].link );
397
  }
398
  }
399
+
400
  setTimeout( function() {
401
  for ( var i = 0; i < styles.length; i++ ) {
402
  styles[ i ].empty();
404
  }
405
  }, 50 );
406
  },
407
+
408
  /**
409
  * Converts relative URLs to absolute URLs since the
410
  * styles will be added to a <style> tag.
414
  * @param {String} styles
415
  * @param {String} href
416
  */
417
+ convertURLs: function( styles, href )
418
  {
419
  href = href.substring( 0, href.lastIndexOf( '/' ) );
420
 
421
+ if ( href.length ) {
422
+ href += '/';
423
  }
424
+
425
  return styles.replace( this.regex.urls, "$1" + href + "$2$3" );
426
  },
427
+
428
  /**
429
  * Returns the value of 1em in pixels.
430
  *
432
  * @method getEmPixelValue
433
  * @return {Number}
434
  */
435
+ getEmPxValue: function()
436
  {
437
  if ( this.emPxValue ) {
438
  return this.emPxValue;
439
  }
440
+
441
  var value = null,
442
  doc = window.document,
443
  docElem = doc.documentElement,
478
 
479
  // Restore the original values.
480
  docElem.style.fontSize = originalHTMLFontSize;
481
+
482
  if ( originalBodyFontSize ) {
483
  body.style.fontSize = originalBodyFontSize;
484
  }
491
  return value;
492
  }
493
  };
494
+
495
  /**
496
  * Force jQuery functions to return certain values
497
+ * based on the current simulated media query.
498
+ *
499
  * @since 1.10
500
  * @class ForceJQueryValues
501
  */
502
  var ForceJQueryValues = {
503
+
504
  /**
505
+ * jQuery functions that have been overwritten. Saved for
506
  * restoring them later.
507
  *
508
  * @since 1.10
510
  * @property {Object} _functions
511
  */
512
  _functions: null,
513
+
514
  /**
515
  * Updates forced jQuery methods.
516
  *
520
  update: function()
521
  {
522
  var fn;
523
+
524
  // Cache the original jQuery functions.
525
  if ( ! this._functions ) {
526
+
527
  this._functions = {};
528
+
529
  for ( fn in ForceJQueryFunctions ) {
530
  this._functions[ fn ] = jQuery.fn[ fn ];
531
  }
532
  }
533
+
534
  // Reset the jQuery functions if no width, otherwise, override them.
535
  if ( ! SimulateMediaQuery.width ) {
536
  for ( fn in this._functions ) {
544
  }
545
  }
546
  };
547
+
548
  /**
549
+ * jQuery functions that get overwritten by
550
  * the ForceJQueryValues class.
551
+ *
552
  * @since 1.10
553
  * @class ForceJQueryFunctions
554
  */
555
  var ForceJQueryFunctions = {
556
+
557
  /**
558
  * @since 1.10
559
  * @method width
561
  width: function( val )
562
  {
563
  if ( undefined != val ) {
564
+ return ForceJQueryValues._functions['width'].call( this, val );
565
  }
566
+
567
  if ( $.isWindow( this[0] ) ) {
568
  return SimulateMediaQuery.width;
569
  }
570
+
571
+ return ForceJQueryValues._functions['width'].call( this );
572
  }
573
  };
574
+
575
  /**
576
  * Public API
577
  */
586
  SimulateMediaQuery.update( width, callback );
587
  }
588
  };
589
+
590
+ } )( jQuery );
js/fl-builder-tour.js CHANGED
@@ -1,5 +1,5 @@
1
  (function( $ ) {
2
-
3
  /**
4
  * Logic for the builder's help tour.
5
  *
@@ -7,7 +7,7 @@
7
  * @since 1.4.9
8
  */
9
  FLBuilderTour = {
10
-
11
  /**
12
  * A reference to the Bootstrap Tour object.
13
  *
@@ -16,7 +16,7 @@
16
  * @property {Tour} _tour
17
  */
18
  _tour: null,
19
-
20
  /**
21
  * Starts the tour or restarts it if it
22
  * has already run.
@@ -33,10 +33,15 @@
33
  else {
34
  FLBuilderTour._tour.restart();
35
  }
36
-
 
 
 
 
 
37
  FLBuilderTour._tour.start();
38
  },
39
-
40
  /**
41
  * Returns a config object for the tour.
42
  *
@@ -57,47 +62,32 @@
57
  steps : [
58
  {
59
  animation : false,
60
- element : '.fl-builder-bar',
61
- placement : 'bottom',
62
  title : FLBuilderStrings.tourTemplatesTitle,
63
  content : FLBuilderStrings.tourTemplates,
64
- onShown : function() {
65
- if ( 0 === $( '.fl-template-selector' ).length ) {
66
- $( '.popover[class*=tour-]' ).css( 'visibility', 'hidden' );
67
- FLBuilder._showTemplateSelector();
68
- }
69
- else {
70
- FLBuilderTour._templateSelectorLoaded();
71
- }
72
- }
73
  },
74
  {
75
  animation : false,
76
- element : '#fl-builder-blocks-rows .fl-builder-blocks-section-title',
77
  placement : 'left',
78
  title : FLBuilderStrings.tourAddRowsTitle,
79
  content : FLBuilderStrings.tourAddRows,
80
  onShow : function() {
81
- FLBuilderTour._dimSection( 'body' );
82
- FLBuilderTour._dimSection( '.fl-builder-bar' );
83
- FLBuilder._showPanel();
84
- $( '.fl-template-selector .fl-builder-settings-cancel' ).trigger( 'click' );
85
- $( '#fl-builder-blocks-rows .fl-builder-blocks-section-title' ).trigger( 'click' );
86
  }
87
  },
88
  {
89
  animation : false,
90
- element : '#fl-builder-blocks-basic .fl-builder-blocks-section-title',
91
  placement : 'left',
92
  title : FLBuilderStrings.tourAddContentTitle,
93
  content : FLBuilderStrings.tourAddContent,
94
  onShow : function() {
95
- FLBuilderTour._dimSection( 'body' );
96
- FLBuilderTour._dimSection( '.fl-builder-bar' );
97
- FLBuilder._showPanel();
98
- $( '#fl-builder-blocks-basic .fl-builder-blocks-section-title' ).trigger( 'click' );
99
- $( '.fl-row' ).eq( 0 ).trigger( 'mouseleave' );
100
- $( '.fl-module' ).eq( 0 ).trigger( 'mouseleave' );
101
  }
102
  },
103
  {
@@ -128,14 +118,14 @@
128
  },
129
  {
130
  animation : false,
131
- element : '.fl-builder-add-content-button',
132
  placement : 'bottom',
133
  title : FLBuilderStrings.tourAddContentButtonTitle,
134
  content : FLBuilderStrings.tourAddContentButton,
135
  onShow : function() {
136
  FLBuilderTour._dimSection( 'body' );
137
  $( '.fl-row' ).eq( 0 ).trigger( 'mouseleave' );
138
- $( '.fl-module' ).eq( 0 ).trigger( 'mouseleave' );
139
  }
140
  },
141
  {
@@ -178,7 +168,7 @@
178
  }
179
  ]
180
  };
181
-
182
  // Remove the first step if no templates.
183
  if( FLBuilderConfig.lite ) {
184
  config.steps.shift();
@@ -189,10 +179,9 @@
189
  else if ( 'fl-builder-template' == FLBuilderConfig.postType ) {
190
  config.steps.shift();
191
  }
192
-
193
  return config;
194
  },
195
-
196
  /**
197
  * Callback for when the tour starts.
198
  *
@@ -203,17 +192,17 @@
203
  _onStart: function()
204
  {
205
  var body = $( 'body' );
206
-
 
207
  body.append( '<div class="fl-builder-tour-mask"></div>' );
208
- body.on( 'fl-builder.template-selector-loaded', FLBuilderTour._templateSelectorLoaded );
209
-
210
  if ( 0 === $( '.fl-row' ).length && 'module' != FLBuilderConfig.userTemplateType ) {
211
  $( '.fl-builder-content' ).append( '<div class="fl-builder-tour-demo-content fl-row fl-row-fixed-width fl-row-bg-none"> <div class="fl-row-content-wrap"> <div class="fl-row-content fl-row-fixed-width fl-node-content"> <div class="fl-col-group"> <div class="fl-col" style="width:100%"> <div class="fl-col-content fl-node-content"> <div class="fl-module fl-module-rich-text" data-type="rich-text" data-name="Text Editor"> <div class="fl-module-content fl-node-content"> <div class="fl-rich-text"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pellentesque ut lorem non cursus. Sed mauris nunc, porttitor iaculis lorem a, sollicitudin lacinia sapien. Proin euismod orci lacus, et sollicitudin leo posuere ac. In hac habitasse platea dictumst. Maecenas elit magna, consequat in turpis suscipit, ultrices rhoncus arcu. Phasellus finibus sapien nec elit tempus venenatis. Maecenas tincidunt sapien non libero maximus, in aliquam felis tincidunt. Mauris mollis ultricies facilisis. Duis condimentum dignissim tortor sit amet facilisis. Aenean gravida lacus eu risus molestie egestas. Donec ut dolor dictum, fringilla metus malesuada, viverra nunc. Maecenas ut purus ac justo aliquet lacinia. Cras vestibulum elementum tincidunt. Maecenas mattis tortor neque, consectetur dignissim neque tempor nec.</p></div> </div> </div> </div> </div> </div> </div> </div> </div>' );
212
  FLBuilder._setupEmptyLayout();
213
  FLBuilder._highlightEmptyCols();
214
  }
215
  },
216
-
217
  /**
218
  * Callback for when the tour is navigated
219
  * to the previous step.
@@ -226,7 +215,7 @@
226
  {
227
  $( '.fl-builder-tour-dimmed' ).remove();
228
  },
229
-
230
  /**
231
  * Callback for when the tour is navigated
232
  * to the next step.
@@ -239,7 +228,7 @@
239
  {
240
  $( '.fl-builder-tour-dimmed' ).remove();
241
  },
242
-
243
  /**
244
  * Callback for when the tour ends.
245
  *
@@ -259,7 +248,7 @@
259
  FLBuilder._showPanel();
260
  FLBuilder._initTemplateSelector();
261
  },
262
-
263
  /**
264
  * Dims a section of the page.
265
  *
@@ -272,27 +261,7 @@
272
  {
273
  $( selector ).find( '.fl-builder-tour-dimmed' ).remove();
274
  $( selector ).append( '<div class="fl-builder-tour-dimmed"></div>' );
275
- },
276
-
277
- /**
278
- * Fires when the template selector loads
279
- * and positions the popup.
280
- *
281
- * @since 1.4.9
282
- * @access private
283
- * @method _templateSelectorLoaded
284
- */
285
- _templateSelectorLoaded: function()
286
- {
287
- var header = $( '.fl-builder-settings-lightbox .fl-lightbox-header' ),
288
- height = header.height(),
289
- top = header.offset().top + 75;
290
-
291
- $( '.popover[class*=tour-]' ).css({
292
- top: ( top + height) + 'px',
293
- visibility: 'visible'
294
- });
295
  }
296
  };
297
 
298
- })( jQuery );
1
  (function( $ ) {
2
+
3
  /**
4
  * Logic for the builder's help tour.
5
  *
7
  * @since 1.4.9
8
  */
9
  FLBuilderTour = {
10
+
11
  /**
12
  * A reference to the Bootstrap Tour object.
13
  *
16
  * @property {Tour} _tour
17
  */
18
  _tour: null,
19
+
20
  /**
21
  * Starts the tour or restarts it if it
22
  * has already run.
33
  else {
34
  FLBuilderTour._tour.restart();
35
  }
36
+
37
+ // Save existing settings first if any exist. Don't proceed if it fails.
38
+ if ( ! FLBuilder._triggerSettingsSave( false, true ) ) {
39
+ return;
40
+ }
41
+
42
  FLBuilderTour._tour.start();
43
  },
44
+
45
  /**
46
  * Returns a config object for the tour.
47
  *
62
  steps : [
63
  {
64
  animation : false,
65
+ element : '.fl-builder--content-library-panel',
66
+ placement : 'left',
67
  title : FLBuilderStrings.tourTemplatesTitle,
68
  content : FLBuilderStrings.tourTemplates,
69
+ onShow : function() {
70
+ FLBuilder.ContentPanel.show('templates');
71
+ },
 
 
 
 
 
 
72
  },
73
  {
74
  animation : false,
75
+ element : '.fl-builder--content-library-panel',
76
  placement : 'left',
77
  title : FLBuilderStrings.tourAddRowsTitle,
78
  content : FLBuilderStrings.tourAddRows,
79
  onShow : function() {
80
+ FLBuilder.ContentPanel.show('rows');
 
 
 
 
81
  }
82
  },
83
  {
84
  animation : false,
85
+ element : '.fl-builder--content-library-panel',
86
  placement : 'left',
87
  title : FLBuilderStrings.tourAddContentTitle,
88
  content : FLBuilderStrings.tourAddContent,
89
  onShow : function() {
90
+ FLBuilder.ContentPanel.show('modules');
 
 
 
 
 
91
  }
92
  },
93
  {
118
  },
119
  {
120
  animation : false,
121
+ element : '.fl-builder-content-panel-button',
122
  placement : 'bottom',
123
  title : FLBuilderStrings.tourAddContentButtonTitle,
124
  content : FLBuilderStrings.tourAddContentButton,
125
  onShow : function() {
126
  FLBuilderTour._dimSection( 'body' );
127
  $( '.fl-row' ).eq( 0 ).trigger( 'mouseleave' );
128
+ $( '.fl-module' ).eq( 0 ).trigger( 'mouseleave' );
129
  }
130
  },
131
  {
168
  }
169
  ]
170
  };
171
+
172
  // Remove the first step if no templates.
173
  if( FLBuilderConfig.lite ) {
174
  config.steps.shift();
179
  else if ( 'fl-builder-template' == FLBuilderConfig.postType ) {
180
  config.steps.shift();
181
  }
 
182
  return config;
183
  },
184
+
185
  /**
186
  * Callback for when the tour starts.
187
  *
192
  _onStart: function()
193
  {
194
  var body = $( 'body' );
195
+ body.scrollTop(0);
196
+
197
  body.append( '<div class="fl-builder-tour-mask"></div>' );
198
+
 
199
  if ( 0 === $( '.fl-row' ).length && 'module' != FLBuilderConfig.userTemplateType ) {
200
  $( '.fl-builder-content' ).append( '<div class="fl-builder-tour-demo-content fl-row fl-row-fixed-width fl-row-bg-none"> <div class="fl-row-content-wrap"> <div class="fl-row-content fl-row-fixed-width fl-node-content"> <div class="fl-col-group"> <div class="fl-col" style="width:100%"> <div class="fl-col-content fl-node-content"> <div class="fl-module fl-module-rich-text" data-type="rich-text" data-name="Text Editor"> <div class="fl-module-content fl-node-content"> <div class="fl-rich-text"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pellentesque ut lorem non cursus. Sed mauris nunc, porttitor iaculis lorem a, sollicitudin lacinia sapien. Proin euismod orci lacus, et sollicitudin leo posuere ac. In hac habitasse platea dictumst. Maecenas elit magna, consequat in turpis suscipit, ultrices rhoncus arcu. Phasellus finibus sapien nec elit tempus venenatis. Maecenas tincidunt sapien non libero maximus, in aliquam felis tincidunt. Mauris mollis ultricies facilisis. Duis condimentum dignissim tortor sit amet facilisis. Aenean gravida lacus eu risus molestie egestas. Donec ut dolor dictum, fringilla metus malesuada, viverra nunc. Maecenas ut purus ac justo aliquet lacinia. Cras vestibulum elementum tincidunt. Maecenas mattis tortor neque, consectetur dignissim neque tempor nec.</p></div> </div> </div> </div> </div> </div> </div> </div> </div>' );
201
  FLBuilder._setupEmptyLayout();
202
  FLBuilder._highlightEmptyCols();
203
  }
204
  },
205
+
206
  /**
207
  * Callback for when the tour is navigated
208
  * to the previous step.
215
  {
216
  $( '.fl-builder-tour-dimmed' ).remove();
217
  },
218
+
219
  /**
220
  * Callback for when the tour is navigated
221
  * to the next step.
228
  {
229
  $( '.fl-builder-tour-dimmed' ).remove();
230
  },
231
+
232
  /**
233
  * Callback for when the tour ends.
234
  *
248
  FLBuilder._showPanel();
249
  FLBuilder._initTemplateSelector();
250
  },
251
+
252
  /**
253
  * Dims a section of the page.
254
  *
261
  {
262
  $( selector ).find( '.fl-builder-tour-dimmed' ).remove();
263
  $( selector ).append( '<div class="fl-builder-tour-dimmed"></div>' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  }
265
  };
266
 
267
+ })( jQuery );
js/fl-builder-ui-main-menu.js ADDED
@@ -0,0 +1,418 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($, FLBuilder) {
2
+
3
+ /**
4
+ * Base prototype for views in the menu
5
+ */
6
+ var PanelView = FLExtendableObject.create({
7
+
8
+ templateName: "fl-main-menu-panel-view",
9
+
10
+ name: "Untitled View",
11
+
12
+ isShowing: false,
13
+
14
+ isRootView: false,
15
+
16
+ items: {},
17
+
18
+ /**
19
+ * Initialize the view
20
+ *
21
+ * @return void
22
+ */
23
+ init: function() {
24
+ this.template = wp.template(this.templateName);
25
+ },
26
+
27
+ /**
28
+ * Render the view
29
+ *
30
+ * @return String
31
+ */
32
+ render: function() {
33
+ return this.template(this);
34
+ },
35
+
36
+ /**
37
+ * Setup Events
38
+ *
39
+ * @return void
40
+ */
41
+ bindEvents: function() {
42
+ this.$items = this.$el.find('.fl-builder--menu-item');
43
+ },
44
+
45
+ /**
46
+ * Make this the current view
47
+ *
48
+ * @return void
49
+ */
50
+ show: function() {
51
+ this.$el.addClass('is-showing');
52
+ },
53
+
54
+ /**
55
+ * Resign the active view
56
+ *
57
+ * @return void
58
+ */
59
+ hide: function() {
60
+ this.$el.removeClass('is-showing');
61
+ },
62
+
63
+ /**
64
+ * Handle transitioning the view in
65
+ *
66
+ * @return void
67
+ */
68
+ transitionIn: function(reverse) {
69
+ requestAnimationFrame( this.show.bind(this) );
70
+ },
71
+
72
+ /**
73
+ * Handle transition away from the view
74
+ *
75
+ * @return void
76
+ */
77
+ transitionOut: function(reverse) {
78
+ this.hide();
79
+ },
80
+ });
81
+
82
+ /**
83
+ * Menu Panel
84
+ */
85
+ var MainMenuPanel = FLExtendableObject.create({
86
+
87
+ templateName: 'fl-main-menu-panel',
88
+
89
+ template: null,
90
+
91
+ menu: null,
92
+
93
+ views: {},
94
+
95
+ viewNavigationStack: [],
96
+
97
+ isShowing: false,
98
+
99
+ shouldShowTabs: false,
100
+
101
+ /**
102
+ * Setup and render the menu
103
+ *
104
+ * @return void
105
+ */
106
+ init: function() {
107
+
108
+ // Render Panel
109
+ this.template = wp.template(this.templateName);
110
+ $('body').prepend( this.template(this) );
111
+ this.$el = $('.fl-builder--main-menu-panel');
112
+ this.$el.find('.fl-builder--main-menu-panel-views').html('');
113
+
114
+ // Render Views
115
+ for (var key in FLBuilderConfig.mainMenu) {
116
+ this.renderPanel( key );
117
+ var hook = 'render' + key.charAt(0).toUpperCase() + key.slice(1) + 'Panel';
118
+
119
+ FLBuilder.addHook( hook, $.proxy( function(){
120
+ this.renderPanel( key );
121
+ }, this ) );
122
+ }
123
+
124
+ // Event Listeners
125
+ $('body').on('click', '.fl-builder--main-menu-panel .pop-view', this.goToPreviousView.bind(this));
126
+
127
+ this.$tabs = this.$el.find('.fl-builder--tabs > span'); /* on purpose */
128
+ this.$tabs.on('click', this.onItemClick.bind(this));
129
+
130
+ this.$barTitle = $('.fl-builder-bar-title'); /* on purpose */
131
+ $('body').on('click', '.fl-builder-bar-title', this.toggle.bind(this));
132
+
133
+ var hide = this.hide.bind(this);
134
+ FLBuilder.addHook('didShowPublishActions', hide);
135
+ FLBuilder.addHook('didBeginSearch', hide);
136
+ FLBuilder.addHook('didBeginPreview', hide);
137
+ FLBuilder.addHook('didShowContentPanel', hide);
138
+ FLBuilder.addHook('endEditingSession', hide);
139
+ FLBuilder.addHook('didFocusSearchBox', hide);
140
+ FLBuilder.addHook('didEnterRevisionPreview', hide);
141
+ FLBuilder.addHook('didFailSettingsSave', hide);
142
+ FLBuilder.addHook('showKeyboardShortcuts', hide);
143
+
144
+ this.$mask = $('.fl-builder--main-menu-panel-mask');
145
+ this.$mask.on('click', hide);
146
+
147
+ Tools.init();
148
+ Help.init();
149
+ },
150
+
151
+ /**
152
+ * Render the panel
153
+ *
154
+ * @param String key
155
+ * @return void
156
+ */
157
+ renderPanel: function( key ) {
158
+ var data, view, $html;
159
+
160
+ $( 'fl-builder--main-menu-panel-view[data-name="' + key + '"]' ).remove();
161
+ data = FLBuilderConfig.mainMenu[ key ];
162
+ data.handle = key;
163
+ view = PanelView.create( data );
164
+ view.init();
165
+ $html = $( view.render() );
166
+ view.$el = $html;
167
+ $( '.fl-builder--main-menu-panel-views' ).append( $html );
168
+ view.bindEvents();
169
+ view.$el.find( '.fl-builder--menu-item' ).on( 'click', this.onItemClick.bind( this ) );
170
+
171
+ if ( view.isRootView ) {
172
+ this.rootView = view;
173
+ this.currentView = view;
174
+ }
175
+
176
+ this.views[ key ] = view;
177
+ },
178
+
179
+ /**
180
+ * Show the menu
181
+ *
182
+ * @return void
183
+ */
184
+ show: function() {
185
+ if (this.isShowing) return;
186
+ this.$el.addClass('is-showing');
187
+ this.$barTitle.addClass('is-showing-menu');
188
+ this.currentView.transitionIn();
189
+ this.isShowing = true;
190
+ this.$mask.show();
191
+ FLBuilder.triggerHook('didOpenMainMenu');
192
+ },
193
+
194
+ /**
195
+ * Hide the menu
196
+ *
197
+ * @return void
198
+ */
199
+ hide: function() {
200
+ if (!this.isShowing) return;
201
+ this.$el.removeClass('is-showing');
202
+ this.$barTitle.removeClass('is-showing-menu');
203
+ this.isShowing = false;
204
+ this.resetViews();
205
+ this.$mask.hide();
206
+ },
207
+
208
+ /**
209
+ * Toggle show/hide the menu
210
+ *
211
+ * @return void
212
+ */
213
+ toggle: function() {
214
+ if (this.isShowing) {
215
+ this.hide();
216
+ } else {
217
+ this.show();
218
+ }
219
+ },
220
+
221
+ /**
222
+ * Handle item click
223
+ *
224
+ * @param {Event} e
225
+ * @return void
226
+ */
227
+ onItemClick: function(e) {
228
+ var $item = $(e.currentTarget),
229
+ type = $item.data('type');
230
+
231
+ switch (type) {
232
+ case "view":
233
+ var name = $item.data('view');
234
+ this.goToView(name);
235
+ break;
236
+ case "event":
237
+ var hook = $item.data('event');
238
+ FLBuilder.triggerHook(hook, $item);
239
+ break;
240
+ case "link":
241
+ // follow link
242
+ break;
243
+ }
244
+ },
245
+
246
+ /**
247
+ * Display a specific view
248
+ *
249
+ * @param String name
250
+ * @return void
251
+ */
252
+ goToView: function(name) {
253
+
254
+ var currentView = this.currentView;
255
+ var newView = this.views[name];
256
+
257
+ currentView.transitionOut();
258
+ newView.transitionIn();
259
+ this.currentView = newView;
260
+ this.viewNavigationStack.push(currentView);
261
+ },
262
+
263
+ /**
264
+ * Pop a view off the stack
265
+ *
266
+ * @return void
267
+ */
268
+ goToPreviousView: function() {
269
+ var currentView = this.currentView;
270
+ var newView = this.viewNavigationStack.pop();
271
+ currentView.transitionOut(true);
272
+ newView.transitionIn(true);
273
+ this.currentView = newView;
274
+ //var item = newView.$el.find('.fl-builder--menu-item:first-child').eq(0).trigger('focus');
275
+ $('.fl-builder-bar-title-caret').focus();
276
+ },
277
+
278
+ /**
279
+ * Reset to root view
280
+ *
281
+ * @return void
282
+ */
283
+ resetViews: function() {
284
+ if (this.currentView != this.rootView ) {
285
+ this.currentView.hide();
286
+ this.rootView.show();
287
+ this.currentView = this.rootView;
288
+ this.viewNavigationStack = [];
289
+ }
290
+ },
291
+ });
292
+
293
+ FLBuilder.MainMenu = MainMenuPanel;
294
+
295
+ /**
296
+ * Handle tools menu actions
297
+ */
298
+ var Tools = {
299
+
300
+ /**
301
+ * Setup listeners for tools actions
302
+ * @return void
303
+ */
304
+ init: function() {
305
+ FLBuilder.addHook('saveTemplate', this.saveTemplate.bind(this));
306
+ FLBuilder.addHook('saveCoreTemplate', this.saveCoreTemplate.bind(this));
307
+ FLBuilder.addHook('duplicateLayout', this.duplicateLayout.bind(this));
308
+ FLBuilder.addHook('showLayoutSettings', this.showLayoutSettings.bind(this));
309
+ FLBuilder.addHook('showGlobalSettings', this.showGlobalSettings.bind(this));
310
+ FLBuilder.addHook('toggleUISkin', this.toggleUISkin.bind(this));
311
+ FLBuilder.addHook('clearLayoutCache', this.clearLayoutCache.bind(this));
312
+ },
313
+
314
+ /**
315
+ * Show the save template lightbox
316
+ * @return void
317
+ */
318
+ saveTemplate: function() {
319
+ FLBuilder._saveUserTemplateClicked();
320
+ MainMenuPanel.hide();
321
+ },
322
+
323
+ /**
324
+ * Show save core template lightbox
325
+ * @return void
326
+ */
327
+ saveCoreTemplate: function() {
328
+ FLBuilderCoreTemplatesAdmin._saveClicked();
329
+ MainMenuPanel.hide();
330
+ },
331
+
332
+ /**
333
+ * Trigger duplicate layout
334
+ * @return void
335
+ */
336
+ duplicateLayout: function() {
337
+ FLBuilder._duplicateLayoutClicked();
338
+ MainMenuPanel.hide();
339
+ },
340
+
341
+ /**
342
+ * Show the global settings lightbox
343
+ * @return void
344
+ */
345
+ showGlobalSettings: function() {
346
+ FLBuilder._globalSettingsClicked();
347
+ MainMenuPanel.hide();
348
+ },
349
+
350
+ /**
351
+ * Show the layout js/css lightbox
352
+ * @return void
353
+ */
354
+ showLayoutSettings: function() {
355
+ FLBuilder._layoutSettingsClicked();
356
+ MainMenuPanel.hide();
357
+ },
358
+
359
+ /**
360
+ * Clear cache for this layout
361
+ * @return void
362
+ */
363
+ clearLayoutCache: function() {
364
+ FLBuilder.ajax({
365
+ action: 'clear_cache'
366
+ }, function() {
367
+ location.href = FLBuilderConfig.editUrl;
368
+ });
369
+ FLBuilder.showAjaxLoader();
370
+ MainMenuPanel.hide();
371
+ },
372
+
373
+ /**
374
+ * Toggle between the UI Skins
375
+ * @var Event
376
+ * @return void
377
+ */
378
+ toggleUISkin: function(e) {
379
+ var $item = $('a[data-event="toggleUISkin"]');
380
+ if ($('body').hasClass('fl-builder-ui-skin--light')) {
381
+ var fromSkin = 'light';
382
+ var toSkin = 'dark';
383
+ }
384
+ if ($('body').hasClass('fl-builder-ui-skin--dark')) {
385
+ var fromSkin = 'dark';
386
+ var toSkin = 'light';
387
+ }
388
+ $('body').removeClass('fl-builder-ui-skin--' + fromSkin ).addClass('fl-builder-ui-skin--' + toSkin);
389
+ // ajax save
390
+ FLBuilder.ajax({
391
+ action: 'save_ui_skin',
392
+ skin_name: toSkin,
393
+ });
394
+ },
395
+ }
396
+
397
+ var Help = {
398
+
399
+ /**
400
+ * Init the help controller
401
+ * @return void
402
+ */
403
+ init: function() {
404
+ FLBuilder.addHook('beginTour', this.onStartTourClicked.bind(this));
405
+ },
406
+
407
+ /**
408
+ * Handle tour item click
409
+ *
410
+ * @return void
411
+ */
412
+ onStartTourClicked: function() {
413
+ FLBuilderTour.start();
414
+ MainMenuPanel.hide();
415
+ },
416
+ }
417
+
418
+ })(jQuery, FLBuilder);
js/fl-builder-ui-panel-content-library.js ADDED
@@ -0,0 +1,1008 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($, FLBuilder) {
2
+
3
+ /**
4
+ * Panel tab controller. A controller object exists for each of the tabs
5
+ * in the content panel.
6
+ */
7
+ var PanelTab = FLExtendableObject.create({
8
+
9
+ handle: "",
10
+
11
+ name: "",
12
+
13
+ panel: null,
14
+
15
+ shouldShowTabItem: true,
16
+
17
+ isShowing: false,
18
+
19
+ views: {},
20
+
21
+ activeView: null,
22
+
23
+ defaultView: null,
24
+
25
+ categorySelector: null,
26
+
27
+ /**
28
+ * Initialize the tab
29
+ *
30
+ * @param {Object} args
31
+ * @return void
32
+ */
33
+ init: function(args) {
34
+
35
+ // Order matters here
36
+
37
+ // Init category selector
38
+ this.categorySelector = CategorySelector.create({
39
+ handle: 'selector-' + this.handle,
40
+ tab: this,
41
+ items: []
42
+ });
43
+ this.categorySelector.init();
44
+ $(this.categorySelector).on('categorySelected', this.onViewSelected.bind(this));
45
+
46
+ // Init view object
47
+ var views = args.views;
48
+ this.initViews(args.views);
49
+
50
+ // Ensure at least one view
51
+ if (Object.keys(this.views).length === 0) {
52
+ var view = {
53
+ handle: "noViews",
54
+ name: "No Views",
55
+ templateName: "fl-content-panel-no-view"
56
+ };
57
+ this.addView(view);
58
+ }
59
+
60
+ // Ensure an Active View
61
+ if (!this.activeView) {
62
+ var key = Object.keys(this.views)[0];
63
+ var view = this.views[key];
64
+ this.activeView = view;
65
+ }
66
+ this.defaultView = this.activeView;
67
+
68
+ $(this.panel).on('afterRender', this.renderView.bind(this, this.activeView ));
69
+ $(this.panel).on('onShow onShowTab', this.initScroller.bind(this) );
70
+ FLBuilder.addHook('contentItemsChanged', this.onLibraryDataChanged.bind(this));
71
+ },
72
+
73
+ /**
74
+ * Initialize all views
75
+ *
76
+ * @param {Object} views
77
+ * @return void
78
+ */
79
+ initViews: function(views) {
80
+ for( var i in views) {
81
+ var args = views[i];
82
+
83
+ this.categorySelector.addItem(args);
84
+ if ( 'separator' !== args.type ) {
85
+ this.addView(args);
86
+ }
87
+ }
88
+ },
89
+
90
+ /**
91
+ * Init a new view and add to this.views
92
+ *
93
+ * @param {Object} args
94
+ * @return void
95
+ */
96
+ addView: function(args) {
97
+
98
+ var viewType = PanelView;
99
+ switch(this.handle) {
100
+ case 'modules':
101
+ viewType = ModulesPanelView;
102
+ break;
103
+ case 'rows':
104
+ viewType = RowsPanelView;
105
+ break;
106
+ case 'templates':
107
+ viewType = TemplatesPanelView;
108
+ break;
109
+ case 'saved':
110
+ viewType = SavedPanelView;
111
+ break;
112
+ default:
113
+ viewType = PanelView;
114
+ }
115
+
116
+ if (!_.isNull(this.viewController) && !_.isUndefined(this.viewController)) {
117
+ viewType = window[this.viewController];
118
+ }
119
+
120
+ var view = viewType.create(args),
121
+ handle = view.handle;
122
+
123
+ view.init();
124
+
125
+ this.views[handle] = view;
126
+ if (view.isShowing) this.activeView = view;
127
+ },
128
+
129
+ /**
130
+ * Render a view into the tab dom
131
+ *
132
+ * @param String | {Object} name
133
+ * @return void
134
+ */
135
+ renderView: function(name) {
136
+
137
+ this.$el = this.panel.$el.find('.fl-builder--panel-view[data-tab="' + this.handle + '"]');
138
+
139
+ // Test if object was passed or string handle
140
+ if (_.isObject(name)) {
141
+ var view = name;
142
+ } else {
143
+ var view = this.views[name];
144
+ }
145
+ if (!_.isObject(view) || !_.isFunction(view.render)) return;
146
+
147
+ var html = view.render();
148
+ this.$el.find('.fl-nanoscroller-content').html(html);
149
+
150
+ this.activeView = view;
151
+
152
+ FLBuilder._initSortables();
153
+
154
+ if ( this === this.panel.activeTab ) {
155
+ this.renderGroupSelector();
156
+ }
157
+
158
+ this.initScroller();
159
+
160
+ this.$el.find('.fl-nanoscroller-content').scrollTop(0);
161
+ },
162
+
163
+ /**
164
+ * Setup nanoscroller on the current panel view.
165
+ *
166
+ * @return void
167
+ */
168
+ initScroller: function() {
169
+ this.$el.nanoScroller({
170
+ alwaysVisible: true,
171
+ preventPageScrolling: true,
172
+ paneClass: 'fl-nanoscroller-pane',
173
+ sliderClass: 'fl-nanoscroller-slider',
174
+ contentClass: 'fl-nanoscroller-content'
175
+ });
176
+ },
177
+
178
+ /**
179
+ * Show this tab
180
+ *
181
+ * @return void
182
+ */
183
+ show: function() {
184
+ $(this.activeView).trigger('onBeforeShow');
185
+ this.renderGroupSelector();
186
+ this.isShowing = true;
187
+ this.$el.addClass('is-showing');
188
+
189
+ this.$el.find('.fl-nanoscroller-content').scrollTop(0);
190
+ },
191
+
192
+ /**
193
+ * Hide the tab
194
+ *
195
+ * @return void
196
+ */
197
+ hide: function() {
198
+ this.isShowing = false;
199
+ this.$el.removeClass('is-showing');
200
+ if ( this.activeView !== this.defaultView ) {
201
+ this.renderView( this.defaultView );
202
+ }
203
+ if (_.isObject(this.categorySelector)) {
204
+ this.categorySelector.close();
205
+ }
206
+ },
207
+
208
+ /**
209
+ * Render the group selector into the panel header if tab has multiple views.
210
+ *
211
+ * @return void
212
+ */
213
+ renderGroupSelector: function() {
214
+ var $groupSelect = this.panel.$groupSelect,
215
+ $search = this.panel.$el.find('.fl-builder-panel-search');
216
+
217
+ if ( this.isSearchEnabled ) {
218
+ $search.show();
219
+ } else {
220
+ $search.hide();
221
+ }
222
+
223
+ if ( Object.keys(this.views).length > 1 && !_.isUndefined( this.categorySelector ) ) {
224
+
225
+ var html = this.categorySelector.render(),
226
+ header = this.panel.$el.find('.fl-builder-content-group-select');
227
+
228
+ $groupSelect.html(html);
229
+
230
+ $groupSelect.show();
231
+ this.panel.$el.removeClass('single-view');
232
+ } else {
233
+ $groupSelect.hide();
234
+ $search.hide();
235
+ this.panel.$el.addClass('single-view');
236
+ }
237
+ },
238
+
239
+ /**
240
+ * Handle a view being chosen
241
+ *
242
+ * @param {Event} e
243
+ * @param {Object} viewName
244
+ * @return void
245
+ */
246
+ onViewSelected: function(e, viewName) {
247
+ this.renderView(viewName);
248
+ this.categorySelector.close();
249
+ },
250
+
251
+ /**
252
+ * Handle update of library data
253
+ *
254
+ * @return void
255
+ */
256
+ onLibraryDataChanged: function() {
257
+ this.renderView( this.activeView );
258
+ },
259
+ });
260
+
261
+ /**
262
+ * Panel view controller prototype. See controllers for module,
263
+ * row, template and saved views below.
264
+ */
265
+ var PanelView = FLExtendableObject.create({
266
+
267
+ /**
268
+ * The wp.template reference.
269
+ */
270
+ templateName: '',
271
+
272
+ /**
273
+ * String name of the view.
274
+ */
275
+ name: '',
276
+
277
+ /**
278
+ * String handle for the view.
279
+ */
280
+ handle: '',
281
+
282
+ /**
283
+ * Query to retrieve content items.
284
+ */
285
+ query: null,
286
+
287
+ /**
288
+ * Initialize view controller
289
+ *
290
+ * @return void
291
+ */
292
+ init: function() {
293
+ this.template = wp.template(this.templateName);
294
+
295
+ $(this).on('afterRender', this.bindEvents.bind(this));
296
+ $(this).trigger('afterInit');
297
+ },
298
+
299
+ /**
300
+ * Filter the data object before it's passed to the wp.template function
301
+ *
302
+ * @param {object} data
303
+ * @return {object}
304
+ */
305
+ filterTemplateData: function(data) {
306
+
307
+ if (!_.isNull(this.query) && !_.isUndefined(this.query)) {
308
+ data.queryResults = FLBuilder.Search.byQuery(this.query);
309
+ }
310
+ return data;
311
+ },
312
+
313
+ /**
314
+ * Render view html.
315
+ *
316
+ * @return jQuery DOM
317
+ */
318
+ render: function() {
319
+ $(this).trigger('beforeRender');
320
+
321
+ var data = this;
322
+ data = this.filterTemplateData(data);
323
+
324
+ var $html = $(this.template(data));
325
+ this.$el = $html;
326
+ $(this).trigger('afterRender');
327
+ return $html;
328
+ },
329
+
330
+ /**
331
+ * Setup event listeners. Fired after render.
332
+ *
333
+ * @return void
334
+ */
335
+ bindEvents: function() {},
336
+
337
+ /**
338
+ * Stub for child objects to extend
339
+ *
340
+ * @return void
341
+ */
342
+ transitionIn:function() {},
343
+
344
+ /**
345
+ * Stub for child objects to extend
346
+ *
347
+ * @return void
348
+ */
349
+ transitionOut: function() {},
350
+ });
351
+
352
+ /**
353
+ * Panel view controller for module views.
354
+ */
355
+ var ModulesPanelView = PanelView.create({
356
+
357
+ /**
358
+ * The wp.template reference.
359
+ */
360
+ templateName: 'fl-content-panel-modules-view',
361
+
362
+ /**
363
+ * Bind Events
364
+ *
365
+ * @return void
366
+ */
367
+ bindEvents: function() {
368
+
369
+ this.$sections = this.$el; // should really change this in the template.
370
+
371
+ this.$items = this.$el.find('.fl-builder-block, .fl-builder-blocks-section-title');
372
+ },
373
+ });
374
+
375
+ /**
376
+ * Panel view controller for row views.
377
+ */
378
+ var RowsPanelView = PanelView.create({
379
+
380
+ /**
381
+ * The wp.template reference.
382
+ */
383
+ templateName: 'fl-content-panel-row-templates-view',
384
+
385
+ /**
386
+ * Bind events
387
+ *
388
+ * @return void
389
+ */
390
+ bindEvents: function() {
391
+ this.$items = this.$el.find('.fl-builder-block, .fl-builder-blocks-section-title');
392
+ },
393
+ });
394
+
395
+ /**
396
+ * Panel view controller for template views
397
+ */
398
+ var TemplatesPanelView = PanelView.create({
399
+
400
+ /**
401
+ * The wp.template reference.
402
+ */
403
+ templateName: 'fl-content-panel-templates-view',
404
+
405
+ /**
406
+ * Bind event listeners. Fires after render.
407
+ *
408
+ * @return void
409
+ */
410
+ bindEvents: function() {
411
+
412
+ this.$items = this.$el.find('.fl-builder--template-collection-item');
413
+
414
+ this.$items.on('click', this.onTemplateClick.bind(this));
415
+
416
+ this.$userTemplateSections = $('.fl-user-templates');
417
+
418
+ this.$userTemplates = this.$el.find('.fl-user-template, .fl-builder--save-new-user-template');
419
+
420
+ this.$saveNewTemplateInput = this.$el.find('.fl-save-control input[name="template-name"]');
421
+ this.$saveNewTemplateCat = this.$el.find('.fl-save-control input[name="template-category"]');
422
+ this.$saveNewTemplateBtn = this.$el.find('.fl-save-control button');
423
+ this.$saveNewMask = this.$el.find('.fl-save-control-mask');
424
+
425
+ this.$saveNewTemplateInput.on('focus', this.onSaveInputFocus.bind(this));
426
+ this.$saveNewTemplateInput.on('keyup', this.onSaveInputKeyup.bind(this));
427
+ this.$saveNewTemplateBtn.on('click', this.onSaveButtonClick.bind(this));
428
+ this.$saveNewMask.on('click', this.resetSaveInput.bind(this));
429
+ },
430
+
431
+ /**
432
+ * Handle input focus
433
+ *
434
+ * @return void
435
+ */
436
+ onSaveInputFocus: function() {
437
+ this.resetSaveInput();
438
+ this.$saveNewMask.show();
439
+ },
440
+
441
+ /**
442
+ * Clear the input and collapse
443
+ *
444
+ * @return void
445
+ */
446
+ resetSaveInput: function() {
447
+ this.$saveNewTemplateInput.val("");
448
+ this.$saveNewTemplateBtn.hide();
449
+ this.$saveNewMask.hide();
450
+ },
451
+
452
+ /**
453
+ * Handle key up
454
+ *
455
+ * @param {Event} e
456
+ * @return void
457
+ */
458
+ onSaveInputKeyup: function(e) {
459
+ var input = $(e.currentTarget),
460
+ value = input.val(),
461
+ button = input.siblings('button');
462
+ if (value !== '') {
463
+ button.show();
464
+ } else {
465
+ button.hide();
466
+ }
467
+ },
468
+
469
+ /**
470
+ * Handle save button click
471
+ *
472
+ * @param {Event} e
473
+ * @return void
474
+ */
475
+ onSaveButtonClick: function(e) {
476
+ var button = $(e.currentTarget),
477
+ value = button.siblings('input[name="template-name"]').val(),
478
+ category = button.siblings('input[name="template-category"]').val(),
479
+ settings = {
480
+ name: value,
481
+ category: category
482
+ };
483
+
484
+ if ("" !== value) {
485
+
486
+ FLBuilder.ajax({
487
+ action: 'save_user_template',
488
+ settings: settings,
489
+ }, FLBuilder._saveUserTemplateSettingsComplete);
490
+ }
491
+ },
492
+
493
+ /**
494
+ * Handle template clicked event
495
+ * @return void
496
+ */
497
+ onTemplateClick: function(e) {
498
+ var $item = $(e.currentTarget),
499
+ id = $item.data('id'),
500
+ type = $item.data('type');
501
+ FLBuilder._requestTemplateInsert(id, type);
502
+ },
503
+ });
504
+
505
+ /**
506
+ * Panel view controller for saved modules and rows.
507
+ */
508
+ var SavedPanelView = PanelView.create({
509
+
510
+ /**
511
+ * The wp.template reference
512
+ */
513
+ templateName: 'fl-content-panel-saved-view',
514
+
515
+ /**
516
+ * Filter the data before it's given to the template function
517
+ *
518
+ * @param {object} data
519
+ * @return {object}
520
+ */
521
+ filterTemplateData: function(data) {
522
+
523
+ data.queryResults = FLBuilder.Search.byQuery({
524
+ kind: "template",
525
+ type: "user",
526
+ content: ["module", "row"]
527
+ });
528
+
529
+ return data;
530
+ },
531
+ });
532
+
533
+ /**
534
+ * Controller for category chooser.
535
+ * One of these objects gets used by a PanelTab and rendered above the current panel view.
536
+ */
537
+ var CategorySelector = FLExtendableObject.create({
538
+
539
+ /**
540
+ * The wp.template reference.
541
+ */
542
+ templateName: 'fl-content-panel-category-selector',
543
+
544
+ /**
545
+ * Template function retreived by wp.template()
546
+ */
547
+ template: null,
548
+
549
+ /**
550
+ * Reference to the tab controller that owns this selector.
551
+ */
552
+ tab: null,
553
+
554
+ /**
555
+ * Whether or not the selector's menu is currently open.
556
+ */
557
+ isOpen: false,
558
+
559
+ /**
560
+ * The items to list in the menu
561
+ */
562
+ items: {},
563
+
564
+ /**
565
+ * Initial setup
566
+ *
567
+ * @return void
568
+ */
569
+ init: function() {
570
+ this.template = wp.template(this.templateName);
571
+ $(this).on('afterRender', this.bindEvents.bind(this));
572
+ $(this.tab.panel).on('didShowSearchControls', this.close.bind(this) );
573
+ },
574
+
575
+ /**
576
+ * Render the html for the selector. Requires this.tab to be set.
577
+ *
578
+ * @return jQuery DOM
579
+ */
580
+ render: function() {
581
+ this.close();
582
+ var $html = $(this.template(this));
583
+ this.$el = $html;
584
+ $(this).trigger('afterRender');
585
+ return $html;
586
+ },
587
+
588
+ /**
589
+ * Bind event listeners. Triggered after render.
590
+ *
591
+ * @return void
592
+ */
593
+ bindEvents: function() {
594
+ this.$selectorTitle = this.$el.find('.fl-builder--selector-display');
595
+ this.$selectorTitle.on('click', this.toggleOpenClose.bind(this));
596
+
597
+ this.$categories = this.$el.find('.fl-builder--selector-menu .fl-builder--menu-item');
598
+ this.$categories.on('click', this.onCategoryClick.bind(this));
599
+ },
600
+
601
+ /**
602
+ * Add an item to the menu
603
+ *
604
+ * @param {object} item
605
+ * @return void
606
+ */
607
+ addItem: function(item) {
608
+
609
+ var handle;
610
+ if( _.isUndefined(item.handle)) {
611
+ handle = _.uniqueId('sep_');
612
+ } else {
613
+ handle = item.handle;
614
+ }
615
+ this.items[handle] = item;
616
+ },
617
+
618
+ /**
619
+ * Open the menu.
620
+ *
621
+ * @return void
622
+ */
623
+ open: function() {
624
+ if (this.isOpen) return;
625
+ this.$el.addClass('is-showing');
626
+ this.isOpen = true;
627
+ },
628
+
629
+ /**
630
+ * Close the menu.
631
+ *
632
+ * @return void
633
+ */
634
+ close: function() {
635
+ if (!this.isOpen) return;
636
+ this.$el.removeClass('is-showing');
637
+ this.isOpen = false;
638
+ this.$selectorTitle.find("button").focus();
639
+ },
640
+
641
+ /**
642
+ * Toggle the menu between open and closed states.
643
+ *
644
+ * @return void
645
+ */
646
+ toggleOpenClose: function() {
647
+ if (this.isOpen) {
648
+ this.close();
649
+ } else {
650
+ this.open();
651
+ }
652
+ },
653
+
654
+ /**
655
+ * Fired one would of the menu items is clicked.
656
+ *
657
+ * {Event} e
658
+ * @return void
659
+ */
660
+ onCategoryClick: function(e) {
661
+ var viewName = $(e.target).data('view');
662
+ $(this).trigger('categorySelected', viewName);
663
+ },
664
+ });
665
+
666
+ /**
667
+ * Panel housing all the draggable content items and templates for the builder.
668
+ */
669
+ FLBuilder.ContentPanel = FLExtendableObject.create({
670
+
671
+ /**
672
+ * Name of the js template for the panel.
673
+ */
674
+ templateName: 'fl-content-panel-base',
675
+
676
+ /**
677
+ * wp.template function to render the panel
678
+ */
679
+ template: null,
680
+
681
+ /**
682
+ * Tab section controller objects.
683
+ */
684
+ tabs: {},
685
+
686
+ /**
687
+ * A reference to the active tab controller object.
688
+ */
689
+ activeTab: null,
690
+
691
+ /**
692
+ * Whether or not the panel is currently visible.
693
+ */
694
+ isShowing: false,
695
+
696
+ /**
697
+ * Initialize and render the panel.
698
+ *
699
+ * @return void
700
+ */
701
+ init: function() {
702
+
703
+ if (!FLBuilderConfig.panelData) return;
704
+
705
+ var items = FLBuilderConfig.panelData.tabs;
706
+
707
+ for( var i in items) {
708
+ var item = items[i];
709
+
710
+ tab = PanelTab.create(item);
711
+ tab.panel = this;
712
+ tab.views = {};
713
+ tab.init(item);
714
+
715
+ this.tabs[i] = tab;
716
+ if (tab.isShowing) {
717
+ this.activeTab = tab;
718
+ }
719
+
720
+ if (!this.activeTab) {
721
+ var firstTab = Object.keys(this.tabs)[0];
722
+ var tab = this.tabs[firstTab];
723
+ tab.isShowing = true;
724
+ this.activeTab = tab;
725
+ }
726
+ }
727
+
728
+ // Render panel
729
+ this.template = wp.template(this.templateName);
730
+ this.render();
731
+
732
+ this.renderSearchResults = wp.template('fl-search-results-panel');
733
+ this.renderNoResults = wp.template('fl-search-no-results');
734
+
735
+ FLBuilder.triggerHook('contentPanelDidInit');
736
+ },
737
+
738
+ /**
739
+ * Render the base HTML for the panel
740
+ *
741
+ * @return void
742
+ */
743
+ render: function() {
744
+ $('body').prepend(this.template(this));
745
+ this.$el = $(".fl-builder--content-library-panel");
746
+ this.bindEvents();
747
+ this.$groupSelect = this.$el.find('.fl-builder-content-group-select');
748
+ $(this).trigger('afterRender');
749
+ },
750
+
751
+ /**
752
+ * Setup event listeners for the base panel.
753
+ *
754
+ * @return void
755
+ */
756
+ bindEvents: function() {
757
+
758
+ this.$tabs = this.$el.find('.fl-builder--tabs [data-tab]');
759
+ this.$tabs.on('mouseup', this.onTabItemMouseUp.bind( this ));
760
+ this.$tabs.on('click', this.onTabItemClick.bind( this ));
761
+
762
+ this.$search = this.$el.find('.fl-builder-panel-search');
763
+ this.$searchBtn = this.$search.find('.fl-builder-toggle-panel-search');
764
+ this.$searchInput = this.$search.find('input[name="search-term"]');
765
+ this.$searchBtn.on('click', this.onSearchButtonClicked.bind(this) );
766
+ this.$search.find('.fl-builder-dismiss-panel-search').on('click', this.onDismissButtonClicked.bind(this) );
767
+ this.$searchInput.on('keyup', this.onSearchTermChanged.bind(this) );
768
+ this.$searchPanel = this.$el.find('.fl-builder--search-results-panel');
769
+
770
+ FLBuilder.addHook('showContentPanel', this.show.bind( this ));
771
+ FLBuilder.addHook('showModules', this.show.bind( this, 'modules' ));
772
+ FLBuilder.addHook('showRows', this.show.bind( this, 'rows' ));
773
+ FLBuilder.addHook('showTemplates', this.show.bind( this, 'templates' ));
774
+ FLBuilder.addHook('showSaved', this.show.bind( this, 'saved' ));
775
+ FLBuilder.addHook('showSearch', this.goToSearch.bind(this) );
776
+
777
+ var hide = this.hide.bind(this);
778
+ FLBuilder.addHook('hideContentPanel', hide );
779
+ FLBuilder.addHook('didShowLightbox', hide );
780
+ FLBuilder.addHook('didShowPublishActions', hide );
781
+ FLBuilder.addHook('didBeginSearch', hide );
782
+ FLBuilder.addHook('didInitDrag', hide );
783
+ FLBuilder.addHook('didOpenMainMenu', hide );
784
+ FLBuilder.addHook('didApplyTemplate', hide );
785
+
786
+ var toggle = this.toggleShowHide.bind( this );
787
+ FLBuilder.addHook('toggleContentPanel', toggle );
788
+
789
+ FLBuilder.addHook('didStopDrag', this.hideSearchControls.bind(this) );
790
+ },
791
+
792
+ /**
793
+ * Align the panel arrow with the + button
794
+ */
795
+ alignPanelArrow: function() {
796
+ var $panel = this.$el,
797
+ panelOffset = null,
798
+ $arrow = this.$el.find('.fl-builder--panel-arrow'),
799
+ $button = $('.fl-builder-content-panel-button'),
800
+ arrowOffset,
801
+ arrowX,
802
+ animationDuration = this.$el.css('animation-duration');
803
+
804
+ if ( $button.length == 0 ) return;
805
+ this.$el.css('animation-duration', '0s');
806
+ this.show();
807
+ panelOffset = $panel[0].getBoundingClientRect();
808
+ arrowOffset = $arrow[0].getBoundingClientRect();
809
+ this.hide();
810
+ this.$el.css('animation-duration', animationDuration );
811
+
812
+ buttonOffset = $button[0].getBoundingClientRect();
813
+ var buttonCenterX = buttonOffset.x + ( buttonOffset.width / 2 );
814
+
815
+
816
+ if ( buttonCenterX < panelOffset.x ) {
817
+ // move the panel & the arrow
818
+ arrowX = 20;
819
+ } else {
820
+ arrowX = ( buttonCenterX - panelOffset.x ) - ( arrowOffset.width / 2 );
821
+ }
822
+
823
+ /* Position the arrow */
824
+ $arrow.css({
825
+ right: 'auto',
826
+ left: arrowX + 'px'
827
+ });
828
+ },
829
+
830
+ /**
831
+ * Show content panel
832
+ *
833
+ * @param String tabName
834
+ * @return void
835
+ */
836
+ show: function(tabName) {
837
+
838
+ FLBuilder.triggerHook('willShowContentPanel');
839
+
840
+ if (typeof tabName !== 'undefined') {
841
+ this.showTab(tabName);
842
+ }
843
+
844
+ if (this.isShowing) return;
845
+
846
+ // Save existing settings first if any exist. Don't proceed if it fails.
847
+ if ( ! FLBuilder._triggerSettingsSave( false, true ) ) {
848
+ return;
849
+ }
850
+
851
+ $('body').addClass('fl-builder-content-panel-is-showing');
852
+ this.isShowing = true;
853
+ $(this).trigger('onShow');
854
+ FLBuilder.triggerHook('didShowContentPanel');
855
+ },
856
+
857
+ /**
858
+ * Hide content panel
859
+ *
860
+ * @return void
861
+ */
862
+ hide: function() {
863
+ if ( ! this.isShowing ) {
864
+ return;
865
+ } else if ( this.$el.hasClass( 'fl-builder-ui-pinned' ) ) {
866
+ return;
867
+ }
868
+
869
+ $('body').removeClass('fl-builder-content-panel-is-showing');
870
+ this.isShowing = false;
871
+ $(this).trigger('onHide');
872
+ FLBuilder.triggerHook('didHideContentPanel');
873
+ },
874
+
875
+ /**
876
+ * Toggle between show and hide states.
877
+ *
878
+ * @return void
879
+ */
880
+ toggleShowHide: function() {
881
+ if (this.isShowing) {
882
+ this.hide();
883
+ } else {
884
+ this.show();
885
+ }
886
+ },
887
+
888
+ /**
889
+ * Display one of the panel tabs
890
+ *
891
+ * @param String handle
892
+ * @return void
893
+ */
894
+ showTab: function(handle) {
895
+ var tab = this.tabs[handle];
896
+ if (!_.isObject(tab)) return;
897
+
898
+ if (_.isObject(this.activeTab)) {
899
+ this.activeTab.hide();
900
+ this.$tabs.filter('.is-showing').removeClass('is-showing');
901
+ }
902
+ this.hideSearchControls();
903
+ tab.show();
904
+ this.$tabs.filter('[data-tab="' + tab.handle + '"]').addClass('is-showing');
905
+ this.activeTab = tab;
906
+ $(this).trigger('onShowTab');
907
+ },
908
+
909
+ goToSearch: function() {
910
+ this.show('modules');
911
+ this.$el.find('.fl-builder-toggle-panel-search').trigger('click');
912
+ },
913
+
914
+ onTabItemMouseUp: function(e) {
915
+ $(e.currentTarget).blur();
916
+ },
917
+
918
+ /**
919
+ * Handle tab clicks.
920
+ *
921
+ * @param {Event} e
922
+ * @return void
923
+ */
924
+ onTabItemClick: function(e) {
925
+ var el = $(e.target),
926
+ name = el.data('tab');
927
+ this.showTab(name);
928
+ },
929
+
930
+ /**
931
+ * Handle search icon click
932
+ */
933
+ onSearchButtonClicked: function() {
934
+ this.showSearchControls();
935
+ },
936
+
937
+ onDismissButtonClicked: function() {
938
+ this.hideSearchControls();
939
+ this.$searchBtn.focus();
940
+ },
941
+
942
+ showSearchControls: function() {
943
+ this.$search.addClass('is-showing-input');
944
+ this.$search.find('input[name="search-term"]').focus();
945
+
946
+ $('.fl-builder--selector-display-label').attr('tabindex', -1 );
947
+ this.$searchBtn.attr('tabindex', -1 );
948
+
949
+ $(this).trigger('didShowSearchControls');
950
+ },
951
+
952
+ hideSearchControls: function() {
953
+ this.$search.removeClass('is-showing-input');
954
+ this.clearSearchInput();
955
+ this.hideSearchResults();
956
+ $('.fl-builder--selector-display-label').attr('tabindex', null );
957
+ this.$searchBtn.attr('tabindex', null );
958
+ },
959
+
960
+ onSearchTermChanged: function(e) {
961
+ var value = this.$searchInput.val();
962
+ if ( "" !== value ) {
963
+ var results = FLBuilder.Search.byTerm(value);
964
+ if (results.term != "") {
965
+ this.showSearchResults(results);
966
+ } else {
967
+ this.hideSearchResults();
968
+ }
969
+ } else {
970
+ this.hideSearchResults();
971
+ }
972
+ },
973
+
974
+ clearSearchInput: function() {
975
+ this.$searchInput.val("");
976
+ this.hideSearchResults();
977
+ },
978
+
979
+ /**
980
+ * Display the found results in the results panel.
981
+ * @var Object - the found results
982
+ * @return void
983
+ */
984
+ showSearchResults: function(data) {
985
+
986
+ if (data.total > 0) {
987
+ var $html = $(this.renderSearchResults(data));
988
+ this.$searchPanel.html($html);
989
+
990
+ FLBuilder._initSortables();
991
+ } else {
992
+ var $html = $(this.renderNoResults(data));
993
+ this.$searchPanel.html($html);
994
+ }
995
+ $('body').addClass('fl-builder-search-results-panel-is-showing');
996
+ },
997
+
998
+ /**
999
+ * Hide the search results panel
1000
+ * @return void
1001
+ */
1002
+ hideSearchResults: function() {
1003
+ $('body').removeClass('fl-builder-search-results-panel-is-showing');
1004
+ },
1005
+
1006
+ });
1007
+
1008
+ })(jQuery, FLBuilder);
js/fl-builder-ui-pinned.js ADDED
@@ -0,0 +1,702 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function( $ ) {
2
+
3
+ /**
4
+ * Helper for pinning the builder UI to the
5
+ * sides of the browser window.
6
+ *
7
+ * @since 2.0
8
+ * @class PinnedUI
9
+ */
10
+ var PinnedUI = {
11
+
12
+ /**
13
+ * @since 2.0
14
+ * @method init
15
+ */
16
+ init: function() {
17
+
18
+ if ( 'module' === FLBuilderConfig.userTemplateType ) {
19
+ return;
20
+ }
21
+
22
+ this.initPanel();
23
+ this.pinOrUnpin();
24
+ this.bind();
25
+ },
26
+
27
+ /**
28
+ * @since 2.0
29
+ * @method bind
30
+ */
31
+ bind: function() {
32
+ var win = $( window ),
33
+ body = $( 'body' );
34
+
35
+ win.on( 'resize', _.throttle( this.windowResize.bind( this ), 250 ) );
36
+
37
+ body.delegate( '.fl-builder-ui-pinned-collapse', 'click', this.collapse );
38
+ body.delegate( '.fl-builder--content-library-panel .fl-builder--tabs', 'click', this.closeLightboxOnPanelClick );
39
+
40
+ FLBuilder.addHook( 'didShowLightbox', this.pinLightboxOnOpen.bind( this ) );
41
+ FLBuilder.addHook( 'didHideAllLightboxes', this.pinnedLightboxClosed.bind( this ) );
42
+ FLBuilder.addHook( 'endEditingSession', this.hide.bind( this ) );
43
+ FLBuilder.addHook( 'didHideEditingUI', this.hide.bind( this ) );
44
+ FLBuilder.addHook( 'publishButtonClicked', this.hide.bind( this ) );
45
+ FLBuilder.addHook( 'restartEditingSession', this.show.bind( this ) );
46
+ FLBuilder.addHook( 'didShowEditingUI', this.show.bind( this ) );
47
+ FLBuilder.addHook( 'didShowLightbox', this.uncollapse.bind(this) );
48
+ FLBuilder.addHook( 'willShowContentPanel', this.uncollapse.bind(this) );
49
+ FLBuilder.addHook( 'willShowContentPanel', this.closeLightboxOnPanelClick.bind(this) );
50
+ },
51
+
52
+ /**
53
+ * Checks to see if the UI is currently pinned or not.
54
+ *
55
+ * @since 2.0
56
+ * @method isPinned
57
+ * @return {Boolean}
58
+ */
59
+ isPinned: function() {
60
+ return $( '.fl-builder--content-library-panel' ).hasClass( 'fl-builder-ui-pinned' );
61
+ },
62
+
63
+ /**
64
+ * Pins the UI.
65
+ *
66
+ * @since 2.0
67
+ * @method pin
68
+ * @param {String} position
69
+ * @param {Boolean} savePosition
70
+ */
71
+ pin: function( position, savePosition ) {
72
+ this.pinPanel( position );
73
+ this.pinLightboxes();
74
+
75
+ if ( savePosition ) {
76
+ this.savePosition();
77
+ }
78
+
79
+ FLBuilder._resizeLayout();
80
+ },
81
+
82
+ /**
83
+ * Unpins the UI.
84
+ *
85
+ * @since 2.0
86
+ * @method unpin
87
+ * @param {Boolean} savePosition
88
+ */
89
+ unpin: function( savePosition ) {
90
+ this.unpinLightboxes();
91
+ this.unpinPanel();
92
+
93
+ if ( savePosition ) {
94
+ this.savePosition();
95
+ }
96
+
97
+ FLBuilder._resizeLayout();
98
+ },
99
+
100
+ /**
101
+ * Pins or unpins the UI based on the window size.
102
+ *
103
+ * @since 2.0
104
+ * @method pinOrUnpin
105
+ */
106
+ pinOrUnpin: function()
107
+ {
108
+ var panel = $( '.fl-builder--content-library-panel' ),
109
+ pinned = this.isPinned();
110
+
111
+ if ( window.innerWidth <= 500 ) {
112
+ if ( pinned ) {
113
+ this.unpin( false );
114
+ }
115
+ this.disableDragAndResize();
116
+ } else {
117
+ if ( ! pinned ) {
118
+ this.restorePosition();
119
+ }
120
+ this.enableDragAndResize();
121
+ }
122
+ },
123
+
124
+ /**
125
+ * Shows the pinned UI if it has been hidden.
126
+ *
127
+ * @since 2.0
128
+ * @method show
129
+ */
130
+ show: function()
131
+ {
132
+ var panel = $( '.fl-builder--content-library-panel' );
133
+
134
+ if ( panel.hasClass( 'fl-builder-ui-pinned-hidden' ) ) {
135
+ panel.removeClass( 'fl-builder-ui-pinned-hidden' );
136
+ panel.show();
137
+ this.restorePosition();
138
+ }
139
+ },
140
+
141
+ /**
142
+ * Hides pinned lightboxes without unpinning them.
143
+ *
144
+ * @since 2.0
145
+ * @method hide
146
+ */
147
+ hide: function()
148
+ {
149
+ var body = $( 'body' ),
150
+ panel = $( '.fl-builder--content-library-panel' );
151
+
152
+ if ( this.isPinned() ) {
153
+ this.uncollapse();
154
+ panel.addClass( 'fl-builder-ui-pinned-hidden' );
155
+ panel.hide();
156
+ body.css( 'margin', '' );
157
+ }
158
+ },
159
+
160
+ /**
161
+ * Collapse all pinned UI elements.
162
+ *
163
+ * @since 2.0
164
+ * @method collapse
165
+ */
166
+ collapse: function()
167
+ {
168
+ var button = $( this ).find('i:visible'),
169
+ body = $( 'body' ),
170
+ toggle = button.data( 'toggle' ),
171
+ position = button.data( 'position' ),
172
+ panel = $( '.fl-builder--content-library-panel' ),
173
+ width = panel.outerWidth();
174
+
175
+ if ( 'hide' === toggle ) {
176
+ panel.css( position, '-' + width + 'px' );
177
+ body.css( 'margin-' + position, '' );
178
+ body.addClass( 'fl-builder-ui-pinned-is-collapsed' );
179
+ } else {
180
+ panel.css( position, '0px' );
181
+ body.css( 'margin-' + position, width + 'px' );
182
+ body.removeClass( 'fl-builder-ui-pinned-is-collapsed' );
183
+ }
184
+ },
185
+
186
+ /**
187
+ * Uncollapse all pinned UI elements.
188
+ *
189
+ * @since 2.0
190
+ * @method uncollapse
191
+ */
192
+ uncollapse: function()
193
+ {
194
+ if ( this.isCollapsed() ) {
195
+ $( '.fl-builder-ui-pinned-collapse:visible' ).trigger( 'click' );
196
+ }
197
+ },
198
+
199
+ /**
200
+ * Return whether or not the panel is currently collapsed
201
+ *
202
+ * @since 2.0
203
+ * @method isCollapsed
204
+ */
205
+ isCollapsed: function() {
206
+ return $('body').hasClass('fl-builder-ui-pinned-is-collapsed');
207
+ },
208
+
209
+ /**
210
+ * Initializes pinning for the main content panel.
211
+ *
212
+ * @since 2.0
213
+ * @method initPanel
214
+ */
215
+ initPanel: function() {
216
+ var panel = $( '.fl-builder--content-library-panel' );
217
+
218
+ panel.draggable( {
219
+ cursor : 'move',
220
+ handle : '.fl-builder--tabs',
221
+ cancel : '.fl-builder--tabs button',
222
+ scroll : false,
223
+ drag : this.drag.bind( this ),
224
+ stop : this.dragStop.bind( this ),
225
+ start : this.dragStart.bind( this ),
226
+ } ).resizable( {
227
+ handles : 'e, w',
228
+ minHeight : 400,
229
+ minWidth : 380,
230
+ maxWidth : 500,
231
+ start : this.resizeStart.bind( this ),
232
+ stop : this.resizeStop.bind( this )
233
+ } );
234
+
235
+ panel.addClass( 'fl-builder-ui-pinned-container' );
236
+ panel.find( '.ui-resizable-e, .ui-resizable-w' ).hide();
237
+ },
238
+
239
+ /**
240
+ * Pins the main content panel.
241
+ *
242
+ * @since 2.0
243
+ * @method pinPanel
244
+ * @param {String} position
245
+ */
246
+ pinPanel: function( position ) {
247
+ var panel = $( '.fl-builder--content-library-panel' ),
248
+ width = panel.width(),
249
+ body = $( 'body' ),
250
+ preview = $( '.fl-responsive-preview, .fl-responsive-preview-mask' ),
251
+ content = $( FLBuilder._contentClass ).parentsUntil( 'body' ).last();
252
+
253
+ body.addClass( 'fl-builder-ui-is-pinned fl-builder-ui-is-pinned-' + position );
254
+ body.addClass( 'fl-builder-content-panel-is-showing' );
255
+ body.css( 'margin-' + position, width + 'px' );
256
+ preview.css( 'margin-' + position, width + 'px' );
257
+ content.addClass( 'fl-builder-ui-pinned-content-transform' );
258
+ panel.addClass( 'fl-builder-ui-pinned fl-builder-ui-pinned-' + position );
259
+ panel.find( '.ui-resizable-' + ( 'left' === position ? 'e' : 'w' ) ).show();
260
+ panel.on( 'resize', _.throttle( this.resize.bind( this ), 250 ) );
261
+ panel.attr( 'style', '' );
262
+ FLBuilder.ContentPanel.isShowing = true;
263
+ },
264
+
265
+ /**
266
+ * Unpins the main content panel.
267
+ *
268
+ * @since 2.0
269
+ * @method unpinPanel
270
+ */
271
+ unpinPanel: function() {
272
+ var panel = $( '.fl-builder--content-library-panel' ),
273
+ tab = panel.find( '.fl-builder--panel-content .is-showing' ).data( 'tab' ),
274
+ body = $( 'body' ),
275
+ preview = $( '.fl-responsive-preview, .fl-responsive-preview-mask' ),
276
+ content = $( FLBuilder._contentClass ).parentsUntil( 'body' ).last();
277
+
278
+ body.css( 'margin-left', '' );
279
+ body.css( 'margin-right', '' );
280
+ body.removeClass( 'fl-builder-ui-is-pinned' );
281
+ body.removeClass( 'fl-builder-ui-is-pinned-left' );
282
+ body.removeClass( 'fl-builder-ui-is-pinned-right' );
283
+ preview.css( 'margin-left', '' );
284
+ preview.css( 'margin-right', '' );
285
+ content.removeClass( 'fl-lightbox-content-transform' );
286
+ panel.removeClass( 'fl-builder-ui-pinned' );
287
+ panel.removeClass( 'fl-builder-ui-pinned-left' );
288
+ panel.removeClass( 'fl-builder-ui-pinned-right' );
289
+ panel.find( '.ui-resizable-handle' ).hide();
290
+ panel.off( 'resize' );
291
+ panel.attr( 'style', '' );
292
+ panel.find( '.fl-builder--tabs [data-tab=' + tab + ']' ).addClass( 'is-showing' );
293
+ },
294
+
295
+ /**
296
+ * Pins all open lightboxes.
297
+ *
298
+ * @since 2.0
299
+ * @method pinLightboxes
300
+ */
301
+ pinLightboxes: function() {
302
+ var self = this;
303
+
304
+ $( '.fl-lightbox-resizable' ).each( function() {
305
+ self.pinLightbox( $( this ) );
306
+ } );
307
+
308
+ FLBuilder._reinitEditorFields();
309
+ },
310
+
311
+ /**
312
+ * Pins a single lightbox.
313
+ *
314
+ * @since 2.0
315
+ * @method pinLightbox
316
+ * @param {Object} lightbox
317
+ */
318
+ pinLightbox: function( lightbox ) {
319
+ var panel = $( '.fl-builder--content-library-panel' ),
320
+ wrapper = lightbox.closest( '.fl-lightbox-wrap' );
321
+
322
+ if ( ! wrapper.closest( '.fl-builder-ui-pinned' ).length ) {
323
+ panel.append( wrapper );
324
+ lightbox.attr( 'style', '' );
325
+ lightbox.draggable( 'disable' );
326
+ lightbox.resizable( 'disable' );
327
+ }
328
+
329
+ if ( lightbox.is( ':visible' ) ) {
330
+ panel.find( '.fl-builder--tabs .is-showing' ).removeClass( 'is-showing' );
331
+ }
332
+ },
333
+
334
+ /**
335
+ * Pins a lightbox when it opens if it's not already pinned.
336
+ *
337
+ * @since 2.0
338
+ * @method pinLightboxOnOpen
339
+ * @param {Object} e
340
+ * @param {FLLightbox} boxObject
341
+ */
342
+ pinLightboxOnOpen: function( e, boxObject ) {
343
+ var lightbox = boxObject._node.find( '.fl-lightbox-resizable' );
344
+
345
+ if ( ! lightbox.length ) {
346
+ return;
347
+ }
348
+
349
+ if ( ! lightbox.hasClass( 'fl-builder-ui-pinning-initialized' ) ) {
350
+ lightbox.draggable( 'option', 'start', this.dragStart.bind( this ) );
351
+ lightbox.draggable( 'option', 'drag', this.drag.bind( this ) );
352
+ lightbox.draggable( 'option', 'stop', this.dragStop.bind( this ) );
353
+ lightbox.addClass( 'fl-builder-ui-pinning-initialized' );
354
+ }
355
+
356
+ if ( this.isPinned() ) {
357
+ this.pinLightbox( lightbox );
358
+ }
359
+
360
+ FLBuilder.addHook( 'responsive-editing-switched', this.resize );
361
+ },
362
+
363
+ /**
364
+ * Handles a pinned lightbox closing.
365
+ *
366
+ * @since 2.0
367
+ * @method pinnedLightboxClosed
368
+ */
369
+ pinnedLightboxClosed: function() {
370
+ var panel = $( '.fl-builder--content-library-panel' )
371
+ tab = null;
372
+
373
+ if ( this.isPinned() ) {
374
+ tab = panel.find( '.fl-builder--panel-content .is-showing' ).data( 'tab' );
375
+ panel.find( '.fl-builder--tabs [data-tab=' + tab + ']' ).addClass( 'is-showing' );
376
+ }
377
+
378
+ $( '.fl-lightbox' ).removeClass( 'fl-lightbox-prevent-animation' );
379
+ },
380
+
381
+ /**
382
+ * Unpins all pinned lightboxes.
383
+ *
384
+ * @since 2.0
385
+ * @method unpinLightboxes
386
+ */
387
+ unpinLightboxes: function() {
388
+ var body = $( 'body' ),
389
+ panel = $( '.fl-builder--content-library-panel' );
390
+
391
+ panel.find( '.fl-lightbox-wrap' ).each( function() {
392
+ var wrapper = $( this ),
393
+ lightbox = wrapper.find( '.fl-lightbox' ),
394
+ top = 0,
395
+ left = 0;
396
+
397
+ lightbox.draggable( 'enable' );
398
+ lightbox.resizable( 'enable' );
399
+ lightbox.find( '.ui-resizable-handle' ).show();
400
+ body.append( wrapper );
401
+
402
+ if ( lightbox.is( ':visible' ) ) {
403
+ top = parseInt( panel.css( 'top' ) ) - parseInt( wrapper.css( 'top' ) ) - parseInt( wrapper.css( 'padding-top' ) );
404
+ left = parseInt( panel.css( 'left' ) ) - parseInt( wrapper.css( 'padding-left' ) );
405
+ lightbox.css( {
406
+ top : ( top < 0 ? 0 : top ) + 'px',
407
+ left : left + 'px',
408
+ } );
409
+ lightbox.addClass( 'fl-lightbox-prevent-animation' );
410
+ body.removeClass( 'fl-builder-content-panel-is-showing' );
411
+ FLBuilder.ContentPanel.isShowing = false;
412
+ } else {
413
+ lightbox.css( {
414
+ top : '25px',
415
+ left : '25px',
416
+ } );
417
+ }
418
+ } );
419
+
420
+ FLBuilder._reinitEditorFields();
421
+ },
422
+
423
+ /**
424
+ * Closes lightboxes when a panel tab is clicked.
425
+ *
426
+ * @since 2.0
427
+ * @method closeLightboxOnPanelClick
428
+ */
429
+ closeLightboxOnPanelClick: function() {
430
+ FLBuilder._triggerSettingsSave( false, true );
431
+ },
432
+
433
+ /**
434
+ * Unpins if pinned when the window is resized down to a
435
+ * small device size.
436
+ *
437
+ * @since 2.0
438
+ * @method windowResize
439
+ */
440
+ windowResize: function()
441
+ {
442
+ this.pinOrUnpin();
443
+ },
444
+
445
+ /**
446
+ * Callback for when content panel resize starts.
447
+ *
448
+ * @since 2.0
449
+ * @method resizeStart
450
+ */
451
+ resizeStart: function()
452
+ {
453
+ $( 'body' ).addClass( 'fl-builder-resizable-is-resizing' );
454
+
455
+ FLBuilder._destroyOverlayEvents();
456
+ FLBuilder._removeAllOverlays();
457
+ },
458
+
459
+ /**
460
+ * Callback for when content panel resizes.
461
+ *
462
+ * @since 2.0
463
+ * @method resize
464
+ */
465
+ resize: function()
466
+ {
467
+ var body = $( 'body' ),
468
+ preview = $( '.fl-responsive-preview, .fl-responsive-preview-mask' ),
469
+ panel = $( '.fl-builder--content-library-panel' ),
470
+ width = panel.outerWidth();
471
+
472
+ if ( panel.hasClass( 'fl-builder-ui-pinned-left' ) ) {
473
+ body.css( 'margin-left', width + 'px' );
474
+ preview.css( 'margin-left', width + 'px' );
475
+ } else if ( panel.hasClass( 'fl-builder-ui-pinned-right' ) ) {
476
+ body.css( 'margin-right', width + 'px' );
477
+ preview.css( 'margin-right', width + 'px' );
478
+ }
479
+ },
480
+
481
+ /**
482
+ * Callback for when content panel resize stops.
483
+ *
484
+ * @since 2.0
485
+ * @method resizeStop
486
+ */
487
+ resizeStop: function()
488
+ {
489
+ $( 'body' ).removeClass( 'fl-builder-resizable-is-resizing' );
490
+
491
+ FLBuilder._bindOverlayEvents();
492
+ FLBuilder._resizeLayout();
493
+ this.savePosition();
494
+ },
495
+
496
+ /**
497
+ * Callback for when content panel drag starts.
498
+ *
499
+ * @since 2.0
500
+ * @method dragStart
501
+ */
502
+ dragStart: function( e, ui )
503
+ {
504
+ var body = $( 'body' ),
505
+ target = $( e.target ),
506
+ actions = $( '.fl-builder-bar-actions' );
507
+
508
+ if ( ! $( '.fl-lightbox-resizable:visible' ).length ) {
509
+ actions.addClass( 'fl-builder-content-panel-pin-zone' );
510
+ }
511
+
512
+ body.addClass( 'fl-builder-draggable-is-dragging' );
513
+ body.append( '<div class="fl-builder-ui-pin-zone fl-builder-ui-pin-zone-left"></div>' );
514
+ body.append( '<div class="fl-builder-ui-pin-zone fl-builder-ui-pin-zone-right"></div>' );
515
+ FLBuilder._destroyOverlayEvents();
516
+ },
517
+
518
+ /**
519
+ * Callback for when content panel is dragged.
520
+ *
521
+ * @since 2.0
522
+ * @method drag
523
+ */
524
+ drag: function( e, ui )
525
+ {
526
+ var body = $( 'body' ),
527
+ preview = $( '.fl-responsive-preview' ),
528
+ win = $( window ),
529
+ winWidth = preview.length ? preview.width() : win.width(),
530
+ scrollTop = win.scrollTop(),
531
+ panel = $( '.fl-builder--content-library-panel' ),
532
+ offsetTop = panel.offset().top,
533
+ actions = $( '.fl-builder-bar-actions' ),
534
+ target = $( e.target );
535
+
536
+ if ( target.hasClass( 'fl-builder--content-library-panel' ) ) {
537
+ if ( e.clientX < winWidth - 75 && offsetTop - scrollTop < 46 ) {
538
+ actions.addClass( 'fl-builder-content-panel-pin-zone-hover' );
539
+ } else {
540
+ actions.removeClass( 'fl-builder-content-panel-pin-zone-hover' );
541
+ }
542
+ }
543
+
544
+ if ( target.hasClass( 'fl-builder-ui-pinned' ) ) {
545
+ this.unpinPanel();
546
+ } else if ( e.clientX < 75 ) {
547
+ body.addClass( 'fl-builder-ui-show-pin-zone fl-builder-ui-show-pin-zone-left' );
548
+ } else if ( e.clientX > winWidth - 75 ) {
549
+ body.addClass( 'fl-builder-ui-show-pin-zone fl-builder-ui-show-pin-zone-right' );
550
+ } else {
551
+ body.removeClass( 'fl-builder-ui-show-pin-zone' );
552
+ body.removeClass( 'fl-builder-ui-show-pin-zone-left' );
553
+ body.removeClass( 'fl-builder-ui-show-pin-zone-right' );
554
+ }
555
+ },
556
+
557
+ /**
558
+ * Callback for when content panel drag stops.
559
+ *
560
+ * @since 2.0
561
+ * @method dragStop
562
+ */
563
+ dragStop: function( e, ui )
564
+ {
565
+ var win = $( window ),
566
+ body = $( 'body' ),
567
+ actions = $( '.fl-builder-bar-actions' ),
568
+ zones = $( '.fl-builder-ui-pin-zone' ),
569
+ panel = $( '.fl-builder--content-library-panel' ),
570
+ lightbox = $( '.fl-lightbox-resizable:visible' ),
571
+ target = $( e.target );
572
+
573
+ body.removeClass( 'fl-builder-draggable-is-dragging' );
574
+ actions.removeClass( 'fl-builder-content-panel-pin-zone' );
575
+ actions.removeClass( 'fl-builder-content-panel-pin-zone-hover' );
576
+ zones.remove();
577
+
578
+ if ( lightbox.length && parseInt( lightbox.css( 'top' ) ) < 0 ) {
579
+ lightbox.css( 'top', '0' );
580
+ }
581
+
582
+ if ( body.hasClass( 'fl-builder-ui-show-pin-zone' ) ) {
583
+ if ( body.hasClass( 'fl-builder-ui-show-pin-zone-left' ) ) {
584
+ this.pin( 'left', true );
585
+ } else {
586
+ this.pin( 'right', true );
587
+ }
588
+ body.removeClass( 'fl-builder-ui-show-pin-zone' );
589
+ body.removeClass( 'fl-builder-ui-show-pin-zone-left' );
590
+ body.removeClass( 'fl-builder-ui-show-pin-zone-right' );
591
+ } else if( panel.find( '.fl-lightbox' ).length ) {
592
+ this.unpin( true );
593
+ } else {
594
+ panel.attr( 'style', '' );
595
+ this.savePosition();
596
+ }
597
+
598
+ FLBuilder._bindOverlayEvents();
599
+ },
600
+
601
+ /**
602
+ * Disables draggable and resizable.
603
+ *
604
+ * @since 2.0
605
+ * @method disableDragAndResize
606
+ */
607
+ disableDragAndResize: function() {
608
+ var panel = $( '.fl-builder--content-library-panel' ),
609
+ lightboxes = $( '.fl-lightbox-resizable' );
610
+
611
+ panel.draggable( 'disable' );
612
+ panel.resizable( 'disable' );
613
+
614
+ lightboxes.draggable( 'disable' );
615
+ lightboxes.resizable( 'disable' );
616
+ },
617
+
618
+ /**
619
+ * Enables draggable and resizable.
620
+ *
621
+ * @since 2.0
622
+ * @method enableDragAndResize
623
+ */
624
+ enableDragAndResize: function() {
625
+ var panel = $( '.fl-builder--content-library-panel' ),
626
+ lightboxes = $( '.fl-lightbox-resizable:not(.fl-lightbox-width-full)' );
627
+
628
+ panel.draggable( 'enable' );
629
+ panel.resizable( 'enable' );
630
+
631
+ if ( ! this.isPinned() ) {
632
+ lightboxes.draggable( 'enable' );
633
+ lightboxes.resizable( 'enable' );
634
+ }
635
+ },
636
+
637
+ /**
638
+ * Save the position data for the pinned UI.
639
+ *
640
+ * @since 2.0
641
+ * @method savePosition
642
+ */
643
+ savePosition: function()
644
+ {
645
+ var panel = $( '.fl-builder--content-library-panel' ),
646
+ lightbox = $( '.fl-lightbox-resizable:visible' ),
647
+ data = {
648
+ pinned: {
649
+ width : panel.width(),
650
+ position : null
651
+ }
652
+ };
653
+
654
+ if ( panel.hasClass( 'fl-builder-ui-pinned-left' ) ) {
655
+ data.pinned.position = 'left';
656
+ } else if ( panel.hasClass( 'fl-builder-ui-pinned-right' ) ) {
657
+ data.pinned.position = 'right';
658
+ } else if ( lightbox.length ) {
659
+ data.lightbox = {
660
+ width : lightbox.width(),
661
+ height : lightbox.height(),
662
+ top : parseInt( lightbox.css( 'top' ) ) < 0 ? '0px' : lightbox.css( 'top' ),
663
+ left : lightbox.css( 'left' )
664
+ };
665
+ }
666
+
667
+ FLBuilderConfig.userSettings.pinned = data.pinned;
668
+
669
+ if ( data.lightbox ) {
670
+ FLBuilderConfig.userSettings.lightbox = data.lightbox;
671
+ }
672
+
673
+ FLBuilder.ajax( {
674
+ action : 'save_pinned_ui_position',
675
+ data : data
676
+ } );
677
+ },
678
+
679
+ /**
680
+ * Restores the pinned UI position for the current user.
681
+ *
682
+ * @since 2.0
683
+ * @method restorePosition
684
+ */
685
+ restorePosition: function()
686
+ {
687
+ var panel = $( '.fl-builder--content-library-panel' ),
688
+ settings = FLBuilderConfig.userSettings.pinned;
689
+
690
+ if ( settings && settings.position ) {
691
+ panel.width( settings.width );
692
+ this.pin( settings.position, false );
693
+ panel.width( settings.width );
694
+ }
695
+ },
696
+ };
697
+
698
+ $( function() {
699
+ PinnedUI.init();
700
+ } );
701
+
702
+ } )( jQuery );
js/fl-builder-ui-settings-forms.js ADDED
@@ -0,0 +1,864 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function( $ ) {
2
+
3
+ /**
4
+ * Helper for rendering builder settings forms.
5
+ *
6
+ * @since 2.0
7
+ * @class FLBuilderSettingsForms
8
+ */
9
+ FLBuilderSettingsForms = {
10
+
11
+ /**
12
+ * Config for the current form that is rendering.
13
+ *
14
+ * @since 2.0
15
+ * @property {Object} config
16
+ */
17
+ config : null,
18
+
19
+ /**
20
+ * Settings cache for the current form so we can compare
21
+ * later and see if settings have changed before saving.
22
+ *
23
+ * @since 2.0
24
+ * @property {Object} settings
25
+ */
26
+ settings : null,
27
+
28
+ /**
29
+ * A reference to the AJAX object for rendering legacy settings.
30
+ *
31
+ * @since 2.0
32
+ * @property {Object} legacyXhr
33
+ */
34
+ legacyXhr : null,
35
+
36
+ /**
37
+ * @since 2.0
38
+ * @method init
39
+ */
40
+ init: function() {
41
+ this.bind();
42
+ },
43
+
44
+ /**
45
+ * @since 2.0
46
+ * @method bind
47
+ */
48
+ bind: function() {
49
+ FLBuilder.addHook( 'didDeleteRow', this.closeOnDeleteNode );
50
+ FLBuilder.addHook( 'didDeleteColumn', this.closeOnDeleteNode );
51
+ FLBuilder.addHook( 'didDeleteModule', this.closeOnDeleteNode );
52
+ },
53
+
54
+ /**
55
+ * Renders a settings form.
56
+ *
57
+ * @since 2.0
58
+ * @method render
59
+ * @param {Object} config
60
+ * @param {Function} callback
61
+ */
62
+ render: function( config, callback ) {
63
+ var forms = FLBuilderSettingsConfig.forms,
64
+ modules = FLBuilderSettingsConfig.modules,
65
+ defaults = {
66
+ type : 'general',
67
+ id : null,
68
+ nodeId : null,
69
+ className : '',
70
+ attrs : '',
71
+ title : '',
72
+ badges : [],
73
+ tabs : [],
74
+ buttons : [],
75
+ settings : {},
76
+ legacy : null,
77
+ rules : null,
78
+ preview : null,
79
+ helper : null
80
+ };
81
+
82
+ // Merge the config into the defaults and make sure we have a callback.
83
+ config = $.extend( defaults, config );
84
+ callback = undefined === callback ? function(){} : callback;
85
+
86
+ // Add the form data to the config.
87
+ if ( ! config.id ) {
88
+ return;
89
+ } else if ( 'general' === config.type && undefined !== forms[ config.id ] ) {
90
+ config = $.extend( true, config, forms[ config.id ] );
91
+ } else if ( 'module' === config.type && undefined !== modules[ config.id ] ) {
92
+ config = $.extend( true, config, modules[ config.id ] );
93
+ } else {
94
+ return;
95
+ }
96
+
97
+ // Store the config so it can be accessed by forms.
98
+ this.config = config;
99
+
100
+ // Render the lightbox and form.
101
+ if ( this.renderLightbox( config ) ) {
102
+
103
+ // Finish rendering.
104
+ if ( config.legacy || ! this.renderLegacySettings( config, callback ) ) {
105
+ this.renderComplete( config, callback );
106
+ } else {
107
+ this.showLightboxLoader();
108
+ }
109
+ }
110
+ },
111
+
112
+ /**
113
+ * Renders the lightbox for a settings form.
114
+ *
115
+ * @since 2.0
116
+ * @method renderLightbox
117
+ * @param {Object} config
118
+ * @return {Boolean}
119
+ */
120
+ renderLightbox: function( config ) {
121
+ var template = wp.template( 'fl-builder-settings' ),
122
+ form = FLBuilder._lightbox._node.find( 'form.fl-builder-settings' ),
123
+ nested = $( '.fl-lightbox-wrap[data-parent]' );
124
+
125
+ // Don't render a node form if it's already open.
126
+ if ( config.nodeId && config.nodeId === form.data( 'node' ) && ! config.lightbox ) {
127
+ FLBuilder._focusFirstSettingsControl();
128
+ return false;
129
+ }
130
+
131
+ // Render the lightbox and form.
132
+ if ( ! config.lightbox ) {
133
+
134
+ // Save existing settings first if any exist. Don't proceed if it fails.
135
+ if ( ! FLBuilder._triggerSettingsSave( true, true ) ) {
136
+ return false;
137
+ }
138
+
139
+ // Cancel any preview refreshes.
140
+ if ( FLBuilder.preview ) {
141
+ FLBuilder.preview.cancel();
142
+ }
143
+
144
+ FLBuilder._closePanel();
145
+ FLBuilder._showLightbox();
146
+ FLBuilder._setLightboxContent( template( config ) );
147
+ } else {
148
+ config.lightbox.setContent( template( config ) );
149
+ }
150
+
151
+ return true;
152
+ },
153
+
154
+ /**
155
+ * Initializes a form when rendering is complete.
156
+ *
157
+ * @since 2.0
158
+ * @method renderComplete
159
+ * @param {Object} config
160
+ * @param {Function} callback
161
+ */
162
+ renderComplete: function( config, callback ) {
163
+ var form = $( '.fl-builder-settings:visible' );
164
+
165
+ // This is done on a timeout to keep it from delaying painting
166
+ // of the settings form in the DOM by a fraction of a second.
167
+ setTimeout( function() {
168
+ if ( config.legacy ) {
169
+ this.renderLegacySettingsComplete( config.legacy );
170
+ }
171
+
172
+ callback();
173
+
174
+ FLBuilder._initSettingsForms();
175
+
176
+ if ( config.rules ) {
177
+ FLBuilder._initSettingsValidation( config.rules );
178
+ }
179
+ if ( config.preview ) {
180
+ FLBuilder.preview = new FLBuilderPreview( config.preview );
181
+ }
182
+ if ( config.helper ) {
183
+ config.helper.init();
184
+ }
185
+
186
+ // Cache the original settings.
187
+ if ( ! form.closest( '.fl-lightbox-wrap[data-parent]' ).length ) {
188
+ this.settings = FLBuilder._getSettings( form );
189
+ }
190
+
191
+ }.bind( this ), 1 );
192
+ },
193
+
194
+ /**
195
+ * Renders the fields for a section in a settings form.
196
+ *
197
+ * @since 2.0
198
+ * @method renderFields
199
+ * @param {Object} fields
200
+ * @param {Object} settings
201
+ * @return {String}
202
+ */
203
+ renderFields: function( fields, settings ) {
204
+ var template = wp.template( 'fl-builder-settings-row' ),
205
+ html = '',
206
+ field = null,
207
+ name = null,
208
+ value = null,
209
+ isMultiple = false,
210
+ responsive = null,
211
+ responsiveFields = [ 'dimension', 'unit' ],
212
+ settings = ! settings ? this.config.settings : settings,
213
+ globalSettings = FLBuilderConfig.global;
214
+
215
+ for ( name in fields ) {
216
+
217
+ field = fields[ name ];
218
+ isMultiple = field.multiple ? true : false;
219
+ supportsResponsive = $.inArray( field['type'], responsiveFields ) > -1,
220
+ value = ! _.isUndefined( settings[ name ] ) ? settings[ name ] : '';
221
+
222
+ // Use a default value if not set in the settings.
223
+ if ( _.isUndefined( settings[ name ] ) && field['default'] ) {
224
+ value = field['default'];
225
+ }
226
+
227
+ // Check to see if responsive is enabled for this field.
228
+ if ( field['responsive'] && globalSettings.responsive_enabled && ! isMultiple && supportsResponsive ) {
229
+ responsive = field['responsive'];
230
+ } else {
231
+ responsive = null;
232
+ }
233
+
234
+ html += template( {
235
+ field : field,
236
+ name : name,
237
+ rootName : name,
238
+ value : value,
239
+ preview : JSON.stringify( field['preview'] ? field['preview'] : { type: 'refresh' } ),
240
+ responsive : responsive,
241
+ rowClass : field['row_class'] ? ' ' + field['row_class'] : '',
242
+ isMultiple : isMultiple,
243
+ supportsMultiple : 'editor' !== field.type && 'photo' !== field.type && 'service' !== field.type,
244
+ settings : settings,
245
+ globalSettings : globalSettings,
246
+ template : $( '#tmpl-fl-builder-field-' + field.type )
247
+ } );
248
+ }
249
+
250
+ return html;
251
+ },
252
+
253
+ /**
254
+ * Renders a single field for a settings form.
255
+ *
256
+ * @since 2.0
257
+ * @method renderField
258
+ * @param {Object} config
259
+ * @return {String}
260
+ */
261
+ renderField: function( config ) {
262
+ var template = wp.template( 'fl-builder-field' );
263
+ return template( config );
264
+ },
265
+
266
+ /**
267
+ * Renders a custom template for a section.
268
+ *
269
+ * @since 2.0
270
+ * @method renderSectionTemplate
271
+ * @param {Object} section
272
+ * @param {Object} settings
273
+ * @return {String}
274
+ */
275
+ renderSectionTemplate: function( section, settings ) {
276
+ var template = wp.template( section.template.id );
277
+
278
+ return template( {
279
+ section : section,
280
+ settings : settings
281
+ } );
282
+ },
283
+
284
+ /**
285
+ * Renders a custom template for a tab.
286
+ *
287
+ * @since 2.0
288
+ * @method renderTabTemplate
289
+ * @param {Object} tab
290
+ * @param {Object} settings
291
+ * @return {String}
292
+ */
293
+ renderTabTemplate: function( tab, settings ) {
294
+ var template = wp.template( tab.template.id );
295
+
296
+ return template( {
297
+ tab : tab,
298
+ settings : settings
299
+ } );
300
+ },
301
+
302
+ /**
303
+ * Renders any legacy custom fields that need to be
304
+ * rendered on the server with PHP.
305
+ *
306
+ * @since 2.0
307
+ * @method renderLegacyField
308
+ * @param {Object} config
309
+ * @param {Function} callback
310
+ * @return {Boolean}
311
+ */
312
+ renderLegacySettings: function( config, callback ) {
313
+ var form = $( '.fl-builder-settings:visible' ),
314
+ name = null,
315
+ ele = null,
316
+ render = false,
317
+ data = {
318
+ 'tabs' : [],
319
+ 'sections' : [],
320
+ 'fields' : [],
321
+ 'settings' : null,
322
+ 'node_id' : null
323
+ };
324
+
325
+ // Fields
326
+ form.find( '.fl-legacy-field' ).each( function() {
327
+ ele = $( this );
328
+ data.fields.push( ele.attr( 'data-field' ) );
329
+ FLBuilderSettingsForms.showFieldLoader( ele );
330
+ render = true;
331
+ } );
332
+
333
+ // Sections
334
+ form.find( '.fl-legacy-settings-section' ).each( function() {
335
+ ele = $( this );
336
+ data.sections.push( { tab: ele.attr( 'data-tab' ), section: ele.attr( 'data-section' ) } );
337
+ render = true;
338
+ } );
339
+
340
+ // Tabs
341
+ form.find( '.fl-legacy-settings-tab' ).each( function() {
342
+ ele = $( this );
343
+ data.tabs.push( ele.attr( 'data-tab' ) );
344
+ render = true;
345
+ } );
346
+
347
+ // Send a node ID if we have it, otherwise, send the settings.
348
+ if ( form.attr( 'data-node' ) ) {
349
+ data.node_id = form.attr( 'data-node' );
350
+ } else {
351
+ data.settings = FLBuilder._getOriginalSettings( form, true );
352
+ }
353
+
354
+ // Cancel an existing legacy AJAX request if we have one.
355
+ if ( this.legacyXhr ) {
356
+ this.legacyXhr.abort();
357
+ this.legacyXhr = null;
358
+ }
359
+
360
+ // We still fire the AJAX request even if we don't need to render new
361
+ // tabs, sections or fields just in case any field extras need to render.
362
+ this.legacyXhr = FLBuilder.ajax( $.extend( this.getLegacyVars(), {
363
+ action : 'render_legacy_settings',
364
+ data : data,
365
+ form : form.attr( 'data-form-id' ),
366
+ group : form.attr( 'data-form-group' ),
367
+ lightbox : form.closest( '.fl-builder-lightbox' ).attr( 'data-instance-id' )
368
+ } ), function( response ) {
369
+ FLBuilderSettingsForms.renderLegacySettingsComplete( response );
370
+ if ( render ) {
371
+ FLBuilderSettingsForms.renderComplete( config, callback );
372
+ }
373
+ FLBuilderSettingsForms.hideLightboxLoader();
374
+ } );
375
+
376
+ return render;
377
+ },
378
+
379
+ /**
380
+ * Callback for when legacy settings are done rendering.
381
+ *
382
+ * @since 2.0
383
+ * @method renderLegacySettingsComplete
384
+ * @param {String} response
385
+ */
386
+ renderLegacySettingsComplete: function( response ) {
387
+ var data = 'object' === typeof response ? response : JSON.parse( response ),
388
+ lightbox = null,
389
+ form = null,
390
+ name = '',
391
+ field = null,
392
+ section = null,
393
+ tab = null,
394
+ settings = null;
395
+
396
+ // Get the form object.
397
+ if ( data.lightbox ) {
398
+ lightbox = $( '.fl-builder-lightbox[data-instance-id=' + data.lightbox + ']' );
399
+ form = lightbox.length ? lightbox.find( '.fl-builder-settings' ) : null;
400
+ } else {
401
+ form = $( '.fl-builder-settings:visible' );
402
+ lightbox = form.closest( '.fl-builder-lightbox' );
403
+ }
404
+
405
+ // Bail if the form no longer exists.
406
+ if ( ! form || ! form.length ) {
407
+ return;
408
+ }
409
+
410
+ // Fields
411
+ for ( name in data.fields ) {
412
+ field = $( '#fl-field-' + name ).attr( 'id', '' );
413
+ field.after( data.fields[ name ] ).remove();
414
+ }
415
+
416
+ // Field extras
417
+ for ( name in data.extras ) {
418
+ field = $( '#fl-field-' + name ).find( '.fl-field-control-wrapper' );
419
+ field.prepend( data.extras[ name ].before );
420
+ field.append( data.extras[ name ].after );
421
+ }
422
+
423
+ // Sections
424
+ for ( tab in data.sections ) {
425
+ for ( name in data.sections[ tab ] ) {
426
+ section = $( '#fl-builder-settings-section-' + name );
427
+ section.html( data.sections[ tab ][ name ] );
428
+ }
429
+ }
430
+
431
+ // Tabs
432
+ for ( name in data.tabs ) {
433
+ tab = $( '#fl-builder-settings-tab-' + name );
434
+ tab.html( data.tabs[ name ] );
435
+ }
436
+
437
+ // Refresh cached settings only if it's the main form.
438
+ if ( ! lightbox.data( 'parent' ) ) {
439
+ this.settings = FLBuilder._getSettings( form );
440
+
441
+ if ( FLBuilder.preview ) {
442
+ FLBuilder.preview._savedSettings = this.settings;
443
+ }
444
+ }
445
+
446
+ // Support for Themer before it supported JS fields. This can be removed in a future version.
447
+ if ( ! _.isUndefined( window.FLThemeBuilderFieldConnections ) ) {
448
+ FLThemeBuilderFieldConnections._initSettingsForms();
449
+ }
450
+
451
+ // Clear the legacy AJAX object.
452
+ this.legacyXhr = null;
453
+ },
454
+
455
+ /**
456
+ * Returns legacy variables that were sent in AJAX requests
457
+ * when a nested settings form was rendered.
458
+ *
459
+ * @since 2.0
460
+ * @method getLegacyVars
461
+ * @return {Object}
462
+ */
463
+ getLegacyVars: function() {
464
+ var form = $( '.fl-builder-settings:visible' ),
465
+ lightbox = form.closest( '.fl-builder-lightbox' ),
466
+ parent = lightbox.attr( 'data-parent' ),
467
+ settings = null,
468
+ nodeId = null,
469
+ vars = {};
470
+
471
+ if ( parent ) {
472
+ parent = $( '.fl-builder-lightbox[data-instance-id=' + parent + ']' );
473
+ form = parent.find( 'form.fl-builder-settings' );
474
+ settings = FLBuilder._getSettings( form );
475
+ nodeId = form.attr( 'data-node' );
476
+
477
+ if ( nodeId ) {
478
+ vars.node_id = nodeId;
479
+ vars.node_settings = settings;
480
+ }
481
+ }
482
+
483
+ return vars;
484
+ },
485
+
486
+ /**
487
+ * Checks to see if the main form settings has changed.
488
+ *
489
+ * @since 2.0
490
+ * @method settingsHaveChanged
491
+ * @return {Boolean}
492
+ */
493
+ settingsHaveChanged: function()
494
+ {
495
+ var form = FLBuilder._lightbox._node.find( 'form.fl-builder-settings' ),
496
+ settings = FLBuilder._getSettings( form ),
497
+ result = ! this.settings ? false : JSON.stringify( this.settings ) != JSON.stringify( settings );
498
+
499
+ return result;
500
+ },
501
+
502
+ /**
503
+ * Closes the settings lightbox when an associated node is deleted.
504
+ *
505
+ * @since 2.0
506
+ * @method closeOnDeleteNode
507
+ * @param {Object} e
508
+ * @param {String} nodeId
509
+ */
510
+ closeOnDeleteNode: function( e, nodeId )
511
+ {
512
+ if ( $( '.fl-builder-settings[data-node="' + nodeId + '"]' ).length ) {
513
+ FLLightbox.closeAll();
514
+ }
515
+ },
516
+
517
+ /**
518
+ * Shows the loader for the current lightbox that is visible.
519
+ *
520
+ * @since 2.0
521
+ * @method showLightboxLoader
522
+ */
523
+ showLightboxLoader: function() {
524
+ $( '.fl-builder-settings:visible' ).append( '<div class="fl-builder-loading"></div>' );
525
+ },
526
+
527
+ /**
528
+ * Hides the loader for the current lightbox that is visible.
529
+ *
530
+ * @since 2.0
531
+ * @method hideLightboxLoader
532
+ */
533
+ hideLightboxLoader: function( ele ) {
534
+ $( '.fl-builder-settings:visible .fl-builder-loading' ).remove();
535
+ },
536
+
537
+ /**
538
+ * Shows the loader for a field that is loading.
539
+ *
540
+ * @since 2.0
541
+ * @method showFieldLoader
542
+ * @param {Object} ele
543
+ */
544
+ showFieldLoader: function( ele ) {
545
+ var wrapper = ele.closest( '.fl-field-control' ).find( '.fl-field-control-wrapper' );
546
+ wrapper.hide().after( '<div class="fl-field-loader">' + FLBuilderStrings.fieldLoading + '</div>' );
547
+ },
548
+
549
+ /**
550
+ * Hides the loader for a field that is loading.
551
+ *
552
+ * @since 2.0
553
+ * @method hideFieldLoader
554
+ * @param {Object} ele
555
+ */
556
+ hideFieldLoader: function( ele ) {
557
+ var field = ele.closest( '.fl-field' ),
558
+ wrapper = ele.closest( '.fl-field-control' ).find( '.fl-field-control-wrapper' );
559
+
560
+ wrapper.show();
561
+ field.find( '.fl-field-loader' ).remove();
562
+ }
563
+ };
564
+
565
+ /**
566
+ * Helper for working with settings forms config.
567
+ *
568
+ * @since 2.0
569
+ * @class FLBuilderSettingsConfig
570
+ */
571
+ FLBuilderSettingsConfig = 'undefined' === typeof FLBuilderSettingsConfig ? {} : FLBuilderSettingsConfig;
572
+
573
+ $.extend( FLBuilderSettingsConfig, {
574
+
575
+ /**
576
+ * @since 2.0
577
+ * @method init
578
+ */
579
+ init: function() {
580
+
581
+ // Save settings
582
+ FLBuilder.addHook( 'didSaveNodeSettings', this.updateOnNodeEvent.bind( this ) );
583
+ FLBuilder.addHook( 'didSaveNodeSettingsComplete', this.updateOnNodeEvent.bind( this ) );
584
+ FLBuilder.addHook( 'didSaveGlobalSettingsComplete', this.updateOnSaveGlobalSettings.bind( this ) );
585
+ FLBuilder.addHook( 'didSaveLayoutSettingsComplete', this.updateOnSaveLayoutSettings.bind( this ) );
586
+
587
+ // Add nodes
588
+ FLBuilder.addHook( 'didAddRow', this.updateOnNodeEvent.bind( this ) );
589
+ FLBuilder.addHook( 'didAddColumnGroup', this.updateOnNodeEvent.bind( this ) );
590
+ FLBuilder.addHook( 'didAddColumn', this.updateOnNodeEvent.bind( this ) );
591
+ FLBuilder.addHook( 'didAddModule', this.updateOnNodeEvent.bind( this ) );
592
+
593
+ // Delete nodes
594
+ FLBuilder.addHook( 'didDeleteRow', this.updateOnNodeEvent.bind( this ) );
595
+ FLBuilder.addHook( 'didDeleteColumn', this.updateOnNodeEvent.bind( this ) );
596
+ FLBuilder.addHook( 'didDeleteModule', this.updateOnNodeEvent.bind( this ) );
597
+
598
+ // Duplicate nodes
599
+ FLBuilder.addHook( 'didDuplicateRow', this.updateOnNodeEvent.bind( this ) );
600
+ FLBuilder.addHook( 'didDuplicateColumn', this.updateOnNodeEvent.bind( this ) );
601
+ FLBuilder.addHook( 'didDuplicateModule', this.updateOnNodeEvent.bind( this ) );
602
+
603
+ // Resize nodes
604
+ FLBuilder.addHook( 'didResizeRow', this.updateOnRowResize.bind( this ) );
605
+ FLBuilder.addHook( 'didResizeColumn', this.updateOnColumnResize.bind( this ) );
606
+
607
+ // Reset node widths
608
+ FLBuilder.addHook( 'didResetRowWidth', this.updateOnResetRowWidth.bind( this ) );
609
+ FLBuilder.addHook( 'didResetColumnWidths', this.updateOnResetColumnWidths.bind( this ) );
610
+
611
+ // Apply templates
612
+ FLBuilder.addHook( 'didApplyTemplateComplete', this.updateOnApplyTemplate.bind( this ) );
613
+ FLBuilder.addHook( 'didApplyRowTemplateComplete', this.updateOnApplyTemplate.bind( this ) );
614
+ FLBuilder.addHook( 'didSaveGlobalNodeTemplate', this.updateOnApplyTemplate.bind( this ) );
615
+ FLBuilder.addHook( 'didRestoreRevisionComplete', this.updateOnApplyTemplate.bind( this ) );
616
+ },
617
+
618
+ /**
619
+ * Updates the global settings when they are saved.
620
+ *
621
+ * @since 2.0
622
+ * @method updateOnSaveGlobalSettings
623
+ * @param {Object} e
624
+ * @param {Object} settings
625
+ */
626
+ updateOnSaveGlobalSettings: function( e, settings ) {
627
+ this.settings.global = settings;
628
+ },
629
+
630
+ /**
631
+ * Updates the layout settings when they are saved.
632
+ *
633
+ * @since 2.0
634
+ * @method updateOnSaveLayoutSettings
635
+ * @param {Object} e
636
+ * @param {Object} settings
637
+ */
638
+ updateOnSaveLayoutSettings: function( e, settings ) {
639
+ this.settings.layout = settings;
640
+ },
641
+
642
+ /**
643
+ * Updates the node config when an event is triggered.
644
+ *
645
+ * @since 2.0
646
+ * @method updateOnNodeEvent
647
+ */
648
+ updateOnNodeEvent: function() {
649
+
650
+ var event = arguments[0];
651
+
652
+ if ( event.namespace.indexOf( 'didAdd' ) > -1 ) {
653
+ this.addNode( arguments[1] );
654
+ } else if ( event.namespace.indexOf( 'didSaveNodeSettings' ) > -1 ) {
655
+ this.updateNode( arguments[1].nodeId, arguments[1].settings );
656
+ } else if ( event.namespace.indexOf( 'didDelete' ) > -1 ) {
657
+ this.deleteNodes();
658
+ } else if ( event.namespace.indexOf( 'didDuplicate' ) > -1 ) {
659
+ this.duplicateNode( arguments[1].oldNodeId, arguments[1].newNodeId );
660
+ }
661
+ },
662
+
663
+ /**
664
+ * Updates the node config when a row is resized.
665
+ *
666
+ * @since 2.0
667
+ * @method updateOnRowResize
668
+ * @param {Object} e
669
+ * @param {Object} data
670
+ */
671
+ updateOnRowResize: function( e, data ) {
672
+ this.nodes[ data.rowId ].max_content_width = data.rowWidth;
673
+ },
674
+
675
+ /**
676
+ * Updates the node config when a row width is reset.
677
+ *
678
+ * @since 2.0
679
+ * @method updateOnResetRowWidth
680
+ * @param {Object} e
681
+ * @param {String} nodeId
682
+ */
683
+ updateOnResetRowWidth: function( e, nodeId ) {
684
+ this.nodes[ nodeId ].max_content_width = '';
685
+ },
686
+
687
+ /**
688
+ * Updates the node config when a column is resized.
689
+ *
690
+ * @since 2.0
691
+ * @method updateOnColumnResize
692
+ * @param {Object} e
693
+ * @param {Object} data
694
+ */
695
+ updateOnColumnResize: function( e, data ) {
696
+ this.nodes[ data.colId ].size = data.colWidth;
697
+ this.nodes[ data.siblingId ].size = data.siblingWidth;
698
+ },
699
+
700
+ /**
701
+ * Updates the node config when column widths are reset.
702
+ *
703
+ * @since 2.0
704
+ * @method updateOnResetColumnWidths
705
+ * @param {Object} e
706
+ * @param {Object} data
707
+ */
708
+ updateOnResetColumnWidths: function( e, data ) {
709
+ var self = this;
710
+
711
+ data.cols.each( function() {
712
+ var col = $( this ),
713
+ colId = col.attr( 'data-node' );
714
+
715
+ if ( self.nodes[ colId ] ) {
716
+ self.nodes[ colId ].size = parseFloat( col[0].style.width );
717
+ }
718
+ } );
719
+ },
720
+
721
+ /**
722
+ * Updates the node config when a template is applied.
723
+ *
724
+ * @since 2.0
725
+ * @method updateOnApplyTemplate
726
+ * @param {Object} e
727
+ * @param {Object} config
728
+ */
729
+ updateOnApplyTemplate: function( e, config ) {
730
+ this.nodes = config.nodes;
731
+ this.attachments = config.attachments;
732
+ },
733
+
734
+ /**
735
+ * Adds the settings config for a new node.
736
+ *
737
+ * @since 2.0
738
+ * @method addNode
739
+ * @param {String} nodeId
740
+ * @param {Object} settings
741
+ */
742
+ addNode: function( nodeId, settings ) {
743
+
744
+ var node = $( '.fl-node-' + nodeId ),
745
+ isRow = node.hasClass( 'fl-row' ),
746
+ isCol = node.hasClass( 'fl-col' ),
747
+ isColGroup = node.hasClass( 'fl-col-group' ),
748
+ isModule = node.hasClass( 'fl-module' ),
749
+ self = this;
750
+
751
+ if ( this.nodes[ nodeId ] ) {
752
+ return;
753
+ }
754
+
755
+ if ( ! settings ) {
756
+
757
+ if ( isRow ) {
758
+ settings = $.extend( {}, this.defaults.row );
759
+ } else if ( isCol ) {
760
+ settings = $.extend( {}, this.defaults.column );
761
+ } else if ( isModule ) {
762
+ settings = $.extend( {}, this.defaults.modules[ node.attr( 'data-type' ) ] );
763
+ }
764
+
765
+ if ( isRow || isColGroup ) {
766
+ node.find( '.fl-col' ).each( function() {
767
+ var col = $( this ), defaults = $.extend( {}, self.defaults.column );
768
+ defaults.size = parseFloat( col[0].style.width );
769
+ self.addNode( col.attr( 'data-node' ), defaults );
770
+ } );
771
+ } else if ( isModule ) {
772
+ self.addNode( node.closest( '.fl-row' ).attr( 'data-node' ) );
773
+ self.addNode( node.closest( '.fl-col' ).attr( 'data-node' ) );
774
+ self.updateOnResetColumnWidths( null, {
775
+ cols: node.closest( '.fl-col-group' ).find( '> .fl-col' )
776
+ } );
777
+ }
778
+ }
779
+
780
+ if ( settings ) {
781
+ this.nodes[ nodeId ] = settings;
782
+ }
783
+ },
784
+
785
+ /**
786
+ * Update the settings config for a node.
787
+ *
788
+ * @since 2.0
789
+ * @method updateNode
790
+ * @param {String} nodeId
791
+ * @param {Object} settings
792
+ */
793
+ updateNode: function( nodeId, settings ) {
794
+ var node = $( '.fl-node-' + nodeId ),
795
+ self = this;
796
+
797
+ if ( node.hasClass( 'fl-col' ) ) {
798
+ node.closest( '.fl-col-group' ).find( '> .fl-col' ).each( function() {
799
+ var col = $( this ), colId = col.attr( 'data-node' );
800
+ self.nodes[ colId ].size = parseFloat( col[0].style.width );
801
+ self.nodes[ colId ].equal_height = settings.equal_height;
802
+ self.nodes[ colId ].content_alignment = settings.content_alignment;
803
+ self.nodes[ colId ].responsive_order = settings.responsive_order;
804
+ } );
805
+ }
806
+
807
+ this.nodes[ nodeId ] = settings;
808
+ },
809
+
810
+ /**
811
+ * Duplicates settings config for a node.
812
+ *
813
+ * @since 2.0
814
+ * @method duplicateNode
815
+ * @param {String} oldNode
816
+ * @param {String} newNode
817
+ */
818
+ duplicateNode: function( oldNodeId, newNodeId ) {
819
+
820
+ var newNode = $( '.fl-node-' + newNodeId ),
821
+ newNodes = newNode.find( '[data-node]' ),
822
+ oldNode = $( '.fl-node-' + oldNodeId ),
823
+ oldNodes = oldNode.find( '[data-node]' ),
824
+ self = this;
825
+
826
+ this.nodes[ newNodeId ] = this.nodes[ oldNodeId ];
827
+
828
+ newNodes.each( function( i ) {
829
+
830
+ oldNodeId = oldNodes.eq( i ).attr( 'data-node' );
831
+ newNodeId = $( this ).attr( 'data-node' );
832
+
833
+ if ( self.nodes[ oldNodeId ] ) {
834
+ self.nodes[ newNodeId ] = self.nodes[ oldNodeId ];
835
+ }
836
+ } );
837
+ },
838
+
839
+ /**
840
+ * Deletes any nodes that are no longer in the DOM.
841
+ *
842
+ * @since 2.0
843
+ * @method deleteNodes
844
+ */
845
+ deleteNodes: function() {
846
+
847
+ var nodeId = '',
848
+ content = $( FLBuilder._contentClass ).html();
849
+
850
+ for ( nodeId in this.nodes ) {
851
+ if ( content.indexOf( nodeId ) === -1 ) {
852
+ this.nodes[ nodeId ] = null;
853
+ delete this.nodes[ nodeId ];
854
+ }
855
+ }
856
+ }
857
+ } );
858
+
859
+ $( function() {
860
+ FLBuilderSettingsConfig.init();
861
+ FLBuilderSettingsForms.init();
862
+ } );
863
+
864
+ } )( jQuery );
js/fl-builder-ui.js ADDED
@@ -0,0 +1,1185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($, FLBuilder) {
2
+
3
+ /**
4
+ * Polyfill for String.startsWith()
5
+ */
6
+ if (!String.prototype.startsWith) {
7
+ String.prototype.startsWith = function(searchString, position){
8
+ position = position || 0;
9
+ return this.substr(position, searchString.length) === searchString;
10
+ };
11
+ }
12
+
13
+ // Calculate width of text from DOM element or string. By Phil Freo <http://philfreo.com>
14
+ $.fn.textWidth = function(text, font) {
15
+ if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
16
+ $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
17
+ return $.fn.textWidth.fakeEl.width();
18
+ };
19
+
20
+ /**
21
+ * Base object that all view objects can delegate to.
22
+ * Has the ability to create new objects with itself as the new object's prototype.
23
+ */
24
+ FLExtendableObject = {
25
+ /**
26
+ * Create new object with the current object set as its prototype.
27
+ * @var mixin - Object with properties to be mixed into the final object.
28
+ * @return object
29
+ */
30
+ create: function(mixin) {
31
+ // create a new object with this object as it's prototype.
32
+ var obj = Object.create(this);
33
+ // mix any given properties into it
34
+ obj = $.extend(obj, mixin);
35
+
36
+ $(this).trigger('onCreate');
37
+
38
+ return obj;
39
+ },
40
+ };
41
+
42
+ /**
43
+ * jQuery function to set a class while removing all other classes from
44
+ * the same element that start with the prefix.
45
+ * This is to allow for class states where only one state from the group of classes
46
+ * can be present at any time.
47
+ */
48
+ $.fn.switchClass = function (prefix, ending) {
49
+ return this.each(function() {
50
+
51
+ $(this).removeClass(function(i, classesString) {
52
+ var classesToRemove = [];
53
+ var classes = classesString.split(' ');
54
+ for(var i in classes) {
55
+ if (classes[i].startsWith(prefix)) {
56
+ classesToRemove.push(classes[i]);
57
+ }
58
+ }
59
+ return classesToRemove.join(' ');
60
+ });
61
+ return $(this).addClass(prefix + ending);
62
+ });
63
+ };
64
+
65
+
66
+ var KeyShortcuts = {
67
+
68
+ /**
69
+ * Initialize the keyboard shortcut manager.
70
+ * @return void
71
+ */
72
+ init: function() {
73
+
74
+ FLBuilder.addHook('cancelTask', this.onCancelTask.bind(this));
75
+ FLBuilder.addHook('showSavedMessage', this.onSaveShortcut.bind(this));
76
+ FLBuilder.addHook('goToNextTab', this.onNextPrevTabShortcut.bind(this, 'next'));
77
+ FLBuilder.addHook('goToPrevTab', this.onNextPrevTabShortcut.bind(this, 'prev'));
78
+
79
+ FLBuilder.addHook('endEditingSession', this.onEndEditingSession.bind(this));
80
+ FLBuilder.addHook('restartEditingSession', this.onRestartEditingSession.bind(this));
81
+
82
+ this.setDefaultKeyboardShortcuts();
83
+ },
84
+
85
+ /**
86
+ * Add single keyboard shortcut
87
+ * @var string A hook to be triggered by `FLBuilder.triggerhook(hook)`
88
+ * @var string The key combination to trigger the command.
89
+ * @var bool isGlobal - If the shortcut should work even inside inputs.
90
+ * @return void
91
+ */
92
+ addShortcut: function( hook, key, isGlobal ) {
93
+ var fn = $.proxy(this, 'onTriggerKey', hook);
94
+ if ( isGlobal ) {
95
+ Mousetrap.bindGlobal(key, fn);
96
+ } else {
97
+ Mousetrap.bind(key, fn);
98
+ }
99
+ },
100
+
101
+ /**
102
+ * Clear all registered key commands.
103
+ * @return void
104
+ */
105
+ reset: function() {
106
+ Mousetrap.reset();
107
+ },
108
+
109
+ /**
110
+ * Set the default shortcuts
111
+ * @return void
112
+ */
113
+ setDefaultKeyboardShortcuts: function() {
114
+ this.reset();
115
+
116
+ for( var action in FLBuilderConfig.keyboardShortcuts ) {
117
+ var code = FLBuilderConfig.keyboardShortcuts[action].keyCode,
118
+ isGlobal = FLBuilderConfig.keyboardShortcuts[action].isGlobal;
119
+
120
+ this.addShortcut( action, code, isGlobal);
121
+ }
122
+ },
123
+
124
+ /**
125
+ * Handle a key command by triggering the associated hook.
126
+ * @var string the hook to be fired.
127
+ * @return void
128
+ */
129
+ onTriggerKey: function(hook, e) {
130
+ FLBuilder.triggerHook(hook);
131
+
132
+ if (e.preventDefault) {
133
+ e.preventDefault();
134
+ } else {
135
+ // internet explorer
136
+ e.returnValue = false;
137
+ }
138
+ },
139
+
140
+ /**
141
+ * Cancel out of the current task - triggered by pressing ESC
142
+ * @return void
143
+ */
144
+ onCancelTask: function() {
145
+
146
+ // Is the editor in preview mode?
147
+ if (EditingUI.isPreviewing) {
148
+ EditingUI.endPreview();
149
+ return;
150
+ }
151
+
152
+ // Are the publish actions showing?
153
+ if (PublishActions.isShowing) {
154
+ PublishActions.hide();
155
+ return;
156
+ }
157
+
158
+ // Is the content panel showing?
159
+ if (FLBuilder.ContentPanel.isShowing) {
160
+ FLBuilder.ContentPanel.hide();
161
+ return;
162
+ }
163
+ },
164
+
165
+ /**
166
+ * Pause the active keyboard shortcut listeners.
167
+ * @return void
168
+ */
169
+ pause: function() {
170
+ Mousetrap.pause();
171
+ },
172
+
173
+ /**
174
+ * Unpause the active keyboard shortcut listeners.
175
+ * @return void
176
+ */
177
+ unpause: function() {
178
+ Mousetrap.unpause();
179
+ },
180
+
181
+ /**
182
+ * Handle ending the editing session
183
+ * @return void
184
+ */
185
+ onEndEditingSession: function() {
186
+ this.reset();
187
+ this.addShortcut('restartEditingSession', 'mod+e');
188
+ },
189
+
190
+ /**
191
+ * Handle restarting the editing session
192
+ * @return void
193
+ */
194
+ onRestartEditingSession: function() {
195
+ this.reset();
196
+ this.setDefaultKeyboardShortcuts();
197
+ },
198
+
199
+ /**
200
+ * Handle CMD+S Save Shortcut
201
+ *
202
+ * @return void
203
+ */
204
+ onSaveShortcut: function() {
205
+ if (FLBuilder.SaveManager.layoutNeedsPublish()) {
206
+
207
+ var message = FLBuilderStrings.savedStatus.hasAlreadySaved;
208
+ FLBuilder.SaveManager.showStatusMessage(message);
209
+
210
+ setTimeout(function() {
211
+ FLBuilder.SaveManager.resetStatusMessage();
212
+ }, 2000);
213
+
214
+ } else {
215
+ var message = FLBuilderStrings.savedStatus.nothingToSave;
216
+ FLBuilder.SaveManager.showStatusMessage(message);
217
+
218
+ setTimeout(function() {
219
+ FLBuilder.SaveManager.resetStatusMessage();
220
+ }, 2000);
221
+ }
222
+ },
223
+
224
+ onNextPrevTabShortcut: function( direction, e ) {
225
+
226
+ var $lightbox = $('.fl-lightbox:visible'),
227
+ $tabs = $lightbox.find('.fl-builder-settings-tabs a'),
228
+ $activeTab,
229
+ $nextTab;
230
+
231
+ if ( $lightbox.length > 0 ) {
232
+ $activeTab = $tabs.filter('a.fl-active');
233
+
234
+ if ( 'next' == direction ) {
235
+
236
+ if ( $activeTab.is( $tabs.last() ) ) {
237
+
238
+ $nextTab = $tabs.first();
239
+
240
+ } else {
241
+
242
+ $nextTab = $activeTab.next('a');
243
+ }
244
+
245
+ } else {
246
+
247
+ if ( $activeTab.is( $tabs.first() ) ) {
248
+ $nextTab = $tabs.last();
249
+ } else {
250
+ $nextTab = $activeTab.prev('a');
251
+ }
252
+ }
253
+ $nextTab.trigger('click');
254
+ }
255
+
256
+ FLBuilder._calculateSettingsTabsOverflow();
257
+ e.preventDefault();
258
+ },
259
+ };
260
+
261
+ var KeyShortcutsUI = {
262
+
263
+ isShowing: false,
264
+
265
+ /**
266
+ * Fire up the keyboard shortcut UI
267
+ *
268
+ * @return void
269
+ */
270
+ init: function() {
271
+
272
+ this.render();
273
+
274
+ FLBuilder.addHook( 'showKeyboardShortcuts', this.show.bind( this ) );
275
+ },
276
+
277
+ /**
278
+ * Render the UI into the DOM
279
+ *
280
+ * @return void
281
+ */
282
+ render: function() {
283
+ var renderUI = wp.template('fl-keyboard-shortcuts'),
284
+ renderData = FLBuilderConfig.keyboardShortcuts;
285
+
286
+ this.$el = $( renderUI( renderData ) );
287
+ $('body').append( this.$el );
288
+
289
+ this.$el.find('.dismiss-shortcut-ui').on('click', this.hide.bind( this ) );
290
+ this.$el.on('click', this.hide.bind( this ) );
291
+ },
292
+
293
+ /**
294
+ * Show the keyboard shortcut UI
295
+ *
296
+ * @return void
297
+ */
298
+ show: function() {
299
+ if ( this.isShowing ) return;
300
+ this.$el.addClass('is-showing');
301
+ this.isShowing = true;
302
+ },
303
+
304
+ /**
305
+ * Hide the keyboard shortcut UI
306
+ *
307
+ * @return void
308
+ */
309
+ hide: function() {
310
+ if ( !this.isShowing ) return;
311
+ this.$el.removeClass('is-showing');
312
+ this.isShowing = false;
313
+ },
314
+
315
+ /**
316
+ * Toggle the UI on and off
317
+ *
318
+ * @return void
319
+ */
320
+ toggle: function() {
321
+ if ( this.isShowing ) {
322
+ this.hide();
323
+ } else {
324
+ this.show();
325
+ }
326
+ },
327
+ }
328
+
329
+
330
+ /**
331
+ * Publish actions button bar UI
332
+ */
333
+ var PublishActions = FLExtendableObject.create({
334
+
335
+ /**
336
+ * Is the button bar showing?
337
+ * @var bool
338
+ */
339
+ isShowing: false,
340
+
341
+ /**
342
+ * Setup the bar
343
+ * @return void
344
+ */
345
+ init: function() {
346
+
347
+ this.$el = $('.fl-builder-publish-actions');
348
+ this.$defaultBarButtons = $('.fl-builder-bar-actions');
349
+ this.$clickAwayMask = $('.fl-builder-publish-actions-click-away-mask');
350
+
351
+ this.$doneBtn = this.$defaultBarButtons.find('.fl-builder-done-button');
352
+ this.$doneBtn.on('click', this.onDoneTriggered.bind(this));
353
+
354
+ this.$actions = this.$el.find('.fl-builder-button');
355
+ this.$actions.on('click', this.onActionClicked.bind(this));
356
+
357
+ FLBuilder.addHook('triggerDone', this.onDoneTriggered.bind(this));
358
+
359
+ var hide = this.hide.bind(this);
360
+ FLBuilder.addHook('cancelPublishActions', hide);
361
+ FLBuilder.addHook('endEditingSession', hide);
362
+ this.$clickAwayMask.on('click', hide );
363
+ },
364
+
365
+ /**
366
+ * Fired when the done button is clicked or hook is triggered.
367
+ * @return void
368
+ */
369
+ onDoneTriggered: function() {
370
+ if (FLBuilder.SaveManager.layoutNeedsPublish()) {
371
+ this.show();
372
+ } else {
373
+ if ( FLBuilderConfig.shouldRefreshOnPublish ) {
374
+ FLBuilder._exit();
375
+ } else {
376
+ FLBuilder._exitWithoutRefresh();
377
+ }
378
+ }
379
+ },
380
+
381
+ /**
382
+ * Display the publish actions.
383
+ * @return void
384
+ */
385
+ show: function() {
386
+ if (this.isShowing) return;
387
+
388
+ // Save existing settings first if any exist. Don't proceed if it fails.
389
+ if ( ! FLBuilder._triggerSettingsSave( false, true ) ) {
390
+ return;
391
+ }
392
+
393
+ this.$el.removeClass('is-hidden');
394
+ this.$defaultBarButtons.css('opacity', '0');
395
+ this.$clickAwayMask.show();
396
+ this.isShowing = true;
397
+ FLBuilder.triggerHook('didShowPublishActions');
398
+ },
399
+
400
+ /**
401
+ * Hide the publish actions.
402
+ * @return void
403
+ */
404
+ hide: function() {
405
+ if (!this.isShowing) return;
406
+ this.$el.addClass('is-hidden');
407
+ this.$defaultBarButtons.css('opacity', '1');
408
+ this.$clickAwayMask.hide();
409
+ this.isShowing = false;
410
+ },
411
+
412
+ /**
413
+ * Fired when a publish action (or cancel) is clicked.
414
+ * @return void
415
+ */
416
+ onActionClicked: function(e) {
417
+ var action = $(e.currentTarget).data('action');
418
+ switch(action) {
419
+ case "dismiss":
420
+ this.hide();
421
+ break;
422
+ case "discard":
423
+ this.hide();
424
+ EditingUI.muteToolbar();
425
+ FLBuilder._discardButtonClicked();
426
+ break;
427
+ case "publish":
428
+ this.hide();
429
+ EditingUI.muteToolbar();
430
+ FLBuilder._publishButtonClicked();
431
+ FLBuilder._destroyOverlayEvents();
432
+ break;
433
+ case "draft":
434
+ this.hide();
435
+ EditingUI.muteToolbar();
436
+ FLBuilder._draftButtonClicked();
437
+ break;
438
+ default:
439
+ // draft
440
+ this.hide();
441
+ EditingUI.muteToolbar();
442
+ FLBuilder._draftButtonClicked();
443
+ }
444
+ FLBuilder.triggerHook( action + 'ButtonClicked' );
445
+ },
446
+ });
447
+
448
+
449
+ /**
450
+ * Editing UI State Controller
451
+ */
452
+ var EditingUI = {
453
+
454
+ /**
455
+ * @var bool - whether or not the editor is in preview mode.
456
+ */
457
+ isPreviewing: false,
458
+
459
+ /**
460
+ * Setup the controller.
461
+ * @return void
462
+ */
463
+ init: function() {
464
+ this.$el = $('body');
465
+ this.$mainToolbar = $('.fl-builder-bar');
466
+ this.$mainToolbarContent = this.$mainToolbar.find('.fl-builder-bar-content');
467
+ this.$wpAdminBar = $('#wpadminbar');
468
+ this.$endPreviewBtn = $('.fl-builder--preview-actions .end-preview-btn');
469
+
470
+ FLBuilder.addHook('endEditingSession', this.endEditingSession.bind(this) );
471
+ FLBuilder.addHook('previewLayout', this.togglePreview.bind(this) );
472
+
473
+ // End preview btn
474
+ this.$endPreviewBtn.on('click', this.endPreview.bind(this));
475
+
476
+ // Preview mode device size icons
477
+ this.$deviceIcons = $('.fl-builder--preview-actions i');
478
+ this.$deviceIcons.on('click', this.onDeviceIconClick.bind(this));
479
+
480
+ // Admin bar link to re-enable editor
481
+ var $link = this.$wpAdminBar.find('#wp-admin-bar-fl-builder-frontend-edit-link > a, #wp-admin-bar-fl-theme-builder-frontend-edit-link > a');
482
+ $link.on('click', this.onClickPageBuilderToolbarLink.bind(this));
483
+
484
+ // Take admin bar links out of the tab order
485
+ $('#wpadminbar a').attr('tabindex', '-1');
486
+
487
+ var restart = this.restartEditingSession.bind(this);
488
+ FLBuilder.addHook('restartEditingSession', restart);
489
+
490
+ FLBuilder.addHook('didHideAllLightboxes', this.unmuteToolbar.bind(this));
491
+ FLBuilder.addHook('didCancelDiscard', this.unmuteToolbar.bind(this));
492
+ FLBuilder.addHook('didEnterRevisionPreview', this.hide.bind(this));
493
+ FLBuilder.addHook('didExitRevisionPreview', this.show.bind(this));
494
+ FLBuilder.addHook('didPublishLayout', this.onPublish.bind(this));
495
+ },
496
+
497
+ /**
498
+ * Handle exit w/o preview
499
+ * @return void
500
+ */
501
+ endEditingSession: function() {
502
+ FLBuilder._destroyOverlayEvents();
503
+ FLBuilder._removeAllOverlays();
504
+ FLBuilder._removeEmptyColHighlights();
505
+ FLBuilder._removeColHighlightGuides();
506
+ FLBuilder._unbindEvents();
507
+
508
+ $('html').removeClass('fl-builder-edit').addClass('fl-builder-show-admin-bar');
509
+ $('body').removeClass('fl-builder-edit');
510
+ $('#wpadminbar a').attr('tabindex', null );
511
+ this.hideMainToolbar();
512
+ FLBuilder.ContentPanel.hide();
513
+ FLBuilderLayout.init();
514
+ },
515
+
516
+ /**
517
+ * Re-enter the editor without refresh after having left without refresh.
518
+ * @return void
519
+ */
520
+ restartEditingSession: function(e) {
521
+
522
+ FLBuilder._initTemplateSelector();
523
+ FLBuilder._bindOverlayEvents();
524
+ FLBuilder._highlightEmptyCols();
525
+
526
+ $('html').addClass('fl-builder-edit').removeClass('fl-builder-show-admin-bar');
527
+ $('body').addClass('fl-builder-edit');
528
+ $('#wpadminbar a').attr('tabindex', '-1');
529
+ this.showMainToolbar();
530
+
531
+ e.preventDefault();
532
+ },
533
+
534
+ /**
535
+ * Handle re-entering the editor when you click the toolbar button.
536
+ * @return void
537
+ */
538
+ onClickPageBuilderToolbarLink: function(e) {
539
+ FLBuilder.triggerHook('restartEditingSession');
540
+ e.preventDefault();
541
+ },
542
+
543
+ /**
544
+ * Make admin bar dot green
545
+ *
546
+ * @return void
547
+ */
548
+ onPublish: function() {
549
+ var $dot = this.$wpAdminBar.find('#wp-admin-bar-fl-builder-frontend-edit-link > a span');
550
+ $dot.css('color', '#6bc373');
551
+ },
552
+
553
+ /**
554
+ * Hides the entire UI.
555
+ * @return void
556
+ */
557
+ hide: function() {
558
+ if ( $( 'html' ).hasClass( 'fl-builder-edit' ) ) {
559
+ FLBuilder._unbindEvents();
560
+ FLBuilder._destroyOverlayEvents();
561
+ FLBuilder._removeAllOverlays();
562
+ $('html').removeClass('fl-builder-edit')
563
+ $('body').removeClass('admin-bar');
564
+ this.hideMainToolbar();
565
+ FLBuilder.ContentPanel.hide();
566
+ FLBuilderLayout.init();
567
+ FLBuilder.triggerHook('didHideEditingUI');
568
+ }
569
+ },
570
+
571
+ /**
572
+ * Shows the UI when it's hidden.
573
+ * @return void
574
+ */
575
+ show: function() {
576
+ if ( ! $( 'html' ).hasClass( 'fl-builder-edit' ) ) {
577
+ FLBuilder._bindOverlayEvents();
578
+ this.showMainToolbar();
579
+ FLBuilderResponsiveEditing._switchTo('default');
580
+ $('html').addClass('fl-builder-edit');
581
+ $('body').addClass('admin-bar');
582
+ FLBuilder.triggerHook('didShowEditingUI');
583
+ }
584
+ },
585
+
586
+ /**
587
+ * Enter Preview Mode
588
+ * @return void
589
+ */
590
+ beginPreview: function() {
591
+
592
+ // Save existing settings first if any exist. Don't proceed if it fails.
593
+ if ( ! FLBuilder._triggerSettingsSave( false, true ) ) {
594
+ return;
595
+ }
596
+
597
+ this.isPreviewing = true;
598
+ this.hide();
599
+ $('html').addClass('fl-builder-preview');
600
+ $('html, body').removeClass('fl-builder-edit');
601
+ FLBuilder._removeEmptyColHighlights();
602
+ FLBuilder._removeColHighlightGuides();
603
+ FLBuilder.triggerHook('didBeginPreview');
604
+ },
605
+
606
+ /**
607
+ * Leave preview module
608
+ * @return void
609
+ */
610
+ endPreview: function() {
611
+ this.isPreviewing = false;
612
+ this.show();
613
+ FLBuilder._highlightEmptyCols();
614
+ $('html').removeClass('fl-builder-preview');
615
+ $('html, body').addClass('fl-builder-edit');
616
+ },
617
+
618
+ /**
619
+ * Toggle in and out of preview mode
620
+ * @return void
621
+ */
622
+ togglePreview: function() {
623
+ if (this.isPreviewing) {
624
+ this.endPreview();
625
+ } else {
626
+ this.beginPreview();
627
+ }
628
+ },
629
+
630
+ /**
631
+ * Hide the editor toolbar
632
+ * @return void
633
+ */
634
+ hideMainToolbar: function() {
635
+ this.$mainToolbar.addClass('is-hidden');
636
+ $('html').removeClass('fl-builder-is-showing-toolbar');
637
+ },
638
+
639
+ /**
640
+ * Show the editor toolbar
641
+ * @return void
642
+ */
643
+ showMainToolbar: function() {
644
+ this.unmuteToolbar();
645
+ this.$mainToolbar.removeClass('is-hidden');
646
+ $('html').addClass('fl-builder-is-showing-toolbar');
647
+ },
648
+
649
+ /**
650
+ * Handle clicking a responsive device icon while in preview
651
+ * @return void
652
+ */
653
+ onDeviceIconClick: function(e) {
654
+ var mode = $(e.target).data('mode');
655
+ FLBuilderResponsiveEditing._switchTo(mode);
656
+ },
657
+
658
+ /**
659
+ * Make toolbar innert
660
+ * @return void
661
+ */
662
+ muteToolbar: function() {
663
+ this.$mainToolbarContent.addClass('is-muted');
664
+ FLBuilder._hideTipTips();
665
+ },
666
+
667
+ /**
668
+ * Re-activate the toolbar
669
+ * @return void
670
+ */
671
+ unmuteToolbar: function() {
672
+ this.$mainToolbarContent.removeClass('is-muted');
673
+ },
674
+ };
675
+
676
+ var BrowserState = {
677
+
678
+ isEditing: true,
679
+
680
+ /**
681
+ * Init the browser state controller
682
+ *
683
+ * @return void
684
+ */
685
+ init: function() {
686
+
687
+ if ( history.pushState ) {
688
+ FLBuilder.addHook('endEditingSession', this.onLeaveBuilder.bind(this) );
689
+ FLBuilder.addHook('restartEditingSession', this.onEnterBuilder.bind(this) );
690
+ history.pushState( {}, document.title, FLBuilderConfig.editUrl );
691
+ window.onpopstate = this.onPopHistoryState.bind(this);
692
+ }
693
+ },
694
+
695
+ /**
696
+ * Handle restarting the edit session.
697
+ *
698
+ * @return void
699
+ */
700
+ onEnterBuilder: function() {
701
+ history.replaceState( {}, document.title, FLBuilderConfig.editUrl );
702
+ this.isEditing = true;
703
+ },
704
+
705
+ /**
706
+ * Handle exiting the builder.
707
+ *
708
+ * @return void
709
+ */
710
+ onLeaveBuilder: function() {
711
+ history.replaceState( {}, document.title, FLBuilderConfig.url );
712
+ this.isEditing = false;
713
+ },
714
+
715
+ /**
716
+ * Handle change browser history state.
717
+ *
718
+ * @var {Event} e
719
+ * @return void
720
+ */
721
+ onPopHistoryState: function(e) {
722
+ if ( ! this.isEditing && window.location.search.indexOf( 'fl_builder' ) > -1 ) {
723
+ FLBuilder.triggerHook('restartEditingSession');
724
+ } else if ( this.isEditing ) {
725
+ FLBuilder.triggerHook('endEditingSession');
726
+ }
727
+ },
728
+ };
729
+
730
+
731
+ /**
732
+ * Content Library Search
733
+ */
734
+ var SearchUI = {
735
+
736
+ /**
737
+ * Setup the search controller
738
+ * @return void
739
+ */
740
+ init: function() {
741
+ this.$searchBox = $('.fl-builder--search');
742
+ this.$searchBoxInput = this.$searchBox.find('input#fl-builder-search-input');
743
+ this.$searchBoxClear = this.$searchBox.find('.search-clear');
744
+
745
+ this.$searchBoxInput.on('focus', this.onSearchInputFocus.bind(this));
746
+ this.$searchBoxInput.on('blur', this.onSearchInputBlur.bind(this));
747
+ this.$searchBoxInput.on('keyup', this.onSearchTermChange.bind(this));
748
+ this.$searchBoxClear.on('click', this.onSearchTermClearClicked.bind(this));
749
+
750
+ this.renderSearchResults = wp.template('fl-search-results-panel');
751
+ this.renderNoResults = wp.template('fl-search-no-results');
752
+
753
+ FLBuilder.addHook('didStartDrag', this.hideSearchResults.bind(this));
754
+ FLBuilder.addHook('focusSearch', this.focusSearchBox.bind(this));
755
+ },
756
+
757
+ focusSearchBox: function() {
758
+ this.$searchBoxInput.trigger('focus');
759
+ },
760
+
761
+ /**
762
+ * Fires when focusing on the search field.
763
+ * @return void
764
+ */
765
+ onSearchInputFocus: function() {
766
+ this.$searchBox.addClass('is-expanded');
767
+ FLBuilder.triggerHook('didFocusSearchBox');
768
+ },
769
+
770
+ /**
771
+ * Fires when blurring out of the search field.
772
+ * @return void
773
+ */
774
+ onSearchInputBlur: function(e) {
775
+ this.$searchBox.removeClass('is-expanded has-text');
776
+ this.$searchBoxInput.val('');
777
+ this.hideSearchResults();
778
+ },
779
+
780
+ /**
781
+ * Fires when a key is pressed inside the search field.
782
+ * @return void
783
+ */
784
+ onSearchTermChange: function(e) {
785
+ if (e.key == 'Escape') {
786
+ this.$searchBoxInput.blur();
787
+ return;
788
+ }
789
+ FLBuilder.triggerHook('didBeginSearch');
790
+
791
+ var value = this.$searchBoxInput.val();
792
+ if (value != '') {
793
+ this.$searchBox.addClass('has-text');
794
+ } else {
795
+ this.$searchBox.removeClass('has-text');
796
+ }
797
+
798
+ var results = FLBuilder.Search.byTerm(value);
799
+ if (results.term != "") {
800
+ this.showSearchResults(results);
801
+ } else {
802
+ this.hideSearchResults();
803
+ }
804
+ },
805
+
806
+ /**
807
+ * Fires when the clear button is clicked.
808
+ * @return void
809
+ */
810
+ onSearchTermClearClicked: function() {
811
+ this.$searchBox.removeClass('has-text').addClass('is-expanded');
812
+ this.$searchBoxInput.val('').focus();
813
+
814
+ this.hideSearchResults();
815
+ },
816
+
817
+ /**
818
+ * Display the found results in the results panel.
819
+ * @var Object - the found results
820
+ * @return void
821
+ */
822
+ showSearchResults: function(data) {
823
+
824
+ if (data.total > 0) {
825
+ var $html = $(this.renderSearchResults(data)),
826
+ $panel = $('.fl-builder--search-results-panel');
827
+ $panel.html($html);
828
+
829
+ FLBuilder._initSortables();
830
+ } else {
831
+ var $html = $(this.renderNoResults(data)),
832
+ $panel = $('.fl-builder--search-results-panel');
833
+ $panel.html($html);
834
+ }
835
+ $('body').addClass('fl-builder-search-results-panel-is-showing');
836
+ },
837
+
838
+ /**
839
+ * Hide the search results panel
840
+ * @return void
841
+ */
842
+ hideSearchResults: function() {
843
+ $('body').removeClass('fl-builder-search-results-panel-is-showing');
844
+ },
845
+ };
846
+
847
+ var RowResize = {
848
+
849
+ /**
850
+ * @var {jQuery}
851
+ */
852
+ $row: null,
853
+
854
+ /**
855
+ * @var {jQuery}
856
+ */
857
+ $rowContent: null,
858
+
859
+ /**
860
+ * @var {Object}
861
+ */
862
+ row: null,
863
+
864
+ /**
865
+ * @var {Object}
866
+ */
867
+ drag: {},
868
+
869
+ /**
870
+ * Setup basic events for row content overlays
871
+ * @return void
872
+ */
873
+ init: function() {
874
+
875
+ if ( this.userCanResize() ) {
876
+ var $layoutContent = $( FLBuilder._contentClass );
877
+
878
+ $layoutContent.delegate('.fl-block-row-resize', 'mouseenter', this.onDragHandleHover.bind(this) );
879
+ $layoutContent.delegate('.fl-block-row-resize', 'mousedown', this.onDragHandleDown.bind(this) );
880
+ }
881
+ },
882
+
883
+ /**
884
+ * Check if the user is able to resize rows
885
+ *
886
+ * @return bool
887
+ */
888
+ userCanResize: function() {
889
+ return FLBuilderConfig.rowResize.userCanResizeRows;
890
+ },
891
+
892
+ /**
893
+ * Hover over a row resize drag handle.
894
+ * @return void
895
+ */
896
+ onDragHandleHover: function(e) {
897
+
898
+ if (this.drag.isDragging) {
899
+ return
900
+ };
901
+
902
+ var originalWidth,
903
+ $handle = $(e.target);
904
+
905
+ this.$row = $handle.closest('.fl-row');
906
+ this.$rowContent = this.$row.find('.fl-row-content');
907
+
908
+ this.row = {
909
+ node: this.$row.data('node'),
910
+ isFixedWidth: this.$row.hasClass('fl-row-fixed-width'),
911
+ settings: $( '.fl-builder-row-settings[data-node=' + this.$row.data( 'node' ) + ']' )
912
+ };
913
+
914
+ this.drag = {
915
+ edge: null,
916
+ isDragging: false,
917
+ originalPosition: null,
918
+ originalWidth: null,
919
+ calculatedWidth: null,
920
+ operation: null,
921
+ };
922
+
923
+ if (this.row.isFixedWidth) {
924
+ this.drag.originalWidth = this.$row.width();
925
+ } else {
926
+ this.drag.originalWidth = this.$rowContent.width();
927
+ }
928
+
929
+ this.dragInit();
930
+ },
931
+
932
+ /**
933
+ * Handle mouse down on the drag handle
934
+ * @return void
935
+ */
936
+ onDragHandleDown: function() {
937
+ $('body').addClass( 'fl-builder-row-resizing' );
938
+ },
939
+
940
+ /**
941
+ * Setup the draggable handler
942
+ * @return void
943
+ */
944
+ dragInit: function(e) {
945
+ this.$row.find('.fl-block-row-resize').draggable( {
946
+ axis : 'x',
947
+ start : this.dragStart.bind(this),
948
+ drag : this.dragging.bind(this),
949
+ stop : this.dragStop.bind(this)
950
+ });
951
+ },
952
+
953
+ /**
954
+ * Handle drag started
955
+ * @var {Event}
956
+ * @var {Object}
957
+ * @return void
958
+ */
959
+ dragStart: function(e, ui) {
960
+
961
+ var body = $( 'body' ),
962
+ $handle = $(ui.helper);
963
+
964
+ this.drag.isDragging = true;
965
+
966
+ if (this.row.isFixedWidth) {
967
+ this.drag.originalWidth = this.$row.width();
968
+ } else {
969
+ this.drag.originalWidth = this.$rowContent.width();
970
+ }
971
+
972
+ if ($handle.hasClass( 'fl-block-col-resize-e' )) {
973
+ this.drag.edge = 'e';
974
+ this.$feedback = $handle.find('.fl-block-col-resize-feedback-left');
975
+ }
976
+ if ($handle.hasClass( 'fl-block-col-resize-w' )) {
977
+ this.drag.edge = 'w';
978
+ this.$feedback = $handle.find('.fl-block-col-resize-feedback-right');
979
+ }
980
+
981
+ body.addClass( 'fl-builder-row-resizing' );
982
+ FLBuilder._colResizing = true;
983
+ FLBuilder._destroyOverlayEvents();
984
+ FLBuilder._closePanel();
985
+ },
986
+
987
+ /**
988
+ * Handle drag
989
+ * @var {Event}
990
+ * @var {Object}
991
+ * @return void
992
+ */
993
+ dragging: function(e, ui) {
994
+
995
+ var currentPosition = ui.position.left,
996
+ originalPosition = ui.originalPosition.left,
997
+ originalWidth = this.drag.originalWidth,
998
+ distance = 0,
999
+ edge = this.drag.edge,
1000
+ minAllowedWidth = FLBuilderConfig.rowResize.minAllowedWidth,
1001
+ maxAllowedWidth = FLBuilderConfig.rowResize.maxAllowedWidth;
1002
+
1003
+ if (originalPosition !== currentPosition) {
1004
+
1005
+ if (originalPosition > currentPosition) {
1006
+ if (edge === 'w') {
1007
+ this.drag.operation = '+';
1008
+ } else {
1009
+ this.drag.operation = '-';
1010
+ }
1011
+ } else {
1012
+ if (edge === 'e') {
1013
+ this.drag.operation = '+';
1014
+ } else {
1015
+ this.drag.operation = '-';
1016
+ }
1017
+ }
1018
+
1019
+ distance = Math.abs(originalPosition - currentPosition);
1020
+
1021
+ if (this.drag.operation === '+') {
1022
+ this.drag.calculatedWidth = originalWidth + (distance * 2);
1023
+ } else {
1024
+ this.drag.calculatedWidth = originalWidth - (distance * 2);
1025
+ }
1026
+
1027
+ if ( false !== minAllowedWidth && this.drag.calculatedWidth < minAllowedWidth ) {
1028
+ this.drag.calculatedWidth = minAllowedWidth;
1029
+ }
1030
+ if ( false !== maxAllowedWidth && this.drag.calculatedWidth > maxAllowedWidth ) {
1031
+ this.drag.calculatedWidth = maxAllowedWidth;
1032
+ }
1033
+
1034
+
1035
+ if (this.row.isFixedWidth) {
1036
+ this.$row.css('max-width', this.drag.calculatedWidth + 'px');
1037
+ }
1038
+
1039
+ this.$rowContent.css('max-width', this.drag.calculatedWidth + 'px');
1040
+
1041
+ if (!_.isUndefined(this.$feedback)) {
1042
+ this.$feedback.html(this.drag.calculatedWidth + 'px').show();
1043
+ }
1044
+
1045
+ if ( this.row.settings.length ) {
1046
+ this.row.settings.find( '[name=max_content_width]' ).val( this.drag.calculatedWidth );
1047
+ }
1048
+ }
1049
+ },
1050
+
1051
+ /**
1052
+ * Handle drag ended
1053
+ * @var {Event}
1054
+ * @var {Object}
1055
+ * @return void
1056
+ */
1057
+ dragStop: function(e, ui) {
1058
+ this.drag.isDragging = false;
1059
+
1060
+ if (!_.isUndefined(this.$feedback)) {
1061
+ this.$feedback.hide();
1062
+ }
1063
+
1064
+ var data = {
1065
+ action: 'resize_row_content',
1066
+ node: this.row.node,
1067
+ width: this.drag.calculatedWidth
1068
+ },
1069
+ body = $( 'body' );
1070
+
1071
+ FLBuilder.ajax(data);
1072
+ FLBuilder._bindOverlayEvents();
1073
+ body.removeClass( 'fl-builder-row-resizing' );
1074
+
1075
+ $( '.fl-block-overlay' ).each( function() {
1076
+ FLBuilder._buildOverlayOverflowMenu( $( this ) );
1077
+ } );
1078
+
1079
+ $('body').removeClass( 'fl-builder-row-resizing' );
1080
+
1081
+ // Set the resizing flag to false with a timeout so other events get the right value.
1082
+ setTimeout( function() { FLBuilder._colResizing = false; }, 50 );
1083
+
1084
+ FLBuilder.triggerHook( 'didResizeRow', {
1085
+ rowId : this.row.node,
1086
+ rowWidth : this.drag.calculatedWidth
1087
+ } );
1088
+ },
1089
+ };
1090
+
1091
+
1092
+ var Toolbar = {
1093
+
1094
+ /**
1095
+ * wp.template id suffix
1096
+ */
1097
+ templateName: 'fl-toolbar',
1098
+
1099
+ /**
1100
+ * Initialize the toolbar controller
1101
+ *
1102
+ * @return void
1103
+ */
1104
+ init: function() {
1105
+ this.template = wp.template(this.templateName);
1106
+ this.render();
1107
+ this.initTipTips();
1108
+
1109
+ /* "Add Content" Button */
1110
+ var $addContentBtn = this.$el.find('.fl-builder-content-panel-button');
1111
+ $addContentBtn.on('click', FLBuilder._togglePanel );
1112
+
1113
+ this.$el.find('.fl-builder-buy-button').on('click', FLBuilder._upgradeClicked);
1114
+ this.$el.find('.fl-builder-upgrade-button').on('click', FLBuilder._upgradeClicked);
1115
+
1116
+ // Old search controller
1117
+ //SearchUI.init();
1118
+ },
1119
+
1120
+ /**
1121
+ * Render the toolbar html
1122
+ * @param object
1123
+ * @return void
1124
+ */
1125
+ render: function(data) {
1126
+ var $html = $(this.template(data));
1127
+ this.$el = $html;
1128
+ this.el = $html.get(0);
1129
+ EditingUI.$mainToolbar = this.$el;
1130
+ $('body').prepend($html);
1131
+ $('html').addClass('fl-builder-is-showing-toolbar');
1132
+ },
1133
+
1134
+ /**
1135
+ * Add tooltips
1136
+ *
1137
+ * @return void
1138
+ */
1139
+ initTipTips: function() {
1140
+
1141
+ // Saving indicator tooltip
1142
+ $('.fl-builder--saving-indicator').tipTip({
1143
+ defaultPosition: 'bottom',
1144
+ edgeOffset: 14
1145
+ });
1146
+
1147
+ // Publish actions tooltip
1148
+ $('.fl-builder-publish-actions .fl-builder-button-group .fl-builder-button').tipTip({
1149
+ defaultPosition: 'bottom',
1150
+ edgeOffset: 6
1151
+ });
1152
+ }
1153
+ };
1154
+
1155
+ /**
1156
+ * Kick off initializers when FLBuilder inits.
1157
+ */
1158
+ $(function() {
1159
+
1160
+ // Render Order matters here
1161
+ FLBuilder.ContentPanel.init();
1162
+
1163
+ if ( !FLBuilderConfig.simpleUi ) {
1164
+ FLBuilder.MainMenu.init();
1165
+ }
1166
+
1167
+ if ( FLBuilderConfig.showToolbar ) {
1168
+ Toolbar.init();
1169
+ FLBuilder.ContentPanel.alignPanelArrow();
1170
+ } else {
1171
+ $('html').addClass('fl-builder-no-toolbar');
1172
+ }
1173
+ // End Render Order
1174
+
1175
+ KeyShortcuts.init();
1176
+ KeyShortcutsUI.init();
1177
+ EditingUI.init();
1178
+ BrowserState.init();
1179
+ RowResize.init();
1180
+ PublishActions.init();
1181
+
1182
+ FLBuilder.triggerHook( 'didInitUI' );
1183
+ });
1184
+
1185
+ })(jQuery, FLBuilder);
js/fl-builder.js CHANGED
@@ -176,6 +176,26 @@
176
  */
177
  _multiplePhotoSelector : null,
178
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  /**
180
  * A jQuery reference to a row that a new column group
181
  * should be added to once it's finished rendering.
@@ -292,11 +312,15 @@
292
  FLBuilder._initSortables();
293
  FLBuilder._initStrings();
294
  FLBuilder._initTipTips();
 
295
  FLBuilder._bindEvents();
296
  FLBuilder._bindOverlayEvents();
297
  FLBuilder._setupEmptyLayout();
298
  FLBuilder._highlightEmptyCols();
299
- FLBuilder._showTourOrTemplates();
 
 
 
300
  },
301
 
302
  /**
@@ -319,7 +343,7 @@
319
  return jQuery.fn.oldReady( function() {
320
  try {
321
  if ( 'function' == typeof fn ) {
322
- fn();
323
  }
324
  }
325
  catch ( e ){
@@ -437,29 +461,6 @@
437
  });
438
  },
439
 
440
- /**
441
- * Initializes the lightboxes for the builder interface.
442
- *
443
- * @since 1.0
444
- * @access private
445
- * @method _initLightboxes
446
- */
447
- _initLightboxes: function()
448
- {
449
- /* Main builder lightbox */
450
- FLBuilder._lightbox = new FLLightbox({
451
- className: 'fl-builder-lightbox fl-builder-settings-lightbox'
452
- });
453
-
454
- FLBuilder._lightbox.on('close', FLBuilder._lightboxClosed);
455
- FLBuilder._lightbox.on('beforeClose', FLBuilder._destroyEditorFields);
456
-
457
- /* Actions lightbox */
458
- FLBuilder._actionsLightbox = new FLLightbox({
459
- className: 'fl-builder-actions-lightbox'
460
- });
461
- },
462
-
463
  /**
464
  * Initializes jQuery sortables for drag and drop.
465
  *
@@ -473,7 +474,7 @@
473
  appendTo: 'body',
474
  cursor: 'move',
475
  cursorAt: {
476
- left: 60,
477
  top: 20
478
  },
479
  distance: 1,
@@ -612,10 +613,14 @@
612
  */
613
  _bindEvents: function()
614
  {
 
615
  /* Links */
616
- $('a').on('click', FLBuilder._preventDefault);
 
617
  $('.fl-page-nav .nav a').on('click', FLBuilder._headerLinkClicked);
618
 
 
 
619
  /* Heartbeat */
620
  $(document).on('heartbeat-tick', FLBuilder._initPostLock);
621
 
@@ -629,15 +634,6 @@
629
  $('body').delegate('.fl-builder-submenu', 'mouseleave', FLBuilder._submenuMouseleave);
630
  $('body').delegate('.fl-builder-submenu .fl-builder-has-submenu', 'mouseenter', FLBuilder._submenuNestedParentMouseenter);
631
 
632
- /* Bar */
633
- $('.fl-builder-tools-button').on('click', FLBuilder._toolsClicked);
634
- $('.fl-builder-done-button').on('click', FLBuilder._doneClicked);
635
- $('.fl-builder-add-content-button').on('click', FLBuilder._showPanel);
636
- $('.fl-builder-templates-button').on('click', FLBuilder._changeTemplateClicked);
637
- $('.fl-builder-buy-button').on('click', FLBuilder._upgradeClicked);
638
- $('.fl-builder-upgrade-button').on('click', FLBuilder._upgradeClicked);
639
- $('.fl-builder-help-button').on('click', FLBuilder._helpButtonClicked);
640
-
641
  /* Panel */
642
  $('.fl-builder-panel-actions .fl-builder-panel-close').on('click', FLBuilder._closePanel);
643
  $('.fl-builder-blocks-section-title').on('click', FLBuilder._blockSectionTitleClicked);
@@ -647,21 +643,12 @@
647
  $('body').delegate('.fl-builder-node-template-edit', 'click', FLBuilder._editNodeTemplateClicked);
648
  $('body').delegate('.fl-builder-node-template-delete', 'click', FLBuilder._deleteNodeTemplateClicked);
649
 
650
- /* Drag and Drop */
651
- $('body').delegate('.fl-builder-block', 'mousedown', FLBuilder._blockDragInit);
652
  $('body').on('mouseup', FLBuilder._blockDragCancel);
653
 
654
  /* Actions Lightbox */
655
  $('body').delegate('.fl-builder-actions .fl-builder-cancel-button', 'click', FLBuilder._cancelButtonClicked);
656
 
657
- /* Expand/Contract Lightbox */
658
- $('body').delegate('.fl-lightbox-controls .fa', 'click', FLBuilder._resizeLightbox);
659
-
660
- /* Save Actions */
661
- $('body').delegate('.fl-builder-save-actions .fl-builder-publish-button', 'click', FLBuilder._publishButtonClicked);
662
- $('body').delegate('.fl-builder-save-actions .fl-builder-draft-button', 'click', FLBuilder._draftButtonClicked);
663
- $('body').delegate('.fl-builder-save-actions .fl-builder-discard-button', 'click', FLBuilder._discardButtonClicked);
664
-
665
  /* Tools Actions */
666
  $('body').delegate('.fl-builder-save-user-template-button', 'click', FLBuilder._saveUserTemplateClicked);
667
  $('body').delegate('.fl-builder-duplicate-layout-button', 'click', FLBuilder._duplicateLayoutClicked);
@@ -672,9 +659,7 @@
672
  $('body').delegate('.fl-builder-global-settings .fl-builder-settings-save', 'click', FLBuilder._saveGlobalSettingsClicked);
673
  $('body').delegate('.fl-builder-global-settings .fl-builder-settings-cancel', 'click', FLBuilder._cancelLayoutSettingsClicked);
674
 
675
- /* Template Selector */
676
- $('body').delegate('.fl-template-category-select', 'change', FLBuilder._templateCategoryChanged);
677
- $('body').delegate('.fl-template-preview', 'click', FLBuilder._templateClicked);
678
  $('body').delegate('.fl-user-template', 'click', FLBuilder._userTemplateClicked);
679
  $('body').delegate('.fl-user-template-edit', 'click', FLBuilder._editUserTemplateClicked);
680
  $('body').delegate('.fl-user-template-delete', 'click', FLBuilder._deleteUserTemplateClicked);
@@ -687,7 +672,6 @@
687
 
688
  /* Help Actions */
689
  $('body').delegate('.fl-builder-help-tour-button', 'click', FLBuilder._startHelpTour);
690
- $('body').delegate('.fl-builder-help-video-button', 'click', FLBuilder._watchVideoClicked);
691
  $('body').delegate('.fl-builder-knowledge-base-button', 'click', FLBuilder._viewKnowledgeBaseClicked);
692
  $('body').delegate('.fl-builder-forums-button', 'click', FLBuilder._visitForumsClicked);
693
 
@@ -706,8 +690,12 @@
706
  $('body').delegate('.fl-row-overlay', 'click', FLBuilder._rowSettingsClicked);
707
  $('body').delegate('.fl-builder-row-settings .fl-builder-settings-save', 'click', FLBuilder._saveSettings);
708
 
 
 
 
709
  /* Columns */
710
  $('body').delegate('.fl-col-overlay .fl-block-move', 'mousedown', FLBuilder._colDragInit);
 
711
  $('body').delegate('.fl-col-overlay .fl-block-remove', 'click', FLBuilder._deleteColClicked);
712
  $('body').delegate('.fl-col-overlay', 'click', FLBuilder._colSettingsClicked);
713
  $('body').delegate('.fl-builder-col-settings .fl-builder-settings-save', 'click', FLBuilder._saveSettings);
@@ -738,8 +726,15 @@
738
 
739
  /* Settings */
740
  $('body').delegate('.fl-builder-settings-tabs a', 'click', FLBuilder._settingsTabClicked);
 
 
741
  $('body').delegate('.fl-builder-settings-cancel', 'click', FLBuilder._settingsCancelClicked);
742
 
 
 
 
 
 
743
  /* Tooltips */
744
  $('body').delegate('.fl-help-tooltip-icon', 'mouseover', FLBuilder._showHelpTooltip);
745
  $('body').delegate('.fl-help-tooltip-icon', 'mouseout', FLBuilder._hideHelpTooltip);
@@ -792,8 +787,23 @@
792
  $('body').delegate('.fl-loop-data-source-select select[name=data_source]', 'change', FLBuilder._loopDataSourceChange);
793
  $('body').delegate('.fl-custom-query select[name=post_type]', 'change', FLBuilder._customQueryPostTypeChange);
794
 
795
- /* Text Fields - Add Value Selector */
796
- $('body').delegate('.fl-select-add-value', 'change', FLBuilder._textFieldAddValueSelectChange);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
797
  },
798
 
799
  /**
@@ -876,6 +886,7 @@
876
  _headerLinkClicked: function(e)
877
  {
878
  var link = $(this),
 
879
  href = link.attr('href');
880
 
881
  // ignore links with a #hash
@@ -890,7 +901,7 @@
890
  }
891
 
892
  FLBuilder._exitUrl = href.indexOf('?') > -1 ? href : href + '?fl_builder';
893
- FLBuilder._doneClicked();
894
  },
895
 
896
  /**
@@ -933,7 +944,7 @@
933
  }
934
  } ).tipTip( {
935
  defaultPosition : 'top',
936
- delay : 1500
937
  } );
938
  },
939
 
@@ -946,7 +957,7 @@
946
  */
947
  _hideTipTips: function()
948
  {
949
- $('#tiptip_holder').stop().remove();
950
  },
951
 
952
  /* Submenus
@@ -962,10 +973,12 @@
962
  */
963
  _submenuParentClicked: function( e )
964
  {
965
- var parent = $( this ),
 
966
  submenu = parent.find( '.fl-builder-submenu' );
967
 
968
  if ( parent.hasClass( 'fl-builder-submenu-open' ) ) {
 
969
  parent.removeClass( 'fl-builder-submenu-open' );
970
  parent.removeClass( 'fl-builder-submenu-right' );
971
  }
@@ -975,6 +988,7 @@
975
  parent.addClass( 'fl-builder-submenu-right' );
976
  }
977
 
 
978
  parent.addClass( 'fl-builder-submenu-open' );
979
  }
980
 
@@ -993,9 +1007,11 @@
993
  */
994
  _submenuChildClicked: function( e )
995
  {
996
- var parent = $( this ).parents( '.fl-builder-has-submenu' );
 
997
 
998
  if ( ! parent.parents( '.fl-builder-has-submenu' ).length ) {
 
999
  parent.removeClass( 'fl-builder-submenu-open' );
1000
  }
1001
  },
@@ -1028,8 +1044,10 @@
1028
  */
1029
  _submenuMouseleave: function( e )
1030
  {
1031
- var menu = $( this ),
 
1032
  timeout = setTimeout( function() {
 
1033
  menu.closest( '.fl-builder-has-submenu' ).removeClass( 'fl-builder-submenu-open' );
1034
  }, 500 );
1035
 
@@ -1070,103 +1088,6 @@
1070
  /* Bar
1071
  ----------------------------------------------------------*/
1072
 
1073
- /**
1074
- * Shows the actions lightbox when the tools button is clicked.
1075
- *
1076
- * @since 1.0
1077
- * @access private
1078
- * @method _toolsClicked
1079
- */
1080
- _toolsClicked: function()
1081
- {
1082
- var buttons = [],
1083
- lite = FLBuilderConfig.lite,
1084
- enabledTemplates = FLBuilderConfig.enabledTemplates,
1085
- isRowTemplate = 'row' == FLBuilderConfig.userTemplateType,
1086
- isModuleTemplate = 'module' == FLBuilderConfig.userTemplateType;
1087
-
1088
- // Template buttons
1089
- if(!lite && !isRowTemplate && !isModuleTemplate && (enabledTemplates == 'enabled' || enabledTemplates == 'user')) {
1090
- buttons[ 10 ] = {
1091
- 'key': 'save-user-template',
1092
- 'label': FLBuilderStrings.saveTemplate
1093
- };
1094
- }
1095
-
1096
- // Duplicate button
1097
- if(FLBuilderConfig.isUserTemplate) {
1098
- if ( typeof window.opener == 'undefined' || ! window.opener ) {
1099
- buttons[ 20 ] = {
1100
- 'key': 'duplicate-layout',
1101
- 'label': FLBuilderStrings.duplicateLayout
1102
- };
1103
- }
1104
- }
1105
- else {
1106
- buttons[ 20 ] = {
1107
- 'key': 'duplicate-layout',
1108
- 'label': FLBuilderStrings.duplicateLayout
1109
- };
1110
- }
1111
-
1112
- // Layout settings button
1113
- buttons[ 30 ] = {
1114
- 'key': 'layout-settings',
1115
- 'label': FLBuilderStrings.editLayoutSettings
1116
- };
1117
-
1118
- // Global settings button
1119
- buttons[ 40 ] = {
1120
- 'key': 'global-settings',
1121
- 'label': FLBuilderStrings.editGlobalSettings
1122
- };
1123
-
1124
- // Show the lightbox.
1125
- FLBuilder._showActionsLightbox({
1126
- 'className' : 'fl-builder-tools-actions',
1127
- 'title' : FLBuilderStrings.actionsLightboxTitle,
1128
- 'buttons' : buttons
1129
- });
1130
- },
1131
-
1132
- /**
1133
- * Shows the actions lightbox when the done button is clicked.
1134
- *
1135
- * @since 1.0
1136
- * @access private
1137
- * @method _doneClicked
1138
- */
1139
- _doneClicked: function()
1140
- {
1141
- var buttons = [],
1142
- publishButtonText = FLBuilderStrings.publish;
1143
-
1144
- if(FLBuilderConfig.postStatus != 'publish' && !FLBuilderConfig.userCanPublish) {
1145
- publishButtonText = FLBuilderStrings.submitForReview;
1146
- }
1147
-
1148
- buttons[ 10 ] = {
1149
- 'key': 'publish',
1150
- 'label': publishButtonText
1151
- };
1152
-
1153
- buttons[ 20 ] = {
1154
- 'key': 'draft',
1155
- 'label': FLBuilderStrings.draft
1156
- };
1157
-
1158
- buttons[ 30 ] = {
1159
- 'key': 'discard',
1160
- 'label': FLBuilderStrings.discard
1161
- };
1162
-
1163
- FLBuilder._showActionsLightbox({
1164
- 'className': 'fl-builder-save-actions',
1165
- 'title': FLBuilderStrings.actionsLightboxTitle,
1166
- 'buttons': buttons
1167
- });
1168
- },
1169
-
1170
  /**
1171
  * Opens a new window with the upgrade URL when the
1172
  * upgrade button is clicked.
@@ -1181,46 +1102,16 @@
1181
  },
1182
 
1183
  /**
1184
- * Shows the actions lightbox when the help button is clicked.
1185
  *
1186
- * @since 1.4.9
1187
  * @access private
1188
- * @method _helpButtonClicked
 
 
1189
  */
1190
- _helpButtonClicked: function()
1191
- {
1192
- var buttons = {};
1193
-
1194
- if ( FLBuilderConfig.help.tour ) {
1195
- buttons[ 10 ] = {
1196
- 'key': 'help-tour',
1197
- 'label': FLBuilderStrings.takeHelpTour
1198
- };
1199
- }
1200
- if ( FLBuilderConfig.help.video ) {
1201
- buttons[ 20 ] = {
1202
- 'key': 'help-video',
1203
- 'label': FLBuilderStrings.watchHelpVideo
1204
- };
1205
- }
1206
- if ( FLBuilderConfig.help.knowledge_base ) {
1207
- buttons[ 30 ] = {
1208
- 'key': 'knowledge-base',
1209
- 'label': FLBuilderStrings.viewKnowledgeBase
1210
- };
1211
- }
1212
- if ( FLBuilderConfig.help.forums ) {
1213
- buttons[ 40 ] = {
1214
- 'key': 'forums',
1215
- 'label': FLBuilderStrings.visitForums
1216
- };
1217
- }
1218
-
1219
- FLBuilder._showActionsLightbox({
1220
- 'className': 'fl-builder-help-actions',
1221
- 'title': FLBuilderStrings.actionsLightboxTitle,
1222
- 'buttons': buttons
1223
- });
1224
  },
1225
 
1226
  /* Panel
@@ -1235,9 +1126,6 @@
1235
  */
1236
  _closePanel: function()
1237
  {
1238
- $('.fl-builder-panel').stop(true, true).animate({ right: '-350px' }, 500, function(){ $(this).hide(); });
1239
- $('.fl-builder-bar .fl-builder-add-content-button').stop(true, true).fadeIn();
1240
-
1241
  FLBuilder.triggerHook('hideContentPanel');
1242
  },
1243
 
@@ -1250,12 +1138,21 @@
1250
  */
1251
  _showPanel: function()
1252
  {
1253
- $('.fl-builder-bar .fl-builder-add-content-button').stop(true, true).fadeOut();
1254
- $('.fl-builder-panel').stop(true, true).show().animate({ right: '0' }, 500);
1255
-
1256
  FLBuilder.triggerHook('showContentPanel');
1257
  },
1258
 
 
 
 
 
 
 
 
 
 
 
 
 
1259
  /**
1260
  * Opens or closes a section in the builder's content panel
1261
  * when a section title is clicked.
@@ -1283,22 +1180,65 @@
1283
  /* Save Actions
1284
  ----------------------------------------------------------*/
1285
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1286
  /**
1287
  * Publishes the layout when the publish button is clicked.
1288
  *
1289
  * @since 1.0
1290
  * @access private
 
1291
  * @method _publishButtonClicked
1292
  */
1293
- _publishButtonClicked: function()
1294
  {
1295
- FLBuilder.showAjaxLoader();
 
1296
 
1297
- FLBuilder.ajax({
1298
- action: 'save_layout'
1299
- }, FLBuilder._exit);
 
 
 
 
 
 
 
 
 
 
 
 
 
1300
 
1301
- FLBuilder._actionsLightbox.close();
 
 
 
1302
  },
1303
 
1304
  /**
@@ -1315,8 +1255,6 @@
1315
  FLBuilder.ajax({
1316
  action: 'save_draft'
1317
  }, FLBuilder._exit);
1318
-
1319
- FLBuilder._actionsLightbox.close();
1320
  },
1321
 
1322
  /**
@@ -1338,8 +1276,8 @@
1338
  FLBuilder.ajax({
1339
  action: 'clear_draft_layout'
1340
  }, FLBuilder._exit);
1341
-
1342
- FLBuilder._actionsLightbox.close();
1343
  }
1344
  },
1345
 
@@ -1373,7 +1311,11 @@
1373
  if ( FLBuilderConfig.isUserTemplate && typeof window.opener != 'undefined' && window.opener ) {
1374
 
1375
  if ( typeof window.opener.FLBuilder != 'undefined' ) {
1376
- window.opener.FLBuilder._updateLayout();
 
 
 
 
1377
  }
1378
 
1379
  window.close();
@@ -1393,6 +1335,32 @@
1393
  }
1394
  },
1395
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1396
  /* Tools Actions
1397
  ----------------------------------------------------------*/
1398
 
@@ -1405,7 +1373,6 @@
1405
  */
1406
  _duplicateLayoutClicked: function()
1407
  {
1408
- FLBuilder._actionsLightbox.close();
1409
  FLBuilder.showAjaxLoader();
1410
 
1411
  FLBuilder.ajax({
@@ -1442,29 +1409,13 @@
1442
  */
1443
  _layoutSettingsClicked: function()
1444
  {
1445
- FLBuilder._actionsLightbox.close();
1446
- FLBuilder._showLightbox();
1447
- FLBuilder._closePanel();
1448
-
1449
- FLBuilder.ajax({
1450
- action: 'render_layout_settings'
1451
- }, FLBuilder._layoutSettingsLoaded);
1452
- },
1453
-
1454
- /**
1455
- * Sets the lightbox content when the layout settings have loaded.
1456
- *
1457
- * @since 1.7
1458
- * @access private
1459
- * @method _layoutSettingsLoaded
1460
- * @param {String} response The JSON with the HTML for the layout settings form.
1461
- */
1462
- _layoutSettingsLoaded: function( response )
1463
- {
1464
- var data = JSON.parse( response );
1465
-
1466
- FLBuilder._setSettingsFormContent( data.html );
1467
- FLBuilder._layoutSettingsInitCSS();
1468
  },
1469
 
1470
  /**
@@ -1550,7 +1501,10 @@
1550
  FLBuilder.ajax( {
1551
  action: 'save_layout_settings',
1552
  settings: settings
1553
- }, FLBuilder._updateLayout );
 
 
 
1554
  },
1555
 
1556
  /**
@@ -1588,43 +1542,13 @@
1588
  */
1589
  _globalSettingsClicked: function()
1590
  {
1591
- FLBuilder._actionsLightbox.close();
1592
- FLBuilder._showLightbox();
1593
-
1594
- FLBuilder.ajax({
1595
- action: 'render_global_settings'
1596
- }, FLBuilder._globalSettingsLoaded);
1597
- },
1598
-
1599
- /**
1600
- * Sets the lightbox content when the global settings have loaded.
1601
- *
1602
- * @since 1.0
1603
- * @access private
1604
- * @method _globalSettingsLoaded
1605
- * @param {String} response The JSON with the HTML for the global settings form.
1606
- */
1607
- _globalSettingsLoaded: function(response)
1608
- {
1609
- var data = JSON.parse(response);
1610
-
1611
- FLBuilder._setSettingsFormContent(data.html);
1612
- FLBuilder._layoutSettingsInitCSS();
1613
-
1614
- FLBuilder._initSettingsValidation({
1615
- row_width: {
1616
- required: true,
1617
- number: true
1618
- },
1619
- responsive_breakpoint: {
1620
- required: true,
1621
- number: true
1622
- },
1623
- medium_breakpoint: {
1624
- required: true,
1625
- number: true
1626
- }
1627
- });
1628
  },
1629
 
1630
  /**
@@ -1666,6 +1590,8 @@
1666
  {
1667
  FLBuilderConfig.global = JSON.parse( response );
1668
 
 
 
1669
  FLBuilder._updateLayout();
1670
  },
1671
 
@@ -1682,138 +1608,45 @@
1682
  */
1683
  _initTemplateSelector: function()
1684
  {
1685
- var rows = $(FLBuilder._contentClass).find('.fl-row');
1686
-
1687
- if(rows.length === 0) {
1688
- FLBuilder._showTemplateSelector();
1689
- }
1690
- },
1691
-
1692
- /**
1693
- * Shows the template selector when the templates button
1694
- * has been clicked.
1695
- *
1696
- * @since 1.0
1697
- * @access private
1698
- * @method _changeTemplateClicked
1699
- */
1700
- _changeTemplateClicked: function()
1701
- {
1702
- FLBuilder._actionsLightbox.close();
1703
- FLBuilder._showTemplateSelector();
1704
- },
1705
-
1706
- /**
1707
- * Shows the template selector lightbox.
1708
- *
1709
- * @since 1.0
1710
- * @access private
1711
- * @method _showTemplateSelector
1712
- */
1713
- _showTemplateSelector: function()
1714
- {
1715
- if ( FLBuilderConfig.simpleUi ) {
1716
- return;
1717
- }
1718
- if ( 'row' == FLBuilderConfig.userTemplateType || 'module' == FLBuilderConfig.userTemplateType ) {
1719
- return;
1720
- }
1721
- if ( 'disabled' == FLBuilderConfig.enabledTemplates ) {
1722
- return;
1723
- }
1724
- if ( 0 === $( '.fl-builder-templates-button' ).length ) {
1725
- return;
1726
- }
1727
-
1728
- FLBuilder._showLightbox( false );
1729
-
1730
- FLBuilder.ajax({
1731
- action: 'render_template_selector'
1732
- }, FLBuilder._templateSelectorLoaded );
1733
- },
1734
-
1735
- /**
1736
- * Sets the lightbox content when the template selector has loaded.
1737
- *
1738
- * @since 1.0
1739
- * @access private
1740
- * @method _templateSelectorLoaded
1741
- * @param {String} response The JSON with the HTML for the template selector.
1742
- */
1743
- _templateSelectorLoaded: function( response )
1744
- {
1745
- var data = JSON.parse( response ),
1746
- select = null,
1747
- userTemplates = null;
1748
-
1749
- // Set the lightbox content.
1750
- FLBuilder._setLightboxContent( data.html );
1751
-
1752
- // Set the vars.
1753
- select = $( '.fl-template-category-select' );
1754
- tabs = $( '.fl-builder-settings-tab' );
1755
- userTemplatesTab = $( '#fl-builder-settings-tab-yours' );
1756
- userTemplates = $( '.fl-user-template' );
1757
-
1758
- // Default to the user templates tab?
1759
- if ( 'user' == FLBuilderConfig.enabledTemplates || userTemplates.length > 0 || ( userTemplatesTab.length > 0 && tabs.length == 1 ) ) {
1760
- select.val( 'fl-builder-settings-tab-yours' );
1761
- $( '.fl-builder-settings-tab' ).removeClass( 'fl-active' );
1762
- $( '#fl-builder-settings-tab-yours' ).addClass( 'fl-active' );
1763
- }
1764
 
1765
- // Show the no templates message?
1766
- if ( 0 === userTemplates.length ) {
1767
- $( '.fl-user-templates-message' ).show();
1768
  }
1769
-
1770
- $( 'body' ).trigger( 'fl-builder.template-selector-loaded' );
1771
  },
1772
 
1773
  /**
1774
- * Callback to show a template category when the
1775
- * select is changed.
1776
- *
1777
- * @since 1.5.7
1778
- * @access private
1779
- * @method _templateCategoryChanged
1780
- */
1781
- _templateCategoryChanged: function()
1782
- {
1783
- $( '.fl-template-selector .fl-builder-settings-tab' ).hide();
1784
- $( '#' + $( this ).val() ).show();
1785
- },
1786
 
1787
- /**
1788
- * Callback for when a user clicks a core template in
1789
- * the template selector.
1790
- *
1791
- * @since 1.0
1792
- * @access private
1793
- * @method _templateClicked
1794
- */
1795
- _templateClicked: function()
1796
- {
1797
- var template = $(this),
1798
- index = template.closest('.fl-template-preview').attr('data-id');
1799
-
1800
- if($(FLBuilder._contentClass).children('.fl-row').length > 0) {
1801
 
 
1802
  if(index == 0) {
1803
  if(confirm(FLBuilderStrings.changeTemplateMessage)) {
1804
  FLBuilder._lightbox._node.hide();
1805
- FLBuilder._applyTemplate(0, false, 'core');
1806
  }
1807
  }
 
1808
  else {
1809
  FLBuilder._selectedTemplateId = index;
1810
- FLBuilder._selectedTemplateType = 'core';
1811
  FLBuilder._showTemplateActions();
1812
  FLBuilder._lightbox._node.hide();
1813
  }
1814
  }
 
1815
  else {
1816
- FLBuilder._applyTemplate(index, false, 'core');
1817
  }
1818
  },
1819
 
@@ -1885,7 +1718,7 @@
1885
  */
1886
  _templateCancelClicked: function()
1887
  {
1888
- FLBuilder._lightbox._node.show();
1889
  },
1890
 
1891
  /**
@@ -1913,7 +1746,7 @@
1913
  action: 'apply_template',
1914
  template_id: id,
1915
  append: append
1916
- }, FLBuilder._updateLayout);
1917
  }
1918
  else {
1919
 
@@ -1921,26 +1754,46 @@
1921
  action: 'apply_user_template',
1922
  template_id: id,
1923
  append: append
1924
- }, FLBuilder._updateTemplateLayout);
1925
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1926
  },
1927
 
1928
  /**
1929
- * Callback method when applying user template to the current layout
1930
 
1931
  * @since 1.9.5
1932
  * @access private
1933
- * @method _updateTemplateLayout
1934
- * @param {string} response The JSON with the new layout settings
1935
  */
1936
- _updateTemplateLayout: function(response)
1937
  {
1938
- var data = JSON.parse(response);
1939
- if( data !== null ) {
 
1940
  $( '#fl-builder-layout-css' ).html( data.layout_css );
1941
  }
1942
 
1943
- FLBuilder._updateLayout();
 
1944
  },
1945
 
1946
  /* User Template Settings
@@ -1956,33 +1809,15 @@
1956
  */
1957
  _saveUserTemplateClicked: function()
1958
  {
1959
- FLBuilder._actionsLightbox.close();
1960
- FLBuilder._showLightbox(false);
1961
-
1962
- FLBuilder.ajax({
1963
- action: 'render_user_template_settings'
1964
- }, FLBuilder._userTemplateSettingsLoaded);
1965
- },
1966
-
1967
- /**
1968
- * Sets the lightbox content when the user template settings are loaded.
1969
- *
1970
- * @since 1.1.9
1971
- * @access private
1972
- * @method _userTemplateSettingsLoaded
1973
- * @param {String} response The JSON with the HTML for the user template settings form.
1974
- */
1975
- _userTemplateSettingsLoaded: function(response)
1976
- {
1977
- var data = JSON.parse(response);
1978
-
1979
- FLBuilder._setSettingsFormContent(data.html);
1980
-
1981
- FLBuilder._initSettingsValidation({
1982
- name: {
1983
- required: true
1984
  }
1985
- });
1986
  },
1987
 
1988
  /**
@@ -2000,8 +1835,6 @@
2000
 
2001
  if(valid) {
2002
 
2003
- FLBuilder.showAjaxLoader();
2004
-
2005
  FLBuilder.ajax({
2006
  action: 'save_user_template',
2007
  settings: settings
@@ -2018,9 +1851,13 @@
2018
  * @access private
2019
  * @method _saveUserTemplateSettingsComplete
2020
  */
2021
- _saveUserTemplateSettingsComplete: function()
2022
  {
2023
- FLBuilder.alert(FLBuilderStrings.templateSaved);
 
 
 
 
2024
  },
2025
 
2026
  /**
@@ -2085,7 +1922,10 @@
2085
  var template = $( this ).closest( '.fl-user-template' ),
2086
  id = template.attr( 'data-id' ),
2087
  all = $( '.fl-user-template[data-id=' + id + ']' ),
2088
- parent = null;
 
 
 
2089
 
2090
  if ( confirm( FLBuilderStrings.deleteTemplate ) ) {
2091
 
@@ -2094,21 +1934,17 @@
2094
  template_id: id
2095
  } );
2096
 
2097
- all.fadeOut( function() {
2098
-
2099
- template = $( this );
2100
- parent = template.closest( '.fl-user-template-category' );
2101
-
2102
- template.remove();
2103
-
2104
- if ( 0 === parent.find( '.fl-user-template' ).length ) {
2105
- parent.remove();
2106
- }
2107
- if ( 1 === $( '.fl-user-template' ).length ) {
2108
- $( '.fl-user-templates').hide();
2109
- $( '.fl-user-templates-message').show();
2110
  }
2111
- });
 
 
 
 
2112
  }
2113
 
2114
  e.stopPropagation();
@@ -2117,22 +1953,6 @@
2117
  /* Help Actions
2118
  ----------------------------------------------------------*/
2119
 
2120
- /**
2121
- * Shows the getting started video when the watch video button
2122
- * is clicked.
2123
- *
2124
- * @since 1.4.9
2125
- * @access private
2126
- * @method _watchVideoClicked
2127
- */
2128
- _watchVideoClicked: function()
2129
- {
2130
- var template = wp.template( 'fl-video-lightbox' );
2131
-
2132
- FLBuilder._actionsLightbox.close();
2133
- FLBuilder._lightbox.open( template( { video : FLBuilderConfig.help.video_embed } ) );
2134
- },
2135
-
2136
  /**
2137
  * Opens a new window with the knowledge base URL when the
2138
  * view knowledge base button is clicked.
@@ -2143,8 +1963,6 @@
2143
  */
2144
  _viewKnowledgeBaseClicked: function()
2145
  {
2146
- FLBuilder._actionsLightbox.close();
2147
-
2148
  window.open( FLBuilderConfig.help.knowledge_base_url );
2149
  },
2150
 
@@ -2158,8 +1976,6 @@
2158
  */
2159
  _visitForumsClicked: function()
2160
  {
2161
- FLBuilder._actionsLightbox.close();
2162
-
2163
  window.open( FLBuilderConfig.help.forums_url );
2164
  },
2165
 
@@ -2177,6 +1993,7 @@
2177
  _showTourOrTemplates: function()
2178
  {
2179
  if ( ! FLBuilderConfig.simpleUi && ! FLBuilderConfig.isUserTemplate ) {
 
2180
  if ( FLBuilderConfig.help.tour && FLBuilderConfig.newUser ) {
2181
  FLBuilder._showTourLightbox();
2182
  }
@@ -2264,7 +2081,7 @@
2264
  content.removeClass('fl-builder-empty');
2265
  content.find('.fl-builder-empty-message').remove();
2266
 
2267
- if(content.children('.fl-row').length === 0) {
2268
  content.addClass('fl-builder-empty');
2269
  content.append('<span class="fl-builder-empty-message">'+ FLBuilderStrings.emptyMessage +'</span>');
2270
  FLBuilder._initSortables();
@@ -2272,6 +2089,31 @@
2272
  }
2273
  },
2274
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2275
  /**
2276
  * Sends an AJAX request to render the layout and is typically
2277
  * used as a callback to many of the builder's save operations.
@@ -2340,6 +2182,22 @@
2340
  }
2341
  },
2342
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2343
  /**
2344
  * Initializes MediaElements.js audio and video players.
2345
  *
@@ -2490,7 +2348,6 @@
2490
  FLBuilder._highlightRowsAndColsForDrag( target );
2491
  FLBuilder._adjustColHeightsForDrag();
2492
  FLBuilder._disableGlobalRows();
2493
- FLBuilder._closePanel();
2494
  FLBuilder._destroyOverlayEvents();
2495
  FLBuilder._removeAllOverlays();
2496
  FLBuilder._initSortables();
@@ -2502,6 +2359,8 @@
2502
  if ( initialPos > 0 ) {
2503
  scrollTo( 0, node.offset().top - initialPos );
2504
  }
 
 
2505
  },
2506
 
2507
  /**
@@ -2515,11 +2374,14 @@
2515
  */
2516
  _blockDragStart: function(e, ui)
2517
  {
 
2518
  // Let the builder know dragging has started.
2519
  FLBuilder._dragging = true;
2520
 
2521
  // Removed the drag init class as we're done with that.
2522
  $( '.fl-node-drag-init' ).removeClass( 'fl-node-drag-init' );
 
 
2523
  },
2524
 
2525
  /**
@@ -2600,6 +2462,10 @@
2600
  * Callback that fires when an element that is being
2601
  * dragged position changes.
2602
  *
 
 
 
 
2603
  * @since 1.9
2604
  * @access private
2605
  * @method _blockDragChange
@@ -2608,8 +2474,8 @@
2608
  */
2609
  _blockDragChange: function( e, ui )
2610
  {
2611
- ui.placeholder.hide();
2612
- ui.placeholder.fadeIn( 100 );
2613
  },
2614
 
2615
  /**
@@ -2719,6 +2585,8 @@
2719
 
2720
  // Scroll the page back to where it was.
2721
  scrollTo( 0, parent.offset().top - initialPos );
 
 
2722
  },
2723
 
2724
  /**
@@ -2796,6 +2664,7 @@
2796
  FLBuilder._removeColHighlightGuides();
2797
  FLBuilder._removeModuleOverlays();
2798
  FLBuilder._hideTipTips();
 
2799
  },
2800
 
2801
  /**
@@ -2878,15 +2747,15 @@
2878
  // Save a copy of the original actions.
2879
  actions.data( 'original', actions.clone() );
2880
 
2881
- // Get the actions width and items.
2882
- actionsWidth = actions[0].getBoundingClientRect().width;
2883
  items = actions.find( ' > i, > span.fl-builder-has-submenu' );
2884
 
2885
  // Find visible and overflow items.
2886
  for( ; i < items.length; i++ ) {
2887
 
2888
  item = items.eq( i );
2889
- itemsWidth += item.outerWidth();
2890
 
2891
  if ( itemsWidth > actionsWidth ) {
2892
  overflowItems.push( item );
@@ -2942,6 +2811,8 @@
2942
  $('.fl-row').removeClass('fl-block-overlay-active');
2943
  $('.fl-row-overlay').remove();
2944
  $('.fl-module').removeClass('fl-module-adjust-height');
 
 
2945
  },
2946
 
2947
  /**
@@ -3000,7 +2871,7 @@
3000
  // Append the overlay.
3001
  overlay = FLBuilder._appendOverlay( row, template( {
3002
  global : row.hasClass( 'fl-node-global' ),
3003
- node : row.attr('data-node')
3004
  } ) );
3005
 
3006
  // Adjust the overlay position if covered by negative margin content.
@@ -3025,6 +2896,9 @@
3025
  module.addClass( 'fl-module-adjust-height' );
3026
  }
3027
  } );
 
 
 
3028
  }
3029
  },
3030
 
@@ -3264,7 +3138,7 @@
3264
  */
3265
  _addRowComplete: function(response)
3266
  {
3267
- var data = JSON.parse(response),
3268
  content = $(FLBuilder._contentClass),
3269
  rowId = $(data.html).data('node'),
3270
  module = FLBuilder._addModuleAfterNodeRender;
@@ -3284,6 +3158,7 @@
3284
  }
3285
 
3286
  FLBuilder._removeNodeLoadingPlaceholder( $( '.fl-node-' + rowId ) );
 
3287
  } );
3288
  },
3289
 
@@ -3325,15 +3200,18 @@
3325
  */
3326
  _deleteRow: function(row)
3327
  {
 
 
3328
  FLBuilder.ajax({
3329
  action: 'delete_node',
3330
- node_id: row.attr('data-node')
3331
  });
3332
 
3333
  row.empty();
3334
  row.remove();
3335
  FLBuilder._setupEmptyLayout();
3336
  FLBuilder._removeRowOverlays();
 
3337
  },
3338
 
3339
  /**
@@ -3346,23 +3224,41 @@
3346
  */
3347
  _rowCopyClicked: function(e)
3348
  {
3349
- var row = $( this ).closest( '.fl-row' ),
3350
- nodeId = row.attr( 'data-node' ),
3351
- position = $( FLBuilder._contentClass + ' .fl-row' ).index( row ) + 1,
3352
- clone = row.clone();
 
 
 
 
 
 
 
 
 
3353
 
3354
- clone.addClass( 'fl-builder-node-clone' );
3355
- clone.attr( 'data-node', nodeId + '-clone' );
3356
  clone.find( '.fl-block-overlay' ).remove();
3357
  row.after( clone );
3358
 
 
 
 
 
3359
  FLBuilder._showNodeLoading( nodeId + '-clone' );
3360
  FLBuilder._newRowPosition = position;
3361
 
3362
  FLBuilder.ajax( {
3363
  action: 'copy_row',
3364
- node_id: nodeId
3365
- }, FLBuilder._rowCopyComplete );
 
 
 
 
 
 
3366
 
3367
  e.stopPropagation();
3368
  },
@@ -3373,16 +3269,20 @@
3373
  * @since 1.7
3374
  * @access private
3375
  * @method _rowCopyComplete
3376
- * @param {String} response The JSON encoded response.
3377
  */
3378
- _rowCopyComplete: function( response )
3379
  {
3380
- var data = JSON.parse( response );
3381
-
3382
  data.nodeParent = $( FLBuilder._contentClass );
3383
  data.nodePosition = FLBuilder._newRowPosition;
3384
 
3385
  FLBuilder._renderLayout( data, function() {
 
 
 
 
 
 
3386
  data.nodeParent.find( '.fl-builder-node-loading' ).eq( 0 ).remove();
3387
  } );
3388
  },
@@ -3399,46 +3299,94 @@
3399
  {
3400
  var button = $( this ),
3401
  nodeId = button.closest( '.fl-row' ).attr( 'data-node' ),
3402
- global = button.closest( '.fl-block-overlay-global' ).length > 0;
 
3403
 
3404
  if ( global && 'row' != FLBuilderConfig.userTemplateType ) {
3405
  if ( FLBuilderConfig.userCanEditGlobalTemplates ) {
3406
- window.open( $( '.fl-row[data-node="' + nodeId + '"]' ).attr( 'data-template-url' ) );
 
3407
  }
3408
  }
3409
  else if ( button.hasClass( 'fl-block-settings' ) ) {
3410
 
3411
- FLBuilder._closePanel();
3412
- FLBuilder._showLightbox();
3413
-
3414
- FLBuilder.ajax({
3415
- action: 'render_row_settings',
3416
- node_id: nodeId
3417
- }, FLBuilder._rowSettingsLoaded);
 
 
 
 
 
 
 
 
3418
  }
3419
 
3420
  e.stopPropagation();
3421
  },
3422
 
3423
  /**
3424
- * Sets the lightbox content when the row settings have
3425
- * loaded and creates a new preview.
3426
  *
3427
- * @since 1.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3428
  * @access private
3429
- * @method _rowSettingsLoaded
3430
- * @param {String} response The JSON response with the HTML for the row settings form.
3431
  */
3432
- _rowSettingsLoaded: function(response)
3433
  {
3434
- var data = JSON.parse(response);
 
 
 
 
 
 
 
 
 
3435
 
3436
- FLBuilder._setSettingsFormContent(data.settings);
3437
 
3438
- FLBuilder.preview = new FLBuilderPreview({
3439
- type : 'row',
3440
- state : data.state
 
 
 
 
 
3441
  });
 
 
 
 
 
3442
  },
3443
 
3444
  /* Columns
@@ -3470,6 +3418,18 @@
3470
  });
3471
  },
3472
 
 
 
 
 
 
 
 
 
 
 
 
 
3473
  /**
3474
  * Sets up dashed borders to show where things can
3475
  * be dropped in rows and columns.
@@ -3612,6 +3572,9 @@
3612
  parentFirst = hasParentCol ? 0 === parentIndex : false,
3613
  parentLast = hasParentCol ? numParentCols === parentIndex + 1 : false,
3614
  contentWidth = col.find( '> .fl-col-content' ).width(),
 
 
 
3615
  template = wp.template( 'fl-col-overlay' ),
3616
  overlay = null;
3617
 
@@ -3648,7 +3611,9 @@
3648
  parentFirst : parentFirst,
3649
  parentLast : parentLast,
3650
  numParentCols : numParentCols,
3651
- contentWidth : contentWidth
 
 
3652
  } ) );
3653
 
3654
  // Build the overlay overflow menu if needed.
@@ -3686,6 +3651,7 @@
3686
 
3687
  FLBuilder._removeColOverlays();
3688
  FLBuilder._removeColHighlightGuides();
 
3689
  },
3690
 
3691
  /**
@@ -3702,6 +3668,7 @@
3702
  cols.removeClass('fl-block-overlay-active');
3703
  cols.find('.fl-col-overlay').remove();
3704
  $('body').removeClass('fl-block-overlay-muted');
 
3705
  },
3706
 
3707
  /**
@@ -3895,6 +3862,7 @@
3895
  FLBuilder._highlightEmptyCols();
3896
  FLBuilder._initDropTargets();
3897
  FLBuilder._initSortables();
 
3898
  },
3899
 
3900
  /**
@@ -3908,9 +3876,11 @@
3908
  */
3909
  _colSettingsClicked: function(e)
3910
  {
3911
- var button = $( this ),
3912
- col = button.closest('.fl-col'),
3913
- nodeId = null;
 
 
3914
 
3915
  if ( FLBuilder._colResizing ) {
3916
  return;
@@ -3923,51 +3893,96 @@
3923
  nodeId = col.attr('data-node');
3924
  }
3925
 
3926
- FLBuilder._closePanel();
3927
- FLBuilder._showLightbox();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3928
 
3929
- FLBuilder.ajax({
3930
- action: 'render_column_settings',
3931
- node_id: nodeId
3932
- }, FLBuilder._colSettingsLoaded);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3933
 
3934
  e.stopPropagation();
3935
  },
3936
 
3937
  /**
3938
- * Sets the lightbox content when the column settings have
3939
- * loaded and creates a new preview.
3940
  *
3941
- * @since 1.1.9
3942
  * @access private
3943
- * @method _colSettingsLoaded
3944
- * @param {String} response The JSON response with the HTML for the column settings form.
3945
  */
3946
- _colSettingsLoaded: function( response )
3947
  {
3948
- var data = JSON.parse( response ),
3949
- settings = null,
3950
- nodeId = null,
3951
- col = null,
3952
- content = null;
3953
-
3954
- FLBuilder._setSettingsFormContent( data.settings );
3955
 
3956
- settings = $( '.fl-builder-col-settings' );
3957
- nodeId = settings.data( 'node' );
3958
- col = $( '.fl-col[data-node="' + nodeId + '"]' );
3959
- content = col.find( '> .fl-col-content' );
3960
 
3961
- if ( col.siblings( '.fl-col' ).length === 0 ) {
3962
- $( settings ).find( '#fl-builder-settings-section-general' ).css( 'display', 'none' );
3963
- }
3964
- else if( content.width() <= 40 ) {
3965
- $( '#fl-field-size' ).hide();
3966
- }
3967
 
3968
- FLBuilder.preview = new FLBuilderPreview( {
3969
- type : 'col',
3970
- state : data.state
3971
  } );
3972
  },
3973
 
@@ -4024,10 +4039,11 @@
4024
  */
4025
  _deleteCol: function(col)
4026
  {
4027
- var row = col.closest('.fl-row'),
4028
- group = col.closest('.fl-col-group'),
4029
- cols = null,
4030
- width = 0;
 
4031
 
4032
  col.remove();
4033
  rowCols = row.find('.fl-row-content > .fl-col-group > .fl-col');
@@ -4054,16 +4070,21 @@
4054
  }
4055
 
4056
  groupCols.css('width', width + '%');
 
 
 
 
4057
  }
4058
 
4059
  FLBuilder.ajax({
4060
  action : 'delete_col',
4061
- node_id : col.attr('data-node'),
4062
  new_width : width
4063
  });
4064
 
4065
  FLBuilder._initDropTargets();
4066
  FLBuilder._initSortables();
 
4067
  }
4068
  },
4069
 
@@ -4125,9 +4146,9 @@
4125
  // Add a module to a newly created column.
4126
  if ( moduleData !== null ) {
4127
 
4128
- $( '[data-node="' + moduleData.module.data( 'node' ) + '"]' ).remove()
4129
 
4130
- col = $( '[data-node="' + moduleData.colId + '"]' );
4131
 
4132
  if ( 'after' == moduleData.position ) {
4133
  col.next().find( '.fl-col-content' ).append( moduleData.module );
@@ -4139,6 +4160,12 @@
4139
  FLBuilder._reorderModule( moduleData.module );
4140
  FLBuilder._addModuleAfterNodeRender = null;
4141
  }
 
 
 
 
 
 
4142
  } );
4143
  },
4144
 
@@ -4215,7 +4242,9 @@
4215
  FLBuilder._addModuleAfterNodeRender = null;
4216
  }
4217
 
 
4218
  FLBuilder._removeNodeLoadingPlaceholder( $( '.fl-node-' + groupId ) );
 
4219
  } );
4220
  },
4221
 
@@ -4228,7 +4257,7 @@
4228
  */
4229
  _initColDragResizing: function()
4230
  {
4231
- $( '.fl-block-col-resize' ).draggable( {
4232
  axis : 'x',
4233
  start : FLBuilder._colDragResizeStart,
4234
  drag : FLBuilder._colDragResize,
@@ -4248,27 +4277,36 @@
4248
  _colDragResizeStart: function( e, ui )
4249
  {
4250
  // Setup resize vars.
4251
- var handle = $( ui.helper ),
4252
- direction = '',
4253
- resizeParent = handle.hasClass( 'fl-block-col-resize-parent' ),
4254
- parentCol = resizeParent ? handle.closest( '.fl-col' ).parents( '.fl-col' ) : null,
4255
- group = resizeParent ? parentCol.parents( '.fl-col-group' ) : handle.closest( '.fl-col-group' ),
4256
- cols = group.find( '> .fl-col' ),
4257
- col = resizeParent ? parentCol : handle.closest( '.fl-col' ),
4258
- sibling = null,
4259
- availWidth = 100,
4260
- i = 0;
 
 
 
 
 
 
4261
 
4262
  // Find the direction and sibling.
4263
  if ( handle.hasClass( 'fl-block-col-resize-e' ) ) {
4264
  direction = 'e';
4265
- sibling = col.nextAll( '.fl-col' ).first();
4266
  }
4267
  else {
4268
  direction = 'w';
4269
- sibling = col.prevAll( '.fl-col' ).first();
4270
  }
4271
 
 
 
 
4272
  // Find the available width.
4273
  for ( ; i < cols.length; i++ ) {
4274
 
@@ -4282,6 +4320,15 @@
4282
  availWidth -= parseFloat( cols.eq( i )[ 0 ].style.width );
4283
  }
4284
 
 
 
 
 
 
 
 
 
 
4285
  // Build the resize data object.
4286
  FLBuilder._colResizeData = {
4287
  handle : handle,
@@ -4293,7 +4340,9 @@
4293
  colWidth : parseFloat( col[ 0 ].style.width ) / 100,
4294
  sibling : sibling,
4295
  offset : ui.position.left,
4296
- availWidth : availWidth
 
 
4297
  };
4298
 
4299
  // Set the resizing flag.
@@ -4323,6 +4372,7 @@
4323
  {
4324
  // Setup resize vars.
4325
  var data = FLBuilder._colResizeData,
 
4326
  change = ( data.offset - ui.position.left ) / data.groupWidth,
4327
  colWidth = 'e' == data.direction ? ( data.colWidth - change ) * 100 : ( data.colWidth + change ) * 100,
4328
  colRound = Math.round( colWidth * 100 ) / 100,
@@ -4355,6 +4405,18 @@
4355
  data.col.css( 'width', colRound + '%' );
4356
  data.sibling.css( 'width', siblingRound + '%' );
4357
 
 
 
 
 
 
 
 
 
 
 
 
 
4358
  // Trigger the col-resize-drag hook.
4359
  FLBuilder.triggerHook( 'col-resize-drag' );
4360
  },
@@ -4370,8 +4432,12 @@
4370
  */
4371
  _colDragResizeStop: function( e, ui )
4372
  {
4373
- var data = FLBuilder._colResizeData,
4374
- overlay = FLBuilder._colResizeData.handle.closest( '.fl-block-overlay' );
 
 
 
 
4375
 
4376
  // Hide the feedback divs.
4377
  FLBuilder._colResizeData.feedbackLeft.hide();
@@ -4380,10 +4446,10 @@
4380
  // Save the resize data.
4381
  FLBuilder.ajax({
4382
  action : 'resize_cols',
4383
- col_id : data.col.data( 'node' ),
4384
- col_width : parseFloat( data.col[ 0 ].style.width ),
4385
- sibling_id : data.sibling.data( 'node' ),
4386
- sibling_width : parseFloat( data.sibling[ 0 ].style.width )
4387
  });
4388
 
4389
  // Build the overlay overflow menu if needed.
@@ -4403,6 +4469,13 @@
4403
 
4404
  // Trigger the col-resize-stop hook.
4405
  FLBuilder.triggerHook( 'col-resize-stop' );
 
 
 
 
 
 
 
4406
  },
4407
 
4408
  /**
@@ -4416,16 +4489,38 @@
4416
  */
4417
  _resetColumnWidthsClicked: function( e )
4418
  {
4419
- var group = $( this ).parents( '.fl-col-group' ).last(),
4420
- groupIds = [ group.data( 'node' ) ],
4421
- children = group.find( '.fl-col-group' ),
4422
- i = 0;
 
 
 
 
 
 
 
 
 
 
 
4423
 
4424
- FLBuilder._resetColumnWidths( group );
4425
 
4426
- for ( ; i < children.length; i++ ) {
4427
- FLBuilder._resetColumnWidths( children.eq( i ) );
4428
- groupIds.push( children.eq( i ).data( 'node' ) );
 
 
 
 
 
 
 
 
 
 
 
4429
  }
4430
 
4431
  FLBuilder.ajax({
@@ -4463,6 +4558,10 @@
4463
  }
4464
 
4465
  cols.css( 'width', width + '%' );
 
 
 
 
4466
  },
4467
 
4468
  /* Modules
@@ -4493,6 +4592,9 @@
4493
  parentFirst = hasParentCol ? 0 === parentCol.index() : false,
4494
  parentLast = hasParentCol ? numParentCols === parentCol.index() + 1 : false,
4495
  contentWidth = col.find( '> .fl-col-content' ).width(),
 
 
 
4496
  template = wp.template( 'fl-module-overlay' ),
4497
  overlay = null;
4498
 
@@ -4520,7 +4622,9 @@
4520
  numParentCols : numParentCols,
4521
  parentFirst : parentFirst,
4522
  parentLast : parentLast,
4523
- contentWidth : contentWidth
 
 
4524
  } ) );
4525
 
4526
  // Build the overlay overflow menu if necessary.
@@ -4570,6 +4674,7 @@
4570
  modules.removeClass('fl-block-overlay-active');
4571
  modules.find('.fl-module-overlay').remove();
4572
  $('body').removeClass('fl-block-overlay-muted');
 
4573
  },
4574
 
4575
  /**
@@ -4770,11 +4875,12 @@
4770
  */
4771
  _deleteModule: function(module)
4772
  {
4773
- var row = module.closest('.fl-row');
 
4774
 
4775
  FLBuilder.ajax({
4776
  action: 'delete_node',
4777
- node_id: module.attr('data-node')
4778
  });
4779
 
4780
  module.empty();
@@ -4782,6 +4888,7 @@
4782
  row.removeClass('fl-block-overlay-muted');
4783
  FLBuilder._highlightEmptyCols();
4784
  FLBuilder._removeAllOverlays();
 
4785
  },
4786
 
4787
  /**
@@ -4797,21 +4904,36 @@
4797
  var module = $( this ).closest( '.fl-module' )
4798
  nodeId = module.attr( 'data-node' ),
4799
  position = module.index() + 1,
4800
- clone = module.clone();
 
 
4801
 
4802
- clone.addClass( 'fl-builder-node-clone' );
4803
- clone.attr( 'data-node', nodeId + '-clone' );
 
 
 
 
4804
  clone.find( '.fl-block-overlay' ).remove();
4805
  module.after( clone );
4806
 
 
 
 
 
4807
  FLBuilder._showNodeLoading( nodeId + '-clone' );
4808
  FLBuilder._newModuleParent = module.parent();
4809
  FLBuilder._newModulePosition = position;
4810
 
4811
  FLBuilder.ajax({
4812
  action: 'copy_module',
4813
- node_id: nodeId
4814
- }, FLBuilder._moduleCopyComplete);
 
 
 
 
 
4815
 
4816
  e.stopPropagation();
4817
  },
@@ -4822,16 +4944,20 @@
4822
  * @since 1.7
4823
  * @access private
4824
  * @method _moduleCopyComplete
4825
- * @param {String} response The JSON encoded response.
4826
  */
4827
- _moduleCopyComplete: function( response )
4828
  {
4829
- var data = JSON.parse( response );
4830
-
4831
  data.nodeParent = FLBuilder._newModuleParent;
4832
  data.nodePosition = FLBuilder._newModulePosition;
4833
 
4834
  FLBuilder._renderLayout( data, function(){
 
 
 
 
 
 
4835
  data.nodeParent.find( '.fl-builder-node-loading' ).eq( 0 ).remove();
4836
  } );
4837
  },
@@ -4848,9 +4974,9 @@
4848
  _moduleSettingsClicked: function(e)
4849
  {
4850
  var button = $( this ),
 
4851
  nodeId = button.closest( '.fl-module' ).attr( 'data-node' ),
4852
  parentId = button.closest( '.fl-col' ).attr( 'data-node' ),
4853
- type = button.closest( '.fl-module' ).attr( 'data-type' ),
4854
  global = button.closest( '.fl-block-overlay-global' ).length > 0;
4855
 
4856
  e.stopPropagation();
@@ -4862,7 +4988,12 @@
4862
  return;
4863
  }
4864
 
4865
- FLBuilder._showModuleSettings(nodeId, parentId, type);
 
 
 
 
 
4866
  },
4867
 
4868
  /**
@@ -4871,84 +5002,48 @@
4871
  * @since 1.0
4872
  * @access private
4873
  * @method _showModuleSettings
4874
- * @param {String} nodeId The node ID for the module.
4875
- * @param {String} parentId The node ID for the module's parent.
4876
- * @param {String} type The type of module.
4877
- */
4878
- _showModuleSettings: function(nodeId, parentId, type)
4879
- {
4880
- FLBuilder._closePanel();
4881
- FLBuilder._showLightbox();
4882
-
4883
- FLBuilder.ajax({
4884
- action: 'render_module_settings',
4885
- node_id: nodeId,
4886
- type: type,
4887
- parent_id: parentId
4888
- }, FLBuilder._moduleSettingsLoaded);
4889
- },
4890
-
4891
- /**
4892
- * Sets the lightbox content when the module settings have
4893
- * loaded and creates a new preview.
4894
- *
4895
- * @since 1.0
4896
- * @access private
4897
- * @method _moduleSettingsLoaded
4898
- * @param {Object} response The JSON encoded module settings data.
4899
  */
4900
- _moduleSettingsLoaded: function(response)
4901
  {
4902
- var data = JSON.parse(response),
4903
- html = $('<div>'+ data.settings +'</div>'),
4904
- link = html.find('link.fl-builder-settings-css'),
4905
- script = html.find('script.fl-builder-settings-js'),
4906
- form = html.find('.fl-builder-settings'),
4907
- type = form.attr('data-type'),
4908
- layout = null,
4909
- state = null,
4910
- helper = null;
4911
-
4912
- // Append the settings css and js?
4913
- if($.inArray(type, FLBuilder._loadedModuleAssets) > -1) {
4914
- link.remove();
4915
- script.remove();
4916
- }
4917
- else {
4918
- $('head').append(link);
4919
- $('head').append(script);
4920
- FLBuilder._loadedModuleAssets.push(type);
4921
- }
4922
-
4923
- // Set the content.
4924
- FLBuilder._setSettingsFormContent(html);
4925
-
4926
- // Get layout data for a new module preview.
4927
- if ( 'undefined' != typeof data.layout ) {
4928
- layout = data.layout;
4929
- layout.nodeParent = FLBuilder._newModuleParent;
4930
- layout.nodePosition = FLBuilder._newModulePosition;
4931
- }
4932
-
4933
- // Get state data for the module preview.
4934
- if ( 'undefined' != typeof data.state ) {
4935
- state = data.state;
4936
- }
4937
-
4938
- // Create a new preview.
4939
- FLBuilder.preview = new FLBuilderPreview({
4940
- type : 'module',
4941
- layout : layout,
4942
- state : state
4943
- });
4944
-
4945
- // Init the settings form helper.
4946
- helper = FLBuilder._moduleHelpers[type];
4947
 
4948
- if(typeof helper !== 'undefined') {
4949
- FLBuilder._initSettingsValidation(helper.rules);
4950
- helper.init();
4951
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4952
  },
4953
 
4954
  /**
@@ -4979,7 +5074,6 @@
4979
  }
4980
  if(valid) {
4981
  FLBuilder._saveSettings();
4982
- FLBuilder._lightbox.close();
4983
  }
4984
  else {
4985
  FLBuilder._toggleSettingsTabErrors();
@@ -4999,7 +5093,7 @@
4999
  * @param {String} widget The type of widget if this module is a widget.
5000
  * @param {String} alias A module alias key if this module is an alias to another module.
5001
  */
5002
- _addModule: function(parent, parentId, type, position, widget, alias)
5003
  {
5004
  // Show the loader.
5005
  FLBuilder._showNodeLoadingPlaceholder( parent, position );
@@ -5015,7 +5109,7 @@
5015
  }
5016
 
5017
  // Send the request.
5018
- FLBuilder.ajax({
5019
  action : 'render_new_module',
5020
  parent_id : parentId,
5021
  type : type,
@@ -5023,7 +5117,7 @@
5023
  node_preview : 1,
5024
  widget : typeof widget === 'undefined' ? '' : widget,
5025
  alias : typeof alias === 'undefined' ? '' : alias
5026
- }, FLBuilder._addModuleComplete);
5027
  },
5028
 
5029
  /**
@@ -5035,12 +5129,26 @@
5035
  * @method _addModuleComplete
5036
  * @param {String} response The JSON encoded response.
5037
  */
5038
- _addModuleComplete: function(response)
5039
  {
5040
- FLBuilder._showLightbox();
5041
- FLBuilder._moduleSettingsLoaded(response);
 
 
 
 
 
5042
 
5043
- $('.fl-builder-module-settings').data('new-module', '1');
 
 
 
 
 
 
 
 
 
5044
  },
5045
 
5046
  /**
@@ -5091,41 +5199,34 @@
5091
  */
5092
  _showNodeTemplateSettings: function( e )
5093
  {
5094
- var form = $( '.fl-builder-settings-lightbox .fl-builder-settings' );
5095
-
5096
- FLBuilder._saveSettings();
5097
- FLBuilder._showLightbox();
5098
-
5099
- FLBuilder.ajax( {
5100
- action : 'render_node_template_settings',
5101
- node_id : form.attr( 'data-node' )
5102
- }, FLBuilder._nodeTemplateSettingsLoaded );
5103
- },
5104
 
5105
- /**
5106
- * Sets the lightbox content when the node template settings have loaded.
5107
- *
5108
- * @since 1.6.3
5109
- * @access private
5110
- * @method _nodeTemplateSettingsLoaded
5111
- * @param {String} response The JSON with the HTML for the settings form.
5112
- */
5113
- _nodeTemplateSettingsLoaded: function( response )
5114
- {
5115
- var data = JSON.parse( response );
5116
 
5117
- FLBuilder._showLightbox( false );
5118
- FLBuilder._setSettingsFormContent( data.html );
 
5119
 
5120
- FLBuilder._initSettingsValidation({
5121
- name: {
5122
- required: true
 
 
 
 
 
 
 
5123
  }
5124
- });
5125
-
5126
- if ( ! FLBuilderConfig.userCanEditGlobalTemplates ) {
5127
- $( '#fl-field-global' ).hide();
5128
- }
5129
  },
5130
 
5131
  /**
@@ -5137,18 +5238,22 @@
5137
  */
5138
  _saveNodeTemplate: function()
5139
  {
5140
- var form = $( '.fl-builder-settings-lightbox .fl-builder-settings' ),
5141
- valid = form.validate().form();
 
5142
 
5143
  if ( valid ) {
5144
 
5145
- FLBuilder.showAjaxLoader();
5146
 
5147
  FLBuilder.ajax({
5148
  action : 'save_node_template',
5149
- node_id : form.attr( 'data-node' ),
5150
  settings : FLBuilder._getSettings( form )
5151
- }, FLBuilder._saveNodeTemplateComplete);
 
 
 
5152
 
5153
  FLBuilder._lightbox.close();
5154
  }
@@ -5163,26 +5268,35 @@
5163
  */
5164
  _saveNodeTemplateComplete: function( response )
5165
  {
5166
- var data = JSON.parse( response ),
5167
- panel = $( '.fl-builder-saved-' + data.type + 's' ),
5168
- blocks = panel.find( '.fl-builder-block' ),
5169
- block = null,
5170
- text = '',
5171
- name = data.name.toLowerCase(),
5172
- i = 0,
5173
- template = wp.template( 'fl-node-template-block' );
 
 
 
 
 
 
 
 
 
 
 
 
 
5174
 
5175
- // Show the success alert.
5176
- if ( 'row' == data.type ) {
5177
- FLBuilder.alert( FLBuilderStrings.rowTemplateSaved );
5178
- }
5179
- else if ( 'module' == data.type ) {
5180
- FLBuilder.alert( FLBuilderStrings.moduleTemplateSaved );
5181
- }
5182
 
5183
  // Update the layout for global templates.
5184
  if ( data.layout ) {
5185
  FLBuilder._renderLayout( data.layout );
 
5186
  }
5187
 
5188
  // Add the new template to the builder panel.
@@ -5237,8 +5351,13 @@
5237
  action = '',
5238
  callback = null;
5239
 
 
 
 
 
 
5240
  // A saved row was dropped.
5241
- if ( item.hasClass( 'fl-builder-block-saved-row' ) || item.hasClass( 'fl-builder-block-row-template' ) ) {
5242
  node = item.closest( '.fl-row' );
5243
  position = ! node.length ? 0 : $( FLBuilder._contentClass + ' .fl-row' ).index( node );
5244
  position = parent.hasClass( 'fl-drop-target-last' ) ? position + 1 : position;
@@ -5310,7 +5429,15 @@
5310
  template_type : item.attr( 'data-type' ),
5311
  parent_id : parentId,
5312
  position : position
5313
- }, callback );
 
 
 
 
 
 
 
 
5314
 
5315
  // Remove the helper.
5316
  item.remove();
@@ -5350,7 +5477,8 @@
5350
  block = button.closest( '.fl-builder-block' ),
5351
  global = block.hasClass( 'fl-builder-block-global' ),
5352
  callback = global ? FLBuilder._updateLayout : undefined,
5353
- message = global ? FLBuilderStrings.deleteGlobalTemplate : FLBuilderStrings.deleteTemplate;
 
5354
 
5355
  if ( confirm( message ) ) {
5356
 
@@ -5377,6 +5505,15 @@
5377
  action : 'delete_node_template',
5378
  template_id : block.attr( 'data-id' )
5379
  }, callback);
 
 
 
 
 
 
 
 
 
5380
  }
5381
  },
5382
 
@@ -5392,13 +5529,20 @@
5392
  */
5393
  _initSettingsForms: function()
5394
  {
 
5395
  FLBuilder._initColorPickers();
5396
  FLBuilder._initSelectFields();
 
5397
  FLBuilder._initMultipleFields();
5398
  FLBuilder._initAutoSuggestFields();
5399
  FLBuilder._initLinkFields();
5400
  FLBuilder._initFontFields();
5401
  FLBuilder._initOrderingFields();
 
 
 
 
 
5402
 
5403
  /**
5404
  * Hook for settings form init.
@@ -5407,17 +5551,32 @@
5407
  },
5408
 
5409
  /**
5410
- * Sets the content for the settings lightbox.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5411
  *
5412
  * @since 1.0
5413
  * @access private
5414
  * @method _setSettingsFormContent
5415
- * @param {String} html The HTML content for the lightbox.
5416
  */
5417
- _setSettingsFormContent: function(html)
5418
  {
5419
- FLBuilder._setLightboxContent(html);
5420
- FLBuilder._initSettingsForms();
5421
  },
5422
 
5423
  /**
@@ -5430,17 +5589,201 @@
5430
  */
5431
  _settingsTabClicked: function(e)
5432
  {
5433
- var tab = $(this),
5434
- form = tab.closest('.fl-builder-settings'),
5435
- id = tab.attr('href').split('#').pop();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5436
 
5437
- form.find('.fl-builder-settings-tab').removeClass('fl-active');
5438
- form.find('#' + id).addClass('fl-active');
5439
- form.find('.fl-builder-settings-tabs .fl-active').removeClass('fl-active');
5440
- $(this).addClass('fl-active');
 
5441
  e.preventDefault();
5442
  },
5443
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5444
  /**
5445
  * Reverts an active preview and hides the lightbox when
5446
  * the cancel button of a settings lightbox is clicked.
@@ -5488,6 +5831,35 @@
5488
  FLLightbox.closeParent(this);
5489
  },
5490
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5491
  /**
5492
  * Initializes validation logic for a settings form.
5493
  *
@@ -5552,6 +5924,8 @@
5552
  tabLink.addClass('error');
5553
  }
5554
  }
 
 
5555
  },
5556
 
5557
  /**
@@ -5564,7 +5938,7 @@
5564
  * @param {Object} form The settings form element.
5565
  * @return {Object} The settings object.
5566
  */
5567
- _getSettings: function(form)
5568
  {
5569
  FLBuilder._updateEditorFields();
5570
 
@@ -5671,14 +6045,61 @@
5671
  }
5672
  ).join( ',' );
5673
 
5674
- try {
5675
- delete settings[ 'as_values_' + key ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  */
177
  _multiplePhotoSelector : null,
178
 
179
+ /**
180
+ * A jQuery reference to a group that a new column
181
+ * should be added to once it's finished rendering.
182
+ *
183
+ * @since 2.0
184
+ * @access private
185
+ * @property {Object} _newColParent
186
+ */
187
+ _newColParent : null,
188
+
189
+ /**
190
+ * The position a column should be added to within
191
+ * a group once it finishes rendering.
192
+ *
193
+ * @since 2.0
194
+ * @access private
195
+ * @property {Number} _newColPosition
196
+ */
197
+ _newColPosition : 0,
198
+
199
  /**
200
  * A jQuery reference to a row that a new column group
201
  * should be added to once it's finished rendering.
312
  FLBuilder._initSortables();
313
  FLBuilder._initStrings();
314
  FLBuilder._initTipTips();
315
+ FLBuilder._initTinyMCE();
316
  FLBuilder._bindEvents();
317
  FLBuilder._bindOverlayEvents();
318
  FLBuilder._setupEmptyLayout();
319
  FLBuilder._highlightEmptyCols();
320
+
321
+ FLBuilder.addHook('didInitUI', FLBuilder._showTourOrTemplates.bind(FLBuilder) );
322
+
323
+ FLBuilder.triggerHook('init');
324
  },
325
 
326
  /**
343
  return jQuery.fn.oldReady( function() {
344
  try {
345
  if ( 'function' == typeof fn ) {
346
+ fn( $ );
347
  }
348
  }
349
  catch ( e ){
461
  });
462
  },
463
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
464
  /**
465
  * Initializes jQuery sortables for drag and drop.
466
  *
474
  appendTo: 'body',
475
  cursor: 'move',
476
  cursorAt: {
477
+ left: 85,
478
  top: 20
479
  },
480
  distance: 1,
613
  */
614
  _bindEvents: function()
615
  {
616
+
617
  /* Links */
618
+ $excludedLinks = $('.fl-builder-bar a, .fl-builder--content-library-panel a, .fl-page-nav .nav a'); // links in ui shouldn't be disabled.
619
+ $('a').not($excludedLinks).on('click', FLBuilder._preventDefault);
620
  $('.fl-page-nav .nav a').on('click', FLBuilder._headerLinkClicked);
621
 
622
+ $('body').delegate('button.fl-builder-button', 'mouseup', this._buttonMouseUp.bind(this) );
623
+
624
  /* Heartbeat */
625
  $(document).on('heartbeat-tick', FLBuilder._initPostLock);
626
 
634
  $('body').delegate('.fl-builder-submenu', 'mouseleave', FLBuilder._submenuMouseleave);
635
  $('body').delegate('.fl-builder-submenu .fl-builder-has-submenu', 'mouseenter', FLBuilder._submenuNestedParentMouseenter);
636
 
 
 
 
 
 
 
 
 
 
637
  /* Panel */
638
  $('.fl-builder-panel-actions .fl-builder-panel-close').on('click', FLBuilder._closePanel);
639
  $('.fl-builder-blocks-section-title').on('click', FLBuilder._blockSectionTitleClicked);
643
  $('body').delegate('.fl-builder-node-template-edit', 'click', FLBuilder._editNodeTemplateClicked);
644
  $('body').delegate('.fl-builder-node-template-delete', 'click', FLBuilder._deleteNodeTemplateClicked);
645
 
646
+ $('body').delegate('.fl-builder-block', 'mousedown', FLBuilder._blockDragInit );
 
647
  $('body').on('mouseup', FLBuilder._blockDragCancel);
648
 
649
  /* Actions Lightbox */
650
  $('body').delegate('.fl-builder-actions .fl-builder-cancel-button', 'click', FLBuilder._cancelButtonClicked);
651
 
 
 
 
 
 
 
 
 
652
  /* Tools Actions */
653
  $('body').delegate('.fl-builder-save-user-template-button', 'click', FLBuilder._saveUserTemplateClicked);
654
  $('body').delegate('.fl-builder-duplicate-layout-button', 'click', FLBuilder._duplicateLayoutClicked);
659
  $('body').delegate('.fl-builder-global-settings .fl-builder-settings-save', 'click', FLBuilder._saveGlobalSettingsClicked);
660
  $('body').delegate('.fl-builder-global-settings .fl-builder-settings-cancel', 'click', FLBuilder._cancelLayoutSettingsClicked);
661
 
662
+ /* Template Panel Tab */
 
 
663
  $('body').delegate('.fl-user-template', 'click', FLBuilder._userTemplateClicked);
664
  $('body').delegate('.fl-user-template-edit', 'click', FLBuilder._editUserTemplateClicked);
665
  $('body').delegate('.fl-user-template-delete', 'click', FLBuilder._deleteUserTemplateClicked);
672
 
673
  /* Help Actions */
674
  $('body').delegate('.fl-builder-help-tour-button', 'click', FLBuilder._startHelpTour);
 
675
  $('body').delegate('.fl-builder-knowledge-base-button', 'click', FLBuilder._viewKnowledgeBaseClicked);
676
  $('body').delegate('.fl-builder-forums-button', 'click', FLBuilder._visitForumsClicked);
677
 
690
  $('body').delegate('.fl-row-overlay', 'click', FLBuilder._rowSettingsClicked);
691
  $('body').delegate('.fl-builder-row-settings .fl-builder-settings-save', 'click', FLBuilder._saveSettings);
692
 
693
+ /* Rows Submenu */
694
+ $('body').delegate('.fl-block-col-submenu .fl-block-row-reset', 'click', FLBuilder._resetRowWidthClicked);
695
+
696
  /* Columns */
697
  $('body').delegate('.fl-col-overlay .fl-block-move', 'mousedown', FLBuilder._colDragInit);
698
+ $('body').delegate('.fl-block-col-copy', 'click', FLBuilder._copyColClicked);
699
  $('body').delegate('.fl-col-overlay .fl-block-remove', 'click', FLBuilder._deleteColClicked);
700
  $('body').delegate('.fl-col-overlay', 'click', FLBuilder._colSettingsClicked);
701
  $('body').delegate('.fl-builder-col-settings .fl-builder-settings-save', 'click', FLBuilder._saveSettings);
726
 
727
  /* Settings */
728
  $('body').delegate('.fl-builder-settings-tabs a', 'click', FLBuilder._settingsTabClicked);
729
+ $('body').delegate('.fl-builder-settings-tabs a', 'show', FLBuilder._calculateSettingsTabsOverflow);
730
+ $('body').delegate('.fl-builder-settings-tabs a', 'hide', FLBuilder._calculateSettingsTabsOverflow);
731
  $('body').delegate('.fl-builder-settings-cancel', 'click', FLBuilder._settingsCancelClicked);
732
 
733
+ /* Settings Tabs Overflow menu */
734
+ $('body').delegate('.fl-builder-settings-tabs-overflow-menu > a', 'click', FLBuilder._settingsTabsToOverflowMenuItemClicked.bind(this));
735
+ $('body').delegate('.fl-builder-settings-tabs-more', 'click', FLBuilder._toggleTabsOverflowMenu.bind(this) );
736
+ $('body').delegate('.fl-builder-settings-tabs-overflow-click-mask', 'click', FLBuilder._hideTabsOverflowMenu.bind(this));
737
+
738
  /* Tooltips */
739
  $('body').delegate('.fl-help-tooltip-icon', 'mouseover', FLBuilder._showHelpTooltip);
740
  $('body').delegate('.fl-help-tooltip-icon', 'mouseout', FLBuilder._hideHelpTooltip);
787
  $('body').delegate('.fl-loop-data-source-select select[name=data_source]', 'change', FLBuilder._loopDataSourceChange);
788
  $('body').delegate('.fl-custom-query select[name=post_type]', 'change', FLBuilder._customQueryPostTypeChange);
789
 
790
+ /* Number Fields */
791
+ $('body').delegate('.fl-field input[type=number]', 'focus', FLBuilder._onNumberFieldFocus );
792
+ $('body').delegate('.fl-field input[type=number]', 'blur', FLBuilder._onNumberFieldBlur );
793
+
794
+ // Live Preview
795
+ FLBuilder.addHook( 'didCompleteAJAX', FLBuilder._refreshSettingsPreviewReference );
796
+ FLBuilder.addHook( 'didRenderLayoutComplete', FLBuilder._refreshSettingsPreviewReference );
797
+ },
798
+
799
+ /**
800
+ * Remove events when ending the edit session
801
+ * @since 2.0
802
+ * @access private
803
+ */
804
+ _unbindEvents: function() {
805
+ $('a').off('click', FLBuilder._preventDefault);
806
+ $('.fl-page-nav .nav a').off('click', FLBuilder._headerLinkClicked);
807
  },
808
 
809
  /**
886
  _headerLinkClicked: function(e)
887
  {
888
  var link = $(this),
889
+
890
  href = link.attr('href');
891
 
892
  // ignore links with a #hash
901
  }
902
 
903
  FLBuilder._exitUrl = href.indexOf('?') > -1 ? href : href + '?fl_builder';
904
+ FLBuilder.triggerHook('triggerDone');
905
  },
906
 
907
  /**
944
  }
945
  } ).tipTip( {
946
  defaultPosition : 'top',
947
+ delay : 1000
948
  } );
949
  },
950
 
957
  */
958
  _hideTipTips: function()
959
  {
960
+ $('#tiptip_holder').stop().hide();
961
  },
962
 
963
  /* Submenus
973
  */
974
  _submenuParentClicked: function( e )
975
  {
976
+ var body = $( 'body' ),
977
+ parent = $( this ),
978
  submenu = parent.find( '.fl-builder-submenu' );
979
 
980
  if ( parent.hasClass( 'fl-builder-submenu-open' ) ) {
981
+ body.removeClass( 'fl-builder-submenu-open' );
982
  parent.removeClass( 'fl-builder-submenu-open' );
983
  parent.removeClass( 'fl-builder-submenu-right' );
984
  }
988
  parent.addClass( 'fl-builder-submenu-right' );
989
  }
990
 
991
+ body.addClass( 'fl-builder-submenu-open' );
992
  parent.addClass( 'fl-builder-submenu-open' );
993
  }
994
 
1007
  */
1008
  _submenuChildClicked: function( e )
1009
  {
1010
+ var body = $( 'body' ),
1011
+ parent = $( this ).parents( '.fl-builder-has-submenu' );
1012
 
1013
  if ( ! parent.parents( '.fl-builder-has-submenu' ).length ) {
1014
+ body.removeClass( 'fl-builder-submenu-open' );
1015
  parent.removeClass( 'fl-builder-submenu-open' );
1016
  }
1017
  },
1044
  */
1045
  _submenuMouseleave: function( e )
1046
  {
1047
+ var body = $( 'body' ),
1048
+ menu = $( this ),
1049
  timeout = setTimeout( function() {
1050
+ body.removeClass( 'fl-builder-submenu-open' );
1051
  menu.closest( '.fl-builder-has-submenu' ).removeClass( 'fl-builder-submenu-open' );
1052
  }, 500 );
1053
 
1088
  /* Bar
1089
  ----------------------------------------------------------*/
1090
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1091
  /**
1092
  * Opens a new window with the upgrade URL when the
1093
  * upgrade button is clicked.
1102
  },
1103
 
1104
  /**
1105
+ * Fires blur on mouse up to avoid focus ring when clicked with mouse.
1106
  *
1107
+ * @since 2.0
1108
  * @access private
1109
+ * @method _buttonMouseUp
1110
+ * @param {Event} e
1111
+ * @return void
1112
  */
1113
+ _buttonMouseUp: function(e) {
1114
+ $(e.currentTarget).blur();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1115
  },
1116
 
1117
  /* Panel
1126
  */
1127
  _closePanel: function()
1128
  {
 
 
 
1129
  FLBuilder.triggerHook('hideContentPanel');
1130
  },
1131
 
1138
  */
1139
  _showPanel: function()
1140
  {
 
 
 
1141
  FLBuilder.triggerHook('showContentPanel');
1142
  },
1143
 
1144
+ /**
1145
+ * Toggle the panel open or closed.
1146
+ *
1147
+ * @since 2.0
1148
+ * @access private
1149
+ * @method _togglePanel
1150
+ */
1151
+ _togglePanel: function()
1152
+ {
1153
+ FLBuilder.triggerHook('toggleContentPanel');
1154
+ },
1155
+
1156
  /**
1157
  * Opens or closes a section in the builder's content panel
1158
  * when a section title is clicked.
1180
  /* Save Actions
1181
  ----------------------------------------------------------*/
1182
 
1183
+ /**
1184
+ * Publish the current layout
1185
+ *
1186
+ * @since 2.0
1187
+ * @access private
1188
+ * @method _publishLayout
1189
+ * @param bool whether or not builder should exit after publish
1190
+ * @return void
1191
+ */
1192
+ _publishLayout: function( shouldExit ) {
1193
+
1194
+ // Save existing settings first if any exist. Don't proceed if it fails.
1195
+ if ( ! FLBuilder._triggerSettingsSave( false, true ) ) {
1196
+ return;
1197
+ }
1198
+
1199
+ if ( _.isUndefined( shouldExit ) ) {
1200
+ var shouldExit = true;
1201
+ }
1202
+
1203
+ FLBuilder.ajax( {
1204
+ action: 'save_layout'
1205
+ }, this._onPublishComplete.bind( this, shouldExit ) );
1206
+ },
1207
+
1208
  /**
1209
  * Publishes the layout when the publish button is clicked.
1210
  *
1211
  * @since 1.0
1212
  * @access private
1213
+ * @param bool whether or not builder should exit after publish
1214
  * @method _publishButtonClicked
1215
  */
1216
+ _publishButtonClicked: function( shouldExit )
1217
  {
1218
+ FLBuilder._publishLayout( shouldExit );
1219
+ },
1220
 
1221
+ /**
1222
+ * Fires on successful ajax publish.
1223
+ *
1224
+ * @since 2.0
1225
+ * @access private
1226
+ * @param bool whether or not builder should exit after publish
1227
+ * @return void
1228
+ */
1229
+ _onPublishComplete: function( shouldExit ) {
1230
+ if ( shouldExit ) {
1231
+ if ( FLBuilderConfig.shouldRefreshOnPublish ) {
1232
+ FLBuilder._exit();
1233
+ } else {
1234
+ FLBuilder._exitWithoutRefresh();
1235
+ }
1236
+ }
1237
 
1238
+ // Change the admin bar status dot to green if it isn't already
1239
+ $('#wp-admin-bar-fl-builder-frontend-edit-link .fl-builder-admin-bar-status-dot').css('color', '#6bc373');
1240
+
1241
+ FLBuilder.triggerHook( 'didPublishLayout' );
1242
  },
1243
 
1244
  /**
1255
  FLBuilder.ajax({
1256
  action: 'save_draft'
1257
  }, FLBuilder._exit);
 
 
1258
  },
1259
 
1260
  /**
1276
  FLBuilder.ajax({
1277
  action: 'clear_draft_layout'
1278
  }, FLBuilder._exit);
1279
+ } else {
1280
+ FLBuilder.triggerHook('didCancelDiscard');
1281
  }
1282
  },
1283
 
1311
  if ( FLBuilderConfig.isUserTemplate && typeof window.opener != 'undefined' && window.opener ) {
1312
 
1313
  if ( typeof window.opener.FLBuilder != 'undefined' ) {
1314
+ if ( 'undefined' === typeof FLBuilderGlobalNodeId ) {
1315
+ window.opener.FLBuilder._updateLayout();
1316
+ } else {
1317
+ window.opener.FLBuilder._updateNode( FLBuilderGlobalNodeId );
1318
+ }
1319
  }
1320
 
1321
  window.close();
1335
  }
1336
  },
1337
 
1338
+ /**
1339
+ * Allow the editing session to end but don't redirect to any url.
1340
+ *
1341
+ * @since 2.0
1342
+ * @return void
1343
+ */
1344
+ _exitWithoutRefresh: function() {
1345
+ var href = window.location.href;
1346
+
1347
+ if ( FLBuilderConfig.isUserTemplate && typeof window.opener != 'undefined' && window.opener ) {
1348
+
1349
+ if ( typeof window.opener.FLBuilder != 'undefined' ) {
1350
+ if ( 'undefined' === typeof FLBuilderGlobalNodeId ) {
1351
+ window.opener.FLBuilder._updateLayout();
1352
+ } else {
1353
+ window.opener.FLBuilder._updateNode( FLBuilderGlobalNodeId );
1354
+ }
1355
+ }
1356
+
1357
+ window.close();
1358
+ }
1359
+ else {
1360
+ FLBuilder.triggerHook('endEditingSession');
1361
+ }
1362
+ },
1363
+
1364
  /* Tools Actions
1365
  ----------------------------------------------------------*/
1366
 
1373
  */
1374
  _duplicateLayoutClicked: function()
1375
  {
 
1376
  FLBuilder.showAjaxLoader();
1377
 
1378
  FLBuilder.ajax({
1409
  */
1410
  _layoutSettingsClicked: function()
1411
  {
1412
+ FLBuilderSettingsForms.render( {
1413
+ id : 'layout',
1414
+ className : 'fl-builder-layout-settings',
1415
+ settings : FLBuilderSettingsConfig.settings.layout
1416
+ }, function() {
1417
+ FLBuilder._layoutSettingsInitCSS();
1418
+ } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1419
  },
1420
 
1421
  /**
1501
  FLBuilder.ajax( {
1502
  action: 'save_layout_settings',
1503
  settings: settings
1504
+ }, function() {
1505
+ FLBuilder.triggerHook( 'didSaveLayoutSettingsComplete', settings );
1506
+ FLBuilder._updateLayout();
1507
+ } );
1508
  },
1509
 
1510
  /**
1542
  */
1543
  _globalSettingsClicked: function()
1544
  {
1545
+ FLBuilderSettingsForms.render( {
1546
+ id : 'global',
1547
+ className : 'fl-builder-global-settings',
1548
+ settings : FLBuilderSettingsConfig.settings.global
1549
+ }, function() {
1550
+ FLBuilder._layoutSettingsInitCSS();
1551
+ } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1552
  },
1553
 
1554
  /**
1590
  {
1591
  FLBuilderConfig.global = JSON.parse( response );
1592
 
1593
+ FLBuilder.triggerHook( 'didSaveGlobalSettingsComplete', FLBuilderConfig.global );
1594
+
1595
  FLBuilder._updateLayout();
1596
  },
1597
 
1608
  */
1609
  _initTemplateSelector: function()
1610
  {
1611
+ var rows = $(FLBuilder._contentClass).find('.fl-row'),
1612
+ layoutHasContent = ( rows.length > 0 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1613
 
1614
+ if( ! layoutHasContent ) {
1615
+ FLBuilder.ContentPanel.show('modules');
 
1616
  }
 
 
1617
  },
1618
 
1619
  /**
1620
+ * Show options for inserting or appending a template when a template is selected.
1621
+ * This logic was moved from `_templateClicked` to unbind it from the specific event.
1622
+ *
1623
+ * @since 2.0
1624
+ * @access private
1625
+ * @method _requestTemplateInsert
1626
+ */
1627
+ _requestTemplateInsert: function(index, type) {
 
 
 
 
1628
 
1629
+ // if there are existing rows in the layout
1630
+ if( FLBuilder.layoutHasContent() ) {
 
 
 
 
 
 
 
 
 
 
 
 
1631
 
1632
+ // If the template is blank, no need to ask
1633
  if(index == 0) {
1634
  if(confirm(FLBuilderStrings.changeTemplateMessage)) {
1635
  FLBuilder._lightbox._node.hide();
1636
+ FLBuilder._applyTemplate(0, false, type);
1637
  }
1638
  }
1639
+ // present options Replace or Append
1640
  else {
1641
  FLBuilder._selectedTemplateId = index;
1642
+ FLBuilder._selectedTemplateType = type;
1643
  FLBuilder._showTemplateActions();
1644
  FLBuilder._lightbox._node.hide();
1645
  }
1646
  }
1647
+ // if there are no rows, just insert the template.
1648
  else {
1649
+ FLBuilder._applyTemplate(index, false, type);
1650
  }
1651
  },
1652
 
1718
  */
1719
  _templateCancelClicked: function()
1720
  {
1721
+ FLBuilder.triggerHook( 'showContentPanel' );
1722
  },
1723
 
1724
  /**
1746
  action: 'apply_template',
1747
  template_id: id,
1748
  append: append
1749
+ }, FLBuilder._applyTemplateComplete);
1750
  }
1751
  else {
1752
 
1754
  action: 'apply_user_template',
1755
  template_id: id,
1756
  append: append
1757
+ }, FLBuilder._applyUserTemplateComplete);
1758
  }
1759
+
1760
+ FLBuilder.triggerHook('didApplyTemplate');
1761
+ },
1762
+
1763
+ /**
1764
+ * Callback for when applying a template completes.
1765
+
1766
+ * @since 2.0
1767
+ * @access private
1768
+ * @method _applyTemplateComplete
1769
+ * @param {String} response
1770
+ */
1771
+ _applyTemplateComplete: function( response )
1772
+ {
1773
+ var data = JSON.parse( response );
1774
+
1775
+ FLBuilder._renderLayout( data.layout );
1776
+ FLBuilder.triggerHook( 'didApplyTemplateComplete', data.config );
1777
  },
1778
 
1779
  /**
1780
+ * Callback for when applying a user template completes.
1781
 
1782
  * @since 1.9.5
1783
  * @access private
1784
+ * @method _applyUserTemplateComplete
1785
+ * @param {string} response
1786
  */
1787
+ _applyUserTemplateComplete: function( response )
1788
  {
1789
+ var data = JSON.parse( response );
1790
+
1791
+ if ( null !== data.layout_css ) {
1792
  $( '#fl-builder-layout-css' ).html( data.layout_css );
1793
  }
1794
 
1795
+ FLBuilder._renderLayout( data.layout );
1796
+ FLBuilder.triggerHook( 'didApplyTemplateComplete', data.config );
1797
  },
1798
 
1799
  /* User Template Settings
1809
  */
1810
  _saveUserTemplateClicked: function()
1811
  {
1812
+ FLBuilderSettingsForms.render( {
1813
+ id : 'user_template',
1814
+ className : 'fl-builder-user-template-settings',
1815
+ rules : {
1816
+ name: {
1817
+ required: true
1818
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1819
  }
1820
+ } );
1821
  },
1822
 
1823
  /**
1835
 
1836
  if(valid) {
1837
 
 
 
1838
  FLBuilder.ajax({
1839
  action: 'save_user_template',
1840
  settings: settings
1851
  * @access private
1852
  * @method _saveUserTemplateSettingsComplete
1853
  */
1854
+ _saveUserTemplateSettingsComplete: function(data)
1855
  {
1856
+ if ( !data ) return;
1857
+ var data = JSON.parse(data);
1858
+
1859
+ FLBuilderConfig.contentItems.template.push(data);
1860
+ FLBuilder.triggerHook('contentItemsChanged');
1861
  },
1862
 
1863
  /**
1922
  var template = $( this ).closest( '.fl-user-template' ),
1923
  id = template.attr( 'data-id' ),
1924
  all = $( '.fl-user-template[data-id=' + id + ']' ),
1925
+ parent = null,
1926
+ index = null,
1927
+ i = null,
1928
+ item = null;
1929
 
1930
  if ( confirm( FLBuilderStrings.deleteTemplate ) ) {
1931
 
1934
  template_id: id
1935
  } );
1936
 
1937
+ // Remove the item from library
1938
+ for(i in FLBuilderConfig.contentItems.template) {
1939
+ item = FLBuilderConfig.contentItems.template[i];
1940
+ if (item.postId == id) {
1941
+ index = i;
 
 
 
 
 
 
 
 
1942
  }
1943
+ }
1944
+ if (!_.isNull(index)) {
1945
+ FLBuilderConfig.contentItems.template.splice(index, 1);
1946
+ FLBuilder.triggerHook('contentItemsChanged');
1947
+ }
1948
  }
1949
 
1950
  e.stopPropagation();
1953
  /* Help Actions
1954
  ----------------------------------------------------------*/
1955
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1956
  /**
1957
  * Opens a new window with the knowledge base URL when the
1958
  * view knowledge base button is clicked.
1963
  */
1964
  _viewKnowledgeBaseClicked: function()
1965
  {
 
 
1966
  window.open( FLBuilderConfig.help.knowledge_base_url );
1967
  },
1968
 
1976
  */
1977
  _visitForumsClicked: function()
1978
  {
 
 
1979
  window.open( FLBuilderConfig.help.forums_url );
1980
  },
1981
 
1993
  _showTourOrTemplates: function()
1994
  {
1995
  if ( ! FLBuilderConfig.simpleUi && ! FLBuilderConfig.isUserTemplate ) {
1996
+
1997
  if ( FLBuilderConfig.help.tour && FLBuilderConfig.newUser ) {
1998
  FLBuilder._showTourLightbox();
1999
  }
2081
  content.removeClass('fl-builder-empty');
2082
  content.find('.fl-builder-empty-message').remove();
2083
 
2084
+ if ( ! content.find( '.fl-row, .fl-builder-block' ).length ) {
2085
  content.addClass('fl-builder-empty');
2086
  content.append('<span class="fl-builder-empty-message">'+ FLBuilderStrings.emptyMessage +'</span>');
2087
  FLBuilder._initSortables();
2089
  }
2090
  },
2091
 
2092
+ /**
2093
+ * Sends an AJAX request to re-render a single node.
2094
+ *
2095
+ * @since 2.0
2096
+ * @access private
2097
+ * @method _updateNode
2098
+ * @param {String} nodeId
2099
+ * @param {Function} callback
2100
+ */
2101
+ _updateNode: function( nodeId, callback )
2102
+ {
2103
+ if ( ! $( '.fl-node-' + nodeId ).length ) {
2104
+ return;
2105
+ }
2106
+
2107
+ FLBuilder._showNodeLoading( nodeId );
2108
+
2109
+ FLBuilder.ajax( {
2110
+ action : 'render_node',
2111
+ node_id : nodeId
2112
+ }, function( response ) {
2113
+ FLBuilder._renderLayout( JSON.parse( response ), callback );
2114
+ }.bind( this ) );
2115
+ },
2116
+
2117
  /**
2118
  * Sends an AJAX request to render the layout and is typically
2119
  * used as a callback to many of the builder's save operations.
2182
  }
2183
  },
2184
 
2185
+ /**
2186
+ * Checks to see if any rows exist in the layout, or if it is blank.
2187
+ *
2188
+ * @since 2.0
2189
+ * @method layoutHasContent
2190
+ * @return {Boolean}
2191
+ */
2192
+ layoutHasContent: function()
2193
+ {
2194
+ if( $(FLBuilder._contentClass).children('.fl-row').length > 0) {
2195
+ return true;
2196
+ } else {
2197
+ return false;
2198
+ }
2199
+ },
2200
+
2201
  /**
2202
  * Initializes MediaElements.js audio and video players.
2203
  *
2348
  FLBuilder._highlightRowsAndColsForDrag( target );
2349
  FLBuilder._adjustColHeightsForDrag();
2350
  FLBuilder._disableGlobalRows();
 
2351
  FLBuilder._destroyOverlayEvents();
2352
  FLBuilder._removeAllOverlays();
2353
  FLBuilder._initSortables();
2359
  if ( initialPos > 0 ) {
2360
  scrollTo( 0, node.offset().top - initialPos );
2361
  }
2362
+
2363
+ FLBuilder.triggerHook('didInitDrag');
2364
  },
2365
 
2366
  /**
2374
  */
2375
  _blockDragStart: function(e, ui)
2376
  {
2377
+
2378
  // Let the builder know dragging has started.
2379
  FLBuilder._dragging = true;
2380
 
2381
  // Removed the drag init class as we're done with that.
2382
  $( '.fl-node-drag-init' ).removeClass( 'fl-node-drag-init' );
2383
+
2384
+ FLBuilder.triggerHook('didStartDrag');
2385
  },
2386
 
2387
  /**
2462
  * Callback that fires when an element that is being
2463
  * dragged position changes.
2464
  *
2465
+ * What we're doing here keeps it from appearing jumpy when draging
2466
+ * between columns. Without this you'd see the placeholder jump into
2467
+ * a column position briefly when you didn't intend for it to.
2468
+ *
2469
  * @since 1.9
2470
  * @access private
2471
  * @method _blockDragChange
2474
  */
2475
  _blockDragChange: function( e, ui )
2476
  {
2477
+ ui.placeholder.css( 'opacity', '0' );
2478
+ ui.placeholder.animate( { 'opacity': '1' }, 100 );
2479
  },
2480
 
2481
  /**
2585
 
2586
  // Scroll the page back to where it was.
2587
  scrollTo( 0, parent.offset().top - initialPos );
2588
+
2589
+ FLBuilder.triggerHook('didStopDrag');
2590
  },
2591
 
2592
  /**
2664
  FLBuilder._removeColHighlightGuides();
2665
  FLBuilder._removeModuleOverlays();
2666
  FLBuilder._hideTipTips();
2667
+ FLBuilder._closeAllSubmenus();
2668
  },
2669
 
2670
  /**
2747
  // Save a copy of the original actions.
2748
  actions.data( 'original', actions.clone() );
2749
 
2750
+ // Get the actions width and items. Subtract any padding plus 2px (8px)
2751
+ actionsWidth = Math.floor(actions[0].getBoundingClientRect().width) - 8;
2752
  items = actions.find( ' > i, > span.fl-builder-has-submenu' );
2753
 
2754
  // Find visible and overflow items.
2755
  for( ; i < items.length; i++ ) {
2756
 
2757
  item = items.eq( i );
2758
+ itemsWidth += Math.floor(item[0].getBoundingClientRect().width);
2759
 
2760
  if ( itemsWidth > actionsWidth ) {
2761
  overflowItems.push( item );
2811
  $('.fl-row').removeClass('fl-block-overlay-active');
2812
  $('.fl-row-overlay').remove();
2813
  $('.fl-module').removeClass('fl-module-adjust-height');
2814
+ $('body').removeClass( 'fl-builder-row-resizing' );
2815
+ FLBuilder._closeAllSubmenus();
2816
  },
2817
 
2818
  /**
2871
  // Append the overlay.
2872
  overlay = FLBuilder._appendOverlay( row, template( {
2873
  global : row.hasClass( 'fl-node-global' ),
2874
+ node : row.attr('data-node'),
2875
  } ) );
2876
 
2877
  // Adjust the overlay position if covered by negative margin content.
2896
  module.addClass( 'fl-module-adjust-height' );
2897
  }
2898
  } );
2899
+
2900
+ // Build the overlay overflow menu if needed.
2901
+ FLBuilder._buildOverlayOverflowMenu( overlay );
2902
  }
2903
  },
2904
 
3138
  */
3139
  _addRowComplete: function(response)
3140
  {
3141
+ var data = 'object' === typeof response ? response : JSON.parse(response),
3142
  content = $(FLBuilder._contentClass),
3143
  rowId = $(data.html).data('node'),
3144
  module = FLBuilder._addModuleAfterNodeRender;
3158
  }
3159
 
3160
  FLBuilder._removeNodeLoadingPlaceholder( $( '.fl-node-' + rowId ) );
3161
+ FLBuilder.triggerHook( 'didAddRow', rowId );
3162
  } );
3163
  },
3164
 
3200
  */
3201
  _deleteRow: function(row)
3202
  {
3203
+ var nodeId = row.attr('data-node');
3204
+
3205
  FLBuilder.ajax({
3206
  action: 'delete_node',
3207
+ node_id: nodeId
3208
  });
3209
 
3210
  row.empty();
3211
  row.remove();
3212
  FLBuilder._setupEmptyLayout();
3213
  FLBuilder._removeRowOverlays();
3214
+ FLBuilder.triggerHook( 'didDeleteRow', nodeId );
3215
  },
3216
 
3217
  /**
3224
  */
3225
  _rowCopyClicked: function(e)
3226
  {
3227
+ var row = $( this ).closest( '.fl-row' ),
3228
+ nodeId = row.attr( 'data-node' ),
3229
+ position = $( FLBuilder._contentClass + ' .fl-row' ).index( row ) + 1,
3230
+ clone = row.clone(),
3231
+ form = $( '.fl-builder-settings[data-node]' ),
3232
+ formNodeId = form.attr( 'data-node' ),
3233
+ formNode = ( formNodeId === nodeId ) ? row : row.find( '[data-node="' + formNodeId + '"]' ),
3234
+ settings = null;
3235
+
3236
+ if ( form.length && formNode.length ) {
3237
+ settings = FLBuilder._getSettings( form );
3238
+ FLBuilderSettingsConfig.nodes[ formNodeId ] = settings;
3239
+ }
3240
 
3241
+ clone.addClass( 'fl-node-' + nodeId + '-clone fl-builder-node-clone' );
 
3242
  clone.find( '.fl-block-overlay' ).remove();
3243
  row.after( clone );
3244
 
3245
+ $( 'html, body' ).animate( {
3246
+ scrollTop: clone.offset().top - 75
3247
+ }, 500 );
3248
+
3249
  FLBuilder._showNodeLoading( nodeId + '-clone' );
3250
  FLBuilder._newRowPosition = position;
3251
 
3252
  FLBuilder.ajax( {
3253
  action: 'copy_row',
3254
+ node_id: nodeId,
3255
+ settings: settings,
3256
+ settings_id: formNodeId
3257
+ }, function( response ) {
3258
+ var data = JSON.parse( response );
3259
+ data.duplicatedRow = nodeId;
3260
+ FLBuilder._rowCopyComplete( data );
3261
+ } );
3262
 
3263
  e.stopPropagation();
3264
  },
3269
  * @since 1.7
3270
  * @access private
3271
  * @method _rowCopyComplete
3272
+ * @param {Object} data
3273
  */
3274
+ _rowCopyComplete: function( data )
3275
  {
 
 
3276
  data.nodeParent = $( FLBuilder._contentClass );
3277
  data.nodePosition = FLBuilder._newRowPosition;
3278
 
3279
  FLBuilder._renderLayout( data, function() {
3280
+
3281
+ FLBuilder.triggerHook( 'didDuplicateRow', {
3282
+ newNodeId : data.nodeId,
3283
+ oldNodeId : data.duplicatedRow
3284
+ } );
3285
+
3286
  data.nodeParent.find( '.fl-builder-node-loading' ).eq( 0 ).remove();
3287
  } );
3288
  },
3299
  {
3300
  var button = $( this ),
3301
  nodeId = button.closest( '.fl-row' ).attr( 'data-node' ),
3302
+ global = button.closest( '.fl-block-overlay-global' ).length > 0,
3303
+ win = null;
3304
 
3305
  if ( global && 'row' != FLBuilderConfig.userTemplateType ) {
3306
  if ( FLBuilderConfig.userCanEditGlobalTemplates ) {
3307
+ win = window.open( $( '.fl-row[data-node="' + nodeId + '"]' ).attr( 'data-template-url' ) );
3308
+ win.FLBuilderGlobalNodeId = nodeId;
3309
  }
3310
  }
3311
  else if ( button.hasClass( 'fl-block-settings' ) ) {
3312
 
3313
+ FLBuilderSettingsForms.render( {
3314
+ id : 'row',
3315
+ nodeId : nodeId,
3316
+ className : 'fl-builder-row-settings',
3317
+ attrs : 'data-node="' + nodeId + '"',
3318
+ buttons : ! global ? ['save-as'] : [],
3319
+ badges : global ? [ FLBuilderStrings.global ] : [],
3320
+ settings : FLBuilderSettingsConfig.nodes[ nodeId ],
3321
+ preview : {
3322
+ type: 'row'
3323
+ }
3324
+ }, function() {
3325
+ $( '#fl-field-width select' ).on( 'change', FLBuilder._rowWidthChanged );
3326
+ $( '#fl-field-content_width select' ).on( 'change', FLBuilder._rowWidthChanged );
3327
+ } );
3328
  }
3329
 
3330
  e.stopPropagation();
3331
  },
3332
 
3333
  /**
3334
+ * Shows or hides the row max-width setting when the
3335
+ * row or row content width is changed.
3336
  *
3337
+ * @since 2.0
3338
+ * @access private
3339
+ * @method _rowWidthChanged
3340
+ */
3341
+ _rowWidthChanged: function()
3342
+ {
3343
+ var rowWidth = $( '#fl-field-width select' ).val(),
3344
+ contentWidth = $( '#fl-field-content_width select' ).val(),
3345
+ maxWidth = $( '#fl-field-max_content_width' );
3346
+
3347
+ if ( 'fixed' == rowWidth || ( 'full' == rowWidth && 'fixed' == contentWidth ) ) {
3348
+ maxWidth.show();
3349
+ } else {
3350
+ maxWidth.hide();
3351
+ }
3352
+ },
3353
+
3354
+ /**
3355
+ * Resets the max-width of a row.
3356
+ *
3357
+ * @since 2.0
3358
  * @access private
3359
+ * @method _resetRowWidthClicked
 
3360
  */
3361
+ _resetRowWidthClicked: function( e )
3362
  {
3363
+ var button = $( this ),
3364
+ row = button.closest( '.fl-row' ),
3365
+ nodeId = row.attr( 'data-node' ),
3366
+ content = row.find( '.fl-row-content' ),
3367
+ width = FLBuilderConfig.global.row_width + 'px',
3368
+ settings = $( '.fl-builder-row-settings' );
3369
+
3370
+ if ( row.hasClass( 'fl-row-fixed-width' ) ) {
3371
+ row.css( 'max-width', width );
3372
+ }
3373
 
3374
+ content.css( 'max-width', width );
3375
 
3376
+ if ( settings.length ) {
3377
+ settings.find( '[name=max_content_width]' ).val( '' );
3378
+ }
3379
+
3380
+ FLBuilder.ajax({
3381
+ action : 'resize_row_content',
3382
+ node : nodeId,
3383
+ width : ''
3384
  });
3385
+
3386
+ FLBuilder._closeAllSubmenus();
3387
+ FLBuilder.triggerHook( 'didResetRowWidth', nodeId );
3388
+
3389
+ e.stopPropagation();
3390
  },
3391
 
3392
  /* Columns
3418
  });
3419
  },
3420
 
3421
+ /**
3422
+ * Remove any column highlights
3423
+ *
3424
+ * @since 2.0
3425
+ * @access private
3426
+ * @method _removeEmptyColHighlights
3427
+ */
3428
+ _removeEmptyColHighlights: function() {
3429
+ $( '.fl-row-highlight' ).removeClass('fl-row-highlight');
3430
+ $( '.fl-col-highlight' ).removeClass('fl-col-highlight');
3431
+ },
3432
+
3433
  /**
3434
  * Sets up dashed borders to show where things can
3435
  * be dropped in rows and columns.
3572
  parentFirst = hasParentCol ? 0 === parentIndex : false,
3573
  parentLast = hasParentCol ? numParentCols === parentIndex + 1 : false,
3574
  contentWidth = col.find( '> .fl-col-content' ).width(),
3575
+ row = col.closest('.fl-row'),
3576
+ rowIsFixedWidth = !! row.find('.fl-row-fixed-width').addBack('.fl-row-fixed-width').length,
3577
+ userCanResizeRows = FLBuilderConfig.rowResize.userCanResizeRows,
3578
  template = wp.template( 'fl-col-overlay' ),
3579
  overlay = null;
3580
 
3611
  parentFirst : parentFirst,
3612
  parentLast : parentLast,
3613
  numParentCols : numParentCols,
3614
+ contentWidth : contentWidth,
3615
+ rowIsFixedWidth : rowIsFixedWidth,
3616
+ userCanResizeRows : userCanResizeRows,
3617
  } ) );
3618
 
3619
  // Build the overlay overflow menu if needed.
3651
 
3652
  FLBuilder._removeColOverlays();
3653
  FLBuilder._removeColHighlightGuides();
3654
+ FLBuilder._closeAllSubmenus();
3655
  },
3656
 
3657
  /**
3668
  cols.removeClass('fl-block-overlay-active');
3669
  cols.find('.fl-col-overlay').remove();
3670
  $('body').removeClass('fl-block-overlay-muted');
3671
+ FLBuilder._closeAllSubmenus();
3672
  },
3673
 
3674
  /**
3862
  FLBuilder._highlightEmptyCols();
3863
  FLBuilder._initDropTargets();
3864
  FLBuilder._initSortables();
3865
+ FLBuilder._closeAllSubmenus();
3866
  },
3867
 
3868
  /**
3876
  */
3877
  _colSettingsClicked: function(e)
3878
  {
3879
+ var button = $( this ),
3880
+ col = button.closest('.fl-col'),
3881
+ content = col.find( '> .fl-col-content' ),
3882
+ global = button.closest( '.fl-block-overlay-global' ).length > 0,
3883
+ nodeId = null;
3884
 
3885
  if ( FLBuilder._colResizing ) {
3886
  return;
3893
  nodeId = col.attr('data-node');
3894
  }
3895
 
3896
+ FLBuilderSettingsForms.render( {
3897
+ id : 'col',
3898
+ nodeId : nodeId,
3899
+ className : 'fl-builder-col-settings',
3900
+ attrs : 'data-node="' + nodeId + '"',
3901
+ badges : global ? [ FLBuilderStrings.global ] : [],
3902
+ settings : FLBuilderSettingsConfig.nodes[ nodeId ],
3903
+ preview : {
3904
+ type: 'col'
3905
+ }
3906
+ }, function() {
3907
+ if ( col.siblings( '.fl-col' ).length === 0 ) {
3908
+ $( '#fl-builder-settings-section-general' ).hide();
3909
+ }
3910
+ else if( content.width() <= 40 ) {
3911
+ $( '#fl-field-size' ).hide();
3912
+ }
3913
+ } );
3914
 
3915
+ e.stopPropagation();
3916
+ },
3917
+
3918
+ /**
3919
+ * Callback for when the copy column button is clicked.
3920
+ *
3921
+ * @since 2.0
3922
+ * @access private
3923
+ * @method _copyColClicked
3924
+ * @param {Object} e The event object.
3925
+ */
3926
+ _copyColClicked: function( e )
3927
+ {
3928
+ var col = $( this ).closest( '.fl-col' ),
3929
+ nodeId = col.attr( 'data-node' ),
3930
+ clone = col.clone(),
3931
+ group = col.parent(),
3932
+ form = $( '.fl-builder-settings[data-node]' ),
3933
+ formNodeId = form.attr( 'data-node' ),
3934
+ formNode = ( formNodeId === nodeId ) ? col : col.find( '[data-node="' + formNodeId + '"]' ),
3935
+ settings = null;
3936
+
3937
+ if ( form.length && formNode.length ) {
3938
+ settings = FLBuilder._getSettings( form );
3939
+ FLBuilderSettingsConfig.nodes[ formNodeId ] = settings;
3940
+ }
3941
+
3942
+ clone.addClass( 'fl-node-' + nodeId + '-clone fl-builder-node-clone' );
3943
+ clone.find( '.fl-block-overlay' ).remove();
3944
+ col.after( clone );
3945
+
3946
+ FLBuilder._showNodeLoading( nodeId + '-clone' );
3947
+ FLBuilder._newColParent = group;
3948
+ FLBuilder._newColPosition = col.index() + 1;
3949
+ FLBuilder._resetColumnWidths( group );
3950
+
3951
+ FLBuilder.ajax( {
3952
+ action: 'copy_col',
3953
+ node_id: nodeId,
3954
+ settings: settings,
3955
+ settings_id: formNodeId
3956
+ }, function( response ){
3957
+ var data = JSON.parse( response );
3958
+ data.duplicatedColumn = nodeId;
3959
+ FLBuilder._copyColComplete( data );
3960
+ } );
3961
 
3962
  e.stopPropagation();
3963
  },
3964
 
3965
  /**
3966
+ * Callback for when a column has been duplicated.
 
3967
  *
3968
+ * @since 2.0
3969
  * @access private
3970
+ * @method _copyColComplete
3971
+ * @param {Object} data
3972
  */
3973
+ _copyColComplete: function( data )
3974
  {
3975
+ data.nodeParent = FLBuilder._newColParent;
3976
+ data.nodePosition = FLBuilder._newColPosition;
 
 
 
 
 
3977
 
3978
+ FLBuilder._renderLayout( data, function(){
 
 
 
3979
 
3980
+ FLBuilder.triggerHook( 'didDuplicateColumn', {
3981
+ newNodeId : data.nodeId,
3982
+ oldNodeId : data.duplicatedColumn
3983
+ } );
 
 
3984
 
3985
+ data.nodeParent.find( '.fl-builder-node-loading' ).eq( 0 ).remove();
 
 
3986
  } );
3987
  },
3988
 
4039
  */
4040
  _deleteCol: function(col)
4041
  {
4042
+ var nodeId = col.attr('data-node'),
4043
+ row = col.closest('.fl-row'),
4044
+ group = col.closest('.fl-col-group'),
4045
+ cols = null,
4046
+ width = 0;
4047
 
4048
  col.remove();
4049
  rowCols = row.find('.fl-row-content > .fl-col-group > .fl-col');
4070
  }
4071
 
4072
  groupCols.css('width', width + '%');
4073
+
4074
+ FLBuilder.triggerHook( 'didResetColumnWidths', {
4075
+ cols : groupCols
4076
+ } );
4077
  }
4078
 
4079
  FLBuilder.ajax({
4080
  action : 'delete_col',
4081
+ node_id : nodeId,
4082
  new_width : width
4083
  });
4084
 
4085
  FLBuilder._initDropTargets();
4086
  FLBuilder._initSortables();
4087
+ FLBuilder.triggerHook( 'didDeleteColumn', nodeId );
4088
  }
4089
  },
4090
 
4146
  // Add a module to a newly created column.
4147
  if ( moduleData !== null ) {
4148
 
4149
+ $( '.fl-module[data-node="' + moduleData.module.data( 'node' ) + '"]' ).remove()
4150
 
4151
+ col = $( '.fl-col[data-node="' + moduleData.colId + '"]' );
4152
 
4153
  if ( 'after' == moduleData.position ) {
4154
  col.next().find( '.fl-col-content' ).append( moduleData.module );
4160
  FLBuilder._reorderModule( moduleData.module );
4161
  FLBuilder._addModuleAfterNodeRender = null;
4162
  }
4163
+
4164
+ FLBuilder.triggerHook( 'didAddColumn', data.nodeId );
4165
+
4166
+ FLBuilder.triggerHook( 'didResetColumnWidths', {
4167
+ cols : $( '.fl-node-' + data.nodeId ).find( '> .fl-col' )
4168
+ } );
4169
  } );
4170
  },
4171
 
4242
  FLBuilder._addModuleAfterNodeRender = null;
4243
  }
4244
 
4245
+ // Remove the loading placeholder.
4246
  FLBuilder._removeNodeLoadingPlaceholder( $( '.fl-node-' + groupId ) );
4247
+ FLBuilder.triggerHook( 'didAddColumnGroup', groupId );
4248
  } );
4249
  },
4250
 
4257
  */
4258
  _initColDragResizing: function()
4259
  {
4260
+ $( '.fl-block-col-resize' ).not( '.fl-block-row-resize' ).draggable( {
4261
  axis : 'x',
4262
  start : FLBuilder._colDragResizeStart,
4263
  drag : FLBuilder._colDragResize,
4277
  _colDragResizeStart: function( e, ui )
4278
  {
4279
  // Setup resize vars.
4280
+ var handle = $( ui.helper ),
4281
+ direction = '',
4282
+ resizeParent = handle.hasClass( 'fl-block-col-resize-parent' ),
4283
+ parentCol = resizeParent ? handle.closest( '.fl-col' ).parents( '.fl-col' ) : null,
4284
+ group = resizeParent ? parentCol.parents( '.fl-col-group' ) : handle.closest( '.fl-col-group' ),
4285
+ cols = group.find( '> .fl-col' ),
4286
+ col = resizeParent ? parentCol : handle.closest( '.fl-col' ),
4287
+ colId = col.attr( 'data-node' ),
4288
+ colSetting = $( '[data-node=' + colId + '] #fl-field-size input' ),
4289
+ sibling = null,
4290
+ siblingId = null,
4291
+ siblingSetting = null,
4292
+ availWidth = 100,
4293
+ i = 0,
4294
+ setting = null,
4295
+ settingType = null;
4296
 
4297
  // Find the direction and sibling.
4298
  if ( handle.hasClass( 'fl-block-col-resize-e' ) ) {
4299
  direction = 'e';
4300
+ sibling = col.nextAll( '.fl-col' ).first();
4301
  }
4302
  else {
4303
  direction = 'w';
4304
+ sibling = col.prevAll( '.fl-col' ).first();
4305
  }
4306
 
4307
+ siblingId = sibling.attr( 'data-node' );
4308
+ siblingSetting = $( '[data-node=' + siblingId + '] #fl-field-size input' );
4309
+
4310
  // Find the available width.
4311
  for ( ; i < cols.length; i++ ) {
4312
 
4320
  availWidth -= parseFloat( cols.eq( i )[ 0 ].style.width );
4321
  }
4322
 
4323
+ // Find the setting if a column form is open.
4324
+ if ( colSetting.length ) {
4325
+ setting = colSetting;
4326
+ settingType = 'col';
4327
+ } else if ( siblingSetting.length ) {
4328
+ setting = siblingSetting;
4329
+ settingType = 'sibling';
4330
+ }
4331
+
4332
  // Build the resize data object.
4333
  FLBuilder._colResizeData = {
4334
  handle : handle,
4340
  colWidth : parseFloat( col[ 0 ].style.width ) / 100,
4341
  sibling : sibling,
4342
  offset : ui.position.left,
4343
+ availWidth : availWidth,
4344
+ setting : setting,
4345
+ settingType : settingType
4346
  };
4347
 
4348
  // Set the resizing flag.
4372
  {
4373
  // Setup resize vars.
4374
  var data = FLBuilder._colResizeData,
4375
+ overlay = data.handle.closest( '.fl-block-overlay' ),
4376
  change = ( data.offset - ui.position.left ) / data.groupWidth,
4377
  colWidth = 'e' == data.direction ? ( data.colWidth - change ) * 100 : ( data.colWidth + change ) * 100,
4378
  colRound = Math.round( colWidth * 100 ) / 100,
4405
  data.col.css( 'width', colRound + '%' );
4406
  data.sibling.css( 'width', siblingRound + '%' );
4407
 
4408
+ // Update the setting if the col or sibling's settings are open.
4409
+ if ( data.setting ) {
4410
+ if ( 'col' === data.settingType ) {
4411
+ data.setting.val( parseFloat( data.col[ 0 ].style.width ) );
4412
+ } else if ( 'sibling' === data.settingType ) {
4413
+ data.setting.val( parseFloat( data.sibling[ 0 ].style.width ) );
4414
+ }
4415
+ }
4416
+
4417
+ // Build the overlay overflow menu if needed.
4418
+ FLBuilder._buildOverlayOverflowMenu( overlay );
4419
+
4420
  // Trigger the col-resize-drag hook.
4421
  FLBuilder.triggerHook( 'col-resize-drag' );
4422
  },
4432
  */
4433
  _colDragResizeStop: function( e, ui )
4434
  {
4435
+ var data = FLBuilder._colResizeData,
4436
+ overlay = FLBuilder._colResizeData.handle.closest( '.fl-block-overlay' ),
4437
+ colId = data.col.data( 'node' ),
4438
+ colWidth = parseFloat( data.col[ 0 ].style.width ),
4439
+ siblingId = data.sibling.data( 'node' ),
4440
+ siblingWidth = parseFloat( data.sibling[ 0 ].style.width );
4441
 
4442
  // Hide the feedback divs.
4443
  FLBuilder._colResizeData.feedbackLeft.hide();
4446
  // Save the resize data.
4447
  FLBuilder.ajax({
4448
  action : 'resize_cols',
4449
+ col_id : colId,
4450
+ col_width : colWidth,
4451
+ sibling_id : siblingId,
4452
+ sibling_width : siblingWidth
4453
  });
4454
 
4455
  // Build the overlay overflow menu if needed.
4469
 
4470
  // Trigger the col-resize-stop hook.
4471
  FLBuilder.triggerHook( 'col-resize-stop' );
4472
+
4473
+ FLBuilder.triggerHook( 'didResizeColumn', {
4474
+ colId : colId,
4475
+ colWidth : colWidth,
4476
+ siblingId : siblingId,
4477
+ siblingWidth : siblingWidth
4478
+ } );
4479
  },
4480
 
4481
  /**
4489
  */
4490
  _resetColumnWidthsClicked: function( e )
4491
  {
4492
+ var button = $( this ),
4493
+ isRow = !! button.closest( '.fl-row-overlay' ).length,
4494
+ group = null,
4495
+ groups = null,
4496
+ groupIds = [],
4497
+ children = null,
4498
+ i = 0,
4499
+ settings = $( '.fl-builder-col-settings' ),
4500
+ col = null;
4501
+
4502
+ if ( isRow ) {
4503
+ groups = button.closest( '.fl-row' ).find( '.fl-row-content > .fl-col-group' );
4504
+ } else {
4505
+ groups = button.parents( '.fl-col-group' ).last();
4506
+ }
4507
 
4508
+ groups.each( function() {
4509
 
4510
+ group = $( this );
4511
+ children = group.find( '.fl-col-group' );
4512
+ groupIds.push( group.data( 'node' ) );
4513
+ FLBuilder._resetColumnWidths( group );
4514
+
4515
+ for ( i = 0; i < children.length; i++ ) {
4516
+ FLBuilder._resetColumnWidths( children.eq( i ) );
4517
+ groupIds.push( children.eq( i ).data( 'node' ) );
4518
+ }
4519
+ } );
4520
+
4521
+ if ( settings.length ) {
4522
+ col = $( '.fl-node-' + settings.attr( 'data-node' ) );
4523
+ settings.find( '#fl-field-size input' ).val( parseFloat( col[ 0 ].style.width ) );
4524
  }
4525
 
4526
  FLBuilder.ajax({
4558
  }
4559
 
4560
  cols.css( 'width', width + '%' );
4561
+
4562
+ FLBuilder.triggerHook( 'didResetColumnWidths', {
4563
+ cols : cols
4564
+ } );
4565
  },
4566
 
4567
  /* Modules
4592
  parentFirst = hasParentCol ? 0 === parentCol.index() : false,
4593
  parentLast = hasParentCol ? numParentCols === parentCol.index() + 1 : false,
4594
  contentWidth = col.find( '> .fl-col-content' ).width(),
4595
+ row = module.closest('.fl-row'),
4596
+ rowIsFixedWidth = !! row.find('.fl-row-fixed-width').addBack('.fl-row-fixed-width').length,
4597
+ userCanResizeRows = FLBuilderConfig.rowResize.userCanResizeRows,
4598
  template = wp.template( 'fl-module-overlay' ),
4599
  overlay = null;
4600
 
4622
  numParentCols : numParentCols,
4623
  parentFirst : parentFirst,
4624
  parentLast : parentLast,
4625
+ contentWidth : contentWidth,
4626
+ rowIsFixedWidth : rowIsFixedWidth,
4627
+ userCanResizeRows : userCanResizeRows,
4628
  } ) );
4629
 
4630
  // Build the overlay overflow menu if necessary.
4674
  modules.removeClass('fl-block-overlay-active');
4675
  modules.find('.fl-module-overlay').remove();
4676
  $('body').removeClass('fl-block-overlay-muted');
4677
+ FLBuilder._closeAllSubmenus();
4678
  },
4679
 
4680
  /**
4875
  */
4876
  _deleteModule: function(module)
4877
  {
4878
+ var row = module.closest('.fl-row'),
4879
+ nodeId = module.attr('data-node');
4880
 
4881
  FLBuilder.ajax({
4882
  action: 'delete_node',
4883
+ node_id: nodeId
4884
  });
4885
 
4886
  module.empty();
4888
  row.removeClass('fl-block-overlay-muted');
4889
  FLBuilder._highlightEmptyCols();
4890
  FLBuilder._removeAllOverlays();
4891
+ FLBuilder.triggerHook( 'didDeleteModule', nodeId );
4892
  },
4893
 
4894
  /**
4904
  var module = $( this ).closest( '.fl-module' )
4905
  nodeId = module.attr( 'data-node' ),
4906
  position = module.index() + 1,
4907
+ clone = module.clone(),
4908
+ form = $( '.fl-builder-module-settings[data-node=' + nodeId + ']' ),
4909
+ settings = null;
4910
 
4911
+ if ( form.length ) {
4912
+ settings = FLBuilder._getSettings( form );
4913
+ FLBuilderSettingsConfig.nodes[ nodeId ] = settings;
4914
+ }
4915
+
4916
+ clone.addClass( 'fl-node-' + nodeId + '-clone fl-builder-node-clone' );
4917
  clone.find( '.fl-block-overlay' ).remove();
4918
  module.after( clone );
4919
 
4920
+ $( 'html, body' ).animate( {
4921
+ scrollTop: clone.offset().top - 75
4922
+ }, 500 );
4923
+
4924
  FLBuilder._showNodeLoading( nodeId + '-clone' );
4925
  FLBuilder._newModuleParent = module.parent();
4926
  FLBuilder._newModulePosition = position;
4927
 
4928
  FLBuilder.ajax({
4929
  action: 'copy_module',
4930
+ node_id: nodeId,
4931
+ settings: settings
4932
+ }, function( response ) {
4933
+ var data = JSON.parse( response );
4934
+ data.duplicatedModule = nodeId;
4935
+ FLBuilder._moduleCopyComplete( data );
4936
+ } );
4937
 
4938
  e.stopPropagation();
4939
  },
4944
  * @since 1.7
4945
  * @access private
4946
  * @method _moduleCopyComplete
4947
+ * @param {Object}
4948
  */
4949
+ _moduleCopyComplete: function( data )
4950
  {
 
 
4951
  data.nodeParent = FLBuilder._newModuleParent;
4952
  data.nodePosition = FLBuilder._newModulePosition;
4953
 
4954
  FLBuilder._renderLayout( data, function(){
4955
+
4956
+ FLBuilder.triggerHook( 'didDuplicateModule', {
4957
+ newNodeId : data.nodeId,
4958
+ oldNodeId : data.duplicatedModule
4959
+ } );
4960
+
4961
  data.nodeParent.find( '.fl-builder-node-loading' ).eq( 0 ).remove();
4962
  } );
4963
  },
4974
  _moduleSettingsClicked: function(e)
4975
  {
4976
  var button = $( this ),
4977
+ type = button.closest( '.fl-module' ).attr( 'data-type' ),
4978
  nodeId = button.closest( '.fl-module' ).attr( 'data-node' ),
4979
  parentId = button.closest( '.fl-col' ).attr( 'data-node' ),
 
4980
  global = button.closest( '.fl-block-overlay-global' ).length > 0;
4981
 
4982
  e.stopPropagation();
4988
  return;
4989
  }
4990
 
4991
+ FLBuilder._showModuleSettings( {
4992
+ type : type,
4993
+ nodeId : nodeId,
4994
+ parentId : parentId,
4995
+ global : global
4996
+ } );
4997
  },
4998
 
4999
  /**
5002
  * @since 1.0
5003
  * @access private
5004
  * @method _showModuleSettings
5005
+ * @param {Object} data
5006
+ * @param {Function} callback
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5007
  */
5008
+ _showModuleSettings: function( data, callback )
5009
  {
5010
+ var config = FLBuilderSettingsConfig.modules[ data.type ],
5011
+ settings = data.settings ? data.settings : FLBuilderSettingsConfig.nodes[ data.nodeId ],
5012
+ head = $( 'head' ),
5013
+ layout = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5014
 
5015
+ // Add settings CSS and JS.
5016
+ if ( -1 === $.inArray( data.type, FLBuilder._loadedModuleAssets ) ) {
5017
+ if ( '' !== config.assets.css ) {
5018
+ head.append( config.assets.css );
5019
+ }
5020
+ if ( '' !== config.assets.js ) {
5021
+ head.append( config.assets.js );
5022
+ }
5023
+ FLBuilder._loadedModuleAssets.push( data.type );
5024
+ }
5025
+
5026
+ // Render the form.
5027
+ FLBuilderSettingsForms.render( {
5028
+ type : 'module',
5029
+ id : data.type,
5030
+ nodeId : data.nodeId,
5031
+ className : 'fl-builder-module-settings fl-builder-' + data.type + '-settings',
5032
+ attrs : 'data-node="' + data.nodeId + '" data-parent="' + data.parentId + '" data-type="' + data.type + '"',
5033
+ buttons : ! data.global ? ['save-as'] : [],
5034
+ badges : data.global ? [ FLBuilderStrings.global ] : [],
5035
+ settings : settings ? settings : FLBuilderSettingsConfig.defaults.modules[ data.type ],
5036
+ legacy : data.legacy,
5037
+ helper : FLBuilder._moduleHelpers[ data.type ],
5038
+ rules : FLBuilder._moduleHelpers[ data.type ] ? FLBuilder._moduleHelpers[ data.type ].rules : null,
5039
+ preview : {
5040
+ type : 'module',
5041
+ layout : data.layout,
5042
+ callback : function() {
5043
+ FLBuilder.triggerHook( 'didAddModule', data.nodeId );
5044
+ }
5045
+ }
5046
+ }, callback );
5047
  },
5048
 
5049
  /**
5074
  }
5075
  if(valid) {
5076
  FLBuilder._saveSettings();
 
5077
  }
5078
  else {
5079
  FLBuilder._toggleSettingsTabErrors();
5093
  * @param {String} widget The type of widget if this module is a widget.
5094
  * @param {String} alias A module alias key if this module is an alias to another module.
5095
  */
5096
+ _addModule: function( parent, parentId, type, position, widget, alias )
5097
  {
5098
  // Show the loader.
5099
  FLBuilder._showNodeLoadingPlaceholder( parent, position );
5109
  }
5110
 
5111
  // Send the request.
5112
+ FLBuilder.ajax( {
5113
  action : 'render_new_module',
5114
  parent_id : parentId,
5115
  type : type,
5117
  node_preview : 1,
5118
  widget : typeof widget === 'undefined' ? '' : widget,
5119
  alias : typeof alias === 'undefined' ? '' : alias
5120
+ }, FLBuilder._addModuleComplete );
5121
  },
5122
 
5123
  /**
5129
  * @method _addModuleComplete
5130
  * @param {String} response The JSON encoded response.
5131
  */
5132
+ _addModuleComplete: function( response )
5133
  {
5134
+ var data = JSON.parse( response );
5135
+
5136
+ // Setup a preview layout if we have one.
5137
+ if ( data.layout ) {
5138
+ data.layout.nodeParent = FLBuilder._newModuleParent;
5139
+ data.layout.nodePosition = FLBuilder._newModulePosition;
5140
+ }
5141
 
5142
+ // Render the module if a settings form is already open.
5143
+ if ( $( 'form.fl-builder-settings' ).length ) {
5144
+ if ( data.layout ) {
5145
+ FLBuilder._renderLayout( data.layout );
5146
+ }
5147
+ } else {
5148
+ FLBuilder._showModuleSettings( data, function() {
5149
+ $( '.fl-builder-module-settings' ).data( 'new-module', '1' );
5150
+ } );
5151
+ }
5152
  },
5153
 
5154
  /**
5199
  */
5200
  _showNodeTemplateSettings: function( e )
5201
  {
5202
+ var form = $( '.fl-builder-settings-lightbox .fl-builder-settings' ),
5203
+ nodeId = form.attr( 'data-node' ),
5204
+ title = FLBuilderStrings.saveModule;
 
 
 
 
 
 
 
5205
 
5206
+ if ( form.hasClass( 'fl-builder-row-settings' ) ) {
5207
+ title = FLBuilderStrings.saveRow;
5208
+ }
 
 
 
 
 
 
 
 
5209
 
5210
+ if ( ! FLBuilder._triggerSettingsSave( false, false, false ) ) {
5211
+ return false;
5212
+ }
5213
 
5214
+ FLBuilderSettingsForms.render( {
5215
+ id : 'node_template',
5216
+ nodeId : nodeId,
5217
+ title : title,
5218
+ attrs : 'data-node="' + nodeId + '"',
5219
+ className : 'fl-builder-node-template-settings',
5220
+ rules : {
5221
+ name: {
5222
+ required: true
5223
+ }
5224
  }
5225
+ }, function() {
5226
+ if ( ! FLBuilderConfig.userCanEditGlobalTemplates ) {
5227
+ $( '#fl-field-global' ).hide();
5228
+ }
5229
+ } );
5230
  },
5231
 
5232
  /**
5238
  */
5239
  _saveNodeTemplate: function()
5240
  {
5241
+ var form = $( '.fl-builder-node-template-settings' ),
5242
+ nodeId = form.attr( 'data-node' ),
5243
+ valid = form.validate().form();
5244
 
5245
  if ( valid ) {
5246
 
5247
+ FLBuilder._showNodeLoading( nodeId );
5248
 
5249
  FLBuilder.ajax({
5250
  action : 'save_node_template',
5251
+ node_id : nodeId,
5252
  settings : FLBuilder._getSettings( form )
5253
+ }, function( response ) {
5254
+ FLBuilder._saveNodeTemplateComplete( response );
5255
+ FLBuilder._hideNodeLoading( nodeId );
5256
+ } );
5257
 
5258
  FLBuilder._lightbox.close();
5259
  }
5268
  */
5269
  _saveNodeTemplateComplete: function( response )
5270
  {
5271
+ var data = JSON.parse( response ),
5272
+ panel = $( '.fl-builder-saved-' + data.type + 's' ),
5273
+ blocks = panel.find( '.fl-builder-block' ),
5274
+ block = null,
5275
+ text = '',
5276
+ name = data.name.toLowerCase(),
5277
+ i = 0,
5278
+ template = wp.template( 'fl-node-template-block' ),
5279
+ newLibraryItem = {
5280
+ name: data.name,
5281
+ isGlobal: data.global,
5282
+ content: data.type,
5283
+ id: data.id,
5284
+ postID: data.postID,
5285
+ kind: "template",
5286
+ type: "user",
5287
+ link: data.link,
5288
+ category: {
5289
+ uncategorized: FLBuilderStrings.uncategorized
5290
+ }
5291
+ };
5292
 
5293
+ FLBuilderConfig.contentItems.template.push(newLibraryItem);
5294
+ FLBuilder.triggerHook('contentItemsChanged');
 
 
 
 
 
5295
 
5296
  // Update the layout for global templates.
5297
  if ( data.layout ) {
5298
  FLBuilder._renderLayout( data.layout );
5299
+ FLBuilder.triggerHook( 'didSaveGlobalNodeTemplate', data.config );
5300
  }
5301
 
5302
  // Add the new template to the builder panel.
5351
  action = '',
5352
  callback = null;
5353
 
5354
+ // A node template was dropped back into the templates list.
5355
+ if ( parent.hasClass( 'fl-builder-blocks-section-content' ) ) {
5356
+ item.remove();
5357
+ return;
5358
+ }
5359
  // A saved row was dropped.
5360
+ else if ( item.hasClass( 'fl-builder-block-saved-row' ) || item.hasClass( 'fl-builder-block-row-template' ) ) {
5361
  node = item.closest( '.fl-row' );
5362
  position = ! node.length ? 0 : $( FLBuilder._contentClass + ' .fl-row' ).index( node );
5363
  position = parent.hasClass( 'fl-drop-target-last' ) ? position + 1 : position;
5429
  template_type : item.attr( 'data-type' ),
5430
  parent_id : parentId,
5431
  position : position
5432
+ }, function( response ) {
5433
+ if ( action.indexOf( 'row' ) > -1 ) {
5434
+ var data = JSON.parse( response );
5435
+ FLBuilder.triggerHook( 'didApplyRowTemplateComplete', data.config );
5436
+ callback( data.layout );
5437
+ } else {
5438
+ callback( response );
5439
+ }
5440
+ } );
5441
 
5442
  // Remove the helper.
5443
  item.remove();
5477
  block = button.closest( '.fl-builder-block' ),
5478
  global = block.hasClass( 'fl-builder-block-global' ),
5479
  callback = global ? FLBuilder._updateLayout : undefined,
5480
+ message = global ? FLBuilderStrings.deleteGlobalTemplate : FLBuilderStrings.deleteTemplate,
5481
+ index = null;
5482
 
5483
  if ( confirm( message ) ) {
5484
 
5505
  action : 'delete_node_template',
5506
  template_id : block.attr( 'data-id' )
5507
  }, callback);
5508
+
5509
+ // Remove the item from library
5510
+ index = _.findIndex(FLBuilderConfig.contentItems.template, {
5511
+ id: block.attr('data-id'),
5512
+ type: 'user'
5513
+ });
5514
+
5515
+ FLBuilderConfig.contentItems.template.splice(index, 1);
5516
+ FLBuilder.triggerHook('contentItemsChanged');
5517
  }
5518
  },
5519
 
5529
  */
5530
  _initSettingsForms: function()
5531
  {
5532
+ FLBuilder._initCodeFields();
5533
  FLBuilder._initColorPickers();
5534
  FLBuilder._initSelectFields();
5535
+ FLBuilder._initEditorFields();
5536
  FLBuilder._initMultipleFields();
5537
  FLBuilder._initAutoSuggestFields();
5538
  FLBuilder._initLinkFields();
5539
  FLBuilder._initFontFields();
5540
  FLBuilder._initOrderingFields();
5541
+ FLBuilder._initTimezoneFields();
5542
+ FLBuilder._focusFirstSettingsControl();
5543
+ FLBuilder._lightbox._resizeEditors();
5544
+
5545
+ $( '.fl-builder-settings-fields' ).css( 'visibility', 'visible' );
5546
 
5547
  /**
5548
  * Hook for settings form init.
5551
  },
5552
 
5553
  /**
5554
+ * Destroys all active settings forms.
5555
+ *
5556
+ * @since 2.0
5557
+ * @access private
5558
+ * @method _destroySettingsForms
5559
+ */
5560
+ _destroySettingsForms: function()
5561
+ {
5562
+ FLBuilder._destroyEditorFields();
5563
+ },
5564
+
5565
+ /**
5566
+ * Inserts settings forms rendered with PHP. This method is only around for
5567
+ * backwards compatibility with third party settings forms that are
5568
+ * still being rendered via AJAX. Going forward, all settings forms
5569
+ * should be rendered on the frontend using FLBuilderSettingsForms.render.
5570
  *
5571
  * @since 1.0
5572
  * @access private
5573
  * @method _setSettingsFormContent
5574
+ * @param {String} html
5575
  */
5576
+ _setSettingsFormContent: function( html )
5577
  {
5578
+ $( '.fl-legacy-settings' ).remove();
5579
+ $( 'body' ).append( html );
5580
  },
5581
 
5582
  /**
5589
  */
5590
  _settingsTabClicked: function(e)
5591
  {
5592
+ var tab = $( this ),
5593
+ form = tab.closest( '.fl-builder-settings' ),
5594
+ id = tab.attr( 'href' ).split( '#' ).pop();
5595
+
5596
+ FLBuilder._resetSettingsTabsState();
5597
+
5598
+ form.find( '.fl-builder-settings-tab' ).removeClass( 'fl-active' );
5599
+ form.find( '#' + id ).addClass( 'fl-active' );
5600
+ form.find( '.fl-builder-settings-tabs .fl-active' ).removeClass( 'fl-active' );
5601
+ form.find( 'a[href*=' + id + ']' ).addClass( 'fl-active' );
5602
+
5603
+ FLBuilder._focusFirstSettingsControl();
5604
+
5605
+ e.preventDefault();
5606
+ },
5607
+
5608
+ _resetSettingsTabsState: function() {
5609
+ var $lightbox = $('.fl-lightbox:visible');
5610
+
5611
+ FLBuilder._hideTabsOverflowMenu();
5612
+
5613
+ $lightbox.find('.fl-builder-settings-tabs .fl-active').removeClass('fl-active');
5614
+ $lightbox.find('.fl-builder-settings-tabs-overflow-menu .fl-active').removeClass('fl-active');
5615
+ $lightbox.find('.fl-contains-active').removeClass('fl-contains-active');
5616
+ },
5617
+
5618
+ /**
5619
+ * Measures tabs and adds extra items to overflow menu.
5620
+ *
5621
+ * @since 2.0
5622
+ * @access private
5623
+ * @return void
5624
+ * @method _settingsTabsToOverflowMenu
5625
+ */
5626
+ _calculateSettingsTabsOverflow: function() {
5627
+
5628
+ var $lightbox = $('.fl-lightbox:visible'),
5629
+ lightboxWidth = $lightbox.outerWidth(),
5630
+ isSlim = $lightbox.hasClass('fl-lightbox-width-slim'),
5631
+ $tabWrap = $lightbox.find('.fl-builder-settings-tabs'),
5632
+ $overflowMenu = $lightbox.find('.fl-builder-settings-tabs-overflow-menu'),
5633
+ $overflowMenuBtn = $lightbox.find('.fl-builder-settings-tabs-more'),
5634
+ $tabs = $tabWrap.find('a'),
5635
+ shouldEjectRemainingTabs = false,
5636
+ tabsAreaWidth = lightboxWidth - 60, /* 60 is size of "more" btn */
5637
+ tabsWidthTotal = 0,
5638
+ tabPadding = isSlim ? ( 8 * 2 ) : ( 15 * 2 );
5639
+
5640
+ // Reset the menu
5641
+ $overflowMenu.html('');
5642
+ FLBuilder._hideTabsOverflowMenu();
5643
+
5644
+ $tabs.removeClass('fl-overflowed');
5645
+
5646
+ // Measure each tab
5647
+ $tabs.each(function() {
5648
+
5649
+ if ( !$(this).is(":visible") ) {
5650
+ return true;
5651
+ }
5652
+
5653
+ // Calculate size until too wide for tab area.
5654
+ if ( !shouldEjectRemainingTabs ) {
5655
+
5656
+ // Width of text + padding + bumper space
5657
+ var currentTabWidth = $(this).textWidth() + tabPadding + 12;
5658
+ tabsWidthTotal += currentTabWidth;
5659
+
5660
+ if ( tabsWidthTotal >= tabsAreaWidth ) {
5661
+ shouldEjectRemainingTabs = true;
5662
+ } else {
5663
+ }
5664
+ }
5665
+
5666
+ if ( shouldEjectRemainingTabs ) {
5667
+
5668
+ var label = $(this).html(),
5669
+ handle = $(this).attr('href'),
5670
+ classAttr = "";
5671
+
5672
+ if ( $(this).hasClass('fl-active') ) {
5673
+ classAttr = 'fl-active';
5674
+ }
5675
+ if ( $(this).hasClass('error') ) {
5676
+ classAttr += ' error';
5677
+ }
5678
+ if ( classAttr !== '' ) {
5679
+ classAttr = 'class="' + classAttr + '"';
5680
+ }
5681
+
5682
+ var $item = $('<a href="' + handle + '" ' + classAttr + '>' + label + '</a>');
5683
+
5684
+ $overflowMenu.append( $item );
5685
+ $(this).addClass('fl-overflowed');
5686
+ } else {
5687
+
5688
+ $(this).removeClass('fl-overflowed');
5689
+ }
5690
+
5691
+ });
5692
+
5693
+ if ( shouldEjectRemainingTabs ) {
5694
+ $lightbox.addClass('fl-lightbox-has-tab-overflow');
5695
+ } else {
5696
+ $lightbox.removeClass('fl-lightbox-has-tab-overflow');
5697
+ }
5698
+
5699
+ if ( $overflowMenu.find('.fl-active').length > 0 ) {
5700
+ $overflowMenuBtn.addClass('fl-contains-active');
5701
+ } else {
5702
+ $overflowMenuBtn.removeClass('fl-contains-active');
5703
+ }
5704
+
5705
+ if ( $overflowMenu.find('.error').length > 0 ) {
5706
+ $overflowMenuBtn.addClass('fl-contains-errors');
5707
+ } else {
5708
+ $overflowMenuBtn.removeClass('fl-contains-errors');
5709
+ }
5710
+ },
5711
+
5712
+ /**
5713
+ * Trigger the orignal tab when a menu item is clicked.
5714
+ *
5715
+ * @since 2.0
5716
+ * @var {Event} e
5717
+ * @return void
5718
+ */
5719
+ _settingsTabsToOverflowMenuItemClicked: function(e) {
5720
+ var $item = $(e.currentTarget),
5721
+ handle = $item.attr('href'),
5722
+ $tabsWrap = $item.closest('.fl-lightbox-header-wrap').find('.fl-builder-settings-tabs'),
5723
+ $tab = $tabsWrap.find('a[href="' + handle + '"]'),
5724
+ $moreBtn = $tabsWrap.find('.fl-builder-settings-tabs-more');
5725
 
5726
+ FLBuilder._resetSettingsTabsState();
5727
+ $tab.trigger('click');
5728
+ $item.addClass('fl-active');
5729
+ $moreBtn.addClass('fl-contains-active');
5730
+ FLBuilder._hideTabsOverflowMenu();
5731
  e.preventDefault();
5732
  },
5733
 
5734
+ /**
5735
+ * Check if overflow menu contains any tabs
5736
+ *
5737
+ * @since 2.0
5738
+ * @return bool
5739
+ */
5740
+ _hasOverflowTabs: function() {
5741
+ var $lightbox = $('.fl-lightbox:visible'),
5742
+ $tabs = $lightbox.find('.fl-builder-settings-tabs-overflow-menu a');
5743
+
5744
+ if ( $tabs.length > 0 ) {
5745
+ return true;
5746
+ } else {
5747
+ return false;
5748
+ }
5749
+ },
5750
+
5751
+ /**
5752
+ * Show the overflow menu
5753
+ *
5754
+ */
5755
+ _showTabsOverflowMenu: function() {
5756
+
5757
+ if ( ! FLBuilder._hasOverflowTabs() ) return;
5758
+
5759
+ var $lightbox = $('.fl-lightbox:visible');
5760
+ $lightbox.find('.fl-builder-settings-tabs-overflow-menu').css('display', 'flex');
5761
+ $lightbox.find('.fl-builder-settings-tabs-overflow-click-mask').show();
5762
+ this.isShowingSettingsTabsOverflowMenu = true;
5763
+ },
5764
+
5765
+ /**
5766
+ * Hide the overflow menu
5767
+ */
5768
+ _hideTabsOverflowMenu: function() {
5769
+ var $lightbox = $('.fl-lightbox:visible');
5770
+ $lightbox.find('.fl-builder-settings-tabs-overflow-menu').css('display', 'none');
5771
+ $lightbox.find('.fl-builder-settings-tabs-overflow-click-mask').hide();
5772
+ this.isShowingSettingsTabsOverflowMenu = false;
5773
+ },
5774
+
5775
+ /**
5776
+ * Toggle the overflow menu
5777
+ */
5778
+ _toggleTabsOverflowMenu: function( e ) {
5779
+ if ( FLBuilder.isShowingSettingsTabsOverflowMenu ) {
5780
+ FLBuilder._hideTabsOverflowMenu();
5781
+ } else {
5782
+ FLBuilder._showTabsOverflowMenu();
5783
+ }
5784
+ e.stopPropagation();
5785
+ },
5786
+
5787
  /**
5788
  * Reverts an active preview and hides the lightbox when
5789
  * the cancel button of a settings lightbox is clicked.
5831
  FLLightbox.closeParent(this);
5832
  },
5833
 
5834
+ /**
5835
+ * Focus the first visible control in a settings panel
5836
+ *
5837
+ * @since 2.0
5838
+ */
5839
+ _focusFirstSettingsControl: function() {
5840
+ var form = $( '.fl-builder-settings:visible' ),
5841
+ tab = form.find( '.fl-builder-settings-tab.fl-active' ),
5842
+ field = tab.find('.fl-field').first(),
5843
+ input = field.find( 'input:not([type="hidden"]), textarea, select, button, a, .fl-editor-field' ).first();
5844
+
5845
+ // TinyMCE fields
5846
+ if ( 'undefined' !== typeof tinyMCE && input.hasClass('fl-editor-field') ) {
5847
+ var id = input.find('textarea.wp-editor-area').attr('id');
5848
+ tinyMCE.get( id ).focus();
5849
+
5850
+ // Everybody else
5851
+ } else {
5852
+ setTimeout(function() {
5853
+ input.focus().css('animation-name', 'fl-grab-attention');
5854
+ }, 300 );
5855
+ }
5856
+ // Grab attention
5857
+ field.css('animation-name', 'fl-grab-attention');
5858
+ field.on('animationend', function() {
5859
+ field.css('animation-name', '');
5860
+ });
5861
+ },
5862
+
5863
  /**
5864
  * Initializes validation logic for a settings form.
5865
  *
5924
  tabLink.addClass('error');
5925
  }
5926
  }
5927
+
5928
+ FLBuilder._calculateSettingsTabsOverflow();
5929
  },
5930
 
5931
  /**
5938
  * @param {Object} form The settings form element.
5939
  * @return {Object} The settings object.
5940
  */
5941
+ _getSettings: function( form )
5942
  {
5943
  FLBuilder._updateEditorFields();
5944
 
6045
  }
6046
  ).join( ',' );
6047
 
6048
+ try {
6049
+ delete settings[ 'as_values_' + key ];
6050
+ }
6051
+ catch( e ) {}
6052
+ }
6053
+ }
6054
+
6055
+ // Merge in the original settings in case legacy fields haven't rendered yet.
6056
+ settings = $.extend( {}, FLBuilder._getOriginalSettings( form ), settings );
6057
+
6058
+ // Return the settings.
6059
+ return settings;
6060
+ },
6061
+
6062
+ /**
6063
+ * Returns JSON encoded settings to be used in HTML form elements.
6064
+ *
6065
+ * @since 2.0
6066
+ * @access private
6067
+ * @method _getSettingsJSONForHTML
6068
+ * @param {Object} settings The settings object.
6069
+ * @return {String} The settings JSON.
6070
+ */
6071
+ _getSettingsJSONForHTML: function( settings )
6072
+ {
6073
+ return JSON.stringify( settings ).replace( /\'/g, '&#39;' ).replace( '<wbr \/>', '<wbr>' );
6074
+ },
6075
+
6076
+ /**
6077
+ * Returns the original sett