Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-27 03:20:27 +01:00
178 Zeilen
4,9 KiB
Text
178 Zeilen
4,9 KiB
Text
|
import { dasherize } from "@ember/string";
|
||
|
|
||
|
export default {
|
||
|
name: "custom-wizard-field",
|
||
|
initialize(app) {
|
||
|
if (window.location.pathname.indexOf("/w/") < 0) return;
|
||
|
|
||
|
const FieldComponent = requirejs("wizard/components/wizard-field").default;
|
||
|
const FieldModel = requirejs("wizard/models/wizard-field").default;
|
||
|
const { cook } = requirejs("discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite");
|
||
|
const DEditor = requirejs("discourse/components/d-editor").default;
|
||
|
const { clipboardHelpers } = requirejs("discourse/lib/utilities");
|
||
|
const { toMarkdown } = requirejs("discourse/lib/to-markdown");
|
||
|
|
||
|
FieldComponent.reopen({
|
||
|
classNameBindings: ["field.id"],
|
||
|
|
||
|
cookedDescription: function () {
|
||
|
return cook(this.get("field.description"));
|
||
|
}.property("field.description"),
|
||
|
|
||
|
inputComponentName: function () {
|
||
|
const type = this.get("field.type");
|
||
|
const id = this.get("field.id");
|
||
|
if (["text_only"].includes(type)) return false;
|
||
|
return dasherize(type === "component" ? id : `wizard-field-${type}`);
|
||
|
}.property("field.type", "field.id"),
|
||
|
});
|
||
|
|
||
|
const StandardFieldValidation = [
|
||
|
"text",
|
||
|
"number",
|
||
|
"textarea",
|
||
|
"dropdown",
|
||
|
"tag",
|
||
|
"image",
|
||
|
"user_selector",
|
||
|
"text_only",
|
||
|
"composer",
|
||
|
"category",
|
||
|
"group",
|
||
|
"date",
|
||
|
"time",
|
||
|
"date_time",
|
||
|
];
|
||
|
|
||
|
FieldModel.reopen({
|
||
|
check() {
|
||
|
if (this.customCheck) {
|
||
|
return this.customCheck();
|
||
|
}
|
||
|
|
||
|
let valid = this.valid;
|
||
|
|
||
|
if (!this.required) {
|
||
|
this.setValid(true);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
const val = this.get("value");
|
||
|
const type = this.get("type");
|
||
|
|
||
|
if (type === "checkbox") {
|
||
|
valid = val;
|
||
|
} else if (type === "upload") {
|
||
|
valid = val && val.id > 0;
|
||
|
} else if (StandardFieldValidation.indexOf(type) > -1) {
|
||
|
valid = val && val.toString().length > 0;
|
||
|
} else if (type === "url") {
|
||
|
valid = true;
|
||
|
}
|
||
|
|
||
|
this.setValid(valid);
|
||
|
|
||
|
return valid;
|
||
|
},
|
||
|
});
|
||
|
|
||
|
const isInside = (text, regex) => {
|
||
|
const matches = text.match(regex);
|
||
|
return matches && matches.length % 2;
|
||
|
};
|
||
|
|
||
|
DEditor.reopen({
|
||
|
isComposer: true,
|
||
|
|
||
|
didInsertElement() {
|
||
|
this._super();
|
||
|
if (this.wizardComposerEvents) {
|
||
|
this.appEvents.on("wizard-editor:insert-text", this, "_wizardInsertText");
|
||
|
this.appEvents.on("wizard-editor:replace-text", this, "_wizardReplaceText");
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_wizardInsertText(args = {}) {
|
||
|
if (args.fieldId === this.fieldId) {
|
||
|
this._insertText(args.text, args.options);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_wizardReplaceText(args = {}) {
|
||
|
if (args.fieldId === this.fieldId) {
|
||
|
this._replaceText(args.oldVal, args.newVal, args.opts = {});
|
||
|
}
|
||
|
},
|
||
|
|
||
|
paste(e) {
|
||
|
if (!$(".d-editor-input").is(":focus")) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const isComposer = this.isComposer;
|
||
|
let { clipboard, canPasteHtml, canUpload } = clipboardHelpers(e, {
|
||
|
siteSettings: this.siteSettings,
|
||
|
canUpload: isComposer,
|
||
|
});
|
||
|
|
||
|
let plainText = clipboard.getData("text/plain");
|
||
|
let html = clipboard.getData("text/html");
|
||
|
let handled = false;
|
||
|
|
||
|
const { pre, lineVal } = this._getSelected(null, { lineVal: true });
|
||
|
const isInlinePasting = pre.match(/[^\n]$/);
|
||
|
const isCodeBlock = isInside(pre, /(^|\n)```/g);
|
||
|
|
||
|
if (
|
||
|
plainText &&
|
||
|
this.siteSettings.enable_rich_text_paste &&
|
||
|
!isInlinePasting &&
|
||
|
!isCodeBlock
|
||
|
) {
|
||
|
plainText = plainText.trim().replace(/\r/g, "");
|
||
|
const table = this._extractTable(plainText);
|
||
|
if (table) {
|
||
|
this.appEvents.trigger("wizard-editor:insert-text", {
|
||
|
fieldId: this.fieldId,
|
||
|
text: table
|
||
|
});
|
||
|
handled = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (canPasteHtml && plainText) {
|
||
|
if (isInlinePasting) {
|
||
|
canPasteHtml = !(
|
||
|
lineVal.match(/^```/) ||
|
||
|
isInside(pre, /`/g) ||
|
||
|
lineVal.match(/^ /)
|
||
|
);
|
||
|
} else {
|
||
|
canPasteHtml = !isCodeBlock;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (canPasteHtml && !handled) {
|
||
|
let markdown = toMarkdown(html);
|
||
|
|
||
|
if (!plainText || plainText.length < markdown.length) {
|
||
|
if (isInlinePasting) {
|
||
|
markdown = markdown.replace(/^#+/, "").trim();
|
||
|
markdown = pre.match(/\S$/) ? ` ${markdown}` : markdown;
|
||
|
}
|
||
|
|
||
|
this.appEvents.trigger("composer:insert-text", {
|
||
|
fieldId: this.fieldId,
|
||
|
text: markdown
|
||
|
});
|
||
|
handled = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (handled || (canUpload && !plainText)) {
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
},
|
||
|
});
|
||
|
}
|
||
|
}
|