Skip to content

Commit

Permalink
fix(util/datepicker): Remove usages of scope().
Browse files Browse the repository at this point in the history
A few places use `element.scope()` to retrieve the proper scope,
however, this is only available when Angular's debugging option
is enabled and thus fails in production.

Replace usages of `.scope()` in `util.js` and `datepicker.js`
with appropriate alternatives.

Fixes angular#6474.
  • Loading branch information
topherfangio committed Jan 19, 2016
1 parent bf78b0c commit 45e90fa
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 81 deletions.
2 changes: 1 addition & 1 deletion src/components/datepicker/datePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@
if (this.$attrs['ngDisabled']) {
// The expression is to be evaluated against the directive element's scope and not
// the directive's isolate scope.
var scope = this.$mdUtil.validateScope(this.$element) ? this.$element.scope() : null;
var scope = this.$scope.$parent;

if (scope) {
scope.$watch(this.$attrs['ngDisabled'], function(isDisabled) {
Expand Down
105 changes: 105 additions & 0 deletions src/core/util/autofocus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
angular.module('material.core')
.directive('mdAutofocus', MdAutofocusDirective)

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

/**
* @ngdoc directive
* @name mdAutofocus
* @module material.core.util
*
*
* @description
* `$mdUtil.findFocusTarget()` provides an optional way to identify the focused element when a dialog, bottomsheet, sideNav
* or other element opens. This is optional attribute finds a nested element with the mdAutoFocus attribute and optional
* expression. An expression may be specified as the directive value; to enable conditional activation of the autoFocus.
*
* @usage
* ### Dialog
* <hljs lang="html">
* <md-dialog>
* <form>
* <md-input-container>
* <label for="testInput">Label</label>
* <input id="testInput" type="text" md-autofocus>
* </md-input-container>
* </form>
* </md-dialog>
* </hljs>
*
* ### Bottomsheet
* <hljs lang="html">
* <md-bottom-sheet class="md-list md-has-header">
* <md-subheader>Comment Actions</md-subheader>
* <md-list>
* <md-list-item ng-repeat="item in items">
*
* <md-button md-autofocus="$index == 2">
* <md-icon md-svg-src="{{item.icon}}"></md-icon>
* <span class="md-inline-list-icon-label">{{ item.name }}</span>
* </md-button>
*
* </md-list-item>
* </md-list>
* </md-bottom-sheet>
* </hljs>
*
* ### Autocomplete
* <hljs lang="html">
* <md-autocomplete
* md-autofocus
* md-selected-item="selectedItem"
* md-search-text="searchText"
* md-items="item in getMatches(searchText)"
* md-item-text="item.display">
* <span md-highlight-text="searchText">{{item.display}}</span>
* </md-autocomplete>
* </hljs>
*
* ### Sidenav
* <hljs lang="html">
* <div layout="row" ng-controller="MyController">
* <md-sidenav md-component-id="left" class="md-sidenav-left">
* Left Nav!
* </md-sidenav>
*
* <md-content>
* Center Content
* <md-button ng-click="openLeftMenu()">
* Open Left Menu
* </md-button>
* </md-content>
*
* <md-sidenav md-component-id="right"
* md-is-locked-open="$mdMedia('min-width: 333px')"
* class="md-sidenav-right">
* <form>
* <md-input-container>
* <label for="testInput">Test input</label>
* <input id="testInput" type="text"
* ng-model="data" md-autofocus>
* </md-input-container>
* </form>
* </md-sidenav>
* </div>
* </hljs>
**/
function MdAutofocusDirective() {
return {
restrict: 'A',

link: postLink
}
}

function postLink(scope, element, attrs) {
var attr = attrs.mdAutoFocus || attrs.mdAutofocus || attrs.mdSidenavFocus;

// Setup a watcher on the proper attribute to update a class we can check for in $mdUtil
scope.$watch(attr, function(canAutofocus) {
element.toggleClass('_md-can-autofocus', canAutofocus);
});
}
32 changes: 32 additions & 0 deletions src/core/util/autofocus.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
describe('md-autofocus', function() {
var $rootScope, pageScope, element;

beforeEach(module('material.core'));
beforeEach(inject(function(_$rootScope_) {
$rootScope = _$rootScope_;
}));

it('adds/removes the _md-can-autofocus class', function() {
build('<input id="test" type="text" md-autofocus="shouldAutoFocus">');

// By default, we assume an undefined value for the expression is true
expect(element).toHaveClass('_md-can-autofocus');

// Set the expression to false
pageScope.$apply('shouldAutoFocus=false');
expect(element).not.toHaveClass('_md-can-autofocus');

// Set the expression to true
pageScope.$apply('shouldAutoFocus=true');
expect(element).toHaveClass('_md-can-autofocus');
});

function build(template) {
inject(function($compile) {
pageScope = $rootScope.$new();
element = $compile(template)(pageScope);

pageScope.$apply();
});
}
});
90 changes: 10 additions & 80 deletions src/core/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,87 +95,12 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
},

/**
* @ngdoc directive
* @name mdAutofocus
* @module material.core.util
* Finds the proper focus target by searching the DOM.
*
*
* @description
* `$mdUtil.findFocusTarget()` provides an optional way to identify the focused element when a dialog, bottomsheet, sideNav
* or other element opens. This is optional attribute finds a nested element with the mdAutoFocus attribute and optional
* expression. An expression may be specified as the directive value; to enable conditional activation of the autoFocus.
*
* @usage
* ### Dialog
* <hljs lang="html">
* <md-dialog>
* <form>
* <md-input-container>
* <label for="testInput">Label</label>
* <input id="testInput" type="text" md-autofocus>
* </md-input-container>
* </form>
* </md-dialog>
* </hljs>
*
* ### Bottomsheet
* <hljs lang="html">
* <md-bottom-sheet class="md-list md-has-header">
* <md-subheader>Comment Actions</md-subheader>
* <md-list>
* <md-list-item ng-repeat="item in items">
*
* <md-button md-autofocus="$index == 2">
* <md-icon md-svg-src="{{item.icon}}"></md-icon>
* <span class="md-inline-list-icon-label">{{ item.name }}</span>
* </md-button>
*
* </md-list-item>
* </md-list>
* </md-bottom-sheet>
* </hljs>
*
* ### Autocomplete
* <hljs lang="html">
* <md-autocomplete
* md-autofocus
* md-selected-item="selectedItem"
* md-search-text="searchText"
* md-items="item in getMatches(searchText)"
* md-item-text="item.display">
* <span md-highlight-text="searchText">{{item.display}}</span>
* </md-autocomplete>
* </hljs>
*
* ### Sidenav
* <hljs lang="html">
* <div layout="row" ng-controller="MyController">
* <md-sidenav md-component-id="left" class="md-sidenav-left">
* Left Nav!
* </md-sidenav>
*
* <md-content>
* Center Content
* <md-button ng-click="openLeftMenu()">
* Open Left Menu
* </md-button>
* </md-content>
*
* <md-sidenav md-component-id="right"
* md-is-locked-open="$mdMedia('min-width: 333px')"
* class="md-sidenav-right">
* <form>
* <md-input-container>
* <label for="testInput">Test input</label>
* <input id="testInput" type="text"
* ng-model="data" md-autofocus>
* </md-input-container>
* </form>
* </md-sidenav>
* </div>
* </hljs>
**/
* @param containerEl
* @param attributeVal
* @returns {*}
*/
findFocusTarget: function(containerEl, attributeVal) {
var AUTO_FOCUS = '[md-autofocus]';
var elToFocus;
Expand Down Expand Up @@ -210,10 +135,15 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
items.length && angular.forEach(items, function(it) {
it = angular.element(it);

// Check the element for the _md-can-autofocus class to ensure any associated function
// is true.
var isFocusable = it.hasClass('_md-can-autofocus');
/*
// If the expression evaluates to FALSE, then it is not focusable target
var focusExpression = it[0].getAttribute(attribute);
var isFocusable = !focusExpression || !$mdUtil.validateScope(it) ? true :
(it.scope().$eval(focusExpression) !== false );
*/

if (isFocusable) elFound = it;
});
Expand Down

0 comments on commit 45e90fa

Please sign in to comment.