Bläddra i källkod

Converted all client code to Standard JS compliant

NGPixel 8 år sedan
förälder
incheckning
547f3065d3

+ 11 - 0
.editorconfig

@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.{jade,pug}]
+trim_trailing_whitespace = false

+ 174 - 0
.eslintrc.json

@@ -0,0 +1,174 @@
+{
+  "parserOptions": {
+    "ecmaVersion": 8,
+    "ecmaFeatures": {
+      "experimentalObjectRestSpread": true,
+      "jsx": true
+    },
+    "sourceType": "module"
+  },
+
+  "env": {
+    "es6": true,
+    "node": true
+  },
+
+  "plugins": [
+    "standard",
+    "promise"
+  ],
+
+  "globals": {
+    "document": false,
+    "navigator": false,
+    "window": false,
+    "app": true,
+    "appconfig": true,
+    "appdata": true,
+    "db": true,
+    "entries": true,
+    "git": true,
+    "lang": true,
+    "lcdata": true,
+    "mark": true,
+    "rights": true,
+    "upl": true,
+    "winston": true,
+    "ws": true,
+    "Mongoose": true,
+    "CORE_PATH": true,
+    "ROOTPATH": true,
+    "IS_DEBUG": true,
+    "PROCNAME": true,
+    "WSInternalKey": true
+  },
+
+  "rules": {
+    "accessor-pairs": 2,
+    "arrow-spacing": [2, { "before": true, "after": true }],
+    "block-spacing": [2, "always"],
+    "brace-style": [2, "1tbs", { "allowSingleLine": true }],
+    "camelcase": [2, { "properties": "never" }],
+    "comma-dangle": [2, "never"],
+    "comma-spacing": [2, { "before": false, "after": true }],
+    "comma-style": [2, "last"],
+    "constructor-super": 2,
+    "curly": [2, "multi-line"],
+    "dot-location": [2, "property"],
+    "eol-last": 2,
+    "eqeqeq": [2, "always", {"null": "ignore"}],
+    "func-call-spacing": [2, "never"],
+    "handle-callback-err": [2, "^(err|error)$" ],
+    "indent": [2, 2, { "SwitchCase": 1 }],
+    "key-spacing": [2, { "beforeColon": false, "afterColon": true }],
+    "keyword-spacing": [2, { "before": true, "after": true }],
+    "new-cap": [2, { "newIsCap": true, "capIsNew": false }],
+    "new-parens": 2,
+    "no-array-constructor": 2,
+    "no-caller": 2,
+    "no-class-assign": 2,
+    "no-cond-assign": 2,
+    "no-const-assign": 2,
+    "no-constant-condition": [2, { "checkLoops": false }],
+    "no-control-regex": 2,
+    "no-debugger": 2,
+    "no-delete-var": 2,
+    "no-dupe-args": 2,
+    "no-dupe-class-members": 2,
+    "no-dupe-keys": 2,
+    "no-duplicate-case": 2,
+    "no-duplicate-imports": 2,
+    "no-empty-character-class": 2,
+    "no-empty-pattern": 2,
+    "no-eval": 2,
+    "no-ex-assign": 2,
+    "no-extend-native": 2,
+    "no-extra-bind": 2,
+    "no-extra-boolean-cast": 2,
+    "no-extra-parens": [2, "functions"],
+    "no-fallthrough": 2,
+    "no-floating-decimal": 2,
+    "no-func-assign": 2,
+    "no-global-assign": 2,
+    "no-implied-eval": 2,
+    "no-inner-declarations": [2, "functions"],
+    "no-invalid-regexp": 2,
+    "no-irregular-whitespace": 2,
+    "no-iterator": 2,
+    "no-label-var": 2,
+    "no-labels": [2, { "allowLoop": false, "allowSwitch": false }],
+    "no-lone-blocks": 2,
+    "no-mixed-spaces-and-tabs": 2,
+    "no-multi-spaces": 2,
+    "no-multi-str": 2,
+    "no-multiple-empty-lines": [2, { "max": 1 }],
+    "no-negated-in-lhs": 2,
+    "no-new": 2,
+    "no-new-func": 2,
+    "no-new-object": 2,
+    "no-new-require": 2,
+    "no-new-symbol": 2,
+    "no-new-wrappers": 2,
+    "no-obj-calls": 2,
+    "no-octal": 2,
+    "no-octal-escape": 2,
+    "no-path-concat": 2,
+    "no-proto": 2,
+    "no-redeclare": 2,
+    "no-regex-spaces": 2,
+    "no-return-assign": [2, "except-parens"],
+    "no-self-assign": 2,
+    "no-self-compare": 2,
+    "no-sequences": 2,
+    "no-shadow-restricted-names": 2,
+    "no-sparse-arrays": 2,
+    "no-tabs": 2,
+    "no-template-curly-in-string": 2,
+    "no-this-before-super": 2,
+    "no-throw-literal": 2,
+    "no-trailing-spaces": 2,
+    "no-undef": 2,
+    "no-undef-init": 2,
+    "no-unexpected-multiline": 2,
+    "no-unmodified-loop-condition": 2,
+    "no-unneeded-ternary": [2, { "defaultAssignment": false }],
+    "no-unreachable": 2,
+    "no-unsafe-finally": 2,
+    "no-unsafe-negation": 2,
+    "no-unused-vars": [2, { "vars": "all", "args": "none" }],
+    "no-useless-call": 2,
+    "no-useless-computed-key": 2,
+    "no-useless-constructor": 2,
+    "no-useless-escape": 2,
+    "no-useless-rename": 2,
+    "no-whitespace-before-property": 2,
+    "no-with": 2,
+    "object-property-newline": [2, { "allowMultiplePropertiesPerLine": true }],
+    "one-var": [2, { "initialized": "never" }],
+    "operator-linebreak": [2, "after", { "overrides": { "?": "before", ":": "before" } }],
+    "padded-blocks": [2, "never"],
+    "quotes": [2, "single", { "avoidEscape": true, "allowTemplateLiterals": true }],
+    "rest-spread-spacing": [2, "never"],
+    "semi": [2, "never"],
+    "semi-spacing": [2, { "before": false, "after": true }],
+    "space-before-blocks": [2, "always"],
+    "space-before-function-paren": [2, "always"],
+    "space-in-parens": [2, "never"],
+    "space-infix-ops": 2,
+    "space-unary-ops": [2, { "words": true, "nonwords": false }],
+    "spaced-comment": [2, "always", { "line": { "markers": ["*package", "!", ","] }, "block": { "balanced": true, "markers": ["*package", "!", ","], "exceptions": ["*"] } }],
+    "template-curly-spacing": [2, "never"],
+    "unicode-bom": [2, "never"],
+    "use-isnan": 2,
+    "valid-typeof": 2,
+    "wrap-iife": [2, "any", { "functionPrototypeMethods": true }],
+    "yield-star-spacing": [2, "both"],
+    "yoda": [2, "never"],
+
+    "standard/object-curly-even-spacing": [2, "either"],
+    "standard/array-bracket-even-spacing": [2, "either"],
+    "standard/computed-property-even-spacing": [2, "even"],
+
+    "promise/param-names": 2
+  }
+}

