'use strict'; /** * @workInProgress * @ngdoc service * @name angular.service.$invalidWidgets * * @description * Keeps references to all invalid widgets found during validation. * Can be queried to find whether there are any invalid widgets currently displayed. * * @example */ angularServiceInject("$invalidWidgets", function(){ var invalidWidgets = []; /** Remove an element from the array of invalid widgets */ invalidWidgets.markValid = function(element){ var index = indexOf(invalidWidgets, element); if (index != -1) invalidWidgets.splice(index, 1); }; /** Add an element to the array of invalid widgets */ invalidWidgets.markInvalid = function(element){ var index = indexOf(invalidWidgets, element); if (index === -1) invalidWidgets.push(element); }; /** Return count of all invalid widgets that are currently visible */ invalidWidgets.visible = function() { var count = 0; forEach(invalidWidgets, function(widget){ count = count + (isVisible(widget) ? 1 : 0); }); return count; }; /* At the end of each eval removes all invalid widgets that are not part of the current DOM. */ this.$onEval(PRIORITY_LAST, function() { for(var i = 0; i < invalidWidgets.length;) { var widget = invalidWidgets[i]; if (isOrphan(widget[0])) { invalidWidgets.splice(i, 1); if (widget.dealoc) widget.dealoc(); } else { i++; } } }); /** * Traverses DOM element's (widget's) parents and considers the element to be an orphant if one of * it's parents isn't the current window.document. */ function isOrphan(widget) { if (widget == window.document) return false; var parent = widget.parentNode; return !parent || isOrphan(parent); } return invalidWidgets; });