or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

commands.mdconfiguration.mdcontent-operations.mdeditor-management.mdimage-upload.mdindex.mdmenus.mdselection.md

image-upload.mddocs/

0

# Image Upload

1

2

Image upload functionality with support for local uploads, network images, and various cloud storage services.

3

4

## Capabilities

5

6

### Upload Images

7

8

Upload image files to the editor.

9

10

```javascript { .api }

11

/**

12

* Upload image files to the editor

13

* @param files - FileList or Array of File objects to upload

14

*/

15

uploadImg(files: FileList | File[]): void;

16

```

17

18

**Usage Examples:**

19

20

```javascript

21

// Upload from file input

22

const fileInput = document.getElementById('imageInput');

23

fileInput.addEventListener('change', function(e) {

24

if (e.target.files.length > 0) {

25

editor.uploadImg.uploadImg(e.target.files);

26

}

27

});

28

29

// Upload programmatically

30

function uploadImages(files) {

31

editor.uploadImg.uploadImg(files);

32

}

33

34

// Drag and drop upload

35

const dropZone = document.getElementById('editor-container');

36

dropZone.addEventListener('drop', function(e) {

37

e.preventDefault();

38

const files = Array.from(e.dataTransfer.files).filter(file =>

39

file.type.startsWith('image/')

40

);

41

if (files.length > 0) {

42

editor.uploadImg.uploadImg(files);

43

}

44

});

45

```

46

47

## Upload Configuration

48

49

### Server Configuration

50

51

Configure server endpoint and upload parameters.

52

53

```javascript { .api }

54

interface ServerConfig {

55

/** Server endpoint for image upload */

56

uploadImgServer?: string;

57

58

/** Custom filename for uploads */

59

uploadFileName?: string;

60

61

/** Additional parameters for image upload */

62

uploadImgParams?: {[key: string]: any};

63

64

/** Custom headers for image upload requests */

65

uploadImgHeaders?: {[key: string]: string};

66

67

/** Send cookies with upload requests */

68

withCredentials?: boolean;

69

70

/** Upload timeout in milliseconds */

71

uploadImgTimeout?: number;

72

}

73

```

74

75

**Usage Examples:**

76

77

```javascript

78

// Basic server configuration

79

editor.customConfig.uploadImgServer = '/api/upload/image';

80

81

// Advanced server configuration

82

editor.customConfig.uploadImgServer = 'https://api.example.com/upload';

83

editor.customConfig.uploadFileName = 'custom_file_name';

84

editor.customConfig.uploadImgParams = {

85

token: 'user-auth-token',

86

folder: 'editor-uploads'

87

};

88

editor.customConfig.uploadImgHeaders = {

89

'Authorization': 'Bearer ' + authToken,

90

'X-Upload-Source': 'wangEditor'

91

};

92

editor.customConfig.withCredentials = true;

93

editor.customConfig.uploadImgTimeout = 30000; // 30 seconds

94

```

95

96

### Upload Limits

97

98

Configure upload size and quantity limits.

99

100

```javascript { .api }

101

interface UploadLimits {

102

/** Maximum image file size in bytes */

103

uploadImgMaxSize?: number;

104

105

/** Maximum number of images to upload at once */

106

uploadImgMaxLength?: number;

107

108

/** Show base64 format for uploaded images */

109

uploadImgShowBase64?: boolean;

110

}

111

```

112

113

**Usage Examples:**

114

115

```javascript

116

// Size and quantity limits

117

editor.customConfig.uploadImgMaxSize = 5 * 1024 * 1024; // 5MB limit

118

editor.customConfig.uploadImgMaxLength = 10; // Max 10 images at once

119

120

// Base64 image support

121

editor.customConfig.uploadImgShowBase64 = true; // Allow base64 images

122

123

// Strict limits for comments/forums

124

editor.customConfig.uploadImgMaxSize = 1 * 1024 * 1024; // 1MB

125

editor.customConfig.uploadImgMaxLength = 3; // Max 3 images

126

127

// Generous limits for content creation

128

editor.customConfig.uploadImgMaxSize = 20 * 1024 * 1024; // 20MB

129

editor.customConfig.uploadImgMaxLength = 50; // Max 50 images

130

```

131

132

### Upload Hooks

133

134

Configure upload lifecycle callbacks.

135

136

```javascript { .api }

137

interface UploadHooks {

138

/** Called before upload starts */

139

before?: (xhr: XMLHttpRequest, editor: any, files: File[]) => void | false;

140

141

/** Called after successful upload */

142

success?: (xhr: XMLHttpRequest, editor: any, result: any) => void;

143

144

/** Called after failed upload */

145

fail?: (xhr: XMLHttpRequest, editor: any, result: any) => void;

146

147

/** Called on upload error */

148

error?: (xhr: XMLHttpRequest, editor: any, error: any) => void;

149

150

/** Called on upload timeout */

151

timeout?: (xhr: XMLHttpRequest, editor: any) => void;

152

153

/** Custom image insertion function */

154

customInsert?: (insertImg: Function, result: any, editor: any) => void;

155

}

156

```

