(function () { 'use strict'; angular.module('foundation.iconic', []) .provider('Iconic', Iconic) .directive('zfIconic', zfIconic) ; // iconic wrapper function Iconic() { // default path var assetPath = 'assets/img/iconic/'; /** * Sets the path used to locate the iconic SVG files * @param {string} path - the base path used to locate the iconic SVG files */ this.setAssetPath = function (path) { assetPath = angular.isString(path) ? path : assetPath; }; /** * Service implementation * @returns {{}} */ this.$get = function () { var iconicObject = new IconicJS(); var service = { getAccess: getAccess, getAssetPath: getAssetPath }; return service; /** * * @returns {Window.IconicJS} */ function getAccess() { return iconicObject; } /** * * @returns {string} */ function getAssetPath() { return assetPath; } }; } zfIconic.$inject = ['Iconic', 'FoundationApi', '$compile']; function zfIconic(iconic, foundationApi, $compile) { var directive = { restrict: 'A', template: '', transclude: true, replace: true, scope: { dynSrc: '=?', dynIcon: '=?', size: '@?', icon: '@', iconDir: '@?' }, compile: compile }; return directive; function compile() { var contents, assetPath; return { pre: preLink, post: postLink }; function preLink(scope, element, attrs) { if (scope.iconDir) { // path set via attribute assetPath = scope.iconDir; } else { // default path assetPath = iconic.getAssetPath(); } // make sure ends with / if (assetPath.charAt(assetPath.length - 1) !== '/') { assetPath += '/'; } if (scope.dynSrc) { attrs.$set('data-src', scope.dynSrc); } else if (scope.dynIcon) { attrs.$set('data-src', assetPath + scope.dynIcon + '.svg'); } else { if (scope.icon) { attrs.$set('data-src', assetPath + scope.icon + '.svg'); } else { // To support expressions on data-src attrs.$set('data-src', attrs.src); } } // check if size already added as class if (!element.hasClass('iconic-sm') && !element.hasClass('iconic-md') && !element.hasClass('iconic-lg')) { var iconicClass; switch (scope.size) { case 'small': iconicClass = 'iconic-sm'; break; case 'medium': iconicClass = 'iconic-md'; break; case 'large': iconicClass = 'iconic-lg'; break; default: iconicClass = 'iconic-fluid'; } element.addClass(iconicClass); } // save contents of un-inject html, to use for dynamic re-injection contents = element[0].outerHTML; } function postLink(scope, element, attrs) { var svgElement, ico = iconic.getAccess(); injectSvg(element[0]); foundationApi.subscribe('resize', function () { // only run update on current element ico.update(element[0]); }); // handle dynamic updating of src if (scope.dynSrc) { scope.$watch('dynSrc', function (newVal, oldVal) { if (newVal && newVal !== oldVal) { reinjectSvg(scope.dynSrc); } }); } // handle dynamic updating of icon if (scope.dynIcon) { scope.$watch('dynIcon', function (newVal, oldVal) { if (newVal && newVal !== oldVal) { reinjectSvg(assetPath + scope.dynIcon + '.svg'); } }); } function reinjectSvg(newSrc) { if (svgElement) { // set html svgElement.empty(); svgElement.append(angular.element(contents)); // set new source svgElement.attr('data-src', newSrc); // reinject injectSvg(svgElement[0]); } } function injectSvg(element) { ico.inject(element, { each: function (injectedElem) { // compile injected svg var angElem = angular.element(injectedElem); svgElement = $compile(angElem)(angElem.scope()); } }); } } } } })();