1
0
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:
Toby Zerner
2015-07-15 14:00:11 +09:30
parent 4480e0a83f
commit ab6c03c0cc
220 changed files with 9785 additions and 5919 deletions

View File

@@ -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>;
}

View File

@@ -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);
}

View 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>;
}

View File

@@ -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);
}

View File

@@ -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);
}

View 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>;
}

View File

@@ -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}/>;
}

View File

@@ -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), ' ']);
};

View 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>;
});
};

View File

@@ -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;
};

View File

@@ -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>;
}