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

Commit 8fc36d4

Browse files
committed
refactor(sidenav): remove md-sidenav-focus directive
BREAKING CHANGE: Removed the `md-sidenav-focus` directive. It was deprecated in favor of `md-autofocus`. Please see the [md-autofocus Docs](https://material.angularjs.org/latest/api/directive/mdAutofocus) and [md-sidenav Basic Usage Demo](https://material.angularjs.org/latest/demo/sidenav#basic-usage) for examples.
1 parent f023ce7 commit 8fc36d4

File tree

7 files changed

+31
-89
lines changed

7 files changed

+31
-89
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4739,7 +4739,7 @@ it is disabled, change it to an ng-disabled expression.
47394739
- **md-scroll-xy**
47404740
* <md-divider **md-inset**="" >
47414741
* <md-linear-progress **md-buffer-value**="someValue" **md-mode**="query" >
4742-
* <md-circular-rogress **md-mode**="query" **md-diameter**="60" >
4742+
* <md-circular-progress **md-mode**="query" **md-diameter**="60" >
47434743
* <md-sidenav>
47444744
- **md-is-open**="isOpen"
47454745
- **md-is-locked-open**="isLockedOpen"

src/components/sidenav/sidenav.js

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ angular
1212
])
1313
.factory('$mdSidenav', SidenavService)
1414
.directive('mdSidenav', SidenavDirective)
15-
.directive('mdSidenavFocus', SidenavFocusDirective)
1615
.controller('$mdSidenavController', SidenavController);
1716

1817

@@ -151,39 +150,6 @@ function SidenavService($mdComponentRegistry, $mdUtil, $q, $log) {
151150
}
152151
}
153152

154-
/**
155-
* @ngdoc directive
156-
* @name mdSidenavFocus
157-
* @module material.components.sidenav
158-
*
159-
* @restrict A
160-
*
161-
* @description
162-
* `mdSidenavFocus` provides a way to specify the focused element when a sidenav opens.
163-
* This is completely optional, as the sidenav itself is focused by default.
164-
*
165-
* @usage
166-
* <hljs lang="html">
167-
* <md-sidenav>
168-
* <form>
169-
* <md-input-container>
170-
* <label for="testInput">Label</label>
171-
* <input id="testInput" type="text" md-sidenav-focus>
172-
* </md-input-container>
173-
* </form>
174-
* </md-sidenav>
175-
* </hljs>
176-
**/
177-
function SidenavFocusDirective() {
178-
return {
179-
restrict: 'A',
180-
require: '^mdSidenav',
181-
link: function(scope, element, attr, sidenavCtrl) {
182-
// @see $mdUtil.findFocusTarget(...)
183-
}
184-
};
185-
}
186-
187153
/**
188154
* @ngdoc directive
189155
* @name mdSidenav
@@ -362,12 +328,10 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $mdInterac
362328

363329
/**
364330
* Toggle the SideNav view and attach/detach listeners
365-
* @param isOpen
331+
* @param {boolean} isOpen
366332
*/
367333
function updateIsOpen(isOpen) {
368-
// Support deprecated md-sidenav-focus attribute as fallback
369-
var focusEl = $mdUtil.findFocusTarget(element) ||
370-
$mdUtil.findFocusTarget(element,'[md-sidenav-focus]') || element;
334+
var focusEl = $mdUtil.findFocusTarget(element) || element;
371335
var parent = element.parent();
372336
var restorePositioning;
373337

src/components/sidenav/sidenav.spec.js

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -122,24 +122,6 @@ describe('mdSidenav', function() {
122122
expect($document.activeElement).toBe(el[0]);
123123
}));
124124

