Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 9521a1e

Browse files
ThomasBurlesonRobert Messerle
authored andcommitted
fix(icons): support for ngDirectives using compile phase
1 parent 3f6b4af commit 9521a1e

File tree

2 files changed

+82
-38
lines changed

2 files changed

+82
-38
lines changed

src/components/icon/iconDirective.js

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -148,36 +148,9 @@ function mdIconDirective($mdIcon, $mdTheming, $mdAria, $interpolate ) {
148148
svgSrc : '@mdSvgSrc'
149149
},
150150
restrict: 'E',
151-
transclude:true,
152-
template: getTemplate,
153-
link: postLink
151+
link : postLink
154152
};
155153

156-
function getTemplate(element, attr) {
157-
var isEmptyAttr = function(key) { return angular.isDefined(attr[key]) ? attr[key].length == 0 : false },
158-
hasAttrValue = function(key) { return attr[key] && attr[key].length > 0; },
159-
attrValue = function(key) { return hasAttrValue(key) ? attr[key] : '' };
160-
161-
// If using the deprecated md-font-icon API
162-
// If using ligature-based font-icons, transclude the ligature or NRCs
163-
164-
var tmplFontIcon = '<span class="md-font {{classNames}}" ng-class="fontIcon"></span>';
165-
var tmplFontSet = '<span class="{{classNames}}" ng-transclude></span>';
166-
167-
var tmpl = hasAttrValue('mdSvgIcon') ? '' :
168-
hasAttrValue('mdSvgSrc') ? '' :
169-
isEmptyAttr('mdFontIcon') ? '' :
170-
hasAttrValue('mdFontIcon') ? tmplFontIcon : tmplFontSet;
171-
172-
// If available, lookup the fontSet style and add to the list of classnames
173-
// NOTE: Material Icons expects classnames like `.material-icons.md-48` instead of `.material-icons .md-48`
174-
175-
var names = (tmpl == tmplFontSet) ? $mdIcon.fontSet(attrValue('mdFontSet')) + ' ' : '';
176-
names = (names + attrValue('class')).trim();
177-
178-
return $interpolate( tmpl )({ classNames: names });
179-
}
180-
181154

