Utils.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. 'use strict';
  2. var domQuery = require('min-dom').query,
  3. domClear = require('min-dom').clear,
  4. is = require('bpmn-js/lib/util/ModelUtil').is,
  5. forEach = require('lodash/forEach'),
  6. domify = require('min-dom').domify,
  7. Ids = require('ids').default;
  8. var SPACE_REGEX = /\s/;
  9. // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar
  10. var QNAME_REGEX = /^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i;
  11. // for ID validation as per BPMN Schema (QName - Namespace)
  12. var ID_REGEX = /^[a-z_][\w-.]*$/i;
  13. var PLACEHOLDER_REGEX = /\$\{([^}]*)\}/g;
  14. var HTML_ESCAPE_MAP = {
  15. '&': '&',
  16. '<': '&lt;',
  17. '>': '&gt;',
  18. '"': '&quot;',
  19. '\'': '&#39;'
  20. };
  21. function selectedOption(selectBox) {
  22. if (selectBox.selectedIndex >= 0) {
  23. return selectBox.options[selectBox.selectedIndex].value;
  24. }
  25. }
  26. module.exports.selectedOption = selectedOption;
  27. function selectedType(elementSyntax, inputNode) {
  28. var typeSelect = domQuery(elementSyntax, inputNode);
  29. return selectedOption(typeSelect);
  30. }
  31. module.exports.selectedType = selectedType;
  32. /**
  33. * Retrieve the root element the document this
  34. * business object is contained in.
  35. *
  36. * @return {ModdleElement}
  37. */
  38. function getRoot(businessObject) {
  39. var parent = businessObject;
  40. while (parent.$parent) {
  41. parent = parent.$parent;
  42. }
  43. return parent;
  44. }
  45. module.exports.getRoot = getRoot;
  46. /**
  47. * filters all elements in the list which have a given type.
  48. * removes a new list
  49. */
  50. function filterElementsByType(objectList, type) {
  51. var list = objectList || [];
  52. var result = [];
  53. forEach(list, function(obj) {
  54. if (is(obj, type)) {
  55. result.push(obj);
  56. }
  57. });
  58. return result;
  59. }
  60. module.exports.filterElementsByType = filterElementsByType;
  61. function findRootElementsByType(businessObject, referencedType) {
  62. var root = getRoot(businessObject);
  63. return filterElementsByType(root.rootElements, referencedType);
  64. }
  65. module.exports.findRootElementsByType = findRootElementsByType;
  66. function removeAllChildren(domElement) {
  67. while (domElement.firstChild) {
  68. domElement.removeChild(domElement.firstChild);
  69. }
  70. }
  71. module.exports.removeAllChildren = removeAllChildren;
  72. /**
  73. * adds an empty option to the list
  74. */
  75. function addEmptyParameter(list) {
  76. return list.push({ 'label': '', 'value': '', 'name': '' });
  77. }
  78. module.exports.addEmptyParameter = addEmptyParameter;
  79. /**
  80. * returns a list with all root elements for the given parameter 'referencedType'
  81. */
  82. function refreshOptionsModel(businessObject, referencedType) {
  83. var model = [];
  84. var referableObjects = findRootElementsByType(businessObject, referencedType);
  85. forEach(referableObjects, function(obj) {
  86. model.push({
  87. label: (obj.name || '') + ' (id='+obj.id+')',
  88. value: obj.id,
  89. name: obj.name
  90. });
  91. });
  92. return model;
  93. }
  94. module.exports.refreshOptionsModel = refreshOptionsModel;
  95. /**
  96. * fills the drop down with options
  97. */
  98. function updateOptionsDropDown(domSelector, businessObject, referencedType, entryNode) {
  99. var options = refreshOptionsModel(businessObject, referencedType);
  100. addEmptyParameter(options);
  101. var selectBox = domQuery(domSelector, entryNode);
  102. domClear(selectBox);
  103. forEach(options, function(option) {
  104. var optionEntry = domify('<option value="' + escapeHTML(option.value) + '">' + escapeHTML(option.label) + '</option>');
  105. selectBox.appendChild(optionEntry);
  106. });
  107. return options;
  108. }
  109. module.exports.updateOptionsDropDown = updateOptionsDropDown;
  110. /**
  111. * checks whether the id value is valid
  112. *
  113. * @param {ModdleElement} bo
  114. * @param {String} idValue
  115. * @param {Function} translate
  116. *
  117. * @return {String} error message
  118. */
  119. function isIdValid(bo, idValue, translate) {
  120. var assigned = bo.$model.ids.assigned(idValue);
  121. var idExists = assigned && assigned !== bo;
  122. if (!idValue || idExists) {
  123. return translate('Element must have an unique id.');
  124. }
  125. return validateId(idValue, translate);
  126. }
  127. module.exports.isIdValid = isIdValid;
  128. function validateId(idValue, translate) {
  129. idValue = stripPlaceholders(idValue);
  130. if (containsSpace(idValue)) {
  131. return translate('Id must not contain spaces.');
  132. }
  133. if (!ID_REGEX.test(idValue)) {
  134. if (QNAME_REGEX.test(idValue)) {
  135. return translate('Id must not contain prefix.');
  136. }
  137. return translate('Id must be a valid QName.');
  138. }
  139. }
  140. module.exports.validateId = validateId;
  141. function containsSpace(value) {
  142. return SPACE_REGEX.test(value);
  143. }
  144. module.exports.containsSpace = containsSpace;
  145. function stripPlaceholders(idValue) {
  146. // replace expression e.g. ${VERSION_TAG}
  147. // use only the content between ${}
  148. // for the REGEX check
  149. return idValue.replace(PLACEHOLDER_REGEX, '$1');
  150. }
  151. /**
  152. * generate a semantic id with given prefix
  153. */
  154. function nextId(prefix) {
  155. var ids = new Ids([32,32,1]);
  156. return ids.nextPrefixed(prefix);
  157. }
  158. module.exports.nextId = nextId;
  159. function triggerClickEvent(element) {
  160. var evt;
  161. var eventType = 'click';
  162. if (document.createEvent) {
  163. try {
  164. // Chrome, Safari, Firefox
  165. evt = new MouseEvent((eventType), { view: window, bubbles: true, cancelable: true });
  166. } catch (e) {
  167. // IE 11, PhantomJS (wat!)
  168. evt = document.createEvent('MouseEvent');
  169. evt.initEvent((eventType), true, true);
  170. }
  171. return element.dispatchEvent(evt);
  172. } else {
  173. // Welcome IE
  174. evt = document.createEventObject();
  175. return element.fireEvent('on' + eventType, evt);
  176. }
  177. }
  178. module.exports.triggerClickEvent = triggerClickEvent;
  179. function escapeHTML(str) {
  180. str = '' + str;
  181. return str && str.replace(/[&<>"']/g, function(match) {
  182. return HTML_ESCAPE_MAP[match];
  183. });
  184. }
  185. module.exports.escapeHTML = escapeHTML;