lakelib 0.1.8 → 0.1.10
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 +705 -295
- 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,42 @@ 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
|
-
|
|
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);
|
|
2735
|
-
}
|
|
2736
|
-
};
|
|
2737
|
-
}
|
|
2738
|
-
const formData = new FormData();
|
|
2739
|
-
const data = option.data || {};
|
|
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;
|
|
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 nativeViewport = viewport.get(0);
|
|
2722
|
+
const viewportRect = nativeViewport.getBoundingClientRect();
|
|
2723
|
+
const offsetLeft = viewportRect.x;
|
|
2724
|
+
const offsetTop = viewportRect.y;
|
|
2725
|
+
left -= offsetLeft;
|
|
2726
|
+
right -= offsetLeft;
|
|
2727
|
+
top -= offsetTop;
|
|
2728
|
+
bottom -= offsetTop;
|
|
2729
|
+
viewportWidth = viewportRect.width;
|
|
2730
|
+
viewportHeight = viewportRect.height;
|
|
2750
2731
|
}
|
|
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
2732
|
}
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2733
|
+
const position = {
|
|
2734
|
+
left,
|
|
2735
|
+
right: viewportWidth - right,
|
|
2736
|
+
top,
|
|
2737
|
+
bottom: viewportHeight - bottom,
|
|
2764
2738
|
};
|
|
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;
|
|
2739
|
+
return position;
|
|
2797
2740
|
}
|
|
2798
2741
|
|
|
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
|
-
}
|
|
2742
|
+
const boxInstances = new Map();
|
|
2859
2743
|
|
|
2860
2744
|
const boxes = new Map();
|
|
2861
2745
|
|
|
@@ -2867,7 +2751,7 @@ const boxData = {};
|
|
|
2867
2751
|
const effectData = {};
|
|
2868
2752
|
const framework = safeTemplate `
|
|
2869
2753
|
<span class="lake-box-strip"><br /></span>
|
|
2870
|
-
<div class="lake-box-container" contenteditable="false"
|
|
2754
|
+
<div class="lake-box-container" contenteditable="false"></div>
|
|
2871
2755
|
<span class="lake-box-strip"><br /></span>
|
|
2872
2756
|
`;
|
|
2873
2757
|
class Box {
|
|
@@ -2932,6 +2816,9 @@ class Box {
|
|
|
2932
2816
|
debug(`Box '${this.name}' (id = ${this.node.id}) value:`);
|
|
2933
2817
|
debug(this.value);
|
|
2934
2818
|
});
|
|
2819
|
+
if (this.type === 'block') {
|
|
2820
|
+
container.attr('draggable', 'true');
|
|
2821
|
+
}
|
|
2935
2822
|
}
|
|
2936
2823
|
// Returns the type of the box.
|
|
2937
2824
|
get type() {
|
|
@@ -3009,28 +2896,235 @@ class Box {
|
|
|
3009
2896
|
}
|
|
3010
2897
|
debug(`Box '${this.name}' (id = ${this.node.id}) rendered`);
|
|
3011
2898
|
}
|
|
3012
|
-
// Destroys a rendered box.
|
|
3013
|
-
unmount() {
|
|
3014
|
-
|
|
3015
|
-
|
|
2899
|
+
// Destroys a rendered box.
|
|
2900
|
+
unmount() {
|
|
2901
|
+
this.event.emit('blur');
|
|
2902
|
+
for (const cleanup of effectData[this.node.id].cleanup) {
|
|
2903
|
+
cleanup();
|
|
2904
|
+
}
|
|
2905
|
+
boxData[this.node.id] = {};
|
|
2906
|
+
effectData[this.node.id].setup = [];
|
|
2907
|
+
effectData[this.node.id].cleanup = [];
|
|
2908
|
+
this.event.removeAllListeners();
|
|
2909
|
+
this.node.empty();
|
|
2910
|
+
debug(`Box '${this.name}' (id = ${this.node.id}) unmounted`);
|
|
2911
|
+
}
|
|
2912
|
+
// Returns a HTML string of the box.
|
|
2913
|
+
getHTML() {
|
|
2914
|
+
const component = boxes.get(this.name);
|
|
2915
|
+
if (component === undefined) {
|
|
2916
|
+
return '';
|
|
2917
|
+
}
|
|
2918
|
+
if (component.html === undefined) {
|
|
2919
|
+
return this.node.outerHTML();
|
|
2920
|
+
}
|
|
2921
|
+
return component.html(this);
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
|
|
2925
|
+
// Returns an already generated box instance or generates a new instance if it does not exist.
|
|
2926
|
+
function getBox(boxNode) {
|
|
2927
|
+
if (typeof boxNode === 'string') {
|
|
2928
|
+
return new Box(boxNode);
|
|
2929
|
+
}
|
|
2930
|
+
boxNode = query(boxNode);
|
|
2931
|
+
const container = boxNode.closestContainer();
|
|
2932
|
+
if (container.length === 0) {
|
|
2933
|
+
return new Box(boxNode);
|
|
2934
|
+
}
|
|
2935
|
+
let instanceMap = boxInstances.get(container.id);
|
|
2936
|
+
if (!instanceMap) {
|
|
2937
|
+
instanceMap = new Map();
|
|
2938
|
+
boxInstances.set(container.id, instanceMap);
|
|
2939
|
+
}
|
|
2940
|
+
let box = instanceMap.get(boxNode.id);
|
|
2941
|
+
if (box) {
|
|
2942
|
+
return box;
|
|
2943
|
+
}
|
|
2944
|
+
box = new Box(boxNode);
|
|
2945
|
+
instanceMap.set(box.node.id, box);
|
|
2946
|
+
return box;
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2949
|
+
/**
|
|
2950
|
+
The MIT License (MIT)
|
|
2951
|
+
|
|
2952
|
+
Copyright (c) 2016-present react-component
|
|
2953
|
+
|
|
2954
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
2955
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
2956
|
+
in the Software without restriction, including without limitation the rights
|
|
2957
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
2958
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
2959
|
+
furnished to do so, subject to the following conditions:
|
|
2960
|
+
|
|
2961
|
+
The above copyright notice and this permission notice shall be included in
|
|
2962
|
+
all copies or substantial portions of the Software.
|
|
2963
|
+
|
|
2964
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
2965
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
2966
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
2967
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
2968
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
2969
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
2970
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
2971
|
+
|
|
2972
|
+
Repository: https://github.com/react-component/upload
|
|
2973
|
+
*/
|
|
2974
|
+
function getError(option, xhr) {
|
|
2975
|
+
const msg = `Cannot ${option.method} ${option.action} ${xhr.status}'`;
|
|
2976
|
+
const err = new Error(msg);
|
|
2977
|
+
err.status = xhr.status;
|
|
2978
|
+
err.method = option.method;
|
|
2979
|
+
err.url = option.action;
|
|
2980
|
+
return err;
|
|
2981
|
+
}
|
|
2982
|
+
function getBody(xhr) {
|
|
2983
|
+
const text = xhr.responseText || xhr.response;
|
|
2984
|
+
if (!text) {
|
|
2985
|
+
return text;
|
|
2986
|
+
}
|
|
2987
|
+
try {
|
|
2988
|
+
return JSON.parse(text);
|
|
2989
|
+
}
|
|
2990
|
+
catch (e) {
|
|
2991
|
+
return text;
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
function request(option) {
|
|
2995
|
+
const xhr = new XMLHttpRequest();
|
|
2996
|
+
if (option.onProgress && xhr.upload) {
|
|
2997
|
+
xhr.upload.onprogress = (e) => {
|
|
2998
|
+
if (e.total > 0) {
|
|
2999
|
+
e.percent = (e.loaded / e.total) * 100;
|
|
3000
|
+
}
|
|
3001
|
+
if (option.onProgress) {
|
|
3002
|
+
option.onProgress(e);
|
|
3003
|
+
}
|
|
3004
|
+
};
|
|
3005
|
+
}
|
|
3006
|
+
const formData = new FormData();
|
|
3007
|
+
const data = option.data || {};
|
|
3008
|
+
Object.keys(data).forEach(key => {
|
|
3009
|
+
const value = data[key];
|
|
3010
|
+
// support key-value array data
|
|
3011
|
+
if (Array.isArray(value)) {
|
|
3012
|
+
value.forEach(item => {
|
|
3013
|
+
// { list: [ 11, 22 ] }
|
|
3014
|
+
// formData.append('list[]', 11);
|
|
3015
|
+
formData.append(`${key}[]`, item);
|
|
3016
|
+
});
|
|
3017
|
+
return;
|
|
3018
|
+
}
|
|
3019
|
+
formData.append(key, value);
|
|
3020
|
+
});
|
|
3021
|
+
const filename = option.filename || 'file';
|
|
3022
|
+
if (option.file instanceof Blob) {
|
|
3023
|
+
formData.append(filename, option.file, option.file.name);
|
|
3024
|
+
}
|
|
3025
|
+
else {
|
|
3026
|
+
formData.append(filename, option.file);
|
|
3027
|
+
}
|
|
3028
|
+
xhr.onerror = (e) => {
|
|
3029
|
+
if (option.onError) {
|
|
3030
|
+
option.onError(e);
|
|
3031
|
+
}
|
|
3032
|
+
};
|
|
3033
|
+
xhr.onload = () => {
|
|
3034
|
+
// allow success when 2xx status
|
|
3035
|
+
// see https://github.com/react-component/upload/issues/34
|
|
3036
|
+
if (xhr.status < 200 || xhr.status >= 300) {
|
|
3037
|
+
if (!option.onError) {
|
|
3038
|
+
return;
|
|
3039
|
+
}
|
|
3040
|
+
return option.onError(getError(option, xhr), getBody(xhr));
|
|
3041
|
+
}
|
|
3042
|
+
if (!option.onSuccess) {
|
|
3043
|
+
return;
|
|
3044
|
+
}
|
|
3045
|
+
return option.onSuccess(getBody(xhr), xhr);
|
|
3046
|
+
};
|
|
3047
|
+
xhr.open(option.method, option.action, true);
|
|
3048
|
+
// Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179
|
|
3049
|
+
if (option.withCredentials && 'withCredentials' in xhr) {
|
|
3050
|
+
xhr.withCredentials = true;
|
|
3051
|
+
}
|
|
3052
|
+
const headers = option.headers || {};
|
|
3053
|
+
// when set headers['X-Requested-With'] = null , can close default XHR header
|
|
3054
|
+
// see https://github.com/react-component/upload/issues/33
|
|
3055
|
+
if (headers['X-Requested-With'] !== null) {
|
|
3056
|
+
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
3057
|
+
}
|
|
3058
|
+
Object.keys(headers).forEach(h => {
|
|
3059
|
+
if (headers[h] !== null) {
|
|
3060
|
+
xhr.setRequestHeader(h, headers[h]);
|
|
3061
|
+
}
|
|
3062
|
+
});
|
|
3063
|
+
xhr.send(formData);
|
|
3064
|
+
return xhr;
|
|
3065
|
+
}
|
|
3066
|
+
|
|
3067
|
+
// String
|
|
3068
|
+
|
|
3069
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
3070
|
+
__proto__: null,
|
|
3071
|
+
appendDeepest: appendDeepest,
|
|
3072
|
+
camelCase: camelCase,
|
|
3073
|
+
changeTagName: changeTagName,
|
|
3074
|
+
debug: debug,
|
|
3075
|
+
denormalizeValue: denormalizeValue,
|
|
3076
|
+
encode: encode,
|
|
3077
|
+
fileSize: fileSize,
|
|
3078
|
+
fixNumberedList: fixNumberedList,
|
|
3079
|
+
getBox: getBox,
|
|
3080
|
+
getCSS: getCSS,
|
|
3081
|
+
getDeepest: getDeepest,
|
|
3082
|
+
inString: inString,
|
|
3083
|
+
mergeNodes: mergeNodes,
|
|
3084
|
+
modifierText: modifierText,
|
|
3085
|
+
morph: morph,
|
|
3086
|
+
nodeAndView: nodeAndView,
|
|
3087
|
+
normalizeValue: normalizeValue,
|
|
3088
|
+
parseStyle: parseStyle,
|
|
3089
|
+
query: query,
|
|
3090
|
+
removeBr: removeBr,
|
|
3091
|
+
removeZWS: removeZWS,
|
|
3092
|
+
request: request,
|
|
3093
|
+
safeTemplate: safeTemplate,
|
|
3094
|
+
setBlockIndent: setBlockIndent,
|
|
3095
|
+
splitNodes: splitNodes,
|
|
3096
|
+
template: template,
|
|
3097
|
+
toHex: toHex,
|
|
3098
|
+
toNodeList: toNodeList,
|
|
3099
|
+
wrapNodeList: wrapNodeList
|
|
3100
|
+
});
|
|
3101
|
+
|
|
3102
|
+
class Fragment {
|
|
3103
|
+
constructor(fragment) {
|
|
3104
|
+
this.fragment = fragment !== null && fragment !== void 0 ? fragment : document.createDocumentFragment();
|
|
3105
|
+
}
|
|
3106
|
+
// Returns the descendants of the fragment which are selected by the specified CSS selector.
|
|
3107
|
+
find(selector) {
|
|
3108
|
+
const nodeList = [];
|
|
3109
|
+
let child = new Nodes(this.fragment.firstChild);
|
|
3110
|
+
while (child.length > 0) {
|
|
3111
|
+
if (child.matches(selector)) {
|
|
3112
|
+
nodeList.push(child.get(0));
|
|
3113
|
+
}
|
|
3114
|
+
else if (child.isElement) {
|
|
3115
|
+
child.find(selector).each(node => {
|
|
3116
|
+
nodeList.push(node);
|
|
3117
|
+
});
|
|
3118
|
+
}
|
|
3119
|
+
child = child.next();
|
|
3016
3120
|
}
|
|
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`);
|
|
3121
|
+
return new Nodes(nodeList);
|
|
3023
3122
|
}
|
|
3024
|
-
//
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
}
|
|
3030
|
-
if (component.html === undefined) {
|
|
3031
|
-
return this.node.outerHTML();
|
|
3032
|
-
}
|
|
3033
|
-
return component.html(this);
|
|
3123
|
+
// Inserts the specified node as the last child.
|
|
3124
|
+
append(node) {
|
|
3125
|
+
node.each(nativeNode => {
|
|
3126
|
+
this.fragment.appendChild(nativeNode);
|
|
3127
|
+
});
|
|
3034
3128
|
}
|
|
3035
3129
|
}
|
|
3036
3130
|
|
|
@@ -3440,7 +3534,7 @@ function toBookmark(range, bookmark) {
|
|
|
3440
3534
|
}
|
|
3441
3535
|
if (focus.length > 0 && anchor.length === 0) {
|
|
3442
3536
|
if (focus.isBox) {
|
|
3443
|
-
const box =
|
|
3537
|
+
const box = getBox(focus);
|
|
3444
3538
|
if (box.getContainer().length === 0) {
|
|
3445
3539
|
box.render();
|
|
3446
3540
|
}
|
|
@@ -3861,7 +3955,7 @@ function addMark(range, value) {
|
|
|
3861
3955
|
if (range.isCollapsed) {
|
|
3862
3956
|
if (range.isBox) {
|
|
3863
3957
|
const boxNode = range.startNode.closest('lake-box');
|
|
3864
|
-
const box =
|
|
3958
|
+
const box = getBox(boxNode);
|
|
3865
3959
|
if (box.type === 'block') {
|
|
3866
3960
|
const newBlock = query('<p><br /></p>');
|
|
3867
3961
|
if (range.isBoxStart) {
|
|
@@ -4160,6 +4254,7 @@ var enUS = {
|
|
|
4160
4254
|
fontColor: 'Font color',
|
|
4161
4255
|
highlight: 'Highlight',
|
|
4162
4256
|
image: 'Image',
|
|
4257
|
+
file: 'File',
|
|
4163
4258
|
removeColor: 'Remove color',
|
|
4164
4259
|
},
|
|
4165
4260
|
link: {
|
|
@@ -4181,6 +4276,10 @@ var enUS = {
|
|
|
4181
4276
|
zoomOut: 'Zoom out',
|
|
4182
4277
|
zoomIn: 'Zoom in',
|
|
4183
4278
|
},
|
|
4279
|
+
file: {
|
|
4280
|
+
download: 'Download',
|
|
4281
|
+
remove: 'Delete',
|
|
4282
|
+
},
|
|
4184
4283
|
codeBlock: {
|
|
4185
4284
|
langType: 'Select language',
|
|
4186
4285
|
},
|
|
@@ -4230,6 +4329,7 @@ var zhCN = {
|
|
|
4230
4329
|
fontColor: '文字颜色',
|
|
4231
4330
|
highlight: '文字背景',
|
|
4232
4331
|
image: '图片',
|
|
4332
|
+
file: '文件',
|
|
4233
4333
|
removeColor: '默认',
|
|
4234
4334
|
},
|
|
4235
4335
|
link: {
|
|
@@ -4251,6 +4351,10 @@ var zhCN = {
|
|
|
4251
4351
|
zoomOut: '缩小',
|
|
4252
4352
|
zoomIn: '放大',
|
|
4253
4353
|
},
|
|
4354
|
+
file: {
|
|
4355
|
+
download: '下载',
|
|
4356
|
+
remove: '删除',
|
|
4357
|
+
},
|
|
4254
4358
|
codeBlock: {
|
|
4255
4359
|
langType: '选择代码语言',
|
|
4256
4360
|
},
|
|
@@ -4300,6 +4404,7 @@ var ja = {
|
|
|
4300
4404
|
fontColor: '文字色',
|
|
4301
4405
|
highlight: '文字の背景',
|
|
4302
4406
|
image: '画像',
|
|
4407
|
+
file: 'ファイル',
|
|
4303
4408
|
removeColor: 'デフォルト',
|
|
4304
4409
|
},
|
|
4305
4410
|
link: {
|
|
@@ -4321,6 +4426,10 @@ var ja = {
|
|
|
4321
4426
|
zoomOut: '縮小',
|
|
4322
4427
|
zoomIn: '拡大',
|
|
4323
4428
|
},
|
|
4429
|
+
file: {
|
|
4430
|
+
download: 'ダウンロード',
|
|
4431
|
+
remove: '削除',
|
|
4432
|
+
},
|
|
4324
4433
|
codeBlock: {
|
|
4325
4434
|
langType: 'コード言語を選択',
|
|
4326
4435
|
},
|
|
@@ -4370,6 +4479,7 @@ var ko = {
|
|
|
4370
4479
|
fontColor: '글자 색상',
|
|
4371
4480
|
highlight: '글자 배경',
|
|
4372
4481
|
image: '이미지',
|
|
4482
|
+
file: '파일',
|
|
4373
4483
|
removeColor: '기본색',
|
|
4374
4484
|
},
|
|
4375
4485
|
link: {
|
|
@@ -4391,6 +4501,10 @@ var ko = {
|
|
|
4391
4501
|
zoomOut: '축소',
|
|
4392
4502
|
zoomIn: '확대',
|
|
4393
4503
|
},
|
|
4504
|
+
file: {
|
|
4505
|
+
download: '다운로드',
|
|
4506
|
+
remove: '삭제',
|
|
4507
|
+
},
|
|
4394
4508
|
codeBlock: {
|
|
4395
4509
|
langType: '코드언어 선택',
|
|
4396
4510
|
},
|
|
@@ -4673,14 +4787,14 @@ class Dropdown {
|
|
|
4673
4787
|
}
|
|
4674
4788
|
}
|
|
4675
4789
|
|
|
4676
|
-
var version = "0.1.
|
|
4790
|
+
var version = "0.1.10";
|
|
4677
4791
|
|
|
4678
4792
|
// Inserts a box into the specified range.
|
|
4679
4793
|
function insertBox(range, boxName, boxValue) {
|
|
4680
4794
|
if (range.commonAncestor.isOutside) {
|
|
4681
4795
|
return null;
|
|
4682
4796
|
}
|
|
4683
|
-
const box =
|
|
4797
|
+
const box = getBox(boxName);
|
|
4684
4798
|
if (boxValue) {
|
|
4685
4799
|
box.value = boxValue;
|
|
4686
4800
|
}
|
|
@@ -4719,7 +4833,7 @@ function removeBox(range) {
|
|
|
4719
4833
|
if (boxNode.length === 0) {
|
|
4720
4834
|
return null;
|
|
4721
4835
|
}
|
|
4722
|
-
const box =
|
|
4836
|
+
const box = getBox(boxNode);
|
|
4723
4837
|
if (box.type === 'block') {
|
|
4724
4838
|
const paragraph = query('<p><br /></p>');
|
|
4725
4839
|
boxNode.before(paragraph);
|
|
@@ -4823,20 +4937,20 @@ class Selection {
|
|
|
4823
4937
|
return new Range();
|
|
4824
4938
|
}
|
|
4825
4939
|
// Adds the saved range to the native selection.
|
|
4826
|
-
|
|
4940
|
+
sync() {
|
|
4827
4941
|
this.selection.removeAllRanges();
|
|
4828
4942
|
this.selection.addRange(this.range.get());
|
|
4829
4943
|
}
|
|
4830
|
-
//
|
|
4831
|
-
|
|
4944
|
+
// Updates the saved range with the range of the native selection.
|
|
4945
|
+
updateByRange() {
|
|
4832
4946
|
const newRange = this.getRangeFromNativeSelection();
|
|
4833
4947
|
if (this.range.get() === newRange.get()) {
|
|
4834
4948
|
return;
|
|
4835
4949
|
}
|
|
4836
4950
|
this.range = newRange;
|
|
4837
4951
|
}
|
|
4838
|
-
//
|
|
4839
|
-
|
|
4952
|
+
// Updates the saved range with the range represented by the bookmark.
|
|
4953
|
+
updateByBookmark() {
|
|
4840
4954
|
const range = this.range;
|
|
4841
4955
|
const container = this.container;
|
|
4842
4956
|
const boxFocus = container.find('lake-box[focus]');
|
|
@@ -4845,7 +4959,7 @@ class Selection {
|
|
|
4845
4959
|
anchor: new Nodes(),
|
|
4846
4960
|
focus: boxFocus,
|
|
4847
4961
|
});
|
|
4848
|
-
this.
|
|
4962
|
+
this.sync();
|
|
4849
4963
|
return;
|
|
4850
4964
|
}
|
|
4851
4965
|
const anchor = container.find('lake-bookmark[type="anchor"]');
|
|
@@ -4854,7 +4968,7 @@ class Selection {
|
|
|
4854
4968
|
anchor,
|
|
4855
4969
|
focus,
|
|
4856
4970
|
});
|
|
4857
|
-
this.
|
|
4971
|
+
this.sync();
|
|
4858
4972
|
}
|
|
4859
4973
|
getAppliedItems() {
|
|
4860
4974
|
const appliedItems = [];
|
|
@@ -4961,8 +5075,6 @@ class Command {
|
|
|
4961
5075
|
}
|
|
4962
5076
|
}
|
|
4963
5077
|
|
|
4964
|
-
const boxInstances = new Map();
|
|
4965
|
-
|
|
4966
5078
|
// Saves and controls the history of the value of the editor.
|
|
4967
5079
|
// Example:
|
|
4968
5080
|
// before initialization: value: 'a', list: [], index: 0, canUndo: false
|
|
@@ -5040,7 +5152,7 @@ class History {
|
|
|
5040
5152
|
const range = this.selection.range;
|
|
5041
5153
|
const newContainer = this.container.clone(true);
|
|
5042
5154
|
newContainer.find('lake-box').each(nativeNode => {
|
|
5043
|
-
const box =
|
|
5155
|
+
const box = getBox(nativeNode);
|
|
5044
5156
|
box.getContainer().empty();
|
|
5045
5157
|
});
|
|
5046
5158
|
if (range.commonAncestor.isOutside) {
|
|
@@ -5090,7 +5202,7 @@ class History {
|
|
|
5090
5202
|
}
|
|
5091
5203
|
this.index--;
|
|
5092
5204
|
}
|
|
5093
|
-
this.selection.
|
|
5205
|
+
this.selection.updateByBookmark();
|
|
5094
5206
|
debug(`History undone, the last index is ${this.index}`);
|
|
5095
5207
|
}
|
|
5096
5208
|
redo() {
|
|
@@ -5112,7 +5224,7 @@ class History {
|
|
|
5112
5224
|
break;
|
|
5113
5225
|
}
|
|
5114
5226
|
}
|
|
5115
|
-
this.selection.
|
|
5227
|
+
this.selection.updateByBookmark();
|
|
5116
5228
|
debug(`History redone, the last index is ${this.index}`);
|
|
5117
5229
|
}
|
|
5118
5230
|
continue() {
|
|
@@ -5219,17 +5331,17 @@ class BoxManager {
|
|
|
5219
5331
|
getNames() {
|
|
5220
5332
|
return Array.from(boxes.keys());
|
|
5221
5333
|
}
|
|
5222
|
-
getInstances(
|
|
5223
|
-
let instanceMap = boxInstances.get(
|
|
5334
|
+
getInstances(container) {
|
|
5335
|
+
let instanceMap = boxInstances.get(container.id);
|
|
5224
5336
|
if (!instanceMap) {
|
|
5225
5337
|
instanceMap = new Map();
|
|
5226
|
-
boxInstances.set(
|
|
5338
|
+
boxInstances.set(container.id, instanceMap);
|
|
5227
5339
|
return instanceMap;
|
|
5228
5340
|
}
|
|
5229
5341
|
return instanceMap;
|
|
5230
5342
|
}
|
|
5231
|
-
rectifyInstances(
|
|
5232
|
-
const instanceMap = this.getInstances(
|
|
5343
|
+
rectifyInstances(container) {
|
|
5344
|
+
const instanceMap = this.getInstances(container);
|
|
5233
5345
|
for (const box of instanceMap.values()) {
|
|
5234
5346
|
if (!box.node.get(0).isConnected) {
|
|
5235
5347
|
box.unmount();
|
|
@@ -5237,20 +5349,16 @@ class BoxManager {
|
|
|
5237
5349
|
}
|
|
5238
5350
|
}
|
|
5239
5351
|
}
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
const instanceMap = this.getInstances(editor);
|
|
5246
|
-
this.findAll(editor).each(boxNativeNode => {
|
|
5247
|
-
const boxNode = new Nodes(boxNativeNode);
|
|
5352
|
+
renderAll(container) {
|
|
5353
|
+
this.rectifyInstances(container);
|
|
5354
|
+
const instanceMap = this.getInstances(container);
|
|
5355
|
+
container.find('lake-box').each(boxNativeNode => {
|
|
5356
|
+
const boxNode = query(boxNativeNode);
|
|
5248
5357
|
if (instanceMap.get(boxNode.id)) {
|
|
5249
5358
|
return;
|
|
5250
5359
|
}
|
|
5251
|
-
const box =
|
|
5360
|
+
const box = getBox(boxNode);
|
|
5252
5361
|
box.render();
|
|
5253
|
-
instanceMap.set(box.node.id, box);
|
|
5254
5362
|
});
|
|
5255
5363
|
}
|
|
5256
5364
|
}
|
|
@@ -5278,6 +5386,22 @@ const defaultConfig = {
|
|
|
5278
5386
|
indentWithTab: true,
|
|
5279
5387
|
lang: 'en-US',
|
|
5280
5388
|
minChangeSize: 5,
|
|
5389
|
+
onMessage: (type, message) => {
|
|
5390
|
+
if (type === 'success') {
|
|
5391
|
+
// eslint-disable-next-line no-console
|
|
5392
|
+
console.log(message);
|
|
5393
|
+
return;
|
|
5394
|
+
}
|
|
5395
|
+
if (type === 'warning') {
|
|
5396
|
+
// eslint-disable-next-line no-console
|
|
5397
|
+
console.warn(message);
|
|
5398
|
+
return;
|
|
5399
|
+
}
|
|
5400
|
+
if (type === 'error') {
|
|
5401
|
+
// eslint-disable-next-line no-console
|
|
5402
|
+
console.error(message);
|
|
5403
|
+
}
|
|
5404
|
+
},
|
|
5281
5405
|
};
|
|
5282
5406
|
class Editor {
|
|
5283
5407
|
constructor(config) {
|
|
@@ -5316,13 +5440,13 @@ class Editor {
|
|
|
5316
5440
|
this.history.save();
|
|
5317
5441
|
};
|
|
5318
5442
|
this.selectionchangeListener = () => {
|
|
5319
|
-
this.selection.
|
|
5443
|
+
this.selection.updateByRange();
|
|
5320
5444
|
this.updateBoxSelectionStyle();
|
|
5321
5445
|
this.emitStateChangeEvent();
|
|
5322
5446
|
};
|
|
5323
5447
|
this.clickListener = event => {
|
|
5324
5448
|
const targetNode = new Nodes(event.target);
|
|
5325
|
-
if (targetNode.closest('.lake-popup').length > 0) {
|
|
5449
|
+
if (!targetNode.get(0).isConnected || targetNode.closest('.lake-popup').length > 0) {
|
|
5326
5450
|
return;
|
|
5327
5451
|
}
|
|
5328
5452
|
this.event.emit('click', targetNode);
|
|
@@ -5338,8 +5462,8 @@ class Editor {
|
|
|
5338
5462
|
const range = this.selection.range;
|
|
5339
5463
|
const clonedRange = range.clone();
|
|
5340
5464
|
clonedRange.adaptBox();
|
|
5341
|
-
this.
|
|
5342
|
-
const box =
|
|
5465
|
+
this.container.find('lake-box').each(boxNativeNode => {
|
|
5466
|
+
const box = getBox(boxNativeNode);
|
|
5343
5467
|
const boxContainer = box.getContainer();
|
|
5344
5468
|
if (boxContainer.length === 0) {
|
|
5345
5469
|
return;
|
|
@@ -5350,6 +5474,7 @@ class Editor {
|
|
|
5350
5474
|
boxContainer.removeClass('lake-box-selected');
|
|
5351
5475
|
boxContainer.removeClass('lake-box-focused');
|
|
5352
5476
|
boxContainer.addClass('lake-box-activated');
|
|
5477
|
+
box.event.emit('focus');
|
|
5353
5478
|
return;
|
|
5354
5479
|
}
|
|
5355
5480
|
}
|
|
@@ -5359,16 +5484,19 @@ class Editor {
|
|
|
5359
5484
|
boxContainer.removeClass('lake-box-hovered');
|
|
5360
5485
|
boxContainer.removeClass('lake-box-selected');
|
|
5361
5486
|
boxContainer.addClass('lake-box-focused');
|
|
5487
|
+
box.event.emit('focus');
|
|
5362
5488
|
}
|
|
5363
5489
|
else {
|
|
5364
5490
|
boxContainer.removeClass('lake-box-focused');
|
|
5365
5491
|
boxContainer.addClass('lake-box-selected');
|
|
5492
|
+
box.event.emit('blur');
|
|
5366
5493
|
}
|
|
5367
5494
|
return;
|
|
5368
5495
|
}
|
|
5369
5496
|
boxContainer.removeClass('lake-box-activated');
|
|
5370
5497
|
boxContainer.removeClass('lake-box-focused');
|
|
5371
5498
|
boxContainer.removeClass('lake-box-selected');
|
|
5499
|
+
box.event.emit('blur');
|
|
5372
5500
|
});
|
|
5373
5501
|
this.event.emit('boxselectionstylechange');
|
|
5374
5502
|
}, 50, {
|
|
@@ -5473,7 +5601,7 @@ class Editor {
|
|
|
5473
5601
|
const range = selection.range;
|
|
5474
5602
|
const stripNode = range.startNode.closest('.lake-box-strip');
|
|
5475
5603
|
const boxNode = stripNode.closest('lake-box');
|
|
5476
|
-
const box =
|
|
5604
|
+
const box = getBox(boxNode);
|
|
5477
5605
|
if (box.type === 'inline') {
|
|
5478
5606
|
if (range.isBoxStart) {
|
|
5479
5607
|
range.setStartBefore(boxNode);
|
|
@@ -5555,15 +5683,15 @@ class Editor {
|
|
|
5555
5683
|
}
|
|
5556
5684
|
bindHistoryEvents() {
|
|
5557
5685
|
this.history.event.on('undo', value => {
|
|
5558
|
-
this.box.renderAll(this);
|
|
5686
|
+
this.box.renderAll(this.container);
|
|
5559
5687
|
this.emitChangeEvent(value);
|
|
5560
5688
|
});
|
|
5561
5689
|
this.history.event.on('redo', value => {
|
|
5562
|
-
this.box.renderAll(this);
|
|
5690
|
+
this.box.renderAll(this.container);
|
|
5563
5691
|
this.emitChangeEvent(value);
|
|
5564
5692
|
});
|
|
5565
5693
|
this.history.event.on('save', value => {
|
|
5566
|
-
this.box.rectifyInstances(this);
|
|
5694
|
+
this.box.rectifyInstances(this.container);
|
|
5567
5695
|
this.emitChangeEvent(value);
|
|
5568
5696
|
});
|
|
5569
5697
|
}
|
|
@@ -5710,8 +5838,8 @@ class Editor {
|
|
|
5710
5838
|
this.container.empty();
|
|
5711
5839
|
this.togglePlaceholderClass(htmlParser.getHTML());
|
|
5712
5840
|
this.container.append(fragment);
|
|
5713
|
-
Editor.box.renderAll(this);
|
|
5714
|
-
this.selection.
|
|
5841
|
+
Editor.box.renderAll(this.container);
|
|
5842
|
+
this.selection.updateByBookmark();
|
|
5715
5843
|
}
|
|
5716
5844
|
// Returns the contents from the editor.
|
|
5717
5845
|
getValue() {
|
|
@@ -5721,21 +5849,35 @@ class Editor {
|
|
|
5721
5849
|
this.selection.toBookmark(bookmark);
|
|
5722
5850
|
return value;
|
|
5723
5851
|
}
|
|
5852
|
+
// Sets the current range to the center position of the box.
|
|
5853
|
+
selectBox(box) {
|
|
5854
|
+
let boxNode = box;
|
|
5855
|
+
if (box instanceof Box) {
|
|
5856
|
+
boxNode = box.node;
|
|
5857
|
+
}
|
|
5858
|
+
else {
|
|
5859
|
+
boxNode = box;
|
|
5860
|
+
}
|
|
5861
|
+
this.selection.range.selectBox(boxNode);
|
|
5862
|
+
}
|
|
5724
5863
|
// Inserts a box into the position of the selection.
|
|
5725
5864
|
insertBox(boxName, boxValue) {
|
|
5726
5865
|
const box = insertBox(this.selection.range, boxName, boxValue);
|
|
5727
5866
|
if (!box) {
|
|
5728
5867
|
throw new Error(`Box '${boxName}' cannot be inserted outside the editor.`);
|
|
5729
5868
|
}
|
|
5730
|
-
const instanceMap = this.box.getInstances(this);
|
|
5869
|
+
const instanceMap = this.box.getInstances(this.container);
|
|
5731
5870
|
instanceMap.set(box.node.id, box);
|
|
5732
5871
|
return box;
|
|
5733
5872
|
}
|
|
5734
5873
|
// Removes the selected box.
|
|
5735
|
-
removeBox() {
|
|
5736
|
-
|
|
5874
|
+
removeBox(box = null) {
|
|
5875
|
+
if (box) {
|
|
5876
|
+
this.selectBox(box);
|
|
5877
|
+
}
|
|
5878
|
+
box = removeBox(this.selection.range);
|
|
5737
5879
|
if (box) {
|
|
5738
|
-
const instanceMap = this.box.getInstances(this);
|
|
5880
|
+
const instanceMap = this.box.getInstances(this.container);
|
|
5739
5881
|
instanceMap.delete(box.node.id);
|
|
5740
5882
|
}
|
|
5741
5883
|
return box;
|
|
@@ -5754,10 +5896,10 @@ class Editor {
|
|
|
5754
5896
|
this.container.append(fragment);
|
|
5755
5897
|
Editor.plugin.loadAll(this);
|
|
5756
5898
|
if (!this.readonly) {
|
|
5757
|
-
this.selection.
|
|
5899
|
+
this.selection.updateByBookmark();
|
|
5758
5900
|
this.history.save();
|
|
5759
5901
|
}
|
|
5760
|
-
Editor.box.renderAll(this);
|
|
5902
|
+
Editor.box.renderAll(this.container);
|
|
5761
5903
|
if (this.toolbar) {
|
|
5762
5904
|
this.toolbar.render(this);
|
|
5763
5905
|
}
|
|
@@ -6414,15 +6556,26 @@ const toolbarItems = [
|
|
|
6414
6556
|
accept: 'image/*',
|
|
6415
6557
|
multiple: true,
|
|
6416
6558
|
},
|
|
6559
|
+
{
|
|
6560
|
+
name: 'file',
|
|
6561
|
+
type: 'upload',
|
|
6562
|
+
icon: icons.get('attachment'),
|
|
6563
|
+
tooltip: locale => locale.toolbar.file(),
|
|
6564
|
+
accept: '*',
|
|
6565
|
+
multiple: true,
|
|
6566
|
+
},
|
|
6417
6567
|
];
|
|
6418
6568
|
|
|
6419
|
-
function
|
|
6420
|
-
const { editor, file, onError, onSuccess } = config;
|
|
6421
|
-
const { requestMethod, requestAction, requestTypes } = editor.config
|
|
6569
|
+
function uploadFile(config) {
|
|
6570
|
+
const { editor, name, file, onError, onSuccess } = config;
|
|
6571
|
+
const { requestMethod, requestAction, requestTypes } = editor.config[name];
|
|
6422
6572
|
if (requestTypes.indexOf(file.type) < 0) {
|
|
6423
|
-
|
|
6573
|
+
if (onError) {
|
|
6574
|
+
onError(`File '${file.name}' is not allowed for uploading.`);
|
|
6575
|
+
}
|
|
6576
|
+
throw new Error(`Cannot upload file '${file.name}' because its type '${file.type}' is not found in ['${requestTypes.join('\', \'')}'].`);
|
|
6424
6577
|
}
|
|
6425
|
-
const box = editor.insertBox(
|
|
6578
|
+
const box = editor.insertBox(name, {
|
|
6426
6579
|
url: URL.createObjectURL(file),
|
|
6427
6580
|
status: 'uploading',
|
|
6428
6581
|
name: file.name,
|
|
@@ -6441,7 +6594,7 @@ function uploadImage(config) {
|
|
|
6441
6594
|
box.updateValue('status', 'error');
|
|
6442
6595
|
box.render();
|
|
6443
6596
|
if (onError) {
|
|
6444
|
-
onError();
|
|
6597
|
+
onError(error.toString());
|
|
6445
6598
|
}
|
|
6446
6599
|
},
|
|
6447
6600
|
onSuccess: body => {
|
|
@@ -6449,7 +6602,7 @@ function uploadImage(config) {
|
|
|
6449
6602
|
box.updateValue('status', 'error');
|
|
6450
6603
|
box.render();
|
|
6451
6604
|
if (onError) {
|
|
6452
|
-
onError();
|
|
6605
|
+
onError('Cannot find the url field.');
|
|
6453
6606
|
}
|
|
6454
6607
|
return;
|
|
6455
6608
|
}
|
|
@@ -6492,9 +6645,9 @@ const defaultItems = [
|
|
|
6492
6645
|
'blockQuote',
|
|
6493
6646
|
'hr',
|
|
6494
6647
|
];
|
|
6495
|
-
const toolbarItemMap = new Map();
|
|
6648
|
+
const toolbarItemMap$1 = new Map();
|
|
6496
6649
|
toolbarItems.forEach(item => {
|
|
6497
|
-
toolbarItemMap.set(item.name, item);
|
|
6650
|
+
toolbarItemMap$1.set(item.name, item);
|
|
6498
6651
|
});
|
|
6499
6652
|
class Toolbar {
|
|
6500
6653
|
constructor(config) {
|
|
@@ -6581,9 +6734,11 @@ class Toolbar {
|
|
|
6581
6734
|
const target = event.target;
|
|
6582
6735
|
const files = target.files || [];
|
|
6583
6736
|
for (const file of files) {
|
|
6584
|
-
|
|
6737
|
+
uploadFile({
|
|
6585
6738
|
editor,
|
|
6739
|
+
name: item.name,
|
|
6586
6740
|
file,
|
|
6741
|
+
onError: error => editor.config.onMessage('error', error),
|
|
6587
6742
|
});
|
|
6588
6743
|
}
|
|
6589
6744
|
});
|
|
@@ -6658,7 +6813,7 @@ class Toolbar {
|
|
|
6658
6813
|
}
|
|
6659
6814
|
let item;
|
|
6660
6815
|
if (typeof name === 'string') {
|
|
6661
|
-
item = toolbarItemMap.get(name);
|
|
6816
|
+
item = toolbarItemMap$1.get(name);
|
|
6662
6817
|
if (!item) {
|
|
6663
6818
|
return;
|
|
6664
6819
|
}
|
|
@@ -6695,7 +6850,7 @@ const hrBox = {
|
|
|
6695
6850
|
box.useEffect(() => {
|
|
6696
6851
|
const hrNode = box.getContainer().find('.lake-hr');
|
|
6697
6852
|
hrNode.on('click', () => {
|
|
6698
|
-
editor.
|
|
6853
|
+
editor.selectBox(box);
|
|
6699
6854
|
});
|
|
6700
6855
|
});
|
|
6701
6856
|
return '<div class="lake-hr"><hr /></div>';
|
|
@@ -6839,7 +6994,7 @@ function openFullScreen(box) {
|
|
|
6839
6994
|
let currentIndex = 0;
|
|
6840
6995
|
const allImageBox = editor.container.find('lake-box[name="image"]');
|
|
6841
6996
|
allImageBox.each((node, index) => {
|
|
6842
|
-
const imageBox =
|
|
6997
|
+
const imageBox = getBox(node);
|
|
6843
6998
|
const imageValue = imageBox.value;
|
|
6844
6999
|
if (imageValue.status !== 'done') {
|
|
6845
7000
|
return;
|
|
@@ -6922,7 +7077,7 @@ function openFullScreen(box) {
|
|
|
6922
7077
|
if (savedRange) {
|
|
6923
7078
|
// fix(image): lose focus when zooming in the iOS
|
|
6924
7079
|
editor.selection.range = savedRange;
|
|
6925
|
-
editor.selection.
|
|
7080
|
+
editor.selection.sync();
|
|
6926
7081
|
}
|
|
6927
7082
|
box.event.emit('closefullscreen');
|
|
6928
7083
|
}, 0);
|
|
@@ -6930,20 +7085,6 @@ function openFullScreen(box) {
|
|
|
6930
7085
|
lightbox.init();
|
|
6931
7086
|
lightbox.loadAndOpen(currentIndex);
|
|
6932
7087
|
}
|
|
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
7088
|
// Displays error icon and filename.
|
|
6948
7089
|
function renderError(imageNode, box) {
|
|
6949
7090
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -7167,13 +7308,19 @@ const imageBox = {
|
|
|
7167
7308
|
else {
|
|
7168
7309
|
imageNode.find('.lake-button-remove').on('click', event => {
|
|
7169
7310
|
event.stopPropagation();
|
|
7170
|
-
|
|
7311
|
+
const xhr = box.getData('xhr');
|
|
7312
|
+
if (xhr) {
|
|
7313
|
+
xhr.abort();
|
|
7314
|
+
}
|
|
7315
|
+
editor.removeBox(box);
|
|
7316
|
+
editor.history.save();
|
|
7317
|
+
editor.selection.sync();
|
|
7171
7318
|
});
|
|
7172
7319
|
}
|
|
7173
7320
|
box.event.emit('render');
|
|
7174
7321
|
});
|
|
7175
7322
|
imageNode.on('click', () => {
|
|
7176
|
-
editor.
|
|
7323
|
+
editor.selectBox(box);
|
|
7177
7324
|
});
|
|
7178
7325
|
},
|
|
7179
7326
|
html: box => {
|
|
@@ -7182,6 +7329,232 @@ const imageBox = {
|
|
|
7182
7329
|
},
|
|
7183
7330
|
};
|
|
7184
7331
|
|
|
7332
|
+
const toolbarItemMap = new Map();
|
|
7333
|
+
class BoxToolbar {
|
|
7334
|
+
constructor(config) {
|
|
7335
|
+
this.placement = 'top';
|
|
7336
|
+
this.buttonItemList = [];
|
|
7337
|
+
this.dropdownItemList = [];
|
|
7338
|
+
this.root = query(config.root);
|
|
7339
|
+
this.editor = config.editor;
|
|
7340
|
+
this.box = config.box;
|
|
7341
|
+
this.items = config.items;
|
|
7342
|
+
if (config.placement) {
|
|
7343
|
+
this.placement = config.placement;
|
|
7344
|
+
}
|
|
7345
|
+
this.container = query('<div class="lake-box-toolbar" />');
|
|
7346
|
+
this.root.addClass('lake-custom-properties');
|
|
7347
|
+
}
|
|
7348
|
+
appendDivider() {
|
|
7349
|
+
this.container.append('<div class="lake-box-toolbar-divider" />');
|
|
7350
|
+
}
|
|
7351
|
+
appendButton(item) {
|
|
7352
|
+
const button = new Button({
|
|
7353
|
+
root: this.container,
|
|
7354
|
+
name: item.name,
|
|
7355
|
+
icon: item.icon,
|
|
7356
|
+
tooltip: typeof item.tooltip === 'string' ? item.tooltip : item.tooltip(this.editor.locale),
|
|
7357
|
+
tabIndex: -1,
|
|
7358
|
+
onClick: () => {
|
|
7359
|
+
item.onClick(this.box, item.name);
|
|
7360
|
+
},
|
|
7361
|
+
});
|
|
7362
|
+
button.render();
|
|
7363
|
+
}
|
|
7364
|
+
appendDropdown(item) {
|
|
7365
|
+
const dropdown = new Dropdown({
|
|
7366
|
+
root: this.container,
|
|
7367
|
+
locale: this.editor.locale,
|
|
7368
|
+
name: item.name,
|
|
7369
|
+
icon: item.icon,
|
|
7370
|
+
accentIcon: item.accentIcon,
|
|
7371
|
+
downIcon: item.downIcon,
|
|
7372
|
+
defaultValue: item.defaultValue,
|
|
7373
|
+
tooltip: item.tooltip,
|
|
7374
|
+
width: item.width,
|
|
7375
|
+
menuType: item.menuType,
|
|
7376
|
+
menuItems: item.menuItems,
|
|
7377
|
+
tabIndex: -1,
|
|
7378
|
+
placement: this.placement === 'top' ? 'bottom' : 'top',
|
|
7379
|
+
onSelect: value => {
|
|
7380
|
+
item.onSelect(this.box, value);
|
|
7381
|
+
},
|
|
7382
|
+
});
|
|
7383
|
+
dropdown.render();
|
|
7384
|
+
}
|
|
7385
|
+
updatePosition() {
|
|
7386
|
+
const boxNode = this.box.node;
|
|
7387
|
+
const position = nodeAndView(boxNode);
|
|
7388
|
+
if (position.left < 0 || position.right < 0 || position.top < 0 || position.bottom < 0) {
|
|
7389
|
+
this.container.hide();
|
|
7390
|
+
return;
|
|
7391
|
+
}
|
|
7392
|
+
this.container.show('flex');
|
|
7393
|
+
const boxNativeNode = this.box.node.get(0);
|
|
7394
|
+
const boxRect = boxNativeNode.getBoundingClientRect();
|
|
7395
|
+
const boxX = boxRect.x + window.scrollX;
|
|
7396
|
+
const boxY = boxRect.y + window.scrollY;
|
|
7397
|
+
const left = (boxX + boxRect.width / 2 - this.container.width() / 2).toFixed(1);
|
|
7398
|
+
const top = (boxY - this.container.height() - 6).toFixed(1);
|
|
7399
|
+
this.container.css({
|
|
7400
|
+
left: `${left}px`,
|
|
7401
|
+
top: `${top}px`,
|
|
7402
|
+
});
|
|
7403
|
+
}
|
|
7404
|
+
// Renders a toolbar for the specified box.
|
|
7405
|
+
render() {
|
|
7406
|
+
this.root.empty();
|
|
7407
|
+
this.root.append(this.container);
|
|
7408
|
+
this.items.forEach(name => {
|
|
7409
|
+
if (name === '|') {
|
|
7410
|
+
this.appendDivider();
|
|
7411
|
+
return;
|
|
7412
|
+
}
|
|
7413
|
+
let item;
|
|
7414
|
+
if (typeof name === 'string') {
|
|
7415
|
+
item = toolbarItemMap.get(name);
|
|
7416
|
+
if (!item) {
|
|
7417
|
+
return;
|
|
7418
|
+
}
|
|
7419
|
+
}
|
|
7420
|
+
else {
|
|
7421
|
+
item = name;
|
|
7422
|
+
}
|
|
7423
|
+
if (item.type === 'button') {
|
|
7424
|
+
this.buttonItemList.push(item);
|
|
7425
|
+
this.appendButton(item);
|
|
7426
|
+
return;
|
|
7427
|
+
}
|
|
7428
|
+
if (item.type === 'dropdown') {
|
|
7429
|
+
this.dropdownItemList.push(item);
|
|
7430
|
+
this.appendDropdown(item);
|
|
7431
|
+
}
|
|
7432
|
+
});
|
|
7433
|
+
this.updatePosition();
|
|
7434
|
+
}
|
|
7435
|
+
unmount() {
|
|
7436
|
+
this.container.remove();
|
|
7437
|
+
}
|
|
7438
|
+
}
|
|
7439
|
+
|
|
7440
|
+
const boxToolbarItems = [
|
|
7441
|
+
{
|
|
7442
|
+
name: 'download',
|
|
7443
|
+
type: 'button',
|
|
7444
|
+
icon: icons.get('download'),
|
|
7445
|
+
tooltip: locale => locale.file.download(),
|
|
7446
|
+
onClick: box => {
|
|
7447
|
+
window.open(box.value.url);
|
|
7448
|
+
},
|
|
7449
|
+
},
|
|
7450
|
+
{
|
|
7451
|
+
name: 'remove',
|
|
7452
|
+
type: 'button',
|
|
7453
|
+
icon: icons.get('remove'),
|
|
7454
|
+
tooltip: locale => locale.file.remove(),
|
|
7455
|
+
onClick: box => {
|
|
7456
|
+
const editor = box.getEditor();
|
|
7457
|
+
if (!editor) {
|
|
7458
|
+
return;
|
|
7459
|
+
}
|
|
7460
|
+
editor.removeBox(box);
|
|
7461
|
+
editor.history.save();
|
|
7462
|
+
editor.selection.sync();
|
|
7463
|
+
},
|
|
7464
|
+
},
|
|
7465
|
+
];
|
|
7466
|
+
function appendContent(fileNode, box) {
|
|
7467
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7468
|
+
const editor = box.getEditor();
|
|
7469
|
+
if (!editor) {
|
|
7470
|
+
return;
|
|
7471
|
+
}
|
|
7472
|
+
const value = box.value;
|
|
7473
|
+
const infoNode = query(safeTemplate `
|
|
7474
|
+
<div class="lake-file-info">
|
|
7475
|
+
<div class="lake-file-type"></div>
|
|
7476
|
+
<div class="lake-file-name">${value.name} (${fileSize(value.size)})</div>
|
|
7477
|
+
</div>
|
|
7478
|
+
`);
|
|
7479
|
+
const typeNode = infoNode.find('.lake-file-type');
|
|
7480
|
+
if (value.status === 'uploading') {
|
|
7481
|
+
const percent = Math.round(value.percent || 0);
|
|
7482
|
+
const progressNode = query(safeTemplate `
|
|
7483
|
+
<div class="lake-progress">
|
|
7484
|
+
<div class="lake-percent">${percent} %</div>
|
|
7485
|
+
</div>
|
|
7486
|
+
`);
|
|
7487
|
+
const circleNotchIcon = icons.get('circleNotch');
|
|
7488
|
+
if (circleNotchIcon) {
|
|
7489
|
+
progressNode.prepend(circleNotchIcon);
|
|
7490
|
+
}
|
|
7491
|
+
typeNode.replaceWith(progressNode);
|
|
7492
|
+
}
|
|
7493
|
+
else {
|
|
7494
|
+
const fileIcon = value.status === 'error' ? icons.get('warningCircle') : icons.get('file');
|
|
7495
|
+
if (fileIcon) {
|
|
7496
|
+
typeNode.append(fileIcon);
|
|
7497
|
+
}
|
|
7498
|
+
}
|
|
7499
|
+
fileNode.append(infoNode);
|
|
7500
|
+
});
|
|
7501
|
+
}
|
|
7502
|
+
const fileBox = {
|
|
7503
|
+
type: 'inline',
|
|
7504
|
+
name: 'file',
|
|
7505
|
+
render: box => {
|
|
7506
|
+
const editor = box.getEditor();
|
|
7507
|
+
if (!editor) {
|
|
7508
|
+
return;
|
|
7509
|
+
}
|
|
7510
|
+
const value = box.value;
|
|
7511
|
+
const container = box.getContainer();
|
|
7512
|
+
const fileNode = query('<div class="lake-file" />');
|
|
7513
|
+
fileNode.addClass(`lake-file-${value.status}`);
|
|
7514
|
+
if (editor.readonly) {
|
|
7515
|
+
fileNode.addClass('lake-file-readonly');
|
|
7516
|
+
}
|
|
7517
|
+
appendContent(fileNode, box);
|
|
7518
|
+
container.empty();
|
|
7519
|
+
container.append(fileNode);
|
|
7520
|
+
if (!editor.readonly) {
|
|
7521
|
+
fileNode.on('click', () => {
|
|
7522
|
+
editor.selectBox(box);
|
|
7523
|
+
});
|
|
7524
|
+
let toolbar = null;
|
|
7525
|
+
const scrollListener = () => {
|
|
7526
|
+
if (toolbar) {
|
|
7527
|
+
toolbar.updatePosition();
|
|
7528
|
+
}
|
|
7529
|
+
};
|
|
7530
|
+
box.event.on('focus', () => {
|
|
7531
|
+
const items = value.status === 'done' ? boxToolbarItems : boxToolbarItems.filter(item => item.name === 'remove');
|
|
7532
|
+
toolbar = new BoxToolbar({
|
|
7533
|
+
root: editor.popupContainer,
|
|
7534
|
+
editor,
|
|
7535
|
+
box,
|
|
7536
|
+
items,
|
|
7537
|
+
});
|
|
7538
|
+
toolbar.render();
|
|
7539
|
+
editor.root.on('scroll', scrollListener);
|
|
7540
|
+
});
|
|
7541
|
+
box.event.on('blur', () => {
|
|
7542
|
+
if (toolbar) {
|
|
7543
|
+
toolbar.unmount();
|
|
7544
|
+
toolbar = null;
|
|
7545
|
+
}
|
|
7546
|
+
editor.root.off('scroll', scrollListener);
|
|
7547
|
+
});
|
|
7548
|
+
}
|
|
7549
|
+
else {
|
|
7550
|
+
fileNode.on('click', () => {
|
|
7551
|
+
window.open(value.url);
|
|
7552
|
+
});
|
|
7553
|
+
}
|
|
7554
|
+
box.event.emit('render');
|
|
7555
|
+
},
|
|
7556
|
+
};
|
|
7557
|
+
|
|
7185
7558
|
const config = {
|
|
7186
7559
|
comment: '#57606a',
|
|
7187
7560
|
name: '#444d56',
|
|
@@ -7286,7 +7659,7 @@ const codeBlockBox = {
|
|
|
7286
7659
|
Please check if the "lake-codemirror" library is added to this page.
|
|
7287
7660
|
`.trim());
|
|
7288
7661
|
codeBlockNode.on('click', () => {
|
|
7289
|
-
editor.
|
|
7662
|
+
editor.selectBox(box);
|
|
7290
7663
|
});
|
|
7291
7664
|
return;
|
|
7292
7665
|
}
|
|
@@ -7391,7 +7764,7 @@ var copy = (editor) => {
|
|
|
7391
7764
|
if (!dataTransfer) {
|
|
7392
7765
|
return;
|
|
7393
7766
|
}
|
|
7394
|
-
const box =
|
|
7767
|
+
const box = getBox(boxNode);
|
|
7395
7768
|
const content = box.getHTML();
|
|
7396
7769
|
dataTransfer.setData('text/html', content);
|
|
7397
7770
|
});
|
|
@@ -7418,7 +7791,7 @@ var cut = (editor) => {
|
|
|
7418
7791
|
if (!dataTransfer) {
|
|
7419
7792
|
return;
|
|
7420
7793
|
}
|
|
7421
|
-
const box =
|
|
7794
|
+
const box = getBox(boxNode);
|
|
7422
7795
|
const content = box.getHTML();
|
|
7423
7796
|
dataTransfer.setData('text/html', content);
|
|
7424
7797
|
editor.removeBox();
|
|
@@ -7484,7 +7857,7 @@ function insertFirstNode(editor, otherNode) {
|
|
|
7484
7857
|
const range = editor.selection.range;
|
|
7485
7858
|
const boxNode = range.startNode.closest('lake-box');
|
|
7486
7859
|
if (boxNode.length > 0) {
|
|
7487
|
-
const box =
|
|
7860
|
+
const box = getBox(boxNode);
|
|
7488
7861
|
if (box.type === 'inline') {
|
|
7489
7862
|
if (range.isBoxStart) {
|
|
7490
7863
|
range.setStartBefore(boxNode);
|
|
@@ -7515,7 +7888,7 @@ function insertFirstNode(editor, otherNode) {
|
|
|
7515
7888
|
}
|
|
7516
7889
|
const block = range.startNode.closestBlock();
|
|
7517
7890
|
if (otherNode.isBlockBox) {
|
|
7518
|
-
const box =
|
|
7891
|
+
const box = getBox(otherNode);
|
|
7519
7892
|
const value = otherNode.attr('value') !== '' ? box.value : undefined;
|
|
7520
7893
|
editor.insertBox(box.name, value);
|
|
7521
7894
|
otherNode.remove();
|
|
@@ -7527,7 +7900,7 @@ function insertFirstNode(editor, otherNode) {
|
|
|
7527
7900
|
if (block.isEmpty && block.name === 'p') {
|
|
7528
7901
|
block.replaceWith(otherNode);
|
|
7529
7902
|
otherNode.find('lake-box').each(node => {
|
|
7530
|
-
|
|
7903
|
+
getBox(node).render();
|
|
7531
7904
|
});
|
|
7532
7905
|
range.shrinkAfter(otherNode);
|
|
7533
7906
|
return;
|
|
@@ -7601,9 +7974,11 @@ var paste = (editor) => {
|
|
|
7601
7974
|
if (dataTransfer.files.length > 0) {
|
|
7602
7975
|
for (const file of dataTransfer.files) {
|
|
7603
7976
|
if (requestTypes.indexOf(file.type) >= 0) {
|
|
7604
|
-
|
|
7977
|
+
uploadFile({
|
|
7605
7978
|
editor,
|
|
7979
|
+
name: file.type.indexOf('image/') === 0 ? 'image' : 'file',
|
|
7606
7980
|
file,
|
|
7981
|
+
onError: error => editor.config.onMessage('error', error),
|
|
7607
7982
|
});
|
|
7608
7983
|
}
|
|
7609
7984
|
}
|
|
@@ -7626,7 +8001,7 @@ var paste = (editor) => {
|
|
|
7626
8001
|
editor.event.emit('beforepaste', fragment);
|
|
7627
8002
|
fixClipboardData(fragment);
|
|
7628
8003
|
pasteFragment(editor, fragment);
|
|
7629
|
-
editor.box.renderAll(editor);
|
|
8004
|
+
editor.box.renderAll(editor.container);
|
|
7630
8005
|
});
|
|
7631
8006
|
};
|
|
7632
8007
|
|
|
@@ -7654,7 +8029,7 @@ var drop = (editor) => {
|
|
|
7654
8029
|
dragEvent.preventDefault();
|
|
7655
8030
|
return;
|
|
7656
8031
|
}
|
|
7657
|
-
const box =
|
|
8032
|
+
const box = getBox(boxNode);
|
|
7658
8033
|
if (box.type === 'inline') {
|
|
7659
8034
|
dragEvent.preventDefault();
|
|
7660
8035
|
return;
|
|
@@ -7752,7 +8127,7 @@ var drop = (editor) => {
|
|
|
7752
8127
|
return;
|
|
7753
8128
|
}
|
|
7754
8129
|
dragEvent.preventDefault();
|
|
7755
|
-
const draggedBox =
|
|
8130
|
+
const draggedBox = getBox(draggedNode);
|
|
7756
8131
|
const range = editor.selection.range;
|
|
7757
8132
|
if (targetBlock.isBox) {
|
|
7758
8133
|
if (dropPosition === 'top') {
|
|
@@ -8494,15 +8869,17 @@ class LinkPopup {
|
|
|
8494
8869
|
if (!this.linkNode) {
|
|
8495
8870
|
return;
|
|
8496
8871
|
}
|
|
8872
|
+
const position = nodeAndView(this.linkNode);
|
|
8873
|
+
if (position.left < 0 || position.right < 0 || position.top < 0 || position.bottom < 0) {
|
|
8874
|
+
this.container.css('visibility', 'hidden');
|
|
8875
|
+
return;
|
|
8876
|
+
}
|
|
8877
|
+
this.container.css('visibility', '');
|
|
8497
8878
|
const linkNativeNode = this.linkNode.get(0);
|
|
8498
8879
|
// Returns a DOMRect object providing information about the size of an element and its position relative to the viewport.
|
|
8499
8880
|
const linkRect = linkNativeNode.getBoundingClientRect();
|
|
8500
8881
|
const linkX = linkRect.x + window.scrollX;
|
|
8501
8882
|
const linkY = linkRect.y + window.scrollY;
|
|
8502
|
-
if (linkX < 0 || linkY < 0) {
|
|
8503
|
-
this.hide();
|
|
8504
|
-
return;
|
|
8505
|
-
}
|
|
8506
8883
|
// link.x + popup.width > window.width
|
|
8507
8884
|
if (linkRect.x + this.container.width() > window.innerWidth) {
|
|
8508
8885
|
// link.x + window.scrollX - (popup.width - link.width)
|
|
@@ -8564,14 +8941,14 @@ var link = (editor) => {
|
|
|
8564
8941
|
const range = editor.selection.range;
|
|
8565
8942
|
range.setStartAfter(node);
|
|
8566
8943
|
range.collapseToStart();
|
|
8567
|
-
editor.selection.
|
|
8944
|
+
editor.selection.sync();
|
|
8568
8945
|
editor.history.save();
|
|
8569
8946
|
},
|
|
8570
8947
|
onRemove: node => {
|
|
8571
8948
|
const range = editor.selection.range;
|
|
8572
8949
|
range.setStartAfter(node);
|
|
8573
8950
|
range.collapseToStart();
|
|
8574
|
-
editor.selection.
|
|
8951
|
+
editor.selection.sync();
|
|
8575
8952
|
editor.history.save();
|
|
8576
8953
|
},
|
|
8577
8954
|
});
|
|
@@ -8618,7 +8995,7 @@ var hr = (editor) => {
|
|
|
8618
8995
|
const fragment = new Fragment(nativeFragment);
|
|
8619
8996
|
fragment.find('hr').each(nativeNode => {
|
|
8620
8997
|
const node = query(nativeNode);
|
|
8621
|
-
const box =
|
|
8998
|
+
const box = getBox('hr');
|
|
8622
8999
|
node.replaceWith(box.node);
|
|
8623
9000
|
});
|
|
8624
9001
|
});
|
|
@@ -8642,7 +9019,7 @@ var image = (editor) => {
|
|
|
8642
9019
|
const fragment = new Fragment(nativeFragment);
|
|
8643
9020
|
fragment.find('img').each(nativeNode => {
|
|
8644
9021
|
const node = query(nativeNode);
|
|
8645
|
-
const box =
|
|
9022
|
+
const box = getBox('image');
|
|
8646
9023
|
const value = node.attr('data-lake-value');
|
|
8647
9024
|
if (value === '') {
|
|
8648
9025
|
box.value = {
|
|
@@ -8664,6 +9041,39 @@ var image = (editor) => {
|
|
|
8664
9041
|
});
|
|
8665
9042
|
};
|
|
8666
9043
|
|
|
9044
|
+
var file = (editor) => {
|
|
9045
|
+
editor.setPluginConfig('file', {
|
|
9046
|
+
requestMethod: 'POST',
|
|
9047
|
+
requestTypes: [
|
|
9048
|
+
'application/zip',
|
|
9049
|
+
'application/x-zip-compressed',
|
|
9050
|
+
'application/vnd.rar',
|
|
9051
|
+
'image/gif',
|
|
9052
|
+
'image/jpeg',
|
|
9053
|
+
'image/png',
|
|
9054
|
+
'image/svg+xml',
|
|
9055
|
+
'text/plain',
|
|
9056
|
+
'text/html',
|
|
9057
|
+
'application/pdf',
|
|
9058
|
+
'application/msword',
|
|
9059
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
9060
|
+
'application/vnd.ms-excel',
|
|
9061
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
9062
|
+
'application/vnd.ms-powerpoint',
|
|
9063
|
+
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
9064
|
+
],
|
|
9065
|
+
});
|
|
9066
|
+
if (editor.readonly) {
|
|
9067
|
+
return;
|
|
9068
|
+
}
|
|
9069
|
+
editor.command.add('file', {
|
|
9070
|
+
execute: (value) => {
|
|
9071
|
+
editor.insertBox('file', value);
|
|
9072
|
+
editor.history.save();
|
|
9073
|
+
},
|
|
9074
|
+
});
|
|
9075
|
+
};
|
|
9076
|
+
|
|
8667
9077
|
const langList = [
|
|
8668
9078
|
'text',
|
|
8669
9079
|
'c',
|
|
@@ -9288,8 +9698,7 @@ var backspaceKey = (editor) => {
|
|
|
9288
9698
|
const prevNode = range.getPrevNode();
|
|
9289
9699
|
if (prevNode.isBox) {
|
|
9290
9700
|
event.preventDefault();
|
|
9291
|
-
|
|
9292
|
-
editor.removeBox();
|
|
9701
|
+
editor.removeBox(prevNode);
|
|
9293
9702
|
editor.history.save();
|
|
9294
9703
|
return;
|
|
9295
9704
|
}
|
|
@@ -9408,8 +9817,7 @@ var deleteKey = (editor) => {
|
|
|
9408
9817
|
const nextNode = range.getNextNode();
|
|
9409
9818
|
if (nextNode.isBox) {
|
|
9410
9819
|
event.preventDefault();
|
|
9411
|
-
|
|
9412
|
-
editor.removeBox();
|
|
9820
|
+
editor.removeBox(nextNode);
|
|
9413
9821
|
editor.history.save();
|
|
9414
9822
|
return;
|
|
9415
9823
|
}
|
|
@@ -9590,7 +9998,7 @@ var escapeKey = (editor) => {
|
|
|
9590
9998
|
event.preventDefault();
|
|
9591
9999
|
const boxNode = range.commonAncestor.closest('lake-box');
|
|
9592
10000
|
range.selectBoxEnd(boxNode);
|
|
9593
|
-
selection.
|
|
10001
|
+
selection.sync();
|
|
9594
10002
|
return;
|
|
9595
10003
|
}
|
|
9596
10004
|
if (editor.hasFocus) {
|
|
@@ -9602,6 +10010,7 @@ var escapeKey = (editor) => {
|
|
|
9602
10010
|
|
|
9603
10011
|
Editor.box.add(hrBox);
|
|
9604
10012
|
Editor.box.add(imageBox);
|
|
10013
|
+
Editor.box.add(fileBox);
|
|
9605
10014
|
Editor.box.add(codeBlockBox);
|
|
9606
10015
|
Editor.plugin.add(copy);
|
|
9607
10016
|
Editor.plugin.add(cut);
|
|
@@ -9631,6 +10040,7 @@ Editor.plugin.add(formatPainter);
|
|
|
9631
10040
|
Editor.plugin.add(link);
|
|
9632
10041
|
Editor.plugin.add(hr);
|
|
9633
10042
|
Editor.plugin.add(image);
|
|
10043
|
+
Editor.plugin.add(file);
|
|
9634
10044
|
Editor.plugin.add(codeBlock);
|
|
9635
10045
|
Editor.plugin.add(markdown);
|
|
9636
10046
|
Editor.plugin.add(enterKey);
|