Unyson - Version 2.3.0

Version Description

  • Options can be used in Customizer #410
  • Fixed #77
Download this release

Release Info

Developer Unyson
Plugin Icon 128x128 Unyson
Version 2.3.0
Comparing to
See all releases

Code changes from version 2.2.10 to 2.3.0

Files changed (34) hide show
  1. framework/core/components/backend.php +209 -56
  2. framework/core/components/theme.php +15 -0
  3. framework/helpers/class-fw-flash-messages.php +4 -1
  4. framework/helpers/database.php +78 -3
  5. framework/helpers/general.php +2 -0
  6. framework/includes/customizer/class--fw-customizer-control-option-wrapper.php +59 -0
  7. framework/includes/option-types/addable-box/static/js/scripts.js +3 -0
  8. framework/includes/option-types/addable-option/static/js/scripts.js +5 -2
  9. framework/includes/option-types/addable-popup/static/js/addable-popup.js +8 -1
  10. framework/includes/option-types/class-fw-option-type-undefined.php +44 -0
  11. framework/includes/option-types/color-picker/class-fw-option-type-color-picker.php +1 -4
  12. framework/includes/option-types/color-picker/static/css/styles.css +3 -0
  13. framework/includes/option-types/color-picker/static/js/scripts.js +10 -1
  14. framework/includes/option-types/datetime-picker/static/css/style.css +1 -2
  15. framework/includes/option-types/gradient/class-fw-option-type-gradient.php +1 -1
  16. framework/includes/option-types/multi-picker/static/css/multi-picker.css +4 -0
  17. framework/includes/option-types/multi-upload/static/css/modal.css +15 -0
  18. framework/includes/option-types/multi/static/css/styles.css +4 -0
  19. framework/includes/option-types/rgba-color-picker/static/js/scripts.js +2 -0
  20. framework/includes/option-types/simple.php +4 -0
  21. framework/includes/option-types/switch/static/css/styles.css +4 -0
  22. framework/includes/option-types/typography/class-fw-option-type-typography.php +1 -1
  23. framework/includes/option-types/typography/static/css/styles.css +80 -63
  24. framework/includes/option-types/upload/static/css/modal.css +14 -0
  25. framework/includes/option-types/upload/static/js/any-files.js +2 -2
  26. framework/includes/option-types/upload/static/js/images-only.js +2 -2
  27. framework/manifest.php +1 -1
  28. framework/static/css/backend-options.css +24 -5
  29. framework/static/css/fw.css +11 -8
  30. framework/static/js/backend-customizer.js +84 -0
  31. framework/static/js/fw.js +23 -4
  32. framework/views/backend-option-design-customizer.php +126 -0
  33. readme.txt +5 -1
  34. unyson.php +1 -1
