[6a3a178] | 1 | /* jshint node: true */
|
---|
| 2 | 'use strict';
|
---|
| 3 |
|
---|
| 4 | var REGEXP_PARTS = /(\*|\?)/g;
|
---|
| 5 |
|
---|
| 6 | /**
|
---|
| 7 | # wildcard
|
---|
| 8 |
|
---|
| 9 | Very simple wildcard matching, which is designed to provide the same
|
---|
| 10 | functionality that is found in the
|
---|
| 11 | [eve](https://github.com/adobe-webplatform/eve) eventing library.
|
---|
| 12 |
|
---|
| 13 | ## Usage
|
---|
| 14 |
|
---|
| 15 | It works with strings:
|
---|
| 16 |
|
---|
| 17 | <<< examples/strings.js
|
---|
| 18 |
|
---|
| 19 | Arrays:
|
---|
| 20 |
|
---|
| 21 | <<< examples/arrays.js
|
---|
| 22 |
|
---|
| 23 | Objects (matching against keys):
|
---|
| 24 |
|
---|
| 25 | <<< examples/objects.js
|
---|
| 26 |
|
---|
| 27 | ## Alternative Implementations
|
---|
| 28 |
|
---|
| 29 | - <https://github.com/isaacs/node-glob>
|
---|
| 30 |
|
---|
| 31 | Great for full file-based wildcard matching.
|
---|
| 32 |
|
---|
| 33 | - <https://github.com/sindresorhus/matcher>
|
---|
| 34 |
|
---|
| 35 | A well cared for and loved JS wildcard matcher.
|
---|
| 36 | **/
|
---|
| 37 |
|
---|
| 38 | function WildcardMatcher(text, separator) {
|
---|
| 39 | this.text = text = text || '';
|
---|
| 40 | this.hasWild = text.indexOf('*') >= 0;
|
---|
| 41 | this.separator = separator;
|
---|
| 42 | this.parts = text.split(separator).map(this.classifyPart.bind(this));
|
---|
| 43 | }
|
---|
| 44 |
|
---|
| 45 | WildcardMatcher.prototype.match = function(input) {
|
---|
| 46 | var matches = true;
|
---|
| 47 | var parts = this.parts;
|
---|
| 48 | var ii;
|
---|
| 49 | var partsCount = parts.length;
|
---|
| 50 | var testParts;
|
---|
| 51 |
|
---|
| 52 | if (typeof input == 'string' || input instanceof String) {
|
---|
| 53 | if (!this.hasWild && this.text != input) {
|
---|
| 54 | matches = false;
|
---|
| 55 | } else {
|
---|
| 56 | testParts = (input || '').split(this.separator);
|
---|
| 57 | for (ii = 0; matches && ii < partsCount; ii++) {
|
---|
| 58 | if (parts[ii] === '*') {
|
---|
| 59 | continue;
|
---|
| 60 | } else if (ii < testParts.length) {
|
---|
| 61 | matches = parts[ii] instanceof RegExp
|
---|
| 62 | ? parts[ii].test(testParts[ii])
|
---|
| 63 | : parts[ii] === testParts[ii];
|
---|
| 64 | } else {
|
---|
| 65 | matches = false;
|
---|
| 66 | }
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | // If matches, then return the component parts
|
---|
| 70 | matches = matches && testParts;
|
---|
| 71 | }
|
---|
| 72 | }
|
---|
| 73 | else if (typeof input.splice == 'function') {
|
---|
| 74 | matches = [];
|
---|
| 75 |
|
---|
| 76 | for (ii = input.length; ii--; ) {
|
---|
| 77 | if (this.match(input[ii])) {
|
---|
| 78 | matches[matches.length] = input[ii];
|
---|
| 79 | }
|
---|
| 80 | }
|
---|
| 81 | }
|
---|
| 82 | else if (typeof input == 'object') {
|
---|
| 83 | matches = {};
|
---|
| 84 |
|
---|
| 85 | for (var key in input) {
|
---|
| 86 | if (this.match(key)) {
|
---|
| 87 | matches[key] = input[key];
|
---|
| 88 | }
|
---|
| 89 | }
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | return matches;
|
---|
| 93 | };
|
---|
| 94 |
|
---|
| 95 | WildcardMatcher.prototype.classifyPart = function(part) {
|
---|
| 96 | // in the event that we have been provided a part that is not just a wildcard
|
---|
| 97 | // then turn this into a regular expression for matching purposes
|
---|
| 98 | if (part === '*') {
|
---|
| 99 | return part;
|
---|
| 100 | } else if (part.indexOf('*') >= 0 || part.indexOf('?') >= 0) {
|
---|
| 101 | return new RegExp(part.replace(REGEXP_PARTS, '\.$1'));
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 | return part;
|
---|
| 105 | };
|
---|
| 106 |
|
---|
| 107 | module.exports = function(text, test, separator) {
|
---|
| 108 | var matcher = new WildcardMatcher(text, separator || /[\/\.]/);
|
---|
| 109 | if (typeof test != 'undefined') {
|
---|
| 110 | return matcher.match(test);
|
---|
| 111 | }
|
---|
| 112 |
|
---|
| 113 | return matcher;
|
---|
| 114 | };
|
---|