From 5f64621d46339b2548e10d387eeddfa3e261d064 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 22 Mar 2023 15:31:10 +0100 Subject: [PATCH 1/2] Use `String.prototype.replaceAll()` where appropriate This fairly new method allows replacing *multiple* occurrences within a string without having to use regular expressions. Please refer to: - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll#browser_compatibility --- external/builder/test-fixtures.js | 2 +- external/builder/test-fixtures_esprima.js | 2 +- external/importL10n/locales.js | 2 +- src/core/catalog.js | 2 +- src/core/core_utils.js | 2 +- src/core/file_spec.js | 6 +++--- src/display/content_disposition.js | 2 +- test/unit/ui_utils_spec.js | 7 ++++--- web/pdf_link_service.js | 2 +- web/ui_utils.js | 3 +-- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/external/builder/test-fixtures.js b/external/builder/test-fixtures.js index 90b501879..65ea532dc 100644 --- a/external/builder/test-fixtures.js +++ b/external/builder/test-fixtures.js @@ -21,7 +21,7 @@ files.forEach(function (expectationFilename) { .readFileSync(expectationFilename) .toString() .trim() - .replace(/__filename/g, fs.realpathSync(inFilename)); + .replaceAll("__filename", fs.realpathSync(inFilename)); const outLines = []; const outFilename = function (line) { diff --git a/external/builder/test-fixtures_esprima.js b/external/builder/test-fixtures_esprima.js index 35128aee5..947b4cf6c 100644 --- a/external/builder/test-fixtures_esprima.js +++ b/external/builder/test-fixtures_esprima.js @@ -21,7 +21,7 @@ files.forEach(function (expectationFilename) { .readFileSync(expectationFilename) .toString() .trim() - .replace(/__filename/g, fs.realpathSync(inFilename)); + .replaceAll("__filename", fs.realpathSync(inFilename)); const input = fs.readFileSync(inFilename).toString(); const defines = { diff --git a/external/importL10n/locales.js b/external/importL10n/locales.js index bc10a284e..798fd715b 100644 --- a/external/importL10n/locales.js +++ b/external/importL10n/locales.js @@ -27,7 +27,7 @@ const DEFAULT_LOCALE = "en-US"; const EXCLUDE_LANG_CODES = ["ca-valencia", "ja-JP-mac"]; function normalizeText(s) { - return s.replace(/\r\n?/g, "\n").replace(/\uFEFF/g, ""); + return s.replace(/\r\n?/g, "\n").replaceAll("\uFEFF", ""); } function downloadLanguageCodes() { diff --git a/src/core/catalog.js b/src/core/catalog.js index 2dff6d2d0..6cb33baa3 100644 --- a/src/core/catalog.js +++ b/src/core/catalog.js @@ -989,7 +989,7 @@ class Catalog { if (javaScript === null) { javaScript = new Map(); } - js = stringToPDFString(js).replace(/\u0000/g, ""); + js = stringToPDFString(js).replaceAll("\x00", ""); javaScript.set(name, js); } diff --git a/src/core/core_utils.js b/src/core/core_utils.js index f4541dabe..e721dd980 100644 --- a/src/core/core_utils.js +++ b/src/core/core_utils.js @@ -341,7 +341,7 @@ function _collectJS(entry, xref, list, parents) { } else if (typeof js === "string") { code = js; } - code = code && stringToPDFString(code).replace(/\u0000/g, ""); + code = code && stringToPDFString(code).replaceAll("\x00", ""); if (code) { list.push(code); } diff --git a/src/core/file_spec.js b/src/core/file_spec.js index 3eb1c5a7d..da85e9046 100644 --- a/src/core/file_spec.js +++ b/src/core/file_spec.js @@ -68,9 +68,9 @@ class FileSpec { if (!this._filename && this.root) { const filename = pickPlatformItem(this.root) || "unnamed"; this._filename = stringToPDFString(filename) - .replace(/\\\\/g, "\\") - .replace(/\\\//g, "/") - .replace(/\\/g, "/"); + .replaceAll("\\\\", "\\") + .replaceAll("\\/", "/") + .replaceAll("\\", "/"); } return this._filename; } diff --git a/src/display/content_disposition.js b/src/display/content_disposition.js index 0e9ddd11b..787d848d1 100644 --- a/src/display/content_disposition.js +++ b/src/display/content_disposition.js @@ -199,7 +199,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) { function (matches, charset, encoding, text) { if (encoding === "q" || encoding === "Q") { // RFC 2047 section 4.2. - text = text.replace(/_/g, " "); + text = text.replaceAll("_", " "); text = text.replace(/=([0-9a-fA-F]{2})/g, function (match, hex) { return String.fromCharCode(parseInt(hex, 16)); }); diff --git a/test/unit/ui_utils_spec.js b/test/unit/ui_utils_spec.js index 704008175..4935489f7 100644 --- a/test/unit/ui_utils_spec.js +++ b/test/unit/ui_utils_spec.js @@ -157,9 +157,10 @@ describe("ui_utils", function () { }); it("should modify string with non-displayable characters", function () { - const str = Array.from(Array(32).keys()) - .map(x => String.fromCharCode(x) + "a") - .join(""); + const str = Array.from( + Array(32).keys(), + x => String.fromCharCode(x) + "a" + ).join(""); // \x00 is replaced by an empty string. const expected = "a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a"; diff --git a/web/pdf_link_service.js b/web/pdf_link_service.js index de8172e6b..249dce587 100644 --- a/web/pdf_link_service.js +++ b/web/pdf_link_service.js @@ -352,7 +352,7 @@ class PDFLinkService { if (params.has("search")) { this.eventBus.dispatch("findfromurlhash", { source: this, - query: params.get("search").replace(/"/g, ""), + query: params.get("search").replaceAll('"', ""), phraseSearch: params.get("phrase") === "true", }); } diff --git a/web/ui_utils.js b/web/ui_utils.js index 82c57c790..59574db85 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -211,7 +211,6 @@ function parseQueryString(query) { return params; } -const NullCharactersRegExp = /\x00/g; const InvisibleCharactersRegExp = /[\x01-\x1F]/g; /** @@ -226,7 +225,7 @@ function removeNullCharacters(str, replaceInvisible = false) { if (replaceInvisible) { str = str.replace(InvisibleCharactersRegExp, " "); } - return str.replace(NullCharactersRegExp, ""); + return str.replaceAll("\x00", ""); } /** From 1fc09f02355df3c9303bf9720116562b9be86063 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Thu, 23 Mar 2023 12:34:08 +0100 Subject: [PATCH 2/2] Enable the `unicorn/prefer-string-replace-all` ESLint plugin rule Note that the `replaceAll` method still requires that a *global* regular expression is used, however by using this method it's immediately obvious when looking at the code that all occurrences will be replaced; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll#parameters Please find additional details at https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-replace-all.md --- .eslintrc | 1 + extensions/firefox/tools/l10n.js | 2 +- external/builder/builder.js | 10 +++++----- external/builder/test-fixtures.js | 2 +- external/builder/test-fixtures_esprima.js | 2 +- external/cmapscompress/parse.js | 2 +- external/importL10n/locales.js | 2 +- gulpfile.js | 11 ++++++----- src/core/core_utils.js | 2 +- src/core/document.js | 2 +- src/core/evaluator.js | 2 +- src/core/fonts.js | 6 +++--- src/core/fonts_utils.js | 2 +- src/core/metadata_parser.js | 6 +++--- src/core/xfa/fonts.js | 12 ++++++------ src/core/xfa/template.js | 2 +- src/core/xfa/xhtml.js | 6 +++--- src/core/xml_parser.js | 2 +- src/display/content_disposition.js | 6 +++--- src/scripting_api/aform.js | 2 +- src/scripting_api/util.js | 8 ++++---- test/unit/xml_spec.js | 4 ++-- test/webserver.js | 14 +++++++------- web/l10n_utils.js | 2 +- web/pdf_find_controller.js | 2 +- web/ui_utils.js | 2 +- 26 files changed, 58 insertions(+), 56 deletions(-) diff --git a/.eslintrc b/.eslintrc index b9fb08559..5418053e4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -60,6 +60,7 @@ "unicorn/prefer-logical-operator-over-ternary": "error", "unicorn/prefer-modern-dom-apis": "error", "unicorn/prefer-regexp-test": "error", + "unicorn/prefer-string-replace-all": "error", "unicorn/prefer-string-starts-ends-with": "error", "unicorn/no-typeof-undefined": ["error", { "checkGlobalVariables": false, }], diff --git a/extensions/firefox/tools/l10n.js b/extensions/firefox/tools/l10n.js index 7cc43dc8e..7abfc7d0d 100644 --- a/extensions/firefox/tools/l10n.js +++ b/extensions/firefox/tools/l10n.js @@ -23,7 +23,7 @@ if (!args) { return text; } - return text.replace(/\{\{\s*(\w+)\s*\}\}/g, function (all, name) { + return text.replaceAll(/\{\{\s*(\w+)\s*\}\}/g, function (all, name) { return name in args ? args[name] : "{{" + name + "}}"; }); } diff --git a/external/builder/builder.js b/external/builder/builder.js index a20d21634..5eb9d70bb 100644 --- a/external/builder/builder.js +++ b/external/builder/builder.js @@ -41,7 +41,7 @@ function preprocess(inFilename, outFilename, defines) { } function expandCssImports(content, baseUrl) { - return content.replace( + return content.replaceAll( /^\s*@import\s+url\(([^)]+)\);\s*$/gm, function (all, url) { const file = path.join(path.dirname(baseUrl), url); @@ -121,7 +121,7 @@ function preprocess(inFilename, outFilename, defines) { } } function expand(line) { - line = line.replace(/__[\w]+__/g, function (variable) { + line = line.replaceAll(/__[\w]+__/g, function (variable) { variable = variable.substring(2, variable.length - 2); if (variable in defines) { return defines[variable]; @@ -210,9 +210,9 @@ function preprocess(inFilename, outFilename, defines) { ) { writeLine( line - .replace(/^\/\/|^$/g, "") + .replaceAll(/^\/\/|^$/g, "") ); } } diff --git a/external/builder/test-fixtures.js b/external/builder/test-fixtures.js index 65ea532dc..09b0e9a55 100644 --- a/external/builder/test-fixtures.js +++ b/external/builder/test-fixtures.js @@ -36,7 +36,7 @@ files.forEach(function (expectationFilename) { builder.preprocess(inFilename, outFilename, defines); out = outLines.join("\n").trim(); } catch (e) { - out = ("Error: " + e.message).replace(/^/gm, "//"); + out = ("Error: " + e.message).replaceAll(/^/gm, "//"); } if (out !== expectation) { errors++; diff --git a/external/builder/test-fixtures_esprima.js b/external/builder/test-fixtures_esprima.js index 947b4cf6c..a0fec7b68 100644 --- a/external/builder/test-fixtures_esprima.js +++ b/external/builder/test-fixtures_esprima.js @@ -42,7 +42,7 @@ files.forEach(function (expectationFilename) { try { out = p2.preprocessPDFJSCode(ctx, input); } catch (e) { - out = ("Error: " + e.message).replace(/^/gm, "//"); + out = ("Error: " + e.message).replaceAll(/^/gm, "//"); } if (out !== expectation) { errors++; diff --git a/external/cmapscompress/parse.js b/external/cmapscompress/parse.js index 5978d7f93..edb5ab3ca 100644 --- a/external/cmapscompress/parse.js +++ b/external/cmapscompress/parse.js @@ -19,7 +19,7 @@ exports.parseAdobeCMap = function (content) { throw new Error("cmap was not found"); } - const body = m[1].replace(/\r\n?/g, "\n"); + const body = m[1].replaceAll(/\r\n?/g, "\n"); const result = { type: 1, wmode: 0, diff --git a/external/importL10n/locales.js b/external/importL10n/locales.js index 798fd715b..0e16f3843 100644 --- a/external/importL10n/locales.js +++ b/external/importL10n/locales.js @@ -27,7 +27,7 @@ const DEFAULT_LOCALE = "en-US"; const EXCLUDE_LANG_CODES = ["ca-valencia", "ja-JP-mac"]; function normalizeText(s) { - return s.replace(/\r\n?/g, "\n").replaceAll("\uFEFF", ""); + return s.replaceAll(/\r\n?/g, "\n").replaceAll("\uFEFF", ""); } function downloadLanguageCodes() { diff --git a/gulpfile.js b/gulpfile.js index ac7b5185c..11894222f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -130,7 +130,7 @@ function safeSpawnSync(command, parameters, options) { if (!/[\s`~!#$*(){[|\\;'"<>?]/.test(param)) { return param; } - return '"' + param.replace(/([$\\"`])/g, "\\$1") + '"'; + return '"' + param.replaceAll(/([$\\"`])/g, "\\$1") + '"'; }); const result = spawnSync(command, parameters, options); @@ -909,7 +909,7 @@ function preprocessCSS(source, defines) { // Strip out all license headers in the middle. const reg = /\n\/\* Copyright(.|\n)*?Mozilla Foundation(.|\n)*?\*\//g; - out = out.replace(reg, ""); + out = out.replaceAll(reg, ""); const i = source.lastIndexOf("/"); return createStringSource(source.substr(i + 1), out); @@ -1557,9 +1557,10 @@ function buildLibHelper(bundleDefines, inputStream, outputDir) { }).code; const removeCjsSrc = /^(var\s+\w+\s*=\s*(_interopRequireDefault\()?require\(".*?)(?:\/src)(\/[^"]*"\)\)?;)$/gm; - content = content.replace(removeCjsSrc, (all, prefix, interop, suffix) => { - return prefix + suffix; - }); + content = content.replaceAll( + removeCjsSrc, + (all, prefix, interop, suffix) => prefix + suffix + ); return licenseHeaderLibre + content; } const babel = require("@babel/core"); diff --git a/src/core/core_utils.js b/src/core/core_utils.js index e721dd980..3e6f64adf 100644 --- a/src/core/core_utils.js +++ b/src/core/core_utils.js @@ -303,7 +303,7 @@ function escapePDFName(str) { // Replace "(", ")", "\n", "\r" and "\" by "\(", "\)", "\\n", "\\r" and "\\" // in order to write it in a PDF file. function escapeString(str) { - return str.replace(/([()\\\n\r])/g, match => { + return str.replaceAll(/([()\\\n\r])/g, match => { if (match === "\n") { return "\\n"; } else if (match === "\r") { diff --git a/src/core/document.js b/src/core/document.js index b66f4d56c..54f70655d 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -1144,7 +1144,7 @@ class PDFDocument { } let fontFamily = descriptor.get("FontFamily"); // For example, "Wingdings 3" is not a valid font name in the css specs. - fontFamily = fontFamily.replace(/[ ]+(\d)/g, "$1"); + fontFamily = fontFamily.replaceAll(/[ ]+(\d)/g, "$1"); const fontWeight = descriptor.get("FontWeight"); // Angle is expressed in degrees counterclockwise in PDF diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 8b28d5b03..912538af8 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -4086,7 +4086,7 @@ class PartialEvaluator { } // Using base font name as a font name. - baseFontName = baseFontName.name.replace(/[,_]/g, "-"); + baseFontName = baseFontName.name.replaceAll(/[,_]/g, "-"); const metrics = this.getBaseFontMetrics(baseFontName); // Simulating descriptor flags attribute diff --git a/src/core/fonts.js b/src/core/fonts.js index 43274086f..37b91682a 100644 --- a/src/core/fonts.js +++ b/src/core/fonts.js @@ -903,7 +903,7 @@ function createPostTable(properties) { function createPostscriptName(name) { // See https://docs.microsoft.com/en-us/typography/opentype/spec/recom#name. - return name.replace(/[^\x21-\x7E]|[[\](){}<>/%]/g, "").slice(0, 63); + return name.replaceAll(/[^\x21-\x7E]|[[\](){}<>/%]/g, "").slice(0, 63); } function createNameTable(name, proto) { @@ -994,7 +994,7 @@ class Font { // Fallback to checking the font name, in order to improve text-selection, // since the /Flags-entry is often wrong (fixes issue13845.pdf). if (!isSerifFont && !properties.isSimulatedFlags) { - const baseName = name.replace(/[,_]/g, "-").split("-")[0], + const baseName = name.replaceAll(/[,_]/g, "-").split("-")[0], serifFonts = getSerifFonts(); for (const namePart of baseName.split("+")) { if (serifFonts[namePart]) { @@ -1445,7 +1445,7 @@ class Font { for (let j = 0, jj = nameTable.length; j < jj; j++) { for (let k = 0, kk = nameTable[j].length; k < kk; k++) { const nameEntry = - nameTable[j][k] && nameTable[j][k].replace(/\s/g, ""); + nameTable[j][k] && nameTable[j][k].replaceAll(/\s/g, ""); if (!nameEntry) { continue; } diff --git a/src/core/fonts_utils.js b/src/core/fonts_utils.js index 6287786f3..f1bbf6762 100644 --- a/src/core/fonts_utils.js +++ b/src/core/fonts_utils.js @@ -181,7 +181,7 @@ function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) { } function normalizeFontName(name) { - return name.replace(/[,_]/g, "-").replace(/\s/g, ""); + return name.replaceAll(/[,_]/g, "-").replaceAll(/\s/g, ""); } export { diff --git a/src/core/metadata_parser.js b/src/core/metadata_parser.js index f959126a4..9541dae4d 100644 --- a/src/core/metadata_parser.js +++ b/src/core/metadata_parser.js @@ -36,12 +36,12 @@ class MetadataParser { // Start by removing any "junk" before the first tag (see issue 10395). return data .replace(/^[^<]+/, "") - .replace(/>\\376\\377([^<]+)/g, function (all, codes) { + .replaceAll(/>\\376\\377([^<]+)/g, function (all, codes) { const bytes = codes - .replace(/\\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) { + .replaceAll(/\\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) { return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1); }) - .replace(/&(amp|apos|gt|lt|quot);/g, function (str, name) { + .replaceAll(/&(amp|apos|gt|lt|quot);/g, function (str, name) { switch (name) { case "amp": return "&"; diff --git a/src/core/xfa/fonts.js b/src/core/xfa/fonts.js index 94b41fdbd..b92cde49e 100644 --- a/src/core/xfa/fonts.js +++ b/src/core/xfa/fonts.js @@ -99,7 +99,7 @@ class FontFinder { } const pattern = /,|-|_| |bolditalic|bold|italic|regular|it/gi; - let name = fontName.replace(pattern, ""); + let name = fontName.replaceAll(pattern, ""); font = this.fonts.get(name); if (font) { this.cache.set(fontName, font); @@ -109,7 +109,7 @@ class FontFinder { const maybe = []; for (const [family, pdfFont] of this.fonts.entries()) { - if (family.replace(pattern, "").toLowerCase().startsWith(name)) { + if (family.replaceAll(pattern, "").toLowerCase().startsWith(name)) { maybe.push(pdfFont); } } @@ -119,7 +119,7 @@ class FontFinder { if ( pdfFont.regular.name && pdfFont.regular.name - .replace(pattern, "") + .replaceAll(pattern, "") .toLowerCase() .startsWith(name) ) { @@ -129,9 +129,9 @@ class FontFinder { } if (maybe.length === 0) { - name = name.replace(/psmt|mt/gi, ""); + name = name.replaceAll(/psmt|mt/gi, ""); for (const [family, pdfFont] of this.fonts.entries()) { - if (family.replace(pattern, "").toLowerCase().startsWith(name)) { + if (family.replaceAll(pattern, "").toLowerCase().startsWith(name)) { maybe.push(pdfFont); } } @@ -142,7 +142,7 @@ class FontFinder { if ( pdfFont.regular.name && pdfFont.regular.name - .replace(pattern, "") + .replaceAll(pattern, "") .toLowerCase() .startsWith(name) ) { diff --git a/src/core/xfa/template.js b/src/core/xfa/template.js index 69c654028..3e3865b3d 100644 --- a/src/core/xfa/template.js +++ b/src/core/xfa/template.js @@ -5731,7 +5731,7 @@ class Text extends ContentObject { [$finalize]() { if (typeof this[$content] === "string") { - this[$content] = this[$content].replace(/\r\n/g, "\n"); + this[$content] = this[$content].replaceAll("\r\n", "\n"); } } diff --git a/src/core/xfa/xhtml.js b/src/core/xfa/xhtml.js index e39c88d0e..f87aa8afd 100644 --- a/src/core/xfa/xhtml.js +++ b/src/core/xfa/xhtml.js @@ -231,9 +231,9 @@ class XhtmlObject extends XmlObject { [$onText](str, richText = false) { if (!richText) { - str = str.replace(crlfRegExp, ""); + str = str.replaceAll(crlfRegExp, ""); if (!this.style.includes("xfa-spacerun:yes")) { - str = str.replace(spacesRegExp, " "); + str = str.replaceAll(spacesRegExp, " "); } } else { this[$richText] = true; @@ -351,7 +351,7 @@ class XhtmlObject extends XmlObject { let value; if (this[$richText]) { value = this[$content] - ? this[$content].replace(crlfForRichTextRegExp, "\n") + ? this[$content].replaceAll(crlfForRichTextRegExp, "\n") : undefined; } else { value = this[$content] || undefined; diff --git a/src/core/xml_parser.js b/src/core/xml_parser.js index cadd7d31d..31648e23e 100644 --- a/src/core/xml_parser.js +++ b/src/core/xml_parser.js @@ -48,7 +48,7 @@ function isWhitespaceString(s) { class XMLParserBase { _resolveEntities(s) { - return s.replace(/&([^;]+);/g, (all, entity) => { + return s.replaceAll(/&([^;]+);/g, (all, entity) => { if (entity.substring(0, 2) === "#x") { return String.fromCodePoint(parseInt(entity.substring(2), 16)); } else if (entity.substring(0, 1) === "#") { diff --git a/src/display/content_disposition.js b/src/display/content_disposition.js index 787d848d1..b1af420a8 100644 --- a/src/display/content_disposition.js +++ b/src/display/content_disposition.js @@ -152,7 +152,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) { parts[i] = parts[i].slice(0, quotindex); parts.length = i + 1; // Truncates and stop the iteration. } - parts[i] = parts[i].replace(/\\(.)/g, "$1"); + parts[i] = parts[i].replaceAll(/\\(.)/g, "$1"); } value = parts.join('"'); } @@ -194,13 +194,13 @@ function getFilenameFromContentDispositionHeader(contentDisposition) { // encoding = q or b // encoded-text = any printable ASCII character other than ? or space. // ... but Firefox permits ? and space. - return value.replace( + return value.replaceAll( /=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g, function (matches, charset, encoding, text) { if (encoding === "q" || encoding === "Q") { // RFC 2047 section 4.2. text = text.replaceAll("_", " "); - text = text.replace(/=([0-9a-fA-F]{2})/g, function (match, hex) { + text = text.replaceAll(/=([0-9a-fA-F]{2})/g, function (match, hex) { return String.fromCharCode(parseInt(hex, 16)); }); return textdecode(charset, text); diff --git a/src/scripting_api/aform.js b/src/scripting_api/aform.js index 9ec325328..f12917ac4 100644 --- a/src/scripting_api/aform.js +++ b/src/scripting_api/aform.js @@ -60,7 +60,7 @@ class AForm { if (!actions) { actions = []; this._dateActionsCache.set(cFormat, actions); - cFormat.replace( + cFormat.replaceAll( /(d+)|(m+)|(y+)|(H+)|(M+)|(s+)/g, function (match, d, m, y, H, M, s) { if (d) { diff --git a/src/scripting_api/util.js b/src/scripting_api/util.js index 8496683e3..b4840fb5b 100644 --- a/src/scripting_api/util.js +++ b/src/scripting_api/util.js @@ -65,7 +65,7 @@ class Util extends PDFObject { const ZERO = 4; const HASH = 8; let i = 0; - return args[0].replace( + return args[0].replaceAll( pattern, function (match, nDecSep, cFlags, nWidth, nPrecision, cConvChar) { // cConvChar must be one of d, f, s, x @@ -287,7 +287,7 @@ class Util extends PDFObject { const patterns = /(mmmm|mmm|mm|m|dddd|ddd|dd|d|yyyy|yy|HH|H|hh|h|MM|M|ss|s|tt|t|\\.)/g; - return cFormat.replace(patterns, function (match, pattern) { + return cFormat.replaceAll(patterns, function (match, pattern) { if (pattern in handlers) { return handlers[pattern](data); } @@ -523,12 +523,12 @@ class Util extends PDFObject { }; // escape the string - const escapedFormat = cFormat.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); + const escapedFormat = cFormat.replaceAll(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); const patterns = /(mmmm|mmm|mm|m|dddd|ddd|dd|d|yyyy|yy|HH|H|hh|h|MM|M|ss|s|tt|t)/g; const actions = []; - const re = escapedFormat.replace( + const re = escapedFormat.replaceAll( patterns, function (match, patternElement) { const { pattern, action } = handlers[patternElement]; diff --git a/test/unit/xml_spec.js b/test/unit/xml_spec.js index eb2b920bd..14a32e67e 100644 --- a/test/unit/xml_spec.js +++ b/test/unit/xml_spec.js @@ -103,8 +103,8 @@ describe("XML", function () { const buffer = []; root.dump(buffer); - expect(buffer.join("").replace(/\s+/g, "")).toEqual( - xml.replace(/\s+/g, "") + expect(buffer.join("").replaceAll(/\s+/g, "")).toEqual( + xml.replaceAll(/\s+/g, "") ); }); }); diff --git a/test/webserver.js b/test/webserver.js index c2d5b96de..74c9d2950 100644 --- a/test/webserver.js +++ b/test/webserver.js @@ -79,7 +79,7 @@ WebServer.prototype = { } }, _handler(req, res) { - var url = req.url.replace(/\/\//g, "/"); + var url = req.url.replaceAll("//", "/"); var urlParts = /([^?]*)((?:\?(.*))?)/.exec(url); try { // Guard against directory traversal attacks such as @@ -89,7 +89,7 @@ WebServer.prototype = { // path.normalize returns a path on the basis of the current platform. // Windows paths cause issues in statFile and serverDirectoryIndex. // Converting to unix path would avoid platform checks in said functions. - pathPart = pathPart.replace(/\\/g, "/"); + pathPart = pathPart.replaceAll("\\", "/"); } catch (ex) { // If the URI cannot be decoded, a `URIError` is thrown. This happens for // malformed URIs such as `http://localhost:8888/%s%s` and should be @@ -196,11 +196,11 @@ WebServer.prototype = { // Escape untrusted input so that it can safely be used in a HTML response // in HTML and in HTML attributes. return untrusted - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) - .replace(/'/g, "'"); + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); } function serveDirectoryIndex(dir) { diff --git a/web/l10n_utils.js b/web/l10n_utils.js index 258dac7e2..42e2d46de 100644 --- a/web/l10n_utils.js +++ b/web/l10n_utils.js @@ -117,7 +117,7 @@ function formatL10nValue(text, args) { if (!args) { return text; } - return text.replace(/\{\{\s*(\w+)\s*\}\}/g, (all, name) => { + return text.replaceAll(/\{\{\s*(\w+)\s*\}\}/g, (all, name) => { return name in args ? args[name] : "{{" + name + "}}"; }); } diff --git a/web/pdf_find_controller.js b/web/pdf_find_controller.js index cbb2b4f6b..6a316d50e 100644 --- a/web/pdf_find_controller.js +++ b/web/pdf_find_controller.js @@ -663,7 +663,7 @@ class PDFFindController { #convertToRegExpString(query, hasDiacritics) { const { matchDiacritics } = this._state; let isUnicode = false; - query = query.replace( + query = query.replaceAll( SPECIAL_CHARS_REG_EXP, ( match, diff --git a/web/ui_utils.js b/web/ui_utils.js index 59574db85..58b12d688 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -223,7 +223,7 @@ function removeNullCharacters(str, replaceInvisible = false) { return str; } if (replaceInvisible) { - str = str.replace(InvisibleCharactersRegExp, " "); + str = str.replaceAll(InvisibleCharactersRegExp, " "); } return str.replaceAll("\x00", ""); }