angular-breadcrumb
Advanced tools
Comparing version
{ | ||
"name": "angular-breadcrumb", | ||
"description": "AngularJS module that generates a breadcrumb from ui-router's states", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"main": "release/angular-breadcrumb.js", | ||
@@ -23,3 +23,3 @@ "ignore": [ | ||
"dependencies": { | ||
"angular": ">=1.0.8", | ||
"angular": ">=1.2.0", | ||
"angular-ui-router": ">=0.2.0" | ||
@@ -26,0 +26,0 @@ }, |
@@ -0,1 +1,16 @@ | ||
<a name="0.5.0"></a> | ||
## 0.5.0 (2016-11-14) | ||
#### Bug Fixes | ||
* Register listeners once to prevent scope being retained ([181f4c09](http://github.com/ncuillery/angular-breadcrumb/commit/181f4c0901007cbd72c7a9470cb9503eb6ab4d5a), closes [#98](http://github.com/ncuillery/angular-breadcrumb/issues/98)) | ||
#### Features | ||
* Expose ncyBreadcrumbStateRef for ui-sref usage in custom template ([56cec38b](http://github.com/ncuillery/angular-breadcrumb/commit/56cec38b1169ba91a766bb64f44ddff81d8af2a8), closes [#54](http://github.com/ncuillery/angular-breadcrumb/issues/54)) | ||
* **ncyBreadcrumbLast:** Add custom templating ([974f99b5](http://github.com/ncuillery/angular-breadcrumb/commit/974f99b584c85e45b1c0eb1acb4081bf103de06f), closes [#123](http://github.com/ncuillery/angular-breadcrumb/issues/123), [#125](http://github.com/ncuillery/angular-breadcrumb/issues/125)) | ||
<a name="0.4.1"></a> | ||
@@ -23,3 +38,3 @@ ### 0.4.1 (2015-08-09) | ||
* Add force to ncyBreadcrumb options ([31125a38](http://github.com/ncuillery/angular-breadcrumb/commit/31125a386d706dd76df807b3b02e1fccea38fb59), closes [#77](http://github.com/ncuillery/angular-breadcrumb/issues/78)) | ||
* Add force to ncyBreadcrumb options ([31125a38](http://github.com/ncuillery/angular-breadcrumb/commit/31125a386d706dd76df807b3b02e1fccea38fb59), closes [#78](http://github.com/ncuillery/angular-breadcrumb/issues/78)) | ||
* **ncyBreadcrumbText:** Add ncyBreadcrumbText directive ([82b2b443](http://github.com/ncuillery/angular-breadcrumb/commit/82b2b443fab220cd9ac7d3a8c90c1edc4291e54a), closes [#71](http://github.com/ncuillery/angular-breadcrumb/issues/71), [#83](http://github.com/ncuillery/angular-breadcrumb/issues/83)) | ||
@@ -26,0 +41,0 @@ |
@@ -1,4 +0,4 @@ | ||
/*! angular-breadcrumb - v0.4.0-dev-2015-08-07 | ||
/*! angular-breadcrumb - v0.4.1-dev-2016-04-12 | ||
* http://ncuillery.github.io/angular-breadcrumb | ||
* Copyright (c) 2015 Nicolas Cuillery; Licensed MIT */ | ||
* Copyright (c) 2016 Nicolas Cuillery; Licensed MIT */ | ||
@@ -22,2 +22,12 @@ (function (window, angular, undefined) { | ||
var $registeredListeners = {}; | ||
function registerListenerOnce(tag, $rootScope, event, fn) { | ||
var deregisterListenerFn = $registeredListeners[tag]; | ||
if ( deregisterListenerFn !== undefined ) { | ||
deregisterListenerFn(); | ||
} | ||
deregisterListenerFn = $rootScope.$on(event, fn); | ||
$registeredListeners[tag] = deregisterListenerFn; | ||
} | ||
function $Breadcrumb() { | ||
@@ -29,2 +39,4 @@ | ||
templateUrl: null, | ||
templateLast: 'default', | ||
templateLastUrl: null, | ||
includeAbstract : false | ||
@@ -42,3 +54,3 @@ }; | ||
// Early catch of $viewContentLoaded event | ||
$rootScope.$on('$viewContentLoaded', function (event) { | ||
registerListenerOnce('$Breadcrumb.$viewContentLoaded', $rootScope, '$viewContentLoaded', function (event) { | ||
// With nested views, the event occur several times, in "wrong" order | ||
@@ -86,2 +98,3 @@ if(!event.targetScope.ncyBreadcrumbIgnore && | ||
conf.ncyBreadcrumbLink = $state.href(ref.state, parentParams || $stateParams || {}); | ||
conf.ncyBreadcrumbStateRef = stateRef; | ||
chain.unshift(conf); | ||
@@ -126,2 +139,18 @@ } | ||
getTemplateLast: function(templates) { | ||
if($$options.templateLastUrl) { | ||
// templateUrl takes precedence over template | ||
return null; | ||
} else if(templates[$$options.templateLast]) { | ||
// Predefined templates (default) | ||
return templates[$$options.templateLast]; | ||
} else { | ||
return $$options.templateLast; | ||
} | ||
}, | ||
getTemplateLastUrl: function() { | ||
return $$options.templateLastUrl; | ||
}, | ||
getStatesChain: function(exitOnFirst) { // Deliberately undocumented param, see getLastStep | ||
@@ -162,2 +191,3 @@ var chain = []; | ||
} else { | ||
// Workaround for Angular 1.2.x | ||
var expressions = []; | ||
@@ -219,3 +249,3 @@ angular.forEach(interpolationFunction.parts, function(part) { | ||
labelWatchers = []; | ||
var viewScope = $breadcrumb.$getLastViewScope(); | ||
@@ -235,3 +265,3 @@ scope.steps = $breadcrumb.getStatesChain(); | ||
$rootScope.$on('$viewContentLoaded', function (event) { | ||
registerListenerOnce('BreadcrumbDirective.$viewContentLoaded', $rootScope, '$viewContentLoaded', function (event) { | ||
if(!event.targetScope.ncyBreadcrumbIgnore) { | ||
@@ -251,2 +281,5 @@ renderBreadcrumb(); | ||
function BreadcrumbLastDirective($interpolate, $breadcrumb, $rootScope) { | ||
var $$templates = { | ||
'default': '{{ncyBreadcrumbLabel}}' | ||
}; | ||
@@ -256,6 +289,9 @@ return { | ||
scope: {}, | ||
template: '{{ncyBreadcrumbLabel}}', | ||
template: $breadcrumb.getTemplateLast($$templates), | ||
templateUrl: $breadcrumb.getTemplateLastUrl(), | ||
compile: function(cElement, cAttrs) { | ||
// Override the default template if ncyBreadcrumbLast has a value | ||
// This should likely be removed in a future version since global | ||
// templating is now available for ncyBreadcrumbLast | ||
var template = cElement.attr(cAttrs.$attr.ncyBreadcrumbLast); | ||
@@ -273,3 +309,3 @@ if(template) { | ||
labelWatchers = []; | ||
var viewScope = $breadcrumb.$getLastViewScope(); | ||
@@ -291,3 +327,3 @@ var lastStep = $breadcrumb.getLastStep(); | ||
$rootScope.$on('$viewContentLoaded', function (event) { | ||
registerListenerOnce('BreadcrumbLastDirective.$viewContentLoaded', $rootScope, '$viewContentLoaded', function (event) { | ||
if(!event.targetScope.ncyBreadcrumbIgnore) { | ||
@@ -321,3 +357,3 @@ renderLabel(); | ||
} | ||
var separator = cElement.attr(cAttrs.$attr.ncyBreadcrumbTextSeparator) || ' / '; | ||
@@ -328,3 +364,3 @@ | ||
var labelWatchers = []; | ||
var registerWatchersText = function(labelWatcherArray, interpolationFunction, viewScope) { | ||
@@ -344,3 +380,3 @@ angular.forEach(getExpression(interpolationFunction), function(expression) { | ||
labelWatchers = []; | ||
var viewScope = $breadcrumb.$getLastViewScope(); | ||
@@ -359,7 +395,7 @@ var steps = $breadcrumb.getStatesChain(); | ||
}); | ||
scope.ncyBreadcrumbChain = combinedLabels.join(separator); | ||
}; | ||
$rootScope.$on('$viewContentLoaded', function (event) { | ||
registerListenerOnce('BreadcrumbTextDirective.$viewContentLoaded', $rootScope, '$viewContentLoaded', function (event) { | ||
if(!event.targetScope.ncyBreadcrumbIgnore) { | ||
@@ -366,0 +402,0 @@ renderLabel(); |
@@ -1,4 +0,4 @@ | ||
/*! angular-breadcrumb - v0.4.0-dev-2015-08-07 | ||
/*! angular-breadcrumb - v0.4.1-dev-2016-04-12 | ||
* http://ncuillery.github.io/angular-breadcrumb | ||
* Copyright (c) 2015 Nicolas Cuillery; Licensed MIT */ | ||
!function(a,b,c){"use strict";function d(a,c){return b.equals(a.length,c.length)?a>c:a.length>c.length}function e(a){var b=a.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/);if(!b||4!==b.length)throw new Error("Invalid state ref '"+a+"'");return{state:b[1],paramExpr:b[3]||null}}function f(){var a={prefixStateName:null,template:"bootstrap3",templateUrl:null,includeAbstract:!1};this.setOptions=function(c){b.extend(a,c)},this.$get=["$state","$stateParams","$rootScope",function(b,f,g){var h=g;g.$on("$viewContentLoaded",function(a){!a.targetScope.ncyBreadcrumbIgnore&&d(a.targetScope.$id,h.$id)&&(h=a.targetScope)});var i=function(a){var b=a.parent||(/^(.+)\.[^.]+$/.exec(a.name)||[])[1],c="object"==typeof b;return c?b.name:b},j=function(c,d){for(var g,i,j=e(d),k=!1,l=!1,m=0,n=c.length;n>m;m+=1)if(c[m].name===j.state)return;g=b.get(j.state),g.ncyBreadcrumb&&(g.ncyBreadcrumb.force&&(k=!0),g.ncyBreadcrumb.skip&&(l=!0)),g["abstract"]&&!a.includeAbstract&&!k||l||(j.paramExpr&&(i=h.$eval(j.paramExpr)),g.ncyBreadcrumbLink=b.href(j.state,i||f||{}),c.unshift(g))},k=function(a){var c=e(a),d=b.get(c.state);if(d.ncyBreadcrumb&&d.ncyBreadcrumb.parent){var f="function"==typeof d.ncyBreadcrumb.parent,g=f?d.ncyBreadcrumb.parent(h):d.ncyBreadcrumb.parent;if(g)return g}return i(d)};return{getTemplate:function(b){return a.templateUrl?null:b[a.template]?b[a.template]:a.template},getTemplateUrl:function(){return a.templateUrl},getStatesChain:function(c){for(var d=[],e=b.$current.self.name;e;e=k(e))if(j(d,e),c&&d.length)return d;return a.prefixStateName&&j(d,a.prefixStateName),d},getLastStep:function(){var a=this.getStatesChain(!0);return a.length?a[0]:c},$getLastViewScope:function(){return h}}}]}function g(a,c,d){var e={bootstrap2:'<ul class="breadcrumb"><li ng-repeat="step in steps" ng-switch="$last || !!step.abstract" ng-class="{active: $last}"><a ng-switch-when="false" href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a><span ng-switch-when="true">{{step.ncyBreadcrumbLabel}}</span><span class="divider" ng-hide="$last">/</span></li></ul>',bootstrap3:'<ol class="breadcrumb"><li ng-repeat="step in steps" ng-class="{active: $last}" ng-switch="$last || !!step.abstract"><a ng-switch-when="false" href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a><span ng-switch-when="true">{{step.ncyBreadcrumbLabel}}</span></li></ol>'};return{restrict:"AE",replace:!0,scope:{},template:c.getTemplate(e),templateUrl:c.getTemplateUrl(),link:{post:function(e){var f=[],g=function(){l(f),f=[];var d=c.$getLastViewScope();e.steps=c.getStatesChain(),b.forEach(e.steps,function(b){if(b.ncyBreadcrumb&&b.ncyBreadcrumb.label){var c=a(b.ncyBreadcrumb.label);b.ncyBreadcrumbLabel=c(d),k(f,c,d,b)}else b.ncyBreadcrumbLabel=b.name})};d.$on("$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||g()}),g()}}}}function h(a,b,c){return{restrict:"A",scope:{},template:"{{ncyBreadcrumbLabel}}",compile:function(d,e){var f=d.attr(e.$attr.ncyBreadcrumbLast);return f&&d.html(f),{post:function(d){var e=[],f=function(){l(e),e=[];var c=b.$getLastViewScope(),f=b.getLastStep();if(f)if(d.ncyBreadcrumbLink=f.ncyBreadcrumbLink,f.ncyBreadcrumb&&f.ncyBreadcrumb.label){var g=a(f.ncyBreadcrumb.label);d.ncyBreadcrumbLabel=g(c),k(e,g,c,d)}else d.ncyBreadcrumbLabel=f.name};c.$on("$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||f()}),f()}}}}}function i(a,c,d){return{restrict:"A",scope:{},template:"{{ncyBreadcrumbChain}}",compile:function(e,f){var g=e.attr(f.$attr.ncyBreadcrumbText);g&&e.html(g);var h=e.attr(f.$attr.ncyBreadcrumbTextSeparator)||" / ";return{post:function(e){var f=[],g=function(a,c,d){b.forEach(j(c),function(b){var c=d.$watch(b,function(a,b){a!==b&&i()});a.push(c)})},i=function(){l(f),f=[];var d=c.$getLastViewScope(),i=c.getStatesChain(),j=[];b.forEach(i,function(b){if(b.ncyBreadcrumb&&b.ncyBreadcrumb.label){var c=a(b.ncyBreadcrumb.label);j.push(c(d)),g(f,c,d)}else j.push(b.name)}),e.ncyBreadcrumbChain=j.join(h)};d.$on("$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||i()}),i()}}}}}var j=function(a){if(a.expressions)return a.expressions;var c=[];return b.forEach(a.parts,function(a){b.isFunction(a)&&c.push(a.exp)}),c},k=function(a,c,d,e){b.forEach(j(c),function(b){var f=d.$watch(b,function(){e.ncyBreadcrumbLabel=c(d)});a.push(f)})},l=function(a){b.forEach(a,function(a){a()})};g.$inject=["$interpolate","$breadcrumb","$rootScope"],h.$inject=["$interpolate","$breadcrumb","$rootScope"],i.$inject=["$interpolate","$breadcrumb","$rootScope"],b.module("ncy-angular-breadcrumb",["ui.router.state"]).provider("$breadcrumb",f).directive("ncyBreadcrumb",g).directive("ncyBreadcrumbLast",h).directive("ncyBreadcrumbText",i)}(window,window.angular); | ||
* Copyright (c) 2016 Nicolas Cuillery; Licensed MIT */ | ||
!function(a,b,c){"use strict";function d(a,c){return b.equals(a.length,c.length)?a>c:a.length>c.length}function e(a){var b=a.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/);if(!b||4!==b.length)throw new Error("Invalid state ref '"+a+"'");return{state:b[1],paramExpr:b[3]||null}}function f(a,b,d,e){var f=k[a];f!==c&&f(),f=b.$on(d,e),k[a]=f}function g(){var a={prefixStateName:null,template:"bootstrap3",templateUrl:null,templateLast:"default",templateLastUrl:null,includeAbstract:!1};this.setOptions=function(c){b.extend(a,c)},this.$get=["$state","$stateParams","$rootScope",function(b,g,h){var i=h;f("$Breadcrumb.$viewContentLoaded",h,"$viewContentLoaded",function(a){!a.targetScope.ncyBreadcrumbIgnore&&d(a.targetScope.$id,i.$id)&&(i=a.targetScope)});var j=function(a){var b=a.parent||(/^(.+)\.[^.]+$/.exec(a.name)||[])[1],c="object"==typeof b;return c?b.name:b},k=function(c,d){for(var f,h,j=e(d),k=!1,l=!1,m=0,n=c.length;n>m;m+=1)if(c[m].name===j.state)return;f=b.get(j.state),f.ncyBreadcrumb&&(f.ncyBreadcrumb.force&&(k=!0),f.ncyBreadcrumb.skip&&(l=!0)),f["abstract"]&&!a.includeAbstract&&!k||l||(j.paramExpr&&(h=i.$eval(j.paramExpr)),f.ncyBreadcrumbLink=b.href(j.state,h||g||{}),f.ncyBreadcrumbStateRef=d,c.unshift(f))},l=function(a){var c=e(a),d=b.get(c.state);if(d.ncyBreadcrumb&&d.ncyBreadcrumb.parent){var f="function"==typeof d.ncyBreadcrumb.parent,g=f?d.ncyBreadcrumb.parent(i):d.ncyBreadcrumb.parent;if(g)return g}return j(d)};return{getTemplate:function(b){return a.templateUrl?null:b[a.template]?b[a.template]:a.template},getTemplateUrl:function(){return a.templateUrl},getTemplateLast:function(b){return a.templateLastUrl?null:b[a.templateLast]?b[a.templateLast]:a.templateLast},getTemplateLastUrl:function(){return a.templateLastUrl},getStatesChain:function(c){for(var d=[],e=b.$current.self.name;e;e=l(e))if(k(d,e),c&&d.length)return d;return a.prefixStateName&&k(d,a.prefixStateName),d},getLastStep:function(){var a=this.getStatesChain(!0);return a.length?a[0]:c},$getLastViewScope:function(){return i}}}]}function h(a,c,d){var e={bootstrap2:'<ul class="breadcrumb"><li ng-repeat="step in steps" ng-switch="$last || !!step.abstract" ng-class="{active: $last}"><a ng-switch-when="false" href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a><span ng-switch-when="true">{{step.ncyBreadcrumbLabel}}</span><span class="divider" ng-hide="$last">/</span></li></ul>',bootstrap3:'<ol class="breadcrumb"><li ng-repeat="step in steps" ng-class="{active: $last}" ng-switch="$last || !!step.abstract"><a ng-switch-when="false" href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a><span ng-switch-when="true">{{step.ncyBreadcrumbLabel}}</span></li></ol>'};return{restrict:"AE",replace:!0,scope:{},template:c.getTemplate(e),templateUrl:c.getTemplateUrl(),link:{post:function(e){var g=[],h=function(){n(g),g=[];var d=c.$getLastViewScope();e.steps=c.getStatesChain(),b.forEach(e.steps,function(b){if(b.ncyBreadcrumb&&b.ncyBreadcrumb.label){var c=a(b.ncyBreadcrumb.label);b.ncyBreadcrumbLabel=c(d),m(g,c,d,b)}else b.ncyBreadcrumbLabel=b.name})};f("BreadcrumbDirective.$viewContentLoaded",d,"$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||h()}),h()}}}}function i(a,b,c){var d={"default":"{{ncyBreadcrumbLabel}}"};return{restrict:"A",scope:{},template:b.getTemplateLast(d),templateUrl:b.getTemplateLastUrl(),compile:function(d,e){var g=d.attr(e.$attr.ncyBreadcrumbLast);return g&&d.html(g),{post:function(d){var e=[],g=function(){n(e),e=[];var c=b.$getLastViewScope(),f=b.getLastStep();if(f)if(d.ncyBreadcrumbLink=f.ncyBreadcrumbLink,f.ncyBreadcrumb&&f.ncyBreadcrumb.label){var g=a(f.ncyBreadcrumb.label);d.ncyBreadcrumbLabel=g(c),m(e,g,c,d)}else d.ncyBreadcrumbLabel=f.name};f("BreadcrumbLastDirective.$viewContentLoaded",c,"$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||g()}),g()}}}}}function j(a,c,d){return{restrict:"A",scope:{},template:"{{ncyBreadcrumbChain}}",compile:function(e,g){var h=e.attr(g.$attr.ncyBreadcrumbText);h&&e.html(h);var i=e.attr(g.$attr.ncyBreadcrumbTextSeparator)||" / ";return{post:function(e){var g=[],h=function(a,c,d){b.forEach(l(c),function(b){var c=d.$watch(b,function(a,b){a!==b&&j()});a.push(c)})},j=function(){n(g),g=[];var d=c.$getLastViewScope(),f=c.getStatesChain(),j=[];b.forEach(f,function(b){if(b.ncyBreadcrumb&&b.ncyBreadcrumb.label){var c=a(b.ncyBreadcrumb.label);j.push(c(d)),h(g,c,d)}else j.push(b.name)}),e.ncyBreadcrumbChain=j.join(i)};f("BreadcrumbTextDirective.$viewContentLoaded",d,"$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||j()}),j()}}}}}var k={},l=function(a){if(a.expressions)return a.expressions;var c=[];return b.forEach(a.parts,function(a){b.isFunction(a)&&c.push(a.exp)}),c},m=function(a,c,d,e){b.forEach(l(c),function(b){var f=d.$watch(b,function(){e.ncyBreadcrumbLabel=c(d)});a.push(f)})},n=function(a){b.forEach(a,function(a){a()})};h.$inject=["$interpolate","$breadcrumb","$rootScope"],i.$inject=["$interpolate","$breadcrumb","$rootScope"],j.$inject=["$interpolate","$breadcrumb","$rootScope"],b.module("ncy-angular-breadcrumb",["ui.router.state"]).provider("$breadcrumb",g).directive("ncyBreadcrumb",h).directive("ncyBreadcrumbLast",i).directive("ncyBreadcrumbText",j)}(window,window.angular); |
'use strict'; | ||
var LIVERELOAD_PORT = 35729; | ||
var lrSnippet = require('connect-livereload')({ port: LIVERELOAD_PORT }); | ||
var lrSnippet = require('connect-livereload')({ | ||
port: LIVERELOAD_PORT | ||
}); | ||
var mountFolder = function (connect, dir) { | ||
@@ -177,4 +179,15 @@ return connect.static(require('path').resolve(dir)); | ||
release: ["sample/*.zip"], | ||
test: ["testDependencies/*"] | ||
test: ["testDependencies/*"], | ||
meteor: ['.build.*', 'versions.json'] | ||
}, | ||
exec: { | ||
'meteor-init': { | ||
command: [ | ||
'type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; }' | ||
].join(';') | ||
}, | ||
'meteor-publish': { | ||
command: 'meteor publish' | ||
} | ||
}, | ||
compress: { | ||
@@ -186,3 +199,7 @@ release: { | ||
files: [ | ||
{expand: true, cwd: 'release/', src: ['*.js']} | ||
{ | ||
expand: true, | ||
cwd: 'release/', | ||
src: ['*.js'] | ||
} | ||
] | ||
@@ -207,7 +224,10 @@ } | ||
testMinimal: { | ||
command: 'bower install angular#=1.0.8 angular-mocks#=1.0.8 angular-sanitize#=1.0.8 angular-ui-router#=0.2.0 --config.directory=. --config.cwd=testDependencies' | ||
command: 'bower install angular#=1.2.29 angular-mocks#=1.2.29 angular-sanitize#=1.2.29 angular-ui-router#=0.2.18 --config.directory=. --config.cwd=testDependencies' | ||
}, | ||
test1dot2: { | ||
command: 'bower install angular#=1.2.18 angular-mocks#=1.2.18 angular-sanitize#=1.2.18 angular-ui-router#=0.2.15 --config.directory=. --config.cwd=testDependencies' | ||
test1dot3: { | ||
command: 'bower install angular#=1.3.20 angular-mocks#=1.3.20 angular-sanitize#=1.3.20 angular-ui-router#=0.2.18 --config.directory=. --config.cwd=testDependencies' | ||
}, | ||
test1dot4: { | ||
command: 'bower install angular#=1.4.10 angular-mocks#=1.4.10 angular-sanitize#=1.4.10 angular-ui-router#=0.2.18 --config.directory=. --config.cwd=testDependencies' | ||
}, | ||
testLatest: { | ||
@@ -235,6 +255,10 @@ command: 'bower install angular angular-mocks angular-sanitize angular-ui-router --config.directory=. --config.cwd=testDependencies' | ||
grunt.loadNpmTasks('grunt-text-replace'); | ||
grunt.loadNpmTasks('grunt-exec'); | ||
grunt.registerTask('test', ['jshint', 'testMin', 'test1dot2', 'testLatest']); | ||
grunt.registerTask('meteor-publish', ['exec:meteor-init', 'exec:meteor-publish']); | ||
grunt.registerTask('test', ['jshint', 'testMin', 'test1dot3', 'test1dot4', 'testLatest']); | ||
grunt.registerTask('testMin', ['clean:test', 'shell:testMinimal', 'karma']); | ||
grunt.registerTask('test1dot2', ['clean:test', 'shell:test1dot2', 'karma']); | ||
grunt.registerTask('test1dot3', ['clean:test', 'shell:test1dot3', 'karma']); | ||
grunt.registerTask('test1dot4', ['clean:test', 'shell:test1dot4', 'karma']); | ||
grunt.registerTask('testLatest', ['clean:test', 'shell:testLatest', 'karma']); | ||
@@ -246,4 +270,4 @@ | ||
grunt.registerTask('release-prepare', 'Update all files for a release', function(target) { | ||
if(!target) { | ||
grunt.registerTask('release-prepare', 'Update all files for a release', function (target) { | ||
if (!target) { | ||
target = 'patch'; | ||
@@ -250,0 +274,0 @@ } |
{ | ||
"name": "angular-breadcrumb", | ||
"description": "AngularJS module that generates a breadcrumb from ui-router's states", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"homepage": "http://ncuillery.github.io/angular-breadcrumb", | ||
@@ -44,11 +44,20 @@ "author": { | ||
"grunt-conventional-changelog": "~1.1.0", | ||
"grunt-karma": "~0.6.2", | ||
"grunt-exec": "^0.4.6", | ||
"grunt-karma": "~0.12.2", | ||
"grunt-open": "~0.2.0", | ||
"grunt-shell": "~0.7.0", | ||
"grunt-text-replace": "^0.3.12", | ||
"karma": "~0.10.2", | ||
"karma-coverage": "~0.1.0", | ||
"karma-story-reporter": "~0.2.2" | ||
"jasmine-core": "^2.4.1", | ||
"karma": "^0.13.22", | ||
"karma-coverage": "~0.1.5", | ||
"karma-jasmine": "^0.3.8", | ||
"karma-phantomjs-launcher": "^1.0.0", | ||
"karma-story-reporter": "^0.3.1", | ||
"phantomjs-prebuilt": "^2.1.7", | ||
"spacejam": "^1.1.1" | ||
}, | ||
"keywords": ["angular", "breadcrumb"] | ||
"keywords": [ | ||
"angular", | ||
"breadcrumb" | ||
] | ||
} |
# [](http://ncuillery.github.io/angular-breadcrumb/) | ||
[](https://travis-ci.org/ncuillery/angular-breadcrumb) [](https://coveralls.io/r/ncuillery/angular-breadcrumb) | ||
[](https://travis-ci.org/ncuillery/angular-breadcrumb) [](https://coveralls.io/r/ncuillery/angular-breadcrumb) | ||
[](https://badge.fury.io/js/angular-breadcrumb) | ||
@@ -4,0 +5,0 @@ Angular-breadcrumb is a module for [AngularJS](http://angularjs.org), which generates a breadcrumb for any page of your application. It is strongly based on the [ui-router](https://github.com/angular-ui/ui-router) framework and its hierarchical tree of states. |
@@ -1,4 +0,4 @@ | ||
/*! angular-breadcrumb - v0.4.1 | ||
/*! angular-breadcrumb - v0.5.0 | ||
* http://ncuillery.github.io/angular-breadcrumb | ||
* Copyright (c) 2015 Nicolas Cuillery; Licensed MIT */ | ||
* Copyright (c) 2016 Nicolas Cuillery; Licensed MIT */ | ||
@@ -22,2 +22,12 @@ (function (window, angular, undefined) { | ||
var $registeredListeners = {}; | ||
function registerListenerOnce(tag, $rootScope, event, fn) { | ||
var deregisterListenerFn = $registeredListeners[tag]; | ||
if ( deregisterListenerFn !== undefined ) { | ||
deregisterListenerFn(); | ||
} | ||
deregisterListenerFn = $rootScope.$on(event, fn); | ||
$registeredListeners[tag] = deregisterListenerFn; | ||
} | ||
function $Breadcrumb() { | ||
@@ -29,2 +39,4 @@ | ||
templateUrl: null, | ||
templateLast: 'default', | ||
templateLastUrl: null, | ||
includeAbstract : false | ||
@@ -42,3 +54,3 @@ }; | ||
// Early catch of $viewContentLoaded event | ||
$rootScope.$on('$viewContentLoaded', function (event) { | ||
registerListenerOnce('$Breadcrumb.$viewContentLoaded', $rootScope, '$viewContentLoaded', function (event) { | ||
// With nested views, the event occur several times, in "wrong" order | ||
@@ -86,2 +98,3 @@ if(!event.targetScope.ncyBreadcrumbIgnore && | ||
conf.ncyBreadcrumbLink = $state.href(ref.state, parentParams || $stateParams || {}); | ||
conf.ncyBreadcrumbStateRef = stateRef; | ||
chain.unshift(conf); | ||
@@ -126,2 +139,18 @@ } | ||
getTemplateLast: function(templates) { | ||
if($$options.templateLastUrl) { | ||
// templateUrl takes precedence over template | ||
return null; | ||
} else if(templates[$$options.templateLast]) { | ||
// Predefined templates (default) | ||
return templates[$$options.templateLast]; | ||
} else { | ||
return $$options.templateLast; | ||
} | ||
}, | ||
getTemplateLastUrl: function() { | ||
return $$options.templateLastUrl; | ||
}, | ||
getStatesChain: function(exitOnFirst) { // Deliberately undocumented param, see getLastStep | ||
@@ -162,2 +191,3 @@ var chain = []; | ||
} else { | ||
// Workaround for Angular 1.2.x | ||
var expressions = []; | ||
@@ -219,3 +249,3 @@ angular.forEach(interpolationFunction.parts, function(part) { | ||
labelWatchers = []; | ||
var viewScope = $breadcrumb.$getLastViewScope(); | ||
@@ -235,3 +265,3 @@ scope.steps = $breadcrumb.getStatesChain(); | ||
$rootScope.$on('$viewContentLoaded', function (event) { | ||
registerListenerOnce('BreadcrumbDirective.$viewContentLoaded', $rootScope, '$viewContentLoaded', function (event) { | ||
if(!event.targetScope.ncyBreadcrumbIgnore) { | ||
@@ -251,2 +281,5 @@ renderBreadcrumb(); | ||
function BreadcrumbLastDirective($interpolate, $breadcrumb, $rootScope) { | ||
var $$templates = { | ||
'default': '{{ncyBreadcrumbLabel}}' | ||
}; | ||
@@ -256,6 +289,9 @@ return { | ||
scope: {}, | ||
template: '{{ncyBreadcrumbLabel}}', | ||
template: $breadcrumb.getTemplateLast($$templates), | ||
templateUrl: $breadcrumb.getTemplateLastUrl(), | ||
compile: function(cElement, cAttrs) { | ||
// Override the default template if ncyBreadcrumbLast has a value | ||
// This should likely be removed in a future version since global | ||
// templating is now available for ncyBreadcrumbLast | ||
var template = cElement.attr(cAttrs.$attr.ncyBreadcrumbLast); | ||
@@ -273,3 +309,3 @@ if(template) { | ||
labelWatchers = []; | ||
var viewScope = $breadcrumb.$getLastViewScope(); | ||
@@ -291,3 +327,3 @@ var lastStep = $breadcrumb.getLastStep(); | ||
$rootScope.$on('$viewContentLoaded', function (event) { | ||
registerListenerOnce('BreadcrumbLastDirective.$viewContentLoaded', $rootScope, '$viewContentLoaded', function (event) { | ||
if(!event.targetScope.ncyBreadcrumbIgnore) { | ||
@@ -321,3 +357,3 @@ renderLabel(); | ||
} | ||
var separator = cElement.attr(cAttrs.$attr.ncyBreadcrumbTextSeparator) || ' / '; | ||
@@ -328,3 +364,3 @@ | ||
var labelWatchers = []; | ||
var registerWatchersText = function(labelWatcherArray, interpolationFunction, viewScope) { | ||
@@ -344,3 +380,3 @@ angular.forEach(getExpression(interpolationFunction), function(expression) { | ||
labelWatchers = []; | ||
var viewScope = $breadcrumb.$getLastViewScope(); | ||
@@ -359,7 +395,7 @@ var steps = $breadcrumb.getStatesChain(); | ||
}); | ||
scope.ncyBreadcrumbChain = combinedLabels.join(separator); | ||
}; | ||
$rootScope.$on('$viewContentLoaded', function (event) { | ||
registerListenerOnce('BreadcrumbTextDirective.$viewContentLoaded', $rootScope, '$viewContentLoaded', function (event) { | ||
if(!event.targetScope.ncyBreadcrumbIgnore) { | ||
@@ -366,0 +402,0 @@ renderLabel(); |
@@ -1,4 +0,4 @@ | ||
/*! angular-breadcrumb - v0.4.1 | ||
/*! angular-breadcrumb - v0.5.0 | ||
* http://ncuillery.github.io/angular-breadcrumb | ||
* Copyright (c) 2015 Nicolas Cuillery; Licensed MIT */ | ||
!function(a,b,c){"use strict";function d(a,c){return b.equals(a.length,c.length)?a>c:a.length>c.length}function e(a){var b=a.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/);if(!b||4!==b.length)throw new Error("Invalid state ref '"+a+"'");return{state:b[1],paramExpr:b[3]||null}}function f(){var a={prefixStateName:null,template:"bootstrap3",templateUrl:null,includeAbstract:!1};this.setOptions=function(c){b.extend(a,c)},this.$get=["$state","$stateParams","$rootScope",function(b,f,g){var h=g;g.$on("$viewContentLoaded",function(a){!a.targetScope.ncyBreadcrumbIgnore&&d(a.targetScope.$id,h.$id)&&(h=a.targetScope)});var i=function(a){var b=a.parent||(/^(.+)\.[^.]+$/.exec(a.name)||[])[1],c="object"==typeof b;return c?b.name:b},j=function(c,d){for(var g,i,j=e(d),k=!1,l=!1,m=0,n=c.length;n>m;m+=1)if(c[m].name===j.state)return;g=b.get(j.state),g.ncyBreadcrumb&&(g.ncyBreadcrumb.force&&(k=!0),g.ncyBreadcrumb.skip&&(l=!0)),g["abstract"]&&!a.includeAbstract&&!k||l||(j.paramExpr&&(i=h.$eval(j.paramExpr)),g.ncyBreadcrumbLink=b.href(j.state,i||f||{}),c.unshift(g))},k=function(a){var c=e(a),d=b.get(c.state);if(d.ncyBreadcrumb&&d.ncyBreadcrumb.parent){var f="function"==typeof d.ncyBreadcrumb.parent,g=f?d.ncyBreadcrumb.parent(h):d.ncyBreadcrumb.parent;if(g)return g}return i(d)};return{getTemplate:function(b){return a.templateUrl?null:b[a.template]?b[a.template]:a.template},getTemplateUrl:function(){return a.templateUrl},getStatesChain:function(c){for(var d=[],e=b.$current.self.name;e;e=k(e))if(j(d,e),c&&d.length)return d;return a.prefixStateName&&j(d,a.prefixStateName),d},getLastStep:function(){var a=this.getStatesChain(!0);return a.length?a[0]:c},$getLastViewScope:function(){return h}}}]}function g(a,c,d){var e={bootstrap2:'<ul class="breadcrumb"><li ng-repeat="step in steps" ng-switch="$last || !!step.abstract" ng-class="{active: $last}"><a ng-switch-when="false" href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a><span ng-switch-when="true">{{step.ncyBreadcrumbLabel}}</span><span class="divider" ng-hide="$last">/</span></li></ul>',bootstrap3:'<ol class="breadcrumb"><li ng-repeat="step in steps" ng-class="{active: $last}" ng-switch="$last || !!step.abstract"><a ng-switch-when="false" href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a><span ng-switch-when="true">{{step.ncyBreadcrumbLabel}}</span></li></ol>'};return{restrict:"AE",replace:!0,scope:{},template:c.getTemplate(e),templateUrl:c.getTemplateUrl(),link:{post:function(e){var f=[],g=function(){l(f),f=[];var d=c.$getLastViewScope();e.steps=c.getStatesChain(),b.forEach(e.steps,function(b){if(b.ncyBreadcrumb&&b.ncyBreadcrumb.label){var c=a(b.ncyBreadcrumb.label);b.ncyBreadcrumbLabel=c(d),k(f,c,d,b)}else b.ncyBreadcrumbLabel=b.name})};d.$on("$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||g()}),g()}}}}function h(a,b,c){return{restrict:"A",scope:{},template:"{{ncyBreadcrumbLabel}}",compile:function(d,e){var f=d.attr(e.$attr.ncyBreadcrumbLast);return f&&d.html(f),{post:function(d){var e=[],f=function(){l(e),e=[];var c=b.$getLastViewScope(),f=b.getLastStep();if(f)if(d.ncyBreadcrumbLink=f.ncyBreadcrumbLink,f.ncyBreadcrumb&&f.ncyBreadcrumb.label){var g=a(f.ncyBreadcrumb.label);d.ncyBreadcrumbLabel=g(c),k(e,g,c,d)}else d.ncyBreadcrumbLabel=f.name};c.$on("$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||f()}),f()}}}}}function i(a,c,d){return{restrict:"A",scope:{},template:"{{ncyBreadcrumbChain}}",compile:function(e,f){var g=e.attr(f.$attr.ncyBreadcrumbText);g&&e.html(g);var h=e.attr(f.$attr.ncyBreadcrumbTextSeparator)||" / ";return{post:function(e){var f=[],g=function(a,c,d){b.forEach(j(c),function(b){var c=d.$watch(b,function(a,b){a!==b&&i()});a.push(c)})},i=function(){l(f),f=[];var d=c.$getLastViewScope(),i=c.getStatesChain(),j=[];b.forEach(i,function(b){if(b.ncyBreadcrumb&&b.ncyBreadcrumb.label){var c=a(b.ncyBreadcrumb.label);j.push(c(d)),g(f,c,d)}else j.push(b.name)}),e.ncyBreadcrumbChain=j.join(h)};d.$on("$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||i()}),i()}}}}}var j=function(a){if(a.expressions)return a.expressions;var c=[];return b.forEach(a.parts,function(a){b.isFunction(a)&&c.push(a.exp)}),c},k=function(a,c,d,e){b.forEach(j(c),function(b){var f=d.$watch(b,function(){e.ncyBreadcrumbLabel=c(d)});a.push(f)})},l=function(a){b.forEach(a,function(a){a()})};g.$inject=["$interpolate","$breadcrumb","$rootScope"],h.$inject=["$interpolate","$breadcrumb","$rootScope"],i.$inject=["$interpolate","$breadcrumb","$rootScope"],b.module("ncy-angular-breadcrumb",["ui.router.state"]).provider("$breadcrumb",f).directive("ncyBreadcrumb",g).directive("ncyBreadcrumbLast",h).directive("ncyBreadcrumbText",i)}(window,window.angular); | ||
* Copyright (c) 2016 Nicolas Cuillery; Licensed MIT */ | ||
!function(a,b,c){"use strict";function d(a,c){return b.equals(a.length,c.length)?a>c:a.length>c.length}function e(a){var b=a.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/);if(!b||4!==b.length)throw new Error("Invalid state ref '"+a+"'");return{state:b[1],paramExpr:b[3]||null}}function f(a,b,d,e){var f=k[a];f!==c&&f(),f=b.$on(d,e),k[a]=f}function g(){var a={prefixStateName:null,template:"bootstrap3",templateUrl:null,templateLast:"default",templateLastUrl:null,includeAbstract:!1};this.setOptions=function(c){b.extend(a,c)},this.$get=["$state","$stateParams","$rootScope",function(b,g,h){var i=h;f("$Breadcrumb.$viewContentLoaded",h,"$viewContentLoaded",function(a){!a.targetScope.ncyBreadcrumbIgnore&&d(a.targetScope.$id,i.$id)&&(i=a.targetScope)});var j=function(a){var b=a.parent||(/^(.+)\.[^.]+$/.exec(a.name)||[])[1],c="object"==typeof b;return c?b.name:b},k=function(c,d){for(var f,h,j=e(d),k=!1,l=!1,m=0,n=c.length;n>m;m+=1)if(c[m].name===j.state)return;f=b.get(j.state),f.ncyBreadcrumb&&(f.ncyBreadcrumb.force&&(k=!0),f.ncyBreadcrumb.skip&&(l=!0)),f["abstract"]&&!a.includeAbstract&&!k||l||(j.paramExpr&&(h=i.$eval(j.paramExpr)),f.ncyBreadcrumbLink=b.href(j.state,h||g||{}),f.ncyBreadcrumbStateRef=d,c.unshift(f))},l=function(a){var c=e(a),d=b.get(c.state);if(d.ncyBreadcrumb&&d.ncyBreadcrumb.parent){var f="function"==typeof d.ncyBreadcrumb.parent,g=f?d.ncyBreadcrumb.parent(i):d.ncyBreadcrumb.parent;if(g)return g}return j(d)};return{getTemplate:function(b){return a.templateUrl?null:b[a.template]?b[a.template]:a.template},getTemplateUrl:function(){return a.templateUrl},getTemplateLast:function(b){return a.templateLastUrl?null:b[a.templateLast]?b[a.templateLast]:a.templateLast},getTemplateLastUrl:function(){return a.templateLastUrl},getStatesChain:function(c){for(var d=[],e=b.$current.self.name;e;e=l(e))if(k(d,e),c&&d.length)return d;return a.prefixStateName&&k(d,a.prefixStateName),d},getLastStep:function(){var a=this.getStatesChain(!0);return a.length?a[0]:c},$getLastViewScope:function(){return i}}}]}function h(a,c,d){var e={bootstrap2:'<ul class="breadcrumb"><li ng-repeat="step in steps" ng-switch="$last || !!step.abstract" ng-class="{active: $last}"><a ng-switch-when="false" href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a><span ng-switch-when="true">{{step.ncyBreadcrumbLabel}}</span><span class="divider" ng-hide="$last">/</span></li></ul>',bootstrap3:'<ol class="breadcrumb"><li ng-repeat="step in steps" ng-class="{active: $last}" ng-switch="$last || !!step.abstract"><a ng-switch-when="false" href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a><span ng-switch-when="true">{{step.ncyBreadcrumbLabel}}</span></li></ol>'};return{restrict:"AE",replace:!0,scope:{},template:c.getTemplate(e),templateUrl:c.getTemplateUrl(),link:{post:function(e){var g=[],h=function(){n(g),g=[];var d=c.$getLastViewScope();e.steps=c.getStatesChain(),b.forEach(e.steps,function(b){if(b.ncyBreadcrumb&&b.ncyBreadcrumb.label){var c=a(b.ncyBreadcrumb.label);b.ncyBreadcrumbLabel=c(d),m(g,c,d,b)}else b.ncyBreadcrumbLabel=b.name})};f("BreadcrumbDirective.$viewContentLoaded",d,"$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||h()}),h()}}}}function i(a,b,c){var d={"default":"{{ncyBreadcrumbLabel}}"};return{restrict:"A",scope:{},template:b.getTemplateLast(d),templateUrl:b.getTemplateLastUrl(),compile:function(d,e){var g=d.attr(e.$attr.ncyBreadcrumbLast);return g&&d.html(g),{post:function(d){var e=[],g=function(){n(e),e=[];var c=b.$getLastViewScope(),f=b.getLastStep();if(f)if(d.ncyBreadcrumbLink=f.ncyBreadcrumbLink,f.ncyBreadcrumb&&f.ncyBreadcrumb.label){var g=a(f.ncyBreadcrumb.label);d.ncyBreadcrumbLabel=g(c),m(e,g,c,d)}else d.ncyBreadcrumbLabel=f.name};f("BreadcrumbLastDirective.$viewContentLoaded",c,"$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||g()}),g()}}}}}function j(a,c,d){return{restrict:"A",scope:{},template:"{{ncyBreadcrumbChain}}",compile:function(e,g){var h=e.attr(g.$attr.ncyBreadcrumbText);h&&e.html(h);var i=e.attr(g.$attr.ncyBreadcrumbTextSeparator)||" / ";return{post:function(e){var g=[],h=function(a,c,d){b.forEach(l(c),function(b){var c=d.$watch(b,function(a,b){a!==b&&j()});a.push(c)})},j=function(){n(g),g=[];var d=c.$getLastViewScope(),f=c.getStatesChain(),j=[];b.forEach(f,function(b){if(b.ncyBreadcrumb&&b.ncyBreadcrumb.label){var c=a(b.ncyBreadcrumb.label);j.push(c(d)),h(g,c,d)}else j.push(b.name)}),e.ncyBreadcrumbChain=j.join(i)};f("BreadcrumbTextDirective.$viewContentLoaded",d,"$viewContentLoaded",function(a){a.targetScope.ncyBreadcrumbIgnore||j()}),j()}}}}}var k={},l=function(a){if(a.expressions)return a.expressions;var c=[];return b.forEach(a.parts,function(a){b.isFunction(a)&&c.push(a.exp)}),c},m=function(a,c,d,e){b.forEach(l(c),function(b){var f=d.$watch(b,function(){e.ncyBreadcrumbLabel=c(d)});a.push(f)})},n=function(a){b.forEach(a,function(a){a()})};h.$inject=["$interpolate","$breadcrumb","$rootScope"],i.$inject=["$interpolate","$breadcrumb","$rootScope"],j.$inject=["$interpolate","$breadcrumb","$rootScope"],b.module("ncy-angular-breadcrumb",["ui.router.state"]).provider("$breadcrumb",g).directive("ncyBreadcrumb",h).directive("ncyBreadcrumbLast",i).directive("ncyBreadcrumbText",j)}(window,window.angular); |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
69292
10.19%14
7.69%1010
11.11%31
3.33%26
30%1
Infinity%