Actualización
This commit is contained in:
189
main/inc/lib/mxgraph/src/js/io/mxCellCodec.js
Normal file
189
main/inc/lib/mxgraph/src/js/io/mxCellCodec.js
Normal file
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxCellCodec
|
||||
*
|
||||
* Codec for <mxCell>s. This class is created and registered
|
||||
* dynamically at load time and used implicitely via <mxCodec>
|
||||
* and the <mxCodecRegistry>.
|
||||
*
|
||||
* Transient Fields:
|
||||
*
|
||||
* - children
|
||||
* - edges
|
||||
* - overlays
|
||||
* - mxTransient
|
||||
*
|
||||
* Reference Fields:
|
||||
*
|
||||
* - parent
|
||||
* - source
|
||||
* - target
|
||||
*
|
||||
* Transient fields can be added using the following code:
|
||||
*
|
||||
* mxCodecRegistry.getCodec(mxCell).exclude.push('name_of_field');
|
||||
*
|
||||
* To subclass <mxCell>, replace the template and add an alias as
|
||||
* follows.
|
||||
*
|
||||
* (code)
|
||||
* function CustomCell(value, geometry, style)
|
||||
* {
|
||||
* mxCell.apply(this, arguments);
|
||||
* }
|
||||
*
|
||||
* mxUtils.extend(CustomCell, mxCell);
|
||||
*
|
||||
* mxCodecRegistry.getCodec(mxCell).template = new CustomCell();
|
||||
* mxCodecRegistry.addAlias('CustomCell', 'mxCell');
|
||||
* (end)
|
||||
*/
|
||||
var codec = new mxObjectCodec(new mxCell(),
|
||||
['children', 'edges', 'overlays', 'mxTransient'],
|
||||
['parent', 'source', 'target']);
|
||||
|
||||
/**
|
||||
* Function: isCellCodec
|
||||
*
|
||||
* Returns true since this is a cell codec.
|
||||
*/
|
||||
codec.isCellCodec = function()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Overidden to disable conversion of value to number.
|
||||
*/
|
||||
codec.isNumericAttribute = function(dec, attr, obj)
|
||||
{
|
||||
return attr.nodeName !== 'value' && mxObjectCodec.prototype.isNumericAttribute.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: isExcluded
|
||||
*
|
||||
* Excludes user objects that are XML nodes.
|
||||
*/
|
||||
codec.isExcluded = function(obj, attr, value, isWrite)
|
||||
{
|
||||
return mxObjectCodec.prototype.isExcluded.apply(this, arguments) ||
|
||||
(isWrite && attr == 'value' &&
|
||||
value.nodeType == mxConstants.NODETYPE_ELEMENT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: afterEncode
|
||||
*
|
||||
* Encodes an <mxCell> and wraps the XML up inside the
|
||||
* XML of the user object (inversion).
|
||||
*/
|
||||
codec.afterEncode = function(enc, obj, node)
|
||||
{
|
||||
if (obj.value != null && obj.value.nodeType == mxConstants.NODETYPE_ELEMENT)
|
||||
{
|
||||
// Wraps the graphical annotation up in the user object (inversion)
|
||||
// by putting the result of the default encoding into a clone of the
|
||||
// user object (node type 1) and returning this cloned user object.
|
||||
var tmp = node;
|
||||
node = mxUtils.importNode(enc.document, obj.value, true);
|
||||
node.appendChild(tmp);
|
||||
|
||||
// Moves the id attribute to the outermost XML node, namely the
|
||||
// node which denotes the object boundaries in the file.
|
||||
var id = tmp.getAttribute('id');
|
||||
node.setAttribute('id', id);
|
||||
tmp.removeAttribute('id');
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: beforeDecode
|
||||
*
|
||||
* Decodes an <mxCell> and uses the enclosing XML node as
|
||||
* the user object for the cell (inversion).
|
||||
*/
|
||||
codec.beforeDecode = function(dec, node, obj)
|
||||
{
|
||||
var inner = node.cloneNode(true);
|
||||
var classname = this.getName();
|
||||
|
||||
if (node.nodeName != classname)
|
||||
{
|
||||
// Passes the inner graphical annotation node to the
|
||||
// object codec for further processing of the cell.
|
||||
var tmp = node.getElementsByTagName(classname)[0];
|
||||
|
||||
if (tmp != null && tmp.parentNode == node)
|
||||
{
|
||||
mxUtils.removeWhitespace(tmp, true);
|
||||
mxUtils.removeWhitespace(tmp, false);
|
||||
tmp.parentNode.removeChild(tmp);
|
||||
inner = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
inner = null;
|
||||
}
|
||||
|
||||
// Creates the user object out of the XML node
|
||||
obj.value = node.cloneNode(true);
|
||||
var id = obj.value.getAttribute('id');
|
||||
|
||||
if (id != null)
|
||||
{
|
||||
obj.setId(id);
|
||||
obj.value.removeAttribute('id');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Uses ID from XML file as ID for cell in model
|
||||
obj.setId(node.getAttribute('id'));
|
||||
}
|
||||
|
||||
// Preprocesses and removes all Id-references in order to use the
|
||||
// correct encoder (this) for the known references to cells (all).
|
||||
if (inner != null)
|
||||
{
|
||||
for (var i = 0; i < this.idrefs.length; i++)
|
||||
{
|
||||
var attr = this.idrefs[i];
|
||||
var ref = inner.getAttribute(attr);
|
||||
|
||||
if (ref != null)
|
||||
{
|
||||
inner.removeAttribute(attr);
|
||||
var object = dec.objects[ref] || dec.lookup(ref);
|
||||
|
||||
if (object == null)
|
||||
{
|
||||
// Needs to decode forward reference
|
||||
var element = dec.getElementById(ref);
|
||||
|
||||
if (element != null)
|
||||
{
|
||||
var decoder = mxCodecRegistry.codecs[element.nodeName] || this;
|
||||
object = decoder.decode(dec, element);
|
||||
}
|
||||
}
|
||||
|
||||
obj[attr] = object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inner;
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
157
main/inc/lib/mxgraph/src/js/io/mxChildChangeCodec.js
Normal file
157
main/inc/lib/mxgraph/src/js/io/mxChildChangeCodec.js
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxChildChangeCodec
|
||||
*
|
||||
* Codec for <mxChildChange>s. This class is created and registered
|
||||
* dynamically at load time and used implicitely via <mxCodec> and
|
||||
* the <mxCodecRegistry>.
|
||||
*
|
||||
* Transient Fields:
|
||||
*
|
||||
* - model
|
||||
* - previous
|
||||
* - previousIndex
|
||||
* - child
|
||||
*
|
||||
* Reference Fields:
|
||||
*
|
||||
* - parent
|
||||
*/
|
||||
var codec = new mxObjectCodec(new mxChildChange(),
|
||||
['model', 'child', 'previousIndex'],
|
||||
['parent', 'previous']);
|
||||
|
||||
/**
|
||||
* Function: isReference
|
||||
*
|
||||
* Returns true for the child attribute if the child
|
||||
* cell had a previous parent or if we're reading the
|
||||
* child as an attribute rather than a child node, in
|
||||
* which case it's always a reference.
|
||||
*/
|
||||
codec.isReference = function(obj, attr, value, isWrite)
|
||||
{
|
||||
if (attr == 'child' && (obj.previous != null || !isWrite))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return mxUtils.indexOf(this.idrefs, attr) >= 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: afterEncode
|
||||
*
|
||||
* Encodes the child recusively and adds the result
|
||||
* to the given node.
|
||||
*/
|
||||
codec.afterEncode = function(enc, obj, node)
|
||||
{
|
||||
if (this.isReference(obj, 'child', obj.child, true))
|
||||
{
|
||||
// Encodes as reference (id)
|
||||
node.setAttribute('child', enc.getId(obj.child));
|
||||
}
|
||||
else
|
||||
{
|
||||
// At this point, the encoder is no longer able to know which cells
|
||||
// are new, so we have to encode the complete cell hierarchy and
|
||||
// ignore the ones that are already there at decoding time. Note:
|
||||
// This can only be resolved by moving the notify event into the
|
||||
// execute of the edit.
|
||||
enc.encodeCell(obj.child, node);
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: beforeDecode
|
||||
*
|
||||
* Decodes the any child nodes as using the respective
|
||||
* codec from the registry.
|
||||
*/
|
||||
codec.beforeDecode = function(dec, node, obj)
|
||||
{
|
||||
if (node.firstChild != null &&
|
||||
node.firstChild.nodeType == mxConstants.NODETYPE_ELEMENT)
|
||||
{
|
||||
// Makes sure the original node isn't modified
|
||||
node = node.cloneNode(true);
|
||||
|
||||
var tmp = node.firstChild;
|
||||
obj.child = dec.decodeCell(tmp, false);
|
||||
|
||||
var tmp2 = tmp.nextSibling;
|
||||
tmp.parentNode.removeChild(tmp);
|
||||
tmp = tmp2;
|
||||
|
||||
while (tmp != null)
|
||||
{
|
||||
tmp2 = tmp.nextSibling;
|
||||
|
||||
if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT)
|
||||
{
|
||||
// Ignores all existing cells because those do not need to
|
||||
// be re-inserted into the model. Since the encoded version
|
||||
// of these cells contains the new parent, this would leave
|
||||
// to an inconsistent state on the model (ie. a parent
|
||||
// change without a call to parentForCellChanged).
|
||||
var id = tmp.getAttribute('id');
|
||||
|
||||
if (dec.lookup(id) == null)
|
||||
{
|
||||
dec.decodeCell(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
tmp.parentNode.removeChild(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var childRef = node.getAttribute('child');
|
||||
obj.child = dec.getObject(childRef);
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: afterDecode
|
||||
*
|
||||
* Restores object state in the child change.
|
||||
*/
|
||||
codec.afterDecode = function(dec, node, obj)
|
||||
{
|
||||
// Cells are encoded here after a complete transaction so the previous
|
||||
// parent must be restored on the cell for the case where the cell was
|
||||
// added. This is needed for the local model to identify the cell as a
|
||||
// new cell and register the ID.
|
||||
if (obj.child != null)
|
||||
{
|
||||
if (obj.child.parent != null && obj.previous != null &&
|
||||
obj.child.parent != obj.previous)
|
||||
{
|
||||
|
||||
obj.previous = obj.child.parent;
|
||||
}
|
||||
|
||||
obj.child.parent = obj.previous;
|
||||
obj.previous = obj.parent;
|
||||
obj.previousIndex = obj.index;
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
596
main/inc/lib/mxgraph/src/js/io/mxCodec.js
Normal file
596
main/inc/lib/mxgraph/src/js/io/mxCodec.js
Normal file
@@ -0,0 +1,596 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
* Class: mxCodec
|
||||
*
|
||||
* XML codec for JavaScript object graphs. See <mxObjectCodec> for a
|
||||
* description of the general encoding/decoding scheme. This class uses the
|
||||
* codecs registered in <mxCodecRegistry> for encoding/decoding each object.
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* In order to resolve references, especially forward references, the mxCodec
|
||||
* constructor must be given the document that contains the referenced
|
||||
* elements.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* The following code is used to encode a graph model.
|
||||
*
|
||||
* (code)
|
||||
* var encoder = new mxCodec();
|
||||
* var result = encoder.encode(graph.getModel());
|
||||
* var xml = mxUtils.getXml(result);
|
||||
* (end)
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Using the code below, an XML document is decoded into an existing model. The
|
||||
* document may be obtained using one of the functions in mxUtils for loading
|
||||
* an XML file, eg. <mxUtils.get>, or using <mxUtils.parseXml> for parsing an
|
||||
* XML string.
|
||||
*
|
||||
* (code)
|
||||
* var doc = mxUtils.parseXml(xmlString);
|
||||
* var codec = new mxCodec(doc);
|
||||
* codec.decode(doc.documentElement, graph.getModel());
|
||||
* (end)
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* This example demonstrates parsing a list of isolated cells into an existing
|
||||
* graph model. Note that the cells do not have a parent reference so they can
|
||||
* be added anywhere in the cell hierarchy after parsing.
|
||||
*
|
||||
* (code)
|
||||
* var xml = '<root><mxCell id="2" value="Hello," vertex="1"><mxGeometry x="20" y="20" width="80" height="30" as="geometry"/></mxCell><mxCell id="3" value="World!" vertex="1"><mxGeometry x="200" y="150" width="80" height="30" as="geometry"/></mxCell><mxCell id="4" value="" edge="1" source="2" target="3"><mxGeometry relative="1" as="geometry"/></mxCell></root>';
|
||||
* var doc = mxUtils.parseXml(xml);
|
||||
* var codec = new mxCodec(doc);
|
||||
* var elt = doc.documentElement.firstChild;
|
||||
* var cells = [];
|
||||
*
|
||||
* while (elt != null)
|
||||
* {
|
||||
* cells.push(codec.decode(elt));
|
||||
* elt = elt.nextSibling;
|
||||
* }
|
||||
*
|
||||
* graph.addCells(cells);
|
||||
* (end)
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Using the following code, the selection cells of a graph are encoded and the
|
||||
* output is displayed in a dialog box.
|
||||
*
|
||||
* (code)
|
||||
* var enc = new mxCodec();
|
||||
* var cells = graph.getSelectionCells();
|
||||
* mxUtils.alert(mxUtils.getPrettyXml(enc.encode(cells)));
|
||||
* (end)
|
||||
*
|
||||
* Newlines in the XML can be converted to <br>, in which case a '<br>' argument
|
||||
* must be passed to <mxUtils.getXml> as the second argument.
|
||||
*
|
||||
* Debugging:
|
||||
*
|
||||
* For debugging I/O you can use the following code to get the sequence of
|
||||
* encoded objects:
|
||||
*
|
||||
* (code)
|
||||
* var oldEncode = mxCodec.prototype.encode;
|
||||
* mxCodec.prototype.encode = function(obj)
|
||||
* {
|
||||
* mxLog.show();
|
||||
* mxLog.debug('mxCodec.encode: obj='+mxUtils.getFunctionName(obj.constructor));
|
||||
*
|
||||
* return oldEncode.apply(this, arguments);
|
||||
* };
|
||||
* (end)
|
||||
*
|
||||
* Note that the I/O system adds object codecs for new object automatically. For
|
||||
* decoding those objects, the constructor should be written as follows:
|
||||
*
|
||||
* (code)
|
||||
* var MyObj = function(name)
|
||||
* {
|
||||
* // ...
|
||||
* };
|
||||
* (end)
|
||||
*
|
||||
* Constructor: mxCodec
|
||||
*
|
||||
* Constructs an XML encoder/decoder for the specified
|
||||
* owner document.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* document - Optional XML document that contains the data.
|
||||
* If no document is specified then a new document is created
|
||||
* using <mxUtils.createXmlDocument>.
|
||||
*/
|
||||
function mxCodec(document)
|
||||
{
|
||||
this.document = document || mxUtils.createXmlDocument();
|
||||
this.objects = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: document
|
||||
*
|
||||
* The owner document of the codec.
|
||||
*/
|
||||
mxCodec.prototype.document = null;
|
||||
|
||||
/**
|
||||
* Variable: objects
|
||||
*
|
||||
* Maps from IDs to objects.
|
||||
*/
|
||||
mxCodec.prototype.objects = null;
|
||||
|
||||
/**
|
||||
* Variable: elements
|
||||
*
|
||||
* Lookup table for resolving IDs to elements.
|
||||
*/
|
||||
mxCodec.prototype.elements = null;
|
||||
|
||||
/**
|
||||
* Variable: encodeDefaults
|
||||
*
|
||||
* Specifies if default values should be encoded. Default is false.
|
||||
*/
|
||||
mxCodec.prototype.encodeDefaults = false;
|
||||
|
||||
|
||||
/**
|
||||
* Function: putObject
|
||||
*
|
||||
* Assoiates the given object with the given ID and returns the given object.
|
||||
*
|
||||
* Parameters
|
||||
*
|
||||
* id - ID for the object to be associated with.
|
||||
* obj - Object to be associated with the ID.
|
||||
*/
|
||||
mxCodec.prototype.putObject = function(id, obj)
|
||||
{
|
||||
this.objects[id] = obj;
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getObject
|
||||
*
|
||||
* Returns the decoded object for the element with the specified ID in
|
||||
* <document>. If the object is not known then <lookup> is used to find an
|
||||
* object. If no object is found, then the element with the respective ID
|
||||
* from the document is parsed using <decode>.
|
||||
*/
|
||||
mxCodec.prototype.getObject = function(id)
|
||||
{
|
||||
var obj = null;
|
||||
|
||||
if (id != null)
|
||||
{
|
||||
obj = this.objects[id];
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
obj = this.lookup(id);
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
var node = this.getElementById(id);
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
obj = this.decode(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: lookup
|
||||
*
|
||||
* Hook for subclassers to implement a custom lookup mechanism for cell IDs.
|
||||
* This implementation always returns null.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* (code)
|
||||
* var codec = new mxCodec();
|
||||
* codec.lookup = function(id)
|
||||
* {
|
||||
* return model.getCell(id);
|
||||
* };
|
||||
* (end)
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* id - ID of the object to be returned.
|
||||
*/
|
||||
mxCodec.prototype.lookup = function(id)
|
||||
{
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getElementById
|
||||
*
|
||||
* Returns the element with the given ID from <document>.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* id - String that contains the ID.
|
||||
*/
|
||||
mxCodec.prototype.getElementById = function(id)
|
||||
{
|
||||
if (this.elements == null)
|
||||
{
|
||||
// Throws custom error for cases where a reference should be resolved
|
||||
// in an empty document. This happens if an XML node is decoded without
|
||||
// passing the owner document to the codec constructor.
|
||||
if (this.document.documentElement == null)
|
||||
{
|
||||
throw new Error('mxCodec constructor needs document parameter');
|
||||
}
|
||||
|
||||
this.elements = new Object();
|
||||
this.addElement(this.document.documentElement);
|
||||
}
|
||||
|
||||
return this.elements[id];
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: addElement
|
||||
*
|
||||
* Adds the given element to <elements> if it has an ID.
|
||||
*/
|
||||
mxCodec.prototype.addElement = function(node)
|
||||
{
|
||||
if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
|
||||
{
|
||||
var id = node.getAttribute('id');
|
||||
|
||||
if (id != null && this.elements[id] == null)
|
||||
{
|
||||
this.elements[id] = node;
|
||||
}
|
||||
}
|
||||
|
||||
node = node.firstChild;
|
||||
|
||||
while (node != null)
|
||||
{
|
||||
this.addElement(node);
|
||||
node = node.nextSibling;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getId
|
||||
*
|
||||
* Returns the ID of the specified object. This implementation
|
||||
* calls <reference> first and if that returns null handles
|
||||
* the object as an <mxCell> by returning their IDs using
|
||||
* <mxCell.getId>. If no ID exists for the given cell, then
|
||||
* an on-the-fly ID is generated using <mxCellPath.create>.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* obj - Object to return the ID for.
|
||||
*/
|
||||
mxCodec.prototype.getId = function(obj)
|
||||
{
|
||||
var id = null;
|
||||
|
||||
if (obj != null)
|
||||
{
|
||||
id = this.reference(obj);
|
||||
|
||||
if (id == null && obj instanceof mxCell)
|
||||
{
|
||||
id = obj.getId();
|
||||
|
||||
if (id == null)
|
||||
{
|
||||
// Uses an on-the-fly Id
|
||||
id = mxCellPath.create(obj);
|
||||
|
||||
if (id.length == 0)
|
||||
{
|
||||
id = 'root';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: reference
|
||||
*
|
||||
* Hook for subclassers to implement a custom method
|
||||
* for retrieving IDs from objects. This implementation
|
||||
* always returns null.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* (code)
|
||||
* var codec = new mxCodec();
|
||||
* codec.reference = function(obj)
|
||||
* {
|
||||
* return obj.getCustomId();
|
||||
* };
|
||||
* (end)
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* obj - Object whose ID should be returned.
|
||||
*/
|
||||
mxCodec.prototype.reference = function(obj)
|
||||
{
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: encode
|
||||
*
|
||||
* Encodes the specified object and returns the resulting
|
||||
* XML node.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* obj - Object to be encoded.
|
||||
*/
|
||||
mxCodec.prototype.encode = function(obj)
|
||||
{
|
||||
var node = null;
|
||||
|
||||
if (obj != null && obj.constructor != null)
|
||||
{
|
||||
var enc = mxCodecRegistry.getCodec(obj.constructor);
|
||||
|
||||
if (enc != null)
|
||||
{
|
||||
node = enc.encode(this, obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mxUtils.isNode(obj))
|
||||
{
|
||||
node = mxUtils.importNode(this.document, obj, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mxLog.warn('mxCodec.encode: No codec for ' + mxUtils.getFunctionName(obj.constructor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decode
|
||||
*
|
||||
* Decodes the given XML node. The optional "into"
|
||||
* argument specifies an existing object to be
|
||||
* used. If no object is given, then a new instance
|
||||
* is created using the constructor from the codec.
|
||||
*
|
||||
* The function returns the passed in object or
|
||||
* the new instance if no object was given.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* node - XML node to be decoded.
|
||||
* into - Optional object to be decodec into.
|
||||
*/
|
||||
mxCodec.prototype.decode = function(node, into)
|
||||
{
|
||||
var obj = null;
|
||||
|
||||
if (node != null && node.nodeType == mxConstants.NODETYPE_ELEMENT)
|
||||
{
|
||||
var ctor = null;
|
||||
|
||||
try
|
||||
{
|
||||
ctor = window[node.nodeName];
|
||||
}
|
||||
catch (err)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
var dec = mxCodecRegistry.getCodec(ctor);
|
||||
|
||||
if (dec != null)
|
||||
{
|
||||
obj = dec.decode(this, node, into);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = node.cloneNode(true);
|
||||
obj.removeAttribute('as');
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: encodeCell
|
||||
*
|
||||
* Encoding of cell hierarchies is built-into the core, but
|
||||
* is a higher-level function that needs to be explicitely
|
||||
* used by the respective object encoders (eg. <mxModelCodec>,
|
||||
* <mxChildChangeCodec> and <mxRootChangeCodec>). This
|
||||
* implementation writes the given cell and its children as a
|
||||
* (flat) sequence into the given node. The children are not
|
||||
* encoded if the optional includeChildren is false. The
|
||||
* function is in charge of adding the result into the
|
||||
* given node and has no return value.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* cell - <mxCell> to be encoded.
|
||||
* node - Parent XML node to add the encoded cell into.
|
||||
* includeChildren - Optional boolean indicating if the
|
||||
* function should include all descendents. Default is true.
|
||||
*/
|
||||
mxCodec.prototype.encodeCell = function(cell, node, includeChildren)
|
||||
{
|
||||
node.appendChild(this.encode(cell));
|
||||
|
||||
if (includeChildren == null || includeChildren)
|
||||
{
|
||||
var childCount = cell.getChildCount();
|
||||
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
this.encodeCell(cell.getChildAt(i), node);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: isCellCodec
|
||||
*
|
||||
* Returns true if the given codec is a cell codec. This uses
|
||||
* <mxCellCodec.isCellCodec> to check if the codec is of the
|
||||
* given type.
|
||||
*/
|
||||
mxCodec.prototype.isCellCodec = function(codec)
|
||||
{
|
||||
if (codec != null && typeof(codec.isCellCodec) == 'function')
|
||||
{
|
||||
return codec.isCellCodec();
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decodeCell
|
||||
*
|
||||
* Decodes cells that have been encoded using inversion, ie.
|
||||
* where the user object is the enclosing node in the XML,
|
||||
* and restores the group and graph structure in the cells.
|
||||
* Returns a new <mxCell> instance that represents the
|
||||
* given node.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* node - XML node that contains the cell data.
|
||||
* restoreStructures - Optional boolean indicating whether
|
||||
* the graph structure should be restored by calling insert
|
||||
* and insertEdge on the parent and terminals, respectively.
|
||||
* Default is true.
|
||||
*/
|
||||
mxCodec.prototype.decodeCell = function(node, restoreStructures)
|
||||
{
|
||||
restoreStructures = (restoreStructures != null) ? restoreStructures : true;
|
||||
var cell = null;
|
||||
|
||||
if (node != null && node.nodeType == mxConstants.NODETYPE_ELEMENT)
|
||||
{
|
||||
// Tries to find a codec for the given node name. If that does
|
||||
// not return a codec then the node is the user object (an XML node
|
||||
// that contains the mxCell, aka inversion).
|
||||
var decoder = mxCodecRegistry.getCodec(node.nodeName);
|
||||
|
||||
// Tries to find the codec for the cell inside the user object.
|
||||
// This assumes all node names inside the user object are either
|
||||
// not registered or they correspond to a class for cells.
|
||||
if (!this.isCellCodec(decoder))
|
||||
{
|
||||
var child = node.firstChild;
|
||||
|
||||
while (child != null && !this.isCellCodec(decoder))
|
||||
{
|
||||
decoder = mxCodecRegistry.getCodec(child.nodeName);
|
||||
child = child.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.isCellCodec(decoder))
|
||||
{
|
||||
decoder = mxCodecRegistry.getCodec(mxCell);
|
||||
}
|
||||
|
||||
cell = decoder.decode(this, node);
|
||||
|
||||
if (restoreStructures)
|
||||
{
|
||||
this.insertIntoGraph(cell);
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: insertIntoGraph
|
||||
*
|
||||
* Inserts the given cell into its parent and terminal cells.
|
||||
*/
|
||||
mxCodec.prototype.insertIntoGraph = function(cell)
|
||||
{
|
||||
var parent = cell.parent;
|
||||
var source = cell.getTerminal(true);
|
||||
var target = cell.getTerminal(false);
|
||||
|
||||
// Fixes possible inconsistencies during insert into graph
|
||||
cell.setTerminal(null, false);
|
||||
cell.setTerminal(null, true);
|
||||
cell.parent = null;
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
parent.insert(cell);
|
||||
}
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
source.insertEdge(cell, true);
|
||||
}
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
target.insertEdge(cell, false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: setAttribute
|
||||
*
|
||||
* Sets the attribute on the specified node to value. This is a
|
||||
* helper method that makes sure the attribute and value arguments
|
||||
* are not null.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* node - XML node to set the attribute for.
|
||||
* attributes - Attributename to be set.
|
||||
* value - New value of the attribute.
|
||||
*/
|
||||
mxCodec.prototype.setAttribute = function(node, attribute, value)
|
||||
{
|
||||
if (attribute != null && value != null)
|
||||
{
|
||||
node.setAttribute(attribute, value);
|
||||
}
|
||||
};
|
||||
137
main/inc/lib/mxgraph/src/js/io/mxCodecRegistry.js
Normal file
137
main/inc/lib/mxgraph/src/js/io/mxCodecRegistry.js
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
var mxCodecRegistry =
|
||||
{
|
||||
/**
|
||||
* Class: mxCodecRegistry
|
||||
*
|
||||
* Singleton class that acts as a global registry for codecs.
|
||||
*
|
||||
* Adding an <mxCodec>:
|
||||
*
|
||||
* 1. Define a default codec with a new instance of the
|
||||
* object to be handled.
|
||||
*
|
||||
* (code)
|
||||
* var codec = new mxObjectCodec(new mxGraphModel());
|
||||
* (end)
|
||||
*
|
||||
* 2. Define the functions required for encoding and decoding
|
||||
* objects.
|
||||
*
|
||||
* (code)
|
||||
* codec.encode = function(enc, obj) { ... }
|
||||
* codec.decode = function(dec, node, into) { ... }
|
||||
* (end)
|
||||
*
|
||||
* 3. Register the codec in the <mxCodecRegistry>.
|
||||
*
|
||||
* (code)
|
||||
* mxCodecRegistry.register(codec);
|
||||
* (end)
|
||||
*
|
||||
* <mxObjectCodec.decode> may be used to either create a new
|
||||
* instance of an object or to configure an existing instance,
|
||||
* in which case the into argument points to the existing
|
||||
* object. In this case, we say the codec "configures" the
|
||||
* object.
|
||||
*
|
||||
* Variable: codecs
|
||||
*
|
||||
* Maps from constructor names to codecs.
|
||||
*/
|
||||
codecs: [],
|
||||
|
||||
/**
|
||||
* Variable: aliases
|
||||
*
|
||||
* Maps from classnames to codecnames.
|
||||
*/
|
||||
aliases: [],
|
||||
|
||||
/**
|
||||
* Function: register
|
||||
*
|
||||
* Registers a new codec and associates the name of the template
|
||||
* constructor in the codec with the codec object.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* codec - <mxObjectCodec> to be registered.
|
||||
*/
|
||||
register: function(codec)
|
||||
{
|
||||
if (codec != null)
|
||||
{
|
||||
var name = codec.getName();
|
||||
mxCodecRegistry.codecs[name] = codec;
|
||||
|
||||
var classname = mxUtils.getFunctionName(codec.template.constructor);
|
||||
|
||||
if (classname != name)
|
||||
{
|
||||
mxCodecRegistry.addAlias(classname, name);
|
||||
}
|
||||
}
|
||||
|
||||
return codec;
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: addAlias
|
||||
*
|
||||
* Adds an alias for mapping a classname to a codecname.
|
||||
*/
|
||||
addAlias: function(classname, codecname)
|
||||
{
|
||||
mxCodecRegistry.aliases[classname] = codecname;
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: getCodec
|
||||
*
|
||||
* Returns a codec that handles objects that are constructed
|
||||
* using the given constructor.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* ctor - JavaScript constructor function.
|
||||
*/
|
||||
getCodec: function(ctor)
|
||||
{
|
||||
var codec = null;
|
||||
|
||||
if (ctor != null)
|
||||
{
|
||||
var name = mxUtils.getFunctionName(ctor);
|
||||
var tmp = mxCodecRegistry.aliases[name];
|
||||
|
||||
if (tmp != null)
|
||||
{
|
||||
name = tmp;
|
||||
}
|
||||
|
||||
codec = mxCodecRegistry.codecs[name];
|
||||
|
||||
// Registers a new default codec for the given constructor
|
||||
// if no codec has been previously defined.
|
||||
if (codec == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
codec = new mxObjectCodec(new ctor());
|
||||
mxCodecRegistry.register(codec);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codec;
|
||||
}
|
||||
|
||||
};
|
||||
88
main/inc/lib/mxgraph/src/js/io/mxDefaultKeyHandlerCodec.js
Normal file
88
main/inc/lib/mxgraph/src/js/io/mxDefaultKeyHandlerCodec.js
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxDefaultKeyHandlerCodec
|
||||
*
|
||||
* Custom codec for configuring <mxDefaultKeyHandler>s. This class is created
|
||||
* and registered dynamically at load time and used implicitely via
|
||||
* <mxCodec> and the <mxCodecRegistry>. This codec only reads configuration
|
||||
* data for existing key handlers, it does not encode or create key handlers.
|
||||
*/
|
||||
var codec = new mxObjectCodec(new mxDefaultKeyHandler());
|
||||
|
||||
/**
|
||||
* Function: encode
|
||||
*
|
||||
* Returns null.
|
||||
*/
|
||||
codec.encode = function(enc, obj)
|
||||
{
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decode
|
||||
*
|
||||
* Reads a sequence of the following child nodes
|
||||
* and attributes:
|
||||
*
|
||||
* Child Nodes:
|
||||
*
|
||||
* add - Binds a keystroke to an actionname.
|
||||
*
|
||||
* Attributes:
|
||||
*
|
||||
* as - Keycode.
|
||||
* action - Actionname to execute in editor.
|
||||
* control - Optional boolean indicating if
|
||||
* the control key must be pressed.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* (code)
|
||||
* <mxDefaultKeyHandler as="keyHandler">
|
||||
* <add as="88" control="true" action="cut"/>
|
||||
* <add as="67" control="true" action="copy"/>
|
||||
* <add as="86" control="true" action="paste"/>
|
||||
* </mxDefaultKeyHandler>
|
||||
* (end)
|
||||
*
|
||||
* The keycodes are for the x, c and v keys.
|
||||
*
|
||||
* See also: <mxDefaultKeyHandler.bindAction>,
|
||||
* http://www.js-examples.com/page/tutorials__key_codes.html
|
||||
*/
|
||||
codec.decode = function(dec, node, into)
|
||||
{
|
||||
if (into != null)
|
||||
{
|
||||
var editor = into.editor;
|
||||
node = node.firstChild;
|
||||
|
||||
while (node != null)
|
||||
{
|
||||
if (!this.processInclude(dec, node, into) &&
|
||||
node.nodeName == 'add')
|
||||
{
|
||||
var as = node.getAttribute('as');
|
||||
var action = node.getAttribute('action');
|
||||
var control = node.getAttribute('control');
|
||||
|
||||
into.bindAction(as, action, control);
|
||||
}
|
||||
|
||||
node = node.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
return into;
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
54
main/inc/lib/mxgraph/src/js/io/mxDefaultPopupMenuCodec.js
Normal file
54
main/inc/lib/mxgraph/src/js/io/mxDefaultPopupMenuCodec.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxDefaultPopupMenuCodec
|
||||
*
|
||||
* Custom codec for configuring <mxDefaultPopupMenu>s. This class is created
|
||||
* and registered dynamically at load time and used implicitely via
|
||||
* <mxCodec> and the <mxCodecRegistry>. This codec only reads configuration
|
||||
* data for existing popup menus, it does not encode or create menus. Note
|
||||
* that this codec only passes the configuration node to the popup menu,
|
||||
* which uses the config to dynamically create menus. See
|
||||
* <mxDefaultPopupMenu.createMenu>.
|
||||
*/
|
||||
var codec = new mxObjectCodec(new mxDefaultPopupMenu());
|
||||
|
||||
/**
|
||||
* Function: encode
|
||||
*
|
||||
* Returns null.
|
||||
*/
|
||||
codec.encode = function(enc, obj)
|
||||
{
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decode
|
||||
*
|
||||
* Uses the given node as the config for <mxDefaultPopupMenu>.
|
||||
*/
|
||||
codec.decode = function(dec, node, into)
|
||||
{
|
||||
var inc = node.getElementsByTagName('include')[0];
|
||||
|
||||
if (inc != null)
|
||||
{
|
||||
this.processInclude(dec, inc, into);
|
||||
}
|
||||
else if (into != null)
|
||||
{
|
||||
into.config = node;
|
||||
}
|
||||
|
||||
return into;
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
312
main/inc/lib/mxgraph/src/js/io/mxDefaultToolbarCodec.js
Normal file
312
main/inc/lib/mxgraph/src/js/io/mxDefaultToolbarCodec.js
Normal file
@@ -0,0 +1,312 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
* Class: mxDefaultToolbarCodec
|
||||
*
|
||||
* Custom codec for configuring <mxDefaultToolbar>s. This class is created
|
||||
* and registered dynamically at load time and used implicitely via
|
||||
* <mxCodec> and the <mxCodecRegistry>. This codec only reads configuration
|
||||
* data for existing toolbars handlers, it does not encode or create toolbars.
|
||||
*/
|
||||
var mxDefaultToolbarCodec = mxCodecRegistry.register(function()
|
||||
{
|
||||
var codec = new mxObjectCodec(new mxDefaultToolbar());
|
||||
|
||||
/**
|
||||
* Function: encode
|
||||
*
|
||||
* Returns null.
|
||||
*/
|
||||
codec.encode = function(enc, obj)
|
||||
{
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decode
|
||||
*
|
||||
* Reads a sequence of the following child nodes
|
||||
* and attributes:
|
||||
*
|
||||
* Child Nodes:
|
||||
*
|
||||
* add - Adds a new item to the toolbar. See below for attributes.
|
||||
* separator - Adds a vertical separator. No attributes.
|
||||
* hr - Adds a horizontal separator. No attributes.
|
||||
* br - Adds a linefeed. No attributes.
|
||||
*
|
||||
* Attributes:
|
||||
*
|
||||
* as - Resource key for the label.
|
||||
* action - Name of the action to execute in enclosing editor.
|
||||
* mode - Modename (see below).
|
||||
* template - Template name for cell insertion.
|
||||
* style - Optional style to override the template style.
|
||||
* icon - Icon (relative/absolute URL).
|
||||
* pressedIcon - Optional icon for pressed state (relative/absolute URL).
|
||||
* id - Optional ID to be used for the created DOM element.
|
||||
* toggle - Optional 0 or 1 to disable toggling of the element. Default is
|
||||
* 1 (true).
|
||||
*
|
||||
* The action, mode and template attributes are mutually exclusive. The
|
||||
* style can only be used with the template attribute. The add node may
|
||||
* contain another sequence of add nodes with as and action attributes
|
||||
* to create a combo box in the toolbar. If the icon is specified then
|
||||
* a list of the child node is expected to have its template attribute
|
||||
* set and the action is ignored instead.
|
||||
*
|
||||
* Nodes with a specified template may define a function to be used for
|
||||
* inserting the cloned template into the graph. Here is an example of such
|
||||
* a node:
|
||||
*
|
||||
* (code)
|
||||
* <add as="Swimlane" template="swimlane" icon="images/swimlane.gif"><![CDATA[
|
||||
* function (editor, cell, evt, targetCell)
|
||||
* {
|
||||
* var pt = mxUtils.convertPoint(
|
||||
* editor.graph.container, mxEvent.getClientX(evt),
|
||||
* mxEvent.getClientY(evt));
|
||||
* return editor.addVertex(targetCell, cell, pt.x, pt.y);
|
||||
* }
|
||||
* ]]></add>
|
||||
* (end)
|
||||
*
|
||||
* In the above function, editor is the enclosing <mxEditor> instance, cell
|
||||
* is the clone of the template, evt is the mouse event that represents the
|
||||
* drop and targetCell is the cell under the mousepointer where the drop
|
||||
* occurred. The targetCell is retrieved using <mxGraph.getCellAt>.
|
||||
*
|
||||
* Futhermore, nodes with the mode attribute may define a function to
|
||||
* be executed upon selection of the respective toolbar icon. In the
|
||||
* example below, the default edge style is set when this specific
|
||||
* connect-mode is activated:
|
||||
*
|
||||
* (code)
|
||||
* <add as="connect" mode="connect"><![CDATA[
|
||||
* function (editor)
|
||||
* {
|
||||
* if (editor.defaultEdge != null)
|
||||
* {
|
||||
* editor.defaultEdge.style = 'straightEdge';
|
||||
* }
|
||||
* }
|
||||
* ]]></add>
|
||||
* (end)
|
||||
*
|
||||
* Both functions require <mxDefaultToolbarCodec.allowEval> to be set to true.
|
||||
*
|
||||
* Modes:
|
||||
*
|
||||
* select - Left mouse button used for rubberband- & cell-selection.
|
||||
* connect - Allows connecting vertices by inserting new edges.
|
||||
* pan - Disables selection and switches to panning on the left button.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* To add items to the toolbar:
|
||||
*
|
||||
* (code)
|
||||
* <mxDefaultToolbar as="toolbar">
|
||||
* <add as="save" action="save" icon="images/save.gif"/>
|
||||
* <br/><hr/>
|
||||
* <add as="select" mode="select" icon="images/select.gif"/>
|
||||
* <add as="connect" mode="connect" icon="images/connect.gif"/>
|
||||
* </mxDefaultToolbar>
|
||||
* (end)
|
||||
*/
|
||||
codec.decode = function(dec, node, into)
|
||||
{
|
||||
if (into != null)
|
||||
{
|
||||
var editor = into.editor;
|
||||
node = node.firstChild;
|
||||
|
||||
while (node != null)
|
||||
{
|
||||
if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
|
||||
{
|
||||
if (!this.processInclude(dec, node, into))
|
||||
{
|
||||
if (node.nodeName == 'separator')
|
||||
{
|
||||
into.addSeparator();
|
||||
}
|
||||
else if (node.nodeName == 'br')
|
||||
{
|
||||
into.toolbar.addBreak();
|
||||
}
|
||||
else if (node.nodeName == 'hr')
|
||||
{
|
||||
into.toolbar.addLine();
|
||||
}
|
||||
else if (node.nodeName == 'add')
|
||||
{
|
||||
var as = node.getAttribute('as');
|
||||
as = mxResources.get(as) || as;
|
||||
var icon = node.getAttribute('icon');
|
||||
var pressedIcon = node.getAttribute('pressedIcon');
|
||||
var action = node.getAttribute('action');
|
||||
var mode = node.getAttribute('mode');
|
||||
var template = node.getAttribute('template');
|
||||
var toggle = node.getAttribute('toggle') != '0';
|
||||
var text = mxUtils.getTextContent(node);
|
||||
var elt = null;
|
||||
|
||||
if (action != null)
|
||||
{
|
||||
elt = into.addItem(as, icon, action, pressedIcon);
|
||||
}
|
||||
else if (mode != null)
|
||||
{
|
||||
var funct = (mxDefaultToolbarCodec.allowEval) ? mxUtils.eval(text) : null;
|
||||
elt = into.addMode(as, icon, mode, pressedIcon, funct);
|
||||
}
|
||||
else if (template != null || (text != null && text.length > 0))
|
||||
{
|
||||
var cell = editor.templates[template];
|
||||
var style = node.getAttribute('style');
|
||||
|
||||
if (cell != null && style != null)
|
||||
{
|
||||
cell = editor.graph.cloneCells([cell])[0];
|
||||
cell.setStyle(style);
|
||||
}
|
||||
|
||||
var insertFunction = null;
|
||||
|
||||
if (text != null && text.length > 0 && mxDefaultToolbarCodec.allowEval)
|
||||
{
|
||||
insertFunction = mxUtils.eval(text);
|
||||
}
|
||||
|
||||
elt = into.addPrototype(as, icon, cell, pressedIcon, insertFunction, toggle);
|
||||
}
|
||||
else
|
||||
{
|
||||
var children = mxUtils.getChildNodes(node);
|
||||
|
||||
if (children.length > 0)
|
||||
{
|
||||
if (icon == null)
|
||||
{
|
||||
var combo = into.addActionCombo(as);
|
||||
|
||||
for (var i=0; i<children.length; i++)
|
||||
{
|
||||
var child = children[i];
|
||||
|
||||
if (child.nodeName == 'separator')
|
||||
{
|
||||
into.addOption(combo, '---');
|
||||
}
|
||||
else if (child.nodeName == 'add')
|
||||
{
|
||||
var lab = child.getAttribute('as');
|
||||
var act = child.getAttribute('action');
|
||||
into.addActionOption(combo, lab, act);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var select = null;
|
||||
var create = function()
|
||||
{
|
||||
var template = editor.templates[select.value];
|
||||
|
||||
if (template != null)
|
||||
{
|
||||
var clone = template.clone();
|
||||
var style = select.options[select.selectedIndex].cellStyle;
|
||||
|
||||
if (style != null)
|
||||
{
|
||||
clone.setStyle(style);
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
else
|
||||
{
|
||||
mxLog.warn('Template '+template+' not found');
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
var img = into.addPrototype(as, icon, create, null, null, toggle);
|
||||
select = into.addCombo();
|
||||
|
||||
// Selects the toolbar icon if a selection change
|
||||
// is made in the corresponding combobox.
|
||||
mxEvent.addListener(select, 'change', function()
|
||||
{
|
||||
into.toolbar.selectMode(img, function(evt)
|
||||
{
|
||||
var pt = mxUtils.convertPoint(editor.graph.container,
|
||||
mxEvent.getClientX(evt), mxEvent.getClientY(evt));
|
||||
|
||||
return editor.addVertex(null, funct(), pt.x, pt.y);
|
||||
});
|
||||
|
||||
into.toolbar.noReset = false;
|
||||
});
|
||||
|
||||
// Adds the entries to the combobox
|
||||
for (var i=0; i<children.length; i++)
|
||||
{
|
||||
var child = children[i];
|
||||
|
||||
if (child.nodeName == 'separator')
|
||||
{
|
||||
into.addOption(select, '---');
|
||||
}
|
||||
else if (child.nodeName == 'add')
|
||||
{
|
||||
var lab = child.getAttribute('as');
|
||||
var tmp = child.getAttribute('template');
|
||||
var option = into.addOption(select, lab, tmp || template);
|
||||
option.cellStyle = child.getAttribute('style');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assigns an ID to the created element to access it later.
|
||||
if (elt != null)
|
||||
{
|
||||
var id = node.getAttribute('id');
|
||||
|
||||
if (id != null && id.length > 0)
|
||||
{
|
||||
elt.setAttribute('id', id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node = node.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
return into;
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
|
||||
/**
|
||||
* Variable: allowEval
|
||||
*
|
||||
* Static global switch that specifies if the use of eval is allowed for
|
||||
* evaluating text content. Default is true. Set this to false if stylesheets
|
||||
* may contain user input
|
||||
*/
|
||||
mxDefaultToolbarCodec.allowEval = true;
|
||||
245
main/inc/lib/mxgraph/src/js/io/mxEditorCodec.js
Normal file
245
main/inc/lib/mxgraph/src/js/io/mxEditorCodec.js
Normal file
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxEditorCodec
|
||||
*
|
||||
* Codec for <mxEditor>s. This class is created and registered
|
||||
* dynamically at load time and used implicitely via <mxCodec>
|
||||
* and the <mxCodecRegistry>.
|
||||
*
|
||||
* Transient Fields:
|
||||
*
|
||||
* - modified
|
||||
* - lastSnapshot
|
||||
* - ignoredChanges
|
||||
* - undoManager
|
||||
* - graphContainer
|
||||
* - toolbarContainer
|
||||
*/
|
||||
var codec = new mxObjectCodec(new mxEditor(),
|
||||
['modified', 'lastSnapshot', 'ignoredChanges',
|
||||
'undoManager', 'graphContainer', 'toolbarContainer']);
|
||||
|
||||
/**
|
||||
* Function: beforeDecode
|
||||
*
|
||||
* Decodes the ui-part of the configuration node by reading
|
||||
* a sequence of the following child nodes and attributes
|
||||
* and passes the control to the default decoding mechanism:
|
||||
*
|
||||
* Child Nodes:
|
||||
*
|
||||
* stylesheet - Adds a CSS stylesheet to the document.
|
||||
* resource - Adds the basename of a resource bundle.
|
||||
* add - Creates or configures a known UI element.
|
||||
*
|
||||
* These elements may appear in any order given that the
|
||||
* graph UI element is added before the toolbar element
|
||||
* (see Known Keys).
|
||||
*
|
||||
* Attributes:
|
||||
*
|
||||
* as - Key for the UI element (see below).
|
||||
* element - ID for the element in the document.
|
||||
* style - CSS style to be used for the element or window.
|
||||
* x - X coordinate for the new window.
|
||||
* y - Y coordinate for the new window.
|
||||
* width - Width for the new window.
|
||||
* height - Optional height for the new window.
|
||||
* name - Name of the stylesheet (absolute/relative URL).
|
||||
* basename - Basename of the resource bundle (see <mxResources>).
|
||||
*
|
||||
* The x, y, width and height attributes are used to create a new
|
||||
* <mxWindow> if the element attribute is not specified in an add
|
||||
* node. The name and basename are only used in the stylesheet and
|
||||
* resource nodes, respectively.
|
||||
*
|
||||
* Known Keys:
|
||||
*
|
||||
* graph - Main graph element (see <mxEditor.setGraphContainer>).
|
||||
* title - Title element (see <mxEditor.setTitleContainer>).
|
||||
* toolbar - Toolbar element (see <mxEditor.setToolbarContainer>).
|
||||
* status - Status bar element (see <mxEditor.setStatusContainer>).
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* (code)
|
||||
* <ui>
|
||||
* <stylesheet name="css/process.css"/>
|
||||
* <resource basename="resources/app"/>
|
||||
* <add as="graph" element="graph"
|
||||
* style="left:70px;right:20px;top:20px;bottom:40px"/>
|
||||
* <add as="status" element="status"/>
|
||||
* <add as="toolbar" x="10" y="20" width="54"/>
|
||||
* </ui>
|
||||
* (end)
|
||||
*/
|
||||
codec.afterDecode = function(dec, node, obj)
|
||||
{
|
||||
// Assigns the specified templates for edges
|
||||
var defaultEdge = node.getAttribute('defaultEdge');
|
||||
|
||||
if (defaultEdge != null)
|
||||
{
|
||||
node.removeAttribute('defaultEdge');
|
||||
obj.defaultEdge = obj.templates[defaultEdge];
|
||||
}
|
||||
|
||||
// Assigns the specified templates for groups
|
||||
var defaultGroup = node.getAttribute('defaultGroup');
|
||||
|
||||
if (defaultGroup != null)
|
||||
{
|
||||
node.removeAttribute('defaultGroup');
|
||||
obj.defaultGroup = obj.templates[defaultGroup];
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decodeChild
|
||||
*
|
||||
* Overrides decode child to handle special child nodes.
|
||||
*/
|
||||
codec.decodeChild = function(dec, child, obj)
|
||||
{
|
||||
if (child.nodeName == 'Array')
|
||||
{
|
||||
var role = child.getAttribute('as');
|
||||
|
||||
if (role == 'templates')
|
||||
{
|
||||
this.decodeTemplates(dec, child, obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (child.nodeName == 'ui')
|
||||
{
|
||||
this.decodeUi(dec, child, obj);
|
||||
return;
|
||||
}
|
||||
|
||||
mxObjectCodec.prototype.decodeChild.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decodeTemplates
|
||||
*
|
||||
* Decodes the cells from the given node as templates.
|
||||
*/
|
||||
codec.decodeUi = function(dec, node, editor)
|
||||
{
|
||||
var tmp = node.firstChild;
|
||||
while (tmp != null)
|
||||
{
|
||||
if (tmp.nodeName == 'add')
|
||||
{
|
||||
var as = tmp.getAttribute('as');
|
||||
var elt = tmp.getAttribute('element');
|
||||
var style = tmp.getAttribute('style');
|
||||
var element = null;
|
||||
|
||||
if (elt != null)
|
||||
{
|
||||
element = document.getElementById(elt);
|
||||
|
||||
if (element != null && style != null)
|
||||
{
|
||||
element.style.cssText += ';' + style;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var x = parseInt(tmp.getAttribute('x'));
|
||||
var y = parseInt(tmp.getAttribute('y'));
|
||||
var width = tmp.getAttribute('width');
|
||||
var height = tmp.getAttribute('height');
|
||||
|
||||
// Creates a new window around the element
|
||||
element = document.createElement('div');
|
||||
element.style.cssText = style;
|
||||
|
||||
var wnd = new mxWindow(mxResources.get(as) || as,
|
||||
element, x, y, width, height, false, true);
|
||||
wnd.setVisible(true);
|
||||
}
|
||||
|
||||
// TODO: Make more generic
|
||||
if (as == 'graph')
|
||||
{
|
||||
editor.setGraphContainer(element);
|
||||
}
|
||||
else if (as == 'toolbar')
|
||||
{
|
||||
editor.setToolbarContainer(element);
|
||||
}
|
||||
else if (as == 'title')
|
||||
{
|
||||
editor.setTitleContainer(element);
|
||||
}
|
||||
else if (as == 'status')
|
||||
{
|
||||
editor.setStatusContainer(element);
|
||||
}
|
||||
else if (as == 'map')
|
||||
{
|
||||
editor.setMapContainer(element);
|
||||
}
|
||||
}
|
||||
else if (tmp.nodeName == 'resource')
|
||||
{
|
||||
mxResources.add(tmp.getAttribute('basename'));
|
||||
}
|
||||
else if (tmp.nodeName == 'stylesheet')
|
||||
{
|
||||
mxClient.link('stylesheet', tmp.getAttribute('name'));
|
||||
}
|
||||
|
||||
tmp = tmp.nextSibling;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decodeTemplates
|
||||
*
|
||||
* Decodes the cells from the given node as templates.
|
||||
*/
|
||||
codec.decodeTemplates = function(dec, node, editor)
|
||||
{
|
||||
if (editor.templates == null)
|
||||
{
|
||||
editor.templates = [];
|
||||
}
|
||||
|
||||
var children = mxUtils.getChildNodes(node);
|
||||
for (var j=0; j<children.length; j++)
|
||||
{
|
||||
var name = children[j].getAttribute('as');
|
||||
var child = children[j].firstChild;
|
||||
|
||||
while (child != null && child.nodeType != 1)
|
||||
{
|
||||
child = child.nextSibling;
|
||||
}
|
||||
|
||||
if (child != null)
|
||||
{
|
||||
// LATER: Only single cells means you need
|
||||
// to group multiple cells within another
|
||||
// cell. This should be changed to support
|
||||
// arrays of cells, or the wrapper must
|
||||
// be automatically handled in this class.
|
||||
editor.templates[name] = dec.decodeCell(child);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
64
main/inc/lib/mxgraph/src/js/io/mxGenericChangeCodec.js
Normal file
64
main/inc/lib/mxgraph/src/js/io/mxGenericChangeCodec.js
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
* Class: mxGenericChangeCodec
|
||||
*
|
||||
* Codec for <mxValueChange>s, <mxStyleChange>s, <mxGeometryChange>s,
|
||||
* <mxCollapseChange>s and <mxVisibleChange>s. This class is created
|
||||
* and registered dynamically at load time and used implicitely
|
||||
* via <mxCodec> and the <mxCodecRegistry>.
|
||||
*
|
||||
* Transient Fields:
|
||||
*
|
||||
* - model
|
||||
* - previous
|
||||
*
|
||||
* Reference Fields:
|
||||
*
|
||||
* - cell
|
||||
*
|
||||
* Constructor: mxGenericChangeCodec
|
||||
*
|
||||
* Factory function that creates a <mxObjectCodec> for
|
||||
* the specified change and fieldname.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* obj - An instance of the change object.
|
||||
* variable - The fieldname for the change data.
|
||||
*/
|
||||
var mxGenericChangeCodec = function(obj, variable)
|
||||
{
|
||||
var codec = new mxObjectCodec(obj, ['model', 'previous'], ['cell']);
|
||||
|
||||
/**
|
||||
* Function: afterDecode
|
||||
*
|
||||
* Restores the state by assigning the previous value.
|
||||
*/
|
||||
codec.afterDecode = function(dec, node, obj)
|
||||
{
|
||||
// Allows forward references in sessions. This is a workaround
|
||||
// for the sequence of edits in mxGraph.moveCells and cellsAdded.
|
||||
if (mxUtils.isNode(obj.cell))
|
||||
{
|
||||
obj.cell = dec.decodeCell(obj.cell, false);
|
||||
}
|
||||
|
||||
obj.previous = obj[variable];
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
return codec;
|
||||
};
|
||||
|
||||
// Registers the codecs
|
||||
mxCodecRegistry.register(mxGenericChangeCodec(new mxValueChange(), 'value'));
|
||||
mxCodecRegistry.register(mxGenericChangeCodec(new mxStyleChange(), 'style'));
|
||||
mxCodecRegistry.register(mxGenericChangeCodec(new mxGeometryChange(), 'geometry'));
|
||||
mxCodecRegistry.register(mxGenericChangeCodec(new mxCollapseChange(), 'collapsed'));
|
||||
mxCodecRegistry.register(mxGenericChangeCodec(new mxVisibleChange(), 'visible'));
|
||||
mxCodecRegistry.register(mxGenericChangeCodec(new mxCellAttributeChange(), 'value'));
|
||||
28
main/inc/lib/mxgraph/src/js/io/mxGraphCodec.js
Normal file
28
main/inc/lib/mxgraph/src/js/io/mxGraphCodec.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxGraphCodec
|
||||
*
|
||||
* Codec for <mxGraph>s. This class is created and registered
|
||||
* dynamically at load time and used implicitely via <mxCodec>
|
||||
* and the <mxCodecRegistry>.
|
||||
*
|
||||
* Transient Fields:
|
||||
*
|
||||
* - graphListeners
|
||||
* - eventListeners
|
||||
* - view
|
||||
* - container
|
||||
* - cellRenderer
|
||||
* - editor
|
||||
* - selection
|
||||
*/
|
||||
return new mxObjectCodec(new mxGraph(),
|
||||
['graphListeners', 'eventListeners', 'view', 'container',
|
||||
'cellRenderer', 'editor', 'selection']);
|
||||
|
||||
}());
|
||||
197
main/inc/lib/mxgraph/src/js/io/mxGraphViewCodec.js
Normal file
197
main/inc/lib/mxgraph/src/js/io/mxGraphViewCodec.js
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxGraphViewCodec
|
||||
*
|
||||
* Custom encoder for <mxGraphView>s. This class is created
|
||||
* and registered dynamically at load time and used implicitely via
|
||||
* <mxCodec> and the <mxCodecRegistry>. This codec only writes views
|
||||
* into a XML format that can be used to create an image for
|
||||
* the graph, that is, it contains absolute coordinates with
|
||||
* computed perimeters, edge styles and cell styles.
|
||||
*/
|
||||
var codec = new mxObjectCodec(new mxGraphView());
|
||||
|
||||
/**
|
||||
* Function: encode
|
||||
*
|
||||
* Encodes the given <mxGraphView> using <encodeCell>
|
||||
* starting at the model's root. This returns the
|
||||
* top-level graph node of the recursive encoding.
|
||||
*/
|
||||
codec.encode = function(enc, view)
|
||||
{
|
||||
return this.encodeCell(enc, view,
|
||||
view.graph.getModel().getRoot());
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: encodeCell
|
||||
*
|
||||
* Recursively encodes the specifed cell. Uses layer
|
||||
* as the default nodename. If the cell's parent is
|
||||
* null, then graph is used for the nodename. If
|
||||
* <mxGraphModel.isEdge> returns true for the cell,
|
||||
* then edge is used for the nodename, else if
|
||||
* <mxGraphModel.isVertex> returns true for the cell,
|
||||
* then vertex is used for the nodename.
|
||||
*
|
||||
* <mxGraph.getLabel> is used to create the label
|
||||
* attribute for the cell. For graph nodes and vertices
|
||||
* the bounds are encoded into x, y, width and height.
|
||||
* For edges the points are encoded into a points
|
||||
* attribute as a space-separated list of comma-separated
|
||||
* coordinate pairs (eg. x0,y0 x1,y1 ... xn,yn). All
|
||||
* values from the cell style are added as attribute
|
||||
* values to the node.
|
||||
*/
|
||||
codec.encodeCell = function(enc, view, cell)
|
||||
{
|
||||
var model = view.graph.getModel();
|
||||
var state = view.getState(cell);
|
||||
var parent = model.getParent(cell);
|
||||
|
||||
if (parent == null || state != null)
|
||||
{
|
||||
var childCount = model.getChildCount(cell);
|
||||
var geo = view.graph.getCellGeometry(cell);
|
||||
var name = null;
|
||||
|
||||
if (parent == model.getRoot())
|
||||
{
|
||||
name = 'layer';
|
||||
}
|
||||
else if (parent == null)
|
||||
{
|
||||
name = 'graph';
|
||||
}
|
||||
else if (model.isEdge(cell))
|
||||
{
|
||||
name = 'edge';
|
||||
}
|
||||
else if (childCount > 0 && geo != null)
|
||||
{
|
||||
name = 'group';
|
||||
}
|
||||
else if (model.isVertex(cell))
|
||||
{
|
||||
name = 'vertex';
|
||||
}
|
||||
|
||||
if (name != null)
|
||||
{
|
||||
var node = enc.document.createElement(name);
|
||||
var lab = view.graph.getLabel(cell);
|
||||
|
||||
if (lab != null)
|
||||
{
|
||||
node.setAttribute('label', view.graph.getLabel(cell));
|
||||
|
||||
if (view.graph.isHtmlLabel(cell))
|
||||
{
|
||||
node.setAttribute('html', true);
|
||||
}
|
||||
}
|
||||
|
||||
if (parent == null)
|
||||
{
|
||||
var bounds = view.getGraphBounds();
|
||||
|
||||
if (bounds != null)
|
||||
{
|
||||
node.setAttribute('x', Math.round(bounds.x));
|
||||
node.setAttribute('y', Math.round(bounds.y));
|
||||
node.setAttribute('width', Math.round(bounds.width));
|
||||
node.setAttribute('height', Math.round(bounds.height));
|
||||
}
|
||||
|
||||
node.setAttribute('scale', view.scale);
|
||||
}
|
||||
else if (state != null && geo != null)
|
||||
{
|
||||
// Writes each key, value in the style pair to an attribute
|
||||
for (var i in state.style)
|
||||
{
|
||||
var value = state.style[i];
|
||||
|
||||
// Tries to turn objects and functions into strings
|
||||
if (typeof(value) == 'function' &&
|
||||
typeof(value) == 'object')
|
||||
{
|
||||
value = mxStyleRegistry.getName(value);
|
||||
}
|
||||
|
||||
if (value != null &&
|
||||
typeof(value) != 'function' &&
|
||||
typeof(value) != 'object')
|
||||
{
|
||||
node.setAttribute(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
var abs = state.absolutePoints;
|
||||
|
||||
// Writes the list of points into one attribute
|
||||
if (abs != null && abs.length > 0)
|
||||
{
|
||||
var pts = Math.round(abs[0].x) + ',' + Math.round(abs[0].y);
|
||||
|
||||
for (var i=1; i<abs.length; i++)
|
||||
{
|
||||
pts += ' ' + Math.round(abs[i].x) + ',' +
|
||||
Math.round(abs[i].y);
|
||||
}
|
||||
|
||||
node.setAttribute('points', pts);
|
||||
}
|
||||
|
||||
// Writes the bounds into 4 attributes
|
||||
else
|
||||
{
|
||||
node.setAttribute('x', Math.round(state.x));
|
||||
node.setAttribute('y', Math.round(state.y));
|
||||
node.setAttribute('width', Math.round(state.width));
|
||||
node.setAttribute('height', Math.round(state.height));
|
||||
}
|
||||
|
||||
var offset = state.absoluteOffset;
|
||||
|
||||
// Writes the offset into 2 attributes
|
||||
if (offset != null)
|
||||
{
|
||||
if (offset.x != 0)
|
||||
{
|
||||
node.setAttribute('dx', Math.round(offset.x));
|
||||
}
|
||||
|
||||
if (offset.y != 0)
|
||||
{
|
||||
node.setAttribute('dy', Math.round(offset.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i=0; i<childCount; i++)
|
||||
{
|
||||
var childNode = this.encodeCell(enc,
|
||||
view, model.getChildAt(cell, i));
|
||||
|
||||
if (childNode != null)
|
||||
{
|
||||
node.appendChild(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
80
main/inc/lib/mxgraph/src/js/io/mxModelCodec.js
Normal file
80
main/inc/lib/mxgraph/src/js/io/mxModelCodec.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxModelCodec
|
||||
*
|
||||
* Codec for <mxGraphModel>s. This class is created and registered
|
||||
* dynamically at load time and used implicitely via <mxCodec>
|
||||
* and the <mxCodecRegistry>.
|
||||
*/
|
||||
var codec = new mxObjectCodec(new mxGraphModel());
|
||||
|
||||
/**
|
||||
* Function: encodeObject
|
||||
*
|
||||
* Encodes the given <mxGraphModel> by writing a (flat) XML sequence of
|
||||
* cell nodes as produced by the <mxCellCodec>. The sequence is
|
||||
* wrapped-up in a node with the name root.
|
||||
*/
|
||||
codec.encodeObject = function(enc, obj, node)
|
||||
{
|
||||
var rootNode = enc.document.createElement('root');
|
||||
enc.encodeCell(obj.getRoot(), rootNode);
|
||||
node.appendChild(rootNode);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decodeChild
|
||||
*
|
||||
* Overrides decode child to handle special child nodes.
|
||||
*/
|
||||
codec.decodeChild = function(dec, child, obj)
|
||||
{
|
||||
if (child.nodeName == 'root')
|
||||
{
|
||||
this.decodeRoot(dec, child, obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
mxObjectCodec.prototype.decodeChild.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decodeRoot
|
||||
*
|
||||
* Reads the cells into the graph model. All cells
|
||||
* are children of the root element in the node.
|
||||
*/
|
||||
codec.decodeRoot = function(dec, root, model)
|
||||
{
|
||||
var rootCell = null;
|
||||
var tmp = root.firstChild;
|
||||
|
||||
while (tmp != null)
|
||||
{
|
||||
var cell = dec.decodeCell(tmp);
|
||||
|
||||
if (cell != null && cell.getParent() == null)
|
||||
{
|
||||
rootCell = cell;
|
||||
}
|
||||
|
||||
tmp = tmp.nextSibling;
|
||||
}
|
||||
|
||||
// Sets the root on the model if one has been decoded
|
||||
if (rootCell != null)
|
||||
{
|
||||
model.setRoot(rootCell);
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
1077
main/inc/lib/mxgraph/src/js/io/mxObjectCodec.js
Normal file
1077
main/inc/lib/mxgraph/src/js/io/mxObjectCodec.js
Normal file
File diff suppressed because it is too large
Load Diff
83
main/inc/lib/mxgraph/src/js/io/mxRootChangeCodec.js
Normal file
83
main/inc/lib/mxgraph/src/js/io/mxRootChangeCodec.js
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxRootChangeCodec
|
||||
*
|
||||
* Codec for <mxRootChange>s. This class is created and registered
|
||||
* dynamically at load time and used implicitely via <mxCodec> and
|
||||
* the <mxCodecRegistry>.
|
||||
*
|
||||
* Transient Fields:
|
||||
*
|
||||
* - model
|
||||
* - previous
|
||||
* - root
|
||||
*/
|
||||
var codec = new mxObjectCodec(new mxRootChange(),
|
||||
['model', 'previous', 'root']);
|
||||
|
||||
/**
|
||||
* Function: onEncode
|
||||
*
|
||||
* Encodes the child recursively.
|
||||
*/
|
||||
codec.afterEncode = function(enc, obj, node)
|
||||
{
|
||||
enc.encodeCell(obj.root, node);
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: beforeDecode
|
||||
*
|
||||
* Decodes the optional children as cells
|
||||
* using the respective decoder.
|
||||
*/
|
||||
codec.beforeDecode = function(dec, node, obj)
|
||||
{
|
||||
if (node.firstChild != null &&
|
||||
node.firstChild.nodeType == mxConstants.NODETYPE_ELEMENT)
|
||||
{
|
||||
// Makes sure the original node isn't modified
|
||||
node = node.cloneNode(true);
|
||||
|
||||
var tmp = node.firstChild;
|
||||
obj.root = dec.decodeCell(tmp, false);
|
||||
|
||||
var tmp2 = tmp.nextSibling;
|
||||
tmp.parentNode.removeChild(tmp);
|
||||
tmp = tmp2;
|
||||
|
||||
while (tmp != null)
|
||||
{
|
||||
tmp2 = tmp.nextSibling;
|
||||
dec.decodeCell(tmp);
|
||||
tmp.parentNode.removeChild(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: afterDecode
|
||||
*
|
||||
* Restores the state by assigning the previous value.
|
||||
*/
|
||||
codec.afterDecode = function(dec, node, obj)
|
||||
{
|
||||
obj.previous = obj.root;
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
217
main/inc/lib/mxgraph/src/js/io/mxStylesheetCodec.js
Normal file
217
main/inc/lib/mxgraph/src/js/io/mxStylesheetCodec.js
Normal file
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
* Class: mxStylesheetCodec
|
||||
*
|
||||
* Codec for <mxStylesheet>s. This class is created and registered
|
||||
* dynamically at load time and used implicitely via <mxCodec>
|
||||
* and the <mxCodecRegistry>.
|
||||
*/
|
||||
var mxStylesheetCodec = mxCodecRegistry.register(function()
|
||||
{
|
||||
var codec = new mxObjectCodec(new mxStylesheet());
|
||||
|
||||
/**
|
||||
* Function: encode
|
||||
*
|
||||
* Encodes a stylesheet. See <decode> for a description of the
|
||||
* format.
|
||||
*/
|
||||
codec.encode = function(enc, obj)
|
||||
{
|
||||
var node = enc.document.createElement(this.getName());
|
||||
|
||||
for (var i in obj.styles)
|
||||
{
|
||||
var style = obj.styles[i];
|
||||
var styleNode = enc.document.createElement('add');
|
||||
|
||||
if (i != null)
|
||||
{
|
||||
styleNode.setAttribute('as', i);
|
||||
|
||||
for (var j in style)
|
||||
{
|
||||
var value = this.getStringValue(j, style[j]);
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
var entry = enc.document.createElement('add');
|
||||
entry.setAttribute('value', value);
|
||||
entry.setAttribute('as', j);
|
||||
styleNode.appendChild(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (styleNode.childNodes.length > 0)
|
||||
{
|
||||
node.appendChild(styleNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getStringValue
|
||||
*
|
||||
* Returns the string for encoding the given value.
|
||||
*/
|
||||
codec.getStringValue = function(key, value)
|
||||
{
|
||||
var type = typeof(value);
|
||||
|
||||
if (type == 'function')
|
||||
{
|
||||
value = mxStyleRegistry.getName(style[j]);
|
||||
}
|
||||
else if (type == 'object')
|
||||
{
|
||||
value = null;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: decode
|
||||
*
|
||||
* Reads a sequence of the following child nodes
|
||||
* and attributes:
|
||||
*
|
||||
* Child Nodes:
|
||||
*
|
||||
* add - Adds a new style.
|
||||
*
|
||||
* Attributes:
|
||||
*
|
||||
* as - Name of the style.
|
||||
* extend - Name of the style to inherit from.
|
||||
*
|
||||
* Each node contains another sequence of add and remove nodes with the following
|
||||
* attributes:
|
||||
*
|
||||
* as - Name of the style (see <mxConstants>).
|
||||
* value - Value for the style.
|
||||
*
|
||||
* Instead of the value-attribute, one can put Javascript expressions into
|
||||
* the node as follows if <mxStylesheetCodec.allowEval> is true:
|
||||
* <add as="perimeter">mxPerimeter.RectanglePerimeter</add>
|
||||
*
|
||||
* A remove node will remove the entry with the name given in the as-attribute
|
||||
* from the style.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* (code)
|
||||
* <mxStylesheet as="stylesheet">
|
||||
* <add as="text">
|
||||
* <add as="fontSize" value="12"/>
|
||||
* </add>
|
||||
* <add as="defaultVertex" extend="text">
|
||||
* <add as="shape" value="rectangle"/>
|
||||
* </add>
|
||||
* </mxStylesheet>
|
||||
* (end)
|
||||
*/
|
||||
codec.decode = function(dec, node, into)
|
||||
{
|
||||
var obj = into || new this.template.constructor();
|
||||
var id = node.getAttribute('id');
|
||||
|
||||
if (id != null)
|
||||
{
|
||||
dec.objects[id] = obj;
|
||||
}
|
||||
|
||||
node = node.firstChild;
|
||||
|
||||
while (node != null)
|
||||
{
|
||||
if (!this.processInclude(dec, node, obj) && node.nodeName == 'add')
|
||||
{
|
||||
var as = node.getAttribute('as');
|
||||
|
||||
if (as != null)
|
||||
{
|
||||
var extend = node.getAttribute('extend');
|
||||
var style = (extend != null) ? mxUtils.clone(obj.styles[extend]) : null;
|
||||
|
||||
if (style == null)
|
||||
{
|
||||
if (extend != null)
|
||||
{
|
||||
mxLog.warn('mxStylesheetCodec.decode: stylesheet ' +
|
||||
extend + ' not found to extend');
|
||||
}
|
||||
|
||||
style = new Object();
|
||||
}
|
||||
|
||||
var entry = node.firstChild;
|
||||
|
||||
while (entry != null)
|
||||
{
|
||||
if (entry.nodeType == mxConstants.NODETYPE_ELEMENT)
|
||||
{
|
||||
var key = entry.getAttribute('as');
|
||||
|
||||
if (entry.nodeName == 'add')
|
||||
{
|
||||
var text = mxUtils.getTextContent(entry);
|
||||
var value = null;
|
||||
|
||||
if (text != null && text.length > 0 && mxStylesheetCodec.allowEval)
|
||||
{
|
||||
value = mxUtils.eval(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = entry.getAttribute('value');
|
||||
|
||||
if (mxUtils.isNumeric(value))
|
||||
{
|
||||
value = parseFloat(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
style[key] = value;
|
||||
}
|
||||
}
|
||||
else if (entry.nodeName == 'remove')
|
||||
{
|
||||
delete style[key];
|
||||
}
|
||||
}
|
||||
|
||||
entry = entry.nextSibling;
|
||||
}
|
||||
|
||||
obj.putCellStyle(as, style);
|
||||
}
|
||||
}
|
||||
|
||||
node = node.nextSibling;
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
|
||||
/**
|
||||
* Variable: allowEval
|
||||
*
|
||||
* Static global switch that specifies if the use of eval is allowed for
|
||||
* evaluating text content. Default is true. Set this to false if stylesheets
|
||||
* may contain user input.
|
||||
*/
|
||||
mxStylesheetCodec.allowEval = true;
|
||||
42
main/inc/lib/mxgraph/src/js/io/mxTerminalChangeCodec.js
Normal file
42
main/inc/lib/mxgraph/src/js/io/mxTerminalChangeCodec.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
mxCodecRegistry.register(function()
|
||||
{
|
||||
/**
|
||||
* Class: mxTerminalChangeCodec
|
||||
*
|
||||
* Codec for <mxTerminalChange>s. This class is created and registered
|
||||
* dynamically at load time and used implicitely via <mxCodec> and
|
||||
* the <mxCodecRegistry>.
|
||||
*
|
||||
* Transient Fields:
|
||||
*
|
||||
* - model
|
||||
* - previous
|
||||
*
|
||||
* Reference Fields:
|
||||
*
|
||||
* - cell
|
||||
* - terminal
|
||||
*/
|
||||
var codec = new mxObjectCodec(new mxTerminalChange(),
|
||||
['model', 'previous'], ['cell', 'terminal']);
|
||||
|
||||
/**
|
||||
* Function: afterDecode
|
||||
*
|
||||
* Restores the state by assigning the previous value.
|
||||
*/
|
||||
codec.afterDecode = function(dec, node, obj)
|
||||
{
|
||||
obj.previous = obj.terminal;
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Returns the codec into the registry
|
||||
return codec;
|
||||
|
||||
}());
|
||||
Reference in New Issue
Block a user