|
45 | 45 | // Publish service instance
|
46 | 46 | return {
|
47 | 47 | applyThemeColors: applyThemeColors,
|
48 |
| - getThemeColor: getThemeColor |
| 48 | + getThemeColor: getThemeColor, |
| 49 | + hasTheme: hasTheme |
49 | 50 | };
|
50 | 51 |
|
51 | 52 | // ********************************************
|
|
80 | 81 | try {
|
81 | 82 | // Assign the calculate RGBA color values directly as inline CSS
|
82 | 83 | element.css(interpolateColors(colorExpression));
|
83 |
| - } catch( e ) { |
| 84 | + } catch (e) { |
84 | 85 | $log.error(e.message);
|
85 | 86 | }
|
86 | 87 |
|
|
154 | 155 | return rgbColors;
|
155 | 156 | }
|
156 | 157 |
|
| 158 | + /** |
| 159 | + * Check if expression has defined theme |
| 160 | + * e.g. |
| 161 | + * 'myTheme-primary' => true |
| 162 | + * 'red-800' => false |
| 163 | + */ |
| 164 | + function hasTheme(expression) { |
| 165 | + return angular.isDefined($mdTheming.THEMES[expression.split('-')[0]]); |
| 166 | + } |
| 167 | + |
157 | 168 | /**
|
158 | 169 | * For the evaluated expression, extract the color parts into a hash map
|
159 | 170 | */
|
|
198 | 209 | var themeColors = $mdTheming.THEMES[theme].colors;
|
199 | 210 |
|
200 | 211 | if (parts[1] === 'hue') {
|
201 |
| - var hueNumber = parseInt(parts.splice(2, 1)[0],10); |
| 212 | + var hueNumber = parseInt(parts.splice(2, 1)[0], 10); |
202 | 213 |
|
203 | 214 | if (hueNumber < 1 || hueNumber > 3) {
|
204 | 215 | throw new Error($mdUtil.supplant('mdColors: \'hue-{hueNumber}\' is not a valid hue, can be only \'hue-1\', \'hue-2\' and \'hue-3\'', {hueNumber: hueNumber}));
|
|
260 | 271 | function MdColorsDirective($mdColors, $mdUtil, $log, $parse) {
|
261 | 272 | return {
|
262 | 273 | restrict: 'A',
|
| 274 | + require: ['^?mdTheme'], |
263 | 275 | compile: function (tElem, tAttrs) {
|
264 | 276 | var shouldWatch = shouldColorsWatch();
|
265 | 277 |
|
266 |
| - return function (scope, element, attrs) { |
267 |
| - var colorExpression = function () { |
268 |
| - // Json.parse() does not work because the keys are not quoted; |
269 |
| - // use $parse to convert to a hash map |
270 |
| - return $parse(attrs.mdColors)(scope); |
| 278 | + return function (scope, element, attrs, ctrl) { |
| 279 | + var mdThemeController = ctrl[0]; |
| 280 | + |
| 281 | + var parseColors = function (theme) { |
| 282 | + /** |
| 283 | + * Json.parse() does not work because the keys are not quoted; |
| 284 | + * use $parse to convert to a hash map |
| 285 | + */ |
| 286 | + var colors = $parse(attrs.mdColors)(scope); |
| 287 | + |
| 288 | + /** |
| 289 | + * If mdTheme is defined up the DOM tree |
| 290 | + * we add mdTheme theme to colors who doesn't specified a theme |
| 291 | + * |
| 292 | + * # example |
| 293 | + * <hljs lang="html"> |
| 294 | + * <div md-theme="myTheme"> |
| 295 | + * <div md-colors="{background: 'primary-600'}"> |
| 296 | + * <span md-colors="{background: 'mySecondTheme-accent-200'}">Color demo</span> |
| 297 | + * </div> |
| 298 | + * </div> |
| 299 | + * </hljs> |
| 300 | + * |
| 301 | + * 'primary-600' will be 'myTheme-primary-600', |
| 302 | + * but 'mySecondTheme-accent-200' will stay the same cause it has a theme prefix |
| 303 | + */ |
| 304 | + if (mdThemeController) { |
| 305 | + Object.keys(colors).forEach(function (prop) { |
| 306 | + var color = colors[prop]; |
| 307 | + if (!$mdColors.hasTheme(color)) { |
| 308 | + colors[prop] = (theme || mdThemeController.$mdTheme) + '-' + color; |
| 309 | + } |
| 310 | + }); |
| 311 | + } |
| 312 | + |
| 313 | + return colors; |
271 | 314 | };
|
272 | 315 |
|
| 316 | + /** |
| 317 | + * Registering for mgTheme changes and asking mdTheme controller run our callback whenever a theme changes |
| 318 | + */ |
| 319 | + var unregisterChanges = angular.noop; |
| 320 | + |
| 321 | + if (mdThemeController) { |
| 322 | + unregisterChanges = mdThemeController.registerChanges(function (theme) { |
| 323 | + $mdColors.applyThemeColors(element, parseColors(theme)); |
| 324 | + }); |
| 325 | + } |
| 326 | + |
| 327 | + scope.$on('destroy', function () { |
| 328 | + unregisterChanges(); |
| 329 | + }); |
| 330 | + |
273 | 331 | try {
|
274 | 332 | if (shouldWatch) {
|
275 |
| - scope.$watch(colorExpression, angular.bind(this, |
| 333 | + scope.$watch(parseColors, angular.bind(this, |
276 | 334 | $mdColors.applyThemeColors, element
|
277 | 335 | ), true);
|
278 | 336 | }
|
279 | 337 | else {
|
280 |
| - $mdColors.applyThemeColors(element, colorExpression()); |
| 338 | + $mdColors.applyThemeColors(element, parseColors()); |
281 | 339 | }
|
282 | 340 |
|
283 | 341 | }
|
|
288 | 346 | };
|
289 | 347 |
|
290 | 348 | function shouldColorsWatch() {
|
291 |
| - // Simulate 1x binding and mark mdColorsWatch == false |
292 |
| - var rawColorExpression = tAttrs.mdColors; |
293 |
| - var bindOnce = rawColorExpression.indexOf('::') > -1; |
294 |
| - var isStatic = bindOnce ? true : STATIC_COLOR_EXPRESSION.test(tAttrs.mdColors); |
| 349 | + // Simulate 1x binding and mark mdColorsWatch == false |
| 350 | + var rawColorExpression = tAttrs.mdColors; |
| 351 | + var bindOnce = rawColorExpression.indexOf('::') > -1; |
| 352 | + var isStatic = bindOnce ? true : STATIC_COLOR_EXPRESSION.test(tAttrs.mdColors); |
295 | 353 |
|
296 |
| - // Remove it for the postLink... |
297 |
| - tAttrs.mdColors = rawColorExpression.replace('::',''); |
| 354 | + // Remove it for the postLink... |
| 355 | + tAttrs.mdColors = rawColorExpression.replace('::', ''); |
298 | 356 |
|
299 |
| - var hasWatchAttr = angular.isDefined(tAttrs.mdColorsWatch); |
| 357 | + var hasWatchAttr = angular.isDefined(tAttrs.mdColorsWatch); |
300 | 358 |
|
301 |
| - return (bindOnce || isStatic) ? false : |
302 |
| - hasWatchAttr ? $mdUtil.parseAttributeBoolean(tAttrs.mdColorsWatch) : true; |
303 |
| - } |
| 359 | + return (bindOnce || isStatic) ? false : |
| 360 | + hasWatchAttr ? $mdUtil.parseAttributeBoolean(tAttrs.mdColorsWatch) : true; |
| 361 | + } |
304 | 362 | }
|
305 | 363 | };
|
306 | 364 |
|
|
0 commit comments