Newer
Older
text = text.replace(/@[Ee][Ee]@/g, "\1h\1y\1" + "3\1i"); // Blinking bright yellow on brown
text = text.replace(/@[Ee][Ff]@/g, "\1h\1w\1" + "3\1i"); // Blinking bright white on brown
// White background, blinking foreground
text = text.replace(/@[Ff]0@/g, "\1n\1k\1" + "7\1i"); // Blinking black on white
text = text.replace(/@[Ff]1@/g, "\1n\1b\1" + "7\1i"); // Blinking blue on white
text = text.replace(/@[Ff]2@/g, "\1n\1g\1" + "7\1i"); // Blinking green on white
text = text.replace(/@[Ff]3@/g, "\1n\1c\1" + "7\1i"); // Blinking cyan on white
text = text.replace(/@[Ff]4@/g, "\1n\1r\1" + "7\1i"); // Blinking red on white
text = text.replace(/@[Ff]5@/g, "\1n\1m\1" + "7\1i"); // Blinking magenta on white
text = text.replace(/@[Ff]6@/g, "\1n\1y\1" + "7\1i"); // Blinking yellow/brown on white
text = text.replace(/@[Ff]7@/g, "\1n\1w\1" + "7\1i"); // Blinking white on white
text = text.replace(/@[Ff]8@/g, "\1h\1k\1" + "7\1i"); // Blinking bright black on white
text = text.replace(/@[Ff]9@/g, "\1h\1b\1" + "7\1i"); // Blinking bright blue on white
text = text.replace(/@[Ff][Aa]@/g, "\1h\1g\1" + "7\1i"); // Blinking bright green on white
text = text.replace(/@[Ff][Bb]@/g, "\1h\1c\1" + "7\1i"); // Blinking bright cyan on white
text = text.replace(/@[Ff][Cc]@/g, "\1h\1r\1" + "7\1i"); // Blinking bright red on white
text = text.replace(/@[Ff][Dd]@/g, "\1h\1m\1" + "7\1i"); // Blinking bright magenta on white
text = text.replace(/@[Ff][Ee]@/g, "\1h\1y\1" + "7\1i"); // Blinking bright yellow on white
text = text.replace(/@[Ff][Ff]@/g, "\1h\1w\1" + "7\1i"); // Blinking bright white on white
15021
15022
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032
15033
15034
15035
15036
15037
15038
15039
15040
15041
15042
15043
return text;
}
else
return pText; // No Wildcat-style attribute codes found, so just return the text.
}
// Converts Celerity attribute codes to Synchronet attribute codes.
//
// Parameters:
// pText: A string containing the text to convert
//
// Return value: The text with the color codes converted
function celerityAttrsToSyncAttrs(pText)
{
// First, see if the text has any Celerity-style attribute codes at
// all. We'll be performing a bunch of search & replace commands,
// so we don't want to do all that work for nothing.. :)
if (/\|[kbgcrmywdBGCRMYWS]/.test(pText))
{
// Using the \|S code (swap foreground & background)
// Blue background
var text = pText.replace(/\|b\|S\|k/g, "\1n\1k\1" + "4"); // Black on blue
text = text.replace(/\|b\|S\|b/g, "\1n\1b\1" + "4"); // Blue on blue
text = text.replace(/\|b\|S\|g/g, "\1n\1g\1" + "4"); // Green on blue
text = text.replace(/\|b\|S\|c/g, "\1n\1c\1" + "4"); // Cyan on blue
text = text.replace(/\|b\|S\|r/g, "\1n\1r\1" + "4"); // Red on blue
text = text.replace(/\|b\|S\|m/g, "\1n\1m\1" + "4"); // Magenta on blue
text = text.replace(/\|b\|S\|y/g, "\1n\1y\1" + "4"); // Yellow/brown on blue
text = text.replace(/\|b\|S\|w/g, "\1n\1w\1" + "4"); // White on blue
text = text.replace(/\|b\|S\|d/g, "\1h\1k\1" + "4"); // Bright black on blue
text = text.replace(/\|b\|S\|B/g, "\1h\1b\1" + "4"); // Bright blue on blue
text = text.replace(/\|b\|S\|G/g, "\1h\1g\1" + "4"); // Bright green on blue
text = text.replace(/\|b\|S\|C/g, "\1h\1c\1" + "4"); // Bright cyan on blue
text = text.replace(/\|b\|S\|R/g, "\1h\1r\1" + "4"); // Bright red on blue
text = text.replace(/\|b\|S\|M/g, "\1h\1m\1" + "4"); // Bright magenta on blue
text = text.replace(/\|b\|S\|Y/g, "\1h\1y\1" + "4"); // Yellow on blue
text = text.replace(/\|b\|S\|W/g, "\1h\1w\1" + "4"); // Bright white on blue
// Green background
text = text.replace(/\|g\|S\|k/g, "\1n\1k\1" + "2"); // Black on green
text = text.replace(/\|g\|S\|b/g, "\1n\1b\1" + "2"); // Blue on green
text = text.replace(/\|g\|S\|g/g, "\1n\1g\1" + "2"); // Green on green
text = text.replace(/\|g\|S\|c/g, "\1n\1c\1" + "2"); // Cyan on green
text = text.replace(/\|g\|S\|r/g, "\1n\1r\1" + "2"); // Red on green
text = text.replace(/\|g\|S\|m/g, "\1n\1m\1" + "2"); // Magenta on green
text = text.replace(/\|g\|S\|y/g, "\1n\1y\1" + "2"); // Yellow/brown on green
text = text.replace(/\|g\|S\|w/g, "\1n\1w\1" + "2"); // White on green
text = text.replace(/\|g\|S\|d/g, "\1h\1k\1" + "2"); // Bright black on green
text = text.replace(/\|g\|S\|B/g, "\1h\1b\1" + "2"); // Bright blue on green
text = text.replace(/\|g\|S\|G/g, "\1h\1g\1" + "2"); // Bright green on green
text = text.replace(/\|g\|S\|C/g, "\1h\1c\1" + "2"); // Bright cyan on green
text = text.replace(/\|g\|S\|R/g, "\1h\1r\1" + "2"); // Bright red on green
text = text.replace(/\|g\|S\|M/g, "\1h\1m\1" + "2"); // Bright magenta on green
text = text.replace(/\|g\|S\|Y/g, "\1h\1y\1" + "2"); // Yellow on green
text = text.replace(/\|g\|S\|W/g, "\1h\1w\1" + "2"); // Bright white on green
// Cyan background
text = text.replace(/\|c\|S\|k/g, "\1n\1k\1" + "6"); // Black on cyan
text = text.replace(/\|c\|S\|b/g, "\1n\1b\1" + "6"); // Blue on cyan
text = text.replace(/\|c\|S\|g/g, "\1n\1g\1" + "6"); // Green on cyan
text = text.replace(/\|c\|S\|c/g, "\1n\1c\1" + "6"); // Cyan on cyan
text = text.replace(/\|c\|S\|r/g, "\1n\1r\1" + "6"); // Red on cyan
text = text.replace(/\|c\|S\|m/g, "\1n\1m\1" + "6"); // Magenta on cyan
text = text.replace(/\|c\|S\|y/g, "\1n\1y\1" + "6"); // Yellow/brown on cyan
text = text.replace(/\|c\|S\|w/g, "\1n\1w\1" + "6"); // White on cyan
text = text.replace(/\|c\|S\|d/g, "\1h\1k\1" + "6"); // Bright black on cyan
text = text.replace(/\|c\|S\|B/g, "\1h\1b\1" + "6"); // Bright blue on cyan
text = text.replace(/\|c\|S\|G/g, "\1h\1g\1" + "6"); // Bright green on cyan
text = text.replace(/\|c\|S\|C/g, "\1h\1c\1" + "6"); // Bright cyan on cyan
text = text.replace(/\|c\|S\|R/g, "\1h\1r\1" + "6"); // Bright red on cyan
text = text.replace(/\|c\|S\|M/g, "\1h\1m\1" + "6"); // Bright magenta on cyan
text = text.replace(/\|c\|S\|Y/g, "\1h\1y\1" + "6"); // Yellow on cyan
text = text.replace(/\|c\|S\|W/g, "\1h\1w\1" + "6"); // Bright white on cyan
// Red background
text = text.replace(/\|r\|S\|k/g, "\1n\1k\1" + "1"); // Black on red
text = text.replace(/\|r\|S\|b/g, "\1n\1b\1" + "1"); // Blue on red
text = text.replace(/\|r\|S\|g/g, "\1n\1g\1" + "1"); // Green on red
text = text.replace(/\|r\|S\|c/g, "\1n\1c\1" + "1"); // Cyan on red
text = text.replace(/\|r\|S\|r/g, "\1n\1r\1" + "1"); // Red on red
text = text.replace(/\|r\|S\|m/g, "\1n\1m\1" + "1"); // Magenta on red
text = text.replace(/\|r\|S\|y/g, "\1n\1y\1" + "1"); // Yellow/brown on red
text = text.replace(/\|r\|S\|w/g, "\1n\1w\1" + "1"); // White on red
text = text.replace(/\|r\|S\|d/g, "\1h\1k\1" + "1"); // Bright black on red
text = text.replace(/\|r\|S\|B/g, "\1h\1b\1" + "1"); // Bright blue on red
text = text.replace(/\|r\|S\|G/g, "\1h\1g\1" + "1"); // Bright green on red
text = text.replace(/\|r\|S\|C/g, "\1h\1c\1" + "1"); // Bright cyan on red
text = text.replace(/\|r\|S\|R/g, "\1h\1r\1" + "1"); // Bright red on red
text = text.replace(/\|r\|S\|M/g, "\1h\1m\1" + "1"); // Bright magenta on red
text = text.replace(/\|r\|S\|Y/g, "\1h\1y\1" + "1"); // Yellow on red
text = text.replace(/\|r\|S\|W/g, "\1h\1w\1" + "1"); // Bright white on red
// Magenta background
text = text.replace(/\|m\|S\|k/g, "\1n\1k\1" + "5"); // Black on magenta
text = text.replace(/\|m\|S\|b/g, "\1n\1b\1" + "5"); // Blue on magenta
text = text.replace(/\|m\|S\|g/g, "\1n\1g\1" + "5"); // Green on magenta
text = text.replace(/\|m\|S\|c/g, "\1n\1c\1" + "5"); // Cyan on magenta
text = text.replace(/\|m\|S\|r/g, "\1n\1r\1" + "5"); // Red on magenta
text = text.replace(/\|m\|S\|m/g, "\1n\1m\1" + "5"); // Magenta on magenta
text = text.replace(/\|m\|S\|y/g, "\1n\1y\1" + "5"); // Yellow/brown on magenta
text = text.replace(/\|m\|S\|w/g, "\1n\1w\1" + "5"); // White on magenta
text = text.replace(/\|m\|S\|d/g, "\1h\1k\1" + "5"); // Bright black on magenta
text = text.replace(/\|m\|S\|B/g, "\1h\1b\1" + "5"); // Bright blue on magenta
text = text.replace(/\|m\|S\|G/g, "\1h\1g\1" + "5"); // Bright green on magenta
text = text.replace(/\|m\|S\|C/g, "\1h\1c\1" + "5"); // Bright cyan on magenta
text = text.replace(/\|m\|S\|R/g, "\1h\1r\1" + "5"); // Bright red on magenta
text = text.replace(/\|m\|S\|M/g, "\1h\1m\1" + "5"); // Bright magenta on magenta
text = text.replace(/\|m\|S\|Y/g, "\1h\1y\1" + "5"); // Yellow on magenta
text = text.replace(/\|m\|S\|W/g, "\1h\1w\1" + "5"); // Bright white on magenta
// Brown background
text = text.replace(/\|y\|S\|k/g, "\1n\1k\1" + "3"); // Black on brown
text = text.replace(/\|y\|S\|b/g, "\1n\1b\1" + "3"); // Blue on brown
text = text.replace(/\|y\|S\|g/g, "\1n\1g\1" + "3"); // Green on brown
text = text.replace(/\|y\|S\|c/g, "\1n\1c\1" + "3"); // Cyan on brown
text = text.replace(/\|y\|S\|r/g, "\1n\1r\1" + "3"); // Red on brown
text = text.replace(/\|y\|S\|m/g, "\1n\1m\1" + "3"); // Magenta on brown
text = text.replace(/\|y\|S\|y/g, "\1n\1y\1" + "3"); // Yellow/brown on brown
text = text.replace(/\|y\|S\|w/g, "\1n\1w\1" + "3"); // White on brown
text = text.replace(/\|y\|S\|d/g, "\1h\1k\1" + "3"); // Bright black on brown
text = text.replace(/\|y\|S\|B/g, "\1h\1b\1" + "3"); // Bright blue on brown
text = text.replace(/\|y\|S\|G/g, "\1h\1g\1" + "3"); // Bright green on brown
text = text.replace(/\|y\|S\|C/g, "\1h\1c\1" + "3"); // Bright cyan on brown
text = text.replace(/\|y\|S\|R/g, "\1h\1r\1" + "3"); // Bright red on brown
text = text.replace(/\|y\|S\|M/g, "\1h\1m\1" + "3"); // Bright magenta on brown
text = text.replace(/\|y\|S\|Y/g, "\1h\1y\1" + "3"); // Yellow on brown
text = text.replace(/\|y\|S\|W/g, "\1h\1w\1" + "3"); // Bright white on brown
// White background
text = text.replace(/\|w\|S\|k/g, "\1n\1k\1" + "7"); // Black on white
text = text.replace(/\|w\|S\|b/g, "\1n\1b\1" + "7"); // Blue on white
text = text.replace(/\|w\|S\|g/g, "\1n\1g\1" + "7"); // Green on white
text = text.replace(/\|w\|S\|c/g, "\1n\1c\1" + "7"); // Cyan on white
text = text.replace(/\|w\|S\|r/g, "\1n\1r\1" + "7"); // Red on white
text = text.replace(/\|w\|S\|m/g, "\1n\1m\1" + "7"); // Magenta on white
text = text.replace(/\|w\|S\|y/g, "\1n\1y\1" + "7"); // Yellow/brown on white
text = text.replace(/\|w\|S\|w/g, "\1n\1w\1" + "7"); // White on white
text = text.replace(/\|w\|S\|d/g, "\1h\1k\1" + "7"); // Bright black on white
text = text.replace(/\|w\|S\|B/g, "\1h\1b\1" + "7"); // Bright blue on white
text = text.replace(/\|w\|S\|G/g, "\1h\1g\1" + "7"); // Bright green on white
text = text.replace(/\|w\|S\|C/g, "\1h\1c\1" + "7"); // Bright cyan on white
text = text.replace(/\|w\|S\|R/g, "\1h\1r\1" + "7"); // Bright red on white
text = text.replace(/\|w\|S\|M/g, "\1h\1m\1" + "7"); // Bright magenta on white
text = text.replace(/\|w\|S\|Y/g, "\1h\1y\1" + "7"); // Yellow on white
text = text.replace(/\|w\|S\|W/g, "\1h\1w\1" + "7"); // Bright white on white
// Colors on black background
15170
15171
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196
15197
15198
15199
15200
15201
text = text.replace(/\|k/g, "\1n\1k\1" + "0"); // Black on black
text = text.replace(/\|k\|S\|k/g, "\1n\1k\1" + "0"); // Black on black
text = text.replace(/\|b/g, "\1n\1b\1" + "0"); // Blue on black
text = text.replace(/\|k\|S\|b/g, "\1n\1b\1" + "0"); // Blue on black
text = text.replace(/\|g/g, "\1n\1g\1" + "0"); // Green on black
text = text.replace(/\|k\|S\|g/g, "\1n\1g\1" + "0"); // Green on black
text = text.replace(/\|c/g, "\1n\1c\1" + "0"); // Cyan on black
text = text.replace(/\|k\|S\|c/g, "\1n\1c\1" + "0"); // Cyan on black
text = text.replace(/\|r/g, "\1n\1r\1" + "0"); // Red on black
text = text.replace(/\|k\|S\|r/g, "\1n\1r\1" + "0"); // Red on black
text = text.replace(/\|m/g, "\1n\1m\1" + "0"); // Magenta on black
text = text.replace(/\|k\|S\|m/g, "\1n\1m\1" + "0"); // Magenta on black
text = text.replace(/\|y/g, "\1n\1y\1" + "0"); // Yellow/brown on black
text = text.replace(/\|k\|S\|y/g, "\1n\1y\1" + "0"); // Yellow/brown on black
text = text.replace(/\|w/g, "\1n\1w\1" + "0"); // White on black
text = text.replace(/\|k\|S\|w/g, "\1n\1w\1" + "0"); // White on black
text = text.replace(/\|d/g, "\1h\1k\1" + "0"); // Bright black on black
text = text.replace(/\|k\|S\|d/g, "\1h\1k\1" + "0"); // Bright black on black
text = text.replace(/\|B/g, "\1h\1b\1" + "0"); // Bright blue on black
text = text.replace(/\|k\|S\|B/g, "\1h\1b\1" + "0"); // Bright blue on black
text = text.replace(/\|G/g, "\1h\1g\1" + "0"); // Bright green on black
text = text.replace(/\|k\|S\|G/g, "\1h\1g\1" + "0"); // Bright green on black
text = text.replace(/\|C/g, "\1h\1c\1" + "0"); // Bright cyan on black
text = text.replace(/\|k\|S\|C/g, "\1h\1c\1" + "0"); // Bright cyan on black
text = text.replace(/\|R/g, "\1h\1r\1" + "0"); // Bright red on black
text = text.replace(/\|k\|S\|R/g, "\1h\1r\1" + "0"); // Bright red on black
text = text.replace(/\|M/g, "\1h\1m\1" + "0"); // Bright magenta on black
text = text.replace(/\|k\|S\|M/g, "\1h\1m\1" + "0"); // Bright magenta on black
text = text.replace(/\|Y/g, "\1h\1y\1" + "0"); // Yellow on black
text = text.replace(/\|k\|S\|Y/g, "\1h\1y\1" + "0"); // Yellow on black
text = text.replace(/\|W/g, "\1h\1w\1" + "0"); // Bright white on black
text = text.replace(/\|k\|S\|W/g, "\1h\1w\1" + "0"); // Bright white on black
15202
15203
15204
15205
15206
15207
15208
15209
15210
15211
15212
15213
15214
15215
15216
15217
15218
15219
15220
15221
return text;
}
else
return pText; // No Celerity-style attribute codes found, so just return the text.
}
// Converts Renegade attribute (color) codes to Synchronet attribute codes.
//
// Parameters:
// pText: A string containing the text to convert
//
// Return value: The text with the color codes converted
function renegadeAttrsToSyncAttrs(pText)
{
// First, see if the text has any Renegade-style attribute codes at
// all. We'll be performing a bunch of search & replace commands,
// so we don't want to do all that work for nothing.. :)
if (/\|[0-3][0-9]/.test(pText))
{
15222
15223
15224
15225
15226
15227
15228
15229
15230
15231
15232
15233
15234
15235
15236
15237
15238
15239
15240
15241
15242
15243
15244
15245
15246
15247
15248
15249
15250
15251
15252
15253
var text = pText.replace(/\|00/g, "\1n\1k"); // Normal black
text = text.replace(/\|01/g, "\1n\1b"); // Normal blue
text = text.replace(/\|02/g, "\1n\1g"); // Normal green
text = text.replace(/\|03/g, "\1n\1c"); // Normal cyan
text = text.replace(/\|04/g, "\1n\1r"); // Normal red
text = text.replace(/\|05/g, "\1n\1m"); // Normal magenta
text = text.replace(/\|06/g, "\1n\1y"); // Normal brown
text = text.replace(/\|07/g, "\1n\1w"); // Normal white
text = text.replace(/\|08/g, "\1n\1k\1h"); // High intensity black
text = text.replace(/\|09/g, "\1n\1b\1h"); // High intensity blue
text = text.replace(/\|10/g, "\1n\1g\1h"); // High intensity green
text = text.replace(/\|11/g, "\1n\1c\1h"); // High intensity cyan
text = text.replace(/\|12/g, "\1n\1r\1h"); // High intensity red
text = text.replace(/\|13/g, "\1n\1m\1h"); // High intensity magenta
text = text.replace(/\|14/g, "\1n\1y\1h"); // Yellow (high intensity brown)
text = text.replace(/\|15/g, "\1n\1w\1h"); // High intensity white
text = text.replace(/\|16/g, "\1" + "0"); // Background black
text = text.replace(/\|17/g, "\1" + "4"); // Background blue
text = text.replace(/\|18/g, "\1" + "2"); // Background green
text = text.replace(/\|19/g, "\1" + "6"); // Background cyan
text = text.replace(/\|20/g, "\1" + "1"); // Background red
text = text.replace(/\|21/g, "\1" + "5"); // Background magenta
text = text.replace(/\|22/g, "\1" + "3"); // Background brown
text = text.replace(/\|23/g, "\1" + "7"); // Background white
text = text.replace(/\|24/g, "\1i\1w\1" + "0"); // Blinking white on black
text = text.replace(/\|25/g, "\1i\1w\1" + "4"); // Blinking white on blue
text = text.replace(/\|26/g, "\1i\1w\1" + "2"); // Blinking white on green
text = text.replace(/\|27/g, "\1i\1w\1" + "6"); // Blinking white on cyan
text = text.replace(/\|28/g, "\1i\1w\1" + "1"); // Blinking white on red
text = text.replace(/\|29/g, "\1i\1w\1" + "5"); // Blinking white on magenta
text = text.replace(/\|30/g, "\1i\1w\1" + "3"); // Blinking white on yellow/brown
text = text.replace(/\|31/g, "\1i\1w\1" + "7"); // Blinking white on white
15254
15255
15256
15257
15258
15259
15260
15261
15262
15263
15264
15265
15266
15267
15268
15269
15270
15271
15272
15273
15274
15275
return text;
}
else
return pText; // No Renegade-style attribute codes found, so just return the text.
}
// Converts ANSI attribute codes to Synchronet attribute codes.
//
// Parameters:
// pText: A string containing the text to convert
//
// Return value: The text with the color codes converted
function ANSIAttrsToSyncAttrs(pText)
{
// TODO: Test & update this some more.. Not sure if this is working 100% right.
// Web pages with ANSI code information:
// http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html
// http://ascii-table.com/ansi-escape-sequences.php
// http://stackoverflow.com/questions/4842424/list-of-ansi-color-escape-sequences
// First, see if the text has any ANSI attribute codes at all. We'll be
15276
15277
15278
15279
15280
15281
15282
15283
15284
15285
15286
15287
15288
15289
15290
15291
15292
15293
15294
15295
15296
15297
15298
15299
15300
15301
15302
15303
15304
15305
15306
15307
15308
15309
15310
15311
15312
15313
15314
15315
15316
15317
15318
15319
15320
15321
15322
15323
15324
15325
15326
15327
15328
15329
15330
15331
15332
15333
15334
15335
15336
15337
15338
15339
15340
15341
15342
15343
15344
15345
15346
15347
15348
15349
15350
15351
15352
15353
15354
15355
15356
15357
15358
15359
// performing a bunch of search & replace commands, so we don't want to do
// all that work for nothing.
if (textHasANSICodes(pText))
{
var text = "";
var tempDirExists = true;
// Temporary (to get it to run the old way for now)
tempDirExists = false;
/*
var readerTmpDir = backslash(system.node_dir + "DDMsgReaderTemp");
if (!file_exists(readerTmpDir))
tempDirExists = mkdir(readerTmpDir);
*/
if (tempDirExists)
{
var wroteTempFile = true;
var tmpFileName = readerTmpDir + "tmpMessage.ans";
var msgTmpFile = new File(tmpFileName);
if (msgTmpFile.open("w"))
{
wroteTempFile = msgTmpFile.write(pText);
msgTmpFile.close();
}
// If the temp file was written, then convert it to Synchronet
// attributes using ans2asc.
if (wroteTempFile)
{
var convertedTempFileName = readerTmpDir + "tmpMessage.asc";
var cmdLine = system.exec_dir + "ans2asc \"" + tmpFileName + "\" \""
+ convertedTempFileName + "\"";
// Note: Both system.exec(cmdLine) and
// bbs.exec(cmdLine, EX_NATIVE, gStartupPath) could be used to
// execute the command, but system.exec() seems noticeably faster.
system.exec(cmdLine);
var convertedTmpFile = new File(convertedTempFileName);
if (convertedTmpFile.open("r"))
{
text = convertedTmpFile.read();
convertedTmpFile.close();
}
}
deltree(readerTmpDir);
}
else
{
// Attributes
var text = pText.replace(/\[0[mM]/g, "\1n"); // All attributes off
text = text.replace(/\[1[mM]/g, "\1h"); // Bold on (use high intensity)
text = text.replace(/\[5[mM]/g, "\1i"); // Blink on
// Foreground colors
text = text.replace(/\[30[mM]/g, "\1k"); // Black foreground
text = text.replace(/\[31[mM]/g, "\1r"); // Red foreground
text = text.replace(/\[32[mM]/g, "\1g"); // Green foreground
text = text.replace(/\[33[mM]/g, "\1y"); // Yellow foreground
text = text.replace(/\[34[mM]/g, "\1b"); // Blue foreground
text = text.replace(/\[35[mM]/g, "\1m"); // Magenta foreground
text = text.replace(/\[36[mM]/g, "\1c"); // Cyan foreground
text = text.replace(/\[37[mM]/g, "\1w"); // White foreground
// Background colors
text = text.replace(/\[40[mM]/g, "\1" + "0"); // Black background
text = text.replace(/\[41[mM]/g, "\1" + "1"); // Red background
text = text.replace(/\[42[mM]/g, "\1" + "2"); // Green background
text = text.replace(/\[43[mM]/g, "\1" + "3"); // Yellow background
text = text.replace(/\[44[mM]/g, "\1" + "4"); // Blue background
text = text.replace(/\[45[mM]/g, "\1" + "5"); // Magenta background
text = text.replace(/\[46[mM]/g, "\1" + "6"); // Cyan background
text = text.replace(/\[47[mM]/g, "\1" + "7"); // White background
// Convert ;-delimited modes (such as [Value;...;Valuem)
text = ANSIMultiConvertToSyncCodes(text);
// Remove ANSI codes that are not wanted (such as moving the cursor, etc.)
text = text.replace(/\[[0-9]+[aA]/g, ""); // Cursor up
text = text.replace(/\[[0-9]+[bB]/g, ""); // Cursor down
text = text.replace(/\[[0-9]+[cC]/g, ""); // Cursor forward
text = text.replace(/\[[0-9]+[dD]/g, ""); // Cursor backward
text = text.replace(/\[[0-9]+;[0-9]+[hH]/g, ""); // Cursor position
text = text.replace(/\[[0-9]+;[0-9]+[fF]/g, ""); // Cursor position
text = text.replace(/\[[sS]/g, ""); // Restore cursor position
text = text.replace(/\[2[jJ]/g, ""); // Erase display
text = text.replace(/\[[kK]/g, ""); // Erase line
text = text.replace(/\[=[0-9]+[hH]/g, ""); // Set various screen modes
text = text.replace(/\[=[0-9]+[lL]/g, ""); // Reset various screen modes
}
return text;
}
else
return pText; // No ANSI codes found, so just return the text.
}
// Returns whether or not some text has any ANSI codes in it.
//
// Parameters:
// pText: The text to test
//
// Return value: Boolean - Whether or not the text has ANSI codes in it
function textHasANSICodes(pText)
{
return(/\[[0-9]+[mM]/.test(pText) || /\[[0-9]+(;[0-9]+)+[mM]/.test(pText) ||
/\[[0-9]+[aAbBcCdD]/.test(pText) || /\[[0-9]+;[0-9]+[hHfF]/.test(pText) ||
/\[[sSuUkK]/.test(pText) || /\[2[jJ]/.test(pText));
}
15380
15381
15382
15383
15384
15385
15386
15387
15388
15389
15390
15391
15392
15393
15394
15395
15396
15397
15398
15399
15400
15401
15402
15403
15404
15405
15406
15407
15408
15409
15410
15411
15412
15413
15414
15415
15416
15417
15418
15419
15420
15421
15422
15423
15424
15425
// Converts ANSI ;-delimited modes (such as [Value;...;Valuem) to Synchronet
// attribute codes
//
// Parameters:
// pText: The text with ANSI ;-delimited modes to convert
//
// Return value: The text with ANSI ;-delimited modes converted to Synchronet attributes
function ANSIMultiConvertToSyncCodes(pText)
{
var multiMatches = pText.match(/\[[0-9]+(;[0-9]+)+m/g);
if (multiMatches == null)
return pText;
var updatedText = pText;
for (var i = 0; i < multiMatches.length; ++i)
{
// Copy the string, with the [ removed from the beginning and the
// trailing 'm' removed
var text = multiMatches[i].substr(2);
text = text.substr(0, text.length-1);
var codes = text.split(";");
var syncCodes = "";
for (var idx = 0; idx < codes.length; ++idx)
{
if (codes[idx] == "0") // All attributes off
syncCodes += "\1n";
else if (codes[idx] == "1") // Bold on (high intensity)
syncCodes += "\1h";
else if (codes[idx] == "5") // Blink on
syncCodes += "\1i";
else if (codes[idx] == "30") // Black foreground
syncCodes += "\1k";
else if (codes[idx] == "31") // Red foreground
syncCodes += "\1r";
else if (codes[idx] == "32") // Green foreground
syncCodes += "\1g";
else if (codes[idx] == "33") // Yellow foreground
syncCodes += "\1y";
else if (codes[idx] == "34") // Blue foreground
syncCodes += "\1b";
else if (codes[idx] == "35") // Magenta foreground
syncCodes += "\1m";
else if (codes[idx] == "36") // Cyan foreground
syncCodes += "\1c";
else if (codes[idx] == "37") // White foreground
syncCodes += "\1w";
else if (codes[idx] == "40") // Black background
else if (codes[idx] == "41") // Red background
else if (codes[idx] == "42") // Green background
else if (codes[idx] == "43") // Yellow background
else if (codes[idx] == "44") // Blue background
else if (codes[idx] == "45") // Magenta background
else if (codes[idx] == "46") // Cyan background
else if (codes[idx] == "47") // White background
15441
15442
15443
15444
15445
15446
15447
15448
15449
15450
15451
15452
15453
15454
15455
15456
15457
15458
15459
15460
15461
15462
15463
15464
15465
15466
15467
15468
15469
15470
15471
15472
15473
15474
15475
15476
15477
15478
15479
15480
15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
}
updatedText = updatedText.replace(multiMatches[i], syncCodes);
}
return updatedText;
}
// Returns whether a given message group index & sub-board index (or the current ones,
// based on bbs.curgrp and bbs.cursub) are for the last message sub-board on the system.
//
// Parameters:
// pGrpIdx: Optional - The index of the message group. If not specified, this will
// default to bbs.curgrp. If bbs.curgrp is not defined in that case,
// then this method will return false.
// pSubIdx: Optional - The index of the message sub-board. If not specified, this will
// default to bbs.cursub. If bbs.cursub is not defined in that case,
// then this method will return false.
//
// Return value: Boolean - Whether or not the current/given message group index & sub-board
// index are for the last message sub-board on the system. If there
// are any issues with any of the values (including bbs.curgrp or
// bbs.cursub), this method will return false.
function curMsgSubBoardIsLast(pGrpIdx, pSubIdx)
{
var curGrp = 0;
if (typeof(pGrpIdx) == "number")
curGrp = pGrpIdx;
else if (typeof(bbs.curgrp) == "number")
curGrp = bbs.curgrp;
else
return false;
var curSub = 0;
if (typeof(pSubIdx) == "number")
curSub = pSubIdx;
else if (typeof(bbs.cursub) == "number")
curSub = bbs.cursub;
else
return false;
return (curGrp == msg_area.grp_list.length-1) && (curSub == msg_area.grp_list[msg_area.grp_list.length-1].sub_list.length-1);
}
// Parses arguments, where each argument in the given array is in the format
// -arg=val. If the value is the string "true" or "false", then the value will
// be a boolean. Otherwise, the value will be a string.
//
// Parameters:
// pArgArr: An array of strings containing values in the format -arg=val
//
// Return value: An object containing the argument values. The index will be
// the argument names, converted to lowercase. The values will
// be either the string argument values or boolean values, depending
// on the formats of the arguments passed in.
function parseArgs(pArgArr)
{
15495
15496
15497
15498
15499
15500
15501
15502
15503
15504
15505
15506
15507
15508
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518
15519
15520
15521
15522
var argVals = new Object();
// Set default values for parameters that are just true/false values
argVals.chooseareafirst = false;
argVals.personalemail = false;
argVals.personalemailsent = false;
argVals.verboselogging = false;
argVals.suppresssearchtypetext = false;
// Sanity checking for pArgArr - Make sure it's an array
if ((typeof(pArgArr) != "object") || (typeof(pArgArr.length) != "number"))
return argVals;
// Go through pArgArr looking for strings in the format -arg=val and parse them
// into objects in the argVals array.
var equalsIdx = 0;
var argName = "";
var argVal = "";
var argValLower = ""; // For case-insensitive "true"/"false" matching
var argValIsTrue = false;
for (var i = 0; i < pArgArr.length; ++i)
{
// We're looking for strings that start with "-", except strings that are
// only "-".
if ((typeof(pArgArr[i]) != "string") || (pArgArr[i].length == 0) ||
(pArgArr[i].charAt(0) != "-") || (pArgArr[i] == "-"))
{
continue;
}
15524
15525
15526
15527
15528
15529
15530
15531
15532
15533
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
// Look for an = and if found, split the string on the =
equalsIdx = pArgArr[i].indexOf("=");
// If a = is found, then split on it and add the argument name & value
// to the array. Otherwise (if the = is not found), then treat the
// argument as a boolean and set it to true (to enable an option).
if (equalsIdx > -1)
{
argName = pArgArr[i].substring(1, equalsIdx).toLowerCase();
argVal = pArgArr[i].substr(equalsIdx+1);
argValLower = argVal.toLowerCase();
// If the argument value is the word "true" or "false", then add it as a
// boolean. Otherwise, add it as a string.
argValIsTrue = (argValLower == "true");
if (argValIsTrue || (argValLower == "false"))
argVals[argName] = argValIsTrue;
else
argVals[argName] = argVal;
}
else // An equals sign (=) was not found. Add as a boolean set to true to enable the option.
{
argName = pArgArr[i].substr(1).toLowerCase();
if ((argName == "chooseareafirst") || (argName == "personalemail") ||
(argName == "personalemailsent") || (argName == "allpersonalemail") ||
(argName == "verboselogging") || (argName == "suppresssearchtypetext"))
{
argVals[argName] = true;
}
}
}
// Sanity checking
// If the arguments include personalEmail and personalEmail is enabled,
// then check to see if a search type was specified - If so, only allow
// keyword search and from name search.
if (argVals.hasOwnProperty("personalemail") && argVals.personalemail)
{
// If a search type is specified, only allow keyword search & from name
// search
if (argVals.hasOwnProperty("search"))
{
var searchValLower = argVals.search.toLowerCase();
if ((searchValLower != "keyword_search") && (searchValLower != "from_name_search"))
delete argVals.search;
}
}
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
15581
15582
15583
15584
15585
15586
15587
15588
15589
15590
15591
15592
15593
// If the arguments include userNum, make sure the value is all digits. If so,
// add altUserNum to the arguments as a number type for user matching when looking
// for personal email to the user.
if (argVals.hasOwnProperty("usernum"))
{
if (/^[0-9]+$/.test(argVals.usernum))
{
var specifiedUserNum = Number(argVals.usernum);
// If the specified number is different than the current logged-in
// user, then load the other user account and read their name and
// alias and also store their user number in the arg vals as a
// number.
if (specifiedUserNum != user.number)
{
var theUser = new User(specifiedUserNum);
argVals.altUserNum = theUser.number;
argVals.altUserName = theUser.name;
argVals.altUserAlias = theUser.alias;
}
else
delete argVals.usernum;
}
else
delete argVals.usernum;
}
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
15629
15630
15631
15632
15633
return argVals;
}
// Returns a string describing all message attributes (main, auxiliary, and net).
//
// Parameters:
// pMsgHdr: A message header object.
//
// Return value: A string describing all of the message attributes
function makeAllMsgAttrStr(pMsgHdr)
{
if ((pMsgHdr == null) || (typeof(pMsgHdr) != "object"))
return "";
var msgAttrStr = makeMainMsgAttrStr(pMsgHdr.attr);
var auxAttrStr = makeAuxMsgAttrStr(pMsgHdr.auxattr);
if (auxAttrStr.length > 0)
{
if (msgAttrStr.length > 0)
msgAttrStr += ", ";
msgAttrStr += auxAttrStr;
}
var netAttrStr = makeNetMsgAttrStr(pMsgHdr.netattr);
if (netAttrStr.length > 0)
{
if (msgAttrStr.length > 0)
msgAttrStr += ", ";
msgAttrStr += netAttrStr;
}
return msgAttrStr;
}
// Returns a string describing the main message attributes. Makes use of the
// gMainMsgAttrStrs object for the main message attributes and description
// strings.
//
// Parameters:
// pMainMsgAttrs: The bit field for the main message attributes
// (normally, the 'attr' property of a header object)
// pIfEmptyString: Optional - A string to use if there are no attributes set
//
// Return value: A string describing the main message attributes
function makeMainMsgAttrStr(pMainMsgAttrs, pIfEmptyString)
{
var msgAttrStr = "";
if (typeof(pMainMsgAttrs) == "number")
{
for (var prop in gMainMsgAttrStrs)
{
if ((pMainMsgAttrs & prop) == prop)
{
if (msgAttrStr.length > 0)
msgAttrStr += ", ";
msgAttrStr += gMainMsgAttrStrs[prop];
}
}
}
if ((msgAttrStr.length == 0) && (typeof(pIfEmptyString) == "string"))
msgAttrStr = pIfEmptyString;
return msgAttrStr;
}
// Returns a string describing auxiliary message attributes. Makes use of the
// gAuxMsgAttrStrs object for the auxiliary message attributes and description
// strings.
//
// Parameters:
// pAuxMsgAttrs: The bit field for the auxiliary message attributes
// (normally, the 'auxattr' property of a header object)
// pIfEmptyString: Optional - A string to use if there are no attributes set
//
// Return value: A string describing the auxiliary message attributes
function makeAuxMsgAttrStr(pAuxMsgAttrs, pIfEmptyString)
{
var msgAttrStr = "";
if (typeof(pAuxMsgAttrs) == "number")
{
for (var prop in gAuxMsgAttrStrs)
{
if ((pAuxMsgAttrs & prop) == prop)
{
if (msgAttrStr.length > 0)
msgAttrStr += ", ";
msgAttrStr += gAuxMsgAttrStrs[prop];
}
}
}
if ((msgAttrStr.length == 0) && (typeof(pIfEmptyString) == "string"))
msgAttrStr = pIfEmptyString;
return msgAttrStr;
}
// Returns a string describing network message attributes. Makes use of the
// gNetMsgAttrStrs object for the network message attributes and description
// strings.
//
// Parameters:
// pNetMsgAttrs: The bit field for the network message attributes
// (normally, the 'netattr' property of a header object)
// pIfEmptyString: Optional - A string to use if there are no attributes set
//
// Return value: A string describing the network message attributes
function makeNetMsgAttrStr(pNetMsgAttrs, pIfEmptyString)
{
var msgAttrStr = "";
if (typeof(pNetMsgAttrs) == "number")
{
for (var prop in gNetMsgAttrStrs)
{
if ((pNetMsgAttrs & prop) == prop)
{
if (msgAttrStr.length > 0)
msgAttrStr += ", ";
msgAttrStr += gNetMsgAttrStrs[prop];
}
}
}
if ((msgAttrStr.length == 0) && (typeof(pIfEmptyString) == "string"))
msgAttrStr = pIfEmptyString;
15714
15715
15716
15717
15718
15719
15720
15721
15722
15723
15724
15725
15726
15727
15728
15729
15730
15731
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744
15745
15746
15747
15748
15749
15750
15751
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763
return msgAttrStr;
}
// Given a sub-board code, this function returns a sub-board's group and name.
// If the given sub-board code is "mail", then this will return "Personal mail".
//
// Parameters:
// pSubBoardCode: An internal sub-board code
//
// Return value: A string containing the sub-board code group & name, or
// "Personal email" if it's the personal email sub-board
function subBoardGrpAndName(pSubBoardCode)
{
if (typeof(pSubBoardCode) != "string")
return "";
var subBoardGrpAndName = "";
if (pSubBoardCode == "mail")
subBoardGrpAndName = "Personal mail";
else
{
subBoardGrpAndName = msg_area.sub[pSubBoardCode].grp_name + " - "
+ msg_area.sub[pSubBoardCode].name;
}
return subBoardGrpAndName;
}
// Returns whether a given string matches the current user's name, handle, or alias.
// Does a case-insensitive match.
//
// Parameters:
// pStr: The string to match against the user's name/handle/alias
//
// Return value: Boolean - Whether or not the string matches the current user's name,
// handle, or alias
function userNameHandleAliasMatch(pStr)
{
if (typeof(pStr) != "string")
return false;
var strUpper = pStr.toUpperCase();
return ((strUpper == user.name.toUpperCase()) || (strUpper == user.handle.toUpperCase()) || (strUpper == user.alias.toUpperCase()));
}
// Writes a log message to the system log (using LOG_INFO log level) and to the
// node log. This will prepend the text "Digital Distortion Message Reader ("
// + user.alias + "): " to the log message.
//
// Parameters:
// pMessage: The message to log
// pLogLevel: The log level. Optional - Defaults to LOG_INFO.
function writeToSysAndNodeLog(pMessage, pLogLevel)
{
if (typeof(pMessage) != "string")
return;
var logMessage = "Digital Distortion Message Reader (" + user.alias + "): " + pMessage;
var logLevel = (typeof(pLogLevel) == "number" ? pLogLevel : LOG_INFO);
log(logLevel, logMessage);
bbs.log_str(logMessage);
}
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
// This function looks up and returns a sub-board code from the sub-board number.
// If no matching sub-board is found, this will return an empty string.
//
// Parameters:
// pSubBoardNum: A sub-board number
//
// Return value: The sub-board code. If no matching sub-board is found, an empty
// string will be returned.
function getSubBoardCodeFromNum(pSubBoardNum)
{
// Ensure we're using a numeric type for the sub-board number
// (in case pSubBoardNum is a string rather than a number)
var subNum = Number(pSubBoardNum);
var subBoardCode = "";
for (var subCode in msg_area.sub)
{
if (msg_area.sub[subCode].number == subNum)
{
subBoardCode = subCode;
break;
}
}
return subBoardCode;
}
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
// Separates message text and any attachment data.
//
// Parameters:
// pMsgHdr: The message header object
// pMsgText: The text of a message
// pGetB64Data: Optional boolean - Whether or not to get the Base64-encoded
// data for base64-encoded attachments (i.e., in multi-part MIME
// emails). Defaults to true.
//
// Return value: An object containing the following properties:
// msgText: The text of the message, without any of the
// attachment base64-encoded data, etc. If
// the message doesn't have any attachments, then
// this will likely be the same as pMsgText.
// attachments: An array of objects containing the following properties
// for each attachment:
// B64Data: Base64-encoded file data - Only for attachments
// that were attached as base64 in the message (i.e.,
// in a multi-part MIME message). If the attachment
// was uploaded to the user's Synchronet mailbox,
// then the object won't have the B64Data property.
// filename: The name of the attached file
// fullyPathedFilename: The full path & filename of the
// attached file saved on the BBS machine
// errorMsg: An error message if anything went wrong. If
// nothing went wrong, this will be an empty string.
function determineMsgAttachments(pMsgHdr, pMsgText, pGetB64Data)
{
var retObj = new Object();
retObj.msgText = "";
retObj.attachments = [];
retObj.errorMsg = "";
// Keep track of the user's inbox directory: sbbs/data/file/<userNum>.in
var userInboxDir = backslash(backslash(system.data_dir + "file") + format("%04d.in", user.number));
// If the message subject is a filename that exists in the user's
// inbox directory, then add its filename to the list of attached
// filenames that will be returned
var fullyPathedAttachmentFilename = userInboxDir + pMsgHdr.subject;
if (file_exists(fullyPathedAttachmentFilename))
{
retObj.attachments.push({ filename: pMsgHdr.subject,
fullyPathedFilename: fullyPathedAttachmentFilename });
}
// The message to prepend onto the message text if the message has attachments
var msgHasAttachmentsTxt = "\1n\1g\1h- This message contains one or more attachments. Press CTRL-A to download.\1n\r\n"
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
15864
15865
15866
15867
15868
15869
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
15887
15888
15889
15890
15891
15892
15893
15894
15895
15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916
15917
15918
15919
15920
15921
15922
15923
15924
15925
15926
15927
15928
15929
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
15963
15964
15965
15966
15967
15968
15969
15970
15971
15972
15973
15974
15975
15976
15977
15978
15979
15980
15981
15982
15983
15984
15985
15986
15987
15988
15989
15990
15991
15992
15993
15994
15995
15996
15997
15998
15999
16000
+ "\1n\1g\1h--------------------------------------------------------------------------\1n\r\n";
// Sanity checking
if (typeof(pMsgText) != "string")
{
// If there are any attachments, prepend the message text with a message
// saying that the message contains attachments.
if (retObj.attachments.length > 0)
retObj.msgText = msgHasAttachmentsTxt + retObj.msgText;
return retObj;
}
// If the message text doesn't include a line starting with -- and a
// line starting with "Content-type:", then then just return the
// the same text in retObj.
//var hasMultiParts = /--\S+\s*Content-Type:/.test(pMsgText);
//var hasMultiParts = ((dashDashIdx > -1) && (/Content-Type/.test(pMsgText)));
var dashDashIdx = pMsgText.indexOf("--");
var hasMultiParts = ((dashDashIdx > -1) && (pMsgText.indexOf("Content-Type", dashDashIdx+1) > dashDashIdx));
if (!hasMultiParts)
{
//retObj.msgText = pMsgText;
// If there are any attachments, prepend the message text with a message
// saying that the message contains attachments.
if (retObj.attachments.length > 0)
retObj.msgText = msgHasAttachmentsTxt + pMsgText;
else
retObj.msgText = pMsgText;
return retObj;
}
var getB64Data = true;
if (typeof(pGetB64Data) == "boolean")
getB64Data = pGetB64Data;
// Look in the message text for a line starting with -- followed by some characters,
// then whitespace
var sepMatches = /--\S+\s/.exec(pMsgText);
var msgSeparator = sepMatches[0];
// If the last character in msgSeparator is a whitepsace character, then
// remove it.
if (/\s/.test(msgSeparator.substr(msgSeparator.length-1, 1)))
msgSeparator = msgSeparator.substr(0, msgSeparator.length-1);
var contentType = ""; // The content type of the current section
var lastContentType = ""; // The content type of the last section
var contentEncodingType = "";
var sepIdx = 0;
var lastSepIdx = -1;
var lastContentTypeIdx = -1;
var lastContentEncodingTypeIdx = -1;
var startIdx = 0;
var gotMessageText = false; // In case the message has both text/plain & text/html
while ((sepIdx = pMsgText.indexOf(msgSeparator, startIdx)) >= 0)
{
var contentEncodingTypeIdx = -1;
// Look for a "Content-Type:" from the starting index
var contentTypeIdx = pMsgText.indexOf("Content-Type: ", startIdx+msgSeparator.length);
if (contentTypeIdx > -1)
{
// Extract the content-type string up to a newline or 15 characters
// if there's no newline
var newlineIdx = pMsgText.indexOf("\n", contentTypeIdx+14);
contentType = pMsgText.substring(contentTypeIdx+14, newlineIdx > -1 ? newlineIdx : contentTypeIdx+29);
// If the last character is whitespace (i.e., a newline), then remove it.
if (/\s/.test(contentType.substr(contentType.length-1, 1)))
contentType = contentType.substr(0, contentType.length-1);
// Update the start index for looking for the next message separator string
// - This should be after the "Content-type:" value.
startIdx = contentTypeIdx + contentType.length;
}
else
{
// No "Content-Type:" string was found
// Update the start index for looking for the next message separator string
startIdx = sepIdx + msgSeparator.length;
}
if ((lastSepIdx > -1) && (lastContentTypeIdx > -1))
{
// msgTextSearchStartIdx stores the index of where to start looking
// for the message text. It could be lastContentTypeIdx, or it could
// be the content encoding type index if the "Content encoding type"
// text is found for the current message part.
var msgTextSearchStartIdx = lastContentTypeIdx;
// Look for "Content-Transfer-Encoding:" right after the content type
// and extract the content encoding type string
contentEncodingTypeIdx = pMsgText.indexOf("Content-Transfer-Encoding:", lastContentTypeIdx);
// If "Content-Transfer-Encoding:" wasn't found after the content type,
// then look just before the content type, but after the last separator
// string.
if (contentEncodingTypeIdx == -1)
contentEncodingTypeIdx = pMsgText.indexOf("Content-Transfer-Encoding:", lastSepIdx);
// If the next "Content-Encoding-Type" is after the current section,
// then this section doesn't have a content type, so blank it out.
if (contentEncodingTypeIdx > sepIdx)
{
contentEncodingTypeIdx = -1;
contentEncodingType = "";
}
else
{
msgTextSearchStartIdx = contentEncodingTypeIdx;
// Extract the content encoding type
var newlineIdx = pMsgText.indexOf("\n", contentEncodingTypeIdx+26);
contentEncodingType = pMsgText.substring(contentEncodingTypeIdx, newlineIdx);
// If the last character is whitespace (i.e., a newline), then remove it.
if (/\s/.test(contentEncodingType.substr(contentEncodingType.length-1, 1)))
contentEncodingType = contentEncodingType.substr(0, contentEncodingType.length-1);
// Update startIdx based on the length of the "content encoding type" string
startIdx += contentEncodingType.length;
// Now, store just the content type in contentEncodingType (i.e., "base64").
contentEncodingType = contentEncodingType.substr(27).toLowerCase();
}
// Look for the message text
var contentTypeSearchIdx = -1;
//if ((contentTypeSearchIdx = lastContentType.indexOf("text/plain")) > -1)
if ((contentTypeSearchIdx = lastContentType.indexOf("text/")) > -1)
{
if (!gotMessageText)
{
var newlineIdx = pMsgText.indexOf("\n", msgTextSearchStartIdx); // Used to be lastContentTypeIdx
if (newlineIdx > -1)
retObj.msgText = pMsgText.substring(newlineIdx+1, sepIdx);
else
retObj.msgText = pMsgText.substring(lastSepIdx, sepIdx);
gotMessageText = true;
}
}
else
{
// Look for a filename in the content-type specification
// If it doesn't contain the filename, then we'll have to look on the
// next line for the filename.
var attachmentFilename = "";
var matches = /name="(.*)"/.exec(lastContentType);
if (matches != null)
{
if (matches.length >= 2)
attachmentFilename = matches[1];
}
if (attachmentFilename.length == 0)
{
// Look for the filename on the next line
var newlineIdx = pMsgText.indexOf("\n", lastContentTypeIdx);
if (newlineIdx > -1)
{
// 1000 chars should be enough
var nextLine = pMsgText.substr(newlineIdx+1, 1000);
var matches = /name="(.*)"/.exec(nextLine);