client/js: format code to ESLint
This commit is contained in:
parent
48c9001194
commit
4329b1620f
67 changed files with 1150 additions and 533 deletions
293
client/.eslintrc.yml
Normal file
293
client/.eslintrc.yml
Normal file
|
@ -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'
|
|
@ -377,8 +377,9 @@ class Api extends events.EventTarget {
|
||||||
try {
|
try {
|
||||||
if (this.userName && this.token) {
|
if (this.userName && this.token) {
|
||||||
req.auth = null;
|
req.auth = null;
|
||||||
req.set('Authorization', 'Token '
|
// eslint-disable-next-line no-undef
|
||||||
+ new Buffer(this.userName + ":" + this.token).toString('base64'))
|
req.set('Authorization', 'Token ' + new Buffer(
|
||||||
|
this.userName + ":" + this.token).toString('base64'))
|
||||||
} else if (this.userName && this.userPassword) {
|
} else if (this.userName && this.userPassword) {
|
||||||
req.auth(
|
req.auth(
|
||||||
this.userName,
|
this.userName,
|
||||||
|
|
|
@ -34,7 +34,9 @@ class CommentsController {
|
||||||
requestPage: (offset, limit) => {
|
requestPage: (offset, limit) => {
|
||||||
return PostList.search(
|
return PostList.search(
|
||||||
'sort:comment-date comment-count-min:1',
|
'sort:comment-date comment-count-min:1',
|
||||||
offset, limit, fields);
|
offset,
|
||||||
|
limit,
|
||||||
|
fields);
|
||||||
},
|
},
|
||||||
pageRenderer: pageCtx => {
|
pageRenderer: pageCtx => {
|
||||||
Object.assign(pageCtx, {
|
Object.assign(pageCtx, {
|
||||||
|
@ -68,9 +70,10 @@ class CommentsController {
|
||||||
e.detail.comment.delete()
|
e.detail.comment.delete()
|
||||||
.catch(error => window.alert(error.message));
|
.catch(error => window.alert(error.message));
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = router => {
|
module.exports = router => {
|
||||||
router.enter(['comments'],
|
router.enter(['comments'], (ctx, next) => {
|
||||||
(ctx, next) => { new CommentsController(ctx); });
|
new CommentsController(ctx);
|
||||||
};
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -41,10 +41,10 @@ class HomeController {
|
||||||
showError(message) {
|
showError(message) {
|
||||||
this._homeView.showError(message);
|
this._homeView.showError(message);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = router => {
|
module.exports = router => {
|
||||||
router.enter([], (ctx, next) => {
|
router.enter([], (ctx, next) => {
|
||||||
ctx.controller = new HomeController();
|
ctx.controller = new HomeController();
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@ class NotFoundController {
|
||||||
topNavigation.setTitle('Not found');
|
topNavigation.setTitle('Not found');
|
||||||
this._notFoundView = new NotFoundView(path);
|
this._notFoundView = new NotFoundView(path);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = router => {
|
module.exports = router => {
|
||||||
router.enter(null, (ctx, next) => {
|
router.enter(null, (ctx, next) => {
|
||||||
ctx.controller = new NotFoundController(ctx.canonicalPath);
|
ctx.controller = new NotFoundController(ctx.canonicalPath);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ class PostDetailController extends BasePostController {
|
||||||
if (this._id !== e.detail.post.id) {
|
if (this._id !== e.detail.post.id) {
|
||||||
router.replace(
|
router.replace(
|
||||||
uri.formatClientLink('post', e.detail.post.id, section),
|
uri.formatClientLink('post', e.detail.post.id, section),
|
||||||
null, false);
|
null,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +72,8 @@ class PostDetailController extends BasePostController {
|
||||||
router.replace(
|
router.replace(
|
||||||
uri.formatClientLink(
|
uri.formatClientLink(
|
||||||
'post', e.detail.targetPost.id, 'merge'),
|
'post', e.detail.targetPost.id, 'merge'),
|
||||||
null, false);
|
null,
|
||||||
|
false);
|
||||||
}, error => {
|
}, error => {
|
||||||
this._view.showError(error.message);
|
this._view.showError(error.message);
|
||||||
this._view.enableForm();
|
this._view.enableForm();
|
||||||
|
|
|
@ -13,7 +13,8 @@ const EmptyView = require('../views/empty_view.js');
|
||||||
|
|
||||||
const fields = [
|
const fields = [
|
||||||
'id', 'thumbnailUrl', 'type', 'safety',
|
'id', 'thumbnailUrl', 'type', 'safety',
|
||||||
'score', 'favoriteCount', 'commentCount', 'tags', 'version'];
|
'score', 'favoriteCount', 'commentCount', 'tags', 'version'
|
||||||
|
];
|
||||||
|
|
||||||
class PostListController {
|
class PostListController {
|
||||||
constructor(ctx) {
|
constructor(ctx) {
|
||||||
|
@ -62,8 +63,7 @@ class PostListController {
|
||||||
|
|
||||||
_evtTag(e) {
|
_evtTag(e) {
|
||||||
Promise.all(
|
Promise.all(
|
||||||
this._bulkEditTags.map(tag =>
|
this._bulkEditTags.map(tag => e.detail.post.tags.addByName(tag)))
|
||||||
e.detail.post.tags.addByName(tag)))
|
|
||||||
.then(e.detail.post.save())
|
.then(e.detail.post.save())
|
||||||
.catch(error => window.alert(error.message));
|
.catch(error => window.alert(error.message));
|
||||||
}
|
}
|
||||||
|
@ -117,5 +117,7 @@ class PostListController {
|
||||||
module.exports = router => {
|
module.exports = router => {
|
||||||
router.enter(
|
router.enter(
|
||||||
['posts'],
|
['posts'],
|
||||||
(ctx, next) => { ctx.controller = new PostListController(ctx); });
|
(ctx, next) => {
|
||||||
|
ctx.controller = new PostListController(ctx);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,10 +18,10 @@ class PostMainController extends BasePostController {
|
||||||
|
|
||||||
let parameters = ctx.parameters;
|
let parameters = ctx.parameters;
|
||||||
Promise.all([
|
Promise.all([
|
||||||
Post.get(ctx.parameters.id),
|
Post.get(ctx.parameters.id),
|
||||||
PostList.getAround(
|
PostList.getAround(
|
||||||
ctx.parameters.id,
|
ctx.parameters.id,
|
||||||
parameters ? parameters.query : null),
|
parameters ? parameters.query : null),
|
||||||
]).then(responses => {
|
]).then(responses => {
|
||||||
const [post, aroundResponse] = responses;
|
const [post, aroundResponse] = responses;
|
||||||
|
|
||||||
|
|
|
@ -57,33 +57,32 @@ class PostUploadController {
|
||||||
this._view.clearMessages();
|
this._view.clearMessages();
|
||||||
|
|
||||||
e.detail.uploadables.reduce(
|
e.detail.uploadables.reduce(
|
||||||
(promise, uploadable) =>
|
(promise, uploadable) => promise.then(() => this._uploadSinglePost(
|
||||||
promise.then(() => this._uploadSinglePost(
|
uploadable, e.detail.skipDuplicates)),
|
||||||
uploadable, e.detail.skipDuplicates)),
|
|
||||||
Promise.resolve())
|
Promise.resolve())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this._view.clearMessages();
|
this._view.clearMessages();
|
||||||
misc.disableExitConfirmation();
|
misc.disableExitConfirmation();
|
||||||
const ctx = router.show(uri.formatClientLink('posts'));
|
const ctx = router.show(uri.formatClientLink('posts'));
|
||||||
ctx.controller.showSuccess('Posts uploaded.');
|
ctx.controller.showSuccess('Posts uploaded.');
|
||||||
}, error => {
|
}, error => {
|
||||||
if (error.uploadable) {
|
if (error.uploadable) {
|
||||||
if (error.similarPosts) {
|
if (error.similarPosts) {
|
||||||
error.uploadable.lookalikes = error.similarPosts;
|
error.uploadable.lookalikes = error.similarPosts;
|
||||||
this._view.updateUploadable(error.uploadable);
|
this._view.updateUploadable(error.uploadable);
|
||||||
this._view.showInfo(genericErrorMessage);
|
this._view.showInfo(genericErrorMessage);
|
||||||
this._view.showInfo(
|
this._view.showInfo(
|
||||||
error.message, error.uploadable);
|
error.message, error.uploadable);
|
||||||
} else {
|
|
||||||
this._view.showError(genericErrorMessage);
|
|
||||||
this._view.showError(
|
|
||||||
error.message, error.uploadable);
|
|
||||||
}
|
|
||||||
} else {
|
} 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) {
|
_uploadSinglePost(uploadable, skipDuplicates) {
|
||||||
|
@ -153,7 +152,9 @@ class PostUploadController {
|
||||||
post.newContent = uploadable.url || uploadable.file;
|
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)
|
// 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;`
|
// 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;
|
return post;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ class SettingsController {
|
||||||
settings.save(e.detail);
|
settings.save(e.detail);
|
||||||
this._view.showSuccess('Settings saved.');
|
this._view.showSuccess('Settings saved.');
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = router => {
|
module.exports = router => {
|
||||||
router.enter(['settings'], (ctx, next) => {
|
router.enter(['settings'], (ctx, next) => {
|
||||||
|
|
|
@ -45,5 +45,7 @@ class SnapshotsController {
|
||||||
|
|
||||||
module.exports = router => {
|
module.exports = router => {
|
||||||
router.enter(['history'],
|
router.enter(['history'],
|
||||||
(ctx, next) => { ctx.controller = new SnapshotsController(ctx); });
|
(ctx, next) => {
|
||||||
|
ctx.controller = new SnapshotsController(ctx);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -69,7 +69,8 @@ class TagController {
|
||||||
if (this._name !== e.detail.tag.names[0]) {
|
if (this._name !== e.detail.tag.names[0]) {
|
||||||
router.replace(
|
router.replace(
|
||||||
uri.formatClientLink('tag', e.detail.tag.names[0], section),
|
uri.formatClientLink('tag', e.detail.tag.names[0], section),
|
||||||
null, false);
|
null,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +106,8 @@ class TagController {
|
||||||
router.replace(
|
router.replace(
|
||||||
uri.formatClientLink(
|
uri.formatClientLink(
|
||||||
'tag', e.detail.targetTagName, 'merge'),
|
'tag', e.detail.targetTagName, 'merge'),
|
||||||
null, false);
|
null,
|
||||||
|
false);
|
||||||
}, error => {
|
}, error => {
|
||||||
this._view.showError(error.message);
|
this._view.showError(error.message);
|
||||||
this._view.enableForm();
|
this._view.enableForm();
|
||||||
|
|
|
@ -16,7 +16,8 @@ const fields = [
|
||||||
'implications',
|
'implications',
|
||||||
'creationTime',
|
'creationTime',
|
||||||
'usages',
|
'usages',
|
||||||
'category'];
|
'category'
|
||||||
|
];
|
||||||
|
|
||||||
class TagListController {
|
class TagListController {
|
||||||
constructor(ctx) {
|
constructor(ctx) {
|
||||||
|
@ -81,5 +82,7 @@ class TagListController {
|
||||||
module.exports = router => {
|
module.exports = router => {
|
||||||
router.enter(
|
router.enter(
|
||||||
['tags'],
|
['tags'],
|
||||||
(ctx, next) => { ctx.controller = new TagListController(ctx); });
|
(ctx, next) => {
|
||||||
|
ctx.controller = new TagListController(ctx);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,7 +42,7 @@ class UserController {
|
||||||
userTokenPromise,
|
userTokenPromise,
|
||||||
User.get(userName)
|
User.get(userName)
|
||||||
]).then(responses => {
|
]).then(responses => {
|
||||||
const [userTokens, user] = responses;
|
const [userTokens, user] = responses;
|
||||||
const isLoggedIn = api.isLoggedIn(user);
|
const isLoggedIn = api.isLoggedIn(user);
|
||||||
const infix = isLoggedIn ? 'self' : 'any';
|
const infix = isLoggedIn ? 'self' : 'any';
|
||||||
|
|
||||||
|
@ -133,7 +133,8 @@ class UserController {
|
||||||
if (this._name !== e.detail.user.name) {
|
if (this._name !== e.detail.user.name) {
|
||||||
router.replace(
|
router.replace(
|
||||||
uri.formatClientLink('user', e.detail.user.name, section),
|
uri.formatClientLink('user', e.detail.user.name, section),
|
||||||
null, false);
|
null,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ class UserListController {
|
||||||
defaultLimit: 30,
|
defaultLimit: 30,
|
||||||
getClientUrlForPage: (offset, limit) => {
|
getClientUrlForPage: (offset, limit) => {
|
||||||
const parameters = Object.assign(
|
const parameters = Object.assign(
|
||||||
{}, this._ctx.parameters, {offset, offset, limit: limit});
|
{}, this._ctx.parameters, {offset: offset, limit: limit});
|
||||||
return uri.formatClientLink('users', parameters);
|
return uri.formatClientLink('users', parameters);
|
||||||
},
|
},
|
||||||
requestPage: (offset, limit) => {
|
requestPage: (offset, limit) => {
|
||||||
|
@ -71,5 +71,7 @@ class UserListController {
|
||||||
module.exports = router => {
|
module.exports = router => {
|
||||||
router.enter(
|
router.enter(
|
||||||
['users'],
|
['users'],
|
||||||
(ctx, next) => { ctx.controller = new UserListController(ctx); });
|
(ctx, next) => {
|
||||||
|
ctx.controller = new UserListController(ctx);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -121,7 +121,9 @@ class AutoCompleteControl {
|
||||||
document.body.appendChild(this._suggestionDiv);
|
document.body.appendChild(this._suggestionDiv);
|
||||||
|
|
||||||
views.monitorNodeRemoval(
|
views.monitorNodeRemoval(
|
||||||
this._sourceInputNode, () => { this._uninstall(); });
|
this._sourceInputNode, () => {
|
||||||
|
this._uninstall();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_uninstall() {
|
_uninstall() {
|
||||||
|
@ -137,13 +139,21 @@ class AutoCompleteControl {
|
||||||
if (key === KEY_ESCAPE) {
|
if (key === KEY_ESCAPE) {
|
||||||
func = this.hide;
|
func = this.hide;
|
||||||
} else if (key === KEY_TAB && shift) {
|
} else if (key === KEY_TAB && shift) {
|
||||||
func = () => { this._selectPrevious(); };
|
func = () => {
|
||||||
|
this._selectPrevious();
|
||||||
|
};
|
||||||
} else if (key === KEY_TAB && !shift) {
|
} else if (key === KEY_TAB && !shift) {
|
||||||
func = () => { this._selectNext(); };
|
func = () => {
|
||||||
|
this._selectNext();
|
||||||
|
};
|
||||||
} else if (key === KEY_UP) {
|
} else if (key === KEY_UP) {
|
||||||
func = () => { this._selectPrevious(); };
|
func = () => {
|
||||||
|
this._selectPrevious();
|
||||||
|
};
|
||||||
} else if (key === KEY_DOWN) {
|
} else if (key === KEY_DOWN) {
|
||||||
func = () => { this._selectNext(); };
|
func = () => {
|
||||||
|
this._selectNext();
|
||||||
|
};
|
||||||
} else if (key === KEY_RETURN && this._activeResult >= 0) {
|
} else if (key === KEY_RETURN && this._activeResult >= 0) {
|
||||||
func = () => {
|
func = () => {
|
||||||
this._confirm(this._getActiveSuggestion());
|
this._confirm(this._getActiveSuggestion());
|
||||||
|
@ -165,13 +175,17 @@ class AutoCompleteControl {
|
||||||
} else {
|
} else {
|
||||||
window.clearTimeout(this._showTimeout);
|
window.clearTimeout(this._showTimeout);
|
||||||
this._showTimeout = window.setTimeout(
|
this._showTimeout = window.setTimeout(
|
||||||
() => { this._showOrHide(); }, 250);
|
() => {
|
||||||
|
this._showOrHide();
|
||||||
|
}, 250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtBlur(e) {
|
_evtBlur(e) {
|
||||||
window.clearTimeout(this._showTimeout);
|
window.clearTimeout(this._showTimeout);
|
||||||
window.setTimeout(() => { this.hide(); }, 50);
|
window.setTimeout(() => {
|
||||||
|
this.hide();
|
||||||
|
}, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getActiveSuggestion() {
|
_getActiveSuggestion() {
|
||||||
|
@ -261,10 +275,10 @@ class AutoCompleteControl {
|
||||||
// choose where to view the suggestions: if there's more space above
|
// choose where to view the suggestions: if there's more space above
|
||||||
// the input - draw the suggestions above it, otherwise below
|
// the input - draw the suggestions above it, otherwise below
|
||||||
const direction =
|
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 x = inputRect.left - bodyRect.left;
|
||||||
let y = direction == 1 ?
|
let y = direction === 1 ?
|
||||||
inputRect.bottom - bodyRect.top - verticalShift :
|
inputRect.bottom - bodyRect.top - verticalShift :
|
||||||
inputRect.top - bodyRect.top - listRect.height + verticalShift;
|
inputRect.top - bodyRect.top - listRect.height + verticalShift;
|
||||||
|
|
||||||
|
@ -276,7 +290,7 @@ class AutoCompleteControl {
|
||||||
const prevHeight = listRect.height;
|
const prevHeight = listRect.height;
|
||||||
listRect = this._suggestionDiv.getBoundingClientRect();
|
listRect = this._suggestionDiv.getBoundingClientRect();
|
||||||
const heightDelta = prevHeight - listRect.height;
|
const heightDelta = prevHeight - listRect.height;
|
||||||
if (direction == -1) {
|
if (direction === -1) {
|
||||||
y += heightDelta;
|
y += heightDelta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,6 +310,6 @@ class AutoCompleteControl {
|
||||||
activeItem.classList.add('active');
|
activeItem.classList.add('active');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = AutoCompleteControl;
|
module.exports = AutoCompleteControl;
|
||||||
|
|
|
@ -212,11 +212,6 @@ class CommentControl extends events.EventTarget {
|
||||||
this._selectTab('preview');
|
this._selectTab('preview');
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtEditClick(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.enterEditMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
_evtSaveChangesClick(e) {
|
_evtSaveChangesClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.dispatchEvent(new CustomEvent('submit', {
|
this.dispatchEvent(new CustomEvent('submit', {
|
||||||
|
@ -260,6 +255,6 @@ class CommentControl extends events.EventTarget {
|
||||||
_forgetHeight() {
|
_forgetHeight() {
|
||||||
this._heightKeeperNode.style.minHeight = null;
|
this._heightKeeperNode.style.minHeight = null;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = CommentControl;
|
module.exports = CommentControl;
|
||||||
|
|
|
@ -54,6 +54,6 @@ class CommentListControl extends events.EventTarget {
|
||||||
_evtRemove(e) {
|
_evtRemove(e) {
|
||||||
this._uninstallCommentNode(e.detail.comment);
|
this._uninstallCommentNode(e.detail.comment);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = CommentListControl;
|
module.exports = CommentListControl;
|
||||||
|
|
|
@ -39,6 +39,7 @@ class ExpanderControl {
|
||||||
this._syncIcon();
|
this._syncIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line accessor-pairs
|
||||||
set title(newTitle) {
|
set title(newTitle) {
|
||||||
if (this._expanderNode) {
|
if (this._expanderNode) {
|
||||||
this._expanderNode
|
this._expanderNode
|
||||||
|
|
|
@ -107,7 +107,9 @@ class PostContentControl {
|
||||||
this._reinstall();
|
this._reinstall();
|
||||||
optimizedResize.add(() => this._refreshSize());
|
optimizedResize.add(() => this._refreshSize());
|
||||||
views.monitorNodeRemoval(
|
views.monitorNodeRemoval(
|
||||||
this._hostNode, () => { this._uninstall(); });
|
this._hostNode, () => {
|
||||||
|
this._uninstall();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_reinstall() {
|
_reinstall() {
|
||||||
|
|
|
@ -37,7 +37,6 @@ class PostEditSidebarControl extends events.EventTarget {
|
||||||
canEditPostFlags: api.hasPrivilege('posts:edit:flags'),
|
canEditPostFlags: api.hasPrivilege('posts:edit:flags'),
|
||||||
canEditPostContent: api.hasPrivilege('posts:edit:content'),
|
canEditPostContent: api.hasPrivilege('posts:edit:content'),
|
||||||
canEditPostThumbnail: api.hasPrivilege('posts:edit:thumbnail'),
|
canEditPostThumbnail: api.hasPrivilege('posts:edit:thumbnail'),
|
||||||
canEditPostSource : api.hasPrivilege('posts:edit:source'),
|
|
||||||
canCreateAnonymousPosts: api.hasPrivilege('posts:create:anonymous'),
|
canCreateAnonymousPosts: api.hasPrivilege('posts:create:anonymous'),
|
||||||
canDeletePosts: api.hasPrivilege('posts:delete'),
|
canDeletePosts: api.hasPrivilege('posts:delete'),
|
||||||
canFeaturePosts: api.hasPrivilege('posts:feature'),
|
canFeaturePosts: api.hasPrivilege('posts:feature'),
|
||||||
|
@ -78,8 +77,7 @@ class PostEditSidebarControl extends events.EventTarget {
|
||||||
|
|
||||||
if (this._contentInputNode) {
|
if (this._contentInputNode) {
|
||||||
this._contentFileDropper = new FileDropperControl(
|
this._contentFileDropper = new FileDropperControl(
|
||||||
this._contentInputNode, {
|
this._contentInputNode, {allowUrls: true,
|
||||||
allowUrls: true,
|
|
||||||
lock: true,
|
lock: true,
|
||||||
urlPlaceholder: '...or paste an URL here.'});
|
urlPlaceholder: '...or paste an URL here.'});
|
||||||
this._contentFileDropper.addEventListener('fileadd', e => {
|
this._contentFileDropper.addEventListener('fileadd', e => {
|
||||||
|
@ -284,6 +282,7 @@ class PostEditSidebarControl extends events.EventTarget {
|
||||||
try {
|
try {
|
||||||
success = document.execCommand('copy');
|
success = document.execCommand('copy');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
// continue regardless of error
|
||||||
}
|
}
|
||||||
textarea.blur();
|
textarea.blur();
|
||||||
document.body.removeChild(textarea);
|
document.body.removeChild(textarea);
|
||||||
|
@ -383,10 +382,16 @@ class PostEditSidebarControl extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
get _videoFlags() {
|
get _videoFlags() {
|
||||||
if (!this._loopVideoInputNode) return undefined;
|
if (!this._loopVideoInputNode) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
let ret = [];
|
let ret = [];
|
||||||
if (this._loopVideoInputNode.checked) ret.push('loop');
|
if (this._loopVideoInputNode.checked) {
|
||||||
if (this._soundVideoInputNode.checked) ret.push('sound');
|
ret.push('loop');
|
||||||
|
}
|
||||||
|
if (this._soundVideoInputNode.checked) {
|
||||||
|
ret.push('sound');
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,6 +467,6 @@ class PostEditSidebarControl extends events.EventTarget {
|
||||||
showError(message) {
|
showError(message) {
|
||||||
views.showError(this._hostNode, message);
|
views.showError(this._hostNode, message);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = PostEditSidebarControl;
|
module.exports = PostEditSidebarControl;
|
||||||
|
|
|
@ -48,7 +48,7 @@ function _getNoteCentroid(note) {
|
||||||
const y0 = note.polygon.at(i).y;
|
const y0 = note.polygon.at(i).y;
|
||||||
const x1 = note.polygon.at((i + 1) % vertexCount).x;
|
const x1 = note.polygon.at((i + 1) % vertexCount).x;
|
||||||
const y1 = note.polygon.at((i + 1) % vertexCount).y;
|
const y1 = note.polygon.at((i + 1) % vertexCount).y;
|
||||||
const a = x0 * y1 - x1 * y0;
|
const a = (x0 * y1) - (x1 * y0);
|
||||||
signedArea += a;
|
signedArea += a;
|
||||||
centroid.x += (x0 + x1) * a;
|
centroid.x += (x0 + x1) * a;
|
||||||
centroid.y += (y0 + y1) * a;
|
centroid.y += (y0 + y1) * a;
|
||||||
|
@ -188,12 +188,12 @@ class SelectedState extends ActiveState {
|
||||||
evtCanvasKeyDown(e) {
|
evtCanvasKeyDown(e) {
|
||||||
const delta = e.ctrlKey ? 10 : 1;
|
const delta = e.ctrlKey ? 10 : 1;
|
||||||
const offsetMap = {
|
const offsetMap = {
|
||||||
[KEY_LEFT]: [-delta, 0],
|
[KEY_LEFT]: [-delta, 0],
|
||||||
[KEY_UP]: [0, -delta],
|
[KEY_UP]: [0, -delta],
|
||||||
[KEY_DOWN]: [0, delta],
|
[KEY_DOWN]: [0, delta],
|
||||||
[KEY_RIGHT]: [delta, 0],
|
[KEY_RIGHT]: [delta, 0],
|
||||||
};
|
};
|
||||||
if (offsetMap.hasOwnProperty(e.which)) {
|
if (Object.prototype.hasOwnProperty.call(offsetMap, e.witch)) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -283,8 +283,8 @@ class SelectedState extends ActiveState {
|
||||||
const origin = _getNoteCentroid(this._note);
|
const origin = _getNoteCentroid(this._note);
|
||||||
const originalSize = _getNoteSize(this._note);
|
const originalSize = _getNoteSize(this._note);
|
||||||
const targetSize = new Point(
|
const targetSize = new Point(
|
||||||
originalSize.x + x / this._control.boundingBox.width,
|
originalSize.x + (x / this._control.boundingBox.width),
|
||||||
originalSize.y + y / this._control.boundingBox.height);
|
originalSize.y + (y / this._control.boundingBox.height));
|
||||||
const scale = new Point(
|
const scale = new Point(
|
||||||
targetSize.x / originalSize.x,
|
targetSize.x / originalSize.x,
|
||||||
targetSize.y / originalSize.y);
|
targetSize.y / originalSize.y);
|
||||||
|
@ -305,7 +305,7 @@ class MovingPointState extends ActiveState {
|
||||||
}
|
}
|
||||||
|
|
||||||
evtCanvasKeyDown(e) {
|
evtCanvasKeyDown(e) {
|
||||||
if (e.which == KEY_ESCAPE) {
|
if (e.which === KEY_ESCAPE) {
|
||||||
this._notePoint.x = this._originalNotePoint.x;
|
this._notePoint.x = this._originalNotePoint.x;
|
||||||
this._notePoint.y = this._originalNotePoint.y;
|
this._notePoint.y = this._originalNotePoint.y;
|
||||||
this._control._state = new SelectedState(this._control, this._note);
|
this._control._state = new SelectedState(this._control, this._note);
|
||||||
|
@ -333,7 +333,7 @@ class MovingNoteState extends ActiveState {
|
||||||
}
|
}
|
||||||
|
|
||||||
evtCanvasKeyDown(e) {
|
evtCanvasKeyDown(e) {
|
||||||
if (e.which == KEY_ESCAPE) {
|
if (e.which === KEY_ESCAPE) {
|
||||||
for (let i of misc.range(this._note.polygon.length)) {
|
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).x = this._originalPolygon[i].x;
|
||||||
this._note.polygon.at(i).y = this._originalPolygon[i].y;
|
this._note.polygon.at(i).y = this._originalPolygon[i].y;
|
||||||
|
@ -366,7 +366,7 @@ class ScalingNoteState extends ActiveState {
|
||||||
}
|
}
|
||||||
|
|
||||||
evtCanvasKeyDown(e) {
|
evtCanvasKeyDown(e) {
|
||||||
if (e.which == KEY_ESCAPE) {
|
if (e.which === KEY_ESCAPE) {
|
||||||
for (let i of misc.range(this._note.polygon.length)) {
|
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).x = this._originalPolygon[i].x;
|
||||||
this._note.polygon.at(i).y = this._originalPolygon[i].y;
|
this._note.polygon.at(i).y = this._originalPolygon[i].y;
|
||||||
|
@ -384,12 +384,12 @@ class ScalingNoteState extends ActiveState {
|
||||||
const originalPolygonPoint = this._originalPolygon[i];
|
const originalPolygonPoint = this._originalPolygon[i];
|
||||||
polygonPoint.x =
|
polygonPoint.x =
|
||||||
originalMousePoint.x +
|
originalMousePoint.x +
|
||||||
(originalPolygonPoint.x - originalMousePoint.x) *
|
((originalPolygonPoint.x - originalMousePoint.x) *
|
||||||
(1 + (mousePoint.x - originalMousePoint.x) / originalSize.x);
|
(1 + ((mousePoint.x - originalMousePoint.x) / originalSize.x)));
|
||||||
polygonPoint.y =
|
polygonPoint.y =
|
||||||
originalMousePoint.y +
|
originalMousePoint.y +
|
||||||
(originalPolygonPoint.y - originalMousePoint.y) *
|
((originalPolygonPoint.y - originalMousePoint.y) *
|
||||||
(1 + (mousePoint.y - originalMousePoint.y) / originalSize.y);
|
(1 + ((mousePoint.y - originalMousePoint.y) / originalSize.y)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,12 +466,12 @@ class DrawingPolygonState extends ActiveState {
|
||||||
}
|
}
|
||||||
|
|
||||||
evtCanvasKeyDown(e) {
|
evtCanvasKeyDown(e) {
|
||||||
if (e.which == KEY_ESCAPE) {
|
if (e.which === KEY_ESCAPE) {
|
||||||
this._note.polygon.remove(this._note.polygon.secondLastPoint);
|
this._note.polygon.remove(this._note.polygon.secondLastPoint);
|
||||||
if (this._note.polygon.length === 1) {
|
if (this._note.polygon.length === 1) {
|
||||||
this._cancel();
|
this._cancel();
|
||||||
}
|
}
|
||||||
} else if (e.which == KEY_RETURN) {
|
} else if (e.which === KEY_RETURN) {
|
||||||
this._finish();
|
this._finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -674,13 +674,13 @@ class PostNotesOverlayControl extends events.EventTarget {
|
||||||
const x = (
|
const x = (
|
||||||
-bodyRect.left +
|
-bodyRect.left +
|
||||||
svgRect.left +
|
svgRect.left +
|
||||||
svgRect.width * centroid.x -
|
(svgRect.width * centroid.x) -
|
||||||
noteRect.width / 2);
|
(noteRect.width / 2));
|
||||||
const y = (
|
const y = (
|
||||||
-bodyRect.top +
|
-bodyRect.top +
|
||||||
svgRect.top +
|
svgRect.top +
|
||||||
svgRect.height * centroid.y -
|
(svgRect.height * centroid.y) -
|
||||||
noteRect.height / 2);
|
(noteRect.height / 2));
|
||||||
this._textNode.style.left = x + 'px';
|
this._textNode.style.left = x + 'px';
|
||||||
this._textNode.style.top = y + 'px';
|
this._textNode.style.top = y + 'px';
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,6 +197,6 @@ class PostReadonlySidebarControl extends events.EventTarget {
|
||||||
_evtChangeScore(e) {
|
_evtChangeScore(e) {
|
||||||
this._installScore();
|
this._installScore();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = PostReadonlySidebarControl;
|
module.exports = PostReadonlySidebarControl;
|
||||||
|
|
|
@ -36,22 +36,21 @@ class TagAutoCompleteControl extends AutoCompleteControl {
|
||||||
const term = misc.escapeSearchTerm(text);
|
const term = misc.escapeSearchTerm(text);
|
||||||
const query = (
|
const query = (
|
||||||
text.length < minLengthForPartialSearch
|
text.length < minLengthForPartialSearch
|
||||||
? term + '*'
|
? term + '*'
|
||||||
: '*' + term + '*') + ' sort:usages';
|
: '*' + term + '*') + ' sort:usages';
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
TagList.search(
|
TagList.search(
|
||||||
query, 0, this._options.maxResults,
|
query, 0, this._options.maxResults, ['names', 'category', 'usages'])
|
||||||
['names', 'category', 'usages'])
|
.then(
|
||||||
.then(
|
response => resolve(
|
||||||
response => resolve(
|
_tagListToMatches(response.results, this._options)),
|
||||||
_tagListToMatches(response.results, this._options)),
|
reject);
|
||||||
reject);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
super(input, options);
|
super(input, options);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = TagAutoCompleteControl;
|
module.exports = TagAutoCompleteControl;
|
||||||
|
|
|
@ -51,7 +51,7 @@ class SuggestionList {
|
||||||
}
|
}
|
||||||
|
|
||||||
set(suggestion, weight) {
|
set(suggestion, weight) {
|
||||||
if (this._suggestions.hasOwnProperty(suggestion)) {
|
if (Object.prototype.hasOwnProperty.call(this._suggestions, suggestion)) {
|
||||||
weight = Math.max(weight, this._suggestions[suggestion]);
|
weight = Math.max(weight, this._suggestions[suggestion]);
|
||||||
}
|
}
|
||||||
this._suggestions[suggestion] = weight;
|
this._suggestions[suggestion] = weight;
|
||||||
|
@ -72,7 +72,7 @@ class SuggestionList {
|
||||||
tuples.sort((a, b) => {
|
tuples.sort((a, b) => {
|
||||||
let weightDiff = b[1] - a[1];
|
let weightDiff = b[1] - a[1];
|
||||||
let nameDiff = a[0].localeCompare(b[0]);
|
let nameDiff = a[0].localeCompare(b[0]);
|
||||||
return weightDiff == 0 ? nameDiff : weightDiff;
|
return weightDiff === 0 ? nameDiff : weightDiff;
|
||||||
});
|
});
|
||||||
return tuples.map(tuple => {
|
return tuples.map(tuple => {
|
||||||
return {tagName: tuple[0], weight: tuple[1]};
|
return {tagName: tuple[0], weight: tuple[1]};
|
||||||
|
@ -102,7 +102,7 @@ class TagInputControl extends events.EventTarget {
|
||||||
},
|
},
|
||||||
confirm: tag => {
|
confirm: tag => {
|
||||||
this._tagInputNode.value = '';
|
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
|
// so they need to be looked up in API
|
||||||
this.addTagByName(tag.names[0], SOURCE_USER_INPUT);
|
this.addTagByName(tag.names[0], SOURCE_USER_INPUT);
|
||||||
},
|
},
|
||||||
|
@ -160,7 +160,7 @@ class TagInputControl extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
addTag(tag, source) {
|
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);
|
const listItemNode = this._getListItemNode(tag);
|
||||||
if (source !== SOURCE_IMPLICATION) {
|
if (source !== SOURCE_IMPLICATION) {
|
||||||
listItemNode.classList.add('duplicate');
|
listItemNode.classList.add('duplicate');
|
||||||
|
@ -240,7 +240,7 @@ class TagInputControl extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtInputKeyDown(e) {
|
_evtInputKeyDown(e) {
|
||||||
if (e.which == KEY_RETURN || e.which == KEY_SPACE) {
|
if (e.which === KEY_RETURN || e.which === KEY_SPACE) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._hideAutoComplete();
|
this._hideAutoComplete();
|
||||||
this.addTagByText(this._tagInputNode.value, SOURCE_USER_INPUT);
|
this.addTagByText(this._tagInputNode.value, SOURCE_USER_INPUT);
|
||||||
|
@ -328,8 +328,8 @@ class TagInputControl extends events.EventTarget {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
api.get(
|
api.get(
|
||||||
uri.formatApiLink('tag-siblings', tag.names[0]),
|
uri.formatApiLink('tag-siblings', tag.names[0]),
|
||||||
{noProgress: true})
|
{noProgress: true})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
return Promise.resolve(response.results);
|
return Promise.resolve(response.results);
|
||||||
}, response => {
|
}, response => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ class EventTarget {
|
||||||
this[method] = this.eventTarget[method].bind(this.eventTarget);
|
this[method] = this.eventTarget[method].bind(this.eventTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function proxyEvent(source, target, sourceEventType, targetEventType) {
|
function proxyEvent(source, target, sourceEventType, targetEventType) {
|
||||||
if (!source.addEventListener) {
|
if (!source.addEventListener) {
|
||||||
|
|
|
@ -60,17 +60,17 @@ api.fetchConfig().then(() => {
|
||||||
window.alert('Could not fetch basic configuration from server');
|
window.alert('Could not fetch basic configuration from server');
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
api.loginFromCookies().then(() => {
|
api.loginFromCookies().then(() => {
|
||||||
tags.refreshCategoryColorMap();
|
tags.refreshCategoryColorMap();
|
||||||
|
router.start();
|
||||||
|
}, error => {
|
||||||
|
if (window.location.href.indexOf('login') !== -1) {
|
||||||
|
api.forget();
|
||||||
router.start();
|
router.start();
|
||||||
}, error => {
|
} else {
|
||||||
if (window.location.href.indexOf('login') !== -1) {
|
const ctx = router.start('/');
|
||||||
api.forget();
|
ctx.controller.showError(
|
||||||
router.start();
|
'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);
|
error.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,16 +22,41 @@ class Comment extends events.EventTarget {
|
||||||
return comment;
|
return comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() { return this._id; }
|
get id() {
|
||||||
get postId() { return this._postId; }
|
return this._id;
|
||||||
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; }
|
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() {
|
save() {
|
||||||
const detail = {
|
const detail = {
|
||||||
|
@ -56,8 +81,8 @@ class Comment extends events.EventTarget {
|
||||||
|
|
||||||
delete() {
|
delete() {
|
||||||
return api.delete(
|
return api.delete(
|
||||||
uri.formatApiLink('comment', this.id),
|
uri.formatApiLink('comment', this.id),
|
||||||
{version: this._version})
|
{version: this._version})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.dispatchEvent(new CustomEvent('delete', {
|
this.dispatchEvent(new CustomEvent('delete', {
|
||||||
detail: {
|
detail: {
|
||||||
|
@ -70,8 +95,8 @@ class Comment extends events.EventTarget {
|
||||||
|
|
||||||
setScore(score) {
|
setScore(score) {
|
||||||
return api.put(
|
return api.put(
|
||||||
uri.formatApiLink('comment', this.id, 'score'),
|
uri.formatApiLink('comment', this.id, 'score'),
|
||||||
{score: score})
|
{score: score})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this._updateFromResponse(response);
|
this._updateFromResponse(response);
|
||||||
this.dispatchEvent(new CustomEvent('changeScore', {
|
this.dispatchEvent(new CustomEvent('changeScore', {
|
||||||
|
@ -84,15 +109,15 @@ class Comment extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateFromResponse(response) {
|
_updateFromResponse(response) {
|
||||||
this._version = response.version;
|
this._version = response.version;
|
||||||
this._id = response.id;
|
this._id = response.id;
|
||||||
this._postId = response.postId;
|
this._postId = response.postId;
|
||||||
this._text = response.text;
|
this._text = response.text;
|
||||||
this._user = response.user;
|
this._user = response.user;
|
||||||
this._creationTime = response.creationTime;
|
this._creationTime = response.creationTime;
|
||||||
this._lastEditTime = response.lastEditTime;
|
this._lastEditTime = response.lastEditTime;
|
||||||
this._score = parseInt(response.score);
|
this._score = parseInt(response.score);
|
||||||
this._ownScore = parseInt(response.ownScore);
|
this._ownScore = parseInt(response.ownScore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,17 @@ class Note extends events.EventTarget {
|
||||||
this._polygon = new PointList();
|
this._polygon = new PointList();
|
||||||
}
|
}
|
||||||
|
|
||||||
get text() { return this._text; }
|
get text() {
|
||||||
get polygon() { return this._polygon; }
|
return this._text;
|
||||||
|
}
|
||||||
|
|
||||||
set text(value) { this._text = value; }
|
get polygon() {
|
||||||
|
return this._polygon;
|
||||||
|
}
|
||||||
|
|
||||||
|
set text(value) {
|
||||||
|
this._text = value;
|
||||||
|
}
|
||||||
|
|
||||||
static fromResponse(response) {
|
static fromResponse(response) {
|
||||||
const note = new Note();
|
const note = new Note();
|
||||||
|
|
|
@ -9,8 +9,13 @@ class Point extends events.EventTarget {
|
||||||
this._y = y;
|
this._y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
get x() { return this._x; }
|
get x() {
|
||||||
get y() { return this._y; }
|
return this._x;
|
||||||
|
}
|
||||||
|
|
||||||
|
get y() {
|
||||||
|
return this._y;
|
||||||
|
}
|
||||||
|
|
||||||
set x(value) {
|
set x(value) {
|
||||||
this._x = value;
|
this._x = value;
|
||||||
|
@ -21,6 +26,6 @@ class Point extends events.EventTarget {
|
||||||
this._y = value;
|
this._y = value;
|
||||||
this.dispatchEvent(new CustomEvent('change', {detail: {point: this}}));
|
this.dispatchEvent(new CustomEvent('change', {detail: {point: this}}));
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = Point;
|
module.exports = Point;
|
||||||
|
|
|
@ -23,43 +23,141 @@ class Post extends events.EventTarget {
|
||||||
this._updateFromResponse({});
|
this._updateFromResponse({});
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() { return this._id; }
|
get id() {
|
||||||
get type() { return this._type; }
|
return this._id;
|
||||||
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 flags() { return this._flags; }
|
get type() {
|
||||||
get tags() { return this._tags; }
|
return this._type;
|
||||||
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 mimeType() {
|
||||||
get commentCount() { return this._commentCount; }
|
return this._mimeType;
|
||||||
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; }
|
get creationTime() {
|
||||||
set safety(value) { this._safety = value; }
|
return this._creationTime;
|
||||||
set relations(value) { this._relations = value; }
|
}
|
||||||
set newContent(value) { this._newContent = value; }
|
|
||||||
set newThumbnail(value) { this._newThumbnail = value; }
|
get user() {
|
||||||
set source(value) { this._source = value; }
|
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) {
|
static fromResponse(response) {
|
||||||
const ret = new Post();
|
const ret = new Post();
|
||||||
|
@ -158,8 +256,8 @@ class Post extends events.EventTarget {
|
||||||
|
|
||||||
feature() {
|
feature() {
|
||||||
return api.post(
|
return api.post(
|
||||||
uri.formatApiLink('featured-post'),
|
uri.formatApiLink('featured-post'),
|
||||||
{id: this._id})
|
{id: this._id})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
|
@ -167,8 +265,8 @@ class Post extends events.EventTarget {
|
||||||
|
|
||||||
delete() {
|
delete() {
|
||||||
return api.delete(
|
return api.delete(
|
||||||
uri.formatApiLink('post', this.id),
|
uri.formatApiLink('post', this.id),
|
||||||
{version: this._version})
|
{version: this._version})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.dispatchEvent(new CustomEvent('delete', {
|
this.dispatchEvent(new CustomEvent('delete', {
|
||||||
detail: {
|
detail: {
|
||||||
|
@ -202,8 +300,8 @@ class Post extends events.EventTarget {
|
||||||
|
|
||||||
setScore(score) {
|
setScore(score) {
|
||||||
return api.put(
|
return api.put(
|
||||||
uri.formatApiLink('post', this.id, 'score'),
|
uri.formatApiLink('post', this.id, 'score'),
|
||||||
{score: score})
|
{score: score})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
const prevFavorite = this._ownFavorite;
|
const prevFavorite = this._ownFavorite;
|
||||||
this._updateFromResponse(response);
|
this._updateFromResponse(response);
|
||||||
|
@ -274,29 +372,29 @@ class Post extends events.EventTarget {
|
||||||
|
|
||||||
_updateFromResponse(response) {
|
_updateFromResponse(response) {
|
||||||
const map = () => ({
|
const map = () => ({
|
||||||
_version: response.version,
|
_version: response.version,
|
||||||
_id: response.id,
|
_id: response.id,
|
||||||
_type: response.type,
|
_type: response.type,
|
||||||
_mimeType: response.mimeType,
|
_mimeType: response.mimeType,
|
||||||
_creationTime: response.creationTime,
|
_creationTime: response.creationTime,
|
||||||
_user: response.user,
|
_user: response.user,
|
||||||
_safety: response.safety,
|
_safety: response.safety,
|
||||||
_contentUrl: response.contentUrl,
|
_contentUrl: response.contentUrl,
|
||||||
_fullContentUrl: new URL(response.contentUrl, document.getElementsByTagName('base')[0].href).href,
|
_fullContentUrl: new URL(response.contentUrl, document.getElementsByTagName('base')[0].href).href,
|
||||||
_thumbnailUrl: response.thumbnailUrl,
|
_thumbnailUrl: response.thumbnailUrl,
|
||||||
_source: response.source,
|
_source: response.source,
|
||||||
_canvasWidth: response.canvasWidth,
|
_canvasWidth: response.canvasWidth,
|
||||||
_canvasHeight: response.canvasHeight,
|
_canvasHeight: response.canvasHeight,
|
||||||
_fileSize: response.fileSize,
|
_fileSize: response.fileSize,
|
||||||
|
|
||||||
_flags: [...response.flags || []],
|
_flags: [...response.flags || []],
|
||||||
_relations: [...response.relations || []],
|
_relations: [...response.relations || []],
|
||||||
|
|
||||||
_score: response.score,
|
_score: response.score,
|
||||||
_commentCount: response.commentCount,
|
_commentCount: response.commentCount,
|
||||||
_favoriteCount: response.favoriteCount,
|
_favoriteCount: response.favoriteCount,
|
||||||
_ownScore: response.ownScore,
|
_ownScore: response.ownScore,
|
||||||
_ownFavorite: response.ownFavorite,
|
_ownFavorite: response.ownFavorite,
|
||||||
_hasCustomThumbnail: response.hasCustomThumbnail,
|
_hasCustomThumbnail: response.hasCustomThumbnail,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -309,6 +407,6 @@ class Post extends events.EventTarget {
|
||||||
Object.assign(this, map());
|
Object.assign(this, map());
|
||||||
Object.assign(this._orig, map());
|
Object.assign(this._orig, map());
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = Post;
|
module.exports = Post;
|
||||||
|
|
|
@ -18,13 +18,13 @@ class PostList extends AbstractList {
|
||||||
|
|
||||||
static search(text, offset, limit, fields) {
|
static search(text, offset, limit, fields) {
|
||||||
return api.get(
|
return api.get(
|
||||||
uri.formatApiLink(
|
uri.formatApiLink(
|
||||||
'posts', {
|
'posts', {
|
||||||
query: PostList._decorateSearchQuery(text || ''),
|
query: PostList._decorateSearchQuery(text || ''),
|
||||||
offset: offset,
|
offset: offset,
|
||||||
limit: limit,
|
limit: limit,
|
||||||
fields: fields.join(','),
|
fields: fields.join(','),
|
||||||
}))
|
}))
|
||||||
.then(response => {
|
.then(response => {
|
||||||
return Promise.resolve(Object.assign(
|
return Promise.resolve(Object.assign(
|
||||||
{},
|
{},
|
||||||
|
|
|
@ -30,6 +30,7 @@ class Settings extends events.EventTarget {
|
||||||
try {
|
try {
|
||||||
Object.assign(ret, JSON.parse(localStorage.getItem('settings')));
|
Object.assign(ret, JSON.parse(localStorage.getItem('settings')));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
// continue regardless of error
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -50,6 +51,6 @@ class Settings extends events.EventTarget {
|
||||||
get() {
|
get() {
|
||||||
return this.cache;
|
return this.cache;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = new Settings();
|
module.exports = new Settings();
|
||||||
|
|
|
@ -10,12 +10,29 @@ class Snapshot extends events.EventTarget {
|
||||||
this._updateFromResponse({});
|
this._updateFromResponse({});
|
||||||
}
|
}
|
||||||
|
|
||||||
get operation() { return this._operation; }
|
get operation() {
|
||||||
get type() { return this._type; }
|
return this._operation;
|
||||||
get id() { return this._id; }
|
}
|
||||||
get user() { return this._user; }
|
|
||||||
get data() { return this._data; }
|
get type() {
|
||||||
get time() { return this._time; }
|
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) {
|
static fromResponse(response) {
|
||||||
const ret = new Snapshot();
|
const ret = new Snapshot();
|
||||||
|
@ -26,11 +43,11 @@ class Snapshot extends events.EventTarget {
|
||||||
_updateFromResponse(response) {
|
_updateFromResponse(response) {
|
||||||
const map = {
|
const map = {
|
||||||
_operation: response.operation,
|
_operation: response.operation,
|
||||||
_type: response.type,
|
_type: response.type,
|
||||||
_id: response.id,
|
_id: response.id,
|
||||||
_user: response.user,
|
_user: response.user,
|
||||||
_data: response.data,
|
_data: response.data,
|
||||||
_time: response.time,
|
_time: response.time,
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.assign(this, map);
|
Object.assign(this, map);
|
||||||
|
|
|
@ -8,7 +8,7 @@ const Snapshot = require('./snapshot.js');
|
||||||
class SnapshotList extends AbstractList {
|
class SnapshotList extends AbstractList {
|
||||||
static search(text, offset, limit) {
|
static search(text, offset, limit) {
|
||||||
return api.get(uri.formatApiLink(
|
return api.get(uri.formatApiLink(
|
||||||
'snapshots', {query: text, offset: offset, limit: limit}))
|
'snapshots', {query: text, offset: offset, limit: limit}))
|
||||||
.then(response => {
|
.then(response => {
|
||||||
return Promise.resolve(Object.assign(
|
return Promise.resolve(Object.assign(
|
||||||
{},
|
{},
|
||||||
|
|
|
@ -20,18 +20,49 @@ class Tag extends events.EventTarget {
|
||||||
this._updateFromResponse({});
|
this._updateFromResponse({});
|
||||||
}
|
}
|
||||||
|
|
||||||
get names() { return this._names; }
|
get names() {
|
||||||
get category() { return this._category; }
|
return this._names;
|
||||||
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; }
|
get category() {
|
||||||
set category(value) { this._category = value; }
|
return this._category;
|
||||||
set description(value) { this._description = value; }
|
}
|
||||||
|
|
||||||
|
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) {
|
static fromResponse(response) {
|
||||||
const ret = new Tag();
|
const ret = new Tag();
|
||||||
|
@ -113,8 +144,8 @@ class Tag extends events.EventTarget {
|
||||||
|
|
||||||
delete() {
|
delete() {
|
||||||
return api.delete(
|
return api.delete(
|
||||||
uri.formatApiLink('tag', this._origName),
|
uri.formatApiLink('tag', this._origName),
|
||||||
{version: this._version})
|
{version: this._version})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.dispatchEvent(new CustomEvent('delete', {
|
this.dispatchEvent(new CustomEvent('delete', {
|
||||||
detail: {
|
detail: {
|
||||||
|
@ -127,14 +158,14 @@ class Tag extends events.EventTarget {
|
||||||
|
|
||||||
_updateFromResponse(response) {
|
_updateFromResponse(response) {
|
||||||
const map = {
|
const map = {
|
||||||
_version: response.version,
|
_version: response.version,
|
||||||
_origName: response.names ? response.names[0] : null,
|
_origName: response.names ? response.names[0] : null,
|
||||||
_names: response.names,
|
_names: response.names,
|
||||||
_category: response.category,
|
_category: response.category,
|
||||||
_description: response.description,
|
_description: response.description,
|
||||||
_creationTime: response.creationTime,
|
_creationTime: response.creationTime,
|
||||||
_lastEditTime: response.lastEditTime,
|
_lastEditTime: response.lastEditTime,
|
||||||
_postCount: response.usages || 0,
|
_postCount: response.usages || 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let obj of [this, this._orig]) {
|
for (let obj of [this, this._orig]) {
|
||||||
|
@ -145,6 +176,6 @@ class Tag extends events.EventTarget {
|
||||||
Object.assign(this, map);
|
Object.assign(this, map);
|
||||||
Object.assign(this._orig, map);
|
Object.assign(this._orig, map);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = Tag;
|
module.exports = Tag;
|
||||||
|
|
|
@ -7,22 +7,41 @@ const events = require('../events.js');
|
||||||
class TagCategory extends events.EventTarget {
|
class TagCategory extends events.EventTarget {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._name = '';
|
this._name = '';
|
||||||
this._color = '#000000';
|
this._color = '#000000';
|
||||||
this._tagCount = 0;
|
this._tagCount = 0;
|
||||||
this._isDefault = false;
|
this._isDefault = false;
|
||||||
this._origName = null;
|
this._origName = null;
|
||||||
this._origColor = null;
|
this._origColor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() { return this._name; }
|
get name() {
|
||||||
get color() { return this._color; }
|
return this._name;
|
||||||
get tagCount() { return this._tagCount; }
|
}
|
||||||
get isDefault() { return this._isDefault; }
|
|
||||||
get isTransient() { return !this._origName; }
|
|
||||||
|
|
||||||
set name(value) { this._name = value; }
|
get color() {
|
||||||
set color(value) { this._color = value; }
|
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) {
|
static fromResponse(response) {
|
||||||
const ret = new TagCategory();
|
const ret = new TagCategory();
|
||||||
|
@ -64,8 +83,8 @@ class TagCategory extends events.EventTarget {
|
||||||
|
|
||||||
delete() {
|
delete() {
|
||||||
return api.delete(
|
return api.delete(
|
||||||
uri.formatApiLink('tag-category', this._origName),
|
uri.formatApiLink('tag-category', this._origName),
|
||||||
{version: this._version})
|
{version: this._version})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.dispatchEvent(new CustomEvent('delete', {
|
this.dispatchEvent(new CustomEvent('delete', {
|
||||||
detail: {
|
detail: {
|
||||||
|
@ -77,12 +96,12 @@ class TagCategory extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateFromResponse(response) {
|
_updateFromResponse(response) {
|
||||||
this._version = response.version;
|
this._version = response.version;
|
||||||
this._name = response.name;
|
this._name = response.name;
|
||||||
this._color = response.color;
|
this._color = response.color;
|
||||||
this._isDefault = response.default;
|
this._isDefault = response.default;
|
||||||
this._tagCount = response.usages;
|
this._tagCount = response.usages;
|
||||||
this._origName = this.name;
|
this._origName = this.name;
|
||||||
this._origColor = this.color;
|
this._origColor = this.color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,13 @@ const Tag = require('./tag.js');
|
||||||
class TagList extends AbstractList {
|
class TagList extends AbstractList {
|
||||||
static search(text, offset, limit, fields) {
|
static search(text, offset, limit, fields) {
|
||||||
return api.get(
|
return api.get(
|
||||||
uri.formatApiLink(
|
uri.formatApiLink(
|
||||||
'tags', {
|
'tags', {
|
||||||
query: text,
|
query: text,
|
||||||
offset: offset,
|
offset: offset,
|
||||||
limit: limit,
|
limit: limit,
|
||||||
fields: fields.join(','),
|
fields: fields.join(','),
|
||||||
}))
|
}))
|
||||||
.then(response => {
|
.then(response => {
|
||||||
return Promise.resolve(Object.assign(
|
return Promise.resolve(Object.assign(
|
||||||
{},
|
{},
|
||||||
|
|
|
@ -12,7 +12,7 @@ class TopNavigationItem {
|
||||||
this.imageUrl = imageUrl === undefined ? null : imageUrl;
|
this.imageUrl = imageUrl === undefined ? null : imageUrl;
|
||||||
this.key = null;
|
this.key = null;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
class TopNavigation extends events.EventTarget {
|
class TopNavigation extends events.EventTarget {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -72,7 +72,7 @@ class TopNavigation extends events.EventTarget {
|
||||||
hide(key) {
|
hide(key) {
|
||||||
this.get(key).available = false;
|
this.get(key).available = false;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function _makeTopNavigation() {
|
function _makeTopNavigation() {
|
||||||
const ret = new TopNavigation();
|
const ret = new TopNavigation();
|
||||||
|
|
|
@ -11,28 +11,89 @@ class User extends events.EventTarget {
|
||||||
this._updateFromResponse({});
|
this._updateFromResponse({});
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() { return this._name; }
|
get name() {
|
||||||
get rank() { return this._rank; }
|
return this._name;
|
||||||
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; }
|
get rank() {
|
||||||
set rank(value) { this._rank = value; }
|
return this._rank;
|
||||||
set email(value) { this._email = value || null; }
|
}
|
||||||
set avatarStyle(value) { this._avatarStyle = value; }
|
|
||||||
set avatarContent(value) { this._avatarContent = value; }
|
get email() {
|
||||||
set password(value) { this._password = value; }
|
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) {
|
static fromResponse(response) {
|
||||||
const ret = new User();
|
const ret = new User();
|
||||||
|
@ -91,8 +152,8 @@ class User extends events.EventTarget {
|
||||||
|
|
||||||
delete() {
|
delete() {
|
||||||
return api.delete(
|
return api.delete(
|
||||||
uri.formatApiLink('user', this._orig._name),
|
uri.formatApiLink('user', this._orig._name),
|
||||||
{version: this._version})
|
{version: this._version})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.dispatchEvent(new CustomEvent('delete', {
|
this.dispatchEvent(new CustomEvent('delete', {
|
||||||
detail: {
|
detail: {
|
||||||
|
@ -105,27 +166,27 @@ class User extends events.EventTarget {
|
||||||
|
|
||||||
_updateFromResponse(response) {
|
_updateFromResponse(response) {
|
||||||
const map = {
|
const map = {
|
||||||
_version: response.version,
|
_version: response.version,
|
||||||
_name: response.name,
|
_name: response.name,
|
||||||
_rank: response.rank,
|
_rank: response.rank,
|
||||||
_email: response.email,
|
_email: response.email,
|
||||||
_avatarStyle: response.avatarStyle,
|
_avatarStyle: response.avatarStyle,
|
||||||
_avatarUrl: response.avatarUrl,
|
_avatarUrl: response.avatarUrl,
|
||||||
_creationTime: response.creationTime,
|
_creationTime: response.creationTime,
|
||||||
_lastLoginTime: response.lastLoginTime,
|
_lastLoginTime: response.lastLoginTime,
|
||||||
_commentCount: response.commentCount,
|
_commentCount: response.commentCount,
|
||||||
_favoritePostCount: response.favoritePostCount,
|
_favoritePostCount: response.favoritePostCount,
|
||||||
_uploadedPostCount: response.uploadedPostCount,
|
_uploadedPostCount: response.uploadedPostCount,
|
||||||
_likedPostCount: response.likedPostCount,
|
_likedPostCount: response.likedPostCount,
|
||||||
_dislikedPostCount: response.dislikedPostCount,
|
_dislikedPostCount: response.dislikedPostCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.assign(this, map);
|
Object.assign(this, map);
|
||||||
Object.assign(this._orig, map);
|
Object.assign(this._orig, map);
|
||||||
|
|
||||||
this._password = null;
|
this._password = null;
|
||||||
this._avatarContent = null;
|
this._avatarContent = null;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = User;
|
module.exports = User;
|
||||||
|
|
|
@ -8,8 +8,8 @@ const User = require('./user.js');
|
||||||
class UserList extends AbstractList {
|
class UserList extends AbstractList {
|
||||||
static search(text, offset, limit) {
|
static search(text, offset, limit) {
|
||||||
return api.get(
|
return api.get(
|
||||||
uri.formatApiLink(
|
uri.formatApiLink(
|
||||||
'users', {query: text, offset: offset, limit: limit}))
|
'users', {query: text, offset: offset, limit: limit}))
|
||||||
.then(response => {
|
.then(response => {
|
||||||
return Promise.resolve(Object.assign(
|
return Promise.resolve(Object.assign(
|
||||||
{},
|
{},
|
||||||
|
|
|
@ -11,16 +11,41 @@ class UserToken extends events.EventTarget {
|
||||||
this._updateFromResponse({});
|
this._updateFromResponse({});
|
||||||
}
|
}
|
||||||
|
|
||||||
get token() { return this._token; }
|
get token() {
|
||||||
get note() { return this._note; }
|
return this._token;
|
||||||
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; }
|
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) {
|
static fromResponse(response) {
|
||||||
if (typeof response.results !== 'undefined') {
|
if (typeof response.results !== 'undefined') {
|
||||||
|
@ -98,14 +123,14 @@ class UserToken extends events.EventTarget {
|
||||||
|
|
||||||
_updateFromResponse(response) {
|
_updateFromResponse(response) {
|
||||||
const map = {
|
const map = {
|
||||||
_token: response.token,
|
_token: response.token,
|
||||||
_note: response.note,
|
_note: response.note,
|
||||||
_enabled: response.enabled,
|
_enabled: response.enabled,
|
||||||
_expirationTime: response.expirationTime,
|
_expirationTime: response.expirationTime,
|
||||||
_version: response.version,
|
_version: response.version,
|
||||||
_creationTime: response.creationTime,
|
_creationTime: response.creationTime,
|
||||||
_lastEditTime: response.lastEditTime,
|
_lastEditTime: response.lastEditTime,
|
||||||
_lastUsageTime: response.lastUsageTime,
|
_lastUsageTime: response.lastUsageTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.assign(this, map);
|
Object.assign(this, map);
|
||||||
|
|
|
@ -51,7 +51,7 @@ class Context {
|
||||||
replaceState() {
|
replaceState() {
|
||||||
history.replaceState(this.state, this.title, this.canonicalPath);
|
history.replaceState(this.state, this.title, this.canonicalPath);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
class Route {
|
class Route {
|
||||||
constructor(path) {
|
constructor(path) {
|
||||||
|
@ -119,7 +119,7 @@ class Route {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
class Router {
|
class Router {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -217,14 +217,14 @@ class Router {
|
||||||
if (current === ctx.canonicalPath) {
|
if (current === ctx.canonicalPath) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.stop();
|
this.stop();
|
||||||
location.href = ctx.canonicalPath;
|
location.href = ctx.canonicalPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
get url() {
|
get url() {
|
||||||
return location.pathname + location.search + location.hash;
|
return location.pathname + location.search + location.hash;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const _onPopState = router => {
|
const _onPopState = router => {
|
||||||
let loaded = false;
|
let loaded = false;
|
||||||
|
|
|
@ -5,6 +5,7 @@ const settings = require('../models/settings.js');
|
||||||
|
|
||||||
let paused = false;
|
let paused = false;
|
||||||
const _originalStopCallback = mousetrap.prototype.stopCallback;
|
const _originalStopCallback = mousetrap.prototype.stopCallback;
|
||||||
|
// eslint-disable-next-line func-names
|
||||||
mousetrap.prototype.stopCallback = function(...args) {
|
mousetrap.prototype.stopCallback = function(...args) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (paused) {
|
if (paused) {
|
||||||
|
@ -28,6 +29,10 @@ function unbind(hotkey) {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
bind: bind,
|
bind: bind,
|
||||||
unbind: unbind,
|
unbind: unbind,
|
||||||
pause: () => { paused = true; },
|
pause: () => {
|
||||||
unpause: () => { paused = false; },
|
paused = true;
|
||||||
|
},
|
||||||
|
unpause: () => {
|
||||||
|
paused = false;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
class TagPermalinkFixWrapper extends BaseMarkdownWrapper {
|
||||||
preprocess(text) {
|
preprocess(text) {
|
||||||
return text.replace(/^#/g, '%%%#');
|
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 {
|
class EntityPermalinkWrapper extends BaseMarkdownWrapper {
|
||||||
preprocess(text) {
|
preprocess(text) {
|
||||||
// URL-based permalinks
|
// URL-based permalinks
|
||||||
|
@ -127,7 +127,7 @@ function createRenderer() {
|
||||||
const renderer = new marked.Renderer();
|
const renderer = new marked.Renderer();
|
||||||
renderer.image = (href, title, alt) => {
|
renderer.image = (href, title, alt) => {
|
||||||
let [_, url, width, height] =
|
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 = '<img src="' + sanitize(url) + '" alt="' + sanitize(alt);
|
let res = '<img src="' + sanitize(url) + '" alt="' + sanitize(alt);
|
||||||
if (width) {
|
if (width) {
|
||||||
res += '" width="' + width;
|
res += '" width="' + width;
|
||||||
|
|
|
@ -12,8 +12,8 @@ function decamelize(str, sep) {
|
||||||
.toLowerCase();
|
.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
function* range(start=0, end=null, step=1) {
|
function *range(start = 0, end = null, step = 1) {
|
||||||
if (end == null) {
|
if (end === null) {
|
||||||
end = start;
|
end = start;
|
||||||
start = 0;
|
start = 0;
|
||||||
}
|
}
|
||||||
|
@ -63,17 +63,17 @@ function formatRelativeTime(timeString) {
|
||||||
const future = now < then;
|
const future = now < then;
|
||||||
|
|
||||||
const descriptions = [
|
const descriptions = [
|
||||||
[60, 'a few seconds', null],
|
[60, 'a few seconds', null],
|
||||||
[60 * 2, 'a minute', null],
|
[60 * 2, 'a minute', null],
|
||||||
[60 * 60, '% minutes', 60],
|
[60 * 60, '% minutes', 60],
|
||||||
[60 * 60 * 2, 'an hour', null],
|
[60 * 60 * 2, 'an hour', null],
|
||||||
[60 * 60 * 24, '% hours', 60 * 60],
|
[60 * 60 * 24, '% hours', 60 * 60],
|
||||||
[60 * 60 * 24 * 2, 'a day', null],
|
[60 * 60 * 24 * 2, 'a day', null],
|
||||||
[60 * 60 * 24 * 30.42, '% days', 60 * 60 * 24],
|
[60 * 60 * 24 * 30.42, '% days', 60 * 60 * 24],
|
||||||
[60 * 60 * 24 * 30.42 * 2, 'a month', null],
|
[60 * 60 * 24 * 30.42 * 2, 'a month', null],
|
||||||
[60 * 60 * 24 * 30.42 * 12, '% months', 60 * 60 * 24 * 30.42],
|
[60 * 60 * 24 * 30.42 * 12, '% months', 60 * 60 * 24 * 30.42],
|
||||||
[60 * 60 * 24 * 30.42 * 12 * 2, 'a year', null],
|
[60 * 60 * 24 * 30.42 * 12 * 2, 'a year', null],
|
||||||
[8640000000000000 /*max*/, '% years', 60 * 60 * 24 * 30.42 * 12],
|
[8640000000000000 /* max*/, '% years', 60 * 60 * 24 * 30.42 * 12],
|
||||||
];
|
];
|
||||||
|
|
||||||
let text = null;
|
let text = null;
|
||||||
|
@ -192,7 +192,7 @@ function dataURItoBlob(dataURI) {
|
||||||
unescape(chunks[1]);
|
unescape(chunks[1]);
|
||||||
const mimeString = chunks[0].split(':')[1].split(';')[0];
|
const mimeString = chunks[0].split(':')[1].split(';')[0];
|
||||||
const data = new Uint8Array(byteString.length);
|
const data = new Uint8Array(byteString.length);
|
||||||
for (var i = 0; i < byteString.length; i++) {
|
for (let i = 0; i < byteString.length; i++) {
|
||||||
data[i] = byteString.charCodeAt(i);
|
data[i] = byteString.charCodeAt(i);
|
||||||
}
|
}
|
||||||
return new Blob([data], {type: mimeString});
|
return new Blob([data], {type: mimeString});
|
||||||
|
@ -206,21 +206,21 @@ function getPrettyTagName(tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
range: range,
|
range: range,
|
||||||
formatRelativeTime: formatRelativeTime,
|
formatRelativeTime: formatRelativeTime,
|
||||||
formatFileSize: formatFileSize,
|
formatFileSize: formatFileSize,
|
||||||
formatMarkdown: formatMarkdown,
|
formatMarkdown: formatMarkdown,
|
||||||
formatInlineMarkdown: formatInlineMarkdown,
|
formatInlineMarkdown: formatInlineMarkdown,
|
||||||
unindent: unindent,
|
unindent: unindent,
|
||||||
enableExitConfirmation: enableExitConfirmation,
|
enableExitConfirmation: enableExitConfirmation,
|
||||||
disableExitConfirmation: disableExitConfirmation,
|
disableExitConfirmation: disableExitConfirmation,
|
||||||
confirmPageExit: confirmPageExit,
|
confirmPageExit: confirmPageExit,
|
||||||
escapeHtml: escapeHtml,
|
escapeHtml: escapeHtml,
|
||||||
makeCssName: makeCssName,
|
makeCssName: makeCssName,
|
||||||
splitByWhitespace: splitByWhitespace,
|
splitByWhitespace: splitByWhitespace,
|
||||||
arraysDiffer: arraysDiffer,
|
arraysDiffer: arraysDiffer,
|
||||||
decamelize: decamelize,
|
decamelize: decamelize,
|
||||||
escapeSearchTerm: escapeSearchTerm,
|
escapeSearchTerm: escapeSearchTerm,
|
||||||
dataURItoBlob: dataURItoBlob,
|
dataURItoBlob: dataURItoBlob,
|
||||||
getPrettyTagName: getPrettyTagName,
|
getPrettyTagName: getPrettyTagName,
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@ function resize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function runCallbacks() {
|
function runCallbacks() {
|
||||||
callbacks.forEach(function(callback) {
|
callbacks.forEach(callback => {
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
running = false;
|
running = false;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/* eslint-disable func-names, no-extend-native */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// fix iterating over NodeList in Chrome and Opera
|
// fix iterating over NodeList in Chrome and Opera
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
const nprogress = require('nprogress');
|
const nprogress = require('nprogress');
|
||||||
|
|
||||||
let nesting = 0;
|
let nesting = 0;
|
||||||
|
@ -20,5 +22,5 @@ function done() {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
start: start,
|
start: start,
|
||||||
done: done,
|
done: done,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
const direction = {
|
const direction = {
|
||||||
NONE: null,
|
NONE: null,
|
||||||
LEFT: 'left',
|
LEFT: 'left',
|
||||||
|
@ -26,30 +28,29 @@ function handleTouchMove(handler, evt) {
|
||||||
} else {
|
} else {
|
||||||
handler._direction = direction.RIGHT;
|
handler._direction = direction.RIGHT;
|
||||||
}
|
}
|
||||||
|
} else if (yDirection > 0) {
|
||||||
|
handler._direction = direction.DOWN;
|
||||||
} else {
|
} else {
|
||||||
if (yDirection > 0) {
|
handler._direction = direction.UP;
|
||||||
handler._direction = direction.DOWN;
|
|
||||||
} else {
|
|
||||||
handler._direction = direction.UP;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTouchEnd(handler) {
|
function handleTouchEnd(handler) {
|
||||||
switch (handler._direction) {
|
switch (handler._direction) {
|
||||||
case direction.NONE:
|
case direction.NONE:
|
||||||
return;
|
return;
|
||||||
case direction.LEFT:
|
case direction.LEFT:
|
||||||
handler._swipeLeftTask();
|
handler._swipeLeftTask();
|
||||||
break;
|
break;
|
||||||
case direction.RIGHT:
|
case direction.RIGHT:
|
||||||
handler._swipeRightTask();
|
handler._swipeRightTask();
|
||||||
break;
|
break;
|
||||||
case direction.DOWN:
|
case direction.DOWN:
|
||||||
handler._swipeDownTask();
|
handler._swipeDownTask();
|
||||||
break;
|
break;
|
||||||
case direction.UP:
|
case direction.UP:
|
||||||
handler._swipeUpTask();
|
handler._swipeUpTask();
|
||||||
|
// no default
|
||||||
}
|
}
|
||||||
|
|
||||||
handler._xStart = null;
|
handler._xStart = null;
|
||||||
|
@ -58,10 +59,10 @@ function handleTouchEnd(handler) {
|
||||||
|
|
||||||
class Touch {
|
class Touch {
|
||||||
constructor(target,
|
constructor(target,
|
||||||
swipeLeft = () => {},
|
swipeLeft = () => {},
|
||||||
swipeRight = () => {},
|
swipeRight = () => {},
|
||||||
swipeUp = () => {},
|
swipeUp = () => {},
|
||||||
swipeDown = () => {}) {
|
swipeDown = () => {}) {
|
||||||
this._target = target;
|
this._target = target;
|
||||||
|
|
||||||
this._swipeLeftTask = swipeLeft;
|
this._swipeLeftTask = swipeLeft;
|
||||||
|
@ -74,12 +75,18 @@ class Touch {
|
||||||
this._direction = direction.NONE;
|
this._direction = direction.NONE;
|
||||||
|
|
||||||
this._target.addEventListener('touchstart',
|
this._target.addEventListener('touchstart',
|
||||||
(evt) => { handleTouchStart(this, evt); });
|
evt => {
|
||||||
|
handleTouchStart(this, evt);
|
||||||
|
});
|
||||||
this._target.addEventListener('touchmove',
|
this._target.addEventListener('touchmove',
|
||||||
(evt) => { handleTouchMove(this, evt); });
|
evt => {
|
||||||
|
handleTouchMove(this, evt);
|
||||||
|
});
|
||||||
this._target.addEventListener('touchend',
|
this._target.addEventListener('touchend',
|
||||||
() => { handleTouchEnd(this); });
|
() => {
|
||||||
|
handleTouchEnd(this);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Touch;
|
module.exports = Touch;
|
||||||
|
|
|
@ -72,7 +72,7 @@ function extractRootDomain(url) {
|
||||||
if (arrLen > 2) {
|
if (arrLen > 2) {
|
||||||
domain = splitArr[arrLen - 2] + '.' + splitArr[arrLen - 1];
|
domain = splitArr[arrLen - 2] + '.' + splitArr[arrLen - 1];
|
||||||
// check to see if it's using a Country Code Top Level Domain (ccTLD) (i.e. ".me.uk")
|
// check to see if it's using a Country Code Top Level Domain (ccTLD) (i.e. ".me.uk")
|
||||||
if (splitArr[arrLen - 2].length == 2 && splitArr[arrLen - 1].length == 2) {
|
if (splitArr[arrLen - 2].length === 2 && splitArr[arrLen - 1].length === 2) {
|
||||||
// this is using a ccTLD
|
// this is using a ccTLD
|
||||||
domain = splitArr[arrLen - 3] + '.' + domain;
|
domain = splitArr[arrLen - 3] + '.' + domain;
|
||||||
}
|
}
|
||||||
|
@ -85,11 +85,11 @@ function escapeColons(text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
formatClientLink: formatClientLink,
|
formatClientLink: formatClientLink,
|
||||||
formatApiLink: formatApiLink,
|
formatApiLink: formatApiLink,
|
||||||
escapeColons: escapeColons,
|
escapeColons: escapeColons,
|
||||||
escapeParam: escapeParam,
|
escapeParam: escapeParam,
|
||||||
unescapeParam: unescapeParam,
|
unescapeParam: unescapeParam,
|
||||||
extractHostname: extractHostname,
|
extractHostname: extractHostname,
|
||||||
extractRootDomain: extractRootDomain,
|
extractRootDomain: extractRootDomain,
|
||||||
};
|
};
|
||||||
|
|
|
@ -94,11 +94,10 @@ function makeSelect(options) {
|
||||||
name: options.name,
|
name: options.name,
|
||||||
disabled: options.readonly,
|
disabled: options.readonly,
|
||||||
},
|
},
|
||||||
...Object.keys(options.keyValues).map(key =>
|
...Object.keys(options.keyValues).map(key => makeElement(
|
||||||
makeElement(
|
'option',
|
||||||
'option',
|
{value: key, selected: key === options.selectedKey},
|
||||||
{value: key, selected: key === options.selectedKey},
|
options.keyValues[key])));
|
||||||
options.keyValues[key])));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeInput(options) {
|
function makeInput(options) {
|
||||||
|
@ -157,10 +156,7 @@ function makeColorInput(options) {
|
||||||
color: ${options.value}`,
|
color: ${options.value}`,
|
||||||
});
|
});
|
||||||
return makeElement(
|
return makeElement(
|
||||||
'label', {class: 'color'},
|
'label', {class: 'color'}, textInput, backgroundPreviewNode, textPreviewNode);
|
||||||
textInput,
|
|
||||||
backgroundPreviewNode,
|
|
||||||
textPreviewNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeNumericInput(options) {
|
function makeNumericInput(options) {
|
||||||
|
@ -175,14 +171,12 @@ function makeDateInput(options) {
|
||||||
|
|
||||||
function getPostUrl(id, parameters) {
|
function getPostUrl(id, parameters) {
|
||||||
return uri.formatClientLink(
|
return uri.formatClientLink(
|
||||||
'post', id,
|
'post', id, parameters ? {query: parameters.query} : {});
|
||||||
parameters ? {query: parameters.query} : {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPostEditUrl(id, parameters) {
|
function getPostEditUrl(id, parameters) {
|
||||||
return uri.formatClientLink(
|
return uri.formatClientLink(
|
||||||
'post', id, 'edit',
|
'post', id, 'edit', parameters ? {query: parameters.query} : {});
|
||||||
parameters ? {query: parameters.query} : {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function makePostLink(id, includeHash) {
|
function makePostLink(id, includeHash) {
|
||||||
|
@ -335,26 +329,25 @@ function clearMessages(target) {
|
||||||
function htmlToDom(html) {
|
function htmlToDom(html) {
|
||||||
// code taken from jQuery + Krasimir Tsonev's blog
|
// code taken from jQuery + Krasimir Tsonev's blog
|
||||||
const wrapMap = {
|
const wrapMap = {
|
||||||
_: [1, '<div>', '</div>'],
|
_: [1, '<div>', '</div>'],
|
||||||
option: [1, '<select multiple>', '</select>'],
|
option: [1, '<select multiple>', '</select>'],
|
||||||
legend: [1, '<fieldset>', '</fieldset>'],
|
legend: [1, '<fieldset>', '</fieldset>'],
|
||||||
area: [1, '<map>', '</map>'],
|
area: [1, '<map>', '</map>'],
|
||||||
param: [1, '<object>', '</object>'],
|
param: [1, '<object>', '</object>'],
|
||||||
thead: [1, '<table>', '</table>'],
|
thead: [1, '<table>', '</table>'],
|
||||||
tr: [2, '<table><tbody>', '</tbody></table>'],
|
tr: [2, '<table><tbody>', '</tbody></table>'],
|
||||||
td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
|
td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
|
||||||
col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
|
col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
|
||||||
};
|
};
|
||||||
wrapMap.optgroup = wrapMap.option;
|
wrapMap.optgroup = wrapMap.option;
|
||||||
wrapMap.tbody =
|
wrapMap.tbody = wrapMap.thead;
|
||||||
wrapMap.tfoot =
|
wrapMap.tfoot = wrapMap.thead;
|
||||||
wrapMap.colgroup =
|
wrapMap.colgroup = wrapMap.thead;
|
||||||
wrapMap.caption =
|
wrapMap.caption = wrapMap.thead;
|
||||||
wrapMap.thead;
|
|
||||||
wrapMap.th = wrapMap.td;
|
wrapMap.th = wrapMap.td;
|
||||||
|
|
||||||
let element = document.createElement('div');
|
let element = document.createElement('div');
|
||||||
const match = /<\s*(\w+)[^>]*?>/g.exec(html);
|
const match = (/<\s*(\w+)[^>]*?>/g).exec(html);
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
const tag = match[1];
|
const tag = match[1];
|
||||||
|
@ -381,32 +374,32 @@ function getTemplate(templatePath) {
|
||||||
ctx = {};
|
ctx = {};
|
||||||
}
|
}
|
||||||
Object.assign(ctx, {
|
Object.assign(ctx, {
|
||||||
getPostUrl: getPostUrl,
|
getPostUrl: getPostUrl,
|
||||||
getPostEditUrl: getPostEditUrl,
|
getPostEditUrl: getPostEditUrl,
|
||||||
makeRelativeTime: makeRelativeTime,
|
makeRelativeTime: makeRelativeTime,
|
||||||
makeFileSize: makeFileSize,
|
makeFileSize: makeFileSize,
|
||||||
makeMarkdown: makeMarkdown,
|
makeMarkdown: makeMarkdown,
|
||||||
makeThumbnail: makeThumbnail,
|
makeThumbnail: makeThumbnail,
|
||||||
makeRadio: makeRadio,
|
makeRadio: makeRadio,
|
||||||
makeCheckbox: makeCheckbox,
|
makeCheckbox: makeCheckbox,
|
||||||
makeSelect: makeSelect,
|
makeSelect: makeSelect,
|
||||||
makeInput: makeInput,
|
makeInput: makeInput,
|
||||||
makeButton: makeButton,
|
makeButton: makeButton,
|
||||||
makeTextarea: makeTextarea,
|
makeTextarea: makeTextarea,
|
||||||
makeTextInput: makeTextInput,
|
makeTextInput: makeTextInput,
|
||||||
makePasswordInput: makePasswordInput,
|
makePasswordInput: makePasswordInput,
|
||||||
makeEmailInput: makeEmailInput,
|
makeEmailInput: makeEmailInput,
|
||||||
makeColorInput: makeColorInput,
|
makeColorInput: makeColorInput,
|
||||||
makeDateInput: makeDateInput,
|
makeDateInput: makeDateInput,
|
||||||
makePostLink: makePostLink,
|
makePostLink: makePostLink,
|
||||||
makeTagLink: makeTagLink,
|
makeTagLink: makeTagLink,
|
||||||
makeUserLink: makeUserLink,
|
makeUserLink: makeUserLink,
|
||||||
makeFlexboxAlign: makeFlexboxAlign,
|
makeFlexboxAlign: makeFlexboxAlign,
|
||||||
makeAccessKey: makeAccessKey,
|
makeAccessKey: makeAccessKey,
|
||||||
makeElement: makeElement,
|
makeElement: makeElement,
|
||||||
makeCssName: misc.makeCssName,
|
makeCssName: misc.makeCssName,
|
||||||
makeNumericInput: makeNumericInput,
|
makeNumericInput: makeNumericInput,
|
||||||
formatClientLink: uri.formatClientLink
|
formatClientLink: uri.formatClientLink
|
||||||
});
|
});
|
||||||
return htmlToDom(templateFactory(ctx));
|
return htmlToDom(templateFactory(ctx));
|
||||||
};
|
};
|
||||||
|
@ -444,7 +437,7 @@ function enableForm(form) {
|
||||||
function syncScrollPosition() {
|
function syncScrollPosition() {
|
||||||
window.requestAnimationFrame(
|
window.requestAnimationFrame(
|
||||||
() => {
|
() => {
|
||||||
if (history.state && history.state.hasOwnProperty('scrollX')) {
|
if (history.state && Object.prototype.hasOwnProperty.call(history.state, 'scrollX')) {
|
||||||
window.scrollTo(history.state.scrollX, history.state.scrollY);
|
window.scrollTo(history.state.scrollX, history.state.scrollY);
|
||||||
} else {
|
} else {
|
||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
|
@ -520,24 +513,24 @@ document.addEventListener('click', e => {
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
htmlToDom: htmlToDom,
|
htmlToDom: htmlToDom,
|
||||||
getTemplate: getTemplate,
|
getTemplate: getTemplate,
|
||||||
emptyContent: emptyContent,
|
emptyContent: emptyContent,
|
||||||
replaceContent: replaceContent,
|
replaceContent: replaceContent,
|
||||||
enableForm: enableForm,
|
enableForm: enableForm,
|
||||||
disableForm: disableForm,
|
disableForm: disableForm,
|
||||||
decorateValidator: decorateValidator,
|
decorateValidator: decorateValidator,
|
||||||
makeTagLink: makeTagLink,
|
makeTagLink: makeTagLink,
|
||||||
makePostLink: makePostLink,
|
makePostLink: makePostLink,
|
||||||
makeCheckbox: makeCheckbox,
|
makeCheckbox: makeCheckbox,
|
||||||
makeRadio: makeRadio,
|
makeRadio: makeRadio,
|
||||||
syncScrollPosition: syncScrollPosition,
|
syncScrollPosition: syncScrollPosition,
|
||||||
slideDown: slideDown,
|
slideDown: slideDown,
|
||||||
slideUp: slideUp,
|
slideUp: slideUp,
|
||||||
monitorNodeRemoval: monitorNodeRemoval,
|
monitorNodeRemoval: monitorNodeRemoval,
|
||||||
clearMessages: clearMessages,
|
clearMessages: clearMessages,
|
||||||
appendExclamationMark: appendExclamationMark,
|
appendExclamationMark: appendExclamationMark,
|
||||||
showError: showError,
|
showError: showError,
|
||||||
showSuccess: showSuccess,
|
showSuccess: showSuccess,
|
||||||
showInfo: showInfo,
|
showInfo: showInfo,
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@ function isScrolledIntoView(element) {
|
||||||
do {
|
do {
|
||||||
top += element.offsetTop || 0;
|
top += element.offsetTop || 0;
|
||||||
element = element.offsetParent;
|
element = element.offsetParent;
|
||||||
} while(element);
|
} while (element);
|
||||||
return (
|
return (
|
||||||
(top >= window.scrollY) &&
|
(top >= window.scrollY) &&
|
||||||
(top <= window.scrollY + window.innerHeight));
|
(top <= window.scrollY + window.innerHeight));
|
||||||
|
|
|
@ -47,7 +47,7 @@ class HelpView {
|
||||||
views.replaceContent(this._hostNode, sourceNode);
|
views.replaceContent(this._hostNode, sourceNode);
|
||||||
|
|
||||||
for (let itemNode of
|
for (let itemNode of
|
||||||
sourceNode.querySelectorAll('.primary [data-name]')) {
|
sourceNode.querySelectorAll('.primary [data-name]')) {
|
||||||
itemNode.classList.toggle(
|
itemNode.classList.toggle(
|
||||||
'active',
|
'active',
|
||||||
itemNode.getAttribute('data-name') === section);
|
itemNode.getAttribute('data-name') === section);
|
||||||
|
@ -59,7 +59,7 @@ class HelpView {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let itemNode of
|
for (let itemNode of
|
||||||
sourceNode.querySelectorAll('.secondary [data-name]')) {
|
sourceNode.querySelectorAll('.secondary [data-name]')) {
|
||||||
itemNode.classList.toggle(
|
itemNode.classList.toggle(
|
||||||
'active',
|
'active',
|
||||||
itemNode.getAttribute('data-name') === subsection);
|
itemNode.getAttribute('data-name') === subsection);
|
||||||
|
|
|
@ -27,9 +27,8 @@ class HomeView {
|
||||||
this._autoCompleteControl = new TagAutoCompleteControl(
|
this._autoCompleteControl = new TagAutoCompleteControl(
|
||||||
this._searchInputNode,
|
this._searchInputNode,
|
||||||
{
|
{
|
||||||
confirm: tag =>
|
confirm: tag => this._autoCompleteControl.replaceSelectedText(
|
||||||
this._autoCompleteControl.replaceSelectedText(
|
misc.escapeSearchTerm(tag.names[0]), true),
|
||||||
misc.escapeSearchTerm(tag.names[0]), true),
|
|
||||||
});
|
});
|
||||||
this._formNode.addEventListener(
|
this._formNode.addEventListener(
|
||||||
'submit', e => this._evtFormSubmit(e));
|
'submit', e => this._evtFormSubmit(e));
|
||||||
|
@ -99,8 +98,7 @@ class HomeView {
|
||||||
_evtFormSubmit(e) {
|
_evtFormSubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._searchInputNode.blur();
|
this._searchInputNode.blur();
|
||||||
router.show(uri.formatClientLink('posts', {
|
router.show(uri.formatClientLink('posts', {query: this._searchInputNode.value}));
|
||||||
query: this._searchInputNode.value}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ const navTemplate = views.getTemplate('manual-pager-nav');
|
||||||
|
|
||||||
function _removeConsecutiveDuplicates(a) {
|
function _removeConsecutiveDuplicates(a) {
|
||||||
return a.filter((item, pos, ary) => {
|
return a.filter((item, pos, ary) => {
|
||||||
return !pos || item != ary[pos - 1];
|
return !pos || item !== ary[pos - 1];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,20 +23,22 @@ function _getVisiblePageNumbers(currentPage, totalPages) {
|
||||||
pagesVisible.push(i);
|
pagesVisible.push(i);
|
||||||
}
|
}
|
||||||
for (let i = currentPage - threshold;
|
for (let i = currentPage - threshold;
|
||||||
i <= currentPage + threshold;
|
i <= currentPage + threshold;
|
||||||
i++) {
|
i++) {
|
||||||
pagesVisible.push(i);
|
pagesVisible.push(i);
|
||||||
}
|
}
|
||||||
pagesVisible = pagesVisible.filter((item, pos, ary) => {
|
pagesVisible = pagesVisible.filter((item, pos, ary) => {
|
||||||
return item >= 1 && item <= totalPages;
|
return item >= 1 && item <= totalPages;
|
||||||
});
|
});
|
||||||
pagesVisible = pagesVisible.sort((a, b) => { return a - b; });
|
pagesVisible = pagesVisible.sort((a, b) => {
|
||||||
|
return a - b;
|
||||||
|
});
|
||||||
pagesVisible = _removeConsecutiveDuplicates(pagesVisible);
|
pagesVisible = _removeConsecutiveDuplicates(pagesVisible);
|
||||||
return pagesVisible;
|
return pagesVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getPages(
|
function _getPages(
|
||||||
currentPage, pageNumbers, limit, defaultLimit, removedItems) {
|
currentPage, pageNumbers, limit, defaultLimit, removedItems) {
|
||||||
const pages = new Map();
|
const pages = new Map();
|
||||||
let prevPage = 0;
|
let prevPage = 0;
|
||||||
for (let page of pageNumbers) {
|
for (let page of pageNumbers) {
|
||||||
|
@ -46,7 +48,7 @@ function _getPages(
|
||||||
pages.set(page, {
|
pages.set(page, {
|
||||||
number: page,
|
number: page,
|
||||||
offset:
|
offset:
|
||||||
(page - 1) * limit -
|
((page - 1) * limit) -
|
||||||
(page > currentPage ? removedItems : 0),
|
(page > currentPage ? removedItems : 0),
|
||||||
limit: limit === defaultLimit ? null : limit,
|
limit: limit === defaultLimit ? null : limit,
|
||||||
active: currentPage === page,
|
active: currentPage === page,
|
||||||
|
|
|
@ -43,7 +43,7 @@ class PostMainView {
|
||||||
margin,
|
margin,
|
||||||
iosCorrectedInnerHeight() -
|
iosCorrectedInnerHeight() -
|
||||||
topNavigationNode.getBoundingClientRect().height -
|
topNavigationNode.getBoundingClientRect().height -
|
||||||
margin * 2,
|
(margin * 2),
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ class PostMainView {
|
||||||
});
|
});
|
||||||
keyboard.bind(['a', 'left'], showPreviousImage);
|
keyboard.bind(['a', 'left'], showPreviousImage);
|
||||||
keyboard.bind(['d', 'right'], showNextImage);
|
keyboard.bind(['d', 'right'], showNextImage);
|
||||||
keyboard.bind('del', (e) => {
|
keyboard.bind('del', e => {
|
||||||
if (ctx.editMode) {
|
if (ctx.editMode) {
|
||||||
this.sidebarControl._evtDeleteClick(e);
|
this.sidebarControl._evtDeleteClick(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,7 @@ class PostMergeView extends events.EventTarget {
|
||||||
_refreshSide(post, sideNode, sideName, isEditable) {
|
_refreshSide(post, sideNode, sideName, isEditable) {
|
||||||
views.replaceContent(
|
views.replaceContent(
|
||||||
sideNode,
|
sideNode,
|
||||||
sideTemplate(Object.assign({}, this._ctx, {
|
sideTemplate(Object.assign({}, this._ctx, {post: post,
|
||||||
post: post,
|
|
||||||
name: sideName,
|
name: sideName,
|
||||||
editable: isEditable})));
|
editable: isEditable})));
|
||||||
|
|
||||||
|
@ -85,10 +84,10 @@ class PostMergeView extends events.EventTarget {
|
||||||
'.target-post-content :checked').value;
|
'.target-post-content :checked').value;
|
||||||
this.dispatchEvent(new CustomEvent('submit', {
|
this.dispatchEvent(new CustomEvent('submit', {
|
||||||
detail: {
|
detail: {
|
||||||
post: checkedTargetPost == 'left' ?
|
post: checkedTargetPost === 'left' ?
|
||||||
this._rightPost :
|
this._rightPost :
|
||||||
this._leftPost,
|
this._leftPost,
|
||||||
targetPost: checkedTargetPost == 'left' ?
|
targetPost: checkedTargetPost === 'left' ?
|
||||||
this._leftPost :
|
this._leftPost :
|
||||||
this._rightPost,
|
this._rightPost,
|
||||||
useOldContent: checkedTargetPostContent !== checkedTargetPost,
|
useOldContent: checkedTargetPostContent !== checkedTargetPost,
|
||||||
|
|
|
@ -52,10 +52,6 @@ class BulkEditor extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class BulkSafetyEditor extends BulkEditor {
|
class BulkSafetyEditor extends BulkEditor {
|
||||||
constructor(hostNode) {
|
|
||||||
super(hostNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
_evtOpenLinkClick(e) {
|
_evtOpenLinkClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.toggleOpen(true);
|
this.toggleOpen(true);
|
||||||
|
@ -75,9 +71,8 @@ class BulkTagEditor extends BulkEditor {
|
||||||
this._autoCompleteControl = new TagAutoCompleteControl(
|
this._autoCompleteControl = new TagAutoCompleteControl(
|
||||||
this._inputNode,
|
this._inputNode,
|
||||||
{
|
{
|
||||||
confirm: tag =>
|
confirm: tag => this._autoCompleteControl.replaceSelectedText(
|
||||||
this._autoCompleteControl.replaceSelectedText(
|
tag.names[0], false),
|
||||||
tag.names[0], false),
|
|
||||||
});
|
});
|
||||||
this._hostNode.addEventListener('submit', e => this._evtFormSubmit(e));
|
this._hostNode.addEventListener('submit', e => this._evtFormSubmit(e));
|
||||||
}
|
}
|
||||||
|
@ -132,9 +127,8 @@ class PostsHeaderView extends events.EventTarget {
|
||||||
this._autoCompleteControl = new TagAutoCompleteControl(
|
this._autoCompleteControl = new TagAutoCompleteControl(
|
||||||
this._queryInputNode,
|
this._queryInputNode,
|
||||||
{
|
{
|
||||||
confirm: tag =>
|
confirm: tag => this._autoCompleteControl.replaceSelectedText(
|
||||||
this._autoCompleteControl.replaceSelectedText(
|
misc.escapeSearchTerm(tag.names[0]), true),
|
||||||
misc.escapeSearchTerm(tag.names[0]), true),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
keyboard.bind('p', () => this._focusFirstPostNode());
|
keyboard.bind('p', () => this._focusFirstPostNode());
|
||||||
|
@ -246,7 +240,7 @@ class PostsHeaderView extends events.EventTarget {
|
||||||
_navigate() {
|
_navigate() {
|
||||||
this._autoCompleteControl.hide();
|
this._autoCompleteControl.hide();
|
||||||
let parameters = {query: this._queryInputNode.value};
|
let parameters = {query: this._queryInputNode.value};
|
||||||
|
|
||||||
// convert falsy values to an empty string "" so that we can correctly compare with the current query
|
// convert falsy values to an empty string "" so that we can correctly compare with the current query
|
||||||
const prevQuery = this._ctx.parameters.query ? this._ctx.parameters.query : "";
|
const prevQuery = this._ctx.parameters.query ? this._ctx.parameters.query : "";
|
||||||
parameters.offset = parameters.query === prevQuery ? this._ctx.parameters.offset : 0;
|
parameters.offset = parameters.query === prevQuery ? this._ctx.parameters.offset : 0;
|
||||||
|
|
|
@ -100,7 +100,7 @@ class PostsPageView extends events.EventTarget {
|
||||||
if (tagFlipperNode) {
|
if (tagFlipperNode) {
|
||||||
let tagged = true;
|
let tagged = true;
|
||||||
for (let tag of this._ctx.bulkEdit.tags) {
|
for (let tag of this._ctx.bulkEdit.tags) {
|
||||||
tagged = tagged & post.tags.isTaggedWith(tag);
|
tagged &= post.tags.isTaggedWith(tag);
|
||||||
}
|
}
|
||||||
tagFlipperNode.classList.toggle('tagged', tagged);
|
tagFlipperNode.classList.toggle('tagged', tagged);
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ class PostsPageView extends events.EventTarget {
|
||||||
if (safetyFlipperNode) {
|
if (safetyFlipperNode) {
|
||||||
for (let linkNode of safetyFlipperNode.querySelectorAll('a')) {
|
for (let linkNode of safetyFlipperNode.querySelectorAll('a')) {
|
||||||
const safety = linkNode.getAttribute('data-safety');
|
const safety = linkNode.getAttribute('data-safety');
|
||||||
linkNode.classList.toggle('active', post.safety == safety);
|
linkNode.classList.toggle('active', post.safety === safety);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ class RegistrationView extends events.EventTarget {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.dispatchEvent(new CustomEvent('submit', {
|
this.dispatchEvent(new CustomEvent('submit', {
|
||||||
detail: {
|
detail: {
|
||||||
name: this._userNameFieldNode.value,
|
name: this._userNameFieldNode.value,
|
||||||
password: this._passwordFieldNode.value,
|
password: this._passwordFieldNode.value,
|
||||||
email: this._emailFieldNode.value,
|
email: this._emailFieldNode.value,
|
||||||
},
|
},
|
||||||
|
|
|
@ -33,7 +33,7 @@ class TagEditView extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let node of this._formNode.querySelectorAll(
|
for (let node of this._formNode.querySelectorAll(
|
||||||
'input, select, textarea')) {
|
'input, select, textarea')) {
|
||||||
node.addEventListener(
|
node.addEventListener(
|
||||||
'change', e => {
|
'change', e => {
|
||||||
this.dispatchEvent(new CustomEvent('change'));
|
this.dispatchEvent(new CustomEvent('change'));
|
||||||
|
|
|
@ -22,9 +22,8 @@ class TagMergeView extends events.EventTarget {
|
||||||
this._autoCompleteControl = new TagAutoCompleteControl(
|
this._autoCompleteControl = new TagAutoCompleteControl(
|
||||||
this._targetTagFieldNode,
|
this._targetTagFieldNode,
|
||||||
{
|
{
|
||||||
confirm: tag =>
|
confirm: tag => this._autoCompleteControl.replaceSelectedText(
|
||||||
this._autoCompleteControl.replaceSelectedText(
|
tag.names[0], false),
|
||||||
tag.names[0], false),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,8 @@ class TagsHeaderView extends events.EventTarget {
|
||||||
this._autoCompleteControl = new TagAutoCompleteControl(
|
this._autoCompleteControl = new TagAutoCompleteControl(
|
||||||
this._queryInputNode,
|
this._queryInputNode,
|
||||||
{
|
{
|
||||||
confirm: tag =>
|
confirm: tag => this._autoCompleteControl.replaceSelectedText(
|
||||||
this._autoCompleteControl.replaceSelectedText(
|
misc.escapeSearchTerm(tag.names[0]), true),
|
||||||
misc.escapeSearchTerm(tag.names[0]), true),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ class UserEditView extends events.EventTarget {
|
||||||
constructor(ctx) {
|
constructor(ctx) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
ctx.userNamePattern = api.getUserNameRegex() + /|^$/.source;
|
ctx.userNamePattern = api.getUserNameRegex() + (/|^$/).source;
|
||||||
ctx.passwordPattern = api.getPasswordRegex() + /|^$/.source;
|
ctx.passwordPattern = api.getPasswordRegex() + (/|^$/).source;
|
||||||
|
|
||||||
this._user = ctx.user;
|
this._user = ctx.user;
|
||||||
this._hostNode = ctx.hostNode;
|
this._hostNode = ctx.hostNode;
|
||||||
|
|
|
@ -92,9 +92,9 @@ class UserTokenView extends events.EventTarget {
|
||||||
expirationTime:
|
expirationTime:
|
||||||
(this._userTokenExpirationTimeInputNode
|
(this._userTokenExpirationTimeInputNode
|
||||||
&& this._userTokenExpirationTimeInputNode.value) ?
|
&& this._userTokenExpirationTimeInputNode.value) ?
|
||||||
new Date(this._userTokenExpirationTimeInputNode.value)
|
new Date(this._userTokenExpirationTimeInputNode.value)
|
||||||
.toISOString() :
|
.toISOString() :
|
||||||
undefined,
|
undefined,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ class UserView extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.hostNode = this._hostNode.querySelector('#user-content-holder');
|
ctx.hostNode = this._hostNode.querySelector('#user-content-holder');
|
||||||
if (ctx.section == 'edit') {
|
if (ctx.section === 'edit') {
|
||||||
if (!this._ctx.canEditAnything) {
|
if (!this._ctx.canEditAnything) {
|
||||||
this._view = new EmptyView();
|
this._view = new EmptyView();
|
||||||
this._view.showError(
|
this._view.showError(
|
||||||
|
@ -46,7 +46,7 @@ class UserView extends events.EventTarget {
|
||||||
this._view = new UserEditView(ctx);
|
this._view = new UserEditView(ctx);
|
||||||
events.proxyEvent(this._view, this, 'submit');
|
events.proxyEvent(this._view, this, 'submit');
|
||||||
}
|
}
|
||||||
} else if (ctx.section == 'list-tokens') {
|
} else if (ctx.section === 'list-tokens') {
|
||||||
if (!this._ctx.canListTokens) {
|
if (!this._ctx.canListTokens) {
|
||||||
this._view = new EmptyView();
|
this._view = new EmptyView();
|
||||||
this._view.showError(
|
this._view.showError(
|
||||||
|
@ -57,7 +57,7 @@ class UserView extends events.EventTarget {
|
||||||
events.proxyEvent(this._view, this, 'submit', 'create-token');
|
events.proxyEvent(this._view, this, 'submit', 'create-token');
|
||||||
events.proxyEvent(this._view, this, 'update', 'update-token');
|
events.proxyEvent(this._view, this, 'update', 'update-token');
|
||||||
}
|
}
|
||||||
} else if (ctx.section == 'delete') {
|
} else if (ctx.section === 'delete') {
|
||||||
if (!this._ctx.canDelete) {
|
if (!this._ctx.canDelete) {
|
||||||
this._view = new EmptyView();
|
this._view = new EmptyView();
|
||||||
this._view.showError(
|
this._view.showError(
|
||||||
|
|
Loading…
Reference in a new issue