UNPKG

angular-material-npfixed

Version:

The Angular Material project is an implementation of Material Design in Angular.js. This project provides a set of reusable, well-tested, and accessible Material Design UI components. Angular Material is supported internally at Google by the Angular.js, M

176 lines (150 loc) 4.76 kB
/** * @ngdoc module * @name material.core.aria * @description * Aria Expectations for ngMaterial components. */ angular .module('material.core') .provider('$mdAria', MdAriaProvider); /** * @ngdoc service * @name $mdAriaProvider * @module material.core.aria * * @description * * Modify options of the `$mdAria` service, which will be used by most of the Angular Material * components. * * You are able to disable `$mdAria` warnings, by using the following markup. * * <hljs lang="js"> * app.config(function($mdAriaProvider) { * // Globally disables all ARIA warnings. * $mdAriaProvider.disableWarnings(); * }); * </hljs> * */ function MdAriaProvider() { var config = { /** Whether we should show ARIA warnings in the console if labels are missing on the element */ showWarnings: true }; return { disableWarnings: disableWarnings, $get: function($$rAF, $log, $window, $interpolate) { return MdAriaService.apply(config, arguments); } }; /** * @ngdoc method * @name $mdAriaProvider#disableWarnings * @description Disables all ARIA warnings generated by Angular Material. */ function disableWarnings() { config.showWarnings = false; } } /* * @ngInject */ function MdAriaService($$rAF, $log, $window, $interpolate) { // Load the showWarnings option from the current context and store it inside of a scope variable, // because the context will be probably lost in some function calls. var showWarnings = this.showWarnings; return { expect: expect, expectAsync: expectAsync, expectWithText: expectWithText, expectWithoutText: expectWithoutText, getText: getText }; /** * Check if expected attribute has been specified on the target element or child * @param element * @param attrName * @param {optional} defaultValue What to set the attr to if no value is found */ function expect(element, attrName, defaultValue) { var node = angular.element(element)[0] || element; // if node exists and neither it nor its children have the attribute if (node && ((!node.hasAttribute(attrName) || node.getAttribute(attrName).length === 0) && !childHasAttribute(node, attrName))) { defaultValue = angular.isString(defaultValue) ? defaultValue.trim() : ''; if (defaultValue.length) { element.attr(attrName, defaultValue); } else if (showWarnings) { $log.warn('ARIA: Attribute "', attrName, '", required for accessibility, is missing on node:', node); } } } function expectAsync(element, attrName, defaultValueGetter) { // Problem: when retrieving the element's contents synchronously to find the label, // the text may not be defined yet in the case of a binding. // There is a higher chance that a binding will be defined if we wait one frame. $$rAF(function() { expect(element, attrName, defaultValueGetter()); }); } function expectWithText(element, attrName) { var content = getText(element) || ""; var hasBinding = content.indexOf($interpolate.startSymbol()) > -1; if (hasBinding) { expectAsync(element, attrName, function() { return getText(element); }); } else { expect(element, attrName, content); } } function expectWithoutText(element, attrName) { var content = getText(element); var hasBinding = content.indexOf($interpolate.startSymbol()) > -1; if ( !hasBinding && !content) { expect(element, attrName, content); } } function getText(element) { element = element[0] || element; var walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false); var text = ''; var node; while (node = walker.nextNode()) { if (!isAriaHiddenNode(node)) { text += node.textContent; } } return text.trim() || ''; function isAriaHiddenNode(node) { while (node.parentNode && (node = node.parentNode) !== element) { if (node.getAttribute && node.getAttribute('aria-hidden') === 'true') { return true; } } } } function childHasAttribute(node, attrName) { var hasChildren = node.hasChildNodes(), hasAttr = false; function isHidden(el) { var style = el.currentStyle ? el.currentStyle : $window.getComputedStyle(el); return (style.display === 'none'); } if (hasChildren) { var children = node.childNodes; for (var i=0; i < children.length; i++) { var child = children[i]; if (child.nodeType === 1 && child.hasAttribute(attrName)) { if (!isHidden(child)) { hasAttr = true; } } } } return hasAttr; } }