lakelib 0.1.8 → 0.1.9
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/lake.css +93 -8
- package/dist/lake.min.js +26 -17
- package/dist/lake.min.js.map +1 -1
- package/lib/lake.css +93 -8
- package/lib/lake.js +708 -294
- package/lib/lake.js.map +1 -1
- package/lib/types/boxes/file.d.ts +2 -0
- package/lib/types/css/index.d.ts +3 -0
- package/lib/types/editor.d.ts +5 -1
- package/lib/types/i18n/en-US/index.d.ts +5 -0
- package/lib/types/i18n/ja/index.d.ts +5 -0
- package/lib/types/i18n/ko/index.d.ts +5 -0
- package/lib/types/i18n/types.d.ts +40 -12
- package/lib/types/i18n/zh-CN/index.d.ts +5 -0
- package/lib/types/managers/box-manager.d.ts +3 -5
- package/lib/types/managers/selection.d.ts +3 -3
- package/lib/types/plugins/file.d.ts +3 -0
- package/lib/types/types/box-toolbar.d.ts +21 -0
- package/lib/types/ui/box-toolbar.d.ts +31 -0
- package/lib/types/ui/upload.d.ts +3 -2
- package/lib/types/utils/file-size.d.ts +1 -0
- package/lib/types/utils/get-box.d.ts +4 -0
- package/lib/types/utils/index.d.ts +3 -0
- package/lib/types/utils/node-and-view.d.ts +9 -0
- package/package.json +1 -1
package/lib/lake.js
CHANGED
|
@@ -37,8 +37,12 @@ var checkCircle = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height
|
|
|
37
37
|
|
|
38
38
|
var warningCircle = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"#000000\" viewBox=\"0 0 256 256\"><path d=\"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm-8-80V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,172Z\"></path></svg>";
|
|
39
39
|
|
|
40
|
+
var file$1 = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"#000000\" viewBox=\"0 0 256 256\"><path d=\"M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40V216a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160ZM200,216H56V40h88V88a8,8,0,0,0,8,8h48V216Z\"></path></svg>";
|
|
41
|
+
|
|
40
42
|
var open = "<svg width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6.25 4.5A1.75 1.75 0 0 0 4.5 6.25v11.5c0 .966.783 1.75 1.75 1.75h11.5a1.75 1.75 0 0 0 1.75-1.75v-4a.75.75 0 0 1 1.5 0v4A3.25 3.25 0 0 1 17.75 21H6.25A3.25 3.25 0 0 1 3 17.75V6.25A3.25 3.25 0 0 1 6.25 3h4a.75.75 0 0 1 0 1.5h-4ZM13 3.75a.75.75 0 0 1 .75-.75h6.5a.75.75 0 0 1 .75.75v6.5a.75.75 0 0 1-1.5 0V5.56l-5.22 5.22a.75.75 0 0 1-1.06-1.06l5.22-5.22h-4.69a.75.75 0 0 1-.75-.75Z\" fill=\"#000000\"/></svg>";
|
|
41
43
|
|
|
44
|
+
var download = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"#000000\" viewBox=\"0 0 256 256\"><path d=\"M224,144v64a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V144a8,8,0,0,1,16,0v56H208V144a8,8,0,0,1,16,0Zm-101.66,5.66a8,8,0,0,0,11.32,0l40-40a8,8,0,0,0-11.32-11.32L136,124.69V32a8,8,0,0,0-16,0v92.69L93.66,98.34a8,8,0,0,0-11.32,11.32Z\"></path></svg>";
|
|
45
|
+
|
|
42
46
|
var copy$1 = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"#000000\" viewBox=\"0 0 256 256\"><path d=\"M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z\"></path></svg>";
|
|
43
47
|
|
|
44
48
|
var remove = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"#000000\" viewBox=\"0 0 256 256\"><path d=\"M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z\"></path></svg>";
|
|
@@ -133,6 +137,8 @@ var hr$1 = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\"
|
|
|
133
137
|
|
|
134
138
|
var image$1 = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"#000000\" viewBox=\"0 0 256 256\"><path d=\"M216,40H40A16,16,0,0,0,24,56V200a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A16,16,0,0,0,216,40Zm0,16V158.75l-26.07-26.06a16,16,0,0,0-22.63,0l-20,20-44-44a16,16,0,0,0-22.62,0L40,149.37V56ZM40,172l52-52,80,80H40Zm176,28H194.63l-36-36,20-20L216,181.38V200ZM144,100a12,12,0,1,1,12,12A12,12,0,0,1,144,100Z\"></path></svg>";
|
|
135
139
|
|
|
140
|
+
var attachment = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"#000000\" viewBox=\"0 0 256 256\"><path d=\"M209.66,122.34a8,8,0,0,1,0,11.32l-82.05,82a56,56,0,0,1-79.2-79.21L147.67,35.73a40,40,0,1,1,56.61,56.55L105,193A24,24,0,1,1,71,159L154.3,74.38A8,8,0,1,1,165.7,85.6L82.39,170.31a8,8,0,1,0,11.27,11.36L192.93,81A24,24,0,1,0,159,47L59.76,147.68a40,40,0,1,0,56.53,56.62l82.06-82A8,8,0,0,1,209.66,122.34Z\"></path></svg>";
|
|
141
|
+
|
|
136
142
|
var codeBlock$1 = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"#000000\" viewBox=\"0 0 256 256\"><path d=\"M58.34,101.66l-32-32a8,8,0,0,1,0-11.32l32-32A8,8,0,0,1,69.66,37.66L43.31,64,69.66,90.34a8,8,0,0,1-11.32,11.32Zm40,0a8,8,0,0,0,11.32,0l32-32a8,8,0,0,0,0-11.32l-32-32A8,8,0,0,0,98.34,37.66L124.69,64,98.34,90.34A8,8,0,0,0,98.34,101.66ZM200,40H176a8,8,0,0,0,0,16h24V200H56V136a8,8,0,0,0-16,0v64a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Z\"></path></svg>";
|
|
137
143
|
|
|
138
144
|
var table = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"#000000\" viewBox=\"0 0 256 256\"><path d=\"M224,48H32a8,8,0,0,0-8,8V192a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A8,8,0,0,0,224,48ZM40,112H80v32H40Zm56,0H216v32H96ZM216,64V96H40V64ZM40,160H80v32H40Zm176,32H96V160H216v32Z\"></path></svg>";
|
|
@@ -160,7 +166,9 @@ const icons = new Map([
|
|
|
160
166
|
['check', check],
|
|
161
167
|
['checkCircle', checkCircle],
|
|
162
168
|
['warningCircle', warningCircle],
|
|
169
|
+
['file', file$1],
|
|
163
170
|
['open', open],
|
|
171
|
+
['download', download],
|
|
164
172
|
['copy', copy$1],
|
|
165
173
|
['remove', remove],
|
|
166
174
|
['maximize', maximize],
|
|
@@ -208,6 +216,7 @@ const icons = new Map([
|
|
|
208
216
|
['unlink', unlink],
|
|
209
217
|
['hr', hr$1],
|
|
210
218
|
['image', image$1],
|
|
219
|
+
['attachment', attachment],
|
|
211
220
|
['codeBlock', codeBlock$1],
|
|
212
221
|
['table', table],
|
|
213
222
|
]);
|
|
@@ -324,12 +333,29 @@ function denormalizeValue(value) {
|
|
|
324
333
|
// Mac: mod+Z returns ⌘+Z
|
|
325
334
|
// Windows / Linux: mod+Z returns Ctrl+Z
|
|
326
335
|
function modifierText(value, userAgent) {
|
|
336
|
+
// for generating i18n files
|
|
337
|
+
if (typeof window === 'undefined') {
|
|
338
|
+
return value;
|
|
339
|
+
}
|
|
327
340
|
userAgent = userAgent !== null && userAgent !== void 0 ? userAgent : navigator.userAgent;
|
|
328
341
|
const isMac = userAgent.indexOf('Mac OS X') >= 0;
|
|
329
342
|
const modText = isMac ? '⌘' : 'Ctrl';
|
|
330
343
|
return value.replace(/(^|\+|\s)mod(\+|\s|$)/g, `$1${modText}$2`);
|
|
331
344
|
}
|
|
332
345
|
|
|
346
|
+
// Returns a human-readable file size string from a number.
|
|
347
|
+
function fileSize(size) {
|
|
348
|
+
const units = ['KB', 'MB', 'GB'];
|
|
349
|
+
let i = 0;
|
|
350
|
+
size /= 1024;
|
|
351
|
+
while (size > 1024 && i < 2) {
|
|
352
|
+
size /= 1024;
|
|
353
|
+
i++;
|
|
354
|
+
}
|
|
355
|
+
const sizeString = size > 0 ? Math.max(size, 0.1).toFixed(1) : 0;
|
|
356
|
+
return `${sizeString} ${units[i]}`;
|
|
357
|
+
}
|
|
358
|
+
|
|
333
359
|
// Returns a property value of all CSS properties of an element
|
|
334
360
|
function getCSS(element, propertyName) {
|
|
335
361
|
const camelPropertyName = camelCase(propertyName);
|
|
@@ -2678,184 +2704,46 @@ function morph(node, otherNode, config = {}) {
|
|
|
2678
2704
|
morphNormalizedContent(node.get(0), normalizedContent, ctx);
|
|
2679
2705
|
}
|
|
2680
2706
|
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
Repository: https://github.com/react-component/upload
|
|
2705
|
-
*/
|
|
2706
|
-
function getError(option, xhr) {
|
|
2707
|
-
const msg = `Cannot ${option.method} ${option.action} ${xhr.status}'`;
|
|
2708
|
-
const err = new Error(msg);
|
|
2709
|
-
err.status = xhr.status;
|
|
2710
|
-
err.method = option.method;
|
|
2711
|
-
err.url = option.action;
|
|
2712
|
-
return err;
|
|
2713
|
-
}
|
|
2714
|
-
function getBody(xhr) {
|
|
2715
|
-
const text = xhr.responseText || xhr.response;
|
|
2716
|
-
if (!text) {
|
|
2717
|
-
return text;
|
|
2718
|
-
}
|
|
2719
|
-
try {
|
|
2720
|
-
return JSON.parse(text);
|
|
2721
|
-
}
|
|
2722
|
-
catch (e) {
|
|
2723
|
-
return text;
|
|
2724
|
-
}
|
|
2725
|
-
}
|
|
2726
|
-
function request(option) {
|
|
2727
|
-
const xhr = new XMLHttpRequest();
|
|
2728
|
-
if (option.onProgress && xhr.upload) {
|
|
2729
|
-
xhr.upload.onprogress = (e) => {
|
|
2730
|
-
if (e.total > 0) {
|
|
2731
|
-
e.percent = (e.loaded / e.total) * 100;
|
|
2732
|
-
}
|
|
2733
|
-
if (option.onProgress) {
|
|
2734
|
-
option.onProgress(e);
|
|
2707
|
+
// Returns an object that indicates the specified node's position relative to the viewport.
|
|
2708
|
+
function nodeAndView(node) {
|
|
2709
|
+
const nativeNode = node.get(0);
|
|
2710
|
+
const rect = nativeNode.getBoundingClientRect();
|
|
2711
|
+
let left = rect.left;
|
|
2712
|
+
let right = rect.right;
|
|
2713
|
+
let top = rect.top;
|
|
2714
|
+
let bottom = rect.bottom;
|
|
2715
|
+
let viewportWidth = window.innerWidth;
|
|
2716
|
+
let viewportHeight = window.innerHeight;
|
|
2717
|
+
const container = node.closestContainer();
|
|
2718
|
+
if (container.length > 0) {
|
|
2719
|
+
const viewport = container.closestScroller();
|
|
2720
|
+
if (viewport.length > 0) {
|
|
2721
|
+
const containerWrapper = container.parent();
|
|
2722
|
+
if (containerWrapper.length > 0) {
|
|
2723
|
+
const nativeContainerWrapper = containerWrapper.get(0);
|
|
2724
|
+
const offsetLeft = nativeContainerWrapper.offsetLeft - window.scrollX;
|
|
2725
|
+
const offsetTop = nativeContainerWrapper.offsetTop - window.scrollY;
|
|
2726
|
+
left -= offsetLeft;
|
|
2727
|
+
right -= offsetLeft;
|
|
2728
|
+
top -= offsetTop;
|
|
2729
|
+
bottom -= offsetTop;
|
|
2735
2730
|
}
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
Object.keys(data).forEach(key => {
|
|
2741
|
-
const value = data[key];
|
|
2742
|
-
// support key-value array data
|
|
2743
|
-
if (Array.isArray(value)) {
|
|
2744
|
-
value.forEach(item => {
|
|
2745
|
-
// { list: [ 11, 22 ] }
|
|
2746
|
-
// formData.append('list[]', 11);
|
|
2747
|
-
formData.append(`${key}[]`, item);
|
|
2748
|
-
});
|
|
2749
|
-
return;
|
|
2731
|
+
const nativeViewport = viewport.get(0);
|
|
2732
|
+
const viewportRect = nativeViewport.getBoundingClientRect();
|
|
2733
|
+
viewportWidth = viewportRect.width;
|
|
2734
|
+
viewportHeight = viewportRect.height;
|
|
2750
2735
|
}
|
|
2751
|
-
formData.append(key, value);
|
|
2752
|
-
});
|
|
2753
|
-
const filename = option.filename || 'file';
|
|
2754
|
-
if (option.file instanceof Blob) {
|
|
2755
|
-
formData.append(filename, option.file, option.file.name);
|
|
2756
|
-
}
|
|
2757
|
-
else {
|
|
2758
|
-
formData.append(filename, option.file);
|
|
2759
2736
|
}
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2737
|
+
const position = {
|
|
2738
|
+
left,
|
|
2739
|
+
right: viewportWidth - right,
|
|
2740
|
+
top,
|
|
2741
|
+
bottom: viewportHeight - bottom,
|
|
2764
2742
|
};
|
|
2765
|
-
|
|
2766
|
-
// allow success when 2xx status
|
|
2767
|
-
// see https://github.com/react-component/upload/issues/34
|
|
2768
|
-
if (xhr.status < 200 || xhr.status >= 300) {
|
|
2769
|
-
if (!option.onError) {
|
|
2770
|
-
return;
|
|
2771
|
-
}
|
|
2772
|
-
return option.onError(getError(option, xhr), getBody(xhr));
|
|
2773
|
-
}
|
|
2774
|
-
if (!option.onSuccess) {
|
|
2775
|
-
return;
|
|
2776
|
-
}
|
|
2777
|
-
return option.onSuccess(getBody(xhr), xhr);
|
|
2778
|
-
};
|
|
2779
|
-
xhr.open(option.method, option.action, true);
|
|
2780
|
-
// Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179
|
|
2781
|
-
if (option.withCredentials && 'withCredentials' in xhr) {
|
|
2782
|
-
xhr.withCredentials = true;
|
|
2783
|
-
}
|
|
2784
|
-
const headers = option.headers || {};
|
|
2785
|
-
// when set headers['X-Requested-With'] = null , can close default XHR header
|
|
2786
|
-
// see https://github.com/react-component/upload/issues/33
|
|
2787
|
-
if (headers['X-Requested-With'] !== null) {
|
|
2788
|
-
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
2789
|
-
}
|
|
2790
|
-
Object.keys(headers).forEach(h => {
|
|
2791
|
-
if (headers[h] !== null) {
|
|
2792
|
-
xhr.setRequestHeader(h, headers[h]);
|
|
2793
|
-
}
|
|
2794
|
-
});
|
|
2795
|
-
xhr.send(formData);
|
|
2796
|
-
return xhr;
|
|
2743
|
+
return position;
|
|
2797
2744
|
}
|
|
2798
2745
|
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
var index = /*#__PURE__*/Object.freeze({
|
|
2802
|
-
__proto__: null,
|
|
2803
|
-
appendDeepest: appendDeepest,
|
|
2804
|
-
camelCase: camelCase,
|
|
2805
|
-
changeTagName: changeTagName,
|
|
2806
|
-
debug: debug,
|
|
2807
|
-
denormalizeValue: denormalizeValue,
|
|
2808
|
-
encode: encode,
|
|
2809
|
-
fixNumberedList: fixNumberedList,
|
|
2810
|
-
getCSS: getCSS,
|
|
2811
|
-
getDeepest: getDeepest,
|
|
2812
|
-
inString: inString,
|
|
2813
|
-
mergeNodes: mergeNodes,
|
|
2814
|
-
modifierText: modifierText,
|
|
2815
|
-
morph: morph,
|
|
2816
|
-
normalizeValue: normalizeValue,
|
|
2817
|
-
parseStyle: parseStyle,
|
|
2818
|
-
query: query,
|
|
2819
|
-
removeBr: removeBr,
|
|
2820
|
-
removeZWS: removeZWS,
|
|
2821
|
-
request: request,
|
|
2822
|
-
safeTemplate: safeTemplate,
|
|
2823
|
-
setBlockIndent: setBlockIndent,
|
|
2824
|
-
splitNodes: splitNodes,
|
|
2825
|
-
template: template,
|
|
2826
|
-
toHex: toHex,
|
|
2827
|
-
toNodeList: toNodeList,
|
|
2828
|
-
wrapNodeList: wrapNodeList
|
|
2829
|
-
});
|
|
2830
|
-
|
|
2831
|
-
class Fragment {
|
|
2832
|
-
constructor(fragment) {
|
|
2833
|
-
this.fragment = fragment !== null && fragment !== void 0 ? fragment : document.createDocumentFragment();
|
|
2834
|
-
}
|
|
2835
|
-
// Returns the descendants of the fragment which are selected by the specified CSS selector.
|
|
2836
|
-
find(selector) {
|
|
2837
|
-
const nodeList = [];
|
|
2838
|
-
let child = new Nodes(this.fragment.firstChild);
|
|
2839
|
-
while (child.length > 0) {
|
|
2840
|
-
if (child.matches(selector)) {
|
|
2841
|
-
nodeList.push(child.get(0));
|
|
2842
|
-
}
|
|
2843
|
-
else if (child.isElement) {
|
|
2844
|
-
child.find(selector).each(node => {
|
|
2845
|
-
nodeList.push(node);
|
|
2846
|
-
});
|
|
2847
|
-
}
|
|
2848
|
-
child = child.next();
|
|
2849
|
-
}
|
|
2850
|
-
return new Nodes(nodeList);
|
|
2851
|
-
}
|
|
2852
|
-
// Inserts the specified node as the last child.
|
|
2853
|
-
append(node) {
|
|
2854
|
-
node.each(nativeNode => {
|
|
2855
|
-
this.fragment.appendChild(nativeNode);
|
|
2856
|
-
});
|
|
2857
|
-
}
|
|
2858
|
-
}
|
|
2746
|
+
const boxInstances = new Map();
|
|
2859
2747
|
|
|
2860
2748
|
const boxes = new Map();
|
|
2861
2749
|
|
|
@@ -2867,7 +2755,7 @@ const boxData = {};
|
|
|
2867
2755
|
const effectData = {};
|
|
2868
2756
|
const framework = safeTemplate `
|
|
2869
2757
|
<span class="lake-box-strip"><br /></span>
|
|
2870
|
-
<div class="lake-box-container" contenteditable="false"
|
|
2758
|
+
<div class="lake-box-container" contenteditable="false"></div>
|
|
2871
2759
|
<span class="lake-box-strip"><br /></span>
|
|
2872
2760
|
`;
|
|
2873
2761
|
class Box {
|
|
@@ -2932,6 +2820,9 @@ class Box {
|
|
|
2932
2820
|
debug(`Box '${this.name}' (id = ${this.node.id}) value:`);
|
|
2933
2821
|
debug(this.value);
|
|
2934
2822
|
});
|
|
2823
|
+
if (this.type === 'block') {
|
|
2824
|
+
container.attr('draggable', 'true');
|
|
2825
|
+
}
|
|
2935
2826
|
}
|
|
2936
2827
|
// Returns the type of the box.
|
|
2937
2828
|
get type() {
|
|
@@ -3009,28 +2900,235 @@ class Box {
|
|
|
3009
2900
|
}
|
|
3010
2901
|
debug(`Box '${this.name}' (id = ${this.node.id}) rendered`);
|
|
3011
2902
|
}
|
|
3012
|
-
// Destroys a rendered box.
|
|
3013
|
-
unmount() {
|
|
3014
|
-
|
|
3015
|
-
|
|
2903
|
+
// Destroys a rendered box.
|
|
2904
|
+
unmount() {
|
|
2905
|
+
this.event.emit('blur');
|
|
2906
|
+
for (const cleanup of effectData[this.node.id].cleanup) {
|
|
2907
|
+
cleanup();
|
|
2908
|
+
}
|
|
2909
|
+
boxData[this.node.id] = {};
|
|
2910
|
+
effectData[this.node.id].setup = [];
|
|
2911
|
+
effectData[this.node.id].cleanup = [];
|
|
2912
|
+
this.event.removeAllListeners();
|
|
2913
|
+
this.node.empty();
|
|
2914
|
+
debug(`Box '${this.name}' (id = ${this.node.id}) unmounted`);
|
|
2915
|
+
}
|
|
2916
|
+
// Returns a HTML string of the box.
|
|
2917
|
+
getHTML() {
|
|
2918
|
+
const component = boxes.get(this.name);
|
|
2919
|
+
if (component === undefined) {
|
|
2920
|
+
return '';
|
|
2921
|
+
}
|
|
2922
|
+
if (component.html === undefined) {
|
|
2923
|
+
return this.node.outerHTML();
|
|
2924
|
+
}
|
|
2925
|
+
return component.html(this);
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2929
|
+
// Returns an already generated box instance or generates a new instance if it does not exist.
|
|
2930
|
+
function getBox(boxNode) {
|
|
2931
|
+
if (typeof boxNode === 'string') {
|
|
2932
|
+
return new Box(boxNode);
|
|
2933
|
+
}
|
|
2934
|
+
boxNode = query(boxNode);
|
|
2935
|
+
const container = boxNode.closestContainer();
|
|
2936
|
+
if (container.length === 0) {
|
|
2937
|
+
return new Box(boxNode);
|
|
2938
|
+
}
|
|
2939
|
+
let instanceMap = boxInstances.get(container.id);
|
|
2940
|
+
if (!instanceMap) {
|
|
2941
|
+
instanceMap = new Map();
|
|
2942
|
+
boxInstances.set(container.id, instanceMap);
|
|
2943
|
+
}
|
|
2944
|
+
let box = instanceMap.get(boxNode.id);
|
|
2945
|
+
if (box) {
|
|
2946
|
+
return box;
|
|
2947
|
+
}
|
|
2948
|
+
box = new Box(boxNode);
|
|
2949
|
+
instanceMap.set(box.node.id, box);
|
|
2950
|
+
return box;
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
/**
|
|
2954
|
+
The MIT License (MIT)
|
|
2955
|
+
|
|
2956
|
+
Copyright (c) 2016-present react-component
|
|
2957
|
+
|
|
2958
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
2959
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
2960
|
+
in the Software without restriction, including without limitation the rights
|
|
2961
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
2962
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
2963
|
+
furnished to do so, subject to the following conditions:
|
|
2964
|
+
|
|
2965
|
+
The above copyright notice and this permission notice shall be included in
|
|
2966
|
+
all copies or substantial portions of the Software.
|
|
2967
|
+
|
|
2968
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
2969
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
2970
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
2971
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
2972
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
2973
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
2974
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
2975
|
+
|
|
2976
|
+
Repository: https://github.com/react-component/upload
|
|
2977
|
+
*/
|
|
2978
|
+
function getError(option, xhr) {
|
|
2979
|
+
const msg = `Cannot ${option.method} ${option.action} ${xhr.status}'`;
|
|
2980
|
+
const err = new Error(msg);
|
|
2981
|
+
err.status = xhr.status;
|
|
2982
|
+
err.method = option.method;
|
|
2983
|
+
err.url = option.action;
|
|
2984
|
+
return err;
|
|
2985
|
+
}
|
|
2986
|
+
function getBody(xhr) {
|
|
2987
|
+
const text = xhr.responseText || xhr.response;
|
|
2988
|
+
if (!text) {
|
|
2989
|
+
return text;
|
|
2990
|
+
}
|
|
2991
|
+
try {
|
|
2992
|
+
return JSON.parse(text);
|
|
2993
|
+
}
|
|
2994
|
+
catch (e) {
|
|
2995
|
+
return text;
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
function request(option) {
|
|
2999
|
+
const xhr = new XMLHttpRequest();
|
|
3000
|
+
if (option.onProgress && xhr.upload) {
|
|
3001
|
+
xhr.upload.onprogress = (e) => {
|
|
3002
|
+
if (e.total > 0) {
|
|
3003
|
+
e.percent = (e.loaded / e.total) * 100;
|
|
3004
|
+
}
|
|
3005
|
+
if (option.onProgress) {
|
|
3006
|
+
option.onProgress(e);
|
|
3007
|
+
}
|
|
3008
|
+
};
|
|
3009
|
+
}
|
|
3010
|
+
const formData = new FormData();
|
|
3011
|
+
const data = option.data || {};
|
|
3012
|
+
Object.keys(data).forEach(key => {
|
|
3013
|
+
const value = data[key];
|
|
3014
|
+
// support key-value array data
|
|
3015
|
+
if (Array.isArray(value)) {
|
|
3016
|
+
value.forEach(item => {
|
|
3017
|
+
// { list: [ 11, 22 ] }
|
|
3018
|
+
// formData.append('list[]', 11);
|
|
3019
|
+
formData.append(`${key}[]`, item);
|
|
3020
|
+
});
|
|
3021
|
+
return;
|
|
3022
|
+
}
|
|
3023
|
+
formData.append(key, value);
|
|
3024
|
+
});
|
|
3025
|
+
const filename = option.filename || 'file';
|
|
3026
|
+
if (option.file instanceof Blob) {
|
|
3027
|
+
formData.append(filename, option.file, option.file.name);
|
|
3028
|
+
}
|
|
3029
|
+
else {
|
|
3030
|
+
formData.append(filename, option.file);
|
|
3031
|
+
}
|
|
3032
|
+
xhr.onerror = (e) => {
|
|
3033
|
+
if (option.onError) {
|
|
3034
|
+
option.onError(e);
|
|
3035
|
+
}
|
|
3036
|
+
};
|
|
3037
|
+
xhr.onload = () => {
|
|
3038
|
+
// allow success when 2xx status
|
|
3039
|
+
// see https://github.com/react-component/upload/issues/34
|
|
3040
|
+
if (xhr.status < 200 || xhr.status >= 300) {
|
|
3041
|
+
if (!option.onError) {
|
|
3042
|
+
return;
|
|
3043
|
+
}
|
|
3044
|
+
return option.onError(getError(option, xhr), getBody(xhr));
|
|
3045
|
+
}
|
|
3046
|
+
if (!option.onSuccess) {
|
|
3047
|
+
return;
|
|
3048
|
+
}
|
|
3049
|
+
return option.onSuccess(getBody(xhr), xhr);
|
|
3050
|
+
};
|
|
3051
|
+
xhr.open(option.method, option.action, true);
|
|
3052
|
+
// Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179
|
|
3053
|
+
if (option.withCredentials && 'withCredentials' in xhr) {
|
|
3054
|
+
xhr.withCredentials = true;
|
|
3055
|
+
}
|
|
3056
|
+
const headers = option.headers || {};
|
|
3057
|
+
// when set headers['X-Requested-With'] = null , can close default XHR header
|
|
3058
|
+
// see https://github.com/react-component/upload/issues/33
|
|
3059
|
+
if (headers['X-Requested-With'] !== null) {
|
|
3060
|
+
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
3061
|
+
}
|
|
3062
|
+
Object.keys(headers).forEach(h => {
|
|
3063
|
+
if (headers[h] !== null) {
|
|
3064
|
+
xhr.setRequestHeader(h, headers[h]);
|
|
3065
|
+
}
|
|
3066
|
+
});
|
|
3067
|
+
xhr.send(formData);
|
|
3068
|
+
return xhr;
|
|
3069
|
+
}
|
|
3070
|
+
|
|
3071
|
+
// String
|
|
3072
|
+
|
|
3073
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
3074
|
+
__proto__: null,
|
|
3075
|
+
appendDeepest: appendDeepest,
|
|
3076
|
+
camelCase: camelCase,
|
|
3077
|
+
changeTagName: changeTagName,
|
|
3078
|
+
debug: debug,
|
|
3079
|
+
denormalizeValue: denormalizeValue,
|
|
3080
|
+
encode: encode,
|
|
3081
|
+
fileSize: fileSize,
|
|
3082
|
+
fixNumberedList: fixNumberedList,
|
|
3083
|
+
getBox: getBox,
|
|
3084
|
+
getCSS: getCSS,
|
|
3085
|
+
getDeepest: getDeepest,
|
|
3086
|
+
inString: inString,
|
|
3087
|
+
mergeNodes: mergeNodes,
|
|
3088
|
+
modifierText: modifierText,
|
|
3089
|
+
morph: morph,
|
|
3090
|
+
nodeAndView: nodeAndView,
|
|
3091
|
+
normalizeValue: normalizeValue,
|
|
3092
|
+
parseStyle: parseStyle,
|
|
3093
|
+
query: query,
|
|
3094
|
+
removeBr: removeBr,
|
|
3095
|
+
removeZWS: removeZWS,
|
|
3096
|
+
request: request,
|
|
3097
|
+
safeTemplate: safeTemplate,
|
|
3098
|
+
setBlockIndent: setBlockIndent,
|
|
3099
|
+
splitNodes: splitNodes,
|
|
3100
|
+
template: template,
|
|
3101
|
+
toHex: toHex,
|
|
3102
|
+
toNodeList: toNodeList,
|
|
3103
|
+
wrapNodeList: wrapNodeList
|
|
3104
|
+
});
|
|
3105
|
+
|
|
3106
|
+
class Fragment {
|
|
3107
|
+
constructor(fragment) {
|
|
3108
|
+
this.fragment = fragment !== null && fragment !== void 0 ? fragment : document.createDocumentFragment();
|
|
3109
|
+
}
|
|
3110
|
+
// Returns the descendants of the fragment which are selected by the specified CSS selector.
|
|
3111
|
+
find(selector) {
|
|
3112
|
+
const nodeList = [];
|
|
3113
|
+
let child = new Nodes(this.fragment.firstChild);
|
|
3114
|
+
while (child.length > 0) {
|
|
3115
|
+
if (child.matches(selector)) {
|
|
3116
|
+
nodeList.push(child.get(0));
|
|
3117
|
+
}
|
|
3118
|
+
else if (child.isElement) {
|
|
3119
|
+
child.find(selector).each(node => {
|
|
3120
|
+
nodeList.push(node);
|
|
3121
|
+
});
|
|
3122
|
+
}
|
|
3123
|
+
child = child.next();
|
|
3016
3124
|
}
|
|
3017
|
-
|
|
3018
|
-
effectData[this.node.id].setup = [];
|
|
3019
|
-
effectData[this.node.id].cleanup = [];
|
|
3020
|
-
this.event.removeAllListeners();
|
|
3021
|
-
this.node.empty();
|
|
3022
|
-
debug(`Box '${this.name}' (id = ${this.node.id}) unmounted`);
|
|
3125
|
+
return new Nodes(nodeList);
|
|
3023
3126
|
}
|
|
3024
|
-
//
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
}
|
|
3030
|
-
if (component.html === undefined) {
|
|
3031
|
-
return this.node.outerHTML();
|
|
3032
|
-
}
|
|
3033
|
-
return component.html(this);
|
|
3127
|
+
// Inserts the specified node as the last child.
|
|
3128
|
+
append(node) {
|
|
3129
|
+
node.each(nativeNode => {
|
|
3130
|
+
this.fragment.appendChild(nativeNode);
|
|
3131
|
+
});
|
|
3034
3132
|
}
|
|
3035
3133
|
}
|
|
3036
3134
|
|
|
@@ -3440,7 +3538,7 @@ function toBookmark(range, bookmark) {
|
|
|
3440
3538
|
}
|
|
3441
3539
|
if (focus.length > 0 && anchor.length === 0) {
|
|
3442
3540
|
if (focus.isBox) {
|
|
3443
|
-
const box =
|
|
3541
|
+
const box = getBox(focus);
|
|
3444
3542
|
if (box.getContainer().length === 0) {
|
|
3445
3543
|
box.render();
|
|
3446
3544
|
}
|
|
@@ -3861,7 +3959,7 @@ function addMark(range, value) {
|
|
|
3861
3959
|
if (range.isCollapsed) {
|
|
3862
3960
|
if (range.isBox) {
|
|
3863
3961
|
const boxNode = range.startNode.closest('lake-box');
|
|
3864
|
-
const box =
|
|
3962
|
+
const box = getBox(boxNode);
|
|
3865
3963
|
if (box.type === 'block') {
|
|
3866
3964
|
const newBlock = query('<p><br /></p>');
|
|
3867
3965
|
if (range.isBoxStart) {
|
|
@@ -4160,6 +4258,7 @@ var enUS = {
|
|
|
4160
4258
|
fontColor: 'Font color',
|
|
4161
4259
|
highlight: 'Highlight',
|
|
4162
4260
|
image: 'Image',
|
|
4261
|
+
file: 'File',
|
|
4163
4262
|
removeColor: 'Remove color',
|
|
4164
4263
|
},
|
|
4165
4264
|
link: {
|
|
@@ -4181,6 +4280,10 @@ var enUS = {
|
|
|
4181
4280
|
zoomOut: 'Zoom out',
|
|
4182
4281
|
zoomIn: 'Zoom in',
|
|
4183
4282
|
},
|
|
4283
|
+
file: {
|
|
4284
|
+
download: 'Download',
|
|
4285
|
+
remove: 'Delete',
|
|
4286
|
+
},
|
|
4184
4287
|
codeBlock: {
|
|
4185
4288
|
langType: 'Select language',
|
|
4186
4289
|
},
|
|
@@ -4230,6 +4333,7 @@ var zhCN = {
|
|
|
4230
4333
|
fontColor: '文字颜色',
|
|
4231
4334
|
highlight: '文字背景',
|
|
4232
4335
|
image: '图片',
|
|
4336
|
+
file: '文件',
|
|
4233
4337
|
removeColor: '默认',
|
|
4234
4338
|
},
|
|
4235
4339
|
link: {
|
|
@@ -4251,6 +4355,10 @@ var zhCN = {
|
|
|
4251
4355
|
zoomOut: '缩小',
|
|
4252
4356
|
zoomIn: '放大',
|
|
4253
4357
|
},
|
|
4358
|
+
file: {
|
|
4359
|
+
download: '下载',
|
|
4360
|
+
remove: '删除',
|
|
4361
|
+
},
|
|
4254
4362
|
codeBlock: {
|
|
4255
4363
|
langType: '选择代码语言',
|
|
4256
4364
|
},
|
|
@@ -4300,6 +4408,7 @@ var ja = {
|
|
|
4300
4408
|
fontColor: '文字色',
|
|
4301
4409
|
highlight: '文字の背景',
|
|
4302
4410
|
image: '画像',
|
|
4411
|
+
file: 'ファイル',
|
|
4303
4412
|
removeColor: 'デフォルト',
|
|
4304
4413
|
},
|
|
4305
4414
|
link: {
|
|
@@ -4321,6 +4430,10 @@ var ja = {
|
|
|
4321
4430
|
zoomOut: '縮小',
|
|
4322
4431
|
zoomIn: '拡大',
|
|
4323
4432
|
},
|
|
4433
|
+
file: {
|
|
4434
|
+
download: 'ダウンロード',
|
|
4435
|
+
remove: '削除',
|
|
4436
|
+
},
|
|
4324
4437
|
codeBlock: {
|
|
4325
4438
|
langType: 'コード言語を選択',
|
|
4326
4439
|
},
|
|
@@ -4370,6 +4483,7 @@ var ko = {
|
|
|
4370
4483
|
fontColor: '글자 색상',
|
|
4371
4484
|
highlight: '글자 배경',
|
|
4372
4485
|
image: '이미지',
|
|
4486
|
+
file: '파일',
|
|
4373
4487
|
removeColor: '기본색',
|
|
4374
4488
|
},
|
|
4375
4489
|
link: {
|
|
@@ -4391,6 +4505,10 @@ var ko = {
|
|
|
4391
4505
|
zoomOut: '축소',
|
|
4392
4506
|
zoomIn: '확대',
|
|
4393
4507
|
},
|
|
4508
|
+
file: {
|
|
4509
|
+
download: '다운로드',
|
|
4510
|
+
remove: '삭제',
|
|
4511
|
+
},
|
|
4394
4512
|
codeBlock: {
|
|
4395
4513
|
langType: '코드언어 선택',
|
|
4396
4514
|
},
|
|
@@ -4673,14 +4791,14 @@ class Dropdown {
|
|
|
4673
4791
|
}
|
|
4674
4792
|
}
|
|
4675
4793
|
|
|
4676
|
-
var version = "0.1.
|
|
4794
|
+
var version = "0.1.9";
|
|
4677
4795
|
|
|
4678
4796
|
// Inserts a box into the specified range.
|
|
4679
4797
|
function insertBox(range, boxName, boxValue) {
|
|
4680
4798
|
if (range.commonAncestor.isOutside) {
|
|
4681
4799
|
return null;
|
|
4682
4800
|
}
|
|
4683
|
-
const box =
|
|
4801
|
+
const box = getBox(boxName);
|
|
4684
4802
|
if (boxValue) {
|
|
4685
4803
|
box.value = boxValue;
|
|
4686
4804
|
}
|
|
@@ -4719,7 +4837,7 @@ function removeBox(range) {
|
|
|
4719
4837
|
if (boxNode.length === 0) {
|
|
4720
4838
|
return null;
|
|
4721
4839
|
}
|
|
4722
|
-
const box =
|
|
4840
|
+
const box = getBox(boxNode);
|
|
4723
4841
|
if (box.type === 'block') {
|
|
4724
4842
|
const paragraph = query('<p><br /></p>');
|
|
4725
4843
|
boxNode.before(paragraph);
|
|
@@ -4823,20 +4941,20 @@ class Selection {
|
|
|
4823
4941
|
return new Range();
|
|
4824
4942
|
}
|
|
4825
4943
|
// Adds the saved range to the native selection.
|
|
4826
|
-
|
|
4944
|
+
sync() {
|
|
4827
4945
|
this.selection.removeAllRanges();
|
|
4828
4946
|
this.selection.addRange(this.range.get());
|
|
4829
4947
|
}
|
|
4830
|
-
//
|
|
4831
|
-
|
|
4948
|
+
// Updates the saved range with the range of the native selection.
|
|
4949
|
+
updateByRange() {
|
|
4832
4950
|
const newRange = this.getRangeFromNativeSelection();
|
|
4833
4951
|
if (this.range.get() === newRange.get()) {
|
|
4834
4952
|
return;
|
|
4835
4953
|
}
|
|
4836
4954
|
this.range = newRange;
|
|
4837
4955
|
}
|
|
4838
|
-
//
|
|
4839
|
-
|
|
4956
|
+
// Updates the saved range with the range represented by the bookmark.
|
|
4957
|
+
updateByBookmark() {
|
|
4840
4958
|
const range = this.range;
|
|
4841
4959
|
const container = this.container;
|
|
4842
4960
|
const boxFocus = container.find('lake-box[focus]');
|
|
@@ -4845,7 +4963,7 @@ class Selection {
|
|
|
4845
4963
|
anchor: new Nodes(),
|
|
4846
4964
|
focus: boxFocus,
|
|
4847
4965
|
});
|
|
4848
|
-
this.
|
|
4966
|
+
this.sync();
|
|
4849
4967
|
return;
|
|
4850
4968
|
}
|
|
4851
4969
|
const anchor = container.find('lake-bookmark[type="anchor"]');
|
|
@@ -4854,7 +4972,7 @@ class Selection {
|
|
|
4854
4972
|
anchor,
|
|
4855
4973
|
focus,
|
|
4856
4974
|
});
|
|
4857
|
-
this.
|
|
4975
|
+
this.sync();
|
|
4858
4976
|
}
|
|
4859
4977
|
getAppliedItems() {
|
|
4860
4978
|
const appliedItems = [];
|
|
@@ -4961,8 +5079,6 @@ class Command {
|
|
|
4961
5079
|
}
|
|
4962
5080
|
}
|
|
4963
5081
|
|
|
4964
|
-
const boxInstances = new Map();
|
|
4965
|
-
|
|
4966
5082
|
// Saves and controls the history of the value of the editor.
|
|
4967
5083
|
// Example:
|
|
4968
5084
|
// before initialization: value: 'a', list: [], index: 0, canUndo: false
|
|
@@ -5040,7 +5156,7 @@ class History {
|
|
|
5040
5156
|
const range = this.selection.range;
|
|
5041
5157
|
const newContainer = this.container.clone(true);
|
|
5042
5158
|
newContainer.find('lake-box').each(nativeNode => {
|
|
5043
|
-
const box =
|
|
5159
|
+
const box = getBox(nativeNode);
|
|
5044
5160
|
box.getContainer().empty();
|
|
5045
5161
|
});
|
|
5046
5162
|
if (range.commonAncestor.isOutside) {
|
|
@@ -5090,7 +5206,7 @@ class History {
|
|
|
5090
5206
|
}
|
|
5091
5207
|
this.index--;
|
|
5092
5208
|
}
|
|
5093
|
-
this.selection.
|
|
5209
|
+
this.selection.updateByBookmark();
|
|
5094
5210
|
debug(`History undone, the last index is ${this.index}`);
|
|
5095
5211
|
}
|
|
5096
5212
|
redo() {
|
|
@@ -5112,7 +5228,7 @@ class History {
|
|
|
5112
5228
|
break;
|
|
5113
5229
|
}
|
|
5114
5230
|
}
|
|
5115
|
-
this.selection.
|
|
5231
|
+
this.selection.updateByBookmark();
|
|
5116
5232
|
debug(`History redone, the last index is ${this.index}`);
|
|
5117
5233
|
}
|
|
5118
5234
|
continue() {
|
|
@@ -5219,17 +5335,17 @@ class BoxManager {
|
|
|
5219
5335
|
getNames() {
|
|
5220
5336
|
return Array.from(boxes.keys());
|
|
5221
5337
|
}
|
|
5222
|
-
getInstances(
|
|
5223
|
-
let instanceMap = boxInstances.get(
|
|
5338
|
+
getInstances(container) {
|
|
5339
|
+
let instanceMap = boxInstances.get(container.id);
|
|
5224
5340
|
if (!instanceMap) {
|
|
5225
5341
|
instanceMap = new Map();
|
|
5226
|
-
boxInstances.set(
|
|
5342
|
+
boxInstances.set(container.id, instanceMap);
|
|
5227
5343
|
return instanceMap;
|
|
5228
5344
|
}
|
|
5229
5345
|
return instanceMap;
|
|
5230
5346
|
}
|
|
5231
|
-
rectifyInstances(
|
|
5232
|
-
const instanceMap = this.getInstances(
|
|
5347
|
+
rectifyInstances(container) {
|
|
5348
|
+
const instanceMap = this.getInstances(container);
|
|
5233
5349
|
for (const box of instanceMap.values()) {
|
|
5234
5350
|
if (!box.node.get(0).isConnected) {
|
|
5235
5351
|
box.unmount();
|
|
@@ -5237,20 +5353,16 @@ class BoxManager {
|
|
|
5237
5353
|
}
|
|
5238
5354
|
}
|
|
5239
5355
|
}
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
const instanceMap = this.getInstances(editor);
|
|
5246
|
-
this.findAll(editor).each(boxNativeNode => {
|
|
5247
|
-
const boxNode = new Nodes(boxNativeNode);
|
|
5356
|
+
renderAll(container) {
|
|
5357
|
+
this.rectifyInstances(container);
|
|
5358
|
+
const instanceMap = this.getInstances(container);
|
|
5359
|
+
container.find('lake-box').each(boxNativeNode => {
|
|
5360
|
+
const boxNode = query(boxNativeNode);
|
|
5248
5361
|
if (instanceMap.get(boxNode.id)) {
|
|
5249
5362
|
return;
|
|
5250
5363
|
}
|
|
5251
|
-
const box =
|
|
5364
|
+
const box = getBox(boxNode);
|
|
5252
5365
|
box.render();
|
|
5253
|
-
instanceMap.set(box.node.id, box);
|
|
5254
5366
|
});
|
|
5255
5367
|
}
|
|
5256
5368
|
}
|
|
@@ -5278,6 +5390,22 @@ const defaultConfig = {
|
|
|
5278
5390
|
indentWithTab: true,
|
|
5279
5391
|
lang: 'en-US',
|
|
5280
5392
|
minChangeSize: 5,
|
|
5393
|
+
onMessage: (type, message) => {
|
|
5394
|
+
if (type === 'success') {
|
|
5395
|
+
// eslint-disable-next-line no-console
|
|
5396
|
+
console.log(message);
|
|
5397
|
+
return;
|
|
5398
|
+
}
|
|
5399
|
+
if (type === 'warning') {
|
|
5400
|
+
// eslint-disable-next-line no-console
|
|
5401
|
+
console.warn(message);
|
|
5402
|
+
return;
|
|
5403
|
+
}
|
|
5404
|
+
if (type === 'error') {
|
|
5405
|
+
// eslint-disable-next-line no-console
|
|
5406
|
+
console.error(message);
|
|
5407
|
+
}
|
|
5408
|
+
},
|
|
5281
5409
|
};
|
|
5282
5410
|
class Editor {
|
|
5283
5411
|
constructor(config) {
|
|
@@ -5316,13 +5444,13 @@ class Editor {
|
|
|
5316
5444
|
this.history.save();
|
|
5317
5445
|
};
|
|
5318
5446
|
this.selectionchangeListener = () => {
|
|
5319
|
-
this.selection.
|
|
5447
|
+
this.selection.updateByRange();
|
|
5320
5448
|
this.updateBoxSelectionStyle();
|
|
5321
5449
|
this.emitStateChangeEvent();
|
|
5322
5450
|
};
|
|
5323
5451
|
this.clickListener = event => {
|
|
5324
5452
|
const targetNode = new Nodes(event.target);
|
|
5325
|
-
if (targetNode.closest('.lake-popup').length > 0) {
|
|
5453
|
+
if (!targetNode.get(0).isConnected || targetNode.closest('.lake-popup').length > 0) {
|
|
5326
5454
|
return;
|
|
5327
5455
|
}
|
|
5328
5456
|
this.event.emit('click', targetNode);
|
|
@@ -5338,8 +5466,8 @@ class Editor {
|
|
|
5338
5466
|
const range = this.selection.range;
|
|
5339
5467
|
const clonedRange = range.clone();
|
|
5340
5468
|
clonedRange.adaptBox();
|
|
5341
|
-
this.
|
|
5342
|
-
const box =
|
|
5469
|
+
this.container.find('lake-box').each(boxNativeNode => {
|
|
5470
|
+
const box = getBox(boxNativeNode);
|
|
5343
5471
|
const boxContainer = box.getContainer();
|
|
5344
5472
|
if (boxContainer.length === 0) {
|
|
5345
5473
|
return;
|
|
@@ -5350,6 +5478,7 @@ class Editor {
|
|
|
5350
5478
|
boxContainer.removeClass('lake-box-selected');
|
|
5351
5479
|
boxContainer.removeClass('lake-box-focused');
|
|
5352
5480
|
boxContainer.addClass('lake-box-activated');
|
|
5481
|
+
box.event.emit('focus');
|
|
5353
5482
|
return;
|
|
5354
5483
|
}
|
|
5355
5484
|
}
|
|
@@ -5359,16 +5488,19 @@ class Editor {
|
|
|
5359
5488
|
boxContainer.removeClass('lake-box-hovered');
|
|
5360
5489
|
boxContainer.removeClass('lake-box-selected');
|
|
5361
5490
|
boxContainer.addClass('lake-box-focused');
|
|
5491
|
+
box.event.emit('focus');
|
|
5362
5492
|
}
|
|
5363
5493
|
else {
|
|
5364
5494
|
boxContainer.removeClass('lake-box-focused');
|
|
5365
5495
|
boxContainer.addClass('lake-box-selected');
|
|
5496
|
+
box.event.emit('blur');
|
|
5366
5497
|
}
|
|
5367
5498
|
return;
|
|
5368
5499
|
}
|
|
5369
5500
|
boxContainer.removeClass('lake-box-activated');
|
|
5370
5501
|
boxContainer.removeClass('lake-box-focused');
|
|
5371
5502
|
boxContainer.removeClass('lake-box-selected');
|
|
5503
|
+
box.event.emit('blur');
|
|
5372
5504
|
});
|
|
5373
5505
|
this.event.emit('boxselectionstylechange');
|
|
5374
5506
|
}, 50, {
|
|
@@ -5473,7 +5605,7 @@ class Editor {
|
|
|
5473
5605
|
const range = selection.range;
|
|
5474
5606
|
const stripNode = range.startNode.closest('.lake-box-strip');
|
|
5475
5607
|
const boxNode = stripNode.closest('lake-box');
|
|
5476
|
-
const box =
|
|
5608
|
+
const box = getBox(boxNode);
|
|
5477
5609
|
if (box.type === 'inline') {
|
|
5478
5610
|
if (range.isBoxStart) {
|
|
5479
5611
|
range.setStartBefore(boxNode);
|
|
@@ -5555,15 +5687,15 @@ class Editor {
|
|
|
5555
5687
|
}
|
|
5556
5688
|
bindHistoryEvents() {
|
|
5557
5689
|
this.history.event.on('undo', value => {
|
|
5558
|
-
this.box.renderAll(this);
|
|
5690
|
+
this.box.renderAll(this.container);
|
|
5559
5691
|
this.emitChangeEvent(value);
|
|
5560
5692
|
});
|
|
5561
5693
|
this.history.event.on('redo', value => {
|
|
5562
|
-
this.box.renderAll(this);
|
|
5694
|
+
this.box.renderAll(this.container);
|
|
5563
5695
|
this.emitChangeEvent(value);
|
|
5564
5696
|
});
|
|
5565
5697
|
this.history.event.on('save', value => {
|
|
5566
|
-
this.box.rectifyInstances(this);
|
|
5698
|
+
this.box.rectifyInstances(this.container);
|
|
5567
5699
|
this.emitChangeEvent(value);
|
|
5568
5700
|
});
|
|
5569
5701
|
}
|
|
@@ -5710,8 +5842,8 @@ class Editor {
|
|
|
5710
5842
|
this.container.empty();
|
|
5711
5843
|
this.togglePlaceholderClass(htmlParser.getHTML());
|
|
5712
5844
|
this.container.append(fragment);
|
|
5713
|
-
Editor.box.renderAll(this);
|
|
5714
|
-
this.selection.
|
|
5845
|
+
Editor.box.renderAll(this.container);
|
|
5846
|
+
this.selection.updateByBookmark();
|
|
5715
5847
|
}
|
|
5716
5848
|
// Returns the contents from the editor.
|
|
5717
5849
|
getValue() {
|
|
@@ -5721,21 +5853,35 @@ class Editor {
|
|
|
5721
5853
|
this.selection.toBookmark(bookmark);
|
|
5722
5854
|
return value;
|
|
5723
5855
|
}
|
|
5856
|
+
// Sets the current range to the center position of the box.
|
|
5857
|
+
selectBox(box) {
|
|
5858
|
+
let boxNode = box;
|
|
5859
|
+
if (box instanceof Box) {
|
|
5860
|
+
boxNode = box.node;
|
|
5861
|
+
}
|
|
5862
|
+
else {
|
|
5863
|
+
boxNode = box;
|
|
5864
|
+
}
|
|
5865
|
+
this.selection.range.selectBox(boxNode);
|
|
5866
|
+
}
|
|
5724
5867
|
// Inserts a box into the position of the selection.
|
|
5725
5868
|
insertBox(boxName, boxValue) {
|
|
5726
5869
|
const box = insertBox(this.selection.range, boxName, boxValue);
|
|
5727
5870
|
if (!box) {
|
|
5728
5871
|
throw new Error(`Box '${boxName}' cannot be inserted outside the editor.`);
|
|
5729
5872
|
}
|
|
5730
|
-
const instanceMap = this.box.getInstances(this);
|
|
5873
|
+
const instanceMap = this.box.getInstances(this.container);
|
|
5731
5874
|
instanceMap.set(box.node.id, box);
|
|
5732
5875
|
return box;
|
|
5733
5876
|
}
|
|
5734
5877
|
// Removes the selected box.
|
|
5735
|
-
removeBox() {
|
|
5736
|
-
|
|
5878
|
+
removeBox(box = null) {
|
|
5879
|
+
if (box) {
|
|
5880
|
+
this.selectBox(box);
|
|
5881
|
+
}
|
|
5882
|
+
box = removeBox(this.selection.range);
|
|
5737
5883
|
if (box) {
|
|
5738
|
-
const instanceMap = this.box.getInstances(this);
|
|
5884
|
+
const instanceMap = this.box.getInstances(this.container);
|
|
5739
5885
|
instanceMap.delete(box.node.id);
|
|
5740
5886
|
}
|
|
5741
5887
|
return box;
|
|
@@ -5754,10 +5900,10 @@ class Editor {
|
|
|
5754
5900
|
this.container.append(fragment);
|
|
5755
5901
|
Editor.plugin.loadAll(this);
|
|
5756
5902
|
if (!this.readonly) {
|
|
5757
|
-
this.selection.
|
|
5903
|
+
this.selection.updateByBookmark();
|
|
5758
5904
|
this.history.save();
|
|
5759
5905
|
}
|
|
5760
|
-
Editor.box.renderAll(this);
|
|
5906
|
+
Editor.box.renderAll(this.container);
|
|
5761
5907
|
if (this.toolbar) {
|
|
5762
5908
|
this.toolbar.render(this);
|
|
5763
5909
|
}
|
|
@@ -6414,15 +6560,26 @@ const toolbarItems = [
|
|
|
6414
6560
|
accept: 'image/*',
|
|
6415
6561
|
multiple: true,
|
|
6416
6562
|
},
|
|
6563
|
+
{
|
|
6564
|
+
name: 'file',
|
|
6565
|
+
type: 'upload',
|
|
6566
|
+
icon: icons.get('attachment'),
|
|
6567
|
+
tooltip: locale => locale.toolbar.file(),
|
|
6568
|
+
accept: '*',
|
|
6569
|
+
multiple: true,
|
|
6570
|
+
},
|
|
6417
6571
|
];
|
|
6418
6572
|
|
|
6419
|
-
function
|
|
6420
|
-
const { editor, file, onError, onSuccess } = config;
|
|
6421
|
-
const { requestMethod, requestAction, requestTypes } = editor.config
|
|
6573
|
+
function uploadFile(config) {
|
|
6574
|
+
const { editor, name, file, onError, onSuccess } = config;
|
|
6575
|
+
const { requestMethod, requestAction, requestTypes } = editor.config[name];
|
|
6422
6576
|
if (requestTypes.indexOf(file.type) < 0) {
|
|
6423
|
-
|
|
6577
|
+
if (onError) {
|
|
6578
|
+
onError(`File '${file.name}' is not allowed for uploading.`);
|
|
6579
|
+
}
|
|
6580
|
+
throw new Error(`Cannot upload file '${file.name}' because its type '${file.type}' is not found in ['${requestTypes.join('\', \'')}'].`);
|
|
6424
6581
|
}
|
|
6425
|
-
const box = editor.insertBox(
|
|
6582
|
+
const box = editor.insertBox(name, {
|
|
6426
6583
|
url: URL.createObjectURL(file),
|
|
6427
6584
|
status: 'uploading',
|
|
6428
6585
|
name: file.name,
|
|
@@ -6441,7 +6598,7 @@ function uploadImage(config) {
|
|
|
6441
6598
|
box.updateValue('status', 'error');
|
|
6442
6599
|
box.render();
|
|
6443
6600
|
if (onError) {
|
|
6444
|
-
onError();
|
|
6601
|
+
onError(error.toString());
|
|
6445
6602
|
}
|
|
6446
6603
|
},
|
|
6447
6604
|
onSuccess: body => {
|
|
@@ -6449,7 +6606,7 @@ function uploadImage(config) {
|
|
|
6449
6606
|
box.updateValue('status', 'error');
|
|
6450
6607
|
box.render();
|
|
6451
6608
|
if (onError) {
|
|
6452
|
-
onError();
|
|
6609
|
+
onError('Cannot find the url field.');
|
|
6453
6610
|
}
|
|
6454
6611
|
return;
|
|
6455
6612
|
}
|
|
@@ -6492,9 +6649,9 @@ const defaultItems = [
|
|
|
6492
6649
|
'blockQuote',
|
|
6493
6650
|
'hr',
|
|
6494
6651
|
];
|
|
6495
|
-
const toolbarItemMap = new Map();
|
|
6652
|
+
const toolbarItemMap$1 = new Map();
|
|
6496
6653
|
toolbarItems.forEach(item => {
|
|
6497
|
-
toolbarItemMap.set(item.name, item);
|
|
6654
|
+
toolbarItemMap$1.set(item.name, item);
|
|
6498
6655
|
});
|
|
6499
6656
|
class Toolbar {
|
|
6500
6657
|
constructor(config) {
|
|
@@ -6581,9 +6738,11 @@ class Toolbar {
|
|
|
6581
6738
|
const target = event.target;
|
|
6582
6739
|
const files = target.files || [];
|
|
6583
6740
|
for (const file of files) {
|
|
6584
|
-
|
|
6741
|
+
uploadFile({
|
|
6585
6742
|
editor,
|
|
6743
|
+
name: item.name,
|
|
6586
6744
|
file,
|
|
6745
|
+
onError: error => editor.config.onMessage('error', error),
|
|
6587
6746
|
});
|
|
6588
6747
|
}
|
|
6589
6748
|
});
|
|
@@ -6658,7 +6817,7 @@ class Toolbar {
|
|
|
6658
6817
|
}
|
|
6659
6818
|
let item;
|
|
6660
6819
|
if (typeof name === 'string') {
|
|
6661
|
-
item = toolbarItemMap.get(name);
|
|
6820
|
+
item = toolbarItemMap$1.get(name);
|
|
6662
6821
|
if (!item) {
|
|
6663
6822
|
return;
|
|
6664
6823
|
}
|
|
@@ -6695,7 +6854,7 @@ const hrBox = {
|
|
|
6695
6854
|
box.useEffect(() => {
|
|
6696
6855
|
const hrNode = box.getContainer().find('.lake-hr');
|
|
6697
6856
|
hrNode.on('click', () => {
|
|
6698
|
-
editor.
|
|
6857
|
+
editor.selectBox(box);
|
|
6699
6858
|
});
|
|
6700
6859
|
});
|
|
6701
6860
|
return '<div class="lake-hr"><hr /></div>';
|
|
@@ -6839,7 +6998,7 @@ function openFullScreen(box) {
|
|
|
6839
6998
|
let currentIndex = 0;
|
|
6840
6999
|
const allImageBox = editor.container.find('lake-box[name="image"]');
|
|
6841
7000
|
allImageBox.each((node, index) => {
|
|
6842
|
-
const imageBox =
|
|
7001
|
+
const imageBox = getBox(node);
|
|
6843
7002
|
const imageValue = imageBox.value;
|
|
6844
7003
|
if (imageValue.status !== 'done') {
|
|
6845
7004
|
return;
|
|
@@ -6922,7 +7081,7 @@ function openFullScreen(box) {
|
|
|
6922
7081
|
if (savedRange) {
|
|
6923
7082
|
// fix(image): lose focus when zooming in the iOS
|
|
6924
7083
|
editor.selection.range = savedRange;
|
|
6925
|
-
editor.selection.
|
|
7084
|
+
editor.selection.sync();
|
|
6926
7085
|
}
|
|
6927
7086
|
box.event.emit('closefullscreen');
|
|
6928
7087
|
}, 0);
|
|
@@ -6930,20 +7089,6 @@ function openFullScreen(box) {
|
|
|
6930
7089
|
lightbox.init();
|
|
6931
7090
|
lightbox.loadAndOpen(currentIndex);
|
|
6932
7091
|
}
|
|
6933
|
-
// Removes current box.
|
|
6934
|
-
function removeImageBox(box) {
|
|
6935
|
-
const editor = box.getEditor();
|
|
6936
|
-
if (!editor) {
|
|
6937
|
-
return;
|
|
6938
|
-
}
|
|
6939
|
-
const xhr = box.getData('xhr');
|
|
6940
|
-
if (xhr) {
|
|
6941
|
-
xhr.abort();
|
|
6942
|
-
}
|
|
6943
|
-
editor.selection.range.selectBox(box.node);
|
|
6944
|
-
editor.removeBox();
|
|
6945
|
-
editor.history.save();
|
|
6946
|
-
}
|
|
6947
7092
|
// Displays error icon and filename.
|
|
6948
7093
|
function renderError(imageNode, box) {
|
|
6949
7094
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -7167,13 +7312,19 @@ const imageBox = {
|
|
|
7167
7312
|
else {
|
|
7168
7313
|
imageNode.find('.lake-button-remove').on('click', event => {
|
|
7169
7314
|
event.stopPropagation();
|
|
7170
|
-
|
|
7315
|
+
const xhr = box.getData('xhr');
|
|
7316
|
+
if (xhr) {
|
|
7317
|
+
xhr.abort();
|
|
7318
|
+
}
|
|
7319
|
+
editor.removeBox(box);
|
|
7320
|
+
editor.history.save();
|
|
7321
|
+
editor.selection.sync();
|
|
7171
7322
|
});
|
|
7172
7323
|
}
|
|
7173
7324
|
box.event.emit('render');
|
|
7174
7325
|
});
|
|
7175
7326
|
imageNode.on('click', () => {
|
|
7176
|
-
editor.
|
|
7327
|
+
editor.selectBox(box);
|
|
7177
7328
|
});
|
|
7178
7329
|
},
|
|
7179
7330
|
html: box => {
|
|
@@ -7182,6 +7333,232 @@ const imageBox = {
|
|
|
7182
7333
|
},
|
|
7183
7334
|
};
|
|
7184
7335
|
|
|
7336
|
+
const toolbarItemMap = new Map();
|
|
7337
|
+
class BoxToolbar {
|
|
7338
|
+
constructor(config) {
|
|
7339
|
+
this.placement = 'top';
|
|
7340
|
+
this.buttonItemList = [];
|
|
7341
|
+
this.dropdownItemList = [];
|
|
7342
|
+
this.root = query(config.root);
|
|
7343
|
+
this.editor = config.editor;
|
|
7344
|
+
this.box = config.box;
|
|
7345
|
+
this.items = config.items;
|
|
7346
|
+
if (config.placement) {
|
|
7347
|
+
this.placement = config.placement;
|
|
7348
|
+
}
|
|
7349
|
+
this.container = query('<div class="lake-box-toolbar" />');
|
|
7350
|
+
this.root.addClass('lake-custom-properties');
|
|
7351
|
+
}
|
|
7352
|
+
appendDivider() {
|
|
7353
|
+
this.container.append('<div class="lake-box-toolbar-divider" />');
|
|
7354
|
+
}
|
|
7355
|
+
appendButton(item) {
|
|
7356
|
+
const button = new Button({
|
|
7357
|
+
root: this.container,
|
|
7358
|
+
name: item.name,
|
|
7359
|
+
icon: item.icon,
|
|
7360
|
+
tooltip: typeof item.tooltip === 'string' ? item.tooltip : item.tooltip(this.editor.locale),
|
|
7361
|
+
tabIndex: -1,
|
|
7362
|
+
onClick: () => {
|
|
7363
|
+
item.onClick(this.box, item.name);
|
|
7364
|
+
},
|
|
7365
|
+
});
|
|
7366
|
+
button.render();
|
|
7367
|
+
}
|
|
7368
|
+
appendDropdown(item) {
|
|
7369
|
+
const dropdown = new Dropdown({
|
|
7370
|
+
root: this.container,
|
|
7371
|
+
locale: this.editor.locale,
|
|
7372
|
+
name: item.name,
|
|
7373
|
+
icon: item.icon,
|
|
7374
|
+
accentIcon: item.accentIcon,
|
|
7375
|
+
downIcon: item.downIcon,
|
|
7376
|
+
defaultValue: item.defaultValue,
|
|
7377
|
+
tooltip: item.tooltip,
|
|
7378
|
+
width: item.width,
|
|
7379
|
+
menuType: item.menuType,
|
|
7380
|
+
menuItems: item.menuItems,
|
|
7381
|
+
tabIndex: -1,
|
|
7382
|
+
placement: this.placement === 'top' ? 'bottom' : 'top',
|
|
7383
|
+
onSelect: value => {
|
|
7384
|
+
item.onSelect(this.box, value);
|
|
7385
|
+
},
|
|
7386
|
+
});
|
|
7387
|
+
dropdown.render();
|
|
7388
|
+
}
|
|
7389
|
+
updatePosition() {
|
|
7390
|
+
const boxNode = this.box.node;
|
|
7391
|
+
const position = nodeAndView(boxNode);
|
|
7392
|
+
if (position.left < 0 || position.right < 0 || position.top < 0 || position.bottom < 0) {
|
|
7393
|
+
this.container.hide();
|
|
7394
|
+
return;
|
|
7395
|
+
}
|
|
7396
|
+
this.container.show('flex');
|
|
7397
|
+
const boxNativeNode = this.box.node.get(0);
|
|
7398
|
+
const boxRect = boxNativeNode.getBoundingClientRect();
|
|
7399
|
+
const boxX = boxRect.x + window.scrollX;
|
|
7400
|
+
const boxY = boxRect.y + window.scrollY;
|
|
7401
|
+
const left = (boxX + boxRect.width / 2 - this.container.width() / 2).toFixed(1);
|
|
7402
|
+
const top = (boxY - this.container.height() - 6).toFixed(1);
|
|
7403
|
+
this.container.css({
|
|
7404
|
+
left: `${left}px`,
|
|
7405
|
+
top: `${top}px`,
|
|
7406
|
+
});
|
|
7407
|
+
}
|
|
7408
|
+
// Renders a toolbar for the specified box.
|
|
7409
|
+
render() {
|
|
7410
|
+
this.root.empty();
|
|
7411
|
+
this.root.append(this.container);
|
|
7412
|
+
this.items.forEach(name => {
|
|
7413
|
+
if (name === '|') {
|
|
7414
|
+
this.appendDivider();
|
|
7415
|
+
return;
|
|
7416
|
+
}
|
|
7417
|
+
let item;
|
|
7418
|
+
if (typeof name === 'string') {
|
|
7419
|
+
item = toolbarItemMap.get(name);
|
|
7420
|
+
if (!item) {
|
|
7421
|
+
return;
|
|
7422
|
+
}
|
|
7423
|
+
}
|
|
7424
|
+
else {
|
|
7425
|
+
item = name;
|
|
7426
|
+
}
|
|
7427
|
+
if (item.type === 'button') {
|
|
7428
|
+
this.buttonItemList.push(item);
|
|
7429
|
+
this.appendButton(item);
|
|
7430
|
+
return;
|
|
7431
|
+
}
|
|
7432
|
+
if (item.type === 'dropdown') {
|
|
7433
|
+
this.dropdownItemList.push(item);
|
|
7434
|
+
this.appendDropdown(item);
|
|
7435
|
+
}
|
|
7436
|
+
});
|
|
7437
|
+
this.updatePosition();
|
|
7438
|
+
}
|
|
7439
|
+
unmount() {
|
|
7440
|
+
this.container.remove();
|
|
7441
|
+
}
|
|
7442
|
+
}
|
|
7443
|
+
|
|
7444
|
+
const boxToolbarItems = [
|
|
7445
|
+
{
|
|
7446
|
+
name: 'download',
|
|
7447
|
+
type: 'button',
|
|
7448
|
+
icon: icons.get('download'),
|
|
7449
|
+
tooltip: locale => locale.file.download(),
|
|
7450
|
+
onClick: box => {
|
|
7451
|
+
window.open(box.value.url);
|
|
7452
|
+
},
|
|
7453
|
+
},
|
|
7454
|
+
{
|
|
7455
|
+
name: 'remove',
|
|
7456
|
+
type: 'button',
|
|
7457
|
+
icon: icons.get('remove'),
|
|
7458
|
+
tooltip: locale => locale.file.remove(),
|
|
7459
|
+
onClick: box => {
|
|
7460
|
+
const editor = box.getEditor();
|
|
7461
|
+
if (!editor) {
|
|
7462
|
+
return;
|
|
7463
|
+
}
|
|
7464
|
+
editor.removeBox(box);
|
|
7465
|
+
editor.history.save();
|
|
7466
|
+
editor.selection.sync();
|
|
7467
|
+
},
|
|
7468
|
+
},
|
|
7469
|
+
];
|
|
7470
|
+
function appendContent(fileNode, box) {
|
|
7471
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7472
|
+
const editor = box.getEditor();
|
|
7473
|
+
if (!editor) {
|
|
7474
|
+
return;
|
|
7475
|
+
}
|
|
7476
|
+
const value = box.value;
|
|
7477
|
+
const infoNode = query(safeTemplate `
|
|
7478
|
+
<div class="lake-file-info">
|
|
7479
|
+
<div class="lake-file-type"></div>
|
|
7480
|
+
<div class="lake-file-name">${value.name} (${fileSize(value.size)})</div>
|
|
7481
|
+
</div>
|
|
7482
|
+
`);
|
|
7483
|
+
const typeNode = infoNode.find('.lake-file-type');
|
|
7484
|
+
if (value.status === 'uploading') {
|
|
7485
|
+
const percent = Math.round(value.percent || 0);
|
|
7486
|
+
const progressNode = query(safeTemplate `
|
|
7487
|
+
<div class="lake-progress">
|
|
7488
|
+
<div class="lake-percent">${percent} %</div>
|
|
7489
|
+
</div>
|
|
7490
|
+
`);
|
|
7491
|
+
const circleNotchIcon = icons.get('circleNotch');
|
|
7492
|
+
if (circleNotchIcon) {
|
|
7493
|
+
progressNode.prepend(circleNotchIcon);
|
|
7494
|
+
}
|
|
7495
|
+
typeNode.replaceWith(progressNode);
|
|
7496
|
+
}
|
|
7497
|
+
else {
|
|
7498
|
+
const fileIcon = value.status === 'error' ? icons.get('warningCircle') : icons.get('file');
|
|
7499
|
+
if (fileIcon) {
|
|
7500
|
+
typeNode.append(fileIcon);
|
|
7501
|
+
}
|
|
7502
|
+
}
|
|
7503
|
+
fileNode.append(infoNode);
|
|
7504
|
+
});
|
|
7505
|
+
}
|
|
7506
|
+
const fileBox = {
|
|
7507
|
+
type: 'inline',
|
|
7508
|
+
name: 'file',
|
|
7509
|
+
render: box => {
|
|
7510
|
+
const editor = box.getEditor();
|
|
7511
|
+
if (!editor) {
|
|
7512
|
+
return;
|
|
7513
|
+
}
|
|
7514
|
+
const value = box.value;
|
|
7515
|
+
const container = box.getContainer();
|
|
7516
|
+
const fileNode = query('<div class="lake-file" />');
|
|
7517
|
+
fileNode.addClass(`lake-file-${value.status}`);
|
|
7518
|
+
if (editor.readonly) {
|
|
7519
|
+
fileNode.addClass('lake-file-readonly');
|
|
7520
|
+
}
|
|
7521
|
+
appendContent(fileNode, box);
|
|
7522
|
+
container.empty();
|
|
7523
|
+
container.append(fileNode);
|
|
7524
|
+
if (!editor.readonly) {
|
|
7525
|
+
fileNode.on('click', () => {
|
|
7526
|
+
editor.selectBox(box);
|
|
7527
|
+
});
|
|
7528
|
+
let toolbar = null;
|
|
7529
|
+
const scrollListener = () => {
|
|
7530
|
+
if (toolbar) {
|
|
7531
|
+
toolbar.updatePosition();
|
|
7532
|
+
}
|
|
7533
|
+
};
|
|
7534
|
+
box.event.on('focus', () => {
|
|
7535
|
+
const items = value.status === 'done' ? boxToolbarItems : boxToolbarItems.filter(item => item.name === 'remove');
|
|
7536
|
+
toolbar = new BoxToolbar({
|
|
7537
|
+
root: editor.popupContainer,
|
|
7538
|
+
editor,
|
|
7539
|
+
box,
|
|
7540
|
+
items,
|
|
7541
|
+
});
|
|
7542
|
+
toolbar.render();
|
|
7543
|
+
editor.root.on('scroll', scrollListener);
|
|
7544
|
+
});
|
|
7545
|
+
box.event.on('blur', () => {
|
|
7546
|
+
if (toolbar) {
|
|
7547
|
+
toolbar.unmount();
|
|
7548
|
+
toolbar = null;
|
|
7549
|
+
}
|
|
7550
|
+
editor.root.off('scroll', scrollListener);
|
|
7551
|
+
});
|
|
7552
|
+
}
|
|
7553
|
+
else {
|
|
7554
|
+
fileNode.on('click', () => {
|
|
7555
|
+
window.open(value.url);
|
|
7556
|
+
});
|
|
7557
|
+
}
|
|
7558
|
+
box.event.emit('render');
|
|
7559
|
+
},
|
|
7560
|
+
};
|
|
7561
|
+
|
|
7185
7562
|
const config = {
|
|
7186
7563
|
comment: '#57606a',
|
|
7187
7564
|
name: '#444d56',
|
|
@@ -7286,7 +7663,7 @@ const codeBlockBox = {
|
|
|
7286
7663
|
Please check if the "lake-codemirror" library is added to this page.
|
|
7287
7664
|
`.trim());
|
|
7288
7665
|
codeBlockNode.on('click', () => {
|
|
7289
|
-
editor.
|
|
7666
|
+
editor.selectBox(box);
|
|
7290
7667
|
});
|
|
7291
7668
|
return;
|
|
7292
7669
|
}
|
|
@@ -7391,7 +7768,7 @@ var copy = (editor) => {
|
|
|
7391
7768
|
if (!dataTransfer) {
|
|
7392
7769
|
return;
|
|
7393
7770
|
}
|
|
7394
|
-
const box =
|
|
7771
|
+
const box = getBox(boxNode);
|
|
7395
7772
|
const content = box.getHTML();
|
|
7396
7773
|
dataTransfer.setData('text/html', content);
|
|
7397
7774
|
});
|
|
@@ -7418,7 +7795,7 @@ var cut = (editor) => {
|
|
|
7418
7795
|
if (!dataTransfer) {
|
|
7419
7796
|
return;
|
|
7420
7797
|
}
|
|
7421
|
-
const box =
|
|
7798
|
+
const box = getBox(boxNode);
|
|
7422
7799
|
const content = box.getHTML();
|
|
7423
7800
|
dataTransfer.setData('text/html', content);
|
|
7424
7801
|
editor.removeBox();
|
|
@@ -7484,7 +7861,7 @@ function insertFirstNode(editor, otherNode) {
|
|
|
7484
7861
|
const range = editor.selection.range;
|
|
7485
7862
|
const boxNode = range.startNode.closest('lake-box');
|
|
7486
7863
|
if (boxNode.length > 0) {
|
|
7487
|
-
const box =
|
|
7864
|
+
const box = getBox(boxNode);
|
|
7488
7865
|
if (box.type === 'inline') {
|
|
7489
7866
|
if (range.isBoxStart) {
|
|
7490
7867
|
range.setStartBefore(boxNode);
|
|
@@ -7515,7 +7892,7 @@ function insertFirstNode(editor, otherNode) {
|
|
|
7515
7892
|
}
|
|
7516
7893
|
const block = range.startNode.closestBlock();
|
|
7517
7894
|
if (otherNode.isBlockBox) {
|
|
7518
|
-
const box =
|
|
7895
|
+
const box = getBox(otherNode);
|
|
7519
7896
|
const value = otherNode.attr('value') !== '' ? box.value : undefined;
|
|
7520
7897
|
editor.insertBox(box.name, value);
|
|
7521
7898
|
otherNode.remove();
|
|
@@ -7527,7 +7904,7 @@ function insertFirstNode(editor, otherNode) {
|
|
|
7527
7904
|
if (block.isEmpty && block.name === 'p') {
|
|
7528
7905
|
block.replaceWith(otherNode);
|
|
7529
7906
|
otherNode.find('lake-box').each(node => {
|
|
7530
|
-
|
|
7907
|
+
getBox(node).render();
|
|
7531
7908
|
});
|
|
7532
7909
|
range.shrinkAfter(otherNode);
|
|
7533
7910
|
return;
|
|
@@ -7601,9 +7978,11 @@ var paste = (editor) => {
|
|
|
7601
7978
|
if (dataTransfer.files.length > 0) {
|
|
7602
7979
|
for (const file of dataTransfer.files) {
|
|
7603
7980
|
if (requestTypes.indexOf(file.type) >= 0) {
|
|
7604
|
-
|
|
7981
|
+
uploadFile({
|
|
7605
7982
|
editor,
|
|
7983
|
+
name: file.type.indexOf('image/') === 0 ? 'image' : 'file',
|
|
7606
7984
|
file,
|
|
7985
|
+
onError: error => editor.config.onMessage('error', error),
|
|
7607
7986
|
});
|
|
7608
7987
|
}
|
|
7609
7988
|
}
|
|
@@ -7626,7 +8005,7 @@ var paste = (editor) => {
|
|
|
7626
8005
|
editor.event.emit('beforepaste', fragment);
|
|
7627
8006
|
fixClipboardData(fragment);
|
|
7628
8007
|
pasteFragment(editor, fragment);
|
|
7629
|
-
editor.box.renderAll(editor);
|
|
8008
|
+
editor.box.renderAll(editor.container);
|
|
7630
8009
|
});
|
|
7631
8010
|
};
|
|
7632
8011
|
|
|
@@ -7654,7 +8033,7 @@ var drop = (editor) => {
|
|
|
7654
8033
|
dragEvent.preventDefault();
|
|
7655
8034
|
return;
|
|
7656
8035
|
}
|
|
7657
|
-
const box =
|
|
8036
|
+
const box = getBox(boxNode);
|
|
7658
8037
|
if (box.type === 'inline') {
|
|
7659
8038
|
dragEvent.preventDefault();
|
|
7660
8039
|
return;
|
|
@@ -7752,7 +8131,7 @@ var drop = (editor) => {
|
|
|
7752
8131
|
return;
|
|
7753
8132
|
}
|
|
7754
8133
|
dragEvent.preventDefault();
|
|
7755
|
-
const draggedBox =
|
|
8134
|
+
const draggedBox = getBox(draggedNode);
|
|
7756
8135
|
const range = editor.selection.range;
|
|
7757
8136
|
if (targetBlock.isBox) {
|
|
7758
8137
|
if (dropPosition === 'top') {
|
|
@@ -8494,15 +8873,17 @@ class LinkPopup {
|
|
|
8494
8873
|
if (!this.linkNode) {
|
|
8495
8874
|
return;
|
|
8496
8875
|
}
|
|
8876
|
+
const position = nodeAndView(this.linkNode);
|
|
8877
|
+
if (position.left < 0 || position.right < 0 || position.top < 0 || position.bottom < 0) {
|
|
8878
|
+
this.container.css('visibility', 'hidden');
|
|
8879
|
+
return;
|
|
8880
|
+
}
|
|
8881
|
+
this.container.css('visibility', '');
|
|
8497
8882
|
const linkNativeNode = this.linkNode.get(0);
|
|
8498
8883
|
// Returns a DOMRect object providing information about the size of an element and its position relative to the viewport.
|
|
8499
8884
|
const linkRect = linkNativeNode.getBoundingClientRect();
|
|
8500
8885
|
const linkX = linkRect.x + window.scrollX;
|
|
8501
8886
|
const linkY = linkRect.y + window.scrollY;
|
|
8502
|
-
if (linkX < 0 || linkY < 0) {
|
|
8503
|
-
this.hide();
|
|
8504
|
-
return;
|
|
8505
|
-
}
|
|
8506
8887
|
// link.x + popup.width > window.width
|
|
8507
8888
|
if (linkRect.x + this.container.width() > window.innerWidth) {
|
|
8508
8889
|
// link.x + window.scrollX - (popup.width - link.width)
|
|
@@ -8564,14 +8945,14 @@ var link = (editor) => {
|
|
|
8564
8945
|
const range = editor.selection.range;
|
|
8565
8946
|
range.setStartAfter(node);
|
|
8566
8947
|
range.collapseToStart();
|
|
8567
|
-
editor.selection.
|
|
8948
|
+
editor.selection.sync();
|
|
8568
8949
|
editor.history.save();
|
|
8569
8950
|
},
|
|
8570
8951
|
onRemove: node => {
|
|
8571
8952
|
const range = editor.selection.range;
|
|
8572
8953
|
range.setStartAfter(node);
|
|
8573
8954
|
range.collapseToStart();
|
|
8574
|
-
editor.selection.
|
|
8955
|
+
editor.selection.sync();
|
|
8575
8956
|
editor.history.save();
|
|
8576
8957
|
},
|
|
8577
8958
|
});
|
|
@@ -8618,7 +8999,7 @@ var hr = (editor) => {
|
|
|
8618
8999
|
const fragment = new Fragment(nativeFragment);
|
|
8619
9000
|
fragment.find('hr').each(nativeNode => {
|
|
8620
9001
|
const node = query(nativeNode);
|
|
8621
|
-
const box =
|
|
9002
|
+
const box = getBox('hr');
|
|
8622
9003
|
node.replaceWith(box.node);
|
|
8623
9004
|
});
|
|
8624
9005
|
});
|
|
@@ -8642,7 +9023,7 @@ var image = (editor) => {
|
|
|
8642
9023
|
const fragment = new Fragment(nativeFragment);
|
|
8643
9024
|
fragment.find('img').each(nativeNode => {
|
|
8644
9025
|
const node = query(nativeNode);
|
|
8645
|
-
const box =
|
|
9026
|
+
const box = getBox('image');
|
|
8646
9027
|
const value = node.attr('data-lake-value');
|
|
8647
9028
|
if (value === '') {
|
|
8648
9029
|
box.value = {
|
|
@@ -8664,6 +9045,39 @@ var image = (editor) => {
|
|
|
8664
9045
|
});
|
|
8665
9046
|
};
|
|
8666
9047
|
|
|
9048
|
+
var file = (editor) => {
|
|
9049
|
+
editor.setPluginConfig('file', {
|
|
9050
|
+
requestMethod: 'POST',
|
|
9051
|
+
requestTypes: [
|
|
9052
|
+
'application/zip',
|
|
9053
|
+
'application/x-zip-compressed',
|
|
9054
|
+
'application/vnd.rar',
|
|
9055
|
+
'image/gif',
|
|
9056
|
+
'image/jpeg',
|
|
9057
|
+
'image/png',
|
|
9058
|
+
'image/svg+xml',
|
|
9059
|
+
'text/plain',
|
|
9060
|
+
'text/html',
|
|
9061
|
+
'application/pdf',
|
|
9062
|
+
'application/msword',
|
|
9063
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
9064
|
+
'application/vnd.ms-excel',
|
|
9065
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
9066
|
+
'application/vnd.ms-powerpoint',
|
|
9067
|
+
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
9068
|
+
],
|
|
9069
|
+
});
|
|
9070
|
+
if (editor.readonly) {
|
|
9071
|
+
return;
|
|
9072
|
+
}
|
|
9073
|
+
editor.command.add('file', {
|
|
9074
|
+
execute: (value) => {
|
|
9075
|
+
editor.insertBox('file', value);
|
|
9076
|
+
editor.history.save();
|
|
9077
|
+
},
|
|
9078
|
+
});
|
|
9079
|
+
};
|
|
9080
|
+
|
|
8667
9081
|
const langList = [
|
|
8668
9082
|
'text',
|
|
8669
9083
|
'c',
|
|
@@ -9288,8 +9702,7 @@ var backspaceKey = (editor) => {
|
|
|
9288
9702
|
const prevNode = range.getPrevNode();
|
|
9289
9703
|
if (prevNode.isBox) {
|
|
9290
9704
|
event.preventDefault();
|
|
9291
|
-
|
|
9292
|
-
editor.removeBox();
|
|
9705
|
+
editor.removeBox(prevNode);
|
|
9293
9706
|
editor.history.save();
|
|
9294
9707
|
return;
|
|
9295
9708
|
}
|
|
@@ -9408,8 +9821,7 @@ var deleteKey = (editor) => {
|
|
|
9408
9821
|
const nextNode = range.getNextNode();
|
|
9409
9822
|
if (nextNode.isBox) {
|
|
9410
9823
|
event.preventDefault();
|
|
9411
|
-
|
|
9412
|
-
editor.removeBox();
|
|
9824
|
+
editor.removeBox(nextNode);
|
|
9413
9825
|
editor.history.save();
|
|
9414
9826
|
return;
|
|
9415
9827
|
}
|
|
@@ -9590,7 +10002,7 @@ var escapeKey = (editor) => {
|
|
|
9590
10002
|
event.preventDefault();
|
|
9591
10003
|
const boxNode = range.commonAncestor.closest('lake-box');
|
|
9592
10004
|
range.selectBoxEnd(boxNode);
|
|
9593
|
-
selection.
|
|
10005
|
+
selection.sync();
|
|
9594
10006
|
return;
|
|
9595
10007
|
}
|
|
9596
10008
|
if (editor.hasFocus) {
|
|
@@ -9602,6 +10014,7 @@ var escapeKey = (editor) => {
|
|
|
9602
10014
|
|
|
9603
10015
|
Editor.box.add(hrBox);
|
|
9604
10016
|
Editor.box.add(imageBox);
|
|
10017
|
+
Editor.box.add(fileBox);
|
|
9605
10018
|
Editor.box.add(codeBlockBox);
|
|
9606
10019
|
Editor.plugin.add(copy);
|
|
9607
10020
|
Editor.plugin.add(cut);
|
|
@@ -9631,6 +10044,7 @@ Editor.plugin.add(formatPainter);
|
|
|
9631
10044
|
Editor.plugin.add(link);
|
|
9632
10045
|
Editor.plugin.add(hr);
|
|
9633
10046
|
Editor.plugin.add(image);
|
|
10047
|
+
Editor.plugin.add(file);
|
|
9634
10048
|
Editor.plugin.add(codeBlock);
|
|
9635
10049
|
Editor.plugin.add(markdown);
|
|
9636
10050
|
Editor.plugin.add(enterKey);
|