BpmnSearchProvider.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import {
  2. map,
  3. filter,
  4. sortBy
  5. } from 'min-dash';
  6. import {
  7. getLabel
  8. } from '../../util/LabelUtil';
  9. /**
  10. * @typedef {import('diagram-js/lib/core/Canvas').default} Canvas
  11. * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
  12. * @typedef {import('diagram-js/lib/features/search-pad/SearchPad').default} SearchPad
  13. *
  14. * @typedef {import('diagram-js/lib/features/search-pad/SearchPadProvider').default} SearchPadProvider
  15. * @typedef {import('diagram-js/lib/features/search-pad/SearchPadProvider').SearchResult} SearchResult
  16. */
  17. /**
  18. * Provides ability to search for BPMN elements.
  19. *
  20. * @implements {SearchPadProvider}
  21. *
  22. * @param {ElementRegistry} elementRegistry
  23. * @param {SearchPad} searchPad
  24. * @param {Canvas} canvas
  25. */
  26. export default function BpmnSearchProvider(elementRegistry, searchPad, canvas) {
  27. this._elementRegistry = elementRegistry;
  28. this._canvas = canvas;
  29. searchPad.registerProvider(this);
  30. }
  31. BpmnSearchProvider.$inject = [
  32. 'elementRegistry',
  33. 'searchPad',
  34. 'canvas'
  35. ];
  36. /**
  37. * @param {string} pattern
  38. *
  39. * @return {SearchResult[]}
  40. */
  41. BpmnSearchProvider.prototype.find = function(pattern) {
  42. var rootElement = this._canvas.getRootElement();
  43. var elements = this._elementRegistry.filter(function(element) {
  44. if (element.labelTarget) {
  45. return false;
  46. }
  47. return true;
  48. });
  49. // do not include root element
  50. elements = filter(elements, function(element) {
  51. return element !== rootElement;
  52. });
  53. elements = map(elements, function(element) {
  54. return {
  55. primaryTokens: matchAndSplit(getLabel(element), pattern),
  56. secondaryTokens: matchAndSplit(element.id, pattern),
  57. element: element
  58. };
  59. });
  60. // exclude non-matched elements
  61. elements = filter(elements, function(element) {
  62. return hasMatched(element.primaryTokens) || hasMatched(element.secondaryTokens);
  63. });
  64. elements = sortBy(elements, function(element) {
  65. return getLabel(element.element) + element.element.id;
  66. });
  67. return elements;
  68. };
  69. /**
  70. * @param {Token[]} tokens
  71. *
  72. * @return {boolean}
  73. */
  74. function hasMatched(tokens) {
  75. var matched = filter(tokens, function(token) {
  76. return !!token.matched;
  77. });
  78. return matched.length > 0;
  79. }
  80. /**
  81. * @param {string} text
  82. * @param {string} pattern
  83. *
  84. * @return {Token[]}
  85. */
  86. function matchAndSplit(text, pattern) {
  87. var tokens = [],
  88. originalText = text;
  89. if (!text) {
  90. return tokens;
  91. }
  92. text = text.toLowerCase();
  93. pattern = pattern.toLowerCase();
  94. var i = text.indexOf(pattern);
  95. if (i > -1) {
  96. if (i !== 0) {
  97. tokens.push({
  98. normal: originalText.substr(0, i)
  99. });
  100. }
  101. tokens.push({
  102. matched: originalText.substr(i, pattern.length)
  103. });
  104. if (pattern.length + i < text.length) {
  105. tokens.push({
  106. normal: originalText.substr(pattern.length + i, text.length)
  107. });
  108. }
  109. } else {
  110. tokens.push({
  111. normal: originalText
  112. });
  113. }
  114. return tokens;
  115. }