in src/core/services/theming/theming.js [1001:1122]
function parseRules(theme, colorType, rules) {
checkValidPalette(theme, colorType);
rules = rules.replace(/THEME_NAME/g, theme.name);
var themeNameRegex = new RegExp('\\.md-' + theme.name + '-theme', 'g');
// Matches '{{ primary-color }}', etc
var hueRegex = new RegExp('([\'"])?{{\\s*([a-zA-Z]+)-?(color|default)?-?(contrast)?-?((?:\\d\\.?\\d*)|(?:[a-zA-Z]+))?\\s*}}(["\'])?','g');
var simpleVariableRegex = /'?"?{{\s*([a-zA-Z]+)-(A?\d+|hue-[0-3]|shadow|default)-?(contrast)?-?((?:\d\.?\d*)|(?:[a-zA-Z]+))?\s*}}'?"?/g;
var defaultBgHue = theme.colors['background'].hues['default'];
var defaultBgContrastType = PALETTES[theme.colors['background'].name][defaultBgHue].contrastType;
// find and replace simple variables where we use a specific hue, not an entire palette
// eg. "{{primary-100}}"
// \(' + THEME_COLOR_TYPES.join('\|') + '\)'
rules = rules.replace(simpleVariableRegex, function(match, colorType, hue, contrast, opacity) {
var regexColorType = colorType;
if (colorType === 'foreground') {
if (hue === 'shadow') {
return theme.foregroundShadow;
} else if (theme.foregroundPalette[hue]) {
// Use user defined palette number (ie: foreground-2)
return rgba(colorToRgbaArray(theme.foregroundPalette[hue]));
} else if (theme.foregroundPalette['1']){
return rgba(colorToRgbaArray(theme.foregroundPalette['1']));
}
// Default to background-default-contrast-{opacity}
colorType = 'background';
contrast = 'contrast';
if (!opacity && hue) {
// Convert references to legacy hues to opacities (i.e. foreground-4 to *-divider)
switch (hue) {
// hue-1 uses default opacity
case '2':
opacity = 'secondary';
break;
case '3':
opacity = 'disabled';
break;
case '4':
opacity = 'divider';
}
}
hue = 'default';
}
// `default` is also accepted as a hue-value, because the background palettes are
// using it as a name for the default hue.
if (hue.indexOf('hue') === 0 || hue === 'default') {
hue = theme.colors[colorType].hues[hue];
}
var colorDetails = (PALETTES[ theme.colors[colorType].name ][hue] || '');
// If user has specified a foreground color, use those
if (colorType === 'background' && contrast && regexColorType !== 'foreground' &&
colorDetails.contrastType === defaultBgContrastType) {
// Don't process if colorType was changed
switch (opacity) {
case 'secondary':
case 'icon':
if (theme.foregroundPalette['2']) {
return rgba(colorToRgbaArray(theme.foregroundPalette['2']));
}
break;
case 'disabled':
case 'hint':
if (theme.foregroundPalette['3']) {
return rgba(colorToRgbaArray(theme.foregroundPalette['3']));
}
break;
case 'divider':
if (theme.foregroundPalette['4']) {
return rgba(colorToRgbaArray(theme.foregroundPalette['4']));
}
break;
default:
if (theme.foregroundPalette['1']) {
return rgba(colorToRgbaArray(theme.foregroundPalette['1']));
}
break;
}
}
if (contrast && opacity) {
opacity = colorDetails.opacity[opacity] || opacity;
}
return rgba(colorDetails[contrast ? 'contrast' : 'value'], opacity);
});
var generatedRules = [];
// For each type, generate rules for each hue (ie. default, md-hue-1, md-hue-2, md-hue-3)
angular.forEach(['default', 'hue-1', 'hue-2', 'hue-3'], function(hueName) {
var newRule = rules
.replace(hueRegex, function(match, _, matchedColorType, hueType, contrast, opacity) {
var color = theme.colors[matchedColorType];
var palette = PALETTES[color.name];
var hueValue = color.hues[hueName];
if (contrast && opacity) {
opacity = palette[hueValue].opacity[opacity] || opacity;
}
return rgba(palette[hueValue][hueType === 'color' ? 'value' : 'contrast'], opacity);
});
if (hueName !== 'default') {
newRule = newRule.replace(themeNameRegex, '.md-' + theme.name + '-theme.md-' + hueName);
}
// Don't apply a selector rule to the default theme, making it easier to override
// styles of the base-component
if (theme.name === 'default') {
var themeRuleRegex = /((?:\s|>|\.|\w|-|:|\(|\)|\[|]|"|'|=)*)\.md-default-theme((?:\s|>|\.|\w|-|:|\(|\)|\[|]|"|'|=)*)/g;
newRule = newRule.replace(themeRuleRegex, function(match, start, end) {
return match + ', ' + start + end;
});
}
generatedRules.push(newRule);
});
return generatedRules;
}