157

158

**Usage Examples:**

159

160

```javascript

161

editor.customConfig.uploadImgHooks = {

162

before: function(xhr, editor, files) {

163

console.log('Upload starting...', files.length, 'files');

164

165

// Validate files

166

for (let file of files) {

167

if (!file.type.startsWith('image/')) {

168

alert('Only image files are allowed');

169

return false; // Cancel upload

170

}

171

}

172

173

// Show loading indicator

174

showLoadingIndicator();

175

},

176

177

success: function(xhr, editor, result) {

178

console.log('Upload successful:', result);

179

hideLoadingIndicator();

180

181

// Process server response

182

if (result.code === 0) {

183

console.log('Images uploaded:', result.data);

184

}

185

},

186

187

fail: function(xhr, editor, result) {

188

console.log('Upload failed:', result);

189

hideLoadingIndicator();

190

alert('Upload failed: ' + (result.message || 'Unknown error'));

191

},

192

193

error: function(xhr, editor, error) {

194

console.error('Upload error:', error);

195

hideLoadingIndicator();

196

alert('Upload error occurred');

197

},

198

199

timeout: function(xhr, editor) {

200

console.log('Upload timeout');

201

hideLoadingIndicator();

202

alert('Upload timed out. Please try again.');

203

},

204

205

customInsert: function(insertImg, result, editor) {

206

// Custom logic for inserting images

207

if (result.code === 0 && result.data) {

208

result.data.forEach(url => {

209

insertImg(url);

210

});

211

}

212

}

213

};

214

```

215

216

### Custom Upload Implementation

217

218

Completely custom upload handling.

219

220

```javascript { .api }

221

interface CustomUpload {

222

/** Custom image upload implementation */

223

customUploadImg?: (files: FileList, insert: (url: string) => void) => void;

224

}

225

```

226

227

**Usage Examples:**

228

229

```javascript

230

// Complete custom upload

231

editor.customConfig.customUploadImg = function(files, insert) {

232

console.log('Custom upload:', files.length, 'files');

233

234

// Convert to array for easier handling

235

const fileArray = Array.from(files);

236

237

// Upload each file

238

fileArray.forEach(file => {

239

const formData = new FormData();

240

formData.append('image', file);

241

formData.append('timestamp', Date.now().toString());

242

243

fetch('/api/custom-upload', {

244

method: 'POST',

245

body: formData,

246

headers: {

247

'X-Requested-With': 'XMLHttpRequest'

248

}

249

})

250

.then(response => response.json())

251

.then(result => {

252

if (result.success) {

253

// Insert image into editor

254

insert(result.imageUrl);

255

} else {

256

console.error('Upload failed:', result.error);

257

alert('Upload failed: ' + result.error);

258

}

259

})

260

.catch(error => {

261

console.error('Upload error:', error);

262

alert('Upload error occurred');

263

});

264

});

265

};

266

267

// AWS S3 upload example

268

editor.customConfig.customUploadImg = function(files, insert) {

269

Array.from(files).forEach(file => {

270

// Get presigned URL from your backend

271

fetch('/api/s3-presigned-url', {

272

method: 'POST',

273

headers: {'Content-Type': 'application/json'},

274

body: JSON.stringify({

275

fileName: file.name,

276

fileType: file.type

277

})

278

})

279

.then(response => response.json())

280

.then(data => {

281

// Upload directly to S3

282

return fetch(data.presignedUrl, {

283

method: 'PUT',

284

body: file,

285

headers: {

286

'Content-Type': file.type

287

}

288

});

289

})

290

.then(() => {

291

// Insert the S3 URL

292

const s3Url = `https://your-bucket.s3.amazonaws.com/${file.name}`;

293

insert(s3Url);

294

})

295

.catch(error => {

296

console.error('S3 upload error:', error);

297

alert('Upload to cloud storage failed');

298

});

299

});

300

};

301

```

302

303

### Cloud Storage Integration

304

305

Integration with popular cloud storage services.

306

307

```javascript { .api }

308

interface CloudConfig {

309

/** Enable Qiniu cloud upload */

310

qiniu?: boolean;

311

}

312

```

313

314

**Usage Examples:**

315

316

```javascript

317

// Qiniu cloud storage

318

editor.customConfig.qiniu = true;

319

editor.customConfig.uploadImgServer = 'https://your-qiniu-endpoint.com/upload';

320

321

// Custom cloud integration

322

editor.customConfig.customUploadImg = function(files, insert) {

323

// Cloudinary upload example

324

const cloudinaryUrl = 'https://api.cloudinary.com/v1_1/your-cloud-name/image/upload';

325

326

Array.from(files).forEach(file => {

327

const formData = new FormData();

328

formData.append('file', file);

329

formData.append('upload_preset', 'your-upload-preset');

330

331

fetch(cloudinaryUrl, {

332

method: 'POST',

333

body: formData

334

})

335

.then(response => response.json())

336

.then(result => {

337

if (result.secure_url) {

338

insert(result.secure_url);

339

}

340

})

341

.catch(error => {

342

console.error('Cloudinary upload error:', error);

343

});

344

});

345

};

