mirror of
https://github.com/flarum/core.git
synced 2025-08-23 08:33:45 +02:00
Massive JavaScript cleanup
- Use JSX for templates - Docblock/comment everything - Mostly passes ESLint (still some work to do) - Lots of renaming, refactoring, etc. CSS hasn't been updated yet.
This commit is contained in:
@@ -1,26 +1,36 @@
|
||||
export default function avatar(user, args) {
|
||||
args = args || {}
|
||||
args.className = 'avatar '+(args.className || '')
|
||||
var content = ''
|
||||
/**
|
||||
* The `avatar` helper displays a user's avatar.
|
||||
*
|
||||
* @param {User} user
|
||||
* @param {Object} attrs Attributes to apply to the avatar element
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function avatar(user, attrs = {}) {
|
||||
attrs.className = 'avatar ' + (attrs.className || '');
|
||||
let content = '';
|
||||
|
||||
var title = typeof args.title === 'undefined' || args.title
|
||||
if (!title) { delete args.title }
|
||||
// If the `title` attribute is set to null or false, we don't want to give the
|
||||
// avatar a title. On the other hand, if it hasn't been given at all, we can
|
||||
// safely default it to the user's username.
|
||||
const hasTitle = attrs.title === 'undefined' || attrs.title;
|
||||
if (!hasTitle) delete attrs.title;
|
||||
|
||||
// If a user has been passed, then we will set up an avatar using their
|
||||
// uploaded image, or the first letter of their username if they haven't
|
||||
// uploaded one.
|
||||
if (user) {
|
||||
var username = user.username() || '?'
|
||||
const username = user.username() || '?';
|
||||
const avatarUrl = user.avatarUrl();
|
||||
|
||||
if (title) { args.title = args.title || username }
|
||||
if (hasTitle) attrs.title = attrs.title || username;
|
||||
|
||||
var avatarUrl = user.avatarUrl()
|
||||
if (avatarUrl) {
|
||||
args.src = avatarUrl
|
||||
return m('img', args)
|
||||
return <img {...attrs} src={avatarUrl}/>;
|
||||
}
|
||||
|
||||
content = username.charAt(0).toUpperCase()
|
||||
args.style = {background: user.color()}
|
||||
content = username.charAt(0).toUpperCase();
|
||||
attrs.style = {background: user.color()};
|
||||
}
|
||||
|
||||
if (!args.title) { delete args.title }
|
||||
return m('span', args, content)
|
||||
return <span {...attrs}>{content}</span>;
|
||||
}
|
||||
|
@@ -1,7 +0,0 @@
|
||||
export default function fullTime(time) {
|
||||
var time = moment(time);
|
||||
var datetime = time.format();
|
||||
var full = time.format('LLLL');
|
||||
|
||||
return m('time', {pubdate: '', datetime}, full);
|
||||
}
|
15
js/lib/helpers/fullTime.js
Normal file
15
js/lib/helpers/fullTime.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* The `fullTime` helper displays a formatted time string wrapped in a <time>
|
||||
* tag.
|
||||
*
|
||||
* @param {Date} time
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function fullTime(time) {
|
||||
const mo = moment(time);
|
||||
|
||||
const datetime = mo.format();
|
||||
const full = mo.format('LLLL');
|
||||
|
||||
return <time pubdate datetime={datetime}>{full}</time>;
|
||||
}
|
@@ -1,21 +1,37 @@
|
||||
import truncate from '../utils/truncate';
|
||||
import { truncate } from 'flarum/utils/string';
|
||||
|
||||
export default function(string, phrase, length) {
|
||||
if (!phrase) {
|
||||
return string;
|
||||
}
|
||||
/**
|
||||
* The `highlight` helper searches for a word phrase in a string, and wraps
|
||||
* matches with the <mark> tag.
|
||||
*
|
||||
* @param {String} string The string to highlight.
|
||||
* @param {String|RegExp} phrase The word or words to highlight.
|
||||
* @param {Integer} [length] The number of characters to truncate the string to.
|
||||
* The string will be truncated surrounding the first match.
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function highlight(string, phrase, length) {
|
||||
if (!phrase && !length) return string;
|
||||
|
||||
// Convert the word phrase into a global regular expression (if it isn't
|
||||
// already) so we can search the string for matched.
|
||||
const regexp = phrase instanceof RegExp ? phrase : new RegExp(phrase, 'gi');
|
||||
|
||||
let highlightedString = string;
|
||||
let highlighted = string;
|
||||
let start = 0;
|
||||
|
||||
// If a length was given, the truncate the string surrounding the first match.
|
||||
if (length) {
|
||||
start = Math.max(0, string.search(regexp) - length / 2);
|
||||
highlightedString = truncate(highlightedString, length, start);
|
||||
if (phrase) start = Math.max(0, string.search(regexp) - length / 2);
|
||||
|
||||
highlighted = truncate(highlighted, length, start);
|
||||
}
|
||||
|
||||
highlightedString = $('<div/>').text(highlightedString).html().replace(regexp, '<mark>$&</mark>');
|
||||
// Convert the string into HTML entities, then highlight all matches with
|
||||
// <mark> tags. Then we will return the result as a trusted HTML string.
|
||||
highlighted = $('<div/>').text(highlighted).html();
|
||||
|
||||
return m.trust(highlightedString);
|
||||
if (phrase) highlighted = highlighted.replace(regexp, '<mark>$&</mark>');
|
||||
|
||||
return m.trust(highlighted);
|
||||
}
|
||||
|
@@ -1,11 +0,0 @@
|
||||
import humanTime from 'flarum/utils/human-time';
|
||||
|
||||
export default function humanTimeHelper(time) {
|
||||
var time = moment(time);
|
||||
var datetime = time.format();
|
||||
var full = time.format('LLLL');
|
||||
|
||||
var ago = humanTime(time);
|
||||
|
||||
return m('time', {pubdate: '', datetime, title: full, 'data-humantime': ''}, ago);
|
||||
}
|
19
js/lib/helpers/humanTime.js
Normal file
19
js/lib/helpers/humanTime.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import humanTimeUtil from 'flarum/utils/humanTime';
|
||||
|
||||
/**
|
||||
* The `humanTime` helper displays a time in a human-friendly time-ago format
|
||||
* (e.g. '12 days ago'), wrapped in a <time> tag with other information about
|
||||
* the time.
|
||||
*
|
||||
* @param {Date} time
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function humanTime(time) {
|
||||
const mo = moment(time);
|
||||
|
||||
const datetime = mo.format();
|
||||
const full = mo.format('LLLL');
|
||||
const ago = humanTimeUtil(time);
|
||||
|
||||
return <time pubdate datetime={datetime} title={full} data-humantime>{ago}</time>;
|
||||
}
|
@@ -1,3 +1,12 @@
|
||||
export default function icon(icon) {
|
||||
return m('i.fa.fa-fw.fa-'+icon)
|
||||
/**
|
||||
* The `icon` helper displays a FontAwesome icon. The fa-fw class is applied.
|
||||
*
|
||||
* @param {String} name The name of the icon class, without the `fa-` prefix.
|
||||
* @param {Object} attrs Any other attributes to apply.
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function icon(name, attrs = {}) {
|
||||
attrs.className = 'icon fa fa-fw fa-' + name + ' ' + (attrs.className || '');
|
||||
|
||||
return <i {...attrs}/>;
|
||||
}
|
||||
|
@@ -1,21 +0,0 @@
|
||||
import Separator from 'flarum/components/separator';
|
||||
|
||||
function isSeparator(item) {
|
||||
return item && item.component === Separator;
|
||||
}
|
||||
|
||||
export default function listItems(array, noWrap) {
|
||||
// Remove duplicate/unnecessary separators
|
||||
var prevItem;
|
||||
var newArray = [];
|
||||
array.forEach(function(item, i) {
|
||||
if ((!prevItem || isSeparator(prevItem) || i === array.length - 1) && isSeparator(item)) {
|
||||
|
||||
} else {
|
||||
prevItem = item;
|
||||
newArray.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
return newArray.map(item => [(noWrap && !isSeparator(item)) ? item : m('li', {className: 'item-'+item.itemName+' '+(item.wrapperClass || (item.props && item.props.wrapperClass) || (item.component && item.component.wrapperClass) || '')}, item), ' ']);
|
||||
};
|
37
js/lib/helpers/listItems.js
Normal file
37
js/lib/helpers/listItems.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import Separator from 'flarum/components/Separator';
|
||||
|
||||
function isSeparator(item) {
|
||||
return item && item.component === Separator;
|
||||
}
|
||||
|
||||
function withoutUnnecessarySeparators(items) {
|
||||
const newItems = [];
|
||||
let prevItem;
|
||||
|
||||
items.forEach((item, i) => {
|
||||
if (!isSeparator(item) || (prevItem && !isSeparator(prevItem) && i !== items.length - 1)) {
|
||||
prevItem = item;
|
||||
newItems.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
return newItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `listItems` helper wraps a collection of components in <li> tags,
|
||||
* stripping out any unnecessary `Separator` components.
|
||||
*
|
||||
* @param {Array} items
|
||||
* @return {Array}
|
||||
*/
|
||||
export default function listItems(items) {
|
||||
return withoutUnnecessarySeparators(items).map(item => {
|
||||
const isListItem = item.component && item.component.isListItem;
|
||||
const className = item.props ? item.props.itemClassName : item.itemClassName;
|
||||
|
||||
return isListItem
|
||||
? item
|
||||
: <li className={(item.itemName ? 'item-' + item.itemName : '') + ' ' + (className || '')}>{item}</li>;
|
||||
});
|
||||
};
|
@@ -1,13 +1,28 @@
|
||||
/**
|
||||
* The `punctuate` helper formats a list of strings (e.g. names) to read
|
||||
* fluently in the application's locale.
|
||||
*
|
||||
* @example
|
||||
* punctuate(['Toby', 'Franz', 'Dominion'])
|
||||
* // Toby, Franz, and Dominion
|
||||
*
|
||||
* @param {Array} items
|
||||
* @return {Array}
|
||||
*/
|
||||
export default function punctuate(items) {
|
||||
var newItems = [];
|
||||
const punctuated = [];
|
||||
|
||||
// FIXME: update to use translation
|
||||
items.forEach((item, i) => {
|
||||
newItems.push(item);
|
||||
punctuated.push(item);
|
||||
|
||||
if (i <= items.length - 2) {
|
||||
newItems.push((items.length > 2 ? ', ' : '')+(i === items.length - 2 ? ' and ' : ''));
|
||||
// If this item is not the last one, then we will follow it with some
|
||||
// punctuation. If the list is more than 2 items long, we'll add a comma.
|
||||
// And if this is the second-to-last item, we'll add 'and'.
|
||||
if (i < items.length - 1) {
|
||||
punctuated.push((items.length > 2 ? ', ' : '') + (i === items.length - 2 ? ' and ' : ''));
|
||||
}
|
||||
});
|
||||
|
||||
return newItems;
|
||||
return punctuated;
|
||||
};
|
||||
|
@@ -1,5 +1,12 @@
|
||||
/**
|
||||
* The `username` helper displays a user's username in a <span class="username">
|
||||
* tag. If the user doesn't exist, the username will be displayed as [deleted].
|
||||
*
|
||||
* @param {User} user
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function username(user) {
|
||||
var username = (user && user.username()) || '[deleted]';
|
||||
const name = (user && user.username()) || '[deleted]';
|
||||
|
||||
return m('span.username', username);
|
||||
return <span className="username">{name}</span>;
|
||||
}
|
||||
|
Reference in New Issue
Block a user