mxStylesheetCodec.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /**
  2. * Copyright (c) 2006-2015, JGraph Ltd
  3. * Copyright (c) 2006-2015, Gaudenz Alder
  4. */
  5. /**
  6. * Class: mxStylesheetCodec
  7. *
  8. * Codec for <mxStylesheet>s. This class is created and registered
  9. * dynamically at load time and used implicitly via <mxCodec>
  10. * and the <mxCodecRegistry>.
  11. */
  12. var mxStylesheetCodec = mxCodecRegistry.register(function()
  13. {
  14. var codec = new mxObjectCodec(new mxStylesheet());
  15. /**
  16. * Function: encode
  17. *
  18. * Encodes a stylesheet. See <decode> for a description of the
  19. * format.
  20. */
  21. codec.encode = function(enc, obj)
  22. {
  23. var node = enc.document.createElement(this.getName());
  24. for (var i in obj.styles)
  25. {
  26. var style = obj.styles[i];
  27. var styleNode = enc.document.createElement('add');
  28. if (i != null)
  29. {
  30. styleNode.setAttribute('as', i);
  31. for (var j in style)
  32. {
  33. var value = this.getStringValue(j, style[j]);
  34. if (value != null)
  35. {
  36. var entry = enc.document.createElement('add');
  37. entry.setAttribute('value', value);
  38. entry.setAttribute('as', j);
  39. styleNode.appendChild(entry);
  40. }
  41. }
  42. if (styleNode.childNodes.length > 0)
  43. {
  44. node.appendChild(styleNode);
  45. }
  46. }
  47. }
  48. return node;
  49. };
  50. /**
  51. * Function: getStringValue
  52. *
  53. * Returns the string for encoding the given value.
  54. */
  55. codec.getStringValue = function(key, value)
  56. {
  57. var type = typeof(value);
  58. if (type == 'function')
  59. {
  60. value = mxStyleRegistry.getName(value);
  61. }
  62. else if (type == 'object')
  63. {
  64. value = null;
  65. }
  66. return value;
  67. };
  68. /**
  69. * Function: decode
  70. *
  71. * Reads a sequence of the following child nodes
  72. * and attributes:
  73. *
  74. * Child Nodes:
  75. *
  76. * add - Adds a new style.
  77. *
  78. * Attributes:
  79. *
  80. * as - Name of the style.
  81. * extend - Name of the style to inherit from.
  82. *
  83. * Each node contains another sequence of add and remove nodes with the following
  84. * attributes:
  85. *
  86. * as - Name of the style (see <mxConstants>).
  87. * value - Value for the style.
  88. *
  89. * Instead of the value-attribute, one can put Javascript expressions into
  90. * the node as follows if <mxStylesheetCodec.allowEval> is true:
  91. * <add as="perimeter">mxPerimeter.RectanglePerimeter</add>
  92. *
  93. * A remove node will remove the entry with the name given in the as-attribute
  94. * from the style.
  95. *
  96. * Example:
  97. *
  98. * (code)
  99. * <mxStylesheet as="stylesheet">
  100. * <add as="text">
  101. * <add as="fontSize" value="12"/>
  102. * </add>
  103. * <add as="defaultVertex" extend="text">
  104. * <add as="shape" value="rectangle"/>
  105. * </add>
  106. * </mxStylesheet>
  107. * (end)
  108. */
  109. codec.decode = function(dec, node, into)
  110. {
  111. var obj = into || new this.template.constructor();
  112. var id = node.getAttribute('id');
  113. if (id != null)
  114. {
  115. dec.objects[id] = obj;
  116. }
  117. node = node.firstChild;
  118. while (node != null)
  119. {
  120. if (!this.processInclude(dec, node, obj) && node.nodeName == 'add')
  121. {
  122. var as = node.getAttribute('as');
  123. if (as != null)
  124. {
  125. var extend = node.getAttribute('extend');
  126. var style = (extend != null) ? mxUtils.clone(obj.styles[extend]) : null;
  127. if (style == null)
  128. {
  129. if (extend != null)
  130. {
  131. mxLog.warn('mxStylesheetCodec.decode: stylesheet ' +
  132. extend + ' not found to extend');
  133. }
  134. style = new Object();
  135. }
  136. var entry = node.firstChild;
  137. while (entry != null)
  138. {
  139. if (entry.nodeType == mxConstants.NODETYPE_ELEMENT)
  140. {
  141. var key = entry.getAttribute('as');
  142. if (entry.nodeName == 'add')
  143. {
  144. var text = mxUtils.getTextContent(entry);
  145. var value = null;
  146. if (text != null && text.length > 0 && mxStylesheetCodec.allowEval)
  147. {
  148. value = mxUtils.eval(text);
  149. }
  150. else
  151. {
  152. value = entry.getAttribute('value');
  153. if (mxUtils.isNumeric(value))
  154. {
  155. value = parseFloat(value);
  156. }
  157. }
  158. if (value != null)
  159. {
  160. style[key] = value;
  161. }
  162. }
  163. else if (entry.nodeName == 'remove')
  164. {
  165. delete style[key];
  166. }
  167. }
  168. entry = entry.nextSibling;
  169. }
  170. obj.putCellStyle(as, style);
  171. }
  172. }
  173. node = node.nextSibling;
  174. }
  175. return obj;
  176. };
  177. // Returns the codec into the registry
  178. return codec;
  179. }());
  180. /**
  181. * Variable: allowEval
  182. *
  183. * Static global switch that specifies if the use of eval is allowed for
  184. * evaluating text content. Default is true. Set this to false if stylesheets
  185. * may contain user input.
  186. */
  187. mxStylesheetCodec.allowEval = true;
  188. __mxOutput.mxStylesheetCodec = typeof mxStylesheetCodec !== 'undefined' ? mxStylesheetCodec : undefined;