ibs-format 1.4.13 → 1.4.15
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 +9 -9
- package/index.js +86 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# Description
|
|
2
2
|
|
|
3
|
-
Detect the user-defined identifiers in the text and convert them into HTML tags like bold, italic, strike, and many more having XSS (Cross-site scripting) security with escaping functionality, also detect the links like URLs, email, and IP addresses and wrap them into Anchor tag `<a
|
|
3
|
+
Text formatting in Javascript. Detect the user-defined identifiers in the text and convert them into HTML tags like bold, italic, strike, and many more having XSS (Cross-site scripting) security with escaping functionality, also detect the links like URLs, email, and IP addresses and wrap them into Anchor tag `<a>` with also other user define formatting.
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
|
-
- [Online Demo](#demo)
|
|
6
|
+
- [Online Demo](#online-demo)
|
|
7
7
|
- [Supported browsers](#browsers)
|
|
8
8
|
- [Installation](#installation)
|
|
9
9
|
- [Usage](#usage)
|
|
10
10
|
- [Text Formatting](#text-formatting)
|
|
11
11
|
- [Links Detecting](#links-detecting)
|
|
12
|
-
- [Cross Site Scripting (XSS)](#cross-site-scripting)
|
|
13
|
-
- [Format the text at run time using custom Pipe](#pipe)
|
|
14
|
-
- [Use the external 'ngx-linkifyjs' library for detecting the links](#linkifyjs)
|
|
12
|
+
- [Cross Site Scripting (XSS)](#cross-site-scripting-(xss))
|
|
13
|
+
- [Format the text at run time using custom Pipe](#format-the-text-at-run-time-using-custom-pipe)
|
|
14
|
+
- [Use the external 'ngx-linkifyjs' library for detecting the links](#use-the-external-'ngx-linkifyjs'-library-for-detecting-the-links)
|
|
15
15
|
- [Precautions](#precautions)
|
|
16
16
|
|
|
17
|
-
<a name="demo"/>
|
|
17
|
+
<a name="online-demo"/>
|
|
18
18
|
|
|
19
19
|
# Online Demo
|
|
20
20
|
|
|
@@ -122,7 +122,7 @@ and my email is <a href='mailto:info@myemail.com' target='_blank'>info@myemail.c
|
|
|
122
122
|
```js
|
|
123
123
|
myText = ibsFormat(myText, null, obj);
|
|
124
124
|
```
|
|
125
|
-
<a name="cross-site-scripting"/>
|
|
125
|
+
<a name="cross-site-scripting-(xss)"/>
|
|
126
126
|
|
|
127
127
|
# Cross Site Scripting (XSS).
|
|
128
128
|
|
|
@@ -138,7 +138,7 @@ Place a JSON object in the forth argument and set it's value to false, if the fo
|
|
|
138
138
|
myText = ibsFormat(myText, tagArray, obj, { allowXssEscaping : false });
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
-
<a name="pipe"/>
|
|
141
|
+
<a name="format-the-text-at-run-time-using-custom-pipe"/>
|
|
142
142
|
|
|
143
143
|
# Format the text at run time using custom Pipe.
|
|
144
144
|
|
|
@@ -176,7 +176,7 @@ import { ibsformatPipe } from './custom-pipe.pipe';
|
|
|
176
176
|
|
|
177
177
|
`<p [innerHTML]="myText | ibsformat"></p>`
|
|
178
178
|
|
|
179
|
-
<a name="linkifyjs"/>
|
|
179
|
+
<a name="use-the-external-'ngx-linkifyjs'-library-for-detecting-the-links"/>
|
|
180
180
|
|
|
181
181
|
# Use the external 'ngx-linkifyjs' library for detecting the links
|
|
182
182
|
|
package/index.js
CHANGED
|
@@ -10,6 +10,64 @@ function ibsFormat(value, arr, linky, escaping) {
|
|
|
10
10
|
value = value.replace(/\n/g, " <br> ");
|
|
11
11
|
}
|
|
12
12
|
if (value != "" && value != null && value != undefined && arr && arr.length > 0) {
|
|
13
|
+
// Preprocess to handle empty formatting markers
|
|
14
|
+
if (arr[0].constructor === Array) {
|
|
15
|
+
arr.forEach(function (formatConfig) {
|
|
16
|
+
let marker = formatConfig[1];
|
|
17
|
+
// Create regex to match empty formatting markers (marker followed by optional whitespace then same marker)
|
|
18
|
+
let escapedMarker = marker.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
19
|
+
let emptyMarkerRegex = new RegExp(escapedMarker + '\\s*' + escapedMarker, 'g');
|
|
20
|
+
|
|
21
|
+
// Find all empty marker pairs and track their positions
|
|
22
|
+
let matches = [];
|
|
23
|
+
let match;
|
|
24
|
+
while ((match = emptyMarkerRegex.exec(value)) !== null) {
|
|
25
|
+
matches.push({
|
|
26
|
+
start: match.index,
|
|
27
|
+
end: match.index + match[0].length,
|
|
28
|
+
content: match[0]
|
|
29
|
+
});
|
|
30
|
+
// Reset lastIndex to avoid infinite loop with zero-length matches
|
|
31
|
+
if (match.index === emptyMarkerRegex.lastIndex) {
|
|
32
|
+
emptyMarkerRegex.lastIndex++;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Process matches from end to start to avoid index shifting
|
|
37
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
38
|
+
let matchObj = matches[i];
|
|
39
|
+
let beforeMatch = value.substring(0, matchObj.start);
|
|
40
|
+
let afterMatch = value.substring(matchObj.end);
|
|
41
|
+
// Replace with just the markers (no formatting)
|
|
42
|
+
value = beforeMatch + marker + marker + afterMatch;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
let marker = arr[1];
|
|
47
|
+
let escapedMarker = marker.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
48
|
+
let emptyMarkerRegex = new RegExp(escapedMarker + '\\s*' + escapedMarker, 'g');
|
|
49
|
+
|
|
50
|
+
let matches = [];
|
|
51
|
+
let match;
|
|
52
|
+
while ((match = emptyMarkerRegex.exec(value)) !== null) {
|
|
53
|
+
matches.push({
|
|
54
|
+
start: match.index,
|
|
55
|
+
end: match.index + match[0].length,
|
|
56
|
+
content: match[0]
|
|
57
|
+
});
|
|
58
|
+
if (match.index === emptyMarkerRegex.lastIndex) {
|
|
59
|
+
emptyMarkerRegex.lastIndex++;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
64
|
+
let matchObj = matches[i];
|
|
65
|
+
let beforeMatch = value.substring(0, matchObj.start);
|
|
66
|
+
let afterMatch = value.substring(matchObj.end);
|
|
67
|
+
value = beforeMatch + marker + marker + afterMatch;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
13
71
|
if (arr[0].constructor === Array) {
|
|
14
72
|
arr.map(function (e) {
|
|
15
73
|
e[2] = (e[0].length + 1).toString();
|
|
@@ -118,10 +176,19 @@ function doubleAstericHandler(text, tag, iden, trim, space) {
|
|
|
118
176
|
box.push(e.indexOf(iden, v));
|
|
119
177
|
}
|
|
120
178
|
}
|
|
121
|
-
|
|
122
|
-
|
|
179
|
+
|
|
180
|
+
// Check if there's content between the ** markers
|
|
181
|
+
let firstIndex = box[0];
|
|
182
|
+
let lastIndex = box[box.length - 1];
|
|
183
|
+
let contentBetween = e.substring(firstIndex + 2, lastIndex);
|
|
184
|
+
|
|
185
|
+
if (contentBetween.trim().length > 0) {
|
|
186
|
+
e = e.replace('**', "<" + tag + ">");
|
|
187
|
+
e = e.replace('**', "</" + tag + ">");
|
|
188
|
+
}
|
|
123
189
|
box = [];
|
|
124
190
|
}
|
|
191
|
+
|
|
125
192
|
arr.push(e);
|
|
126
193
|
});
|
|
127
194
|
arr.forEach(function (e) {
|
|
@@ -162,6 +229,7 @@ function astericHandler(text, tag, iden, trim, space) {
|
|
|
162
229
|
) {
|
|
163
230
|
if (loopCounter == singleStericCounter && loopCounter % 2 == 0) {
|
|
164
231
|
} else {
|
|
232
|
+
// Check if there's actual content between paired asterisks across words
|
|
165
233
|
if (flag == "1") {
|
|
166
234
|
e = e.replace(/\x2a/g, "<" + tag + ">");
|
|
167
235
|
flag = "2";
|
|
@@ -188,8 +256,14 @@ function astericHandler(text, tag, iden, trim, space) {
|
|
|
188
256
|
}
|
|
189
257
|
let firstIndex = box[0];
|
|
190
258
|
let lastIndex = box[box.length - 1];
|
|
191
|
-
|
|
192
|
-
|
|
259
|
+
|
|
260
|
+
// Check if there's content between the * markers
|
|
261
|
+
let contentBetween = e.substring(firstIndex + 1, lastIndex);
|
|
262
|
+
|
|
263
|
+
if (contentBetween.trim().length > 0) {
|
|
264
|
+
e = replaceChar(e, "<" + tag + ">", firstIndex);
|
|
265
|
+
e = replaceChar(e, "</" + tag + ">", lastIndex + trim);
|
|
266
|
+
}
|
|
193
267
|
box = [];
|
|
194
268
|
}
|
|
195
269
|
|
|
@@ -265,8 +339,13 @@ function getFormat(text, tag, iden, trim, space) {
|
|
|
265
339
|
let firstIndex = box[0];
|
|
266
340
|
let lastIndex = box[box.length - 1];
|
|
267
341
|
|
|
268
|
-
|
|
269
|
-
|
|
342
|
+
// Check if there's content between the formatting markers
|
|
343
|
+
let contentBetween = e.substring(firstIndex + iden.length, lastIndex);
|
|
344
|
+
|
|
345
|
+
if (contentBetween.trim().length > 0) {
|
|
346
|
+
e = replaceChar(e, "<" + tag + ">", firstIndex);
|
|
347
|
+
e = replaceChar(e, "</" + tag + ">", lastIndex + trim);
|
|
348
|
+
}
|
|
270
349
|
|
|
271
350
|
box = [];
|
|
272
351
|
}
|
|
@@ -291,7 +370,7 @@ function getFormat(text, tag, iden, trim, space) {
|
|
|
291
370
|
}
|
|
292
371
|
|
|
293
372
|
function linkfy(text, target) {
|
|
294
|
-
let strictUrlExpression = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(
|
|
373
|
+
let strictUrlExpression = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.(?![\p{Extended_Pictographic}])\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.(?![\p{Extended_Pictographic}])\d{1,3}){2})(?!172\.(?![\p{Extended_Pictographic}])(?:1[6-9]|2\d|3[0-1])(?:\.(?![\p{Extended_Pictographic}])\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?![\p{Extended_Pictographic}])(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?![\p{Extended_Pictographic}])(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-)[a-z\u00a1-\uffff0-9]+)(?:\.(?![\p{Extended_Pictographic}])(?:[a-z\u00a1-\uffff0-9]-)[a-z\u00a1-\uffff0-9]+)(?:\.(?![\p{Extended_Pictographic}])(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S)?$/giu;
|
|
295
374
|
let looseUrlExpression = /^https?\:\/\/[^\/\s]+(\/.*)?$/;
|
|
296
375
|
let ip4Expression = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9]+\b(\/[-a-zA-Z0-9@:%_\+.~#?&\/=]*)?/g;
|
|
297
376
|
let emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ibs-format",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.15",
|
|
4
4
|
"description": "Detect the user-defined identifiers in the text and convert them into HTML tags like bold, italic, strike, and many more having XSS (Cross-site scripting) security with escaping functionality, also detect the links like URLs, email, and IP addresses and wrap them into Anchor tag `<a>`.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|