DEV: API extra markup to image wrapper (#25575)

This commit is contained in:
Keegan George 2024-02-14 12:20:53 -08:00 committed by GitHub
parent 53a198ad55
commit 10b33bc601
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 124 additions and 1 deletions

View File

@ -2,6 +2,30 @@ import I18n from "discourse-i18n";
const SCALES = ["100", "75", "50"];
let apiExtraButton = [];
let apiExtraButtonAllowList = [];
export function addImageWrapperButton(label, btnClass, icon = null) {
const markup = [];
markup.push(`<span class="${btnClass}">`);
if (icon) {
markup.push(`
<svg class="fa d-icon d-icon-${icon} svg-icon svg-string" xmlns="http://www.w3.org/2000/svg">
<use href="#${icon}"></use>
</svg>
`);
}
markup.push(label);
markup.push("</span>");
apiExtraButton.push(markup.join(""));
apiExtraButtonAllowList.push(`span.${btnClass}`);
apiExtraButtonAllowList.push(
`svg[class=fa d-icon d-icon-${icon} svg-icon svg-string]`
);
apiExtraButtonAllowList.push(`use[href=#${icon}]`);
}
function isUpload(token) {
return token.content.includes("upload://");
}
@ -157,6 +181,8 @@ function ruleWithImageControls(oldRule) {
result += `</span>`;
result += buildImageDeleteButton();
result += apiExtraButton.join("");
result += "</span></span>";
return result;
@ -205,6 +231,8 @@ export function setup(helper) {
"span.wrap-image-grid-button[data-image-count]",
"svg[class=fa d-icon d-icon-th svg-icon svg-string]",
"use[href=#th]",
...apiExtraButtonAllowList,
]);
helper.registerPlugin((md) => {

View File

@ -101,6 +101,12 @@ export function addComposerUploadMarkdownResolver(resolver) {
export function cleanUpComposerUploadMarkdownResolver() {
uploadMarkdownResolvers = [];
}
let apiImageWrapperBtnEvents = [];
export function addApiImageWrapperButtonClickEvent(fn) {
apiImageWrapperBtnEvents.push(fn);
}
export default Component.extend(ComposerUploadUppy, {
classNameBindings: ["showToolbar:toolbar-visible", ":wmd-controls"],
@ -773,6 +779,12 @@ export default Component.extend(ComposerUploadUppy, {
preview.addEventListener("click", this._handleImageDeleteButtonClick);
preview.addEventListener("keypress", this._handleAltTextInputKeypress);
preview.addEventListener("click", this._handleImageGridButtonClick);
if (apiImageWrapperBtnEvents.length > 0) {
apiImageWrapperBtnEvents.forEach((fn) => {
preview.addEventListener("click", fn);
});
}
},
@on("willDestroyElement")
@ -802,6 +814,12 @@ export default Component.extend(ComposerUploadUppy, {
preview?.removeEventListener("click", this._handleImageGridButtonClick);
preview?.removeEventListener("click", this._handleAltTextCancelButtonClick);
preview?.removeEventListener("keypress", this._handleAltTextInputKeypress);
if (apiImageWrapperBtnEvents.length > 0) {
apiImageWrapperBtnEvents.forEach((fn) => {
preview?.removeEventListener("click", fn);
});
}
},
onExpandPopupMenuOptions(toolbarEvent) {

View File

@ -1,6 +1,7 @@
import $ from "jquery";
import { h } from "virtual-dom";
import {
addApiImageWrapperButtonClickEvent,
addComposerUploadHandler,
addComposerUploadMarkdownResolver,
addComposerUploadPreProcessor,
@ -132,6 +133,7 @@ import {
registerIconRenderer,
replaceIcon,
} from "discourse-common/lib/icon-library";
import { addImageWrapperButton } from "discourse-markdown-it/features/image-controls";
import { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser";
import { modifySelectKit } from "select-kit/mixins/plugin-api";
@ -140,7 +142,7 @@ import { modifySelectKit } from "select-kit/mixins/plugin-api";
// docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md whenever you change the version
// using the format described at https://keepachangelog.com/en/1.0.0/.
export const PLUGIN_API_VERSION = "1.24.0";
export const PLUGIN_API_VERSION = "1.25.0";
// This helper prevents us from applying the same `modifyClass` over and over in test mode.
function canModify(klass, type, resolverName, changes) {
@ -2687,6 +2689,26 @@ class PluginApi {
.lookup("service:admin-custom-user-fields")
.addProperty(userFieldProperty);
}
/**
* Adds a custom button to the composer preview's image wrapper
*
*
* ```
* api.addComposerImageWrapperButton(
* "My Custom Button",
* "custom-button-class"
* "lock"
* (event) => { console.log("Custom button clicked", event)
* });
*
* ```
*
*/
addComposerImageWrapperButton(label, btnClass, icon, fn) {
addImageWrapperButton(label, btnClass, icon);
addApiImageWrapperButtonClickEvent(fn);
}
}
// from http://stackoverflow.com/questions/6832596/how-to-compare-software-version-number-using-js-only-number

View File

@ -1,5 +1,6 @@
import { click, fillIn, triggerKeyEvent, visit } from "@ember/test-helpers";
import { test } from "qunit";
import { withPluginApi } from "discourse/lib/plugin-api";
import {
acceptance,
count,
@ -376,3 +377,53 @@ acceptance("Composer - Image Preview", function (needs) {
);
});
});
acceptance("Composer - Image Preview - Plugin API", function (needs) {
needs.user({});
needs.settings({ allow_uncategorized_topics: true });
needs.site({ can_tag_topics: true });
needs.pretender((server, helper) => {
server.post("/uploads/lookup-urls", () => {
return helper.response([]);
});
});
needs.hooks.beforeEach(() => {
withPluginApi("1.25.0", (api) => {
api.addComposerImageWrapperButton(
"My Custom Button",
"custom-button-class",
"lock",
(event) => {
if (event.target.classList.contains("custom-button-class")) {
document.querySelector(".d-editor-input").value =
"custom button change";
}
}
);
});
});
test("image wrapper includes extra API button and is functional", async function (assert) {
await visit("/");
await click("#create-topic");
await fillIn(
".d-editor-input",
"![image_example_0|666x500](upload://q4iRxcuSAzfnbUaCsbjMXcGrpaK.jpeg)"
);
assert.ok(
exists(".image-wrapper .custom-button-class"),
"The custom button is added to the image preview wrapper"
);
await click(".custom-button-class");
assert.strictEqual(
query(".d-editor-input").value,
"custom button change",
"The custom button changes the editor input"
);
});
});

View File

@ -7,6 +7,10 @@ in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.25.0] - 2024-02-05
- Added `addComposerImageWrapperButton` which is used to add a custom button to the composer preview's image wrapper that appears on hover of an uploaded image.
## [1.24.0] - 2024-01-08
- Added `addAdminSidebarSectionLink` which is used to add a link to a specific admin sidebar section, as a replacement for the `admin-menu` plugin outlet. This only has an effect if the `admin_sidebar_enabled_groups` site setting is in use, which enables the new admin nav sidebar.