diff --git a/package-lock.json b/package-lock.json index ffde1368..18759956 100644 --- a/package-lock.json +++ b/package-lock.json @@ -95,6 +95,11 @@ "@babel/plugin-transform-runtime": "^7.18.2", "@babel/preset-env": "^7.18.2", "@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", "babel-loader": "^8.2.5", "babel-plugin-dynamic-import-node": "^2.3.3", @@ -1782,6 +1787,60 @@ "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": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -2370,6 +2429,30 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "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": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@nightwatch/chai/-/chai-5.0.2.tgz", @@ -5059,6 +5142,12 @@ "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": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -14244,6 +14333,12 @@ "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": { "version": "5.5.0", "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", "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": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", @@ -17001,6 +17102,60 @@ "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": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -17452,6 +17607,30 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "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": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@nightwatch/chai/-/chai-5.0.2.tgz", @@ -19640,6 +19819,12 @@ "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": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -26720,6 +26905,12 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "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": { "version": "5.5.0", "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", "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": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", diff --git a/package.json b/package.json index cea3fb19..8e89248a 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,11 @@ "@babel/plugin-transform-runtime": "^7.18.2", "@babel/preset-env": "^7.18.2", "@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", "babel-loader": "^8.2.5", "babel-plugin-dynamic-import-node": "^2.3.3", diff --git a/src/core/operations/ParseColourCode.mjs b/src/core/operations/ParseColourCode.mjs index 9cf40ba7..045d8f05 100644 --- a/src/core/operations/ParseColourCode.mjs +++ b/src/core/operations/ParseColourCode.mjs @@ -112,7 +112,7 @@ CMYK: ${cmyk} useAlpha: true }).on('colorpickerChange', function(e) { 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")); }); `; diff --git a/src/web/Manager.mjs b/src/web/Manager.mjs index e1e07dfd..08a35d75 100755 --- a/src/web/Manager.mjs +++ b/src/web/Manager.mjs @@ -146,8 +146,7 @@ class Manager { this.addDynamicListener("textarea.arg", "drop", this.recipe.textArgDrop, this.recipe); // Input - this.addMultiEventListener("#input-text", "keyup", this.input.debounceInputChange, this.input); - this.addMultiEventListener("#input-text", "paste", this.input.inputPaste, this.input); + document.getElementById("input-text").addEventListener("keyup", this.input.debounceInputChange.bind(this.input)); 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("#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); 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)); + this.addDynamicListener(".eol-select a", "click", this.input.eolSelectClick, this.input); // Output diff --git a/src/web/extensions/statusBar.mjs b/src/web/extensions/statusBar.mjs new file mode 100644 index 00000000..8a837a51 --- /dev/null +++ b/src/web/extensions/statusBar.mjs @@ -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 ` + abc + + + + sort + + + + + highlight_alt + \u279E + ( selected) + + + location_on + + `; +} + +/** + * Builds the Right-hand-side widgets + * Event listener set up in Manager + * @returns {string} + */ +function constructRHS() { + return ` + language + UTF-16 + + +
`; +} + +/** + * 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); +} diff --git a/src/web/html/index.html b/src/web/html/index.html index d222fee1..3d237bdd 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -219,8 +219,6 @@ - - @@ -267,7 +265,7 @@