├── .gitignore ├── app ├── html │ ├── playlist.html │ ├── query-form.html │ └── index.html ├── css │ └── style.css ├── app.js └── javascript │ └── services │ └── services.js ├── .bowerrc ├── .floo ├── .flooignore ├── bower_components ├── angular-echonest │ ├── .gitignore │ ├── bower.json │ ├── .travis.yml │ ├── .bower.json │ ├── package.json │ ├── LICENSE │ ├── Gruntfile.js │ ├── karma.config.js │ ├── build │ │ ├── angular-echonest.min.js │ │ └── angular-echonest.js │ ├── test │ │ ├── songs.js │ │ └── artists.js │ ├── README.md │ └── src │ │ └── angular-echonest.js ├── angular │ ├── angular.min.js.gzip │ ├── bower.json │ ├── angular-csp.css │ ├── .bower.json │ ├── package.json │ └── README.md ├── angular-mocks │ ├── bower.json │ ├── .bower.json │ ├── package.json │ └── README.md └── ui-router │ ├── bower.json │ ├── .bower.json │ ├── LICENSE │ ├── src │ ├── stateFilters.js │ ├── viewScroll.js │ ├── view.js │ ├── templateFactory.js │ ├── common.js │ ├── viewDirective.js │ ├── stateDirectives.js │ ├── resolve.js │ └── urlRouter.js │ ├── CONTRIBUTING.md │ ├── api │ └── angular-ui-router.d.ts │ ├── README.md │ ├── CHANGELOG.md │ └── release │ └── angular-ui-router.min.js ├── echonest-sample.js ├── README.md └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | /echonest.js -------------------------------------------------------------------------------- /app/html/playlist.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/css/style.css: -------------------------------------------------------------------------------- 1 | style.css 2 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /.floo: -------------------------------------------------------------------------------- 1 | { 2 | "url": "https://floobits.com/HackReactor/Muse" 3 | } -------------------------------------------------------------------------------- /.flooignore: -------------------------------------------------------------------------------- 1 | #* 2 | *.o 3 | *.pyc 4 | *~ 5 | extern/ 6 | node_modules/ 7 | tmp 8 | vendor/ -------------------------------------------------------------------------------- /bower_components/angular-echonest/.gitignore: -------------------------------------------------------------------------------- 1 | app/ 2 | node_modules/ 3 | bower_components/ 4 | .DS_Store -------------------------------------------------------------------------------- /bower_components/angular/angular.min.js.gzip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicmitchell/muse/HEAD/bower_components/angular/angular.min.js.gzip -------------------------------------------------------------------------------- /bower_components/angular-echonest/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-echonest", 3 | "version": "0.2.5", 4 | "main": "build/angular-echonest.js" 5 | } -------------------------------------------------------------------------------- /echonest-sample.js: -------------------------------------------------------------------------------- 1 | // Replace the value below with your EchoNest API key 2 | // Uncomment the line 3 | // Rename this file to 'echonest.js' 4 | // var echonestApiKey = 'API KEY'; -------------------------------------------------------------------------------- /bower_components/angular/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular", 3 | "version": "1.3.5", 4 | "main": "./angular.js", 5 | "ignore": [], 6 | "dependencies": { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /bower_components/angular-mocks/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-mocks", 3 | "version": "1.3.5", 4 | "main": "./angular-mocks.js", 5 | "ignore": [], 6 | "dependencies": { 7 | "angular": "1.3.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /bower_components/angular-echonest/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.10 4 | before_script: 5 | - export DISPLAY=:99.0 6 | - sh -e /etc/init.d/xvfb start 7 | - npm install -g grunt-cli 8 | - npm install -g bower 9 | - bower install angular 10 | - bower install angular-mocks -------------------------------------------------------------------------------- /bower_components/angular/angular-csp.css: -------------------------------------------------------------------------------- 1 | /* Include this file in your html if you are using the CSP mode. */ 2 | 3 | @charset "UTF-8"; 4 | 5 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], 6 | .ng-cloak, .x-ng-cloak, 7 | .ng-hide:not(.ng-hide-animate) { 8 | display: none !important; 9 | } 10 | 11 | ng\:form { 12 | display: block; 13 | } 14 | -------------------------------------------------------------------------------- /app/html/query-form.html: -------------------------------------------------------------------------------- 1 |
9 | -------------------------------------------------------------------------------- /bower_components/angular-echonest/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-echonest", 3 | "main": "build/angular-echonest.js", 4 | "homepage": "https://github.com/Kraku/angular-echonest", 5 | "_release": "65f49da82b", 6 | "_resolution": { 7 | "type": "branch", 8 | "branch": "master", 9 | "commit": "65f49da82b7d43b993c02e1ace30e4092ceed2b2" 10 | }, 11 | "_source": "git://github.com/Kraku/angular-echonest.git", 12 | "_target": "*", 13 | "_originalSource": "angular-echonest", 14 | "_direct": true 15 | } -------------------------------------------------------------------------------- /bower_components/ui-router/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-ui-router", 3 | "version": "0.2.13", 4 | "main": "./release/angular-ui-router.js", 5 | "dependencies": { 6 | "angular": ">= 1.0.8" 7 | }, 8 | "ignore": [ 9 | "**/.*", 10 | "node_modules", 11 | "bower_components", 12 | "component.json", 13 | "package.json", 14 | "lib", 15 | "config", 16 | "sample", 17 | "test", 18 | "tests", 19 | "ngdoc_assets", 20 | "Gruntfile.js", 21 | "files.js" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /bower_components/angular/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular", 3 | "version": "1.3.5", 4 | "main": "./angular.js", 5 | "ignore": [], 6 | "dependencies": {}, 7 | "homepage": "https://github.com/angular/bower-angular", 8 | "_release": "1.3.5", 9 | "_resolution": { 10 | "type": "version", 11 | "tag": "v1.3.5", 12 | "commit": "9acb014af4fd7b0ab001c64fa7bcac454ab4050b" 13 | }, 14 | "_source": "git://github.com/angular/bower-angular.git", 15 | "_target": "1.3.5", 16 | "_originalSource": "angular" 17 | } -------------------------------------------------------------------------------- /bower_components/angular-mocks/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-mocks", 3 | "version": "1.3.5", 4 | "main": "./angular-mocks.js", 5 | "ignore": [], 6 | "dependencies": { 7 | "angular": "1.3.5" 8 | }, 9 | "homepage": "https://github.com/angular/bower-angular-mocks", 10 | "_release": "1.3.5", 11 | "_resolution": { 12 | "type": "version", 13 | "tag": "v1.3.5", 14 | "commit": "e5356ca3fa80f824ac7e3d9651156401e6bf2a38" 15 | }, 16 | "_source": "git://github.com/angular/bower-angular-mocks.git", 17 | "_target": "~1.3.5", 18 | "_originalSource": "angular-mocks", 19 | "_direct": true 20 | } -------------------------------------------------------------------------------- /bower_components/angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular", 3 | "version": "1.3.5", 4 | "description": "HTML enhanced for web apps", 5 | "main": "angular.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/angular/angular.js.git" 12 | }, 13 | "keywords": [ 14 | "angular", 15 | "framework", 16 | "browser", 17 | "client-side" 18 | ], 19 | "author": "Angular Core Team
55 | * $scope.$on('$viewContentLoading',
56 | * function(event, viewConfig){
57 | * // Access to all the view config properties.
58 | * // and one special property 'targetView'
59 | * // viewConfig.targetView
60 | * });
61 | *
62 | */
63 | $rootScope.$broadcast('$viewContentLoading', options);
64 | }
65 | return result;
66 | }
67 | };
68 | }
69 | }
70 |
71 | angular.module('ui.router.state').provider('$view', $ViewProvider);
72 |
--------------------------------------------------------------------------------
/app/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var muse = angular.module('muse', [
4 | 'services',
5 | 'ui.router'
6 | ]);
7 |
8 | muse.config(function($stateProvider){
9 | $stateProvider
10 | .state("query", {
11 | url: '/query',
12 | templateUrl: 'app/html/query-form.html',
13 | controller: 'QueryController'
14 | });
15 | });
16 |
17 | muse.controller("QueryController", function($scope,$http, $q, EchonestFactory) {
18 | //USE songs/artist suggest for error handling
19 | //Search for songs based on query
20 | $scope.search = function(artist,title){
21 | EchonestFactory.search(artist,title);
22 | }
23 |
24 | // var defer = $q.defer();
25 |
26 | // defer.promise.then(function () {
27 | // console.log(EchonestFactory.results.audio_summary.audio_summary.danceability);
28 | // $scope.danceability = EchonestFactory.results.audio_summary.audio_summary.danceability;
29 | // $scope.energy = EchonestFactory.results.audio_summary.audio_summary.energy;
30 | // $scope.instrumentalness = EchonestFactory.results.audio_summary.audio_summary.instrumentalness;
31 | // $scope.liveness = EchonestFactory.results.audio_summary.audio_summary.liveness;
32 | // $scope.speachiness = EchonestFactory.results.audio_summary.audio_summary.speachiness;
33 | // $scope.initial = EchonestFactory.results.songs[0];
34 | // });
35 |
36 | // defer.resolve();
37 | });
38 |
39 |
40 | muse.controller("PlaylistController", function($scope,$http, PlaylistFactory, EchonestFactory) {
41 |
42 | $scope.search = function(artist, danceability, energy){
43 | var playlist = PlaylistFactory.search(EchonestFactory.results.artist_summary.name, danceability, energy);
44 | $scope.playlist = PlaylistFactory.results;
45 | // console.log('PLAYLIST RESULTS', $scope.playlist);
46 | };
47 |
48 | });
49 |
50 |
51 |
52 | muse.controller("YoutubeController", function($scope,$http, YoutubeFactory, EchonestFactory) {
53 |
54 |
55 | $scope.youtubeSearch = function(artist, title){
56 | console.log(EchonestFactory.results);
57 | YoutubeFactory.search(artist, title);
58 | // YoutubeFactory.search(EchonestFactory.results.songs[0].artist_name, EchonestFactory.results.songs[0].title);
59 | console.log('YOUTUBE CONTROLLER', YoutubeFactory);
60 | // $scope.initialDanceability = PlaylistFactory.search($scope.selectedArtist, danceability, energy)[0]
61 | };
62 |
63 | $scope.vidId = YoutubeFactory.results.vidId;
64 | });
65 |
66 |
67 | // create a playlist
68 | // based on:
69 | // genre
70 | // specicied audio_buckets (danceability)
71 |
72 |
73 | // max_danceability no no 0.0 < danceability < 1.0 the maximum danceability of any song
74 | // min_danceability no no 0.0 < danceability < 1.0 the minimum danceability of any song
75 |
76 | //EXPERIMENTAL SPEECH QUERY
77 | // Generates a 20 song playlist of popular music from the 70s sorted by increasing tempo
78 | // http://developer.echonest.com/api/v4/playlist/static?api_key=CNQ7EJLGCHNW8QOIT&description=70s&description=disco&type=artist-description&artist_min_familiarity=.7&sort=tempo-asc&results=20
79 |
--------------------------------------------------------------------------------
/bower_components/angular-echonest/test/songs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Artists', function() {
4 | var echonest, httpBackend;
5 | var apiUrl = 'http://developer.echonest.com/api/v4/';
6 |
7 | var songsApiResponse = {
8 | response: {
9 | songs: [
10 | {
11 | artist_id: '456',
12 | id: '74574',
13 | artist_name: 'motorhead',
14 | title: 'foo bar'
15 | },
16 | {
17 | artist_id: '678',
18 | id: '6546546',
19 | artist_name: 'nirvana',
20 | title: 'bar'
21 | },
22 | {
23 | artist_id: '5453',
24 | id: '321312',
25 | artist_name: 'acdc',
26 | title: 'foo'
27 | }
28 | ],
29 | status: {
30 | code: 0,
31 | message: 'Success',
32 | version: '4.2'
33 | }
34 | }
35 | };
36 |
37 | var songApiResponse = {
38 | response: {
39 | songs: [
40 | {
41 | artist_id: '456',
42 | id: '74574',
43 | artist_name: 'motorhead',
44 | title: 'foo bar'
45 | }
46 | ],
47 | status: {
48 | code: 0,
49 | message: 'Success',
50 | version: '4.2'
51 | }
52 | }
53 | };
54 |
55 | beforeEach(angular.mock.module('angular-echonest'));
56 |
57 | beforeEach(inject(function($injector) {
58 | echonest = $injector.get('Echonest');
59 | httpBackend = $injector.get("$httpBackend");
60 |
61 | httpBackend.when('JSONP', apiUrl + 'song/profile?api_key=&callback=JSON_CALLBACK&format=jsonp&id=SOCZMFK12AC468668F').respond(songApiResponse);
62 | httpBackend.when('JSONP', apiUrl + 'song/search?api_key=&callback=JSON_CALLBACK&format=jsonp&name=foo+bar').respond(songsApiResponse);
63 | httpBackend.when('JSONP', apiUrl + 'song/identify?api_key=&artist=Michael+Jackson&callback=JSON_CALLBACK&code=eJxVlIuNwzAMQ1fxC&format=jsonp&title=Billie+Jean').respond(songsApiResponse);
64 | }));
65 |
66 | //
67 | // Songs
68 | //
69 | it('get method should return song object', function() {
70 | echonest.songs.get({
71 | id: 'SOCZMFK12AC468668F'
72 | }).then(function(song, status) {
73 | expect(song.artist_id).toBe('456');
74 | expect(song.id).toBe('74574');
75 | expect(song.artist_name).toBe('motorhead');
76 | expect(song.title).toBe('foo bar');
77 | });
78 |
79 | httpBackend.flush();
80 | });
81 |
82 | it('search method should return array of song objects', function() {
83 | echonest.songs.search({
84 | name: 'foo bar'
85 | }).then(function(songs, status) {
86 | expect(songs.constructor.name).toBe('Array');
87 | expect(songs[0].constructor.name).toBe('Object');
88 | expect(songs[0].artist_id).toBe('456');
89 | expect(songs[0].id).toBe('74574');
90 | expect(songs[0].artist_name).toBe('motorhead');
91 | expect(songs[0].title).toBe('foo bar');
92 | });
93 |
94 | httpBackend.flush();
95 | });
96 |
97 | it('identify method should return array of song objects', function() {
98 | echonest.songs.identify({
99 | artist: 'Michael Jackson',
100 | title: 'Billie Jean',
101 | code: 'eJxVlIuNwzAMQ1fxC'
102 | }).then(function(songs, status) {
103 | expect(songs.constructor.name).toBe('Array');
104 | expect(songs[0].constructor.name).toBe('Object');
105 | expect(songs[0].artist_id).toBe('456');
106 | expect(songs[0].id).toBe('74574');
107 | expect(songs[0].artist_name).toBe('motorhead');
108 | expect(songs[0].title).toBe('foo bar');
109 | });
110 |
111 | httpBackend.flush();
112 | });
113 | });
114 |
--------------------------------------------------------------------------------
/app/javascript/services/services.js:
--------------------------------------------------------------------------------
1 | var services = angular.module('services', ['angular-echonest'])
2 |
3 | services.config(['EchonestProvider', function(EchonestProvider) {
4 | EchonestProvider.setApiKey(echonestApiKey);
5 | }]);
6 |
7 | services.factory('EchonestFactory', function ($http, Echonest) {
8 |
9 | var results = {};
10 | var search = function(artist, title){
11 | Echonest.songs.search({
12 | artist: artist || null,
13 | title: title || null,
14 | //return songs
15 | }).then(function(songs) {
16 | results.songs = songs;
17 | console.log('SONG RESULT', songs);
18 |
19 | //get artist info on top result
20 | Echonest.artists.get({
21 | id: songs[0].artist_id,
22 | bucket: 'terms'
23 | }).then(function(artist_summary) {
24 | results.artist_summary = artist_summary;
25 | console.log('ARTIST SUMMARY', artist_summary);
26 | return results;
27 | })
28 |
29 | //get audio summary on top result
30 | Echonest.songs.get({
31 | id: songs[0].id,
32 | bucket: 'audio_summary'
33 | }).then(function(audio_summary) {
34 | results.audio_summary = audio_summary;
35 | console.log('AUDIO SUMMARY', audio_summary);
36 | return results;
37 | })
38 | return results;
39 | });
40 | };
41 |
42 | return {
43 | search: search,
44 | results: results
45 | };
46 |
47 | });
48 |
49 | services.factory('PlaylistFactory', function($http){
50 | var results = {};
51 | var search = function(artist, danceability, energy){
52 | var queryURL = 'http://developer.echonest.com/api/v4/playlist/static?api_key=' + echonestApiKey;
53 | if(artist){
54 | queryURL += '&artist=' + artist;
55 | }
56 | if(danceability){
57 | queryURL += '&max_danceability=' + danceability;
58 | }
59 | if(energy){
60 | queryURL += '&max_energy=' + energy;
61 | }
62 | queryURL += '&format=json&results=5&type=artist-radio&bucket=audio_summary';
63 |
64 | $http.get(queryURL)
65 | .success(function(data, status, headers, config) {
66 | results.playlist = data;
67 | return data;
68 | })
69 | .error(function(data, status, headers, config) {
70 | console.log('error');
71 | });
72 | // return results;
73 | };
74 |
75 | return {
76 | search: search,
77 | results: results
78 | };
79 | });
80 |
81 |
82 | services.factory('YoutubeFactory', function ($http) {
83 |
84 | var results = {};
85 | var search = function(artist, title){
86 | console.log(artist);
87 | var youtubeApiKey = 'AIzaSyD8M6zcr3cPZlLL1XmBnRWBUlblNEYzMBo';
88 |
89 | //Query for youtube results based on echonest selected song
90 | var dataurl ='http://gdata.youtube.com/feeds/api/videos?q=' + title + '%20' + artist + '&orderby=rating&alt=json';
91 |
92 | $http.get(dataurl).success(function(data){
93 | console.log('YOUTUBE RESULTS', data.feed.entry)
94 | return data.feed.entry;
95 | var vidId = data.feed.entry[0].id.$t
96 | var result = vidId.split('videos/')[1]
97 | results.push(result);
98 | });
99 |
100 | //Return media for irst result of query
101 | // $http.get('http://developer.echonest.com/api/v4/playlist/static?api_key=' + echonestApiKey + '&artist=' + artist.name + '&format=json&results=5&type=artist').success(function(data, status, headers, config) {
102 | // playlist = data;
103 | // })
104 | // .error(function(data, status, headers, config) {
105 | // console.log('error');
106 | // });
107 | }
108 |
109 | return {
110 | search: search,
111 | results: results
112 | }
113 | });
114 |
--------------------------------------------------------------------------------
/bower_components/ui-router/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 | # Report an Issue
3 |
4 | Help us make UI-Router better! If you think you might have found a bug, or some other weirdness, start by making sure
5 | it hasn't already been reported. You can [search through existing issues](https://github.com/angular-ui/ui-router/search?q=wat%3F&type=Issues)
6 | to see if someone's reported one similar to yours.
7 |
8 | If not, then [create a plunkr](http://bit.ly/UIR-Plunk) that demonstrates the problem (try to use as little code
9 | as possible: the more minimalist, the faster we can debug it).
10 |
11 | Next, [create a new issue](https://github.com/angular-ui/ui-router/issues/new) that briefly explains the problem,
12 | and provides a bit of background as to the circumstances that triggered it. Don't forget to include the link to
13 | that plunkr you created!
14 |
15 | **Note**: If you're unsure how a feature is used, or are encountering some unexpected behavior that you aren't sure
16 | is a bug, it's best to talk it out on
17 | [StackOverflow](http://stackoverflow.com/questions/ask?tags=angularjs,angular-ui-router) before reporting it. This
18 | keeps development streamlined, and helps us focus on building great software.
19 |
20 |
21 | Issues only! |
22 | -------------|
23 | Please keep in mind that the issue tracker is for *issues*. Please do *not* post an issue if you need help or support. Instead, see one of the above-mentioned forums or [IRC](irc://irc.freenode.net/#angularjs). |
24 |
25 | ####Purple Labels
26 | A purple label means that **you** need to take some further action.
27 | - : Your issue is not specific enough, or there is no clear action that we can take. Please clarify and refine your issue.
28 | - : Please [create a plunkr](http://bit.ly/UIR-Plunk)
29 | - : We suspect your issue is really a help request, or could be answered by the community. Please ask your question on [StackOverflow](http://stackoverflow.com/questions/ask?tags=angularjs,angular-ui-router). If you determine that is an actual issue, please explain why.
30 |
31 | If your issue gets labeled with purple label, no further action will be taken until you respond to the label appropriately.
32 |
33 | # Contribute
34 |
35 | **(1)** See the **[Developing](#developing)** section below, to get the development version of UI-Router up and running on your local machine.
36 |
37 | **(2)** Check out the [roadmap](https://github.com/angular-ui/ui-router/milestones) to see where the project is headed, and if your feature idea fits with where we're headed.
38 |
39 | **(3)** If you're not sure, [open an RFC](https://github.com/angular-ui/ui-router/issues/new?title=RFC:%20My%20idea) to get some feedback on your idea.
40 |
41 | **(4)** Finally, commit some code and open a pull request. Code & commits should abide by the following rules:
42 |
43 | - *Always* have test coverage for new features (or regression tests for bug fixes), and *never* break existing tests
44 | - Commits should represent one logical change each; if a feature goes through multiple iterations, squash your commits down to one
45 | - Make sure to follow the [Angular commit message format](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format) so your change will appear in the changelog of the next release.
46 | - Changes should always respect the coding style of the project
47 |
48 |
49 |
50 | # Developing
51 |
52 | UI-Router uses grunt >= 0.4.x. Make sure to upgrade your environment and read the
53 | [Migration Guide](http://gruntjs.com/upgrading-from-0.3-to-0.4).
54 |
55 | Dependencies for building from source and running tests:
56 |
57 | * [grunt-cli](https://github.com/gruntjs/grunt-cli) - run: `$ npm install -g grunt-cli`
58 | * Then, install the development dependencies by running `$ npm install` from the project directory
59 |
60 | There are a number of targets in the gruntfile that are used to generating different builds:
61 |
62 | * `grunt`: Perform a normal build, runs jshint and karma tests
63 | * `grunt build`: Perform a normal build
64 | * `grunt dist`: Perform a clean build and generate documentation
65 | * `grunt dev`: Run dev server (sample app) and watch for changes, builds and runs karma tests on changes.
66 |
--------------------------------------------------------------------------------
/bower_components/ui-router/src/templateFactory.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ngdoc object
3 | * @name ui.router.util.$templateFactory
4 | *
5 | * @requires $http
6 | * @requires $templateCache
7 | * @requires $injector
8 | *
9 | * @description
10 | * Service. Manages loading of templates.
11 | */
12 | $TemplateFactory.$inject = ['$http', '$templateCache', '$injector'];
13 | function $TemplateFactory( $http, $templateCache, $injector) {
14 |
15 | /**
16 | * @ngdoc function
17 | * @name ui.router.util.$templateFactory#fromConfig
18 | * @methodOf ui.router.util.$templateFactory
19 | *
20 | * @description
21 | * Creates a template from a configuration object.
22 | *
23 | * @param {object} config Configuration object for which to load a template.
24 | * The following properties are search in the specified order, and the first one
25 | * that is defined is used to create the template:
26 | *
27 | * @param {string|object} config.template html string template or function to
28 | * load via {@link ui.router.util.$templateFactory#fromString fromString}.
29 | * @param {string|object} config.templateUrl url to load or a function returning
30 | * the url to load via {@link ui.router.util.$templateFactory#fromUrl fromUrl}.
31 | * @param {Function} config.templateProvider function to invoke via
32 | * {@link ui.router.util.$templateFactory#fromProvider fromProvider}.
33 | * @param {object} params Parameters to pass to the template function.
34 | * @param {object} locals Locals to pass to `invoke` if the template is loaded
35 | * via a `templateProvider`. Defaults to `{ params: params }`.
36 | *
37 | * @return {string|object} The template html as a string, or a promise for
38 | * that string,or `null` if no template is configured.
39 | */
40 | this.fromConfig = function (config, params, locals) {
41 | return (
42 | isDefined(config.template) ? this.fromString(config.template, params) :
43 | isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :
44 | isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, locals) :
45 | null
46 | );
47 | };
48 |
49 | /**
50 | * @ngdoc function
51 | * @name ui.router.util.$templateFactory#fromString
52 | * @methodOf ui.router.util.$templateFactory
53 | *
54 | * @description
55 | * Creates a template from a string or a function returning a string.
56 | *
57 | * @param {string|object} template html template as a string or function that
58 | * returns an html template as a string.
59 | * @param {object} params Parameters to pass to the template function.
60 | *
61 | * @return {string|object} The template html as a string, or a promise for that
62 | * string.
63 | */
64 | this.fromString = function (template, params) {
65 | return isFunction(template) ? template(params) : template;
66 | };
67 |
68 | /**
69 | * @ngdoc function
70 | * @name ui.router.util.$templateFactory#fromUrl
71 | * @methodOf ui.router.util.$templateFactory
72 | *
73 | * @description
74 | * Loads a template from the a URL via `$http` and `$templateCache`.
75 | *
76 | * @param {string|Function} url url of the template to load, or a function
77 | * that returns a url.
78 | * @param {Object} params Parameters to pass to the url function.
79 | * @return {string|Promise.33 | * 34 | * 35 | * 36 | * 37 | * 38 | *39 | * 40 | * You can only have one unnamed view within any template (or root html). If you are only using a 41 | * single view and it is unnamed then you can populate it like so: 42 | *
43 | *
44 | * $stateProvider.state("home", {
45 | * template: "HELLO!
"
46 | * })
47 | *
48 | *
49 | * The above is a convenient shortcut equivalent to specifying your view explicitly with the {@link ui.router.state.$stateProvider#views `views`}
50 | * config property, by name, in this case an empty name:
51 | *
52 | * $stateProvider.state("home", {
53 | * views: {
54 | * "": {
55 | * template: "HELLO!
"
56 | * }
57 | * }
58 | * })
59 | *
60 | *
61 | * But typically you'll only use the views property if you name your view or have more than one view
62 | * in the same template. There's not really a compelling reason to name a view if its the only one,
63 | * but you could if you wanted, like so:
64 | * 65 | * 66 | *67 | *
68 | * $stateProvider.state("home", {
69 | * views: {
70 | * "main": {
71 | * template: "HELLO!
"
72 | * }
73 | * }
74 | * })
75 | *
76 | *
77 | * Really though, you'll use views to set up multiple views:
78 | * 79 | * 80 | * 81 | * 82 | *83 | * 84 | *
85 | * $stateProvider.state("home", {
86 | * views: {
87 | * "": {
88 | * template: "HELLO!
"
89 | * },
90 | * "chart": {
91 | * template: " "
92 | * },
93 | * "data": {
94 | * template: " "
95 | * }
96 | * }
97 | * })
98 | *
99 | *
100 | * Examples for `autoscroll`:
101 | *
102 | * 103 | * 105 | *113 | */ 114 | $ViewDirective.$inject = ['$state', '$injector', '$uiViewScroll', '$interpolate']; 115 | function $ViewDirective( $state, $injector, $uiViewScroll, $interpolate) { 116 | 117 | function getService() { 118 | return ($injector.has) ? function(service) { 119 | return $injector.has(service) ? $injector.get(service) : null; 120 | } : function(service) { 121 | try { 122 | return $injector.get(service); 123 | } catch (e) { 124 | return null; 125 | } 126 | }; 127 | } 128 | 129 | var service = getService(), 130 | $animator = service('$animator'), 131 | $animate = service('$animate'); 132 | 133 | // Returns a set of DOM manipulation functions based on which Angular version 134 | // it should use 135 | function getRenderer(attrs, scope) { 136 | var statics = function() { 137 | return { 138 | enter: function (element, target, cb) { target.after(element); cb(); }, 139 | leave: function (element, cb) { element.remove(); cb(); } 140 | }; 141 | }; 142 | 143 | if ($animate) { 144 | return { 145 | enter: function(element, target, cb) { 146 | var promise = $animate.enter(element, null, target, cb); 147 | if (promise && promise.then) promise.then(cb); 148 | }, 149 | leave: function(element, cb) { 150 | var promise = $animate.leave(element, cb); 151 | if (promise && promise.then) promise.then(cb); 152 | } 153 | }; 154 | } 155 | 156 | if ($animator) { 157 | var animate = $animator && $animator(scope, attrs); 158 | 159 | return { 160 | enter: function(element, target, cb) {animate.enter(element, null, target); cb(); }, 161 | leave: function(element, cb) { animate.leave(element); cb(); } 162 | }; 163 | } 164 | 165 | return statics(); 166 | } 167 | 168 | var directive = { 169 | restrict: 'ECA', 170 | terminal: true, 171 | priority: 400, 172 | transclude: 'element', 173 | compile: function (tElement, tAttrs, $transclude) { 174 | return function (scope, $element, attrs) { 175 | var previousEl, currentEl, currentScope, latestLocals, 176 | onloadExp = attrs.onload || '', 177 | autoScrollExp = attrs.autoscroll, 178 | renderer = getRenderer(attrs, scope); 179 | 180 | scope.$on('$stateChangeSuccess', function() { 181 | updateView(false); 182 | }); 183 | scope.$on('$viewContentLoading', function() { 184 | updateView(false); 185 | }); 186 | 187 | updateView(true); 188 | 189 | function cleanupLastView() { 190 | if (previousEl) { 191 | previousEl.remove(); 192 | previousEl = null; 193 | } 194 | 195 | if (currentScope) { 196 | currentScope.$destroy(); 197 | currentScope = null; 198 | } 199 | 200 | if (currentEl) { 201 | renderer.leave(currentEl, function() { 202 | previousEl = null; 203 | }); 204 | 205 | previousEl = currentEl; 206 | currentEl = null; 207 | } 208 | } 209 | 210 | function updateView(firstTime) { 211 | var newScope, 212 | name = getUiViewName(scope, attrs, $element, $interpolate), 213 | previousLocals = name && $state.$current && $state.$current.locals[name]; 214 | 215 | if (!firstTime && previousLocals === latestLocals) return; // nothing to do 216 | newScope = scope.$new(); 217 | latestLocals = $state.$current.locals[name]; 218 | 219 | var clone = $transclude(newScope, function(clone) { 220 | renderer.enter(clone, $element, function onUiViewEnter() { 221 | if(currentScope) { 222 | currentScope.$emit('$viewContentAnimationEnded'); 223 | } 224 | 225 | if (angular.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) { 226 | $uiViewScroll(clone); 227 | } 228 | }); 229 | cleanupLastView(); 230 | }); 231 | 232 | currentEl = clone; 233 | currentScope = newScope; 234 | /** 235 | * @ngdoc event 236 | * @name ui.router.state.directive:ui-view#$viewContentLoaded 237 | * @eventOf ui.router.state.directive:ui-view 238 | * @eventType emits on ui-view directive scope 239 | * @description * 240 | * Fired once the view is **loaded**, *after* the DOM is rendered. 241 | * 242 | * @param {Object} event Event object. 243 | */ 244 | currentScope.$emit('$viewContentLoaded'); 245 | currentScope.$eval(onloadExp); 246 | } 247 | }; 248 | } 249 | }; 250 | 251 | return directive; 252 | } 253 | 254 | $ViewDirectiveFill.$inject = ['$compile', '$controller', '$state', '$interpolate']; 255 | function $ViewDirectiveFill ( $compile, $controller, $state, $interpolate) { 256 | return { 257 | restrict: 'ECA', 258 | priority: -400, 259 | compile: function (tElement) { 260 | var initial = tElement.html(); 261 | return function (scope, $element, attrs) { 262 | var current = $state.$current, 263 | name = getUiViewName(scope, attrs, $element, $interpolate), 264 | locals = current && current.locals[name]; 265 | 266 | if (! locals) { 267 | return; 268 | } 269 | 270 | $element.data('$uiView', { name: name, state: locals.$$state }); 271 | $element.html(locals.$template ? locals.$template : initial); 272 | 273 | var link = $compile($element.contents()); 274 | 275 | if (locals.$$controller) { 276 | locals.$scope = scope; 277 | var controller = $controller(locals.$$controller, locals); 278 | if (locals.$$controllerAs) { 279 | scope[locals.$$controllerAs] = controller; 280 | } 281 | $element.data('$ngControllerController', controller); 282 | $element.children().data('$ngControllerController', controller); 283 | } 284 | 285 | link(scope); 286 | }; 287 | } 288 | }; 289 | } 290 | 291 | /** 292 | * Shared ui-view code for both directives: 293 | * Given scope, element, and its attributes, return the view's name 294 | */ 295 | function getUiViewName(scope, attrs, element, $interpolate) { 296 | var name = $interpolate(attrs.uiView || attrs.name || '')(scope); 297 | var inherited = element.inheritedData('$uiView'); 298 | return name.indexOf('@') >= 0 ? name : (name + '@' + (inherited ? inherited.state.name : '')); 299 | } 300 | 301 | angular.module('ui.router.state').directive('uiView', $ViewDirective); 302 | angular.module('ui.router.state').directive('uiView', $ViewDirectiveFill); 303 | -------------------------------------------------------------------------------- /bower_components/ui-router/src/stateDirectives.js: -------------------------------------------------------------------------------- 1 | function parseStateRef(ref, current) { 2 | var preparsed = ref.match(/^\s*({[^}]*})\s*$/), parsed; 3 | if (preparsed) ref = current + '(' + preparsed[1] + ')'; 4 | parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/); 5 | if (!parsed || parsed.length !== 4) throw new Error("Invalid state ref '" + ref + "'"); 6 | return { state: parsed[1], paramExpr: parsed[3] || null }; 7 | } 8 | 9 | function stateContext(el) { 10 | var stateData = el.parent().inheritedData('$uiView'); 11 | 12 | if (stateData && stateData.state && stateData.state.name) { 13 | return stateData.state; 14 | } 15 | } 16 | 17 | /** 18 | * @ngdoc directive 19 | * @name ui.router.state.directive:ui-sref 20 | * 21 | * @requires ui.router.state.$state 22 | * @requires $timeout 23 | * 24 | * @restrict A 25 | * 26 | * @description 27 | * A directive that binds a link (`` tag) to a state. If the state has an associated 28 | * URL, the directive will automatically generate & update the `href` attribute via 29 | * the {@link ui.router.state.$state#methods_href $state.href()} method. Clicking 30 | * the link will trigger a state transition with optional parameters. 31 | * 32 | * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be 33 | * handled natively by the browser. 34 | * 35 | * You can also use relative state paths within ui-sref, just like the relative 36 | * paths passed to `$state.go()`. You just need to be aware that the path is relative 37 | * to the state that the link lives in, in other words the state that loaded the 38 | * template containing the link. 39 | * 40 | * You can specify options to pass to {@link ui.router.state.$state#go $state.go()} 41 | * using the `ui-sref-opts` attribute. Options are restricted to `location`, `inherit`, 42 | * and `reload`. 43 | * 44 | * @example 45 | * Here's an example of how you'd use ui-sref and how it would compile. If you have the 46 | * following template: 47 | *106 | * 107 | * 109 | * 110 | * 111 | * 112 | *
48 | * Home | About | Next page 49 | * 50 | *
59 | * Home | About | Next page 60 | * 61 | *72 | * 73 | * Home 74 | * 75 | * 76 | * @param {string} ui-sref 'stateName' can be any valid absolute or relative state 77 | * @param {Object} ui-sref-opts options to pass to {@link ui.router.state.$state#go $state.go()} 78 | */ 79 | $StateRefDirective.$inject = ['$state', '$timeout']; 80 | function $StateRefDirective($state, $timeout) { 81 | var allowedOptions = ['location', 'inherit', 'reload']; 82 | 83 | return { 84 | restrict: 'A', 85 | require: ['?^uiSrefActive', '?^uiSrefActiveEq'], 86 | link: function(scope, element, attrs, uiSrefActive) { 87 | var ref = parseStateRef(attrs.uiSref, $state.current.name); 88 | var params = null, url = null, base = stateContext(element) || $state.$current; 89 | var newHref = null, isAnchor = element.prop("tagName") === "A"; 90 | var isForm = element[0].nodeName === "FORM"; 91 | var attr = isForm ? "action" : "href", nav = true; 92 | 93 | var options = { relative: base, inherit: true }; 94 | var optionsOverride = scope.$eval(attrs.uiSrefOpts) || {}; 95 | 96 | angular.forEach(allowedOptions, function(option) { 97 | if (option in optionsOverride) { 98 | options[option] = optionsOverride[option]; 99 | } 100 | }); 101 | 102 | var update = function(newVal) { 103 | if (newVal) params = angular.copy(newVal); 104 | if (!nav) return; 105 | 106 | newHref = $state.href(ref.state, params, options); 107 | 108 | var activeDirective = uiSrefActive[1] || uiSrefActive[0]; 109 | if (activeDirective) { 110 | activeDirective.$$setStateInfo(ref.state, params); 111 | } 112 | if (newHref === null) { 113 | nav = false; 114 | return false; 115 | } 116 | attrs.$set(attr, newHref); 117 | }; 118 | 119 | if (ref.paramExpr) { 120 | scope.$watch(ref.paramExpr, function(newVal, oldVal) { 121 | if (newVal !== params) update(newVal); 122 | }, true); 123 | params = angular.copy(scope.$eval(ref.paramExpr)); 124 | } 125 | update(); 126 | 127 | if (isForm) return; 128 | 129 | element.bind("click", function(e) { 130 | var button = e.which || e.button; 131 | if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) { 132 | // HACK: This is to allow ng-clicks to be processed before the transition is initiated: 133 | var transition = $timeout(function() { 134 | $state.go(ref.state, params, options); 135 | }); 136 | e.preventDefault(); 137 | 138 | // if the state has no URL, ignore one preventDefault from the directive. 139 | var ignorePreventDefaultCount = isAnchor && !newHref ? 1: 0; 140 | e.preventDefault = function() { 141 | if (ignorePreventDefaultCount-- <= 0) 142 | $timeout.cancel(transition); 143 | }; 144 | } 145 | }); 146 | } 147 | }; 148 | } 149 | 150 | /** 151 | * @ngdoc directive 152 | * @name ui.router.state.directive:ui-sref-active 153 | * 154 | * @requires ui.router.state.$state 155 | * @requires ui.router.state.$stateParams 156 | * @requires $interpolate 157 | * 158 | * @restrict A 159 | * 160 | * @description 161 | * A directive working alongside ui-sref to add classes to an element when the 162 | * related ui-sref directive's state is active, and removing them when it is inactive. 163 | * The primary use-case is to simplify the special appearance of navigation menus 164 | * relying on `ui-sref`, by having the "active" state's menu button appear different, 165 | * distinguishing it from the inactive menu items. 166 | * 167 | * ui-sref-active can live on the same element as ui-sref or on a parent element. The first 168 | * ui-sref-active found at the same level or above the ui-sref will be used. 169 | * 170 | * Will activate when the ui-sref's target state or any child state is active. If you 171 | * need to activate only when the ui-sref target state is active and *not* any of 172 | * it's children, then you will use 173 | * {@link ui.router.state.directive:ui-sref-active-eq ui-sref-active-eq} 174 | * 175 | * @example 176 | * Given the following template: 177 | *
178 | *
189 | *
201 | *
30 | * $resolve.study(invocables)(locals, parent, self) 31 | *32 | * is equivalent to 33 | *
34 | * $resolve.resolve(invocables, locals, parent, self) 35 | *36 | * but the former is more efficient (in fact `resolve` just calls `study` 37 | * internally). 38 | * 39 | * @param {object} invocables Invocable objects 40 | * @return {function} a function to pass in locals, parent and self 41 | */ 42 | this.study = function (invocables) { 43 | if (!isObject(invocables)) throw new Error("'invocables' must be an object"); 44 | var invocableKeys = objectKeys(invocables || {}); 45 | 46 | // Perform a topological sort of invocables to build an ordered plan 47 | var plan = [], cycle = [], visited = {}; 48 | function visit(value, key) { 49 | if (visited[key] === VISIT_DONE) return; 50 | 51 | cycle.push(key); 52 | if (visited[key] === VISIT_IN_PROGRESS) { 53 | cycle.splice(0, indexOf(cycle, key)); 54 | throw new Error("Cyclic dependency: " + cycle.join(" -> ")); 55 | } 56 | visited[key] = VISIT_IN_PROGRESS; 57 | 58 | if (isString(value)) { 59 | plan.push(key, [ function() { return $injector.get(value); }], NO_DEPENDENCIES); 60 | } else { 61 | var params = $injector.annotate(value); 62 | forEach(params, function (param) { 63 | if (param !== key && invocables.hasOwnProperty(param)) visit(invocables[param], param); 64 | }); 65 | plan.push(key, value, params); 66 | } 67 | 68 | cycle.pop(); 69 | visited[key] = VISIT_DONE; 70 | } 71 | forEach(invocables, visit); 72 | invocables = cycle = visited = null; // plan is all that's required 73 | 74 | function isResolve(value) { 75 | return isObject(value) && value.then && value.$$promises; 76 | } 77 | 78 | return function (locals, parent, self) { 79 | if (isResolve(locals) && self === undefined) { 80 | self = parent; parent = locals; locals = null; 81 | } 82 | if (!locals) locals = NO_LOCALS; 83 | else if (!isObject(locals)) { 84 | throw new Error("'locals' must be an object"); 85 | } 86 | if (!parent) parent = NO_PARENT; 87 | else if (!isResolve(parent)) { 88 | throw new Error("'parent' must be a promise returned by $resolve.resolve()"); 89 | } 90 | 91 | // To complete the overall resolution, we have to wait for the parent 92 | // promise and for the promise for each invokable in our plan. 93 | var resolution = $q.defer(), 94 | result = resolution.promise, 95 | promises = result.$$promises = {}, 96 | values = extend({}, locals), 97 | wait = 1 + plan.length/3, 98 | merged = false; 99 | 100 | function done() { 101 | // Merge parent values we haven't got yet and publish our own $$values 102 | if (!--wait) { 103 | if (!merged) merge(values, parent.$$values); 104 | result.$$values = values; 105 | result.$$promises = result.$$promises || true; // keep for isResolve() 106 | delete result.$$inheritedValues; 107 | resolution.resolve(values); 108 | } 109 | } 110 | 111 | function fail(reason) { 112 | result.$$failure = reason; 113 | resolution.reject(reason); 114 | } 115 | 116 | // Short-circuit if parent has already failed 117 | if (isDefined(parent.$$failure)) { 118 | fail(parent.$$failure); 119 | return result; 120 | } 121 | 122 | if (parent.$$inheritedValues) { 123 | merge(values, omit(parent.$$inheritedValues, invocableKeys)); 124 | } 125 | 126 | // Merge parent values if the parent has already resolved, or merge 127 | // parent promises and wait if the parent resolve is still in progress. 128 | extend(promises, parent.$$promises); 129 | if (parent.$$values) { 130 | merged = merge(values, omit(parent.$$values, invocableKeys)); 131 | result.$$inheritedValues = omit(parent.$$values, invocableKeys); 132 | done(); 133 | } else { 134 | if (parent.$$inheritedValues) { 135 | result.$$inheritedValues = omit(parent.$$inheritedValues, invocableKeys); 136 | } 137 | parent.then(done, fail); 138 | } 139 | 140 | // Process each invocable in the plan, but ignore any where a local of the same name exists. 141 | for (var i=0, ii=plan.length; i
81 | * var app = angular.module('app', ['ui.router.router']);
82 | *
83 | * app.config(function ($urlRouterProvider) {
84 | * // if the path doesn't match any of the urls you configured
85 | * // otherwise will take care of routing the user to the
86 | * // specified url
87 | * $urlRouterProvider.otherwise('/index');
88 | *
89 | * // Example of using function rule as param
90 | * $urlRouterProvider.otherwise(function ($injector, $location) {
91 | * return '/a/valid/url';
92 | * });
93 | * });
94 | *
95 | *
96 | * @param {string|object} rule The url path you want to redirect to or a function
97 | * rule that returns the url path. The function version is passed two params:
98 | * `$injector` and `$location` services, and must return a url string.
99 | *
100 | * @return {object} `$urlRouterProvider` - `$urlRouterProvider` instance
101 | */
102 | this.otherwise = function (rule) {
103 | if (isString(rule)) {
104 | var redirect = rule;
105 | rule = function () { return redirect; };
106 | }
107 | else if (!isFunction(rule)) throw new Error("'rule' must be a function");
108 | otherwise = rule;
109 | return this;
110 | };
111 |
112 |
113 | function handleIfMatch($injector, handler, match) {
114 | if (!match) return false;
115 | var result = $injector.invoke(handler, handler, { $match: match });
116 | return isDefined(result) ? result : true;
117 | }
118 |
119 | /**
120 | * @ngdoc function
121 | * @name ui.router.router.$urlRouterProvider#when
122 | * @methodOf ui.router.router.$urlRouterProvider
123 | *
124 | * @description
125 | * Registers a handler for a given url matching. if handle is a string, it is
126 | * treated as a redirect, and is interpolated according to the syntax of match
127 | * (i.e. like `String.replace()` for `RegExp`, or like a `UrlMatcher` pattern otherwise).
128 | *
129 | * If the handler is a function, it is injectable. It gets invoked if `$location`
130 | * matches. You have the option of inject the match object as `$match`.
131 | *
132 | * The handler can return
133 | *
134 | * - **falsy** to indicate that the rule didn't match after all, then `$urlRouter`
135 | * will continue trying to find another one that matches.
136 | * - **string** which is treated as a redirect and passed to `$location.url()`
137 | * - **void** or any **truthy** value tells `$urlRouter` that the url was handled.
138 | *
139 | * @example
140 | *
141 | * var app = angular.module('app', ['ui.router.router']);
142 | *
143 | * app.config(function ($urlRouterProvider) {
144 | * $urlRouterProvider.when($state.url, function ($match, $stateParams) {
145 | * if ($state.$current.navigable !== state ||
146 | * !equalForKeys($match, $stateParams) {
147 | * $state.transitionTo(state, $match, false);
148 | * }
149 | * });
150 | * });
151 | *
152 | *
153 | * @param {string|object} what The incoming path that you want to redirect.
154 | * @param {string|object} handler The path you want to redirect your user to.
155 | */
156 | this.when = function (what, handler) {
157 | var redirect, handlerIsString = isString(handler);
158 | if (isString(what)) what = $urlMatcherFactory.compile(what);
159 |
160 | if (!handlerIsString && !isFunction(handler) && !isArray(handler))
161 | throw new Error("invalid 'handler' in when()");
162 |
163 | var strategies = {
164 | matcher: function (what, handler) {
165 | if (handlerIsString) {
166 | redirect = $urlMatcherFactory.compile(handler);
167 | handler = ['$match', function ($match) { return redirect.format($match); }];
168 | }
169 | return extend(function ($injector, $location) {
170 | return handleIfMatch($injector, handler, what.exec($location.path(), $location.search()));
171 | }, {
172 | prefix: isString(what.prefix) ? what.prefix : ''
173 | });
174 | },
175 | regex: function (what, handler) {
176 | if (what.global || what.sticky) throw new Error("when() RegExp must not be global or sticky");
177 |
178 | if (handlerIsString) {
179 | redirect = handler;
180 | handler = ['$match', function ($match) { return interpolate(redirect, $match); }];
181 | }
182 | return extend(function ($injector, $location) {
183 | return handleIfMatch($injector, handler, what.exec($location.path()));
184 | }, {
185 | prefix: regExpPrefix(what)
186 | });
187 | }
188 | };
189 |
190 | var check = { matcher: $urlMatcherFactory.isMatcher(what), regex: what instanceof RegExp };
191 |
192 | for (var n in check) {
193 | if (check[n]) return this.rule(strategies[n](what, handler));
194 | }
195 |
196 | throw new Error("invalid 'what' in when()");
197 | };
198 |
199 | /**
200 | * @ngdoc function
201 | * @name ui.router.router.$urlRouterProvider#deferIntercept
202 | * @methodOf ui.router.router.$urlRouterProvider
203 | *
204 | * @description
205 | * Disables (or enables) deferring location change interception.
206 | *
207 | * If you wish to customize the behavior of syncing the URL (for example, if you wish to
208 | * defer a transition but maintain the current URL), call this method at configuration time.
209 | * Then, at run time, call `$urlRouter.listen()` after you have configured your own
210 | * `$locationChangeSuccess` event handler.
211 | *
212 | * @example
213 | *
214 | * var app = angular.module('app', ['ui.router.router']);
215 | *
216 | * app.config(function ($urlRouterProvider) {
217 | *
218 | * // Prevent $urlRouter from automatically intercepting URL changes;
219 | * // this allows you to configure custom behavior in between
220 | * // location changes and route synchronization:
221 | * $urlRouterProvider.deferIntercept();
222 | *
223 | * }).run(function ($rootScope, $urlRouter, UserService) {
224 | *
225 | * $rootScope.$on('$locationChangeSuccess', function(e) {
226 | * // UserService is an example service for managing user state
227 | * if (UserService.isLoggedIn()) return;
228 | *
229 | * // Prevent $urlRouter's default handler from firing
230 | * e.preventDefault();
231 | *
232 | * UserService.handleLogin().then(function() {
233 | * // Once the user has logged in, sync the current URL
234 | * // to the router:
235 | * $urlRouter.sync();
236 | * });
237 | * });
238 | *
239 | * // Configures $urlRouter's listener *after* your custom listener
240 | * $urlRouter.listen();
241 | * });
242 | *
243 | *
244 | * @param {boolean} defer Indicates whether to defer location change interception. Passing
245 | no parameter is equivalent to `true`.
246 | */
247 | this.deferIntercept = function (defer) {
248 | if (defer === undefined) defer = true;
249 | interceptDeferred = defer;
250 | };
251 |
252 | /**
253 | * @ngdoc object
254 | * @name ui.router.router.$urlRouter
255 | *
256 | * @requires $location
257 | * @requires $rootScope
258 | * @requires $injector
259 | * @requires $browser
260 | *
261 | * @description
262 | *
263 | */
264 | this.$get = $get;
265 | $get.$inject = ['$location', '$rootScope', '$injector', '$browser'];
266 | function $get( $location, $rootScope, $injector, $browser) {
267 |
268 | var baseHref = $browser.baseHref(), location = $location.url(), lastPushedUrl;
269 |
270 | function appendBasePath(url, isHtml5, absolute) {
271 | if (baseHref === '/') return url;
272 | if (isHtml5) return baseHref.slice(0, -1) + url;
273 | if (absolute) return baseHref.slice(1) + url;
274 | return url;
275 | }
276 |
277 | // TODO: Optimize groups of rules with non-empty prefix into some sort of decision tree
278 | function update(evt) {
279 | if (evt && evt.defaultPrevented) return;
280 | var ignoreUpdate = lastPushedUrl && $location.url() === lastPushedUrl;
281 | lastPushedUrl = undefined;
282 | if (ignoreUpdate) return true;
283 |
284 | function check(rule) {
285 | var handled = rule($injector, $location);
286 |
287 | if (!handled) return false;
288 | if (isString(handled)) $location.replace().url(handled);
289 | return true;
290 | }
291 | var n = rules.length, i;
292 |
293 | for (i = 0; i < n; i++) {
294 | if (check(rules[i])) return;
295 | }
296 | // always check otherwise last to allow dynamic updates to the set of rules
297 | if (otherwise) check(otherwise);
298 | }
299 |
300 | function listen() {
301 | listener = listener || $rootScope.$on('$locationChangeSuccess', update);
302 | return listener;
303 | }
304 |
305 | if (!interceptDeferred) listen();
306 |
307 | return {
308 | /**
309 | * @ngdoc function
310 | * @name ui.router.router.$urlRouter#sync
311 | * @methodOf ui.router.router.$urlRouter
312 | *
313 | * @description
314 | * Triggers an update; the same update that happens when the address bar url changes, aka `$locationChangeSuccess`.
315 | * This method is useful when you need to use `preventDefault()` on the `$locationChangeSuccess` event,
316 | * perform some custom logic (route protection, auth, config, redirection, etc) and then finally proceed
317 | * with the transition by calling `$urlRouter.sync()`.
318 | *
319 | * @example
320 | *
321 | * angular.module('app', ['ui.router'])
322 | * .run(function($rootScope, $urlRouter) {
323 | * $rootScope.$on('$locationChangeSuccess', function(evt) {
324 | * // Halt state change from even starting
325 | * evt.preventDefault();
326 | * // Perform custom logic
327 | * var meetsRequirement = ...
328 | * // Continue with the update and state transition if logic allows
329 | * if (meetsRequirement) $urlRouter.sync();
330 | * });
331 | * });
332 | *
333 | */
334 | sync: function() {
335 | update();
336 | },
337 |
338 | listen: function() {
339 | return listen();
340 | },
341 |
342 | update: function(read) {
343 | if (read) {
344 | location = $location.url();
345 | return;
346 | }
347 | if ($location.url() === location) return;
348 |
349 | $location.url(location);
350 | $location.replace();
351 | },
352 |
353 | push: function(urlMatcher, params, options) {
354 | $location.url(urlMatcher.format(params || {}));
355 | lastPushedUrl = options && options.$$avoidResync ? $location.url() : undefined;
356 | if (options && options.replace) $location.replace();
357 | },
358 |
359 | /**
360 | * @ngdoc function
361 | * @name ui.router.router.$urlRouter#href
362 | * @methodOf ui.router.router.$urlRouter
363 | *
364 | * @description
365 | * A URL generation method that returns the compiled URL for a given
366 | * {@link ui.router.util.type:UrlMatcher `UrlMatcher`}, populated with the provided parameters.
367 | *
368 | * @example
369 | *
370 | * $bob = $urlRouter.href(new UrlMatcher("/about/:person"), {
371 | * person: "bob"
372 | * });
373 | * // $bob == "/about/bob";
374 | *
375 | *
376 | * @param {UrlMatcher} urlMatcher The `UrlMatcher` object which is used as the template of the URL to generate.
377 | * @param {object=} params An object of parameter values to fill the matcher's required parameters.
378 | * @param {object=} options Options object. The options are:
379 | *
380 | * - **`absolute`** - {boolean=false}, If true will generate an absolute url, e.g. "http://www.example.com/fullurl".
381 | *
382 | * @returns {string} Returns the fully compiled URL, or `null` if `params` fail validation against `urlMatcher`
383 | */
384 | href: function(urlMatcher, params, options) {
385 | if (!urlMatcher.validates(params)) return null;
386 |
387 | var isHtml5 = $locationProvider.html5Mode();
388 | if (angular.isObject(isHtml5)) {
389 | isHtml5 = isHtml5.enabled;
390 | }
391 |
392 | var url = urlMatcher.format(params);
393 | options = options || {};
394 |
395 | if (!isHtml5 && url !== null) {
396 | url = "#" + $locationProvider.hashPrefix() + url;
397 | }
398 | url = appendBasePath(url, isHtml5, options.absolute);
399 |
400 | if (!options.absolute || !url) {
401 | return url;
402 | }
403 |
404 | var slash = (!isHtml5 && url ? '/' : ''), port = $location.port();
405 | port = (port === 80 || port === 443 ? '' : ':' + port);
406 |
407 | return [$location.protocol(), '://', $location.host(), port, slash, url].join('');
408 | }
409 | };
410 | }
411 | }
412 |
413 | angular.module('ui.router.router').provider('$urlRouter', $UrlRouterProvider);
414 |
--------------------------------------------------------------------------------
/bower_components/ui-router/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | ### 0.2.13 (2014-11-20)
3 |
4 | This release primarily fixes issues reported against 0.2.12
5 |
6 | #### Bug Fixes
7 |
8 | * **$state:** fix $state.includes/.is to apply param types before comparisions fix(uiSref): ma ([19715d15](https://github.com/angular-ui/ui-router/commit/19715d15e3cbfff724519e9febedd05b49c75baa), closes [#1513](https://github.com/angular-ui/ui-router/issues/1513))
9 | * Avoid re-synchronizing from url after .transitionTo ([b267ecd3](https://github.com/angular-ui/ui-router/commit/b267ecd348e5c415233573ef95ebdbd051875f52), closes [#1573](https://github.com/angular-ui/ui-router/issues/1573))
10 | * **$urlMatcherFactory:**
11 | * Built-in date type uses local time zone ([d726bedc](https://github.com/angular-ui/ui-router/commit/d726bedcbb5f70a5660addf43fd52ec730790293))
12 | * make date type fn check .is before running ([aa94ce3b](https://github.com/angular-ui/ui-router/commit/aa94ce3b86632ad05301530a2213099da73a3dc0), closes [#1564](https://github.com/angular-ui/ui-router/issues/1564))
13 | * early binding of array handler bypasses type resolution ([ada4bc27](https://github.com/angular-ui/ui-router/commit/ada4bc27df5eff3ba3ab0de94a09bd91b0f7a28c))
14 | * add 'any' Type for non-encoding non-url params ([3bfd75ab](https://github.com/angular-ui/ui-router/commit/3bfd75ab445ee2f1dd55275465059ed116b10b27), closes [#1562](https://github.com/angular-ui/ui-router/issues/1562))
15 | * fix encoding slashes in params ([0c983a08](https://github.com/angular-ui/ui-router/commit/0c983a08e2947f999683571477debd73038e95cf), closes [#1119](https://github.com/angular-ui/ui-router/issues/1119))
16 | * fix mixed path/query params ordering problem ([a479fbd0](https://github.com/angular-ui/ui-router/commit/a479fbd0b8eb393a94320973e5b9a62d83912ee2), closes [#1543](https://github.com/angular-ui/ui-router/issues/1543))
17 | * **ArrayType:**
18 | * specify empty array mapping corner case ([74aa6091](https://github.com/angular-ui/ui-router/commit/74aa60917e996b0b4e27bbb4eb88c3c03832021d), closes [#1511](https://github.com/angular-ui/ui-router/issues/1511))
19 | * fix .equals for array types ([5e6783b7](https://github.com/angular-ui/ui-router/commit/5e6783b77af9a90ddff154f990b43dbb17eeda6e), closes [#1538](https://github.com/angular-ui/ui-router/issues/1538))
20 | * **Param:** fix default value shorthand declaration ([831d812a](https://github.com/angular-ui/ui-router/commit/831d812a524524c71f0ee1c9afaf0487a5a66230), closes [#1554](https://github.com/angular-ui/ui-router/issues/1554))
21 | * **common:** fixed the _.filter clone to not create sparse arrays ([750f5cf5](https://github.com/angular-ui/ui-router/commit/750f5cf5fd91f9ada96f39e50d39aceb2caf22b6), closes [#1563](https://github.com/angular-ui/ui-router/issues/1563))
22 | * **ie8:** fix calls to indexOf and filter ([dcb31b84](https://github.com/angular-ui/ui-router/commit/dcb31b843391b3e61dee4de13f368c109541813e), closes [#1556](https://github.com/angular-ui/ui-router/issues/1556))
23 |
24 |
25 | #### Features
26 |
27 | * add json parameter Type ([027f1fcf](https://github.com/angular-ui/ui-router/commit/027f1fcf9c0916cea651e88981345da6f9ff214a))
28 |
29 |
30 |
31 | ### 0.2.12 (2014-11-13)
32 |
33 | #### Bug Fixes
34 |
35 | * **$resolve:** use resolve fn result, not parent resolved value of same name ([67f5e00c](https://github.com/angular-ui/ui-router/commit/67f5e00cc9aa006ce3fe6cde9dff261c28eab70a), closes [#1317], [#1353])
36 | * **$state:**
37 | * populate default params in .transitionTo. ([3f60fbe6](https://github.com/angular-ui/ui-router/commit/3f60fbe6d65ebeca8d97952c05aa1d269f1b7ba1), closes [#1396])
38 | * reload() now reinvokes controllers ([73443420](https://github.com/angular-ui/ui-router/commit/7344342018847902594dc1fc62d30a5c30f01763), closes [#582])
39 | * do not emit $viewContentLoading if notify: false ([74255feb](https://github.com/angular-ui/ui-router/commit/74255febdf48ae082a02ca1e735165f2c369a463), closes [#1387](https://github.com/angular-ui/ui-router/issues/1387))
40 | * register states at config-time ([4533fe36](https://github.com/angular-ui/ui-router/commit/4533fe36e0ab2f0143edd854a4145deaa013915a))
41 | * handle parent.name when parent is obj ([4533fe36](https://github.com/angular-ui/ui-router/commit/4533fe36e0ab2f0143edd854a4145deaa013915a))
42 | * **$urlMatcherFactory:**
43 | * register types at config ([4533fe36](https://github.com/angular-ui/ui-router/commit/4533fe36e0ab2f0143edd854a4145deaa013915a), closes [#1476])
44 | * made path params default value "" for backwards compat ([8f998e71](https://github.com/angular-ui/ui-router/commit/8f998e71e43a0b31293331c981f5db0f0097b8ba))
45 | * Pre-replace certain param values for better mapping ([6374a3e2](https://github.com/angular-ui/ui-router/commit/6374a3e29ab932014a7c77d2e1ab884cc841a2e3))
46 | * fixed ParamSet.$$keys() ordering ([9136fecb](https://github.com/angular-ui/ui-router/commit/9136fecbc2bfd4fda748a9914f0225a46c933860))
47 | * empty string policy now respected in Param.value() ([db12c85c](https://github.com/angular-ui/ui-router/commit/db12c85c16f2d105415f9bbbdeb11863f64728e0))
48 | * "string" type now encodes/decodes slashes ([3045e415](https://github.com/angular-ui/ui-router/commit/3045e41577a8b8b8afc6039f42adddf5f3c061ec), closes [#1119])
49 | * allow arrays in both path and query params ([fdd2f2c1](https://github.com/angular-ui/ui-router/commit/fdd2f2c191c4a67c874fdb9ec9a34f8dde9ad180), closes [#1073], [#1045], [#1486], [#1394])
50 | * typed params in search ([8d4cab69](https://github.com/angular-ui/ui-router/commit/8d4cab69dd67058e1a716892cc37b7d80a57037f), closes [#1488](https://github.com/angular-ui/ui-router/issues/1488))
51 | * no longer generate unroutable urls ([cb9fd9d8](https://github.com/angular-ui/ui-router/commit/cb9fd9d8943cb26c7223f6990db29c82ae8740f8), closes [#1487](https://github.com/angular-ui/ui-router/issues/1487))
52 | * handle optional parameter followed by required parameter in url format. ([efc72106](https://github.com/angular-ui/ui-router/commit/efc72106ddcc4774b48ea176a505ef9e95193b41))
53 | * default to parameter string coersion. ([13a468a7](https://github.com/angular-ui/ui-router/commit/13a468a7d54c2fb0751b94c0c1841d580b71e6dc), closes [#1414](https://github.com/angular-ui/ui-router/issues/1414))
54 | * concat respects strictMode/caseInsensitive ([dd72e103](https://github.com/angular-ui/ui-router/commit/dd72e103edb342d9cf802816fe127e1bbd68fd5f), closes [#1395])
55 | * **ui-sref:**
56 | * Allow sref state options to take a scope object ([b5f7b596](https://github.com/angular-ui/ui-router/commit/b5f7b59692ce4933e2d63eb5df3f50a4ba68ccc0))
57 | * replace raw href modification with attrs. ([08c96782](https://github.com/angular-ui/ui-router/commit/08c96782faf881b0c7ab00afc233ee6729548fa0))
58 | * nagivate to state when url is "" fix($state.href): generate href for state with ([656b5aab](https://github.com/angular-ui/ui-router/commit/656b5aab906e5749db9b5a080c6a83b95f50fd91), closes [#1363](https://github.com/angular-ui/ui-router/issues/1363))
59 | * Check that state is defined in isMatch() ([92aebc75](https://github.com/angular-ui/ui-router/commit/92aebc7520f88babdc6e266536086e07263514c3), closes [#1314](https://github.com/angular-ui/ui-router/issues/1314), [#1332](https://github.com/angular-ui/ui-router/issues/1332))
60 | * **uiView:**
61 | * allow inteprolated ui-view names ([81f6a19a](https://github.com/angular-ui/ui-router/commit/81f6a19a432dac9198fd33243855bfd3b4fea8c0), closes [#1324](https://github.com/angular-ui/ui-router/issues/1324))
62 | * Made anim work with angular 1.3 ([c3bb7ad9](https://github.com/angular-ui/ui-router/commit/c3bb7ad903da1e1f3c91019cfd255be8489ff4ef), closes [#1367](https://github.com/angular-ui/ui-router/issues/1367), [#1345](https://github.com/angular-ui/ui-router/issues/1345))
63 | * **urlRouter:** html5Mode accepts an object from angular v1.3.0-rc.3 ([7fea1e9d](https://github.com/angular-ui/ui-router/commit/7fea1e9d0d8c6e09cc6c895ecb93d4221e9adf48))
64 | * **stateFilters:** mark state filters as stateful. ([a00b353e](https://github.com/angular-ui/ui-router/commit/a00b353e3036f64a81245c4e7898646ba218f833), closes [#1479])
65 | * **ui-router:** re-add IE8 compatibility for map/filter/keys ([8ce69d9f](https://github.com/angular-ui/ui-router/commit/8ce69d9f7c886888ab53eca7e53536f36b428aae), closes [#1518], [#1383])
66 | * **package:** point 'main' to a valid filename ([ac903350](https://github.com/angular-ui/ui-router/commit/ac9033501debb63364539d91fbf3a0cba4579f8e))
67 | * **travis:** make CI build faster ([0531de05](https://github.com/angular-ui/ui-router/commit/0531de052e414a8d839fbb4e7635e923e94865b3))
68 |
69 |
70 | #### Features
71 |
72 | ##### Default and Typed params
73 |
74 | This release includes a lot of bug fixes around default/optional and typed parameters. As such, 0.2.12 is the first release where we recommend those features be used.
75 |
76 | * **$state:**
77 | * add state params validation ([b1379e6a](https://github.com/angular-ui/ui-router/commit/b1379e6a4d38f7ed7436e05873932d7c279af578), closes [#1433](https://github.com/angular-ui/ui-router/issues/1433))
78 | * is/includes/get work on relative stateOrName ([232e94b3](https://github.com/angular-ui/ui-router/commit/232e94b3c2ca2c764bb9510046e4b61690c87852))
79 | * .reload() returns state transition promise ([639e0565](https://github.com/angular-ui/ui-router/commit/639e0565dece9d5544cc93b3eee6e11c99bd7373))
80 | * **$templateFactory:** request templateURL as text/html ([ccd60769](https://github.com/angular-ui/ui-router/commit/ccd6076904a4b801d77b47f6e2de4c06ce9962f8), closes [#1287])
81 | * **$urlMatcherFactory:** Made a Params and ParamSet class ([0cc1e6cc](https://github.com/angular-ui/ui-router/commit/0cc1e6cc461a4640618e2bb594566551c54834e2))
82 |
83 |
84 |
85 |
86 | ### 0.2.11 (2014-08-26)
87 |
88 |
89 | #### Bug Fixes
90 |
91 | * **$resolve:** Resolves only inherit from immediate parent fixes #702 ([df34e20c](https://github.com/angular-ui/ui-router/commit/df34e20c576299e7a3c8bd4ebc68d42341c0ace9))
92 | * **$state:**
93 | * change $state.href default options.inherit to true ([deea695f](https://github.com/angular-ui/ui-router/commit/deea695f5cacc55de351ab985144fd233c02a769))
94 | * sanity-check state lookups ([456fd5ae](https://github.com/angular-ui/ui-router/commit/456fd5aec9ea507518927bfabd62b4afad4cf714), closes [#980](https://github.com/angular-ui/ui-router/issues/980))
95 | * didn't comply to inherit parameter ([09836781](https://github.com/angular-ui/ui-router/commit/09836781f126c1c485b06551eb9cfd4fa0f45c35))
96 | * allow view content loading broadcast ([7b78edee](https://github.com/angular-ui/ui-router/commit/7b78edeeb52a74abf4d3f00f79534033d5a08d1a))
97 | * **$urlMatcherFactory:**
98 | * detect injected functions ([91f75ae6](https://github.com/angular-ui/ui-router/commit/91f75ae66c4d129f6f69e53bd547594e9661f5d5))
99 | * syntax ([1ebed370](https://github.com/angular-ui/ui-router/commit/1ebed37069bae8614d41541d56521f5c45f703f3))
100 | * **UrlMatcher:**
101 | * query param function defaults ([f9c20530](https://github.com/angular-ui/ui-router/commit/f9c205304f10d8a4ebe7efe9025e642016479a51))
102 | * don't decode default values ([63607bdb](https://github.com/angular-ui/ui-router/commit/63607bdbbcb432d3fb37856a1cb3da0cd496804e))
103 | * **travis:** update Node version to fix build ([d6b95ef2](https://github.com/angular-ui/ui-router/commit/d6b95ef23d9dacb4eba08897f5190a0bcddb3a48))
104 | * **uiSref:**
105 | * Generate an href for states with a blank url. closes #1293 ([691745b1](https://github.com/angular-ui/ui-router/commit/691745b12fa05d3700dd28f0c8d25f8a105074ad))
106 | * should inherit params by default ([b973dad1](https://github.com/angular-ui/ui-router/commit/b973dad155ad09a7975e1476bd096f7b2c758eeb))
107 | * cancel transition if preventDefault() has been called ([2e6d9167](https://github.com/angular-ui/ui-router/commit/2e6d9167d3afbfbca6427e53e012f94fb5fb8022))
108 | * **uiView:** Fixed infinite loop when is called .go() from a controller. ([e13988b8](https://github.com/angular-ui/ui-router/commit/e13988b8cd6231d75c78876ee9d012cc87f4a8d9), closes [#1194](https://github.com/angular-ui/ui-router/issues/1194))
109 | * **docs:**
110 | * Fixed link to milestones ([6c0ae500](https://github.com/angular-ui/ui-router/commit/6c0ae500cc238ea9fc95adcc15415c55fc9e1f33))
111 | * fix bug in decorator example ([4bd00af5](https://github.com/angular-ui/ui-router/commit/4bd00af50b8b88a49d1545a76290731cb8e0feb1))
112 | * Removed an incorrect semi-colon ([af97cef8](https://github.com/angular-ui/ui-router/commit/af97cef8b967f2e32177e539ef41450dca131a7d))
113 | * Explain return value of rule as function ([5e887890](https://github.com/angular-ui/ui-router/commit/5e8878900a6ffe59a81aed531a3925e34a297377))
114 |
115 |
116 | #### Features
117 |
118 | * **$state:**
119 | * allow parameters to pass unharmed ([8939d057](https://github.com/angular-ui/ui-router/commit/8939d0572ab1316e458ef016317ecff53131a822))
120 | * **BREAKING CHANGE**: state parameters are no longer automatically coerced to strings, and unspecified parameter values are now set to undefined rather than null.
121 | * allow prevent syncUrl on failure ([753060b9](https://github.com/angular-ui/ui-router/commit/753060b910d5d2da600a6fa0757976e401c33172))
122 | * **typescript:** Add typescript definitions for component builds ([521ceb3f](https://github.com/angular-ui/ui-router/commit/521ceb3fd7850646422f411921e21ce5e7d82e0f))
123 | * **uiSref:** extend syntax for ui-sref ([71cad3d6](https://github.com/angular-ui/ui-router/commit/71cad3d636508b5a9fe004775ad1f1adc0c80c3e))
124 | * **uiSrefActive:**
125 | * Also activate for child states. ([bf163ad6](https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01), closes [#818](https://github.com/angular-ui/ui-router/issues/818))
126 | * **BREAKING CHANGE** Since ui-sref-active now activates even when child states are active you may need to swap out your ui-sref-active with ui-sref-active-eq, thought typically we think devs want the auto inheritance.
127 |
128 | * uiSrefActiveEq: new directive with old ui-sref-active behavior
129 | * **$urlRouter:**
130 | * defer URL change interception ([c72d8ce1](https://github.com/angular-ui/ui-router/commit/c72d8ce11916d0ac22c81b409c9e61d7048554d7))
131 | * force URLs to have valid params ([d48505cd](https://github.com/angular-ui/ui-router/commit/d48505cd328d83e39d5706e085ba319715f999a6))
132 | * abstract $location handling ([08b4636b](https://github.com/angular-ui/ui-router/commit/08b4636b294611f08db35f00641eb5211686fb50))
133 | * **$urlMatcherFactory:**
134 | * fail on bad parameters ([d8f124c1](https://github.com/angular-ui/ui-router/commit/d8f124c10d00c7e5dde88c602d966db261aea221))
135 | * date type support ([b7f074ff](https://github.com/angular-ui/ui-router/commit/b7f074ff65ca150a3cdbda4d5ad6cb17107300eb))
136 | * implement type support ([450b1f0e](https://github.com/angular-ui/ui-router/commit/450b1f0e8e03c738174ff967f688b9a6373290f4))
137 | * **UrlMatcher:**
138 | * handle query string arrays ([9cf764ef](https://github.com/angular-ui/ui-router/commit/9cf764efab45fa9309368688d535ddf6e96d6449), closes [#373](https://github.com/angular-ui/ui-router/issues/373))
139 | * injectable functions as defaults ([00966ecd](https://github.com/angular-ui/ui-router/commit/00966ecd91fb745846039160cab707bfca8b3bec))
140 | * default values & type decoding for query params ([a472b301](https://github.com/angular-ui/ui-router/commit/a472b301389fbe84d1c1fa9f24852b492a569d11))
141 | * allow shorthand definitions ([5b724304](https://github.com/angular-ui/ui-router/commit/5b7243049793505e44b6608ea09878c37c95b1f5))
142 | * validates whole interface ([32b27db1](https://github.com/angular-ui/ui-router/commit/32b27db173722e9194ef1d5c0ea7d93f25a98d11))
143 | * implement non-strict matching ([a3e21366](https://github.com/angular-ui/ui-router/commit/a3e21366bee0475c9795a1ec76f70eec41c5b4e3))
144 | * add per-param config support ([07b3029f](https://github.com/angular-ui/ui-router/commit/07b3029f4d409cf955780113df92e36401b47580))
145 | * **BREAKING CHANGE**: the `params` option in state configurations must now be an object keyed by parameter name.
146 |
147 | ### 0.2.10 (2014-03-12)
148 |
149 |
150 | #### Bug Fixes
151 |
152 | * **$state:** use $browser.baseHref() when generating urls with .href() ([cbcc8488](https://github.com/angular-ui/ui-router/commit/cbcc84887d6b6d35258adabb97c714cd9c1e272d))
153 | * **bower.json:** JS files should not be ignored ([ccdab193](https://github.com/angular-ui/ui-router/commit/ccdab193315f304eb3be5f5b97c47a926c79263e))
154 | * **dev:** karma:background task is missing, can't run grunt:dev. ([d9f7b898](https://github.com/angular-ui/ui-router/commit/d9f7b898e8e3abb8c846b0faa16a382913d7b22b))
155 | * **sample:** Contacts menu button not staying active when navigating to detail states. Need t ([2fcb8443](https://github.com/angular-ui/ui-router/commit/2fcb84437cb43ade12682a92b764f13cac77dfe7))
156 | * **uiSref:** support mock-clicks/events with no data ([717d3ff7](https://github.com/angular-ui/ui-router/commit/717d3ff7d0ba72d239892dee562b401cdf90e418))
157 | * **uiView:**
158 | * Do NOT autoscroll when autoscroll attr is missing ([affe5bd7](https://github.com/angular-ui/ui-router/commit/affe5bd785cdc3f02b7a9f64a52e3900386ec3a0), closes [#807](https://github.com/angular-ui/ui-router/issues/807))
159 | * Refactoring uiView directive to copy ngView logic ([548fab6a](https://github.com/angular-ui/ui-router/commit/548fab6ab9debc9904c5865c8bc68b4fc3271dd0), closes [#857](https://github.com/angular-ui/ui-router/issues/857), [#552](https://github.com/angular-ui/ui-router/issues/552))
160 |
161 |
162 | #### Features
163 |
164 | * **$state:** includes() allows glob patterns for state matching. ([2d5f6b37](https://github.com/angular-ui/ui-router/commit/2d5f6b37191a3135f4a6d9e8f344c54edcdc065b))
165 | * **UrlMatcher:** Add support for case insensitive url matching ([642d5247](https://github.com/angular-ui/ui-router/commit/642d524799f604811e680331002feec7199a1fb5))
166 | * **uiSref:** add support for transition options ([2ed7a728](https://github.com/angular-ui/ui-router/commit/2ed7a728cee6854b38501fbc1df6139d3de5b28a))
167 | * **uiView:** add controllerAs config with function ([1ee7334a](https://github.com/angular-ui/ui-router/commit/1ee7334a73efeccc9b95340e315cdfd59944762d))
168 |
169 |
170 | ### 0.2.9 (2014-01-17)
171 |
172 |
173 | This release is identical to 0.2.8. 0.2.8 was re-tagged in git to fix a problem with bower.
174 |
175 |
176 | ### 0.2.8 (2014-01-16)
177 |
178 |
179 | #### Bug Fixes
180 |
181 | * **$state:** allow null to be passed as 'params' param ([094dc30e](https://github.com/angular-ui/ui-router/commit/094dc30e883e1bd14e50a475553bafeaade3b178))
182 | * **$state.go:** param inheritance shouldn't inherit from siblings ([aea872e0](https://github.com/angular-ui/ui-router/commit/aea872e0b983cb433436ce5875df10c838fccedb))
183 | * **bower.json:** fixes bower.json ([eed3cc4d](https://github.com/angular-ui/ui-router/commit/eed3cc4d4dfef1d3ef84b9fd063127538ebf59d3))
184 | * **uiSrefActive:** annotate controller injection ([85921422](https://github.com/angular-ui/ui-router/commit/85921422ff7fb0effed358136426d616cce3d583), closes [#671](https://github.com/angular-ui/ui-router/issues/671))
185 | * **uiView:**
186 | * autoscroll tests pass on 1.2.4 & 1.1.5 ([86eacac0](https://github.com/angular-ui/ui-router/commit/86eacac09ca5e9000bd3b9c7ba6e2cc95d883a3a))
187 | * don't animate initial load ([83b6634d](https://github.com/angular-ui/ui-router/commit/83b6634d27942ca74766b2b1244a7fc52c5643d9))
188 | * test pass against 1.0.8 and 1.2.4 ([a402415a](https://github.com/angular-ui/ui-router/commit/a402415a2a28b360c43b9fe8f4f54c540f6c33de))
189 | * it should autoscroll when expr is missing. ([8bb9e27a](https://github.com/angular-ui/ui-router/commit/8bb9e27a2986725f45daf44c4c9f846385095aff))
190 |
191 |
192 | #### Features
193 |
194 | * **uiSref:** add target attribute behaviour ([c12bf9a5](https://github.com/angular-ui/ui-router/commit/c12bf9a520d30d70294e3d82de7661900f8e394e))
195 | * **uiView:**
196 | * merge autoscroll expression test. ([b89e0f87](https://github.com/angular-ui/ui-router/commit/b89e0f871d5cc35c10925ede986c10684d5c9252))
197 | * cache and test autoscroll expression ([ee262282](https://github.com/angular-ui/ui-router/commit/ee2622828c2ce83807f006a459ac4e11406d9258))
198 |
--------------------------------------------------------------------------------
/bower_components/ui-router/release/angular-ui-router.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * State-based routing for AngularJS
3 | * @version v0.2.13
4 | * @link http://angular-ui.github.com/
5 | * @license MIT License, http://www.opensource.org/licenses/MIT
6 | */
7 | "undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(a,b,c){"use strict";function d(a,b){return M(new(M(function(){},{prototype:a})),b)}function e(a){return L(arguments,function(b){b!==a&&L(b,function(b,c){a.hasOwnProperty(c)||(a[c]=b)})}),a}function f(a,b){var c=[];for(var d in a.path){if(a.path[d]!==b.path[d])break;c.push(a.path[d])}return c}function g(a){if(Object.keys)return Object.keys(a);var c=[];return b.forEach(a,function(a,b){c.push(b)}),c}function h(a,b){if(Array.prototype.indexOf)return a.indexOf(b,Number(arguments[2])||0);var c=a.length>>>0,d=Number(arguments[2])||0;for(d=0>d?Math.ceil(d):Math.floor(d),0>d&&(d+=c);c>d;d++)if(d in a&&a[d]===b)return d;return-1}function i(a,b,c,d){var e,i=f(c,d),j={},k=[];for(var l in i)if(i[l].params&&(e=g(i[l].params),e.length))for(var m in e)h(k,e[m])>=0||(k.push(e[m]),j[e[m]]=a[e[m]]);return M({},j,b)}function j(a,b,c){if(!c){c=[];for(var d in a)c.push(d)}for(var e=0;e