/*! angular-breadcrumb - v0.3.3 * http://ncuillery.github.io/angular-breadcrumb * Copyright (c) 2014 Nicolas Cuillery; Licensed MIT */ (function (window, angular, undefined) { 'use strict'; function isAOlderThanB(scopeA, scopeB) { if(angular.equals(scopeA.length, scopeB.length)) { return scopeA > scopeB; } else { return scopeA.length > scopeB.length; } } function parseStateRef(ref) { var parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/); if (!parsed || parsed.length !== 4) { throw new Error("Invalid state ref '" + ref + "'"); } return { state: parsed[1], paramExpr: parsed[3] || null }; } function $Breadcrumb() { var $$options = { prefixStateName: null, template: 'bootstrap3', templateUrl: null, includeAbstract : false }; this.setOptions = function(options) { angular.extend($$options, options); }; this.$get = ['$state', '$stateParams', '$rootScope', function($state, $stateParams, $rootScope) { var $lastViewScope = $rootScope; // Early catch of $viewContentLoaded event $rootScope.$on('$viewContentLoaded', function (event) { // With nested views, the event occur several times, in "wrong" order if(isAOlderThanB(event.targetScope.$id, $lastViewScope.$id)) { $lastViewScope = event.targetScope; } }); // Get the parent state var $$parentState = function(state) { // Check if state has explicit parent OR we try guess parent from its name var name = state.parent || (/^(.+)\.[^.]+$/.exec(state.name) || [])[1]; // If we were able to figure out parent name then get this state return name; }; // Add the state in the chain if not already in and if not abstract var $$addStateInChain = function(chain, stateRef) { var conf, parentParams, ref = parseStateRef(stateRef); for(var i=0, l=chain.length; i' + '
  • ' + '{{step.ncyBreadcrumbLabel}} ' + '{{step.ncyBreadcrumbLabel}}' + '/' + '
  • ' + '', bootstrap3: '' }; return { restrict: 'AE', replace: true, scope: {}, template: $breadcrumb.getTemplate($$templates), templateUrl: $breadcrumb.getTemplateUrl(), link: { post: function postLink(scope) { var labelWatchers = []; var renderBreadcrumb = function() { deregisterWatchers(labelWatchers); var viewScope = $breadcrumb.$getLastViewScope(); scope.steps = $breadcrumb.getStatesChain(); angular.forEach(scope.steps, function (step) { if (step.ncyBreadcrumb && step.ncyBreadcrumb.label) { var parseLabel = $interpolate(step.ncyBreadcrumb.label); step.ncyBreadcrumbLabel = parseLabel(viewScope); // Watcher for further viewScope updates registerWatchers(labelWatchers, parseLabel, viewScope, step); } else { step.ncyBreadcrumbLabel = step.name; } }); }; $rootScope.$on('$viewContentLoaded', function () { renderBreadcrumb(); }); // View(s) may be already loaded while the directive's linking renderBreadcrumb(); } } }; } BreadcrumbDirective.$inject = ['$interpolate', '$breadcrumb', '$rootScope']; function BreadcrumbLastDirective($interpolate, $breadcrumb, $rootScope) { return { restrict: 'A', scope: {}, template: '{{ncyBreadcrumbLabel}}', compile: function(cElement, cAttrs) { // Override the default template if ncyBreadcrumbLast has a value var template = cElement.attr(cAttrs.$attr.ncyBreadcrumbLast); if(template) { cElement.html(template); } return { post: function postLink(scope) { var labelWatchers = []; var renderLabel = function() { deregisterWatchers(labelWatchers); var viewScope = $breadcrumb.$getLastViewScope(); var lastStep = $breadcrumb.getLastStep(); if(lastStep) { scope.ncyBreadcrumbLink = lastStep.ncyBreadcrumbLink; if (lastStep.ncyBreadcrumb && lastStep.ncyBreadcrumb.label) { var parseLabel = $interpolate(lastStep.ncyBreadcrumb.label); scope.ncyBreadcrumbLabel = parseLabel(viewScope); // Watcher for further viewScope updates // Tricky last arg: the last step is the entire scope of the directive ! registerWatchers(labelWatchers, parseLabel, viewScope, scope); } else { scope.ncyBreadcrumbLabel = lastStep.name; } } }; $rootScope.$on('$viewContentLoaded', function () { renderLabel(); }); // View(s) may be already loaded while the directive's linking renderLabel(); } }; } }; } BreadcrumbLastDirective.$inject = ['$interpolate', '$breadcrumb', '$rootScope']; angular.module('ncy-angular-breadcrumb', ['ui.router.state']) .provider('$breadcrumb', $Breadcrumb) .directive('ncyBreadcrumb', BreadcrumbDirective) .directive('ncyBreadcrumbLast', BreadcrumbLastDirective); })(window, window.angular);