懒羊羊
2023-08-30 71e81ed1d12e4d69f53c8ad9e066650ad4186293
提交 | 用户 | 时间
71e81e 1 /*
2  * Activiti Modeler component part of the Activiti project
3  * Copyright 2005-2014 Alfresco Software, Ltd. All rights reserved.
4
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 'use strict';
20
21 var activitiModeler = angular.module('activitiModeler', [
22   'ngCookies',
23   'ngResource',
24   'ngSanitize',
25   'ngRoute',
26   'ngDragDrop',
27   'mgcrea.ngStrap', 
28   'ngGrid',
29   'ngAnimate',
30   'pascalprecht.translate',
31   'duScroll'
32 ]);
33
34 var activitiModule = activitiModeler;
35
36 activitiModeler
37   // Initialize routes
38   .config(['$selectProvider', '$translateProvider', function ($selectProvider, $translateProvider) {
39
40       // Override caret for bs-select directive
41       angular.extend($selectProvider.defaults, {
42           caretHtml: '&nbsp;<i class="icon icon-caret-down"></i>'
43       });
44         
45         // Initialize angular-translate
46         $translateProvider.useStaticFilesLoader({
47             prefix: './editor-app/i18n/',
48             suffix: '.json'
49         });
50
51         $translateProvider.preferredLanguage('en');
52
53         // remember language
54         $translateProvider.useCookieStorage();
55         
56   }])
57   .run(['$rootScope', '$timeout', '$modal', '$translate', '$location', '$window', '$http', '$q',
58         function($rootScope, $timeout, $modal, $translate, $location, $window, $http, $q) {
59       
60               $rootScope.config = ACTIVITI.CONFIG;
61               
62               $rootScope.editorInitialized = false;
63               
64               $rootScope.editorFactory = $q.defer();
65         
66               $rootScope.forceSelectionRefresh = false;
67         
68               $rootScope.ignoreChanges = false; // by default never ignore changes
69               
70               $rootScope.validationErrors = [];
71               
72               $rootScope.staticIncludeVersion = Date.now();
73
74               /**
75                * A 'safer' apply that avoids concurrent updates (which $apply allows).
76                */
77               $rootScope.safeApply = function(fn) {
78                   var phase = this.$root.$$phase;
79                   if(phase == '$apply' || phase == '$digest') {
80                       if(fn && (typeof(fn) === 'function')) {
81                           fn();
82                       }
83                   } else {
84                       this.$apply(fn);
85                   }
86               };
87       
88       
89             /**
90              * Initialize the event bus: couple all Oryx events with a dispatch of the
91              * event of the event bus. This way, it gets much easier to attach custom logic
92              * to any event.
93              */
94
95             /* Helper method to fetch model from server (always needed) */
96             function fetchModel(modelId) {
97
98                 var modelUrl = KISBPM.URL.getModel(modelId);
99
100                 console.log(modelUrl);
101
102                 $http({method: 'GET', url: modelUrl}).
103                     success(function (data, status, headers, config) {
104                         $rootScope.editor = new ORYX.Editor(data);
105                         $rootScope.modelData = angular.fromJson(data);
106                         $rootScope.editorFactory.resolve();
107                     }).
108                     error(function (data, status, headers, config) {
109                       console.log('Error loading model with id ' + modelId + ' ' + data);
110                     });
111             }
112
113
114             function initScrollHandling() {
115                 var canvasSection = jQuery('#canvasSection');
116                 canvasSection.scroll(function() {
117
118                     // Hides the resizer and quick menu items during scrolling
119
120                     var selectedElements = $rootScope.editor.selection;
121                     var subSelectionElements = $rootScope.editor._subSelection;
122
123                     $rootScope.selectedElements = selectedElements;
124                     $rootScope.subSelectionElements = subSelectionElements;
125                     if (selectedElements && selectedElements.length > 0) {
126                         $rootScope.selectedElementBeforeScrolling = selectedElements[0];
127                     }
128
129                     jQuery('.Oryx_button').each(function(i, obj) {
130                         $rootScope.orginalOryxButtonStyle = obj.style.display;
131                         obj.style.display = 'none';
132                     });
133                     
134                     jQuery('.resizer_southeast').each(function(i, obj) {
135                         $rootScope.orginalResizerSEStyle = obj.style.display;
136                         obj.style.display = 'none';
137                     });
138                     jQuery('.resizer_northwest').each(function(i, obj) {
139                         $rootScope.orginalResizerNWStyle = obj.style.display;
140                         obj.style.display = 'none';
141                     });
142                     $rootScope.editor.handleEvents({type:ORYX.CONFIG.EVENT_CANVAS_SCROLL});
143                 });
144
145                 canvasSection.scrollStopped(function(){
146
147                     // Puts the quick menu items and resizer back when scroll is stopped.
148
149                     $rootScope.editor.setSelection([]); // needed cause it checks for element changes and does nothing if the elements are the same
150                     $rootScope.editor.setSelection($rootScope.selectedElements, $rootScope.subSelectionElements);
151                     $rootScope.selectedElements = undefined;
152                     $rootScope.subSelectionElements = undefined;
153
154                     function handleDisplayProperty(obj) {
155                         if (jQuery(obj).position().top > 0) {
156                             obj.style.display = 'block';
157                         } else {
158                             obj.style.display = 'none';
159                         }
160                     }
161
162                     jQuery('.Oryx_button').each(function(i, obj) {
163                         handleDisplayProperty(obj);
164                     });
165                     
166                     jQuery('.resizer_southeast').each(function(i, obj) {
167                         handleDisplayProperty(obj);
168                     });
169                     jQuery('.resizer_northwest').each(function(i, obj) {
170                         handleDisplayProperty(obj);
171                     });
172
173                 });
174             }
175
176             /**
177              * Initialize the Oryx Editor when the content has been loaded
178              */
179             $rootScope.$on('$includeContentLoaded', function (event) {
180                 if (!$rootScope.editorInitialized) {
181
182                     ORYX._loadPlugins();
183     
184                     var modelId = EDITOR.UTIL.getParameterByName('modelId');
185                     fetchModel(modelId);
186     
187                     $rootScope.window = {};
188                     var updateWindowSize = function() {
189                         $rootScope.window.width = $window.innerWidth;
190                         $rootScope.window.height  = $window.innerHeight;
191                     };
192     
193                     // Window resize hook
194                     angular.element($window).bind('resize', function() {
195                         $rootScope.safeApply(updateWindowSize());
196                     });
197     
198                     $rootScope.$watch('window.forceRefresh', function(newValue) {
199                         if(newValue) {
200                             $timeout(function() {
201                                 updateWindowSize();
202                                 $rootScope.window.forceRefresh = false;
203                             });
204                         }
205                     });
206     
207                     updateWindowSize();
208
209                     // Hook in resizing of main panels when window resizes
210                     // TODO: perhaps move to a separate JS-file?
211                     jQuery(window).resize(function () {
212
213                         // Calculate the offset based on the bottom of the module header
214                         var offset = jQuery("#editor-header").offset();
215                         var propSectionHeight = jQuery('#propertySection').height();
216                         var canvas = jQuery('#canvasSection');
217                         var mainHeader = jQuery('#main-header');
218
219                         if (offset == undefined || offset === null
220                             || propSectionHeight === undefined || propSectionHeight === null
221                             || canvas === undefined || canvas === null || mainHeader === null) {
222                             return;
223                         }
224                         
225                         if ($rootScope.editor)
226                         {
227                             var selectedElements = $rootScope.editor.selection;
228                             var subSelectionElements = $rootScope.editor._subSelection;
229                 
230                             $rootScope.selectedElements = selectedElements;
231                             $rootScope.subSelectionElements = subSelectionElements;
232                             if (selectedElements && selectedElements.length > 0)
233                             {
234                                 $rootScope.selectedElementBeforeScrolling = selectedElements[0];
235                                 
236                                 $rootScope.editor.setSelection([]); // needed cause it checks for element changes and does nothing if the elements are the same
237                                 $rootScope.editor.setSelection($rootScope.selectedElements, $rootScope.subSelectionElements);
238                                 $rootScope.selectedElements = undefined;
239                                 $rootScope.subSelectionElements = undefined;
240                             }
241                         }
242
243                         var totalAvailable = jQuery(window).height() - offset.top - mainHeader.height() - 21;
244                         canvas.height(totalAvailable - propSectionHeight);
245                         jQuery('#paletteSection').height(totalAvailable);
246
247                         // Update positions of the resize-markers, according to the canvas
248
249                         var actualCanvas = null;
250                         if (canvas && canvas[0].children[1]) {
251                             actualCanvas = canvas[0].children[1];
252                         }
253
254                         var canvasTop = canvas.position().top;
255                         var canvasLeft = canvas.position().left;
256                         var canvasHeight = canvas[0].clientHeight;
257                         var canvasWidth = canvas[0].clientWidth;
258                         var iconCenterOffset = 8;
259                         var widthDiff = 0;
260
261                         var actualWidth = 0;
262                         if(actualCanvas) {
263                             // In some browsers, the SVG-element clientwidth isn't available, so we revert to the parent
264                             actualWidth = actualCanvas.clientWidth || actualCanvas.parentNode.clientWidth;
265                         }
266
267
268                         if(actualWidth < canvas[0].clientWidth) {
269                             widthDiff = actualWidth - canvas[0].clientWidth;
270                             // In case the canvas is smaller than the actual viewport, the resizers should be moved
271                             canvasLeft -= widthDiff / 2;
272                             canvasWidth += widthDiff;
273                         }
274
275                         var iconWidth = 17;
276                         var iconOffset = 20;
277
278                         var north = jQuery('#canvas-grow-N');
279                         north.css('top', canvasTop + iconOffset + 'px');
280                         north.css('left', canvasLeft - 10 + (canvasWidth - iconWidth) / 2 + 'px');
281
282                         var south = jQuery('#canvas-grow-S');
283                         south.css('top', (canvasTop + canvasHeight - iconOffset - iconCenterOffset) +  'px');
284                         south.css('left', canvasLeft - 10 + (canvasWidth - iconWidth) / 2 + 'px');
285
286                         var east = jQuery('#canvas-grow-E');
287                         east.css('top', canvasTop - 10 + (canvasHeight - iconWidth) / 2 + 'px');
288                         east.css('left', (canvasLeft + canvasWidth - iconOffset - iconCenterOffset) + 'px');
289
290                         var west = jQuery('#canvas-grow-W');
291                         west.css('top', canvasTop -10 + (canvasHeight - iconWidth) / 2 + 'px');
292                         west.css('left', canvasLeft + iconOffset + 'px');
293
294                         north = jQuery('#canvas-shrink-N');
295                         north.css('top', canvasTop + iconOffset + 'px');
296                         north.css('left', canvasLeft + 10 + (canvasWidth - iconWidth) / 2 + 'px');
297
298                         south = jQuery('#canvas-shrink-S');
299                         south.css('top', (canvasTop + canvasHeight - iconOffset - iconCenterOffset) +  'px');
300                         south.css('left', canvasLeft +10 + (canvasWidth - iconWidth) / 2 + 'px');
301
302                         east = jQuery('#canvas-shrink-E');
303                         east.css('top', canvasTop + 10 + (canvasHeight - iconWidth) / 2 +  'px');
304                         east.css('left', (canvasLeft + canvasWidth - iconOffset - iconCenterOffset) + 'px');
305
306                         west = jQuery('#canvas-shrink-W');
307                         west.css('top', canvasTop + 10 + (canvasHeight - iconWidth) / 2 + 'px');
308                         west.css('left', canvasLeft + iconOffset + 'px');
309                     });
310
311                     jQuery(window).trigger('resize');
312
313                     jQuery.fn.scrollStopped = function(callback) {
314                         jQuery(this).scroll(function(){
315                             var self = this, $this = jQuery(self);
316                             if ($this.data('scrollTimeout')) {
317                                 clearTimeout($this.data('scrollTimeout'));
318                             }
319                             $this.data('scrollTimeout', setTimeout(callback,50,self));
320                         });
321                     };
322                     
323                     // Always needed, cause the DOM element on which the scroll event listeners are attached are changed for every new model
324                     initScrollHandling();
325                     
326                     $rootScope.editorInitialized = true;
327                 }
328             });
329
330             /**
331              * Initialize the event bus: couple all Oryx events with a dispatch of the
332              * event of the event bus. This way, it gets much easier to attach custom logic
333              * to any event.
334              */
335
336             $rootScope.editorFactory.promise.then(function() {
337
338                 KISBPM.eventBus.editor = $rootScope.editor;
339
340                 var eventMappings = [
341                     { oryxType : ORYX.CONFIG.EVENT_SELECTION_CHANGED, kisBpmType : KISBPM.eventBus.EVENT_TYPE_SELECTION_CHANGE },
342                     { oryxType : ORYX.CONFIG.EVENT_DBLCLICK, kisBpmType : KISBPM.eventBus.EVENT_TYPE_DOUBLE_CLICK },
343                     { oryxType : ORYX.CONFIG.EVENT_MOUSEOUT, kisBpmType : KISBPM.eventBus.EVENT_TYPE_MOUSE_OUT },
344                     { oryxType : ORYX.CONFIG.EVENT_MOUSEOVER, kisBpmType : KISBPM.eventBus.EVENT_TYPE_MOUSE_OVER }
345
346                 ];
347
348                 eventMappings.forEach(function(eventMapping) {
349                     $rootScope.editor.registerOnEvent(eventMapping.oryxType, function(event) {
350                         KISBPM.eventBus.dispatch(eventMapping.kisBpmType, event);
351                     });
352                 });
353                 
354                 $rootScope.editor.registerOnEvent(ORYX.CONFIG.EVENT_SHAPEREMOVED, function (event) {
355                     var validateButton = document.getElementById(event.shape.resourceId + "-validate-button");
356                     if (validateButton)
357                     {
358                         validateButton.style.display = 'none';
359                     }
360                 });
361
362                 // The Oryx canvas is ready (we know since we're in this promise callback) and the
363                 // event bus is ready. The editor is now ready for use
364                 KISBPM.eventBus.dispatch(KISBPM.eventBus.EVENT_TYPE_EDITOR_READY, {type : KISBPM.eventBus.EVENT_TYPE_EDITOR_READY});
365
366             });
367             
368             // Alerts
369             $rootScope.alerts = {
370                 queue: []
371             };
372           
373             $rootScope.showAlert = function(alert) {
374                 if(alert.queue.length > 0) {
375                     alert.current = alert.queue.shift();
376                     // Start timout for message-pruning
377                     alert.timeout = $timeout(function() {
378                         if (alert.queue.length == 0) {
379                             alert.current = undefined;
380                             alert.timeout = undefined;
381                         } else {
382                             $rootScope.showAlert(alert);
383                         }
384                     }, (alert.current.type == 'error' ? 5000 : 1000));
385                 } else {
386                     $rootScope.alerts.current = undefined;
387                 }
388             };
389           
390             $rootScope.addAlert = function(message, type) {
391                 var newAlert = {message: message, type: type};
392                 if (!$rootScope.alerts.timeout) {
393                     // Timeout for message queue is not running, start one
394                     $rootScope.alerts.queue.push(newAlert);
395                     $rootScope.showAlert($rootScope.alerts);
396                 } else {
397                     $rootScope.alerts.queue.push(newAlert);
398                 }
399             };
400           
401             $rootScope.dismissAlert = function() {
402                 if (!$rootScope.alerts.timeout) {
403                     $rootScope.alerts.current = undefined;
404                 } else {
405                     $timeout.cancel($rootScope.alerts.timeout);
406                     $rootScope.alerts.timeout = undefined;
407                     $rootScope.showAlert($rootScope.alerts);
408                 }
409             };
410           
411             $rootScope.addAlertPromise = function(promise, type) {
412                 if (promise) {
413                     promise.then(function(data) {
414                         $rootScope.addAlert(data, type);
415                     });
416                 }
417             };
418           
419         }
420   ])
421
422     // Moment-JS date-formatting filter
423     .filter('dateformat', function() {
424         return function(date, format) {
425             if (date) {
426                 if (format) {
427                     return moment(date).format(format);
428                 } else {
429                     return moment(date).calendar();
430                 }
431             }
432             return '';
433         };
434     });