+ 16 - 0
.pug-lintrc.json

@@ -0,0 +1,16 @@
+{
+  "disallowDuplicateAttributes": true,
+  "disallowIdAttributeWithStaticValue": true,
+  "disallowMultipleLineBreaks": true,
+  "requireClassLiteralsBeforeAttributes": true,
+  "requireIdLiteralsBeforeAttributes": true,
+  "requireLineFeedAtFileEnd": true,
+  "requireLowerCaseAttributes": true,
+  "requireLowerCaseTags": true,
+  "requireSpaceAfterCodeOperator": true,
+  "requireStrictEqualityOperators": true,
+  "validateAttributeQuoteMarks": true,
+  "validateAttributeSeparator": ", ",
+  "validateDivTags": true,
+  "validateIndentation": 2
+}

+ 3 - 2
.vscode/settings.json

@@ -1,3 +1,4 @@
 {
-  "eslint.enable": false
-}
+  "eslint.enable": true,
+  "puglint.enable": true
+}

+ 4 - 2
CHANGELOG.md

@@ -1,13 +1,15 @@
 # Change Log
-All notable changes to this project will be documented in this file.  
+All notable changes to this project will be documented in this file.
 This project adheres to [Semantic Versioning](http://semver.org/).
 
 ## [Unreleased]
 ### Added
 - Change log
+- Added .editorconfig, .eslintrc.json and .pug-lintrc.json for code linting
 
 ### Fixed
 - Fixed issue with social accounts with empty name
+- Fixed standard error page styling
 
 ### Changed
 - Updated dependencies + snyk policy
@@ -21,4 +23,4 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 - Updated dependencies + snyk policy
 
 [Unreleased]: https://github.com/Requarks/wiki/compare/v1.0-beta.2...HEAD
-[v1.0-beta.2]: https://github.com/Requarks/wiki/releases/tag/v1.0-beta.2
+[v1.0-beta.2]: https://github.com/Requarks/wiki/releases/tag/v1.0-beta.2

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
assets/js/app.js


+ 28 - 23
client/js/app.js

@@ -1,20 +1,23 @@
 'use strict'
 
+/* global jQuery, _, io, Sticky, alertsData, Alerts */
+/* eslint-disable spaced-comment */
+
 jQuery(document).ready(function ($) {
-	// ====================================
-	// Scroll
-	// ====================================
+  // ====================================
+  // Scroll
+  // ====================================
 
   $('a').smoothScroll({
     speed: 400,
     offset: -70
   })
 
-  var sticky = new Sticky('.stickyscroll')
+  var sticky = new Sticky('.stickyscroll') // eslint-disable-line no-unused-vars
 
-	// ====================================
-	// Notifications
-	// ====================================
+  // ====================================
+  // Notifications
+  // ====================================
 
   $(window).bind('beforeunload', () => {
     $('#notifload').addClass('active')
@@ -32,26 +35,28 @@ jQuery(document).ready(function ($) {
     })
   }
 
-	// ====================================
-	// Establish WebSocket connection
-	// ====================================
+  // ====================================
+  // Establish WebSocket connection
+  // ====================================
 
-  var socket = io(window.location.origin)
+  var socket = io(window.location.origin) // eslint-disable-line no-unused-vars
 
-	// =include components/search.js
+  //=include components/search.js
 
-	// ====================================
-	// Pages logic
-	// ====================================
+  // ====================================
+  // Pages logic
+  // ====================================
 
-	// =include pages/view.js
-	// =include pages/create.js
-	// =include pages/edit.js
-	// =include pages/source.js
-	// =include pages/admin.js
+  //=include pages/view.js
+  //=include pages/create.js
+  //=include pages/edit.js
+  //=include pages/source.js
+  //=include pages/admin.js
 })
 
-// =include helpers/form.js
-// =include helpers/pages.js
+//=include helpers/form.js
+//=include helpers/pages.js
+
+//=include components/alerts.js
 
-// =include components/alerts.js
+/* eslint-enable spaced-comment */

+ 31 - 29
client/js/components/alerts.js

@@ -1,15 +1,17 @@
 'use strict'
 
+/* global Vue, _ */
+
 /**
  * Alerts
  */
-class Alerts {
+class Alerts { // eslint-disable-line no-unused-vars
 
-	/**
-	 * Constructor
-	 *
-	 * @class
-	 */
+  /**
+   * Constructor
+   *
+   * @class
+   */
   constructor () {
     let self = this
 
@@ -28,12 +30,12 @@ class Alerts {
     self.uidNext = 1
   }
 
-	/**
-	 * Show a new Alert
-	 *
-	 * @param      {Object}  options  Alert properties
-	 * @return     {null}  Void
-	 */
+  /**
+   * Show a new Alert
+   *
+   * @param      {Object}  options  Alert properties
+   * @return     {null}  Void
+   */
   push (options) {
     let self = this
 
@@ -56,12 +58,12 @@ class Alerts {
     self.uidNext++
   }
 
-	/**
-	 * Shorthand method for pushing errors
-	 *
-	 * @param      {String}  title    The title
-	 * @param      {String}  message  The message
-	 */
+  /**
+   * Shorthand method for pushing errors
+   *
+   * @param      {String}  title    The title
+   * @param      {String}  message  The message
+   */
   pushError (title, message) {
     this.push({
       class: 'error',
@@ -71,12 +73,12 @@ class Alerts {
     })
   }
 
-	/**
-	 * Shorthand method for pushing success messages
-	 *
-	 * @param      {String}  title    The title
-	 * @param      {String}  message  The message
-	 */
+  /**
+   * Shorthand method for pushing success messages
+   *
+   * @param      {String}  title    The title
+   * @param      {String}  message  The message
+   */
   pushSuccess (title, message) {
     this.push({
       class: 'success',
@@ -86,11 +88,11 @@ class Alerts {
     })
   }
 
-	/**
-	 * Close an alert
-	 *
-	 * @param      {Integer}  uid     The unique ID of the alert
-	 */
+  /**
+   * Close an alert
+   *
+   * @param      {Integer}  uid     The unique ID of the alert
+   */
   close (uid) {
     let self = this
 

+ 2 - 1
client/js/components/editor-codeblock.js

@@ -1,3 +1,4 @@
+/* global $, Vue, ace, mde, _ */
 
 let modelist = ace.require('ace/ext/modelist')
 let codeEditor = null
@@ -57,7 +58,7 @@ let vueCodeBlock = new Vue({
       }, 300)
     },
     cancel: (ev) => {
-      mdeModalOpenState = false
+      mdeModalOpenState = false  // eslint-disable-line no-undef
       $('#modal-editor-codeblock').removeClass('is-active')
       vueCodeBlock.initContent = ''
     },

+ 27 - 26
client/js/components/editor-file.js

@@ -1,3 +1,4 @@
+/* global $, Vue, _, alerts, mde, socket */
 
 let vueFile = new Vue({
   el: '#modal-editor-file',
@@ -23,18 +24,18 @@ let vueFile = new Vue({
   methods: {
 
     open: () => {
-      mdeModalOpenState = true
+      mdeModalOpenState = true // eslint-disable-line no-undef
       $('#modal-editor-file').addClass('is-active')
       vueFile.refreshFolders()
     },
     cancel: (ev) => {
-      mdeModalOpenState = false
+      mdeModalOpenState = false // eslint-disable-line no-undef
       $('#modal-editor-file').removeClass('is-active')
     },
 
-		// -------------------------------------------
-		// INSERT LINK TO FILE
-		// -------------------------------------------
+    // -------------------------------------------
+    // INSERT LINK TO FILE
+    // -------------------------------------------
 
     selectFile: (fileId) => {
       vueFile.currentFile = fileId
@@ -54,9 +55,9 @@ let vueFile = new Vue({
       vueFile.cancel()
     },
 
-		// -------------------------------------------
-		// NEW FOLDER
-		// -------------------------------------------
+    // -------------------------------------------
+    // NEW FOLDER
+    // -------------------------------------------
 
     newFolder: (ev) => {
       vueFile.newFolderName = ''
@@ -68,7 +69,7 @@ let vueFile = new Vue({
       vueFile.newFolderShow = false
     },
     newFolderCreate: (ev) => {
-      let regFolderName = new RegExp('^[a-z0-9][a-z0-9\-]*[a-z0-9]$')
+      let regFolderName = new RegExp('^[a-z0-9][a-z0-9-]*[a-z0-9]$')
       vueFile.newFolderName = _.kebabCase(_.trim(vueFile.newFolderName))
 
       if (_.isEmpty(vueFile.newFolderName) || !regFolderName.test(vueFile.newFolderName)) {
@@ -90,12 +91,12 @@ let vueFile = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// RENAME FILE
-		// -------------------------------------------
+    // -------------------------------------------
+    // RENAME FILE
+    // -------------------------------------------
 
     renameFile: () => {
-      let c = _.find(vueFile.files, ['_id', vueFile.renameFileId ])
+      let c = _.find(vueFile.files, [ '_id', vueFile.renameFileId ])
       vueFile.renameFileFilename = c.basename || ''
       vueFile.renameFileShow = true
       _.delay(() => {
@@ -123,9 +124,9 @@ let vueFile = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// MOVE FILE
-		// -------------------------------------------
+    // -------------------------------------------
+    // MOVE FILE
+    // -------------------------------------------
 
     moveFile: (uid, fld) => {
       vueFile.isLoadingText = 'Moving file...'
@@ -142,13 +143,13 @@ let vueFile = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// DELETE FILE
-		// -------------------------------------------
+    // -------------------------------------------
+    // DELETE FILE
+    // -------------------------------------------
 
     deleteFileWarn: (show) => {
       if (show) {
-        let c = _.find(vueFile.files, ['_id', vueFile.deleteFileId ])
+        let c = _.find(vueFile.files, [ '_id', vueFile.deleteFileId ])
         vueFile.deleteFileFilename = c.filename || 'this file'
       }
       vueFile.deleteFileShow = show
@@ -164,9 +165,9 @@ let vueFile = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// LOAD FROM REMOTE
-		// -------------------------------------------
+    // -------------------------------------------
+    // LOAD FROM REMOTE
+    // -------------------------------------------
 
     selectFolder: (fldName) => {
       vueFile.currentFolder = fldName
@@ -229,9 +230,9 @@ let vueFile = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// IMAGE CONTEXT MENU
-		// -------------------------------------------
+    // -------------------------------------------
+    // IMAGE CONTEXT MENU
+    // -------------------------------------------
 
     attachContextMenus: () => {
       let moveFolders = _.map(vueFile.folders, (f) => {

+ 30 - 29
client/js/components/editor-image.js

@@ -1,3 +1,4 @@
+/* global $, Vue, mde, _, alerts, socket */
 
 let vueImage = new Vue({
   el: '#modal-editor-image',
@@ -26,18 +27,18 @@ let vueImage = new Vue({
   methods: {
 
     open: () => {
-      mdeModalOpenState = true
+      mdeModalOpenState = true // eslint-disable-line no-undef
       $('#modal-editor-image').addClass('is-active')
       vueImage.refreshFolders()
     },
     cancel: (ev) => {
-      mdeModalOpenState = false
+      mdeModalOpenState = false // eslint-disable-line no-undef
       $('#modal-editor-image').removeClass('is-active')
     },
 
-		// -------------------------------------------
-		// INSERT IMAGE
-		// -------------------------------------------
+    // -------------------------------------------
+    // INSERT IMAGE
+    // -------------------------------------------
 
     selectImage: (imageId) => {
       vueImage.currentImage = imageId
@@ -68,9 +69,9 @@ let vueImage = new Vue({
       vueImage.cancel()
     },
 
-		// -------------------------------------------
-		// NEW FOLDER
-		// -------------------------------------------
+    // -------------------------------------------
+    // NEW FOLDER
+    // -------------------------------------------
 
     newFolder: (ev) => {
       vueImage.newFolderName = ''
@@ -82,7 +83,7 @@ let vueImage = new Vue({
       vueImage.newFolderShow = false
     },
     newFolderCreate: (ev) => {
-      let regFolderName = new RegExp('^[a-z0-9][a-z0-9\-]*[a-z0-9]$')
+      let regFolderName = new RegExp('^[a-z0-9][a-z0-9-]*[a-z0-9]$')
       vueImage.newFolderName = _.kebabCase(_.trim(vueImage.newFolderName))
 
       if (_.isEmpty(vueImage.newFolderName) || !regFolderName.test(vueImage.newFolderName)) {
@@ -104,9 +105,9 @@ let vueImage = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// FETCH FROM URL
-		// -------------------------------------------
+    // -------------------------------------------
+    // FETCH FROM URL
+    // -------------------------------------------
 
     fetchFromUrl: (ev) => {
       vueImage.fetchFromUrlURL = ''
@@ -133,12 +134,12 @@ let vueImage = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// RENAME IMAGE
-		// -------------------------------------------
+    // -------------------------------------------
+    // RENAME IMAGE
+    // -------------------------------------------
 
     renameImage: () => {
-      let c = _.find(vueImage.images, ['_id', vueImage.renameImageId ])
+      let c = _.find(vueImage.images, [ '_id', vueImage.renameImageId ])
       vueImage.renameImageFilename = c.basename || ''
       vueImage.renameImageShow = true
       _.delay(() => {
@@ -166,9 +167,9 @@ let vueImage = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// MOVE IMAGE
-		// -------------------------------------------
+    // -------------------------------------------
+    // MOVE IMAGE
+    // -------------------------------------------
 
     moveImage: (uid, fld) => {
       vueImage.isLoadingText = 'Moving image...'
@@ -185,13 +186,13 @@ let vueImage = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// DELETE IMAGE
-		// -------------------------------------------
+    // -------------------------------------------
+    // DELETE IMAGE
+    // -------------------------------------------
 
     deleteImageWarn: (show) => {
       if (show) {
-        let c = _.find(vueImage.images, ['_id', vueImage.deleteImageId ])
+        let c = _.find(vueImage.images, [ '_id', vueImage.deleteImageId ])
         vueImage.deleteImageFilename = c.filename || 'this image'
       }
       vueImage.deleteImageShow = show
@@ -207,9 +208,9 @@ let vueImage = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// LOAD FROM REMOTE
-		// -------------------------------------------
+    // -------------------------------------------
+    // LOAD FROM REMOTE
+    // -------------------------------------------
 
     selectFolder: (fldName) => {
       vueImage.currentFolder = fldName
@@ -272,9 +273,9 @@ let vueImage = new Vue({
       })
     },
 
-		// -------------------------------------------
-		// IMAGE CONTEXT MENU
-		// -------------------------------------------
+    // -------------------------------------------
+    // IMAGE CONTEXT MENU
+    // -------------------------------------------
 
     attachContextMenus: () => {
       let moveFolders = _.map(vueImage.folders, (f) => {

+ 7 - 6
client/js/components/editor-video.js

@@ -1,8 +1,9 @@
+/* global $, Vue, mde, _ */
 
 const videoRules = {
-  'youtube': new RegExp(/(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/, 'i'),
-  'vimeo': new RegExp(/vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^\/]*)\/videos\/|album\/(?:\d+)\/video\/|)(\d+)(?:$|\/|\?)/, 'i'),
-  'dailymotion': new RegExp(/(?:dailymotion\.com(?:\/embed)?(?:\/video|\/hub)|dai\.ly)\/([0-9a-z]+)(?:[\-_0-9a-zA-Z]+(?:#video=)?([a-z0-9]+)?)?/, 'i')
+  'youtube': new RegExp(/(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|&v(?:i)?=))([^#&?]*).*/, 'i'),
+  'vimeo': new RegExp(/vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^/]*)\/videos\/|album\/(?:\d+)\/video\/|)(\d+)(?:$|\/|\?)/, 'i'),
+  'dailymotion': new RegExp(/(?:dailymotion\.com(?:\/embed)?(?:\/video|\/hub)|dai\.ly)\/([0-9a-z]+)(?:[-_0-9a-zA-Z]+(?:#video=)?([a-z0-9]+)?)?/, 'i')
 }
 
 // Vue Video instance
@@ -18,7 +19,7 @@ let vueVideo = new Vue({
       $('#modal-editor-video input').focus()
     },
     cancel: (ev) => {
-      mdeModalOpenState = false
+      mdeModalOpenState = false // eslint-disable-line no-undef
       $('#modal-editor-video').removeClass('is-active')
       vueVideo.link = ''
     },
@@ -27,7 +28,7 @@ let vueVideo = new Vue({
         mde.codemirror.execCommand('singleSelection')
       }
 
-			// Guess video type
+      // Guess video type
 
       let videoType = _.findKey(videoRules, (vr) => {
         return vr.test(vueVideo.link)
@@ -36,7 +37,7 @@ let vueVideo = new Vue({
         videoType = 'video'
       }
 
-			// Insert video tag
+      // Insert video tag
 
       let videoText = '[video](' + vueVideo.link + '){.' + videoType + '}\n'
 

+ 24 - 18
client/js/components/editor.js

@@ -1,3 +1,6 @@
+'use strict'
+
+/* global $, Vue, _, filesize, SimpleMDE, alerts, vueImage, vueFile, vueVideo, vueCodeBlock */
 
 // ====================================
 // Markdown Editor
@@ -5,16 +8,18 @@
 
 if ($('#mk-editor').length === 1) {
   let mdeModalOpenState = false
-  let mdeCurrentEditor = null
+  let mdeCurrentEditor = null // eslint-disable-line no-unused-vars
 
   Vue.filter('filesize', (v) => {
     return _.toUpper(filesize(v))
   })
 
-	// =include editor-image.js
-	// =include editor-file.js
-	// =include editor-video.js
-	// =include editor-codeblock.js
+  /* eslint-disable spaced-comment */
+  //=include editor-image.js
+  //=include editor-file.js
+  //=include editor-video.js
+  //=include editor-codeblock.js
+  /* eslint-enable spaced-comment */
 
   var mde = new SimpleMDE({
     autofocus: true,
@@ -23,12 +28,13 @@ if ($('#mk-editor').length === 1) {
     placeholder: 'Enter Markdown formatted content here...',
     spellChecker: false,
     status: false,
-    toolbar: [{
-      name: 'bold',
-      action: SimpleMDE.toggleBold,
-      className: 'icon-bold',
-      title: 'Bold'
-    },
+    toolbar: [
+      {
+        name: 'bold',
+        action: SimpleMDE.toggleBold,
+        className: 'icon-bold',
+        title: 'Bold'
+      },
       {
         name: 'italic',
         action: SimpleMDE.toggleItalic,
@@ -83,10 +89,10 @@ if ($('#mk-editor').length === 1) {
       {
         name: 'link',
         action: (editor) => {
-					/* if(!mdeModalOpenState) {
-						mdeModalOpenState = true;
-						$('#modal-editor-link').slideToggle();
-					} */
+          /* if(!mdeModalOpenState) {
+            mdeModalOpenState = true;
+            $('#modal-editor-link').slideToggle();
+          } */
         },
         className: 'icon-link2',
         title: 'Insert Link'
@@ -157,7 +163,7 @@ if ($('#mk-editor').length === 1) {
       {
         name: 'table',
         action: (editor) => {
-					// todo
+          // todo
         },
         className: 'icon-table',
         title: 'Insert Table'
@@ -175,7 +181,7 @@ if ($('#mk-editor').length === 1) {
     }
   })
 
-	// -> Save
+  // -> Save
 
   let saveCurrentDocument = (ev) => {
     $.ajax(window.location.href, {
@@ -186,7 +192,7 @@ if ($('#mk-editor').length === 1) {
       method: 'PUT'
     }).then((rData, rStatus, rXHR) => {
       if (rData.ok) {
-        window.location.assign('/' + pageEntryPath)
+        window.location.assign('/' + pageEntryPath) // eslint-disable-line no-undef
       } else {
         alerts.pushError('Something went wrong', rData.error)
       }

+ 5 - 3
client/js/components/search.js

@@ -1,5 +1,7 @@
 'use strict'
 
+/* global $, Vue, _, socket */
+
 if ($('#search-input').length) {
   $('#search-input').focus()
 
@@ -39,9 +41,9 @@ if ($('#search-input').length) {
       },
       searchmoveidx: (val, oldVal) => {
         if (val > 0) {
-          vueHeader.searchmovekey = (vueHeader.searchmovearr[val - 1]) ?
-																			'res.' + vueHeader.searchmovearr[val - 1]._id :
-																			'sug.' + vueHeader.searchmovearr[val - 1]
+          vueHeader.searchmovekey = (vueHeader.searchmovearr[val - 1])
+            ? 'res.' + vueHeader.searchmovearr[val - 1]._id
+            : 'sug.' + vueHeader.searchmovearr[val - 1]
         } else {
           vueHeader.searchmovekey = ''
         }

+ 3 - 0
client/js/helpers/form.js

@@ -1,3 +1,4 @@
+/* eslint-disable no-unused-vars */
 
 function setInputSelection (input, startPos, endPos) {
   input.focus()
@@ -14,3 +15,5 @@ function setInputSelection (input, startPos, endPos) {
     range.select()
   }
 }
+
+/* eslint-enable no-unused-vars */

+ 4 - 0
client/js/helpers/pages.js

@@ -1,3 +1,5 @@
+/* global _ */
+/* eslint-disable no-unused-vars */
 
 function makeSafePath (rawPath) {
   let rawParts = _.split(_.trim(rawPath), '/')
@@ -7,3 +9,5 @@ function makeSafePath (rawPath) {
 
   return _.join(_.filter(rawParts, (r) => { return !_.isEmpty(r) }), '/')
 }
+
+/* eslint-enable no-unused-vars */

+ 2 - 0
client/js/login.js

@@ -1,5 +1,7 @@
 'use strict'
 
+/* global jQuery */
+
 jQuery(document).ready(function ($) {
   $('#login-user').focus()
 })

+ 1 - 0
client/js/modals/admin-users-create.js

@@ -1,3 +1,4 @@
+/* global $, Vue */
 
 // Vue Create User instance
 

+ 1 - 0
client/js/modals/admin-users-delete.js

@@ -1,3 +1,4 @@
+/* global $, Vue */
 
 // Vue Delete User instance
 

+ 3 - 2
client/js/modals/create.js

@@ -1,3 +1,4 @@
+/* global $, _, currentBasePath */
 
 // -> Create New Document
 
@@ -6,7 +7,7 @@ let suggestedCreatePath = currentBasePath + '/new-page'
 $('.btn-create-prompt').on('click', (ev) => {
   $('#txt-create-prompt').val(suggestedCreatePath)
   $('#modal-create-prompt').toggleClass('is-active')
-  setInputSelection($('#txt-create-prompt').get(0), currentBasePath.length + 1, suggestedCreatePath.length)
+  setInputSelection($('#txt-create-prompt').get(0), currentBasePath.length + 1, suggestedCreatePath.length) // eslint-disable-line no-undef
   $('#txt-create-prompt').removeClass('is-danger').next().addClass('is-hidden')
 })
 
@@ -17,7 +18,7 @@ $('#txt-create-prompt').on('keypress', (ev) => {
 })
 
 $('.btn-create-go').on('click', (ev) => {
-  let newDocPath = makeSafePath($('#txt-create-prompt').val())
+  let newDocPath = makeSafePath($('#txt-create-prompt').val()) // eslint-disable-line no-undef
   if (_.isEmpty(newDocPath)) {
     $('#txt-create-prompt').addClass('is-danger').next().removeClass('is-hidden')
   } else {

+ 3 - 2
client/js/modals/move.js

@@ -1,3 +1,4 @@
+/* global $, _, alerts, currentBasePath */
 
 // -> Move Existing Document
 
@@ -10,7 +11,7 @@ let moveInitialDocument = _.lastIndexOf(currentBasePath, '/') + 1
 $('.btn-move-prompt').on('click', (ev) => {
   $('#txt-move-prompt').val(currentBasePath)
   $('#modal-move-prompt').toggleClass('is-active')
-  setInputSelection($('#txt-move-prompt').get(0), moveInitialDocument, currentBasePath.length)
+  setInputSelection($('#txt-move-prompt').get(0), moveInitialDocument, currentBasePath.length) // eslint-disable-line no-undef
   $('#txt-move-prompt').removeClass('is-danger').next().addClass('is-hidden')
 })
 
@@ -21,7 +22,7 @@ $('#txt-move-prompt').on('keypress', (ev) => {
 })
 
 $('.btn-move-go').on('click', (ev) => {
-  let newDocPath = makeSafePath($('#txt-move-prompt').val())
+  let newDocPath = makeSafePath($('#txt-move-prompt').val()) // eslint-disable-line no-undef
   if (_.isEmpty(newDocPath) || newDocPath === currentBasePath || newDocPath === 'home') {
     $('#txt-move-prompt').addClass('is-danger').next().removeClass('is-hidden')
   } else {

+ 7 - 2
client/js/pages/admin.js

@@ -1,3 +1,4 @@
+/* global $, Vue, alerts, _, usrData, usrDataName */
 
 if ($('#page-type-admin-profile').length) {
   let vueProfile = new Vue({
@@ -29,7 +30,9 @@ if ($('#page-type-admin-profile').length) {
   })
 } else if ($('#page-type-admin-users').length) {
 
-	// =include ../modals/admin-users-create.js
+  /* eslint-disable spaced-comment */
+  //=include ../modals/admin-users-create.js
+  /* eslint-enable spaced-comment */
 
 } else if ($('#page-type-admin-users-edit').length) {
   let vueEditUser = new Vue({
@@ -92,5 +95,7 @@ if ($('#page-type-admin-profile').length) {
     }
   })
 
-	// =include ../modals/admin-users-delete.js
+  /* eslint-disable spaced-comment */
+  //=include ../modals/admin-users-delete.js
+  /* eslint-enable spaced-comment */
 }

+ 6 - 3
client/js/pages/create.js

@@ -1,12 +1,15 @@
+/* global $ */
 
 if ($('#page-type-create').length) {
-  let pageEntryPath = $('#page-type-create').data('entrypath')
+  let pageEntryPath = $('#page-type-create').data('entrypath') // eslint-disable-line no-unused-vars
 
-	// -> Discard
+  // -> Discard
 
   $('.btn-create-discard').on('click', (ev) => {
     $('#modal-create-discard').toggleClass('is-active')
   })
 
-	// =include ../components/editor.js
+  /* eslint-disable spaced-comment */
+  //=include ../components/editor.js
+  /* eslint-enable spaced-comment */
 }

+ 6 - 3
client/js/pages/edit.js

@@ -1,12 +1,15 @@
+/* global $ */
 
 if ($('#page-type-edit').length) {
-  let pageEntryPath = $('#page-type-edit').data('entrypath')
+  let pageEntryPath = $('#page-type-edit').data('entrypath') // eslint-disable-line no-unused-vars
 
-	// -> Discard
+  // -> Discard
 
   $('.btn-edit-discard').on('click', (ev) => {
     $('#modal-edit-discard').toggleClass('is-active')
   })
 
-	// =include ../components/editor.js
+  /* eslint-disable spaced-comment */
+  //=include ../components/editor.js
+  /* eslint-enable spaced-comment */
 }

+ 6 - 3
client/js/pages/source.js

@@ -1,3 +1,4 @@
+/* global $, ace */
 
 if ($('#page-type-source').length) {
   var scEditor = ace.edit('source-display')
@@ -9,8 +10,10 @@ if ($('#page-type-source').length) {
   scEditor.setReadOnly(true)
   scEditor.renderer.updateFull()
 
-  let currentBasePath = ($('#page-type-source').data('entrypath') !== 'home') ? $('#page-type-source').data('entrypath') : ''
+  let currentBasePath = ($('#page-type-source').data('entrypath') !== 'home') ? $('#page-type-source').data('entrypath') : '' // eslint-disable-line no-unused-vars
 
-  // =include ../modals/create.js
-	// =include ../modals/move.js
+  /* eslint-disable spaced-comment */
+  //=include ../modals/create.js
+  //=include ../modals/move.js
+  /* eslint-enable spaced-comment */
 }

+ 6 - 3
client/js/pages/view.js

@@ -1,7 +1,10 @@
+/* global $ */
 
 if ($('#page-type-view').length) {
-  let currentBasePath = ($('#page-type-view').data('entrypath') !== 'home') ? $('#page-type-view').data('entrypath') : ''
+  let currentBasePath = ($('#page-type-view').data('entrypath') !== 'home') ? $('#page-type-view').data('entrypath') : '' // eslint-disable-line no-unused-vars
 
-	// =include ../modals/create.js
-	// =include ../modals/move.js
+  /* eslint-disable spaced-comment */
+  //=include ../modals/create.js
+  //=include ../modals/move.js
+  /* eslint-enable spaced-comment */
 }

+ 6 - 2
package.json

@@ -6,7 +6,7 @@
   "scripts": {
     "start": "node server",
     "dev": "gulp dev",
-    "test": "snyk test && istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec ./tests/index.js && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage",
+    "test": "snyk test && standard && pug-lint ./views",
     "snyk-protect": "snyk protect",
     "__prepublish": "npm run snyk-protect"
   },
@@ -101,6 +101,9 @@
     "chai": "^3.5.0",
     "chai-as-promised": "^6.0.0",
     "codacy-coverage": "^2.0.0",
+    "eslint": "^3.15.0",
+    "eslint-plugin-promise": "^3.4.1",
+    "eslint-plugin-standard": "^2.0.1",
     "gulp": "^3.9.1",
     "gulp-babel": "^6.1.2",
     "gulp-clean-css": "^3.0.0",
@@ -123,6 +126,7 @@
     "mocha": "^3.2.0",
     "mocha-lcov-reporter": "^1.2.0",
     "nodemon": "^1.11.0",
+    "pug-lint": "^2.4.0",
     "run-sequence": "^1.2.2",
     "snyk": "^1.24.6",
     "sticky-js": "^1.1.9",
@@ -130,7 +134,7 @@
     "vue": "^2.1.10"
   },
   "standard": {
-     "globals": [
+    "globals": [
       "app",
       "appconfig",
       "appdata",

+ 0 - 12
wiki.sublime-project

@@ -1,12 +0,0 @@
-{
-	"folders":
-	[
-		{
-			"file_exclude_patterns":
-			[
-				"wiki.sublime-project"
-			],
-			"path": "."
-		}
-	]
-}

Vissa filer visades inte eftersom för många filer har ändrats