UNPKG

unserver-unify

Version:

562 lines (559 loc) 21 kB
'use strict'; //Directive used to set metisMenu and minimalize button angular.module('bamboo').directive('sideNavigation', function($timeout) { return { restrict: 'A', link: function(scope, element) { // Call metsi to build when user signup scope.$watch('authentication.user', function() { $timeout(function() { element.metisMenu(); }); }); } }; }).directive('minimalizaSidebar', function($timeout) { return { restrict: 'A', template: '<a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="" ng-click="minimalize()"><i class="fa fa-bars"></i></a>', controller: function($scope) { $scope.minimalize = function() { angular.element('body').toggleClass('mini-navbar'); if (!angular.element('body').hasClass('mini-navbar') || angular.element('body').hasClass('body-small')) { // Hide menu in order to smoothly turn on when maximize menu angular.element('#side-menu').hide(); // For smoothly turn on menu $timeout(function() { angular.element('#side-menu').fadeIn(500); }, 100); } else { // Remove all inline style from jquery fadeIn function to reset menu state angular.element('#side-menu').removeAttr('style'); } }; } }; }).directive('contentList', function() { return { restrict: 'E', templateUrl: 'components/content/content_list.html', // markup for template scope: { setting: '=' // allows data to be passed into directive from controller scope } }; }).directive('mobileContentListView', function() { return { restrict: 'E', templateUrl: 'components/content/mobile_content_list_view.html', // markup for template scope: { setting: '=', // allows data to be passed into directive from controller scope q: "@" }, }; }).directive('contentListView', function() { return { restrict: 'E', templateUrl: 'components/content/content_list_view.html', // markup for template scope: { setting: '=' // allows data to be passed into directive from controller scope } }; }).directive('contentListViewNews', function() { return { restrict: 'E', templateUrl: 'components/content/content_list_view_news.html', // markup for template scope: { setting: '=' // allows data to be passed into directive from controller scope } }; }).directive('focusMe', function($timeout) { return { scope: { trigger: '@focusMe' }, link: function(scope, element) { scope.$watch('trigger', function(value) { if (value === "true") { $timeout(function() { element[0].focus(); }); } }); } }; }).directive('fileModel', ['$parse', function($parse) { return { restrict: 'A', link: function(scope, element, attrs) { var model = $parse(attrs.fileModel); var modelSetter = model.assign; var onChange = $parse(attrs.onChange); element.bind('change', function() { scope.$apply(function() { modelSetter(scope, element[0].files[0]); onChange(scope); }); }); } }; }]).directive('ngThumb', ['$window', function($window) { var helper = { support: !!($window.FileReader && $window.CanvasRenderingContext2D), isFile: function(item) { return angular.isObject(item) && item instanceof $window.File; }, isImage: function(file) { var type = '|' + file.type.slice(file.type.lastIndexOf('/') + 1) + '|'; return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1; } }; return { restrict: 'A', template: '<canvas/>', link: function(scope, element, attributes) { if (!helper.support) return; var params = scope.$eval(attributes.ngThumb); if (!helper.isFile(params.file)) return; if (!helper.isImage(params.file)) return; var canvas = element.find('canvas'); var reader = new FileReader(); reader.onload = onLoadFile; reader.readAsDataURL(params.file); function onLoadFile(event) { var img = new Image(); img.onload = onLoadImage; img.src = event.target.result; } function onLoadImage() { var width = params.width || this.width / this.height * params.height; var height = params.height || this.height / this.width * params.width; canvas.attr({ width: width, height: height }); canvas[0].getContext('2d').drawImage(this, 0, 0, width, height); } } }; }]).directive('passwordConfirm', ['$parse', function($parse) { return { restrict: 'A', scope: { matchTarget: '=', }, require: 'ngModel', link: function link(scope, elem, attrs, ctrl) { var validator = function(value) { ctrl.$setValidity('match', value === scope.matchTarget); return value; } ctrl.$parsers.unshift(validator); ctrl.$formatters.push(validator); // This is to force validator when the original password gets changed scope.$watch('matchTarget', function(newval, oldval) { validator(ctrl.$viewValue); }); } }; }]).directive('preventAction', [function() { return { restrict: 'A', link: function($scope, $ele) { $ele.bind("contextmenu cut copy", function(e) { e.preventDefault(); }) } } }]).factory('$translateStaticFilesLoader', ['$q', '$http', function($q, $http) { return function(options) { if (!options || (!angular.isString(options.prefix) || !angular.isString(options.suffix))) { throw new Error('Couldn\'t load static files, no prefix or suffix specified!'); } var deferred = $q.defer(); $http(angular.extend({ url: [ options.prefix, options.key, options.suffix ].join(''), method: 'GET', params: '' }, options.$http)).then(function(res) { deferred.resolve(res.data); },function(res) { deferred.reject(options.key); }); return deferred.promise; }; }]).directive('ngModelOnblur', function() { // override the default input to update on blur // from http://jsfiddle.net/cn8VF/ return { restrict: 'A', require: 'ngModel', link: function(scope, elm, attr, ngModelCtrl) { if (attr.type === 'radio' || attr.type === 'checkbox') return; elm.unbind('input').unbind('keydown').unbind('change'); elm.bind('blur', function() { scope.$apply(function() { ngModelCtrl.$setViewValue(elm.val()); }); }); } }; }).directive('json', ["$compile", function($compile) { return { restrict: 'E', scope: { child: '=', type: '@', defaultCollapsed: '=' }, link: function(scope, element) { var stringName = "Text"; var objectName = "Object"; var arrayName = "Array"; var refName = "Reference"; var boolName = "Boolean"; scope.valueTypes = [stringName, objectName, arrayName, refName, boolName]; scope.sortableOptions = { axis: 'y' }; if (scope.$parent.defaultCollapsed === undefined) { scope.collapsed = false; } else { scope.collapsed = scope.defaultCollapsed; } if (scope.collapsed) { scope.chevron = "glyphicon-chevron-right"; } else { scope.chevron = "glyphicon-chevron-down"; } ////// // Helper functions ////// var getType = function(obj) { var type = Object.prototype.toString.call(obj); if (type === "[object Object]") { return "Object"; } else if (type === "[object Array]") { return "Array"; } else if (type === "[object Boolean]") { return "Boolean"; } else { return "Literal"; } }; var isNumber = function(n) { return !isNaN(parseFloat(n)) && isFinite(n); }; scope.getType = function(obj) { return getType(obj); }; scope.toggleCollapse = function() { if (scope.collapsed) { scope.collapsed = false; scope.chevron = "glyphicon-chevron-down"; } else { scope.collapsed = true; scope.chevron = "glyphicon-chevron-right"; } }; scope.moveKey = function(obj, key, newkey) { //moves key to newkey in obj if (key !== newkey) { obj[newkey] = obj[key]; delete obj[key]; } }; scope.deleteKey = function(obj, key) { if (getType(obj) == "Object") { if (confirm('Delete "' + key + '" and all it contains?')) { delete obj[key]; } } else if (getType(obj) == "Array") { if (confirm('Delete "' + obj[key] + '"?')) { obj.splice(key, 1); } } else { console.error("object to delete from was " + obj); } }; scope.addItem = function(obj) { if (getType(obj) == "Object") { // check input for key if (scope.keyName == undefined || scope.keyName.length == 0) { alert("Please fill in a name"); } else if (scope.keyName.indexOf("$") == 0) { alert("The name may not start with $ (the dollar sign)"); } else if (scope.keyName.indexOf("_") == 0) { alert("The name may not start with _ (the underscore)"); } else { if (obj[scope.keyName]) { if (!confirm('An item with the name "' + scope.keyName + '" exists already. Do you really want to replace it?')) { return; } } // add item to object switch (scope.valueType) { case stringName: obj[scope.keyName] = scope.valueName ? scope.possibleNumber(scope.valueName) : ""; break; case objectName: obj[scope.keyName] = {}; break; case arrayName: obj[scope.keyName] = []; break; case refName: obj[scope.keyName] = { "Reference!!!!": "todo" }; break; case boolName: obj[scope.keyName] = false; break; } //clean-up scope.keyName = ""; scope.valueName = ""; scope.showAddKey = false; } } else if (getType(obj) == "Array") { // add item to array switch (scope.valueType) { case stringName: obj.push(scope.valueName ? scope.valueName : ""); break; case objectName: obj.push({}); break; case arrayName: obj.push([]); break; case boolName: obj.push(false); break; case refName: obj.push({ "Reference!!!!": "todo" }); break; } scope.valueName = ""; scope.showAddKey = false; } else { console.error("object to add to was " + obj); } }; scope.possibleNumber = function(val) { return isNumber(val) ? parseFloat(val) : val; }; ////// // Template Generation ////// // Note: // sometimes having a different ng-model and then saving it on ng-change // into the object or array is necessary for all updates to work // recursion var switchTemplate = '<span ng-switch on="getType(val)" >' + '<json ng-switch-when="Object" child="val" type="object" default-collapsed="defaultCollapsed"></json>' + '<json ng-switch-when="Array" child="val" type="array" default-collapsed="defaultCollapsed"></json>' + '<span ng-switch-when="Boolean" type="boolean">' + '<input type="checkbox" ng-model="val" ng-model-onblur ng-change="child[key] = val">' + '</span>' + '<span ng-switch-default class="jsonLiteral"><input type="text" ng-model="val" ' + 'placeholder="Empty" ng-model-onblur ng-change="child[key] = possibleNumber(val)"/>' + '</span>' + '</span>'; // display either "plus button" or "key-value inputs" var addItemTemplate = '<div ng-switch on="showAddKey" class="block" >' + '<span ng-switch-when="true">'; if (scope.type == "object") { // input key addItemTemplate += '<input placeholder="Name" type="text" ui-keyup="{\'enter\':\'addItem(child)\'}" ' + 'class="form-control input-sm addItemKeyInput" ng-model="$parent.keyName" /> '; } addItemTemplate += // value type dropdown '<select ng-model="$parent.valueType" ng-options="option for option in valueTypes" class="form-control input-sm"' + 'ng-init="$parent.valueType=\'' + stringName + '\'" ui-keydown="{\'enter\':\'addItem(child)\'}"></select>' // input value + '<span ng-show="$parent.valueType == \'' + stringName + '\'"> : <input type="text" placeholder="Value" ' + 'class="form-control input-sm addItemValueInput" ng-model="$parent.valueName" ui-keyup="{\'enter\':\'addItem(child)\'}"/></span> ' // Add button + '<button class="btn btn-primary btn-sm" ng-click="addItem(child)">Add</button> ' + '<button class="btn btn-default btn-sm" ng-click="$parent.showAddKey=false">Cancel</button>' + '</span>' + '<span ng-switch-default>' // plus button + '<button class="addObjectItemBtn" ng-click="$parent.showAddKey = true"><i class="glyphicon glyphicon-plus"></i></button>' + '</span>' + '</div>'; // start template if (scope.type == "object") { var template = '<i ng-click="toggleCollapse()" class="glyphicon" ng-class="chevron"></i>' + '<span class="jsonItemDesc">' + objectName + '</span>' + '<div class="jsonContents" ng-hide="collapsed">' // repeat + '<span class="block" ng-hide="key.indexOf(\'_\') == 0" ng-repeat="(key, val) in child">' // object key + '<span class="jsonObjectKey">' + '<input class="keyinput" type="text" ng-model="newkey" ng-init="newkey=key" ' + 'ng-blur="moveKey(child, key, newkey)"/>' // delete button + '<i class="deleteKeyBtn glyphicon glyphicon-trash" ng-click="deleteKey(child, key)"></i>' + '</span>' // object value + '<span class="jsonObjectValue">' + switchTemplate + '</span>' + '</span>' // repeat end + addItemTemplate + '</div>'; } else if (scope.type == "array") { var template = '<i ng-click="toggleCollapse()" class="glyphicon"' + 'ng-class="chevron"></i>' + '<span class="jsonItemDesc">' + arrayName + '</span>' + '<div class="jsonContents" ng-hide="collapsed">' + '<ol class="arrayOl" ui-sortable="sortableOptions" ng-model="child">' // repeat + '<li class="arrayItem" ng-repeat="val in child">' // delete button + '<i class="deleteKeyBtn glyphicon glyphicon-trash" ng-click="deleteKey(child, $index)"></i>' + '<i class="moveArrayItemBtn glyphicon glyphicon-align-justify"></i>' + '<span>' + switchTemplate + '</span>' + '</li>' // repeat end + '</ol>' + addItemTemplate + '</div>'; } else { console.error("scope.type was " + scope.type); } var newElement = angular.element(template); $compile(newElement)(scope); element.replaceWith(newElement); } }; }]).filter('encodeURIComponent', function() { return window.encodeURIComponent; }).filter('offset', function() { return function(input, start) { if (input instanceof Array) { start = parseInt(start, 10); return input.slice(start); } else { return input; } }; }).filter('numToLetters', function() { var fn = function(num) { var mod = num % 26, pow = num / 26 | 0, out = mod ? String.fromCharCode(64 + mod) : (--pow, 'Z'); return pow ? fn(pow) + out : out; }; return function(input) { return fn(input); }; }).filter('fileSize', function() { return function(input) { if (isNaN(input)) return input; if (input < (1024 * 1024)) { return (input / 1024).toFixed(2) + ' KB '; } else { return (input / 1024 / 1024).toFixed(2) + ' MB '; } }; }).filter('kbFileSize', function() { return function(input) { if (isNaN(input)) return input; return Math.round(input / 1024) + ' KB'; }; }).filter('secondsToDateTime', [function() { return function(seconds) { return new Date(1970, 0, 1).setSeconds(seconds); }; }]).filter('trans', function($rootScope) { var tran = function(obj) { if ($rootScope.currentLanguage == 'Chinese') { return obj.chn || obj; } else { return obj.eng || obj; } } tran.$stateful = true; return tran; }).filter('isEmpty', function() { var bar; return function(obj) { // null and undefined are "empty" if (obj == null) return true; // Assume if it has a length property with a non-zero value // that that property is correct. if (obj.length > 0) return false; if (obj.length === 0) return true; // Otherwise, does it have any properties of its own? // Note that this doesn't handle // toString and valueOf enumeration bugs in IE < 9 for (bar in obj) { if (obj.hasOwnProperty(bar)) { return false; } } return true; }; }).filter('notEmpty', function() { var bar; return function(obj) { // null and undefined are "empty" if (obj == null) return false; // Assume if it has a length property with a non-zero value // that that property is correct. if (obj.length > 0) return true; if (obj.length === 0) return false; // Otherwise, does it have any properties of its own? // Note that this doesn't handle // toString and valueOf enumeration bugs in IE < 9 for (bar in obj) { if (obj.hasOwnProperty(bar)) { return true; } } return false; }; }).directive("averageStarRating", function() { return { restrict: "AE", template: "<div class='average-rating-container'>" + " <ul class='rating background' class='readonly'>" + " <li ng-repeat='star in stars' class='star'>" + " <i class='fa fa-star'></i>" + //&#9733 " </li>" + " </ul>" + " <ul class='rating foreground' class='readonly' style='width:{{filledInStarsContainerWidth}}%'>" + " <li ng-repeat='star in stars' class='star filled'>" + " <i class='fa fa-star'></i>" + //&#9733 " </li>" + " </ul>" + "</div>", scope: { ratingValue: "=", max: "=max", //optional: default is 5 }, link: function(scope, elem) { if (scope.max == undefined) { scope.max = 5; } function updateStars() { scope.stars = []; for (var i = 0; i < scope.max; i++) { scope.stars.push({}); } var starContainerMaxWidth = 100; //% scope.filledInStarsContainerWidth = scope.ratingValue / scope.max * starContainerMaxWidth; } scope.$watch('ratingValue', function(newval) { if (newval) { updateStars(); } }); } }; }).directive('pageSelect', function() { return { restrict: 'E', template: '<input type="text" size="2" class="select-page" ng-model="inputPage" ng-change="selectPage(inputPage)">', link: function(scope, element) { scope.$watch('currentPage', function(c) { scope.inputPage = c; }); } } }).directive("scroll", function($window) { return function(scope, element) { angular.element($window).bind("scroll", function() { if (this.pageYOffset >= 300) { scope.bottomFlag = true; //console.log('Scrolled below header.'); } else { scope.bottomFlag = false; //console.log('Header is in view.'); } scope.$apply(); }); }; }).directive('ngEnter', function () { return function (scope, element, attrs) { element.bind("keydown keypress", function (event) { if(event.which === 13) { scope.$apply(function (){ scope.$eval(attrs.ngEnter); }); event.preventDefault(); } }); }; }).directive('parseStyle', function() { return function(scope, elem) { elem.html(scope.$eval('\'' + elem.html() + '\'')); } });