mirror of
https://github.com/gchq/CyberChef
synced 2025-01-28 20:25:02 +00:00
Input now uses CodeMirror editor
This commit is contained in:
parent
54fdc05e3a
commit
85ffe48743
17 changed files with 666 additions and 182 deletions
197
package-lock.json
generated
197
package-lock.json
generated
|
@ -95,6 +95,11 @@
|
||||||
"@babel/plugin-transform-runtime": "^7.18.2",
|
"@babel/plugin-transform-runtime": "^7.18.2",
|
||||||
"@babel/preset-env": "^7.18.2",
|
"@babel/preset-env": "^7.18.2",
|
||||||
"@babel/runtime": "^7.18.3",
|
"@babel/runtime": "^7.18.3",
|
||||||
|
"@codemirror/commands": "^6.0.0",
|
||||||
|
"@codemirror/language": "^6.1.0",
|
||||||
|
"@codemirror/search": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.1",
|
||||||
|
"@codemirror/view": "^6.0.2",
|
||||||
"autoprefixer": "^10.4.7",
|
"autoprefixer": "^10.4.7",
|
||||||
"babel-loader": "^8.2.5",
|
"babel-loader": "^8.2.5",
|
||||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||||
|
@ -1782,6 +1787,60 @@
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@codemirror/commands": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-nVJDPiCQXWXj5AZxqNVXyIM3nOYauF4Dko9NGPSwgVdK+lXWJQhI5LGhS/AvdG5b7u7/pTQBkrQmzkLWRBF62A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"@lezer/common": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/language": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-CeqY80nvUFrJcXcBW115aNi06D0PS8NSW6nuJRSwbrYFkE0SfJnPfyLGrcM90AV95lqg5+4xUi99BCmzNaPGJg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"@lezer/common": "^1.0.0",
|
||||||
|
"@lezer/highlight": "^1.0.0",
|
||||||
|
"@lezer/lr": "^1.0.0",
|
||||||
|
"style-mod": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/search": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-rL0rd3AhI0TAsaJPUaEwC63KHLO7KL0Z/dYozXj6E7L3wNHRyx7RfE0/j5HsIf912EE5n2PCb4Vg0rGYmDv4UQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"crelt": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/state": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-6vYgaXc4KjSY0BUfSVDJooGcoswg/RJZpq/ZGjsUYmY0KN1lmB8u03nv+jiG1ncUV5qoggyxFT5AGD5Ak+5Zrw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/view": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-mnVT/q1JvKPjpmjXJNeCi/xHyaJ3abGJsumIVpdQ1nE1MXAyHf7GHWt8QpWMUvDiqF0j+inkhVR2OviTdFFX7Q==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"style-mod": "^4.0.0",
|
||||||
|
"w3c-keyname": "^2.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@colors/colors": {
|
"node_modules/@colors/colors": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
|
||||||
|
@ -2370,6 +2429,30 @@
|
||||||
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
|
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@lezer/common": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@lezer/highlight": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-nsCnNtim90UKsB5YxoX65v3GEIw3iCHw9RM2DtdgkiqAbKh9pCdvi8AWNwkYf10Lu6fxNhXPpkpHbW6mihhvJA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@lezer/common": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lezer/lr": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-k6DEqBh4HxqO/cVGedb6Ern6LS7K6IOzfydJ5WaqCR26v6UR9sIFyb6PS+5rPUs/mXgnBR/QQCW7RkyjSCMoQA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@lezer/common": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nightwatch/chai": {
|
"node_modules/@nightwatch/chai": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@nightwatch/chai/-/chai-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@nightwatch/chai/-/chai-5.0.2.tgz",
|
||||||
|
@ -5059,6 +5142,12 @@
|
||||||
"sha.js": "^2.4.8"
|
"sha.js": "^2.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crelt": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
|
@ -14244,6 +14333,12 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/style-mod": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
@ -14982,6 +15077,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/vkbeautify/-/vkbeautify-0.99.3.tgz",
|
"resolved": "https://registry.npmjs.org/vkbeautify/-/vkbeautify-0.99.3.tgz",
|
||||||
"integrity": "sha512-2ozZEFfmVvQcHWoHLNuiKlUfDKlhh4KGsy54U0UrlLMR1SO+XKAIDqBxtBwHgNrekurlJwE8A9K6L49T78ZQ9Q=="
|
"integrity": "sha512-2ozZEFfmVvQcHWoHLNuiKlUfDKlhh4KGsy54U0UrlLMR1SO+XKAIDqBxtBwHgNrekurlJwE8A9K6L49T78ZQ9Q=="
|
||||||
},
|
},
|
||||||
|
"node_modules/w3c-keyname": {
|
||||||
|
"version": "2.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
|
||||||
|
"integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
|
||||||
|
@ -17001,6 +17102,60 @@
|
||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@codemirror/commands": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-nVJDPiCQXWXj5AZxqNVXyIM3nOYauF4Dko9NGPSwgVdK+lXWJQhI5LGhS/AvdG5b7u7/pTQBkrQmzkLWRBF62A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"@lezer/common": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@codemirror/language": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-CeqY80nvUFrJcXcBW115aNi06D0PS8NSW6nuJRSwbrYFkE0SfJnPfyLGrcM90AV95lqg5+4xUi99BCmzNaPGJg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"@lezer/common": "^1.0.0",
|
||||||
|
"@lezer/highlight": "^1.0.0",
|
||||||
|
"@lezer/lr": "^1.0.0",
|
||||||
|
"style-mod": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@codemirror/search": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-rL0rd3AhI0TAsaJPUaEwC63KHLO7KL0Z/dYozXj6E7L3wNHRyx7RfE0/j5HsIf912EE5n2PCb4Vg0rGYmDv4UQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"crelt": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@codemirror/state": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-6vYgaXc4KjSY0BUfSVDJooGcoswg/RJZpq/ZGjsUYmY0KN1lmB8u03nv+jiG1ncUV5qoggyxFT5AGD5Ak+5Zrw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@codemirror/view": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-mnVT/q1JvKPjpmjXJNeCi/xHyaJ3abGJsumIVpdQ1nE1MXAyHf7GHWt8QpWMUvDiqF0j+inkhVR2OviTdFFX7Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"style-mod": "^4.0.0",
|
||||||
|
"w3c-keyname": "^2.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@colors/colors": {
|
"@colors/colors": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
|
||||||
|
@ -17452,6 +17607,30 @@
|
||||||
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
|
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@lezer/common": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@lezer/highlight": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-nsCnNtim90UKsB5YxoX65v3GEIw3iCHw9RM2DtdgkiqAbKh9pCdvi8AWNwkYf10Lu6fxNhXPpkpHbW6mihhvJA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@lezer/common": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@lezer/lr": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-k6DEqBh4HxqO/cVGedb6Ern6LS7K6IOzfydJ5WaqCR26v6UR9sIFyb6PS+5rPUs/mXgnBR/QQCW7RkyjSCMoQA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@lezer/common": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@nightwatch/chai": {
|
"@nightwatch/chai": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@nightwatch/chai/-/chai-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@nightwatch/chai/-/chai-5.0.2.tgz",
|
||||||
|
@ -19640,6 +19819,12 @@
|
||||||
"sha.js": "^2.4.8"
|
"sha.js": "^2.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"crelt": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
|
@ -26720,6 +26905,12 @@
|
||||||
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"style-mod": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
@ -27303,6 +27494,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/vkbeautify/-/vkbeautify-0.99.3.tgz",
|
"resolved": "https://registry.npmjs.org/vkbeautify/-/vkbeautify-0.99.3.tgz",
|
||||||
"integrity": "sha512-2ozZEFfmVvQcHWoHLNuiKlUfDKlhh4KGsy54U0UrlLMR1SO+XKAIDqBxtBwHgNrekurlJwE8A9K6L49T78ZQ9Q=="
|
"integrity": "sha512-2ozZEFfmVvQcHWoHLNuiKlUfDKlhh4KGsy54U0UrlLMR1SO+XKAIDqBxtBwHgNrekurlJwE8A9K6L49T78ZQ9Q=="
|
||||||
},
|
},
|
||||||
|
"w3c-keyname": {
|
||||||
|
"version": "2.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
|
||||||
|
"integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"watchpack": {
|
"watchpack": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
|
||||||
|
|
|
@ -45,6 +45,11 @@
|
||||||
"@babel/plugin-transform-runtime": "^7.18.2",
|
"@babel/plugin-transform-runtime": "^7.18.2",
|
||||||
"@babel/preset-env": "^7.18.2",
|
"@babel/preset-env": "^7.18.2",
|
||||||
"@babel/runtime": "^7.18.3",
|
"@babel/runtime": "^7.18.3",
|
||||||
|
"@codemirror/commands": "^6.0.0",
|
||||||
|
"@codemirror/language": "^6.1.0",
|
||||||
|
"@codemirror/search": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.1",
|
||||||
|
"@codemirror/view": "^6.0.2",
|
||||||
"autoprefixer": "^10.4.7",
|
"autoprefixer": "^10.4.7",
|
||||||
"babel-loader": "^8.2.5",
|
"babel-loader": "^8.2.5",
|
||||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||||
|
|
|
@ -112,7 +112,7 @@ CMYK: ${cmyk}
|
||||||
useAlpha: true
|
useAlpha: true
|
||||||
}).on('colorpickerChange', function(e) {
|
}).on('colorpickerChange', function(e) {
|
||||||
var color = e.color.string('rgba');
|
var color = e.color.string('rgba');
|
||||||
document.getElementById('input-text').value = color;
|
window.app.manager.input.setInput(color);
|
||||||
window.app.manager.input.debounceInputChange(new Event("keyup"));
|
window.app.manager.input.debounceInputChange(new Event("keyup"));
|
||||||
});
|
});
|
||||||
</script>`;
|
</script>`;
|
||||||
|
|
|
@ -146,8 +146,7 @@ class Manager {
|
||||||
this.addDynamicListener("textarea.arg", "drop", this.recipe.textArgDrop, this.recipe);
|
this.addDynamicListener("textarea.arg", "drop", this.recipe.textArgDrop, this.recipe);
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
this.addMultiEventListener("#input-text", "keyup", this.input.debounceInputChange, this.input);
|
document.getElementById("input-text").addEventListener("keyup", this.input.debounceInputChange.bind(this.input));
|
||||||
this.addMultiEventListener("#input-text", "paste", this.input.inputPaste, this.input);
|
|
||||||
document.getElementById("reset-layout").addEventListener("click", this.app.resetLayout.bind(this.app));
|
document.getElementById("reset-layout").addEventListener("click", this.app.resetLayout.bind(this.app));
|
||||||
this.addListeners("#clr-io,#btn-close-all-tabs", "click", this.input.clearAllIoClick, this.input);
|
this.addListeners("#clr-io,#btn-close-all-tabs", "click", this.input.clearAllIoClick, this.input);
|
||||||
this.addListeners("#open-file,#open-folder", "change", this.input.inputOpen, this.input);
|
this.addListeners("#open-file,#open-folder", "change", this.input.inputOpen, this.input);
|
||||||
|
@ -179,6 +178,7 @@ class Manager {
|
||||||
this.addDynamicListener(".input-filter-result", "click", this.input.filterItemClick, this.input);
|
this.addDynamicListener(".input-filter-result", "click", this.input.filterItemClick, this.input);
|
||||||
document.getElementById("btn-open-file").addEventListener("click", this.input.inputOpenClick.bind(this.input));
|
document.getElementById("btn-open-file").addEventListener("click", this.input.inputOpenClick.bind(this.input));
|
||||||
document.getElementById("btn-open-folder").addEventListener("click", this.input.folderOpenClick.bind(this.input));
|
document.getElementById("btn-open-folder").addEventListener("click", this.input.folderOpenClick.bind(this.input));
|
||||||
|
this.addDynamicListener(".eol-select a", "click", this.input.eolSelectClick, this.input);
|
||||||
|
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
|
|
190
src/web/extensions/statusBar.mjs
Normal file
190
src/web/extensions/statusBar.mjs
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
/**
|
||||||
|
* A Status bar extension for CodeMirror
|
||||||
|
*
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2022
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {showPanel} from "@codemirror/view";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the stats of a document
|
||||||
|
* @param {element} el
|
||||||
|
* @param {Text} doc
|
||||||
|
*/
|
||||||
|
function updateStats(el, doc) {
|
||||||
|
const length = el.querySelector("#stats-length-value"),
|
||||||
|
lines = el.querySelector("#stats-lines-value");
|
||||||
|
length.textContent = doc.length;
|
||||||
|
lines.textContent = doc.lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current selection info
|
||||||
|
* @param {element} el
|
||||||
|
* @param {EditorState} state
|
||||||
|
* @param {boolean} selectionSet
|
||||||
|
*/
|
||||||
|
function updateSelection(el, state, selectionSet) {
|
||||||
|
const selLen = state.selection && state.selection.main ?
|
||||||
|
state.selection.main.to - state.selection.main.from :
|
||||||
|
0;
|
||||||
|
|
||||||
|
const selInfo = el.querySelector("#sel-info"),
|
||||||
|
curOffsetInfo = el.querySelector("#cur-offset-info");
|
||||||
|
|
||||||
|
if (!selectionSet) {
|
||||||
|
selInfo.style.display = "none";
|
||||||
|
curOffsetInfo.style.display = "none";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selLen > 0) { // Range
|
||||||
|
const start = el.querySelector("#sel-start-value"),
|
||||||
|
end = el.querySelector("#sel-end-value"),
|
||||||
|
length = el.querySelector("#sel-length-value");
|
||||||
|
|
||||||
|
selInfo.style.display = "inline-block";
|
||||||
|
curOffsetInfo.style.display = "none";
|
||||||
|
|
||||||
|
start.textContent = state.selection.main.from;
|
||||||
|
end.textContent = state.selection.main.to;
|
||||||
|
length.textContent = state.selection.main.to - state.selection.main.from;
|
||||||
|
} else { // Position
|
||||||
|
const offset = el.querySelector("#cur-offset-value");
|
||||||
|
|
||||||
|
selInfo.style.display = "none";
|
||||||
|
curOffsetInfo.style.display = "inline-block";
|
||||||
|
|
||||||
|
offset.textContent = state.selection.main.from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current character encoding of the document
|
||||||
|
* @param {element} el
|
||||||
|
* @param {EditorState} state
|
||||||
|
*/
|
||||||
|
function updateCharEnc(el, state) {
|
||||||
|
// const charenc = el.querySelector("#char-enc-value");
|
||||||
|
// TODO
|
||||||
|
// charenc.textContent = "TODO";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns what the current EOL separator is set to
|
||||||
|
* @param {element} el
|
||||||
|
* @param {EditorState} state
|
||||||
|
*/
|
||||||
|
function updateEOL(el, state) {
|
||||||
|
const eolLookup = {
|
||||||
|
"\u000a": "LF",
|
||||||
|
"\u000b": "VT",
|
||||||
|
"\u000c": "FF",
|
||||||
|
"\u000d": "CR",
|
||||||
|
"\u000d\u000a": "CRLF",
|
||||||
|
"\u0085": "NEL",
|
||||||
|
"\u2028": "LS",
|
||||||
|
"\u2029": "PS"
|
||||||
|
};
|
||||||
|
|
||||||
|
const val = el.querySelector("#eol-value");
|
||||||
|
val.textContent = eolLookup[state.lineBreak];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the Left-hand-side widgets
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function constructLHS() {
|
||||||
|
return `<span data-toggle="tooltip" title="Input length">
|
||||||
|
<i class="material-icons">abc</i>
|
||||||
|
<span id="stats-length-value"></span>
|
||||||
|
</span>
|
||||||
|
<span data-toggle="tooltip" title="Number of lines">
|
||||||
|
<i class="material-icons">sort</i>
|
||||||
|
<span id="stats-lines-value"></span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span id="sel-info" data-toggle="tooltip" title="Selection">
|
||||||
|
<i class="material-icons">highlight_alt</i>
|
||||||
|
<span id="sel-start-value"></span>\u279E<span id="sel-end-value"></span>
|
||||||
|
(<span id="sel-length-value"></span> selected)
|
||||||
|
</span>
|
||||||
|
<span id="cur-offset-info" data-toggle="tooltip" title="Cursor offset">
|
||||||
|
<i class="material-icons">location_on</i>
|
||||||
|
<span id="cur-offset-value"></span>
|
||||||
|
</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the Right-hand-side widgets
|
||||||
|
* Event listener set up in Manager
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function constructRHS() {
|
||||||
|
return `<span data-toggle="tooltip" title="Input character encoding">
|
||||||
|
<i class="material-icons">language</i>
|
||||||
|
<span id="char-enc-value">UTF-16</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="cm-status-bar-select eol-select">
|
||||||
|
<span class="cm-status-bar-select-btn" data-toggle="tooltip" data-placement="bottom" title="End of line sequence">
|
||||||
|
<i class="material-icons">keyboard_return</i> <span id="eol-value"></span>
|
||||||
|
</span>
|
||||||
|
<div class="cm-status-bar-select-content">
|
||||||
|
<a href="#" data-val="LF">Line Feed, U+000A</a>
|
||||||
|
<a href="#" data-val="VT">Vertical Tab, U+000B</a>
|
||||||
|
<a href="#" data-val="FF">Form Feed, U+000C</a>
|
||||||
|
<a href="#" data-val="CR">Carriage Return, U+000D</a>
|
||||||
|
<a href="#" data-val="CRLF">CR+LF, U+000D U+000A</a>
|
||||||
|
<!-- <a href="#" data-val="NL">Next Line, U+0085</a> This causes problems. -->
|
||||||
|
<a href="#" data-val="LS">Line Separator, U+2028</a>
|
||||||
|
<a href="#" data-val="PS">Paragraph Separator, U+2029</a>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A panel constructor building a panel that re-counts the stats every time the document changes.
|
||||||
|
* @param {EditorView} view
|
||||||
|
* @returns {Panel}
|
||||||
|
*/
|
||||||
|
function wordCountPanel(view) {
|
||||||
|
const dom = document.createElement("div");
|
||||||
|
const lhs = document.createElement("div");
|
||||||
|
const rhs = document.createElement("div");
|
||||||
|
|
||||||
|
dom.className = "cm-status-bar";
|
||||||
|
lhs.innerHTML = constructLHS();
|
||||||
|
rhs.innerHTML = constructRHS();
|
||||||
|
|
||||||
|
dom.appendChild(lhs);
|
||||||
|
dom.appendChild(rhs);
|
||||||
|
|
||||||
|
updateEOL(rhs, view.state);
|
||||||
|
updateCharEnc(rhs, view.state);
|
||||||
|
updateStats(lhs, view.state.doc);
|
||||||
|
updateSelection(lhs, view.state, false);
|
||||||
|
|
||||||
|
return {
|
||||||
|
dom,
|
||||||
|
update(update) {
|
||||||
|
updateEOL(rhs, update.state);
|
||||||
|
updateSelection(lhs, update.state, update.selectionSet);
|
||||||
|
updateCharEnc(rhs, update.state);
|
||||||
|
if (update.docChanged) {
|
||||||
|
updateStats(lhs, update.state.doc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function that build the extension that enables the panel in an editor.
|
||||||
|
* @returns {Extension}
|
||||||
|
*/
|
||||||
|
export function statusBar() {
|
||||||
|
return showPanel.of(wordCountPanel);
|
||||||
|
}
|
|
@ -219,8 +219,6 @@
|
||||||
<label for="input-text">Input</label>
|
<label for="input-text">Input</label>
|
||||||
<span class="pane-controls">
|
<span class="pane-controls">
|
||||||
<div class="io-info" id="input-files-info"></div>
|
<div class="io-info" id="input-files-info"></div>
|
||||||
<div class="io-info" id="input-selection-info"></div>
|
|
||||||
<div class="io-info" id="input-info"></div>
|
|
||||||
<button type="button" class="btn btn-primary bmd-btn-icon" id="btn-new-tab" data-toggle="tooltip" title="Add a new input tab">
|
<button type="button" class="btn btn-primary bmd-btn-icon" id="btn-new-tab" data-toggle="tooltip" title="Add a new input tab">
|
||||||
<i class="material-icons">add</i>
|
<i class="material-icons">add</i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -267,7 +265,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="textarea-wrapper no-select input-wrapper" id="input-wrapper">
|
<div class="textarea-wrapper no-select input-wrapper" id="input-wrapper">
|
||||||
<div id="input-highlighter" class="no-select"></div>
|
<div id="input-highlighter" class="no-select"></div>
|
||||||
<textarea id="input-text" class="input-text" spellcheck="false" tabindex="1" autofocus></textarea>
|
<div id="input-text"></div>
|
||||||
<div class="input-file" id="input-file">
|
<div class="input-file" id="input-file">
|
||||||
<div class="file-overlay" id="file-overlay"></div>
|
<div class="file-overlay" id="file-overlay"></div>
|
||||||
<div style="position: relative; height: 100%;">
|
<div style="position: relative; height: 100%;">
|
||||||
|
|
BIN
src/web/static/fonts/MaterialIcons-Regular.ttf
Normal file
BIN
src/web/static/fonts/MaterialIcons-Regular.ttf
Normal file
Binary file not shown.
Binary file not shown.
|
@ -6,7 +6,24 @@
|
||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#input-text,
|
#input-text {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-editor {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-editor .cm-content {
|
||||||
|
font-family: var(--fixed-width-font-family);
|
||||||
|
font-size: var(--fixed-width-font-size);
|
||||||
|
color: var(--fixed-width-font-colour);
|
||||||
|
}
|
||||||
|
|
||||||
#output-text,
|
#output-text,
|
||||||
#output-html {
|
#output-html {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -163,14 +180,14 @@
|
||||||
|
|
||||||
#input-wrapper,
|
#input-wrapper,
|
||||||
#output-wrapper,
|
#output-wrapper,
|
||||||
#input-wrapper > * ,
|
#input-wrapper > :not(#input-text),
|
||||||
#output-wrapper > .textarea-wrapper > div,
|
#output-wrapper > .textarea-wrapper > div,
|
||||||
#output-wrapper > .textarea-wrapper > textarea {
|
#output-wrapper > .textarea-wrapper > textarea {
|
||||||
height: calc(100% - var(--title-height));
|
height: calc(100% - var(--title-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
#input-wrapper.show-tabs,
|
#input-wrapper.show-tabs,
|
||||||
#input-wrapper.show-tabs > *,
|
#input-wrapper.show-tabs > :not(#input-text),
|
||||||
#output-wrapper.show-tabs,
|
#output-wrapper.show-tabs,
|
||||||
#output-wrapper.show-tabs > .textarea-wrapper > div,
|
#output-wrapper.show-tabs > .textarea-wrapper > div,
|
||||||
#output-wrapper.show-tabs > .textarea-wrapper > textarea {
|
#output-wrapper.show-tabs > .textarea-wrapper > textarea {
|
||||||
|
@ -193,7 +210,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.textarea-wrapper textarea,
|
.textarea-wrapper textarea,
|
||||||
.textarea-wrapper>div {
|
.textarea-wrapper #output-text,
|
||||||
|
.textarea-wrapper #output-html,
|
||||||
|
.textarea-wrapper #output-highlighter {
|
||||||
font-family: var(--fixed-width-font-family);
|
font-family: var(--fixed-width-font-family);
|
||||||
font-size: var(--fixed-width-font-size);
|
font-size: var(--fixed-width-font-size);
|
||||||
color: var(--fixed-width-font-colour);
|
color: var(--fixed-width-font-colour);
|
||||||
|
@ -292,10 +311,6 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#input-info {
|
|
||||||
line-height: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropping-file {
|
.dropping-file {
|
||||||
border: 5px dashed var(--drop-file-border-colour) !important;
|
border: 5px dashed var(--drop-file-border-colour) !important;
|
||||||
}
|
}
|
||||||
|
@ -458,3 +473,73 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
filter: brightness(98%);
|
filter: brightness(98%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Status bar */
|
||||||
|
|
||||||
|
.cm-status-bar {
|
||||||
|
font-family: var(--fixed-width-font-family);
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 8pt;
|
||||||
|
margin: 0 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-status-bar i {
|
||||||
|
font-size: 12pt;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
.cm-status-bar>div>span:first-child i {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropup Button */
|
||||||
|
.cm-status-bar-select-btn {
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The container <div> - needed to position the dropup content */
|
||||||
|
.cm-status-bar-select {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropup content (Hidden by Default) */
|
||||||
|
.cm-status-bar-select-content {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 0;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
min-width: 200px;
|
||||||
|
box-shadow: 0px 4px 4px 0px rgba(0,0,0,0.2);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links inside the dropup */
|
||||||
|
.cm-status-bar-select-content a {
|
||||||
|
color: black;
|
||||||
|
padding: 2px 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change color of dropup links on hover */
|
||||||
|
.cm-status-bar-select-content a:hover {
|
||||||
|
background-color: #ddd
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show the dropup menu on hover */
|
||||||
|
.cm-status-bar-select:hover .cm-status-bar-select-content {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change the background color of the dropup button when the dropup content is shown */
|
||||||
|
.cm-status-bar-select:hover .cm-status-bar-select-btn {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
font-family: 'Material Icons';
|
font-family: 'Material Icons';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: url("../static/fonts/MaterialIcons-Regular.woff2") format('woff2');
|
src: url("../static/fonts/MaterialIcons-Regular.ttf") format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.material-icons {
|
.material-icons {
|
||||||
|
|
|
@ -140,7 +140,7 @@ class ControlsWaiter {
|
||||||
|
|
||||||
const params = [
|
const params = [
|
||||||
includeRecipe ? ["recipe", recipeStr] : undefined,
|
includeRecipe ? ["recipe", recipeStr] : undefined,
|
||||||
includeInput ? ["input", Utils.escapeHtml(input)] : undefined,
|
includeInput && input.length ? ["input", Utils.escapeHtml(input)] : undefined,
|
||||||
];
|
];
|
||||||
|
|
||||||
const hash = params
|
const hash = params
|
||||||
|
|
|
@ -155,12 +155,11 @@ class HighlighterWaiter {
|
||||||
this.mouseTarget = INPUT;
|
this.mouseTarget = INPUT;
|
||||||
this.removeHighlights();
|
this.removeHighlights();
|
||||||
|
|
||||||
const el = e.target;
|
const sel = document.getSelection();
|
||||||
const start = el.selectionStart;
|
const start = sel.baseOffset;
|
||||||
const end = el.selectionEnd;
|
const end = sel.extentOffset;
|
||||||
|
|
||||||
if (start !== 0 || end !== 0) {
|
if (start !== 0 || end !== 0) {
|
||||||
document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end);
|
|
||||||
this.highlightOutput([{start: start, end: end}]);
|
this.highlightOutput([{start: start, end: end}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,12 +247,11 @@ class HighlighterWaiter {
|
||||||
this.mouseTarget !== INPUT)
|
this.mouseTarget !== INPUT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const el = e.target;
|
const sel = document.getSelection();
|
||||||
const start = el.selectionStart;
|
const start = sel.baseOffset;
|
||||||
const end = el.selectionEnd;
|
const end = sel.extentOffset;
|
||||||
|
|
||||||
if (start !== 0 || end !== 0) {
|
if (start !== 0 || end !== 0) {
|
||||||
document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end);
|
|
||||||
this.highlightOutput([{start: start, end: end}]);
|
this.highlightOutput([{start: start, end: end}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,7 +326,6 @@ class HighlighterWaiter {
|
||||||
removeHighlights() {
|
removeHighlights() {
|
||||||
document.getElementById("input-highlighter").innerHTML = "";
|
document.getElementById("input-highlighter").innerHTML = "";
|
||||||
document.getElementById("output-highlighter").innerHTML = "";
|
document.getElementById("output-highlighter").innerHTML = "";
|
||||||
document.getElementById("input-selection-info").innerHTML = "";
|
|
||||||
document.getElementById("output-selection-info").innerHTML = "";
|
document.getElementById("output-selection-info").innerHTML = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,19 @@
|
||||||
|
|
||||||
import LoaderWorker from "worker-loader?inline=no-fallback!../workers/LoaderWorker.js";
|
import LoaderWorker from "worker-loader?inline=no-fallback!../workers/LoaderWorker.js";
|
||||||
import InputWorker from "worker-loader?inline=no-fallback!../workers/InputWorker.mjs";
|
import InputWorker from "worker-loader?inline=no-fallback!../workers/InputWorker.mjs";
|
||||||
import Utils, { debounce } from "../../core/Utils.mjs";
|
import Utils, {debounce} from "../../core/Utils.mjs";
|
||||||
import { toBase64 } from "../../core/lib/Base64.mjs";
|
import {toBase64} from "../../core/lib/Base64.mjs";
|
||||||
import { isImage } from "../../core/lib/FileType.mjs";
|
import {isImage} from "../../core/lib/FileType.mjs";
|
||||||
|
|
||||||
|
import {
|
||||||
|
EditorView, keymap, highlightSpecialChars, drawSelection, rectangularSelection, crosshairCursor
|
||||||
|
} from "@codemirror/view";
|
||||||
|
import {EditorState, Compartment} from "@codemirror/state";
|
||||||
|
import {defaultKeymap, insertTab, insertNewline, history, historyKeymap} from "@codemirror/commands";
|
||||||
|
import {bracketMatching} from "@codemirror/language";
|
||||||
|
import {search, searchKeymap, highlightSelectionMatches} from "@codemirror/search";
|
||||||
|
|
||||||
|
import {statusBar} from "../extensions/statusBar.mjs";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,6 +37,9 @@ class InputWaiter {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
|
|
||||||
|
this.inputTextEl = document.getElementById("input-text");
|
||||||
|
this.initEditor();
|
||||||
|
|
||||||
// Define keys that don't change the input so we don't have to autobake when they are pressed
|
// Define keys that don't change the input so we don't have to autobake when they are pressed
|
||||||
this.badKeys = [
|
this.badKeys = [
|
||||||
16, // Shift
|
16, // Shift
|
||||||
|
@ -61,6 +74,135 @@ class InputWaiter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the CodeMirror Editor and returns the view
|
||||||
|
*/
|
||||||
|
initEditor() {
|
||||||
|
this.inputEditorConf = {
|
||||||
|
eol: new Compartment,
|
||||||
|
lineWrapping: new Compartment
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialState = EditorState.create({
|
||||||
|
doc: null,
|
||||||
|
extensions: [
|
||||||
|
history(),
|
||||||
|
highlightSpecialChars({render: this.renderSpecialChar}),
|
||||||
|
drawSelection(),
|
||||||
|
rectangularSelection(),
|
||||||
|
crosshairCursor(),
|
||||||
|
bracketMatching(),
|
||||||
|
highlightSelectionMatches(),
|
||||||
|
search({top: true}),
|
||||||
|
statusBar(this.inputEditorConf),
|
||||||
|
this.inputEditorConf.lineWrapping.of(EditorView.lineWrapping),
|
||||||
|
this.inputEditorConf.eol.of(EditorState.lineSeparator.of("\n")),
|
||||||
|
EditorState.allowMultipleSelections.of(true),
|
||||||
|
keymap.of([
|
||||||
|
// Explicitly insert a tab rather than indenting the line
|
||||||
|
{ key: "Tab", run: insertTab },
|
||||||
|
// Explicitly insert a new line (using the current EOL char) rather
|
||||||
|
// than messing around with indenting, which does not respect EOL chars
|
||||||
|
{ key: "Enter", run: insertNewline },
|
||||||
|
...historyKeymap,
|
||||||
|
...defaultKeymap,
|
||||||
|
...searchKeymap
|
||||||
|
]),
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
this.inputEditorView = new EditorView({
|
||||||
|
state: initialState,
|
||||||
|
parent: this.inputTextEl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for rendering special characters.
|
||||||
|
* Should mirror the toDOM function in
|
||||||
|
* https://github.com/codemirror/view/blob/main/src/special-chars.ts#L150
|
||||||
|
* But reverts the replacement of line feeds with newline control pictures.
|
||||||
|
* @param {number} code
|
||||||
|
* @param {string} desc
|
||||||
|
* @param {string} placeholder
|
||||||
|
* @returns {element}
|
||||||
|
*/
|
||||||
|
renderSpecialChar(code, desc, placeholder) {
|
||||||
|
const s = document.createElement("span");
|
||||||
|
// CodeMirror changes 0x0a to "NL" instead of "LF". We change it back.
|
||||||
|
s.textContent = code === 0x0a ? "\u240a" : placeholder;
|
||||||
|
s.title = desc;
|
||||||
|
s.setAttribute("aria-label", desc);
|
||||||
|
s.className = "cm-specialChar";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for EOL Select clicks
|
||||||
|
* Sets the line separator
|
||||||
|
* @param {Event} e
|
||||||
|
*/
|
||||||
|
eolSelectClick(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const eolLookup = {
|
||||||
|
"LF": "\u000a",
|
||||||
|
"VT": "\u000b",
|
||||||
|
"FF": "\u000c",
|
||||||
|
"CR": "\u000d",
|
||||||
|
"CRLF": "\u000d\u000a",
|
||||||
|
"NEL": "\u0085",
|
||||||
|
"LS": "\u2028",
|
||||||
|
"PS": "\u2029"
|
||||||
|
};
|
||||||
|
const eolval = eolLookup[e.target.getAttribute("data-val")];
|
||||||
|
const oldInputVal = this.getInput();
|
||||||
|
|
||||||
|
// Update the EOL value
|
||||||
|
this.inputEditorView.dispatch({
|
||||||
|
effects: this.inputEditorConf.eol.reconfigure(EditorState.lineSeparator.of(eolval))
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset the input so that lines are recalculated, preserving the old EOL values
|
||||||
|
this.setInput(oldInputVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets word wrap on the input editor
|
||||||
|
* @param {boolean} wrap
|
||||||
|
*/
|
||||||
|
setWordWrap(wrap) {
|
||||||
|
this.inputEditorView.dispatch({
|
||||||
|
effects: this.inputEditorConf.lineWrapping.reconfigure(
|
||||||
|
wrap ? EditorView.lineWrapping : []
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of the current input
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
getInput() {
|
||||||
|
const doc = this.inputEditorView.state.doc;
|
||||||
|
const eol = this.inputEditorView.state.lineBreak;
|
||||||
|
return doc.sliceString(0, doc.length, eol);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the current input
|
||||||
|
* @param {string} data
|
||||||
|
*/
|
||||||
|
setInput(data) {
|
||||||
|
this.inputEditorView.dispatch({
|
||||||
|
changes: {
|
||||||
|
from: 0,
|
||||||
|
to: this.inputEditorView.state.doc.length,
|
||||||
|
insert: data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the maximum number of tabs to display
|
* Calculates the maximum number of tabs to display
|
||||||
*/
|
*/
|
||||||
|
@ -339,10 +481,8 @@ class InputWaiter {
|
||||||
const activeTab = this.manager.tabs.getActiveInputTab();
|
const activeTab = this.manager.tabs.getActiveInputTab();
|
||||||
if (inputData.inputNum !== activeTab) return;
|
if (inputData.inputNum !== activeTab) return;
|
||||||
|
|
||||||
const inputText = document.getElementById("input-text");
|
|
||||||
|
|
||||||
if (typeof inputData.input === "string") {
|
if (typeof inputData.input === "string") {
|
||||||
inputText.value = inputData.input;
|
this.setInput(inputData.input);
|
||||||
const fileOverlay = document.getElementById("input-file"),
|
const fileOverlay = document.getElementById("input-file"),
|
||||||
fileName = document.getElementById("input-file-name"),
|
fileName = document.getElementById("input-file-name"),
|
||||||
fileSize = document.getElementById("input-file-size"),
|
fileSize = document.getElementById("input-file-size"),
|
||||||
|
@ -355,17 +495,11 @@ class InputWaiter {
|
||||||
fileType.textContent = "";
|
fileType.textContent = "";
|
||||||
fileLoaded.textContent = "";
|
fileLoaded.textContent = "";
|
||||||
|
|
||||||
inputText.style.overflow = "auto";
|
this.inputTextEl.classList.remove("blur");
|
||||||
inputText.classList.remove("blur");
|
|
||||||
inputText.scroll(0, 0);
|
|
||||||
|
|
||||||
const lines = inputData.input.length < (this.app.options.ioDisplayThreshold * 1024) ?
|
|
||||||
inputData.input.count("\n") + 1 : null;
|
|
||||||
this.setInputInfo(inputData.input.length, lines);
|
|
||||||
|
|
||||||
// Set URL to current input
|
// Set URL to current input
|
||||||
const inputStr = toBase64(inputData.input, "A-Za-z0-9+/");
|
const inputStr = toBase64(inputData.input, "A-Za-z0-9+/");
|
||||||
if (inputStr.length > 0 && inputStr.length <= 68267) {
|
if (inputStr.length >= 0 && inputStr.length <= 68267) {
|
||||||
this.setUrl({
|
this.setUrl({
|
||||||
includeInput: true,
|
includeInput: true,
|
||||||
input: inputStr
|
input: inputStr
|
||||||
|
@ -414,7 +548,6 @@ class InputWaiter {
|
||||||
fileLoaded.textContent = inputData.progress + "%";
|
fileLoaded.textContent = inputData.progress + "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setInputInfo(inputData.size, null);
|
|
||||||
this.displayFilePreview(inputData);
|
this.displayFilePreview(inputData);
|
||||||
|
|
||||||
if (!silent) window.dispatchEvent(this.manager.statechange);
|
if (!silent) window.dispatchEvent(this.manager.statechange);
|
||||||
|
@ -488,12 +621,10 @@ class InputWaiter {
|
||||||
*/
|
*/
|
||||||
displayFilePreview(inputData) {
|
displayFilePreview(inputData) {
|
||||||
const activeTab = this.manager.tabs.getActiveInputTab(),
|
const activeTab = this.manager.tabs.getActiveInputTab(),
|
||||||
input = inputData.input,
|
input = inputData.input;
|
||||||
inputText = document.getElementById("input-text");
|
|
||||||
if (inputData.inputNum !== activeTab) return;
|
if (inputData.inputNum !== activeTab) return;
|
||||||
inputText.style.overflow = "hidden";
|
this.inputTextEl.classList.add("blur");
|
||||||
inputText.classList.add("blur");
|
this.setInput(Utils.arrayBufferToStr(input.slice(0, 4096)));
|
||||||
inputText.value = Utils.printable(Utils.arrayBufferToStr(input.slice(0, 4096)));
|
|
||||||
|
|
||||||
this.renderFileThumb();
|
this.renderFileThumb();
|
||||||
|
|
||||||
|
@ -576,7 +707,7 @@ class InputWaiter {
|
||||||
*/
|
*/
|
||||||
async getInputValue(inputNum) {
|
async getInputValue(inputNum) {
|
||||||
return await new Promise(resolve => {
|
return await new Promise(resolve => {
|
||||||
this.getInput(inputNum, false, r => {
|
this.getInputFromWorker(inputNum, false, r => {
|
||||||
resolve(r.data);
|
resolve(r.data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -590,7 +721,7 @@ class InputWaiter {
|
||||||
*/
|
*/
|
||||||
async getInputObj(inputNum) {
|
async getInputObj(inputNum) {
|
||||||
return await new Promise(resolve => {
|
return await new Promise(resolve => {
|
||||||
this.getInput(inputNum, true, r => {
|
this.getInputFromWorker(inputNum, true, r => {
|
||||||
resolve(r.data);
|
resolve(r.data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -604,7 +735,7 @@ class InputWaiter {
|
||||||
* @param {Function} callback - The callback to execute when the input is returned
|
* @param {Function} callback - The callback to execute when the input is returned
|
||||||
* @returns {ArrayBuffer | string | object}
|
* @returns {ArrayBuffer | string | object}
|
||||||
*/
|
*/
|
||||||
getInput(inputNum, getObj, callback) {
|
getInputFromWorker(inputNum, getObj, callback) {
|
||||||
const id = this.callbackID++;
|
const id = this.callbackID++;
|
||||||
|
|
||||||
this.callbacks[id] = callback;
|
this.callbacks[id] = callback;
|
||||||
|
@ -647,29 +778,6 @@ class InputWaiter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays information about the input.
|
|
||||||
*
|
|
||||||
* @param {number} length - The length of the current input string
|
|
||||||
* @param {number} lines - The number of the lines in the current input string
|
|
||||||
*/
|
|
||||||
setInputInfo(length, lines) {
|
|
||||||
let width = length.toString().length.toLocaleString();
|
|
||||||
width = width < 2 ? 2 : width;
|
|
||||||
|
|
||||||
const lengthStr = length.toString().padStart(width, " ").replace(/ /g, " ");
|
|
||||||
let msg = "length: " + lengthStr;
|
|
||||||
|
|
||||||
if (typeof lines === "number") {
|
|
||||||
const linesStr = lines.toString().padStart(width, " ").replace(/ /g, " ");
|
|
||||||
msg += "<br>lines: " + linesStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("input-info").innerHTML = msg;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for input change events.
|
* Handler for input change events.
|
||||||
* Debounces the input so we don't call autobake too often.
|
* Debounces the input so we don't call autobake too often.
|
||||||
|
@ -696,17 +804,13 @@ class InputWaiter {
|
||||||
// Remove highlighting from input and output panes as the offsets might be different now
|
// Remove highlighting from input and output panes as the offsets might be different now
|
||||||
this.manager.highlighter.removeHighlights();
|
this.manager.highlighter.removeHighlights();
|
||||||
|
|
||||||
const textArea = document.getElementById("input-text");
|
const value = this.getInput();
|
||||||
const value = (textArea.value !== undefined) ? textArea.value : "";
|
|
||||||
const activeTab = this.manager.tabs.getActiveInputTab();
|
const activeTab = this.manager.tabs.getActiveInputTab();
|
||||||
|
|
||||||
this.app.progress = 0;
|
this.app.progress = 0;
|
||||||
|
|
||||||
const lines = value.length < (this.app.options.ioDisplayThreshold * 1024) ?
|
|
||||||
(value.count("\n") + 1) : null;
|
|
||||||
this.setInputInfo(value.length, lines);
|
|
||||||
this.updateInputValue(activeTab, value);
|
this.updateInputValue(activeTab, value);
|
||||||
this.manager.tabs.updateInputTabHeader(activeTab, value.replace(/[\n\r]/g, "").slice(0, 100));
|
this.manager.tabs.updateInputTabHeader(activeTab, value.slice(0, 100).replace(/[\n\r]/g, ""));
|
||||||
|
|
||||||
if (e && this.badKeys.indexOf(e.keyCode) < 0) {
|
if (e && this.badKeys.indexOf(e.keyCode) < 0) {
|
||||||
// Fire the statechange event as the input has been modified
|
// Fire the statechange event as the input has been modified
|
||||||
|
@ -714,62 +818,6 @@ class InputWaiter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for input paste events
|
|
||||||
* Checks that the size of the input is below the display limit, otherwise treats it as a file/blob
|
|
||||||
*
|
|
||||||
* @param {event} e
|
|
||||||
*/
|
|
||||||
async inputPaste(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
const self = this;
|
|
||||||
/**
|
|
||||||
* Triggers the input file/binary data overlay
|
|
||||||
*
|
|
||||||
* @param {string} pastedData
|
|
||||||
*/
|
|
||||||
function triggerOverlay(pastedData) {
|
|
||||||
const file = new File([pastedData], "PastedData", {
|
|
||||||
type: "text/plain",
|
|
||||||
lastModified: Date.now()
|
|
||||||
});
|
|
||||||
|
|
||||||
self.loadUIFiles([file]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const pastedData = e.clipboardData.getData("Text");
|
|
||||||
const inputText = document.getElementById("input-text");
|
|
||||||
const selStart = inputText.selectionStart;
|
|
||||||
const selEnd = inputText.selectionEnd;
|
|
||||||
const startVal = inputText.value.slice(0, selStart);
|
|
||||||
const endVal = inputText.value.slice(selEnd);
|
|
||||||
const val = startVal + pastedData + endVal;
|
|
||||||
|
|
||||||
if (val.length >= (this.app.options.ioDisplayThreshold * 1024)) {
|
|
||||||
// Data too large to display, use overlay
|
|
||||||
triggerOverlay(val);
|
|
||||||
return false;
|
|
||||||
} else if (await this.preserveCarriageReturns(val)) {
|
|
||||||
// Data contains a carriage return and the user doesn't wish to edit it, use overlay
|
|
||||||
// We check this in a separate condition to make sure it is not run unless absolutely
|
|
||||||
// necessary.
|
|
||||||
triggerOverlay(val);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// Pasting normally fires the inputChange() event before
|
|
||||||
// changing the value, so instead change it here ourselves
|
|
||||||
// and manually fire inputChange()
|
|
||||||
inputText.value = val;
|
|
||||||
inputText.setSelectionRange(selStart + pastedData.length, selStart + pastedData.length);
|
|
||||||
// Don't debounce here otherwise the keyup event for the Ctrl key will cancel an autobake
|
|
||||||
// (at least for large inputs)
|
|
||||||
this.inputChange(e, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for input dragover events.
|
* Handler for input dragover events.
|
||||||
* Gives the user a visual cue to show that items can be dropped here.
|
* Gives the user a visual cue to show that items can be dropped here.
|
||||||
|
@ -818,7 +866,7 @@ class InputWaiter {
|
||||||
|
|
||||||
if (text) {
|
if (text) {
|
||||||
// Append the text to the current input and fire inputChange()
|
// Append the text to the current input and fire inputChange()
|
||||||
document.getElementById("input-text").value += text;
|
this.setInput(this.getInput() + text);
|
||||||
this.inputChange(e);
|
this.inputChange(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -843,44 +891,6 @@ class InputWaiter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if an input contains carriage returns.
|
|
||||||
* If a CR is detected, checks if the preserve CR option has been set,
|
|
||||||
* and if not, asks the user for their preference.
|
|
||||||
*
|
|
||||||
* @param {string} input - The input to be checked
|
|
||||||
* @returns {boolean} - If true, the input contains a CR which should be
|
|
||||||
* preserved, so display an overlay so it can't be edited
|
|
||||||
*/
|
|
||||||
async preserveCarriageReturns(input) {
|
|
||||||
if (input.indexOf("\r") < 0) return false;
|
|
||||||
|
|
||||||
const optionsStr = "This behaviour can be changed in the <a href='#' onclick='document.getElementById(\"options\").click()'>Options pane</a>";
|
|
||||||
const preserveStr = `A carriage return (\\r, 0x0d) was detected in your input. To preserve it, editing has been disabled.<br>${optionsStr}`;
|
|
||||||
const dontPreserveStr = `A carriage return (\\r, 0x0d) was detected in your input. It has not been preserved.<br>${optionsStr}`;
|
|
||||||
|
|
||||||
switch (this.app.options.preserveCR) {
|
|
||||||
case "always":
|
|
||||||
this.app.alert(preserveStr, 6000);
|
|
||||||
return true;
|
|
||||||
case "never":
|
|
||||||
this.app.alert(dontPreserveStr, 6000);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only preserve for high-entropy inputs
|
|
||||||
const data = Utils.strToArrayBuffer(input);
|
|
||||||
const entropy = Utils.calculateShannonEntropy(data);
|
|
||||||
|
|
||||||
if (entropy > 6) {
|
|
||||||
this.app.alert(preserveStr, 6000);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.app.alert(dontPreserveStr, 6000);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load files from the UI into the inputWorker
|
* Load files from the UI into the inputWorker
|
||||||
*
|
*
|
||||||
|
@ -1080,6 +1090,9 @@ class InputWaiter {
|
||||||
this.manager.worker.setupChefWorker();
|
this.manager.worker.setupChefWorker();
|
||||||
this.addInput(true);
|
this.addInput(true);
|
||||||
this.bakeAll();
|
this.bakeAll();
|
||||||
|
|
||||||
|
// Fire the statechange event as the input has been modified
|
||||||
|
window.dispatchEvent(this.manager.statechange);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -53,6 +53,9 @@ class OptionsWaiter {
|
||||||
selects[i].selectedIndex = 0;
|
selects[i].selectedIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialise options
|
||||||
|
this.setWordWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,14 +139,13 @@ class OptionsWaiter {
|
||||||
* Sets or unsets word wrap on the input and output depending on the wordWrap option value.
|
* Sets or unsets word wrap on the input and output depending on the wordWrap option value.
|
||||||
*/
|
*/
|
||||||
setWordWrap() {
|
setWordWrap() {
|
||||||
document.getElementById("input-text").classList.remove("word-wrap");
|
this.manager.input.setWordWrap(this.app.options.wordWrap);
|
||||||
document.getElementById("output-text").classList.remove("word-wrap");
|
document.getElementById("output-text").classList.remove("word-wrap");
|
||||||
document.getElementById("output-html").classList.remove("word-wrap");
|
document.getElementById("output-html").classList.remove("word-wrap");
|
||||||
document.getElementById("input-highlighter").classList.remove("word-wrap");
|
document.getElementById("input-highlighter").classList.remove("word-wrap");
|
||||||
document.getElementById("output-highlighter").classList.remove("word-wrap");
|
document.getElementById("output-highlighter").classList.remove("word-wrap");
|
||||||
|
|
||||||
if (!this.app.options.wordWrap) {
|
if (!this.app.options.wordWrap) {
|
||||||
document.getElementById("input-text").classList.add("word-wrap");
|
|
||||||
document.getElementById("output-text").classList.add("word-wrap");
|
document.getElementById("output-text").classList.add("word-wrap");
|
||||||
document.getElementById("output-html").classList.add("word-wrap");
|
document.getElementById("output-html").classList.add("word-wrap");
|
||||||
document.getElementById("input-highlighter").classList.add("word-wrap");
|
document.getElementById("input-highlighter").classList.add("word-wrap");
|
||||||
|
|
|
@ -1019,7 +1019,6 @@ class OutputWaiter {
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("output-info").innerHTML = msg;
|
document.getElementById("output-info").innerHTML = msg;
|
||||||
document.getElementById("input-selection-info").innerHTML = "";
|
|
||||||
document.getElementById("output-selection-info").innerHTML = "";
|
document.getElementById("output-selection-info").innerHTML = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1292,9 +1291,7 @@ class OutputWaiter {
|
||||||
if (this.outputs[activeTab].data.type === "string" &&
|
if (this.outputs[activeTab].data.type === "string" &&
|
||||||
active.byteLength <= this.app.options.ioDisplayThreshold * 1024) {
|
active.byteLength <= this.app.options.ioDisplayThreshold * 1024) {
|
||||||
const dishString = await this.getDishStr(this.getOutputDish(activeTab));
|
const dishString = await this.getDishStr(this.getOutputDish(activeTab));
|
||||||
if (!await this.manager.input.preserveCarriageReturns(dishString)) {
|
active = dishString;
|
||||||
active = dishString;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
transferable.push(active);
|
transferable.push(active);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ module.exports = {
|
||||||
// Enter input
|
// Enter input
|
||||||
browser
|
browser
|
||||||
.useCss()
|
.useCss()
|
||||||
.setValue("#input-text", "Don't Panic.")
|
.setValue("#input-text", "Don't Panic.") // TODO
|
||||||
.pause(1000)
|
.pause(1000)
|
||||||
.click("#bake");
|
.click("#bake");
|
||||||
|
|
||||||
|
|
|
@ -409,16 +409,16 @@ function bakeOp(browser, opName, input, args=[]) {
|
||||||
.click("#clr-recipe")
|
.click("#clr-recipe")
|
||||||
.click("#clr-io")
|
.click("#clr-io")
|
||||||
.waitForElementNotPresent("#rec-list li.operation")
|
.waitForElementNotPresent("#rec-list li.operation")
|
||||||
.expect.element("#input-text").to.have.property("value").that.equals("");
|
.expect.element("#input-text").to.have.property("value").that.equals(""); // TODO
|
||||||
|
|
||||||
browser
|
browser
|
||||||
.perform(function() {
|
.perform(function() {
|
||||||
console.log(`Current test: ${opName}`);
|
console.log(`Current test: ${opName}`);
|
||||||
})
|
})
|
||||||
.urlHash("recipe=" + recipeConfig)
|
.urlHash("recipe=" + recipeConfig)
|
||||||
.setValue("#input-text", input)
|
.setValue("#input-text", input) // TODO
|
||||||
.waitForElementPresent("#rec-list li.operation")
|
.waitForElementPresent("#rec-list li.operation")
|
||||||
.expect.element("#input-text").to.have.property("value").that.equals(input);
|
.expect.element("#input-text").to.have.property("value").that.equals(input); // TODO
|
||||||
|
|
||||||
browser
|
browser
|
||||||
.waitForElementVisible("#stale-indicator", 5000)
|
.waitForElementVisible("#stale-indicator", 5000)
|
||||||
|
|
Loading…
Reference in a new issue