1
0
mirror of https://github.com/flarum/core.git synced 2025-10-19 18:56:44 +02:00

Run prettier for all JS files

This commit is contained in:
Franz Liedke
2020-04-17 11:57:55 +02:00
parent 84cf938379
commit 89ef14faf1
145 changed files with 2374 additions and 2050 deletions

View File

@@ -86,7 +86,7 @@ export default class Application {
discussions: Discussion,
posts: Post,
groups: Group,
notifications: Notification
notifications: Notification,
});
/**
@@ -126,22 +126,19 @@ export default class Application {
}
boot() {
this.initializers.toArray().forEach(initializer => initializer(this));
this.initializers.toArray().forEach((initializer) => initializer(this));
this.store.pushPayload({data: this.data.resources});
this.store.pushPayload({ data: this.data.resources });
this.forum = this.store.getById('forums', 1);
this.session = new Session(
this.store.getById('users', this.data.session.userId),
this.data.session.csrfToken
);
this.session = new Session(this.store.getById('users', this.data.session.userId), this.data.session.csrfToken);
this.mount();
}
bootExtensions(extensions) {
Object.keys(extensions).forEach(name => {
Object.keys(extensions).forEach((name) => {
const extension = extensions[name];
const extenders = flattenDeep(extension.extend);
@@ -153,26 +150,20 @@ export default class Application {
}
mount(basePath = '') {
this.modal = m.mount(document.getElementById('modal'), <ModalManager/>);
this.alerts = m.mount(document.getElementById('alerts'), <AlertManager/>);
this.modal = m.mount(document.getElementById('modal'), <ModalManager />);
this.alerts = m.mount(document.getElementById('alerts'), <AlertManager />);
this.drawer = new Drawer();
m.route(
document.getElementById('content'),
basePath + '/',
mapRoutes(this.routes, basePath)
);
m.route(document.getElementById('content'), basePath + '/', mapRoutes(this.routes, basePath));
// Add a class to the body which indicates that the page has been scrolled
// down.
new ScrollListener(top => {
new ScrollListener((top) => {
const $app = $('#app');
const offset = $app.offset().top;
$app
.toggleClass('affix', top >= offset)
.toggleClass('scrolled', top > offset);
$app.toggleClass('affix', top >= offset).toggleClass('scrolled', top > offset);
}).start();
$(() => {
@@ -220,9 +211,7 @@ export default class Application {
}
updateTitle() {
document.title = (this.titleCount ? `(${this.titleCount}) ` : '') +
(this.title ? this.title + ' - ' : '') +
this.forum.attribute('title');
document.title = (this.titleCount ? `(${this.titleCount}) ` : '') + (this.title ? this.title + ' - ' : '') + this.forum.attribute('title');
}
/**
@@ -256,17 +245,19 @@ export default class Application {
// When we deserialize JSON data, if for some reason the server has provided
// a dud response, we don't want the application to crash. We'll show an
// error message to the user instead.
options.deserialize = options.deserialize || (responseText => responseText);
options.deserialize = options.deserialize || ((responseText) => responseText);
options.errorHandler = options.errorHandler || (error => {
throw error;
});
options.errorHandler =
options.errorHandler ||
((error) => {
throw error;
});
// When extracting the data from the response, we can check the server
// response code and show an error message to the user if something's gone
// awry.
const original = options.extract;
options.extract = xhr => {
options.extract = (xhr) => {
let responseText;
if (original) {
@@ -299,55 +290,60 @@ export default class Application {
// returned and show an alert containing its contents.
const deferred = m.deferred();
m.request(options).then(response => deferred.resolve(response), error => {
this.requestError = error;
m.request(options).then(
(response) => deferred.resolve(response),
(error) => {
this.requestError = error;
let children;
let children;
switch (error.status) {
case 422:
children = error.response.errors
.map(error => [error.detail, <br/>])
.reduce((a, b) => a.concat(b), [])
.slice(0, -1);
break;
switch (error.status) {
case 422:
children = error.response.errors
.map((error) => [error.detail, <br />])
.reduce((a, b) => a.concat(b), [])
.slice(0, -1);
break;
case 401:
case 403:
children = app.translator.trans('core.lib.error.permission_denied_message');
break;
case 401:
case 403:
children = app.translator.trans('core.lib.error.permission_denied_message');
break;
case 404:
case 410:
children = app.translator.trans('core.lib.error.not_found_message');
break;
case 404:
case 410:
children = app.translator.trans('core.lib.error.not_found_message');
break;
case 429:
children = app.translator.trans('core.lib.error.rate_limit_exceeded_message');
break;
case 429:
children = app.translator.trans('core.lib.error.rate_limit_exceeded_message');
break;
default:
children = app.translator.trans('core.lib.error.generic_message');
default:
children = app.translator.trans('core.lib.error.generic_message');
}
const isDebug = app.forum.attribute('debug');
error.alert = new Alert({
type: 'error',
children,
controls: isDebug && [
<Button className="Button Button--link" onclick={this.showDebug.bind(this, error)}>
Debug
</Button>,
],
});
try {
options.errorHandler(error);
} catch (error) {
this.alerts.show(error.alert);
}
deferred.reject(error);
}
const isDebug = app.forum.attribute('debug');
error.alert = new Alert({
type: 'error',
children,
controls: isDebug && [
<Button className="Button Button--link" onclick={this.showDebug.bind(this, error)}>Debug</Button>
]
});
try {
options.errorHandler(error);
} catch (error) {
this.alerts.show(error.alert);
}
deferred.reject(error);
});
);
return deferred.promise;
}
@@ -359,7 +355,7 @@ export default class Application {
showDebug(error) {
this.alerts.dismiss(this.requestError.alert);
this.modal.show(new RequestErrorModal({error}));
this.modal.show(new RequestErrorModal({ error }));
}
/**

View File

@@ -70,8 +70,7 @@ export default class Component {
*
* @protected
*/
init() {
}
init() {}
/**
* Called when the component is destroyed, i.e. after a redraw where it is no
@@ -81,8 +80,7 @@ export default class Component {
* @param {Object} e
* @public
*/
onunload() {
}
onunload() {}
/**
* Get the renderable virtual DOM that represents the component's view.
@@ -99,7 +97,7 @@ export default class Component {
* @public
*/
render() {
const vdom = this.retain ? {subtree: 'retain'} : this.view();
const vdom = this.retain ? { subtree: 'retain' } : this.view();
// Override the root element's config attribute with our own function, which
// will set the component instance's element property to the root DOM
@@ -148,8 +146,7 @@ export default class Component {
* @param {Object} vdom
* @public
*/
config() {
}
config() {}
/**
* Get the virtual DOM that represents the component's view.
@@ -201,14 +198,14 @@ export default class Component {
controller: this.bind(undefined, componentProps),
view: view,
props: componentProps,
component: this
component: this,
};
// If a `key` prop was set, then we'll assume that we want that to actually
// show up as an attribute on the component object so that Mithril's key
// algorithm can be applied.
if (componentProps.key) {
output.attrs = {key: componentProps.key};
output.attrs = { key: componentProps.key };
}
return output;
@@ -220,6 +217,5 @@ export default class Component {
* @param {Object} props
* @public
*/
static initProps(props) {
}
static initProps(props) {}
}

View File

@@ -88,7 +88,7 @@ export default class Model {
// relationship data object.
for (const innerKey in data[key]) {
if (data[key][innerKey] instanceof Model) {
data[key][innerKey] = {data: Model.getIdentifier(data[key][innerKey])};
data[key][innerKey] = { data: Model.getIdentifier(data[key][innerKey]) };
}
this.data[key][innerKey] = data[key][innerKey];
}
@@ -109,7 +109,7 @@ export default class Model {
* @public
*/
pushAttributes(attributes) {
this.pushData({attributes});
this.pushData({ attributes });
}
/**
@@ -125,7 +125,7 @@ export default class Model {
const data = {
type: this.data.type,
id: this.data.id,
attributes
attributes,
};
// If a 'relationships' key exists, extract it from the attributes hash and
@@ -138,9 +138,7 @@ export default class Model {
const model = attributes.relationships[key];
data.relationships[key] = {
data: model instanceof Array
? model.map(Model.getIdentifier)
: Model.getIdentifier(model)
data: model instanceof Array ? model.map(Model.getIdentifier) : Model.getIdentifier(model),
};
}
@@ -154,31 +152,38 @@ export default class Model {
this.pushData(data);
const request = {data};
const request = { data };
if (options.meta) request.meta = options.meta;
return app.request(Object.assign({
method: this.exists ? 'PATCH' : 'POST',
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
data: request
}, options)).then(
// If everything went well, we'll make sure the store knows that this
// model exists now (if it didn't already), and we'll push the data that
// the API returned into the store.
payload => {
this.store.data[payload.data.type] = this.store.data[payload.data.type] || {};
this.store.data[payload.data.type][payload.data.id] = this;
return this.store.pushPayload(payload);
},
return app
.request(
Object.assign(
{
method: this.exists ? 'PATCH' : 'POST',
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
data: request,
},
options
)
)
.then(
// If everything went well, we'll make sure the store knows that this
// model exists now (if it didn't already), and we'll push the data that
// the API returned into the store.
(payload) => {
this.store.data[payload.data.type] = this.store.data[payload.data.type] || {};
this.store.data[payload.data.type][payload.data.id] = this;
return this.store.pushPayload(payload);
},
// If something went wrong, though... good thing we backed up our model's
// old data! We'll revert to that and let others handle the error.
response => {
this.pushData(oldData);
m.lazyRedraw();
throw response;
}
);
// If something went wrong, though... good thing we backed up our model's
// old data! We'll revert to that and let others handle the error.
(response) => {
this.pushData(oldData);
m.lazyRedraw();
throw response;
}
);
}
/**
@@ -192,14 +197,21 @@ export default class Model {
delete(data, options = {}) {
if (!this.exists) return m.deferred().resolve().promise;
return app.request(Object.assign({
method: 'DELETE',
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
data
}, options)).then(() => {
this.exists = false;
this.store.remove(this);
});
return app
.request(
Object.assign(
{
method: 'DELETE',
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
data,
},
options
)
)
.then(() => {
this.exists = false;
this.store.remove(this);
});
}
/**
@@ -225,7 +237,7 @@ export default class Model {
* @public
*/
static attribute(name, transform) {
return function() {
return function () {
const value = this.data.attributes && this.data.attributes[name];
return transform ? transform(value) : value;
@@ -243,7 +255,7 @@ export default class Model {
* @public
*/
static hasOne(name) {
return function() {
return function () {
if (this.data.relationships) {
const relationship = this.data.relationships[name];
@@ -267,12 +279,12 @@ export default class Model {
* @public
*/
static hasMany(name) {
return function() {
return function () {
if (this.data.relationships) {
const relationship = this.data.relationships[name];
if (relationship) {
return relationship.data.map(data => app.store.getById(data.type, data.id));
return relationship.data.map((data) => app.store.getById(data.type, data.id));
}
}
@@ -301,7 +313,7 @@ export default class Model {
static getIdentifier(model) {
return {
type: model.data.type,
id: model.data.id
id: model.data.id,
};
}
}

View File

@@ -31,11 +31,16 @@ export default class Session {
* @public
*/
login(data, options = {}) {
return app.request(Object.assign({
method: 'POST',
url: app.forum.attribute('baseUrl') + '/login',
data
}, options));
return app.request(
Object.assign(
{
method: 'POST',
url: app.forum.attribute('baseUrl') + '/login',
data,
},
options
)
);
}
/**

View File

@@ -34,9 +34,7 @@ export default class Store {
pushPayload(payload) {
if (payload.included) payload.included.map(this.pushObject.bind(this));
const result = payload.data instanceof Array
? payload.data.map(this.pushObject.bind(this))
: this.pushObject(payload.data);
const result = payload.data instanceof Array ? payload.data.map(this.pushObject.bind(this)) : this.pushObject(payload.data);
// Attach the original payload to the model that we give back. This is
// useful to consumers as it allows them to access meta information
@@ -58,7 +56,7 @@ export default class Store {
pushObject(data) {
if (!this.models[data.type]) return null;
const type = this.data[data.type] = this.data[data.type] || {};
const type = (this.data[data.type] = this.data[data.type] || {});
if (type[data.id]) {
type[data.id].pushData(data);
@@ -95,11 +93,18 @@ export default class Store {
url += '/' + id;
}
return app.request(Object.assign({
method: 'GET',
url,
data
}, options)).then(this.pushPayload.bind(this));
return app
.request(
Object.assign(
{
method: 'GET',
url,
data,
},
options
)
)
.then(this.pushPayload.bind(this));
}
/**
@@ -124,7 +129,7 @@ export default class Store {
* @public
*/
getBy(type, key, value) {
return this.all(type).filter(model => model[key]() === value)[0];
return this.all(type).filter((model) => model[key]() === value)[0];
}
/**
@@ -137,7 +142,7 @@ export default class Store {
all(type) {
const records = this.data[type];
return records ? Object.keys(records).map(id => records[id]) : [];
return records ? Object.keys(records).map((id) => records[id]) : [];
}
/**
@@ -160,6 +165,6 @@ export default class Store {
createRecord(type, data = {}) {
data.type = data.type || type;
return new (this.models[type])(data, this);
return new this.models[type](data, this);
}
}

View File

@@ -67,7 +67,7 @@ export default class Translator {
const hydrated = [];
const open = [hydrated];
translation.forEach(part => {
translation.forEach((part) => {
const match = part.match(new RegExp('{([a-z0-9_]+)}|<(/?)([a-z0-9_]+)>', 'i'));
if (match) {
@@ -77,7 +77,7 @@ export default class Translator {
if (match[2]) {
open.shift();
} else {
let tag = input[match[3]] || {tag: match[3], children: []};
let tag = input[match[3]] || { tag: match[3], children: [] };
open[0].push(tag);
open.unshift(tag.children || tag);
}
@@ -87,7 +87,7 @@ export default class Translator {
}
});
return hydrated.filter(part => part);
return hydrated.filter((part) => part);
}
pluralize(translation, number) {
@@ -97,7 +97,7 @@ export default class Translator {
standardRules = [],
explicitRules = [];
translation.split('|').forEach(part => {
translation.split('|').forEach((part) => {
if (cPluralRegex.test(part)) {
const matches = part.match(cPluralRegex);
explicitRules[matches[0]] = matches[matches.length - 1];
@@ -122,11 +122,13 @@ export default class Translator {
}
}
} else {
var leftNumber = this.convertNumber(matches[4]);
var leftNumber = this.convertNumber(matches[4]);
var rightNumber = this.convertNumber(matches[5]);
if (('[' === matches[3] ? number >= leftNumber : number > leftNumber) &&
(']' === matches[6] ? number <= rightNumber : number < rightNumber)) {
if (
('[' === matches[3] ? number >= leftNumber : number > leftNumber) &&
(']' === matches[6] ? number <= rightNumber : number < rightNumber)
) {
return explicitRules[e];
}
}
@@ -223,7 +225,7 @@ export default class Translator {
case 'tr':
case 'ur':
case 'zu':
return (number == 1) ? 0 : 1;
return number == 1 ? 0 : 1;
case 'am':
case 'bh':
@@ -237,7 +239,7 @@ export default class Translator {
case 'xbr':
case 'ti':
case 'wa':
return ((number === 0) || (number == 1)) ? 0 : 1;
return number === 0 || number == 1 ? 0 : 1;
case 'be':
case 'bs':
@@ -245,41 +247,41 @@ export default class Translator {
case 'ru':
case 'sr':
case 'uk':
return ((number % 10 == 1) && (number % 100 != 11)) ? 0 : (((number % 10 >= 2) && (number % 10 <= 4) && ((number % 100 < 10) || (number % 100 >= 20))) ? 1 : 2);
return number % 10 == 1 && number % 100 != 11 ? 0 : number % 10 >= 2 && number % 10 <= 4 && (number % 100 < 10 || number % 100 >= 20) ? 1 : 2;
case 'cs':
case 'sk':
return (number == 1) ? 0 : (((number >= 2) && (number <= 4)) ? 1 : 2);
return number == 1 ? 0 : number >= 2 && number <= 4 ? 1 : 2;
case 'ga':
return (number == 1) ? 0 : ((number == 2) ? 1 : 2);
return number == 1 ? 0 : number == 2 ? 1 : 2;
case 'lt':
return ((number % 10 == 1) && (number % 100 != 11)) ? 0 : (((number % 10 >= 2) && ((number % 100 < 10) || (number % 100 >= 20))) ? 1 : 2);
return number % 10 == 1 && number % 100 != 11 ? 0 : number % 10 >= 2 && (number % 100 < 10 || number % 100 >= 20) ? 1 : 2;
case 'sl':
return (number % 100 == 1) ? 0 : ((number % 100 == 2) ? 1 : (((number % 100 == 3) || (number % 100 == 4)) ? 2 : 3));
return number % 100 == 1 ? 0 : number % 100 == 2 ? 1 : number % 100 == 3 || number % 100 == 4 ? 2 : 3;
case 'mk':
return (number % 10 == 1) ? 0 : 1;
return number % 10 == 1 ? 0 : 1;
case 'mt':
return (number == 1) ? 0 : (((number === 0) || ((number % 100 > 1) && (number % 100 < 11))) ? 1 : (((number % 100 > 10) && (number % 100 < 20)) ? 2 : 3));
return number == 1 ? 0 : number === 0 || (number % 100 > 1 && number % 100 < 11) ? 1 : number % 100 > 10 && number % 100 < 20 ? 2 : 3;
case 'lv':
return (number === 0) ? 0 : (((number % 10 == 1) && (number % 100 != 11)) ? 1 : 2);
return number === 0 ? 0 : number % 10 == 1 && number % 100 != 11 ? 1 : 2;
case 'pl':
return (number == 1) ? 0 : (((number % 10 >= 2) && (number % 10 <= 4) && ((number % 100 < 12) || (number % 100 > 14))) ? 1 : 2);
return number == 1 ? 0 : number % 10 >= 2 && number % 10 <= 4 && (number % 100 < 12 || number % 100 > 14) ? 1 : 2;
case 'cy':
return (number == 1) ? 0 : ((number == 2) ? 1 : (((number == 8) || (number == 11)) ? 2 : 3));
return number == 1 ? 0 : number == 2 ? 1 : number == 8 || number == 11 ? 2 : 3;
case 'ro':
return (number == 1) ? 0 : (((number === 0) || ((number % 100 > 0) && (number % 100 < 20))) ? 1 : 2);
return number == 1 ? 0 : number === 0 || (number % 100 > 0 && number % 100 < 20) ? 1 : 2;
case 'ar':
return (number === 0) ? 0 : ((number == 1) ? 1 : ((number == 2) ? 2 : (((number >= 3) && (number <= 10)) ? 3 : (((number >= 11) && (number <= 99)) ? 4 : 5))));
return number === 0 ? 0 : number == 1 ? 1 : number == 2 ? 2 : number >= 3 && number <= 10 ? 3 : number >= 11 && number <= 99 ? 4 : 5;
default:
return 0;

View File

@@ -62,9 +62,9 @@ import userOnline from './helpers/userOnline';
import listItems from './helpers/listItems';
export default {
'extend': extend,
'Session': Session,
'Store': Store,
extend: extend,
Session: Session,
Store: Store,
'utils/evented': evented,
'utils/liveHumanTimes': liveHumanTimes,
'utils/ItemList': ItemList,
@@ -91,8 +91,8 @@ export default {
'models/Discussion': Discussion,
'models/Group': Group,
'models/Forum': Forum,
'Component': Component,
'Translator': Translator,
Component: Component,
Translator: Translator,
'components/AlertManager': AlertManager,
'components/Switch': Switch,
'components/Badge': Badge,
@@ -113,8 +113,8 @@ export default {
'components/Button': Button,
'components/Modal': Modal,
'components/GroupBadge': GroupBadge,
'Model': Model,
'Application': Application,
Model: Model,
Application: Application,
'helpers/fullTime': fullTime,
'helpers/avatar': avatar,
'helpers/icon': icon,
@@ -123,5 +123,5 @@ export default {
'helpers/highlight': highlight,
'helpers/username': username,
'helpers/userOnline': userOnline,
'helpers/listItems': listItems
'helpers/listItems': listItems,
};

View File

@@ -35,22 +35,13 @@ export default class Alert extends Component {
const dismissControl = [];
if (dismissible || dismissible === undefined) {
dismissControl.push(
<Button
icon="fas fa-times"
className="Button Button--link Button--icon Alert-dismiss"
onclick={ondismiss}/>
);
dismissControl.push(<Button icon="fas fa-times" className="Button Button--link Button--icon Alert-dismiss" onclick={ondismiss} />);
}
return (
<div {...attrs}>
<span className="Alert-body">
{children}
</span>
<ul className="Alert-controls">
{listItems(controls.concat(dismissControl))}
</ul>
<span className="Alert-body">{children}</span>
<ul className="Alert-controls">{listItems(controls.concat(dismissControl))}</ul>
</div>
);
}

View File

@@ -19,7 +19,9 @@ export default class AlertManager extends Component {
view() {
return (
<div className="AlertManager">
{this.components.map(component => <div className="AlertManager-alert">{component}</div>)}
{this.components.map((component) => (
<div className="AlertManager-alert">{component}</div>
))}
</div>
);
}

View File

@@ -24,16 +24,12 @@ export default class Badge extends Component {
attrs.className = 'Badge ' + (type ? 'Badge--' + type : '') + ' ' + (attrs.className || '');
attrs.title = extract(attrs, 'label') || '';
return (
<span {...attrs}>
{iconName ? icon(iconName, {className: 'Badge-icon'}) : m.trust('&nbsp;')}
</span>
);
return <span {...attrs}>{iconName ? icon(iconName, { className: 'Badge-icon' }) : m.trust('&nbsp;')}</span>;
}
config(isInitialized) {
if (isInitialized) return;
if (this.props.label) this.$().tooltip({container: 'body'});
if (this.props.label) this.$().tooltip({ container: 'body' });
}
}

View File

@@ -62,9 +62,9 @@ export default class Button extends Component {
const iconName = this.props.icon;
return [
iconName && iconName !== true ? icon(iconName, {className: 'Button-icon'}) : '',
iconName && iconName !== true ? icon(iconName, { className: 'Button-icon' }) : '',
this.props.children ? <span className="Button-label">{this.props.children}</span> : '',
this.props.loading ? LoadingIndicator.component({size: 'tiny', className: 'LoadingIndicator--inline'}) : ''
this.props.loading ? LoadingIndicator.component({ size: 'tiny', className: 'LoadingIndicator--inline' }) : '',
];
}
}

View File

@@ -31,13 +31,8 @@ export default class Checkbox extends Component {
return (
<label className={className}>
<input type="checkbox"
checked={this.props.state}
disabled={this.props.disabled}
onchange={m.withAttr('checked', this.onchange.bind(this))}/>
<div className="Checkbox-display">
{this.getDisplay()}
</div>
<input type="checkbox" checked={this.props.state} disabled={this.props.disabled} onchange={m.withAttr('checked', this.onchange.bind(this))} />
<div className="Checkbox-display">{this.getDisplay()}</div>
{this.props.children}
</label>
);
@@ -50,9 +45,7 @@ export default class Checkbox extends Component {
* @protected
*/
getDisplay() {
return this.loading
? LoadingIndicator.component({size: 'tiny'})
: icon(this.props.state ? 'fas fa-check' : 'fas fa-times');
return this.loading ? LoadingIndicator.component({ size: 'tiny' }) : icon(this.props.state ? 'fas fa-check' : 'fas fa-times');
}
/**

View File

@@ -64,19 +64,13 @@ export default class Dropdown extends Component {
$menu.removeClass('Dropdown-menu--top Dropdown-menu--right');
$menu.toggleClass(
'Dropdown-menu--top',
$menu.offset().top + $menu.height() > $(window).scrollTop() + $(window).height()
);
$menu.toggleClass('Dropdown-menu--top', $menu.offset().top + $menu.height() > $(window).scrollTop() + $(window).height());
if ($menu.offset().top < 0) {
$menu.removeClass('Dropdown-menu--top');
}
$menu.toggleClass(
'Dropdown-menu--right',
isRight || $menu.offset().left + $menu.width() > $(window).scrollLeft() + $(window).width()
);
$menu.toggleClass('Dropdown-menu--right', isRight || $menu.offset().left + $menu.width() > $(window).scrollLeft() + $(window).width());
});
this.$().on('hidden.bs.dropdown', () => {
@@ -98,10 +92,7 @@ export default class Dropdown extends Component {
*/
getButton() {
return (
<button
className={'Dropdown-toggle ' + this.props.buttonClassName}
data-toggle="dropdown"
onclick={this.props.onclick}>
<button className={'Dropdown-toggle ' + this.props.buttonClassName} data-toggle="dropdown" onclick={this.props.onclick}>
{this.getButtonContent()}
</button>
);
@@ -115,17 +106,13 @@ export default class Dropdown extends Component {
*/
getButtonContent() {
return [
this.props.icon ? icon(this.props.icon, {className: 'Button-icon'}) : '',
this.props.icon ? icon(this.props.icon, { className: 'Button-icon' }) : '',
<span className="Button-label">{this.props.label}</span>,
this.props.caretIcon ? icon(this.props.caretIcon, {className: 'Button-caret'}) : ''
this.props.caretIcon ? icon(this.props.caretIcon, { className: 'Button-caret' }) : '',
];
}
getMenu(items) {
return (
<ul className={'Dropdown-menu dropdown-menu ' + this.props.menuClassName}>
{items}
</ul>
);
return <ul className={'Dropdown-menu dropdown-menu ' + this.props.menuClassName}>{items}</ul>;
}
}

View File

@@ -6,7 +6,7 @@ export default class GroupBadge extends Badge {
if (props.group) {
props.icon = props.group.icon();
props.style = {backgroundColor: props.group.color()};
props.style = { backgroundColor: props.group.color() };
props.label = typeof props.label === 'undefined' ? props.group.nameSingular() : props.label;
props.type = 'group--' + props.group.id();

View File

@@ -33,8 +33,6 @@ export default class LinkButton extends Button {
* @return {Boolean}
*/
static isActive(props) {
return typeof props.active !== 'undefined'
? props.active
: m.route() === props.href;
return typeof props.active !== 'undefined' ? props.active : m.route() === props.href;
}
}

View File

@@ -31,10 +31,12 @@ export default class Modal extends Component {
{Button.component({
icon: 'fas fa-times',
onclick: this.hide.bind(this),
className: 'Button Button--icon Button--link'
className: 'Button Button--icon Button--link',
})}
</div>
) : ''}
) : (
''
)}
<form onsubmit={this.onsubmit.bind(this)}>
<div className="Modal-header">
@@ -65,8 +67,7 @@ export default class Modal extends Component {
* @return {String}
* @abstract
*/
className() {
}
className() {}
/**
* Get the title of the modal dialog.
@@ -74,8 +75,7 @@ export default class Modal extends Component {
* @return {String}
* @abstract
*/
title() {
}
title() {}
/**
* Get the content of the modal.
@@ -83,16 +83,14 @@ export default class Modal extends Component {
* @return {VirtualElement}
* @abstract
*/
content() {
}
content() {}
/**
* Handle the modal form's submit event.
*
* @param {Event} e
*/
onsubmit() {
}
onsubmit() {}
/**
* Focus on the first input when the modal is ready to be used.
@@ -101,8 +99,7 @@ export default class Modal extends Component {
this.$('form').find('input, select, textarea').first().focus().select();
}
onhide() {
}
onhide() {}
/**
* Hide the modal.

View File

@@ -13,11 +13,7 @@ export default class ModalManager extends Component {
}
view() {
return (
<div className="ModalManager modal fade">
{this.component && this.component.render()}
</div>
);
return <div className="ModalManager modal fade">{this.component && this.component.render()}</div>;
}
config(isInitialized, context) {
@@ -28,9 +24,7 @@ export default class ModalManager extends Component {
// to be retained across route changes.
context.retain = true;
this.$()
.on('hidden.bs.modal', this.clear.bind(this))
.on('shown.bs.modal', this.onready.bind(this));
this.$().on('hidden.bs.modal', this.clear.bind(this)).on('shown.bs.modal', this.onready.bind(this));
}
/**
@@ -54,10 +48,12 @@ export default class ModalManager extends Component {
m.redraw(true);
const dismissible = !!this.component.isDismissible();
this.$().modal({
backdrop: dismissible || 'static',
keyboard: dismissible
}).modal('show');
this.$()
.modal({
backdrop: dismissible || 'static',
keyboard: dismissible,
})
.modal('show');
}
/**

View File

@@ -19,15 +19,15 @@ import LinkButton from './LinkButton';
*/
export default class Navigation extends Component {
view() {
const {history, pane} = app;
const { history, pane } = app;
return (
<div className={'Navigation ButtonGroup ' + (this.props.className || '')}
<div
className={'Navigation ButtonGroup ' + (this.props.className || '')}
onmouseenter={pane && pane.show.bind(pane)}
onmouseleave={pane && pane.onmouseleave.bind(pane)}>
{history.canGoBack()
? [this.getBackButton(), this.getPaneButton()]
: this.getDrawerButton()}
onmouseleave={pane && pane.onmouseleave.bind(pane)}
>
{history.canGoBack() ? [this.getBackButton(), this.getPaneButton()] : this.getDrawerButton()}
</div>
);
}
@@ -46,7 +46,7 @@ export default class Navigation extends Component {
* @protected
*/
getBackButton() {
const {history} = app;
const { history } = app;
const previous = history.getPrevious() || {};
return LinkButton.component({
@@ -55,11 +55,11 @@ export default class Navigation extends Component {
icon: 'fas fa-chevron-left',
title: previous.title,
config: () => {},
onclick: e => {
onclick: (e) => {
if (e.shiftKey || e.ctrlKey || e.metaKey || e.which === 2) return;
e.preventDefault();
history.back();
}
},
});
}
@@ -70,14 +70,14 @@ export default class Navigation extends Component {
* @protected
*/
getPaneButton() {
const {pane} = app;
const { pane } = app;
if (!pane || !pane.active) return '';
return Button.component({
className: 'Button Button--icon Navigation-pin' + (pane.pinned ? ' active' : ''),
onclick: pane.togglePinned.bind(pane),
icon: 'fas fa-thumbtack'
icon: 'fas fa-thumbtack',
});
}
@@ -90,17 +90,16 @@ export default class Navigation extends Component {
getDrawerButton() {
if (!this.props.drawer) return '';
const {drawer} = app;
const { drawer } = app;
const user = app.session.user;
return Button.component({
className: 'Button Button--icon Navigation-drawer' +
(user && user.newNotificationCount() ? ' new' : ''),
onclick: e => {
className: 'Button Button--icon Navigation-drawer' + (user && user.newNotificationCount() ? ' new' : ''),
onclick: (e) => {
e.stopPropagation();
drawer.show();
},
icon: 'fas fa-bars'
icon: 'fas fa-bars',
});
}
}

View File

@@ -6,9 +6,7 @@ export default class RequestErrorModal extends Modal {
}
title() {
return this.props.error.xhr
? this.props.error.xhr.status+' '+this.props.error.xhr.statusText
: '';
return this.props.error.xhr ? this.props.error.xhr.status + ' ' + this.props.error.xhr.statusText : '';
}
content() {
@@ -20,11 +18,15 @@ export default class RequestErrorModal extends Modal {
responseText = this.props.error.responseText;
}
return <div className="Modal-body">
<pre>
{this.props.error.options.method} {this.props.error.options.url}<br/><br/>
{responseText}
</pre>
</div>;
return (
<div className="Modal-body">
<pre>
{this.props.error.options.method} {this.props.error.options.url}
<br />
<br />
{responseText}
</pre>
</div>
);
}
}

View File

@@ -12,14 +12,21 @@ import icon from '../helpers/icon';
*/
export default class Select extends Component {
view() {
const {options, onchange, value, disabled} = this.props;
const { options, onchange, value, disabled } = this.props;
return (
<span className="Select">
<select className="Select-input FormControl" onchange={onchange ? m.withAttr('value', onchange.bind(this)) : undefined} value={value} disabled={disabled}>
{Object.keys(options).map(key => <option value={key}>{options[key]}</option>)}
<select
className="Select-input FormControl"
onchange={onchange ? m.withAttr('value', onchange.bind(this)) : undefined}
value={value}
disabled={disabled}
>
{Object.keys(options).map((key) => (
<option value={key}>{options[key]}</option>
))}
</select>
{icon('fas fa-sort', {className: 'Select-caret'})}
{icon('fas fa-sort', { className: 'Select-caret' })}
</span>
);
}

View File

@@ -21,14 +21,11 @@ export default class SelectDropdown extends Dropdown {
}
getButtonContent() {
const activeChild = this.props.children.filter(child => child.props.active)[0];
let label = activeChild && activeChild.props.children || this.props.defaultLabel;
const activeChild = this.props.children.filter((child) => child.props.active)[0];
let label = (activeChild && activeChild.props.children) || this.props.defaultLabel;
if (label instanceof Array) label = label[0];
return [
<span className="Button-label">{label}</span>,
icon(this.props.caretIcon, {className: 'Button-caret'})
];
return [<span className="Button-label">{label}</span>, icon(this.props.caretIcon, { className: 'Button-caret' })];
}
}

View File

@@ -5,7 +5,7 @@ import Component from '../Component';
*/
class Separator extends Component {
view() {
return <li className="Dropdown-separator"/>;
return <li className="Dropdown-separator" />;
}
}

View File

@@ -24,12 +24,10 @@ export default class SplitDropdown extends Dropdown {
return [
Button.component(buttonProps),
<button
className={'Dropdown-toggle Button Button--icon ' + this.props.buttonClassName}
data-toggle="dropdown">
{icon(this.props.icon, {className: 'Button-icon'})}
{icon('fas fa-caret-down', {className: 'Button-caret'})}
</button>
<button className={'Dropdown-toggle Button Button--icon ' + this.props.buttonClassName} data-toggle="dropdown">
{icon(this.props.icon, { className: 'Button-icon' })}
{icon('fas fa-caret-down', { className: 'Button-caret' })}
</button>,
];
}

View File

@@ -21,7 +21,7 @@
export function extend(object, method, callback) {
const original = object[method];
object[method] = function(...args) {
object[method] = function (...args) {
const value = original ? original.apply(this, args) : undefined;
callback.apply(this, [value].concat(args));
@@ -57,7 +57,7 @@ export function extend(object, method, callback) {
export function override(object, method, newMethod) {
const original = object[method];
object[method] = function(...args) {
object[method] = function (...args) {
return newMethod.apply(this, [original.bind(this)].concat(args));
};

View File

@@ -31,11 +31,11 @@ export default class Routes {
if (this.model) {
app.store.models[this.type] = this.model;
}
const model = app.store.models[this.type];
this.attributes.forEach(name => model.prototype[name] = model.attribute(name));
this.hasOnes.forEach(name => model.prototype[name] = model.hasOne(name));
this.hasManys.forEach(name => model.prototype[name] = model.hasMany(name));
this.attributes.forEach((name) => (model.prototype[name] = model.attribute(name)));
this.hasOnes.forEach((name) => (model.prototype[name] = model.hasOne(name)));
this.hasManys.forEach((name) => (model.prototype[name] = model.hasMany(name)));
}
}
}

View File

@@ -10,4 +10,4 @@ export default class PostTypes {
extend(app, extension) {
Object.assign(app.postComponents, this.postComponents);
}
}
}

View File

@@ -10,4 +10,4 @@ export default class Routes {
extend(app, extension) {
Object.assign(app.routes, this.routes);
}
}
}

View File

@@ -25,11 +25,11 @@ export default function avatar(user, attrs = {}) {
if (hasTitle) attrs.title = attrs.title || username;
if (avatarUrl) {
return <img {...attrs} src={avatarUrl}/>;
return <img {...attrs} src={avatarUrl} />;
}
content = username.charAt(0).toUpperCase();
attrs.style = {background: user.color()};
attrs.style = { background: user.color() };
}
return <span {...attrs}>{content}</span>;

View File

@@ -11,5 +11,9 @@ export default function fullTime(time) {
const datetime = mo.format();
const full = mo.format('LLLL');
return <time pubdate datetime={datetime}>{full}</time>;
return (
<time pubdate datetime={datetime}>
{full}
</time>
);
}

View File

@@ -15,5 +15,9 @@ export default function humanTime(time) {
const full = mo.format('LLLL');
const ago = humanTimeUtil(time);
return <time pubdate datetime={datetime} title={full} data-humantime>{ago}</time>;
return (
<time pubdate datetime={datetime} title={full} data-humantime>
{ago}
</time>
);
}

View File

@@ -8,5 +8,5 @@
export default function icon(fontClass, attrs = {}) {
attrs.className = 'icon ' + fontClass + ' ' + (attrs.className || '');
return <i {...attrs}/>;
return <i {...attrs} />;
}

View File

@@ -29,7 +29,7 @@ function withoutUnnecessarySeparators(items) {
export default function listItems(items) {
if (!(items instanceof Array)) items = [items];
return withoutUnnecessarySeparators(items).map(item => {
return withoutUnnecessarySeparators(items).map((item) => {
const isListItem = item.component && item.component.isListItem;
const active = item.component && item.component.isActive && item.component.isActive(item.props);
const className = item.props ? item.props.itemClassName : item.itemClassName;
@@ -39,15 +39,12 @@ export default function listItems(items) {
item.attrs.key = item.attrs.key || item.itemName;
}
return isListItem
? item
: <li className={classList([
(item.itemName ? 'item-' + item.itemName : ''),
className,
(active ? 'active' : '')
])}
key={item.itemName}>
{item}
</li>;
return isListItem ? (
item
) : (
<li className={classList([item.itemName ? 'item-' + item.itemName : '', className, active ? 'active' : ''])} key={item.itemName}>
{item}
</li>
);
});
}

View File

@@ -13,7 +13,7 @@ export default function punctuateSeries(items) {
if (items.length === 2) {
return app.translator.trans('core.lib.series.two_text', {
first: items[0],
second: items[1]
second: items[1],
});
} else if (items.length >= 3) {
// If there are three or more items, we will join all but the first and
@@ -27,7 +27,7 @@ export default function punctuateSeries(items) {
return app.translator.trans('core.lib.series.three_text', {
first: items[0],
second,
third: items[items.length - 1]
third: items[items.length - 1],
});
}

View File

@@ -7,7 +7,7 @@ import icon from './icon';
* @return {Object}
*/
export default function userOnline(user) {
if (user.lastSeenAt() && user.isOnline()) {
return <span className="UserOnline">{icon('fas fa-circle')}</span>;
}
if (user.lastSeenAt() && user.isOnline()) {
return <span className="UserOnline">{icon('fas fa-circle')}</span>;
}
}

View File

@@ -19,18 +19,18 @@ Object.assign(Discussion.prototype, {
lastPostNumber: Model.attribute('lastPostNumber'),
commentCount: Model.attribute('commentCount'),
replyCount: computed('commentCount', commentCount => Math.max(0, commentCount - 1)),
replyCount: computed('commentCount', (commentCount) => Math.max(0, commentCount - 1)),
posts: Model.hasMany('posts'),
mostRelevantPost: Model.hasOne('mostRelevantPost'),
lastReadAt: Model.attribute('lastReadAt', Model.transformDate),
lastReadPostNumber: Model.attribute('lastReadPostNumber'),
isUnread: computed('unreadCount', unreadCount => !!unreadCount),
isRead: computed('unreadCount', unreadCount => app.session.user && !unreadCount),
isUnread: computed('unreadCount', (unreadCount) => !!unreadCount),
isRead: computed('unreadCount', (unreadCount) => app.session.user && !unreadCount),
hiddenAt: Model.attribute('hiddenAt', Model.transformDate),
hiddenUser: Model.hasOne('hiddenUser'),
isHidden: computed('hiddenAt', hiddenAt => !!hiddenAt),
isHidden: computed('hiddenAt', (hiddenAt) => !!hiddenAt),
canReply: Model.attribute('canReply'),
canRename: Model.attribute('canRename'),
@@ -84,7 +84,7 @@ Object.assign(Discussion.prototype, {
const items = new ItemList();
if (this.isHidden()) {
items.add('hidden', <Badge type="hidden" icon="fas fa-trash" label={app.translator.trans('core.lib.badge.hidden_tooltip')}/>);
items.add('hidden', <Badge type="hidden" icon="fas fa-trash" label={app.translator.trans('core.lib.badge.hidden_tooltip')} />);
}
return items;
@@ -99,6 +99,6 @@ Object.assign(Discussion.prototype, {
postIds() {
const posts = this.data.relationships.posts;
return posts ? posts.data.map(link => link.id) : [];
}
return posts ? posts.data.map((link) => link.id) : [];
},
});

View File

@@ -6,7 +6,7 @@ Object.assign(Group.prototype, {
nameSingular: Model.attribute('nameSingular'),
namePlural: Model.attribute('namePlural'),
color: Model.attribute('color'),
icon: Model.attribute('icon')
icon: Model.attribute('icon'),
});
Group.ADMINISTRATOR_ID = '1';

View File

@@ -11,5 +11,5 @@ Object.assign(Notification.prototype, {
user: Model.hasOne('user'),
fromUser: Model.hasOne('fromUser'),
subject: Model.hasOne('subject')
subject: Model.hasOne('subject'),
});

View File

@@ -17,13 +17,13 @@ Object.assign(Post.prototype, {
editedAt: Model.attribute('editedAt', Model.transformDate),
editedUser: Model.hasOne('editedUser'),
isEdited: computed('editedAt', editedAt => !!editedAt),
isEdited: computed('editedAt', (editedAt) => !!editedAt),
hiddenAt: Model.attribute('hiddenAt', Model.transformDate),
hiddenUser: Model.hasOne('hiddenUser'),
isHidden: computed('hiddenAt', hiddenAt => !!hiddenAt),
isHidden: computed('hiddenAt', (hiddenAt) => !!hiddenAt),
canEdit: Model.attribute('canEdit'),
canHide: Model.attribute('canHide'),
canDelete: Model.attribute('canDelete')
canDelete: Model.attribute('canDelete'),
});

View File

@@ -32,7 +32,7 @@ Object.assign(User.prototype, {
canDelete: Model.attribute('canDelete'),
avatarColor: null,
color: computed('username', 'avatarUrl', 'avatarColor', function(username, avatarUrl, avatarColor) {
color: computed('username', 'avatarUrl', 'avatarColor', function (username, avatarUrl, avatarColor) {
// If we've already calculated and cached the dominant color of the user's
// avatar, then we can return that in RGB format. If we haven't, we'll want
// to calculate it. Unless the user doesn't have an avatar, in which case
@@ -67,8 +67,8 @@ Object.assign(User.prototype, {
const groups = this.groups();
if (groups) {
groups.forEach(group => {
items.add('group' + group.id(), GroupBadge.component({group}));
groups.forEach((group) => {
items.add('group' + group.id(), GroupBadge.component({ group }));
});
}
@@ -85,7 +85,7 @@ Object.assign(User.prototype, {
const image = new Image();
const user = this;
image.onload = function() {
image.onload = function () {
const colorThief = new ColorThief();
user.avatarColor = colorThief.getColor(this);
user.freshness = new Date();
@@ -106,6 +106,6 @@ Object.assign(User.prototype, {
Object.assign(preferences, newPreferences);
return this.save({preferences});
}
return this.save({ preferences });
},
});

View File

@@ -7,7 +7,7 @@ export default class Drawer {
constructor() {
// Set up an event handler so that whenever the content area is tapped,
// the drawer will close.
$('#content').click(e => {
$('#content').click((e) => {
if (this.isOpen()) {
e.preventDefault();
this.hide();

View File

@@ -28,7 +28,7 @@ export default class ItemList {
*/
isEmpty() {
for (const i in this.items) {
if(this.items.hasOwnProperty(i)) {
if (this.items.hasOwnProperty(i)) {
return false;
}
}
@@ -147,14 +147,15 @@ export default class ItemList {
}
}
return items.sort((a, b) => {
if (a.priority === b.priority) {
return a.key - b.key;
} else if (a.priority > b.priority) {
return -1;
}
return 1;
}).map(item => item.content);
return items
.sort((a, b) => {
if (a.priority === b.priority) {
return a.key - b.key;
} else if (a.priority > b.priority) {
return -1;
}
return 1;
})
.map((item) => item.content);
}
}

View File

@@ -1,9 +1,10 @@
const later = window.requestAnimationFrame ||
const later =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
(callback => window.setTimeout(callback, 1000 / 60));
((callback) => window.setTimeout(callback, 1000 / 60));
/**
* The `ScrollListener` class sets up a listener that handles window scroll
@@ -57,10 +58,7 @@ export default class ScrollListener {
*/
start() {
if (!this.active) {
window.addEventListener(
'scroll',
this.active = this.loop.bind(this)
);
window.addEventListener('scroll', (this.active = this.loop.bind(this)));
}
}

View File

@@ -44,7 +44,7 @@ export default class SubtreeRetainer {
}
});
return needsRebuild ? false : {subtree: 'retain'};
return needsRebuild ? false : { subtree: 'retain' };
}
/**

View File

@@ -13,7 +13,7 @@ export default function classList(classes) {
let classNames;
if (classes instanceof Array) {
classNames = classes.filter(name => name);
classNames = classes.filter((name) => name);
} else {
classNames = [];

View File

@@ -14,12 +14,12 @@ export default function computed(...dependentKeys) {
const dependentValues = {};
let computedValue;
return function() {
return function () {
let recompute = false;
// Read all of the dependent values. If any of them have changed since last
// time, then we'll want to recompute our output.
keys.forEach(key => {
keys.forEach((key) => {
const value = typeof this[key] === 'function' ? this[key]() : this[key];
if (dependentValues[key] !== value) {
@@ -29,7 +29,10 @@ export default function computed(...dependentKeys) {
});
if (recompute) {
computedValue = compute.apply(this, keys.map(key => dependentValues[key]));
computedValue = compute.apply(
this,
keys.map((key) => dependentValues[key])
);
}
return computedValue;

View File

@@ -34,7 +34,7 @@ export default {
* @public
*/
trigger(event, ...args) {
this.getHandlers(event).forEach(handler => handler.apply(this, args));
this.getHandlers(event).forEach((handler) => handler.apply(this, args));
},
/**
@@ -55,7 +55,7 @@ export default {
* @param {function} handler The function to handle the event.
*/
one(event, handler) {
const wrapper = function() {
const wrapper = function () {
handler.apply(this, arguments);
this.off(event, wrapper);
@@ -77,5 +77,5 @@ export default {
if (index !== -1) {
handlers.splice(index, 1);
}
}
}
},
};

View File

@@ -6,7 +6,7 @@
*/
export default function extractText(vdom) {
if (vdom instanceof Array) {
return vdom.map(element => extractText(element)).join('');
return vdom.map((element) => extractText(element)).join('');
} else if (typeof vdom === 'object' && vdom !== null) {
return extractText(vdom.children);
} else {

View File

@@ -33,4 +33,4 @@ export default function humanTime(time) {
}
return ago;
};
}

View File

@@ -1,7 +1,7 @@
import humanTimeUtil from './humanTime';
function updateHumanTimes() {
$('[data-humantime]').each(function() {
$('[data-humantime]').each(function () {
const $this = $(this);
const ago = humanTimeUtil($this.attr('datetime'));

View File

@@ -12,7 +12,7 @@
export default function mixin(Parent, ...mixins) {
class Mixed extends Parent {}
mixins.forEach(object => {
mixins.forEach((object) => {
Object.assign(Mixed.prototype, object);
});

View File

@@ -3,11 +3,11 @@ import Component from '../Component';
export default function patchMithril(global) {
const mo = global.m;
const m = function(comp, ...args) {
const m = function (comp, ...args) {
if (comp.prototype && comp.prototype instanceof Component) {
let children = args.slice(1);
if (children.length === 1 && Array.isArray(children[0])) {
children = children[0]
children = children[0];
}
return comp.component(args[0], children);
@@ -29,14 +29,14 @@ export default function patchMithril(global) {
return node;
};
Object.keys(mo).forEach(key => m[key] = mo[key]);
Object.keys(mo).forEach((key) => (m[key] = mo[key]));
/**
* Redraw only if not in the middle of a computation (e.g. a route change).
*
* @return {void}
*/
m.lazyRedraw = function() {
m.lazyRedraw = function () {
m.startComputation();
m.endComputation();
};

View File

@@ -7,9 +7,7 @@
* @return {String}
*/
export function truncate(string, length, start = 0) {
return (start > 0 ? '...' : '') +
string.substring(start, start + length) +
(string.length > start + length ? '...' : '');
return (start > 0 ? '...' : '') + string.substring(start, start + length) + (string.length > start + length ? '...' : '');
}
/**
@@ -24,7 +22,8 @@ export function truncate(string, length, start = 0) {
* @return {String}
*/
export function slug(string) {
return string.toLowerCase()
return string
.toLowerCase()
.replace(/[^a-z0-9]/gi, '-')
.replace(/-+/g, '-')
.replace(/-$|^-/g, '');
@@ -38,9 +37,7 @@ export function slug(string) {
* @return {String}
*/
export function getPlainContent(string) {
const html = string
.replace(/(<\/p>|<br>)/g, '$1 &nbsp;')
.replace(/<img\b[^>]*>/ig, ' ');
const html = string.replace(/(<\/p>|<br>)/g, '$1 &nbsp;').replace(/<img\b[^>]*>/gi, ' ');
const dom = $('<div/>').html(html);

View File

@@ -10,18 +10,42 @@ function hsvToRgb(h, s, v) {
const t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5: r = v; g = p; b = q; break;
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
}
return {
r: Math.floor(r * 255),
g: Math.floor(g * 255),
b: Math.floor(b * 255)
b: Math.floor(b * 255),
};
}