From bc9558550d915402f8c163376ab1bd1a3615323f Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Thu, 19 Oct 2023 15:28:25 +0200 Subject: [PATCH] DEV: replace registerUnbound usage with default exports (#23802) `registerUnbound` was present for legacy reasons when using helpers in raw-hbs and has been replaced by `registerRawHelper`. For new helpers used only in classic ember template, exporting a default function from `helpers/*.js` is recommended. This change also means that all existing helpers will be available to import in `gjs` files. Co-authored-by: David Taylor --- .../admin/addon/helpers/check-icon.js | 8 +- .../admin/addon/helpers/value-at-tl.js | 8 +- .../addon/helpers/base-path.js | 8 ++ .../addon/helpers/base-url.js | 10 +++ .../addon/helpers/component-for-collection.js | 16 ++-- .../addon/helpers/component-for-row.js | 17 ++-- .../discourse-common/addon/helpers/d-icon.js | 4 +- .../discourse-common/addon/helpers/fa-icon.js | 7 +- .../discourse-common/addon/helpers/get-url.js | 16 ++-- .../addon/helpers/html-safe.js | 12 +-- .../addon/helpers/i18n-yes-no.js | 8 ++ .../discourse-common/addon/helpers/i18n.js | 9 +- .../discourse-common/addon/lib/helpers.js | 6 ++ .../discourse/app/helpers/age-with-tooltip.js | 15 ++++ .../discourse/app/helpers/avatar.js | 86 ++++++++++++++++++ .../discourse/app/helpers/category-link.js | 5 +- .../discourse/app/helpers/cold-age-class.js | 10 +-- .../app/helpers/decorate-username-selector.js | 8 +- .../discourse/app/helpers/dir-span.js | 8 +- .../helpers/directory-column-is-automatic.js | 4 + .../helpers/directory-column-is-user-field.js | 4 + .../app/helpers/directory-item-helpers.js | 43 --------- .../app/helpers/directory-item-label.js | 10 +++ .../directory-item-user-field-value.js | 13 +++ .../app/helpers/directory-item-value.js | 11 +++ .../helpers/directory-table-header-title.js | 5 +- .../discourse/app/helpers/discourse-tag.js | 7 +- .../discourse/app/helpers/discourse-tags.js | 7 +- .../discourse/app/helpers/emoji.js | 7 +- .../discourse/app/helpers/float.js | 6 +- .../discourse/app/helpers/format-age.js | 13 ++- .../discourse/app/helpers/format-date.js | 8 +- .../discourse/app/helpers/format-duration.js | 8 ++ .../discourse/app/helpers/format-username.js | 5 +- .../app/helpers/{application.js => number.js} | 26 ++---- .../discourse/app/helpers/raw-date.js | 9 ++ .../discourse/app/helpers/shorten-url.js | 7 +- .../discourse/app/helpers/theme-helpers.js | 16 ---- .../discourse/app/helpers/theme-i18n.js | 7 ++ .../discourse/app/helpers/theme-prefix.js | 6 ++ .../discourse/app/helpers/theme-setting.js | 7 ++ .../app/helpers/topic-featured-link.js | 7 +- .../discourse/app/helpers/topic-link.js | 7 +- .../discourse/app/helpers/user-avatar.js | 88 +------------------ .../discourse/app/helpers/value-entered.js | 7 +- 45 files changed, 334 insertions(+), 265 deletions(-) create mode 100644 app/assets/javascripts/discourse-common/addon/helpers/base-path.js create mode 100644 app/assets/javascripts/discourse-common/addon/helpers/base-url.js create mode 100644 app/assets/javascripts/discourse-common/addon/helpers/i18n-yes-no.js create mode 100644 app/assets/javascripts/discourse/app/helpers/age-with-tooltip.js create mode 100644 app/assets/javascripts/discourse/app/helpers/avatar.js create mode 100644 app/assets/javascripts/discourse/app/helpers/directory-column-is-automatic.js create mode 100644 app/assets/javascripts/discourse/app/helpers/directory-column-is-user-field.js delete mode 100644 app/assets/javascripts/discourse/app/helpers/directory-item-helpers.js create mode 100644 app/assets/javascripts/discourse/app/helpers/directory-item-label.js create mode 100644 app/assets/javascripts/discourse/app/helpers/directory-item-user-field-value.js create mode 100644 app/assets/javascripts/discourse/app/helpers/directory-item-value.js create mode 100644 app/assets/javascripts/discourse/app/helpers/format-duration.js rename app/assets/javascripts/discourse/app/helpers/{application.js => number.js} (63%) create mode 100644 app/assets/javascripts/discourse/app/helpers/raw-date.js delete mode 100644 app/assets/javascripts/discourse/app/helpers/theme-helpers.js create mode 100644 app/assets/javascripts/discourse/app/helpers/theme-i18n.js create mode 100644 app/assets/javascripts/discourse/app/helpers/theme-prefix.js create mode 100644 app/assets/javascripts/discourse/app/helpers/theme-setting.js diff --git a/app/assets/javascripts/admin/addon/helpers/check-icon.js b/app/assets/javascripts/admin/addon/helpers/check-icon.js index 14ae3e649c0..3acc6ecf568 100644 --- a/app/assets/javascripts/admin/addon/helpers/check-icon.js +++ b/app/assets/javascripts/admin/addon/helpers/check-icon.js @@ -1,8 +1,10 @@ import { htmlSafe } from "@ember/template"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; import { renderIcon } from "discourse-common/lib/icon-library"; -registerUnbound("check-icon", function (value) { +registerRawHelper("check-icon", checkIcon); + +export default function checkIcon(value) { let icon = value ? "check" : "times"; return htmlSafe(renderIcon("string", icon)); -}); +} diff --git a/app/assets/javascripts/admin/addon/helpers/value-at-tl.js b/app/assets/javascripts/admin/addon/helpers/value-at-tl.js index 158b02b5468..9aada034c79 100644 --- a/app/assets/javascripts/admin/addon/helpers/value-at-tl.js +++ b/app/assets/javascripts/admin/addon/helpers/value-at-tl.js @@ -1,6 +1,8 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound("value-at-tl", function (data, params) { +registerRawHelper("value-at-tl", valueAtTl); + +export default function valueAtTl(data, params = {}) { let tl = parseInt(params.level, 10); if (data) { let item = data.find(function (d) { @@ -12,4 +14,4 @@ registerUnbound("value-at-tl", function (data, params) { return 0; } } -}); +} diff --git a/app/assets/javascripts/discourse-common/addon/helpers/base-path.js b/app/assets/javascripts/discourse-common/addon/helpers/base-path.js new file mode 100644 index 00000000000..b12e103d71a --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/helpers/base-path.js @@ -0,0 +1,8 @@ +import getUrl from "discourse-common/lib/get-url"; +import { registerRawHelper } from "discourse-common/lib/helpers"; + +registerRawHelper("base-path", basePath); + +export default function basePath() { + return getUrl(""); +} diff --git a/app/assets/javascripts/discourse-common/addon/helpers/base-url.js b/app/assets/javascripts/discourse-common/addon/helpers/base-url.js new file mode 100644 index 00000000000..cde37687fb2 --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/helpers/base-url.js @@ -0,0 +1,10 @@ +import deprecated from "discourse-common/lib/deprecated"; +import getUrl from "discourse-common/lib/get-url"; +import { registerRawHelper } from "discourse-common/lib/helpers"; + +registerRawHelper("base-url", baseUrl); + +export default function baseUrl() { + deprecated("Use `{{base-path}}` instead of `{{base-url}}`"); + return getUrl(""); +} diff --git a/app/assets/javascripts/discourse-common/addon/helpers/component-for-collection.js b/app/assets/javascripts/discourse-common/addon/helpers/component-for-collection.js index 384012a0e6c..488a547a445 100644 --- a/app/assets/javascripts/discourse-common/addon/helpers/component-for-collection.js +++ b/app/assets/javascripts/discourse-common/addon/helpers/component-for-collection.js @@ -1,8 +1,10 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound( - "component-for-collection", - (collectionIdentifier, selectKit) => { - return selectKit.modifyComponentForCollection(collectionIdentifier); - } -); +registerRawHelper("component-for-collection", componentForCollection); + +export default function componentForCollection( + collectionIdentifier, + selectKit +) { + return selectKit.modifyComponentForCollection(collectionIdentifier); +} diff --git a/app/assets/javascripts/discourse-common/addon/helpers/component-for-row.js b/app/assets/javascripts/discourse-common/addon/helpers/component-for-row.js index 4f8ba12822e..741ca0691cf 100644 --- a/app/assets/javascripts/discourse-common/addon/helpers/component-for-row.js +++ b/app/assets/javascripts/discourse-common/addon/helpers/component-for-row.js @@ -1,8 +1,11 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound( - "component-for-row", - (collectionForIdentifier, item, selectKit) => { - return selectKit.modifyComponentForRow(collectionForIdentifier, item); - } -); +registerRawHelper("component-for-row", componentForRow); + +export default function componentForRow( + collectionForIdentifier, + item, + selectKit +) { + return selectKit.modifyComponentForRow(collectionForIdentifier, item); +} diff --git a/app/assets/javascripts/discourse-common/addon/helpers/d-icon.js b/app/assets/javascripts/discourse-common/addon/helpers/d-icon.js index fa7d04dc611..f7ddab94e04 100644 --- a/app/assets/javascripts/discourse-common/addon/helpers/d-icon.js +++ b/app/assets/javascripts/discourse-common/addon/helpers/d-icon.js @@ -1,9 +1,9 @@ import { htmlSafe } from "@ember/template"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; import { renderIcon } from "discourse-common/lib/icon-library"; export default function icon(id, options = {}) { return htmlSafe(renderIcon("string", id, options)); } -registerUnbound("d-icon", icon); +registerRawHelper("d-icon", icon); diff --git a/app/assets/javascripts/discourse-common/addon/helpers/fa-icon.js b/app/assets/javascripts/discourse-common/addon/helpers/fa-icon.js index ed26d7a09b3..95bb5a501f8 100644 --- a/app/assets/javascripts/discourse-common/addon/helpers/fa-icon.js +++ b/app/assets/javascripts/discourse-common/addon/helpers/fa-icon.js @@ -1,13 +1,14 @@ import { htmlSafe } from "@ember/template"; import deprecated from "discourse-common/lib/deprecated"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; import { renderIcon } from "discourse-common/lib/icon-library"; export function iconHTML(id, params) { return renderIcon("string", id, params); } -registerUnbound("fa-icon", function (icon, params) { +registerRawHelper("fa-icon", faIcon); +export default function faIcon(icon, params) { deprecated("Use `{{d-icon}}` instead of `{{fa-icon}}"); return htmlSafe(iconHTML(icon, params)); -}); +} diff --git a/app/assets/javascripts/discourse-common/addon/helpers/get-url.js b/app/assets/javascripts/discourse-common/addon/helpers/get-url.js index 14d907ec363..98b82aabf3f 100644 --- a/app/assets/javascripts/discourse-common/addon/helpers/get-url.js +++ b/app/assets/javascripts/discourse-common/addon/helpers/get-url.js @@ -1,10 +1,8 @@ -import deprecated from "discourse-common/lib/deprecated"; -import getUrl from "discourse-common/lib/get-url"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { default as emberGetUrl } from "discourse-common/lib/get-url"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound("get-url", (value) => getUrl(value)); -registerUnbound("base-url", () => { - deprecated("Use `{{base-path}}` instead of `{{base-url}}`"); - return getUrl(""); -}); -registerUnbound("base-path", () => getUrl("")); +registerRawHelper("get-url", getUrl); + +export default function getUrl(value) { + return emberGetUrl(value); +} diff --git a/app/assets/javascripts/discourse-common/addon/helpers/html-safe.js b/app/assets/javascripts/discourse-common/addon/helpers/html-safe.js index 11809ba8b88..f0f80d1a779 100644 --- a/app/assets/javascripts/discourse-common/addon/helpers/html-safe.js +++ b/app/assets/javascripts/discourse-common/addon/helpers/html-safe.js @@ -1,6 +1,8 @@ -import { htmlSafe } from "@ember/template"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { htmlSafe as emberHtmlSafe } from "@ember/template"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound("html-safe", function (string) { - return htmlSafe(string); -}); +registerRawHelper("html-safe", htmlSafe); + +export default function htmlSafe(string) { + return emberHtmlSafe(string); +} diff --git a/app/assets/javascripts/discourse-common/addon/helpers/i18n-yes-no.js b/app/assets/javascripts/discourse-common/addon/helpers/i18n-yes-no.js new file mode 100644 index 00000000000..7409f045519 --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/helpers/i18n-yes-no.js @@ -0,0 +1,8 @@ +import { registerRawHelper } from "discourse-common/lib/helpers"; +import I18n from "discourse-i18n"; + +registerRawHelper("i18n-yes-no", i18nYesNo); + +export default function i18nYesNo(value, params) { + return I18n.t(value ? "yes_value" : "no_value", params); +} diff --git a/app/assets/javascripts/discourse-common/addon/helpers/i18n.js b/app/assets/javascripts/discourse-common/addon/helpers/i18n.js index a6da3b4eec9..6be12e597ee 100644 --- a/app/assets/javascripts/discourse-common/addon/helpers/i18n.js +++ b/app/assets/javascripts/discourse-common/addon/helpers/i18n.js @@ -1,11 +1,8 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; import I18n from "discourse-i18n"; +registerRawHelper("i18n", i18n); + export default function i18n(key, params) { return I18n.t(key, params); } -registerUnbound("i18n", i18n); - -registerUnbound("i18n-yes-no", (value, params) => - I18n.t(value ? "yes_value" : "no_value", params) -); diff --git a/app/assets/javascripts/discourse-common/addon/lib/helpers.js b/app/assets/javascripts/discourse-common/addon/lib/helpers.js index f91bdf57cdb..0cce9621eff 100644 --- a/app/assets/javascripts/discourse-common/addon/lib/helpers.js +++ b/app/assets/javascripts/discourse-common/addon/lib/helpers.js @@ -2,6 +2,7 @@ import Helper from "@ember/component/helper"; import { get } from "@ember/object"; import { dasherize } from "@ember/string"; import { htmlSafe } from "@ember/template"; +import deprecated from "discourse-common/lib/deprecated"; import RawHandlebars from "discourse-common/lib/raw-handlebars"; export function makeArray(obj) { @@ -88,6 +89,11 @@ function resolveParams(ctx, options) { * do `export default ...` from a `helpers/*.js` file. */ export function registerUnbound(name, fn) { + deprecated( + `[registerUnbound ${name}] registerUnbound is deprecated. Instead, you should export a default function from 'discourse/helpers/${name}.js'. If the helper is also used in raw-hbs, you can register it using 'registerRawHelper'.`, + { id: "discourse.register-unbound" } + ); + _helpers[name] = Helper.extend({ compute: (params, args) => fn(...params, args), }); diff --git a/app/assets/javascripts/discourse/app/helpers/age-with-tooltip.js b/app/assets/javascripts/discourse/app/helpers/age-with-tooltip.js new file mode 100644 index 00000000000..9623cc0e38d --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/age-with-tooltip.js @@ -0,0 +1,15 @@ +import { htmlSafe } from "@ember/template"; +import { autoUpdatingRelativeAge } from "discourse/lib/formatter"; +import { registerRawHelper } from "discourse-common/lib/helpers"; + +registerRawHelper("age-with-tooltip", ageWithTooltip); + +export default function ageWithTooltip(dt, params = {}) { + return htmlSafe( + autoUpdatingRelativeAge(new Date(dt), { + title: true, + addAgo: params.addAgo || false, + ...(params.defaultFormat && { defaultFormat: params.defaultFormat }), + }) + ); +} diff --git a/app/assets/javascripts/discourse/app/helpers/avatar.js b/app/assets/javascripts/discourse/app/helpers/avatar.js new file mode 100644 index 00000000000..d87e51f4f7f --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/avatar.js @@ -0,0 +1,86 @@ +import { get } from "@ember/object"; +import { htmlSafe } from "@ember/template"; +import { prioritizeNameInUx } from "discourse/lib/settings"; +import { formatUsername } from "discourse/lib/utilities"; +import { avatarImg } from "discourse-common/lib/avatar-utils"; +import { registerRawHelper } from "discourse-common/lib/helpers"; +import I18n from "discourse-i18n"; + +let _customAvatarHelpers; + +export function registerCustomAvatarHelper(fn) { + _customAvatarHelpers = _customAvatarHelpers || []; + _customAvatarHelpers.push(fn); +} + +export function addExtraUserClasses(u, args) { + let extraClasses = classesForUser(u).join(" "); + if (extraClasses && extraClasses.length) { + args.extraClasses = extraClasses; + } + return args; +} + +export function classesForUser(u) { + let result = []; + if (_customAvatarHelpers) { + for (let i = 0; i < _customAvatarHelpers.length; i++) { + result = result.concat(_customAvatarHelpers[i](u)); + } + } + return result; +} + +export function renderAvatar(user, options) { + options = options || {}; + + if (user) { + const name = get(user, options.namePath || "name"); + const username = get(user, options.usernamePath || "username"); + const avatarTemplate = get( + user, + options.avatarTemplatePath || "avatar_template" + ); + + if (!username || !avatarTemplate) { + return ""; + } + + let displayName = prioritizeNameInUx(name) + ? name + : formatUsername(username); + + let title = options.title; + if (!title && !options.ignoreTitle) { + // first try to get a title + title = get(user, "title"); + // if there was no title provided + if (!title) { + // try to retrieve a description + const description = get(user, "description"); + // if a description has been provided + if (description && description.length > 0) { + // prepend the username before the description + title = I18n.t("user.avatar.name_and_description", { + name: displayName, + description, + }); + } + } + } + + return avatarImg({ + size: options.imageSize, + extraClasses: get(user, "extras") || options.extraClasses, + title: title || displayName, + avatarTemplate, + }); + } else { + return ""; + } +} + +registerRawHelper("avatar", avatar); +export default function avatar(user, params) { + return htmlSafe(renderAvatar.call(this, user, params)); +} diff --git a/app/assets/javascripts/discourse/app/helpers/category-link.js b/app/assets/javascripts/discourse/app/helpers/category-link.js index a7f755f8889..e47da2090d8 100644 --- a/app/assets/javascripts/discourse/app/helpers/category-link.js +++ b/app/assets/javascripts/discourse/app/helpers/category-link.js @@ -4,7 +4,7 @@ import { isRTL } from "discourse/lib/text-direction"; import { escapeExpression } from "discourse/lib/utilities"; import Category from "discourse/models/category"; import getURL from "discourse-common/lib/get-url"; -import { helperContext, registerUnbound } from "discourse-common/lib/helpers"; +import { helperContext, registerRawHelper } from "discourse-common/lib/helpers"; import { iconHTML } from "discourse-common/lib/icon-library"; import I18n from "discourse-i18n"; @@ -95,7 +95,8 @@ export function categoryLinkHTML(category, options) { return htmlSafe(categoryBadgeHTML(category, categoryOptions)); } -registerUnbound("category-link", categoryLinkHTML); +export default categoryLinkHTML; +registerRawHelper("category-link", categoryLinkHTML); function buildTopicCount(count) { return ` { +registerRawHelper("decorate-username-selector", decorateUsernameSelector); + +export default function decorateUsernameSelector(username) { return decorateUsername(username); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/dir-span.js b/app/assets/javascripts/discourse/app/helpers/dir-span.js index 02a0e64a888..e422ac0463a 100644 --- a/app/assets/javascripts/discourse/app/helpers/dir-span.js +++ b/app/assets/javascripts/discourse/app/helpers/dir-span.js @@ -1,7 +1,7 @@ import { htmlSafe } from "@ember/template"; import { isRTL } from "discourse/lib/text-direction"; import { escapeExpression } from "discourse/lib/utilities"; -import { helperContext, registerUnbound } from "discourse-common/lib/helpers"; +import { helperContext, registerRawHelper } from "discourse-common/lib/helpers"; function setDir(text) { let content = text ? text : ""; @@ -13,11 +13,13 @@ function setDir(text) { return content; } -export default registerUnbound("dir-span", function (str, params = {}) { +registerRawHelper("dir-span", dirSpan); + +export default function dirSpan(str, params = {}) { let isHtmlSafe = false; if (params.htmlSafe) { isHtmlSafe = params.htmlSafe === "true"; } let text = isHtmlSafe ? str : escapeExpression(str); return htmlSafe(setDir(text)); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/directory-column-is-automatic.js b/app/assets/javascripts/discourse/app/helpers/directory-column-is-automatic.js new file mode 100644 index 00000000000..eff90ed7602 --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/directory-column-is-automatic.js @@ -0,0 +1,4 @@ +export default function directoryColumnIsAutomatic(args) { + // Args should include key/values { column } + return args.column.type === "automatic"; +} diff --git a/app/assets/javascripts/discourse/app/helpers/directory-column-is-user-field.js b/app/assets/javascripts/discourse/app/helpers/directory-column-is-user-field.js new file mode 100644 index 00000000000..6fa2a413326 --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/directory-column-is-user-field.js @@ -0,0 +1,4 @@ +export default function directoryColumnIsUserField(args) { + // Args should include key/values { column } + return args.column.type === "user_field"; +} diff --git a/app/assets/javascripts/discourse/app/helpers/directory-item-helpers.js b/app/assets/javascripts/discourse/app/helpers/directory-item-helpers.js deleted file mode 100644 index cc8445a3000..00000000000 --- a/app/assets/javascripts/discourse/app/helpers/directory-item-helpers.js +++ /dev/null @@ -1,43 +0,0 @@ -import { htmlSafe } from "@ember/template"; -import { number } from "discourse/lib/formatter"; -import { registerUnbound } from "discourse-common/lib/helpers"; -import I18n from "discourse-i18n"; - -registerUnbound("directory-item-label", function (args) { - // Args should include key/values { item, column } - const count = args.item.get(args.column.name); - const translationPrefix = - args.column.type === "automatic" ? "directory." : ""; - return htmlSafe(I18n.t(`${translationPrefix}${args.column.name}`, { count })); -}); - -registerUnbound("directory-item-value", function (args) { - // Args should include key/values { item, column } - return htmlSafe( - `${number( - args.item.get(args.column.name) - )}` - ); -}); - -registerUnbound("directory-item-user-field-value", function (args) { - // Args should include key/values { item, column } - const value = - args.item.user && args.item.user.user_fields - ? args.item.user.user_fields[args.column.user_field_id] - : null; - const content = value || "-"; - return htmlSafe( - `${content}` - ); -}); - -registerUnbound("directory-column-is-automatic", function (args) { - // Args should include key/values { column } - return args.column.type === "automatic"; -}); - -registerUnbound("directory-column-is-user-field", function (args) { - // Args should include key/values { column } - return args.column.type === "user_field"; -}); diff --git a/app/assets/javascripts/discourse/app/helpers/directory-item-label.js b/app/assets/javascripts/discourse/app/helpers/directory-item-label.js new file mode 100644 index 00000000000..64d3bd0f8c4 --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/directory-item-label.js @@ -0,0 +1,10 @@ +import { htmlSafe } from "@ember/template"; +import I18n from "discourse-i18n"; + +export default function directoryItemLabel(args) { + // Args should include key/values { item, column } + const count = args.item.get(args.column.name); + const translationPrefix = + args.column.type === "automatic" ? "directory." : ""; + return htmlSafe(I18n.t(`${translationPrefix}${args.column.name}`, { count })); +} diff --git a/app/assets/javascripts/discourse/app/helpers/directory-item-user-field-value.js b/app/assets/javascripts/discourse/app/helpers/directory-item-user-field-value.js new file mode 100644 index 00000000000..9ea845a159f --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/directory-item-user-field-value.js @@ -0,0 +1,13 @@ +import { htmlSafe } from "@ember/template"; + +export default function directoryItemUserFieldValue(args) { + // Args should include key/values { item, column } + const value = + args.item.user && args.item.user.user_fields + ? args.item.user.user_fields[args.column.user_field_id] + : null; + const content = value || "-"; + return htmlSafe( + `${content}` + ); +} diff --git a/app/assets/javascripts/discourse/app/helpers/directory-item-value.js b/app/assets/javascripts/discourse/app/helpers/directory-item-value.js new file mode 100644 index 00000000000..b0867b60c1b --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/directory-item-value.js @@ -0,0 +1,11 @@ +import { htmlSafe } from "@ember/template"; +import { number } from "discourse/lib/formatter"; + +export default function directoryItemValue(args) { + // Args should include key/values { item, column } + return htmlSafe( + `${number( + args.item.get(args.column.name) + )}` + ); +} diff --git a/app/assets/javascripts/discourse/app/helpers/directory-table-header-title.js b/app/assets/javascripts/discourse/app/helpers/directory-table-header-title.js index 12e8054a261..091a6276fce 100644 --- a/app/assets/javascripts/discourse/app/helpers/directory-table-header-title.js +++ b/app/assets/javascripts/discourse/app/helpers/directory-table-header-title.js @@ -1,9 +1,8 @@ import { htmlSafe } from "@ember/template"; -import { registerUnbound } from "discourse-common/lib/helpers"; import { iconHTML } from "discourse-common/lib/icon-library"; import I18n from "discourse-i18n"; -export default registerUnbound("directory-table-header-title", function (args) { +export default function directoryTableHeaderTitle(args) { // Args should include key/values { field, labelKey, icon, translated } let html = ""; @@ -16,4 +15,4 @@ export default registerUnbound("directory-table-header-title", function (args) { ? args.field : I18n.t(labelKey + "_long", { defaultValue: I18n.t(labelKey) }); return htmlSafe(html); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/discourse-tag.js b/app/assets/javascripts/discourse/app/helpers/discourse-tag.js index 42744b17faa..a42cce18e59 100644 --- a/app/assets/javascripts/discourse/app/helpers/discourse-tag.js +++ b/app/assets/javascripts/discourse/app/helpers/discourse-tag.js @@ -1,7 +1,8 @@ import { htmlSafe } from "@ember/template"; import renderTag from "discourse/lib/render-tag"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -export default registerUnbound("discourse-tag", function (name, params) { +registerRawHelper("discourse-tag", discourseTag); +export default function discourseTag(name, params) { return htmlSafe(renderTag(name, params)); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/discourse-tags.js b/app/assets/javascripts/discourse/app/helpers/discourse-tags.js index f063720a885..a10f5d8ecd3 100644 --- a/app/assets/javascripts/discourse/app/helpers/discourse-tags.js +++ b/app/assets/javascripts/discourse/app/helpers/discourse-tags.js @@ -1,7 +1,8 @@ import { htmlSafe } from "@ember/template"; import renderTags from "discourse/lib/render-tags"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -export default registerUnbound("discourse-tags", function (topic, params) { +registerRawHelper("discourse-tags", discourseTags); +export default function discourseTags(topic, params) { return htmlSafe(renderTags(topic, params)); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/emoji.js b/app/assets/javascripts/discourse/app/helpers/emoji.js index ca2f5129f66..8286efacdce 100644 --- a/app/assets/javascripts/discourse/app/helpers/emoji.js +++ b/app/assets/javascripts/discourse/app/helpers/emoji.js @@ -1,9 +1,10 @@ import { htmlSafe } from "@ember/template"; import { emojiUnescape } from "discourse/lib/text"; import { escapeExpression } from "discourse/lib/utilities"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound("emoji", function (code, options) { +registerRawHelper("emoji", emoji); +export default function emoji(code, options) { const escaped = escapeExpression(`:${code}:`); return htmlSafe(emojiUnescape(escaped, options)); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/float.js b/app/assets/javascripts/discourse/app/helpers/float.js index d58fc3b1890..eaaa8b3e1b8 100644 --- a/app/assets/javascripts/discourse/app/helpers/float.js +++ b/app/assets/javascripts/discourse/app/helpers/float.js @@ -1,5 +1,3 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; - -registerUnbound("float", function (n) { +export default function float(n) { return parseFloat(n).toFixed(1); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/format-age.js b/app/assets/javascripts/discourse/app/helpers/format-age.js index 3483ad8f5db..e8f32492276 100644 --- a/app/assets/javascripts/discourse/app/helpers/format-age.js +++ b/app/assets/javascripts/discourse/app/helpers/format-age.js @@ -1,12 +1,9 @@ import { htmlSafe } from "@ember/template"; -import { autoUpdatingRelativeAge, durationTiny } from "discourse/lib/formatter"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { autoUpdatingRelativeAge } from "discourse/lib/formatter"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound("format-age", function (dt) { +registerRawHelper("format-age", formatAge); +export default function formatAge(dt) { dt = new Date(dt); return htmlSafe(autoUpdatingRelativeAge(dt)); -}); - -registerUnbound("format-duration", function (seconds) { - return htmlSafe(durationTiny(seconds)); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/format-date.js b/app/assets/javascripts/discourse/app/helpers/format-date.js index 9c939648506..58dc000e17a 100644 --- a/app/assets/javascripts/discourse/app/helpers/format-date.js +++ b/app/assets/javascripts/discourse/app/helpers/format-date.js @@ -1,12 +1,14 @@ import { htmlSafe } from "@ember/template"; import { autoUpdatingRelativeAge } from "discourse/lib/formatter"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; /** Display logic for dates. It is unbound in Ember but will use jQuery to update the dates on a regular interval. **/ -registerUnbound("format-date", function (val, params) { + +registerRawHelper("format-date", formatDate); +export default function formatDate(val, params = {}) { let leaveAgo, format = "medium", title = true; @@ -32,4 +34,4 @@ registerUnbound("format-date", function (val, params) { }) ); } -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/format-duration.js b/app/assets/javascripts/discourse/app/helpers/format-duration.js new file mode 100644 index 00000000000..5720e81193b --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/format-duration.js @@ -0,0 +1,8 @@ +import { htmlSafe } from "@ember/template"; +import { durationTiny } from "discourse/lib/formatter"; +import { registerRawHelper } from "discourse-common/lib/helpers"; + +registerRawHelper("format-duration", formatDuration); +export default function formatDuration(seconds) { + return htmlSafe(durationTiny(seconds)); +} diff --git a/app/assets/javascripts/discourse/app/helpers/format-username.js b/app/assets/javascripts/discourse/app/helpers/format-username.js index 6388a900fbd..f851f184e73 100644 --- a/app/assets/javascripts/discourse/app/helpers/format-username.js +++ b/app/assets/javascripts/discourse/app/helpers/format-username.js @@ -1,4 +1,5 @@ import { formatUsername } from "discourse/lib/utilities"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -export default registerUnbound("format-username", formatUsername); +export default formatUsername; +registerRawHelper("format-username", formatUsername); diff --git a/app/assets/javascripts/discourse/app/helpers/application.js b/app/assets/javascripts/discourse/app/helpers/number.js similarity index 63% rename from app/assets/javascripts/discourse/app/helpers/application.js rename to app/assets/javascripts/discourse/app/helpers/number.js index 8cc8cd54169..4076b99d60d 100644 --- a/app/assets/javascripts/discourse/app/helpers/application.js +++ b/app/assets/javascripts/discourse/app/helpers/number.js @@ -1,26 +1,12 @@ import { htmlSafe } from "@ember/template"; -import { - autoUpdatingRelativeAge, - longDate, - number, -} from "discourse/lib/formatter"; +import { number as numberFormatter } from "discourse/lib/formatter"; import { escapeExpression } from "discourse/lib/utilities"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; import I18n from "discourse-i18n"; -registerUnbound("raw-date", (dt) => htmlSafe(longDate(new Date(dt)))); +registerRawHelper("number", number); -registerUnbound("age-with-tooltip", (dt, params) => - htmlSafe( - autoUpdatingRelativeAge(new Date(dt), { - title: true, - addAgo: params.addAgo || false, - ...(params.defaultFormat && { defaultFormat: params.defaultFormat }), - }) - ) -); - -registerUnbound("number", (orig, params) => { +export default function number(orig, params = {}) { orig = Math.round(parseFloat(orig)); if (isNaN(orig)) { orig = 0; @@ -43,7 +29,7 @@ registerUnbound("number", (orig, params) => { let addTitle = params.noTitle ? false : true; // Round off the thousands to one decimal place - const n = number(orig); + const n = numberFormatter(orig); if (n.toString() !== title.toString() && addTitle) { result += " title='" + escapeExpression(title) + "'"; } @@ -55,4 +41,4 @@ registerUnbound("number", (orig, params) => { result += ">" + n + ""; return htmlSafe(result); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/raw-date.js b/app/assets/javascripts/discourse/app/helpers/raw-date.js new file mode 100644 index 00000000000..50202067657 --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/raw-date.js @@ -0,0 +1,9 @@ +import { htmlSafe } from "@ember/template"; +import { longDate } from "discourse/lib/formatter"; +import { registerRawHelper } from "discourse-common/lib/helpers"; + +registerRawHelper("raw-date", rawDate); + +export default function rawDate(dt) { + return htmlSafe(longDate(new Date(dt))); +} diff --git a/app/assets/javascripts/discourse/app/helpers/shorten-url.js b/app/assets/javascripts/discourse/app/helpers/shorten-url.js index 4a35906190d..99c88739b3f 100644 --- a/app/assets/javascripts/discourse/app/helpers/shorten-url.js +++ b/app/assets/javascripts/discourse/app/helpers/shorten-url.js @@ -1,6 +1,7 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound("shorten-url", function (url) { +registerRawHelper("shorten-url", shortenUrl); +export default function shortenUrl(url) { let matches = url.match(/\//g); if (matches && matches.length === 3) { @@ -9,4 +10,4 @@ registerUnbound("shorten-url", function (url) { url = url.replace(/^https?:\/\//, ""); url = url.replace(/^www\./, ""); return url.substring(0, 80); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/theme-helpers.js b/app/assets/javascripts/discourse/app/helpers/theme-helpers.js deleted file mode 100644 index 9eea8faa091..00000000000 --- a/app/assets/javascripts/discourse/app/helpers/theme-helpers.js +++ /dev/null @@ -1,16 +0,0 @@ -import { getSetting as getThemeSetting } from "discourse/lib/theme-settings-store"; -import { registerUnbound } from "discourse-common/lib/helpers"; -import I18n from "discourse-i18n"; - -registerUnbound("theme-i18n", (themeId, key, params) => { - return I18n.t(`theme_translations.${themeId}.${key}`, params); -}); - -registerUnbound( - "theme-prefix", - (themeId, key) => `theme_translations.${themeId}.${key}` -); - -registerUnbound("theme-setting", (themeId, key) => { - return getThemeSetting(themeId, key); -}); diff --git a/app/assets/javascripts/discourse/app/helpers/theme-i18n.js b/app/assets/javascripts/discourse/app/helpers/theme-i18n.js new file mode 100644 index 00000000000..11fffb8522b --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/theme-i18n.js @@ -0,0 +1,7 @@ +import { registerRawHelper } from "discourse-common/lib/helpers"; +import I18n from "discourse-i18n"; + +registerRawHelper("theme-i18n", themeI18n); +export default function themeI18n(themeId, key, params) { + return I18n.t(`theme_translations.${themeId}.${key}`, params); +} diff --git a/app/assets/javascripts/discourse/app/helpers/theme-prefix.js b/app/assets/javascripts/discourse/app/helpers/theme-prefix.js new file mode 100644 index 00000000000..579352cb678 --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/theme-prefix.js @@ -0,0 +1,6 @@ +import { registerRawHelper } from "discourse-common/lib/helpers"; + +registerRawHelper("theme-prefix", themePrefix); +export default function themePrefix(themeId, key) { + return `theme_translations.${themeId}.${key}`; +} diff --git a/app/assets/javascripts/discourse/app/helpers/theme-setting.js b/app/assets/javascripts/discourse/app/helpers/theme-setting.js new file mode 100644 index 00000000000..8c3b08275e9 --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/theme-setting.js @@ -0,0 +1,7 @@ +import { getSetting as getThemeSetting } from "discourse/lib/theme-settings-store"; +import { registerRawHelper } from "discourse-common/lib/helpers"; + +registerRawHelper("theme-setting", themeSetting); +export default function themeSetting(themeId, key) { + return getThemeSetting(themeId, key); +} diff --git a/app/assets/javascripts/discourse/app/helpers/topic-featured-link.js b/app/assets/javascripts/discourse/app/helpers/topic-featured-link.js index f911b8d17c1..e1d9b768b92 100644 --- a/app/assets/javascripts/discourse/app/helpers/topic-featured-link.js +++ b/app/assets/javascripts/discourse/app/helpers/topic-featured-link.js @@ -1,7 +1,8 @@ import { htmlSafe } from "@ember/template"; import renderTopicFeaturedLink from "discourse/lib/render-topic-featured-link"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -export default registerUnbound("topic-featured-link", function (topic, params) { +registerRawHelper("topic-featured-link", topicFeaturedLink); +export default function topicFeaturedLink(topic, params) { return htmlSafe(renderTopicFeaturedLink(topic, params)); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/topic-link.js b/app/assets/javascripts/discourse/app/helpers/topic-link.js index 24aa876896a..8e545ba9cc0 100644 --- a/app/assets/javascripts/discourse/app/helpers/topic-link.js +++ b/app/assets/javascripts/discourse/app/helpers/topic-link.js @@ -1,7 +1,8 @@ import { htmlSafe } from "@ember/template"; -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound("topic-link", (topic, args) => { +registerRawHelper("topic-link", topicLink); +export default function topicLink(topic, args = {}) { const title = topic.get("fancyTitle"); const url = topic.linked_post_number @@ -21,4 +22,4 @@ registerUnbound("topic-link", (topic, args) => { class='${classes.join(" ")}' data-topic-id='${topic.id}'>${title}` ); -}); +} diff --git a/app/assets/javascripts/discourse/app/helpers/user-avatar.js b/app/assets/javascripts/discourse/app/helpers/user-avatar.js index 000bff66bad..90fdb226bcb 100644 --- a/app/assets/javascripts/discourse/app/helpers/user-avatar.js +++ b/app/assets/javascripts/discourse/app/helpers/user-avatar.js @@ -1,87 +1 @@ -import { get } from "@ember/object"; -import { htmlSafe } from "@ember/template"; -import { prioritizeNameInUx } from "discourse/lib/settings"; -import { formatUsername } from "discourse/lib/utilities"; -import { avatarImg } from "discourse-common/lib/avatar-utils"; -import { registerUnbound } from "discourse-common/lib/helpers"; -import I18n from "discourse-i18n"; - -let _customAvatarHelpers; - -export function registerCustomAvatarHelper(fn) { - _customAvatarHelpers = _customAvatarHelpers || []; - _customAvatarHelpers.push(fn); -} - -export function addExtraUserClasses(u, args) { - let extraClasses = classesForUser(u).join(" "); - if (extraClasses && extraClasses.length) { - args.extraClasses = extraClasses; - } - return args; -} - -export function classesForUser(u) { - let result = []; - if (_customAvatarHelpers) { - for (let i = 0; i < _customAvatarHelpers.length; i++) { - result = result.concat(_customAvatarHelpers[i](u)); - } - } - return result; -} - -function renderAvatar(user, options) { - options = options || {}; - - if (user) { - const name = get(user, options.namePath || "name"); - const username = get(user, options.usernamePath || "username"); - const avatarTemplate = get( - user, - options.avatarTemplatePath || "avatar_template" - ); - - if (!username || !avatarTemplate) { - return ""; - } - - let displayName = prioritizeNameInUx(name) - ? name - : formatUsername(username); - - let title = options.title; - if (!title && !options.ignoreTitle) { - // first try to get a title - title = get(user, "title"); - // if there was no title provided - if (!title) { - // try to retrieve a description - const description = get(user, "description"); - // if a description has been provided - if (description && description.length > 0) { - // prepend the username before the description - title = I18n.t("user.avatar.name_and_description", { - name: displayName, - description, - }); - } - } - } - - return avatarImg({ - size: options.imageSize, - extraClasses: get(user, "extras") || options.extraClasses, - title: title || displayName, - avatarTemplate, - }); - } else { - return ""; - } -} - -registerUnbound("avatar", function (user, params) { - return htmlSafe(renderAvatar.call(this, user, params)); -}); - -export { renderAvatar }; +export * from "./avatar"; diff --git a/app/assets/javascripts/discourse/app/helpers/value-entered.js b/app/assets/javascripts/discourse/app/helpers/value-entered.js index 4a6907ae23b..417c987e59e 100644 --- a/app/assets/javascripts/discourse/app/helpers/value-entered.js +++ b/app/assets/javascripts/discourse/app/helpers/value-entered.js @@ -1,6 +1,7 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; +import { registerRawHelper } from "discourse-common/lib/helpers"; -registerUnbound("value-entered", function (value) { +registerRawHelper("value-entered", valueEntered); +export default function valueEntered(value) { if (!value) { return ""; } else if (value.length > 0) { @@ -8,4 +9,4 @@ registerUnbound("value-entered", function (value) { } else { return ""; } -}); +}