From e2b73995e16ad7fde90e90e72e162d485a42d4aa Mon Sep 17 00:00:00 2001 From: Molkobain Date: Tue, 21 Sep 2021 22:49:41 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B03882=20-=20Move=20DataModel=20classes=20?= =?UTF-8?q?fields'=20style=20to=20theme=20instead=20of=20(duplicated)=20in?= =?UTF-8?q?line=20CSS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/themehandler.class.inc.php | 13 +- core/ormStyle.class.inc.php | 2 +- setup/compiler.class.inc.php | 249 +++++++++++++----- .../FieldBadge/FieldBadgeUIBlockFactory.php | 10 - 4 files changed, 185 insertions(+), 89 deletions(-) diff --git a/application/themehandler.class.inc.php b/application/themehandler.class.inc.php index 35936cfe7..4c388a35f 100644 --- a/application/themehandler.class.inc.php +++ b/application/themehandler.class.inc.php @@ -906,7 +906,8 @@ CSS; foreach($aImportsPaths as $sPath) { - $sFilePath = $sPath.'/'.$sFileURI; + $sAlterableFileURI = $sFileURI; + $sFilePath = $sPath.'/'.$sAlterableFileURI; $sImportedFile = realpath($sFilePath); if ($sImportedFile === false){ // Handle shortcut syntax : @import "typo" ; @@ -914,7 +915,7 @@ CSS; $sFilePath2 = "$sFilePath.scss"; $sImportedFile = realpath($sFilePath2); if ($sImportedFile){ - self::FindStylesheetFile("$sFileURI.scss", [ $sPath ], $oFindStylesheetObject, $bImports); + self::FindStylesheetFile("$sAlterableFileURI.scss", [ $sPath ], $oFindStylesheetObject, $bImports); $sImportedFile = false; } } @@ -924,7 +925,7 @@ CSS; // file matched: _typo.scss $sShortCut = substr($sFilePath, strrpos($sFilePath, '/') + 1); $sFilePath = static::ReplaceLastOccurrence($sShortCut, "_$sShortCut.scss", $sFilePath); - $sFileURI = static::ReplaceLastOccurrence($sShortCut, "_$sShortCut.scss", $sFileURI); + $sAlterableFileURI = static::ReplaceLastOccurrence($sShortCut, "_$sShortCut.scss", $sAlterableFileURI); $sImportedFile = realpath($sFilePath); } @@ -932,14 +933,14 @@ CSS; && (!$oFindStylesheetObject->AlreadyFetched($sImportedFile))) { if ($bImports){ - $oFindStylesheetObject->AddImport($sFileURI, $sImportedFile); + $oFindStylesheetObject->AddImport($sAlterableFileURI, $sImportedFile); }else{ - $oFindStylesheetObject->AddStylesheet($sFileURI, $sImportedFile); + $oFindStylesheetObject->AddStylesheet($sAlterableFileURI, $sImportedFile); } $oFindStylesheetObject->UpdateLastModified($sImportedFile); //Regexp matching on all included scss files : @import 'XXX.scss'; - $sDirUri = dirname($sFileURI); + $sDirUri = dirname($sAlterableFileURI); preg_match_all('/@import \s*[\"\']([^\"\']*)\s*[\"\']\s*;/', file_get_contents($sImportedFile), $aMatches); if ( (is_array($aMatches)) && (count($aMatches)!==0) ){ foreach ($aMatches[1] as $sImportedFile){ diff --git a/core/ormStyle.class.inc.php b/core/ormStyle.class.inc.php index 72c8afdd6..e435200af 100644 --- a/core/ormStyle.class.inc.php +++ b/core/ormStyle.class.inc.php @@ -7,7 +7,7 @@ /** * Class ormStyle * - * @since 3.0.0 + * @since 3.0 */ class ormStyle { diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php index d8444f8b4..dc5610060 100644 --- a/setup/compiler.class.inc.php +++ b/setup/compiler.class.inc.php @@ -84,6 +84,11 @@ class MFCompiler protected $sMainPHPCode; // Code that goes into core/main.php protected $aSnippets; protected $aRelations; + /** + * @var array Strings containing dynamic CSS definitions for DM classes + * @since 3.0.0 + */ + protected $aClassesCSSRules; protected $sEnvironment; protected $sCompilationTimeStamp; @@ -104,6 +109,7 @@ class MFCompiler $this->sMainPHPCode .= "define('COMPILATION_TIMESTAMP', '".$this->sCompilationTimeStamp."');\n"; $this->aSnippets = array(); $this->aRelations = array(); + $this->aClassesCSSRules = []; } protected function Log($sText) @@ -411,9 +417,6 @@ class MFCompiler } - /** array of strings containing dynamic CSS class definitions */ - $aClassesCss = []; - $oClasses = $this->oFactory->ListClasses($sModuleName); $iClassCount = $oClasses->length; if ($iClassCount == 0) @@ -429,7 +432,7 @@ class MFCompiler $aAllClasses[] = $sClass; try { - $sCompiledCode .= $this->CompileClass($oClass, $sTempTargetDir, $sFinalTargetDir, $sRelativeDir, $aClassesCss); + $sCompiledCode .= $this->CompileClass($oClass, $sTempTargetDir, $sFinalTargetDir, $sRelativeDir); } catch (DOMFormatException $e) { @@ -868,7 +871,17 @@ EOF return $sPHP; } - protected function GetPropString($oNode, $sTag, $sDefault = null) + /** + * @param $oNode + * @param string $sTag + * @param string|null $sDefault + * @param bool $bAddQuotes If true, surrounds property value with single quotes and escapes existing single quotes + * + * @return string|null + * + * @since 3.0.0 Add param. $bAddQuotes to be equivalent to {@see self::GetMandatoryPropString} and allow retrieving property without surrounding single quotes + */ + protected function GetPropString($oNode, string $sTag, string $sDefault = null, bool $bAddQuotes = true) { $val = $oNode->GetChildText($sTag); if (is_null($val)) @@ -882,18 +895,23 @@ EOF $val = $sDefault; } } - return "'".str_replace("'", "\\'", $val)."'"; + + if ($bAddQuotes) { + $val = "'".str_replace("'", "\\'", $val)."'"; + } + + return $val; } /** * @param $oNode - * @param $sTag + * @param string $sTag * @param bool $bAddQuotes * * @return string * @throws \DOMFormatException */ - protected function GetMandatoryPropString($oNode, $sTag, $bAddQuotes = true) + protected function GetMandatoryPropString($oNode, string $sTag, bool $bAddQuotes = true) { $val = $oNode->GetChildText($sTag); if (!is_null($val) && ($val !== '')) @@ -1084,17 +1102,17 @@ EOF * @param string $sTempTargetDir * @param string $sFinalTargetDir * @param string $sModuleRelativeDir - * @param array $aClassesCss Contains dynamic CSS class definitions * * @return string * @throws \DOMFormatException */ - protected function CompileClass($oClass, $sTempTargetDir, $sFinalTargetDir, $sModuleRelativeDir, &$aClassesCss) + protected function CompileClass($oClass, $sTempTargetDir, $sFinalTargetDir, $sModuleRelativeDir) { $sClass = $oClass->getAttribute('id'); $oProperties = $oClass->GetUniqueElement('properties'); $sPHP = ''; - $sCss = ''; // Contains dynamic CSS class definitions + /** @var Contains dynamic CSS class definitions $sCss */ + $sCss = ''; // Class caracteristics // @@ -1426,20 +1444,37 @@ EOF $aValues[] = $sCode; $oStyleNode = $oValue->GetOptionalElement('style'); if ($oStyleNode) { - $sMainColor = $this->GetMandatoryPropString($oStyleNode, 'main_color'); $sSafeCode = utils::GetSafeId($sCode); $sEnumClass = "ibo-enum--$sClass-$sAttCode-$sSafeCode"; $sEnumClassAlt = "ibo-enum-alt--$sClass-$sAttCode-$sSafeCode"; - $sComplementaryColor = $this->GetMandatoryPropString($oStyleNode, 'complementary_color'); + + $sMainColorForOrm = $this->GetMandatoryPropString($oStyleNode, 'main_color'); + $sMainColorForCss = $this->GetMandatoryPropString($oStyleNode, 'main_color', false); + $sMainColorScssVariableName = "\$$sEnumClass--main-color"; + $sMainColorCssVariableName = "--$sEnumClass--main-color"; + $sComplementaryColorForOrm = $this->GetMandatoryPropString($oStyleNode, 'complementary_color'); + $sComplementaryColorForCss = $this->GetMandatoryPropString($oStyleNode, 'complementary_color', false); + $sComplementaryColorScssVariableName = "\$$sEnumClass--complementary-color"; + $sComplementaryColorCssVariableName = "--$sEnumClass--complementary-color"; $sDecorationClasses = $this->GetPropString($oStyleNode, 'decoration_classes', ''); - $aStyledValues[] = "'$sCode' => new ormStyle('$sEnumClass', '$sEnumClassAlt', $sMainColor, $sComplementaryColor, $sDecorationClasses)"; + + $aStyledValues[] = "'$sCode' => new ormStyle('$sEnumClass', '$sEnumClassAlt', $sMainColorForOrm, $sComplementaryColorForOrm, $sDecorationClasses)"; $sCss .= <<GetOptionalElement('default_style'); - if ($oStyleNode) { - $sMainColor = $this->GetMandatoryPropString($oStyleNode, 'main_color'); + $oDefaultStyleNode = $oField->GetOptionalElement('default_style'); + if ($oDefaultStyleNode) { $sEnumClass = "ibo-enum--$sClass-$sAttCode"; $sEnumClassAlt = "ibo-enum-alt--$sClass-$sAttCode"; - $sComplementaryColor = $this->GetMandatoryPropString($oStyleNode, 'complementary_color'); - $sDecorationClasses = $this->GetPropString($oStyleNode, 'decoration_classes', ''); - $aParameters['default_style'] = "new ormStyle('$sEnumClass', '$sEnumClassAlt', $sMainColor, $sComplementaryColor, $sDecorationClasses)"; + + $sMainColorForOrm = $this->GetMandatoryPropString($oDefaultStyleNode, 'main_color'); + $sMainColorForCss = $this->GetMandatoryPropString($oDefaultStyleNode, 'main_color', false); + $sMainColorScssVariableName = "\$$sEnumClass--main-color"; + $sMainColorCssVariableName = "--$sEnumClass--main-color"; + $sComplementaryColorForOrm = $this->GetMandatoryPropString($oDefaultStyleNode, 'complementary_color'); + $sComplementaryColorForCss = $this->GetMandatoryPropString($oDefaultStyleNode, 'complementary_color', false); + $sComplementaryColorScssVariableName = "\$$sEnumClass--complementary-color"; + $sComplementaryColorCssVariableName = "--$sEnumClass--complementary-color"; + $sDecorationClasses = $this->GetPropString($oDefaultStyleNode, 'decoration_classes', ''); + + $aParameters['default_style'] = "new ormStyle('$sEnumClass', '$sEnumClassAlt', $sMainColorForOrm, $sComplementaryColorForOrm, $sDecorationClasses)"; $sCss .= <<GetOptionalElement('style'); if ($oStyleNode) { - $sMainColor = $this->GetMandatoryPropString($oStyleNode, 'main_color'); $sSafeCode = utils::GetSafeId($sCode); $sEnumClass = "ibo-enum--$sClass-$sAttCode-$sSafeCode"; $sEnumClassAlt = "ibo-enum-alt--$sClass-$sAttCode-$sSafeCode"; - $sComplementaryColor = $this->GetMandatoryPropString($oStyleNode, 'complementary_color'); + + $sMainColorForOrm = $this->GetMandatoryPropString($oStyleNode, 'main_color'); + $sMainColorForCss = $this->GetMandatoryPropString($oStyleNode, 'main_color', false); + $sMainColorScssVariableName = "\$$sEnumClass--main-color"; + $sMainColorCssVariableName = "--$sEnumClass--main-color"; + $sComplementaryColorForOrm = $this->GetMandatoryPropString($oStyleNode, 'complementary_color'); + $sComplementaryColorForCss = $this->GetMandatoryPropString($oStyleNode, 'complementary_color', false); + $sComplementaryColorScssVariableName = "\$$sEnumClass--complementary-color"; + $sComplementaryColorCssVariableName = "--$sEnumClass--complementary-color"; $sDecorationClasses = $this->GetPropString($oStyleNode, 'decoration_classes', ''); - $aStyledValues[] = "'$sCode' => new ormStyle('$sEnumClass', '$sEnumClassAlt', $sMainColor, $sComplementaryColor, $sDecorationClasses)"; + + $aStyledValues[] = "'$sCode' => new ormStyle('$sEnumClass', '$sEnumClassAlt', $sMainColorForOrm, $sComplementaryColorForOrm, $sDecorationClasses)"; $sCss .= <<GetOptionalElement('default_style'); - if ($oStyleNode) { - $sMainColor = $this->GetMandatoryPropString($oStyleNode, 'main_color'); + $oDefaultStyleNode = $oField->GetOptionalElement('default_style'); + if ($oDefaultStyleNode) { $sEnumClass = "ibo-enum--$sClass-$sAttCode"; $sEnumClassAlt = "ibo-enum-alt--$sClass-$sAttCode"; - $sComplementaryColor = $this->GetMandatoryPropString($oStyleNode, 'complementary_color'); - $sDecorationClasses = $this->GetPropString($oStyleNode, 'decoration_classes', ''); - $aParameters['default_style'] = "new ormStyle('$sEnumClass', '$sEnumClassAlt', $sMainColor, $sComplementaryColor, $sDecorationClasses)"; + + $sMainColorForOrm = $this->GetMandatoryPropString($oDefaultStyleNode, 'main_color'); + $sMainColorForCss = $this->GetMandatoryPropString($oDefaultStyleNode, 'main_color', false); + $sMainColorScssVariableName = "\$$sEnumClass--main-color"; + $sMainColorCssVariableName = "--$sEnumClass--main-color"; + $sComplementaryColorForOrm = $this->GetMandatoryPropString($oDefaultStyleNode, 'complementary_color'); + $sComplementaryColorForCss = $this->GetMandatoryPropString($oDefaultStyleNode, 'complementary_color', false); + $sComplementaryColorScssVariableName = "\$$sEnumClass--complementary-color"; + $sComplementaryColorCssVariableName = "--$sEnumClass--complementary-color"; + $sDecorationClasses = $this->GetPropString($oDefaultStyleNode, 'decoration_classes', ''); + + $aParameters['default_style'] = "new ormStyle('$sEnumClass', '$sEnumClassAlt', $sMainColorForOrm, $sComplementaryColorForOrm, $sDecorationClasses)"; $sCss .= <<GetAttribute('id').'"'; } $aParameters['states'] = 'array('.implode(', ', $aStates).')'; - + $aParameters['goal_computing'] = $this->GetPropString($oField, 'goal', 'DefaultMetricComputer'); // Optional, no deadline by default $aParameters['working_time_computing'] = $this->GetPropString($oField, 'working_time', ''); // Blank (different than DefaultWorkingTimeComputer) - + $oThresholds = $oField->GetUniqueElement('thresholds'); $oThresholdNodes = $oThresholds->getElementsByTagName('threshold'); $aThresholds = array(); foreach($oThresholdNodes as $oThreshold) { $iPercent = (int)$oThreshold->getAttribute('id'); - + $oHighlight = $oThreshold->GetUniqueElement('highlight', false); $sHighlight = ''; if($oHighlight) @@ -1612,7 +1698,7 @@ CSS; $sPersistent = $this->GetPropBoolean($oHighlight, 'persistent', false); $sHighlight = "'highlight' => array('code' => '$sCode', 'persistent' => $sPersistent), "; } - + $oActions = $oThreshold->GetUniqueElement('actions'); $oActionNodes = $oActions->getElementsByTagName('action'); $aActions = array(); @@ -1781,7 +1867,7 @@ CSS; { $aParameters['tracking_level'] = $this->TrackingLevelToPHP($sAttType, $sTrackingLevel); } - + $aParams = array(); foreach($aParameters as $sKey => $sValue) { @@ -1795,10 +1881,10 @@ CSS; } catch(Exception $e) { - throw new DOMFormatException("Field: '$sAttCode', (type: $sAttType), ".$e->getMessage()); + throw new DOMFormatException("Field: '$sAttCode', (type: $sAttType), ".$e->getMessage()); } } - + // Lifecycle // $sLifecycle = ''; @@ -1807,13 +1893,13 @@ CSS; if ($oLifecycle) { $sLifecycle .= "\t\t// Lifecycle (status attribute: $sStateAttCode)\n"; $sLifecycle .= "\t\t//\n"; - + $oStimuli = $oLifecycle->GetUniqueElement('stimuli'); foreach ($oStimuli->getElementsByTagName('stimulus') as $oStimulus) { $sStimulus = $oStimulus->getAttribute('id'); $sStimulusClass = $oStimulus->getAttribute('xsi:type'); - + $sLifecycle .= " MetaModel::Init_DefineStimulus(new ".$sStimulusClass."(\"".$sStimulus."\", array()));\n"; } $oHighlightScale = $oLifecycle->GetUniqueElement('highlight_scale', false); @@ -1821,9 +1907,9 @@ CSS; { $sHighlightScale = "\t\t// Higlight Scale\n"; $sHighlightScale .= " MetaModel::Init_DefineHighlightScale( array(\n"; - + $this->CompileFiles($oHighlightScale, $sTempTargetDir.'/'.$sModuleRelativeDir, $sFinalTargetDir.'/'.$sModuleRelativeDir, ''); - + foreach ($oHighlightScale->getElementsByTagName('item') as $oItem) { $sItemCode = $oItem->getAttribute('id'); @@ -1845,32 +1931,32 @@ CSS; case 'HIGHLIGHT_CLASS_CRITICAL': $sColor = 'HILIGHT_CLASS_CRITICAL'; break; - + case 'HILIGHT_CLASS_OK': case 'HIGHLIGHT_CLASS_OK': $sColor = 'HILIGHT_CLASS_OK'; break; - + case 'HIGHLIGHT_CLASS_WARNING': case 'HILIGHT_CLASS_WARNING': $sColor = 'HILIGHT_CLASS_WARNING'; break; - + case 'HIGHLIGHT_CLASS_NONE': case 'HILIGHT_CLASS_NONE': $sColor = 'HILIGHT_CLASS_NONE'; break; - + default: // Future extension, specify your own color?? $sColor = "'".addslashes($sColor)."'"; } $sHighlightScale .= " '$sItemCode' => array('rank' => $fRank, 'color' => $sColor, 'icon' => $sIcon),\n"; - + } $sHighlightScale .= " ));\n"; } - + $oStates = $oLifecycle->GetUniqueElement('states'); $aStatesDependencies = array(); $aStates = array(); @@ -1946,9 +2032,9 @@ CSS; { $sLifecycle .= " 'highlight' => array('code' => '$sCode'),\n"; } - + } - + $sLifecycle .= " \"attribute_list\" => array(\n"; $oFlags = $oState->GetUniqueElement('flags'); @@ -1969,13 +2055,13 @@ CSS; } $sLifecycle .= " )\n"; $sLifecycle .= " );\n"; - + $oTransitions = $oState->GetUniqueElement('transitions'); foreach ($oTransitions->getElementsByTagName('transition') as $oTransition) { $sStimulus = $oTransition->getAttribute('id'); $sTargetState = $oTransition->GetChildText('target'); - + $oActions = $oTransition->GetUniqueElement('actions'); $aVerbs = array(); foreach ($oActions->getElementsByTagName('action') as $oAction) @@ -2051,7 +2137,7 @@ CSS; $sLifecycle .= " );\n"; } } - + // ZLists // $aListRef = array( @@ -2060,7 +2146,7 @@ CSS; 'default_search' => 'default_search', 'list' => 'list', ); - + $oPresentation = $oClass->GetUniqueElement('presentation'); $sZlists = ''; foreach ($aListRef as $sListCode => $sListTag) @@ -2074,12 +2160,12 @@ CSS; $aAttributes = array(); } $this->ArrayOfItemsToZList($aAttributes); - + $sZAttributes = var_export($aAttributes, true); $sZlists .= " MetaModel::Init_SetZListItems('$sListCode', $sZAttributes);\n"; } } - + // Methods $sMethods = ""; $oMethods = $oClass->GetUniqueElement('methods'); @@ -2093,7 +2179,7 @@ CSS; else { $sMethods .= "\n\n".$sMethodCode."\n"; - } + } } // Relations @@ -2247,7 +2333,12 @@ EOF } } - $aClassesCss[] = $sCss; + if (strlen($sCss) > 0) { + if (array_key_exists($sClass, $this->aClassesCSSRules) === false) { + $this->aClassesCSSRules[$sClass] = ''; + } + $this->aClassesCSSRules[$sClass] .= $sCss; + } return $sPHP; } @@ -2884,12 +2975,20 @@ EOF; ); // Build compiled themes folder - $sThemesDir = $sTempTargetDir.'branding/themes/'; - if(!is_dir($sThemesDir)) + $sThemesRelDirPath = 'branding/themes/'; + $sThemesAbsDirPath = $sTempTargetDir.$sThemesRelDirPath; + if(!is_dir($sThemesAbsDirPath)) { - SetupUtils::builddir($sThemesDir); + SetupUtils::builddir($sThemesAbsDirPath); } + // Prepare DM CSS rules for inclusion + $sDmStylesheetFilename = 'datamodel-scss-rules.scss'; + $sDmStylesheetContent = implode("\n", $this->aClassesCSSRules); + // Here we use a hash instead of the current timestamp because the former changes when running unit tests + $sDmStylesheetId = 'datamodel-scss-rules-'.md5($sDmStylesheetContent); + $this->WriteFile($sThemesAbsDirPath.$sDmStylesheetFilename, $sDmStylesheetContent); + // Parsing themes from DM $aThemes = array(); /** @var \DOMNodeList $oThemeNodes */ @@ -2925,6 +3024,8 @@ EOF; } } + // Stylesheets + // - Manually added in the XML /** @var \DOMNodeList $oStylesheets */ $oStylesheets = $oTheme->GetNodes('stylesheets/stylesheet'); foreach($oStylesheets as $oStylesheet) @@ -2933,6 +3034,9 @@ EOF; $aThemeParameters['stylesheets'][$sStylesheetId] = $oStylesheet->GetText(); } + // - Computed from the DM + $aThemeParameters['stylesheets'][$sDmStylesheetId] = $sThemesRelDirPath.$sDmStylesheetFilename; + $aThemes[$sThemeId] = [ 'theme_parameters' => $aThemeParameters, 'precompiled_stylesheet' => $oTheme->GetChildText('precompiled_stylesheet', '') @@ -2943,6 +3047,7 @@ EOF; if(empty($aThemes)) { $aDefaultThemeInfo = ThemeHandler::GetDefaultThemeInformation(); + $aDefaultThemeInfo['parameters']['stylesheets'][$sDmStylesheetId] = $sThemesRelDirPath.$sDmStylesheetFilename; $aThemes[$aDefaultThemeInfo['name']] = $aDefaultThemeInfo['parameters']; } @@ -2958,7 +3063,7 @@ EOF; $aThemeParameters = $aThemeInfos['theme_parameters']; $sPrecompiledStylesheet = $aThemeInfos['precompiled_stylesheet']; - $sThemeDir = $sThemesDir.$sThemeId; + $sThemeDir = $sThemesAbsDirPath.$sThemeId; if(!is_dir($sThemeDir)) { SetupUtils::builddir($sThemeDir); diff --git a/sources/application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php b/sources/application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php index b300e7414..269bbdac2 100644 --- a/sources/application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php +++ b/sources/application/UI/Base/Component/FieldBadge/FieldBadgeUIBlockFactory.php @@ -38,16 +38,6 @@ class FieldBadgeUIBlockFactory extends AbstractUIBlockFactory $sHtml .= ""; } $sHtml .= "$sValue"; - // Add custom style - // TODO 3.0 To be removed when compilation supports generated CSS - $sHtml .= << -.$sStyleClass { - color: $sComplementaryColor; - background-color: $sPrimaryColor; - } - -HTML; } } if (!$oBadge) {