From c528c10a1b013694088c278f49dfcb4181f55c40 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Mon, 8 Oct 2012 19:39:34 +0200 Subject: [PATCH] Added prototype for ACP style editor Currently only the form to create a style exists, more features will be added soon :) --- .gitignore | 50 +++ acpMenu.xml | 25 ++ acptemplates/styleAdd.tpl | 429 +++++++++++++++++++++ acptemplates/styleVariableColor.tpl | 5 + acptemplates/styleVariableUnit.tpl | 12 + files/lib/acp/form/StyleAddForm.class.php | 443 ++++++++++++++++++++++ files/style/styleEditor.less | 37 ++ language/de.xml | 57 +++ package.xml | 21 + userGroupOption.xml | 39 ++ 10 files changed, 1118 insertions(+) create mode 100644 .gitignore create mode 100644 acpMenu.xml create mode 100644 acptemplates/styleAdd.tpl create mode 100644 acptemplates/styleVariableColor.tpl create mode 100644 acptemplates/styleVariableUnit.tpl create mode 100644 files/lib/acp/form/StyleAddForm.class.php create mode 100644 files/style/styleEditor.less create mode 100644 language/de.xml create mode 100644 package.xml create mode 100644 userGroupOption.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..d9b96dd61c --- /dev/null +++ b/.gitignore @@ -0,0 +1,50 @@ +# Linux +# backup files +*~ + +# Windows +# thumbnails +Thumbs.db + +# Mac OS X +# metadata +.DS_Store +# thumbnails +._* + +# Visual Studio PHP +*.sln +*.phpproj +*.puo +*.suo +*.cache + +# Netbeans +nbproject/ +catalog.xml +nbactions.xml + +# Eclipse +.settings/ +.buildpath +.classpath +.project + +# SVN +# svn folders +.svn/ + +# PHPStorm +.idea/ +.nameencodings +.xmlmisc +.xmlmodules +.xmlprojectCodeStyle +.xmlvcs.xml +*.imlworkspace +.xml + +# Community Framework +# Ignore packages build directly in the workspace. They can however be added manually via git add, if wanted. +*.tar +*.tar.gz \ No newline at end of file diff --git a/acpMenu.xml b/acpMenu.xml new file mode 100644 index 0000000000..d03c7fa486 --- /dev/null +++ b/acpMenu.xml @@ -0,0 +1,25 @@ + + + + + + wcf.acp.menu.link.display + 1 + + + + index.php/StyleList/ + wcf.acp.menu.link.style + admin.style.canEditStyle,admin.style.canDeleteStyle + 1 + + + + index.php/StyleAdd/ + wcf.acp.menu.link.style + admin.style.canAddStyle + 2 + + + + diff --git a/acptemplates/styleAdd.tpl b/acptemplates/styleAdd.tpl new file mode 100644 index 0000000000..d2bbf4ed7d --- /dev/null +++ b/acptemplates/styleAdd.tpl @@ -0,0 +1,429 @@ +{include file='header'} + + + +
+
+

{lang}wcf.acp.style.{$action}{/lang}

+
+
+ +{if $errorField} +

{lang}wcf.global.form.error{/lang}

+{/if} + +{if $success|isset} +

{lang}wcf.global.form.{$action}.success{/lang}

