diff --git a/.eslintrc.js b/.eslintrc.js index b838820..86f7b40 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -12,4 +12,3 @@ module.exports = { sourceType: 'module' } } - \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..1e09e1e --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,27 @@ +name: CI + +on: + push: + branches: + - 'master' + paths: + - 'src/**/*' + +jobs: + ci: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [12.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + - run: | + npm i + npm run ci \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..2887d72 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,28 @@ +name: Publish to NPM + +on: + workflow_dispatch: + release: + types: [created] + +jobs: + publish: + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: '14.x' + registry-url: 'https://registry.npmjs.org' + - name: Build eruda code + run: | + npm i + npm run build + - name: Publish package on NPM + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/.npmignore b/.npmignore deleted file mode 100644 index ff2987a..0000000 --- a/.npmignore +++ /dev/null @@ -1,10 +0,0 @@ -/src/ -.eslintignore -.eslintrc.js -prettier.config.js -.gitignore -.npmignore -.travis.yml -index.html -webpack.config.js -.prettierignore \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 230ce1c..6fb324e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.1.0 (29 Nov 2020) + +* feat: support theme + ## v2.0.0 (6 Jan 2020) * feat: theme support \ No newline at end of file diff --git a/README.md b/README.md index 2e49ac0..37a4f75 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # eruda-code [![NPM version][npm-image]][npm-url] -[![Build status][travis-image]][travis-url] +[![Build status][ci-image]][ci-url] [![License][license-image]][npm-url] [npm-image]: https://img.shields.io/npm/v/eruda-code.svg [npm-url]: https://npmjs.org/package/eruda-code -[travis-image]: https://img.shields.io/travis/liriliri/eruda-code.svg -[travis-url]: https://travis-ci.org/liriliri/eruda-code +[ci-image]: https://img.shields.io/github/workflow/status/liriliri/eruda-code/CI?style=flat-square +[ci-url]: https://github.com/liriliri/eruda-code/actions/workflows/main.yml [license-image]: https://img.shields.io/npm/l/eruda-code.svg Eruda plugin for running JavaScript code. @@ -15,7 +15,7 @@ Eruda plugin for running JavaScript code. ## Demo Browse it on your phone: -[http://eruda.liriliri.io/](http://eruda.liriliri.io/) +[http://eruda.liriliri.io/?plugin=code](http://eruda.liriliri.io/?plugin=code) ## Install diff --git a/package.json b/package.json index cc8c3e4..5797ed2 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,22 @@ { "name": "eruda-code", - "version": "2.0.0", + "version": "2.1.0", "description": "Eruda plugin for running JavaScript code", "main": "eruda-code.js", "scripts": { "dev": "webpack-dev-server --host 0.0.0.0", "build": "webpack -p", "ci": "npm run lint && npm run build", - "lint": "eslint src/**/*.js", - "format": "prettier src/**/*.js src/**/*.scss *.js index.html --write" + "lint": "eslint \"src/**/*.js\"", + "format": "prettier \"src/**/*.js\" \"src/**/*.scss\" \"*.js\" \"index.html\" --write" }, + "files": [ + "eruda-code*" + ], "repository": { "type": "git", "url": "git+https://github.com/liriliri/eruda-code.git" }, - "eustia": { - "files": "src/*.js", - "output": "src/util.js", - "format": "es" - }, "keywords": [ "eruda", "plugin" @@ -38,10 +36,12 @@ "babel-loader": "^8.0.6", "codemirror": "^5.50.2", "css-loader": "^3.4.1", - "eruda": "^2.0.0", + "eruda": "^2.6.1", "eslint": "^6.6.0", "handlebars": "^4.5.1", "handlebars-loader": "^1.7.1", + "js-beautify": "^1.14.7", + "licia": "^1.37.0", "node-sass": "^4.13.0", "postcss": "^7.0.21", "postcss-class-prefix": "^0.3.0", diff --git a/src/CodeMirror.css b/src/CodeMirror.css index dd80a3c..a701e93 100644 --- a/src/CodeMirror.css +++ b/src/CodeMirror.css @@ -1,36 +1,41 @@ .CodeMirror { height: 100%; + background: var(--background); + color: var(--foreground); +} + +.CodeMirror-gutters { + background: var(--background); + border-color: var(--border); } /* Sync style with chrome dev-tool */ -.cm-keyword { - color: hsl(310, 86%, 36%); +.cm-s-default .cm-keyword { + color: var(--keyword-color); } -.cm-number { - color: hsl(248, 100%, 41%); +.cm-s-default .cm-number { + color: var(--number-color); } -.cm-comment { - color: hsl(120, 100%, 23%) !important; +.cm-s-default .cm-comment { + color: var(--comment-color) !important; font-style: italic; } -.cm-string { - color: hsl(1, 80%, 43%) !important; -} -.cm-string-2 { - color: hsl(1, 99%, 39%) !important; +.cm-s-default .cm-string, +.cm-s-default .com-string-2 { + color: var(--string-color); } .cm-atom { - color: hsl(310, 86%, 36%); + color: var(--attribute-name-color); } -.cm-def { - color: hsl(240, 73%, 38%); +.cm-s-default .cm-def { + color: var(--foreground); } .cm-operator { - color: hsl(27, 100%, 30%); + color: var(--operator-color); } -.cm-meta { - color: hsl(27, 100%, 30%); +.cm-s-default .cm-meta { + color: var(--tag-name-color); } -.cm-variable-2 { - color: hsl(240, 73%, 38%); +.cm-s-default .cm-variable-2 { + color: var(--var-color); } diff --git a/src/code.js b/src/code.js index 0dffff0..3056d91 100644 --- a/src/code.js +++ b/src/code.js @@ -1,16 +1,21 @@ import CodeMirror from 'codemirror' import 'codemirror/mode/javascript/javascript' -import { nextTick, copy } from './util' +import nextTick from 'licia/nextTick' +import copy from 'licia/copy' +import beautify from 'js-beautify' export default function(eruda) { - let { evalCss, beautify } = eruda.util + let { evalCss } = eruda.util class Code extends eruda.Tool { constructor() { super() this.name = 'code' this._style = evalCss(require('./style.scss')) - this._CodeMirrorStyle = evalCss(require('codemirror/lib/codemirror.css')) + this._CodeMirrorStyle = evalCss( + require('codemirror/lib/codemirror.css') + + require('codemirror/theme/material-darker.css') + ) this._CodeMirrorCustomStyle = evalCss(require('./CodeMirror.css')) this._editor = null } @@ -50,6 +55,7 @@ export default function(eruda) { } copy() { copy(this._editor.getValue()) + eruda.get().notify('Copied') } clear() { this._editor.setValue('') diff --git a/src/style.scss b/src/style.scss index 8396fd4..335f567 100644 --- a/src/style.scss +++ b/src/style.scss @@ -23,7 +23,7 @@ $anim-duration: 0.3s; width: 25%; border-right: 1px solid var(--border); display: inline-block; - transition: background $anim-duration, color $anim-duration; + transition: background-color $anim-duration, color $anim-duration; &:active { background: var(--highlight); color: var(--select-foreground); diff --git a/src/util.js b/src/util.js deleted file mode 100644 index cf6c586..0000000 --- a/src/util.js +++ /dev/null @@ -1,568 +0,0 @@ -// Built by eustia. -'use strict' - -var _ = {} - -/* ------------------------------ allKeys ------------------------------ */ - -export var allKeys = (_.allKeys = (function() { - /* Retrieve all the names of object's own and inherited properties. - * - * |Name |Type |Desc | - * |------|------|---------------------------| - * |obj |object|Object to query | - * |return|array |Array of all property names| - * - * > Members of Object's prototype won't be retrieved. - * - * ```javascript - * var obj = Object.create({zero: 0}); - * obj.one = 1; - * allKeys(obj) // -> ['zero', 'one'] - * ``` - */ - - /* module - * env: all - * test: all - */ - - function exports(obj) { - var ret = [], - key - - for (key in obj) ret.push(key) - - return ret - } - - return exports -})()) - -/* ------------------------------ noop ------------------------------ */ - -export var noop = (_.noop = (function() { - /* A no-operation function. - * - * ```javascript - * noop(); // Does nothing - * ``` - */ - - /* module - * env: all - * test: all - */ - - function exports() {} - - return exports -})()) - -/* ------------------------------ isUndef ------------------------------ */ - -export var isUndef = (_.isUndef = (function() { - /* Check if value is undefined. - * - * |Name |Type |Desc | - * |------|-------|--------------------------| - * |val |* |Value to check | - * |return|boolean|True if value is undefined| - * - * ```javascript - * isUndef(void 0); // -> true - * isUndef(null); // -> false - * ``` - */ - - /* module - * env: all - * test: all - */ - - function exports(val) { - return val === void 0 - } - - return exports -})()) - -/* ------------------------------ optimizeCb ------------------------------ */ - -export var optimizeCb = (_.optimizeCb = (function() { - /* Used for function context binding. - */ - - /* module - * env: all - * test: all - */ - - /* dependencies - * isUndef - */ - - function exports(fn, ctx, argCount) { - if (isUndef(ctx)) return fn - - switch (argCount == null ? 3 : argCount) { - case 1: - return function(val) { - return fn.call(ctx, val) - } - case 3: - return function(val, idx, collection) { - return fn.call(ctx, val, idx, collection) - } - case 4: - return function(accumulator, val, idx, collection) { - return fn.call(ctx, accumulator, val, idx, collection) - } - } - - return function() { - return fn.apply(ctx, arguments) - } - } - - return exports -})()) - -/* ------------------------------ has ------------------------------ */ - -export var has = (_.has = (function() { - /* Checks if key is a direct property. - * - * |Name |Type |Desc | - * |------|-------|--------------------------------| - * |obj |object |Object to query | - * |key |string |Path to check | - * |return|boolean|True if key is a direct property| - * - * ```javascript - * has({one: 1}, 'one'); // -> true - * ``` - */ - - /* module - * env: all - * test: all - */ - - var hasOwnProp = Object.prototype.hasOwnProperty - - function exports(obj, key) { - return hasOwnProp.call(obj, key) - } - - return exports -})()) - -/* ------------------------------ keys ------------------------------ */ - -export var keys = (_.keys = (function(exports) { - /* Create an array of the own enumerable property names of object. - * - * |Name |Type |Desc | - * |------|------|-----------------------| - * |obj |object|Object to query | - * |return|array |Array of property names| - * - * ```javascript - * keys({a: 1}); // -> ['a'] - * ``` - */ - - /* module - * env: all - * test: all - */ - - /* dependencies - * has - */ - - exports = - Object.keys || - function(obj) { - var ret = [], - key - - for (key in obj) { - if (has(obj, key)) ret.push(key) - } - - return ret - } - - return exports -})({})) - -/* ------------------------------ objToStr ------------------------------ */ - -export var objToStr = (_.objToStr = (function() { - /* Alias of Object.prototype.toString. - * - * |Name |Type |Desc | - * |------|------|------------------------------------| - * |value |* |Source value | - * |return|string|String representation of given value| - * - * ```javascript - * objToStr(5); // -> '[object Number]' - * ``` - */ - - /* module - * env: all - * test: all - */ - - var ObjToStr = Object.prototype.toString - - function exports(val) { - return ObjToStr.call(val) - } - - return exports -})()) - -/* ------------------------------ isFn ------------------------------ */ - -export var isFn = (_.isFn = (function() { - /* Check if value is a function. - * - * |Name |Type |Desc | - * |------|-------|---------------------------| - * |val |* |Value to check | - * |return|boolean|True if value is a function| - * - * Generator function is also classified as true. - * - * ```javascript - * isFn(function() {}); // -> true - * isFn(function*() {}); // -> true - * ``` - */ - - /* module - * env: all - * test: all - */ - - /* dependencies - * objToStr - */ - - function exports(val) { - var objStr = objToStr(val) - - return ( - objStr === '[object Function]' || objStr === '[object GeneratorFunction]' - ) - } - - return exports -})()) - -/* ------------------------------ isNum ------------------------------ */ - -export var isNum = (_.isNum = (function() { - /* Check if value is classified as a Number primitive or object. - * - * |Name |Type |Desc | - * |------|-------|-------------------------------------| - * |value |* |Value to check | - * |return|boolean|True if value is correctly classified| - * - * ```javascript - * isNum(5); // -> true - * isNum(5.1); // -> true - * isNum({}); // -> false - * ``` - */ - - /* module - * env: all - * test: all - */ - - /* dependencies - * objToStr - */ - - function exports(val) { - return objToStr(val) === '[object Number]' - } - - return exports -})()) - -/* ------------------------------ isArrLike ------------------------------ */ - -export var isArrLike = (_.isArrLike = (function() { - /* Check if value is array-like. - * - * |Name |Type |Desc | - * |------|-------|---------------------------| - * |value |* |Value to check | - * |return|boolean|True if value is array like| - * - * > Function returns false. - * - * ```javascript - * isArrLike('test'); // -> true - * isArrLike(document.body.children); // -> true; - * isArrLike([1, 2, 3]); // -> true - * ``` - */ - - /* module - * env: all - * test: all - */ - - /* dependencies - * isNum isFn - */ - - var MAX_ARR_IDX = Math.pow(2, 53) - 1 - - function exports(val) { - if (!val) return false - - var len = val.length - - return isNum(len) && len >= 0 && len <= MAX_ARR_IDX && !isFn(val) - } - - return exports -})()) - -/* ------------------------------ each ------------------------------ */ - -export var each = (_.each = (function() { - /* Iterate over elements of collection and invokes iteratee for each element. - * - * |Name |Type |Desc | - * |--------|------------|------------------------------| - * |obj |object array|Collection to iterate over | - * |iteratee|function |Function invoked per iteration| - * |[ctx] |* |Function context | - * - * ```javascript - * each({'a': 1, 'b': 2}, function (val, key) {}); - * ``` - */ - - /* module - * env: all - * test: all - */ - - /* dependencies - * isArrLike keys optimizeCb - */ - - function exports(obj, iteratee, ctx) { - iteratee = optimizeCb(iteratee, ctx) - - var i, len - - if (isArrLike(obj)) { - for (i = 0, len = obj.length; i < len; i++) iteratee(obj[i], i, obj) - } else { - var _keys = keys(obj) - for (i = 0, len = _keys.length; i < len; i++) { - iteratee(obj[_keys[i]], _keys[i], obj) - } - } - - return obj - } - - return exports -})()) - -/* ------------------------------ createAssigner ------------------------------ */ - -export var createAssigner = (_.createAssigner = (function() { - /* Used to create extend, extendOwn and defaults. - * - * |Name |Type |Desc | - * |--------|--------|------------------------------| - * |keysFn |function|Function to get object keys | - * |defaults|boolean |No override when set to true | - * |return |function|Result function, extend... | - */ - - /* module - * env: all - * test: all - */ - - /* dependencies - * isUndef each - */ - - function exports(keysFn, defaults) { - return function(obj) { - each(arguments, function(src, idx) { - if (idx === 0) return - - var keys = keysFn(src) - - each(keys, function(key) { - if (!defaults || isUndef(obj[key])) obj[key] = src[key] - }) - }) - - return obj - } - } - - return exports -})()) - -/* ------------------------------ extend ------------------------------ */ - -export var extend = (_.extend = (function(exports) { - /* Copy all of the properties in the source objects over to the destination object. - * - * |Name |Type |Desc | - * |------|------|------------------| - * |obj |object|Destination object| - * |...src|object|Sources objects | - * |return|object|Destination object| - * - * ```javascript - * extend({name: 'RedHood'}, {age: 24}); // -> {name: 'RedHood', age: 24} - * ``` - */ - - /* module - * env: all - * test: all - */ - - /* dependencies - * createAssigner allKeys - */ - - exports = createAssigner(allKeys) - - return exports -})({})) - -/* ------------------------------ copy ------------------------------ */ - -export var copy = (_.copy = (function() { - /* Copy text to clipboard using document.execCommand. - * - * |Name|Type |Desc | - * |----|--------|-----------------| - * |text|string |Text to copy | - * |[cb]|function|Optional callback| - * - * ```javascript - * copy('text', function (err) - * { - * // Handle errors. - * }); - * ``` - */ - - /* module - * env: browser - * test: browser - */ - - /* dependencies - * extend noop - */ - - function exports(text, cb) { - cb = cb || noop - - var el = document.createElement('textarea'), - body = document.body - - extend(el.style, { - fontSize: '12pt', - border: '0', - padding: '0', - margin: '0', - position: 'absolute', - left: '-9999px' - }) - - el.value = text - - body.appendChild(el) - - // Prevent showing ios keyboard. - el.setAttribute('readonly', '') - el.select() - el.setSelectionRange(0, text.length) - - try { - document.execCommand('copy') - cb() - } catch (e) { - cb(e) - } finally { - body.removeChild(el) - } - } - - return exports -})()) - -/* ------------------------------ nextTick ------------------------------ */ - -export var nextTick = (_.nextTick = (function(exports) { - /* Next tick for both node and browser. - * - * |Name|Type |Desc | - * |----|--------|----------------| - * |cb |function|Function to call| - * - * Use process.nextTick if available. - * - * Otherwise setImmediate or setTimeout is used as fallback. - * - * ```javascript - * nextTick(function () - * { - * // Do something... - * }); - * ``` - */ - - /* module - * env: all - * test: all - */ - - if (typeof process === 'object' && process.nextTick) { - exports = process.nextTick - } else if (typeof setImmediate === 'function') { - exports = function(cb) { - setImmediate(ensureCallable(cb)) - } - } else { - exports = function(cb) { - setTimeout(ensureCallable(cb), 0) - } - } - - function ensureCallable(fn) { - if (typeof fn !== 'function') throw new TypeError(fn + ' is not a function') - - return fn - } - - return exports -})({})) - -export default _ diff --git a/webpack.config.js b/webpack.config.js index a6d9707..f8e0d20 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -11,7 +11,7 @@ module.exports = { entry: './src/index.js', devServer: { contentBase: './', - port: 3000 + port: 8080 }, output: { path: __dirname,