346

```

347

348

## Complete Upload API Interface

349

350

```javascript { .api }

351

interface UploadImgAPI {

352

/** Upload image files */

353

uploadImg(files: FileList | File[]): void;

354

}

355

356

interface UploadConfig {

357

// Server configuration

358

uploadImgServer?: string;

359

uploadFileName?: string;

360

uploadImgParams?: {[key: string]: any};

361

uploadImgHeaders?: {[key: string]: string};

362

withCredentials?: boolean;

363

uploadImgTimeout?: number;

364

365

// Upload limits

366

uploadImgMaxSize?: number;

367

uploadImgMaxLength?: number;

368

uploadImgShowBase64?: boolean;

369

370

// Upload hooks

371

uploadImgHooks?: {

372

before?: (xhr: XMLHttpRequest, editor: any, files: File[]) => void | false;

373

success?: (xhr: XMLHttpRequest, editor: any, result: any) => void;

374

fail?: (xhr: XMLHttpRequest, editor: any, result: any) => void;

375

error?: (xhr: XMLHttpRequest, editor: any, error: any) => void;

376

timeout?: (xhr: XMLHttpRequest, editor: any) => void;

377

customInsert?: (insertImg: Function, result: any, editor: any) => void;

378

};

379

380

// Cloud storage

381

qiniu?: boolean;

382

383

// Custom upload

384

customUploadImg?: (files: FileList, insert: (url: string) => void) => void;

385

386

// UI

387

customAlert?: (info: string) => void;

388

}

389

```

390

391

## Upload Patterns

392

393

### Progress Tracking

394

395

```javascript

396

// Upload with progress tracking

397

editor.customConfig.uploadImgHooks = {

398

before: function(xhr, editor, files) {

399

// Setup progress tracking

400

xhr.upload.onprogress = function(e) {

401

if (e.lengthComputable) {

402

const percentComplete = (e.loaded / e.total) * 100;

403

updateProgressBar(percentComplete);

404

}

405

};

406

},

407

408

success: function(xhr, editor, result) {

409

hideProgressBar();

410

},

411

412

error: function(xhr, editor, error) {

413

hideProgressBar();

414

}

415

};

416

```

417

418

### Batch Upload Management

419

420

```javascript

421

// Handle multiple file uploads with coordination

422

let uploadCounter = 0;

423

let totalUploads = 0;

424

425

editor.customConfig.customUploadImg = function(files, insert) {

426

totalUploads = files.length;

427

uploadCounter = 0;

428

429

showUploadStatus(`Uploading ${totalUploads} images...`);

430

431

Array.from(files).forEach((file, index) => {

432

uploadSingleFile(file, insert, index);

433

});

434

};

435

436

function uploadSingleFile(file, insert, index) {

437

const formData = new FormData();

438

formData.append('image', file);

439

440

fetch('/api/upload', {

441

method: 'POST',

442

body: formData

443

})

444

.then(response => response.json())

445

.then(result => {

446

uploadCounter++;

447

updateUploadStatus(`Uploaded ${uploadCounter}/${totalUploads} images`);

448

449

if (result.success) {

450

insert(result.url);

451

}

452

453

if (uploadCounter === totalUploads) {

454

hideUploadStatus();

455

}

456

})

457

.catch(error => {

458

console.error(`Upload ${index + 1} failed:`, error);

459

uploadCounter++;

460

});

461

}

462

```

463

464

### Image Optimization

465

466

```javascript

467

// Client-side image optimization before upload

468

editor.customConfig.customUploadImg = function(files, insert) {

469

Array.from(files).forEach(file => {

470

// Optimize image before upload

471

optimizeImage(file, {

472

maxWidth: 1200,

473

maxHeight: 800,

474

quality: 0.8

475

})

476

.then(optimizedFile => {

477

return uploadToServer(optimizedFile);

478

})

479

.then(result => {

480

insert(result.url);

481

})

482

.catch(error => {

483

console.error('Image optimization/upload failed:', error);

484

});

485

});

486

};

487

488

function optimizeImage(file, options) {

489

return new Promise((resolve, reject) => {

490

const canvas = document.createElement('canvas');

491

const ctx = canvas.getContext('2d');

492

const img = new Image();

493

494

img.onload = function() {

495

// Calculate new dimensions

496

let { width, height } = img;

497

const maxWidth = options.maxWidth || width;

498

const maxHeight = options.maxHeight || height;

499

500

if (width > maxWidth || height > maxHeight) {

501

const ratio = Math.min(maxWidth / width, maxHeight / height);

502

width *= ratio;

503

height *= ratio;

504

}

505

506

// Draw and compress

507

canvas.width = width;

508

canvas.height = height;

509

ctx.drawImage(img, 0, 0, width, height);

510

511

canvas.toBlob(resolve, file.type, options.quality || 0.9);

512

};

513

514

img.onerror = reject;

515

img.src = URL.createObjectURL(file);

516

});

517

}

518

```