Source:image-cover.directive.js

(function () {
    'use strict';
    // Image cover
    angular
        .module('mohistory')
        .directive('imageCover', imageCover);
    imageCover.$inject = ['$rootScope'];
    /**
     * Applies CSS classes to resize images, so they maintain their aspect 
     * ratios and fill their containing element.
     * @memberof mohistory
     * @name imageCover
     * @ngdoc directive
     */
    function imageCover($rootScope) {
        var directive = {
            link: imageCover,
            restrict: 'A',
        };
        return directive;
        /**
         * Link function responsible for registering event listeners for image
         * load and page resize. Depends on the page width being stored and updated
         * via the rootScope. Also cleans up when directive is destroyed.
         * Assumes HTML is organized similar to the following example:
         * <div image-cover class="image full-clip-container">
         *      <div id="{{i['og:image']}}" class="overlay theme-bg-hover">
         *          {{i['mhs:button'] || 'Learn More'}}
         *          <span class="sr-only">appears over link image on mouse over.</span>
         *      </div>
         *      <img aria-labelledby="{{i['og:image']}}" ng-src="{{i['mhs:image']['small'] || i['og:image']}}" />
         * </div>
         * @memberof imageCover
         * @param {String} scope an AngularJS scope object.
         * @param {String} element the jqLite-wrapped element that this directive matches.
         * @param {String} attrs a hash object with key-value pairs of normalized attribute 
         * names their corresponding attribute values.
         */
        function imageCover(scope, element, attrs) {
            // Find all images that are contained within the element where the
            // directive is linked.
            var image = element.find('img');
            if (image[0]) {
                image.on('load', setImageClass);
                scope.$watch(function () {
                    return $rootScope.viewport.width;
                }, setImageClass);
                scope.$on('$destroy', function () {
                    image.off('load', setImageClass);
                });
            }
            /** 
             * Helper function which adds a class to the image based on its
             * dimensions.
             * @function setImageClass
             * @memberof imageCover
             */
            function setImageClass() {
                var blockHeight = element[0].clientHeight, //box height
                    blockWidth = element[0].clientWidth, //box width
                    imgHeight = image[0].clientHeight, //initial image height
                    imgWidth = image[0].clientWidth; //initial image width
                if ((blockHeight / blockWidth) > (imgHeight / imgWidth)) {
                    if (!image.hasClass('wh')) {
                        image.addClass('wh').removeClass('ww'); //set height 100%
                    }
                } else {
                    if (!image.hasClass('ww')) {
                        image.addClass('ww').removeClass('wh'); //set width 100%
                    }
                }
            }
        }
    }
})();