This repository has been archived by the owner on Aug 22, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
119 lines (103 loc) · 3.34 KB
/
index.js
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
'use strict';
import SnippetsStorage from './lib/storage';
/**
* A snippets registry. Contains snippets, separated by store and sorted by
* priority: a store with higher priority takes precedence when resolving snippet
* for given key
*/
export default class SnippetsRegistry {
/**
* Creates snippets registry, filled with given `data`
* @param {Object|Array} data Registry snippets. If array is given, adds items
* from array in order of precedence, registers global snippets otherwise
*/
constructor(data) {
this._registry = [];
if (Array.isArray(data)) {
data.forEach((snippets, level) => this.add(level, snippets));
} else if (typeof data === 'object') {
this.add(data);
}
}
/**
* Return store for given level
* @param {Number} level
* @return {SnippetsStorage}
*/
get(level) {
for (let i = 0; i < this._registry.length; i++) {
const item = this._registry[i];
if (item.level === level) {
return item.store;
}
}
}
/**
* Adds new store for given level
* @param {Number} [level] Store level (priority). Store with higher level
* takes precedence when resolving snippets
* @param {Object} [snippets] A snippets data for new store
* @return {SnipetsStorage}
*/
add(level, snippets) {
if (level != null && typeof level === 'object') {
snippets = level;
level = 0;
}
const store = new SnippetsStorage(snippets);
// remove previous store from same level
this.remove(level);
this._registry.push({level, store});
this._registry.sort((a, b) => b.level - a.level);
return store;
}
/**
* Remove registry with given level or store
* @param {Number|SnippetsStorage} data Either level or snippets store
*/
remove(data) {
this._registry = this._registry
.filter(item => item.level !== data && item.store !== data);
}
/**
* Returns snippet from registry that matches given name
* @param {String} name
* @return {Snippet}
*/
resolve(name) {
for (let i = 0; i < this._registry.length; i++) {
const snippet = this._registry[i].store.get(name);
if (snippet) {
return snippet;
}
}
}
/**
* Returns all available snippets from current registry. Snippets with the
* same key are resolved by their storage priority.
* @param {Object} options
* @param {Object} options.type Return snippets only of given type: 'string'
* or 'regexp'. Returns all snippets if not defined
* @return {Array}
*/
all(options) {
options = options || {};
const result = new Map();
const fillResult = snippet => {
const type = snippet.key instanceof RegExp ? 'regexp' : 'string';
if ((!options.type || options.type === type) && !result.has(snippet.key)) {
result.set(snippet.key, snippet);
}
};
this._registry.forEach(item => {
item.store.values().forEach(fillResult);
});
return Array.from(result.values());
}
/**
* Removes all stores from registry
*/
clear() {
this._registry.length = 0;
}
}