diff --git a/assets/javascripts/wizard-custom.js b/assets/javascripts/wizard-custom.js
index 9214df5a..61507fd9 100644
--- a/assets/javascripts/wizard-custom.js
+++ b/assets/javascripts/wizard-custom.js
@@ -4,7 +4,6 @@
//= require discourse/app/mixins/singleton
//= require discourse/app/mixins/upload
-//= require discourse/app/mixins/composer-upload
//= require discourse/app/mixins/textarea-text-manipulation
//= require discourse/app/adapters/rest
diff --git a/assets/javascripts/wizard/components/wizard-composer-editor.js.es6 b/assets/javascripts/wizard/components/wizard-composer-editor.js.es6
index b60f7551..1356f6ac 100644
--- a/assets/javascripts/wizard/components/wizard-composer-editor.js.es6
+++ b/assets/javascripts/wizard/components/wizard-composer-editor.js.es6
@@ -4,24 +4,14 @@ import {
on,
} from "discourse-common/utils/decorators";
import { findRawTemplate } from "discourse-common/lib/raw-templates";
-import { next, scheduleOnce, throttle } from "@ember/runloop";
+import { scheduleOnce, throttle } from "@ember/runloop";
import { caretPosition, inCodeBlock } from "discourse/lib/utilities";
import highlightSyntax from "discourse/lib/highlight-syntax";
-import { getToken } from "wizard/lib/ajax";
-import {
- displayErrorForUpload,
- getUploadMarkdown,
- uploadIcon,
- validateUploadedFiles,
-} from "discourse/lib/uploads";
-import { cacheShortUploadUrl } from "pretty-text/upload-short-url";
import { alias } from "@ember/object/computed";
-import WizardI18n from "../lib/wizard-i18n";
import Site from "../models/site";
+import { uploadIcon } from "discourse/lib/uploads";
+import { dasherize } from "@ember/string";
-const uploadMarkdownResolvers = [];
-
-const uploadHandlers = [];
export default ComposerEditor.extend({
classNameBindings: ["fieldClass"],
allowUpload: true,
@@ -35,6 +25,7 @@ export default ComposerEditor.extend({
popupMenuOptions: [],
draftStatus: "null",
replyPlaceholder: alias("field.placeholder"),
+ uploadingFieldId: null,
@on("didInsertElement")
_composerEditorInit() {
@@ -90,6 +81,50 @@ export default ComposerEditor.extend({
}
this._bindUploadTarget();
+
+ const wizardEventNames = ["insert-text", "replace-text"];
+ const eventPrefix = this.eventPrefix;
+ const session = this.get("session");
+ this.appEvents.reopen({
+ trigger(name, ...args) {
+ let eventParts = name.split(":");
+ let currentEventPrefix = eventParts[0];
+ let currentEventName = eventParts[1];
+
+ if (
+ currentEventPrefix !== "wizard-editor" &&
+ wizardEventNames.some((wen) => wen === currentEventName)
+ ) {
+ let wizardName = name.replace(eventPrefix, "wizard-editor");
+ if (currentEventName === "insert-text") {
+ args = {
+ text: args[0],
+ };
+ }
+ if (currentEventName === "replace-text") {
+ args = {
+ oldVal: args[0],
+ newVal: args[1],
+ };
+ }
+ let wizardArgs = Object.assign(
+ {},
+ {
+ fieldId: session.get("uploadingFieldId"),
+ },
+ args
+ );
+ return this._super(wizardName, wizardArgs);
+ } else {
+ return this._super(name, ...args);
+ }
+ },
+ });
+ },
+
+ @discourseComputed("field.id")
+ fileUploadElementId(fieldId) {
+ return `file-uploader-${dasherize(fieldId)}`;
},
@discourseComputed
@@ -105,192 +140,6 @@ export default ComposerEditor.extend({
return uploadIcon(false, this.siteSettings);
},
- _setUploadPlaceholderSend() {
- if (!this.composer.get("reply")) {
- this.composer.set("reply", "");
- }
- this._super(...arguments);
- },
-
- _bindUploadTarget() {
- this._super(...arguments);
- const $element = $(this.element);
- // adding dropZone property post initialization
- $element.fileupload("option", "dropZone", $element);
-
- $element.off("fileuploadsubmit");
-
- $element.on("fileuploadsubmit", (e, data) => {
- const max = this.siteSettings.simultaneous_uploads;
-
- // Limit the number of simultaneous uploads
- if (max > 0 && data.files.length > max) {
- bootbox.alert(
- WizardI18n("post.errors.too_many_dragged_and_dropped_files", { max })
- );
- return false;
- }
-
- // Look for a matching file upload handler contributed from a plugin
- const matcher = (handler) => {
- const ext = handler.extensions.join("|");
- const regex = new RegExp(`\\.(${ext})$`, "i");
- return regex.test(data.files[0].name);
- };
-
- const matchingHandler = uploadHandlers.find(matcher);
- if (data.files.length === 1 && matchingHandler) {
- if (!matchingHandler.method(data.files[0], this)) {
- return false;
- }
- }
-
- // If no plugin, continue as normal
- const isPrivateMessage = this.get("composer.privateMessage");
-
- data.formData = { type: "composer" };
- data.formData.authenticity_token = getToken();
- if (isPrivateMessage) {
- data.formData.for_private_message = true;
- }
- if (this._pasted) {
- data.formData.pasted = true;
- }
-
- const opts = {
- user: this.currentUser,
- siteSettings: this.siteSettings,
- isPrivateMessage,
- allowStaffToUploadAnyFileInPm: this.siteSettings
- .allow_staff_to_upload_any_file_in_pm,
- };
-
- const isUploading = validateUploadedFiles(data.files, opts);
-
- this.setProperties({ uploadProgress: 0, isUploading });
-
- return isUploading;
- });
-
- $element.on("fileuploadprogressall", (e, data) => {
- this.set(
- "uploadProgress",
- parseInt((data.loaded / data.total) * 100, 10)
- );
- });
-
- $element.on("fileuploadfail", (e, data) => {
- this._setUploadPlaceholderDone(data);
- this._resetUpload(true);
-
- const userCancelled = this._xhr && this._xhr._userCancelled;
- this._xhr = null;
-
- if (!userCancelled) {
- displayErrorForUpload(data, this.siteSettings);
- }
- });
-
- $element.on("fileuploadsend", (e, data) => {
- this._pasted = false;
- this._validUploads++;
-
- this._setUploadPlaceholderSend(data);
-
- this.appEvents.trigger("wizard-editor:insert-text", {
- fieldId: this.field.id,
- text: this.uploadPlaceholder,
- });
-
- if (data.xhr && data.originalFiles.length === 1) {
- this.set("isCancellable", true);
- this._xhr = data.xhr();
- }
- });
-
- $element.on("fileuploaddone", (e, data) => {
- let upload = data.result;
-
- this._setUploadPlaceholderDone(data);
-
- if (!this._xhr || !this._xhr._userCancelled) {
- const markdown = uploadMarkdownResolvers.reduce(
- (md, resolver) => resolver(upload) || md,
- getUploadMarkdown(upload)
- );
-
- cacheShortUploadUrl(upload.short_url, upload);
- this.appEvents.trigger("wizard-editor:replace-text", {
- fieldId: this.field.id,
- oldVal: this.uploadPlaceholder.trim(),
- newVal: markdown,
- });
- this._resetUpload(false);
- } else {
- this._resetUpload(true);
- }
- });
- },
-
- _resetUpload(removePlaceholder) {
- next(() => {
- if (this._validUploads > 0) {
- this._validUploads--;
- }
- if (this._validUploads === 0) {
- this.setProperties({
- uploadProgress: 0,
- isUploading: false,
- isCancellable: false,
- });
- }
- if (removePlaceholder) {
- this.appEvents.trigger("wizard-editor:replace-text", {
- fieldId: this.field.id,
- oldVal: this.uploadPlaceholder,
- newVal: "",
- });
- }
- this._resetUploadFilenamePlaceholder();
- });
- },
-
- _registerImageScaleButtonClick($preview) {
- const imageScaleRegex = /!\[(.*?)\|(\d{1,4}x\d{1,4})(,\s*\d{1,3}%)?(.*?)\]\((upload:\/\/.*?)\)(?!(.*`))/g;
- $preview.off("click", ".scale-btn").on("click", ".scale-btn", (e) => {
- const index = parseInt($(e.target).parent().attr("data-image-index"), 10);
-
- const scale = e.target.attributes["data-scale"].value;
- const matchingPlaceholder = this.get("composer.reply").match(
- imageScaleRegex
- );
-
- if (matchingPlaceholder) {
- const match = matchingPlaceholder[index];
-
- if (match) {
- const replacement = match.replace(
- imageScaleRegex,
- `![$1|$2, ${scale}%$4]($5)`
- );
-
- this.appEvents.trigger("wizard-editor:replace-text", {
- fieldId: this.field.id,
- oldVal: matchingPlaceholder[index],
- newVal: replacement,
- options: {
- regex: imageScaleRegex,
- index,
- },
- });
- }
- }
-
- e.preventDefault();
- return;
- });
- },
-
click(e) {
if ($(e.target).hasClass("wizard-composer-hyperlink")) {
this.set("showHyperlinkBox", false);
@@ -372,7 +221,8 @@ export default ComposerEditor.extend({
},
showUploadModal() {
- $(this.element.querySelector(".wizard-composer-upload")).trigger("click");
+ this.session.set("uploadingFieldId", this.field.id);
+ document.getElementById(this.fileUploadElementId).click();
},
},
});
diff --git a/assets/javascripts/wizard/components/wizard-field-composer.js.es6 b/assets/javascripts/wizard/components/wizard-field-composer.js.es6
index 3a4a706c..8b9ecb82 100644
--- a/assets/javascripts/wizard/components/wizard-field-composer.js.es6
+++ b/assets/javascripts/wizard/components/wizard-field-composer.js.es6
@@ -16,7 +16,7 @@ export default Ember.Component.extend({
"composer",
EmberObject.create({
loading: false,
- reply: this.get("field.value"),
+ reply: this.get("field.value") || "",
})
);
},
diff --git a/assets/javascripts/wizard/initializers/custom-wizard.js.es6 b/assets/javascripts/wizard/initializers/custom-wizard.js.es6
index c7c2b8d3..f2095827 100644
--- a/assets/javascripts/wizard/initializers/custom-wizard.js.es6
+++ b/assets/javascripts/wizard/initializers/custom-wizard.js.es6
@@ -111,8 +111,16 @@ export default {
model() {},
});
- $.ajaxPrefilter(function (_, __, jqXHR) {
- jqXHR.setRequestHeader("X-CSRF-Token", getToken());
+ // Add a CSRF token to all AJAX requests
+ let token = getToken();
+ session.set("csrfToken", token);
+ let callbacks = $.Callbacks();
+ $.ajaxPrefilter(callbacks.fire);
+
+ callbacks.add(function (options, originalOptions, xhr) {
+ if (!options.crossDomain) {
+ xhr.setRequestHeader("X-CSRF-Token", session.get("csrfToken"));
+ }
});
},
};
diff --git a/assets/javascripts/wizard/templates/components/wizard-composer-editor.hbs b/assets/javascripts/wizard/templates/components/wizard-composer-editor.hbs
index c4bf1c74..be98db8e 100644
--- a/assets/javascripts/wizard/templates/components/wizard-composer-editor.hbs
+++ b/assets/javascripts/wizard/templates/components/wizard-composer-editor.hbs
@@ -16,24 +16,10 @@
disabled=disableTextarea
outletArgs=(hash composer=composer editorType="composer")}}
-{{input
- class="wizard-composer-upload hidden-upload-field"
- disabled=isUploading
+
- {{loading-spinner size="small"}}{{wizard-i18n "upload_selector.uploading"}} {{uploadProgress}}%
- {{#if isCancellable}}
- {{d-icon "times"}}
- {{/if}}
-
-{{/if}}
+ id={{fileUploadElementId}}
+ class="wizard-composer-upload"
+ accept={{allowedFileTypes}}
+ multiple
+ >
diff --git a/plugin.rb b/plugin.rb
index 752b6b92..6f68ae3b 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# name: discourse-custom-wizard
# about: Create custom wizards
-# version: 1.15.4
+# version: 1.15.5
# authors: Angus McLeod
# url: https://github.com/paviliondev/discourse-custom-wizard
# contact emails: angus@thepavilion.io