sch_test/mxclient/js/io/mxEditorCodec.js

246 lines
6.0 KiB
JavaScript

/**
* 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 implicitly 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: decodeUi
*
* Decodes the ui elements from the given node.
*/
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;
}());