all files / bpmn-js/lib/features/search/ BpmnSearchProvider.js

100% Statements 37/37
100% Branches 12/12
100% Functions 10/10
100% Lines 37/37
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129                                74× 74×   74×                                                       129× 16×   113×       113×     105×               105×                 204× 174×     204×         210× 210×   210× 41×     169× 169×   169×   169×                       161×         169×  
import {
  map,
  filter,
  sortBy
} from 'min-dash';
 
import {
  getLabel
} from '../label-editing/LabelUtil';
 
 
/**
 * Provides ability to search through BPMN elements
 */
export default function BpmnSearchProvider(elementRegistry, searchPad, canvas) {
 
  this._elementRegistry = elementRegistry;
  this._canvas = canvas;
 
  searchPad.registerProvider(this);
}
 
BpmnSearchProvider.$inject = [
  'elementRegistry',
  'searchPad',
  'canvas'
];
 
 
/**
 * Finds all elements that match given pattern
 *
 * <Result> :
 *  {
 *    primaryTokens: <Array<Token>>,
 *    secondaryTokens: <Array<Token>>,
 *    element: <Element>
 *  }
 *
 * <Token> :
 *  {
 *    normal|matched: <String>
 *  }
 *
 * @param  {String} pattern
 * @return {Array<Result>}
 */
BpmnSearchProvider.prototype.find = function(pattern) {
  var rootElement = this._canvas.getRootElement();
 
  var elements = this._elementRegistry.filter(function(element) {
    if (element.labelTarget) {
      return false;
    }
    return true;
  });
 
  // do not include root element
  elements = filter(elements, function(element) {
    return element !== rootElement;
  });
 
  elements = map(elements, function(element) {
    return {
      primaryTokens: matchAndSplit(getLabel(element), pattern),
      secondaryTokens: matchAndSplit(element.id, pattern),
      element: element
    };
  });
 
  // exclude non-matched elements
  elements = filter(elements, function(element) {
    return hasMatched(element.primaryTokens) || hasMatched(element.secondaryTokens);
  });
 
  elements = sortBy(elements, function(element) {
    return getLabel(element.element) + element.element.id;
  });
 
  return elements;
};
 
 
function hasMatched(tokens) {
  var matched = filter(tokens, function(t) {
    return !!t.matched;
  });
 
  return matched.length > 0;
}
 
 
function matchAndSplit(text, pattern) {
  var tokens = [],
      originalText = text;
 
  if (!text) {
    return tokens;
  }
 
  text = text.toLowerCase();
  pattern = pattern.toLowerCase();
 
  var i = text.indexOf(pattern);
 
  if (i > -1) {
    if (i !== 0) {
      tokens.push({
        normal: originalText.substr(0, i)
      });
    }
 
    tokens.push({
      matched: originalText.substr(i, pattern.length)
    });
 
    if (pattern.length + i < text.length) {
      tokens.push({
        normal: originalText.substr(pattern.length + i, text.length)
      });
    }
  } else {
    tokens.push({
      normal: originalText
    });
  }
 
  return tokens;
}