+{/if} + +
+ +
+ +
+
+ + + {* general *} +
+
+ {lang}wcf.acp.style.general.data{/lang} + + +
+
+ + {if $errorField == 'styleName'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.styleName.{$errorType}{/lang} + {/if} + + {/if} +
+ + +
+
+ + {if $errorField == 'authorName'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.authorName.{$errorType}{/lang} + {/if} + + {/if} +
+ + +
+
+ + {if $errorField == 'copyright'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.copyright.{$errorType}{/lang} + {/if} + + {/if} +
+ + +
+
+ + {if $errorField == 'styleVersion'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.styleVersion.{$errorType}{/lang} + {/if} + + {/if} +
+ + +
+
+ + {if $errorField == 'styleDate'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.styleDate.{$errorType}{/lang} + {/if} + + {/if} +
+ + +
+
+ + {if $errorField == 'license'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.license.{$errorType}{/lang} + {/if} + + {/if} +
+ + +
+
+ + {if $errorField == 'authorURL'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.authorURL.{$errorType}{/lang} + {/if} + + {/if} +
+ + +
+
+ + {if $errorField == 'styleDescription'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.styleDescription.{$errorType}{/lang} + {/if} + + {/if} +
+ +
+ +
+ {lang}wcf.acp.style.general.files{/lang} + + +
+
+ TODO: Add upload here! + {if $errorField == 'image'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.image.{$errorType}{/lang} + {/if} + + {/if} + {lang}wcf.acp.style.image.description{/lang} +
+ + {hascontent} + +
+
+ + {if $errorField == 'templateGroupID'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.templateGroupID.{$errorType}{/lang} + {/if} + + {/if} +
+ + {/hascontent} + +
+
+ + {if $errorField == 'iconPath'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.iconPath.{$errorType}{/lang} + {/if} + + {/if} + {lang}wcf.acp.style.iconPath.description{/lang} +
+ + +
+
+ + {if $errorField == 'imagePath'} + + {if $errorType == 'empty'} + {lang}wcf.global.form.error.empty{/lang} + {else} + {lang}wcf.acp.style.error.imagePath.{$errorType}{/lang} + {/if} + + {/if} + {lang}wcf.acp.style.imagePath.description{/lang} +
+ +
+
+ + {* globals *} +
+ {* layout *} +
+ {lang}wcf.acp.style.globals.layout{/lang} + +
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+ + +
+
+
+
+ + {* font *} +
+ {lang}wcf.acp.style.globals.font{/lang} + +
+
+
+ + +
+
+
+
+
+ +
+
+
+
+ + {* colors *} +
+
+ {lang}wcf.acp.style.colors.content{/lang} + + {* content *} +
    +
  • {include file='styleVariableColor' variableName='wcfContentBackgroundColor' languageVariable='backgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfColor' languageVariable='color'}
  • +
  • {include file='styleVariableColor' variableName='wcfDimmedColor' languageVariable='dimmedColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfLinkColor' languageVariable='linkColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfLinkHoverColor' languageVariable='linkHoverColor'}
  • +
+
+ +
+ {lang}wcf.acp.style.colors.container{/lang} + + {* general *} +
    +
  • {include file='styleVariableColor' variableName='wcfContainerBackgroundColor' languageVariable='backgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfContainerAccentBackgroundColor' languageVariable='accentBackgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfContainerBorderColor' languageVariable='borderColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfContainerHoverBackgroundColor' languageVariable='hoverBackgroundColor'}
  • +
+
+ +
+ {lang}wcf.acp.style.colors.userPanel{/lang} + + {* user panel *} +
    +
  • {include file='styleVariableColor' variableName='wcfUserPanelBackgroundColor' languageVariable='backgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfUserPanelColor' languageVariable='color'}
  • +
  • {include file='styleVariableColor' variableName='wcfUserPanelHoverBackgroundColor' languageVariable='hoverBackgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfUserPanelHoverColor' languageVariable='hoverColor'}
  • +
+
+ +
+ {lang}wcf.acp.style.colors.tabular{/lang} + + {* general *} +
    +
  • {include file='styleVariableColor' variableName='wcfTabularBoxBackgroundColor' languageVariable='backgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfTabularBoxColor' languageVariable='color'}
  • +
  • {include file='styleVariableColor' variableName='wcfTabularBoxHoverColor' languageVariable='hoverColor'}
  • +
+
+ +
+ {lang}wcf.acp.style.colors.buttons{/lang} + + {* default button *} +
    +
  • {include file='styleVariableColor' variableName='wcfButtonBackgroundColor' languageVariable='backgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfButtonBorderColor' languageVariable='borderColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfButtonColor' languageVariable='color'}
  • +
+ + {* button:hover *} +
    +
  • {include file='styleVariableColor' variableName='wcfButtonHoverBackgroundColor' languageVariable='hoverBackgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfButtonHoverBorderColor' languageVariable='hoverBorderColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfButtonHoverColor' languageVariable='hoverColor'}
  • +
+ + {* primary button *} +
    +
  • {include file='styleVariableColor' variableName='wcfButtonPrimaryBackgroundColor' languageVariable='primaryBackgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfButtonPrimaryBorderColor' languageVariable='primaryBorderColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfButtonPrimaryColor' languageVariable='primaryColor'}
  • +
+
+ +
+ {lang}wcf.acp.style.colors.formInput{/lang} + + {* default button *} +
    +
  • {include file='styleVariableColor' variableName='wcfInputBackgroundColor' languageVariable='backgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfInputBorderColor' languageVariable='borderColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfInputColor' languageVariable='color'}
  • +
  • {include file='styleVariableColor' variableName='wcfInputHoverBackgroundColor' languageVariable='hoverBackgroundColor'}
  • +
  • {include file='styleVariableColor' variableName='wcfInputHoverBorderColor' languageVariable='hoverBorderColor'}
  • +
+
+
+
+ +
+ + {if $styleID|isset}{/if} +
+
+ +{include file='footer'} \ No newline at end of file diff --git a/acptemplates/styleVariableColor.tpl b/acptemplates/styleVariableColor.tpl new file mode 100644 index 0000000000..beffc0709e --- /dev/null +++ b/acptemplates/styleVariableColor.tpl @@ -0,0 +1,5 @@ +
+
{lang}wcf.acp.style.colors.{$languageVariable}{/lang}
+
+ +
\ No newline at end of file diff --git a/acptemplates/styleVariableUnit.tpl b/acptemplates/styleVariableUnit.tpl new file mode 100644 index 0000000000..e9c76b52da --- /dev/null +++ b/acptemplates/styleVariableUnit.tpl @@ -0,0 +1,12 @@ +
+
+
+ + +
+
\ No newline at end of file diff --git a/files/lib/acp/form/StyleAddForm.class.php b/files/lib/acp/form/StyleAddForm.class.php new file mode 100644 index 0000000000..e714bfeddc --- /dev/null +++ b/files/lib/acp/form/StyleAddForm.class.php @@ -0,0 +1,443 @@ + + * @package com.woltlab.wcf.acp.style + * @subpackage acp.form + * @category Community Framework + */ +class StyleAddForm extends ACPForm { + /** + * @see wcf\acp\form\ACPForm::$activeMenuItem + */ + public $activeMenuItem = 'wcf.acp.menu.link.style.add'; + + /** + * author's name + * @var string + */ + public $authorName = ''; + + /** + * author's URL + * @var string + */ + public $authorURL = ''; + + /** + * list of available font families + * @var array + */ + public $availableFontFamilies = array( + 'Arial, Helvetica, sans-serif' => 'Arial', + 'Chicago, Impact, Compacta, sans-serif' => 'Chicago', + '"Comic Sans MS", sans-serif' => 'Comic Sans', + '"Courier New", Courier, monospace' => 'Courier New', + 'Geneva, Arial, Helvetica, sans-serif' => 'Geneva', + 'Georgia, "Times New Roman", Times, serif' => 'Georgia', + 'Helvetica, Verdana, sans-serif' => 'Helvetica', + 'Impact, Compacta, Chicago, sans-serif' => 'Impact', + '"Lucida Sans", "Lucida Grande", Monaco, Geneva, sans-serif' => 'Lucida', + 'Tahoma, Arial, Helvetica, sans-serif' => 'Tahoma', + '"Times New Roman", Times, Georgia, serif' => 'Times New Roman', + '"Trebuchet MS", Arial, sans-serif' => 'Trebuchet MS', + 'Verdana, Helvetica, sans-serif' => 'Verdana' + ); + + /** + * list of available template groups + * @var array + */ + public $availableTemplateGroups = array(); + + /** + * list of available units + * @var array + */ + public $availableUnits = array('px', 'em', '%', 'pt'); + + /** + * list of color variables + * @var array + */ + public $colors = array(); + + /** + * copyright message + * @var string + */ + public $copyright = ''; + + /** + * font family + * @var string + */ + public $fontFamily = ''; + + /** + * list of global variables + * + * @var unknown_type + */ + public $globals = array(); + + /** + * icon path + * @var string + */ + public $iconPath = 'icon/'; + + /** + * path to preview image + * @var string + */ + public $image = ''; + + /** + * image path + * @var string + */ + public $imagePath = 'images/'; + + /** + * license name + * @var string + */ + public $license = ''; + + /** + * last change date + * @var string + */ + public $styleDate = '0000-00-00'; + + /** + * description + * @var string + */ + public $styleDescription = ''; + + /** + * style name + * @var string + */ + public $styleName = ''; + + /** + * version number + * @var string + */ + public $styleVersion = ''; + + /** + * template group id + * @var integer + */ + public $templateGroupID = 0; + + /** + * fluid or fixed layout + * @var boolean + */ + public $useFluidLayout = true; + + /** + * list of variables and their value + * @var array + */ + public $variables = array(); + + /** + * @see wcf\page\IPage::readParameters() + */ + public function readParameters() { + parent::readParameters(); + + $this->setVariables(); + $this->readStyleVariables(); + + $templateGroupList = new TemplateGroupList(); + $templateGroupList->sqlLimit = 0; + $templateGroupList->sqlOrderBy = "template_group.templateGroupName ASC"; + $templateGroupList->readObjects(); + $this->availableTemplateGroups = $templateGroupList->getObjects(); + } + + /** + * @see wcf\form\IForm::readFormParameters() + */ + public function readFormParameters() { + parent::readFormParameters(); + + // ignore everything except well-formed rgba() + $regEx = new Regex('rgba\(\d{1,3}, \d{1,3}, \d{1,3}, (1|1\.00?|0|0?\.[0-9]{1,2})\)'); + foreach ($this->colors as $variableName) { + if (isset($_POST[$variableName]) && $regEx->match($_POST[$variableName])) { + $this->variables[$variableName] = $_POST[$variableName]; + } + } + + // read variables with units, e.g. 13px + foreach ($this->globals as $variableName) { + if (isset($_POST[$variableName]) && is_numeric($_POST[$variableName])) { + if(isset($_POST[$variableName.'_unit']) && in_array($_POST[$variableName.'_unit'], $this->availableUnits)) { + $this->variables[$variableName] = $_POST[$variableName].$_POST[$variableName.'_unit']; + } + } + } + + $this->useFluidLayout = (isset($_POST['useFluidLayout'])); + + // style data + if (isset($_POST['authorName'])) $this->authorName = StringUtil::trim($_POST['authorName']); + if (isset($_POST['authorURL'])) $this->authorURL = StringUtil::trim($_POST['authorURL']); + if (isset($_POST['copyright'])) $this->copyright = StringUtil::trim($_POST['copyright']); + if (isset($_POST['iconPath'])) $this->iconPath = StringUtil::trim($_POST['iconPath']); + if (isset($_POST['image'])) $this->image = StringUtil::trim($_POST['image']); + if (isset($_POST['imagePath'])) $this->imagePath = StringUtil::trim($_POST['imagePath']); + if (isset($_POST['license'])) $this->license = StringUtil::trim($_POST['license']); + if (isset($_POST['styleDate'])) $this->styleDate = StringUtil::trim($_POST['styleDate']); + if (isset($_POST['styleDescription'])) $this->styleDescription = StringUtil::trim($_POST['styleDescription']); + if (isset($_POST['styleName'])) $this->styleName = StringUtil::trim($_POST['styleName']); + if (isset($_POST['styleVersion'])) $this->styleVersion = StringUtil::trim($_POST['styleVersion']); + if (isset($_POST['templateGroupID'])) $this->templateGroupID = intval($_POST['templateGroupID']); + } + + /** + * @see wcf\form\IForm::validate() + */ + public function validate() { + parent::validate(); + + if (empty($this->authorName)) { + throw new UserInputException('authorName'); + } + + if (empty($this->license)) { + throw new UserInputException('license'); + } + + // validate date + if (empty($this->styleDate)) { + throw new UserInputException('styleDate'); + } + else { + try { + DateUtil::validateDate($this->styleDate); + } + catch (SystemException $e) { + throw new UserInputException('styleDate', 'notValid'); + } + } + + if (empty($this->styleName)) { + throw new UserInputException('styleName'); + } + + // validate version + if (empty($this->styleVersion)) { + throw new UserInputException('styleVersion'); + } + else if (!Package::isValidVersion($this->styleVersion)) { + throw new UserInputException('styleVersion', 'notValid'); + } + + // validate template group id + if ($this->templateGroupID) { + if (!isset($this->availableTemplateGroups[$this->templateGroupID])) { + throw new UserInputException('templateGroupID'); + } + } + + // ensure icon path is below WCF_DIR/icon/ + if ($this->iconPath) { + $relativePath = FileUtil::unifyDirSeperator(FileUtil::getRelativePath(WCF_DIR.'icon/', WCF_DIR.$this->iconPath)); + if (strpos($relativePath, '../') !== false) { + throw new UserInputException('iconPath', 'notValid'); + } + } + + // ensure image path is below WCF_DIR/images/ + if ($this->imagePath) { + $relativePath = FileUtil::unifyDirSeperator(FileUtil::getRelativePath(WCF_DIR.'images/', WCF_DIR.$this->imagePath)); + if (strpos($relativePath, '../') !== false) { + throw new UserInputException('imagePath', 'notValid'); + } + } + } + + /** + * @see wcf\page\IPage::readData() + */ + public function readData() { + parent::readData(); + + // parse global (unit) variables + foreach ($this->globals as $variableName) { + $unit = ''; + $value = $this->variables[$variableName]; + $i = strlen($value) - 1; + while ($i >= 0) { + $unit = $value[$i] . $unit; + if (in_array($unit, $this->availableUnits)) { + $this->variables[$variableName] = str_replace($unit, '', $value); + $this->variables[$variableName.'_unit'] = $unit; + break; + } + + $i--; + } + } + } + + /** + * Sets available variables + */ + protected function setVariables() { + // set color variables + $this->colors = array( + 'wcfButtonBackgroundColor', + 'wcfButtonBorderColor', + 'wcfButtonColor', + 'wcfButtonHoverBackgroundColor', + 'wcfButtonHoverBorderColor', + 'wcfButtonHoverColor', + 'wcfButtonPrimaryBackgroundColor', + 'wcfButtonPrimaryBorderColor', + 'wcfButtonPrimaryColor', + 'wcfColor', + 'wcfContainerAccentBackgroundColor', + 'wcfContainerBackgroundColor', + 'wcfContainerBorderColor', + 'wcfContainerHoverBackgroundColor', + 'wcfContentBackgroundColor', + 'wcfDimmedColor', + 'wcfInputBackgroundColor', + 'wcfInputBorderColor', + 'wcfInputColor', + 'wcfInputHoverBackgroundColor', + 'wcfInputHoverBorderColor', + 'wcfLinkColor', + 'wcfLinkHoverColor', + 'wcfTabularBoxBackgroundColor', + 'wcfTabularBoxColor', + 'wcfTabularBoxHoverColor', + 'wcfUserPanelBackgroundColor', + 'wcfUserPanelColor', + 'wcfUserPanelHoverBackgroundColor', + 'wcfUserPanelHoverColor', + ); + + // set global variables + $this->globals = array( + 'wcfBaseFontSize', + 'wcfContainerBorderRadius', + 'wcfLayoutFixedWidth', + 'wcfLayoutFluidGap' + ); + + EventHandler::getInstance()->fireAction($this, 'setVariables'); + } + + /** + * Reads style variable values. + */ + protected function readStyleVariables() { + $sql = "SELECT variableName, defaultValue + FROM wcf".WCF_N."_style_variable"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute(); + while ($row = $statement->fetchArray()) { + $this->variables[$row['variableName']] = $row['defaultValue']; + } + } + + /** + * @see wcf\form\IForm::save() + */ + public function save() { + parent::save(); + + $this->objectAction = new StyleAction(array(), 'create', array( + 'data' => array( + 'styleName' => $this->styleName, + 'templateGroupID' => $this->templateGroupID, + 'styleDescription' => ($this->styleDescription ? $this->styleDescription : null), + 'styleVersion' => $this->styleVersion, + 'styleDate' => $this->styleDate, + 'image' => $this->image, + 'imagePath' => $this->imagePath, + 'copyright' => $this->copyright, + 'license' => $this->license, + 'authorName' => $this->authorName, + 'authorURL' => $this->authorURL, + 'iconPath' => $this->iconPath + ), + 'variables' => $this->variables + )); + $this->objectAction->executeAction(); + + // call saved event + $this->saved(); + + // reset variables + $this->authorName = $this->authorURL = $this->copyright = $this->fontFamily = ''; + $this->image = $this->license = $this->styleDate = $this->styleDescription = ''; + $this->styleName = $this->styleVersion = 0; + + $this->iconPath = 'icon/'; + $this->imagePath = 'images/'; + $this->templateGroupID = 0; + $this->useFluidLayout = true; + + // reload variables + $this->readStyleVariables(); + + WCF::getTPL()->assign('success', true); + } + + /** + * @see wcf\page\IPage::assignVariables() + */ + public function assignVariables() { + parent::assignVariables(); + + WCF::getTPL()->assign(array( + 'action' => 'add', + 'authorName' => $this->authorName, + 'authorURL' => $this->authorURL, + 'availableFontFamilies' => $this->availableFontFamilies, + 'availableTemplateGroups' => $this->availableTemplateGroups, + 'availableUnits' => $this->availableUnits, + 'copyright' => $this->copyright, + 'fontFamily' => $this->fontFamily, + 'iconPath' => $this->iconPath, + 'image' => $this->image, + 'imagePath' => $this->imagePath, + 'license' => $this->license, + 'styleDate' => $this->styleDate, + 'styleDescription' => $this->styleDescription, + 'styleName' => $this->styleName, + 'styleVersion' => $this->styleVersion, + 'templateGroupID' => $this->templateGroupID, + 'useFluidLayout' => $this->useFluidLayout, + 'variables' => $this->variables + )); + } +} diff --git a/files/style/styleEditor.less b/files/style/styleEditor.less new file mode 100644 index 0000000000..f8f325c27b --- /dev/null +++ b/files/style/styleEditor.less @@ -0,0 +1,37 @@ +.colorPreview { + border: 1px solid @wcfContainerBorderColor; + border-radius: @wcfContainerBorderRadius; + display: inline-block; + + &:hover { + .boxShadow(0, 0, @wcfContainerBorderColor, 15px, 0); + } + + > div { + border: 1px solid @wcfContainerBorderColor; + border-radius: @wcfContainerBorderRadius; + cursor: pointer; + display: block; + height: 60px; + width: 200px; + } +} + +.colorList { + > li { + float: left; + padding: @wcfGapSmall; + + > figure > figcaption { + font-size: 85%; + margin-bottom: @wcfGapSmall; + text-align: center; + } + } + + &:after { + clear: both; + content: ""; + display: block; + } +} \ No newline at end of file diff --git a/language/de.xml b/language/de.xml new file mode 100644 index 0000000000..a5faa13720 --- /dev/null +++ b/language/de.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/package.xml b/package.xml new file mode 100644 index 0000000000..1a8a2a95c1 --- /dev/null +++ b/package.xml @@ -0,0 +1,21 @@ + + + + Style Administration + 1.0.0 Alpha 1 + 2012-10-08 + + + + WoltLab GmbH + http://www.woltlab.com + + + + acptemplates.tar + files.tar + acpMenu.xml + language/*.xml + userGroupOption.xml + + diff --git a/userGroupOption.xml b/userGroupOption.xml new file mode 100644 index 0000000000..55112afe6f --- /dev/null +++ b/userGroupOption.xml @@ -0,0 +1,39 @@ + + + + + + admin.display + + + + + + + + + + + + + -- 2.20.1