125-
it('should focus child with md-sidenav-focus', inject(function($rootScope, $material, $document, $compile) {
126-
jasmine.mockElementFocus(this);
127-
var parent = angular.element('<div>');
128-
var markup = '<md-sidenav md-is-open="show">' +
129-
' <md-input-container><label>Label</label>' +
130-
' <input type="text" md-sidenav-focus>' +
131-
' </md-input-container>' +
132-
'<md-sidenav>';
133-
var sidenavEl = angular.element(markup);
134-
parent.append(sidenavEl);
135-
$compile(parent)($rootScope);
136-
$rootScope.$apply('show = true');
137-
138-
var focusEl = sidenavEl.find('input');
139-
$material.flushOutstandingAnimations();
140-
expect($document.activeElement).toBe(focusEl[0]);
141-
}));
142-
143125
it('should focus child with md-autofocus', inject(function($rootScope, $material, $document, $compile) {
144126
jasmine.mockElementFocus(this);
145127
var parent = angular.element('<div>');
@@ -158,13 +140,13 @@ describe('mdSidenav', function() {
158140
expect($document.activeElement).toBe(focusEl[0]);
159141
}));
160142

161-
it('should focus on last md-sidenav-focus element', inject(function($rootScope, $material, $document, $compile) {
143+
it('should focus on last md-autofocus element', inject(function($rootScope, $material, $document, $compile) {
162144
jasmine.mockElementFocus(this);
163145
var parent = angular.element('<div>');
164146
var markup = '<md-sidenav md-is-open="show">' +
165-
'<md-button md-sidenav-focus>Button</md-button>' +
147+
'<md-button md-autofocus>Button</md-button>' +
166148
'<md-input-container><label>Label</label>' +
167-
'<input type="text" md-sidenav-focus>' +
149+
'<input type="text" md-autofocus>' +
168150
'</md-input-container>' +
169151
'<md-sidenav>';
170152
var sidenavEl = angular.element(markup);

src/core/util/autofocus.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
angular.module('material.core')
22
.directive('mdAutofocus', MdAutofocusDirective)
33

4-
// Support the deprecated md-auto-focus and md-sidenav-focus as well
5-
.directive('mdAutoFocus', MdAutofocusDirective)
6-
.directive('mdSidenavFocus', MdAutofocusDirective);
4+
// Support the deprecated md-auto-focus as well
5+
.directive('mdAutoFocus', MdAutofocusDirective);
76

87
/**
98
* @ngdoc directive

src/core/util/prefixer.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ angular
1010
}]);
1111
});
1212

13+
/**
14+
* @param {string|string[]} initialAttributes
15+
* @param {boolean} buildSelector
16+
* @return {string|string[]|{buildSelector: (function(string|string[]): string),
17+
* buildList: (function(string|string[]): string[]),
18+
* hasAttribute: (function(JQLite|Element, string): HTMLElement),
19+
* removeAttribute: (function(JQLite|Element, string): void)}}
20+
* @constructor
21+
*/
1322
function MdPrefixer(initialAttributes, buildSelector) {
1423
var PREFIXES = ['data', 'x'];
1524

src/core/util/util.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -212,17 +212,17 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
212212
/**
213213
* Finds the proper focus target by searching the DOM.
214214
*
215-
* @param containerEl
216-
* @param attributeVal
217-
* @returns {*}
215+
* @param {!JQLite} containerEl
216+
* @param {string=} attributeVal
217+
* @returns {JQLite|undefined}
218218
*/
219219
findFocusTarget: function(containerEl, attributeVal) {
220220
var AUTO_FOCUS = this.prefixer('md-autofocus', true);
221221
var elToFocus;
222222

223223
elToFocus = scanForFocusable(containerEl, attributeVal || AUTO_FOCUS);
224224

225-
if (!elToFocus && attributeVal != AUTO_FOCUS) {
225+
if (!elToFocus && attributeVal !== AUTO_FOCUS) {
226226
// Scan for deprecated attribute
227227
elToFocus = scanForFocusable(containerEl, this.prefixer('md-auto-focus', true));
228228

@@ -237,12 +237,15 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
237237
/**
238238
* Can target and nested children for specified Selector (attribute)
239239
* whose value may be an expression that evaluates to True/False.
240+
* @param {!JQLite} target
241+
* @param {!string} selector
242+
* @return {JQLite|undefined}
240243
*/
241244
function scanForFocusable(target, selector) {
242245
var elFound, items = target[0].querySelectorAll(selector);
243246

244247
// Find the last child element with the focus attribute
245-
if (items && items.length){
248+
if (items && items.length) {
246249
items.length && angular.forEach(items, function(it) {
247250
it = angular.element(it);
248251

@@ -258,8 +261,8 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
258261

259262
/**
260263
* Disables scroll around the passed parent element.
261-
* @param {Element|angular.JQLite=} element Origin Element (not used)
262-
* @param {Element|angular.JQLite=} parent Element to disable scrolling within.
264+
* @param {Element|JQLite=} element Origin Element (not used)
265+
* @param {Element|JQLite=} parent Element to disable scrolling within.
263266
* Defaults to body if none supplied.
264267
* @param {Object=} options Object of options to modify functionality
265268
* - disableScrollMask Boolean of whether or not to create a scroll mask element or
@@ -291,7 +294,7 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
291294
/**
292295
* Creates a virtual scrolling mask to prevent touchmove, keyboard, scrollbar clicking,
293296
* and wheel events.
294-
* @param {!Element|!angular.JQLite} elementToDisable
297+
* @param {!Element|!JQLite} elementToDisable
295298
* @param {Object=} scrollMaskOptions Object of options to modify functionality
296299
* - disableScrollMask Boolean of whether or not to create a scroll mask element or
297300
* use the passed parent element.
@@ -387,15 +390,16 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
387390
tempNode.children().css('height', '60px');
388391

389392
$document[0].body.appendChild(tempNode[0]);
390-
this.floatingScrollbars.cached = (tempNode[0].offsetWidth == tempNode[0].childNodes[0].offsetWidth);
393+
this.floatingScrollbars.cached =
394+
(tempNode[0].offsetWidth === tempNode[0].childNodes[0].offsetWidth);
391395
tempNode.remove();
392396
}
393397
return this.floatingScrollbars.cached;
394398
},
395399

396400
/**
397401
* Mobile safari only allows you to set focus in click event listeners.
398-
* @param {Element|angular.JQLite} element to focus
402+
* @param {Element|JQLite} element to focus
399403
*/
400404
forceFocus: function(element) {
401405
var node = element[0] || element;

src/core/util/util.spec.js

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -145,22 +145,6 @@ describe('util', function() {
145145

146146
expect(target[0].nodeName).toBe("BUTTON");
147147
}));
148-
149-
it('should find valid a valid focusTarget with a deep "md-sidenav-focus" argument', inject(function($rootScope, $compile, $mdUtil) {
150-
var template = '' +
151-
'<div class="autoFocus">' +
152-
' <md-sidenav>' +
153-
' <button md-sidenav-focus>' +
154-
' <img>' +
155-
' </button>' +
156-
' </md-sidenav>' +
157-
'</div>';
158-
var widget = $compile(template)($rootScope);
159-
$rootScope.$apply();
160-
var target = $mdUtil.findFocusTarget(widget,'[md-sidenav-focus]');
161-
162-
expect(target[0].nodeName).toBe("BUTTON");
163-
}));
164148
});
165149

166150
describe('extractElementByname', function() {

0 commit comments

Comments
 (0)