framework/core/components/backend.php CHANGED
@@ -13,7 +13,9 @@ final class _FW_Component_Backend {
13
  /** @var FW_Form */
14
  private $settings_form;
15
 
16
- private $available_render_designs = array( 'default', 'taxonomy' );
 
 
17
 
18
  /**
19
  * Store option types for registration, until they will be required
@@ -94,28 +96,20 @@ final class _FW_Component_Backend {
94
 
95
  public function __construct() {
96
  $this->print_meta_box_content_callback = create_function( '$post,$args', 'echo $args["args"];' );
97
-
98
- {
99
- $this->undefined_option_type = new FW_Option_Type_Undefined();
100
-
101
- $this->option_types[ $this->undefined_option_type->get_type() ] = $this->undefined_option_type;
102
- }
103
  }
104
 
105
  /**
106
  * @internal
107
  */
108
  public function _init() {
109
- if ( ! is_admin() ) {
110
- return;
 
 
 
 
111
  }
112
 
113
- $this->settings_form = new FW_Form( 'fw_settings', array(
114
- 'render' => array( $this, '_settings_form_render' ),
115
- 'validate' => array( $this, '_settings_form_validate' ),
116
- 'save' => array( $this, '_settings_form_save' ),
117
- ) );
118
-
119
  $this->add_actions();
120
  $this->add_filters();
121
  }
@@ -127,25 +121,31 @@ final class _FW_Component_Backend {
127
  }
128
 
129
  private function add_actions() {
130
- add_action( 'admin_menu', array( $this, '_action_admin_menu' ) );
131
- add_action( 'add_meta_boxes', array( $this, '_action_create_post_meta_boxes' ), 10, 2 );
132
- add_action( 'init', array( $this, '_action_init' ), 20 );
133
- add_action( 'admin_enqueue_scripts', array( $this, '_action_admin_enqueue_scripts' ), 8 );
 
134
 
135
- add_action( 'save_post', array( $this, '_action_save_post' ), 7, 3 );
136
- add_action( 'wp_restore_post_revision', array( $this, '_action_restore_post_revision' ), 10, 2 );
137
- add_action( '_wp_put_post_revision', array( $this, '_action__wp_put_post_revision' ) );
138
- add_action( 'wp_creating_autosave', array( $this, '_action_trigger_wp_create_autosave') );
139
-
140
- // render and submit options from javascript
141
- {
142
- add_action( 'wp_ajax_fw_backend_options_render', array( $this, '_action_ajax_options_render' ) );
143
- add_action( 'wp_ajax_fw_backend_options_get_values', array( $this, '_action_ajax_options_get_values' ) );
144
  }
 
 
 
 
 
 
 
145
  }
146
 
147
  private function add_filters() {
148
- add_filter( 'update_footer', array( $this, '_filter_footer_version' ), 11 );
 
 
149
  }
150
 
151
  /**
@@ -1165,7 +1165,11 @@ final class _FW_Component_Backend {
1165
  *
1166
  * @return string HTML
1167
  */
1168
- public function render_options( $options, $values = array(), $options_data = array(), $design = 'default' ) {
 
 
 
 
1169
  {
1170
  /**
1171
  * register scripts and styles
@@ -1180,7 +1184,6 @@ final class _FW_Component_Backend {
1180
  }
1181
 
1182
  $collected = array();
1183
-
1184
  fw_collect_first_level_options( $collected, $options );
1185
 
1186
  if ( empty( $collected['all'] ) ) {
@@ -1330,7 +1333,11 @@ final class _FW_Component_Backend {
1330
  *
1331
  * @return string
1332
  */
1333
- public function render_option( $id, $option, $data = array(), $design = 'default' ) {
 
 
 
 
1334
  /**
1335
  * register scripts and styles
1336
  * in case if this method is called before enqueue_scripts action
@@ -1566,50 +1573,196 @@ final class _FW_Component_Backend {
1566
  );
1567
  }
1568
 
 
 
 
 
 
 
1569
  return $this->undefined_option_type;
1570
  }
1571
  }
1572
- }
1573
-
1574
- /**
1575
- * This will be returned when tried to get not existing option type
1576
- * to prevent fatal errors for cases when just one option type was typed wrong
1577
- * or any other minor bug that has no sense to crash the whole site
1578
- */
1579
- final class FW_Option_Type_Undefined extends FW_Option_Type {
1580
- public function get_type() {
1581
- return '';
1582
- }
1583
 
1584
  /**
 
1585
  * @internal
1586
- * {@inheritdoc}
1587
  */
1588
- protected function _enqueue_static( $id, $option, $data ) {
 
 
 
 
 
 
 
 
1589
  }
1590
 
1591
  /**
1592
  * @internal
1593
- * {@inheritdoc}
1594
  */
1595
- protected function _render( $id, $name, $data ) {
1596
- return '/* ' . __( 'UNDEFINED OPTION TYPE', 'fw' ) . ' */';
 
 
 
 
 
 
 
 
 
 
 
 
 
1597
  }
1598
 
1599
  /**
1600
- * @internal
1601
- * {@inheritdoc}
 
1602
  */
1603
- protected function _get_value_from_input( $option, $input_value ) {
1604
- return $option['value'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1605
  }
1606
 
1607
  /**
 
 
 
 
 
1608
  * @internal
1609
  */
1610
- protected function _get_defaults() {
1611
- return array(
1612
- 'value' => array()
1613
- );
 
 
 
1614
  }
1615
  }
13
  /** @var FW_Form */
14
  private $settings_form;
15
 
16
+ private $available_render_designs = array( 'default', 'taxonomy', 'customizer' );
17
+
18
+ private $default_render_design = 'default';
19
 
20
  /**
21
  * Store option types for registration, until they will be required
96
 
97
  public function __construct() {
98
  $this->print_meta_box_content_callback = create_function( '$post,$args', 'echo $args["args"];' );
 
 
 
 
 
 
99
  }
100
 
101
  /**
102
  * @internal
103
  */
104
  public function _init() {
105
+ if ( is_admin() ) {
106
+ $this->settings_form = new FW_Form('fw_settings', array(
107
+ 'render' => array($this, '_settings_form_render'),
108
+ 'validate' => array($this, '_settings_form_validate'),
109
+ 'save' => array($this, '_settings_form_save'),
110
+ ));
111
  }
112
 
 
 
 
 
 
 
113
  $this->add_actions();
114
  $this->add_filters();
115
  }
121
  }
122
 
123
  private function add_actions() {
124
+ if ( is_admin() ) {
125
+ add_action('admin_menu', array($this, '_action_admin_menu'));
126
+ add_action('add_meta_boxes', array($this, '_action_create_post_meta_boxes'), 10, 2);
127
+ add_action('init', array($this, '_action_init'), 20);
128
+ add_action('admin_enqueue_scripts', array($this, '_action_admin_enqueue_scripts'), 8);
129
 
130
+ // render and submit options from javascript
131
+ {
132
+ add_action('wp_ajax_fw_backend_options_render', array($this, '_action_ajax_options_render'));
133
+ add_action('wp_ajax_fw_backend_options_get_values', array($this, '_action_ajax_options_get_values'));
134
+ }
 
 
 
 
135
  }
136
+
137
+ add_action('save_post', array($this, '_action_save_post'), 7, 3);
138
+ add_action('wp_restore_post_revision', array($this, '_action_restore_post_revision'), 10, 2);
139
+ add_action('_wp_put_post_revision', array($this, '_action__wp_put_post_revision'));
140
+ add_action('wp_creating_autosave', array($this, '_action_trigger_wp_create_autosave'));
141
+
142
+ add_action('customize_register', array($this, '_action_customize_register'), 7);
143
  }
144
 
145
  private function add_filters() {
146
+ if ( is_admin() ) {
147
+ add_filter('update_footer', array($this, '_filter_footer_version'), 11);
148
+ }
149
  }
150
 
151
  /**
1165
  *
1166
  * @return string HTML
1167
  */
1168
+ public function render_options( $options, $values = array(), $options_data = array(), $design = null ) {
1169
+ if (empty($design)) {
1170
+ $design = $this->default_render_design;
1171
+ }
1172
+
1173
  {
1174
  /**
1175
  * register scripts and styles
1184
  }
1185
 
1186
  $collected = array();
 
1187
  fw_collect_first_level_options( $collected, $options );
1188
 
1189
  if ( empty( $collected['all'] ) ) {
1333
  *
1334
  * @return string
1335
  */
1336
+ public function render_option( $id, $option, $data = array(), $design = null ) {
1337
+ if (empty($design)) {
1338
+ $design = $this->default_render_design;
1339
+ }
1340
+
1341
  /**
1342
  * register scripts and styles
1343
  * in case if this method is called before enqueue_scripts action
1573
  );
1574
  }
1575
 
1576
+ if (!$this->undefined_option_type) {
1577
+ require_once fw_get_framework_directory('/includes/option-types/class-fw-option-type-undefined.php');
1578
+
1579
+ $this->undefined_option_type = new FW_Option_Type_Undefined();
1580
+ }
1581
+
1582
  return $this->undefined_option_type;
1583
  }
1584
  }
 
 
 
 
 
 
 
 
 
 
 
1585
 
1586
  /**
1587
+ * @param WP_Customize_Manager $wp_customize
1588
  * @internal
 
1589
  */
1590
+ public function _action_customize_register($wp_customize) {
1591
+ if (is_admin()) {
1592
+ add_action('admin_enqueue_scripts', array($this, '_action_enqueue_customizer_static'));
1593
+ }
1594
+
1595
+ $this->customizer_register_options(
1596
+ $wp_customize,
1597
+ fw()->theme->get_customizer_options()
1598
+ );
1599
  }
1600
 
1601
  /**
1602
  * @internal
 
1603
  */
1604
+ public function _action_enqueue_customizer_static()
1605
+ {
1606
+ fw()->backend->enqueue_options_static(
1607
+ fw()->theme->get_customizer_options()
1608
+ );
1609
+
1610
+ wp_enqueue_script(
1611
+ 'fw-backend-customizer',
1612
+ fw_get_framework_directory_uri( '/static/js/backend-customizer.js' ),
1613
+ array( 'jquery', 'fw-events', 'backbone' ),
1614
+ fw()->manifest->get_version(),
1615
+ true
1616
+ );
1617
+
1618
+ do_action('fw_admin_enqueue_scripts:customizer');
1619
  }
1620
 
1621
  /**
1622
+ * @param WP_Customize_Manager $wp_customize
1623
+ * @param array $options
1624
+ * @param array $parent_data {'type':'...','id':'...'}
1625
  */
1626
+ private function customizer_register_options($wp_customize, $options, $parent_data = array()) {
1627
+ $collected = array();
1628
+ fw_collect_first_level_options( $collected, $options );
1629
+
1630
+ if (empty($collected['all'])) {
1631
+ return;
1632
+ }
1633
+
1634
+ foreach ($collected['all'] as &$opt) {
1635
+ switch ($opt['type']) {
1636
+ case 'tab':
1637
+ $args = array(
1638
+ 'title' => $opt['option']['title'],
1639
+ 'description' => empty($opt['option']['desc']) ? '' : $opt['option']['desc'],
1640
+ );
1641
+
1642
+ if ($parent_data) {
1643
+ trigger_error('Not supported panel parent, type: '. $parent_data['type'], E_USER_WARNING);
1644
+ break;
1645
+ }
1646
+
1647
+ $wp_customize->add_panel(
1648
+ $opt['id'],
1649
+ $args
1650
+ );
1651
+
1652
+ $this->customizer_register_options(
1653
+ $wp_customize,
1654
+ $opt['option']['options'],
1655
+ array(
1656
+ 'type' => 'panel',
1657
+ 'id' => $opt['id']
1658
+ )
1659
+ );
1660
+ break;
1661
+ case 'box':
1662
+ $args = array(
1663
+ 'title' => $opt['option']['title'],
1664
+ );
1665
+
1666
+ if ($parent_data) {
1667
+ if ($parent_data['type'] === 'panel') {
1668
+ $args['panel'] = $parent_data['id'];
1669
+ } else {
1670
+ trigger_error('Not supported section parent, type: '. $parent_data['type'], E_USER_WARNING);
1671
+ break;
1672
+ }
1673
+ }
1674
+
1675
+ $wp_customize->add_section($opt['id'], $args);
1676
+
1677
+ $this->customizer_register_options(
1678
+ $wp_customize,
1679
+ $opt['option']['options'],
1680
+ array(
1681
+ 'type' => 'section',
1682
+ 'id' => $opt['id']
1683
+ )
1684
+ );
1685
+ break;
1686
+ case 'option':
1687
+ $setting_id = FW_Option_Type::get_default_name_prefix() .'['. $opt['id'] .']';
1688
+
1689
+ {
1690
+ $args = array(
1691
+ 'label' => empty($opt['option']['label']) ? '' : $opt['option']['label'],
1692
+ 'description' => empty($opt['option']['desc']) ? '' : $opt['option']['desc'],
1693
+ 'settings' => $setting_id,
1694
+ 'type' => 'radio',
1695
+ 'choices' => array(
1696
+ 'a' => 'Demo A',
1697
+ 'b' => 'Demo B',
1698
+ ),
1699
+ );
1700
+
1701
+ if ($parent_data) {
1702
+ if ($parent_data['type'] === 'section') {
1703
+ $args['section'] = $parent_data['id'];
1704
+ } else {
1705
+ trigger_error('Not supported control parent, type: '. $parent_data['type'], E_USER_WARNING);
1706
+ break;
1707
+ }
1708
+ } else {
1709
+ // the option is not placed in a section, create a section automatically
1710
+ $args['section'] = 'fw_option_auto_section_'. $opt['id'];
1711
+ $wp_customize->add_section($args['section'], array(
1712
+ 'title' => empty($opt['option']['label']) ? fw_id_to_title($opt['id']) : $opt['option']['label'],
1713
+ ));
1714
+ }
1715
+ }
1716
+
1717
+ if (!class_exists('_FW_Customizer_Control_Option_Wrapper')) {
1718
+ require_once fw_get_framework_directory('/includes/customizer/class--fw-customizer-control-option-wrapper.php');
1719
+ }
1720
+
1721
+ $option_defaults = fw()->backend->option_type($opt['option']['type'])->get_defaults();
1722
+
1723
+ $wp_customize->add_setting(
1724
+ $setting_id,
1725
+ array(
1726
+ 'default' => $option_defaults['value'],
1727
+
1728
+ // added later because we can't create control first without an existing setting
1729
+ //'sanitize_callback' => array($control, 'setting_sanitize_callback'),
1730
+ )
1731
+ );
1732
+
1733
+ $control = new _FW_Customizer_Control_Option_Wrapper(
1734
+ $wp_customize,
1735
+ $opt['id'],
1736
+ $args,
1737
+ array(
1738
+ 'fw_option' => $opt['option']
1739
+ )
1740
+ );
1741
+
1742
+ add_filter( "customize_sanitize_{$setting_id}", array($control, 'setting_sanitize_callback'), 10, 2 );
1743
+
1744
+ $wp_customize->add_control($control);
1745
+ break;
1746
+ default:
1747
+ trigger_error('Not supported option in customizer, type: '. $opt['type'], E_USER_WARNING); // todo: uncomment
1748
+ }
1749
+ }
1750
  }
1751
 
1752
  /**
1753
+ * For e.g. an option-type was rendered using 'customizer' design,
1754
+ * but inside it uses render_options() but it doesn't know the current render design
1755
+ * and the options will be rendered with 'default' design.
1756
+ * This method allows to specify the default design that will be used if not specified on render_options()
1757
+ * @param null|string $design
1758
  * @internal
1759
  */
1760
+ public function _set_default_render_design($design = null)
1761
+ {
1762
+ if (empty($design) || !in_array($design, $this->available_render_designs)) {
1763
+ $this->default_render_design = 'default';
1764
+ } else {
1765
+ $this->default_render_design = $design;
1766
+ }
1767
  }
1768
  }
framework/core/components/theme.php CHANGED
@@ -90,6 +90,21 @@ final class _FW_Component_Theme
90
  }
91
  }
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  public function get_post_options($post_type)
94
  {
95
  $cache_key = self::$cache_key .'/options/posts/'. $post_type;
90
  }
91
  }
92
 
93
+ public function get_customizer_options()
94
+ {
95
+ $cache_key = self::$cache_key .'/options/customizer';
96
+
97
+ try {
98
+ return FW_Cache::get($cache_key);
99
+ } catch (FW_Cache_Not_Found_Exception $e) {
100
+ $options = apply_filters('fw_customizer_options', $this->get_options('customizer'));
101
+
102
+ FW_Cache::set($cache_key, $options);
103
+
104
+ return $options;
105
+ }
106
+ }
107
+
108
  public function get_post_options($post_type)
109
  {
110
  $cache_key = self::$cache_key .'/options/posts/'. $post_type;
framework/helpers/class-fw-flash-messages.php CHANGED
@@ -122,7 +122,10 @@ class FW_Flash_Messages
122
  foreach ($all_messages as $type => $messages) {
123
  if (!empty($messages)) {
124
  foreach ($messages as $id => $data) {
125
- $html[$type] .= '<div class="'. self::$available_types[$type] .' fw-flash-message"><p>'. $data['message'] .'</p></div>';
 
 
 
126
 
127
  unset($all_messages[$type][$id]);
128
  }
122
  foreach ($all_messages as $type => $messages) {
123
  if (!empty($messages)) {
124
  foreach ($messages as $id => $data) {
125
+ $html[$type] .=
126
+ '<div class="'. self::$available_types[$type] .' fw-flash-message">'.
127
+ '<p data-id="'. esc_attr($id) .'">'. $data['message'] .'</p>'.
128
+ '</div>';
129
 
130
  unset($all_messages[$type][$id]);
131
  }
framework/helpers/database.php CHANGED
@@ -2,10 +2,10 @@
2
  die( 'Forbidden' );
3
  }
4
 
5
- /** Framework Settings Options */
6
  {
7
  /**
8
- * Get a framework settings option value from the database
9
  *
10
  * @param string|null $option_id Specific option id (accepts multikey). null - all options
11
  * @param null|mixed $default_value If no option found in the database, this value will be returned
@@ -55,7 +55,7 @@
55
  }
56
 
57
  /**
58
- * Set a framework settings option value in database
59
  *
60
  * @param null $option_id Specific option id (accepts multikey). null - all options
61
  * @param mixed $value
@@ -378,3 +378,78 @@
378
  return fw_update_user_meta( $user_id, 'fw_data', $data );
379
  }
380
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  die( 'Forbidden' );
3
  }
4
 
5
+ /** Theme Settings Options */
6
  {
7
  /**
8
+ * Get a theme settings option value from the database
9
  *
10
  * @param string|null $option_id Specific option id (accepts multikey). null - all options
11
  * @param null|mixed $default_value If no option found in the database, this value will be returned
55
  }
56
 
57
  /**
58
+ * Set a theme settings option value in database
59
  *
60
  * @param null $option_id Specific option id (accepts multikey). null - all options
61
  * @param mixed $value
378
  return fw_update_user_meta( $user_id, 'fw_data', $data );
379
  }
380
  }
381
+
382
+ /** Customizer Framework Options */
383
+ {
384
+ /**
385
+ * Get a customizer framework option value from the database
386
+ *
387
+ * @param string|null $option_id Specific option id (accepts multikey). null - all options
388
+ * @param null|mixed $default_value If no option found in the database, this value will be returned
389
+ * // fixme: Maybe add this parameter? @ param null|bool $get_original_value Original value is that with no translations and other changes
390
+ *
391
+ * @return mixed|null
392
+ */
393
+ function fw_get_db_customizer_option( $option_id = null, $default_value = null ) {
394
+ $value = get_theme_mod(FW_Option_Type::get_default_name_prefix(), array());
395
+
396
+ if (!is_null($option_id)) {
397
+ $value = fw_akg($option_id, $value, $default_value);
398
+ }
399
+
400
+ if (
401
+ (!is_null($option_id) && is_null($value)) // a specific option_id was requested
402
+ ||
403
+ (is_null($option_id) && empty($value)) // all options were requested but the db value is empty (this can happen after Reset)
404
+ ) {
405
+ /**
406
+ * Maybe the options was never saved or the given option id does not exist
407
+ * Extract the default values from the options array and try to find there the option id
408
+ */
409
+
410
+ $cache_key = 'fw_default_options_values/customizer';
411
+
412
+ try {
413
+ $all_options_values = FW_Cache::get( $cache_key );
414
+ } catch ( FW_Cache_Not_Found_Exception $e ) {
415
+ // extract the default values from options array
416
+ $all_options_values = fw_get_options_values_from_input(
417
+ fw()->theme->get_customizer_options(),
418
+ array()
419
+ );
420
+
421
+ FW_Cache::set( $cache_key, $all_options_values );
422
+ }
423
+
424
+ if ( empty( $option_id ) ) {
425
+ // option id not specified, return all options values
426
+ return $all_options_values;
427
+ } else {
428
+ return fw_akg( $option_id, $all_options_values, $default_value );
429
+ }
430
+ } else {
431
+ return $value;
432
+ }
433
+ }
434
+
435
+ /**
436
+ * Set a theme customizer option value in database
437
+ *
438
+ * @param null $option_id Specific option id (accepts multikey). null - all options
439
+ * @param mixed $value
440
+ */
441
+ function fw_set_db_customizer_option( $option_id = null, $value ) {
442
+ $db_value = get_theme_mod(FW_Option_Type::get_default_name_prefix(), array());
443
+
444
+ if (is_null($option_id)) {
445
+ $db_value = $value;
446
+ } else {
447
+ fw_aks($option_id, $value, $db_value);
448
+ }
449
+
450
+ set_theme_mod(
451
+ FW_Option_Type::get_default_name_prefix(),
452
+ $db_value
453
+ );
454
+ }
455
+ }
framework/helpers/general.php CHANGED
@@ -198,6 +198,8 @@ function fw_print($value) {
198
  padding: 0;
199
  border: 1px solid #F5F5F5;
200
  border-radius: 3px;
 
 
201
  }
202
 
203
  div.fw_print_r pre {
198
  padding: 0;
199
  border: 1px solid #F5F5F5;
200
  border-radius: 3px;
201
+ position: relative;
202
+ z-index: 11111;
203
  }
204
 
205
  div.fw_print_r pre {
framework/includes/customizer/class--fw-customizer-control-option-wrapper.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('FW')) die('Forbidden');
2
+
3
+ class _FW_Customizer_Control_Option_Wrapper extends WP_Customize_Control {
4
+ private $fw_option = array();
5
+
6
+ public function __construct( $manager, $id, array $args, array $data ) {
7
+ parent::__construct( $manager, $id, $args);
8
+
9
+ $this->fw_option = $data['fw_option'];
10
+ }
11
+
12
+ public function render_content() {
13
+ fw()->backend->_set_default_render_design('customizer');
14
+ ?>
15
+ <div class="fw-backend-customizer-option">
16
+ <input class="fw-backend-customizer-option-input" type="hidden" <?php $this->link() ?> />
17
+ <div class="fw-backend-customizer-option-inner fw-force-xs">
18
+ <?php
19
+ echo fw()->backend->render_options(
20
+ array($this->id => $this->fw_option),
21
+ array(
22
+ $this->id => $this->value()
23
+ ),
24
+ array(),
25
+ 'customizer'
26
+ );
27
+ ?>
28
+ </div>
29
+ </div>
30
+ <?php
31
+ fw()->backend->_set_default_render_design();
32
+ }
33
+
34
+ public function setting_sanitize_callback($input) {
35
+ $input = json_decode($input, true);
36
+
37
+ if (is_null($input)) {
38
+ return null;
39
+ }
40
+
41
+ $POST = array();
42
+ foreach ($input as $var) {
43
+ fw_aks(
44
+ fw_html_attr_name_to_array_multi_key($var['name']),
45
+ $var['value'],
46
+ $POST
47
+ );
48
+ }
49
+
50
+ $value = fw_get_options_values_from_input(
51
+ array($this->id => $this->fw_option),
52
+ fw_akg(FW_Option_Type::get_default_name_prefix(), $POST)
53
+ );
54
+
55
+ $value = array_pop($value);
56
+
57
+ return $value;
58
+ }
59
+ }
framework/includes/option-types/addable-box/static/js/scripts.js CHANGED
@@ -49,6 +49,9 @@ jQuery(document).ready(function ($) {
49
 
50
  ui.placeholder.height(height);
51
  }
 
 
 
52
  }
53
  });
54
  },
49
 
50
  ui.placeholder.height(height);
51
  }
52
+ },
53
+ update: function(){
54
+ $(this).closest(optionTypeClass).trigger('change'); // for customizer
55
  }
56
  });
57
  },
framework/includes/option-types/addable-option/static/js/scripts.js CHANGED
@@ -1,4 +1,6 @@
1
  jQuery(document).ready(function ($) {
 
 
2
  function initSortable ($options) {
3
  try {
4
  $options.sortable('destroy');
@@ -25,6 +27,9 @@ jQuery(document).ready(function ($) {
25
 
26
  ui.placeholder.height(height);
27
  }
 
 
 
28
  }
29
  });
30
  }
@@ -36,8 +41,6 @@ jQuery(document).ready(function ($) {
36
  }
37
  };
38
 
39
- var optionClass = '.fw-option-type-addable-option';
40
-
41
  fwEvents.on('fw:options:init', function (data) {
42
  var $elements = data.$elements.find(optionClass +':not(.fw-option-initialized)');
43
 
1
  jQuery(document).ready(function ($) {
2
+ var optionClass = '.fw-option-type-addable-option';
3
+
4
  function initSortable ($options) {
5
  try {
6
  $options.sortable('destroy');
27
 
28
  ui.placeholder.height(height);
29
  }
30
+ },
31
+ update: function(){
32
+ $(this).closest(optionClass).trigger('change'); // for customizer
33
  }
34
  });
35
  }
41
  }
42
  };
43
 
 
 
44
  fwEvents.on('fw:options:init', function (data) {
45
  var $elements = data.$elements.find(optionClass +':not(.fw-option-initialized)');
46
 
framework/includes/option-types/addable-popup/static/js/addable-popup.js CHANGED
@@ -54,7 +54,10 @@
54
  cursor: 'move',
55
  distance: 2,
56
  tolerance: 'pointer',
57
- axis: 'y'
 
 
 
58
  });
59
  },
