DEV: Add appEvents for composer / DEditor toolbar events (#26517)

This commit is contained in:
Mark VanLandingham 2024-04-05 08:35:25 -05:00 committed by GitHub
parent b8d04fca88
commit 552203aa1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 61 additions and 36 deletions

View File

@ -162,45 +162,55 @@ class Toolbar {
this.groups[this.groups.length - 1].lastGroup = true; this.groups[this.groups.length - 1].lastGroup = true;
} }
addButton(button) { addButton(buttonAttrs) {
const g = this.groups.findBy("group", button.group); const g = this.groups.findBy("group", buttonAttrs.group);
if (!g) { if (!g) {
throw new Error(`Couldn't find toolbar group ${button.group}`); throw new Error(`Couldn't find toolbar group ${buttonAttrs.group}`);
} }
const createdButton = { const createdButton = {
id: button.id, id: buttonAttrs.id,
tabindex: button.tabindex || "-1", tabindex: buttonAttrs.tabindex || "-1",
className: button.className || button.id, className: buttonAttrs.className || buttonAttrs.id,
label: button.label, label: buttonAttrs.label,
icon: button.icon, icon: buttonAttrs.icon,
action: button.action || ((a) => this.context.send("toolbarButton", a)), action: (button) => {
perform: button.perform || function () {}, buttonAttrs.action
trimLeading: button.trimLeading, ? buttonAttrs.action(button)
popupMenu: button.popupMenu || false, : this.context.send("toolbarButton", button);
preventFocus: button.preventFocus || false, this.context.appEvents.trigger(
condition: button.condition || (() => true), "d-editor:toolbar-button-clicked",
button
);
},
perform: buttonAttrs.perform || function () {},
trimLeading: buttonAttrs.trimLeading,
popupMenu: buttonAttrs.popupMenu || false,
preventFocus: buttonAttrs.preventFocus || false,
condition: buttonAttrs.condition || (() => true),
}; };
if (button.sendAction) { if (buttonAttrs.sendAction) {
createdButton.sendAction = button.sendAction; createdButton.sendAction = buttonAttrs.sendAction;
} }
const title = I18n.t(button.title || `composer.${button.id}_title`); const title = I18n.t(
if (button.shortcut) { buttonAttrs.title || `composer.${buttonAttrs.id}_title`
);
if (buttonAttrs.shortcut) {
const shortcutTitle = `${translateModKey( const shortcutTitle = `${translateModKey(
PLATFORM_KEY_MODIFIER + "+" PLATFORM_KEY_MODIFIER + "+"
)}${translateModKey(button.shortcut)}`; )}${translateModKey(buttonAttrs.shortcut)}`;
createdButton.title = `${title} (${shortcutTitle})`; createdButton.title = `${title} (${shortcutTitle})`;
this.shortcuts[ this.shortcuts[
`${PLATFORM_KEY_MODIFIER}+${button.shortcut}`.toLowerCase() `${PLATFORM_KEY_MODIFIER}+${buttonAttrs.shortcut}`.toLowerCase()
] = createdButton; ] = createdButton;
} else { } else {
createdButton.title = title; createdButton.title = title;
} }
if (button.unshift) { if (buttonAttrs.unshift) {
g.buttons.unshift(createdButton); g.buttons.unshift(createdButton);
} else { } else {
g.buttons.push(createdButton); g.buttons.push(createdButton);

View File

@ -384,6 +384,7 @@ export default class ComposerService extends Service {
options.push( options.push(
this._setupPopupMenuOption({ this._setupPopupMenuOption({
name: "toggle-invisible",
action: "toggleInvisible", action: "toggleInvisible",
icon: "far-eye-slash", icon: "far-eye-slash",
label: "composer.toggle_unlisted", label: "composer.toggle_unlisted",
@ -394,6 +395,7 @@ export default class ComposerService extends Service {
if (this.capabilities.touch) { if (this.capabilities.touch) {
options.push( options.push(
this._setupPopupMenuOption({ this._setupPopupMenuOption({
name: "format-code",
action: "applyFormatCode", action: "applyFormatCode",
icon: "code", icon: "code",
label: "composer.code_title", label: "composer.code_title",
@ -402,6 +404,7 @@ export default class ComposerService extends Service {
options.push( options.push(
this._setupPopupMenuOption({ this._setupPopupMenuOption({
name: "apply-unordered-list",
action: "applyUnorderedList", action: "applyUnorderedList",
icon: "list-ul", icon: "list-ul",
label: "composer.ulist_title", label: "composer.ulist_title",
@ -410,6 +413,7 @@ export default class ComposerService extends Service {
options.push( options.push(
this._setupPopupMenuOption({ this._setupPopupMenuOption({
name: "apply-ordered-list",
action: "applyOrderedList", action: "applyOrderedList",
icon: "list-ol", icon: "list-ol",
label: "composer.olist_title", label: "composer.olist_title",
@ -419,6 +423,7 @@ export default class ComposerService extends Service {
options.push( options.push(
this._setupPopupMenuOption({ this._setupPopupMenuOption({
name: "toggle-whisper",
action: "toggleWhisper", action: "toggleWhisper",
icon: "far-eye-slash", icon: "far-eye-slash",
label: "composer.toggle_whisper", label: "composer.toggle_whisper",
@ -428,6 +433,7 @@ export default class ComposerService extends Service {
options.push( options.push(
this._setupPopupMenuOption({ this._setupPopupMenuOption({
name: "toggle-spreadsheet",
action: "toggleSpreadsheet", action: "toggleSpreadsheet",
icon: "table", icon: "table",
label: "composer.insert_table", label: "composer.insert_table",
@ -653,13 +659,19 @@ export default class ComposerService extends Service {
} }
@action @action
onPopupMenuAction(menuAction) { onPopupMenuAction(menuItem) {
if (typeof menuAction === "function") { // menuItem is an object with keys name & action like so: { name: "toggle-invisible, action: "toggleInvisible" }
return menuAction(this.toolbarEvent); // `action` value can either be a string (to lookup action by) or a function to call
this.appEvents.trigger(
"composer:toolbar-popup-menu-button-clicked",
menuItem
);
if (typeof menuItem.action === "function") {
return menuItem.action(this.toolbarEvent);
} else { } else {
return ( return (
this.actions?.[menuAction]?.bind(this) || // Legacy-style contributions from themes/plugins this.actions?.[menuItem.action]?.bind(this) || // Legacy-style contributions from themes/plugins
this[menuAction] this[menuItem.action]
)(); )();
} }
} }
@ -1411,6 +1423,7 @@ export default class ComposerService extends Service {
await this._setModel(composerModel, opts); await this._setModel(composerModel, opts);
} finally { } finally {
this.skipAutoSave = false; this.skipAutoSave = false;
this.appEvents.trigger("composer:open", { model: this.model });
} }
} }

View File

@ -616,7 +616,7 @@ acceptance("Composer", function (needs) {
await click(".topic-post:nth-of-type(1) button.reply"); await click(".topic-post:nth-of-type(1) button.reply");
await menu.expand(); await menu.expand();
await menu.selectRowByValue("toggleWhisper"); await menu.selectRowByName(I18n.t("composer.toggle_whisper"));
assert.strictEqual( assert.strictEqual(
count(".composer-actions svg.d-icon-far-eye-slash"), count(".composer-actions svg.d-icon-far-eye-slash"),
@ -625,7 +625,7 @@ acceptance("Composer", function (needs) {
); );
await menu.expand(); await menu.expand();
await menu.selectRowByValue("toggleWhisper"); await menu.selectRowByName(I18n.t("composer.toggle_whisper"));
assert.ok( assert.ok(
!exists(".composer-actions svg.d-icon-far-eye-slash"), !exists(".composer-actions svg.d-icon-far-eye-slash"),
@ -633,14 +633,14 @@ acceptance("Composer", function (needs) {
); );
await menu.expand(); await menu.expand();
await menu.selectRowByValue("toggleWhisper"); await menu.selectRowByName(I18n.t("composer.toggle_whisper"));
await click(".toggle-fullscreen"); await click(".toggle-fullscreen");
await menu.expand(); await menu.expand();
assert.ok( assert.ok(
menu.rowByValue("toggleWhisper").exists(), menu.rowByName(I18n.t("composer.toggle_whisper")).exists(),
"whisper toggling is still present when going fullscreen" "whisper toggling is still present when going fullscreen"
); );
}); });
@ -728,8 +728,9 @@ acceptance("Composer", function (needs) {
await click(".topic-post:nth-of-type(1) button.reply"); await click(".topic-post:nth-of-type(1) button.reply");
await selectKit(".toolbar-popup-menu-options").expand(); await selectKit(".toolbar-popup-menu-options").expand();
await selectKit(".toolbar-popup-menu-options").selectRowByValue(
"toggleWhisper" await selectKit(".toolbar-popup-menu-options").selectRowByName(
I18n.t("composer.toggle_whisper")
); );
assert.strictEqual( assert.strictEqual(
@ -748,8 +749,8 @@ acceptance("Composer", function (needs) {
); );
await selectKit(".toolbar-popup-menu-options").expand(); await selectKit(".toolbar-popup-menu-options").expand();
await selectKit(".toolbar-popup-menu-options").selectRowByValue( await selectKit(".toolbar-popup-menu-options").selectRowByName(
"toggleInvisible" I18n.t("composer.toggle_unlisted")
); );
assert.ok( assert.ok(

View File

@ -20,7 +20,7 @@ export default DropdownSelectBoxComponent.extend({
return { return {
icon: content.icon, icon: content.icon,
name: I18n.t(content.label), name: I18n.t(content.label),
id: content.action, id: { name: content.name, action: content.action },
}; };
} }
}) })

View File

@ -13,6 +13,7 @@ import {
query, query,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import I18n from "discourse-i18n";
acceptance("Discourse Presence Plugin", function (needs) { acceptance("Discourse Presence Plugin", function (needs) {
needs.user({ whisperer: true }); needs.user({ whisperer: true });
@ -82,7 +83,7 @@ acceptance("Discourse Presence Plugin", function (needs) {
const menu = selectKit(".toolbar-popup-menu-options"); const menu = selectKit(".toolbar-popup-menu-options");
await menu.expand(); await menu.expand();
await menu.selectRowByValue("toggleWhisper"); await menu.selectRowByName(I18n.t("composer.toggle_whisper"));
assert.strictEqual( assert.strictEqual(
count(".composer-actions svg.d-icon-far-eye-slash"), count(".composer-actions svg.d-icon-far-eye-slash"),