52 | ```
53 |
54 |
55 |
--------------------------------------------------------------------------------
/modules/filters/format/format.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * A replacement utility for internationalization very similar to sprintf.
4 | *
5 | * @param replace {mixed} The tokens to replace depends on type
6 | * string: all instances of $0 will be replaced
7 | * array: each instance of $0, $1, $2 etc. will be placed with each array item in corresponding order
8 | * object: all attributes will be iterated through, with :key being replaced with its corresponding value
9 | * @return string
10 | *
11 | * @example: 'Hello :name, how are you :day'.format({ name:'John', day:'Today' })
12 | * @example: 'Records $0 to $1 out of $2 total'.format(['10', '20', '3000'])
13 | * @example: '$0 agrees to all mentions $0 makes in the event that $0 hits a tree while $0 is driving drunk'.format('Bob')
14 | */
15 | angular.module('ui.filters').filter('format', function(){
16 | return function(value, replace) {
17 | if (!value) {
18 | return value;
19 | }
20 | var target = value.toString(), token;
21 | if (replace === undefined) {
22 | return target;
23 | }
24 | if (!angular.isArray(replace) && !angular.isObject(replace)) {
25 | return target.split('$0').join(replace);
26 | }
27 | token = angular.isArray(replace) && '$' || ':';
28 |
29 | angular.forEach(replace, function(value, key){
30 | target = target.split(token+key).join(value);
31 | });
32 | return target;
33 | };
34 | });
35 |
--------------------------------------------------------------------------------
/modules/directives/currency/currency.js:
--------------------------------------------------------------------------------
1 | /*
2 | Gives the ability to style currency based on its sign.
3 | */
4 | angular.module('ui.directives').directive('uiCurrency', ['ui.config', 'currencyFilter' , function (uiConfig, currencyFilter) {
5 | var options = {
6 | pos: 'ui-currency-pos',
7 | neg: 'ui-currency-neg',
8 | zero: 'ui-currency-zero'
9 | };
10 | if (uiConfig.currency) {
11 | angular.extend(options, uiConfig.currency);
12 | }
13 | return {
14 | restrict: 'EAC',
15 | require: 'ngModel',
16 | link: function (scope, element, attrs, controller) {
17 | var opts, // instance-specific options
18 | renderview,
19 | value;
20 |
21 | opts = angular.extend({}, options, scope.$eval(attrs.uiCurrency));
22 |
23 | renderview = function (viewvalue) {
24 | var num;
25 | num = viewvalue * 1;
26 | element.toggleClass(opts.pos, (num > 0) );
27 | element.toggleClass(opts.neg, (num < 0) );
28 | element.toggleClass(opts.zero, (num === 0) );
29 | if (viewvalue === '') {
30 | element.text('');
31 | } else {
32 | element.text(currencyFilter(num, opts.symbol));
33 | }
34 | return true;
35 | };
36 |
37 | controller.$render = function () {
38 | value = controller.$viewValue;
39 | element.val(value);
40 | renderview(value);
41 | };
42 |
43 | }
44 | };
45 | }]);
46 |
--------------------------------------------------------------------------------
/modules/filters/unique/unique.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Filters out all duplicate items from an array by checking the specified key
3 | * @param [key] {string} the name of the attribute of each object to compare for uniqueness
4 | if the key is empty, the entire object will be compared
5 | if the key === false then no filtering will be performed
6 | * @return {array}
7 | */
8 | angular.module('ui.filters').filter('unique', function () {
9 |
10 | return function (items, filterOn) {
11 |
12 | if (filterOn === false) {
13 | return items;
14 | }
15 |
16 | if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
17 | var hashCheck = {}, newItems = [];
18 |
19 | var extractValueToCompare = function (item) {
20 | if (angular.isObject(item) && angular.isString(filterOn)) {
21 | return item[filterOn];
22 | } else {
23 | return item;
24 | }
25 | };
26 |
27 | angular.forEach(items, function (item) {
28 | var valueToCheck, isDuplicate = false;
29 |
30 | for (var i = 0; i < newItems.length; i++) {
31 | if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
32 | isDuplicate = true;
33 | break;
34 | }
35 | }
36 | if (!isDuplicate) {
37 | newItems.push(item);
38 | }
39 |
40 | });
41 | items = newItems;
42 | }
43 | return items;
44 | };
45 | });
46 |
--------------------------------------------------------------------------------
/modules/directives/sortable/test/sortableSpec.js:
--------------------------------------------------------------------------------
1 | describe('uiSortable', function() {
2 |
3 | // Ensure the sortable angular module is loaded
4 | beforeEach(module('ui.directives'));
5 |
6 | describe('simple use', function() {
7 |
8 | it('should have a ui-sortable class', function() {
9 | inject(function($compile, $rootScope) {
10 | var element;
11 | element = $compile("
")($rootScope);
12 | expect(element.hasClass("ui-sortable")).toBeTruthy();
13 | });
14 | });
15 |
16 | it('should update model when order changes', function() {
17 | inject(function($compile, $rootScope) {
18 | var element;
19 | element = $compile('
{{ item }}
')($rootScope);
20 | $rootScope.$apply(function() {
21 | return $rootScope.items = ["One", "Two", "Three"];
22 | });
23 |
24 | element.find('li:eq(1)').insertAfter(element.find('li:eq(2)'));
25 |
26 | // None of this work, one way is to use .bind("sortupdate")
27 | // and then use .trigger("sortupdate", e, ui) but I have no idea how to
28 | // construct ui object
29 |
30 | // element.sortable('refresh')
31 | // element.sortable('refreshPositions')
32 | // element.trigger('sortupdate')
33 |
34 | // expect($rootScope.items).toEqual(["One", "Three", "Two"])
35 | });
36 | });
37 |
38 | });
39 |
40 | });
--------------------------------------------------------------------------------
/templates/README.md:
--------------------------------------------------------------------------------
1 | # ui-template directives
2 |
3 | #### NOTE: This template is going to be replaced in very near future ###
4 |
5 | These directives are boilerplates for creating your own directives.
6 |
7 | ## Usage
8 |
9 | Add the template module as a dependency to your application module:
10 |
11 | var myAppModule = angular.module('MyApp', ['ui.directives.template'])
12 |
13 | Apply the directive to your html elements:
14 |
15 |
16 |
17 | Default styles are in angular-ui.css and are pretty boring, you could just override these in your
18 | stylesheet and make things more interesting
19 |
20 | ### Options
21 |
22 | All the options can be passed through the directive or set on the html element.
23 | NOTE: attributes override controller options
24 |
25 | myAppModule.controller('MyController', function($scope) {
26 | $scope.SomeNumber = 123;
27 | $scope.uiTemplateOptions = {
28 |
29 | };
30 | });
31 |
32 | // two-way binding with default for scoped.options uiTemplateOptions
33 |
34 |
35 | // one way binding with your own name for scoped options
36 |
37 |
38 |
39 | ### Notes
40 |
41 | ui-template
42 | - one-way binding unless you have in an ng-repeat
43 | - does not currently work with ng-model.
44 | - is supported only for attribute style elements
45 |
46 | ### Todo
47 | - support ng-model
48 |
--------------------------------------------------------------------------------
/modules/directives/animate/animate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Animates the injection of new DOM elements by simply creating the DOM with a class and then immediately removing it
3 | * Animations must be done using CSS3 transitions, but provide excellent flexibility
4 | *
5 | * @todo Add proper support for animating out
6 | * @param [options] {mixed} Can be an object with multiple options, or a string with the animation class
7 | * class {string} the CSS class(es) to use. For example, 'ui-hide' might be an excellent alternative class.
8 | * @example
{{item}}
9 | */
10 | angular.module('ui.directives').directive('uiAnimate', ['ui.config', '$timeout', function (uiConfig, $timeout) {
11 | var options = {};
12 | if (angular.isString(uiConfig.animate)) {
13 | options['class'] = uiConfig.animate;
14 | } else if (uiConfig.animate) {
15 | options = uiConfig.animate;
16 | }
17 | return {
18 | restrict: 'A', // supports using directive as element, attribute and class
19 | link: function ($scope, element, attrs) {
20 | var opts = {};
21 | if (attrs.uiAnimate) {
22 | opts = $scope.$eval(attrs.uiAnimate);
23 | if (angular.isString(opts)) {
24 | opts = {'class': opts};
25 | }
26 | }
27 | opts = angular.extend({'class': 'ui-animate'}, options, opts);
28 |
29 | element.addClass(opts['class']);
30 | $timeout(function () {
31 | element.removeClass(opts['class']);
32 | }, 20, false);
33 | }
34 | };
35 | }]);
36 |
37 |
--------------------------------------------------------------------------------
/modules/filters/inflector/test/inflectorSpec.js:
--------------------------------------------------------------------------------
1 | describe('inflector', function () {
2 | var inflectorFilter, testPhrase = 'here isMy_phone_number';
3 |
4 | beforeEach(module('ui.filters'));
5 | beforeEach(inject(function ($filter) {
6 | inflectorFilter = $filter('inflector');
7 | }));
8 |
9 | describe('default', function () {
10 | it('should default to humanize', function () {
11 | expect(inflectorFilter(testPhrase)).toEqual('Here Is My Phone Number');
12 | });
13 | it('should fail gracefully for invalid input', function () {
14 | expect(inflectorFilter(undefined)).toBeUndefined();
15 | });
16 | it('should do nothing for empty input', function () {
17 | expect(inflectorFilter('')).toEqual('');
18 | });
19 | });
20 |
21 | describe('humanize', function () {
22 | it('should uppercase first letter and separate words with a space', function () {
23 | expect(inflectorFilter(testPhrase, 'humanize')).toEqual('Here Is My Phone Number');
24 | });
25 | });
26 | describe('underscore', function () {
27 | it('should lowercase everything and separate words with an underscore', function () {
28 | expect(inflectorFilter(testPhrase, 'underscore')).toEqual('here_is_my_phone_number');
29 | });
30 | });
31 | describe('variable', function () {
32 | it('should remove all separators and camelHump the phrase', function () {
33 | expect(inflectorFilter(testPhrase, 'variable')).toEqual('hereIsMyPhoneNumber');
34 | });
35 | it('should do nothing if already formatted properly', function () {
36 | expect(inflectorFilter("hereIsMyPhoneNumber", 'variable')).toEqual('hereIsMyPhoneNumber');
37 | });
38 | });
39 | });
--------------------------------------------------------------------------------
/modules/filters/inflector/inflector.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Converts variable-esque naming conventions to something presentational, capitalized words separated by space.
3 | * @param {String} value The value to be parsed and prettified.
4 | * @param {String} [inflector] The inflector to use. Default: humanize.
5 | * @return {String}
6 | * @example {{ 'Here Is my_phoneNumber' | inflector:'humanize' }} => Here Is My Phone Number
7 | * {{ 'Here Is my_phoneNumber' | inflector:'underscore' }} => here_is_my_phone_number
8 | * {{ 'Here Is my_phoneNumber' | inflector:'variable' }} => hereIsMyPhoneNumber
9 | */
10 | angular.module('ui.filters').filter('inflector', function () {
11 | function ucwords(text) {
12 | return text.replace(/^([a-z])|\s+([a-z])/g, function ($1) {
13 | return $1.toUpperCase();
14 | });
15 | }
16 |
17 | function breakup(text, separator) {
18 | return text.replace(/[A-Z]/g, function (match) {
19 | return separator + match;
20 | });
21 | }
22 |
23 | var inflectors = {
24 | humanize: function (value) {
25 | return ucwords(breakup(value, ' ').split('_').join(' '));
26 | },
27 | underscore: function (value) {
28 | return value.substr(0, 1).toLowerCase() + breakup(value.substr(1), '_').toLowerCase().split(' ').join('_');
29 | },
30 | variable: function (value) {
31 | value = value.substr(0, 1).toLowerCase() + ucwords(value.split('_').join(' ')).substr(1).split(' ').join('');
32 | return value;
33 | }
34 | };
35 |
36 | return function (text, inflector, separator) {
37 | if (inflector !== false && angular.isString(text)) {
38 | inflector = inflector || 'humanize';
39 | return inflectors[inflector](text);
40 | } else {
41 | return text;
42 | }
43 | };
44 | });
45 |
--------------------------------------------------------------------------------
/modules/directives/scrollfix/scrollfix.js:
--------------------------------------------------------------------------------
1 | /*global angular, $, document*/
2 | /**
3 | * Adds a 'ui-scrollfix' class to the element when the page scrolls past it's position.
4 | * @param [offset] {int} optional Y-offset to override the detected offset.
5 | * Takes 300 (absolute) or -300 or +300 (relative to detected)
6 | */
7 | angular.module('ui.directives').directive('uiScrollfix', ['$window', function ($window) {
8 | 'use strict';
9 | return {
10 | link: function (scope, elm, attrs) {
11 | var top = elm.offset().top;
12 | if (!attrs.uiScrollfix) {
13 | attrs.uiScrollfix = top;
14 | } else {
15 | // chartAt is generally faster than indexOf: http://jsperf.com/indexof-vs-chartat
16 | if (attrs.uiScrollfix.charAt(0) === '-') {
17 | attrs.uiScrollfix = top - attrs.uiScrollfix.substr(1);
18 | } else if (attrs.uiScrollfix.charAt(0) === '+') {
19 | attrs.uiScrollfix = top + parseFloat(attrs.uiScrollfix.substr(1));
20 | }
21 | }
22 | angular.element($window).on('scroll.ui-scrollfix', function () {
23 | // if pageYOffset is defined use it, otherwise use other crap for IE
24 | var offset;
25 | if (angular.isDefined($window.pageYOffset)) {
26 | offset = $window.pageYOffset;
27 | } else {
28 | var iebody = (document.compatMode && document.compatMode !== "BackCompat") ? document.documentElement : document.body;
29 | offset = iebody.scrollTop;
30 | }
31 | if (!elm.hasClass('ui-scrollfix') && offset > attrs.uiScrollfix) {
32 | elm.addClass('ui-scrollfix');
33 | } else if (elm.hasClass('ui-scrollfix') && offset < attrs.uiScrollfix) {
34 | elm.removeClass('ui-scrollfix');
35 | }
36 | });
37 | }
38 | };
39 | }]);
40 |
--------------------------------------------------------------------------------
/modules/directives/tinymce/tinymce.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Binds a TinyMCE widget to