60
  initItemsTemplates: function () {
@@ -113,6 +116,8 @@
113
  e.preventDefault();
114
  $(this).closest('.item').remove();
115
  utils.toogleNodes();
 
 
116
  });
117
 
118
  nodes.$itemsWrapper.on('click', '.item', function (e) {
@@ -144,6 +149,8 @@
144
  } else {
145
  utils.editItem(utils.modal.get('itemRef'), values);
146
  }
 
 
147
  });
148
 
149
  utils.init();
54
  cursor: 'move',
55
  distance: 2,
56
  tolerance: 'pointer',
57
+ axis: 'y',
58
+ update: function(){
59
+ nodes.$optionWrapper.trigger('change'); // for customizer
60
+ }
61
  });
62
  },
63
  initItemsTemplates: function () {
116
  e.preventDefault();
117
  $(this).closest('.item').remove();
118
  utils.toogleNodes();
119
+
120
+ nodes.$optionWrapper.trigger('change'); // for customizer
121
  });
122
 
123
  nodes.$itemsWrapper.on('click', '.item', function (e) {
149
  } else {
150
  utils.editItem(utils.modal.get('itemRef'), values);
151
  }
152
+
153
+ nodes.$optionWrapper.trigger('change'); // for customizer
154
  });
155
 
156
  utils.init();
