diff --git a/client/.eslintrc.yml b/client/.eslintrc.yml
new file mode 100644
index 0000000..a176248
--- /dev/null
+++ b/client/.eslintrc.yml
@@ -0,0 +1,293 @@
+env:
+ browser: true
+ commonjs: true
+ es6: true
+extends: 'eslint:recommended'
+globals:
+ Atomics: readonly
+ SharedArrayBuffer: readonly
+ignorePatterns:
+ - build.js
+parserOptions:
+ ecmaVersion: 11
+rules:
+ accessor-pairs: error
+ array-bracket-newline: error
+ array-bracket-spacing:
+ - error
+ - never
+ array-callback-return: error
+ array-element-newline: 'off'
+ arrow-body-style: 'off'
+ arrow-parens:
+ - error
+ - as-needed
+ arrow-spacing:
+ - error
+ - after: true
+ before: true
+ block-scoped-var: error
+ block-spacing: error
+ brace-style:
+ - error
+ - 1tbs
+ callback-return: 'off'
+ camelcase: error
+ class-methods-use-this: 'off'
+ comma-dangle: 'off'
+ comma-spacing:
+ - error
+ - after: true
+ before: false
+ comma-style:
+ - error
+ - last
+ complexity: 'off'
+ computed-property-spacing:
+ - error
+ - never
+ consistent-return: 'off'
+ consistent-this: 'off'
+ curly: error
+ default-case: error
+ default-case-last: error
+ default-param-last: error
+ dot-location:
+ - error
+ - property
+ dot-notation:
+ - error
+ - allowKeywords: true
+ eol-last: error
+ eqeqeq: error
+ func-call-spacing: error
+ func-name-matching: error
+ func-names: error
+ func-style:
+ - error
+ - declaration
+ - allowArrowFunctions: true
+ function-call-argument-newline:
+ - error
+ - consistent
+ function-paren-newline: 'off'
+ generator-star-spacing: error
+ global-require: 'off'
+ grouped-accessor-pairs: 'off'
+ guard-for-in: error
+ handle-callback-err: error
+ id-blacklist: error
+ id-length: 'off'
+ id-match: error
+ implicit-arrow-linebreak:
+ - error
+ - beside
+ indent:
+ - error
+ - 4
+ indent-legacy: 'off'
+ init-declarations: error
+ jsx-quotes: error
+ key-spacing: error
+ keyword-spacing:
+ - error
+ - after: true
+ before: true
+ line-comment-position: 'off'
+ linebreak-style:
+ - error
+ - unix
+ lines-around-comment: error
+ lines-around-directive: error
+ lines-between-class-members:
+ - error
+ - always
+ max-classes-per-file: 'off'
+ max-depth: error
+ max-len: 'off'
+ max-lines: 'off'
+ max-lines-per-function: 'off'
+ max-nested-callbacks: error
+ max-params: 'off'
+ max-statements: 'off'
+ max-statements-per-line: error
+ multiline-comment-style:
+ - error
+ - separate-lines
+ multiline-ternary: 'off'
+ new-cap: error
+ new-parens: error
+ newline-after-var: 'off'
+ newline-before-return: 'off'
+ newline-per-chained-call: 'off'
+ no-alert: 'off'
+ no-array-constructor: error
+ no-await-in-loop: error
+ no-bitwise: 'off'
+ no-buffer-constructor: 'off'
+ no-caller: error
+ no-catch-shadow: error
+ no-confusing-arrow: error
+ no-console: error
+ no-constructor-return: error
+ no-continue: 'off'
+ no-div-regex: 'off'
+ no-duplicate-imports: error
+ no-else-return: 'off'
+ no-empty-function: 'off'
+ no-eq-null: error
+ no-eval: error
+ no-extend-native: error
+ no-extra-bind: error
+ no-extra-label: error
+ no-extra-parens: 'off'
+ no-floating-decimal: error
+ no-implicit-globals: error
+ no-implied-eval: error
+ no-inline-comments: 'off'
+ no-invalid-this: error
+ no-iterator: error
+ no-label-var: error
+ no-labels: error
+ no-lone-blocks: error
+ no-lonely-if: error
+ no-loop-func: 'off'
+ no-loss-of-precision: error
+ no-magic-numbers: 'off'
+ no-mixed-operators: error
+ no-mixed-requires: error
+ no-multi-assign: error
+ no-multi-spaces:
+ - error
+ - ignoreEOLComments: true
+ no-multi-str: error
+ no-multiple-empty-lines: error
+ no-native-reassign: error
+ no-negated-condition: 'off'
+ no-negated-in-lhs: error
+ no-nested-ternary: error
+ no-new: 'off'
+ no-new-func: error
+ no-new-object: error
+ no-new-require: error
+ no-new-wrappers: error
+ no-octal-escape: error
+ no-param-reassign: 'off'
+ no-path-concat: error
+ no-plusplus: 'off'
+ no-process-env: error
+ no-process-exit: error
+ no-proto: error
+ no-restricted-exports: error
+ no-restricted-globals: error
+ no-restricted-imports: error
+ no-restricted-modules: error
+ no-restricted-properties: error
+ no-restricted-syntax: error
+ no-return-assign: error
+ no-return-await: error
+ no-script-url: error
+ no-self-compare: error
+ no-sequences: error
+ no-shadow: 'off'
+ no-spaced-func: error
+ no-sync: error
+ no-tabs: error
+ no-template-curly-in-string: error
+ no-ternary: 'off'
+ no-throw-literal: 'off'
+ no-trailing-spaces: error
+ no-undef-init: error
+ no-undefined: 'off'
+ no-underscore-dangle: 'off'
+ no-unmodified-loop-condition: error
+ no-unneeded-ternary: error
+ no-unused-expressions: error
+ no-unused-vars: 'off'
+ no-use-before-define: 'off'
+ no-useless-backreference: error
+ no-useless-call: error
+ no-useless-computed-key: error
+ no-useless-concat: error
+ no-useless-constructor: error
+ no-useless-escape: 'off'
+ no-useless-rename: error
+ no-useless-return: error
+ no-var: 'off'
+ no-void: error
+ no-warning-comments: warn
+ no-whitespace-before-property: error
+ nonblock-statement-body-position: error
+ object-curly-newline: error
+ object-curly-spacing:
+ - error
+ - never
+ object-shorthand: 'off'
+ one-var: 'off'
+ one-var-declaration-per-line: error
+ operator-assignment:
+ - error
+ - always
+ operator-linebreak: 'off'
+ padded-blocks: 'off'
+ padding-line-between-statements: error
+ prefer-arrow-callback: error
+ prefer-const: 'off'
+ prefer-destructuring: 'off'
+ prefer-exponentiation-operator: 'off'
+ prefer-named-capture-group: 'off'
+ prefer-numeric-literals: error
+ prefer-object-spread: 'off'
+ prefer-promise-reject-errors: 'off'
+ prefer-reflect: 'off'
+ prefer-regex-literals: warn
+ prefer-rest-params: 'off'
+ prefer-spread: 'off'
+ prefer-template: 'off'
+ quote-props: 'off'
+ quotes: 'off'
+ radix:
+ - error
+ - as-needed
+ require-atomic-updates: error
+ require-await: error
+ require-jsdoc: 'off'
+ require-unicode-regexp: 'off'
+ rest-spread-spacing: error
+ semi: 'off'
+ semi-spacing:
+ - error
+ - after: true
+ before: false
+ semi-style:
+ - error
+ - last
+ sort-imports: error
+ sort-keys: 'off'
+ sort-vars: error
+ space-before-blocks: error
+ space-before-function-paren: 'off'
+ space-in-parens:
+ - error
+ - never
+ space-infix-ops: error
+ space-unary-ops: error
+ spaced-comment:
+ - error
+ - always
+ strict: error
+ switch-colon-spacing: error
+ symbol-description: error
+ template-curly-spacing:
+ - error
+ - never
+ template-tag-spacing: error
+ unicode-bom:
+ - error
+ - never
+ valid-jsdoc: error
+ vars-on-top: error
+ wrap-iife: error
+ wrap-regex: error
+ yield-star-spacing: error
+ yoda: 'off'
diff --git a/client/js/api.js b/client/js/api.js
index 07ec5ec..303c077 100644
--- a/client/js/api.js
+++ b/client/js/api.js
@@ -377,8 +377,9 @@ class Api extends events.EventTarget {
try {
if (this.userName && this.token) {
req.auth = null;
- req.set('Authorization', 'Token '
- + new Buffer(this.userName + ":" + this.token).toString('base64'))
+ // eslint-disable-next-line no-undef
+ req.set('Authorization', 'Token ' + new Buffer(
+ this.userName + ":" + this.token).toString('base64'))
} else if (this.userName && this.userPassword) {
req.auth(
this.userName,
diff --git a/client/js/controllers/comments_controller.js b/client/js/controllers/comments_controller.js
index 2de638c..67e44ac 100644
--- a/client/js/controllers/comments_controller.js
+++ b/client/js/controllers/comments_controller.js
@@ -34,7 +34,9 @@ class CommentsController {
requestPage: (offset, limit) => {
return PostList.search(
'sort:comment-date comment-count-min:1',
- offset, limit, fields);
+ offset,
+ limit,
+ fields);
},
pageRenderer: pageCtx => {
Object.assign(pageCtx, {
@@ -68,9 +70,10 @@ class CommentsController {
e.detail.comment.delete()
.catch(error => window.alert(error.message));
}
-};
+}
module.exports = router => {
- router.enter(['comments'],
- (ctx, next) => { new CommentsController(ctx); });
-};
+ router.enter(['comments'], (ctx, next) => {
+ new CommentsController(ctx);
+ });
+}
diff --git a/client/js/controllers/home_controller.js b/client/js/controllers/home_controller.js
index cc22ca9..590da67 100644
--- a/client/js/controllers/home_controller.js
+++ b/client/js/controllers/home_controller.js
@@ -41,10 +41,10 @@ class HomeController {
showError(message) {
this._homeView.showError(message);
}
-};
+}
module.exports = router => {
router.enter([], (ctx, next) => {
ctx.controller = new HomeController();
});
-};
+}
diff --git a/client/js/controllers/not_found_controller.js b/client/js/controllers/not_found_controller.js
index 66f52e9..8ceeef0 100644
--- a/client/js/controllers/not_found_controller.js
+++ b/client/js/controllers/not_found_controller.js
@@ -9,10 +9,10 @@ class NotFoundController {
topNavigation.setTitle('Not found');
this._notFoundView = new NotFoundView(path);
}
-};
+}
module.exports = router => {
router.enter(null, (ctx, next) => {
ctx.controller = new NotFoundController(ctx.canonicalPath);
});
-};
+}
diff --git a/client/js/controllers/post_detail_controller.js b/client/js/controllers/post_detail_controller.js
index 47d5430..bd9c2e6 100644
--- a/client/js/controllers/post_detail_controller.js
+++ b/client/js/controllers/post_detail_controller.js
@@ -57,7 +57,8 @@ class PostDetailController extends BasePostController {
if (this._id !== e.detail.post.id) {
router.replace(
uri.formatClientLink('post', e.detail.post.id, section),
- null, false);
+ null,
+ false);
}
}
@@ -71,7 +72,8 @@ class PostDetailController extends BasePostController {
router.replace(
uri.formatClientLink(
'post', e.detail.targetPost.id, 'merge'),
- null, false);
+ null,
+ false);
}, error => {
this._view.showError(error.message);
this._view.enableForm();
diff --git a/client/js/controllers/post_list_controller.js b/client/js/controllers/post_list_controller.js
index fd1adfe..d783607 100644
--- a/client/js/controllers/post_list_controller.js
+++ b/client/js/controllers/post_list_controller.js
@@ -13,7 +13,8 @@ const EmptyView = require('../views/empty_view.js');
const fields = [
'id', 'thumbnailUrl', 'type', 'safety',
- 'score', 'favoriteCount', 'commentCount', 'tags', 'version'];
+ 'score', 'favoriteCount', 'commentCount', 'tags', 'version'
+];
class PostListController {
constructor(ctx) {
@@ -62,8 +63,7 @@ class PostListController {
_evtTag(e) {
Promise.all(
- this._bulkEditTags.map(tag =>
- e.detail.post.tags.addByName(tag)))
+ this._bulkEditTags.map(tag => e.detail.post.tags.addByName(tag)))
.then(e.detail.post.save())
.catch(error => window.alert(error.message));
}
@@ -117,5 +117,7 @@ class PostListController {
module.exports = router => {
router.enter(
['posts'],
- (ctx, next) => { ctx.controller = new PostListController(ctx); });
+ (ctx, next) => {
+ ctx.controller = new PostListController(ctx);
+ });
};
diff --git a/client/js/controllers/post_main_controller.js b/client/js/controllers/post_main_controller.js
index 1914852..924e918 100644
--- a/client/js/controllers/post_main_controller.js
+++ b/client/js/controllers/post_main_controller.js
@@ -18,10 +18,10 @@ class PostMainController extends BasePostController {
let parameters = ctx.parameters;
Promise.all([
- Post.get(ctx.parameters.id),
- PostList.getAround(
- ctx.parameters.id,
- parameters ? parameters.query : null),
+ Post.get(ctx.parameters.id),
+ PostList.getAround(
+ ctx.parameters.id,
+ parameters ? parameters.query : null),
]).then(responses => {
const [post, aroundResponse] = responses;
diff --git a/client/js/controllers/post_upload_controller.js b/client/js/controllers/post_upload_controller.js
index 1124ff7..f16aaf0 100644
--- a/client/js/controllers/post_upload_controller.js
+++ b/client/js/controllers/post_upload_controller.js
@@ -57,33 +57,32 @@ class PostUploadController {
this._view.clearMessages();
e.detail.uploadables.reduce(
- (promise, uploadable) =>
- promise.then(() => this._uploadSinglePost(
- uploadable, e.detail.skipDuplicates)),
+ (promise, uploadable) => promise.then(() => this._uploadSinglePost(
+ uploadable, e.detail.skipDuplicates)),
Promise.resolve())
- .then(() => {
- this._view.clearMessages();
- misc.disableExitConfirmation();
- const ctx = router.show(uri.formatClientLink('posts'));
- ctx.controller.showSuccess('Posts uploaded.');
- }, error => {
- if (error.uploadable) {
- if (error.similarPosts) {
- error.uploadable.lookalikes = error.similarPosts;
- this._view.updateUploadable(error.uploadable);
- this._view.showInfo(genericErrorMessage);
- this._view.showInfo(
- error.message, error.uploadable);
- } else {
- this._view.showError(genericErrorMessage);
- this._view.showError(
- error.message, error.uploadable);
- }
+ .then(() => {
+ this._view.clearMessages();
+ misc.disableExitConfirmation();
+ const ctx = router.show(uri.formatClientLink('posts'));
+ ctx.controller.showSuccess('Posts uploaded.');
+ }, error => {
+ if (error.uploadable) {
+ if (error.similarPosts) {
+ error.uploadable.lookalikes = error.similarPosts;
+ this._view.updateUploadable(error.uploadable);
+ this._view.showInfo(genericErrorMessage);
+ this._view.showInfo(
+ error.message, error.uploadable);
} else {
- this._view.showError(error.message);
+ this._view.showError(genericErrorMessage);
+ this._view.showError(
+ error.message, error.uploadable);
}
- this._view.enableForm();
- });
+ } else {
+ this._view.showError(error.message);
+ }
+ this._view.enableForm();
+ });
}
_uploadSinglePost(uploadable, skipDuplicates) {
@@ -153,7 +152,9 @@ class PostUploadController {
post.newContent = uploadable.url || uploadable.file;
// if uploadable.source is ever going to be a valid field (e.g when setting source directly in the upload window)
// you'll need to change the line below to `post.source = uploadable.source || uploadable.url;`
- if (uploadable.url) post.source = uploadable.url;
+ if (uploadable.url) {
+ post.source = uploadable.url;
+ }
return post;
}
}
diff --git a/client/js/controllers/settings_controller.js b/client/js/controllers/settings_controller.js
index 224b205..7765143 100644
--- a/client/js/controllers/settings_controller.js
+++ b/client/js/controllers/settings_controller.js
@@ -19,7 +19,7 @@ class SettingsController {
settings.save(e.detail);
this._view.showSuccess('Settings saved.');
}
-};
+}
module.exports = router => {
router.enter(['settings'], (ctx, next) => {
diff --git a/client/js/controllers/snapshots_controller.js b/client/js/controllers/snapshots_controller.js
index e64b9db..0e9b773 100644
--- a/client/js/controllers/snapshots_controller.js
+++ b/client/js/controllers/snapshots_controller.js
@@ -45,5 +45,7 @@ class SnapshotsController {
module.exports = router => {
router.enter(['history'],
- (ctx, next) => { ctx.controller = new SnapshotsController(ctx); });
+ (ctx, next) => {
+ ctx.controller = new SnapshotsController(ctx);
+ });
};
diff --git a/client/js/controllers/tag_controller.js b/client/js/controllers/tag_controller.js
index d64ab22..71405dc 100644
--- a/client/js/controllers/tag_controller.js
+++ b/client/js/controllers/tag_controller.js
@@ -69,7 +69,8 @@ class TagController {
if (this._name !== e.detail.tag.names[0]) {
router.replace(
uri.formatClientLink('tag', e.detail.tag.names[0], section),
- null, false);
+ null,
+ false);
}
}
@@ -105,7 +106,8 @@ class TagController {
router.replace(
uri.formatClientLink(
'tag', e.detail.targetTagName, 'merge'),
- null, false);
+ null,
+ false);
}, error => {
this._view.showError(error.message);
this._view.enableForm();
diff --git a/client/js/controllers/tag_list_controller.js b/client/js/controllers/tag_list_controller.js
index 8bc7dbb..db31cc6 100644
--- a/client/js/controllers/tag_list_controller.js
+++ b/client/js/controllers/tag_list_controller.js
@@ -16,7 +16,8 @@ const fields = [
'implications',
'creationTime',
'usages',
- 'category'];
+ 'category'
+];
class TagListController {
constructor(ctx) {
@@ -81,5 +82,7 @@ class TagListController {
module.exports = router => {
router.enter(
['tags'],
- (ctx, next) => { ctx.controller = new TagListController(ctx); });
+ (ctx, next) => {
+ ctx.controller = new TagListController(ctx);
+ });
};
diff --git a/client/js/controllers/user_controller.js b/client/js/controllers/user_controller.js
index 48989af..e192d87 100644
--- a/client/js/controllers/user_controller.js
+++ b/client/js/controllers/user_controller.js
@@ -42,7 +42,7 @@ class UserController {
userTokenPromise,
User.get(userName)
]).then(responses => {
- const [userTokens, user] = responses;
+ const [userTokens, user] = responses;
const isLoggedIn = api.isLoggedIn(user);
const infix = isLoggedIn ? 'self' : 'any';
@@ -133,7 +133,8 @@ class UserController {
if (this._name !== e.detail.user.name) {
router.replace(
uri.formatClientLink('user', e.detail.user.name, section),
- null, false);
+ null,
+ false);
}
}
diff --git a/client/js/controllers/user_list_controller.js b/client/js/controllers/user_list_controller.js
index fa878d8..13dcf43 100644
--- a/client/js/controllers/user_list_controller.js
+++ b/client/js/controllers/user_list_controller.js
@@ -51,7 +51,7 @@ class UserListController {
defaultLimit: 30,
getClientUrlForPage: (offset, limit) => {
const parameters = Object.assign(
- {}, this._ctx.parameters, {offset, offset, limit: limit});
+ {}, this._ctx.parameters, {offset: offset, limit: limit});
return uri.formatClientLink('users', parameters);
},
requestPage: (offset, limit) => {
@@ -71,5 +71,7 @@ class UserListController {
module.exports = router => {
router.enter(
['users'],
- (ctx, next) => { ctx.controller = new UserListController(ctx); });
+ (ctx, next) => {
+ ctx.controller = new UserListController(ctx);
+ });
};
diff --git a/client/js/controls/auto_complete_control.js b/client/js/controls/auto_complete_control.js
index 5ce3bb2..a802209 100644
--- a/client/js/controls/auto_complete_control.js
+++ b/client/js/controls/auto_complete_control.js
@@ -121,7 +121,9 @@ class AutoCompleteControl {
document.body.appendChild(this._suggestionDiv);
views.monitorNodeRemoval(
- this._sourceInputNode, () => { this._uninstall(); });
+ this._sourceInputNode, () => {
+ this._uninstall();
+ });
}
_uninstall() {
@@ -137,13 +139,21 @@ class AutoCompleteControl {
if (key === KEY_ESCAPE) {
func = this.hide;
} else if (key === KEY_TAB && shift) {
- func = () => { this._selectPrevious(); };
+ func = () => {
+ this._selectPrevious();
+ };
} else if (key === KEY_TAB && !shift) {
- func = () => { this._selectNext(); };
+ func = () => {
+ this._selectNext();
+ };
} else if (key === KEY_UP) {
- func = () => { this._selectPrevious(); };
+ func = () => {
+ this._selectPrevious();
+ };
} else if (key === KEY_DOWN) {
- func = () => { this._selectNext(); };
+ func = () => {
+ this._selectNext();
+ };
} else if (key === KEY_RETURN && this._activeResult >= 0) {
func = () => {
this._confirm(this._getActiveSuggestion());
@@ -165,13 +175,17 @@ class AutoCompleteControl {
} else {
window.clearTimeout(this._showTimeout);
this._showTimeout = window.setTimeout(
- () => { this._showOrHide(); }, 250);
+ () => {
+ this._showOrHide();
+ }, 250);
}
}
_evtBlur(e) {
window.clearTimeout(this._showTimeout);
- window.setTimeout(() => { this.hide(); }, 50);
+ window.setTimeout(() => {
+ this.hide();
+ }, 50);
}
_getActiveSuggestion() {
@@ -261,10 +275,10 @@ class AutoCompleteControl {
// choose where to view the suggestions: if there's more space above
// the input - draw the suggestions above it, otherwise below
const direction =
- inputRect.top + inputRect.height / 2 < viewPortHeight / 2 ? 1 : -1;
+ inputRect.top + (inputRect.height / 2) < viewPortHeight / 2 ? 1 : -1;
let x = inputRect.left - bodyRect.left;
- let y = direction == 1 ?
+ let y = direction === 1 ?
inputRect.bottom - bodyRect.top - verticalShift :
inputRect.top - bodyRect.top - listRect.height + verticalShift;
@@ -276,7 +290,7 @@ class AutoCompleteControl {
const prevHeight = listRect.height;
listRect = this._suggestionDiv.getBoundingClientRect();
const heightDelta = prevHeight - listRect.height;
- if (direction == -1) {
+ if (direction === -1) {
y += heightDelta;
}
}
@@ -296,6 +310,6 @@ class AutoCompleteControl {
activeItem.classList.add('active');
}
}
-};
+}
module.exports = AutoCompleteControl;
diff --git a/client/js/controls/comment_control.js b/client/js/controls/comment_control.js
index 849dd4d..c105bc0 100644
--- a/client/js/controls/comment_control.js
+++ b/client/js/controls/comment_control.js
@@ -212,11 +212,6 @@ class CommentControl extends events.EventTarget {
this._selectTab('preview');
}
- _evtEditClick(e) {
- e.preventDefault();
- this.enterEditMode();
- }
-
_evtSaveChangesClick(e) {
e.preventDefault();
this.dispatchEvent(new CustomEvent('submit', {
@@ -260,6 +255,6 @@ class CommentControl extends events.EventTarget {
_forgetHeight() {
this._heightKeeperNode.style.minHeight = null;
}
-};
+}
module.exports = CommentControl;
diff --git a/client/js/controls/comment_list_control.js b/client/js/controls/comment_list_control.js
index ddef71f..4f57fd2 100644
--- a/client/js/controls/comment_list_control.js
+++ b/client/js/controls/comment_list_control.js
@@ -54,6 +54,6 @@ class CommentListControl extends events.EventTarget {
_evtRemove(e) {
this._uninstallCommentNode(e.detail.comment);
}
-};
+}
module.exports = CommentListControl;
diff --git a/client/js/controls/expander_control.js b/client/js/controls/expander_control.js
index beb0e69..28a4ffb 100644
--- a/client/js/controls/expander_control.js
+++ b/client/js/controls/expander_control.js
@@ -39,6 +39,7 @@ class ExpanderControl {
this._syncIcon();
}
+ // eslint-disable-next-line accessor-pairs
set title(newTitle) {
if (this._expanderNode) {
this._expanderNode
diff --git a/client/js/controls/post_content_control.js b/client/js/controls/post_content_control.js
index 856fb77..d1848b3 100644
--- a/client/js/controls/post_content_control.js
+++ b/client/js/controls/post_content_control.js
@@ -107,7 +107,9 @@ class PostContentControl {
this._reinstall();
optimizedResize.add(() => this._refreshSize());
views.monitorNodeRemoval(
- this._hostNode, () => { this._uninstall(); });
+ this._hostNode, () => {
+ this._uninstall();
+ });
}
_reinstall() {
diff --git a/client/js/controls/post_edit_sidebar_control.js b/client/js/controls/post_edit_sidebar_control.js
index 030bb7a..11ce210 100644
--- a/client/js/controls/post_edit_sidebar_control.js
+++ b/client/js/controls/post_edit_sidebar_control.js
@@ -37,7 +37,6 @@ class PostEditSidebarControl extends events.EventTarget {
canEditPostFlags: api.hasPrivilege('posts:edit:flags'),
canEditPostContent: api.hasPrivilege('posts:edit:content'),
canEditPostThumbnail: api.hasPrivilege('posts:edit:thumbnail'),
- canEditPostSource : api.hasPrivilege('posts:edit:source'),
canCreateAnonymousPosts: api.hasPrivilege('posts:create:anonymous'),
canDeletePosts: api.hasPrivilege('posts:delete'),
canFeaturePosts: api.hasPrivilege('posts:feature'),
@@ -78,8 +77,7 @@ class PostEditSidebarControl extends events.EventTarget {
if (this._contentInputNode) {
this._contentFileDropper = new FileDropperControl(
- this._contentInputNode, {
- allowUrls: true,
+ this._contentInputNode, {allowUrls: true,
lock: true,
urlPlaceholder: '...or paste an URL here.'});
this._contentFileDropper.addEventListener('fileadd', e => {
@@ -284,6 +282,7 @@ class PostEditSidebarControl extends events.EventTarget {
try {
success = document.execCommand('copy');
} catch (err) {
+ // continue regardless of error
}
textarea.blur();
document.body.removeChild(textarea);
@@ -383,10 +382,16 @@ class PostEditSidebarControl extends events.EventTarget {
}
get _videoFlags() {
- if (!this._loopVideoInputNode) return undefined;
+ if (!this._loopVideoInputNode) {
+ return undefined;
+ }
let ret = [];
- if (this._loopVideoInputNode.checked) ret.push('loop');
- if (this._soundVideoInputNode.checked) ret.push('sound');
+ if (this._loopVideoInputNode.checked) {
+ ret.push('loop');
+ }
+ if (this._soundVideoInputNode.checked) {
+ ret.push('sound');
+ }
return ret;
}
@@ -462,6 +467,6 @@ class PostEditSidebarControl extends events.EventTarget {
showError(message) {
views.showError(this._hostNode, message);
}
-};
+}
module.exports = PostEditSidebarControl;
diff --git a/client/js/controls/post_notes_overlay_control.js b/client/js/controls/post_notes_overlay_control.js
index bbea095..7bf69b2 100644
--- a/client/js/controls/post_notes_overlay_control.js
+++ b/client/js/controls/post_notes_overlay_control.js
@@ -48,7 +48,7 @@ function _getNoteCentroid(note) {
const y0 = note.polygon.at(i).y;
const x1 = note.polygon.at((i + 1) % vertexCount).x;
const y1 = note.polygon.at((i + 1) % vertexCount).y;
- const a = x0 * y1 - x1 * y0;
+ const a = (x0 * y1) - (x1 * y0);
signedArea += a;
centroid.x += (x0 + x1) * a;
centroid.y += (y0 + y1) * a;
@@ -188,12 +188,12 @@ class SelectedState extends ActiveState {
evtCanvasKeyDown(e) {
const delta = e.ctrlKey ? 10 : 1;
const offsetMap = {
- [KEY_LEFT]: [-delta, 0],
- [KEY_UP]: [0, -delta],
- [KEY_DOWN]: [0, delta],
+ [KEY_LEFT]: [-delta, 0],
+ [KEY_UP]: [0, -delta],
+ [KEY_DOWN]: [0, delta],
[KEY_RIGHT]: [delta, 0],
};
- if (offsetMap.hasOwnProperty(e.which)) {
+ if (Object.prototype.hasOwnProperty.call(offsetMap, e.witch)) {
e.stopPropagation();
e.stopImmediatePropagation();
e.preventDefault();
@@ -283,8 +283,8 @@ class SelectedState extends ActiveState {
const origin = _getNoteCentroid(this._note);
const originalSize = _getNoteSize(this._note);
const targetSize = new Point(
- originalSize.x + x / this._control.boundingBox.width,
- originalSize.y + y / this._control.boundingBox.height);
+ originalSize.x + (x / this._control.boundingBox.width),
+ originalSize.y + (y / this._control.boundingBox.height));
const scale = new Point(
targetSize.x / originalSize.x,
targetSize.y / originalSize.y);
@@ -305,7 +305,7 @@ class MovingPointState extends ActiveState {
}
evtCanvasKeyDown(e) {
- if (e.which == KEY_ESCAPE) {
+ if (e.which === KEY_ESCAPE) {
this._notePoint.x = this._originalNotePoint.x;
this._notePoint.y = this._originalNotePoint.y;
this._control._state = new SelectedState(this._control, this._note);
@@ -333,7 +333,7 @@ class MovingNoteState extends ActiveState {
}
evtCanvasKeyDown(e) {
- if (e.which == KEY_ESCAPE) {
+ if (e.which === KEY_ESCAPE) {
for (let i of misc.range(this._note.polygon.length)) {
this._note.polygon.at(i).x = this._originalPolygon[i].x;
this._note.polygon.at(i).y = this._originalPolygon[i].y;
@@ -366,7 +366,7 @@ class ScalingNoteState extends ActiveState {
}
evtCanvasKeyDown(e) {
- if (e.which == KEY_ESCAPE) {
+ if (e.which === KEY_ESCAPE) {
for (let i of misc.range(this._note.polygon.length)) {
this._note.polygon.at(i).x = this._originalPolygon[i].x;
this._note.polygon.at(i).y = this._originalPolygon[i].y;
@@ -384,12 +384,12 @@ class ScalingNoteState extends ActiveState {
const originalPolygonPoint = this._originalPolygon[i];
polygonPoint.x =
originalMousePoint.x +
- (originalPolygonPoint.x - originalMousePoint.x) *
- (1 + (mousePoint.x - originalMousePoint.x) / originalSize.x);
+ ((originalPolygonPoint.x - originalMousePoint.x) *
+ (1 + ((mousePoint.x - originalMousePoint.x) / originalSize.x)));
polygonPoint.y =
originalMousePoint.y +
- (originalPolygonPoint.y - originalMousePoint.y) *
- (1 + (mousePoint.y - originalMousePoint.y) / originalSize.y);
+ ((originalPolygonPoint.y - originalMousePoint.y) *
+ (1 + ((mousePoint.y - originalMousePoint.y) / originalSize.y)));
}
}
@@ -466,12 +466,12 @@ class DrawingPolygonState extends ActiveState {
}
evtCanvasKeyDown(e) {
- if (e.which == KEY_ESCAPE) {
+ if (e.which === KEY_ESCAPE) {
this._note.polygon.remove(this._note.polygon.secondLastPoint);
if (this._note.polygon.length === 1) {
this._cancel();
}
- } else if (e.which == KEY_RETURN) {
+ } else if (e.which === KEY_RETURN) {
this._finish();
}
}
@@ -674,13 +674,13 @@ class PostNotesOverlayControl extends events.EventTarget {
const x = (
-bodyRect.left +
svgRect.left +
- svgRect.width * centroid.x -
- noteRect.width / 2);
+ (svgRect.width * centroid.x) -
+ (noteRect.width / 2));
const y = (
-bodyRect.top +
svgRect.top +
- svgRect.height * centroid.y -
- noteRect.height / 2);
+ (svgRect.height * centroid.y) -
+ (noteRect.height / 2));
this._textNode.style.left = x + 'px';
this._textNode.style.top = y + 'px';
}
diff --git a/client/js/controls/post_readonly_sidebar_control.js b/client/js/controls/post_readonly_sidebar_control.js
index 0d66252..388c238 100644
--- a/client/js/controls/post_readonly_sidebar_control.js
+++ b/client/js/controls/post_readonly_sidebar_control.js
@@ -197,6 +197,6 @@ class PostReadonlySidebarControl extends events.EventTarget {
_evtChangeScore(e) {
this._installScore();
}
-};
+}
module.exports = PostReadonlySidebarControl;
diff --git a/client/js/controls/tag_auto_complete_control.js b/client/js/controls/tag_auto_complete_control.js
index 3d9130e..f8d3f6c 100644
--- a/client/js/controls/tag_auto_complete_control.js
+++ b/client/js/controls/tag_auto_complete_control.js
@@ -36,22 +36,21 @@ class TagAutoCompleteControl extends AutoCompleteControl {
const term = misc.escapeSearchTerm(text);
const query = (
text.length < minLengthForPartialSearch
- ? term + '*'
- : '*' + term + '*') + ' sort:usages';
+ ? term + '*'
+ : '*' + term + '*') + ' sort:usages';
return new Promise((resolve, reject) => {
TagList.search(
- query, 0, this._options.maxResults,
- ['names', 'category', 'usages'])
- .then(
- response => resolve(
- _tagListToMatches(response.results, this._options)),
- reject);
+ query, 0, this._options.maxResults, ['names', 'category', 'usages'])
+ .then(
+ response => resolve(
+ _tagListToMatches(response.results, this._options)),
+ reject);
});
};
super(input, options);
}
-};
+}
module.exports = TagAutoCompleteControl;
diff --git a/client/js/controls/tag_input_control.js b/client/js/controls/tag_input_control.js
index 1ad0957..e0b1339 100644
--- a/client/js/controls/tag_input_control.js
+++ b/client/js/controls/tag_input_control.js
@@ -51,7 +51,7 @@ class SuggestionList {
}
set(suggestion, weight) {
- if (this._suggestions.hasOwnProperty(suggestion)) {
+ if (Object.prototype.hasOwnProperty.call(this._suggestions, suggestion)) {
weight = Math.max(weight, this._suggestions[suggestion]);
}
this._suggestions[suggestion] = weight;
@@ -72,7 +72,7 @@ class SuggestionList {
tuples.sort((a, b) => {
let weightDiff = b[1] - a[1];
let nameDiff = a[0].localeCompare(b[0]);
- return weightDiff == 0 ? nameDiff : weightDiff;
+ return weightDiff === 0 ? nameDiff : weightDiff;
});
return tuples.map(tuple => {
return {tagName: tuple[0], weight: tuple[1]};
@@ -102,7 +102,7 @@ class TagInputControl extends events.EventTarget {
},
confirm: tag => {
this._tagInputNode.value = '';
- // XXX: tags from autocomplete don't contain implications
+ // note: tags from autocomplete don't contain implications
// so they need to be looked up in API
this.addTagByName(tag.names[0], SOURCE_USER_INPUT);
},
@@ -160,7 +160,7 @@ class TagInputControl extends events.EventTarget {
}
addTag(tag, source) {
- if (source != SOURCE_INIT && this.tags.isTaggedWith(tag.names[0])) {
+ if (source !== SOURCE_INIT && this.tags.isTaggedWith(tag.names[0])) {
const listItemNode = this._getListItemNode(tag);
if (source !== SOURCE_IMPLICATION) {
listItemNode.classList.add('duplicate');
@@ -240,7 +240,7 @@ class TagInputControl extends events.EventTarget {
}
_evtInputKeyDown(e) {
- if (e.which == KEY_RETURN || e.which == KEY_SPACE) {
+ if (e.which === KEY_RETURN || e.which === KEY_SPACE) {
e.preventDefault();
this._hideAutoComplete();
this.addTagByText(this._tagInputNode.value, SOURCE_USER_INPUT);
@@ -328,8 +328,8 @@ class TagInputControl extends events.EventTarget {
return;
}
api.get(
- uri.formatApiLink('tag-siblings', tag.names[0]),
- {noProgress: true})
+ uri.formatApiLink('tag-siblings', tag.names[0]),
+ {noProgress: true})
.then(response => {
return Promise.resolve(response.results);
}, response => {
diff --git a/client/js/events.js b/client/js/events.js
index e395214..945771a 100644
--- a/client/js/events.js
+++ b/client/js/events.js
@@ -11,7 +11,7 @@ class EventTarget {
this[method] = this.eventTarget[method].bind(this.eventTarget);
}
}
-};
+}
function proxyEvent(source, target, sourceEventType, targetEventType) {
if (!source.addEventListener) {
diff --git a/client/js/main.js b/client/js/main.js
index dd974fd..cb0eb07 100644
--- a/client/js/main.js
+++ b/client/js/main.js
@@ -60,17 +60,17 @@ api.fetchConfig().then(() => {
window.alert('Could not fetch basic configuration from server');
}).then(() => {
api.loginFromCookies().then(() => {
- tags.refreshCategoryColorMap();
+ tags.refreshCategoryColorMap();
+ router.start();
+ }, error => {
+ if (window.location.href.indexOf('login') !== -1) {
+ api.forget();
router.start();
- }, error => {
- if (window.location.href.indexOf('login') !== -1) {
- api.forget();
- router.start();
- } else {
- const ctx = router.start('/');
- ctx.controller.showError(
- 'An error happened while trying to log you in: ' +
+ } else {
+ const ctx = router.start('/');
+ ctx.controller.showError(
+ 'An error happened while trying to log you in: ' +
error.message);
- }
- });
+ }
+ });
});
diff --git a/client/js/models/comment.js b/client/js/models/comment.js
index e10e83c..e292ec4 100644
--- a/client/js/models/comment.js
+++ b/client/js/models/comment.js
@@ -22,16 +22,41 @@ class Comment extends events.EventTarget {
return comment;
}
- get id() { return this._id; }
- get postId() { return this._postId; }
- get text() { return this._text || ''; }
- get user() { return this._user; }
- get creationTime() { return this._creationTime; }
- get lastEditTime() { return this._lastEditTime; }
- get score() { return this._score; }
- get ownScore() { return this._ownScore; }
+ get id() {
+ return this._id;
+ }
- set text(value) { this._text = value; }
+ get postId() {
+ return this._postId;
+ }
+
+ get text() {
+ return this._text || '';
+ }
+
+ get user() {
+ return this._user;
+ }
+
+ get creationTime() {
+ return this._creationTime;
+ }
+
+ get lastEditTime() {
+ return this._lastEditTime;
+ }
+
+ get score() {
+ return this._score;
+ }
+
+ get ownScore() {
+ return this._ownScore;
+ }
+
+ set text(value) {
+ this._text = value;
+ }
save() {
const detail = {
@@ -56,8 +81,8 @@ class Comment extends events.EventTarget {
delete() {
return api.delete(
- uri.formatApiLink('comment', this.id),
- {version: this._version})
+ uri.formatApiLink('comment', this.id),
+ {version: this._version})
.then(response => {
this.dispatchEvent(new CustomEvent('delete', {
detail: {
@@ -70,8 +95,8 @@ class Comment extends events.EventTarget {
setScore(score) {
return api.put(
- uri.formatApiLink('comment', this.id, 'score'),
- {score: score})
+ uri.formatApiLink('comment', this.id, 'score'),
+ {score: score})
.then(response => {
this._updateFromResponse(response);
this.dispatchEvent(new CustomEvent('changeScore', {
@@ -84,15 +109,15 @@ class Comment extends events.EventTarget {
}
_updateFromResponse(response) {
- this._version = response.version;
- this._id = response.id;
- this._postId = response.postId;
- this._text = response.text;
- this._user = response.user;
+ this._version = response.version;
+ this._id = response.id;
+ this._postId = response.postId;
+ this._text = response.text;
+ this._user = response.user;
this._creationTime = response.creationTime;
this._lastEditTime = response.lastEditTime;
- this._score = parseInt(response.score);
- this._ownScore = parseInt(response.ownScore);
+ this._score = parseInt(response.score);
+ this._ownScore = parseInt(response.ownScore);
}
}
diff --git a/client/js/models/note.js b/client/js/models/note.js
index 877db4e..1709d44 100644
--- a/client/js/models/note.js
+++ b/client/js/models/note.js
@@ -11,10 +11,17 @@ class Note extends events.EventTarget {
this._polygon = new PointList();
}
- get text() { return this._text; }
- get polygon() { return this._polygon; }
+ get text() {
+ return this._text;
+ }
- set text(value) { this._text = value; }
+ get polygon() {
+ return this._polygon;
+ }
+
+ set text(value) {
+ this._text = value;
+ }
static fromResponse(response) {
const note = new Note();
diff --git a/client/js/models/point.js b/client/js/models/point.js
index f1c551e..bbb05ec 100644
--- a/client/js/models/point.js
+++ b/client/js/models/point.js
@@ -9,8 +9,13 @@ class Point extends events.EventTarget {
this._y = y;
}
- get x() { return this._x; }
- get y() { return this._y; }
+ get x() {
+ return this._x;
+ }
+
+ get y() {
+ return this._y;
+ }
set x(value) {
this._x = value;
@@ -21,6 +26,6 @@ class Point extends events.EventTarget {
this._y = value;
this.dispatchEvent(new CustomEvent('change', {detail: {point: this}}));
}
-};
+}
module.exports = Point;
diff --git a/client/js/models/post.js b/client/js/models/post.js
index d2124ad..be21904 100644
--- a/client/js/models/post.js
+++ b/client/js/models/post.js
@@ -23,43 +23,141 @@ class Post extends events.EventTarget {
this._updateFromResponse({});
}
- get id() { return this._id; }
- get type() { return this._type; }
- get mimeType() { return this._mimeType; }
- get creationTime() { return this._creationTime; }
- get user() { return this._user; }
- get safety() { return this._safety; }
- get contentUrl() { return this._contentUrl; }
- get fullContentUrl() { return this._fullContentUrl; }
- get thumbnailUrl() { return this._thumbnailUrl; }
- get source() { return this._source; }
- get sourceSplit() { return this._source.split('\n'); }
- get canvasWidth() { return this._canvasWidth || 800; }
- get canvasHeight() { return this._canvasHeight || 450; }
- get fileSize() { return this._fileSize || 0; }
- get newContent() { throw 'Invalid operation'; }
- get newThumbnail() { throw 'Invalid operation'; }
+ get id() {
+ return this._id;
+ }
- get flags() { return this._flags; }
- get tags() { return this._tags; }
- get tagNames() { return this._tags.map(tag => tag.names[0]); }
- get notes() { return this._notes; }
- get comments() { return this._comments; }
- get relations() { return this._relations; }
+ get type() {
+ return this._type;
+ }
- get score() { return this._score; }
- get commentCount() { return this._commentCount; }
- get favoriteCount() { return this._favoriteCount; }
- get ownFavorite() { return this._ownFavorite; }
- get ownScore() { return this._ownScore; }
- get hasCustomThumbnail() { return this._hasCustomThumbnail; }
+ get mimeType() {
+ return this._mimeType;
+ }
- set flags(value) { this._flags = value; }
- set safety(value) { this._safety = value; }
- set relations(value) { this._relations = value; }
- set newContent(value) { this._newContent = value; }
- set newThumbnail(value) { this._newThumbnail = value; }
- set source(value) { this._source = value; }
+ get creationTime() {
+ return this._creationTime;
+ }
+
+ get user() {
+ return this._user;
+ }
+
+ get safety() {
+ return this._safety;
+ }
+
+ get contentUrl() {
+ return this._contentUrl;
+ }
+
+ get fullContentUrl() {
+ return this._fullContentUrl;
+ }
+
+ get thumbnailUrl() {
+ return this._thumbnailUrl;
+ }
+
+ get source() {
+ return this._source;
+ }
+
+ get sourceSplit() {
+ return this._source.split('\n');
+ }
+
+ get canvasWidth() {
+ return this._canvasWidth || 800;
+ }
+
+ get canvasHeight() {
+ return this._canvasHeight || 450;
+ }
+
+ get fileSize() {
+ return this._fileSize || 0;
+ }
+
+ get newContent() {
+ throw 'Invalid operation';
+ }
+
+ get newThumbnail() {
+ throw 'Invalid operation';
+ }
+
+ get flags() {
+ return this._flags;
+ }
+
+ get tags() {
+ return this._tags;
+ }
+
+ get tagNames() {
+ return this._tags.map(tag => tag.names[0]);
+ }
+
+ get notes() {
+ return this._notes;
+ }
+
+ get comments() {
+ return this._comments;
+ }
+
+ get relations() {
+ return this._relations;
+ }
+
+ get score() {
+ return this._score;
+ }
+
+ get commentCount() {
+ return this._commentCount;
+ }
+
+ get favoriteCount() {
+ return this._favoriteCount;
+ }
+
+ get ownFavorite() {
+ return this._ownFavorite;
+ }
+
+ get ownScore() {
+ return this._ownScore;
+ }
+
+ get hasCustomThumbnail() {
+ return this._hasCustomThumbnail;
+ }
+
+ set flags(value) {
+ this._flags = value;
+ }
+
+ set safety(value) {
+ this._safety = value;
+ }
+
+ set relations(value) {
+ this._relations = value;
+ }
+
+ set newContent(value) {
+ this._newContent = value;
+ }
+
+ set newThumbnail(value) {
+ this._newThumbnail = value;
+ }
+
+ set source(value) {
+ this._source = value;
+ }
static fromResponse(response) {
const ret = new Post();
@@ -158,8 +256,8 @@ class Post extends events.EventTarget {
feature() {
return api.post(
- uri.formatApiLink('featured-post'),
- {id: this._id})
+ uri.formatApiLink('featured-post'),
+ {id: this._id})
.then(response => {
return Promise.resolve();
});
@@ -167,8 +265,8 @@ class Post extends events.EventTarget {
delete() {
return api.delete(
- uri.formatApiLink('post', this.id),
- {version: this._version})
+ uri.formatApiLink('post', this.id),
+ {version: this._version})
.then(response => {
this.dispatchEvent(new CustomEvent('delete', {
detail: {
@@ -202,8 +300,8 @@ class Post extends events.EventTarget {
setScore(score) {
return api.put(
- uri.formatApiLink('post', this.id, 'score'),
- {score: score})
+ uri.formatApiLink('post', this.id, 'score'),
+ {score: score})
.then(response => {
const prevFavorite = this._ownFavorite;
this._updateFromResponse(response);
@@ -274,29 +372,29 @@ class Post extends events.EventTarget {
_updateFromResponse(response) {
const map = () => ({
- _version: response.version,
- _id: response.id,
- _type: response.type,
- _mimeType: response.mimeType,
- _creationTime: response.creationTime,
- _user: response.user,
- _safety: response.safety,
- _contentUrl: response.contentUrl,
+ _version: response.version,
+ _id: response.id,
+ _type: response.type,
+ _mimeType: response.mimeType,
+ _creationTime: response.creationTime,
+ _user: response.user,
+ _safety: response.safety,
+ _contentUrl: response.contentUrl,
_fullContentUrl: new URL(response.contentUrl, document.getElementsByTagName('base')[0].href).href,
- _thumbnailUrl: response.thumbnailUrl,
- _source: response.source,
- _canvasWidth: response.canvasWidth,
- _canvasHeight: response.canvasHeight,
- _fileSize: response.fileSize,
+ _thumbnailUrl: response.thumbnailUrl,
+ _source: response.source,
+ _canvasWidth: response.canvasWidth,
+ _canvasHeight: response.canvasHeight,
+ _fileSize: response.fileSize,
- _flags: [...response.flags || []],
- _relations: [...response.relations || []],
+ _flags: [...response.flags || []],
+ _relations: [...response.relations || []],
- _score: response.score,
- _commentCount: response.commentCount,
+ _score: response.score,
+ _commentCount: response.commentCount,
_favoriteCount: response.favoriteCount,
- _ownScore: response.ownScore,
- _ownFavorite: response.ownFavorite,
+ _ownScore: response.ownScore,
+ _ownFavorite: response.ownFavorite,
_hasCustomThumbnail: response.hasCustomThumbnail,
});
@@ -309,6 +407,6 @@ class Post extends events.EventTarget {
Object.assign(this, map());
Object.assign(this._orig, map());
}
-};
+}
module.exports = Post;
diff --git a/client/js/models/post_list.js b/client/js/models/post_list.js
index 74f089f..eae1128 100644
--- a/client/js/models/post_list.js
+++ b/client/js/models/post_list.js
@@ -18,13 +18,13 @@ class PostList extends AbstractList {
static search(text, offset, limit, fields) {
return api.get(
- uri.formatApiLink(
- 'posts', {
- query: PostList._decorateSearchQuery(text || ''),
- offset: offset,
- limit: limit,
- fields: fields.join(','),
- }))
+ uri.formatApiLink(
+ 'posts', {
+ query: PostList._decorateSearchQuery(text || ''),
+ offset: offset,
+ limit: limit,
+ fields: fields.join(','),
+ }))
.then(response => {
return Promise.resolve(Object.assign(
{},
diff --git a/client/js/models/settings.js b/client/js/models/settings.js
index b4b04bb..774aa0b 100644
--- a/client/js/models/settings.js
+++ b/client/js/models/settings.js
@@ -30,6 +30,7 @@ class Settings extends events.EventTarget {
try {
Object.assign(ret, JSON.parse(localStorage.getItem('settings')));
} catch (e) {
+ // continue regardless of error
}
return ret;
}
@@ -50,6 +51,6 @@ class Settings extends events.EventTarget {
get() {
return this.cache;
}
-};
+}
module.exports = new Settings();
diff --git a/client/js/models/snapshot.js b/client/js/models/snapshot.js
index 78b367c..cf5a308 100644
--- a/client/js/models/snapshot.js
+++ b/client/js/models/snapshot.js
@@ -10,12 +10,29 @@ class Snapshot extends events.EventTarget {
this._updateFromResponse({});
}
- get operation() { return this._operation; }
- get type() { return this._type; }
- get id() { return this._id; }
- get user() { return this._user; }
- get data() { return this._data; }
- get time() { return this._time; }
+ get operation() {
+ return this._operation;
+ }
+
+ get type() {
+ return this._type;
+ }
+
+ get id() {
+ return this._id;
+ }
+
+ get user() {
+ return this._user;
+ }
+
+ get data() {
+ return this._data;
+ }
+
+ get time() {
+ return this._time;
+ }
static fromResponse(response) {
const ret = new Snapshot();
@@ -26,11 +43,11 @@ class Snapshot extends events.EventTarget {
_updateFromResponse(response) {
const map = {
_operation: response.operation,
- _type: response.type,
- _id: response.id,
- _user: response.user,
- _data: response.data,
- _time: response.time,
+ _type: response.type,
+ _id: response.id,
+ _user: response.user,
+ _data: response.data,
+ _time: response.time,
};
Object.assign(this, map);
diff --git a/client/js/models/snapshot_list.js b/client/js/models/snapshot_list.js
index 3263a6a..475b89a 100644
--- a/client/js/models/snapshot_list.js
+++ b/client/js/models/snapshot_list.js
@@ -8,7 +8,7 @@ const Snapshot = require('./snapshot.js');
class SnapshotList extends AbstractList {
static search(text, offset, limit) {
return api.get(uri.formatApiLink(
- 'snapshots', {query: text, offset: offset, limit: limit}))
+ 'snapshots', {query: text, offset: offset, limit: limit}))
.then(response => {
return Promise.resolve(Object.assign(
{},
diff --git a/client/js/models/tag.js b/client/js/models/tag.js
index c743554..b99c63f 100644
--- a/client/js/models/tag.js
+++ b/client/js/models/tag.js
@@ -20,18 +20,49 @@ class Tag extends events.EventTarget {
this._updateFromResponse({});
}
- get names() { return this._names; }
- get category() { return this._category; }
- get description() { return this._description; }
- get suggestions() { return this._suggestions; }
- get implications() { return this._implications; }
- get postCount() { return this._postCount; }
- get creationTime() { return this._creationTime; }
- get lastEditTime() { return this._lastEditTime; }
+ get names() {
+ return this._names;
+ }
- set names(value) { this._names = value; }
- set category(value) { this._category = value; }
- set description(value) { this._description = value; }
+ get category() {
+ return this._category;
+ }
+
+ get description() {
+ return this._description;
+ }
+
+ get suggestions() {
+ return this._suggestions;
+ }
+
+ get implications() {
+ return this._implications;
+ }
+
+ get postCount() {
+ return this._postCount;
+ }
+
+ get creationTime() {
+ return this._creationTime;
+ }
+
+ get lastEditTime() {
+ return this._lastEditTime;
+ }
+
+ set names(value) {
+ this._names = value;
+ }
+
+ set category(value) {
+ this._category = value;
+ }
+
+ set description(value) {
+ this._description = value;
+ }
static fromResponse(response) {
const ret = new Tag();
@@ -113,8 +144,8 @@ class Tag extends events.EventTarget {
delete() {
return api.delete(
- uri.formatApiLink('tag', this._origName),
- {version: this._version})
+ uri.formatApiLink('tag', this._origName),
+ {version: this._version})
.then(response => {
this.dispatchEvent(new CustomEvent('delete', {
detail: {
@@ -127,14 +158,14 @@ class Tag extends events.EventTarget {
_updateFromResponse(response) {
const map = {
- _version: response.version,
- _origName: response.names ? response.names[0] : null,
- _names: response.names,
- _category: response.category,
- _description: response.description,
+ _version: response.version,
+ _origName: response.names ? response.names[0] : null,
+ _names: response.names,
+ _category: response.category,
+ _description: response.description,
_creationTime: response.creationTime,
_lastEditTime: response.lastEditTime,
- _postCount: response.usages || 0,
+ _postCount: response.usages || 0,
};
for (let obj of [this, this._orig]) {
@@ -145,6 +176,6 @@ class Tag extends events.EventTarget {
Object.assign(this, map);
Object.assign(this._orig, map);
}
-};
+}
module.exports = Tag;
diff --git a/client/js/models/tag_category.js b/client/js/models/tag_category.js
index 04bd8fe..42e54d8 100644
--- a/client/js/models/tag_category.js
+++ b/client/js/models/tag_category.js
@@ -7,22 +7,41 @@ const events = require('../events.js');
class TagCategory extends events.EventTarget {
constructor() {
super();
- this._name = '';
- this._color = '#000000';
- this._tagCount = 0;
+ this._name = '';
+ this._color = '#000000';
+ this._tagCount = 0;
this._isDefault = false;
- this._origName = null;
+ this._origName = null;
this._origColor = null;
}
- get name() { return this._name; }
- get color() { return this._color; }
- get tagCount() { return this._tagCount; }
- get isDefault() { return this._isDefault; }
- get isTransient() { return !this._origName; }
+ get name() {
+ return this._name;
+ }
- set name(value) { this._name = value; }
- set color(value) { this._color = value; }
+ get color() {
+ return this._color;
+ }
+
+ get tagCount() {
+ return this._tagCount;
+ }
+
+ get isDefault() {
+ return this._isDefault;
+ }
+
+ get isTransient() {
+ return !this._origName;
+ }
+
+ set name(value) {
+ this._name = value;
+ }
+
+ set color(value) {
+ this._color = value;
+ }
static fromResponse(response) {
const ret = new TagCategory();
@@ -64,8 +83,8 @@ class TagCategory extends events.EventTarget {
delete() {
return api.delete(
- uri.formatApiLink('tag-category', this._origName),
- {version: this._version})
+ uri.formatApiLink('tag-category', this._origName),
+ {version: this._version})
.then(response => {
this.dispatchEvent(new CustomEvent('delete', {
detail: {
@@ -77,12 +96,12 @@ class TagCategory extends events.EventTarget {
}
_updateFromResponse(response) {
- this._version = response.version;
- this._name = response.name;
- this._color = response.color;
+ this._version = response.version;
+ this._name = response.name;
+ this._color = response.color;
this._isDefault = response.default;
- this._tagCount = response.usages;
- this._origName = this.name;
+ this._tagCount = response.usages;
+ this._origName = this.name;
this._origColor = this.color;
}
}
diff --git a/client/js/models/tag_list.js b/client/js/models/tag_list.js
index d87b694..31a34fa 100644
--- a/client/js/models/tag_list.js
+++ b/client/js/models/tag_list.js
@@ -8,13 +8,13 @@ const Tag = require('./tag.js');
class TagList extends AbstractList {
static search(text, offset, limit, fields) {
return api.get(
- uri.formatApiLink(
- 'tags', {
- query: text,
- offset: offset,
- limit: limit,
- fields: fields.join(','),
- }))
+ uri.formatApiLink(
+ 'tags', {
+ query: text,
+ offset: offset,
+ limit: limit,
+ fields: fields.join(','),
+ }))
.then(response => {
return Promise.resolve(Object.assign(
{},
diff --git a/client/js/models/top_navigation.js b/client/js/models/top_navigation.js
index bf2cffe..44ad671 100644
--- a/client/js/models/top_navigation.js
+++ b/client/js/models/top_navigation.js
@@ -12,7 +12,7 @@ class TopNavigationItem {
this.imageUrl = imageUrl === undefined ? null : imageUrl;
this.key = null;
}
-};
+}
class TopNavigation extends events.EventTarget {
constructor() {
@@ -72,7 +72,7 @@ class TopNavigation extends events.EventTarget {
hide(key) {
this.get(key).available = false;
}
-};
+}
function _makeTopNavigation() {
const ret = new TopNavigation();
diff --git a/client/js/models/user.js b/client/js/models/user.js
index abb5f57..40fbb14 100644
--- a/client/js/models/user.js
+++ b/client/js/models/user.js
@@ -11,28 +11,89 @@ class User extends events.EventTarget {
this._updateFromResponse({});
}
- get name() { return this._name; }
- get rank() { return this._rank; }
- get email() { return this._email; }
- get avatarStyle() { return this._avatarStyle; }
- get avatarUrl() { return this._avatarUrl; }
- get creationTime() { return this._creationTime; }
- get lastLoginTime() { return this._lastLoginTime; }
- get commentCount() { return this._commentCount; }
- get favoritePostCount() { return this._favoritePostCount; }
- get uploadedPostCount() { return this._uploadedPostCount; }
- get likedPostCount() { return this._likedPostCount; }
- get dislikedPostCount() { return this._dislikedPostCount; }
- get rankName() { return api.rankNames.get(this.rank); }
- get avatarContent() { throw 'Invalid operation'; }
- get password() { throw 'Invalid operation'; }
+ get name() {
+ return this._name;
+ }
- set name(value) { this._name = value; }
- set rank(value) { this._rank = value; }
- set email(value) { this._email = value || null; }
- set avatarStyle(value) { this._avatarStyle = value; }
- set avatarContent(value) { this._avatarContent = value; }
- set password(value) { this._password = value; }
+ get rank() {
+ return this._rank;
+ }
+
+ get email() {
+ return this._email;
+ }
+
+ get avatarStyle() {
+ return this._avatarStyle;
+ }
+
+ get avatarUrl() {
+ return this._avatarUrl;
+ }
+
+ get creationTime() {
+ return this._creationTime;
+ }
+
+ get lastLoginTime() {
+ return this._lastLoginTime;
+ }
+
+ get commentCount() {
+ return this._commentCount;
+ }
+
+ get favoritePostCount() {
+ return this._favoritePostCount;
+ }
+
+ get uploadedPostCount() {
+ return this._uploadedPostCount;
+ }
+
+ get likedPostCount() {
+ return this._likedPostCount;
+ }
+
+ get dislikedPostCount() {
+ return this._dislikedPostCount;
+ }
+
+ get rankName() {
+ return api.rankNames.get(this.rank);
+ }
+
+ get avatarContent() {
+ throw 'Invalid operation';
+ }
+
+ get password() {
+ throw 'Invalid operation';
+ }
+
+ set name(value) {
+ this._name = value;
+ }
+
+ set rank(value) {
+ this._rank = value;
+ }
+
+ set email(value) {
+ this._email = value || null;
+ }
+
+ set avatarStyle(value) {
+ this._avatarStyle = value;
+ }
+
+ set avatarContent(value) {
+ this._avatarContent = value;
+ }
+
+ set password(value) {
+ this._password = value;
+ }
static fromResponse(response) {
const ret = new User();
@@ -91,8 +152,8 @@ class User extends events.EventTarget {
delete() {
return api.delete(
- uri.formatApiLink('user', this._orig._name),
- {version: this._version})
+ uri.formatApiLink('user', this._orig._name),
+ {version: this._version})
.then(response => {
this.dispatchEvent(new CustomEvent('delete', {
detail: {
@@ -105,27 +166,27 @@ class User extends events.EventTarget {
_updateFromResponse(response) {
const map = {
- _version: response.version,
- _name: response.name,
- _rank: response.rank,
- _email: response.email,
- _avatarStyle: response.avatarStyle,
- _avatarUrl: response.avatarUrl,
- _creationTime: response.creationTime,
- _lastLoginTime: response.lastLoginTime,
- _commentCount: response.commentCount,
+ _version: response.version,
+ _name: response.name,
+ _rank: response.rank,
+ _email: response.email,
+ _avatarStyle: response.avatarStyle,
+ _avatarUrl: response.avatarUrl,
+ _creationTime: response.creationTime,
+ _lastLoginTime: response.lastLoginTime,
+ _commentCount: response.commentCount,
_favoritePostCount: response.favoritePostCount,
_uploadedPostCount: response.uploadedPostCount,
- _likedPostCount: response.likedPostCount,
+ _likedPostCount: response.likedPostCount,
_dislikedPostCount: response.dislikedPostCount,
};
Object.assign(this, map);
Object.assign(this._orig, map);
- this._password = null;
- this._avatarContent = null;
+ this._password = null;
+ this._avatarContent = null;
}
-};
+}
module.exports = User;
diff --git a/client/js/models/user_list.js b/client/js/models/user_list.js
index c48fc88..d44622c 100644
--- a/client/js/models/user_list.js
+++ b/client/js/models/user_list.js
@@ -8,8 +8,8 @@ const User = require('./user.js');
class UserList extends AbstractList {
static search(text, offset, limit) {
return api.get(
- uri.formatApiLink(
- 'users', {query: text, offset: offset, limit: limit}))
+ uri.formatApiLink(
+ 'users', {query: text, offset: offset, limit: limit}))
.then(response => {
return Promise.resolve(Object.assign(
{},
diff --git a/client/js/models/user_token.js b/client/js/models/user_token.js
index 6e70a94..e49f5aa 100644
--- a/client/js/models/user_token.js
+++ b/client/js/models/user_token.js
@@ -11,16 +11,41 @@ class UserToken extends events.EventTarget {
this._updateFromResponse({});
}
- get token() { return this._token; }
- get note() { return this._note; }
- get enabled() { return this._enabled; }
- get version() { return this._version; }
- get expirationTime() { return this._expirationTime; }
- get creationTime() { return this._creationTime; }
- get lastEditTime() { return this._lastEditTime; }
- get lastUsageTime() { return this._lastUsageTime; }
+ get token() {
+ return this._token;
+ }
- set note(value) { this._note = value; }
+ get note() {
+ return this._note;
+ }
+
+ get enabled() {
+ return this._enabled;
+ }
+
+ get version() {
+ return this._version;
+ }
+
+ get expirationTime() {
+ return this._expirationTime;
+ }
+
+ get creationTime() {
+ return this._creationTime;
+ }
+
+ get lastEditTime() {
+ return this._lastEditTime;
+ }
+
+ get lastUsageTime() {
+ return this._lastUsageTime;
+ }
+
+ set note(value) {
+ this._note = value;
+ }
static fromResponse(response) {
if (typeof response.results !== 'undefined') {
@@ -98,14 +123,14 @@ class UserToken extends events.EventTarget {
_updateFromResponse(response) {
const map = {
- _token: response.token,
- _note: response.note,
- _enabled: response.enabled,
- _expirationTime: response.expirationTime,
- _version: response.version,
- _creationTime: response.creationTime,
- _lastEditTime: response.lastEditTime,
- _lastUsageTime: response.lastUsageTime,
+ _token: response.token,
+ _note: response.note,
+ _enabled: response.enabled,
+ _expirationTime: response.expirationTime,
+ _version: response.version,
+ _creationTime: response.creationTime,
+ _lastEditTime: response.lastEditTime,
+ _lastUsageTime: response.lastUsageTime,
};
Object.assign(this, map);
diff --git a/client/js/router.js b/client/js/router.js
index dd9b9e1..b5b4855 100644
--- a/client/js/router.js
+++ b/client/js/router.js
@@ -51,7 +51,7 @@ class Context {
replaceState() {
history.replaceState(this.state, this.title, this.canonicalPath);
}
-};
+}
class Route {
constructor(path) {
@@ -119,7 +119,7 @@ class Route {
return true;
}
-};
+}
class Router {
constructor() {
@@ -217,14 +217,14 @@ class Router {
if (current === ctx.canonicalPath) {
return;
}
- router.stop();
+ this.stop();
location.href = ctx.canonicalPath;
}
get url() {
return location.pathname + location.search + location.hash;
}
-};
+}
const _onPopState = router => {
let loaded = false;
diff --git a/client/js/util/keyboard.js b/client/js/util/keyboard.js
index c3b9543..8ee6ee9 100644
--- a/client/js/util/keyboard.js
+++ b/client/js/util/keyboard.js
@@ -5,6 +5,7 @@ const settings = require('../models/settings.js');
let paused = false;
const _originalStopCallback = mousetrap.prototype.stopCallback;
+// eslint-disable-next-line func-names
mousetrap.prototype.stopCallback = function(...args) {
var self = this;
if (paused) {
@@ -28,6 +29,10 @@ function unbind(hotkey) {
module.exports = {
bind: bind,
unbind: unbind,
- pause: () => { paused = true; },
- unpause: () => { paused = false; },
+ pause: () => {
+ paused = true;
+ },
+ unpause: () => {
+ paused = false;
+ },
};
diff --git a/client/js/util/markdown.js b/client/js/util/markdown.js
index f326ebb..210280e 100644
--- a/client/js/util/markdown.js
+++ b/client/js/util/markdown.js
@@ -48,7 +48,7 @@ class TildeWrapper extends BaseMarkdownWrapper {
}
}
-//prevent ^#... from being treated as headers, due to tag permalinks
+// prevent ^#... from being treated as headers, due to tag permalinks
class TagPermalinkFixWrapper extends BaseMarkdownWrapper {
preprocess(text) {
return text.replace(/^#/g, '%%%#');
@@ -59,7 +59,7 @@ class TagPermalinkFixWrapper extends BaseMarkdownWrapper {
}
}
-//post, user and tags permalinks
+// post, user and tags permalinks
class EntityPermalinkWrapper extends BaseMarkdownWrapper {
preprocess(text) {
// URL-based permalinks
@@ -127,7 +127,7 @@ function createRenderer() {
const renderer = new marked.Renderer();
renderer.image = (href, title, alt) => {
let [_, url, width, height] =
- /^(.+?)(?:\s=\s*(\d*)\s*x\s*(\d*)\s*)?$/.exec(href);
+ (/^(.+?)(?:\s=\s*(\d*)\s*x\s*(\d*)\s*)?$/).exec(href);
let res = '
- makeElement(
- 'option',
- {value: key, selected: key === options.selectedKey},
- options.keyValues[key])));
+ ...Object.keys(options.keyValues).map(key => makeElement(
+ 'option',
+ {value: key, selected: key === options.selectedKey},
+ options.keyValues[key])));
}
function makeInput(options) {
@@ -157,10 +156,7 @@ function makeColorInput(options) {
color: ${options.value}`,
});
return makeElement(
- 'label', {class: 'color'},
- textInput,
- backgroundPreviewNode,
- textPreviewNode);
+ 'label', {class: 'color'}, textInput, backgroundPreviewNode, textPreviewNode);
}
function makeNumericInput(options) {
@@ -175,14 +171,12 @@ function makeDateInput(options) {
function getPostUrl(id, parameters) {
return uri.formatClientLink(
- 'post', id,
- parameters ? {query: parameters.query} : {});
+ 'post', id, parameters ? {query: parameters.query} : {});
}
function getPostEditUrl(id, parameters) {
return uri.formatClientLink(
- 'post', id, 'edit',
- parameters ? {query: parameters.query} : {});
+ 'post', id, 'edit', parameters ? {query: parameters.query} : {});
}
function makePostLink(id, includeHash) {
@@ -335,26 +329,25 @@ function clearMessages(target) {
function htmlToDom(html) {
// code taken from jQuery + Krasimir Tsonev's blog
const wrapMap = {
- _: [1, '