update
This commit is contained in:
223
ebpm-process-manage/webapp/resource/js/plugins/diff/app/app.css
Normal file
223
ebpm-process-manage/webapp/resource/js/plugins/diff/app/app.css
Normal file
@@ -0,0 +1,223 @@
|
||||
.content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
position: relative;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.di-container {
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
position: relative;
|
||||
|
||||
display: table-cell;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.di-container.left {
|
||||
border-right: dotted 2px #CCC;
|
||||
}
|
||||
|
||||
.di-header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
margin: 20px;
|
||||
padding: 10px;
|
||||
|
||||
background: #EEE;
|
||||
border-radius: 5px;
|
||||
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.di-header:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.di-header h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.right .di-header {
|
||||
right: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.canvas {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.djs-shape.highlight .djs-outline {
|
||||
stroke: yellow !important;
|
||||
stroke-width: 10px;
|
||||
fill: yellow;
|
||||
}
|
||||
|
||||
.djs-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* drag and drop
|
||||
*/
|
||||
|
||||
.drop-marker {
|
||||
border: dashed 5px #CCC;
|
||||
border-radius: 20px;
|
||||
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
}
|
||||
|
||||
.di-container .drop-marker,
|
||||
.di-container.dropping :not(.drop-marker) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropping .drop-marker {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* change details
|
||||
*/
|
||||
.changeDetails table {
|
||||
border: 2px solid orange;
|
||||
width: 300px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.changeDetails th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* markers
|
||||
*/
|
||||
.marker {
|
||||
border-radius: 50%;
|
||||
background-color: gray;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 150%;
|
||||
padding-right: 6px;
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
.marker-changed {
|
||||
font-size: 130%;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
.marker-layout-changed {
|
||||
font-size: 120%;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* changes overview
|
||||
*/
|
||||
#changes-overview {
|
||||
position: absolute;
|
||||
left: 25%;
|
||||
right: 25%;
|
||||
bottom: 0;
|
||||
height: 40%;
|
||||
|
||||
color: #666;
|
||||
|
||||
padding-top: 40px;
|
||||
z-index: 110;
|
||||
}
|
||||
|
||||
#changes-overview.collapsed {
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
#changes-overview .changes {
|
||||
padding: 20px;
|
||||
border-radius: 2px 0;
|
||||
|
||||
position: relative;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#changes-overview table {
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
#changes-overview table tr {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
#changes-overview thead tr {
|
||||
border-bottom: solid 1px #999;
|
||||
}
|
||||
|
||||
#changes-overview .entry:hover {
|
||||
background-color: #EEE;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#changes-overview .status {
|
||||
font-weight: bold;
|
||||
color: #F9F9F9;
|
||||
|
||||
padding: 0 5px;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
|
||||
line-height: 20px
|
||||
}
|
||||
|
||||
#changes-overview .entry.removed .status {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
#changes-overview .entry.added .status {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
#changes-overview .entry.changed .status {
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
#changes-overview .entry.layout-changed .status {
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
#changes-overview .show-hide-toggle {
|
||||
margin: 0 0 0 auto;
|
||||
padding: 5px 10px;
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
background: #F0F0F0;
|
||||
display: inline-block;
|
||||
line-height: 30px;
|
||||
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 0;
|
||||
|
||||
border-radius: 5px 5px 0 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#changes-overview .show-hide-toggle:hover {
|
||||
background: #CCC;
|
||||
}
|
||||
425
ebpm-process-manage/webapp/resource/js/plugins/diff/app/app.js
Normal file
425
ebpm-process-manage/webapp/resource/js/plugins/diff/app/app.js
Normal file
@@ -0,0 +1,425 @@
|
||||
/**(function() {
|
||||
|
||||
'use strict';**/
|
||||
var $ = require('jquery'),
|
||||
_ = require('lodash'),
|
||||
BpmnViewer = require('bpmn-js'),
|
||||
Diffing = require('bpmn-js-diffing');
|
||||
var bpmnModeler=null;
|
||||
function createViewer(side) {
|
||||
return new BpmnViewer({
|
||||
container: '#canvas-' + side,
|
||||
height: '100%',
|
||||
width: '100%'
|
||||
});
|
||||
}
|
||||
|
||||
function syncViewers(a, b) {
|
||||
|
||||
var changing;
|
||||
|
||||
function update(viewer) {
|
||||
return function(e) {
|
||||
if (changing) {
|
||||
return;
|
||||
}
|
||||
|
||||
changing = true;
|
||||
viewer.get('canvas').viewbox(e.viewbox);
|
||||
changing = false;
|
||||
};
|
||||
}
|
||||
|
||||
function syncViewbox(a, b) {
|
||||
a.on('canvas.viewbox.changed', update(b));
|
||||
}
|
||||
|
||||
syncViewbox(a, b);
|
||||
syncViewbox(b, a);
|
||||
}
|
||||
|
||||
function createViewers(left, right) {
|
||||
|
||||
var sides = {};
|
||||
|
||||
sides[left] = createViewer(left);
|
||||
sides[right] = createViewer(right);
|
||||
|
||||
// sync navigation
|
||||
syncViewers(sides[left], sides[right]);
|
||||
|
||||
return sides;
|
||||
}
|
||||
|
||||
|
||||
var viewers = createViewers('left', 'right');
|
||||
|
||||
function getViewer(side) {
|
||||
return viewers[side];
|
||||
}
|
||||
|
||||
function isLoaded(v) {
|
||||
return v.loading !== undefined && !v.loading;
|
||||
}
|
||||
|
||||
function allDiagramsLoaded() {
|
||||
return _.every(viewers, isLoaded);
|
||||
}
|
||||
|
||||
function setLoading(viewer, loading) {
|
||||
viewer.loading = loading;
|
||||
}
|
||||
|
||||
|
||||
function clearDiffs(viewer) {
|
||||
viewer.get('overlays').remove({ type: 'diff' });
|
||||
|
||||
// TODO(nre): expose as external API
|
||||
_.forEach(viewer.get('elementRegistry')._elementMap, function(container) {
|
||||
var gfx = container.gfx;
|
||||
|
||||
gfx
|
||||
.removeClass('diff-added')
|
||||
.removeClass('diff-changed')
|
||||
.removeClass('diff-removed')
|
||||
.removeClass('diff-layout-changed');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function diagramLoading(side, viewer) {
|
||||
|
||||
setLoading(viewer, true);
|
||||
|
||||
var loaded = _.filter(viewers, isLoaded);
|
||||
|
||||
// clear diffs on loaded
|
||||
_.forEach(loaded, function(v) {
|
||||
clearDiffs(v);
|
||||
});
|
||||
}
|
||||
|
||||
function diagramLoaded(err, side, viewer) {
|
||||
if (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
|
||||
setLoading(viewer, err);
|
||||
|
||||
if (allDiagramsLoaded()) {
|
||||
|
||||
// sync viewboxes
|
||||
var other = getViewer(side == 'left' ? 'right' : 'left');
|
||||
viewer.get('canvas').viewbox(other.get('canvas').viewbox());
|
||||
|
||||
showDiff(getViewer('left'), getViewer('right'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// we use $.ajax to load the diagram.
|
||||
// make sure you run the application via web-server (ie. connect (node) or asdf (ruby))
|
||||
|
||||
function loadDiagram(side, diagram) {
|
||||
var viewer = getViewer(side);
|
||||
function done(err) {
|
||||
diagramLoaded(err, side, viewer);
|
||||
}
|
||||
diagramLoading(side, viewer);
|
||||
if (diagram.xml) {
|
||||
viewer.importXML(diagram.xml, done);
|
||||
bpmnModeler=viewer;
|
||||
return;
|
||||
}
|
||||
|
||||
$.get(diagram.url, function(xml) {
|
||||
viewer.importXML(xml, done);
|
||||
});
|
||||
}
|
||||
function showDiff(viewerOld, viewerNew) {
|
||||
var result = Diffing.diff (viewerOld.definitions, viewerNew.definitions);
|
||||
|
||||
|
||||
$.each(result._removed, function(i, obj) {
|
||||
highlight(viewerOld, i, 'diff-removed');
|
||||
addMarker(viewerOld, i, 'marker-removed', '−');
|
||||
});
|
||||
|
||||
|
||||
$.each(result._added, function(i, obj) {
|
||||
highlight(viewerNew, i, 'diff-added');
|
||||
addMarker(viewerNew, i, 'marker-added', '+');
|
||||
});
|
||||
|
||||
|
||||
$.each(result._layoutChanged, function(i, obj) {
|
||||
highlight(viewerOld, i, 'diff-layout-changed');
|
||||
addMarker(viewerOld, i, 'marker-layout-changed', '⇨');
|
||||
|
||||
highlight(viewerNew, i, 'diff-layout-changed');
|
||||
addMarker(viewerNew, i, 'marker-layout-changed', '⇨');
|
||||
});
|
||||
|
||||
|
||||
$.each(result._changed, function(i, obj) {
|
||||
|
||||
highlight(viewerOld, i, 'diff-changed');
|
||||
addMarker(viewerOld, i, 'marker-changed', '✎');
|
||||
|
||||
highlight(viewerNew, i, 'diff-changed');
|
||||
addMarker(viewerNew, i, 'marker-changed', '✎');
|
||||
|
||||
var details = '<table ><tr><th>Attribute</th><th>old</th><th>new</th></tr>';
|
||||
$.each(obj.attrs, function(attr, changes) {
|
||||
details = details + '<tr>' +
|
||||
'<td>' + attr + '</td><td>' + changes.oldValue + '</td>' +
|
||||
'<td>' + changes.newValue + '</td>' +
|
||||
'</tr>';
|
||||
});
|
||||
|
||||
details = details + '</table></div>';
|
||||
|
||||
viewerOld.get('elementRegistry').getGraphicsByElement(i).click (function (event) {
|
||||
$('#changeDetailsOld_' + i).toggle();
|
||||
});
|
||||
|
||||
var detailsOld = '<div id="changeDetailsOld_' + i + '" class="changeDetails">' + details;
|
||||
// attach an overlay to a node
|
||||
/** viewerOld.get('overlays').add(i, 'diff', {
|
||||
position: {
|
||||
bottom: -5,
|
||||
left: 0
|
||||
},
|
||||
html: detailsOld
|
||||
});**/
|
||||
|
||||
$('#changeDetailsOld_' + i).toggle();
|
||||
|
||||
viewerNew.get('elementRegistry').getGraphicsByElement(i).click (function (event) {
|
||||
$('#changeDetailsNew_' + i).toggle();
|
||||
});
|
||||
|
||||
var detailsNew = '<div id="changeDetailsNew_' + i + '" class="changeDetails">' + details;
|
||||
|
||||
// attach an overlay to a node
|
||||
/** viewerNew.get('overlays').add(i, 'diff', {
|
||||
position: {
|
||||
bottom: -5,
|
||||
left: 0
|
||||
},
|
||||
html: detailsNew
|
||||
});**/
|
||||
|
||||
$('#changeDetailsNew_' + i).toggle();
|
||||
});
|
||||
|
||||
// create Table Overview of Changes
|
||||
showChangesOverview (result, viewerOld, viewerNew);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//loadDiagram('left', { url: '../resources/pizza-collaboration/old.bpmn' });
|
||||
//loadDiagram('right', { url: '../resources/pizza-collaboration/new.bpmn' });
|
||||
|
||||
|
||||
function openDiagram(xml, side) {
|
||||
loadDiagram(side, { xml: xml });
|
||||
}
|
||||
|
||||
function openFile(file, target, done) {
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onload = function(e) {
|
||||
var xml = e.target.result;
|
||||
done(xml, target);
|
||||
};
|
||||
|
||||
reader.readAsText(file);
|
||||
}
|
||||
|
||||
|
||||
$('.drop-zone').each(function() {
|
||||
var node = this,
|
||||
element = $(node);
|
||||
|
||||
element.append('<div class="drop-marker" />');
|
||||
|
||||
function removeMarker() {
|
||||
$('.drop-zone').removeClass('dropping');
|
||||
}
|
||||
|
||||
function handleFileSelect(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
var files = e.dataTransfer.files;
|
||||
openFile(files[0], element.attr('target'), openDiagram);
|
||||
|
||||
removeMarker();
|
||||
}
|
||||
|
||||
function handleDragOver(e) {
|
||||
removeMarker();
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
element.addClass('dropping');
|
||||
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
}
|
||||
|
||||
function handleDragLeave(e) {
|
||||
removeMarker();
|
||||
}
|
||||
|
||||
node.addEventListener('dragover', handleDragOver, false);
|
||||
node.ownerDocument.body.addEventListener('dragover', handleDragLeave, false);
|
||||
|
||||
node.addEventListener('drop', handleFileSelect, false);
|
||||
});
|
||||
|
||||
$('.file').on('change', function(e) {
|
||||
openFile(e.target.files[0], $(this).attr('target'), openDiagram);
|
||||
});
|
||||
|
||||
|
||||
function addMarker(viewer, elementId, className, symbol) {
|
||||
|
||||
var overlays = viewer.get('overlays');
|
||||
|
||||
try {
|
||||
// attach an overlay to a node
|
||||
overlays.add(elementId, 'diff', {
|
||||
position: {
|
||||
top: -12,
|
||||
right: 12
|
||||
},
|
||||
html: '<span class="marker ' + className + '">' + symbol + '</span>'
|
||||
});
|
||||
} catch (e) {
|
||||
// fuck you, haha
|
||||
}
|
||||
}
|
||||
|
||||
function highlight(viewer, elementId, marker) {
|
||||
viewer.get('canvas').addMarker(elementId, marker);
|
||||
}
|
||||
|
||||
function unhighlight(viewer, elementId, marker) {
|
||||
viewer.get('canvas').removeMarker(elementId, marker);
|
||||
}
|
||||
|
||||
$('#changes-overview .show-hide-toggle').click(function () {
|
||||
$('#changes-overview').toggleClass('collapsed');
|
||||
});
|
||||
|
||||
|
||||
function showChangesOverview (result, viewerOld, viewerNew) {
|
||||
|
||||
$('#changes-overview table').remove();
|
||||
|
||||
var changesTable = $(
|
||||
'<table>' +
|
||||
'<thead><tr><th></th><th>环节名称</th><th>环节类型</th><th>比对结果</th></tr></thead>' +
|
||||
'</table>');
|
||||
|
||||
var count = 0;
|
||||
|
||||
function addRow(element, type, label) {
|
||||
var html =
|
||||
'<tr class="entry">' +
|
||||
'<td>' + (count++) + '</td><td>' + (element.name || '') + '</td>' +
|
||||
'<td>' + element.$type.replace('bpmn:', '') + '</td>' +
|
||||
'<td><span class="status">' + label + '</span></td>' +
|
||||
'</tr>';
|
||||
|
||||
var row = $(html).data({
|
||||
changed: type,
|
||||
element: element.id
|
||||
}).addClass(type).appendTo(changesTable);
|
||||
}
|
||||
|
||||
$.each(result._removed, function(i, obj) {
|
||||
addRow(obj, 'removed', '刪除');
|
||||
});
|
||||
|
||||
$.each(result._added, function(i, obj) {
|
||||
addRow(obj, 'added', '新增');
|
||||
});
|
||||
|
||||
$.each(result._changed, function(i, obj) {
|
||||
addRow(obj.model, 'changed', '修改');
|
||||
});
|
||||
|
||||
$.each(result._layoutChanged, function(i, obj) {
|
||||
addRow(obj, 'layout-changed', '布局调整');
|
||||
});
|
||||
|
||||
changesTable.appendTo('#changes-overview .changes');
|
||||
|
||||
|
||||
var HIGHLIGHT_CLS = 'highlight';
|
||||
|
||||
$('#changes-overview tr.entry').each(function() {
|
||||
|
||||
var row = $(this);
|
||||
|
||||
var id = row.data('element');
|
||||
var changed = row.data('changed');
|
||||
|
||||
row.hover(function() {
|
||||
|
||||
if (changed == 'removed') {
|
||||
highlight(viewerOld, id, HIGHLIGHT_CLS);
|
||||
} else if (changed == 'added') {
|
||||
highlight(viewerNew, id, HIGHLIGHT_CLS);
|
||||
} else {
|
||||
highlight(viewerOld, id, HIGHLIGHT_CLS);
|
||||
highlight(viewerNew, id, HIGHLIGHT_CLS);
|
||||
}
|
||||
}, function() {
|
||||
|
||||
if (changed == 'removed') {
|
||||
unhighlight(viewerOld, id, HIGHLIGHT_CLS);
|
||||
} else if (changed == 'added') {
|
||||
unhighlight(viewerNew, id, HIGHLIGHT_CLS);
|
||||
} else {
|
||||
unhighlight(viewerOld, id, HIGHLIGHT_CLS);
|
||||
unhighlight(viewerNew, id, HIGHLIGHT_CLS);
|
||||
}
|
||||
});
|
||||
|
||||
row.click(function() {
|
||||
|
||||
var containerWidth = $('.di-container').width();
|
||||
var containerHeight = $('.di-container').height();
|
||||
|
||||
var viewer = (changed == 'removed' ? viewerOld : viewerNew);
|
||||
|
||||
var element = viewer.get('elementRegistry').getById(id);
|
||||
|
||||
var x, y;
|
||||
|
||||
if (element.waypoints) {
|
||||
x = element.waypoints[0].x;
|
||||
y = element.waypoints[0].y;
|
||||
} else {
|
||||
x = element.x + element.width / 2;
|
||||
y = element.y + element.height / 2;
|
||||
}
|
||||
console.log(222);
|
||||
viewer.get('canvas').viewbox({
|
||||
x: x - (containerWidth / 2),
|
||||
y: y - ((containerHeight / 2) - 100),
|
||||
width: containerWidth,
|
||||
height: containerHeight
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**})();**/
|
||||
41192
ebpm-process-manage/webapp/resource/js/plugins/diff/app/bpmn-viewer.js
Normal file
41192
ebpm-process-manage/webapp/resource/js/plugins/diff/app/bpmn-viewer.js
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
var BpmnJS = require('bpmn-js/lib/Viewer');
|
||||
|
||||
BpmnJS.prototype._modules = BpmnJS.prototype._modules.concat([
|
||||
require('bpmn-js/lib/features/movecanvas'),
|
||||
require('bpmn-js/lib/features/zoomscroll')
|
||||
]);
|
||||
|
||||
module.exports = BpmnJS;
|
||||
@@ -0,0 +1,313 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
|
||||
font-size: 12px;
|
||||
color: #444;
|
||||
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
/** widgets **/
|
||||
|
||||
.bjs-powered-by,
|
||||
.io-control {
|
||||
background: #FFF;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 2px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.bjs-powered-by {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.io-control-list {
|
||||
list-style: none;
|
||||
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button.inactive,
|
||||
a.inactive {
|
||||
color: #E0E0E0;
|
||||
color: rgba(10, 10, 10, 0.4) !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.close {
|
||||
font-size: 21px;
|
||||
font-weight: 700;
|
||||
text-shadow: 0 1px 0 #FFF;
|
||||
opacity: .2;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
a:link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
button,
|
||||
a,
|
||||
a:visited {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
button:hover,
|
||||
a:hover {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.vr {
|
||||
display: inline-block;
|
||||
height: 26px;
|
||||
border-right: solid 1px #999;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.io-control-list a,
|
||||
.io-control-list button {
|
||||
padding: 0;
|
||||
outline: none;
|
||||
|
||||
cursor: pointer;
|
||||
font-size: 22px;
|
||||
line-height: 26px;
|
||||
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.io-control-list.io-horizontal,
|
||||
.io-control-list.io-horizontal li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.io-control-list.io-horizontal a,
|
||||
.io-control-list.io-horizontal button {
|
||||
padding: 2px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.io-control hr {
|
||||
border: none;
|
||||
border-top: solid 1px #EEE;
|
||||
}
|
||||
|
||||
|
||||
/** dialogs */
|
||||
|
||||
.io-dialog {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.io-dialog.open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.io-dialog.open:before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
|
||||
background: #666;
|
||||
opacity: 0.2;
|
||||
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.io-dialog .content {
|
||||
position: fixed;
|
||||
|
||||
background: white;
|
||||
padding: 10px 30px 20px 30px;
|
||||
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 2px;
|
||||
|
||||
height: auto;
|
||||
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.io-dialog .project-logo {
|
||||
position: absolute;
|
||||
bottom: 27px;
|
||||
right: 27px;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
@media (max-width: 599px) {
|
||||
.io-dialog .content {
|
||||
left: 20px;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 600px) {
|
||||
|
||||
.io-dialog .content {
|
||||
width: 600px;
|
||||
left: 50%;
|
||||
margin-left: -300px;
|
||||
top: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
/** fonts **/
|
||||
|
||||
@font-face {
|
||||
font-family: 'bpmnio';
|
||||
src: url('../font/bpmnio.eot?2633928');
|
||||
src: url('../font/bpmnio.eot?2633928#iefix') format('embedded-opentype'),
|
||||
url('../font/bpmnio.woff?2633928') format('woff'),
|
||||
url('../font/bpmnio.ttf?2633928') format('truetype'),
|
||||
url('../font/bpmnio.svg?2633928#bpmnio') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
[class^="icon-"]:before,
|
||||
[class*=" icon-"]:before {
|
||||
font-family: "bpmnio";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: none;
|
||||
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
width: 1em;
|
||||
text-align: center;
|
||||
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.icon-plus:before { content: '\e800'; }
|
||||
.icon-loading:before { content: '\e801'; }
|
||||
.icon-minus:before { content: '\e802'; }
|
||||
.icon-open:before { content: '\e803'; }
|
||||
.icon-picture:before { content: '\e804'; }
|
||||
.icon-download:before { content: '\e805'; }
|
||||
.icon-size-reset:before { content: '\e806'; }
|
||||
.icon-bpmn-io:before { content: '\e807'; }
|
||||
.icon-info:before { content: '\e808'; }
|
||||
.icon-comment:before { content: '\e809'; }
|
||||
.icon-undo:before { content: '\e80a'; }
|
||||
.icon-redo:before { content: '\e80b'; }
|
||||
.icon-plus-circled:before { content: '\e80c'; }
|
||||
|
||||
/** animate spinner **/
|
||||
|
||||
.animate-spin {
|
||||
-moz-animation: spin 2s infinite linear;
|
||||
-o-animation: spin 2s infinite linear;
|
||||
-webkit-animation: spin 2s infinite linear;
|
||||
animation: spin 2s infinite linear;
|
||||
display: inline-block;
|
||||
}
|
||||
@-moz-keyframes spin {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-moz-transform: rotate(359deg);
|
||||
-o-transform: rotate(359deg);
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spin {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-moz-transform: rotate(359deg);
|
||||
-o-transform: rotate(359deg);
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@-o-keyframes spin {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-moz-transform: rotate(359deg);
|
||||
-o-transform: rotate(359deg);
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@-ms-keyframes spin {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-moz-transform: rotate(359deg);
|
||||
-o-transform: rotate(359deg);
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@keyframes spin {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-moz-transform: rotate(359deg);
|
||||
-o-transform: rotate(359deg);
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"removed": [
|
||||
"_6-74",
|
||||
"_6-674",
|
||||
"_6-125",
|
||||
"_6-178",
|
||||
"_6-746",
|
||||
"_6-691",
|
||||
"_6-748"
|
||||
],
|
||||
"added": [
|
||||
"ExclusiveGateway_1",
|
||||
"ManualTask_1"
|
||||
],
|
||||
"moved": [
|
||||
"_6-61"
|
||||
],
|
||||
"edited": {
|
||||
"_6-127": {
|
||||
"Name": {
|
||||
"old": "Order a pizza",
|
||||
"new": "Order Pasta!"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
.diff-removed:not(.djs-connection) .djs-visual > :nth-child(1) {
|
||||
fill: #E56283 /* light-red */ !important;
|
||||
}
|
||||
|
||||
.diff-removed.djs-connection .djs-visual > :nth-child(1) {
|
||||
stroke: #BB163F /* red */ !important;
|
||||
}
|
||||
|
||||
.marker.marker-removed {
|
||||
background: #BB163F /* red */;
|
||||
}
|
||||
|
||||
|
||||
.diff-added:not(.djs-connection) .djs-visual > :nth-child(1) {
|
||||
fill: #90DD5F /* light-green */!important;
|
||||
}
|
||||
|
||||
.diff-added.djs-connection .djs-visual > :nth-child(1) {
|
||||
stroke: #54B415 /* green */ !important;
|
||||
}
|
||||
|
||||
.marker.marker-added {
|
||||
background: #54B415 /* green */;
|
||||
}
|
||||
|
||||
|
||||
.diff-layout-changed:not(.djs-connection) .djs-visual > :nth-child(1) {
|
||||
fill: #4D79A3 /* light-blue */ !important;
|
||||
}
|
||||
|
||||
.diff-layout-changed.djs-connection .djs-visual > :nth-child(1) {
|
||||
stroke: #185085 /* blue */ !important;
|
||||
}
|
||||
|
||||
.marker.marker-layout-changed {
|
||||
background: #185085 /* blue */;
|
||||
}
|
||||
|
||||
|
||||
.diff-changed:not(.djs-connection) .djs-visual > :nth-child(1) {
|
||||
fill: #FBC16C /* light-yellow */ !important;
|
||||
}
|
||||
|
||||
.diff-changed.djs-connection .djs-visual > :nth-child(1) {
|
||||
stroke: #CD8318 /* yellow */ !important;
|
||||
}
|
||||
|
||||
.marker.marker-changed {
|
||||
background: #CD8318 /* yellow */;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
function isTracked(element) {
|
||||
return element.$instanceOf('bpmn:FlowElement') ||
|
||||
element.$instanceOf('bpmn:MessageFlow') ||
|
||||
element.$instanceOf('bpmn:Participant') ||
|
||||
element.$instanceOf('bpmn:Lane');
|
||||
}
|
||||
|
||||
function ChangeHandler() {
|
||||
this._layoutChanged = {};
|
||||
this._changed = {};
|
||||
this._removed = {};
|
||||
this._added = {};
|
||||
}
|
||||
|
||||
module.exports = ChangeHandler;
|
||||
|
||||
|
||||
ChangeHandler.prototype.removed = function(model, property, element, idx) {
|
||||
if (isTracked(element)) {
|
||||
this._removed[element.id] = element;
|
||||
}
|
||||
};
|
||||
|
||||
ChangeHandler.prototype.changed = function(model, property, newValue, oldValue) {
|
||||
|
||||
if (model.$instanceOf('bpmndi:BPMNEdge') || model.$instanceOf('bpmndi:BPMNShape')) {
|
||||
this._layoutChanged[model.bpmnElement.id] = model.bpmnElement;
|
||||
}
|
||||
|
||||
if (isTracked(model)) {
|
||||
var changed = this._changed[model.id];
|
||||
|
||||
if (!changed) {
|
||||
changed = this._changed[model.id] = { model: model, attrs: { } };
|
||||
}
|
||||
|
||||
if (oldValue !== undefined || newValue !== undefined) {
|
||||
changed.attrs[property] = { oldValue: oldValue, newValue: newValue };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ChangeHandler.prototype.added = function(model, property, element, idx) {
|
||||
if (isTracked(element)) {
|
||||
this._added[element.id] = element;
|
||||
}
|
||||
};
|
||||
|
||||
ChangeHandler.prototype.moved = function(model, property, oldIndex, newIndex) { };
|
||||
@@ -0,0 +1,82 @@
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
|
||||
var jsondiffpatch = require('jsondiffpatch');
|
||||
|
||||
|
||||
var ChangeHandler = require('./change-handler');
|
||||
|
||||
|
||||
function Differ() { }
|
||||
|
||||
module.exports = Differ;
|
||||
|
||||
|
||||
Differ.prototype.createDiff = function(a, b) {
|
||||
|
||||
// create a configured instance, match objects by name
|
||||
var diffpatcher = jsondiffpatch.create({
|
||||
objectHash: function(obj) {
|
||||
return obj.id || JSON.stringify(obj);
|
||||
}
|
||||
});
|
||||
|
||||
return diffpatcher.diff(a, b);
|
||||
};
|
||||
|
||||
|
||||
Differ.prototype.diff = function(a, b, handler) {
|
||||
|
||||
handler = handler || new ChangeHandler();
|
||||
|
||||
function walk(diff, model) {
|
||||
|
||||
_.forEach(diff, function(d, key) {
|
||||
|
||||
// is array
|
||||
if (d._t === 'a') {
|
||||
|
||||
_.forEach(d, function(val, idx) {
|
||||
|
||||
if (idx === '_t') {
|
||||
return;
|
||||
}
|
||||
|
||||
var removed = /^_/.test(idx),
|
||||
added = !removed && _.isArray(val),
|
||||
moved = removed && val[0] === '';
|
||||
|
||||
idx = parseInt(removed ? idx.slice(1) : idx, 10);
|
||||
|
||||
if (added || (removed && !moved)) {
|
||||
handler[removed ? 'removed' : 'added'](model, key, val[0], idx);
|
||||
} else
|
||||
if (moved) {
|
||||
handler.moved(model, key, val[1], val[2]);
|
||||
} else {
|
||||
walk(val, model[key][idx]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (_.isArray(d)) {
|
||||
handler.changed(model, key, d[0], d[1]);
|
||||
} else {
|
||||
handler.changed(model, key);
|
||||
walk(d, model[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var diff = this.createDiff(a, b);
|
||||
|
||||
walk(diff, b, handler);
|
||||
|
||||
return handler;
|
||||
};
|
||||
|
||||
|
||||
module.exports.diff = function(a, b, handler) {
|
||||
return new Differ().diff(a, b, handler);
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "bpmn-js-diffing",
|
||||
"version": "0.0.0",
|
||||
"description": "Visual diffing of BPMN 2.0 diagrams",
|
||||
"main": "app/app.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bpmn-io/bpmn-js-diffing"
|
||||
},
|
||||
"keywords": [
|
||||
"bpmnjs"
|
||||
],
|
||||
"author": {
|
||||
"name": "Nico Rehwaldt",
|
||||
"url": "https://github.com/Nikku"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "bpmn.io contributors",
|
||||
"url": "https://github.com/bpmn-io"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"browser": {
|
||||
"fs": false
|
||||
},
|
||||
"devDependencies": {
|
||||
"brfs": "^1.2.0",
|
||||
"grunt": "~0.4.4",
|
||||
"grunt-contrib-watch": "~0.5.0",
|
||||
"grunt-contrib-connect": "~0.6.0",
|
||||
"grunt-contrib-jshint": "~0.7.2",
|
||||
"grunt-contrib-copy": "~0.5.0",
|
||||
"grunt-browserify": "^2.1.4",
|
||||
"karma": "^0.12.21",
|
||||
"karma-chrome-launcher": "~0.1.2",
|
||||
"karma-phantomjs-launcher": "0.1.2",
|
||||
"karma-ie-launcher": "~0.1.4",
|
||||
"karma-firefox-launcher": "~0.1.3",
|
||||
"karma-bro": "~0.6.0",
|
||||
"mocha": "^1.21.4",
|
||||
"karma-mocha": "^0.1.7",
|
||||
"chai": "^1.9.1",
|
||||
"karma-chai": "^0.1.0",
|
||||
"bpmn-js": "^0.4.0",
|
||||
"jsondiffpatch": "^0.1.8",
|
||||
"load-grunt-tasks": "~0.3.0",
|
||||
"grunt-karma": "^0.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"bpmn-moddle": "^0.3.0",
|
||||
"bpmn-js": "^0.4.1",
|
||||
"jquery": "^2.1.0",
|
||||
"lodash": "^2.4.0",
|
||||
"grunt-jsdoc": "^0.5.6"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"diagrams":{
|
||||
"0":{
|
||||
"plane":{
|
||||
"planeElement":{
|
||||
"10":{
|
||||
"label":[
|
||||
{
|
||||
"$type":"bpmndi:BPMNLabel",
|
||||
"bounds":{
|
||||
"$type":"dc:Bounds",
|
||||
"height":6,
|
||||
"width":6,
|
||||
"x":645,
|
||||
"y":304
|
||||
}
|
||||
}
|
||||
],
|
||||
"waypoint":{
|
||||
"0":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":623,
|
||||
"y":304
|
||||
}
|
||||
],
|
||||
"1":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":698,
|
||||
"y":304
|
||||
}
|
||||
],
|
||||
"2":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":698,
|
||||
"y":112
|
||||
}
|
||||
],
|
||||
"_0":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":623,
|
||||
"y":87
|
||||
},
|
||||
0,
|
||||
0
|
||||
],
|
||||
"_1":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":673,
|
||||
"y":87
|
||||
},
|
||||
0,
|
||||
0
|
||||
],
|
||||
"_t":"a"
|
||||
}
|
||||
},
|
||||
"7":{
|
||||
"bounds":{
|
||||
"y":[
|
||||
47,
|
||||
264
|
||||
]
|
||||
}
|
||||
},
|
||||
"8":{
|
||||
"label":[
|
||||
{
|
||||
"$type":"bpmndi:BPMNLabel",
|
||||
"bounds":{
|
||||
"$type":"dc:Bounds",
|
||||
"height":6,
|
||||
"width":6,
|
||||
"x":445,
|
||||
"y":137
|
||||
}
|
||||
}
|
||||
],
|
||||
"waypoint":{
|
||||
"0":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":448,
|
||||
"y":112
|
||||
}
|
||||
],
|
||||
"1":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":448,
|
||||
"y":304
|
||||
}
|
||||
],
|
||||
"2":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":523,
|
||||
"y":304
|
||||
}
|
||||
],
|
||||
"_0":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":473,
|
||||
"y":87
|
||||
},
|
||||
0,
|
||||
0
|
||||
],
|
||||
"_1":[
|
||||
{
|
||||
"$type":"dc:Point",
|
||||
"x":523,
|
||||
"y":87
|
||||
},
|
||||
0,
|
||||
0
|
||||
],
|
||||
"_t":"a"
|
||||
}
|
||||
},
|
||||
"_t":"a"
|
||||
}
|
||||
}
|
||||
},
|
||||
"_t":"a"
|
||||
},
|
||||
"rootElements":{
|
||||
"0":{
|
||||
"flowElements":{
|
||||
"3":{
|
||||
"name":[
|
||||
"Service 2",
|
||||
"RANDOM SERVICE"
|
||||
]
|
||||
},
|
||||
"_10":[
|
||||
"",
|
||||
15,
|
||||
3
|
||||
],
|
||||
"_7":[
|
||||
"",
|
||||
14,
|
||||
3
|
||||
],
|
||||
"_t":"a"
|
||||
}
|
||||
},
|
||||
"_t":"a"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user