framework/includes/option-types/class-fw-option-type-undefined.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('FW')) die('Forbidden');
2
+
3
+ /**
4
+ * This will be returned when tried to get not existing option type
5
+ * to prevent fatal errors for cases when just one option type was typed wrong
6
+ * or any other minor bug that has no sense to crash the whole site
7
+ */
8
+ final class FW_Option_Type_Undefined extends FW_Option_Type {
9
+ public function get_type() {
10
+ return '';
11
+ }
12
+
13
+ /**
14
+ * @internal
15
+ * {@inheritdoc}
16
+ */
17
+ protected function _enqueue_static( $id, $option, $data ) {
18
+ }
19
+
20
+ /**
21
+ * @internal
22
+ * {@inheritdoc}
23
+ */
24
+ protected function _render( $id, $name, $data ) {
25
+ return '/* ' . __( 'UNDEFINED OPTION TYPE', 'fw' ) . ' */';
26
+ }
27
+
28
+ /**
29
+ * @internal
30
+ * {@inheritdoc}
31
+ */
32
+ protected function _get_value_from_input( $option, $input_value ) {
33
+ return $option['value'];
34
+ }
35
+
36
+ /**
37
+ * @internal
38
+ */
39
+ protected function _get_defaults() {
40
+ return array(
41
+ 'value' => array()
42
+ );
43
+ }
44
+ }
framework/includes/option-types/color-picker/class-fw-option-type-color-picker.php CHANGED
@@ -23,13 +23,10 @@ class FW_Option_Type_Color_Picker extends FW_Option_Type
23
  fw()->manifest->get_version()
24
  );
25
 
26
- wp_enqueue_script('wp-color-picker');
27
- wp_enqueue_script('fw-events');
28
-
29
  wp_enqueue_script(
30
  'fw-option-'. $this->get_type(),
31
  fw_get_framework_directory_uri('/includes/option-types/'. $this->get_type() .'/static/js/scripts.js'),
32
- array('jquery', 'fw-events'),
33
  fw()->manifest->get_version(),
34
  true
35
  );
23
  fw()->manifest->get_version()
24
  );
25
 
 
 
 
26
  wp_enqueue_script(
27
  'fw-option-'. $this->get_type(),
28
  fw_get_framework_directory_uri('/includes/option-types/'. $this->get_type() .'/static/js/scripts.js'),
29
+ array('jquery', 'fw-events', 'wp-color-picker'),
30
  fw()->manifest->get_version(),
31
  true
32
  );
framework/includes/option-types/color-picker/static/css/styles.css CHANGED
@@ -7,6 +7,9 @@ input.fw-option-type-color-picker {
7
  width: 100px !important;
8
  }
9
  }
 
 
 
10
 
11
  input.fw-option-type-color-picker.iris-error {
12
  background-color: #ffebe8;
7
  width: 100px !important;
8
  }
9
  }
10
+ .fw-force-xs input.fw-option-type-color-picker {
11
+ width: 100px !important;
12
+ }
13
 
14
  input.fw-option-type-color-picker.iris-error {
15
  background-color: #ffebe8;
framework/includes/option-types/color-picker/static/js/scripts.js CHANGED
@@ -27,7 +27,8 @@ jQuery(document).ready(function($){
27
 
28
  fwEvents.on('fw:options:init', function (data) {
29
  data.$elements.find('input.fw-option-type-color-picker:not(.initialized)').each(function(){
30
- var $input = $(this);
 
31
 
32
  $input.iris({
33
  hide: false,
@@ -44,6 +45,14 @@ jQuery(document).ready(function($){
44
  event : event,
45
  ui : ui
46
  });
 
 
 
 
 
 
 
 
47
  },
48
  palettes: true
49
  });
27
 
28
  fwEvents.on('fw:options:init', function (data) {
29
  data.$elements.find('input.fw-option-type-color-picker:not(.initialized)').each(function(){
30
+ var $input = $(this),
31
+ changeTimeoutId = 0;
32
 
33
  $input.iris({
34
  hide: false,
45
  event : event,
46
  ui : ui
47
  });
48
+
49
+ /**
50
+ * If we trigger the 'change' right here, that will block the picker (I don't know why)
51
+ */
52
+ clearTimeout(changeTimeoutId);
53
+ changeTimeoutId = setTimeout(function(){
54
+ $input.trigger('change');
55
+ }, 12);
56
  },
57
  palettes: true
58
  });
framework/includes/option-types/datetime-picker/static/css/style.css CHANGED
@@ -1,8 +1,7 @@
1
  .xdsoft_datetimepicker.xdsoft_noselect {
2
- z-index: 160013;
3
  }
4
 
5
-
6
  .fw-backend-option-input-type-datetime-picker .fw-option-help-in-input {
7
  top: 4px !important;
8
  }
1
  .xdsoft_datetimepicker.xdsoft_noselect {
2
+ z-index: 560100; /* bigger than fw.OptionsModal's z-index */
3
  }
4
 
 
5
  .fw-backend-option-input-type-datetime-picker .fw-option-help-in-input {
6
  top: 4px !important;
7
  }
framework/includes/option-types/gradient/class-fw-option-type-gradient.php CHANGED
@@ -33,7 +33,7 @@ class FW_Option_Type_Gradient extends FW_Option_Type
33
  wp_enqueue_script(
34
  'fw-option-' . $this->get_type(),
35
  fw_get_framework_directory_uri('/includes/option-types/' . $this->get_type() . '/static/js/scripts.js'),
36
- array('jquery'),
37
  fw()->manifest->get_version()
38
  );
39
  }
33
  wp_enqueue_script(
34
  'fw-option-' . $this->get_type(),
35
  fw_get_framework_directory_uri('/includes/option-types/' . $this->get_type() . '/static/js/scripts.js'),
36
+ array('jquery', 'fw-events'),
37
  fw()->manifest->get_version()
38
  );
39
  }
framework/includes/option-types/multi-picker/static/css/multi-picker.css CHANGED
@@ -50,6 +50,10 @@
50
  padding-bottom: 0;
51
  }
52
 
 
 
 
 
53
  /* tabs fixes */
54
 
55
  .fw-option-type-multi-picker > .choice-group .fw-options-tabs-wrapper > .fw-options-tabs-list,
50
  padding-bottom: 0;
51
  }
52
 
53
+ .fw-backend-option-type-multi-picker.fw-backend-option-design-customizer .fw-option-type-multi-picker > .picker-group {
54
+ padding-bottom: 10px;
55
+ }
56
+
57
  /* tabs fixes */
58
 
59
  .fw-option-type-multi-picker > .choice-group .fw-options-tabs-wrapper > .fw-options-tabs-list,
framework/includes/option-types/multi-upload/static/css/modal.css CHANGED
@@ -1,9 +1,24 @@
 
 
1
  .fw-option-type-multi-upload .media-modal {
2
  z-index: 170001;
3
  }
 
4
  .fw-option-type-multi-upload .media-modal-backdrop {
5
  z-index: 170000;
6
  }
 
 
 
 
 
 
 
 
 
 
 
 
7
  .fw-option-type-multi-upload .delete-attachment {
8
  display: none;
9
  }
1
+ /* bigger z-index: make sure it's bigger than fw.OptionsModal's z-index (but do not increase this too much to not affect others) */
2
+
3
  .fw-option-type-multi-upload .media-modal {
4
  z-index: 170001;
5
  }
6
+
7
  .fw-option-type-multi-upload .media-modal-backdrop {
8
  z-index: 170000;
9
  }
10
+
11
+ .wp-customizer .fw-option-type-multi-upload .media-modal {
12
+ z-index: 560101;
13
+ }
14
+
15
+ .wp-customizer .fw-option-type-multi-upload .media-modal-backdrop {
16
+ z-index: 560100;
17
+ }
18
+
19
+ /* end: bigger z-index */
20
+
21
+
22
  .fw-option-type-multi-upload .delete-attachment {
23
  display: none;
24
  }
framework/includes/option-types/multi/static/css/styles.css CHANGED
@@ -20,4 +20,8 @@
20
 
21
  .fw-option-type-multi:not(.fw-option-type-multi-show-borders) > .fw-backend-option:not(:last-child) {
22
  padding-bottom: 0;
 
 
 
 
23
  }
20
 
21
  .fw-option-type-multi:not(.fw-option-type-multi-show-borders) > .fw-backend-option:not(:last-child) {
22
  padding-bottom: 0;
23
+ }
24
+
25
+ .fw-backend-option-type-multi.fw-backend-option-design-customizer .fw-option-type-multi > .fw-backend-option {
26
+ padding: 5px 0 10px;
27
  }
framework/includes/option-types/rgba-color-picker/static/js/scripts.js CHANGED
@@ -55,6 +55,7 @@
55
  iris: $input.data('a8cIris'),
56
  alphaSlider: $alpha_slider.data('uiSlider')
57
  });
 
58
  }
