suneditor 3.0.5 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +1 -1
- package/src/assets/suneditor.css +53 -5
- package/src/core/editor.js +20 -3
- package/src/core/event/eventOrchestrator.js +2 -1
- package/src/core/event/handlers/handler_ww_key.js +2 -2
- package/src/core/logic/dom/html.js +23 -1
- package/src/core/logic/dom/offset.js +24 -1
- package/src/core/logic/panel/viewer.js +6 -4
- package/src/core/logic/shell/_commandExecutor.js +38 -1
- package/src/core/logic/shell/shortcuts.js +1 -1
- package/src/core/schema/options.js +1 -1
- package/src/core/section/constructor.js +3 -3
- package/src/helper/index.js +3 -0
- package/src/helper/msOffice.js +849 -0
- package/src/interfaces/plugins.js +1 -1
- package/src/langs/ckb.js +1 -0
- package/src/langs/cs.js +1 -0
- package/src/langs/da.js +1 -0
- package/src/langs/de.js +1 -0
- package/src/langs/en.js +1 -1
- package/src/langs/es.js +1 -0
- package/src/langs/fa.js +1 -0
- package/src/langs/fr.js +1 -0
- package/src/langs/he.js +1 -0
- package/src/langs/hu.js +1 -0
- package/src/langs/it.js +1 -0
- package/src/langs/ja.js +1 -0
- package/src/langs/km.js +1 -0
- package/src/langs/ko.js +1 -0
- package/src/langs/lv.js +1 -0
- package/src/langs/nl.js +1 -0
- package/src/langs/pl.js +1 -0
- package/src/langs/pt_br.js +1 -0
- package/src/langs/ro.js +1 -0
- package/src/langs/ru.js +1 -0
- package/src/langs/se.js +1 -0
- package/src/langs/tr.js +1 -0
- package/src/langs/uk.js +1 -0
- package/src/langs/ur.js +1 -0
- package/src/langs/zh_cn.js +1 -0
- package/src/modules/contract/Browser.js +99 -10
- package/src/modules/ui/ModalAnchorEditor.js +16 -1
- package/src/plugins/browser/audioGallery.js +13 -0
- package/src/plugins/browser/fileBrowser.js +22 -0
- package/src/plugins/browser/fileGallery.js +14 -0
- package/src/plugins/browser/imageGallery.js +14 -0
- package/src/plugins/browser/videoGallery.js +14 -0
- package/src/plugins/command/fileUpload.js +12 -0
- package/src/plugins/dropdown/layout.js +1 -1
- package/src/plugins/dropdown/template.js +2 -1
- package/src/plugins/field/autocomplete.js +346 -0
- package/src/plugins/index.js +3 -3
- package/src/plugins/modal/audio.js +12 -0
- package/src/plugins/modal/embed.js +12 -0
- package/src/plugins/modal/image/index.js +12 -0
- package/src/plugins/modal/link.js +12 -0
- package/src/plugins/modal/video/index.js +12 -0
- package/src/typedef.js +1 -1
- package/types/core/logic/shell/shortcuts.d.ts +2 -2
- package/types/core/schema/options.d.ts +2 -2
- package/types/helper/index.d.ts +4 -0
- package/types/helper/msOffice.d.ts +11 -0
- package/types/interfaces/plugins.d.ts +1 -1
- package/types/langs/_Lang.d.ts +1 -1
- package/types/modules/contract/Browser.d.ts +32 -0
- package/types/modules/ui/ModalAnchorEditor.d.ts +32 -2
- package/types/plugins/browser/audioGallery.d.ts +26 -0
- package/types/plugins/browser/fileBrowser.d.ts +45 -0
- package/types/plugins/browser/fileGallery.d.ts +28 -0
- package/types/plugins/browser/imageGallery.d.ts +28 -0
- package/types/plugins/browser/videoGallery.d.ts +28 -0
- package/types/plugins/command/fileUpload.d.ts +24 -0
- package/types/plugins/field/autocomplete.d.ts +177 -0
- package/types/plugins/index.d.ts +3 -3
- package/types/plugins/modal/audio.d.ts +24 -0
- package/types/plugins/modal/embed.d.ts +24 -0
- package/types/plugins/modal/image/index.d.ts +24 -0
- package/types/plugins/modal/link.d.ts +28 -1
- package/types/plugins/modal/video/index.d.ts +24 -0
- package/types/typedef.d.ts +1 -1
- package/src/plugins/field/mention.js +0 -251
- package/types/plugins/field/mention.d.ts +0 -104
|
@@ -171,7 +171,7 @@ export class PluginDropdownFree extends Base {
|
|
|
171
171
|
* These plugins typically respond to input events in the wysiwyg area
|
|
172
172
|
*
|
|
173
173
|
* **Commonly used hooks:**
|
|
174
|
-
* - `onInput()` - Responds to input events in the editor (See: `
|
|
174
|
+
* - `onInput()` - Responds to input events in the editor (See: `autocomplete` plugin)
|
|
175
175
|
* - Other event hooks can be used as needed (`onKeydown`, `onClick`, etc.)
|
|
176
176
|
*
|
|
177
177
|
* Child classes MAY optionally implement event hook methods
|
package/src/langs/ckb.js
CHANGED
package/src/langs/cs.js
CHANGED
package/src/langs/da.js
CHANGED
package/src/langs/de.js
CHANGED
package/src/langs/en.js
CHANGED
package/src/langs/es.js
CHANGED
package/src/langs/fa.js
CHANGED
package/src/langs/fr.js
CHANGED
package/src/langs/he.js
CHANGED
package/src/langs/hu.js
CHANGED
package/src/langs/it.js
CHANGED
package/src/langs/ja.js
CHANGED
package/src/langs/km.js
CHANGED
package/src/langs/ko.js
CHANGED
package/src/langs/lv.js
CHANGED
package/src/langs/nl.js
CHANGED
package/src/langs/pl.js
CHANGED
package/src/langs/pt_br.js
CHANGED
package/src/langs/ro.js
CHANGED
package/src/langs/ru.js
CHANGED
package/src/langs/se.js
CHANGED
package/src/langs/tr.js
CHANGED
package/src/langs/uk.js
CHANGED
package/src/langs/ur.js
CHANGED
package/src/langs/zh_cn.js
CHANGED
|
@@ -27,6 +27,19 @@ import ApiManager from '../manager/ApiManager';
|
|
|
27
27
|
* @property {(target: Node) => void} selectorHandler - Function that actions when an item is clicked. Required. Can be overridden in browser.
|
|
28
28
|
* @property {boolean} [useSearch] - Whether to use the search function. Optional. Default: `true`.
|
|
29
29
|
* @property {string} [searchUrl] - File server search url. Optional. Can be overridden in browser.
|
|
30
|
+
* - Requested as `searchUrl + '?keyword=' + keyword`. The server must return:
|
|
31
|
+
* ```js
|
|
32
|
+
* {
|
|
33
|
+
* "result": [
|
|
34
|
+
* {
|
|
35
|
+
* "src": "https://example.com/file.jpg",
|
|
36
|
+
* "name": "file.jpg",
|
|
37
|
+
* "thumbnail": "https://example.com/file_thumb.jpg",
|
|
38
|
+
* "tag": ["photo"]
|
|
39
|
+
* }
|
|
40
|
+
* ]
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
30
43
|
* @property {Object<string, string>} [searchUrlHeader] - File server search http header. Optional. Can be overridden in browser.
|
|
31
44
|
* @property {string} [listClass] - Class name of list div. Required. Can be overridden in browser.
|
|
32
45
|
* @property {(item: BrowserFile) => string} [drawItemHandler] - Function that returns HTML string for rendering each file item. Required. Can be overridden in browser.
|
|
@@ -37,6 +50,7 @@ import ApiManager from '../manager/ApiManager';
|
|
|
37
50
|
* @property {Array<*>} [props] - `props` argument to `drawItemHandler` function. Optional. Can be overridden in browser.
|
|
38
51
|
* @property {number} [columnSize] - Number of `div.se-file-item-column` to be created.
|
|
39
52
|
* - Optional. Can be overridden in browser. Default: 4.
|
|
53
|
+
* @property {number} [expand=1] - Initial folder expand depth. `1` expands the first level, `Infinity` expands all. Default: `1`.
|
|
40
54
|
* @property {((item: BrowserFile) => string)} [thumbnail] - Default thumbnail
|
|
41
55
|
*/
|
|
42
56
|
|
|
@@ -50,6 +64,10 @@ class Browser {
|
|
|
50
64
|
#loading;
|
|
51
65
|
#globalEventHandler;
|
|
52
66
|
|
|
67
|
+
/** @type {Array<BrowserFile>} */
|
|
68
|
+
#allItems = [];
|
|
69
|
+
#searchInput;
|
|
70
|
+
#searchClearBtn;
|
|
53
71
|
#closeSignal = false;
|
|
54
72
|
#bindClose = null;
|
|
55
73
|
|
|
@@ -102,6 +120,7 @@ class Browser {
|
|
|
102
120
|
this.drawItemHandler = (params.drawItemHandler || DrawItems).bind({ thumbnail: params.thumbnail, props: params.props || [] });
|
|
103
121
|
this.selectorHandler = params.selectorHandler;
|
|
104
122
|
this.columnSize = params.columnSize || 4;
|
|
123
|
+
this.expand = params.expand ?? 1;
|
|
105
124
|
this.folderDefaultPath = '';
|
|
106
125
|
this.closeArrow = this.#$.icons.menu_arrow_right;
|
|
107
126
|
this.openArrow = this.#$.icons.menu_arrow_down;
|
|
@@ -139,9 +158,15 @@ class Browser {
|
|
|
139
158
|
this.#$.eventManager.addEvent(this.side, 'click', this.#OnClickSide.bind(this));
|
|
140
159
|
this.#$.eventManager.addEvent(content, 'mousedown', this.#OnMouseDown_browser.bind(this));
|
|
141
160
|
this.#$.eventManager.addEvent(content, 'click', this.#OnClick_browser.bind(this));
|
|
142
|
-
this.#$.eventManager.addEvent(browserFrame.querySelector('form.se-browser-search-form'), 'submit', this.#Search.bind(this));
|
|
143
161
|
this.#$.eventManager.addEvent((this.sideOpenBtn = /** @type {HTMLButtonElement} */ (browserFrame.querySelector('.se-side-open-btn'))), 'click', this.#SideOpen.bind(this));
|
|
144
162
|
this.#$.eventManager.addEvent([this.header, browserFrame.querySelector('.se-browser-main')], 'mousedown', this.#SideClose.bind(this));
|
|
163
|
+
|
|
164
|
+
// search
|
|
165
|
+
const searchForm = browserFrame.querySelector('form.se-browser-search-form');
|
|
166
|
+
this.#searchInput = /** @type {HTMLInputElement} */ (searchForm?.querySelector('input[type="text"]'));
|
|
167
|
+
this.#searchClearBtn = /** @type {HTMLButtonElement} */ (browserFrame.querySelector('.se-browser-search-clear'));
|
|
168
|
+
this.#$.eventManager.addEvent(searchForm, 'submit', this.#Search.bind(this));
|
|
169
|
+
this.#$.eventManager.addEvent(this.#searchClearBtn, 'click', this.#ClearSearch.bind(this));
|
|
145
170
|
}
|
|
146
171
|
|
|
147
172
|
/**
|
|
@@ -195,11 +220,16 @@ class Browser {
|
|
|
195
220
|
this.area.style.display = 'none';
|
|
196
221
|
this.selectedTags = [];
|
|
197
222
|
this.items = [];
|
|
223
|
+
this.#allItems = [];
|
|
198
224
|
this.folders = {};
|
|
199
225
|
this.tree = {};
|
|
200
226
|
this.data = {};
|
|
201
227
|
this.keyword = '';
|
|
202
228
|
this.list.innerHTML = this.tagArea.innerHTML = this.titleArea.textContent = '';
|
|
229
|
+
|
|
230
|
+
if (this.#searchInput) this.#searchInput.value = '';
|
|
231
|
+
if (this.#searchClearBtn) this.#searchClearBtn.style.display = 'none';
|
|
232
|
+
|
|
203
233
|
this.#$.ui.opendBrowser = null;
|
|
204
234
|
this.sideInner = null;
|
|
205
235
|
|
|
@@ -216,8 +246,25 @@ class Browser {
|
|
|
216
246
|
this.#drawFileList(this.searchUrl + '?keyword=' + keyword, this.searchUrlHeader, false);
|
|
217
247
|
} else {
|
|
218
248
|
this.keyword = keyword.toLowerCase();
|
|
219
|
-
this.#drawListItem(this.items, false);
|
|
249
|
+
this.#drawListItem(this.#allItems.length > 0 ? this.#allItems : this.items, false);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @description Collects all file items from every folder in `this.data`.
|
|
255
|
+
* @returns {Array<BrowserFile>}
|
|
256
|
+
*/
|
|
257
|
+
#collectAllItems() {
|
|
258
|
+
const all = [];
|
|
259
|
+
for (const key in this.data) {
|
|
260
|
+
const items = this.data[key];
|
|
261
|
+
if (Array.isArray(items)) {
|
|
262
|
+
for (let i = 0; i < items.length; i++) {
|
|
263
|
+
all.push(items[i]);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
220
266
|
}
|
|
267
|
+
return all;
|
|
221
268
|
}
|
|
222
269
|
|
|
223
270
|
/**
|
|
@@ -306,6 +353,10 @@ class Browser {
|
|
|
306
353
|
|
|
307
354
|
this.list.innerHTML = listHTML;
|
|
308
355
|
|
|
356
|
+
if (keyword) {
|
|
357
|
+
this.#highlightKeyword(keyword);
|
|
358
|
+
}
|
|
359
|
+
|
|
309
360
|
if (update) {
|
|
310
361
|
this.items = items;
|
|
311
362
|
this.tagArea.innerHTML = tagsHTML;
|
|
@@ -341,6 +392,7 @@ class Browser {
|
|
|
341
392
|
} else if (typeof data === 'object') {
|
|
342
393
|
this.sideOpenBtn.style.display = '';
|
|
343
394
|
this.#parseFolderData(data);
|
|
395
|
+
this.#allItems = this.#collectAllItems();
|
|
344
396
|
|
|
345
397
|
this.side.innerHTML = '';
|
|
346
398
|
const sideInner = (this.sideInner = dom.utils.createElement('div', null));
|
|
@@ -412,8 +464,11 @@ class Browser {
|
|
|
412
464
|
* @description Creates a nested folder list from parsed data.
|
|
413
465
|
* @param {BrowserFile[]|BrowserFile} folderData - The structured folder data.
|
|
414
466
|
* @param {HTMLElement} parentElement - The parent element to append folder structure to.
|
|
467
|
+
* @param {number} [depth=0] - Current depth level.
|
|
415
468
|
*/
|
|
416
|
-
#createFolderList(folderData, parentElement) {
|
|
469
|
+
#createFolderList(folderData, parentElement, depth = 0) {
|
|
470
|
+
const expanded = depth < this.expand;
|
|
471
|
+
|
|
417
472
|
for (const key in folderData) {
|
|
418
473
|
const item = folderData[key];
|
|
419
474
|
if (!item) continue;
|
|
@@ -426,10 +481,10 @@ class Browser {
|
|
|
426
481
|
);
|
|
427
482
|
const folderDiv = dom.utils.createElement('div', { class: 'se-menu-folder' }, folderLabel);
|
|
428
483
|
|
|
429
|
-
folderLabel.insertBefore(dom.utils.createElement('button', null, this.closeArrow), folderLabel.firstElementChild);
|
|
484
|
+
folderLabel.insertBefore(dom.utils.createElement('button', null, expanded ? this.openArrow : this.closeArrow), folderLabel.firstElementChild);
|
|
430
485
|
const childContainer = document.createElement('div');
|
|
431
|
-
dom.utils.addClass(childContainer, 'se-menu-child|se-menu-hidden');
|
|
432
|
-
this.#createFolderList(item.children, childContainer);
|
|
486
|
+
dom.utils.addClass(childContainer, expanded ? 'se-menu-child' : 'se-menu-child|se-menu-hidden');
|
|
487
|
+
this.#createFolderList(item.children, childContainer, depth + 1);
|
|
433
488
|
folderDiv.appendChild(childContainer);
|
|
434
489
|
|
|
435
490
|
parentElement.appendChild(folderDiv);
|
|
@@ -540,11 +595,12 @@ class Browser {
|
|
|
540
595
|
dom.utils.removeClass(this.side.querySelectorAll('.active'), 'active');
|
|
541
596
|
dom.utils.addClass([cmdTarget, dom.query.getParentElement(cmdTarget, '.se-menu-folder')], 'active');
|
|
542
597
|
this.tagArea.innerHTML = '';
|
|
598
|
+
this.selectedTags = [];
|
|
543
599
|
|
|
544
600
|
if (typeof data === 'string') {
|
|
545
601
|
this.#drawFileList(data, this.urlHeader, true);
|
|
546
602
|
} else {
|
|
547
|
-
this.#drawListItem(data,
|
|
603
|
+
this.#drawListItem(data, true);
|
|
548
604
|
}
|
|
549
605
|
}
|
|
550
606
|
|
|
@@ -576,9 +632,39 @@ class Browser {
|
|
|
576
632
|
* @param {SubmitEvent} e - Event object
|
|
577
633
|
*/
|
|
578
634
|
#Search(e) {
|
|
579
|
-
const eventTarget = /** @type {HTMLElement} */ (e.currentTarget);
|
|
580
635
|
e.preventDefault();
|
|
581
|
-
|
|
636
|
+
|
|
637
|
+
const keyword = this.#searchInput.value;
|
|
638
|
+
this.search(keyword);
|
|
639
|
+
|
|
640
|
+
if (this.#searchClearBtn) this.#searchClearBtn.style.display = keyword ? '' : 'none';
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* @description Clears the search keyword and restores the current folder's item list.
|
|
645
|
+
*/
|
|
646
|
+
#ClearSearch() {
|
|
647
|
+
if (this.#searchInput) this.#searchInput.value = '';
|
|
648
|
+
if (this.#searchClearBtn) this.#searchClearBtn.style.display = 'none';
|
|
649
|
+
|
|
650
|
+
this.keyword = '';
|
|
651
|
+
this.#drawListItem(this.items, false);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* @description Highlights the search keyword in file name elements.
|
|
656
|
+
* @param {string} keyword - Lowercase keyword to highlight.
|
|
657
|
+
*/
|
|
658
|
+
#highlightKeyword(keyword) {
|
|
659
|
+
const nameEls = this.list.querySelectorAll('.se-file-name-image:not(.se-file-name-back)');
|
|
660
|
+
for (let i = 0; i < nameEls.length; i++) {
|
|
661
|
+
const el = nameEls[i];
|
|
662
|
+
const text = el.textContent;
|
|
663
|
+
const idx = text.toLowerCase().indexOf(keyword);
|
|
664
|
+
if (idx > -1) {
|
|
665
|
+
el.innerHTML = text.substring(0, idx) + '<mark>' + text.substring(idx, idx + keyword.length) + '</mark>' + text.substring(idx + keyword.length);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
582
668
|
}
|
|
583
669
|
|
|
584
670
|
/**
|
|
@@ -633,7 +719,10 @@ function CreateHTMLInfos($, useSearch) {
|
|
|
633
719
|
useSearch
|
|
634
720
|
? /*html*/ `
|
|
635
721
|
<form class="se-browser-search-form">
|
|
636
|
-
<
|
|
722
|
+
<div class="se-browser-search-input-wrap">
|
|
723
|
+
<input type="text" class="se-input-form" placeholder="${lang.search}" aria-label="${lang.search}">
|
|
724
|
+
<button type="button" class="se-btn se-btn-plain se-browser-search-clear" title="${lang.cancel}" aria-label="${lang.cancel}" style="display:none">${icons.cancel}</button>
|
|
725
|
+
</div>
|
|
637
726
|
<button type="submit" class="se-btn" title="${lang.search}" aria-label="${lang.search}">${icons.search}</button>
|
|
638
727
|
</form>`
|
|
639
728
|
: ''
|
|
@@ -13,9 +13,24 @@ const { _w, NO_EVENT } = env;
|
|
|
13
13
|
* @property {{default?: string, check_new_window?: string, check_bookmark?: string}} [defaultRel={}] - Default `rel` values auto-applied by condition.
|
|
14
14
|
* `default` is always applied, `check_new_window` when "Open in new window" is checked, `check_bookmark` for bookmark links.
|
|
15
15
|
* ```js
|
|
16
|
-
* {
|
|
16
|
+
* {
|
|
17
|
+
* relList: ['nofollow', 'noreferrer', 'noopener'],
|
|
18
|
+
* defaultRel: { default: 'noopener', check_new_window: 'noreferrer' }
|
|
19
|
+
* }
|
|
17
20
|
* ```
|
|
18
21
|
* @property {string} [uploadUrl] - File upload URL.
|
|
22
|
+
* - The server must return:
|
|
23
|
+
* ```js
|
|
24
|
+
* {
|
|
25
|
+
* "result": [
|
|
26
|
+
* {
|
|
27
|
+
* "url": "https://example.com/file.pdf",
|
|
28
|
+
* "name": "file.pdf",
|
|
29
|
+
* "size": 1048576
|
|
30
|
+
* }
|
|
31
|
+
* ]
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
19
34
|
* @property {Object<string, string>} [uploadHeaders] - File upload headers.
|
|
20
35
|
* @property {number} [uploadSizeLimit] - File upload size limit.
|
|
21
36
|
* @property {number} [uploadSingleSizeLimit] - File upload single size limit.
|
|
@@ -5,6 +5,19 @@ import { Browser } from '../../modules/contract';
|
|
|
5
5
|
* @typedef {Object} AudioGalleryPluginOptions
|
|
6
6
|
* @property {Array<SunEditor.Module.Browser.File>} [data] - Direct data without server calls
|
|
7
7
|
* @property {string} [url] - Server request URL
|
|
8
|
+
* - The server must return:
|
|
9
|
+
* ```js
|
|
10
|
+
* {
|
|
11
|
+
* "result": [
|
|
12
|
+
* {
|
|
13
|
+
* "src": "https://example.com/audio.mp3",
|
|
14
|
+
* "name": "audio.mp3",
|
|
15
|
+
* "thumbnail": "https://example.com/audio_icon.png",
|
|
16
|
+
* "tag": ["music"]
|
|
17
|
+
* }
|
|
18
|
+
* ]
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
8
21
|
* @property {Object<string, string>} [headers] - Server request headers
|
|
9
22
|
* @property {string|((item: SunEditor.Module.Browser.File) => string)} [thumbnail] - Default thumbnail
|
|
10
23
|
*/
|
|
@@ -5,8 +5,29 @@ import { Browser } from '../../modules/contract';
|
|
|
5
5
|
* @typedef {Object} FileBrowserPluginOptions
|
|
6
6
|
* @property {Object<string, *>|Array<*>} [data] - Direct data without server calls (bypasses URL fetch).
|
|
7
7
|
* @property {string} [url] - Server request URL
|
|
8
|
+
* - The server must return a nested folder structure.
|
|
9
|
+
* - `_data`: array (inline) or string URL (lazy-loaded on folder click).
|
|
10
|
+
* - `"default": true` sets the initially selected folder.
|
|
11
|
+
* ```js
|
|
12
|
+
* {
|
|
13
|
+
* "result": {
|
|
14
|
+
* "root": {
|
|
15
|
+
* "name": "Root",
|
|
16
|
+
* "default": true,
|
|
17
|
+
* "_data": [
|
|
18
|
+
* { "src": "https://example.com/file1.pdf", "name": "file1.pdf" }
|
|
19
|
+
* ],
|
|
20
|
+
* "documents": {
|
|
21
|
+
* "name": "Documents",
|
|
22
|
+
* "_data": "https://api.example.com/files/documents"
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
8
28
|
* @property {Object<string, string>} [headers] - Server request headers
|
|
9
29
|
* @property {string|((item: SunEditor.Module.Browser.File) => string)} [thumbnail] - Default thumbnail URL or a function that returns a thumbnail URL per item.
|
|
30
|
+
* @property {number} [expand=1] - Initial folder expand depth. `1` expands the first level, `Infinity` expands all. Default: `1`.
|
|
10
31
|
* @property {Array<string>} [props] - Additional tag names
|
|
11
32
|
* ```js
|
|
12
33
|
* { url: '/api/files', headers: { Authorization: 'Bearer token' }, thumbnail: (item) => item.thumbUrl }
|
|
@@ -48,6 +69,7 @@ class FileBrowser extends PluginBrowser {
|
|
|
48
69
|
className: 'se-file-browser',
|
|
49
70
|
thumbnail: typeof pluginOptions.thumbnail === 'function' ? pluginOptions.thumbnail : (item) => thumbnail[item.type] || defaultThumbnail,
|
|
50
71
|
props: [...new Set((pluginOptions.props ?? []).concat(['frame']))],
|
|
72
|
+
expand: pluginOptions.expand,
|
|
51
73
|
});
|
|
52
74
|
}
|
|
53
75
|
|
|
@@ -5,6 +5,20 @@ import { Browser } from '../../modules/contract';
|
|
|
5
5
|
* @typedef {Object} FileGalleryPluginOptions
|
|
6
6
|
* @property {Array<SunEditor.Module.Browser.File>} [data] - Direct data without server calls
|
|
7
7
|
* @property {string} [url] - Server request URL
|
|
8
|
+
* - The server must return:
|
|
9
|
+
* ```js
|
|
10
|
+
* {
|
|
11
|
+
* "result": [
|
|
12
|
+
* {
|
|
13
|
+
* "src": "https://example.com/doc.pdf",
|
|
14
|
+
* "name": "doc.pdf",
|
|
15
|
+
* "thumbnail": "https://example.com/pdf_icon.png",
|
|
16
|
+
* "type": "file", // video, image ..[plugin name]
|
|
17
|
+
* "tag": ["document"]
|
|
18
|
+
* }
|
|
19
|
+
* ]
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
8
22
|
* @property {Object<string, string>} [headers] - Server request headers
|
|
9
23
|
* @property {string|((item: SunEditor.Module.Browser.File) => string)} [thumbnail] - Default thumbnail
|
|
10
24
|
*/
|
|
@@ -5,6 +5,20 @@ import { Browser } from '../../modules/contract';
|
|
|
5
5
|
* @typedef ImageGalleryPluginOptions
|
|
6
6
|
* @property {Array<*>} [data] - Direct data without server calls
|
|
7
7
|
* @property {string} [url] - Server request URL
|
|
8
|
+
* - The server must return:
|
|
9
|
+
* ```js
|
|
10
|
+
* {
|
|
11
|
+
* "result": [
|
|
12
|
+
* {
|
|
13
|
+
* "src": "https://example.com/img.jpg",
|
|
14
|
+
* "name": "img.jpg",
|
|
15
|
+
* "thumbnail": "https://example.com/img_thumb.jpg",
|
|
16
|
+
* "alt": "description",
|
|
17
|
+
* "tag": ["nature"]
|
|
18
|
+
* }
|
|
19
|
+
* ]
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
8
22
|
* @property {Object<string, string>} [headers] - Server request headers
|
|
9
23
|
*/
|
|
10
24
|
|
|
@@ -5,6 +5,20 @@ import { Browser } from '../../modules/contract';
|
|
|
5
5
|
* @typedef {Object} VideoGalleryPluginOptions
|
|
6
6
|
* @property {Array<SunEditor.Module.Browser.File>} [data] - Direct data without server calls
|
|
7
7
|
* @property {string} [url] - Server request URL
|
|
8
|
+
* - The server must return:
|
|
9
|
+
* ```js
|
|
10
|
+
* {
|
|
11
|
+
* "result": [
|
|
12
|
+
* {
|
|
13
|
+
* "src": "https://example.com/video.mp4",
|
|
14
|
+
* "name": "video.mp4",
|
|
15
|
+
* "thumbnail": "https://example.com/video_thumb.jpg",
|
|
16
|
+
* "frame": "video",
|
|
17
|
+
* "tag": ["tutorial"]
|
|
18
|
+
* }
|
|
19
|
+
* ]
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
8
22
|
* @property {Object<string, string>} [headers] - Server request headers
|
|
9
23
|
* @property {string|((item: SunEditor.Module.Browser.File) => string)} [thumbnail] - Default thumbnail
|
|
10
24
|
*/
|
|
@@ -8,6 +8,18 @@ const { NO_EVENT } = env;
|
|
|
8
8
|
/**
|
|
9
9
|
* @typedef FileUploadPluginOptions
|
|
10
10
|
* @property {string} uploadUrl - Server request URL for file upload
|
|
11
|
+
* - The server must return:
|
|
12
|
+
* ```js
|
|
13
|
+
* {
|
|
14
|
+
* "result": [
|
|
15
|
+
* {
|
|
16
|
+
* "url": "https://example.com/file.pdf",
|
|
17
|
+
* "name": "file.pdf",
|
|
18
|
+
* "size": 1048576
|
|
19
|
+
* }
|
|
20
|
+
* ]
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
11
23
|
* @property {Object<string, string>} [uploadHeaders] - Server request headers
|
|
12
24
|
* @property {number} [uploadSizeLimit] - Total upload size limit in bytes
|
|
13
25
|
* @property {number} [uploadSingleSizeLimit] - Single file size limit in bytes
|
|
@@ -75,7 +75,7 @@ function CreateHTML(layoutList) {
|
|
|
75
75
|
t = layoutList[i];
|
|
76
76
|
list += /*html*/ `
|
|
77
77
|
<li>
|
|
78
|
-
<button type="button" class="se-btn se-btn-list" data-value="${i}" title="${t.name}" aria-label="${t.name}">
|
|
78
|
+
<button type="button" class="se-btn se-btn-list" data-command="layout" data-value="${i}" title="${t.name}" aria-label="${t.name}">
|
|
79
79
|
${t.name}
|
|
80
80
|
</button>
|
|
81
81
|
</li>`;
|