From db68a431299cd8862a2f9ec25468b2eb7a5ab6e9 Mon Sep 17 00:00:00 2001 From: SarthakDudhe Date: Mon, 4 May 2026 17:09:29 +0530 Subject: [PATCH 01/11] Fix: correctly restore statement mode for unary operators on new line (#1896) --- js/src/javascript/beautifier.js | 18 +++++++++++------- test/data/javascript/tests.js | 10 +++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/js/src/javascript/beautifier.js b/js/src/javascript/beautifier.js index 37350c225..3d8a8c02f 100644 --- a/js/src/javascript/beautifier.js +++ b/js/src/javascript/beautifier.js @@ -1159,7 +1159,17 @@ Beautifier.prototype.handle_operator = function(current_token) { // The conditional starts the statement if appropriate. } else { var preserve_statement_flags = !isGeneratorAsterisk; + var is_prefix_operator = current_token.newlines && in_array(current_token.text, ['--', '++', '~', '!']) && + !is_expression(this._flags.mode) && + (this._flags.last_token.type !== TOKEN.OPERATOR || (this._flags.last_token.text === '--' || this._flags.last_token.text === '++')) && + this._flags.last_token.type !== TOKEN.EQUALS; + if (is_prefix_operator) { + preserve_statement_flags = false; + } this.handle_whitespace_and_comments(current_token, preserve_statement_flags); + if (is_prefix_operator) { + this.print_newline(false, false); + } } // hack for actionscript's import .*; @@ -1294,13 +1304,7 @@ Beautifier.prototype.handle_operator = function(current_token) { // http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1 // if there is a newline between -- or ++ and anything else we should preserve it. - if (current_token.newlines && (current_token.text === '--' || current_token.text === '++' || current_token.text === '~')) { - var new_line_needed = reserved_array(this._flags.last_token, special_words) && current_token.newlines; - if (new_line_needed && (this._previous_flags.if_block || this._previous_flags.else_block)) { - this.restore_mode(); - } - this.print_newline(new_line_needed, true); - } + if (this._flags.last_token.text === ';' && is_expression(this._flags.mode)) { // for (;; ++i) diff --git a/test/data/javascript/tests.js b/test/data/javascript/tests.js index c37efdcb4..23e5c6fc0 100644 --- a/test/data/javascript/tests.js +++ b/test/data/javascript/tests.js @@ -5887,9 +5887,13 @@ exports.test_data = { { input: 'var a={bing:1},b=2,c=3;', output: 'var a = {\n bing: 1\n },\n b = 2,\n c = 3;' }, { - comment: 'Issue #1896: Handle newlines with bitwise ~ operator', - input: 'if (foo) {\nvar bar = 1;\n~bar ? 0 : 1\n }', - output: 'if (foo) {\n var bar = 1;\n ~bar ? 0 : 1\n}' + comment: 'Issue #1896: Handle newlines with bitwise ~ and ! operators', + input: 'if (foo) {\nvar bar = 1\n~bar ? 0 : 1\n }', + output: 'if (foo) {\n var bar = 1\n ~bar ? 0 : 1\n}' + }, + { + input: 'if (foo) {\nvar bar = 1\n!bar ? 0 : 1\n }', + output: 'if (foo) {\n var bar = 1\n !bar ? 0 : 1\n}' }, { From 873a3fbe9e518050a1ecd77938b2f723518850fb Mon Sep 17 00:00:00 2001 From: SarthakDudhe Date: Mon, 4 May 2026 17:27:52 +0530 Subject: [PATCH 02/11] Fix glob security dependency --- package-lock.json | 240 ++++++++++++++++++++++++++++++++++++---------- package.json | 2 +- 2 files changed, 192 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 10f91e277..50f7d78f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "config-chain": "^1.1.13", "editorconfig": "^1.0.4", - "glob": "^10.5.0", + "glob": "^11.1.0", "js-cookie": "^3.0.5", "nopt": "^7.2.1" }, @@ -50,20 +50,12 @@ } }, "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@jridgewell/gen-mapping": { @@ -125,6 +117,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "license": "MIT", "optional": true, "engines": { @@ -475,6 +468,7 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -487,6 +481,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -942,6 +937,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -952,7 +948,8 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/commander": { "version": "2.20.3", @@ -1187,7 +1184,8 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/editorconfig": { "version": "1.0.4", @@ -1238,7 +1236,8 @@ "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/enhanced-resolve": { "version": "5.20.1", @@ -1442,11 +1441,12 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -1460,6 +1460,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", "engines": { "node": ">=14" }, @@ -1502,21 +1503,25 @@ } }, "node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "license": "ISC", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" }, + "engines": { + "node": "20 || >=22" + }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -1528,6 +1533,42 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -1667,6 +1708,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -1771,18 +1813,18 @@ } }, "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/jest-worker": { @@ -1992,6 +2034,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -2013,9 +2056,10 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -2057,6 +2101,86 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/mocha/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/mocha/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/mocha/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mocha/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2251,26 +2375,29 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, "node_modules/path-to-regexp": { "version": "3.3.0", @@ -2767,6 +2894,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -2784,6 +2912,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -2798,6 +2927,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -2807,12 +2937,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -2825,6 +2957,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" @@ -2841,6 +2974,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -2853,6 +2987,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3227,6 +3362,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -3244,6 +3380,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -3261,6 +3398,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3270,12 +3408,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -3290,6 +3430,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -3302,6 +3443,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, "engines": { "node": ">=12" }, diff --git a/package.json b/package.json index 8ca6015e5..a13c17219 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "dependencies": { "config-chain": "^1.1.13", "editorconfig": "^1.0.4", - "glob": "^10.5.0", + "glob": "^11.1.0", "js-cookie": "^3.0.5", "nopt": "^7.2.1" }, From 8b7b983d80c77d48fb5b2a8a67631cd226d5e325 Mon Sep 17 00:00:00 2001 From: SarthakDudhe Date: Mon, 4 May 2026 17:32:54 +0530 Subject: [PATCH 03/11] Update editorconfig dependency --- package-lock.json | 70 +++++++++++++++++++---------------------------- package.json | 2 +- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/package-lock.json b/package-lock.json index 50f7d78f8..3a9c06563 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "config-chain": "^1.1.13", - "editorconfig": "^1.0.4", + "editorconfig": "^3.0.1", "glob": "^11.1.0", "js-cookie": "^3.0.5", "nopt": "^7.2.1" @@ -109,9 +109,10 @@ } }, "node_modules/@one-ini/wasm": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", - "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.2.0.tgz", + "integrity": "sha512-n+L/BvrwKUn7q5O3wHGo+CJZAqfewh38+37sk+eBzv/39lM9pPgPRd4sOZRvSRzo0ukLxzyXso4WlGj2oKZ5hA==", + "license": "MIT" }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -1188,39 +1189,42 @@ "dev": true }, "node_modules/editorconfig": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", - "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-3.0.1.tgz", + "integrity": "sha512-k5NZM2XNIJfH/omUv0SRYaiLae4VRwg1ILW6xLOjuP4AQGAGcvzNij5imJ+m1rbzDIH0ov6EbH53BW96amFXpQ==", + "license": "MIT", "dependencies": { - "@one-ini/wasm": "0.1.1", - "commander": "^10.0.0", - "minimatch": "9.0.1", - "semver": "^7.5.3" + "@one-ini/wasm": "0.2.0", + "commander": "^14.0.0", + "minimatch": "10.0.1", + "semver": "^7.7.2" }, "bin": { "editorconfig": "bin/editorconfig" }, "engines": { - "node": ">=14" + "node": ">=20" } }, "node_modules/editorconfig/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", "engines": { - "node": ">=14" + "node": ">=20" } }, "node_modules/editorconfig/node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1983,17 +1987,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2703,12 +2696,10 @@ } }, "node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3467,11 +3458,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index a13c17219..463c1adb0 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "browserslist": "ie 11", "dependencies": { "config-chain": "^1.1.13", - "editorconfig": "^1.0.4", + "editorconfig": "^3.0.1", "glob": "^11.1.0", "js-cookie": "^3.0.5", "nopt": "^7.2.1" From bcf884b95b210e16d1ea64de532a4d8e79bc98c0 Mon Sep 17 00:00:00 2001 From: SarthakDudhe Date: Mon, 4 May 2026 17:34:51 +0530 Subject: [PATCH 04/11] Focus input after clearing the editor --- web/common-function.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/common-function.js b/web/common-function.js index 00f86a52f..34c11abd6 100644 --- a/web/common-function.js +++ b/web/common-function.js @@ -380,8 +380,10 @@ function selectAll() { function clearAll() { if (the.editor) { the.editor.setValue(''); + the.editor.focus(); } else { $('#source').val(''); + $('#source').focus(); } } From 164cc2f46c64b8dc8c03701d9c4f581d253dae42 Mon Sep 17 00:00:00 2001 From: SarthakDudhe Date: Mon, 4 May 2026 17:37:49 +0530 Subject: [PATCH 05/11] Add tests for web common functions --- js/test/web-common-function-tests.js | 251 +++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 js/test/web-common-function-tests.js diff --git a/js/test/web-common-function-tests.js b/js/test/web-common-function-tests.js new file mode 100644 index 000000000..9073fa7ef --- /dev/null +++ b/js/test/web-common-function-tests.js @@ -0,0 +1,251 @@ +'use strict'; + +var assert = require('assert'); +var fs = require('fs'); +var path = require('path'); +var vm = require('vm'); + +function createElementStub() { + var state = { + focused: false, + selected: false + }; + + var api = { + val: function(value) { + if (arguments.length > 0) { + state.value = value; + return api; + } + return state.value; + }, + prop: function(name, value) { + if (arguments.length > 1) { + state[name] = value; + return api; + } + return state[name]; + }, + text: function(value) { + if (arguments.length > 0) { + state.text = value; + return api; + } + return state.text; + }, + html: function(value) { + if (arguments.length > 0) { + state.html = value; + return api; + } + return state.html; + }, + attr: function(name, value) { + if (arguments.length > 1) { + state[name] = value; + return api; + } + return state[name]; + }, + addClass: function(className) { + state.classes = state.classes || []; + state.classes.push(className); + return api; + }, + removeClass: function(className) { + state.removedClasses = state.removedClasses || []; + state.removedClasses.push(className); + return api; + }, + children: function() { + return api; + }, + bind: function() { + return api; + }, + change: function() { + return api; + }, + click: function() { + return api; + }, + show: function() { + state.hidden = false; + return api; + }, + hide: function() { + state.hidden = true; + return api; + }, + select: function() { + state.selected = true; + return api; + }, + focus: function() { + state.focused = true; + return api; + }, + remove: function() { + state.removed = true; + return api; + }, + append: function() { + return api; + }, + valState: state + }; + + return api; +} + +function createContext() { + var elements = {}; + var cookies = {}; + + function getElement(selector) { + if (!elements[selector]) { + elements[selector] = createElementStub(); + } + return elements[selector]; + } + + var windowObject = { + location: { + href: 'http://localhost/' + }, + navigator: { + platform: '' + }, + screen: { + orientation: { + lock: function() {} + } + }, + open: function() { + return { + focus: function() {} + }; + }, + matchMedia: function() { + return { + matches: false + }; + } + }; + + var context = { + console: console, + window: windowObject, + document: { + querySelector: function() { + return null; + }, + createElement: function() { + return { + style: {}, + click: function() {}, + setAttribute: function() {}, + remove: function() {} + }; + }, + execCommand: function() { + return true; + }, + body: { + appendChild: function() {} + } + }, + Cookies: { + get: function(name) { + return cookies[name]; + }, + set: function(name, value) { + cookies[name] = value; + } + }, + requirejs: function(deps, callback) { + if (typeof deps === 'function') { + deps(); + return; + } + if (typeof callback === 'function') { + callback({}); + } + }, + $: function(selector) { + if (typeof selector === 'function') { + selector(); + return; + } + return getElement(selector); + }, + _elements: elements, + _cookies: cookies + }; + + context.requirejs.config = function() {}; + + return context; +} + +function loadWebCommonFunctions() { + var context = createContext(); + var source = fs.readFileSync(path.join(__dirname, '../../web/common-function.js'), 'utf8'); + vm.runInNewContext(source, context, { + filename: 'web/common-function.js' + }); + return context; +} + +describe('web/common-function.js', function() { + it('hydrates the UI from stored cookie values', function() { + var context = loadWebCommonFunctions(); + + context._cookies.tabsize = '2'; + context._cookies['brace-style'] = 'expand'; + context._cookies['wrap-line-length'] = '80'; + context._cookies['unescape-strings'] = 'on'; + context._cookies.language = 'html'; + + context.read_settings_from_cookie(); + + assert.strictEqual(context._elements['#tabsize'].val(), '2'); + assert.strictEqual(context._elements['#brace-style'].val(), 'expand'); + assert.strictEqual(context._elements['#wrap-line-length'].val(), '80'); + assert.strictEqual(context._elements['#unescape-strings'].prop('checked'), true); + assert.strictEqual(context._elements['#language'].val(), 'html'); + }); + + it('clears the CodeMirror editor and restores focus', function() { + var context = loadWebCommonFunctions(); + var calls = []; + + context.the.editor = { + setValue: function(value) { + calls.push(['setValue', value]); + }, + focus: function() { + calls.push(['focus']); + } + }; + + context.clearAll(); + + assert.deepStrictEqual(calls, [ + ['setValue', ''], + ['focus'] + ]); + }); + + it('clears the textarea and restores focus when CodeMirror is not active', function() { + var context = loadWebCommonFunctions(); + var source = context.$('#source'); + + context.the.editor = null; + + context.clearAll(); + + assert.strictEqual(source.val(), ''); + assert.strictEqual(source.prop('focused'), true); + }); +}); From d3ac7e84a0ad0f2d27c2d34d122875d8b6e8e5f9 Mon Sep 17 00:00:00 2001 From: SarthakDudhe Date: Mon, 4 May 2026 17:42:53 +0530 Subject: [PATCH 06/11] Add core output unit tests --- js/test/core/test_output.js | 65 +++++++++++++++++++ python/jsbeautifier/tests/core/test_output.py | 62 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 js/test/core/test_output.js create mode 100644 python/jsbeautifier/tests/core/test_output.py diff --git a/js/test/core/test_output.js b/js/test/core/test_output.js new file mode 100644 index 000000000..80f75cfe7 --- /dev/null +++ b/js/test/core/test_output.js @@ -0,0 +1,65 @@ +/*jshint mocha:true */ +'use strict'; + +var assert = require('assert'); +var Output = require('../../src/core/output').Output; + +function makeOutput(overrides) { + var options = { + indent_size: 4, + indent_char: ' ', + indent_with_tabs: false, + indent_level: 0, + end_with_newline: false, + wrap_line_length: 0, + indent_empty_lines: false + }; + + Object.keys(overrides || {}).forEach(function(key) { + options[key] = overrides[key]; + }); + + return new Output(options); +} + +describe('Output', function() { + describe('ensure_empty_line_above', function() { + it('should insert a blank line before the current line when the previous line does not match', function() { + var output = makeOutput(); + + output.add_token('alpha'); + output.add_new_line(); + output.add_token('beta'); + output.add_new_line(); + output.add_token('gamma'); + + output.ensure_empty_line_above('skip', 'end'); + + assert.strictEqual(output.get_code('\n'), 'alpha\nbeta\n\ngamma'); + }); + + it('should not insert a blank line when the previous line starts with the requested prefix', function() { + var output = makeOutput(); + + output.add_token('skip-this'); + output.add_new_line(); + output.add_token('gamma'); + + output.ensure_empty_line_above('skip', 'end'); + + assert.strictEqual(output.get_code('\n'), 'skip-this\ngamma'); + }); + + it('should not insert a blank line when the previous line ends with the requested suffix', function() { + var output = makeOutput(); + + output.add_token('end'); + output.add_new_line(); + output.add_token('gamma'); + + output.ensure_empty_line_above('skip', 'end'); + + assert.strictEqual(output.get_code('\n'), 'end\ngamma'); + }); + }); +}); diff --git a/python/jsbeautifier/tests/core/test_output.py b/python/jsbeautifier/tests/core/test_output.py new file mode 100644 index 000000000..8c86cf1c0 --- /dev/null +++ b/python/jsbeautifier/tests/core/test_output.py @@ -0,0 +1,62 @@ +import unittest +from types import SimpleNamespace + +from ...core.output import Output + + +def make_output(**overrides): + options = SimpleNamespace( + indent_size=4, + indent_char=" ", + indent_with_tabs=False, + indent_level=0, + end_with_newline=False, + wrap_line_length=0, + indent_empty_lines=False, + ) + + for key, value in overrides.items(): + setattr(options, key, value) + + return Output(options) + + +class TestOutput(unittest.TestCase): + def test_ensure_empty_line_above_inserts_blank_line(self): + output = make_output() + + output.add_token("alpha") + output.add_new_line() + output.add_token("beta") + output.add_new_line() + output.add_token("gamma") + + output.ensure_empty_line_above("skip", "end") + + self.assertEqual(output.get_code("\n"), "alpha\nbeta\n\ngamma") + + def test_ensure_empty_line_above_skips_matching_prefix(self): + output = make_output() + + output.add_token("skip-this") + output.add_new_line() + output.add_token("gamma") + + output.ensure_empty_line_above("skip", "end") + + self.assertEqual(output.get_code("\n"), "skip-this\ngamma") + + def test_ensure_empty_line_above_skips_matching_suffix(self): + output = make_output() + + output.add_token("end") + output.add_new_line() + output.add_token("gamma") + + output.ensure_empty_line_above("skip", "end") + + self.assertEqual(output.get_code("\n"), "end\ngamma") + + +if __name__ == "__main__": + unittest.main() From 970d523b7ef6275d248427952de07ea98c7f9a44 Mon Sep 17 00:00:00 2001 From: SarthakDudhe Date: Tue, 5 May 2026 19:03:25 +0530 Subject: [PATCH 07/11] Fix Handlebars table helper formatting --- js/src/html/beautifier.js | 157 +++++++++++++++++++------------------- test/data/html/tests.js | 17 +++++ 2 files changed, 96 insertions(+), 78 deletions(-) diff --git a/js/src/html/beautifier.js b/js/src/html/beautifier.js index e32940fb7..eecc08bd1 100644 --- a/js/src/html/beautifier.js +++ b/js/src/html/beautifier.js @@ -818,92 +818,93 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) { // https://www.w3.org/TR/html5/syntax.html#optional-tags if (parser_token.is_empty_element || !parser_token.is_start_tag || !parser_token.parent) { return; - } - if (parser_token.tag_name === 'body') { - // A head element’s end tag may be omitted if the head element is not immediately followed by a space character or a comment. - result = result || this._tag_stack.try_pop('head'); + if (parser_token.tag_start_char === '<') { + if (parser_token.tag_name === 'body') { + // A head element’s end tag may be omitted if the head element is not immediately followed by a space character or a comment. + result = result || this._tag_stack.try_pop('head'); - //} else if (parser_token.tag_name === 'body') { - // DONE: A body element’s end tag may be omitted if the body element is not immediately followed by a comment. + //} else if (parser_token.tag_name === 'body') { + // DONE: A body element’s end tag may be omitted if the body element is not immediately followed by a comment. - } else if (parser_token.tag_name === 'li') { - // An li element’s end tag may be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element. - result = result || this._tag_stack.try_pop('li', ['ol', 'ul', 'menu']); + } else if (parser_token.tag_name === 'li') { + // An li element’s end tag may be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element. + result = result || this._tag_stack.try_pop('li', ['ol', 'ul', 'menu']); - } else if (parser_token.tag_name === 'dd' || parser_token.tag_name === 'dt') { - // A dd element’s end tag may be omitted if the dd element is immediately followed by another dd element or a dt element, or if there is no more content in the parent element. - // A dt element’s end tag may be omitted if the dt element is immediately followed by another dt element or a dd element. - result = result || this._tag_stack.try_pop('dt', ['dl']); - result = result || this._tag_stack.try_pop('dd', ['dl']); + } else if (parser_token.tag_name === 'dd' || parser_token.tag_name === 'dt') { + // A dd element’s end tag may be omitted if the dd element is immediately followed by another dd element or a dt element, or if there is no more content in the parent element. + // A dt element’s end tag may be omitted if the dt element is immediately followed by another dt element or a dd element. + result = result || this._tag_stack.try_pop('dt', ['dl']); + result = result || this._tag_stack.try_pop('dd', ['dl']); - } else if (parser_token.parent.tag_name === 'p' && p_closers.indexOf(parser_token.tag_name) !== -1) { - // IMPORTANT: this else-if works because p_closers has no overlap with any other element we look for in this method - // check for the parent element is an HTML element that is not an ,