Comprehensive file upload system for @editorjs/image supporting multiple input methods including device file selection, URL pasting, drag-and-drop, and clipboard paste operations.
Core upload system handling multiple upload methods with both default HTTP-based uploads and custom upload handlers.
class Uploader {
/**
* Create uploader instance with configuration and callbacks
* @param params - Uploader configuration parameters
* @param params.config - Image tool configuration including endpoints and upload settings
* @param params.onUpload - Callback fired when upload completes successfully with response data
* @param params.onError - Callback fired when upload fails with error message
*/
constructor(params: UploaderParams);
/**
* Handle user file selection and upload with preview generation
* Opens file dialog, generates preview, and uploads selected file
* @param options - Upload options
* @param options.onPreview - Callback to display preview while uploading
*/
uploadSelectedFile(options: UploadOptions): void;
/**
* Upload image by URL using configured endpoint or custom handler
* @param url - Image URL to upload/process
*/
uploadByUrl(url: string): void;
/**
* Upload file from drag-and-drop or paste operations
* @param file - File blob from drop/paste event
* @param options - Upload options
* @param options.onPreview - Callback to display preview while uploading
*/
uploadByFile(file: Blob, options: UploadOptions): void;
}
interface UploaderParams {
/** Image tool configuration including endpoints, field names, and custom upload handlers */
config: ImageConfig;
/** Callback fired when upload completes successfully with server response */
onUpload: (response: UploadResponseFormat) => void;
/** Callback fired when upload fails with error message */
onError: (error: string) => void;
}
interface UploadOptions {
/** Callback fired when preview is ready, receives preview URL or data URL */
onPreview: (src: string) => void;
}Handle user-initiated file selection from device with preview generation and progress feedback.
/**
* Handle clicks on the upload file button and file selection
* Supports both custom and default uploading methods
* @param options - Upload options including preview callback
*/
uploadSelectedFile(options: UploadOptions): void;
interface UploadOptions {
onPreview: (src: string) => void;
}Usage Examples:
// Default endpoint-based upload
const uploader = new Uploader({
config: {
endpoints: {
byFile: '/api/upload'
},
field: 'image',
types: 'image/*',
additionalRequestData: { userId: 123 },
additionalRequestHeaders: { 'X-API-Key': 'key' }
},
onUpload: (response) => {
if (response.success) {
console.log('Upload successful:', response.file.url);
}
},
onError: (error) => {
console.error('Upload failed:', error);
}
});
// Trigger file selection with preview
uploader.uploadSelectedFile({
onPreview: (src) => {
// Show preview while uploading
document.getElementById('preview').src = src;
}
});Upload images by providing a URL, with support for both default HTTP endpoints and custom URL processing.
/**
* Upload image by URL
* Supports both custom and default uploading methods
* @param url - Image URL to upload/process
*/
uploadByUrl(url: string): void;Usage Examples:
// Upload from URL using default endpoint
uploader.uploadByUrl('https://example.com/image.jpg');
// Custom URL upload handler
const customUploader = new Uploader({
config: {
uploader: {
uploadByUrl: async (url) => {
// Custom URL processing
const response = await fetch('/api/process-url', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
imageUrl: url,
processOptions: { resize: true, optimize: true }
})
});
const result = await response.json();
return {
success: result.success ? 1 : 0,
file: {
url: result.processedImageUrl,
originalUrl: url,
dimensions: result.dimensions,
fileSize: result.fileSize
}
};
}
}
},
onUpload: (response) => { /* ... */ },
onError: (error) => { /* ... */ }
});Handle file uploads from drag-and-drop operations and clipboard paste events with preview generation.
/**
* Upload file from drag-and-drop or paste operations
* Generates preview and handles both custom and default upload methods
* @param file - File blob from drop/paste event
* @param options - Upload options including preview callback
*/
uploadByFile(file: Blob, options: UploadOptions): void;Usage Examples:
// Handle drag-and-drop
document.addEventListener('drop', (event) => {
event.preventDefault();
const files = event.dataTransfer.files;
if (files.length > 0) {
uploader.uploadByFile(files[0], {
onPreview: (src) => {
showPreview(src);
}
});
}
});
// Handle clipboard paste
document.addEventListener('paste', (event) => {
const items = event.clipboardData.items;
for (let item of items) {
if (item.type.startsWith('image/')) {
const file = item.getAsFile();
uploader.uploadByFile(file, {
onPreview: (src) => {
showPreview(src);
}
});
break;
}
}
});Comprehensive paste event handling system supporting HTML tags, URL patterns, and file drops with automatic content detection.
/**
* Handle paste events from Editor.js
* Automatically detects and processes different paste types
* @param event - Editor.js paste event
*/
async onPaste(event: PasteEvent): Promise<void>;
interface PasteEvent {
type: 'tag' | 'pattern' | 'file';
detail: HTMLPasteEventDetailExtended | PatternPasteEventDetail | FilePasteEventDetail;
}
static get pasteConfig(): PasteConfig {
return {
tags: [{ img: { src: true } }],
patterns: {
image: /https?:\/\/\S+\.(gif|jpe?g|tiff|png|svg|webp)(\?[a-z0-9=]*)?$/i
},
files: {
mimeTypes: ['image/*']
}
};
}Usage Examples:
// Paste configuration automatically handles:
// 1. HTML img tags
// <img src="https://example.com/image.jpg" alt="Sample">
// 2. Direct image URLs
// https://example.com/photo.png
// 3. File drops from file manager
// Drag files directly from file system
// 4. Clipboard image data
// Screenshots, copied images
// Manual paste handling
class ImageTool {
async onPaste(event: PasteEvent): Promise<void> {
switch (event.type) {
case 'tag':
const imageData = event.detail as HTMLPasteEventDetailExtended;
// Handle blob URLs (e.g., from PDF)
if (/^blob:/.test(imageData.data.src)) {
const response = await fetch(imageData.data.src);
const file = await response.blob();
this.uploadFile(file);
} else {
this.uploadUrl(imageData.data.src);
}
break;
case 'pattern':
const patternData = event.detail as PatternPasteEventDetail;
this.uploadUrl(patternData.data);
break;
case 'file':
const fileData = event.detail as FilePasteEventDetail;
this.uploadFile(fileData.file);
break;
}
}
}Standardized response format expected from upload endpoints with support for additional file metadata.
interface UploadResponseFormat<AdditionalFileData = {}> {
success: number;
file: {
url: string;
} & AdditionalFileData;
}
// Extended response examples
interface ExtendedFileData {
name?: string;
size?: number;
dimensions?: {
width: number;
height: number;
};
thumbnails?: {
small: string;
medium: string;
large: string;
};
metadata?: {
format: string;
colorSpace: string;
hasAlpha: boolean;
};
}Usage Examples:
// Basic response
{
"success": 1,
"file": {
"url": "https://cdn.example.com/uploads/image123.jpg"
}
}
// Extended response with metadata
{
"success": 1,
"file": {
"url": "https://cdn.example.com/uploads/image123.jpg",
"name": "vacation-photo.jpg",
"size": 1024768,
"dimensions": {
"width": 1920,
"height": 1080
},
"thumbnails": {
"small": "https://cdn.example.com/thumbs/small/image123.jpg",
"medium": "https://cdn.example.com/thumbs/medium/image123.jpg",
"large": "https://cdn.example.com/thumbs/large/image123.jpg"
},
"metadata": {
"format": "JPEG",
"colorSpace": "RGB",
"hasAlpha": false
}
}
}
// Error response
{
"success": 0,
"message": "File too large. Maximum size is 10MB."
}Comprehensive error handling system for upload failures with user notification integration.
/**
* Handle upload errors with user notification
* @param errorText - Error message or description
*/
private uploadingFailed(errorText: string): void;Usage Examples:
// Error handling in custom upload
const customUploader = {
uploadByFile: async (file) => {
try {
// Validate file size
if (file.size > 10 * 1024 * 1024) {
throw new Error('File too large. Maximum size is 10MB.');
}
// Validate file type
if (!file.type.startsWith('image/')) {
throw new Error('Only image files are allowed.');
}
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/upload', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const result = await response.json();
if (!result.success) {
throw new Error(result.message || 'Upload failed');
}
return result;
} catch (error) {
// Error will be handled by the tool's error system
throw error;
}
}
};