182155
/**
183156
* Directive postLink
@@ -186,6 +159,8 @@ function mdIconDirective($mdIcon, $mdTheming, $mdAria, $interpolate ) {
186159
function postLink(scope, element, attr) {
187160
$mdTheming(element);
188161

162+
prepareForFontIcon();
163+
189164
// If using a font-icon, then the textual name of the icon itself
190165
// provides the aria-label.
191166

@@ -220,6 +195,7 @@ function mdIconDirective($mdIcon, $mdTheming, $mdAria, $interpolate ) {
220195

221196
});
222197
}
198+
223199
function parentsHaveText() {
224200
var parent = element.parent();
225201
if (parent.attr('aria-label') || parent.text()) {
@@ -230,5 +206,17 @@ function mdIconDirective($mdIcon, $mdTheming, $mdAria, $interpolate ) {
230206
}
231207
return false;
232208
}
209+
210+
function prepareForFontIcon () {
211+
if (!scope.svgIcon && !scope.svgSrc) {
212+
if (scope.fontIcon) {
213+
element.addClass('md-font');
214+
element.addClass(scope.fontIcon);
215+
} else {
216+
element.addClass($mdIcon.fontSet(scope.fontSet));
217+
}
218+
}
219+
220+
}
233221
}
234222
}

src/components/icon/iconDirective.spec.js

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,67 +25,112 @@ describe('mdIcon directive', function() {
2525

2626
it('should render correct HTML with md-font-icon value as class', function() {
2727
el = make( '<md-icon md-font-icon="android"></md-icon>');
28-
expect(el.html()).toEqual('<span class="md-font android" ng-class="fontIcon"></span>');
28+
29+
expect(el.html()).toEqual('');
30+
expect( clean(el.attr('class')) ).toEqual("md-font android");
31+
2932
});
3033

3134
it('should transclude class specifiers', function() {
3235
el = make( '<md-icon md-font-icon="android" class="material-icons"></md-icon>');
33-
expect(el.html()).toEqual('<span class="md-font material-icons android" ng-class="fontIcon"></span>');
36+
37+
expect(el.html()).toEqual('');
38+
expect(el.hasClass('md-font')).toBe(true);
39+
expect(el.hasClass('android')).toBe(true);
40+
expect(el.hasClass('material-icons')).toBe(true);
3441
});
3542

3643
it('should not render any inner content if the md-font-icon value is empty', function() {
3744
el = make( '<md-icon md-font-icon=""></md-icon>' );
3845
expect(el.html()).toEqual('');
3946
});
4047

48+
it('',function() {
49+
el = make('\
50+
<md-icon \
51+
md-font-icon="{{ font.name }}" \
52+
aria-label="{{ font.name + font.size }}" \
53+
class="step" > \
54+
</md-icon> \
55+
');
56+
57+
$scope.$apply(function(){
58+
$scope.font = {
59+
name: 'icon-home',
60+
color: "#777",
61+
size: 48
62+
};
63+
});
64+
65+
expect(el.attr('md-font-icon')).toBe($scope.font.name);
66+
expect(el.hasClass('step')).toBe(true);
67+
expect(el.hasClass('material-icons')).toBe(true);
68+
expect(el.attr('aria-label')).toBe($scope.font.name + $scope.font.size);
69+
expect(el.attr('role')).toBe('img');
70+
})
71+
4172
});
4273

4374
describe('using font-icons with ligatures: md-font-set=""', function() {
4475

4576
it('should render correct HTML with ligatures', function() {
4677
el = make( '<md-icon class="md-48">face</md-icon>');
47-
expect(el.html()).toEqual('<span class="material-icons md-48" ng-transclude=""><span class="ng-scope">face</span></span>');
78+
79+
expect(el.text()).toEqual('face');
80+
expect(el.hasClass('material-icons')).toBeTruthy();
81+
expect(el.hasClass('md-48')).toBeTruthy();
4882
});
4983

5084
it('should render correctly using a md-font-set alias', function() {
5185
$mdIconProvider.fontSet('fa', 'fontawesome');
5286

5387
el = make( '<md-icon md-font-set="fa">email</md-icon>');
54-
expect(el.html()).toEqual('<span class="fontawesome" ng-transclude=""><span class="ng-scope">email</span></span>');
88+
89+
expect(el.text()).toEqual('email');
90+
expect( clean(el.attr('class')) ).toEqual("fontawesome");
5591
});
5692

5793
it('should render correctly using md-font-set value as class', function() {
5894

5995
el = make( '<md-icon md-font-set="fontawesome">email</md-icon>');
60-
expect(el.html()).toEqual('<span class="fontawesome" ng-transclude=""><span class="ng-scope">email</span></span>');
96+
97+
expect(el.text()).toEqual('email');
98+
expect( clean(el.attr('class')) ).toEqual("fontawesome");
6199
});
62100
});
63101

64102
describe('using font-icons with classnames', function() {
65103

66104
it('should render with icon classname', function() {
67105
el = make( '<md-icon class="custom-cake"></md-icon>');
68-
expect(el.html()).toEqual('<span class="material-icons custom-cake" ng-transclude=""></span>');
106+
107+
expect(el.text()).toEqual('');
108+
expect(el.hasClass('material-icons')).toBeTruthy();
109+
expect(el.hasClass('custom-cake')).toBeTruthy();
69110
});
70111

71112
it('should support clearing default fontset', function() {
72113
$mdIconProvider.defaultFontSet('');
73114

74115
el = make( '<md-icon class="custom-cake"></md-icon>');
75-
expect(el.html()).toEqual('<span class="custom-cake" ng-transclude=""></span>');
116+
expect( clean(el.attr('class')) ).toEqual("custom-cake");
76117

77118
el = make( '<md-icon class="custom-cake">apple</md-icon>');
78-
expect(el.html()).toEqual('<span class="custom-cake" ng-transclude=""><span class="ng-scope">apple</span></span>');
119+
expect(el.text()).toEqual('apple');
120+
expect( clean(el.attr('class')) ).toEqual("custom-cake");
79121

80122
});
81123

82124
it('should support clearing an invalid font alias', function() {
83125

84126
el = make( '<md-icon md-font-set="none" class="custom-cake"></md-icon>');
85-
expect(el.html()).toEqual('<span class="none custom-cake" ng-transclude=""></span>');
127+
expect(el.hasClass('none')).toBeTruthy();
128+
expect(el.hasClass('custom-cake')).toBeTruthy();
86129

87130
el = make( '<md-icon md-font-set="none" class="custom-cake">apple</md-icon>');
88-
expect(el.html()).toEqual('<span class="none custom-cake" ng-transclude=""><span class="ng-scope">apple</span></span>');
131+
expect(el.text()).toEqual('apple');
132+
expect(el.hasClass('none')).toBeTruthy();
133+
expect(el.hasClass('custom-cake')).toBeTruthy();
89134

90135
});
91136
});
@@ -224,5 +269,16 @@ describe('mdIcon directive', function() {
224269
return el;
225270
}
226271

272+
/**
273+
* Utility to remove extra attributes to the specs are easy to compare
274+
*/
275+
function clean(style) {
276+
return style
277+
.replace(/ng-scope|ng-isolate-scope|md-default-theme/gi,'')
278+
.replace(/\s\s+/g,' ')
279+
.replace(/\s+\"/g,'"')
280+
.trim();
281+
}
282+
227283

228284
});

0 commit comments

Comments
 (0)