DEV: API extra markup to image wrapper (#25575)
This commit is contained in:
parent
53a198ad55
commit
10b33bc601
|
@ -2,6 +2,30 @@ import I18n from "discourse-i18n";
|
||||||
|
|
||||||
const SCALES = ["100", "75", "50"];
|
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) {
|
function isUpload(token) {
|
||||||
return token.content.includes("upload://");
|
return token.content.includes("upload://");
|
||||||
}
|
}
|
||||||
|
@ -157,6 +181,8 @@ function ruleWithImageControls(oldRule) {
|
||||||
result += `</span>`;
|
result += `</span>`;
|
||||||
result += buildImageDeleteButton();
|
result += buildImageDeleteButton();
|
||||||
|
|
||||||
|
result += apiExtraButton.join("");
|
||||||
|
|
||||||
result += "</span></span>";
|
result += "</span></span>";
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -205,6 +231,8 @@ export function setup(helper) {
|
||||||
"span.wrap-image-grid-button[data-image-count]",
|
"span.wrap-image-grid-button[data-image-count]",
|
||||||
"svg[class=fa d-icon d-icon-th svg-icon svg-string]",
|
"svg[class=fa d-icon d-icon-th svg-icon svg-string]",
|
||||||
"use[href=#th]",
|
"use[href=#th]",
|
||||||
|
|
||||||
|
...apiExtraButtonAllowList,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
helper.registerPlugin((md) => {
|
helper.registerPlugin((md) => {
|
||||||
|
|
|
@ -101,6 +101,12 @@ export function addComposerUploadMarkdownResolver(resolver) {
|
||||||
export function cleanUpComposerUploadMarkdownResolver() {
|
export function cleanUpComposerUploadMarkdownResolver() {
|
||||||
uploadMarkdownResolvers = [];
|
uploadMarkdownResolvers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let apiImageWrapperBtnEvents = [];
|
||||||
|
export function addApiImageWrapperButtonClickEvent(fn) {
|
||||||
|
apiImageWrapperBtnEvents.push(fn);
|
||||||
|
}
|
||||||
|
|
||||||
export default Component.extend(ComposerUploadUppy, {
|
export default Component.extend(ComposerUploadUppy, {
|
||||||
classNameBindings: ["showToolbar:toolbar-visible", ":wmd-controls"],
|
classNameBindings: ["showToolbar:toolbar-visible", ":wmd-controls"],
|
||||||
|
|
||||||
|
@ -773,6 +779,12 @@ export default Component.extend(ComposerUploadUppy, {
|
||||||
preview.addEventListener("click", this._handleImageDeleteButtonClick);
|
preview.addEventListener("click", this._handleImageDeleteButtonClick);
|
||||||
preview.addEventListener("keypress", this._handleAltTextInputKeypress);
|
preview.addEventListener("keypress", this._handleAltTextInputKeypress);
|
||||||
preview.addEventListener("click", this._handleImageGridButtonClick);
|
preview.addEventListener("click", this._handleImageGridButtonClick);
|
||||||
|
|
||||||
|
if (apiImageWrapperBtnEvents.length > 0) {
|
||||||
|
apiImageWrapperBtnEvents.forEach((fn) => {
|
||||||
|
preview.addEventListener("click", fn);
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@on("willDestroyElement")
|
@on("willDestroyElement")
|
||||||
|
@ -802,6 +814,12 @@ export default Component.extend(ComposerUploadUppy, {
|
||||||
preview?.removeEventListener("click", this._handleImageGridButtonClick);
|
preview?.removeEventListener("click", this._handleImageGridButtonClick);
|
||||||
preview?.removeEventListener("click", this._handleAltTextCancelButtonClick);
|
preview?.removeEventListener("click", this._handleAltTextCancelButtonClick);
|
||||||
preview?.removeEventListener("keypress", this._handleAltTextInputKeypress);
|
preview?.removeEventListener("keypress", this._handleAltTextInputKeypress);
|
||||||
|
|
||||||
|
if (apiImageWrapperBtnEvents.length > 0) {
|
||||||
|
apiImageWrapperBtnEvents.forEach((fn) => {
|
||||||
|
preview?.removeEventListener("click", fn);
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onExpandPopupMenuOptions(toolbarEvent) {
|
onExpandPopupMenuOptions(toolbarEvent) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
import { h } from "virtual-dom";
|
import { h } from "virtual-dom";
|
||||||
import {
|
import {
|
||||||
|
addApiImageWrapperButtonClickEvent,
|
||||||
addComposerUploadHandler,
|
addComposerUploadHandler,
|
||||||
addComposerUploadMarkdownResolver,
|
addComposerUploadMarkdownResolver,
|
||||||
addComposerUploadPreProcessor,
|
addComposerUploadPreProcessor,
|
||||||
|
@ -132,6 +133,7 @@ import {
|
||||||
registerIconRenderer,
|
registerIconRenderer,
|
||||||
replaceIcon,
|
replaceIcon,
|
||||||
} from "discourse-common/lib/icon-library";
|
} 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 { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser";
|
||||||
import { modifySelectKit } from "select-kit/mixins/plugin-api";
|
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
|
// docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md whenever you change the version
|
||||||
// using the format described at https://keepachangelog.com/en/1.0.0/.
|
// 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.
|
// This helper prevents us from applying the same `modifyClass` over and over in test mode.
|
||||||
function canModify(klass, type, resolverName, changes) {
|
function canModify(klass, type, resolverName, changes) {
|
||||||
|
@ -2687,6 +2689,26 @@ class PluginApi {
|
||||||
.lookup("service:admin-custom-user-fields")
|
.lookup("service:admin-custom-user-fields")
|
||||||
.addProperty(userFieldProperty);
|
.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
|
// from http://stackoverflow.com/questions/6832596/how-to-compare-software-version-number-using-js-only-number
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { click, fillIn, triggerKeyEvent, visit } from "@ember/test-helpers";
|
import { click, fillIn, triggerKeyEvent, visit } from "@ember/test-helpers";
|
||||||
import { test } from "qunit";
|
import { test } from "qunit";
|
||||||
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||||
import {
|
import {
|
||||||
acceptance,
|
acceptance,
|
||||||
count,
|
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"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -7,6 +7,10 @@ in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
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).
|
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
|
## [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.
|
- 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.
|
||||||
|
|
Loading…
Reference in New Issue