59
  });
60
 
@@ -118,6 +119,7 @@
118
  iris: $input.data('a8cIris'),
119
  alphaSlider: $alpha_slider.data('uiSlider')
120
  });
 
121
  }
122
  });
123
 
55
  iris: $input.data('a8cIris'),
56
  alphaSlider: $alpha_slider.data('uiSlider')
57
  });
58
+ $input.trigger('change');
59
  }
60
  });
61
 
119
  iris: $input.data('a8cIris'),
120
  alphaSlider: $alpha_slider.data('uiSlider')
121
  });
122
+ $input.trigger('change');
123
  }
124
  });
125
 
framework/includes/option-types/simple.php CHANGED
@@ -633,6 +633,10 @@ class FW_Option_Type_Select extends FW_Option_Type
633
  */
634
  protected function _get_value_from_input($option, $input_value)
635
  {
 
 
 
 
636
  if (empty($option['no-validate'])) {
637
  $all_choices = $this->get_choices($option['choices']);
638
 
633
  */
634
  protected function _get_value_from_input($option, $input_value)
635
  {
636
+ if (is_null($input_value)) {
637
+ return $option['value'];
638
+ }
639
+
640
  if (empty($option['no-validate'])) {
641
  $all_choices = $this->get_choices($option['choices']);
642
 
framework/includes/option-types/switch/static/css/styles.css CHANGED
@@ -20,3 +20,7 @@
20
  body.rtl .adaptive-switch {
21
  direction: ltr;
22
  }
 
 
 
 
20
  body.rtl .adaptive-switch {
21
  direction: ltr;
22
  }
23
+
24
+ .fw-backend-option-design-customizer.fw-backend-option-type-switch .adaptive-switch .switch-switcher label.switch-label {
25
+ line-height: inherit;
26
+ }
framework/includes/option-types/typography/class-fw-option-type-typography.php CHANGED
@@ -136,7 +136,7 @@ class FW_Option_Type_Typography extends FW_Option_Type
136
 
137
  public function _get_backend_width_type()
138
  {
139
- return 'auto';
140
  }
141
  }
142
 
136
 
137
  public function _get_backend_width_type()
138
  {
139
+ return 'fixed';
140
  }
141
  }
142
 
framework/includes/option-types/typography/static/css/styles.css CHANGED
@@ -2,12 +2,26 @@
2
  top: 4px !important;
3
  }
4
 
5
- .fw-backend-option-input-type-typography {
6
- max-width: 428px;
 
 
 
 
 
7
  }
8
 
9
- .fw-backend-option-input-type-typography .fw-inner {
10
- width: 100%;
 
 
 
 
 
 
 
 
 
11
  }
12
 
13
  @media (max-width: 782px) {
@@ -17,46 +31,36 @@
17
 
18
  .fw-option-type-typography .fw-option-typography-option {
19
  padding-top: 5px;
 
 
 
 
20
  }
21
 
22
  .fw-option-type-typography .fw-option-typography-option:first-child {
23
  padding-top: 0;
24
  }
25
- }
26
-
27
- @media (min-width: 783px) {
28
- .fw-backend-option-input-type-typography {
29
- width: auto;
30
- }
31
-
32
- .fw-option-type-typography .fw-option-typography-option {
33
- padding-right: 5px;
34
- width: 167px;
35
- }
36
 
37
  .fw-option-type-typography .fw-option-typography-option.fw-option-typography-option-size {
38
- padding-right: 5px;
39
- width: 67px;
40
- }
41
-
42
- body.rtl .fw-option-type-typography .fw-option-typography-option {
43
- padding-right: 0;
44
- padding-left: 5px;
45
- }
46
-
47
- .fw-option-type-typography .fw-option-typography-option:last-child,
48
- .fw-force-xs .fw-option-type-typography .fw-option-typography-option {
49
- padding-right: 0;
50
- }
51
- body.rtl .fw-option-type-typography .fw-option-typography-option:last-child,
52
- body.rtl .fw-force-xs .fw-option-type-typography .fw-option-typography-option {
53
- padding-left: 0;
54
- }
55
-
56
- .fw-force-xs .fw-option-type-typography .fw-option-typography-option {
57
- padding-top: 5px;
58
  }
59
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
  .fw-option-type-typography .fw-option-typography-option input,
62
  .fw-option-type-typography .fw-option-typography-option select {
@@ -111,6 +115,14 @@ body.rtl .fw-option-type-typography .fw-option-typography-option-family .selecti
111
  margin-right: 0;
112
  }
113
  }
 
 
 
 
 
 
 
 
114
 
115
  .fw-option-type-typography .fw-option-typography-option-family-input:focus,
116
  .fw-option-type-typography .fw-option-typography-option-family-input.single .selectize-input.focus {
@@ -185,23 +197,28 @@ body.rtl .fw-option-type-typography .fw-option-typography-option-family .selecti
185
 
186
  @media (max-width: 782px) {
187
  .fw-option-type-typography .selectize-dropdown.fw-option-typography-option-family-input {
188
- width: 100%!important;
189
- }
190
-
191
- .fw-option-type-typography .selectize-dropdown .selectize-dropdown-content div div.preview {
192
- width: 165px;
193
  }
194
 
195
  .fw-option-type-typography .selectize-control.single .selectize-input {
196
- height: 36px;
197
  font-size: 16px;
198
- line-height: 34px;
 
199
  }
200
 
201
  #edittag .fw-option-type-typography .selectize-control.single .selectize-input {
202
  padding: 0 14px;
203
  }
204
  }
 
 
 
 
 
 
 
 
 
205
 
206
  .fw-option-type-typography div.selectize-input.items.full.has-options.has-items {
207
  background: none;
@@ -215,20 +232,12 @@ body.rtl .fw-option-type-typography .fw-option-typography-option-family .selecti
215
  border: none;
216
  top: 33px !important;
217
  }
218
-
219
  @media (max-width: 782px) {
220
  .fw-option-type-typography .selectize-control .selectize-dropdown {
221
- top: 41px !important;
222
  }
223
  }
224
 
225
-
226
- .fw-force-xs .fw-option-type-typography .fw-option-typography-option-style,
227
- .fw-force-xs .fw-option-type-typography .fw-option-typography-option-color,
228
- .fw-force-xs .fw-option-type-typography .fw-option-typography-option-color .fw-option-type-color-picker {
229
- width: 100% !important;
230
- }
231
-
232
  @media (max-width: 782px) {
233
  .fw-option-type-typography .fw-option-typography-option-style,
234
  .fw-option-type-typography .fw-option-typography-option-color,
@@ -236,7 +245,11 @@ body.rtl .fw-option-type-typography .fw-option-typography-option-family .selecti
236
  width: 100% !important;
237
  }
238
  }
