-
Notifications
You must be signed in to change notification settings - Fork 3.4k
feat(themes): register theme on the fly #9413
Conversation
e0ecde8
to
9310a84
Compare
@topherfangio we should find a better approach |
it('does not warns when an unregistered theme is used', function() { | ||
inject(function($log, $compile, $rootScope) { | ||
spyOn($log, 'warn'); | ||
$compile('<div md-deferred-theme="unregistered"></div>')($rootScope); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You actually would want this to warn because the theme isn't registered. This approach loses that information.
@EladBezalel I have another idea. Instead of using a string in md-theme, can you use an object, at least in the deferred class? That way we know if it will be created since the object needs to come from somewhere. |
9310a84
to
3910466
Compare
2681002
to
c72246e
Compare
} | ||
// Iterating backwards to support unregistering during iteration | ||
// http://stackoverflow.com/a/9882349/890293 | ||
for (var i = registeredCallbacks.length - 1; i >= 0; i -= 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't the following work?
registeredCallbacks.reverse().forEach(function(callback) {
Note: forEach
keeps the right order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe 😅 i'll check
c72246e
to
ac16f25
Compare
// Allow us to be invoked via a linking function signature. | ||
var applyTheme = function (scope, el) { | ||
if (el === undefined) { el = scope; scope = undefined; } | ||
if (scope === undefined) { scope = $rootScope; } | ||
applyTheme.inherit(el, el); | ||
}; | ||
|
||
applyTheme.THEMES = angular.extend({}, THEMES); | ||
applyTheme.PALETTES = angular.extend({}, PALETTES); | ||
Object.defineProperty(applyTheme, 'THEMES', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this complexity... unless you want generate the THEMES object on demand (each time the getter is accessed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, generating it once doesn't support themes that are registered on the fly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading this code, the following assertion happen, which seems like the wrong logic:
applyTheme.THEMES !== applyTheme.THEMES
And any app that changes THEMES (say by calling generateTheme
) would not change references to THEMES that already exist.
Looks pretty interesting. Any usage docs so that we can play with it and test it out? 😃 |
Actually I was testing on button demo, had a timeout to resolve a new defined theme after 2 seconds |
@EladBezalel Ok. Can you share that code at least so that we can do some testing on our local machines? Also, this will need docs before we merge it, right? |
There are no docs for the theming service at all.. I wanted to add it but it requires even more work on that.. |
Run |
ac16f25
to
f6e667e
Compare
if ((alwaysWatchTheme && !registerChangeCallback()) || (!alwaysWatchTheme && watchTheme)) { | ||
el.on('$destroy', $rootScope.$watch(lookupThemeName, updateThemeClass) ); | ||
if (ctrl) { | ||
var watchTheme = alwaysWatchTheme || ctrl.$shouldWatch || $mdUtil.parseAttributeBoolean(el.attr('md-theme-watch')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: line too long here :)
|
||
it('should accept $q promise as a theme', function() { | ||
inject(function($compile, $rootScope, $q, $mdTheming) { | ||
$rootScope.promise = $q.resolve('red'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I thought there was a method on $mdTheming
that returns a promise (which eventually is the resolve). To make this test more robust and closer to real use, can you use that method instead of just resolve with a string.
54328ae
to
72ff924
Compare
@@ -453,6 +453,7 @@ describe('$mdThemeProvider with custom styles', function() { | |||
// Verify that $MD_THEME_CSS is still set to '/**/' in the test environment. | |||
// Check angular-material-mocks.js for $MD_THEME_CSS latest value if this test starts to fail. | |||
expect($MD_THEME_CSS).toBe('/**/'); | |||
expect($MD_THEME_CSS).toBe('/**/'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate line?
LGTM |
registeredCallbacks.forEach(function (cb) { | ||
cb(); | ||
// Iterating backwards to support unregistering during iteration | ||
// http://stackoverflow.com/a/9882349/890293 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that comment now invalid? since we are now using a simple reverse
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's still explaining why are we iterating backwards
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The URL does in my case only shows how to loop backwards. But does not explain why we do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The array is being re-indexed when you do a .splice(), which means you'll skip over an index when one is removed, and your cached .length is obsolete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a big deal. But where do we explicitly use a splice
here? I can see no splice and .length` anymore :)
The comment is reasonable if we still use the snippet of that Stackoverflow, and it's still difficult enough to require some extra documentation.
Let's keep it as it is.
72ff924
to
6837c1b
Compare
- Added `defineTheme` functionality to `$mdTheming` service - Added support for promise and a function that returns a promise on `md-theme` directive to support async build of themes fixes #2965
6837c1b
to
433a305
Compare
This reverts commit 0d2386c.
defineTheme
functionality to$mdTheming
servicemd-theme
directive to support async build of themesfixes #2965