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.
Files changed (3) hide show
  1. package/README.md +3 -3
  2. package/netstack.js +86 -32
  3. 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
- [![English](images/flags/US%20-%20United%20States.svg)](#) [![Danish](images/flags/DK%20-%20Denmark.svg)](#) [![German](images/flags/DE%20-%20Germany.svg)](#) [![Russian](images/flags/RU%20-%20Russian%20Federation.svg)](#) [![Chinese](images/flags/CN%20-%20China.svg)](#)
10
+ [![English](images/flags/US%20-%20United%20States.svg)](#) [![Danish](images/flags/DK%20-%20Denmark.svg)](#) [![German](images/flags/DE%20-%20Germany.svg)](#) [![Spanish](images/flags/ES%20-%20Spain.svg)](#) [![Russian](images/flags/RU%20-%20Russian%20Federation.svg)](#) [![Chinese](images/flags/CN%20-%20China.svg)](#)
11
11
 
12
12
  #### Demo
13
13
  [![netStack.js - demo](images/example.jpg)](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 css
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.0.0
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
- // look for the language
127
- for (var i = 0; i < lines.length; ++i) {
128
- if (lang === '') {
129
- var regexes = {
130
- english: /\s+at .*\)/,
131
- danish: /\s+ved .*\)/,
132
- german: /\s+bei .*\)/,
133
- russian: /\s+в .*\)/,
134
- chinese: /\s+在 .*\)/
135
- };
136
-
137
- for (var key in regexes) {
138
- if (regexes[key].test(lines[i])) {
139
- lang = key;
140
- break;
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 (lang === '') return;
147
-
148
- var selectedLanguage = this.search(lang, this.languages);
149
- this.language = selectedLanguage.name;
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
- sanitizedStack = this.formatException(sanitizedStack, selectedLanguage.at);
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*)' + selectedLanguage.at + ' .*?\\)'),
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(selectedLanguage.at + ' ', '');
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:' + selectedLanguage.line + ' \\d+'),
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(selectedLanguage.at + " " + partsFrame, '').trim();
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(selectedLanguage.in + '\\s.*$', 'm'),
269
+ var regFile = new RegExp(languageSet.in + '\\s.*$', 'm'),
216
270
  partsFile = String(regFile.exec(fileLi));
217
271
 
218
- partsFile = partsFile.replace(selectedLanguage.in + ' ', '').replace(':' + partsLine, '').replace('&lt;---', '');
272
+ partsFile = partsFile.replace(languageSet.in + ' ', '').replace(':' + partsLine, '').replace('&lt;---', '');
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>')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "netstack.js",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "A simple and easy JavaScript library for highlighting .NET stack traces",
5
5
  "main": "netstack.js",
6
6
  "scripts": {