summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.eslintignore3
-rw-r--r--.eslintrc.js21
-rw-r--r--README.md6
-rw-r--r--config.json.example2
-rw-r--r--lib/config/default.js1
-rw-r--r--lib/config/environment.js1
-rw-r--r--lib/config/index.js6
-rw-r--r--lib/logger.js28
-rw-r--r--lib/models/index.js1
-rw-r--r--lib/models/user.js2
-rw-r--r--lib/realtime.js3
-rw-r--r--lib/web/imageRouter/filesystem.js2
-rw-r--r--package.json42
-rw-r--r--public/.eslintrc.js28
-rw-r--r--public/docs/features.md4
-rw-r--r--public/docs/slide-example.md1
-rw-r--r--public/docs/yaml-metadata.md39
-rw-r--r--public/js/history.js1
-rw-r--r--public/js/index.js4
-rw-r--r--public/js/lib/editor/index.js8
-rw-r--r--public/js/lib/editor/ui-elements.js2
21 files changed, 129 insertions, 76 deletions
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 00000000..2c3d6b04
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,3 @@
+lib/ot
+public/vendor
+public/build
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 00000000..b826a37b
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,21 @@
+module.exports = {
+ "root": true,
+ "extends": "standard",
+ "env": {
+ "node": true
+ },
+ "rules": {
+ // at some point all of these should return to their default "error" state
+ // but right now, this is not a good choice, because too many places are
+ // wrong.
+ "import/first": ["warn"],
+ "indent": ["warn"],
+ "no-multiple-empty-lines": ["warn"],
+ "no-multi-spaces": ["warn"],
+ "object-curly-spacing": ["warn"],
+ "one-var": ["warn"],
+ "quotes": ["warn"],
+ "semi": ["warn"],
+ "space-infix-ops": ["warn"]
+ }
+};
diff --git a/README.md b/README.md
index 5e49f2ed..6adb93d5 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@
CodiMD
===
-[![Standard - JavaScript Style Guide][standardjs-image]][standardjs-url]
-
[![#CodiMD on matrix.org][matrix.org-image]][matrix.org-url]
[![build status][travis-image]][travis-url]
[![version][github-version-badge]][github-release-page]
@@ -179,6 +177,7 @@ There are some config settings you need to change in the files below.
| `CMD_HOST` | `localhost` | host to listen on |
| `CMD_PORT` | `80` | web app port |
| `CMD_PATH` | `/var/run/codimd.sock` | path to UNIX domain socket to listen on (if specified, `CMD_HOST` and `CMD_PORT` are ignored) |
+| `CMD_LOGLEVEL` | `info` | Defines what kind of logs are provided to stdout. |
| `CMD_ALLOW_ORIGIN` | `localhost, codimd.org` | domain name whitelist (use comma to separate) |
| `CMD_PROTOCOL_USESSL` | `true` or `false` | set to use SSL protocol for resources path (only applied when domain is set) |
| `CMD_URL_ADDPORT` | `true` or `false` | set to add port on callback URL (ports `80` or `443` won't be applied) (only applied when domain is set) |
@@ -274,6 +273,7 @@ There are some config settings you need to change in the files below.
| `host` | `localhost` | host to listen on |
| `port` | `80` | web app port |
| `path` | `/var/run/codimd.sock` | path to UNIX domain socket to listen on (if specified, `host` and `port` are ignored) |
+| `loglevel` | `info` | Defines what kind of logs are provided to stdout. |
| `allowOrigin` | `['localhost']` | domain name whitelist |
| `useSSL` | `true` or `false` | set to use SSL server (if `true`, will auto turn on `protocolUseSSL`) |
| `hsts` | `{"enable": true, "maxAgeSeconds": 31536000, "includeSubdomains": true, "preload": true}` | [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) options to use with HTTPS (default is the example value, max age is a year) |
@@ -371,7 +371,5 @@ See more at [http://operational-transformation.github.io/](http://operational-tr
[travis-url]: https://travis-ci.org/hackmdio/codimd
[github-version-badge]: https://img.shields.io/github/release/hackmdio/codimd.svg
[github-release-page]: https://github.com/hackmdio/codimd/releases
-[standardjs-image]: https://cdn.rawgit.com/feross/standard/master/badge.svg
-[standardjs-url]: https://github.com/feross/standard
[poeditor-image]: https://img.shields.io/badge/POEditor-translate-blue.svg
[poeditor-url]: https://poeditor.com/join/project/1OpGjF2Jir
diff --git a/config.json.example b/config.json.example
index 16c95509..8965add2 100644
--- a/config.json.example
+++ b/config.json.example
@@ -6,6 +6,7 @@
}
},
"development": {
+ "loglevel": "debug",
"hsts": {
"enable": false
},
@@ -16,6 +17,7 @@
},
"production": {
"domain": "localhost",
+ "loglevel": "info"
"hsts": {
"enable": true,
"maxAgeSeconds": "31536000",
diff --git a/lib/config/default.js b/lib/config/default.js
index 15f11aaa..71375b98 100644
--- a/lib/config/default.js
+++ b/lib/config/default.js
@@ -7,6 +7,7 @@ module.exports = {
urlPath: '',
host: '0.0.0.0',
port: 3000,
+ loglevel: 'info',
urlAddPort: false,
allowOrigin: ['localhost'],
useSSL: false,
diff --git a/lib/config/environment.js b/lib/config/environment.js
index 0c7c9a4f..4220e54d 100644
--- a/lib/config/environment.js
+++ b/lib/config/environment.js
@@ -9,6 +9,7 @@ module.exports = {
host: process.env.CMD_HOST,
port: toIntegerConfig(process.env.CMD_PORT),
path: process.env.CMD_PATH,
+ loglevel: process.env.CMD_LOGLEVEL,
urlAddPort: toBooleanConfig(process.env.CMD_URL_ADDPORT),
useSSL: toBooleanConfig(process.env.CMD_USESSL),
hsts: {
diff --git a/lib/config/index.js b/lib/config/index.js
index 4e1fa50d..c1005b0b 100644
--- a/lib/config/index.js
+++ b/lib/config/index.js
@@ -45,6 +45,12 @@ merge(config, require('./hackmdEnvironment'))
merge(config, require('./environment'))
merge(config, require('./dockerSecret'))
+if (['debug', 'verbose', 'info', 'warn', 'error'].includes(config.loglevel)) {
+ logger.level = config.loglevel
+} else {
+ logger.error('Selected loglevel %s doesn\'t exist, using default level \'debug\'. Available options: debug, verbose, info, warn, error', config.loglevel)
+}
+
// load LDAP CA
if (config.ldap.tlsca) {
let ca = config.ldap.tlsca.split(',')
diff --git a/lib/logger.js b/lib/logger.js
index f8b3895c..c70b81b8 100644
--- a/lib/logger.js
+++ b/lib/logger.js
@@ -1,23 +1,19 @@
'use strict'
-const winston = require('winston')
+const {createLogger, format, transports} = require('winston')
-class Logger extends winston.Logger {
- // Implement stream.writable.write interface
- write (chunk) {
- this.info(chunk)
- }
-}
-
-module.exports = new Logger({
+module.exports = createLogger({
+ level: 'debug',
+ format: format.combine(
+ format.uncolorize(),
+ format.timestamp(),
+ format.align(),
+ format.splat(),
+ format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
+ ),
transports: [
- new winston.transports.Console({
- level: 'debug',
- handleExceptions: true,
- json: false,
- colorize: false,
- timestamp: true
+ new transports.Console({
+ handleExceptions: true
})
],
- emitErrs: true,
exitOnError: false
})
diff --git a/lib/models/index.js b/lib/models/index.js
index 0a44ca87..ef70475e 100644
--- a/lib/models/index.js
+++ b/lib/models/index.js
@@ -25,6 +25,7 @@ if (config.dbURL) {
// https://github.com/sequelize/sequelize/issues/6485
function stripNullByte (value) {
value = '' + value
+ // eslint-disable-next-line no-control-regex
return value ? value.replace(/\u0000/g, '') : value
}
sequelize.stripNullByte = stripNullByte
diff --git a/lib/models/user.js b/lib/models/user.js
index 1bd8c745..2ebf6d06 100644
--- a/lib/models/user.js
+++ b/lib/models/user.js
@@ -50,7 +50,7 @@ module.exports = function (sequelize, DataTypes) {
}, {
instanceMethods: {
verifyPassword: function (attempt) {
- if (scrypt.verifyKdfSync(new Buffer(this.password, 'hex'), attempt)) {
+ if (scrypt.verifyKdfSync(Buffer.from(this.password, 'hex'), attempt)) {
return this
} else {
return false
diff --git a/lib/realtime.js b/lib/realtime.js
index 8541bafa..d04ffdc2 100644
--- a/lib/realtime.js
+++ b/lib/realtime.js
@@ -242,6 +242,7 @@ function getStatus (callback) {
}
})
models.User.count().then(function (regcount) {
+ // eslint-disable-next-line standard/no-callback-literal
return callback ? callback({
onlineNotes: Object.keys(notes).length,
onlineUsers: Object.keys(users).length,
@@ -283,7 +284,7 @@ function extractNoteIdFromSocket (socket) {
if (!referer) {
return false
}
- var hostUrl = url.parse(referer)
+ var hostUrl = url.URL.parse(referer)
var noteId = config.urlPath ? hostUrl.pathname.slice(config.urlPath.length + 1, hostUrl.pathname.length).split('/')[1] : hostUrl.pathname.split('/')[1]
return noteId
} else {
diff --git a/lib/web/imageRouter/filesystem.js b/lib/web/imageRouter/filesystem.js
index 8c432b0c..a2f8700d 100644
--- a/lib/web/imageRouter/filesystem.js
+++ b/lib/web/imageRouter/filesystem.js
@@ -16,5 +16,5 @@ exports.uploadImage = function (imagePath, callback) {
return
}
- callback(null, url.resolve(config.serverURL + '/uploads/', path.basename(imagePath)))
+ callback(null, url.URL.resolve(config.serverURL + '/uploads/', path.basename(imagePath)))
}
diff --git a/package.json b/package.json
index 304a526d..bba1e36f 100644
--- a/package.json
+++ b/package.json
@@ -5,9 +5,10 @@
"main": "app.js",
"license": "AGPL-3.0",
"scripts": {
- "test": "npm run-script standard && npm run-script jsonlint",
+ "test": "npm run-script eslint && npm run-script jsonlint",
+ "eslint": "node_modules/.bin/eslint lib public app.js",
"jsonlint": "find . -not -path './node_modules/*' -type f -name '*.json' -o -type f -name '*.json.example' | while read json; do echo $json ; jq . $json; done",
- "standard": "node ./node_modules/standard/bin/cmd.js",
+ "standard": "echo 'standard is no longer being used, use `npm run eslint` instead!' && exit 1",
"dev": "webpack --config webpack.dev.js --progress --colors --watch",
"build": "webpack --config webpack.prod.js --progress --colors --bail",
"postinstall": "bin/heroku",
@@ -129,7 +130,7 @@
"velocity-animate": "^1.4.0",
"visibilityjs": "^1.2.4",
"viz.js": "^1.7.0",
- "winston": "^2.3.0",
+ "winston": "^3.1.0",
"ws": "^6.0.0",
"xss": "^1.0.3"
},
@@ -169,6 +170,12 @@
"css-loader": "^1.0.0",
"doctoc": "^1.3.0",
"ejs-loader": "^0.3.1",
+ "eslint": "^5.9.0",
+ "eslint-config-standard": "^12.0.0",
+ "eslint-plugin-import": "^2.14.0",
+ "eslint-plugin-node": "^8.0.0",
+ "eslint-plugin-promise": "^4.0.1",
+ "eslint-plugin-standard": "^4.0.0",
"exports-loader": "^0.7.0",
"expose-loader": "^0.7.5",
"file-loader": "^2.0.0",
@@ -180,7 +187,6 @@
"mini-css-extract-plugin": "^0.4.1",
"optimize-css-assets-webpack-plugin": "^5.0.0",
"script-loader": "^0.7.2",
- "standard": "^9.0.1",
"string-loader": "^0.0.1",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.7",
@@ -190,34 +196,6 @@
"webpack-merge": "^4.1.4",
"webpack-parallel-uglify-plugin": "^1.1.0"
},
- "standard": {
- "globals": [
- "$",
- "CodeMirror",
- "Cookies",
- "moment",
- "editor",
- "ui",
- "Spinner",
- "modeType",
- "Idle",
- "serverurl",
- "key",
- "gapi",
- "Dropbox",
- "FilePicker",
- "ot",
- "MediaUploader",
- "hex2rgb",
- "num_loaded",
- "Visibility",
- "inlineAttachment"
- ],
- "ignore": [
- "lib/ot",
- "public/vendor"
- ]
- },
"optionalDependencies": {
"bufferutil": "^4.0.0",
"utf-8-validate": "^5.0.1"
diff --git a/public/.eslintrc.js b/public/.eslintrc.js
new file mode 100644
index 00000000..dc37b3cb
--- /dev/null
+++ b/public/.eslintrc.js
@@ -0,0 +1,28 @@
+// this config file is used in concert with the root .eslintrc.js in the root dir.
+module.exports = {
+ "env": {
+ "browser": true
+ },
+ "globals": {
+ "$": false,
+ "CodeMirror": false,
+ "Cookies": false,
+ "moment": false,
+ "editor": false,
+ "ui": false,
+ "Spinner": false,
+ "modeType": false,
+ "Idle": false,
+ "serverurl": false,
+ "key": false,
+ "gapi": false,
+ "Dropbox": false,
+ "FilePicker": false,
+ "ot": false,
+ "MediaUploader": false,
+ "hex2rgb": false,
+ "num_loaded": false,
+ "Visibility": false,
+ "inlineAttachment": false
+ }
+};
diff --git a/public/docs/features.md b/public/docs/features.md
index 31c08d2e..a4ffb633 100644
--- a/public/docs/features.md
+++ b/public/docs/features.md
@@ -72,9 +72,11 @@ Notes can be embedded as follows:
## [Slide Mode](./slide-example):
You can use a special syntax to organize your note into slides.
-After that, you can use the **Slide Mode** <i class="fa fa-tv"></i> to make a presentation.
+After that, you can use the **[Slide Mode](./slide-example)** <i class="fa fa-tv"></i> to make a presentation.
Visit the above link for details.
+To switch the editor into slide mode, set the [document type](./yaml-metadata#type) to `slide`.
+
View
===
## Table of Contents:
diff --git a/public/docs/slide-example.md b/public/docs/slide-example.md
index 5503cbd7..49503669 100644
--- a/public/docs/slide-example.md
+++ b/public/docs/slide-example.md
@@ -1,4 +1,5 @@
---
+type: slide
slideOptions:
transition: slide
---
diff --git a/public/docs/yaml-metadata.md b/public/docs/yaml-metadata.md
index 888345f7..839616a8 100644
--- a/public/docs/yaml-metadata.md
+++ b/public/docs/yaml-metadata.md
@@ -25,7 +25,7 @@ This option will set the note title which prior than content title.
> default: not set
**Example**
-```xml
+```yml
title: meta title
```
@@ -36,7 +36,7 @@ This option will set the note description.
> default: not set
**Example**
-```xml
+```yml
description: meta description
```
@@ -47,7 +47,7 @@ This option will set the tags which prior than content tags.
> default: not set
**Example**
-```xml
+```yml
tags: features, cool, updated
```
@@ -62,7 +62,7 @@ So you can prevent any search engine index your note by set `noindex, nofollow`.
> default: not set
**Example**
-```xml
+```yml
robots: noindex, nofollow
```
@@ -75,13 +75,13 @@ https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
> default: not set (which will be en)
**Example**
-```xml
+```yml
langs: ja-jp
```
dir
---
-This option provide to describe the direction of the text in this note.
+This option specifies the direction of the text in this note.
You can only use whether `rtl` or `ltr`.
Look more at here:
http://www.w3.org/International/questions/qa-html-dir
@@ -89,7 +89,7 @@ http://www.w3.org/International/questions/qa-html-dir
> default: not set (which will be ltr)
**Example**
-```xml
+```yml
dir: rtl
```
@@ -102,35 +102,46 @@ You can only use whether `true` or `false`.
> default: not set (which will be true)
**Example**
-```xml
+```yml
breaks: false
```
GA
---
-This option allow you to enable Google Analytics with your ID.
+This option allows you to enable Google Analytics with your ID.
> default: not set (which won't enable)
**Example**
-```xml
+```yml
GA: UA-12345667-8
```
disqus
---
-This option allow you to enable Disqus with your shortname.
+This option allows you to enable Disqus with your shortname.
> default: not set (which won't enable)
**Example**
-```xml
+```yml
disqus: codimd
```
+type
+---
+This option allows you to switch the document view to the slide preview, to simplify live editing of presentations.
+
+> default: not set
+
+**Example:**
+```yml
+type: slide
+```
+
slideOptions
---
-This option allow you provide custom options to slide mode.
+This option allows you to provide custom options to slide mode.
Please below document for more details:
https://github.com/hakimel/reveal.js/#configuration
@@ -142,7 +153,7 @@ https://github.com/hakimel/reveal.js/tree/master/css/theme
> default: not set (which use default slide options)
**Example**
-```xml
+```yml
slideOptions:
transition: fade
theme: white
diff --git a/public/js/history.js b/public/js/history.js
index b4c26b42..6007bef4 100644
--- a/public/js/history.js
+++ b/public/js/history.js
@@ -218,6 +218,7 @@ export function getStorageHistory (callback) {
if (typeof data === 'string') { data = JSON.parse(data) }
callback(data)
}
+ // eslint-disable-next-line standard/no-callback-literal
callback([])
}
diff --git a/public/js/index.js b/public/js/index.js
index 98c3b6d2..0c575961 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -2511,7 +2511,9 @@ function buildCursor (user) {
// editor actions
function removeNullByte (cm, change) {
var str = change.text.join('\n')
+ // eslint-disable-next-line no-control-regex
if (/\u0000/g.test(str) && change.update) {
+ // eslint-disable-next-line no-control-regex
change.update(change.from, change.to, str.replace(/\u0000/g, '').split('\n'))
}
}
@@ -3046,7 +3048,7 @@ function checkInCode () {
function checkAbove (method) {
var cursor = editor.getCursor()
var text = []
- for (var i = 0; i < cursor.line; i++) { // contain current line
+ for (var i = 0; i < cursor.line; i++) { // contain current line
text.push(editor.getLine(i))
}
text = text.join('\n') + '\n' + editor.getLine(cursor.line).slice(0, cursor.ch)
diff --git a/public/js/lib/editor/index.js b/public/js/lib/editor/index.js
index 0537e927..f05d01b8 100644
--- a/public/js/lib/editor/index.js
+++ b/public/js/lib/editor/index.js
@@ -492,7 +492,7 @@ export default class Editor {
clearInterval(spellcheckTimer)
}
},
- 100,
+ 100
)
}
}
@@ -514,7 +514,7 @@ export default class Editor {
}
setOverrideBrowserKeymap () {
var overrideBrowserKeymap = $(
- '.ui-preferences-override-browser-keymap label > input[type="checkbox"]',
+ '.ui-preferences-override-browser-keymap label > input[type="checkbox"]'
)
if (overrideBrowserKeymap.is(':checked')) {
Cookies.set('preferences-override-browser-keymap', true, {
@@ -529,10 +529,10 @@ export default class Editor {
setPreferences () {
var overrideBrowserKeymap = $(
- '.ui-preferences-override-browser-keymap label > input[type="checkbox"]',
+ '.ui-preferences-override-browser-keymap label > input[type="checkbox"]'
)
var cookieOverrideBrowserKeymap = Cookies.get(
- 'preferences-override-browser-keymap',
+ 'preferences-override-browser-keymap'
)
if (cookieOverrideBrowserKeymap && cookieOverrideBrowserKeymap === 'true') {
overrideBrowserKeymap.prop('checked', true)
diff --git a/public/js/lib/editor/ui-elements.js b/public/js/lib/editor/ui-elements.js
index ca06d30c..29a37782 100644
--- a/public/js/lib/editor/ui-elements.js
+++ b/public/js/lib/editor/ui-elements.js
@@ -67,7 +67,7 @@ export const getUIElements = () => ({
codemirrorScroll: $('.ui-edit-area .CodeMirror .CodeMirror-scroll'),
codemirrorSizer: $('.ui-edit-area .CodeMirror .CodeMirror-sizer'),
codemirrorSizerInner: $(
- '.ui-edit-area .CodeMirror .CodeMirror-sizer > div',
+ '.ui-edit-area .CodeMirror .CodeMirror-sizer > div'
),
markdown: $('.ui-view-area .markdown-body'),
resize: {