From ffcd307746af6a578fe771c31c306feb9d393e9c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 14 Sep 2010 17:25:46 +0200 Subject: [PATCH 1/4] [ticket/9675] Add option to delete template/theme/imageset when deleting style. PHPBB3-9675 --- phpBB/adm/style/acp_styles.html | 14 ++++ phpBB/includes/acp/acp_styles.php | 104 +++++++++++++++++++++++++++++- phpBB/language/en/acp/styles.php | 5 +- 3 files changed, 121 insertions(+), 2 deletions(-) diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html index cb4361dd6f..1978537cf4 100644 --- a/phpBB/adm/style/acp_styles.html +++ b/phpBB/adm/style/acp_styles.html @@ -22,6 +22,20 @@

{L_REPLACE_EXPLAIN}
+ +
+

{L_REPLACE_TEMPLATE_EXPLAIN}
+
+
+
+

{L_REPLACE_THEME_EXPLAIN}
+
+
+
+

{L_REPLACE_IMAGESET_EXPLAIN}
+
+
+

diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 2ccc728031..d9565214db 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -1587,7 +1587,7 @@ parse_css_file = {PARSE_CSS_FILE} { case 'style': $sql_from = STYLES_TABLE; - $sql_select = 'style_name'; + $sql_select = 'style_name, template_id, theme_id, imageset_id'; $sql_where = 'AND style_active = 1'; break; @@ -1678,6 +1678,51 @@ parse_css_file = {PARSE_CSS_FILE} { set_config('default_style', $new_id); } + + // Remove the components + $components = array('template', 'theme', 'imageset'); + foreach ($components as $component) + { + $new_id = request_var('new_' . $component . '_id', 0); + $style_id = $style_row[$component . '_id']; + + if (($new_id == 0) || ($component === 'template' && ($conflicts = $this->check_inheritance($component, $style_id)))) + { + // We can not delete the template, as the selected one is inheriting from this one. + continue; + } + + if ($component == 'imageset') + { + $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . " + WHERE imageset_id = $style_id"; + $db->sql_query($sql); + } + + switch ($component) + { + case 'template': + $sql_from = STYLES_TEMPLATE_TABLE; + break; + + case 'theme': + $sql_from = STYLES_THEME_TABLE; + break; + + case 'imageset': + $sql_from = STYLES_IMAGESET_TABLE;; + break; + } + + $sql = "DELETE FROM $sql_from + WHERE {$component}_id = $style_id"; + $db->sql_query($sql); + + $sql = 'UPDATE ' . STYLES_TABLE . " + SET {$component}_id = $new_id + WHERE {$component}_id = $style_id"; + $db->sql_query($sql); + } } else { @@ -1718,6 +1763,63 @@ parse_css_file = {PARSE_CSS_FILE} 'NAME' => $style_row[$mode . '_name'], ) ); + + if ($mode == 'style') + { + $template->assign_vars(array( + 'S_DELETE_STYLE' => true, + )); + + $components = array('template', 'theme', 'imageset'); + foreach ($components as $mode) + { + $sql_where = ''; + switch ($mode) + { + case 'template': + $sql_from = STYLES_TEMPLATE_TABLE; + $sql_select = 'template_name, template_path, template_storedb'; + $sql_where = ' AND template_inherits_id <> ' . $style_row[$mode . '_id']; + break; + + case 'theme': + $sql_from = STYLES_THEME_TABLE; + $sql_select = 'theme_name, theme_path, theme_storedb'; + break; + + case 'imageset': + $sql_from = STYLES_IMAGESET_TABLE; + $sql_select = 'imageset_name, imageset_path'; + break; + } + + $sql = "SELECT {$mode}_id, {$mode}_name + FROM $sql_from + WHERE {$mode}_id <> {$style_row[$mode . '_id']} + $sql_where + ORDER BY {$mode}_name ASC"; + $result = $db->sql_query($sql); + + $s_options = ''; + + $set_default = true; + while ($row = $db->sql_fetchrow($result)) + { + if ($set_default) + { + $s_options .= ''; + $set_default = false; + } + else + { + $s_options .= ''; + } + } + $db->sql_freeresult($result); + + $template->assign_var('S_REPLACE_' . strtoupper($mode) . '_OPTIONS', $s_options); + } + } } /** diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php index f161a7e6e6..f422f96009 100644 --- a/phpBB/language/en/acp/styles.php +++ b/phpBB/language/en/acp/styles.php @@ -285,11 +285,14 @@ $lang = array_merge($lang, array( 'INSTALLED_TEMPLATE' => 'Installed templates', 'INSTALLED_THEME' => 'Installed themes', + 'KEEP_IMAGESET' => 'Keep imageset', + 'KEEP_TEMPLATE' => 'Keep template', + 'KEEP_THEME' => 'Keep theme', + 'LINE_SPACING' => 'Line spacing', 'LOCALISED_IMAGES' => 'Localised', 'LOCATION_DISABLED_EXPLAIN' => 'This setting is inherited and cannot be changed.', - 'NO_CLASS' => 'Cannot find class in stylesheet.', 'NO_IMAGESET' => 'Cannot find imageset on filesystem.', 'NO_IMAGE' => 'No image', From 18fedfce1739075586aa0e40fabdffba65593793 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 15 Sep 2010 11:21:54 +0200 Subject: [PATCH 2/4] [ticket/9675] Adjust the language-string to reflect the changes. PHPBB3-9675 --- phpBB/language/en/acp/styles.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php index f422f96009..f5531071e4 100644 --- a/phpBB/language/en/acp/styles.php +++ b/phpBB/language/en/acp/styles.php @@ -78,7 +78,7 @@ $lang = array_merge($lang, array( 'DELETE_IMAGESET' => 'Delete imageset', 'DELETE_IMAGESET_EXPLAIN' => 'Here you can remove the selected imageset from the database. Please note that there is no undo capability. It is recommended that you first export your set for possible future use.', 'DELETE_STYLE' => 'Delete style', - 'DELETE_STYLE_EXPLAIN' => 'Here you can remove the selected style. You cannot remove all the style elements from here. These must be deleted individually via their respective forms. Take care when deleting styles, there is no undo facility.', + 'DELETE_STYLE_EXPLAIN' => 'Here you can remove the selected style. Take care in deleting styles, there is no undo capability.', 'DELETE_TEMPLATE' => 'Delete template', 'DELETE_TEMPLATE_EXPLAIN' => 'Here you can remove the selected template set from the database. Please note that there is no undo capability. It is recommended that you first export your set for possible future use.', 'DELETE_THEME' => 'Delete theme', From 0e02f5cb0b7f615f1eadd6606a89bfd1b28f0d0d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 27 Jan 2011 13:30:59 +0100 Subject: [PATCH 3/4] [ticket/9675] Put the code into methods to avoid code duplication. PHPBB3-9675 --- phpBB/adm/style/acp_styles.html | 7 +- phpBB/includes/acp/acp_styles.php | 274 +++++++++++++++++------------- phpBB/language/en/acp/styles.php | 7 +- 3 files changed, 163 insertions(+), 125 deletions(-) diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html index 1978537cf4..098cc723d9 100644 --- a/phpBB/adm/style/acp_styles.html +++ b/phpBB/adm/style/acp_styles.html @@ -23,16 +23,17 @@

+
-

{L_REPLACE_TEMPLATE_EXPLAIN}
+

{L_REPLACE_TEMPLATE_EXPLAIN}
-

{L_REPLACE_THEME_EXPLAIN}
+

{L_REPLACE_THEME_EXPLAIN}
-

{L_REPLACE_IMAGESET_EXPLAIN}
+

{L_REPLACE_IMAGESET_EXPLAIN}
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index d9565214db..2e2807c8cb 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -1587,23 +1587,23 @@ parse_css_file = {PARSE_CSS_FILE} { case 'style': $sql_from = STYLES_TABLE; - $sql_select = 'style_name, template_id, theme_id, imageset_id'; + $sql_select = 'style_id, style_name, template_id, theme_id, imageset_id'; $sql_where = 'AND style_active = 1'; break; case 'template': $sql_from = STYLES_TEMPLATE_TABLE; - $sql_select = 'template_name, template_path, template_storedb'; + $sql_select = 'template_id, template_name, template_path, template_storedb'; break; case 'theme': $sql_from = STYLES_THEME_TABLE; - $sql_select = 'theme_name, theme_path, theme_storedb'; + $sql_select = 'theme_id, theme_name, theme_path, theme_storedb'; break; case 'imageset': $sql_from = STYLES_IMAGESET_TABLE; - $sql_select = 'imageset_name, imageset_path'; + $sql_select = 'imageset_id, imageset_name, imageset_path'; break; } @@ -1633,37 +1633,14 @@ parse_css_file = {PARSE_CSS_FILE} trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING); } - $sql = "SELECT {$mode}_id, {$mode}_name - FROM $sql_from - WHERE {$mode}_id <> $style_id - $sql_where - ORDER BY {$mode}_name ASC"; - $result = $db->sql_query($sql); - - $s_options = ''; - - if ($row = $db->sql_fetchrow($result)) - { - do - { - $s_options .= ''; - } - while ($row = $db->sql_fetchrow($result)); - } - else - { - trigger_error($user->lang['ONLY_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING); - } - $db->sql_freeresult($result); - if ($update) { - $sql = "DELETE FROM $sql_from - WHERE {$mode}_id = $style_id"; - $db->sql_query($sql); - if ($mode == 'style') { + $sql = "DELETE FROM $sql_from + WHERE {$mode}_id = $style_id"; + $db->sql_query($sql); + $sql = 'UPDATE ' . USERS_TABLE . " SET user_style = $new_id WHERE user_style = $style_id"; @@ -1684,58 +1661,13 @@ parse_css_file = {PARSE_CSS_FILE} foreach ($components as $component) { $new_id = request_var('new_' . $component . '_id', 0); - $style_id = $style_row[$component . '_id']; - - if (($new_id == 0) || ($component === 'template' && ($conflicts = $this->check_inheritance($component, $style_id)))) - { - // We can not delete the template, as the selected one is inheriting from this one. - continue; - } - - if ($component == 'imageset') - { - $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . " - WHERE imageset_id = $style_id"; - $db->sql_query($sql); - } - - switch ($component) - { - case 'template': - $sql_from = STYLES_TEMPLATE_TABLE; - break; - - case 'theme': - $sql_from = STYLES_THEME_TABLE; - break; - - case 'imageset': - $sql_from = STYLES_IMAGESET_TABLE;; - break; - } - - $sql = "DELETE FROM $sql_from - WHERE {$component}_id = $style_id"; - $db->sql_query($sql); - - $sql = 'UPDATE ' . STYLES_TABLE . " - SET {$component}_id = $new_id - WHERE {$component}_id = $style_id"; - $db->sql_query($sql); + $component_id = $style_row[$component . '_id']; + $this->remove_component($component, $component_id, $new_id); } } else { - if ($mode == 'imageset') - { - $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . " - WHERE imageset_id = $style_id"; - $db->sql_query($sql); - } - $sql = 'UPDATE ' . STYLES_TABLE . " - SET {$mode}_id = $new_id - WHERE {$mode}_id = $style_id"; - $db->sql_query($sql); + $this->remove_component($mode, $style_id, $new_id); } $cache->destroy('sql', STYLES_TABLE); @@ -1745,11 +1677,12 @@ parse_css_file = {PARSE_CSS_FILE} trigger_error($user->lang[$message] . adm_back_link($this->u_action)); } + $this->display_component_options($mode, $style_row[$mode . '_id'], $style_row); + $this->page_title = 'DELETE_' . $l_prefix; $template->assign_vars(array( 'S_DELETE' => true, - 'S_REPLACE_OPTIONS' => $s_options, 'L_TITLE' => $user->lang[$this->page_title], 'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'], @@ -1769,55 +1702,158 @@ parse_css_file = {PARSE_CSS_FILE} $template->assign_vars(array( 'S_DELETE_STYLE' => true, )); + } + } - $components = array('template', 'theme', 'imageset'); - foreach ($components as $mode) + /** + * Remove template/theme/imageset entry from the database + */ + function remove_component($component, $style_id, $new_id) + { + global $db; + + if (($new_id == 0) || ($component === 'template' && ($conflicts = $this->check_inheritance($component, $style_id)))) + { + // We can not delete the template, as the selected one is inheriting from this one. + return; + } + + if ($component == 'imageset') + { + $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . " + WHERE imageset_id = $style_id"; + $db->sql_query($sql); + } + + switch ($component) + { + case 'template': + $sql_from = STYLES_TEMPLATE_TABLE; + break; + + case 'theme': + $sql_from = STYLES_THEME_TABLE; + break; + + case 'imageset': + $sql_from = STYLES_IMAGESET_TABLE;; + break; + } + + $sql = "DELETE FROM $sql_from + WHERE {$component}_id = $style_id"; + $db->sql_query($sql); + + $sql = 'UPDATE ' . STYLES_TABLE . " + SET {$component}_id = $new_id + WHERE {$component}_id = $style_id"; + $db->sql_query($sql); + } + + /** + * Display the options which can be used to replace a style/template/theme/imageset + */ + function display_component_options($component, $component_id, $style_row = false, $style_id = false) + { + global $db, $template, $user; + + $component_in_use = array(); + if (($component != 'style') && $style_id) + { + $sql = 'SELECT style_id, style_name + FROM ' . STYLES_TABLE . " + WHERE {$component}_id = {$component_id} + AND style_id <> {$style_id} + ORDER BY style_name ASC"; + $result = $db->sql_query($sql); + while ($row = $db->sql_fetchrow($result)) { - $sql_where = ''; - switch ($mode) + $component_in_use[] = $row['style_name']; + } + $db->sql_freeresult($result); + + if ($component === 'template' && ($conflicts = $this->check_inheritance($component, $component_id))) + { + foreach ($conflicts as $temp_id => $conflict_data) { - case 'template': - $sql_from = STYLES_TEMPLATE_TABLE; - $sql_select = 'template_name, template_path, template_storedb'; - $sql_where = ' AND template_inherits_id <> ' . $style_row[$mode . '_id']; - break; - - case 'theme': - $sql_from = STYLES_THEME_TABLE; - $sql_select = 'theme_name, theme_path, theme_storedb'; - break; - - case 'imageset': - $sql_from = STYLES_IMAGESET_TABLE; - $sql_select = 'imageset_name, imageset_path'; - break; + $component_in_use[] = $conflict_data['template_name']; } + } + } - $sql = "SELECT {$mode}_id, {$mode}_name - FROM $sql_from - WHERE {$mode}_id <> {$style_row[$mode . '_id']} - $sql_where - ORDER BY {$mode}_name ASC"; - $result = $db->sql_query($sql); + $sql_where = ''; + switch ($component) + { + case 'style': + $sql_from = STYLES_TABLE; + $sql_where = 'WHERE style_active = 1'; + break; - $s_options = ''; + case 'template': + $sql_from = STYLES_TEMPLATE_TABLE; + $sql_where = 'WHERE template_inherits_id <> ' . $component_id; + break; - $set_default = true; - while ($row = $db->sql_fetchrow($result)) + case 'theme': + $sql_from = STYLES_THEME_TABLE; + break; + + case 'imageset': + $sql_from = STYLES_IMAGESET_TABLE; + break; + } + + $s_options = ''; + if (($component != 'style') && empty($component_in_use)) + { + $sql = "SELECT {$component}_id, {$component}_name + FROM $sql_from + WHERE {$component}_id = {$component_id}"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $s_options .= ''; + $s_options .= ''; + } + else + { + $sql = "SELECT {$component}_id, {$component}_name + FROM $sql_from + $sql_where + ORDER BY {$component}_name ASC"; + $result = $db->sql_query($sql); + + $s_keep_option = $s_options = ''; + while ($row = $db->sql_fetchrow($result)) + { + if ($row[$component . '_id'] != $component_id) { - if ($set_default) - { - $s_options .= ''; - $set_default = false; - } - else - { - $s_options .= ''; - } + $s_options .= ''; } - $db->sql_freeresult($result); + else if ($component != 'style') + { + $s_keep_option = ''; + } + } + $db->sql_freeresult($result); + $s_options = $s_keep_option . $s_options; + } - $template->assign_var('S_REPLACE_' . strtoupper($mode) . '_OPTIONS', $s_options); + if (!$style_row) + { + $template->assign_var('S_REPLACE_' . strtoupper($component) . '_OPTIONS', $s_options); + } + else + { + $template->assign_var('S_REPLACE_OPTIONS', $s_options); + if ($component == 'style') + { + $components = array('template', 'theme', 'imageset'); + foreach ($components as $component) + { + $this->display_component_options($component, $style_row[$component . '_id'], false, $component_id); + } } } } diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php index f5531071e4..8f65b3ef5f 100644 --- a/phpBB/language/en/acp/styles.php +++ b/phpBB/language/en/acp/styles.php @@ -285,9 +285,9 @@ $lang = array_merge($lang, array( 'INSTALLED_TEMPLATE' => 'Installed templates', 'INSTALLED_THEME' => 'Installed themes', - 'KEEP_IMAGESET' => 'Keep imageset', - 'KEEP_TEMPLATE' => 'Keep template', - 'KEEP_THEME' => 'Keep theme', + 'KEEP_IMAGESET' => 'Keep "%s" imageset', + 'KEEP_TEMPLATE' => 'Keep "%s" template', + 'KEEP_THEME' => 'Keep "%s" theme', 'LINE_SPACING' => 'Line spacing', 'LOCALISED_IMAGES' => 'Localised', @@ -325,6 +325,7 @@ $lang = array_merge($lang, array( 'REPLACE_TEMPLATE_EXPLAIN' => 'This template set will replace the one you are deleting in any styles that use it.', 'REPLACE_THEME' => 'Replace theme with', 'REPLACE_THEME_EXPLAIN' => 'This theme will replace the one you are deleting in any styles that use it.', + 'REPLACE_WITH_OPTION' => 'Replace with "%s"', 'REQUIRES_IMAGESET' => 'This style requires the %s imageset to be installed.', 'REQUIRES_TEMPLATE' => 'This style requires the %s template set to be installed.', 'REQUIRES_THEME' => 'This style requires the %s theme to be installed.', From 65020fd5c1d71f44ef74824a27eaf4929b19635c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 27 Jan 2011 14:23:33 +0100 Subject: [PATCH 4/4] [ticket/9675] Correctly check whether the style/component is still in use. And don't allow to delete it in that case. PHPBB3-9675 --- phpBB/includes/acp/acp_styles.php | 92 +++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 28 deletions(-) diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 2e2807c8cb..0f157ceff3 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -1662,7 +1662,7 @@ parse_css_file = {PARSE_CSS_FILE} { $new_id = request_var('new_' . $component . '_id', 0); $component_id = $style_row[$component . '_id']; - $this->remove_component($component, $component_id, $new_id); + $this->remove_component($component, $component_id, $new_id, $style_id); } } else @@ -1708,20 +1708,32 @@ parse_css_file = {PARSE_CSS_FILE} /** * Remove template/theme/imageset entry from the database */ - function remove_component($component, $style_id, $new_id) + function remove_component($component, $component_id, $new_id, $style_id = false) { global $db; - if (($new_id == 0) || ($component === 'template' && ($conflicts = $this->check_inheritance($component, $style_id)))) + if (($new_id == 0) || ($component === 'template' && ($conflicts = $this->check_inheritance($component, $component_id)))) { - // We can not delete the template, as the selected one is inheriting from this one. + // We can not delete the template, as the user wants to keep the component or an other template is inheriting from this one. + return; + } + + $component_in_use = array(); + if ($component != 'style') + { + $component_in_use = $this->component_in_use($component, $component_id, $style_id); + } + + if (($new_id == -1) && !empty($component_in_use)) + { + // We can not delete the component, as it is still in use return; } if ($component == 'imageset') { $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . " - WHERE imageset_id = $style_id"; + WHERE imageset_id = $component_id"; $db->sql_query($sql); } @@ -1741,12 +1753,12 @@ parse_css_file = {PARSE_CSS_FILE} } $sql = "DELETE FROM $sql_from - WHERE {$component}_id = $style_id"; + WHERE {$component}_id = $component_id"; $db->sql_query($sql); $sql = 'UPDATE ' . STYLES_TABLE . " SET {$component}_id = $new_id - WHERE {$component}_id = $style_id"; + WHERE {$component}_id = $component_id"; $db->sql_query($sql); } @@ -1758,27 +1770,9 @@ parse_css_file = {PARSE_CSS_FILE} global $db, $template, $user; $component_in_use = array(); - if (($component != 'style') && $style_id) + if ($component != 'style') { - $sql = 'SELECT style_id, style_name - FROM ' . STYLES_TABLE . " - WHERE {$component}_id = {$component_id} - AND style_id <> {$style_id} - ORDER BY style_name ASC"; - $result = $db->sql_query($sql); - while ($row = $db->sql_fetchrow($result)) - { - $component_in_use[] = $row['style_name']; - } - $db->sql_freeresult($result); - - if ($component === 'template' && ($conflicts = $this->check_inheritance($component, $component_id))) - { - foreach ($conflicts as $temp_id => $conflict_data) - { - $component_in_use[] = $conflict_data['template_name']; - } - } + $component_in_use = $this->component_in_use($component, $component_id, $style_id); } $sql_where = ''; @@ -1852,12 +1846,54 @@ parse_css_file = {PARSE_CSS_FILE} $components = array('template', 'theme', 'imageset'); foreach ($components as $component) { - $this->display_component_options($component, $style_row[$component . '_id'], false, $component_id); + $this->display_component_options($component, $style_row[$component . '_id'], false, $component_id, true); } } } } + /** + * Check whether the component is still used by another style or component + */ + function component_in_use($component, $component_id, $style_id = false) + { + global $db; + + $component_in_use = array(); + + if ($style_id) + { + $sql = 'SELECT style_id, style_name + FROM ' . STYLES_TABLE . " + WHERE {$component}_id = {$component_id} + AND style_id <> {$style_id} + ORDER BY style_name ASC"; + } + else + { + $sql = 'SELECT style_id, style_name + FROM ' . STYLES_TABLE . " + WHERE {$component}_id = {$component_id} + ORDER BY style_name ASC"; + } + $result = $db->sql_query($sql); + while ($row = $db->sql_fetchrow($result)) + { + $component_in_use[] = $row['style_name']; + } + $db->sql_freeresult($result); + + if ($component === 'template' && ($conflicts = $this->check_inheritance($component, $component_id))) + { + foreach ($conflicts as $temp_id => $conflict_data) + { + $component_in_use[] = $conflict_data['template_name']; + } + } + + return $component_in_use; + } + /** * Export style or style elements */