mxDefaultToolbarCodec.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /**
  2. * Copyright (c) 2006-2015, JGraph Ltd
  3. * Copyright (c) 2006-2015, Gaudenz Alder
  4. */
  5. /**
  6. * Class: mxDefaultToolbarCodec
  7. *
  8. * Custom codec for configuring <mxDefaultToolbar>s. This class is created
  9. * and registered dynamically at load time and used implicitly via
  10. * <mxCodec> and the <mxCodecRegistry>. This codec only reads configuration
  11. * data for existing toolbars handlers, it does not encode or create toolbars.
  12. */
  13. var mxDefaultToolbarCodec = mxCodecRegistry.register(function()
  14. {
  15. var codec = new mxObjectCodec(new mxDefaultToolbar());
  16. /**
  17. * Function: encode
  18. *
  19. * Returns null.
  20. */
  21. codec.encode = function(enc, obj)
  22. {
  23. return null;
  24. };
  25. /**
  26. * Function: decode
  27. *
  28. * Reads a sequence of the following child nodes
  29. * and attributes:
  30. *
  31. * Child Nodes:
  32. *
  33. * add - Adds a new item to the toolbar. See below for attributes.
  34. * separator - Adds a vertical separator. No attributes.
  35. * hr - Adds a horizontal separator. No attributes.
  36. * br - Adds a linefeed. No attributes.
  37. *
  38. * Attributes:
  39. *
  40. * as - Resource key for the label.
  41. * action - Name of the action to execute in enclosing editor.
  42. * mode - Modename (see below).
  43. * template - Template name for cell insertion.
  44. * style - Optional style to override the template style.
  45. * icon - Icon (relative/absolute URL).
  46. * pressedIcon - Optional icon for pressed state (relative/absolute URL).
  47. * id - Optional ID to be used for the created DOM element.
  48. * toggle - Optional 0 or 1 to disable toggling of the element. Default is
  49. * 1 (true).
  50. *
  51. * The action, mode and template attributes are mutually exclusive. The
  52. * style can only be used with the template attribute. The add node may
  53. * contain another sequence of add nodes with as and action attributes
  54. * to create a combo box in the toolbar. If the icon is specified then
  55. * a list of the child node is expected to have its template attribute
  56. * set and the action is ignored instead.
  57. *
  58. * Nodes with a specified template may define a function to be used for
  59. * inserting the cloned template into the graph. Here is an example of such
  60. * a node:
  61. *
  62. * (code)
  63. * <add as="Swimlane" template="swimlane" icon="images/swimlane.gif"><![CDATA[
  64. * function (editor, cell, evt, targetCell)
  65. * {
  66. * var pt = mxUtils.convertPoint(
  67. * editor.graph.container, mxEvent.getClientX(evt),
  68. * mxEvent.getClientY(evt));
  69. * return editor.addVertex(targetCell, cell, pt.x, pt.y);
  70. * }
  71. * ]]></add>
  72. * (end)
  73. *
  74. * In the above function, editor is the enclosing <mxEditor> instance, cell
  75. * is the clone of the template, evt is the mouse event that represents the
  76. * drop and targetCell is the cell under the mousepointer where the drop
  77. * occurred. The targetCell is retrieved using <mxGraph.getCellAt>.
  78. *
  79. * Futhermore, nodes with the mode attribute may define a function to
  80. * be executed upon selection of the respective toolbar icon. In the
  81. * example below, the default edge style is set when this specific
  82. * connect-mode is activated:
  83. *
  84. * (code)
  85. * <add as="connect" mode="connect"><![CDATA[
  86. * function (editor)
  87. * {
  88. * if (editor.defaultEdge != null)
  89. * {
  90. * editor.defaultEdge.style = 'straightEdge';
  91. * }
  92. * }
  93. * ]]></add>
  94. * (end)
  95. *
  96. * Both functions require <mxDefaultToolbarCodec.allowEval> to be set to true.
  97. *
  98. * Modes:
  99. *
  100. * select - Left mouse button used for rubberband- & cell-selection.
  101. * connect - Allows connecting vertices by inserting new edges.
  102. * pan - Disables selection and switches to panning on the left button.
  103. *
  104. * Example:
  105. *
  106. * To add items to the toolbar:
  107. *
  108. * (code)
  109. * <mxDefaultToolbar as="toolbar">
  110. * <add as="save" action="save" icon="images/save.gif"/>
  111. * <br/><hr/>
  112. * <add as="select" mode="select" icon="images/select.gif"/>
  113. * <add as="connect" mode="connect" icon="images/connect.gif"/>
  114. * </mxDefaultToolbar>
  115. * (end)
  116. */
  117. codec.decode = function(dec, node, into)
  118. {
  119. if (into != null)
  120. {
  121. var editor = into.editor;
  122. node = node.firstChild;
  123. while (node != null)
  124. {
  125. if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
  126. {
  127. if (!this.processInclude(dec, node, into))
  128. {
  129. if (node.nodeName == 'separator')
  130. {
  131. into.addSeparator();
  132. }
  133. else if (node.nodeName == 'br')
  134. {
  135. into.toolbar.addBreak();
  136. }
  137. else if (node.nodeName == 'hr')
  138. {
  139. into.toolbar.addLine();
  140. }
  141. else if (node.nodeName == 'add')
  142. {
  143. var as = node.getAttribute('as');
  144. as = mxResources.get(as) || as;
  145. var icon = node.getAttribute('icon');
  146. var pressedIcon = node.getAttribute('pressedIcon');
  147. var action = node.getAttribute('action');
  148. var mode = node.getAttribute('mode');
  149. var template = node.getAttribute('template');
  150. var toggle = node.getAttribute('toggle') != '0';
  151. var text = mxUtils.getTextContent(node);
  152. var elt = null;
  153. if (action != null)
  154. {
  155. elt = into.addItem(as, icon, action, pressedIcon);
  156. }
  157. else if (mode != null)
  158. {
  159. var funct = (mxDefaultToolbarCodec.allowEval) ? mxUtils.eval(text) : null;
  160. elt = into.addMode(as, icon, mode, pressedIcon, funct);
  161. }
  162. else if (template != null || (text != null && text.length > 0))
  163. {
  164. var cell = editor.templates[template];
  165. var style = node.getAttribute('style');
  166. if (cell != null && style != null)
  167. {
  168. cell = editor.graph.cloneCell(cell);
  169. cell.setStyle(style);
  170. }
  171. var insertFunction = null;
  172. if (text != null && text.length > 0 && mxDefaultToolbarCodec.allowEval)
  173. {
  174. insertFunction = mxUtils.eval(text);
  175. }
  176. elt = into.addPrototype(as, icon, cell, pressedIcon, insertFunction, toggle);
  177. }
  178. else
  179. {
  180. var children = mxUtils.getChildNodes(node);
  181. if (children.length > 0)
  182. {
  183. if (icon == null)
  184. {
  185. var combo = into.addActionCombo(as);
  186. for (var i=0; i<children.length; i++)
  187. {
  188. var child = children[i];
  189. if (child.nodeName == 'separator')
  190. {
  191. into.addOption(combo, '---');
  192. }
  193. else if (child.nodeName == 'add')
  194. {
  195. var lab = child.getAttribute('as');
  196. var act = child.getAttribute('action');
  197. into.addActionOption(combo, lab, act);
  198. }
  199. }
  200. }
  201. else
  202. {
  203. var select = null;
  204. var create = function()
  205. {
  206. var template = editor.templates[select.value];
  207. if (template != null)
  208. {
  209. var clone = template.clone();
  210. var style = select.options[select.selectedIndex].cellStyle;
  211. if (style != null)
  212. {
  213. clone.setStyle(style);
  214. }
  215. return clone;
  216. }
  217. else
  218. {
  219. mxLog.warn('Template '+template+' not found');
  220. }
  221. return null;
  222. };
  223. var img = into.addPrototype(as, icon, create, null, null, toggle);
  224. select = into.addCombo();
  225. // Selects the toolbar icon if a selection change
  226. // is made in the corresponding combobox.
  227. mxEvent.addListener(select, 'change', function()
  228. {
  229. into.toolbar.selectMode(img, function(evt)
  230. {
  231. var pt = mxUtils.convertPoint(editor.graph.container,
  232. mxEvent.getClientX(evt), mxEvent.getClientY(evt));
  233. return editor.addVertex(null, funct(), pt.x, pt.y);
  234. });
  235. into.toolbar.noReset = false;
  236. });
  237. // Adds the entries to the combobox
  238. for (var i=0; i<children.length; i++)
  239. {
  240. var child = children[i];
  241. if (child.nodeName == 'separator')
  242. {
  243. into.addOption(select, '---');
  244. }
  245. else if (child.nodeName == 'add')
  246. {
  247. var lab = child.getAttribute('as');
  248. var tmp = child.getAttribute('template');
  249. var option = into.addOption(select, lab, tmp || template);
  250. option.cellStyle = child.getAttribute('style');
  251. }
  252. }
  253. }
  254. }
  255. }
  256. // Assigns an ID to the created element to access it later.
  257. if (elt != null)
  258. {
  259. var id = node.getAttribute('id');
  260. if (id != null && id.length > 0)
  261. {
  262. elt.setAttribute('id', id);
  263. }
  264. }
  265. }
  266. }
  267. }
  268. node = node.nextSibling;
  269. }
  270. }
  271. return into;
  272. };
  273. // Returns the codec into the registry
  274. return codec;
  275. }());
  276. /**
  277. * Variable: allowEval
  278. *
  279. * Static global switch that specifies if the use of eval is allowed for
  280. * evaluating text content. Default is true. Set this to false if stylesheets
  281. * may contain user input
  282. */
  283. mxDefaultToolbarCodec.allowEval = true;
  284. __mxOutput.mxDefaultToolbarCodec = typeof mxDefaultToolbarCodec !== 'undefined' ? mxDefaultToolbarCodec : undefined;