239
-
 
 
 
 
240
 
241
  /*
242
  Fix: for color picker width too small or too big
@@ -248,21 +261,25 @@ color: fw-col-sm-2 = 16.66666667%
248
  25% + 16.66666667% = 41.66666667%
249
  */
250
 
251
- @media (min-width: 783px) {
252
- .fw-option-type-typography .fw-option-typography-option-color {
253
- width: 70px; /* should be same width as option type color-picker */
254
- }
255
 
256
- .fw-option-type-typography .fw-option-typography-option-style {
257
- width: 98px;
258
- }
 
 
 
 
259
 
 
260
  .fw-option-type-typography .fw-option-typography-option-size {
261
- width: 67px;
262
  }
263
- /* .fw-backend-option-input-type-typography{
264
- width: 428px;
265
- }*/
266
  }
267
 
268
 
2
  top: 4px !important;
3
  }
4
 
5
+ .fw-option-type-typography .fw-option-typography-option {
6
+ padding-right: 5px;
7
+ width: 167px;
8
+ }
9
+ body.rtl .fw-option-type-typography .fw-option-typography-option {
10
+ padding-right: 0;
11
+ padding-left: 5px;
12
  }
13
 
14
+ .fw-option-type-typography .fw-option-typography-option.fw-option-typography-option-size {
15
+ width: 67px;
16
+ }
17
+
18
+ .fw-option-type-typography .fw-option-typography-option:last-child,
19
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option {
20
+ padding-right: 0;
21
+ }
22
+ body.rtl .fw-option-type-typography .fw-option-typography-option:last-child,
23
+ body.rtl .fw-force-xs .fw-option-type-typography .fw-option-typography-option {
24
+ padding-left: 0;
25
  }
26
 
27
  @media (max-width: 782px) {
31
 
32
  .fw-option-type-typography .fw-option-typography-option {
33
  padding-top: 5px;
34
+ padding-right: 0;
35
+ }
36
+ body.rtl .fw-option-type-typography .fw-option-typography-option {
37
+ padding-left: 0;
38
  }
39
 
40
  .fw-option-type-typography .fw-option-typography-option:first-child {
41
  padding-top: 0;
42
  }
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  .fw-option-type-typography .fw-option-typography-option.fw-option-typography-option-size {
45
+ width: 100%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
  }
48
+ .fw-force-xs .fw-backend-option-input-type-typography {
49
+ width: 100%;
50
+ }
51
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option {
52
+ padding-top: 5px;
53
+ padding-right: 0;
54
+ }
55
+ body.rtl .fw-force-xs .fw-option-type-typography .fw-option-typography-option {
56
+ padding-left: 0;
57
+ }
58
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option:first-child {
59
+ padding-top: 0;
60
+ }
61
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option.fw-option-typography-option-size {
62
+ width: 100%;
63
+ }
64
 
65
  .fw-option-type-typography .fw-option-typography-option input,
66
  .fw-option-type-typography .fw-option-typography-option select {
115
  margin-right: 0;
116
  }
117
  }
118
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option-family .selectize-control.single .selectize-input:after {
119
+ right: 6px;
120
+ }
121
+ .fw-force-xs .fw-option-typography-option.fw-option-typography-option-family,
122
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option-family-input {
123
+ width: 100%;
124
+ margin-right: 0;
125
+ }
126
 
127
  .fw-option-type-typography .fw-option-typography-option-family-input:focus,
128
  .fw-option-type-typography .fw-option-typography-option-family-input.single .selectize-input.focus {
197
 
198
  @media (max-width: 782px) {
199
  .fw-option-type-typography .selectize-dropdown.fw-option-typography-option-family-input {
200
+ width: 100% !important;
 
 
 
 
201
  }
202
 
203
  .fw-option-type-typography .selectize-control.single .selectize-input {
 
204
  font-size: 16px;
205
+ height: 36px;
206
+ line-height: 36px;
207
  }
208
 
209
  #edittag .fw-option-type-typography .selectize-control.single .selectize-input {
210
  padding: 0 14px;
211
  }
212
  }
213
+ .fw-force-xs .fw-option-type-typography .selectize-dropdown.fw-option-typography-option-family-input {
214
+ width: 100%!important;
215
+ }
216
+ .fw-force-xs .fw-option-type-typography .selectize-control.single .selectize-input {
217
+ font-size: 16px;
218
+ }
219
+ #edittag .fw-force-xs .fw-option-type-typography .selectize-control.single .selectize-input {
220
+ padding: 0 14px;
221
+ }
222
 
223
  .fw-option-type-typography div.selectize-input.items.full.has-options.has-items {
224
  background: none;
232
  border: none;
233
  top: 33px !important;
234
  }
 
235
  @media (max-width: 782px) {
236
  .fw-option-type-typography .selectize-control .selectize-dropdown {
237
+ top: 42px !important;
238
  }
239
  }
240
 
 
 
 
 
 
 
 
241
  @media (max-width: 782px) {
242
  .fw-option-type-typography .fw-option-typography-option-style,
243
  .fw-option-type-typography .fw-option-typography-option-color,
245
  width: 100% !important;
246
  }
247
  }
248
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option-style,
249
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option-color,
250
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option-color .fw-option-type-color-picker {
251
+ width: 100% !important;
252
+ }
253
 
254
  /*
255
  Fix: for color picker width too small or too big
261
  25% + 16.66666667% = 41.66666667%
262
  */
263
 
264
+ .fw-option-type-typography .fw-option-typography-option-color {
265
+ width: 70px; /* should be same width as option type color-picker */
266
+ }
 
267
 
268
+ .fw-option-type-typography .fw-option-typography-option-style {
269
+ width: 98px;
270
+ }
271
+
272
+ .fw-option-type-typography .fw-option-typography-option-size {
273
+ width: 67px;
274
+ }
275
 
276
+ @media (max-width: 782px) {
277
  .fw-option-type-typography .fw-option-typography-option-size {
278
+ width: 100%;
279
  }
280
+ }
281
+ .fw-force-xs .fw-option-type-typography .fw-option-typography-option-size {
282
+ width: 100%;
283
  }
284
 
285
 
framework/includes/option-types/upload/static/css/modal.css CHANGED
@@ -1,9 +1,23 @@
 
 
1
  .fw-option-type-upload .media-modal {
2
  z-index: 170001;
3
  }
 
4
  .fw-option-type-upload .media-modal-backdrop {
5
  z-index: 170000;
6
  }
 
 
 
 
 
 
 
 
 
 
 
7
  .fw-option-type-upload .delete-attachment {
8
  display: none;
9
  }
1
+ /* bigger z-index: make sure it's bigger than fw.OptionsModal's z-index (but do not increase this too much to not affect others) */
2
+
3
  .fw-option-type-upload .media-modal {
4
  z-index: 170001;
5
  }
6
+
7
  .fw-option-type-upload .media-modal-backdrop {
8
  z-index: 170000;
9
  }
10
+
11
+ .wp-customizer .fw-option-type-upload .media-modal {
12
+ z-index: 560101;
13
+ }
14
+
15
+ .wp-customizer .fw-option-type-upload .media-modal-backdrop {
16
+ z-index: 560100;
17
+ }
18
+
19
+ /* end: bigger z-index */
20
+
21
  .fw-option-type-upload .delete-attachment {
22
  display: none;
23
  }
