/
ckfindercommand.ts
158 lines (123 loc) · 4.73 KB
/
ckfindercommand.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/* global window */
/**
* @module ckfinder/ckfindercommand
*/
import { Command, type Editor } from 'ckeditor5/src/core.js';
import { CKEditorError } from 'ckeditor5/src/utils.js';
import type { Notification } from 'ckeditor5/src/ui.js';
/**
* The CKFinder command. It is used by the {@link module:ckfinder/ckfinderediting~CKFinderEditing CKFinder editing feature}
* to open the CKFinder file manager to insert an image or a link to a file into the editor content.
*
* ```ts
* editor.execute( 'ckfinder' );
* ```
*
* **Note:** This command uses other features to perform tasks:
* - To insert images the {@link module:image/image/insertimagecommand~InsertImageCommand 'insertImage'} command
* from the {@link module:image/image~Image Image feature}.
* - To insert links to files the {@link module:link/linkcommand~LinkCommand 'link'} command
* from the {@link module:link/link~Link Link feature}.
*/
export default class CKFinderCommand extends Command {
/**
* @inheritDoc
*/
constructor( editor: Editor ) {
super( editor );
// The CKFinder command does not affect data by itself.
this.affectsData = false;
// Remove default document listener to lower its priority.
this.stopListening( this.editor.model.document, 'change' );
// Lower this command listener priority to be sure that refresh() will be called after link & image refresh.
this.listenTo( this.editor.model.document, 'change', () => this.refresh(), { priority: 'low' } );
}
/**
* @inheritDoc
*/
public override refresh(): void {
const imageCommand = this.editor.commands.get( 'insertImage' )!;
const linkCommand = this.editor.commands.get( 'link' )!;
// The CKFinder command is enabled when one of image or link command is enabled.
this.isEnabled = imageCommand.isEnabled || linkCommand.isEnabled;
}
/**
* @inheritDoc
*/
public override execute(): void {
const editor = this.editor;
const openerMethod = this.editor.config.get( 'ckfinder.openerMethod' ) || 'modal';
if ( openerMethod != 'popup' && openerMethod != 'modal' ) {
/**
* The `ckfinder.openerMethod` must be one of: "popup" or "modal".
*
* @error ckfinder-unknown-openermethod
*/
throw new CKEditorError( 'ckfinder-unknown-openermethod', editor );
}
const options = this.editor.config.get( 'ckfinder.options' ) || {};
options.chooseFiles = true;
// Cache the user-defined onInit method
const originalOnInit = options.onInit;
// Pass the lang code to the CKFinder if not defined by user.
if ( !options.language ) {
options.language = editor.locale.uiLanguage;
}
// The onInit method allows to extend CKFinder's behavior. It is used to attach event listeners to file choosing related events.
options.onInit = finder => {
// Call original options.onInit if it was defined by user.
if ( originalOnInit ) {
originalOnInit( finder );
}
finder.on( 'files:choose', ( evt: any ) => {
const files = evt.data.files.toArray();
// Insert links
const links = files.filter( ( file: any ) => !file.isImage() );
const images = files.filter( ( file: any ) => file.isImage() );
for ( const linkFile of links ) {
editor.execute( 'link', linkFile.getUrl() );
}
const imagesUrls = [];
for ( const image of images ) {
const url = image.getUrl();
imagesUrls.push( url ? url : finder.request( 'file:getProxyUrl', { file: image } ) );
}
if ( imagesUrls.length ) {
insertImages( editor, imagesUrls );
}
} );
finder.on( 'file:choose:resizedImage', ( evt: any ) => {
const resizedUrl = evt.data.resizedUrl;
if ( !resizedUrl ) {
const notification: Notification = editor.plugins.get( 'Notification' );
const t = editor.locale.t;
notification.showWarning( t( 'Could not obtain resized image URL.' ), {
title: t( 'Selecting resized image failed' ),
namespace: 'ckfinder'
} );
return;
}
insertImages( editor, [ resizedUrl ] );
} );
};
( window as any ).CKFinder[ openerMethod ]( options );
}
}
function insertImages( editor: Editor, urls: Array<string> ): void {
const imageCommand = editor.commands.get( 'insertImage' )!;
// Check if inserting an image is actually possible - it might be possible to only insert a link.
if ( !imageCommand.isEnabled ) {
const notification: Notification = editor.plugins.get( 'Notification' );
const t = editor.locale.t;
notification.showWarning( t( 'Could not insert image at the current position.' ), {
title: t( 'Inserting image failed' ),
namespace: 'ckfinder'
} );
return;
}
editor.execute( 'insertImage', { source: urls } );
}