diff --git a/CHANGELOG.md b/CHANGELOG.md index d8fdcc197..936cadb56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,10 @@ This changelog records changes to stable releases since 1.50.2. "TBA" changes he ## Nightly (only) +- feat: improve display of HTML elements in the debugger - feat: add node tool picker completion for launch.json ([#1997](https://github.com/microsoft/vscode-js-debug/issues/1997)) - fix: process attachment with `--inspect=:1234` style ([#2063](https://github.com/microsoft/vscode-js-debug/issues/2063)) +- fix: running new npm scripts in internal terminal ([vscode#227285](https://github.com/microsoft/vscode/issues/227285)) ## v1.93 (August 2024) diff --git a/package-lock.json b/package-lock.json index e025d0233..1044987c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,21 +11,21 @@ "license": "MIT", "dependencies": { "@c4312/chromehash": "^0.3.0", - "@jridgewell/gen-mapping": "^0.3.3", - "@jridgewell/trace-mapping": "^0.3.22", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "@vscode/js-debug-browsers": "^1.1.2", "@vscode/l10n": "^0.0.18", "@vscode/win32-app-container-tokens": "^0.1.0", - "acorn": "^8.11.3", + "acorn": "^8.12.1", "acorn-loose": "^8.4.0", "astring": "^1.8.6", "color": "^4.2.3", - "data-uri-to-buffer": "^6.0.1", + "data-uri-to-buffer": "^6.0.2", "default-browser": "^5.2.1", - "dotenv": "^16.4.1", + "dotenv": "^16.4.5", "eslint-visitor-keys": "^3.4.3", "execa": "^5.1.1", - "glob-stream": "^8.0.0", + "glob-stream": "^8.0.2", "got": "^11.8.6", "inversify": "^6.0.2", "js-xxhash": "^3.0.1", @@ -34,13 +34,13 @@ "micromatch": "^4.0.5", "path-browserify": "^1.0.1", "picomatch": "connor4312/picomatch#2fbe90b12eafa7dde816ff8c16be9e77271b0e0b", - "preact": "^10.19.3", - "reflect-metadata": "^0.2.1", + "preact": "^10.23.2", + "reflect-metadata": "^0.2.2", "signale": "^1.4.0", "source-map-support": "^0.5.21", "to-absolute-glob": "^3.0.0", "vscode-tas-client": "^0.1.84", - "ws": "^8.17.1" + "ws": "^8.18.0" }, "devDependencies": { "@c4312/matcha": "^1.3.1", @@ -1410,13 +1410,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -1431,9 +1432,10 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -1444,9 +1446,10 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2684,9 +2687,10 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -4444,9 +4448,10 @@ } }, "node_modules/data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", "engines": { "node": ">= 14" } @@ -4849,14 +4854,15 @@ } }, "node_modules/dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/dprint": { @@ -6806,9 +6812,10 @@ } }, "node_modules/glob-stream": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.0.tgz", - "integrity": "sha512-CdIUuwOkYNv9ZadR3jJvap8CMooKziQZ/QCSPhEb7zqfsEI5YnPmvca7IvbaVE3z58ZdUYD2JsU6AUWjL8WZJA==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", + "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", + "license": "MIT", "dependencies": { "@gulpjs/to-absolute-glob": "^4.0.0", "anymatch": "^3.1.3", @@ -11925,9 +11932,10 @@ } }, "node_modules/preact": { - "version": "10.19.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.3.tgz", - "integrity": "sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==", + "version": "10.23.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", + "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -12317,9 +12325,10 @@ } }, "node_modules/reflect-metadata": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", - "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" }, "node_modules/reflect.getprototypeof": { "version": "1.0.4", @@ -15452,9 +15461,10 @@ } }, "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -16457,13 +16467,13 @@ "dev": true }, "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { @@ -16472,9 +16482,9 @@ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" }, "@jridgewell/sourcemap-codec": { "version": "1.4.15", @@ -16482,9 +16492,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "requires": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -17500,9 +17510,9 @@ } }, "acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==" + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==" }, "acorn-jsx": { "version": "5.3.2", @@ -18884,9 +18894,9 @@ } }, "data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==" + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" }, "dateformat": { "version": "2.2.0", @@ -19165,9 +19175,9 @@ } }, "dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==" + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==" }, "dprint": { "version": "0.47.2", @@ -20788,9 +20798,9 @@ } }, "glob-stream": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.0.tgz", - "integrity": "sha512-CdIUuwOkYNv9ZadR3jJvap8CMooKziQZ/QCSPhEb7zqfsEI5YnPmvca7IvbaVE3z58ZdUYD2JsU6AUWjL8WZJA==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", + "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", "requires": { "@gulpjs/to-absolute-glob": "^4.0.0", "anymatch": "^3.1.3", @@ -24595,9 +24605,9 @@ "dev": true }, "preact": { - "version": "10.19.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.3.tgz", - "integrity": "sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==" + "version": "10.23.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", + "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==" }, "prebuild-install": { "version": "6.1.4", @@ -24907,9 +24917,9 @@ } }, "reflect-metadata": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", - "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==" }, "reflect.getprototypeof": { "version": "1.0.4", @@ -27242,9 +27252,9 @@ } }, "ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "requires": {} }, "xml": { diff --git a/package.json b/package.json index 5b657c5e5..4d038fec5 100644 --- a/package.json +++ b/package.json @@ -51,21 +51,21 @@ }, "dependencies": { "@c4312/chromehash": "^0.3.0", - "@jridgewell/gen-mapping": "^0.3.3", - "@jridgewell/trace-mapping": "^0.3.22", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "@vscode/js-debug-browsers": "^1.1.2", "@vscode/l10n": "^0.0.18", "@vscode/win32-app-container-tokens": "^0.1.0", - "acorn": "^8.11.3", + "acorn": "^8.12.1", "acorn-loose": "^8.4.0", "astring": "^1.8.6", "color": "^4.2.3", - "data-uri-to-buffer": "^6.0.1", + "data-uri-to-buffer": "^6.0.2", "default-browser": "^5.2.1", - "dotenv": "^16.4.1", + "dotenv": "^16.4.5", "eslint-visitor-keys": "^3.4.3", "execa": "^5.1.1", - "glob-stream": "^8.0.0", + "glob-stream": "^8.0.2", "got": "^11.8.6", "inversify": "^6.0.2", "js-xxhash": "^3.0.1", @@ -74,13 +74,13 @@ "micromatch": "^4.0.5", "path-browserify": "^1.0.1", "picomatch": "connor4312/picomatch#2fbe90b12eafa7dde816ff8c16be9e77271b0e0b", - "preact": "^10.19.3", - "reflect-metadata": "^0.2.1", + "preact": "^10.23.2", + "reflect-metadata": "^0.2.2", "signale": "^1.4.0", "source-map-support": "^0.5.21", "to-absolute-glob": "^3.0.0", "vscode-tas-client": "^0.1.84", - "ws": "^8.17.1" + "ws": "^8.18.0" }, "devDependencies": { "@c4312/matcha": "^1.3.1", diff --git a/src/adapter/clientCapabilities.ts b/src/adapter/clientCapabilities.ts new file mode 100644 index 000000000..e5c65ca48 --- /dev/null +++ b/src/adapter/clientCapabilities.ts @@ -0,0 +1,17 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + +import { injectable } from 'inversify'; +import Dap from '../dap/api'; + +export interface IClientCapabilies { + value?: Dap.InitializeParams; +} + +export const IClientCapabilies = Symbol('IClientCapabilies'); + +@injectable() +export class ClientCapabilities implements IClientCapabilies { + value?: Dap.InitializeParams | undefined; +} diff --git a/src/adapter/debugAdapter.ts b/src/adapter/debugAdapter.ts index 7bf3b9f13..4ac22c602 100644 --- a/src/adapter/debugAdapter.ts +++ b/src/adapter/debugAdapter.ts @@ -24,6 +24,7 @@ import { IShutdownParticipants } from '../ui/shutdownParticipants'; import { IAsyncStackPolicy } from './asyncStackPolicy'; import { BreakpointManager } from './breakpoints'; import { ICdpProxyProvider } from './cdpProxy'; +import { IClientCapabilies } from './clientCapabilities'; import { ICompletions } from './completions'; import { IConsole } from './console'; import { Diagnostics } from './diagnosics'; @@ -250,6 +251,7 @@ export class DebugAdapter implements IDisposable { ): Promise { console.assert(params.linesStartAt1); console.assert(params.columnsStartAt1); + this._services.get(IClientCapabilies).value = params; const capabilities = DebugAdapter.capabilities(true); setTimeout(() => this.dap.initialized({}), 0); setTimeout(() => this._thread?.dapInitialized(), 0); @@ -310,6 +312,7 @@ export class DebugAdapter implements IDisposable { supportsEvaluationOptions: extended ? true : false, supportsDebuggerProperties: extended ? true : false, supportsSetSymbolOptions: extended ? true : false, + supportsANSIStyling: true, // supportsDataBreakpoints: false, // supportsDisassembleRequest: false, }; @@ -515,6 +518,7 @@ export class DebugAdapter implements IDisposable { this._services.get(IExceptionPauseService), this._services.get(SmartStepper), this._services.get(IShutdownParticipants), + this._services.get(IClientCapabilies), ); const profile = this._services.get(IProfileController); diff --git a/src/adapter/messageFormat.ts b/src/adapter/messageFormat.ts index 843dd27c4..238871cd5 100644 --- a/src/adapter/messageFormat.ts +++ b/src/adapter/messageFormat.ts @@ -148,13 +148,13 @@ export function formatCssAsAnsi(style: string): string { if (background) escapedSequence += `\x1b[48;5;${background}m`; break; case 'font-weight': - if (match[2] === 'bold') escapedSequence += '\x1b[1m'; + if (match[2] === 'bold') escapedSequence += AnsiStyles.Bold; break; case 'font-style': - if (match[2] === 'italic') escapedSequence += '\x1b[3m'; + if (match[2] === 'italic') escapedSequence += AnsiStyles.Italic; break; case 'text-decoration': - if (match[2] === 'underline') escapedSequence += '\x1b[4m'; + if (match[2] === 'underline') escapedSequence += AnsiStyles.Underline; break; default: // css not mapped, skip @@ -166,3 +166,31 @@ export function formatCssAsAnsi(style: string): string { return escapedSequence; } + +export const enum AnsiStyles { + Reset = '\x1b[0m', + Bold = '\x1b[1m', + Dim = '\x1b[2m', + Italic = '\x1b[3m', + Underline = '\x1b[4m', + Blink = '\x1b[5m', + Reverse = '\x1b[7m', + Hidden = '\x1b[8m', + Strikethrough = '\x1b[9m', + Black = '\x1b[30m', + Red = '\x1b[31m', + Green = '\x1b[32m', + Yellow = '\x1b[33m', + Blue = '\x1b[34m', + Magenta = '\x1b[35m', + Cyan = '\x1b[36m', + White = '\x1b[37m', + BrightBlack = '\x1b[30;1m', + BrightRed = '\x1b[31;1m', + BrightGreen = '\x1b[32;1m', + BrightYellow = '\x1b[33;1m', + BrightBlue = '\x1b[34;1m', + BrightMagenta = '\x1b[35;1m', + BrightCyan = '\x1b[36;1m', + BrightWhite = '\x1b[37;1m', +} diff --git a/src/adapter/objectPreview/index.ts b/src/adapter/objectPreview/index.ts index e0bb908ba..ba2083436 100644 --- a/src/adapter/objectPreview/index.ts +++ b/src/adapter/objectPreview/index.ts @@ -314,12 +314,12 @@ function appendKeyValue( if (key.length + separator.length > characterBudget) { return stringUtils.trimEnd(key, characterBudget); } - return `${key}${separator}${ + return escapeAnsiInString(`${key}${separator}${ stringUtils.trimMiddle( value, characterBudget - key.length - separator.length, ) - }`; // Keep in sync with characterBudget calculation. + }`); // Keep in sync with characterBudget calculation. } function renderPropertyPreview( @@ -341,6 +341,10 @@ function renderPropertyPreview( return appendKeyValue(name, ': ', prop.value ?? 'unknown', characterBudget); } +function escapeAnsiInString(value: string) { + return value.replaceAll('\x1b', '\\x1b'); +} + function quoteStringValue(value: string) { // Try a quote style that doesn't appear in the string, preferring/falling back to single quotes const quoteStyle = value.includes("'") @@ -368,7 +372,7 @@ function renderValue( quote = false; } const value = stringUtils.trimMiddle(stringValue, quote ? budget - 2 : budget); - return quote ? quoteStringValue(value) : value; + return escapeAnsiInString(quote ? quoteStringValue(value) : value); } if (object.type === 'undefined') { diff --git a/src/adapter/templates/getNodeChildren.ts b/src/adapter/templates/getNodeChildren.ts new file mode 100644 index 000000000..c7d1aa61c --- /dev/null +++ b/src/adapter/templates/getNodeChildren.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + +import { remoteFunction } from '.'; + +/** + * Returns an object containing array property descriptors for the given + * range of array indices. + */ +export const getNodeChildren = remoteFunction(function( + this: Node, + start: number, + count: number, +) { + const result: Record = {}; + const from = start === -1 ? 0 : start; + const to = count === -1 ? this.childNodes.length : start + count; + for (let i = from; i < to && i < this.childNodes.length; ++i) { + const cn = this.childNodes[i]; + if (cn.nodeName === '#comment') { + result[i] = ``; + } else if (cn.nodeName === '#text') { + result[i] = cn.textContent || ''; + } else { + result[i] = cn; + } + } + + return result; +}); diff --git a/src/adapter/threads.ts b/src/adapter/threads.ts index 35ba41fdd..ed6e408a7 100644 --- a/src/adapter/threads.ts +++ b/src/adapter/threads.ts @@ -27,6 +27,7 @@ import { ITarget } from '../targets/targets'; import { IShutdownParticipants } from '../ui/shutdownParticipants'; import { BreakpointManager, EntryBreakpointMode } from './breakpoints'; import { UserDefinedBreakpoint } from './breakpoints/userDefinedBreakpoint'; +import { IClientCapabilies } from './clientCapabilities'; import { ICompletions } from './completions'; import { ExceptionMessage, IConsole, QueryObjectsMessage } from './console'; import { customBreakpoints } from './customBreakpoints'; @@ -221,12 +222,20 @@ export class Thread implements IVariableStoreLocationProvider { private readonly exceptionPause: IExceptionPauseService, private readonly _smartStepper: SmartStepper, private readonly shutdown: IShutdownParticipants, + clientCapabilities: IClientCapabilies, ) { this._dap = new DeferredContainer(dap); this._sourceContainer = sourceContainer; this._cdp = cdp; this.id = Thread._lastThreadId++; - this.replVariables = new VariableStore(renameProvider, this._cdp, dap, launchConfig, this); + this.replVariables = new VariableStore( + renameProvider, + this._cdp, + dap, + launchConfig, + clientCapabilities, + this, + ); sourceContainer.onSourceMappedSteppingChange(() => this.refreshStackTrace()); this._initialize(); } diff --git a/src/adapter/variableStore.ts b/src/adapter/variableStore.ts index 246c43198..9450bc93e 100644 --- a/src/adapter/variableStore.ts +++ b/src/adapter/variableStore.ts @@ -15,7 +15,9 @@ import Dap from '../dap/api'; import { IDapApi } from '../dap/connection'; import * as errors from '../dap/errors'; import { ProtocolError } from '../dap/protocolError'; +import { ClientCapabilities, IClientCapabilies } from './clientCapabilities'; import { IWasmVariable, IWasmVariableEvaluation, WasmScope } from './dwarf/wasmSymbolProvider'; +import { AnsiStyles } from './messageFormat'; import * as objectPreview from './objectPreview'; import { MapPreview, SetPreview } from './objectPreview/betterTypes'; import { PreviewContextType } from './objectPreview/contexts'; @@ -23,6 +25,7 @@ import { StackFrame, StackTrace } from './stackTrace'; import { getSourceSuffix, RemoteException, RemoteObjectId } from './templates'; import { getArrayProperties } from './templates/getArrayProperties'; import { getArraySlots } from './templates/getArraySlots'; +import { getNodeChildren } from './templates/getNodeChildren'; import { getDescriptionSymbols, getStringyProps, @@ -204,6 +207,7 @@ class VariableContext { public readonly locationProvider: IVariableStoreLocationProvider, private readonly currentRef: undefined | (() => IVariable | Scope), private readonly settings: IContextSettings, + public readonly clientCapabilities: IClientCapabilies, ) { this.name = ctx.name; this.presentationHint = ctx.presentationHint; @@ -247,6 +251,7 @@ class VariableContext { this.locationProvider, () => v, this.settings, + this.clientCapabilities, ), ...rest, ) as InstanceType; @@ -272,6 +277,8 @@ class VariableContext { return this.createVariable(FunctionVariable, ctx, object, customStringRepr); } else if (object.subtype === 'map' || object.subtype === 'set') { return this.createVariable(SetOrMapVariable, ctx, object, customStringRepr); + } else if (object.subtype === 'node') { + return this.createVariable(NodeVariable, ctx, object, customStringRepr); } else if (!objectPreview.subtypesWithoutPreview.has(object.subtype)) { return this.createVariable(ObjectVariable, ctx, object, customStringRepr); } @@ -851,6 +858,118 @@ class ObjectVariable extends Variable implements IMemoryReadable { } } +class NodeAttributes extends ObjectVariable { + public readonly id = getVariableId(); + + override get accessor(): string { + return (this.context.parent as NodeVariable).accessor; + } + + public override async toDap( + context: PreviewContextType, + valueFormat?: Dap.ValueFormat, + ): Promise { + return Promise.resolve({ + ...await super.toDap(context, valueFormat), + value: '...', + }); + } +} + +class NodeVariable extends Variable { + public override async toDap( + previewContext: PreviewContextType, + valueFormat?: Dap.ValueFormat, + ): Promise { + const description = await this.description(); + const length = description?.node?.childNodeCount || 0; + return { + ...await super.toDap(previewContext, valueFormat), + value: await this.getValuePreview(previewContext), + variablesReference: this.id, + indexedVariables: length > 100 ? length : undefined, + namedVariables: length > 100 ? 1 : undefined, + }; + } + + public override async getChildren(params?: Dap.VariablesParamsExtended): Promise { + switch (params?.filter) { + case 'indexed': + return this.getNodeChildren(params.start, params.count); + case 'named': + return [this.getAttributesVar()]; + default: + return [this.getAttributesVar(), ...(await this.getNodeChildren())]; + } + } + + private getAttributesVar() { + return this.context.createVariable( + NodeAttributes, + { + name: l10n.t('Node Attributes'), + presentationHint: { visibility: 'internal' }, + sortOrder: Number.MAX_SAFE_INTEGER, + }, + this.remoteObject, + undefined, + ); + } + + private async getNodeChildren(start = -1, count = -1) { + let slotsObject: Cdp.Runtime.RemoteObject; + try { + slotsObject = await getNodeChildren({ + cdp: this.context.cdp, + generatePreview: false, + args: [start, count], + objectId: this.remoteObject.objectId, + }); + } catch (e) { + return []; + } + + const result = await this.context.createObjectPropertyVars(slotsObject); + if (slotsObject.objectId) { + await this.context.cdp.Runtime.releaseObject({ objectId: slotsObject.objectId }); + } + + return result; + } + + private readonly description = once(() => + this.context.cdp.DOM.describeNode({ + objectId: this.remoteObject.objectId, + }) + ); + + private async getValuePreview(_previewContext: PreviewContextType) { + const description = await this.description(); + if (!description?.node) { + return ''; + } + + const { localName, attributes, childNodeCount } = description.node; + const styleCheck = this.context.clientCapabilities.value?.supportsANSIStyling ? true : ''; + let str = (styleCheck && AnsiStyles.Blue) + `<${localName}`; + if (attributes) { + for (let i = 0; i < attributes.length; i += 2) { + const key = attributes[i]; + const value = attributes[i + 1]; + str += ` ${(styleCheck && AnsiStyles.BrightBlue)}${key}${(styleCheck + && AnsiStyles.Dim)}=${(styleCheck && AnsiStyles.Yellow)}${JSON.stringify(value)}`; + } + } + str += (styleCheck && AnsiStyles.Blue) + '>'; + if (childNodeCount) { + str += `${(styleCheck && AnsiStyles.Dim)}...${(styleCheck && AnsiStyles.Blue)}`; + } + str += `${(styleCheck && AnsiStyles.Reset)}`; + + return str; + } +} + class FunctionVariable extends ObjectVariable { private readonly baseChildren = once(() => super.getChildren({ variablesReference: this.id })); @@ -1272,6 +1391,7 @@ export class VariableStore { @inject(ICdpApi) private readonly cdp: Cdp.Api, @inject(IDapApi) private readonly dap: Dap.Api, @inject(AnyLaunchConfiguration) private readonly launchConfig: AnyLaunchConfiguration, + @inject(ClientCapabilities) private readonly clientCapabilities: ClientCapabilities, private readonly locationProvider: IVariableStoreLocationProvider, ) { this.contextSettings = { @@ -1293,6 +1413,7 @@ export class VariableStore { this.cdp, this.dap, this.launchConfig, + this.clientCapabilities, this.locationProvider, ); } @@ -1345,6 +1466,7 @@ export class VariableStore { this.locationProvider, () => scope, this.contextSettings, + this.clientCapabilities, ), scopeRef, extraProperties, @@ -1371,6 +1493,7 @@ export class VariableStore { this.locationProvider, () => scope, this.contextSettings, + this.clientCapabilities, ), kind, variables, @@ -1497,6 +1620,7 @@ export class VariableStore { this.locationProvider, undefined, this.contextSettings, + this.clientCapabilities, ); } } diff --git a/src/common/disposable.ts b/src/common/disposable.ts index ef89a75ad..8be976376 100644 --- a/src/common/disposable.ts +++ b/src/common/disposable.ts @@ -38,7 +38,7 @@ export class RefCounter { public dispose() { if (!this.disposed) { this.disposed = true; - this.value.dispose; + this.value.dispose(); } } } diff --git a/src/dap/api.d.ts b/src/dap/api.d.ts index d35476bc9..8d7557e55 100644 --- a/src/dap/api.d.ts +++ b/src/dap/api.d.ts @@ -2611,6 +2611,11 @@ export namespace Dap { * Client supports the `startDebugging` request. */ supportsStartDebuggingRequest?: boolean; + + /** + * The client will interpret ANSI escape sequences in the display of `OutputEvent.output` and `Variable.value` fields when `Capabilities.supportsANSIStyling` is also enabled. + */ + supportsANSIStyling?: boolean; } export interface InitializeResult { @@ -2820,6 +2825,11 @@ export namespace Dap { * Clients may present the first applicable mode in this array as the 'default' mode in gestures that set breakpoints. */ breakpointModes?: (BreakpointMode)[]; + + /** + * The debug adapter supports ANSI escape sequences in styling of `OutputEvent.output` and `Variable.value` fields. + */ + supportsANSIStyling?: boolean; } export interface InitializedEventParams { @@ -3092,6 +3102,10 @@ export namespace Dap { /** * The output to report. + * + * ANSI escape sequences may be used to inflience text color and styling if `supportsANSIStyling` is present in both the adapter's `Capabilities` and the client's `InitializeRequestArguments`. A client may strip any unrecognized ANSI sequences. + * + * If the `supportsANSIStyling` capabilities are not both true, then the client should display the output literally. */ output: string; @@ -5406,6 +5420,11 @@ export namespace Dap { * Clients may present the first applicable mode in this array as the 'default' mode in gestures that set breakpoints. */ breakpointModes?: (BreakpointMode)[]; + + /** + * The debug adapter supports ANSI escape sequences in styling of `OutputEvent.output` and `Variable.value` fields. + */ + supportsANSIStyling?: boolean; } /** diff --git a/src/ioc.ts b/src/ioc.ts index 1b54bbb01..3d38eefa7 100644 --- a/src/ioc.ts +++ b/src/ioc.ts @@ -27,6 +27,7 @@ import { } from './adapter/breakpoints/conditions'; import { LogPointCompiler } from './adapter/breakpoints/conditions/logPoint'; import { CdpProxyProvider, ICdpProxyProvider } from './adapter/cdpProxy'; +import { ClientCapabilities, IClientCapabilies } from './adapter/clientCapabilities'; import { Completions, ICompletions } from './adapter/completions'; import { IConsole } from './adapter/console'; import { Console } from './adapter/console/console'; @@ -163,6 +164,7 @@ export const createTargetContainer = ( container.bind(ITarget).toConstantValue(target); container.bind(ITargetOrigin).toConstantValue(target.targetOrigin()); container.bind(IResourceProvider).to(StatefulResourceProvider).inSingletonScope(); + container.bind(IClientCapabilies).to(ClientCapabilities).inSingletonScope(); container.bind(ISourceMapFactory).to(SourceMapFactory).inSingletonScope(); container.bind(IBreakpointConditionFactory).to(BreakpointConditionFactory).inSingletonScope(); container.bind(LogPointCompiler).toSelf().inSingletonScope(); diff --git a/src/targets/node/bootloader/filters.ts b/src/targets/node/bootloader/filters.ts index b6b82f195..e21f3b7dd 100644 --- a/src/targets/node/bootloader/filters.ts +++ b/src/targets/node/bootloader/filters.ts @@ -68,7 +68,7 @@ export const checkProcessFilter = (env: IBootloaderInfo) => { * session and cause us to think it's over before it actually is. * @see https://github.com/microsoft/vscode-js-debug/issues/645 */ -export const checkNotNpmPrefixCheckOnWindows = () => { +const checkNotNpmPrefixCheckOnWindows = () => { const argv = process.argv; return !( argv.length === 4 @@ -78,6 +78,15 @@ export const checkNotNpmPrefixCheckOnWindows = () => { ); }; +/** + * Similar as above for more recent versions of npm + * @see https://github.com/microsoft/vscode-js-debug/issues/645 + */ +const checkNotNpmPrefixCheckOnWindows2 = () => { + const argv = process.argv; + return !(argv.length === 2 && basename(argv[1]) === 'npm-prefix.js'); +}; + /** * Disable attaching to the node-gyp tree, otherwise some checks it does fails * since Node writes debugger information to stderr. @@ -103,6 +112,7 @@ const allChecks = [ checkNotElectron, checkProcessFilter, checkNotNpmPrefixCheckOnWindows, + checkNotNpmPrefixCheckOnWindows2, ]; /** diff --git a/src/targets/node/nodeAttacherBase.ts b/src/targets/node/nodeAttacherBase.ts index f5d9f3e13..b94860b3d 100644 --- a/src/targets/node/nodeAttacherBase.ts +++ b/src/targets/node/nodeAttacherBase.ts @@ -21,7 +21,7 @@ const appendVars: readonly string[] = ['NODE_OPTIONS', 'VSCODE_INSPECTOR_OPTIONS export abstract class NodeAttacherBase extends NodeLauncherBase { protected async appendEnvironmentVariables(cdp: Cdp.Api, vars: EnvironmentVars) { const expression = - `typeof process==='undefined'||process.pid===undefined?'process not defined':(()=>{` + `typeof Deno==='object'?'deno':typeof process==='undefined'||process.pid===undefined?'process not defined':(()=>{` + Object.entries(vars.defined()) .map(([key, value]) => { const k = JSON.stringify(key); diff --git a/src/test/console/console-format-nodes.txt b/src/test/console/console-format-nodes.txt new file mode 100644 index 000000000..8fb54b146 --- /dev/null +++ b/src/test/console/console-format-nodes.txt @@ -0,0 +1,7 @@ +> result: 
...
 + 0: '\n Content\n ' + > 1: ...

 + 0: 'Paragaph' + 2: '\n More content\n ' + > 3:  + 4: '\n ' diff --git a/src/test/console/console-format-popular-types.txt b/src/test/console/console-format-popular-types.txt index 4a5724e54..c457f41cb 100644 --- a/src/test/console/console-format-popular-types.txt +++ b/src/test/console/console-format-popular-types.txt @@ -318,6 +318,14 @@ Evaluating: 'console.log([true])' stdout> (1) [true] stdout> > (1) [true] +Evaluating: 'console.log(node)' +stdout> p#p +stdout> > 

 + +Evaluating: 'console.log([node])' +stdout> (1) [p#p] +stdout> > (1) [p#p] + Evaluating: 'console.log(new Boolean(true))' stdout> Boolean (true) stdout> > Boolean (true) diff --git a/src/test/console/consoleFormatTest.ts b/src/test/console/consoleFormatTest.ts index a8335c08f..ea94f1ea5 100644 --- a/src/test/console/consoleFormatTest.ts +++ b/src/test/console/consoleFormatTest.ts @@ -151,6 +151,7 @@ describe('console format', () => { 'boxedStringWithProps', 'false', 'true', + 'node', 'new Boolean(true)', 'new Set([1, 2, 3, 4])', 'new Set([1, 2, 3, 4, 5, 6, 7, 8])', @@ -461,6 +462,23 @@ describe('console format', () => { p.assertLog(); }); + itIntegrates('nodes', async ({ r }) => { + const p = await r.launchAndLoad(` +
+ Content +

Paragaph

+ More content +
+
+ `); + + await p.logger.evaluateAndLog('document.getElementById("main")', { + depth: 3, + omitProperties: ['Node Attributes', '[[Prototype]]'], + }); + p.assertLog(); + }); + itIntegrates('error traces in source maps', async ({ r }) => { const handle = await r.launchUrlAndLoad('browserify/browserify.html'); await handle.logger.evaluateAndLog(['try { throwError() } catch (e) { console.error(e) }']); diff --git a/src/test/evaluate/evaluate-default.txt b/src/test/evaluate/evaluate-default.txt index 3ed493cf4..1dd05b9dc 100644 --- a/src/test/evaluate/evaluate-default.txt +++ b/src/test/evaluate/evaluate-default.txt @@ -14,6 +14,8 @@ result: 3 : Uncaught ReferenceError: baz is not defined +result: '\x1b[2m' + > result: Uint8Array(3) [1, 2, 3, buffer: ArrayBuffer(3), byteLength: 3, byteOffset: 0, length: 3, Symbol(Symbol.toStringTag): 'Uint8Array'] 0: 1 1: 2 diff --git a/src/test/evaluate/evaluate.ts b/src/test/evaluate/evaluate.ts index 716eaf8e1..4b34feae5 100644 --- a/src/test/evaluate/evaluate.ts +++ b/src/test/evaluate/evaluate.ts @@ -35,6 +35,9 @@ describe('evaluate', () => { await p.logger.evaluateAndLog(`baz();`); p.log(''); + await p.logger.evaluateAndLog(`'\\x1b[2m'`); + p.log(''); + await p.logger.evaluateAndLog(`new Uint8Array([1, 2, 3]);`); p.log(''); diff --git a/src/test/infra/infra-initialize.txt b/src/test/infra/infra-initialize.txt index 1e0049d3e..6720da753 100644 --- a/src/test/infra/infra-initialize.txt +++ b/src/test/infra/infra-initialize.txt @@ -28,6 +28,7 @@ supportTerminateDebuggee : true supportedChecksumAlgorithms : [ ] + supportsANSIStyling : true supportsBreakpointLocationsRequest : true supportsClipboardContext : true supportsCompletionsRequest : true diff --git a/src/test/logger.ts b/src/test/logger.ts index a8effcb60..a5c0fd796 100644 --- a/src/test/logger.ts +++ b/src/test/logger.ts @@ -10,6 +10,7 @@ interface ILogOptions { format?: Dap.ValueFormat; params?: Partial; logInternalInfo?: boolean; + omitProperties?: string[]; } const kOmitProperties = ['[[ArrayBufferData]]']; @@ -93,8 +94,10 @@ export class Logger { this._dap, rootVariable, (variable, depth) => { - if (kOmitProperties.includes(variable.name)) { - return depth < (options.depth ?? 1); + if ( + kOmitProperties.includes(variable.name) || options.omitProperties?.includes(variable.name) + ) { + return false; } const name = variable.name ? `${variable.name}: ` : ''; diff --git a/src/test/test.ts b/src/test/test.ts index e250c43a0..d31cc6abd 100644 --- a/src/test/test.ts +++ b/src/test/test.ts @@ -111,6 +111,7 @@ class Session { columnsStartAt1: true, pathFormat: 'path', supportsVariablePaging: true, + supportsANSIStyling: true, }), this.dap.once('initialized'), ]); diff --git a/src/test/variables/variables-web-tags.txt b/src/test/variables/variables-web-tags.txt index 5d0fd7ebf..d0a6ed6d2 100644 --- a/src/test/variables/variables-web-tags.txt +++ b/src/test/variables/variables-web-tags.txt @@ -1,7 +1,7 @@ > result: HTMLCollection(2) [meta, title, foo: meta] - > 0: meta - > 1: title + > 0:  + > 1: ... > length: (...) - > foo: meta + > foo:  > [[Prototype]]: HTMLCollection > [[Prototype]]: Object