Skip to content

Commit f6d982a

Browse files
authored
Merge pull request nubasedev#315 from ustacryptact/master
Fix new customized paste options
2 parents 57eba72 + 07a4156 commit f6d982a

File tree

4 files changed

+63
-9
lines changed

4 files changed

+63
-9
lines changed

src/commands/command-orchestrator.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export class CommandOrchestrator {
143143
return this.executeCommand(
144144
this.pasteOptions.command || getDefaultSaveImageCommandName(),
145145
{
146-
saveImage: this.pasteOptions.saveImage,
146+
pasteOptions: this.pasteOptions,
147147
event: event
148148
} as PasteCommandContext
149149
);
@@ -158,7 +158,7 @@ export class CommandOrchestrator {
158158
return this.executeCommand(
159159
this.pasteOptions.command || getDefaultSaveImageCommandName(),
160160
{
161-
saveImage: this.pasteOptions.saveImage,
161+
pasteOptions: this.pasteOptions,
162162
event: event
163163
} as PasteCommandContext
164164
);
@@ -173,7 +173,7 @@ export class CommandOrchestrator {
173173
return this.executeCommand(
174174
this.pasteOptions.command || getDefaultSaveImageCommandName(),
175175
{
176-
saveImage: this.pasteOptions.saveImage,
176+
pasteOptions: this.pasteOptions,
177177
event: event
178178
} as PasteCommandContext
179179
);

src/commands/command.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export interface CommandContext {
3131
export interface PasteCommandContext extends CommandContext {
3232
type: "paste";
3333
event: React.ClipboardEvent | React.DragEvent | React.ChangeEvent;
34-
saveImage: SaveImageHandler;
34+
pasteOptions: PasteOptions;
3535
}
3636

3737
export type ToolbarCommands = string[][];

src/commands/default-commands/save-image-command.tsx

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import {
22
Command,
33
CommandContext,
44
ExecuteOptions,
5-
PasteCommandContext
5+
PasteCommandContext,
6+
PasteOptions
67
} from "../command";
78
import { readFileAsync } from "../../util/files";
89
import { getBreaksNeededForEmptyLineBefore } from "../../util/MarkdownUtil";
@@ -26,6 +27,42 @@ function fileListToArray(list: FileList): Array<File> {
2627
return result;
2728
}
2829

30+
function filterItems(
31+
items: File[],
32+
{ multiple, accept }: Pick<PasteOptions, "multiple" | "accept">
33+
): File[] {
34+
let filteredItems = items;
35+
36+
if (!multiple) {
37+
filteredItems = filteredItems.slice(0, 1);
38+
}
39+
40+
if (accept) {
41+
//https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers
42+
const acceptedTypes = accept.split(",");
43+
const fileExtensions = new Set(
44+
acceptedTypes.filter(t => /^\.\w+/.test(t)).map(t => t.split(".")[1])
45+
);
46+
const mimeTypes = new Set(
47+
acceptedTypes.filter(t => /^[-\w.]+\/[-\w.]+$/.test(t))
48+
);
49+
const anyTypes = new Set(
50+
acceptedTypes
51+
.filter(t => /(audio|video|image)\/\*/.test(t))
52+
.map(t => t.split("/")[0])
53+
);
54+
55+
filteredItems = filteredItems.filter(
56+
f =>
57+
fileExtensions.has(f.name.split(".")[1]) ||
58+
mimeTypes.has(f.type) ||
59+
anyTypes.has(f.type.split("/")[0])
60+
);
61+
}
62+
63+
return filteredItems;
64+
}
65+
2966
export const saveImageCommand: Command = {
3067
async execute({
3168
initialState,
@@ -37,7 +74,10 @@ export const saveImageCommand: Command = {
3774
throw new Error("wrong context");
3875
}
3976
const pasteContext = context as PasteCommandContext;
40-
const { event, saveImage } = pasteContext;
77+
const {
78+
event,
79+
pasteOptions: { saveImage, multiple, accept }
80+
} = pasteContext;
4181

4282
const items = isPasteEvent(context)
4383
? dataTransferToArray((event as React.ClipboardEvent).clipboardData.items)
@@ -47,7 +87,9 @@ export const saveImageCommand: Command = {
4787
(event as React.ChangeEvent<HTMLInputElement>).target.files
4888
);
4989

50-
for (const index in items) {
90+
const filteredItems = filterItems(items, { multiple, accept });
91+
92+
for (const index in filteredItems) {
5193
const initialState = textApi.getState();
5294
const breaksBeforeCount = getBreaksNeededForEmptyLineBefore(
5395
initialState.text,

src/components/ReactMde.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ export interface ReactMdeState {
7373
editorHeight: number;
7474
}
7575

76+
const pasteOptionDefaults: Required<Omit<
77+
PasteOptions,
78+
"saveImage" | "command"
79+
>> = {
80+
accept: "image/*",
81+
multiple: false
82+
};
83+
7684
export class ReactMde extends React.Component<ReactMdeProps, ReactMdeState> {
7785
/**
7886
* "finalRefs" is a clone of "props.refs" except that undefined refs are set to default values
@@ -110,6 +118,8 @@ export class ReactMde extends React.Component<ReactMdeProps, ReactMdeState> {
110118
this.finalRefs.textarea,
111119
this.props.l18n,
112120
this.props.paste
121+
? { ...pasteOptionDefaults, ...this.props.paste }
122+
: undefined
113123
);
114124
const minEditorHeight = Math.min(
115125
props.maxEditorHeight,
@@ -243,8 +253,10 @@ export class ReactMde extends React.Component<ReactMdeProps, ReactMdeState> {
243253
<input
244254
className={classNames("image-input")}
245255
type="file"
246-
accept={this.props.paste.accept || "image/*"}
247-
multiple={this.props.paste.multiple || true}
256+
accept={this.props.paste.accept ?? pasteOptionDefaults.accept}
257+
multiple={
258+
this.props.paste.multiple ?? pasteOptionDefaults.multiple
259+
}
248260
onChange={this.handleImageSelection}
249261
/>
250262
<span>{l18n.pasteDropSelect}</span>

0 commit comments

Comments
 (0)