diff --git a/README.md b/README.md index c11fba8..b8d75a8 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,11 @@ the syntax is checked before they save it back. Once selected this pane as a view of a file, then the pen icon allows to switch to editing mode, and the check mark button allows the file to be saved back. Editing can be aborted by the cancel(X) button. + +### Generative AI usage +The SolidOS team is using GitHub Copilot integrated in Visual Studio Code. +We have added comments in the code to make it explicit which parts are 100% written by AI. +Example: +* Some code was generated by the GPT-5.3-Codex model in GitHub Copilot based on the following prompt: +* Can you refactor this code setUnedited () to use CSS instead of inline js styles + diff --git a/package-lock.json b/package-lock.json index 080fcfa..5e484f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@testing-library/dom": "^10.4.1", "babel-loader": "^10.0.0", "babel-plugin-inline-import": "^3.0.0", + "copy-webpack-plugin": "^14.0.0", "css-loader": "^7.1.2", "eslint": "^9.39.2", "html-webpack-plugin": "^5.6.6", @@ -24,6 +25,7 @@ "solid-logic": "^4.0.6", "solid-ui": "^3.0.5", "style-loader": "^3.3.3", + "terser-webpack-plugin": "^5.4.0", "webpack": "^5.97.1", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3" @@ -5961,6 +5963,40 @@ "dev": true, "license": "MIT" }, + "node_modules/copy-webpack-plugin": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-14.0.0.tgz", + "integrity": "sha512-3JLW90aBGeaTLpM7mYQKpnVdgsUZRExY55giiZgLuX/xTQRUs1dOCwbBnWnvY6Q6rfZoXMNwzOQJCSZPppfqXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-parent": "^6.0.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^7.0.3", + "tinyglobby": "^0.2.12" + }, + "engines": { + "node": ">= 20.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/serialize-javascript": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.4.tgz", + "integrity": "sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/core-js": { "version": "3.47.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", @@ -13077,6 +13113,54 @@ "node": ">=0.6.0" } }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tldts": { "version": "6.1.86", "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", diff --git a/package.json b/package.json index 8f73f0c..550db02 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "LICENSE" ], "scripts": { - "build": "echo nothing to build", + "clean": "rm -rf lib", + "build": "npm run clean && npm run build-dist", + "build-dist": "webpack --progress", "lint": "eslint", "lint-fix": "eslint --fix", "test": "jest --no-coverage", @@ -47,11 +49,12 @@ "solid-ui": "^3.0.3" }, "devDependencies": { - "@babel/preset-env": "^7.28.6", "@babel/eslint-parser": "^7.28.6", + "@babel/preset-env": "^7.28.6", "@testing-library/dom": "^10.4.1", "babel-loader": "^10.0.0", "babel-plugin-inline-import": "^3.0.0", + "copy-webpack-plugin": "^14.0.0", "css-loader": "^7.1.2", "eslint": "^9.39.2", "html-webpack-plugin": "^5.6.6", @@ -62,6 +65,7 @@ "solid-logic": "^4.0.6", "solid-ui": "^3.0.5", "style-loader": "^3.3.3", + "terser-webpack-plugin": "^5.4.0", "webpack": "^5.97.1", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3" diff --git a/src/sourcePane.js b/src/sourcePane.js index 86dda7f..579806a 100644 --- a/src/sourcePane.js +++ b/src/sourcePane.js @@ -122,6 +122,23 @@ const pane = { const myCompactButton = controls.appendChild(compactButton(dom)) const cancelButton = controls.appendChild(UI.widgets.cancelButton(dom)) const saveButton = controls.appendChild(UI.widgets.continueButton(dom)) + + // This code was generated by Generative AI (GPT-5.3-Codex in GitHub Copilot) based on the following prompt: + /* can you refactor this code setUnedited () to use css instead of inline js styles */ + function setControlVisible (button, visible) { + button.classList.toggle('sourcePaneControlVisible', visible) + button.classList.toggle('sourcePaneControlHidden', !visible) + } + + function setTextState (stateClass) { + textArea.classList.remove( + 'sourcePaneTextAreaUnedited', + 'sourcePaneTextAreaEditing', + 'sourcePaneTextAreaEdited', + 'sourcePaneTextAreaError' + ) + textArea.classList.add(stateClass) + } const myEditButton = controls.appendChild(editButton(dom)) function setUnedited () { @@ -154,6 +171,8 @@ const pane = { myCompactButton.style.visibility = 'collapse' textArea.removeAttribute('readonly') } + // end of generative ai refactor + const parseable = { 'text/n3': true, 'text/turtle': true, diff --git a/src/styles/sourcePane.css b/src/styles/sourcePane.css new file mode 100644 index 0000000..c40f221 --- /dev/null +++ b/src/styles/sourcePane.css @@ -0,0 +1,79 @@ +.sourcePane { + width: 100%; +} + +.sourcePaneControls { + display: flex; + justify-content: flex-end; + align-items: center; + gap: 0.4rem; + flex-wrap: nowrap; + width: 100%; + padding-right: 1.6em; + text-align: right; +} +/* generative ai */ +.sourcePaneControls > * { + flex: 0 0 auto; +} + +.sourcePaneTable { + width: 100%; +} + +.sourcePaneControlsCell { + width: 100%; + text-align: right; + padding: 0 0.2em var(--spacing-md, 1em) 0; +} + +.sourcePaneMainCell, +.sourcePaneStatusRow { + width: 100%; +} + +.sourcePaneTextArea { + font-family: monospace; + font-size: 100%; + min-width: 60em; + margin: var(--spacing-md, 1em) 0.2em; + padding: var(--spacing-md, 1em); + border: 0.1em solid #888; + border-radius: var(--border-radius-base, 0.5em); +} + +.sourcePaneCompactButton { + box-sizing: border-box; + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 7.5rem; + padding: var(--spacing-xs, 0.55rem) var(--spacing-md, 0.9rem); + line-height: 1.2; + white-space: nowrap; +} + +/* generative ai */ +.sourcePaneTextAreaUnedited { + color: #888; +} + +.sourcePaneTextAreaEditing { + color: black; +} + +.sourcePaneTextAreaEdited { + color: green; +} + +.sourcePaneTextAreaError { + color: red; +} + +.sourcePaneControlVisible { + visibility: visible; +} + +.sourcePaneControlHidden { + visibility: collapse; +} diff --git a/test/sourcePane.test.js b/test/sourcePane.test.js index 2c3cbe3..8f0d2e1 100644 --- a/test/sourcePane.test.js +++ b/test/sourcePane.test.js @@ -1,5 +1,6 @@ const { context, doc, subject } = require('./helpers/setup') -const pane = require('../src/sourcePane').default +const paneModule = require('../src/sourcePane') +const pane = paneModule.default || paneModule const { findByText, fireEvent, getByTitle, waitFor } = require('@testing-library/dom') const fetchMock = require('jest-fetch-mock') const { parse, sym } = require('rdflib') diff --git a/webpack.config.mjs b/webpack.config.mjs new file mode 100644 index 0000000..2f7a441 --- /dev/null +++ b/webpack.config.mjs @@ -0,0 +1,106 @@ +import path from 'path' +import { moduleRules } from './webpack.module.rules.mjs' +import { createRequire } from 'module' +import TerserPlugin from 'terser-webpack-plugin' +import CopyPlugin from 'copy-webpack-plugin' + +const require = createRequire(import.meta.url) + +const common = { + mode: 'production', + entry: './src/sourcePane.js', + module: { + rules: moduleRules, + }, + externals: { + 'solid-ui': { + commonjs: 'solid-ui', + commonjs2: 'solid-ui', + amd: 'solid-ui', + root: 'UI', + }, + 'solid-logic': { + commonjs: 'solid-logic', + commonjs2: 'solid-logic', + amd: 'solid-logic', + root: 'SolidLogic', + }, + rdflib: { + commonjs: 'rdflib', + commonjs2: 'rdflib', + amd: 'rdflib', + root: '$rdf', + }, + }, + resolve: { + extensions: ['.js', '.ts'], + fallback: { + path: require.resolve('path-browserify') + }, + }, + devtool: 'source-map', +} + +const normalConfig = { + ...common, + mode: 'production', + output: { + path: path.resolve(process.cwd(), 'lib'), + filename: 'source-pane.js', + library: { + type: 'umd', + name: 'SourcePane', + export: 'default', + }, + globalObject: 'this', + clean: true, + }, + plugins: [ + ...(common.plugins || []), + new CopyPlugin({ + patterns: [ + { + from: path.resolve('src/styles'), + to: path.resolve('lib/styles'), + }, + ], + }), + ], + optimization: { + minimize: false, + } +} + +const minConfig = { + ...common, + mode: 'production', + output: { + path: path.resolve(process.cwd(), 'lib'), + filename: 'source-pane.min.js', + library: { + type: 'umd', + name: 'SourcePane', + export: 'default', + }, + globalObject: 'this', + clean: false, + }, + plugins: [ + ...(common.plugins || []), + ], + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + terserOptions: { + format: { + comments: false, + }, + }, + extractComments: false, + }) + ], + } +} + +export default [normalConfig, minConfig]