netstack.js 2.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/netstack.js +86 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
A simple and easy JavaScript library for highlighting .NET stack traces
|
|
8
8
|
|
|
9
9
|
#### Stacktrace - Language support
|
|
10
|
-
[](#) [](#) [](#) [](#) [](#)
|
|
10
|
+
[](#) [](#) [](#) [](#) [](#) [](#)
|
|
11
11
|
|
|
12
12
|
#### Demo
|
|
13
13
|
[](https://elmah.io/tools/stack-trace-formatter/)
|
|
@@ -49,7 +49,7 @@ const stack = new netStack('.stacktrace', {
|
|
|
49
49
|
});
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
#### Ready to go
|
|
52
|
+
#### Ready to go CSS
|
|
53
53
|
```css
|
|
54
54
|
pre, code {background-color:#333; color: #ffffff;}
|
|
55
55
|
.st-type {color: #0a8472; font-weight: bolder;}
|
|
@@ -64,4 +64,4 @@ pre, code {background-color:#333; color: #ffffff;}
|
|
|
64
64
|
---
|
|
65
65
|
### Acknowledgments
|
|
66
66
|
|
|
67
|
-
* [IgoR-NiK](https://github.com/IgoR-NiK)
|
|
67
|
+
* [IgoR-NiK](https://github.com/IgoR-NiK)
|
package/netstack.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* netStack v2.
|
|
2
|
+
* netStack v2.1.1
|
|
3
3
|
* A simple and easy JavaScript library for highlighting .NET stack traces
|
|
4
4
|
* License: Apache 2
|
|
5
5
|
* Author: https://elmah.io
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
{ name: 'english', at: 'at', in: 'in', line: 'line' },
|
|
49
49
|
{ name: 'danish', at: 'ved', in: 'i', line: 'linje' },
|
|
50
50
|
{ name: 'german', at: 'bei', in: 'in', line: 'Zeile' },
|
|
51
|
+
{ name: 'spanish', at: 'en', in: 'en', line: 'línea' },
|
|
51
52
|
{ name: 'russian', at: 'в', in: 'в', line: 'строка' },
|
|
52
53
|
{ name: 'chinese', at: '在', in: '位置', line: '行号' }
|
|
53
54
|
];
|
|
@@ -75,6 +76,8 @@
|
|
|
75
76
|
return null;
|
|
76
77
|
};
|
|
77
78
|
|
|
79
|
+
netStack.prototype.allEqual = arr => arr.every(val => val === arr[0]);
|
|
80
|
+
|
|
78
81
|
netStack.prototype.replacer = function(args, at_language) {
|
|
79
82
|
if (args[0].substring(0).match(/(-{3}>)/)) {
|
|
80
83
|
return '\r\n ' + args[0];
|
|
@@ -85,7 +88,7 @@
|
|
|
85
88
|
}
|
|
86
89
|
};
|
|
87
90
|
|
|
88
|
-
netStack.prototype.formatException = function(exceptionMessage, at_language) {
|
|
91
|
+
netStack.prototype.formatException = function(exceptionMessage, at_language, loop, position) {
|
|
89
92
|
var result = exceptionMessage || '';
|
|
90
93
|
var searchReplaces = [
|
|
91
94
|
{
|
|
@@ -103,7 +106,12 @@
|
|
|
103
106
|
];
|
|
104
107
|
|
|
105
108
|
var self = this;
|
|
106
|
-
searchReplaces.forEach(function(item) {
|
|
109
|
+
searchReplaces.forEach(function(item, index) {
|
|
110
|
+
// multilanguage, skip --- lines
|
|
111
|
+
if (loop === true && position > 0 && index === 1) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
107
115
|
if (item.repl == null) {
|
|
108
116
|
result = result.replace(item.find, function() {
|
|
109
117
|
return self.replacer(arguments, at_language);
|
|
@@ -115,6 +123,22 @@
|
|
|
115
123
|
return result;
|
|
116
124
|
};
|
|
117
125
|
|
|
126
|
+
netStack.prototype.detectLanguagesInOrder = function(input, regexes) {
|
|
127
|
+
let matches = [];
|
|
128
|
+
|
|
129
|
+
for (let [language, regex] of Object.entries(regexes)) {
|
|
130
|
+
let match;
|
|
131
|
+
while ((match = regex.exec(input)) !== null) {
|
|
132
|
+
matches.push({ language, index: match.index });
|
|
133
|
+
}
|
|
134
|
+
regex.lastIndex = 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
matches.sort((a, b) => a.index - b.index);
|
|
138
|
+
|
|
139
|
+
return matches.map((match) => match.language);
|
|
140
|
+
};
|
|
141
|
+
|
|
118
142
|
netStack.prototype.init = function() {
|
|
119
143
|
// Get the stacktrace, sanitize it, and split it into lines
|
|
120
144
|
var stacktrace = this.element.textContent,
|
|
@@ -123,52 +147,82 @@
|
|
|
123
147
|
lang = '',
|
|
124
148
|
clone = '';
|
|
125
149
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
var languagesRegex = {
|
|
151
|
+
english: /\s+at .*?\)/g,
|
|
152
|
+
danish: /\s+ved .*?\)/g,
|
|
153
|
+
german: /\s+bei .*?\)/g,
|
|
154
|
+
spanish: /\s+en .*?\)/g,
|
|
155
|
+
russian: /\s+в .*?\)/g,
|
|
156
|
+
chinese: /\s+在 .*?\)/g
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// look for the language(s) in the stack trace
|
|
160
|
+
lang = this.detectLanguagesInOrder(lines, languagesRegex);
|
|
161
|
+
|
|
162
|
+
// if no language is found, return
|
|
163
|
+
if (lang.length === 0) return;
|
|
164
|
+
|
|
165
|
+
// if multiline option is true, check if the language is the same for all lines
|
|
166
|
+
if (typeof lang === 'object') {
|
|
167
|
+
if (this.allEqual(lang)) {
|
|
168
|
+
lang = lang[0];
|
|
143
169
|
}
|
|
144
170
|
}
|
|
145
171
|
|
|
146
|
-
if
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
172
|
+
// if lang is an array, we have multiple languages
|
|
173
|
+
if (Array.isArray(lang)) {
|
|
174
|
+
var selectedLanguage = [];
|
|
175
|
+
for (var i = 0; i < lang.length; ++i) {
|
|
176
|
+
selectedLanguage.push(this.search(lang[i], this.languages));
|
|
177
|
+
}
|
|
178
|
+
this.language = 'multilanguage';
|
|
179
|
+
} else if (typeof lang === 'string') {
|
|
180
|
+
var selectedLanguage = this.search(lang, this.languages);
|
|
181
|
+
this.language = selectedLanguage.name;
|
|
182
|
+
}
|
|
150
183
|
|
|
151
184
|
// Pritty print result if is set to true
|
|
152
185
|
if (this.settings.prettyprint) {
|
|
153
|
-
|
|
186
|
+
if (Array.isArray(selectedLanguage)) {
|
|
187
|
+
var sanitizedStacks = sanitizedStack;
|
|
188
|
+
const selectedLanguages = [...new Set(selectedLanguage)];
|
|
189
|
+
selectedLanguages.forEach((language, index) => {
|
|
190
|
+
sanitizedStacks = this.formatException(sanitizedStacks, language.at, true, index);
|
|
191
|
+
});
|
|
192
|
+
sanitizedStack = sanitizedStacks;
|
|
193
|
+
} else {
|
|
194
|
+
sanitizedStack = this.formatException(sanitizedStack, selectedLanguage.at);
|
|
195
|
+
}
|
|
196
|
+
|
|
154
197
|
lines = sanitizedStack.split('\n');
|
|
155
198
|
}
|
|
156
199
|
|
|
200
|
+
if (Array.isArray(selectedLanguage)) {
|
|
201
|
+
var langContor = 0;
|
|
202
|
+
}
|
|
203
|
+
|
|
157
204
|
for (var i = 0; i < lines.length; ++i) {
|
|
158
205
|
var li = lines[i],
|
|
159
|
-
hli = new RegExp('(\\S*)' + selectedLanguage.at + ' .*\\)')
|
|
206
|
+
hli = new RegExp('(\\S*)' + selectedLanguage.at + ' .*\\)'),
|
|
207
|
+
languageSet = selectedLanguage;
|
|
208
|
+
|
|
209
|
+
if (Array.isArray(selectedLanguage)) {
|
|
210
|
+
hli = new RegExp('(\\S*)' + selectedLanguage[langContor].at + ' .*\\)');
|
|
211
|
+
languageSet = selectedLanguage[langContor];
|
|
212
|
+
hli.test(lines[i]) ? langContor++ : langContor;
|
|
213
|
+
}
|
|
160
214
|
|
|
161
215
|
if (hli.test(lines[i])) {
|
|
162
216
|
|
|
163
217
|
// Frame
|
|
164
|
-
var regFrame = new RegExp('(\\S*)' +
|
|
218
|
+
var regFrame = new RegExp('(\\S*)' + languageSet.at + ' .*?\\)'),
|
|
165
219
|
partsFrame = String(regFrame.exec(lines[i]));
|
|
166
220
|
|
|
167
221
|
if (partsFrame.substring(partsFrame.length - 1) == ',') {
|
|
168
222
|
partsFrame = partsFrame.slice(0, -1);
|
|
169
223
|
}
|
|
170
224
|
|
|
171
|
-
partsFrame = partsFrame.replace(
|
|
225
|
+
partsFrame = partsFrame.replace(languageSet.at + ' ', '');
|
|
172
226
|
|
|
173
227
|
// Frame -> ParameterList
|
|
174
228
|
var regParamList = /\(.*\)/,
|
|
@@ -204,18 +258,18 @@
|
|
|
204
258
|
var newPartsFrame = partsFrame.replace(partsParamList, stringParam).replace(partsTypeMethod, stringTypeMethod);
|
|
205
259
|
|
|
206
260
|
// Line
|
|
207
|
-
var regLine = new RegExp('\\b:' +
|
|
261
|
+
var regLine = new RegExp('\\b:' + languageSet.line + ' \\d+'),
|
|
208
262
|
partsLine = String(regLine.exec(lines[i]));
|
|
209
263
|
|
|
210
264
|
partsLine = partsLine.replace(':', '').trim();
|
|
211
265
|
|
|
212
|
-
var fileLi = li.replace(
|
|
266
|
+
var fileLi = li.replace(languageSet.at + " " + partsFrame, '').trim();
|
|
213
267
|
|
|
214
268
|
// File => (!) text requires multiline to exec regex, otherwise it will return null.
|
|
215
|
-
var regFile = new RegExp(
|
|
269
|
+
var regFile = new RegExp(languageSet.in + '\\s.*$', 'm'),
|
|
216
270
|
partsFile = String(regFile.exec(fileLi));
|
|
217
271
|
|
|
218
|
-
partsFile = partsFile.replace(
|
|
272
|
+
partsFile = partsFile.replace(languageSet.in + ' ', '').replace(':' + partsLine, '').replace('<---', '');
|
|
219
273
|
|
|
220
274
|
li = li.replace(partsFrame, '<span class="' + this.settings.frame + '">' + newPartsFrame + '</span>')
|
|
221
275
|
.replace(partsFile, '<span class="' + this.settings.file + '">' + partsFile + '</span>')
|