From 95bde8cb1548dd35e0355af9c1a5b287cff993fe Mon Sep 17 00:00:00 2001 From: Eric Oulashin <nightfox@synchro.net> Date: Tue, 16 May 2023 17:37:05 +0000 Subject: [PATCH] Made a fix for the refactored theme config reading code in much of the Digital Distortion tools --- docs/slyedit_readme.txt | 10 +- exec/SlyEdit.js | 7 +- exec/SlyEdit_DCTStuff.js | 42 +++++--- exec/SlyEdit_IceStuff.js | 48 ++++++---- exec/SlyEdit_Misc.js | 77 --------------- xtrn/DDAreaChoosers/DDFileAreaChooser.js | 2 +- xtrn/DDAreaChoosers/DDMsgAreaChooser.js | 2 +- xtrn/DDMsgReader/DDMsgReader.js | 11 +-- xtrn/ddfilelister/ddfilelister.js | 3 +- xtrn/gttrivia/gttrivia.js | 116 +++++++++++++++-------- 10 files changed, 153 insertions(+), 165 deletions(-) diff --git a/docs/slyedit_readme.txt b/docs/slyedit_readme.txt index 6bb810477a..6a7fc5ac7e 100644 --- a/docs/slyedit_readme.txt +++ b/docs/slyedit_readme.txt @@ -1,13 +1,13 @@ SlyEdit message editor - Version 1.84 - Release date: 2023-02-10 + Version 1.85 + Release date: 2023-05-15 by Eric Oulashin Sysop of Digital Distortion BBS BBS internet address: digitaldistortionbbs.com - Alternate: digdist.synchro.net + Alternate: digdist.synchro.net Email: eric.oulashin@gmail.com @@ -918,10 +918,6 @@ message to lower-case and comparing them with the words in the dictionary. =================== Version Date Description ------- ---- ----------- -1.84 2023-02-10 Sysops: When importing a file from the BBS machine, - SlyEdit now prompts to send it immediately or not (if - not, edit it before sending). Sending immediately can be - useful for posting ANSI files unmodified. 1.83 2022-12-13 Quote lines that are wider than the user's terminal width are now wrapped to the user's terminal width to ensure all the quote lines are entirely available to be quoted. diff --git a/exec/SlyEdit.js b/exec/SlyEdit.js index 62fba8b228..3fbbae804b 100644 --- a/exec/SlyEdit.js +++ b/exec/SlyEdit.js @@ -30,6 +30,9 @@ * prompts to send it immediately or not (if not, edit it before * sending). Sending immediately can be useful for posting * ANSI files unmodified. + * 2023-05-15 Eric Oulashin Version 1.85 + * Internal: Refactored readColorConfig() in _DCTStuff.js and _IceStuff.js. + * Removed the readValueSettingConfigFile() function. */ "use strict"; @@ -127,8 +130,8 @@ if (console.screen_columns < 80) } // Version information -var EDITOR_VERSION = "1.84"; -var EDITOR_VER_DATE = "2023-02-10"; +var EDITOR_VERSION = "1.85"; +var EDITOR_VER_DATE = "2023-05-15"; // Program variables diff --git a/exec/SlyEdit_DCTStuff.js b/exec/SlyEdit_DCTStuff.js index 57eb98fc8b..a6e2a552d4 100644 --- a/exec/SlyEdit_DCTStuff.js +++ b/exec/SlyEdit_DCTStuff.js @@ -13,6 +13,7 @@ * 2019-05-04 Eric Oulashin Updated to use require() instead of load() if possible. * 2021-12-11 Eric Oulashin Updated the quote window bottom border text * 2022-11-19 Eric Oulashin Updated readColorConfig() to handle just attribute characters + * 2023-05-15 Eric Oulashin Refactored readColorConfig() */ "use strict"; @@ -56,22 +57,37 @@ readColorConfig(gConfigSettings.DCTColors.ThemeFilename); // pFilename: The name of the color configuration file function readColorConfig(pFilename) { - var colors = readValueSettingConfigFile(pFilename, 512); - if (colors != null) + var themeFile = new File(pFilename); + if (themeFile.open("r")) { - // Convert the color values from just attribute characters to actual attribute codes - for (var prop in colors) + var colorSettingsObj = themeFile.iniGetObject(); + themeFile.close(); + + // DCT-specific colors + for (var prop in gConfigSettings.DCTColors) { - // Remove any instances of specifying the control character - colors[prop] = colors[prop].replace(/\\[xX]01/g, "").replace(/\\[xX]1/g, "").replace(/\\1/g, ""); - // Add actual control characters in the color setting - colors[prop] = attrCodeStr(colors[prop]); + if (colorSettingsObj.hasOwnProperty(prop)) + { + // Using toString() to ensure the color attributes are strings (in case the value is just a number) + var value = colorSettingsObj[prop].toString(); + // Remove any instances of specifying the control character + value = value.replace(/\\[xX]01/g, "").replace(/\\[xX]1/g, "").replace(/\\1/g, ""); + // Add actual control characters in the color setting + gConfigSettings.DCTColors[prop] = attrCodeStr(value); + } + } + // General colors + for (var prop in gConfigSettings.genColors) + { + if (colorSettingsObj.hasOwnProperty(prop)) + { + var value = colorSettingsObj[prop].toString(); + // Remove any instances of specifying the control character + value = value.replace(/\\[xX]01/g, "").replace(/\\[xX]1/g, "").replace(/\\1/g, ""); + // Add actual control characters in the color setting + gConfigSettings.genColors[prop] = attrCodeStr(value); + } } - - gConfigSettings.DCTColors = colors; - // Move the general color settings into gConfigSettings.genColors.* - if (EDITOR_STYLE == "DCT") - moveGenColorsToGenSettings(gConfigSettings.DCTColors, gConfigSettings); } } diff --git a/exec/SlyEdit_IceStuff.js b/exec/SlyEdit_IceStuff.js index 8a47585b1b..ef489d6a9c 100644 --- a/exec/SlyEdit_IceStuff.js +++ b/exec/SlyEdit_IceStuff.js @@ -13,6 +13,7 @@ * 2019-05-04 Eric Oulashin Updated to use require() instead of load() if possible. * 2021-12-11 Eric Oulashin Updated the quote window bottom border text * 2022-11-19 Eric Oulashin Updated readColorConfig() to handle just attribute characters + * 2023-05-15 Eric Oulashin Refactored readColorConfig() */ "use strict"; @@ -41,26 +42,39 @@ readColorConfig(gConfigSettings.iceColors.ThemeFilename); // pFilename: The name of the color configuration file function readColorConfig(pFilename) { - var colors = readValueSettingConfigFile(pFilename, 512); - if (colors != null) + var themeFile = new File(pFilename); + if (themeFile.open("r")) { - // Convert the color values from just attribute characters to actual attribute codes - for (var prop in colors) + var colorSettingsObj = themeFile.iniGetObject(); + themeFile.close(); + + // Ice-specific colors + for (var prop in gConfigSettings.iceColors) { - // Remove any instances of specifying the control character - colors[prop] = colors[prop].replace(/\\[xX]01/g, "").replace(/\\[xX]1/g, "").replace(/\\1/g, ""); - // Add actual control characters in the color setting - colors[prop] = attrCodeStr(colors[prop]); + if (prop == "menuOptClassicColors") // Skip this one (it's a boolean value, not a color) + continue; + if (colorSettingsObj.hasOwnProperty(prop)) + { + // Using toString() to ensure the color attributes are strings (in case the value is just a number) + var value = colorSettingsObj[prop].toString(); + // Remove any instances of specifying the control character + value = value.replace(/\\[xX]01/g, "").replace(/\\[xX]1/g, "").replace(/\\1/g, ""); + // Add actual control characters in the color setting + gConfigSettings.iceColors[prop] = attrCodeStr(value); + } + } + // General colors + for (var prop in gConfigSettings.genColors) + { + if (colorSettingsObj.hasOwnProperty(prop)) + { + var value = colorSettingsObj[prop].toString(); + // Remove any instances of specifying the control character + value = value.replace(/\\[xX]01/g, "").replace(/\\[xX]1/g, "").replace(/\\1/g, ""); + // Add actual control characters in the color setting + gConfigSettings.genColors[prop] = attrCodeStr(value); + } } - - // Make a backup of the menuOptClassicColors setting so we can set it - // back in the Ice color settings object after setting the colors. - var useClassicColorsBackup = gConfigSettings.iceColors.menuOptClassicColors; - gConfigSettings.iceColors = colors; - // Move the general color settings into gConfigSettings.genColors.* - if (EDITOR_STYLE == "ICE") - moveGenColorsToGenSettings(gConfigSettings.iceColors, gConfigSettings); - gConfigSettings.iceColors.menuOptClassicColors = useClassicColorsBackup; } } diff --git a/exec/SlyEdit_Misc.js b/exec/SlyEdit_Misc.js index 032ae12ce3..36c445c1d6 100644 --- a/exec/SlyEdit_Misc.js +++ b/exec/SlyEdit_Misc.js @@ -2295,83 +2295,6 @@ function ReadSlyEditConfigFile() return cfgObj; } -// This function reads a configuration file containing -// setting=value pairs and returns the settings in -// an Object. -// -// Parameters: -// pFilename: The name of the configuration file. -// pLineReadLen: The maximum number of characters to read from each -// line. This is optional; if not specified, then up -// to 512 characters will be read from each line. -// -// Return value: An Object containing the value=setting pairs. If the -// file can't be opened or no settings can be read, then -// this function will return null. -function readValueSettingConfigFile(pFilename, pLineReadLen) -{ - var retObj = null; - - var cfgFile = new File(pFilename); - if (cfgFile.open("r")) - { - // Set the number of characters to read per line. - var numCharsPerLine = 512; - if (pLineReadLen != null) - numCharsPerLine = pLineReadLen; - - var fileLine = null; // A line read from the file - var equalsPos = 0; // Position of a = in the line - var commentPos = 0; // Position of the start of a comment - var setting = null; // A setting name (string) - var settingUpper = null; // Upper-case setting name - var value = null; // A value for a setting (string) - var valueUpper = null; // Upper-cased value - while (!cfgFile.eof) - { - // Read the next line from the config file. - fileLine = cfgFile.readln(numCharsPerLine); - - // fileLine should be a string, but I've seen some cases - // where it isn't, so check its type. - if (typeof(fileLine) != "string") - continue; - - // If the line starts with with a semicolon (the comment - // character) or is blank, then skip it. - if ((fileLine.substr(0, 1) == ";") || (fileLine.length == 0)) - continue; - - // If the line has a semicolon anywhere in it, then remove - // everything from the semicolon onward. - commentPos = fileLine.indexOf(";"); - if (commentPos > -1) - fileLine = fileLine.substr(0, commentPos); - - // Look for an equals sign, and if found, separate the line - // into the setting name (before the =) and the value (after the - // equals sign). - equalsPos = fileLine.indexOf("="); - if (equalsPos > 0) - { - // If retObj hasn't been created yet, then create it. - if (retObj == null) - retObj = {}; - - // Read the setting & value, and trim leading & trailing spaces. Then - // set the value in retObj. - setting = trimSpaces(fileLine.substr(0, equalsPos), true, false, true); - value = trimSpaces(fileLine.substr(equalsPos+1), true, false, true); - retObj[setting] = value; - } - } - - cfgFile.close(); - } - - return retObj; -} - // Splits a string up by a maximum length, preserving whole words. // // Parameters: diff --git a/xtrn/DDAreaChoosers/DDFileAreaChooser.js b/xtrn/DDAreaChoosers/DDFileAreaChooser.js index 3746402126..fc353d1f8e 100644 --- a/xtrn/DDAreaChoosers/DDFileAreaChooser.js +++ b/xtrn/DDAreaChoosers/DDFileAreaChooser.js @@ -1787,7 +1787,7 @@ function DDFileAreaChooser_ReadConfigFile() var onlySyncAttrsRegexWholeWord = new RegExp("^[\x01krgybmcw01234567hinq,;\.dtlasz]+$", 'i'); for (var prop in this.colors) { - if (typeof(colorSettings[prop] === "string")) + if (colorSettings.hasOwnProperty(prop)) { // Make sure the value is a string (for attrCodeStr() etc; in some cases, such as a background attribute of 4, it will be a number) var value = colorSettings[prop].toString(); diff --git a/xtrn/DDAreaChoosers/DDMsgAreaChooser.js b/xtrn/DDAreaChoosers/DDMsgAreaChooser.js index cf49c8a8fb..a14c72bbd1 100644 --- a/xtrn/DDAreaChoosers/DDMsgAreaChooser.js +++ b/xtrn/DDAreaChoosers/DDMsgAreaChooser.js @@ -2153,7 +2153,7 @@ function DDMsgAreaChooser_ReadConfigFile() var onlySyncAttrsRegexWholeWord = new RegExp("^[\x01krgybmcw01234567hinq,;\.dtlasz]+$", 'i'); for (var prop in this.colors) { - if (typeof(colorSettings[prop] === "string")) + if (colorSettings.hasOwnProperty(prop)) { // Make sure the value is a string (for attrCodeStr() etc; in some cases, such as a background attribute of 4, it will be a number) var value = colorSettings[prop].toString(); diff --git a/xtrn/DDMsgReader/DDMsgReader.js b/xtrn/DDMsgReader/DDMsgReader.js index 7cb95379af..2e12a328aa 100644 --- a/xtrn/DDMsgReader/DDMsgReader.js +++ b/xtrn/DDMsgReader/DDMsgReader.js @@ -8452,11 +8452,10 @@ function DigDistMsgReader_ReadConfigFile() // Set any color values specified for (var prop in this.colors) { - //themeSettingsObj.hasOwnProperty(prop) - if (typeof(themeSettingsObj[prop]) === "string") + if (themeSettingsObj.hasOwnProperty(prop)) { // Trim spaces from the color value - var value = trimSpaces(themeSettingsObj[prop], true, true, true); + var value = trimSpaces(themeSettingsObj[prop].toString(), true, true, true); value = value.replace(/\\x01/g, "\x01"); // Replace "\x01" with control character // If the value doesn't have any control characters, then add the control character // before attribute characters @@ -16524,11 +16523,11 @@ function trimSpaces(pString, pLeading, pMultiple, pTrailing) var leading = true; var multiple = true; var trailing = true; - if(typeof(pLeading) != "undefined") + if (typeof(pLeading) != "undefined") leading = pLeading; - if(typeof(pMultiple) != "undefined") + if (typeof(pMultiple) != "undefined") multiple = pMultiple; - if(typeof(pTrailing) != "undefined") + if (typeof(pTrailing) != "undefined") trailing = pTrailing; // To remove both leading & trailing spaces: diff --git a/xtrn/ddfilelister/ddfilelister.js b/xtrn/ddfilelister/ddfilelister.js index 0778e41c18..1b0f6cd889 100644 --- a/xtrn/ddfilelister/ddfilelister.js +++ b/xtrn/ddfilelister/ddfilelister.js @@ -3090,11 +3090,12 @@ function readConfigFile() // Set any color values specified for (var prop in gColors) { - if (typeof(themeSettingsObj[prop]) === "string") + if (themeSettingsObj.hasOwnProperty(prop)) { // Trim leading & trailing spaces from the value when // setting a color. Also, replace any instances of "\x01" or "\1" // with the Synchronet attribute control character. + // Using toString() to ensure the color attributes are strings (in case the value is just a number) var value = trimSpaces(themeSettingsObj[prop].toString(), true, false, true).replace(/\\[xX]01/g, "\x01").replace(/\\1/g, "\x01"); // If the value doesn't have any control characters, then add the control character // before attribute characters diff --git a/xtrn/gttrivia/gttrivia.js b/xtrn/gttrivia/gttrivia.js index 6e8678856b..7d855fcb73 100644 --- a/xtrn/gttrivia/gttrivia.js +++ b/xtrn/gttrivia/gttrivia.js @@ -524,13 +524,36 @@ function playTrivia() // Return value: An object with 'behavior' and 'color' sections with the settings loaded from the .ini file function loadSettings(pStartupPath) { - var settings = {}; + var settings = { + colors: { + error: "YH", + triviaCategoryHdr: "MH", + triviaCategoryListNumbers: "CH", + triviaCategoryListSeparator: "GH", + triviaCategoryName: "C", + categoryNumPrompt: "C", + categoryNumPromptSeparator: "GH", + categoryNumInput: "CH", + questionHdr: "M", + questionHdrNum: "CH", + question: "BH", + answerPrompt: "C", + answerPromptSep: "GH", + answerInput: "CH", + userScore: "CH", + scoreSoFarText: "C", + clueHdr: "RH", + clue: "GH", + answerAfterIncorrect: "G", + answerFact: "G" + } + }; var cfgFileName = genFullPathCfgFilename("gttrivia.ini", pStartupPath); var iniFile = new File(cfgFileName); if (iniFile.open("r")) { settings.behavior = iniFile.iniGetObject("BEHAVIOR"); - settings.colors = iniFile.iniGetObject("COLORS"); + var colorSettingsObj = iniFile.iniGetObject("COLORS"); settings.category_ars = iniFile.iniGetObject("CATEGORY_ARS"); settings.remoteServer = iniFile.iniGetObject("REMOTE_SERVER"); settings.server = iniFile.iniGetObject("SERVER"); @@ -554,44 +577,20 @@ function loadSettings(pStartupPath) if (typeof(settings.behavior.maxNumPlayerScoresToDisplay) !== "number") settings.behavior.maxNumPlayerScoresToDisplay = 10; - if (typeof(settings.colors.error) !== "string") - settings.colors.error = "YH"; - if (typeof(settings.colors.triviaCategoryHdr) !== "string") - settings.colors.triviaCategoryHdr = "MH"; - if (typeof(settings.colors.triviaCategoryListNumbers) !== "string") - settings.colors.triviaCategoryListNumbers = "CH"; - if (typeof(settings.colors.triviaCategoryListSeparator) !== "string") - settings.colors.triviaCategoryListSeparator = "GH"; - if (typeof(settings.colors.triviaCategoryName) !== "string") - settings.colors.triviaCategoryName = "C"; - if (typeof(settings.colors.categoryNumPrompt) !== "string") - settings.colors.categoryNumPrompt = "C"; - if (typeof(settings.colors.categoryNumPromptSeparator) !== "string") - settings.colors.categoryNumPromptSeparator = "GH"; - if (typeof(settings.colors.categoryNumInput) !== "string") - settings.colors.categoryNumInput = "CH"; - if (typeof(settings.colors.questionHdr) !== "string") - settings.colors.questionHdr = "M"; - if (typeof(settings.colors.questionHdrNum) !== "string") - settings.colors.questionHdrNum = "CH"; - if (typeof(settings.colors.question) !== "string") - settings.colors.question = "BH"; - if (typeof(settings.colors.answerPrompt) !== "string") - settings.colors.answerPrompt = "C"; - if (typeof(settings.colors.answerPromptSep) !== "string") - settings.colors.answerPromptSep = "GH"; - if (typeof(settings.colors.answerInput) !== "string") - settings.colors.answerInput = "CH"; - if (typeof(settings.colors.userScore) !== "string") - settings.colors.userScore = "CH"; - if (typeof(settings.colors.scoreSoFarText) !== "string") - settings.colors.scoreSoFarText = "C"; - if (typeof(settings.colors.clueHdr) !== "string") - settings.colors.clueHdr = "RH"; - if (typeof(settings.colors.clue) !== "string") - settings.colors.clue = "GH"; - if (typeof(settings.colors.answerAfterIncorrect) !== "string") - settings.colors.answerAfterIncorrect = "G"; + // Colors - For any setting that matches one in settings.colors, replace it. + var onlySyncAttrCharsRegexWholeWord = new RegExp("^[krgybmcw01234567hinq,;\.dtlasz]+$", 'i'); + for (var prop in settings.colors) + { + if (colorSettingsObj.hasOwnProperty(prop)) + { + // Trim spaces from the color value. Using toString() to ensure the color attributes + // are strings (in case the value is just a number) + var value = trimSpaces(colorSettingsObj[prop].toString(), true, true, true); + value = value.replace(/\\x01/g, "\x01"); // Replace "\x01" with control character + if (onlySyncAttrCharsRegexWholeWord.test(value)) + settings.colors[prop] = value; + } + } settings.behavior.scoresMsgSubBoardsForPosting = splitAndVerifyMsgSubCodes(settings.behavior.scoresMsgSubBoardsForPosting, "scoresMsgSubBoardsForPosting"); settings.server.scoresMsgSubBoardsForReading = splitAndVerifyMsgSubCodes(settings.server.scoresMsgSubBoardsForReading, "scoresMsgSubBoardsForReading"); @@ -2226,6 +2225,43 @@ function add_commas(val, pad) return(s); } +// Removes multiple, leading, and/or trailing spaces +// The search & replace regular expressions used in this +// function came from the following URL: +// http://qodo.co.uk/blog/javascript-trim-leading-and-trailing-spaces +// +// Parameters: +// pString: The string to trim +// pLeading: Whether or not to trim leading spaces (optional, defaults to true) +// pMultiple: Whether or not to trim multiple spaces (optional, defaults to true) +// pTrailing: Whether or not to trim trailing spaces (optional, defaults to true) +// +// Return value: The string with whitespace trimmed +function trimSpaces(pString, pLeading, pMultiple, pTrailing) +{ + var leading = true; + var multiple = true; + var trailing = true; + if (typeof(pLeading) != "undefined") + leading = pLeading; + if (typeof(pMultiple) != "undefined") + multiple = pMultiple; + if (typeof(pTrailing) != "undefined") + trailing = pTrailing; + + // To remove both leading & trailing spaces: + //pString = pString.replace(/(^\s*)|(\s*$)/gi,""); + + if (leading) + pString = pString.replace(/(^\s*)/gi,""); + if (multiple) + pString = pString.replace(/[ ]{2,}/gi," "); + if (trailing) + pString = pString.replace(/(\s*$)/gi,""); + + return pString; +} + // Parses command-line arguments. Returns an object with settings/actions specified. // // Parameters: -- GitLab