UNPKG

webgme

Version:

Web-based Generic Modeling Environment

1,484 lines (1,109 loc) 60.8 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ /*globals angular*/ require('./services/isisUIServices.js'); require('./hierarchicalMenu/hierarchicalMenu.js'); require('./contextmenu/contextmenu.js'); require('./dropdownNavigator/dropdownNavigator.js'); require('./treeNavigator/treeNavigator.js'); require('./itemList/itemList.js'); require('./taxonomyTerms/taxonomyTerms.js'); angular.module('isis.ui.components', [ 'isis.ui.components.templates', 'isis.ui.services', 'isis.ui.hierarchicalMenu', 'isis.ui.contextmenu', 'isis.ui.dropdownNavigator', 'isis.ui.treeNavigator', 'isis.ui.itemList' ]); },{"./contextmenu/contextmenu.js":3,"./dropdownNavigator/dropdownNavigator.js":4,"./hierarchicalMenu/hierarchicalMenu.js":6,"./itemList/itemList.js":9,"./services/isisUIServices.js":16,"./taxonomyTerms/taxonomyTerms.js":18,"./treeNavigator/treeNavigator.js":20}],2:[function(require,module,exports){ !function(a,b,c){"use strict";b.module("ui.sortable",[]).value("uiSortableConfig",{}).directive("uiSortable",["uiSortableConfig","$timeout","$log",function(a,d,e){return{require:"?ngModel",scope:{ngModel:"=",uiSortable:"="},link:function(f,g,h,i){function j(a,b){return b&&"function"==typeof b?function(c,d){a(c,d),b(c,d)}:a}function k(a){var b=a.data("ui-sortable");return b&&"object"==typeof b&&"ui-sortable"===b.widgetFullName?b:null}function l(a,b){var c=a.sortable("option","helper");return"clone"===c||"function"==typeof c&&b.item.sortable.isCustomHelperUsed()}function m(a){return/left|right/.test(a.css("float"))||/inline|table-cell/.test(a.css("display"))}function n(a,b){for(var c=null,d=0;d<a.length;d++){var e=a[d];if(e.element[0]===b[0]){c=e.scope;break}}return c}function o(a,b){b.item.sortable._destroy()}var p,q={},r={"ui-floating":c},s={receive:null,remove:null,start:null,stop:null,update:null},t={helper:null};return b.extend(q,r,a,f.uiSortable),b.element.fn&&b.element.fn.jquery?(i?(f.$watch("ngModel.length",function(){d(function(){k(g)&&g.sortable("refresh")},0,!1)}),s.start=function(a,d){if("auto"===q["ui-floating"]){var e=d.item.siblings(),f=k(b.element(a.target));f.floating=m(e)}d.item.sortable={model:i.$modelValue[d.item.index()],index:d.item.index(),source:d.item.parent(),sourceModel:i.$modelValue,cancel:function(){d.item.sortable._isCanceled=!0},isCanceled:function(){return d.item.sortable._isCanceled},isCustomHelperUsed:function(){return!!d.item.sortable._isCustomHelperUsed},_isCanceled:!1,_isCustomHelperUsed:d.item.sortable._isCustomHelperUsed,_destroy:function(){b.forEach(d.item.sortable,function(a,b){d.item.sortable[b]=c})}}},s.activate=function(a,c){p=g.contents();var d=g.sortable("option","placeholder");if(d&&d.element&&"function"==typeof d.element){var e=d.element();e=b.element(e);var h=g.find('[class="'+e.attr("class")+'"]:not([ng-repeat], [data-ng-repeat])');p=p.not(h)}var i=c.item.sortable._connectedSortables||[];i.push({element:g,scope:f}),c.item.sortable._connectedSortables=i},s.update=function(a,b){if(!b.item.sortable.received){b.item.sortable.dropindex=b.item.index();var c=b.item.parent();b.item.sortable.droptarget=c;var d=n(b.item.sortable._connectedSortables,c);b.item.sortable.droptargetModel=d.ngModel,g.sortable("cancel")}l(g,b)&&!b.item.sortable.received&&"parent"===g.sortable("option","appendTo")&&(p=p.not(p.last())),p.appendTo(g),b.item.sortable.received&&(p=null),b.item.sortable.received&&!b.item.sortable.isCanceled()&&f.$apply(function(){i.$modelValue.splice(b.item.sortable.dropindex,0,b.item.sortable.moved)})},s.stop=function(a,b){!b.item.sortable.received&&"dropindex"in b.item.sortable&&!b.item.sortable.isCanceled()?f.$apply(function(){i.$modelValue.splice(b.item.sortable.dropindex,0,i.$modelValue.splice(b.item.sortable.index,1)[0])}):"dropindex"in b.item.sortable&&!b.item.sortable.isCanceled()||l(g,b)||p.appendTo(g),p=null},s.receive=function(a,b){b.item.sortable.received=!0},s.remove=function(a,b){"dropindex"in b.item.sortable||(g.sortable("cancel"),b.item.sortable.cancel()),b.item.sortable.isCanceled()||f.$apply(function(){b.item.sortable.moved=i.$modelValue.splice(b.item.sortable.index,1)[0]})},t.helper=function(a){return a&&"function"==typeof a?function(b,c){var d=a(b,c);return c.sortable._isCustomHelperUsed=c!==d,d}:a},f.$watch("uiSortable",function(a){var c=k(g);c&&b.forEach(a,function(a,b){return b in r?("ui-floating"!==b||a!==!1&&a!==!0||(c.floating=a),void(q[b]=a)):(s[b]?("stop"===b&&(a=j(a,function(){f.$apply()}),a=j(a,o)),a=j(s[b],a)):t[b]&&(a=t[b](a)),q[b]=a,void g.sortable("option",b,a))})},!0),b.forEach(s,function(a,b){q[b]=j(a,q[b]),"stop"===b&&(q[b]=j(q[b],o))})):e.info("ui.sortable: ngModel not provided!",g),void g.sortable(q)):void e.error("ui.sortable: jQuery should be included before AngularJS!")}}}])}(window,window.angular); },{}],3:[function(require,module,exports){ /*globals angular, $*/ 'use strict'; angular.module( 'isis.ui.contextmenu', ['isis.ui.hierarchicalMenu'] ) .factory( 'contextmenuService', ['$document', '$compile', '$window', '$templateCache', function ($document, $compile, $window, $templateCache) { var service = {}, setPosition, body = $document.find('body') .eq(0), widthWatcher, heightWatcher, menuScope, opened = false, handleKeyUpEvent, handleMouseDownEvent, handleClickEvent, handleScrollEvent, handleResizeEvent, handleBlurEvent, bindEvents, autoCloseOnClick = true, window = angular.element( $window ); handleKeyUpEvent = function (event) { if (opened && event.keyCode === 27) { service.close(); } }; handleMouseDownEvent = function (event) { if (opened && service.menuElement && !$.contains(service.menuElement[0], event.target) && event.target !== service.triggerElement) { service.close(); } }; handleClickEvent = function (event) { if (opened && (autoCloseOnClick || (service.menuElement && !$.contains(service.menuElement[ 0], event.target))) && (event.target !== service.triggerElement)) { service.close(); return false; } }; handleScrollEvent = function () { if (opened) { service.close(); } }; handleResizeEvent = function () { if (opened) { service.close(); } }; handleBlurEvent = function () { if (opened) { service.close(); } }; bindEvents = function () { $document.bind( 'keyup', handleKeyUpEvent ); // Firefox treats a right-click as a click and a contextmenu event while other browsers // just treat it as a contextmenu event $document.bind( 'scroll', handleScrollEvent ); window.bind( 'resize', handleResizeEvent ); window.bind( 'blur', handleBlurEvent ); $document.bind( 'click', handleClickEvent ); $document.bind( 'mousedown', handleMouseDownEvent ); $document.bind( 'contextmenu', handleClickEvent ); }; setPosition = function (position, menuElement) { var menuBounds = menuElement[0].getBoundingClientRect(), menuWidth = menuBounds.right - menuBounds.left, menuHeight = menuBounds.bottom - menuBounds.top, windowHeight = window[0].innerHeight, windowWidth = window[0].innerWidth, windowLeftEdge = window[0].pageXOffset, windowTopEdge = window[0].pageYOffset, windowRightEdge = windowWidth + windowLeftEdge, windowBottomEdge = windowHeight + windowTopEdge, top = Math.max( position.pageY, windowTopEdge ), left = Math.max( position.pageX, windowLeftEdge ), totalHeightNeeded = menuHeight + top, totalWidthNeeded = menuWidth + left, overLeftEdge = totalWidthNeeded - windowRightEdge, overBottomEdge = totalHeightNeeded - windowBottomEdge; //console.log(top, menuHeight, windowTopEdge, windowHeight); if (overBottomEdge > 0) { top = top - overBottomEdge; } if (overLeftEdge > 0) { left = left - overLeftEdge; } menuElement.css( 'top', top + 'px' ); menuElement.css( 'left', left + 'px' ); // Setting property of menu to drop on left side if no room on right for sub menus }; service.open = function (triggerElement, contentTemplateUrl, aScope, position, doNotAutocloseOnClick, menuCssClass) { var shellAngularElement = angular.element($templateCache.get( '/isis-ui-components/templates/contextmenu.html')), menuDOMElement, sameTriggerElement = (service.triggerElement === triggerElement); autoCloseOnClick = doNotAutocloseOnClick !== true; if (opened) { service.close(); } if (!sameTriggerElement) { // do not re-open if the same triggerelement was clicked menuScope = aScope.$new(); menuScope.contentTemplateUrl = contentTemplateUrl; menuScope.menuCssClass = menuCssClass; body.append(shellAngularElement); menuDOMElement = $compile(shellAngularElement)(menuScope); service.menuElement = menuDOMElement; service.triggerElement = triggerElement; setPosition(position, menuDOMElement); widthWatcher = menuScope.$watch( function () { return menuDOMElement[0].scrollWidth; }, function () { setPosition(position, menuDOMElement); } ); heightWatcher = menuScope.$watch( function () { return menuDOMElement[0].scrollHeight; }, function () { setPosition(position, menuDOMElement); } ); bindEvents(); opened = true; } }; service.close = function () { if (angular.isObject(menuScope) && angular.isFunction(menuScope.$destroy)) { service.menuElement.remove(); menuScope.$destroy(); menuScope = undefined; service.menuElement = null; service.triggerElement = null; opened = false; } }; service.triggerElement = null; return service; } ]) .directive( 'isisContextmenu', ['$document', 'contextmenuService', '$window', '$rootScope', function ($document, contextmenuService) { return { restrict: 'A', scope: { contextmenuConfig: '=', contextmenuData: '=', callback: '&contextmenu', disabled: '&contextmenuDisabled' }, link: function (scope, element) { var open, handleContextmenuEvent, options = { triggerEvent: 'contextmenu', contentTemplateUrl: '/isis-ui-components/templates/contextmenu.DefaultContents.html' }; if (!angular.isFunction(scope.disabled)) { scope.disabled = function () { return false; }; } if (angular.isObject(scope.contextmenuConfig)) { angular.extend(options, scope.contextmenuConfig); } element.addClass('context-menu-trigger'); open = function (event) { var position, bounds, menuParentScope; position = { pageX: event.pageX, pageY: event.pageY }; if (scope.contextmenuConfig && scope.contextmenuConfig.position) { bounds = element[0].getBoundingClientRect(); if (scope.contextmenuConfig.position === 'left bottom') { position.pageX = bounds.left + window.pageXOffset; position.pageY = bounds.bottom + window.pageYOffset; } else if (scope.contextmenuConfig.position === 'right bottom') { position.pageX = bounds.right + window.pageXOffset; position.pageY = bounds.bottom + window.pageYOffset; } } if (!scope.disabled()) { menuParentScope = options.menuParentScope || scope; contextmenuService.open( event.target, options.contentTemplateUrl, menuParentScope, position, options.doNotAutoClose, options.menuCssClass ); } }; handleContextmenuEvent = function (event) { if (!scope.disabled()) { if (event.target !== contextmenuService.triggerElement) { event.preventDefault(); event.stopPropagation(); scope.$apply( function () { scope.callback({ $event: event }); open(event); } ); } else { event.preventDefault(); event.stopPropagation(); contextmenuService.close(); } } }; element.bind( options.triggerEvent, handleContextmenuEvent ); scope.$on( '$destroy', function () { element.unbind( options.triggerEvent, handleContextmenuEvent ); } ); } }; } ]); },{}],4:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.dropdownNavigator', ['isis.ui.hierarchicalMenu'] ) .directive( 'dropdownNavigator', function () { return { scope: { navigator: '=' }, restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/dropdownNavigator.html' }; }); },{}],5:[function(require,module,exports){ /*globals angular*/ 'use strict'; /* * An Angular service which helps with creating recursive directives. * @author Mark Lagendijk * @license MIT */ angular.module('isis.ui.RecursionHelper', []) .factory('ISISRecursionHelper', ['$compile', function ($compile) { return { /** * Manually compiles the element, fixing the recursion loop. * @param element * @param [link] A post-link function, or an object with function(s) registered via pre and post properties. * @returns An object containing the linking functions. */ compile: function (element, link) { // Normalize the link parameter if (angular.isFunction(link)) { link = { post: link }; } // Break the recursion loop by removing the contents var contents = element.contents() .remove(); var compiledContents; return { pre: (link && link.pre) ? link.pre : null, /** * Compiles and re-adds the contents */ post: function (scope, element) { // Compile the contents if (!compiledContents) { compiledContents = $compile(contents); } // Re-add the compiled contents to the element compiledContents(scope, function (clone) { element.append(clone); }); // Call the post-linking function, if any if (link && link.post) { link.post.apply(null, arguments); } } }; } }; } ]); },{}],6:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.hierarchicalMenu', [ 'isis.ui.components' ] ) .directive( 'hierarchicalMenu', ['$window', '$document', function ($window, $document) { var window = angular.element( $window ); return { scope: { menu: '=', config: '=' }, restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/hierarchicalMenu.html', link: function ($scope, element) { var whichSideToDropSubs; whichSideToDropSubs = function () { var elementBounds = element[0].getBoundingClientRect(), windowLeftEdge = window[0].pageXOffset, width = elementBounds.right - elementBounds.left, rightBorderX = elementBounds.right, leftBorderX = elementBounds.left, windowWidth = window[0].innerWidth, windowRightEdge = windowWidth + windowLeftEdge, wouldBeRightBorderOfSub = width + rightBorderX; if (windowRightEdge < wouldBeRightBorderOfSub && leftBorderX > width) { element.addClass('drop-left'); } else { element.removeClass('drop-left'); } }; $scope.$watch( function () { return element[0].scrollWidth; }, function () { whichSideToDropSubs(); } ); $document.bind( 'scroll', whichSideToDropSubs ); window.bind( 'resize', whichSideToDropSubs ); $scope.$on('$destroy', function () { $document.unbind( 'scroll', whichSideToDropSubs ); window.unbind( 'resize', whichSideToDropSubs ); }); } }; } ]); },{}],7:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.itemList.item.details', [] ) .controller('ItemListItemDetailsController', function ($scope) { var expanded = false; $scope.config.showDetailsLabel = $scope.config.showDetailsLabel || 'Details'; $scope.config.hideDetailsLabel = $scope.config.hideDetailsLabel || 'Details'; expanded = false; $scope.getExpanderClass = function () { if (expanded) { return 'glyphicon glyphicon-chevron-up'; } else { return 'glyphicon glyphicon-chevron-right'; } }; $scope.getExpanderLabel = function () { if (expanded) { return $scope.config.hideDetailsLabel; } else { return $scope.config.showDetailsLabel; } }; $scope.detailsCollapserClick = function () { expanded = !expanded; }; $scope.shouldBeExpanded = function () { return expanded || !$scope.config.detailsCollapsible; }; }) .directive( 'ilItemDetails', function () { return { restrict: 'E', replace: true, require: '^itemList', controller: 'ItemListItemDetailsController', templateUrl: '/isis-ui-components/templates/itemDetails.html' }; }); },{}],8:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.itemList.item.header', [] ) .directive( 'ilItemHeader', function () { return { restrict: 'E', replace: true, require: '^itemList', templateUrl: '/isis-ui-components/templates/itemHeader.html' // link: function(scope, element) { // var onDragStart, // onDragEnd, // itemId = scope.item.id; // onDragStart = function(e) { // e.dataTransfer.effectAllowed = 'move'; // e.dataTransfer.setData('text', itemId); // element.addClass('dragged'); // if (typeof scope.config.onItemDragStart === 'function') { // scope.config.onItemDragStart(e, scope.item); // } // }; // onDragEnd = function(e) { // element.removeClass('dragged'); // if (typeof scope.config.onItemDragEnd === 'function') { // scope.config.onItemDragEnd(e, scope.item); // } // }; // if (scope.config.itemDraggable) { // console.log(element[0]); // element[0].addEventListener('dragstart', onDragStart); // element[0].addEventListener('dragend', onDragEnd); // } // scope.$on('$destroy', function() { // if (scope.config.itemDraggable) { // element[0].removeEventListener('dragstart', onDragStart); // element[0].removeEventListener('dragend', onDragEnd); // } // }); // } }; }); },{}],9:[function(require,module,exports){ /*globals angular*/ 'use strict'; require('./listItemGroup.js'); require('./itemListFilter.js'); require('./itemListNewItem.js'); require('../contextmenu/contextmenu.js'); angular.module( 'isis.ui.itemList', [ 'isis.ui.itemList.newItem', 'isis.ui.itemList.filter', 'isis.ui.itemList.itemGroup', 'isis.ui.contextmenu', 'isis.ui.taxonomyTerms' ] ) .controller( 'ItemListController', function ($scope) { // Event handlers $scope.sortableOptions = { update: function (e, ui) { if (angular.isFunction($scope.config.itemSort)) { $scope.config.itemSort(event, ui); } }, axis: 'y' }; $scope.itemClick = function ($event, item) { if (angular.isFunction($scope.config.itemClick)) { $scope.config.itemClick($event, item); } }; $scope.itemContextmenu = function ($event, node) { if (angular.isFunction($scope.config.itemContextmenuRenderer)) { $scope.itemContextMenuData = $scope.config.itemContextmenuRenderer($event, node); } }; $scope.itemMenuConfig = { triggerEvent: 'click', position: 'left bottom' }; $scope.config = $scope.config || {}; $scope.config.noItemsMessage = $scope.config.noItemsMessage || 'No items to show.'; }) .directive( 'itemList', function () { return { scope: { listData: '=', config: '=' }, restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/itemList.html', controller: 'ItemListController' }; } ); },{"../contextmenu/contextmenu.js":3,"./itemListFilter.js":10,"./itemListNewItem.js":12,"./listItemGroup.js":15}],10:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.itemList.filter', [] ) .directive( 'itemListFilter', function () { return { scope: false, restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/itemListFilter.html', require: '^itemList' }; }); },{}],11:[function(require,module,exports){ /*globals angular*/ 'use strict'; require('./itemStats.js'); require('./itemMenu.js'); require('./itemDetails.js'); require('./itemHeader.js'); angular.module( 'isis.ui.itemList.item', [ 'isis.ui.itemList.item.stats', 'isis.ui.itemList.item.menu', 'isis.ui.itemList.item.details', 'isis.ui.itemList.item.header' ] ) .directive( 'itemListItem', function () { return { restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/itemListItem.html', link: function(scope, element) { var onDragStart, onDragEnd, itemId = scope.item.id; onDragStart = function(e) { e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text', itemId); element.addClass('dragged'); if (typeof scope.config.onItemDragStart === 'function') { scope.config.onItemDragStart(e, scope.item); } }; onDragEnd = function(e) { element.removeClass('dragged'); if (typeof scope.config.onItemDragEnd === 'function') { scope.config.onItemDragEnd(e, scope.item); } }; if (typeof scope.config.onItemDragEnd === 'function' && typeof scope.config.onItemDragStart === 'function') { element[0].classList.add('draggable'); element[0].setAttribute('draggable', 'true'); element[0].addEventListener('dragstart', onDragStart); element[0].addEventListener('dragend', onDragEnd); } scope.$on('$destroy', function() { if (scope.config.itemDraggable) { element[0].removeEventListener('dragstart', onDragStart); element[0].removeEventListener('dragend', onDragEnd); } }); } }; } ); },{"./itemDetails.js":7,"./itemHeader.js":8,"./itemMenu.js":13,"./itemStats.js":14}],12:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.itemList.newItem', [] ) .directive( 'itemListNewItem', function () { return { restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/itemListNewItem.html', require: '^itemList', compile: function () { return { pre: function (scope, el, attr, itemListCtl) { if (angular.isObject(scope.config) && angular.isObject(scope.config .newItemForm)) { scope.config.newItemForm.controller = scope.config.newItemForm.controller || function () { return itemListCtl; }; scope.formConfig = scope.config.newItemForm; scope.toggleNewItemFormCollapsed = function () { scope.formConfig.expanded = !scope.formConfig.expanded; }; } } }; } }; }); },{}],13:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.itemList.item.menu', [] ) .directive( 'ilItemMenu', function () { return { restrict: 'E', replace: true, require: '^itemList', templateUrl: '/isis-ui-components/templates/itemMenu.html' }; }); },{}],14:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.itemList.item.stats', [] ) .directive( 'ilItemStats', function () { return { scope: false, restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/itemStats.html', require: '^itemList' }; }); },{}],15:[function(require,module,exports){ /*globals angular*/ 'use strict'; require('./itemListItem.js'); require('angular-ui-sortable'); angular.module( 'isis.ui.itemList.itemGroup', [ 'isis.ui.itemList.item', 'ui.sortable' ] ) .directive( 'listItemGroup', function ($compile) { return { require: '^itemList', restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/listItemGroup.html', link: function (scope, element) { var listElement = element.find('>ul'); if (scope.listData && scope.config && scope.config.sortable === true) { listElement.attr('ui-sortable', 'sortableOptions'); element.attr('ng-model', 'listData.items'); $compile(element)(scope); } } }; }); },{"./itemListItem.js":11,"angular-ui-sortable":2}],16:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.services', [] ) .service('isisTemplateService', ['$http', '$templateCache', '$q', function ($http, $templateCache, $q) { this.getTemplate = function (template, templateUrl) { var deferred, cachedTemplate; deferred = $q.defer(); if (template) { deferred.resolve(template); } else if (templateUrl) { cachedTemplate = $templateCache.get(templateUrl); if (cachedTemplate) { deferred.resolve(cachedTemplate); } else { $http({ method: 'GET', url: templateUrl, cache: true }) .then(function (result) { $templateCache.put(templateUrl, result.data); deferred.resolve(result.data); }) . catch (function (error) { deferred.reject(error); }); } } else { deferred.reject('No template or templateUrl has been specified.'); } return deferred.promise; }; } ]); },{}],17:[function(require,module,exports){ /*globals angular*/ 'use strict'; angular.module( 'isis.ui.taxonomyTerm', [] ) .controller('TaxonomyTermController', function ($scope) { $scope.getTermUrl = function () { return ($scope.term && $scope.term.url) || '#'; }; }) .directive( 'taxonomyTerm', function () { return { scope: { term: '=' }, controller: 'TaxonomyTermController', restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/taxonomyTerm.html' }; }); },{}],18:[function(require,module,exports){ /*globals angular*/ 'use strict'; require('./taxonomyTerm.js'); angular.module( 'isis.ui.taxonomyTerms', [ 'isis.ui.taxonomyTerm' ] ) .controller('TaxonomyTermsController', function () { }) .directive( 'taxonomyTerms', function () { return { scope: { terms: '=' }, controller: 'TaxonomyTermsController', restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/taxonomyTerms.html' }; }); },{"./taxonomyTerm.js":17}],19:[function(require,module,exports){ /*globals angular*/ 'use strict'; require('../contextmenu/contextmenu.js'); angular.module( 'isis.ui.treeNavigator.header', [ 'isis.ui.contextmenu' ] ) .directive( 'treeNavigatorHeader', function () { return { scope: false, require: '^treeNavigator', restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/treeNavigator.header.html' }; } ); },{"../contextmenu/contextmenu.js":3}],20:[function(require,module,exports){ /*globals angular*/ 'use strict'; require('./treeNavigator.nodeList.js'); require('./treeNavigator.header.js'); require('./treeNavigator.node.label.js'); angular.module( 'isis.ui.treeNavigator', [ 'isis.ui.treeNavigator.nodeList', 'isis.ui.treeNavigator.header', 'isis.ui.treeNavigator.node.label' ]) .directive( 'treeNavigator', function () { var defaultTreeState; defaultTreeState = { activeNode: null, selectedNodes: [], expandedNodes: [], loadingNodes: [], activeScope: null }; function removeNodeFromList(list, node) { var index; if (angular.isArray(list) && angular.isObject(node)) { index = list.indexOf(node.id); if (index > -1) { list.splice(index, 1); } } } function TreeNavigatorController($log) { var self; self = this; self.$log = $log; self.scopeMenuConfig = { triggerEvent: 'click', position: 'left bottom' }; self.preferencesMenuConfig = { triggerEvent: 'click', position: 'right bottom' }; self.config = self.config || {}; self.config.state = angular.extend(defaultTreeState, self.config.state || {}); self.config.collapsedIconClass = self.config.collapsedIconClass || 'icon-arrow-right'; self.config.expandedIconClass = self.config.expandedIconClass || 'icon-arrow-down'; self.config.extraInfoTemplateUrl = self.config.extraInfoTemplateUrl || '/isis-ui-components/templates/treeNavigator.node.extraInfo.html'; } TreeNavigatorController.prototype.isExpanded = function (node) { var self = this; return (self.config.state.expandedNodes.indexOf(node.id) > -1); }; TreeNavigatorController.prototype.isSelected = function (node) { var self = this; return (self.config.state.selectedNodes.indexOf(node.id) > -1); }; TreeNavigatorController.prototype.updateSelection = function ($event, node) { var index, self; self = this; if (node) { if ($event) { if ($event.shiftKey) { // TODO: properly update selected nodes // start node is active node // end node is theNode // select all opened tree elements between the two nodes self.config.state.selectedNodes = [node.id]; self.$log.warn('Range selection is not implemented properly yet.'); } else if ($event.ctrlKey || $event.metaKey) { index = self.config.state.selectedNodes.indexOf(node.id); if (index > -1) { // already selected, remove this node self.config.state.selectedNodes.splice(index, 1); } else { // select it self.config.state.selectedNodes.push(node.id); } } else { self.config.state.selectedNodes = [node.id]; } } else { // event is not given self.config.state.selectedNodes = [node.id]; } // active node is the clicked node self.config.state.activeNode = node.id; } else { self.config.state.selectedNodes = []; self.config.state.activeNode = null; } }; TreeNavigatorController.prototype.markNodeExpanded = function ($event, node) { var self = this; if (self.config.state.expandedNodes.indexOf(node.id) === -1) { self.config.state.expandedNodes.push(node.id); if (angular.isFunction(self.config.nodeExpanderClick)) { self.config.nodeExpanderClick($event, node, true); } } }; TreeNavigatorController.prototype.markNodeCollapsed = function ($event, node) { removeNodeFromList(this.config.state.expandedNodes, node); }; TreeNavigatorController.prototype.loadSomeChildrenForNode = function ($event, node, isBackPaging) { var self = this, count; if (!node.loading && angular.isFunction(self.config.loadChildren)) { if (self.config.pagination && self.config.pagination.itemsPerPage) { count = self.config.pagination.itemsPerPage; } node.loading = true; self.config.loadChildren($event, node, count, isBackPaging) .then(function (children) { var wasEmptyBefore, index, i; if (Array.isArray(children) && children.length) { for (i = 0; i < children.length; i++) { self.markNodeCollapsed($event, children[i]); index = self.config.state.selectedNodes.indexOf(children[i].id); if (index > -1) { self.config.state.selectedNodes.splice(index, 1); } } wasEmptyBefore = node.children.length === 0; node.children = children; if (isBackPaging === true && !wasEmptyBefore) { node.lastLoadedChildPosition = node.firstLoadedChildPosition - 1; node.firstLoadedChildPosition = node.lastLoadedChildPosition - node.children.length + 1; } else { if (wasEmptyBefore) { node.firstLoadedChildPosition = 0; node.lastLoadedChildPosition = node.children.length - 1; } else { node.firstLoadedChildPosition = node.lastLoadedChildPosition + 1; node.lastLoadedChildPosition = node.firstLoadedChildPosition + node.children.length - 1; } } } else { node.children = []; } //console.log(node.firstLoadedChildPosition, node.lastLoadedChildPosition); node.loading = false; self.markNodeExpanded($event, node); }) . catch (function (e) { node.loading = false; node.children = []; self.$log.error('Error while loading children for ', node, e); }); } }; return { scope: { treeData: '=', config: '=' }, restrict: 'E', replace: true, templateUrl: '/isis-ui-components/templates/treeNavigator.html', controller: TreeNavigatorController, controllerAs: 'ctrl', bindToController: true }; } ) // Based on: http://stackoverflow.com/questions/20444409/handling-ng-click-and-ng-dblclick-on-the-same-element-with-angularjs . directive('isisSglclick', ['$parse', '$timeout', function ($parse, $timeout) { return { restrict: 'A', link: function (scope, element, attr) { var fn = $parse(attr.isisSglclick); var delay = 300, clicks = 0, timer = null; element.on('click', function (event) { clicks++; //count clicks if (clicks === 1) { timer = $timeout(function () { fn(scope, { $event: event }); clicks = 0; //after action performed, reset counter }, delay); } else { $timeout.cancel(timer); //prevent single-click action clicks = 0; //after action performed, reset counter } }); } }; } ]) .directive('isisStopEvent', function () { return { restrict: 'A', link: function (scope, element) { element.bind('click', function (e) { e.stopPropagation(); }); } }; }); },{"./treeNavigator.header.js":19,"./treeNavigator.node.label.js":22,"./treeNavigator.nodeList.js":23}],21:[function(require,module,exports){ /*globals angular*/ 'use strict'; require('./treeNavigator.node.label.js'); angular.module( 'isis.ui.treeNavigator.node', [ 'isis.ui.treeNavigator.node.label' ] ) .directive( 'treeNavigatorNode', function() { function NodeController() { var self; self = this; self.isExpanded = function() { return (self.treeCtrl.config.state.expandedNodes.indexOf(self.node.id) > -1); }; self.isSelected = function() { return (self.treeCtrl.config.state.selectedNodes.indexOf(self.node.id) > -1); }; this.getClass = function() { var cssClassStr = ''; if (self.isExpanded()) { cssClassStr += 'expanded'; } if (self.treeCtrl.config.state.activeNode === self.node.id) { cssClassStr += ' active-node'; } if (self.isSelected()) { cssClassStr += ' selected-node'; } if (self.node.loading) { cssClassStr += ' loading'; } if (angular.isFunction(self.treeCtrl.config.nodeClassGetter)) { cssClassStr += ' ' + self.treeCtrl.config.nodeClassGetter(self.node); } return cssClassStr; }; } return { scope: { node: '=' }, controller: NodeController, controllerAs: 'ctrl', bindToC