diff --git a/edit/codemirror-editing-hooks.js b/edit/codemirror-editing-hooks.js index e06ae770..574e71ca 100644 --- a/edit/codemirror-editing-hooks.js +++ b/edit/codemirror-editing-hooks.js @@ -482,6 +482,7 @@ onDOMscriptReady('/codemirror.js').then(() => { if (!chrome.runtime.getPackageDirectoryEntry) { const themes = [ chrome.i18n.getMessage('defaultTheme'), + /* populate-theme-start*/ '3024-day', '3024-night', 'abcdef', @@ -531,7 +532,8 @@ onDOMscriptReady('/codemirror.js').then(() => { 'xq-dark', 'xq-light', 'yeti', - 'zenburn', + 'zenburn' + /* populate-theme-end */ ]; localStorage.codeMirrorThemes = themes.join(' '); return Promise.resolve(themes); diff --git a/package.json b/package.json index 445ae382..434388f8 100644 --- a/package.json +++ b/package.json @@ -4,5 +4,17 @@ "description": "Redesign the web with Stylus, a user styles manager", "license": "GPL-3.0-only", "repository": "openstyles/stylus", - "author": "Stylus Team" + "author": "Stylus Team", + "devDependencies": { + "codemirror": "^5.39.0", + "eslint": "^5.1.0", + "fs-extra": "^7.0.0", + "updates": "^3.2.3" + }, + "scripts": { + "build": "npm run update && npm run build:cm", + "build:cm": "node tools/update-libraries.js && node tools/update-codemirror-themes.js", + "lint": "eslint **/*.js || true", + "update": "updates -u && npm update" + } } diff --git a/tools/update-codemirror-themes.js b/tools/update-codemirror-themes.js new file mode 100644 index 00000000..ee3c37e9 --- /dev/null +++ b/tools/update-codemirror-themes.js @@ -0,0 +1,40 @@ +#!/usr/bin/env node +'use strict'; + +const fs = require('fs-extra'); +const path = require('path'); + +// Update theme names list in codemirror-editing-hook.js +async function getThemes() { + const p = path.join(__dirname, '..', 'vendor/codemirror/theme/'); + const files = await fs.readdir(p); + return files + .filter(name => name.endsWith('.css')) + .map(name => name.replace('.css', '')) + .sort(); +} + +function replaceThemes(content, themes) { + const list = JSON.stringify(themes, null, 8).replace(/"/g, '\''); + return content.replace( + /\/\*\s*populate-theme-start\s*\*\/[\s\S]+\/\*\s*populate-theme-end\s*\*\//, + // strip off square brackets & first 8 spaces + `/* populate-theme-start*/\n${list.substring(2, list.length - 2)}\n /* populate-theme-end */` + ); +} + +async function updateHook(themes) { + const fileName = path.join(__dirname, '..', 'edit/codemirror-editing-hooks.js'); + const content = await fs.readFile(fileName, 'utf-8'); + fs.writeFile(fileName, replaceThemes(content, themes)); +} + +function exit(err) { + if (err) console.error(err); + process.exit(err ? 1 : 0); +} + +getThemes() + .then(themes => updateHook(themes)) + .then(() => console.log('\x1b[32m%s\x1b[0m', `codemirror themes list updated`)) + .catch(exit); diff --git a/tools/update-libraries.js b/tools/update-libraries.js new file mode 100644 index 00000000..87e5a544 --- /dev/null +++ b/tools/update-libraries.js @@ -0,0 +1,69 @@ +#!/usr/bin/env node +'use strict'; + +const fs = require('fs-extra'); +const path = require('path'); + +const root = path.join(__dirname, '..'); + +const files = { + 'codemirror': [ + 'addon/comment/comment.js', + 'addon/dialog', + 'addon/edit/closebrackets.js', + 'addon/edit/matchbrackets.js', + 'addon/fold/brace-fold.js', + 'addon/fold/comment-fold.js', + 'addon/fold/foldcode.js', + 'addon/fold/foldgutter.css', + 'addon/fold/foldgutter.js', + 'addon/fold/indent-fold.js', + 'addon/hint/css-hint.js', + 'addon/hint/show-hint.css', + 'addon/hint/show-hint.js', + 'addon/lint/css-lint.js', + 'addon/lint/json-lint.js', + 'addon/lint/lint.css', + 'addon/lint/lint.js', + 'addon/scroll/annotatescrollbar.js', + 'addon/search/match-highlighter.js', + 'addon/search/matchesonscrollbar.css', + 'addon/search/matchesonscrollbar.js', + 'addon/search/searchcursor.js', + 'addon/selection/active-line.js', + 'keymap', + 'lib', + 'mode/css', + 'mode/javascript', + 'mode/stylus', + 'theme' + ] +}; + +async function updateReadme(lib) { + const pkg = await fs.readJson(`${root}/node_modules/${lib}/package.json`); + const file = `${root}/vendor/${lib}/README.md`; + const txt = await fs.readFile(file, 'utf8'); + return fs.writeFile(file, txt.replace(/##\s*v[-\w.]+/, `## v${pkg.version}`)); +} + +async function copy(lib, folder) { + try { + await fs.copy(`${root}/node_modules/${lib}/${folder}`, `${root}/vendor/${lib}/${folder}`); + } catch (err) { + exit(err); + } +} + +function exit(err) { + if (err) console.error(err); + process.exit(err ? 1 : 0); +} + +Object.keys(files).forEach(lib => { + updateReadme(lib); + files[lib].forEach(folder => { + copy(lib, folder); + }); + console.log('\x1b[32m%s\x1b[0m', `${lib} files updated`); +}); diff --git a/vendor/README b/vendor/README new file mode 100644 index 00000000..a0517e71 --- /dev/null +++ b/vendor/README @@ -0,0 +1,21 @@ +# Vendor files are populated by the build script: + +## What the build script does + +Using this repo, run `npm install`... the latest versions of: + +* `CodeMirror` (https://github.com/codemirror/CodeMirror) is installed.

+* **TODO**: `jsonlint` () is installed. +* **TODO**: `less` () is installed. +* **TODO**: `lz-string-unsafe` (https://github.com/openstyles/lz-string-unsafe) is installed. +* **TODO**: `node-semver` () is installed. +* **TODO**: `stylus-lang` () is installed.

+* The necessary build tools; see `devDependencies` in the `package.json`. + +## Running the build script + +Use `npm run build` to update packages in the `node_modules` folder & update the vendor folder. + +The following changes are made: + +* Only the essential CodeMirror files are copied directly from the `node_modules` folder to `vendor/codemirror`; see the `vendor/codemirror/README` for specifics. diff --git a/vendor/codemirror/README.md b/vendor/codemirror/README.md new file mode 100644 index 00000000..a325dbf6 --- /dev/null +++ b/vendor/codemirror/README.md @@ -0,0 +1,43 @@ +## v0.0.0 + +List of essential folders & files copied from `node_modules/codemirror` to `vendor/codemirror`: + +_ addon/ +| |_ comment/ +| | |_ comment.js +| |_ dialog/* (all files) +| |_ edit/ +| | |_ closebrackets.js +| | |_ matchbrackets.js +| |_ fold/ +| | |_ brace-fold.js +| | |_ comment-fold.js +| | |_ foldcode.js +| | |_ foldgutter.css +| | |_ foldgutter.js +| | |_ indent-fold.js +| |_ hint/ +| | |_ css-hint.js +| | |_ show-hint.css +| | |_ show-hint.js +| |_ lint/ +| | |_ css-lint.js +| | |_ json-lint.js +| | |_ lint.css +| | |_ lint.js +| |_ scroll/ +| | |_ annotatescrollbar.js +| |_ search/ +| | |_ match-highlighter.js +| | |_ matchesonscrollbar.css +| | |_ matchesonscrollbar.js +| | |_ searchcursor.js +| |_ selection/ +| | |_ active-line.js +|_ keymap/* (all files) +|_ lib/* (all files) +|_ mode/ +| |_ css/* (all files) +| |_ javascript/* (all files) +| |_ stylus/* (all files) +|_ theme/* (all files)