Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

diagram-js

Package Overview
Dependencies
Maintainers
2
Versions
287
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

diagram-js - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

index.js

106

Gruntfile.js

@@ -62,14 +62,23 @@ module.exports = function(grunt) {

browserify: {
vendor: {
src: [ 'snapsvg', 'lodash' ],
dest: '<%= config.dist %>/common.js',
browserifyOptions: {
builtins: false
},
bundleOptions: {
detectGlobals: false,
insertGlobalVars: []
},
bower: {
files: {
'../bower-diagram-js/diagram.js': [ '<%= config.sources %>/**/*.js' ]
},
options: {
debug: true,
transform: [
[ 'exposify', { expose: { snapsvg: 'Snap', 'lodash': '_' } } ]
],
alias: [
'snapsvg',
'lodash'
'<%= config.sources %>/Diagram.js:diagram-js'
]
}
},
src: {
standalone: {
files: {

@@ -80,5 +89,4 @@ '<%= config.dist %>/diagram.js': [ '<%= config.sources %>/**/*.js' ]

debug: true,
external: [ 'snapsvg', 'lodash' ],
alias: [
'<%= config.sources %>/Diagram.js:diagram'
'<%= config.sources %>/Diagram.js:diagram-js'
]

@@ -88,59 +96,2 @@ }

},
copy: {
samples: {
files: [
// copy sample files
{
expand: true,
cwd: '<%= config.samples %>/',
src: ['**/*.*'],
dest: '<%= config.dist %>/<%= config.samples %>'
}
]
},
fonts: {
files: [
{
expand: true,
cwd: '<%= config.fonts %>/',
src: ['fonts/*.woff'],
dest: '<%= config.dist %>'
}
]
}
},
watch: {
sources: {
files: [ '<%= config.sources %>/**/*.js' ],
tasks: [ 'concurrent:sources']
},
samples: {
files: [ '<%= config.samples %>/*.{html,css,js}' ],
tasks: [ 'copy:samples']
},
livereload: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= config.dist %>/*.js',
'<%= config.dist %>/<%= config.samples %>/*.{html,css,js}'
]
}
},
connect: {
options: {
port: 9003,
livereload: 35726,
hostname: 'localhost'
},
livereload: {
options: {
open: true,
base: [
'<%= config.dist %>'
]
}
}
},
jsdoc: {

@@ -154,6 +105,2 @@ dist: {

}
},
concurrent: {
'sources': [ 'browserify:src', 'jshint' ],
'build': [ 'jshint', 'build', 'jsdoc' ]
}

@@ -163,15 +110,18 @@ });

// tasks
grunt.registerTask('test', [ 'karma:single' ]);
grunt.registerTask('build', [ 'browserify', 'copy' ]);
grunt.registerTask('build', function(target) {
var tasks = [ 'browserify:standalone' ];
if (target === 'all') {
tasks.push('browserify:bower');
}
return grunt.task.run(tasks);
});
grunt.registerTask('auto-test', [ 'karma:unit' ]);
grunt.registerTask('auto-build', [
'concurrent:build',
'connect:livereload',
'watch'
]);
grunt.registerTask('default', [ 'jshint', 'test', 'build', 'jsdoc' ]);
};
'use strict';
var diagramModule = require('../di').defaultModule;
var AddShapeHandlerHandler = require('../commands/AddShapeHandler');
var _ = require('lodash');
var AddShapeHandler = require('./cmd/AddShapeHandler'),
AddConnectionHandler = require('./cmd/AddConnectionHandler');
// required components
require('./EventBus');
require('./CommandStack');
require('./GraphicsFactory');
require('./ElementRegistry');

@@ -23,3 +17,3 @@ /**

* the given configuration
*
* @param {Object} options

@@ -95,3 +89,3 @@ * @return {DOMElement} the container element

if (elementRegistry.getShapeById(element.id)) {
if (elementRegistry.getById(element.id)) {
throw new Error('element with id ' + element.id + ' already exists');

@@ -101,2 +95,11 @@ }

// register shape add handlers
commandStack.registerHandler('shape.add', AddShapeHandler);
// register connection add handlers
commandStack.registerHandler('connection.add', AddConnectionHandler);
/**

@@ -128,9 +131,7 @@ * Adds a shape to the canvas

/* jshint -W040 */
return this;
}
// register shape add handlers
commandStack.registerHandler('shape.add', AddShapeHandlerHandler);
/**

@@ -149,4 +150,2 @@ * Adds a connection to the canvas

var gfx = graphicsFactory.createConnection(paper, connection);
/**

@@ -162,5 +161,6 @@ * An event indicating that a new connection has been added to the canvas.

*/
events.fire('connection.added', { element: connection, gfx: gfx });
// for chaining of API calls
commandStack.execute('connection.add', { connection: connection });
/* jshint -W040 */
return this;

@@ -210,3 +210,3 @@ }

function getGraphics(element) {
return elementRegistry.getGraphicsByShape(element);
return elementRegistry.getGraphicsByElement(element);
}

@@ -430,2 +430,27 @@

// redraw shapes / connections on change
var self = this;
events.on('element.changed', function(event) {
if (event.element.waypoints) {
events.fire('connection.changed', event);
} else {
events.fire('shape.changed', event);
}
});
events.on('shape.changed', function(event) {
var element = event.element;
graphicsFactory.updateShape(element, event.gfx || self.getGraphics(element));
});
events.on('connection.changed', function(event) {
var element = event.element;
graphicsFactory.updateConnection(element, event.gfx || self.getGraphics(element));
});
this.zoom = zoom;

@@ -445,4 +470,41 @@ this.scroll = scroll;

diagramModule.type('canvas', [ 'config', 'eventBus', 'commandStack', 'graphicsFactory', 'elementRegistry', Canvas ]);
/**
* Return the absolute bounding box for the given element
*
* The absolute bounding box may be used to display overlays in the
* callers (browser) coordinate system rather than the zoomed in/out
* canvas coordinates.
*
* @param {ElementDescriptor} element
* @return {Bounds} the absolute bounding box
*/
Canvas.prototype.getAbsoluteBBox = function(element) {
var vbox = this.viewbox();
var gfx = this.getGraphics(element);
var transformBBox = gfx.getBBox(true);
var bbox = gfx.getBBox();
var x = (bbox.x - transformBBox.x) * vbox.scale - vbox.x * vbox.scale;
var y = (bbox.y - transformBBox.y) * vbox.scale - vbox.y * vbox.scale;
var width = (bbox.width + 2 * transformBBox.x) * vbox.scale;
var height = (bbox.height + 2 * transformBBox.y) * vbox.scale;
return {
x: x,
y: y,
width: width,
height: height
};
};
Canvas.$inject = [
'config',
'eventBus',
'commandStack',
'graphicsFactory',
'elementRegistry' ];
module.exports = Canvas;

@@ -1,2 +0,2 @@

var diagramModule = require('../di').defaultModule;
'use strict';

@@ -6,4 +6,2 @@ var _ = require('lodash');

require('./EventBus');
/**

@@ -24,3 +22,2 @@ * @namespace djs

function CommandStack(injector, events) {
'use strict';

@@ -32,3 +29,3 @@ /**

var handlerMap = {};
/**

@@ -84,3 +81,3 @@ * The stack containing all re/undoable actions on the diagram

events.fire('commandStack.execute', { id: id });
var handlers = getHandlers(id);

@@ -164,3 +161,3 @@

}
handlers.push(handler);

@@ -180,2 +177,4 @@ }

stackIdx = -1;
events.fire('commandStack.changed');
}

@@ -185,3 +184,3 @@

////// registration ////////////////////////////////////////
function assertValidId(id) {

@@ -207,17 +206,15 @@ if (!id) {

return {
execute: execute,
undo: undo,
redo: redo,
clear: clear,
getStack: getStack,
getStackIndex: getStackIndex,
getHandlers: getHandlers,
registerHandler: registerHandler,
register: register
};
this.execute = execute;
this.undo = undo;
this.redo = redo;
this.clear = clear;
this.getStack = getStack;
this.getStackIndex = getStackIndex;
this.getHandlers = getHandlers;
this.registerHandler = registerHandler;
this.register = register;
}
diagramModule.type('commandStack', [ 'injector', 'eventBus', CommandStack ]);
CommandStack.$inject = [ 'injector', 'eventBus' ];
module.exports = CommandStack;

@@ -1,17 +0,15 @@

var diagramModule = require('../di').defaultModule;
'use strict';
var _ = require('lodash');
// required components
require('./EventBus');
/**
* @class
*
*
* A registry that keeps track of all shapes in the diagram.
*
* @param {EventBus} events the event bus
*
* @param {EventBus} eventBus the event bus
*/
function ElementRegistry(events) {
function ElementRegistry(eventBus) {
// mapping shape.id -> container

@@ -44,5 +42,5 @@ var shapeMap = {};

function removeShape(shape) {
var gfx = getGraphicsByShape(shape);
var gfx = getGraphicsByElement(shape);
if(shape.parent) {
if (shape.parent) {
for(var i = 0; i < shape.parent.children.length;i++) {

@@ -60,5 +58,5 @@ if(shape.parent.children[i].id === shape.id) {

/**
* @method ElementRegistry#getShapeByGraphics
* @method ElementRegistry#getByGraphics
*/
function getShapeByGraphics(gfx) {
function getByGraphics(gfx) {
var id = _.isString(gfx) ? gfx : gfx.id;

@@ -73,5 +71,5 @@

/**
* @method ElementRegistry#getShapeById
* @method ElementRegistry#getById
*/
function getShapeById(id) {
function getById(id) {
var container = shapeMap[id];

@@ -84,5 +82,5 @@ if (container) {

/**
* @method ElementRegistry#getGraphicsByShape
* @method ElementRegistry#getGraphicsByElement
*/
function getGraphicsByShape(shape) {
function getGraphicsByElement(shape) {
var id = _.isString(shape) ? shape : shape.id;

@@ -96,15 +94,15 @@

events.on('shape.added', function(event) {
eventBus.on('shape.added', function(event) {
addShape(event.element, event.gfx);
});
events.on('connection.added', function(event) {
eventBus.on('connection.added', function(event) {
addShape(event.element, event.gfx);
});
events.on('shape.removed', function(event) {
eventBus.on('shape.removed', function(event) {
removeShape(event.element);
});
events.on('connection.removed', function(event) {
eventBus.on('connection.removed', function(event) {
removeShape(event.element);

@@ -114,10 +112,10 @@ });

return {
getGraphicsByShape: getGraphicsByShape,
getShapeById: getShapeById,
getShapeByGraphics: getShapeByGraphics
getGraphicsByElement: getGraphicsByElement,
getById: getById,
getByGraphics: getByGraphics
};
}
diagramModule.type('elementRegistry', [ 'eventBus', ElementRegistry ]);
ElementRegistry.$inject = [ 'eventBus' ];
module.exports = ElementRegistry;

@@ -1,2 +0,2 @@

var diagramModule = require('../di').defaultModule;
'use strict';

@@ -17,8 +17,6 @@ var _ = require('lodash');

* @class
*
*
* A general purpose event bus
*/
function EventBus() {
'use strict';
var listenerMap = {};

@@ -37,3 +35,3 @@

function extendEvent(event, type) {
var propagationStopped,

@@ -71,3 +69,3 @@ defaultPrevented;

* @method Events#on
*
*
* @param {String} event

@@ -93,3 +91,3 @@ * @param {Function} callback

* Register an event listener that is executed only once.
*
*
* @method Events#once

@@ -104,2 +102,4 @@ *

/* jshint -W040 */
var self = this;

@@ -117,7 +117,7 @@ var wrappedCallback = function() {

* Removes event listeners by event and callback.
*
*
* If no callback is given, all listeners for a given event name are being removed.
*
* @method Events#off
*
*
* @param {String} event

@@ -147,3 +147,3 @@ * @param {Function} [callback]

* Fires a named event.
*
*
* @method Events#fire

@@ -170,3 +170,3 @@ *

* events.fire({ type: 'foo' }, 'I am bar!');
*
*
* @param {String} [name] the optional event name

@@ -177,2 +177,5 @@ * @param {Object} [event] the event object

function fire() {
/* jshint -W040 */
var event, eventType,

@@ -237,4 +240,3 @@ listeners, i, l,

diagramModule.type('eventBus', EventBus);
module.exports = EventBus;

@@ -1,69 +0,105 @@

var diagramModule = require('../di').defaultModule;
'use strict';
// required components
require('./EventBus');
/**
* Creates a gfx container for shapes and connections
*
* The layout is as follows:
*
* <g data-element-id="element-1" class="djs-group djs-(type=shape|connection)">
* <g class="djs-visual">
* <!-- the renderer draws in here -->
* </g>
*
* <!-- extensions (overlays, click box, ...) goes here
* </g>
*
* @param {Object} root
* @param {String} type the type of the element, i.e. shape | connection
*/
function createContainer(root, type) {
var gfxContainer = root.group();
require('../draw/Snap');
require('../draw/Renderer');
gfxContainer
.addClass('djs-group')
.addClass('djs-' + type);
var gfxGroup = gfxContainer.group().addClass('djs-visual');
return gfxContainer;
}
/**
* Clears the graphical representation of the element and returns the
* cleared result (the <g class="djs-visual" /> element).
*/
function clearVisual(gfx) {
var oldVisual = gfx.select('.djs-visual');
var newVisual = gfx.group().addClass('djs-visual').before(oldVisual);
oldVisual.remove();
return newVisual;
}
function createContainerFactory(type) {
return function(root, data) {
return createContainer(root, type).attr('data-element-id', data.id);
};
}
/**
* A factory that creates graphical elements
*
* @param {EventBus} events
* @param {Renderer} renderer
* @param {Snap} snap
*/
function GraphicsFactory(events, renderer, snap) {
function GraphicsFactory(renderer, snap) {
this._renderer = renderer;
this._snap = snap;
}
function createParent(paper, type) {
GraphicsFactory.prototype.createShape = createContainerFactory('shape');
return paper
.group()
.addClass('djs-group')
.addClass('djs-' + type);
}
GraphicsFactory.prototype.createConnection = createContainerFactory('connection');
function createShape(paper, data) {
GraphicsFactory.prototype.createPaper = function(options) {
return this._snap.createSnapAt(options.width, options.height, options.container);
};
var parent = createParent(paper, 'shape');
var gfx = renderer.drawShape(parent, data);
gfx.addClass('djs-visual');
GraphicsFactory.prototype.updateShape = function(element, gfx) {
setPosition(parent, data.x, data.y);
// clear visual
var gfxGroup = clearVisual(gfx);
if (data.hidden) {
parent.attr('visibility', 'hidden');
}
// redraw
this._renderer.drawShape(gfxGroup, element);
return parent;
// update positioning
gfx.translate(element.x, element.y);
if (element.hidden) {
gfx.attr('visibility', 'hidden');
}
};
function createConnection(paper, data) {
var parent = createParent(paper, 'connection');
var gfx = renderer.drawConnection(parent, data);
gfx.addClass('djs-visual');
GraphicsFactory.prototype.updateConnection = function(element, gfx) {
return parent;
}
// clear visual
var gfxGroup = clearVisual(gfx);
this._renderer.drawConnection(gfxGroup, element);
function setPosition(gfx, x, y) {
var positionMatrix = new snap.Matrix();
positionMatrix.translate(x, y);
gfx.transform(positionMatrix);
if (element.hidden) {
gfx.attr('visibility', 'hidden');
}
};
function createPaper(options) {
return snap.createSnapAt(options.width, options.height, options.container);
}
// API
this.createConnection = createConnection;
this.createShape = createShape;
this.createPaper = createPaper;
}
GraphicsFactory.$inject = [ 'renderer', 'snap' ];
diagramModule.type('graphicsFactory', [ 'eventBus', 'renderer', 'snap', GraphicsFactory ]);
module.exports = GraphicsFactory;

@@ -1,8 +0,5 @@

var di = require('./di');
'use strict';
// diagram-js main components
require('./core/Canvas');
require('./core/EventBus');
var di = require('didi');
/**

@@ -12,4 +9,58 @@ * @namespace djs

var defaultModule = di.defaultModule;
/**
* Bootstrap an injector from a list of modules, instantiating a number of default components
*
* @param {Array<didi.Module>} bootstrapModules
*
* @return {didi.Injector} a injector to use to access the components
*/
function bootstrap(bootstrapModules) {
var modules = [];
var components = [];
function hasModule(m) {
return modules.indexOf(m) >= 0;
}
function addModule(m) {
modules.push(m);
}
function visit(m) {
if (hasModule(m)) {
return;
}
(m.__depends__ || []).forEach(visit);
if (hasModule(m)) {
return;
}
addModule(m);
(m.__init__ || []).forEach(function(c) {
components.push(c);
});
}
bootstrapModules.forEach(visit);
var injector = new di.Injector(modules);
components.forEach(function(c) {
// eagerly resolve main components
injector.get(c);
});
return injector;
}
/**
* Creates an injector from passed options.
*
* @param {Object} options
* @return {didi.Injector}
*/
function createInjector(options) {

@@ -19,58 +70,68 @@

var components = [ 'canvas', 'eventBus' ].concat(options.components || []),
modules = [].concat(options.modules || []);
var configModule = {
'config': ['value', options]
};
if (modules.indexOf(defaultModule) === -1) {
modules.unshift(defaultModule);
}
var coreModule = require('./core');
return di.bootstrap(modules, components, options);
var modules = [ configModule, coreModule ].concat(options.modules || []);
return bootstrap(modules);
}
/**
* @class
*
* The main diagram-js entry point that bootstraps the diagram with the given
* The main diagram-js entry point that bootstraps the diagram with the given
* configuration.
*
*
* To register extensions with the diagram, pass them as Array<didi.Module> to the constructor
*
* @example
*
* Given you would like to create a plug-in that logs whenever a shape
* or connection was added to the canvas:
*
* * Create the plug-in file:
*
* ```javascript
* function MyLoggingPlugin(events) {
* events.on('shape.added', function(event) {
* console.log('shape ', event.shape, ' was added to the diagram');
* });
* }
*
* module.exports = {
* __init__: [ 'myLoggingPlugin'],
* myLoggingPlugin: [ 'type', [ 'eventBus', MyLoggingPlugin ]]
* };
* ```
*
* * Instantiate the diagram with the new plug-in
*
* ```javascript
* var diagram = new Diagram({ modules: [ require('path-to-plugin-file') ] });
*
* diagram.invoke([ 'canvas', function(canvas) {
* // add shape to drawing canvas
* canvas.addShape({ x: 10, y: 10 });
* });
*
* // 'shape ... was added to the diagram' logged to console
* ```
*
* @param {Object} options
* @param {String[]} options.components a list of components to instantiate when creating the diagram
* @param {String[]} options.modules a list of modules to use for locating instantiatable diagram components
* @param {Array<didi.Module>} [options.modules] external modules to instantiate with the diagram
* @param {didi.Injector} [injector] an (optional) injector to bootstrap the diagram with
*/
function Diagram(options, injector) {
'use strict';
// create injector unless explicitly specified
injector = injector || createInjector(options);
this.injector = injector = injector || createInjector(options);
// fire diagram init because
// all components have been loaded now
// API
/**
* An event indicating that all plug-ins are loaded.
*
* Use this event to fire other events to interested plug-ins
*
* @memberOf Diagram
*
* @event diagram.init
*
* @example
*
* events.on('diagram.init', function() {
* events.fire('my-custom-event', { foo: 'BAR' });
* });
*
* @type {Object}
* @property {snapsvg.Paper} paper the initialized drawing paper
*/
injector.get('eventBus').fire('diagram.init');
function destroy() {
injector.get('eventBus').fire('diagram.destroy');
}
// API
/**
* Resolves a diagram service

@@ -80,4 +141,4 @@ *

*
* @param {Function|Object[]} function that should be called with internal diagram services on
* @param {Object} locals a number of locals to use to resolve certain dependencies
* @param {String} name the name of the diagram service to be retrieved
* @param {Object} [locals] a number of locals to use to resolve certain dependencies
*/

@@ -88,3 +149,3 @@ this.get = injector.get;

* Executes a function into which diagram services are injected
*
*
* @method Diagram#invoke

@@ -97,8 +158,26 @@ *

// init
// indicate via event
/**
* Destroys the diagram
* An event indicating that all plug-ins are loaded.
*
* @method Diagram#destroy
* Use this event to fire other events to interested plug-ins
*
* @memberOf Diagram
*
* @event diagram.init
*
* @example
*
* events.on('diagram.init', function() {
* events.fire('my-custom-event', { foo: 'BAR' });
* });
*
* @type {Object}
* @property {snapsvg.Paper} paper the initialized drawing paper
*/
this.destroy = destroy;
this.get('eventBus').fire('diagram.init');
}

@@ -108,40 +187,10 @@

/**
* The main diagram module that can be used
* to register an extension on the diagram.
*
* @field Diagram.components
* @type {didi.Module}
*/
module.exports.components = defaultModule;
/**
* Registers an extension with the diagram.
*
* @method Diagram.plugin
* @example
* Destroys the diagram
*
* var Diagram = require('Diagram');
*
* Diagram.plugin('mySamplePlugin', [ 'eventBus', function(events) {
* events.on('shape.added', function(event) {
* console.log('shape ', event.shape, ' was added to the diagram');
* });
* }]);
*
* var diagram = new Diagram({ components: ['mySamplePlugin'] });
*
* diagram.invoke([ 'canvas', function(canvas) {
*
* // add shape to drawing canvas
* canvas.addShape({ x: 10, y: 10 });
* });
*
* // 'shape ... was added to the diagram' logged to console
*
* @param {String} pluginId a unique identifier to reference this plugin from other components
* @param {Object[]|Function} definition the plugin definition
*
* @see Diagram
* @method Diagram#destroy
*/
module.exports.plugin = defaultModule.type;
Diagram.prototype.destroy = function() {
this.get('eventBus').fire('diagram.destroy');
};
'use strict';
var diagramModule = require('../di').defaultModule;
// required components
require('../core/EventBus');
require('./Styles');
function flattenPoints(points) {

@@ -27,6 +22,5 @@ var result = [];

*
* @param {EventBus} events
* @param {Styles} styles
*/
function Renderer(events, styles) {
function Renderer(styles) {
this.CONNECTION_STYLE = styles.style([ 'no-fill' ]);

@@ -36,3 +30,3 @@ this.SHAPE_STYLE = styles.style({ fill: 'fuchsia' });

Renderer.prototype.drawShape = function drawShape(paper, data) {
Renderer.prototype.drawShape = function drawShape(gfxGroup, data) {
if (!data.width || !data.height) {

@@ -42,12 +36,12 @@ throw new Error('must specify width and height properties for new shape');

return paper.rect(0, 0, data.width, data.height, 10, 10).attr(this.SHAPE_STYLE);
return gfxGroup.rect(0, 0, data.width, data.height, 10, 10).attr(this.SHAPE_STYLE);
};
Renderer.prototype.drawConnection = function drawConnection(paper, data) {
Renderer.prototype.drawConnection = function drawConnection(gfxGroup, data) {
var points = flattenPoints(data.waypoints);
return paper.polyline(points).attr(this.CONNECTION_STYLE);
return gfxGroup.polyline(points).attr(this.CONNECTION_STYLE);
};
diagramModule.type('renderer', [ 'eventBus', 'styles', Renderer ]);
Renderer.$inject = ['styles'];

@@ -54,0 +48,0 @@

@@ -1,3 +0,1 @@

var diagramModule = require('../di').defaultModule;
var snapsvg = require('snapsvg');

@@ -8,5 +6,2 @@

// register as a value
diagramModule.value('snap', snapsvg);
module.exports = snapsvg;

@@ -0,1 +1,3 @@

'use strict';
var Snap = require('snapsvg');

@@ -73,3 +75,3 @@

* @method snapsvg.Element#hasClass
*
*
* @param {String} cls the class to query for

@@ -130,3 +132,3 @@ * @return {Boolean} returns true if the element has the given class

Snap.plugin(function (Snap, Element, Paper, global) {
/*

@@ -133,0 +135,0 @@ * @method snapsvg.Element#translate

@@ -1,5 +0,6 @@

var diagramModule = require('../di').defaultModule;
'use strict';
var _ = require('lodash');
/**

@@ -61,4 +62,2 @@ * A component that manages shape styles

diagramModule.type('styles', Styles);
module.exports = Styles;

@@ -0,0 +0,0 @@ var _ = require('lodash'),

@@ -1,10 +0,13 @@

var diagramModule = require('../../di').defaultModule;
'use strict';
require('./MoveEvents');
require('./MoveVisuals');
function Move() {}
diagramModule.type('move', [ 'moveEvents', 'moveVisuals', Move ]);
module.exports = Move;
module.exports = {
__depends__: [
require('../interaction-events'),
require('../selection'),
require('../outline'),
require('../rules')
],
__init__: [ 'moveEvents', 'moveVisuals' ],
moveEvents: [ 'type', require('./MoveEvents') ],
moveVisuals: [ 'type', require('./MoveVisuals') ]
};

@@ -0,17 +1,9 @@

'use strict';
var _ = require('lodash');
require('../../core/EventBus');
require('../../core/CommandStack');
require('../../core/ElementRegistry');
var MoveShapesHandler = require('./cmd/MoveShapesHandler'),
Draggable = require('../Draggable');
require('../selection/Service');
require('../InteractionEvents');
var MoveShapesHandler = require('../../commands/MoveShapesHandler'),
Draggable = require('../Draggable'),
Diagram = require('../../Diagram');
/**

@@ -21,3 +13,3 @@ * @class

* A plugin that makes shapes draggable / droppable.
*
*
* @param {EventBus} events the event bus

@@ -31,3 +23,3 @@ * @param {Selection} selection the selection service

///// execution of actual move ///////////////////////////
function executeMove(ctx) {

@@ -44,5 +36,5 @@

var hoverGfx = ctx.hoverGfx;
if (hoverGfx) {
moveContext.newParent = shapes.getShapeByGraphics(hoverGfx);
moveContext.newParent = shapes.getByGraphics(hoverGfx);
}

@@ -81,3 +73,3 @@

_.forEach(dragShapes, function(s) {
var gfx = shapes.getGraphicsByShape(s);
var gfx = shapes.getGraphicsByElement(s);
dragGraphics.push(gfx);

@@ -96,6 +88,6 @@ });

* @memberOf MoveEvents
*
*
* @event shape.move.start
* @type {Object}
*
*
* @property {djs.ElementDescriptor} element the shape descriptor

@@ -113,6 +105,6 @@ * @property {Object} gfx the graphical representation of the shape

* @memberOf MoveEvents
*
*
* @event shape.move
* @type {Object}
*
*
* @property {djs.ElementDescriptor} element the shape descriptor

@@ -130,6 +122,6 @@ * @property {Object} gfx the graphical representation of the shape

* @memberOf MoveEvents
*
*
* @event shape.move.over
* @type {Object}
*
*
* @property {djs.ElementDescriptor} element the shape descriptor

@@ -144,10 +136,10 @@ * @property {Object} gfx the graphical object that is dragged over

/**
* An event indicating that a shape is dragged out of another shape after
* An event indicating that a shape is dragged out of another shape after
* it had been previously dragged over it
*
* @memberOf MoveEvents
*
*
* @event shape.move.out
* @type {Object}
*
*
* @property {djs.ElementDescriptor} element the shape descriptor

@@ -165,6 +157,6 @@ * @property {Object} gfx the graphical object that is dragged out

* @memberOf MoveEvents
*
*
* @event shape.move.end
* @type {Object}
*
*
* @property {djs.ElementDescriptor} element the shape descriptor

@@ -190,6 +182,5 @@ * @property {Object} gfx the graphical representation of the shape

Diagram.plugin('moveEvents', [
'eventBus', 'selection', 'elementRegistry',
'commandStack', 'interactionEvents', MoveEvents ]);
MoveEvents.$inject = [ 'eventBus', 'selection', 'elementRegistry', 'commandStack' ];
module.exports = MoveEvents;

@@ -1,20 +0,8 @@

require('../../core/EventBus');
require('../../core/Canvas');
require('../../core/ElementRegistry');
'use strict';
require('../../draw/Snap');
require('../../draw/Styles');
var _ = require('lodash');
require('../selection/Service');
require('../services/Rules');
var ShapeUtil = require('../../util/ShapeUtil');
require('../Outline');
require('./MoveEvents');
var Diagram = require('../../Diagram'),
_ = require('lodash'),
ShapeUtil = require('../../util/ShapeUtil');
/**

@@ -38,3 +26,3 @@ * @class

function getGfx(s) {
return shapes.getGraphicsByShape(s);
return shapes.getGraphicsByElement(s);
}

@@ -62,3 +50,3 @@

function addDragger(shape, dragGroup) {
var gfx = shapes.getGraphicsByShape(shape);
var gfx = shapes.getGraphicsByElement(shape);
var dragger = gfx.clone();

@@ -162,6 +150,13 @@ var bbox = gfx.getBBox();

Diagram.plugin('moveVisuals', [
'eventBus', 'selection', 'elementRegistry', 'canvas', 'snap', 'styles', 'rules', 'moveEvents', MoveVisuals
]);
MoveVisuals.$inject = [
'eventBus',
'selection',
'elementRegistry',
'canvas',
'snap',
'styles',
'rules'
];
module.exports = MoveVisuals;

@@ -0,0 +0,0 @@ // Copyright Joyent, Inc. and other Node contributors.

@@ -0,0 +0,0 @@ function IdGenerator(prefix) {

@@ -0,0 +0,0 @@ var _ = require('lodash');

var _ = require('lodash');
/**
* Adds an element to a collection and returns true if the
* Adds an element to a collection and returns true if the
* element was added.

@@ -36,7 +36,7 @@ *

* Collects self + child shapes up to a given depth from a list of shapes.
*
*
* @param {djs.ShapeDescriptor[]} shapes the shapes to select the children from
* @param {Boolean} unique whether to return a unique result set (no duplicates)
* @param {Number} maxDepth the depth to search through or -1 for infinite
*
*
* @return {djs.ShapeDescriptor[]} found shapes

@@ -68,6 +68,6 @@ */

* Return self + direct children for a number of shapes
*
*
* @param {djs.ShapeDescriptor[]} shapes to query
* @param {Boolean} allowDuplicates to allow duplicates in the result set
*
*
* @return {djs.ShapeDescriptor[]} the collected shapes

@@ -81,6 +81,6 @@ */

* Return self + ALL children for a number of shapes
*
*
* @param {djs.ShapeDescriptor[]} shapes to query
* @param {Boolean} allowDuplicates to allow duplicates in the result set
*
*
* @return {djs.ShapeDescriptor[]} the collected shapes

@@ -105,3 +105,3 @@ */

// TODO(nre): think about parent->child magic
var old = shape.parent;

@@ -108,0 +108,0 @@ if (old && old.children) {

{
"name": "diagram-js",
"version": "0.1.0",
"version": "0.2.0",
"description": "A modeling framework for the web",
"main": "lib/Diagram.js",
"scripts": {

@@ -21,29 +20,27 @@ "test": "grunt test"

"devDependencies": {
"karma": "~0.12.0",
"karma-jasmine": "~0.2.0",
"didi": "~0.0.4",
"exposify": "https://github.com/Nikku/exposify/archive/v0.2.0-transform-arguments-0.tar.gz",
"grunt": "~0.4.4",
"grunt-browserify": "~2.1.0",
"grunt-contrib-jshint": "~0.7.2",
"grunt-contrib-watch": "~0.5.0",
"grunt-jsdoc": "~0.5.1",
"grunt-karma": "~0.8.0",
"grunt-release": "~0.7.0",
"jsondiffpatch": "^0.1.7",
"karma": "~0.12.8",
"karma-bro": "~0.2.0",
"karma-chrome-launcher": "~0.1.2",
"karma-firefox-launcher": "~0.1.3",
"karma-ie-launcher": "~0.1.4",
"karma-jasmine": "https://github.com/Nikku/karma-jasmine/archive/jasmine-v2.0.0-latest-1.tar.gz",
"karma-phantomjs-launcher": "0.1.2",
"karma-ie-launcher": "~0.1.4",
"karma-firefox-launcher": "~0.1.3",
"karma-bro": "~0.2.0",
"browserify": "~3.44.2",
"grunt": "~0.4.0",
"grunt-karma": "~0.8.0",
"grunt-browserify": "~1.3.0",
"grunt-contrib-copy": "~0.5.0",
"grunt-contrib-watch": "~0.5.0",
"grunt-contrib-connect": "~0.6.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-release": "~0.7.0",
"grunt-jsdoc": "~0.5.1",
"grunt-concurrent": "~0.4.0",
"load-grunt-tasks": "~0.3.0",
"lodash": "~2.4.0",
"didi": "~0.0.4"
"time-grunt": "~0.3.0"
},
"peerDependencies": {
"lodash": "~2.4.0",
"didi": "~0.0.4"
},
"dependencies": {
"lodash": "~2.4.0",
"eve": "0.4.1",

@@ -50,0 +47,0 @@ "snapsvg": "https://github.com/Nikku/Snap.svg/archive/v0.2.2-browserify.tar.gz"

@@ -0,0 +0,0 @@ # diagram.js

@@ -0,0 +0,0 @@ module.exports = function(karma) {

var _ = require('lodash');
module.exports.addDeepEquals = function() {
var jsondiffpatch = require('jsondiffpatch');
var compare = jsondiffpatch.create({
objectHash: function (obj) {
return JSON.stringify(obj);
}
});
function deepEquals(actual, expected) {
var actualClone = _.cloneDeep(actual);
var expectedClone = _.cloneDeep(expected);
var result = {
pass: _.isEqual(actualClone, expectedClone)
};
var message;
if (!result.pass) {
message =
'Expected elements to equal but got diff\n' +
JSON.stringify(compare.diff(actualClone, expectedClone), null, ' ');
} else {
message = 'Expected elements not to equal';
}
result.message = message;
return result;
}
jasmine.addMatchers({
toDeepEqual: function(util) {
return {
compare: deepEquals
};
}
});
};
module.exports.addBBoxMatchers = function() {

@@ -5,0 +46,0 @@

@@ -0,11 +1,17 @@

'use strict';
var Events = require('../../../lib/core/EventBus');
var TestHelper = require('../../TestHelper'),
inject = TestHelper.inject,
bootstrapDiagram = TestHelper.bootstrapDiagram;
var TestHelper = require('../../TestHelper');
/* global bootstrapDiagram, inject */
var createSpy = jasmine.createSpy;
var Matchers = require('../../Matchers');
describe('Canvas', function() {
beforeEach(Matchers.addDeepEquals);
var container;

@@ -114,3 +120,3 @@

var gfx = elementRegistry.getGraphicsByShape(shape);
var gfx = elementRegistry.getGraphicsByElement(shape);

@@ -141,4 +147,4 @@ // then

// then
expect(elementRegistry.getShapeById('s2')).not.toBeDefined();
expect(elementRegistry.getShapeById('s3')).not.toBeDefined();
expect(elementRegistry.getById('s2')).not.toBeDefined();
expect(elementRegistry.getById('s3')).not.toBeDefined();
}));

@@ -168,4 +174,4 @@

// then
expect(elementRegistry.getShapeById('s2')).toEqual(s2);
expect(elementRegistry.getShapeById('s3')).toEqual(s3);
expect(elementRegistry.getById('s2')).toEqual(s2);
expect(elementRegistry.getById('s3')).toEqual(s3);

@@ -616,2 +622,71 @@ expect(s2.parent).toEqual(s1);

describe('getAbsoluteBBox', function() {
beforeEach(bootstrapDiagram({ canvas: { width: 300, height: 300 } }));
it('should return abs position (default zoom)', inject(function(canvas) {
// given
var shape = { id: 's0', x: 10, y: 20, width: 300, height: 200 };
canvas.addShape(shape);
// when
var bbox = canvas.getAbsoluteBBox(shape);
// then
expect(bbox).toDeepEqual({ x: 10, y: 20, width: 300, height: 200 });
}));
it('should return abs position (moved)', inject(function(canvas) {
// given
var shape = { id: 's0', x: 10, y: 20, width: 300, height: 200 };
canvas.addShape(shape);
canvas.viewbox({ x: 50, y: 50, width: 300, height: 300 });
// when
var bbox = canvas.getAbsoluteBBox(shape);
// then
expect(bbox).toDeepEqual({ x: -40, y: -30, width: 300, height: 200 });
}));
it('should return abs position (zoomed in)', inject(function(canvas) {
// given
var shape = { id: 's0', x: 10, y: 20, width: 300, height: 200 };
canvas.addShape(shape);
canvas.viewbox({ x: 50, y: 50, width: 600, height: 600 });
// when
var bbox = canvas.getAbsoluteBBox(shape);
// then
expect(bbox).toDeepEqual({ x: -20, y: -15, width: 150, height: 100 });
}));
it('should return abs position (zoomed in)', inject(function(canvas) {
// given
var shape = { id: 's0', x: 10, y: 20, width: 300, height: 200 };
canvas.addShape(shape);
canvas.viewbox({ x: 50, y: 50, width: 150, height: 150 });
// when
var bbox = canvas.getAbsoluteBBox(shape);
// then
expect(bbox).toDeepEqual({ x: -80, y: -60, width: 600, height: 400 });
}));
});
});

@@ -0,8 +1,9 @@

'use strict';
var CommandStack = require('../../../lib/core/CommandStack'),
Events = require('../../../lib/core/EventBus');
describe('CommandStack', function() {
'use strict';
/**

@@ -12,3 +13,3 @@ * Create a new handler with the given identifier

function handler(name) {
return {

@@ -52,5 +53,5 @@ execute: function(ctx) {

function expectStack(actions, idx) {
function expectStack(actions, idx) {
expect(commandStack.getStack()).toEqual(actions);
expect(commandStack.getStackIndex()).toEqual(idx);
expect(commandStack.getStackIndex()).toEqual(idx);
}

@@ -90,3 +91,3 @@

var ctx = {};
// when

@@ -125,3 +126,3 @@ commandStack.execute('a', ctx);

var ctx = {};
// when

@@ -148,3 +149,3 @@ commandStack.execute('a', ctx);

var ctx = {};
// when

@@ -176,3 +177,3 @@ commandStack.execute('a', ctx);

]);
});

@@ -188,3 +189,3 @@

var ctx = {};
// when

@@ -225,3 +226,3 @@ commandStack.execute('a', ctx);

var ctx = {};
// when

@@ -228,0 +229,0 @@ commandStack.execute('a', ctx);

@@ -0,1 +1,4 @@

'use strict';
var EventBus = require('../../../lib/core/EventBus'),

@@ -6,3 +9,2 @@ ElementRegistry = require('../../../lib/core/ElementRegistry');

describe('elementRegistry', function() {
'use strict';

@@ -16,4 +18,5 @@ var eventBus, shapes;

it('should register shape on add', function() {
// given

@@ -27,13 +30,14 @@ var shape = { id: 's0' },

// then
expect(shapes.getShapeByGraphics(gfx)).toBe(shape);
expect(shapes.getShapeByGraphics(gfx.id)).toBe(shape);
expect(shapes.getByGraphics(gfx)).toBe(shape);
expect(shapes.getByGraphics(gfx.id)).toBe(shape);
expect(shapes.getShapeById(shape.id)).toBe(shape);
expect(shapes.getById(shape.id)).toBe(shape);
expect(shapes.getGraphicsByShape(shape)).toBe(gfx);
expect(shapes.getGraphicsByShape(shape.id)).toBe(gfx);
expect(shapes.getGraphicsByElement(shape)).toBe(gfx);
expect(shapes.getGraphicsByElement(shape.id)).toBe(gfx);
});
it('should unregister shape on remove', function() {
// given

@@ -48,10 +52,11 @@ var shape = { id: 's0' },

// then
expect(shapes.getShapeByGraphics(gfx)).not.toBeDefined();
expect(shapes.getShapeByGraphics(gfx.id)).not.toBeDefined();
expect(shapes.getByGraphics(gfx)).not.toBeDefined();
expect(shapes.getByGraphics(gfx.id)).not.toBeDefined();
expect(shapes.getShapeById(shape.id)).not.toBeDefined();
expect(shapes.getById(shape.id)).not.toBeDefined();
expect(shapes.getGraphicsByShape(shape)).not.toBeDefined();
expect(shapes.getGraphicsByShape(shape.id)).not.toBeDefined();
expect(shapes.getGraphicsByElement(shape)).not.toBeDefined();
expect(shapes.getGraphicsByElement(shape.id)).not.toBeDefined();
});
});

@@ -0,1 +1,3 @@

'use strict';
var Events = require('../../../lib/core/EventBus');

@@ -5,4 +7,4 @@

describe('eventBus', function() {
'use strict';

@@ -13,4 +15,5 @@ function createEventEmitter() {

it('should fire listener', function() {
// given

@@ -29,4 +32,5 @@ var e = createEventEmitter();

it('should fire typed listener', function() {
// given

@@ -45,4 +49,5 @@ var e = createEventEmitter();

it('should stopPropagation', function() {
// given

@@ -67,2 +72,3 @@ var e = createEventEmitter();

it('should remove listeners by event type', function() {

@@ -87,2 +93,3 @@

it('should remove listener by callback', function() {

@@ -107,2 +114,3 @@

it('should fire event by name', function() {

@@ -121,2 +129,3 @@

it('once should only fire once', function() {

@@ -145,7 +154,8 @@

});
});
describe('Events(priority) ', function() {
'use strict';
describe('event priorities', function() {
var e,

@@ -238,3 +248,3 @@ listener1,

it(' user should be able to stop propagation' +
it('user should be able to stop propagation' +
' to handler with lower priority.', function() {

@@ -273,2 +283,3 @@

});
});

@@ -0,3 +1,6 @@

'use strict';
var Diagram = require('../../lib/Diagram');
describe('diagram', function() {

@@ -16,14 +19,6 @@

describe('static', function() {
it('should offer #plugin API', function() {
expect(Diagram.plugin).toBeDefined();
});
});
describe('runtime', function() {
it('should bootstrap app', function() {
it('should bootstrap', function() {

@@ -40,4 +35,5 @@ var diagram = new Diagram({

it('should expose diagram services', function() {
it('should offer #destroy method', function() {
// when
var diagram = new Diagram({

@@ -51,9 +47,46 @@ canvas: {

diagram.invoke([ 'canvas', function(canvas) {
canvas
.addShape({ id: 's1', x: 10, y: 10, width: 30, height: 30 })
.addShape({ id: 's2', x: 100, y: 100, width: 30, height: 30 });
// then
expect(diagram.destroy).toBeDefined();
});
canvas.addConnection({ id: 'c1', waypoints: [ { x: 25, y: 25 }, {x: 115, y: 115} ]});
}]);
describe('should expose diagram services', function() {
it('via #get', function() {
// when
var diagram = new Diagram({
canvas: {
container: container,
width: 700,
height: 500
}
});
// then
expect(diagram.get('canvas')).toBeDefined();
});
it('via #invoke', function() {
// when
var diagram = new Diagram({
canvas: {
container: container,
width: 700,
height: 500
}
});
diagram.invoke([ 'canvas', function(canvas) {
canvas
.addShape({ id: 's1', x: 10, y: 10, width: 30, height: 30 })
.addShape({ id: 's2', x: 100, y: 100, width: 30, height: 30 });
canvas.addConnection({ id: 'c1', waypoints: [ { x: 25, y: 25 }, {x: 115, y: 115} ]});
}]);
});
});

@@ -60,0 +93,0 @@

@@ -1,5 +0,7 @@

var Styles = require('../../../lib/draw/Styles'),
TestHelper = require('../../TestHelper');
'use strict';
var Styles = require('../../../lib/draw/Styles');
describe('draw/Styles', function() {

@@ -10,5 +12,5 @@

describe('#cls', function() {
it('should create style with traits given', function() {
// given

@@ -15,0 +17,0 @@ var expectedStyle = {

@@ -0,8 +1,11 @@

'use strict';
var TestHelper = require('../../TestHelper');
/* global bootstrapDiagram, inject */
var Events = require('../../../lib/core/EventBus');
var TestHelper = require('../../TestHelper'),
inject = TestHelper.inject,
bootstrapDiagram = TestHelper.bootstrapDiagram;
describe('environment/Mocking', function() {

@@ -39,2 +42,3 @@

}));
});

@@ -1,13 +0,17 @@

var Events = require('../../../../lib/features/move');
'use strict';
var TestHelper = require('../../../TestHelper'),
inject = TestHelper.inject,
bootstrapDiagram = TestHelper.bootstrapDiagram;
var TestHelper = require('../../../TestHelper');
/* global bootstrapDiagram, inject */
var moveModule = require('../../../../lib/features/move');
describe('features/move', function() {
describe('bootstrap', function() {
beforeEach(bootstrapDiagram({ components: [ 'move' ] }));
beforeEach(bootstrapDiagram({ modules: [ moveModule ] }));

@@ -14,0 +18,0 @@ it('should bootstrap diagram with component', inject(function() {

@@ -0,0 +0,0 @@ var _ = require('lodash');

@@ -0,0 +0,0 @@ var ShapeUtil = require('../../../lib/util/ShapeUtil');

@@ -0,1 +1,3 @@

'use strict';
var _ = require('lodash');

@@ -22,3 +24,3 @@ var Diagram = require('../lib/Diagram');

* var mockEvents;
*
*
* beforeEach(bootstrapDiagram(function() {

@@ -33,3 +35,3 @@ * mockEvents = new Events();

* });
*
*
* @param {Object} (options) optional options to be passed to the diagram upon instantiation

@@ -83,3 +85,3 @@ * @param {Object|Function} locals the local overrides to be used by the diagram or a function that produces them

* var mockEvents;
*
*
* beforeEach(bootstrapDiagram(...));

@@ -92,3 +94,3 @@ *

* });
*
*
* @param {Function} fn the function to inject to

@@ -99,2 +101,7 @@ * @return {Function} a function that can be passed to it to carry out the injection

return function() {
if (!DIAGRAM) {
throw new Error('no bootstraped diagram, ensure you created it via #bootstrapDiagram');
}
DIAGRAM.invoke(fn);

@@ -105,3 +112,3 @@ };

module.exports.bootstrapDiagram = bootstrapDiagram;
module.exports.inject = inject;
module.exports.bootstrapDiagram = (window || global).bootstrapDiagram = bootstrapDiagram;
module.exports.inject = (window || global).inject = inject;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc