UNPKG

sheercms

Version:

Sheer Cliff CMS is a simple and powerful content management system (CMS) for Node JS.

497 lines (434 loc) 16.9 kB
var app = angular.module('app', ['ngRoute', 'ngSanitize', 'ui.sortable', 'ui.select2', 'angularFileUpload', 'ui.bootstrap', 'ui.calendar', 'ngQuickDate', 'angular-data.DSCacheFactory', 'ngCookies']); app.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/', { redirectTo: '/content' }). when('/menus', { templateUrl: '/cms/static/routes/menus/menus.html', controller: 'MenuController' }). when('/content', { templateUrl: '/cms/static/routes/content/content.html', controller: 'ContentController', reloadOnSearch: false }). when('/media', { templateUrl: '/cms/static/routes/content/content.html', controller: 'ContentController', reloadOnSearch: false }). when('/edit/:contentId', { templateUrl: '/cms/static/routes/content/edit.html', controller: 'EditController' }). when('/users', { templateUrl: '/cms/static/routes/users/users.html', controller: 'UserController' }). when('/templates', { templateUrl: '/cms/static/routes/templates/templates.html', controller: 'TemplateController' }). when('/types', { templateUrl: '/cms/static/routes/types/contentTypes.html', controller: 'ContentTypeController' }). when('/dashboard', { templateUrl: '/cms/static/routes/dashboard/dashboard.html', controller: 'DashboardController' }). when('/logs', { templateUrl: '/cms/static/routes/logs/logs.html', controller: 'LogController' }). when('/cache', { templateUrl: '/cms/static/routes/cache/cache.html', controller: 'CacheController' }). when('/packages', { templateUrl: '/cms/static/routes/packages/packages.html', controller: 'PackageController' }). when('/stats', { templateUrl: '/cms/static/routes/stats/stats.html', controller: 'StatController' }); }]); app.constant('uiAceConfig', {}) .directive('uiAce', ['uiAceConfig', function (uiAceConfig) { if (angular.isUndefined(window.ace)) { throw new Error('ui-ace need ace to work... (o rly?)'); } /** * Sets editor options such as the wrapping mode or the syntax checker. * * The supported options are: * * <ul> * <li>showGutter</li> * <li>useWrapMode</li> * <li>onLoad</li> * <li>theme</li> * <li>mode</li> * </ul> * * @param acee * @param session ACE editor session * @param {object} opts Options to be set */ var setOptions = function(acee, session, opts) { // Boolean options if (angular.isDefined(opts.showGutter)) { acee.renderer.setShowGutter(opts.showGutter); } if (angular.isDefined(opts.useWrapMode)) { session.setUseWrapMode(opts.useWrapMode); } if (angular.isDefined(opts.showInvisibles)) { acee.renderer.setShowInvisibles(opts.showInvisibles); } if (angular.isDefined(opts.showIndentGuides)) { acee.renderer.setDisplayIndentGuides(opts.showIndentGuides); } if (angular.isDefined(opts.useSoftTabs)) { session.setUseSoftTabs(opts.useSoftTabs); } // commands if (angular.isDefined(opts.disableSearch) && opts.disableSearch) { acee.commands.addCommands([ { name: 'unfind', bindKey: { win: 'Ctrl-F', mac: 'Command-F' }, exec: function () { return false; }, readOnly: true } ]); } // onLoad callback if (angular.isFunction(opts.onLoad)) { opts.onLoad(acee); } // Basic options if (angular.isString(opts.theme)) { acee.setTheme('ace/theme/' + opts.theme); } if (angular.isString(opts.mode)) { session.setMode('ace/mode/' + opts.mode); } //additional settings acee.setShowPrintMargin(false); }; return { restrict: 'EA', require: '?ngModel', link: function (scope, elm, attrs, ngModel) { /** * Corresponds the uiAceConfig ACE configuration. * @type object */ var options = uiAceConfig.ace || {}; /** * uiAceConfig merged with user options via json in attribute or data binding * @type object */ var opts = angular.extend({}, options, scope.$eval(attrs.uiAce)); /** * ACE editor * @type object */ var acee = window.ace.edit(elm[0]); /** * ACE editor session. * @type object * @see [EditSession]{@link http://ace.c9.io/#nav=api&api=edit_session} */ var session = acee.getSession(); /** * Reference to a change listener created by the listener factory. * @function * @see listenerFactory.onChange */ var onChangeListener; /** * Reference to a blur listener created by the listener factory. * @function * @see listenerFactory.onBlur */ var onBlurListener; /** * Calls a callback by checking its existing. The argument list * is variable and thus this function is relying on the arguments * object. * @throws {Error} If the callback isn't a function */ var executeUserCallback = function () { /** * The callback function grabbed from the array-like arguments * object. The first argument should always be the callback. * * @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments} * @type {*} */ var callback = arguments[0]; /** * Arguments to be passed to the callback. These are taken * from the array-like arguments object. The first argument * is stripped because that should be the callback function. * * @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments} * @type {Array} */ var args = Array.prototype.slice.call(arguments, 1); if (angular.isDefined(callback)) { scope.$apply(function () { if (angular.isFunction(callback)) { callback(args); } else { throw new Error('ui-ace use a function as callback.'); } }); } }; /** * Listener factory. Until now only change listeners can be created. * @type object */ var listenerFactory = { /** * Creates a change listener which propagates the change event * and the editor session to the callback from the user option * onChange. It might be exchanged during runtime, if this * happens the old listener will be unbound. * * @param callback callback function defined in the user options * @see onChangeListener */ onChange: function (callback) { return function (e) { var newValue = session.getValue(); if (newValue !== scope.$eval(attrs.value) && !scope.$$phase && !scope.$root.$$phase) { if (angular.isDefined(ngModel)) { scope.$apply(function () { ngModel.$setViewValue(newValue); }); } executeUserCallback(callback, e, acee); } }; }, /** * Creates a blur listener which propagates the editor session * to the callback from the user option onBlur. It might be * exchanged during runtime, if this happens the old listener * will be unbound. * * @param callback callback function defined in the user options * @see onBlurListener */ onBlur: function (callback) { return function () { executeUserCallback(callback, acee); }; } }; attrs.$observe('readonly', function (value) { acee.setReadOnly(value === 'true'); }); // Value Blind if (angular.isDefined(ngModel)) { ngModel.$formatters.push(function (value) { if (angular.isUndefined(value) || value === null) { return ''; } else if (angular.isObject(value) || angular.isArray(value)) { throw new Error('ui-ace cannot use an object or an array as a model'); } return value; }); ngModel.$render = function () { session.setValue(ngModel.$viewValue); }; } // set the options here, even if we try to watch later, if this // line is missing things go wrong (and the tests will also fail) setOptions(acee, session, opts); // Listen for option updates scope.$watch( attrs.uiAce, function() { opts = angular.extend({}, options, scope.$eval(attrs.uiAce)); // unbind old change listener session.removeListener('change', onChangeListener); // bind new change listener onChangeListener = listenerFactory.onChange(opts.onChange); session.on('change', onChangeListener); // unbind old blur listener //session.removeListener('blur', onBlurListener); acee.removeListener('blur', onBlurListener); // bind new blur listener onBlurListener = listenerFactory.onBlur(opts.onBlur); acee.on('blur', onBlurListener); setOptions(acee, session, opts); }, /* deep watch */ true ); // EVENTS onChangeListener = listenerFactory.onChange(opts.onChange); session.on('change', onChangeListener); onBlurListener = listenerFactory.onBlur(opts.onBlur); acee.on('blur', onBlurListener); elm.on('$destroy', function () { acee.session.$stopWorker(); acee.destroy(); }); scope.$watch(function() { return [elm[0].offsetWidth, elm[0].offsetHeight]; }, function() { acee.resize(); acee.renderer.updateFull(); }, true); } }; }]); app.directive('tabs', function ($parse) { return { restrict: 'AC', link: function (scope, element, attrs) { //find the tallest pane and make them all that size /*var t = 0; element.find(".tabs-body > div").each(function() { var h = $(this).height(); if (h > t) t = h; }); if (t < 0) element.find(".tabs-body").css("height", t + "px");*/ element.find(".tabs-head a").on("click", function() { var i = $(this).parent().index(); element.find(".tabs-head li").removeClass("active"); $(this).parent().addClass("active"); element.find(".tabs-body > div").removeClass("active"); element.find(".tabs-body > div:eq(" + i + ")").addClass("active"); }); } }; }); app.run(function($rootScope) { /*$rootScope.themeConfig = {}; function loadThemeConfig() { ThemeService.getCurrentTheme().then(function(config) { $rootScope.themeConfig = config; }); } loadThemeConfig(); */ }); app.controller('LoginController', function($scope, $location, GroupService) { function init() { GroupService.clearAllCache(); } init(); }); app.controller('CMSController', function($scope, $location, UserService, $modal, $cookieStore, CacheService) { $scope.pageData = null; $scope.global = { helloName: "", isAdmin: false }; $scope.menu = null; $scope.menuClicked = function(item, sub) { $scope.menu.selectedItem = item if (item.items && item.items.length > 0) { for(var i = 0; i < $scope.menu.items.length; i++) { $scope.menu.items[i].expanded = false; } item.expanded = true; } }; $scope.editProfile = function() { var modalInstance = $modal.open({ templateUrl: 'UserProfileDialog', controller: UserProfileDialogController, resolve: { user: function () { return $scope.pageData.user; }, parentScope: function() { return $scope; } } }); modalInstance.result.then(function() { //closed }); }; $scope.setHelloName = function() { var user = $scope.pageData.user; if (user) { $scope.global.helloName = (user.firstName && user.firstName.length > 0) ? user.firstName : user.username; } }; $scope.resize = function() { if (arguments && arguments.length > 0) { var winH = $(window).height(); //remove all min-heights for (var i = 0; i < arguments.length; i++) { var el = $(arguments[i]); el.css("min-height", ''); } var firstEl = $(arguments[0]); var curH = firstEl.height(); var h = (winH - 70); if (curH > h) h = curH; firstEl.css("min-height", h + 'px'); //remaining elements are inside first element for (var i = 1; i < arguments.length; i++) { var el = $(arguments[i]); el.css("min-height", h + 'px'); } } }; function init() { var pageDataJson = $("#pageData").val(); $scope.pageData = JSON.parse(pageDataJson); $scope.menu = $scope.pageData.menu; $scope.global.isAdmin = $scope.pageData.isAdmin; $scope.setHelloName(); //should we clear the cache var cookie = $cookieStore.get('sheercms'); if (cookie) { /*if (cookie.clearCache == true) { CacheService.clearClientCache(); cookie.clearCache = false; $cookieStore.put('sheercms', cookie); }*/ $scope.global.cookie = cookie; } //select the first menu item $scope.menu.selectedItem = $scope.menu.items[0]; $scope.$on('$locationChangeStart', function(event) { $scope.menu.selectedItem = null; var path = $location.path(); if (path && path.indexOf('/') === 0) { if (path === '/') { //my dashboard $scope.menu.selectedItem = $scope.menu.items[0]; } else { path = '#' + path.substr(1); for(var i = 0; i < $scope.menu.items.length; i++) { var m = $scope.menu.items[i]; if (path === m.url) { $scope.menu.selectedItem = m; break; } } } } }); } init(); });