framework/includes/option-types/upload/static/js/any-files.js CHANGED
@@ -36,9 +36,9 @@
36
  frame.on('select', function() {
37
  var attachment = frame.state().get('selection').first();
38
 
39
- elements.$input.val(attachment.id);
40
  elements.$textField.text(attachment.get('filename'));
41
  elements.$uploadButton.text(l10n.buttonEdit);
 
42
  elements.$container.removeClass('empty');
43
 
44
  fwe.trigger('fw:option-type:upload:change', {
@@ -61,9 +61,9 @@
61
  });
62
 
63
  elements.$deleteButton.on('click', function(e) {
64
- elements.$input.val('');
65
  elements.$textField.text('');
66
  elements.$uploadButton.text(l10n.buttonAdd);
 
67
  elements.$container.addClass('empty');
68
 
69
  fwe.trigger('fw:option-type:upload:clear', {$element: elements.$container});
36
  frame.on('select', function() {
37
  var attachment = frame.state().get('selection').first();
38
 
 
39
  elements.$textField.text(attachment.get('filename'));
40
  elements.$uploadButton.text(l10n.buttonEdit);
41
+ elements.$input.val(attachment.id).trigger('change');
42
  elements.$container.removeClass('empty');
43
 
44
  fwe.trigger('fw:option-type:upload:change', {
61
  });
62
 
63
  elements.$deleteButton.on('click', function(e) {
 
64
  elements.$textField.text('');
65
  elements.$uploadButton.text(l10n.buttonAdd);
66
+ elements.$input.val('').trigger('change');
67
  elements.$container.addClass('empty');
68
 
69
  fwe.trigger('fw:option-type:upload:clear', {$element: elements.$container});
framework/includes/option-types/upload/static/js/images-only.js CHANGED
@@ -60,7 +60,6 @@
60
  {variable: 'data'}
61
  );
62
 
63
- elements.$input.val(attachment.id);
64
  elements.$uploadButton.text(l10n.buttonEdit);
65
  elements.$thumb
66
  .html(compiled)
@@ -68,6 +67,7 @@
68
  'data-attid': attachment.id,
69
  'data-origsrc': attachment.get('url')
70
  });
 
71
  elements.$container.removeClass('empty');
72
 
73
  fwe.trigger('fw:option-type:upload:change', {
@@ -94,11 +94,11 @@
94
  });
95
 
96
  elements.$thumb.on('click', '.clear-uploads-thumb', function(e) {
97
- elements.$input.val('');
98
  elements.$uploadButton.text(l10n.buttonAdd);
99
  elements.$thumb
100
  .html(templates.thumb.empty)
101
  .removeAttr('data-attid data-origsrc');
 
102
  elements.$container.addClass('empty');
103
 
104
  fwe.trigger('fw:option-type:upload:clear', {$element: elements.$container});
60
  {variable: 'data'}
61
  );
62
 
 
63
  elements.$uploadButton.text(l10n.buttonEdit);
64
  elements.$thumb
65
  .html(compiled)
67
  'data-attid': attachment.id,
68
  'data-origsrc': attachment.get('url')
69
  });
70
+ elements.$input.val(attachment.id).trigger('change');
71
  elements.$container.removeClass('empty');
72
 
73
  fwe.trigger('fw:option-type:upload:change', {
94
  });
95
 
96
  elements.$thumb.on('click', '.clear-uploads-thumb', function(e) {
 
97
  elements.$uploadButton.text(l10n.buttonAdd);
98
  elements.$thumb
99
  .html(templates.thumb.empty)
100
  .removeAttr('data-attid data-origsrc');
101
+ elements.$input.val('').trigger('change');
102
  elements.$container.addClass('empty');
103
 
104
  fwe.trigger('fw:option-type:upload:clear', {$element: elements.$container});
framework/manifest.php CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
- $manifest['version'] = '2.2.10';
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
+ $manifest['version'] = '2.3.0';
framework/static/css/backend-options.css CHANGED
@@ -751,6 +751,7 @@ body.rtl .fw-postbox > .inside > .fw-backend-options-last-border-hider {
751
  }
752
 
753
  .fw-backend-option-design-default > .fw-backend-option-input > .fw-inner,
 
754
  .fw-backend-option-design-taxonomy > td > .fw-backend-option-input > .fw-inner {
755
  position: relative;
756
  max-width: 100%;
@@ -761,18 +762,15 @@ body.rtl .fw-postbox > .inside > .fw-backend-options-last-border-hider {
761
  }
762
 
763
  .fw-backend-option-design-default > .fw-backend-option-input.width-type-fixed > .fw-inner,
 
764
  .fw-backend-option-design-taxonomy > td > .fw-backend-option-input.width-type-fixed > .fw-inner,
765
  .fw-backend-option-fixed-width {
766
  width: 100%;
767
  max-width: 428px;
768
  }
769
 
770
- .fw-backend-option-design-default > .fw-backend-option-input.width-type-fixed > .fw-inner,
771
- .fw-backend-option-design-taxonomy > td > .fw-backend-option-input.width-type-fixed > .fw-inner {
772
-
773
- }
774
-
775
  .fw-backend-option-design-default > .fw-backend-option-input.width-type-full > .fw-inner,
 
776
  .fw-backend-option-design-taxonomy > td > .fw-backend-option-input.width-type-full > .fw-inner {
777
  width: 100%;
778
  }
@@ -803,6 +801,27 @@ body.rtl .fw-backend-option-design-default > .fw-backend-option-desc > .fw-inner
803
  }
804
 
805
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
806
  /* Options Groups */
807
 
808
  .fw-backend-options-group {
751
  }
752
 
753
  .fw-backend-option-design-default > .fw-backend-option-input > .fw-inner,
754
+ .fw-backend-option-design-customizer > .fw-backend-option-input > .fw-inner,
755
  .fw-backend-option-design-taxonomy > td > .fw-backend-option-input > .fw-inner {
756
  position: relative;
757
  max-width: 100%;
762
  }
763
 
764
  .fw-backend-option-design-default > .fw-backend-option-input.width-type-fixed > .fw-inner,
765
+ .fw-backend-option-design-customizer > .fw-backend-option-input.width-type-fixed > .fw-inner,
766
  .fw-backend-option-design-taxonomy > td > .fw-backend-option-input.width-type-fixed > .fw-inner,
767
  .fw-backend-option-fixed-width {
768
  width: 100%;
769
  max-width: 428px;
770
  }
771
 
 
 
 
 
 
772
  .fw-backend-option-design-default > .fw-backend-option-input.width-type-full > .fw-inner,
773
+ .fw-backend-option-design-customizer > .fw-backend-option-input.width-type-full > .fw-inner,
774
  .fw-backend-option-design-taxonomy > td > .fw-backend-option-input.width-type-full > .fw-inner {
775
  width: 100%;
776
  }
801
  }
802
 
803
 
804
+ .fw-backend-option-design-customizer > .fw-backend-option-desc {
805
+ padding-bottom: 6px;
806
+ }
807
+
808
+ .fw-backend-option-design-customizer label,
809
+ .fw-backend-option-design-customizer label .customize-control-title {
810
+ line-height: inherit;
811
+ }
812
+
813
+ .fw-backend-option-design-customizer > .fw-backend-option-label {
814
+ padding-bottom: 5px;
815
+ }
816
+
817
+ .fw-backend-option-design-customizer > .fw-backend-option-label .fw-option-help {
818
+ display: inline-block;
819
+ vertical-align: middle;
820
+ }
821
+ .fw-backend-option-design-customizer > .fw-backend-option-label .customize-control-title {
822
+ display: inline-block;
823
+ }
824
+
825
  /* Options Groups */
826
 
827
  .fw-backend-options-group {
framework/static/css/fw.css CHANGED
@@ -2775,20 +2775,23 @@ a.fw-wp-link:hover {
2775
  /* end: Animations */
2776
 
2777
 
2778
- /* WP Modal */
2779
 
2780
- .media-modal {
2781
- z-index: 170001;
2782
  }
2783
 
2784
- .media-modal-backdrop {
2785
- z-index: 170000;
2786
  }
2787
 
2788
- /* end: WP Modal */
2789
-
 
2790
 
2791
- /* modal */
 
 
2792
 
2793
  .fw-modal .media-modal-close:focus {
2794
  -webkit-box-shadow: none;
2775
  /* end: Animations */
2776
 
2777
 
2778
+ /* modal */
2779
 
2780
+ body > div:not(.fw-modal) > .media-modal {
2781
+ z-index: 161001;
2782
  }
2783
 
2784
+ body > div:not(.fw-modal) > .media-modal-backdrop {
2785
+ z-index: 161000;
2786
  }
2787
 
2788
+ body.wp-customizer > div:not(.fw-modal) > .media-modal {
2789
+ z-index: 561001; /* bigger than .wp-customizer .media-modal */
2790
+ }
2791
 
2792
+ body.wp-customizer > div:not(.fw-modal) > .media-modal-backdrop {
2793
+ z-index: 561000;
2794
+ }
2795
 
2796
  .fw-modal .media-modal-close:focus {
2797
  -webkit-box-shadow: none;
framework/static/js/backend-customizer.js ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function($){
2
+ var initialized = false,
3
+ changeTimeoutId = 0,
4
+ /**
5
+ * @type {Object} {'#options_wrapper_id':'~'}
6
+ */
7
+ pendingChanges = {},
8
+ /**
9
+ * Extract all input values within option and save them to the customizer input (to trigger preview update)
10
+ */
11
+ processPendingChanges = function(){
12
+ $.each(pendingChanges, function(optionsWrapperId){
13
+ var $optionsWrapper = $('#'+ optionsWrapperId),
14
+ $input = $optionsWrapper.closest('.fw-backend-customizer-option').find('> input.fw-backend-customizer-option-input'),
15
+ newValue = JSON.stringify($optionsWrapper.find(':input').serializeArray());
16
+
17
+ if ($input.val() === newValue) {
18
+ return;
19
+ }
20
+
21
+ $input.val(newValue).trigger('change');
22
+ });
23
+
24
+ pendingChanges = {};
25
+ },
26
+ randomIdIncrement = 0,
27
+ init = function(){
28
+ if (initialized) {
29
+ return;
30
+ }
31
+
32
+ /**
33
+ * Populate all <input class="fw-backend-customizer-option-input" ... /> with (initial) options values
34
+ */
35
+ $('#customize-theme-controls .fw-backend-customizer-option').each(function(){
36
+ $(this).find('> input.fw-backend-customizer-option-input').val(
37
+ JSON.stringify(
38
+ $(this).find('> .fw-backend-customizer-option-inner :input').serializeArray()
39
+ )
40
+ );
41
+ });
42
+
43
+ /**
44
+ * When something may be changed, removed, added; add to pending changes
45
+ */
46
+ $('#customize-theme-controls').on(
47
+ 'change keyup click paste',
48
+ '.fw-backend-customizer-option > .fw-backend-customizer-option-inner > .fw-backend-option > .fw-backend-option-input',
49
+ function(e){
50
+ clearTimeout(changeTimeoutId);
51
+
52
+ {
53
+ var optionsWrapperId = $(this).attr('id');
54
+
55
+ if (!optionsWrapperId) {
56
+ optionsWrapperId = 'rnid-'+ (++randomIdIncrement);
57
+ $(this).attr('id', optionsWrapperId);
58
+ }
59
+
60
+ pendingChanges[optionsWrapperId] = '~';
61
+ }
62
+
63
+ changeTimeoutId = setTimeout(
64
+ processPendingChanges,
65
+ /**
66
+ * Let css animations finish,
67
+ * to prevent block/glitch in the middle of the animation when the iframe will reload.
68
+ * Bigger than 300, which most of the css animations are.
69
+ */
70
+ 333
71
+ );
72
+ }
73
+ );
74
+
75
+ initialized = true;
76
+ };
77
+
78
+ fwEvents.one('fw:options:init', function(){
79
+ setTimeout(
80
+ init,
81
+ 40 // must be later than first 'fw:options:init' on body http://bit.ly/1F1dDUZ
82
+ );
83
+ });
84
+ });
framework/static/js/fw.js CHANGED
@@ -658,11 +658,30 @@ fw.getQueryString = function(name) {
658
  }
659
 
660
  /**
661
- * adjust the z-index for the new frame's backdrop and modal
662
- * (160000 is what wp sets for its modals)
663
  */
664
- $backdrop.css('z-index', 160000 + (stackSize * 2 + 1));
665
- $modal.css('z-index', 160000 + (stackSize * 2 + 2));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
666
 
667
  // show effect on close
668
  (function(){
658
  }
659
 
660
  /**
661
+ * Adjust the z-index for the new frame's backdrop and modal
 
662
  */
663
+ {
664
+ $backdrop.css('z-index',
665
+ /**
666
+ * Use modal z-index because backdrop z-index in some cases can be too smaller
667
+ * and when there are 2+ modals open, first modal will cover the second backdrop
668
+ *
669
+ * For e.g.
670
+ *
671
+ * - second modal | z-index: 560003
672
+ * - second backdrop | z-index: 559902
673
+ *
674
+ * - first modal | z-index: 560002 (This will cover the above backdrop)
675
+ * - first backdrop | z-index: 559901
676
+ */
677
+ parseInt($modal.css('z-index'))
678
+ + stackSize * 2 + 1
679
+ );
680
+ $modal.css('z-index',
681
+ parseInt($modal.css('z-index'))
682
+ + stackSize * 2 + 2
683
+ );
684
+ }
685
 
686
  // show effect on close
687
  (function(){
framework/views/backend-option-design-customizer.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('FW')) die('Forbidden');
2
+ /**
3
+ * @var string $id
4
+ * @var array $option
5
+ * @var array $data
6
+ */
7
+
8
+ {
9
+ if (!isset($option['label'])) {
10
+ $option['label'] = fw_id_to_title($id);
11
+ }
12
+
13
+ if (!isset($option['desc'])) {
14
+ $option['desc'] = '';
15
+ }
16
+ }
17
+
18
+ {
19
+ $help = false;
20
+
21
+ if (!empty($option['help'])) {
22
+ $help = array(
23
+ 'icon' => 'info',
24
+ 'html' => '{undefined}',
25
+ );
26
+
27
+ if (is_array($option['help'])) {
28
+ $help = array_merge($help, $option['help']);
29
+ } else {
30
+ $help['html'] = $option['help'];
31
+ }
32
+
33
+ switch ($help['icon']) {
34
+ case 'info':
35
+ $help['class'] = 'dashicons dashicons-info';
36
+ break;
37
+ case 'video':
38
+ $help['class'] = 'dashicons dashicons-video-alt3';
39
+ break;
40
+ default:
41
+ $help['class'] = 'dashicons dashicons-smiley';
42
+ }
43
+ }
44
+ }
45
+
46
+ {
47
+ $classes = array(
48
+ 'option' => array(
49
+ 'fw-backend-option',
50
+ 'fw-backend-option-design-customizer',
51
+ 'fw-backend-option-type-'. $option['type'],
52
+ 'fw-row'
53
+ ),
54
+ 'label' => array(
55
+ 'fw-backend-option-label',
56
+ 'responsive' => 'fw-col-xs-12',
57
+ ),
58
+ 'input' => array(
59
+ 'fw-backend-option-input',
60
+ 'fw-backend-option-input-type-'. $option['type'],
61
+ 'responsive' => 'fw-col-xs-12',
62
+ ),
63
+ 'desc' => array(
64
+ 'fw-backend-option-desc',
65
+ 'responsive' => 'fw-col-xs-12',
66
+ ),
67
+ );
68
+
69
+ /** Additional classes for option div */
70
+ {
71
+ if ($help) {
72
+ $classes['option'][] = 'with-help';
73
+ }
74
+
75
+ if ($option['label'] === false) {
76
+ $classes['label']['hidden'] = 'fw-hidden';
77
+ unset($classes['label']['responsive']);
78
+
79
+ $classes['input']['responsive'] = 'fw-col-xs-12';
80
+ $classes['desc']['responsive'] = 'fw-col-xs-12';
81
+ }
82
+ }
83
+
84
+ /** Additional classes for input div */
85
+ {
86
+ $width_type = fw()->backend->option_type($option['type'])->_get_backend_width_type();
87
+
88
+ if (!in_array($width_type, array('auto', 'fixed', 'full'))) {
89
+ $width_type = 'auto';
90
+ }
91
+
92
+ $classes['input']['width-type'] = 'width-type-'. $width_type;
93
+ }
94
+
95
+ foreach ($classes as $key => $_classes) {
96
+ $classes[$key] = implode(' ', $_classes);
97
+ }
98
+ unset($key, $_classes);
99
+ }
100
+ ?>
101
+ <div class="<?php echo esc_attr($classes['option']) ?>" id="fw-backend-option-<?php echo esc_attr($data['id_prefix'] . $id) ?>">
102
+ <?php if ($option['label'] !== false): ?>
103
+ <div class="<?php echo esc_attr($classes['label']) ?>">
104
+ <div class="fw-inner">
105
+ <label for="<?php echo $data['id_prefix'] . esc_attr($id) ?>"><span class="customize-control-title"><?php echo fw_htmlspecialchars($option['label']) ?></span></label>
106
+ <?php if ($help): ?><div class="fw-option-help fw-option-help-in-label <?php echo esc_attr($help['class']) ?>" title="<?php echo esc_attr($help['html']) ?>"></div><?php endif; ?>
107
+ <div class="fw-clear"></div>
108
+ </div>
109
+ </div>
110
+ <?php endif; ?>
111
+ <?php if ($option['desc']): ?>
112
+ <div class="<?php echo esc_attr($classes['desc']) ?>">
113
+ <div class="fw-inner"><span class="description customize-control-description"><?php echo ($option['desc'] ? $option['desc'] : '') ?></span></div>
114
+ </div>
115
+ <?php endif; ?>
116
+ <div class="<?php echo esc_attr($classes['input']) ?>">
117
+ <div class="fw-inner fw-pull-<?php echo is_rtl() ? 'right' : 'left'; ?>">
118
+ <div class="fw-inner-option">
119
+ <?php echo fw()->backend->option_type($option['type'])->render($id, $option, $data) ?>
120
+ </div>
121
+ <div class="fw-clear"></div>
122
+ </div>
123
+ <div class="fw-clear"></div>
124
+ </div>
125
+ <div class="fw-clear"></div>
126
+ </div>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: unyson, themefusecom
3
  Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
4
  Requires at least: 4.0.0
5
  Tested up to: 4.2
6
- Stable tag: 2.2.10
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -86,6 +86,10 @@ Yes; Unyson will work with any theme.
86
 
87
  == Changelog ==
88
 
 
 
 
 
89
  = 2.2.10 =
90
  * Fixed [#539](https://github.com/ThemeFuse/Unyson/issues/539)
91
 
3
  Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
4
  Requires at least: 4.0.0
5
  Tested up to: 4.2
6
+ Stable tag: 2.3.0
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
86
 
87
  == Changelog ==
88
 
89
+ = 2.3.0 =
90
+ * Options can be used in [Customizer](https://codex.wordpress.org/Theme_Customization_API) [#410](https://github.com/ThemeFuse/Unyson/issues/410)
91
+ * Fixed [#77](https://github.com/ThemeFuse/Unyson/issues/77)
92
+
93
  = 2.2.10 =
94
  * Fixed [#539](https://github.com/ThemeFuse/Unyson/issues/539)
95
 
unyson.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Unyson
4
  * Plugin URI: http://unyson.themefuse.com/
5
  * Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
6
- * Version: 2.2.10
7
  * Author: ThemeFuse
8
  * Author URI: http://themefuse.com
9
  * License: GPL2+
3
  * Plugin Name: Unyson
4
  * Plugin URI: http://unyson.themefuse.com/
5
  * Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
6
+ * Version: 2.3.0
7
  * Author: ThemeFuse
8
  * Author URI: http://themefuse.com
9
  * License: GPL2+