rn-rich-text-editor 0.0.5 → 0.0.7

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.
@@ -1,133 +1,710 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HTML = void 0;
3
4
  exports.createHTML = createHTML;
4
5
  const contentCSS_1 = require("./contentCSS");
5
- function createHTML() {
6
- return {
7
- html: `
6
+ function createHTML(options = {}) {
7
+ const { backgroundColor = '#FFF', color = '#000033', caretColor = '', placeholderColor = '#a9a9a9', contentCSSText = '', cssText = '', initialCSSText = '', pasteAsPlainText = false, pasteListener = false, keyDownListener = false, keyUpListener = false, inputListener = false, autoCapitalize = 'off', enterKeyHint = '', initialFocus = false, spellcheck = true, autoCorrect = false, defaultParagraphSeparator = 'div',
8
+ // When first gaining focus, the cursor moves to the end of the text
9
+ firstFocusEnd = true, useContainer = true, styleWithCSS = false, useCharacter = true, defaultHttps = true, } = options;
10
+ return `
8
11
  <!DOCTYPE html>
9
12
  <html>
10
13
  <head>
11
- <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
12
- <style>
13
- html, body {
14
- margin: 0;
15
- padding: 0;
16
- font-family: system-ui;
17
- min-height: 200px;
18
- height: 100%;
19
- }
20
- #editor {
21
- padding: 12px;
22
- min-height: 150px;
23
- outline: none;
24
- -webkit-user-select: text;
25
- user-select: text;
26
- }
27
- [placeholder]:empty::before {
28
- content: attr(placeholder);
29
- color: #999;
30
- }
31
- </style>
32
- ${(0, contentCSS_1.getContentCSS)()}
14
+ <title>RN Rich Text Editor</title>
15
+ <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
16
+ <style>
17
+ ${initialCSSText}
18
+ * {outline: 0px solid transparent;-webkit-tap-highlight-color: rgba(0,0,0,0);-webkit-touch-callout: none;box-sizing: border-box;}
19
+ html, body { margin: 0; padding: 0;font-family: Arial, Helvetica, sans-serif; font-size:1em; height: 100%}
20
+ body { overflow-y: hidden; -webkit-overflow-scrolling: touch;background-color: ${backgroundColor};caret-color: ${caretColor};}
21
+ .content {font-family: Arial, Helvetica, sans-serif;color: ${color}; width: 100%;${useContainer ? '' : 'height:100%;'}-webkit-overflow-scrolling: touch;padding-left: 0;padding-right: 0;}
22
+ .pell { height: 100%;} .pell-content { outline: 0; overflow-y: auto;padding: 10px;height: 100%;${contentCSSText}}
23
+ </style>
24
+ <style>
25
+ [placeholder]:empty:before { content: attr(placeholder); color: ${placeholderColor};}
26
+ [placeholder]:empty:focus:before { content: attr(placeholder);color: ${placeholderColor};display:block;}
27
+ </style>
28
+ ${(0, contentCSS_1.getContentCSS)()}
29
+ <style>${cssText}</style>
33
30
  </head>
34
31
  <body>
35
- <div id="editor" contenteditable="true" placeholder="Start typing..."></div>
36
-
32
+ <div class="content"><div id="editor" class="pell"/></div>
37
33
  <script>
38
- const editor = document.getElementById('editor');
39
-
40
- function post(type, data) {
41
- window.ReactNativeWebView.postMessage(
42
- JSON.stringify({ type, data })
43
- );
44
- }
45
-
46
- editor.addEventListener('input', () => {
47
- post('CONTENT_CHANGE', editor.innerHTML);
48
- post('OFFSET_HEIGHT', editor.scrollHeight);
49
- });
50
-
51
- document.addEventListener('selectionchange', () => {
52
- post('SELECTION_CHANGE', {
53
- bold: document.queryCommandState('bold'),
54
- italic: document.queryCommandState('italic'),
55
- underline: document.queryCommandState('underline')
34
+ var __DEV__ = !!${window.__DEV__};
35
+ var _ = (function (exports) {
36
+ var anchorNode, focusNode, anchorOffset, focusOffset, _focusCollapse = false, cNode;
37
+ var _log = console.log;
38
+ var placeholderColor = '${placeholderColor}';
39
+ var _randomID = 99;
40
+ var generateId = function (){
41
+ return "auto_" + (++ _randomID);
42
+ }
43
+
44
+ var body = document.body, docEle = document.documentElement;
45
+ var defaultParagraphSeparatorString = 'defaultParagraphSeparator';
46
+ var formatBlock = 'formatBlock';
47
+ var editor = null, editorFoucs = false, o_height = 0, compositionStatus = 0, paragraphStatus = 0, enterStatus = 0;
48
+ function addEventListener(parent, type, listener) {
49
+ return parent.addEventListener(type, listener);
50
+ };
51
+ function appendChild(parent, child) {
52
+ return parent.appendChild(child);
53
+ };
54
+ function createElement(tag) {
55
+ return document.createElement(tag);
56
+ };
57
+ function queryCommandState(command) {
58
+ return document.queryCommandState(command);
59
+ };
60
+ function queryCommandValue(command) {
61
+ return document.queryCommandValue(command);
62
+ };
63
+ function query(command){
64
+ return document.querySelector(command);
65
+ }
66
+ function querys(command){
67
+ return document.querySelectorAll(command);
68
+ }
69
+
70
+ function exec(command) {
71
+ var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
72
+ return document.execCommand(command, false, value);
73
+ };
74
+
75
+ function asyncExec(command){
76
+ var args = Array.prototype.slice.call(arguments);
77
+ setTimeout(function(){
78
+ exec.apply(null, args);
79
+ }, 0);
80
+ }
81
+
82
+ function _postMessage(data){
83
+ exports.window.postMessage(JSON.stringify(data));
84
+ }
85
+ function postAction(data){
86
+ editor.content.contentEditable === 'true' && _postMessage(data);
87
+ };
88
+
89
+ exports.isRN && (
90
+ console.log = function (){
91
+ var data = Array.prototype.slice.call(arguments);
92
+ __DEV__ && _log.apply(null, data);
93
+ __DEV__ && postAction({type: 'LOG', data});
94
+ }
95
+ )
96
+
97
+ function formatParagraph(async){
98
+ (async ? asyncExec: exec)(formatBlock, '<' + editor.paragraphSeparator + '>' );
99
+ }
100
+
101
+ function getNodeByClass(node, className){
102
+ return node ? (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(className)? node : getNodeByClass(node.parentNode, className)): node;
103
+ }
104
+
105
+ function getNodeByName(node, name){
106
+ return node? (node.nodeType === Node.ELEMENT_NODE && node.nodeName === name? node: getNodeByName(node.parentNode, name)): node;
107
+ }
108
+
109
+ function setCollapse(node){
110
+ var selection = window.getSelection();
111
+ selection.selectAllChildren(node);
112
+ selection.collapseToEnd();
113
+ }
114
+
115
+ function checkboxNode(node){
116
+ return getNodeByClass(node, 'x-todo');
117
+ }
118
+
119
+ function execCheckboxList (node, html){
120
+ var html = createCheckbox(node ? node.innerHTML: '');
121
+ var HTML = "<ol class='x-todo'><li>"+ html +"</li></ol>"
122
+ var foNode;
123
+ if (node){
124
+ node.innerHTML = HTML;
125
+ foNode = node.firstChild;
126
+ } else {
127
+ exec("insertHTML", HTML);
128
+ }
129
+
130
+ foNode && setTimeout(function (){
131
+ setCollapse(foNode);
132
+ });
133
+ }
134
+
135
+ var _checkboxFlag = 0; // 1 = add checkbox; 2 = cancel checkbox
136
+ function cancelCheckboxList(box){
137
+ _checkboxFlag = 2;
138
+ exec("insertOrderedList");
139
+ setCollapse(box);
140
+ }
141
+
142
+ function createCheckbox(end){
143
+ var html = '<span contenteditable="false" class="x-todo-box"><input type="checkbox"></span>';
144
+ if (end && typeof end !== 'boolean'){
145
+ html += end;
146
+ } else if(end !== false){
147
+ html += "<br/>"
148
+ }
149
+ return html;
150
+ }
151
+
152
+ function insertCheckbox (node){
153
+ var li = getNodeByName(node, 'LI');
154
+ li.insertBefore(document.createRange().createContextualFragment(createCheckbox(false)), li.firstChild);
155
+ setCollapse(node);
156
+ }
157
+
158
+ function getCheckbox (node){
159
+ return getNodeByClass(node, "x-todo-box");
160
+ }
161
+
162
+ function saveSelection(){
163
+ var sel = window.getSelection();
164
+ currentSelection = sel;
165
+ anchorNode = sel.anchorNode;
166
+ anchorOffset = sel.anchorOffset;
167
+ focusNode = sel.focusNode;
168
+ focusOffset = sel.focusOffset;
169
+ }
170
+
171
+ function focusCurrent(){
172
+ editor.content.focus();
173
+ try {
174
+ var selection = window.getSelection();
175
+ if (anchorNode){
176
+ if (anchorNode !== selection.anchorNode && !selection.containsNode(anchorNode)){
177
+ _focusCollapse = true;
178
+ selection.collapse(anchorNode, anchorOffset);
179
+ }
180
+ } else if(${firstFocusEnd} && !_focusCollapse ){
181
+ _focusCollapse = true;
182
+ selection.selectAllChildren(editor.content);
183
+ selection.collapseToEnd();
184
+ }
185
+ } catch(e){
186
+ console.log(e)
187
+ }
188
+ }
189
+
190
+ var _keyDown = false;
191
+ function handleChange (event){
192
+ var node = anchorNode;
193
+ Actions.UPDATE_HEIGHT();
194
+ Actions.UPDATE_OFFSET_Y();
195
+ if (_keyDown){
196
+ if(_checkboxFlag === 1 && checkboxNode(node)){
197
+ _checkboxFlag = 0;
198
+ var sib = node.previousSibling;
199
+ if (!sib || sib.childNodes.length > 1){
200
+ insertCheckbox(node);
201
+ }
202
+ } else if(_checkboxFlag === 2){
203
+ _checkboxFlag = 0;
204
+ var sp = createElement(editor.paragraphSeparator);
205
+ var br = createElement('br');
206
+ sp.appendChild(br);
207
+ setTimeout(function (){
208
+ node.replaceChild(sp, node.lastElementChild);
209
+ setCollapse(sp);
210
+ });
211
+ }
212
+ }
213
+ }
214
+
215
+ function adjustNestedElements() {
216
+ // adjust ul/ol if we use p separator
217
+ // since nesting is not valid for p
218
+ if (editor.paragraphSeparator == 'p') {
219
+ var selection = window.getSelection();
220
+
221
+ let lists = document.querySelectorAll("ol, ul");
222
+ for (let i = 0; i < lists.length; i++) {
223
+ let ele = lists[i];
224
+ let parentNode = ele.parentNode;
225
+ if (parentNode.tagName === 'P' && parentNode.lastChild === parentNode.firstChild) {
226
+ parentNode.insertAdjacentElement('beforebegin', ele);
227
+ parentNode.remove()
228
+ }
229
+ }
230
+
231
+ selection.collapse(anchorNode, anchorOffset);
232
+ }
233
+ }
234
+
235
+ var Actions = {
236
+ bold: { state: function() { return queryCommandState('bold'); }, result: function() { return exec('bold'); }},
237
+ italic: { state: function() { return queryCommandState('italic'); }, result: function() { return exec('italic'); }},
238
+ underline: { state: function() { return queryCommandState('underline'); }, result: function() { return exec('underline'); }},
239
+ strikeThrough: { state: function() { return queryCommandState('strikeThrough'); }, result: function() { return exec('strikeThrough'); }},
240
+ subscript: { state: function() { return queryCommandState('subscript'); }, result: function() { return exec('subscript'); }},
241
+ superscript: { state: function() { return queryCommandState('superscript'); }, result: function() { return exec('superscript'); }},
242
+ heading1: { state: function() { return queryCommandValue(formatBlock) === 'h1'; }, result: function() { return exec(formatBlock, '<h1>'); }},
243
+ heading2: { state: function() { return queryCommandValue(formatBlock) === 'h2'; }, result: function() { return exec(formatBlock, '<h2>'); }},
244
+ heading3: { state: function() { return queryCommandValue(formatBlock) === 'h3'; }, result: function() { return exec(formatBlock, '<h3>'); }},
245
+ heading4: { state: function() { return queryCommandValue(formatBlock) === 'h4'; }, result: function() { return exec(formatBlock, '<h4>'); }},
246
+ heading5: { state: function() { return queryCommandValue(formatBlock) === 'h5'; }, result: function() { return exec(formatBlock, '<h5>'); }},
247
+ heading6: { state: function() { return queryCommandValue(formatBlock) === 'h6'; }, result: function() { return exec(formatBlock, '<h6>'); }},
248
+ paragraph: { state: function() { return queryCommandValue(formatBlock) === 'p'; }, result: function() { return exec(formatBlock, '<p>'); }},
249
+ quote: { result: function() { return exec(formatBlock, '<blockquote>'); }},
250
+ removeFormat: { result: function() { return exec('removeFormat'); }},
251
+ orderedList: {
252
+ state: function() { return !checkboxNode(window.getSelection().anchorNode) && queryCommandState('insertOrderedList'); },
253
+ result: function() {
254
+ if (!!checkboxNode(window.getSelection().anchorNode)) return;
255
+
256
+ let flag = exec('insertOrderedList');
257
+ adjustNestedElements();
258
+ return flag;
259
+ }
260
+ },
261
+ unorderedList: {
262
+ state: function() { return queryCommandState('insertUnorderedList');},
263
+ result: function() {
264
+ if (!!checkboxNode(window.getSelection().anchorNode)) return;
265
+
266
+ let flag = exec('insertUnorderedList');
267
+ adjustNestedElements();
268
+ return flag;
269
+ }
270
+ },
271
+ code: { result: function(type) {
272
+ var flag = exec(formatBlock, '<pre>');
273
+ var node = anchorNode.nodeName === "PRE" ? anchorNode: anchorNode.parentNode;
274
+ if (node.nodeName === 'PRE'){
275
+ type && node.setAttribute("type", type);
276
+ node.innerHTML = "<code type='"+(type || '') +"'>" + node.innerHTML + "</code>";
277
+ // var br = createElement("br");
278
+ // node.parentNode.insertBefore(br, node.nextSibling);
279
+ setTimeout(function (){
280
+ setCollapse(node.firstChild);
281
+ });
282
+ }
283
+ return flag;
284
+ }},
285
+ line: { result: function() { return exec('insertHorizontalRule'); }},
286
+ redo: { result: function() { return exec('redo'); }},
287
+ undo: { result: function() { return exec('undo'); }},
288
+ indent: { result: function() { return exec('indent'); }},
289
+ outdent: { result: function() { return exec('outdent'); }},
290
+ outdent: { result: function() { return exec('outdent'); }},
291
+ justifyCenter: { state: function() { return queryCommandState('justifyCenter'); }, result: function() { return exec('justifyCenter'); }},
292
+ justifyLeft: { state: function() { return queryCommandState('justifyLeft'); }, result: function() { return exec('justifyLeft'); }},
293
+ justifyRight: { state: function() { return queryCommandState('justifyRight'); }, result: function() { return exec('justifyRight'); }},
294
+ justifyFull: { state: function() { return queryCommandState('justifyFull'); }, result: function() { return exec('justifyFull'); }},
295
+ hiliteColor: { state: function() { return queryCommandValue('backColor'); }, result: function(color) { return exec('backColor', color); }},
296
+ foreColor: { state: function() { return queryCommandValue('foreColor'); }, result: function(color) { return exec('foreColor', color); }},
297
+ fontSize: { state: function() { return queryCommandValue('fontSize'); }, result: function(size) { return exec('fontSize', size); }},
298
+ fontName: { result: function(name) { return exec('fontName', name); }},
299
+ link: {
300
+ // result: function(data) {
301
+ // data = data || {};
302
+ // var title = data.title;
303
+ // title = title || window.getSelection().toString();
304
+ // // title = title || window.prompt('Enter the link title');
305
+ // var url = data.url || window.prompt('Enter the link URL');
306
+ // if (url){
307
+ // exec('insertHTML', "<a href='"+ url +"'>"+(title || url)+"</a>");
308
+ // }
309
+ // }
310
+ result: function(data) {
311
+ var sel = document.getSelection();
312
+ data = data || {};
313
+ var url = data.url || window.prompt('Enter the link URL');
314
+
315
+ if (url) {
316
+ let href = url
317
+ if (${defaultHttps} && !href.startsWith("http")) {
318
+ href = "https://" + href
319
+ }
320
+
321
+ var el = document.createElement("a");
322
+ el.setAttribute("href", href);
323
+
324
+ var title = data.title || sel.toString() || url;
325
+ el.text = title;
326
+
327
+ // when adding a link, if our current node is empty, it may have a <br>
328
+ // if so, replace it with '' so the added link doesn't end up with an extra space.
329
+ // Also, if totally empty, we must format the paragraph to add the link into the container.
330
+ var mustFormat = false;
331
+ if (sel.anchorNode && sel.anchorNode.innerHTML === '<br>') {
332
+ sel.anchorNode.innerHTML = '';
333
+ } else if (!sel.anchorNode || sel.anchorNode === editor.content) {
334
+ mustFormat = true;
335
+ }
336
+
337
+ // insert like this so we can replace current selection, if any
338
+ var range = sel.getRangeAt(0);
339
+ range.deleteContents();
340
+ range.insertNode(el);
341
+
342
+ // restore cursor to end
343
+ range.setStartAfter(el);
344
+ range.setEndAfter(el);
345
+ sel.removeAllRanges();
346
+ sel.addRange(range);
347
+
348
+ // format paragraph if needed
349
+ if (mustFormat){
350
+ formatParagraph();
351
+ }
352
+
353
+ // save selection, and fire on change to our webview
354
+ saveSelection();
355
+ editor.settings.onChange();
356
+ }
357
+ }
358
+ },
359
+ image: {
360
+ result: function(url, style) {
361
+ if (url){
362
+ exec('insertHTML', "<img style='"+ (style || '')+"' src='"+ url +"'/>");
363
+ // This is needed, or the image will not be inserted if the html is empty
364
+ exec('insertHTML', "<br/>");
365
+ Actions.UPDATE_HEIGHT();
366
+ }
367
+ }
368
+ },
369
+ html: {
370
+ result: function (html){
371
+ if (html){
372
+ exec('insertHTML', html);
373
+ Actions.UPDATE_HEIGHT();
374
+ }
375
+ }
376
+ },
377
+ text: { result: function (text){ text && exec('insertText', text); }},
378
+ video: {
379
+ result: function(url, style) {
380
+ if (url) {
381
+ var thumbnail = url.replace(/.(mp4|m3u8)/g, '') + '-thumbnail';
382
+ var html = "<br><div style='"+ (style || '')+"'><video src='"+ url +"' poster='"+ thumbnail + "' controls><source src='"+ url +"' type='video/mp4'>No video tag support</video></div><br>";
383
+ exec('insertHTML', html);
384
+ Actions.UPDATE_HEIGHT();
385
+ }
386
+ }
387
+ },
388
+ checkboxList: {
389
+ state: function(){return checkboxNode(window.getSelection().anchorNode)},
390
+ result: function() {
391
+ if (queryCommandState('insertOrderedList')) return;
392
+ var pNode;
393
+ if (anchorNode){
394
+ pNode = anchorNode.parentNode;
395
+ if (anchorNode === editor.content) pNode = null;
396
+ }
397
+
398
+ if (anchorNode === editor.content || queryCommandValue(formatBlock) === ''){
399
+ formatParagraph();
400
+ }
401
+
402
+ var box = checkboxNode(anchorNode);
403
+ if (!!box){
404
+ cancelCheckboxList(box.parentNode);
405
+ } else {
406
+ !queryCommandState('insertOrderedList') && execCheckboxList(anchorNode);
407
+ }
408
+ }
409
+ },
410
+ content: {
411
+ setDisable: function(dis){ this.blur(); editor.content.contentEditable = !dis},
412
+ setHtml: function(html) { editor.content.innerHTML = html; Actions.UPDATE_HEIGHT(); },
413
+ getHtml: function() { return editor.content.innerHTML; },
414
+ blur: function() { editor.content.blur(); },
415
+ focus: function() { focusCurrent(); },
416
+ postHtml: function (){ postAction({type: 'CONTENT_HTML_RESPONSE', data: editor.content.innerHTML}); },
417
+ setPlaceholder: function(placeholder){ editor.content.setAttribute("placeholder", placeholder) },
418
+
419
+ setContentStyle: function(styles) {
420
+ styles = styles || {};
421
+ var bgColor = styles.backgroundColor, color = styles.color, pColor = styles.placeholderColor;
422
+ if (bgColor && bgColor !== body.style.backgroundColor) body.style.backgroundColor = bgColor;
423
+ if (color && color !== editor.content.style.color) editor.content.style.color = color;
424
+ if (pColor && pColor !== placeholderColor){
425
+ var rule1="[placeholder]:empty:before {content:attr(placeholder);color:"+pColor+";}";
426
+ var rule2="[placeholder]:empty:focus:before{content:attr(placeholder);color:"+pColor+";}";
427
+ try {
428
+ document.styleSheets[1].deleteRule(0);document.styleSheets[1].deleteRule(0);
429
+ document.styleSheets[1].insertRule(rule1); document.styleSheets[1].insertRule(rule2);
430
+ placeholderColor = pColor;
431
+ } catch (e){
432
+ console.log("set placeholderColor error!")
433
+ }
434
+ }
435
+ },
436
+
437
+ commandDOM: function (command){
438
+ try {new Function("$", command)(exports.document.querySelector.bind(exports.document))} catch(e){console.log(e.message)};
439
+ },
440
+ command: function (command){
441
+ try {new Function("$", command)(exports.document)} catch(e){console.log(e.message)};
442
+ }
443
+ },
444
+
445
+ init: function (){
446
+ if (${useContainer}){
447
+ // setInterval(Actions.UPDATE_HEIGHT, 150);
448
+ Actions.UPDATE_HEIGHT();
449
+ } else {
450
+ // react-native-webview There is a bug in the body and html height setting of a certain version of 100%
451
+ // body.style.height = docEle.clientHeight + 'px';
452
+ }
453
+ },
454
+
455
+ UPDATE_HEIGHT: function() {
456
+ if (!${useContainer}) return;
457
+ // var height = Math.max(docEle.scrollHeight, body.scrollHeight);
458
+ var height = editor.content.scrollHeight;
459
+ if (o_height !== height){
460
+ _postMessage({type: 'OFFSET_HEIGHT', data: o_height = height});
461
+ }
462
+ },
463
+
464
+ UPDATE_OFFSET_Y: function (){
465
+ if (!${useContainer}) return;
466
+ var node = anchorNode || window.getSelection().anchorNode;
467
+ var sel = window.getSelection();
468
+ if (node){
469
+ var siblingOffset = (node.nextSibling && node.nextSibling.offsetTop) || (node.previousSibling && node.previousSibling.offsetTop)
470
+ var rectOffset = null;
471
+ if (sel.rangeCount > 0) {
472
+ var range = sel.getRangeAt(0);
473
+ var rect = range.getClientRects()[0];
474
+ rectOffset = rect ? rect.y : null;
475
+ }
476
+
477
+ var offsetY = node.offsetTop || siblingOffset || rectOffset || node.parentNode.offsetTop;
478
+ if (offsetY){
479
+ _postMessage({type: 'OFFSET_Y', data: offsetY});
480
+ }
481
+ }
482
+ }
483
+ };
484
+
485
+ var init = function init(settings) {
486
+
487
+ var paragraphSeparator = settings[defaultParagraphSeparatorString];
488
+ var content = settings.element.content = createElement('div');
489
+ content.id = 'content';
490
+ content.contentEditable = true;
491
+ content.spellcheck = ${spellcheck};
492
+ content.autofocus = ${initialFocus};
493
+ content.enterKeyHint = '${enterKeyHint}';
494
+ content.autocapitalize = '${autoCapitalize}';
495
+ content.autocorrect = ${autoCorrect};
496
+ content.autocomplete = 'off';
497
+ content.className = "pell-content";
498
+ content.oninput = function (_ref) {
499
+ // var firstChild = _ref.target.firstChild;
500
+ if ((anchorNode === void 0 || anchorNode === content) && queryCommandValue(formatBlock) === ''){
501
+ if ( !compositionStatus || anchorNode === content){
502
+ formatParagraph(true);
503
+ paragraphStatus = 0;
504
+ } else {
505
+ paragraphStatus = 1;
506
+ }
507
+ } else if (content.innerHTML === '<br>'){
508
+ content.innerHTML = '';
509
+ } else if (enterStatus && queryCommandValue(formatBlock) === 'blockquote') {
510
+ formatParagraph();
511
+ }
512
+
513
+ saveSelection();
514
+ handleChange(_ref);
515
+ settings.onChange();
516
+ ${inputListener} && postAction({type: "ON_INPUT", data: {inputType: _ref.inputType, data: _ref.data}});
517
+ };
518
+ appendChild(settings.element, content);
519
+
520
+ if (settings.styleWithCSS) exec('styleWithCSS');
521
+ exec(defaultParagraphSeparatorString, paragraphSeparator);
522
+
523
+ var actionsHandler = [];
524
+ for (var k in Actions){
525
+ if (typeof Actions[k] === 'object' && Actions[k].state){
526
+ actionsHandler[k] = Actions[k]
527
+ }
528
+ }
529
+
530
+ function handler() {
531
+ var activeTools = [];
532
+ for(var k in actionsHandler){
533
+ const state = Actions[k].state()
534
+ if ( state ){
535
+ activeTools.push(typeof state === "boolean" ? k : {type: k, value: Actions[k].state()});
536
+ }
537
+ }
538
+ postAction({type: 'SELECTION_CHANGE', data: activeTools});
539
+ };
540
+
541
+ var _handleStateDT = null;
542
+ function handleState(){
543
+ clearTimeout(_handleStateDT);
544
+ _handleStateDT = setTimeout(function (){
545
+ handler();
546
+ saveSelection();
547
+ }, 50);
548
+ }
549
+
550
+ function handleSelecting(event){
551
+ event.stopPropagation();
552
+ handleState();
553
+ }
554
+
555
+ function postKeyAction(event, type){
556
+ postAction({type: type, data: {keyCode: event.keyCode, key: event.key}});
557
+ }
558
+ function handleKeyup(event){
559
+ enterStatus = 0;
560
+ _keyDown = false;
561
+ if (event.keyCode === 8) handleSelecting (event);
562
+ ${keyUpListener} && postKeyAction(event, "CONTENT_KEYUP")
563
+ }
564
+ function handleKeydown(event){
565
+ _keyDown = true;
566
+ handleState();
567
+ if (event.key === 'Enter'){
568
+ enterStatus = 1; // set enter true
569
+ var box;
570
+ var block = queryCommandValue(formatBlock);
571
+ if (anchorNode.innerHTML === '<br>' && anchorNode.parentNode !== editor.content){
572
+ // setCollapse(editor.content);
573
+ } else if (queryCommandState('insertOrderedList') && !!(box = checkboxNode(anchorNode))){
574
+ var node = anchorNode && anchorNode.childNodes[1];
575
+ if (node && node.nodeName === 'BR'){
576
+ cancelCheckboxList(box.parentNode);
577
+ event.preventDefault();
578
+ } else{
579
+ // add checkbox
580
+ _checkboxFlag = 1;
581
+ }
582
+ }
583
+ if (block === 'pre' && anchorNode.innerHTML === '<br>'){
584
+ // code end enter new line (Unfinished)
585
+ if (!anchorNode.nextSibling){
586
+ event.preventDefault();
587
+ var node = anchorNode.parentNode;
588
+ var br = createElement("br");
589
+ node.parentNode.insertBefore(br, node.nextSibling);
590
+ setTimeout(function (){
591
+ setCollapse(br);
592
+ });
593
+ }
594
+ }
595
+ }
596
+ ${keyDownListener} && postKeyAction(event, "CONTENT_KEYDOWN");
597
+ }
598
+ function handleFocus (){
599
+ editorFoucs = true;
600
+ setTimeout(function (){
601
+ Actions.UPDATE_OFFSET_Y();
602
+ });
603
+ postAction({type: 'CONTENT_FOCUSED'});
604
+ }
605
+ function handleBlur (){
606
+ editorFoucs = false;
607
+ postAction({type: 'SELECTION_CHANGE', data: []});
608
+ postAction({type: 'CONTENT_BLUR'});
609
+ }
610
+ function handleClick(event){
611
+ var ele = event.target;
612
+ if (ele.nodeName === 'INPUT' && ele.type === 'checkbox'){
613
+ // Set whether the checkbox is selected by default
614
+ if (ele.checked) ele.setAttribute('checked', '');
615
+ else ele.removeAttribute('checked');
616
+ }
617
+ if (ele.nodeName === 'A' && ele.getAttribute('href')) {
618
+ postAction({type: 'LINK_TOUCHED', data: ele.getAttribute('href')});
619
+ }
620
+ }
621
+ addEventListener(content, 'touchcancel', handleSelecting);
622
+ addEventListener(content, 'mouseup', handleSelecting);
623
+ addEventListener(content, 'touchend', handleSelecting);
624
+ addEventListener(content, 'keyup', handleKeyup);
625
+ addEventListener(content, 'click', handleClick);
626
+ addEventListener(content, 'keydown', handleKeydown);
627
+ addEventListener(content, 'blur', handleBlur);
628
+ addEventListener(content, 'focus', handleFocus);
629
+ addEventListener(content, 'paste', function (e) {
630
+ // get text representation of clipboard
631
+ var text = (e.originalEvent || e).clipboardData.getData('text/plain');
632
+
633
+ ${pasteListener} && postAction({type: 'CONTENT_PASTED', data: text});
634
+ if (${pasteAsPlainText}) {
635
+ // cancel paste
636
+ e.preventDefault();
637
+ // insert text manually
638
+ exec("insertText", text);
639
+ }
640
+ });
641
+ addEventListener(content, 'compositionstart', function(event){
642
+ if(${useCharacter}){
643
+ compositionStatus = 1;
644
+ }
645
+ })
646
+ addEventListener(content, 'compositionend', function (event){
647
+ if(${useCharacter}){
648
+ compositionStatus = 0;
649
+ paragraphStatus && formatParagraph(true);
650
+ }
651
+ })
652
+
653
+ var message = function (event){
654
+ var msgData = JSON.parse(event.data), action = Actions[msgData.type];
655
+ if (action ){
656
+ if ( action[msgData.name]){
657
+ var flag = msgData.name === 'result';
658
+ // insert image or link need current focus
659
+ flag && focusCurrent();
660
+ action[msgData.name](msgData.data, msgData.options);
661
+ flag && handleState();
662
+ } else {
663
+ action(msgData.data, msgData.options);
664
+ }
665
+ }
666
+ };
667
+ document.addEventListener("message", message , false);
668
+ window.addEventListener("message", message , false);
669
+ document.addEventListener('mouseup', function (event) {
670
+ event.preventDefault();
671
+ Actions.content.focus();
672
+ handleSelecting(event);
673
+ });
674
+ return {content, paragraphSeparator: paragraphSeparator, settings};
675
+ };
676
+
677
+ var _handleCTime = null;
678
+ editor = init({
679
+ element: document.getElementById('editor'),
680
+ defaultParagraphSeparator: '${defaultParagraphSeparator}',
681
+ styleWithCSS: ${styleWithCSS},
682
+ onChange: function (){
683
+ clearTimeout(_handleCTime);
684
+ _handleCTime = setTimeout(function(){
685
+ var html = Actions.content.getHtml();
686
+ postAction({type: 'CONTENT_CHANGE', data: html});
687
+ }, 50);
688
+ }
689
+ })
690
+ return {
691
+ sendEvent: function (type, data){
692
+ event.preventDefault();
693
+ event.stopPropagation();
694
+ var id = event.currentTarget.id;
695
+ if ( !id ) event.currentTarget.id = id = generateId();
696
+ _postMessage({type, id, data});
697
+ }
698
+ }
699
+ })({
700
+ window: window.ReactNativeWebView || window.parent,
701
+ isRN: !!window.ReactNativeWebView ,
702
+ document: document
56
703
  });
57
- });
58
-
59
- editor.addEventListener('focus', () => {
60
- post('CONTENT_FOCUSED');
61
- });
62
-
63
- editor.addEventListener('blur', () => {
64
- post('CONTENT_BLUR');
65
- });
66
-
67
- window.addEventListener('message', e => {
68
- const msg = JSON.parse(e.data);
69
- const type = msg.type;
70
-
71
- if (type === 'focus') {
72
- editor.focus();
73
- } else if (type === 'blur') {
74
- editor.blur();
75
- } else {
76
- // Restore focus so format commands apply to the editor (important when toolbar tap steals focus)
77
- editor.focus();
78
- if (type === 'bold') {
79
- document.execCommand('bold');
80
- } else if (type === 'italic') {
81
- document.execCommand('italic');
82
- } else if (type === 'underline') {
83
- document.execCommand('underline');
84
- } else if (type === 'strikethrough') {
85
- document.execCommand('strikeThrough');
86
- } else if (type === 'removeFormat') {
87
- document.execCommand('removeFormat');
88
- } else if (type === 'undo') {
89
- document.execCommand('undo');
90
- } else if (type === 'redo') {
91
- document.execCommand('redo');
92
- } else if (type === 'insertUnorderedList') {
93
- document.execCommand('insertUnorderedList');
94
- } else if (type === 'insertOrderedList') {
95
- document.execCommand('insertOrderedList');
96
- } else if (type === 'checkboxList') {
97
- document.execCommand('insertOrderedList');
98
- } else if (type === 'indent') {
99
- document.execCommand('indent');
100
- } else if (type === 'outdent') {
101
- document.execCommand('outdent');
102
- } else if (type === 'justifyLeft') {
103
- document.execCommand('justifyLeft');
104
- } else if (type === 'justifyCenter') {
105
- document.execCommand('justifyCenter');
106
- } else if (type === 'justifyRight') {
107
- document.execCommand('justifyRight');
108
- } else if (type === 'justifyFull') {
109
- document.execCommand('justifyFull');
110
- } else if (type === 'blockquote') {
111
- document.execCommand('formatBlock', false, 'blockquote');
112
- } else if (type === 'code') {
113
- document.execCommand('formatBlock', false, 'pre');
114
- } else if (type === 'link') {
115
- const url = prompt('Enter link URL:');
116
- if (url) {
117
- const sel = window.getSelection();
118
- const range = sel.getRangeAt(0);
119
- const link = document.createElement('a');
120
- link.href = url;
121
- link.textContent = sel.toString() || url;
122
- range.deleteContents();
123
- range.insertNode(link);
124
- }
125
- }
126
- }
127
- });
128
704
  </script>
129
705
  </body>
130
706
  </html>
131
- `
132
- };
707
+ `;
133
708
  }
709
+ const HTML = createHTML();
710
+ exports.HTML = HTML;