1/* @file 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16let RICH_EDITOR = {}; 17let storage = window.localStorage; 18RICH_EDITOR.editor = document.getElementById('editorjs_box'); 19 20RICH_EDITOR.setHtml = function (contents) { 21 let paddingLeft = storage.getItem('paddingLeft'); 22 if (contents) { 23 RICH_EDITOR.editor.style.paddingLeft = paddingLeft + 'px'; 24 } 25 let base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; 26 if (base64regex.test(contents)) { 27 RICH_EDITOR.editor.innerHTML = decodeURIComponent(escape(atob(contents))); 28 } else { 29 RICH_EDITOR.editor.innerHTML = contents; 30 } 31}; 32 33RICH_EDITOR.getHtml = function () { 34 return document.getElementById('editorjs_box').innerHTML; 35}; 36 37RICH_EDITOR.undo = function () { 38 document.execCommand('undo', false, null); 39}; 40 41RICH_EDITOR.redo = function () { 42 document.execCommand('redo', false, null); 43}; 44 45RICH_EDITOR.setBold = function () { 46 document.execCommand('bold'); 47}; 48 49RICH_EDITOR.setItalic = function () { 50 document.execCommand('italic', false, null); 51}; 52 53RICH_EDITOR.setSubscript = function () { 54 document.execCommand('subscript', false, null); 55}; 56 57RICH_EDITOR.setSuperscript = function () { 58 document.execCommand('superscript', false, null); 59}; 60 61RICH_EDITOR.setStrikeThrough = function () { 62 document.execCommand('strikeThrough', false, null); 63}; 64 65RICH_EDITOR.setUnderline = function () { 66 document.execCommand('underline', false, null); 67}; 68 69RICH_EDITOR.getListStyle = function () { 70 let selection; 71 let type; 72 if (window.getSelection) { 73 selection = getSelection(); 74 } 75 if (!selection) { 76 return; 77 } 78 let range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange(); 79 try { 80 let child = range.commonAncestorContainer; 81 for (let i = 0; i < 10; i++) { 82 if (child.nodeName === 'OL') { 83 console.info('insertOrderedList'); 84 document.execCommand('insertOrderedList', false, null); 85 return child.style['list-style']; 86 } 87 if (child.nodeName === 'UL') { 88 console.info('insertUnorderedList'); 89 document.execCommand('insertUnorderedList', false, null); 90 return child.style['list-style']; 91 } 92 if (child.parentNode) { 93 child = child.parentNode; 94 } 95 } 96 } catch (err) { 97 console.error(err); 98 } 99 100}; 101 102RICH_EDITOR.setNumbers = function () { 103 let listStyle = RICH_EDITOR.getListStyle(); 104 if (listStyle === 'decimal') { 105 return; 106 } 107 document.execCommand('insertOrderedList', false, null); 108 let selection; 109 let type; 110 if (window.getSelection) { 111 selection = getSelection(); 112 } 113 if (!selection) { 114 return; 115 } 116 let range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange(); 117 try { 118 let child = range.commonAncestorContainer; 119 for (let i = 0; i < 10; i++) { 120 if (child.nodeName === 'OL') { 121 child.style['list-style'] = 'decimal'; 122 break; 123 } 124 if (child.parentNode) { 125 child = child.parentNode; 126 } 127 } 128 } catch (err) { 129 console.error(err); 130 } 131}; 132 133RICH_EDITOR.setABC = function () { 134 let listStyle = RICH_EDITOR.getListStyle(); 135 if (listStyle === 'lower-alpha') { 136 return; 137 } 138 document.execCommand('insertOrderedList', false, null); 139 let selection; 140 let type; 141 if (window.getSelection) { 142 selection = getSelection(); 143 } 144 if (!selection) { 145 return; 146 } 147 let range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange(); 148 try { 149 let child = range.commonAncestorContainer; 150 for (let i = 0; i < 10; i++) { 151 if (child.nodeName === 'OL') { 152 child.style['list-style'] = 'lower-alpha'; 153 break; 154 } 155 if (child.parentNode) { 156 child = child.parentNode; 157 } 158 } 159 } catch (err) { 160 console.error(err); 161 } 162}; 163 164RICH_EDITOR.setBullets = function () { 165 let listStyle = RICH_EDITOR.getListStyle(); 166 if (listStyle === 'disc') { 167 return; 168 } 169 document.execCommand('insertUnorderedList', false, null); 170 let selection; 171 let type; 172 if (window.getSelection) { 173 selection = getSelection(); 174 } 175 if (!selection) { 176 return; 177 } 178 let range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange(); 179 try { 180 let child = range.commonAncestorContainer; 181 for (let i = 0; i < 10; i++) { 182 if (child.nodeName === 'UL') { 183 child.style['list-style'] = 'disc'; 184 break; 185 } 186 if (child.parentNode) { 187 child = child.parentNode; 188 } 189 } 190 } catch (err) { 191 console.error(err); 192 } 193}; 194 195RICH_EDITOR.setSquare = function () { 196 let listStyle = RICH_EDITOR.getListStyle(); 197 if (listStyle === 'square') { 198 return; 199 } 200 document.execCommand('insertUnorderedList', false, null); 201 let selection; 202 let type; 203 if (window.getSelection) { 204 selection = getSelection(); 205 } 206 if (!selection) { 207 return; 208 } 209 let range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange(); 210 try { 211 let child = range.commonAncestorContainer; 212 for (let i = 0; i < 10; i++) { 213 if (child.nodeName === 'UL') { 214 child.style['list-style'] = 'square'; 215 break; 216 } 217 if (child.parentNode) { 218 child = child.parentNode; 219 } 220 } 221 } catch (err) { 222 console.error(err); 223 } 224}; 225 226RICH_EDITOR.setTextColor = function (color) { 227 document.execCommand('foreColor', false, color); 228}; 229 230RICH_EDITOR.setFontSize = function (fontSize) { 231 document.execCommand('fontSize', false, fontSize); 232}; 233 234RICH_EDITOR.execFontSize = function (size, unit) { 235 if (size === '12') { 236 document.execCommand('fontSize', false, 3); 237 } else if (size === '16') { 238 document.execCommand('fontSize', false, 4); 239 } else if (size === '20') { 240 document.execCommand('fontSize', false, 5); 241 } else if (size === '24') { 242 document.execCommand('fontSize', false, 6); 243 } else if (size === '28') { 244 document.execCommand('fontSize', false, 7); 245 } 246}; 247 248let pad = 24; 249RICH_EDITOR.setIndent = function () { 250 let parents = document.getElementById('editorjs_box'); 251 parents.removeAttribute('padding-left'); 252 if (pad >= 408) { 253 return; 254 } 255 pad = pad + 24; 256 parents.style.paddingLeft = pad + 'px'; 257 if (!storage) { 258 return; 259 } 260 storage.setItem('paddingLeft', pad); 261}; 262 263RICH_EDITOR.setOutdent = function () { 264 let parents = document.getElementById('editorjs_box'); 265 parents.removeAttribute('padding-left'); 266 if (pad === 24) { 267 parents.style.paddingLeft = 24 + 'px'; 268 if (!storage) { 269 return; 270 } 271 storage.setItem('paddingLeft', pad); 272 } else { 273 pad = pad - 24; 274 parents.style.paddingLeft = pad + 'px'; 275 if (!storage) { 276 return; 277 } 278 storage.setItem('paddingLeft', pad); 279 } 280}; 281 282RICH_EDITOR.setJustifyLeft = function () { 283 document.execCommand('justifyLeft', false, null); 284}; 285 286RICH_EDITOR.setJustifyCenter = function () { 287 document.execCommand('justifyCenter', false, null); 288}; 289 290RICH_EDITOR.setJustifyRight = function () { 291 document.execCommand('justifyRight', false, null); 292}; 293 294RICH_EDITOR.insertImage = function (url) { 295 let html = '<br></br><img src="' + url + 296 '" alt="picvision" style="margin:0px auto;width:90%;display:table-cell;' + 297 'vertical-align:middle;border-radius:10px;max-width:90%" /><br></br>'; 298 document.getElementById('editorjs_box').innerHTML += html; 299 document.getElementById('editorjs_box').scrollIntoView(false); 300}; 301 302RICH_EDITOR.insertHTML = function (html) { 303 document.execCommand('insertHTML', false, html); 304}; 305 306RICH_EDITOR.setDone = function () { 307 let html = '<input type="checkbox" checked="checked"/> '; 308 document.execCommand('insertHTML', false, html); 309}; 310 311RICH_EDITOR.addTodo = function (e) { 312 let KEY_ENTER; 313 KEY_ENTER = 13; 314 if (e.which === KEY_ENTER) { 315 let node = RICH_EDITOR.getSelectedAnchorNode(); 316 if (node && node.nodeName === '#text') { 317 node = node.parentElement; 318 } 319 if (node && node.nodeName === 'SPAN' && node.previousElementSibling && 320 node.previousElementSibling.className === 'note-checkbox') { 321 RICH_EDITOR.setTodo(); 322 e.preventDefault(); 323 } 324 } 325}; 326 327RICH_EDITOR.setTodo = function () { 328 let parent = document.getElementById('editorjs_box'); 329 let isContentEmpty = parent.innerHTML.trim().length === 0 || parent.innerHTML === '<br>'; 330 let html = (isContentEmpty ? '' : '<br/>') + 331 '<span> </span>' + 332 '<input name="checkbox" type="checkbox" onclick="onCheckChange(this)" class="note-checkbox">' + 333 '<span class="note-checkbox-txt"> </span>'; 334 document.execCommand('insertHTML', false, html); 335}; 336 337function onCheckChange(checkbox) { 338 if (checkbox.checked === true) { 339 checkbox.setAttribute('checked', 'checked'); 340 } else { 341 checkbox.removeAttribute('checked'); 342 } 343} 344 345RICH_EDITOR.restorerange = function () { 346 let selection = window.getSelection(); 347 selection.removeAllRanges(); 348 let range = document.createRange(); 349 range.setStart(RICH_EDITOR.currentSelection.startContainer, RICH_EDITOR.currentSelection.startOffset); 350 range.setEnd(RICH_EDITOR.currentSelection.endContainer, RICH_EDITOR.currentSelection.endOffset); 351 selection.addRange(range); 352}; 353 354// 获取光标开始位置归属节点 355 356RICH_EDITOR.getSelectedAnchorNode = function () { 357 let node; 358 let selection; 359 if (window.getSelection) { 360 selection = getSelection(); 361 node = selection.anchorNode; 362 } 363 if (!node && document.selection) { 364 selection = document.selection; 365 let range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange(); 366 node = range.commonAncestorContainer ? range.commonAncestorContainer : range.parentElement 367 ? range.parentElement() : range.item(0); 368 } 369 return node; 370}; 371 372RICH_EDITOR.cancelSelection = function () { 373 let selection = window.getSelection(); 374 selection.removeAllRanges(); 375}; 376 377let callBackToApp = window.callBackToApp; 378 379function getHtmlContent() { 380 console.log('getHtmlContent'); 381 let htmlString = RICH_EDITOR.getHtml(); 382 let imgName = getImagePathFromContent(htmlString); 383 htmlString = window.btoa(unescape(encodeURIComponent(htmlString))); 384 callBackToApp.callbackImagePath(imgName); 385 let str = callBackToApp.callbackhtml(htmlString); 386 console.log('getHtmlContent end'); 387} 388 389function saveHtmlContent() { 390 console.log('saveHtmlContent'); 391 let htmlString = RICH_EDITOR.getHtml(); 392 let imgName = getImagePathFromContent(htmlString); 393 htmlString = window.btoa(unescape(encodeURIComponent(htmlString))); 394 395 callBackToApp.callbackImagePath(imgName); 396 let str = callBackToApp.callbackhtmlSave(htmlString); 397 console.log('saveHtmlContent end'); 398} 399 400function getImagePathFromContent(contentInfo) { 401 let imgReg = /<img[^>]+>/g; 402 let imgName = ''; 403 let srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i; 404 let imgArray = contentInfo.match(imgReg); 405 // 取第一张图片做为标题栏后的缩略图 406 if (imgArray && imgArray.length > 0) { 407 let src = imgArray[0].match(srcReg); 408 if (src != null && src.length > 1) { 409 imgName = src[1]; 410 if (imgName.indexOf('shuxue.png') >= 0 || imgName.indexOf('cake.png') >= 0) { 411 imgName = '/res/' + imgName; 412 } 413 } 414 } 415 return imgName; 416} 417 418function scheduledSaveContent() { 419 if (callBackToApp !== undefined) { 420 console.info('scheduledSaveContent'); 421 let htmlString = RICH_EDITOR.getHtml(); 422 let imgName = getImagePathFromContent(htmlString); 423 htmlString = window.btoa(unescape(encodeURIComponent(htmlString))); 424 callBackToApp.callbackImagePath(imgName); 425 let str = callBackToApp.callbackScheduledSave(htmlString); 426 console.info('scheduledSaveContent end'); 427 } 428} 429 430document.body.addEventListener('paste', (event) => { 431 let length = event.clipboardData.items.length; 432 if (length > 0) { 433 let file = event.clipboardData.items[0].getAsFile(); 434 const reader = new FileReader(); 435 reader.onloadend = () => { 436 callBackToApp.callbackPasteImage(reader.result); 437 }; 438 reader.readAsDataURL(file); 439 event.preventDefault(); 440 } 441}); 442 443RICH_EDITOR.getFontSizes = function () { 444 document.execCommand('fontSize', false, null); 445 let fontElements = window.getSelection().anchorNode.parentNode; 446 let getSize = parseInt(window.getComputedStyle(fontElements, null).fontSize); 447 let str = callBackToApp.callbackGetSize(getSize); 448}; 449 450RICH_EDITOR.insertImageHtml = function (contents) { 451 let selection = window.getSelection(); 452 if (!selection.rangeCount) { 453 return false; 454 } 455 selection.deleteFromDocument(); 456 let img = document.createElement('img'); 457 img.src = contents; 458 selection.getRangeAt(0).insertNode(img); 459 return true; 460}; 461 462document.addEventListener('click', (e) => { 463 console.info(`lsq: e is ${JSON.stringify(e)}`); 464 let parent = document.getElementById('editorjs_box'); 465 if (parent.id !== 'editorjs_box') { 466 e.preventDefault(); 467 } 468}); 469 470document.getElementById('addToDo').addEventListener('click', () => { 471 callBackToApp.addToDo(); 472}); 473 474document.getElementById('chooseStyle').addEventListener('click', () => { 475 callBackToApp.chooseStyle(); 476}); 477 478document.getElementById('openAlbum').addEventListener('click', () => { 479 callBackToApp.openAlbum(); 480}); 481 482function changeSizeToRk() { 483 document.getElementById('img1').style.width = '40px'; 484 document.getElementById('img1').style.height = '40px'; 485 document.getElementById('img2').style.width = '40px'; 486 document.getElementById('img2').style.height = '40px'; 487 document.getElementById('img3').style.width = '40px'; 488 document.getElementById('img3').style.height = '40px'; 489 document.getElementById('lable1').style.fontSize = '20px'; 490 document.getElementById('lable2').style.fontSize = '20px'; 491 document.getElementById('lable3').style.fontSize = '20px'; 492} 493 494function changeSizeToPhone() { 495 document.getElementById('img1').style.width = '24px'; 496 document.getElementById('img1').style.height = '24px'; 497 document.getElementById('img2').style.width = '24px'; 498 document.getElementById('img2').style.height = '24px'; 499 document.getElementById('img3').style.width = '24px'; 500 document.getElementById('img3').style.height = '24px'; 501 document.getElementById('lable1').style.fontSize = '12px'; 502 document.getElementById('lable2').style.fontSize = '12px'; 503 document.getElementById('lable3').style.fontSize = '12px'; 504} 505 506function changeSizeToTablet() { 507 document.getElementById('img1').style.width = '28px'; 508 document.getElementById('img1').style.height = '28px'; 509 document.getElementById('img2').style.width = '28px'; 510 document.getElementById('img2').style.height = '28px'; 511 document.getElementById('img3').style.width = '28px'; 512 document.getElementById('img3').style.height = '28px'; 513 document.getElementById('lable1').style.fontSize = '12px'; 514 document.getElementById('lable2').style.fontSize = '12px'; 515 document.getElementById('lable3').style.fontSize = '12px'; 516} 517 518function hiddenButton() { 519 document.getElementById('buttonBox').style.display = 'none'; 520} 521 522RICH_EDITOR.getFocus = function () { 523 return document.getElementById('editorjs_box').focus(); 524}; 525 526RICH_EDITOR.getBlur = function () { 527 return document.getElementById('editorjs_box').blur(); 528}; 529 530document.getElementById('editorjs_box').addEventListener('click', () => { 531 document.getElementById('buttonBox').style.display = 'flex'; 532});