From daf092373c126b118f4ca1d7d66d063d980d8675 Mon Sep 17 00:00:00 2001 From: Torsten Schneider Date: Sat, 27 Feb 2021 09:35:33 +0100 Subject: [PATCH] Switch to TinyMCE --- .../app/Http/Controllers/AdminController.php | 1 - .../app/Http/Controllers/PageController.php | 4 + motorradig/package-lock.json | 5 - motorradig/package.json | 3 +- motorradig/public/js/app.js | 21511 ---------------- motorradig/resources/js/app.js | 1 - motorradig/resources/js/bootstrap.js | 1 + motorradig/resources/js/suneditor.js | 25 - .../resources/views/admin/edit_home.blade.php | 21 +- motorradig/resources/views/home.blade.php | 6 +- 10 files changed, 23 insertions(+), 21555 deletions(-) delete mode 100644 motorradig/resources/js/suneditor.js diff --git a/motorradig/app/Http/Controllers/AdminController.php b/motorradig/app/Http/Controllers/AdminController.php index a8807a6..bba4a2a 100644 --- a/motorradig/app/Http/Controllers/AdminController.php +++ b/motorradig/app/Http/Controllers/AdminController.php @@ -59,7 +59,6 @@ class AdminController extends Controller return view('admin.edit_home')->with('content',$page->content); } public function store_home(Request $request) { - dd($request); $request->validate( [ 'pagecontent' => 'required' diff --git a/motorradig/app/Http/Controllers/PageController.php b/motorradig/app/Http/Controllers/PageController.php index d73d08d..bc0d4e7 100644 --- a/motorradig/app/Http/Controllers/PageController.php +++ b/motorradig/app/Http/Controllers/PageController.php @@ -87,6 +87,10 @@ class PageController extends Controller public function page_home() { $page=Page::where('name','home')->first(); $content=$page->content; + + $content = rtrim(ltrim($content,'"'),'"'); + + return view('home')->with('content',$content); } diff --git a/motorradig/package-lock.json b/motorradig/package-lock.json index a265057..9b8a310 100644 --- a/motorradig/package-lock.json +++ b/motorradig/package-lock.json @@ -8596,11 +8596,6 @@ } } }, - "suneditor": { - "version": "2.36.4", - "resolved": "https://registry.npmjs.org/suneditor/-/suneditor-2.36.4.tgz", - "integrity": "sha512-xOB96cQWzt8PQ8fSF6Q5NzxMPpOFTeaQBbHTx+ZuUt6s7hxh2LE8bh0yU+hLmeoXfBCTtV/A0zb+e7sLy2G0BA==" - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/motorradig/package.json b/motorradig/package.json index 248b8c8..db2c0f4 100644 --- a/motorradig/package.json +++ b/motorradig/package.json @@ -24,7 +24,6 @@ }, "dependencies": { "@fortawesome/fontawesome-free": "^5.14.0", - "lightbox2": "^2.11.3", - "suneditor": "^2.36.4" + "lightbox2": "^2.11.3" } } diff --git a/motorradig/public/js/app.js b/motorradig/public/js/app.js index 7a6a240..ecb1293 100644 --- a/motorradig/public/js/app.js +++ b/motorradig/public/js/app.js @@ -6386,112 +6386,6 @@ module.exports = { //# sourceMappingURL=bootstrap.js.map -/***/ }), - -/***/ "./node_modules/css-loader/index.js?!./node_modules/postcss-loader/src/index.js?!./node_modules/suneditor/dist/css/suneditor.min.css": -/*!*******************************************************************************************************************************************!*\ - !*** ./node_modules/css-loader??ref--6-1!./node_modules/postcss-loader/src??ref--6-2!./node_modules/suneditor/dist/css/suneditor.min.css ***! - \*******************************************************************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -exports = module.exports = __webpack_require__(/*! ../../../css-loader/lib/css-base.js */ "./node_modules/css-loader/lib/css-base.js")(false); -// imports - - -// module -exports.push([module.i, ".sun-editor{width:auto;height:auto;box-sizing:border-box;font-family:Helvetica Neue,sans-serif;border:1px solid #dadada;background-color:#fff;color:#000;user-select:none;-o-user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none}.sun-editor *{box-sizing:border-box;-webkit-user-drag:none;overflow:visible}.sun-editor-common button,.sun-editor-common input,.sun-editor-common select,.sun-editor-common textarea{font-size:14px;line-height:1.5}.sun-editor-common blockquote,.sun-editor-common body,.sun-editor-common button,.sun-editor-common code,.sun-editor-common dd,.sun-editor-common div,.sun-editor-common dl,.sun-editor-common dt,.sun-editor-common fieldset,.sun-editor-common form,.sun-editor-common h1,.sun-editor-common h2,.sun-editor-common h3,.sun-editor-common h4,.sun-editor-common h5,.sun-editor-common h6,.sun-editor-common input,.sun-editor-common legend,.sun-editor-common li,.sun-editor-common ol,.sun-editor-common p,.sun-editor-common pre,.sun-editor-common select,.sun-editor-common td,.sun-editor-common textarea,.sun-editor-common th,.sun-editor-common ul{margin:0;padding:0;border:0}.sun-editor-common dl,.sun-editor-common li,.sun-editor-common menu,.sun-editor-common ol,.sun-editor-common ul{list-style:none!important}.sun-editor-common hr{margin:6px 0!important}.sun-editor textarea{resize:none;border:0;padding:0}.sun-editor button{border:0;background-color:transparent;touch-action:manipulation;cursor:pointer;outline:none}.sun-editor button,.sun-editor input,.sun-editor select,.sun-editor textarea{vertical-align:middle}.sun-editor button span{display:block;margin:0;padding:0}.sun-editor button .txt{display:block;margin-top:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.sun-editor button *{pointer-events:none;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden}.sun-editor .se-svg,.sun-editor button>svg{width:16px;height:16px;margin:auto;fill:currentColor;display:block;text-align:center;float:none}.sun-editor .close>svg,.sun-editor .se-dialog-close>svg{width:10px;height:10px}.sun-editor .se-btn-select>svg{float:right;width:10px;height:10px}.sun-editor .se-btn-list>.se-list-icon{display:inline-block;width:16px;height:16px;margin:-1px 10px 0 0;vertical-align:middle}.sun-editor .se-line-breaker>button>svg{width:24px;height:24px}.sun-editor button>i:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;font-size:15px;line-height:2}.sun-editor button>[class=se-icon-text]{font-size:20px;line-height:1}.sun-editor .se-arrow,.sun-editor .se-arrow:after{position:absolute;display:block;width:0;height:0;border:11px solid transparent}.sun-editor .se-arrow.se-arrow-up{top:-11px;left:20px;margin-left:-11px;border-top-width:0;border-bottom-color:#dadada}.sun-editor .se-arrow.se-arrow-up:after{top:1px;margin-left:-11px;content:\" \";border-top-width:0;border-bottom-color:#fff}.sun-editor .se-toolbar .se-arrow.se-arrow-up:after{border-bottom-color:#fafafa}.sun-editor .se-arrow.se-arrow-down{top:0;left:0;margin-left:-11px;border-bottom-width:0;border-top-color:#dadada}.sun-editor .se-arrow.se-arrow-down:after{top:-12px;margin-left:-11px;content:\" \";border-bottom-width:0;border-top-color:#fff}.sun-editor .se-toolbar .se-arrow.se-arrow-down:after{border-top-color:#fafafa}.sun-editor .se-container{position:relative;width:100%;height:100%}.sun-editor button{color:#000}.sun-editor .se-btn{float:left;width:34px;height:34px;border:0;border-radius:4px;margin:1px!important;padding:0;font-size:12px;line-height:27px}.sun-editor .se-btn:enabled:focus,.sun-editor .se-btn:enabled:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-btn:enabled:active{background-color:#d1d1d1;border-color:#c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-btn-primary{color:#000;background-color:#c7deff;border:1px solid #80bdff;border-radius:4px}.sun-editor .se-btn-primary:focus,.sun-editor .se-btn-primary:hover{color:#000;background-color:#80bdff;border-color:#3f9dff;outline:0 none}.sun-editor .se-btn-primary:active{color:#fff;background-color:#3f9dff;border-color:#4592ff;box-shadow:inset 0 3px 5px #4592ff}.sun-editor input,.sun-editor select,.sun-editor textarea{color:#000;border:1px solid #ccc;border-radius:4px}.sun-editor input:focus,.sun-editor select:focus,.sun-editor textarea:focus{border:1px solid #80bdff;outline:0;box-shadow:0 0 0 .2rem #c7deff;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.sun-editor .se-btn:enabled.active{color:#4592ff;outline:0 none}.sun-editor .se-btn:enabled.active:focus,.sun-editor .se-btn:enabled.active:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-btn:enabled.active:active{background-color:#d1d1d1;border-color:#c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-btn:enabled.on{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-btn:enabled.on:focus,.sun-editor .se-btn:enabled.on:hover{background-color:#d1d1d1;border-color:#c1c1c1;outline:0 none}.sun-editor .se-btn:enabled.on:active{background-color:#c1c1c1;border-color:#b1b1b1;box-shadow:inset 0 3px 5px #b1b1b1}.sun-editor .se-btn-list:disabled,.sun-editor .se-btn:disabled,.sun-editor button:disabled{cursor:not-allowed;background-color:inherit;color:#bdbdbd}.sun-editor .se-loading-box{position:absolute;display:none;width:100%;height:100%;top:0;left:0;background-color:#fff;opacity:.7;filter:alpha(opacity=70);z-index:2147483647}.sun-editor .se-loading-box .se-loading-effect{position:absolute;display:block;top:50%;left:50%;height:25px;width:25px;border-top:2px solid #07d;border-right:2px solid transparent;border-radius:50%;-webkit-animation:spinner .8s linear infinite;animation:spinner .8s linear infinite;margin:-25px 0 0 -25px}.sun-editor .se-line-breaker{position:absolute;display:none;width:100%;height:1px;cursor:text;border-top:1px solid #3288ff;z-index:7}.sun-editor .se-line-breaker>button.se-btn{position:relative;display:inline-block;width:30px;height:30px;top:-15px;float:none;left:-50%;background-color:#fff;border:1px solid #0c2240;opacity:.6;cursor:pointer}.sun-editor .se-line-breaker>button.se-btn:hover{opacity:.9;background-color:#fff;border-color:#041b39}.sun-editor .se-line-breaker-component{position:absolute;display:none;width:24px;height:24px;background-color:#fff;border:1px solid #0c2240;opacity:.6;border-radius:4px;cursor:pointer;z-index:7}.sun-editor .se-line-breaker-component:hover{opacity:.9}.sun-editor .se-toolbar{display:block;position:relative;height:auto;width:100%;overflow:visible;padding:0;margin:0;background-color:#fafafa;outline:1px solid #dadada;z-index:5}.sun-editor .se-toolbar-cover{position:absolute;display:none;font-size:36px;width:100%;height:100%;top:0;left:0;background-color:#fefefe;opacity:.5;filter:alpha(opacity=50);cursor:not-allowed;z-index:4}.sun-editor .se-toolbar-separator-vertical{display:inline-block;height:0;width:0;margin:1px;vertical-align:top}.sun-editor .se-toolbar.se-toolbar-balloon,.sun-editor .se-toolbar.se-toolbar-inline{display:none;position:absolute;box-shadow:0 3px 9px rgba(0,0,0,.5);-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5)}.sun-editor .se-toolbar.se-toolbar-balloon{z-index:2147483647;width:auto}.sun-editor .se-toolbar.se-toolbar-sticky{position:fixed;top:0}.sun-editor .se-toolbar-sticky-dummy{display:none;position:static;z-index:-1}.sun-editor .se-btn-module{display:inline-block}.sun-editor .se-btn-module-border{border:1px solid #dadada;border-radius:4px}.sun-editor .se-btn-module-enter{display:block;width:100%;height:1px;margin-bottom:5px;background-color:transparent}.sun-editor .se-toolbar-more-layer{margin:0 -3px;background-color:#fafafa}.sun-editor .se-toolbar-more-layer .se-more-layer{display:none;border-top:1px solid #dadada}.sun-editor .se-toolbar-more-layer .se-more-layer .se-more-form{display:inline-block;width:100%;height:auto;padding:4px 3px 0}.sun-editor .se-btn-module .se-btn-more.se-btn-more-text{width:auto;padding:0 4px}.sun-editor .se-btn-module .se-btn-more:focus,.sun-editor .se-btn-module .se-btn-more:hover{color:#000;background-color:#d1d1d1;border-color:#c1c1c1;outline:0 none}.sun-editor .se-btn-module .se-btn-more.on{color:#333;background-color:#d1d1d1;border-color:#c1c1c1;outline:0 none}.sun-editor .se-btn-module .se-btn-more.on:hover{color:#000;background-color:#c1c1c1;border-color:#b1b1b1;outline:0 none}.sun-editor .se-menu-list,.sun-editor .se-menu-list li{float:left;padding:0;margin:0}.sun-editor .se-menu-list li{position:relative}.sun-editor .se-btn-select{width:auto;display:flex;padding:4px 6px}.sun-editor .se-btn-select .txt{flex:auto;text-align:left}.sun-editor.se-rtl .se-btn-select svg{margin:auto 1px}.sun-editor .se-btn-select.se-btn-tool-font{width:100px}.sun-editor .se-btn-select.se-btn-tool-format{width:82px}.sun-editor .se-btn-select.se-btn-tool-size{width:78px}.sun-editor .se-btn-tray{position:relative;width:100%;height:auto;padding:4px 3px 0;margin:0}.sun-editor .se-menu-tray{position:absolute;top:0;left:0;width:100%;height:0}.sun-editor .se-submenu{overflow-x:hidden;overflow-y:auto}.sun-editor .se-list-layer{display:none;position:absolute;top:0;left:0;height:auto;z-index:5;border:1px solid #bababa;border-radius:4px;padding:6px 0;background-color:#fff;box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0 none}.sun-editor .se-list-layer .se-list-inner{padding:0;margin:0;overflow-x:initial;overflow-y:initial;overflow:visible}.sun-editor .se-list-layer button{margin:0;width:100%}.sun-editor .se-list-inner ul{width:100%;padding:0}.sun-editor .se-list-inner li>button{min-width:100%;width:-webkit-max-content;width:-moz-max-content;width:max-content}.sun-editor .se-list-inner .se-list-basic li{width:100%}.sun-editor .se-list-inner .se-list-basic li button.active{background-color:#80bdff;border:1px solid #3f9dff;border-left:0;border-right:0}.sun-editor .se-list-inner .se-list-basic li button.active:hover{background-color:#3f9dff;border:1px solid #4592ff;border-left:0;border-right:0}.sun-editor .se-list-inner .se-list-basic li button.active:active{background-color:#4592ff;border:1px solid #407dd1;border-left:0;border-right:0;box-shadow:inset 0 3px 5px #407dd1}.sun-editor .se-list-inner .se-list-checked li button>.se-svg{float:left;padding:6px 6px 0 0}.sun-editor .se-list-inner .se-list-checked li button>.se-svg>svg{display:none}.sun-editor .se-list-inner .se-list-checked li button.se-checked{color:#4592ff}.sun-editor .se-list-inner .se-list-checked li button.se-checked>.se-svg>svg{display:block}.sun-editor .se-btn-list{width:100%;height:auto;min-height:32px;padding:0 14px;cursor:pointer;font-size:12px;line-height:normal;text-indent:0;text-decoration:none;text-align:left}.sun-editor .se-btn-list.default_value{background-color:#f3f3f3;border-top:1px dotted #b1b1b1;border-bottom:1px dotted #b1b1b1}.sun-editor .se-btn-list:focus,.sun-editor .se-btn-list:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-btn-list:active{background-color:#d1d1d1;border-color:#c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-list-layer.se-list-font-size{min-width:140px;max-height:300px}.sun-editor .se-list-layer.se-list-font-family{min-width:156px}.sun-editor .se-list-layer.se-list-font-family .default{border-bottom:1px solid #ccc}.sun-editor .se-list-layer.se-list-line{width:125px}.sun-editor .se-list-layer.se-list-align .se-list-inner{left:9px;width:125px}.sun-editor .se-list-layer.se-list-format{min-width:156px}.sun-editor .se-list-layer.se-list-format li{padding:0;width:100%}.sun-editor .se-list-layer.se-list-format ul .se-btn-list{line-height:100%}.sun-editor .se-list-layer.se-list-format ul .se-btn-list[data-value=h1]{height:40px}.sun-editor .se-list-layer.se-list-format ul .se-btn-list[data-value=h2]{height:34px}.sun-editor .se-list-layer.se-list-format ul p{font-size:13px}.sun-editor .se-list-layer.se-list-format ul div{font-size:13px;padding:4px 2px}.sun-editor .se-list-layer.se-list-format ul h1{font-size:2em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h2{font-size:1.5em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h3{font-size:1.17em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h4{font-size:1em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h5{font-size:.83em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h6{font-size:.67em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul blockquote{font-size:13px;color:#999;height:22px;margin:0;background-color:transparent;line-height:1.5;border-color:#b1b1b1;padding:0 0 0 7px;border-left:5px #b1b1b1;border-style:solid}.sun-editor .se-list-layer.se-list-format ul pre{font-size:13px;color:#666;padding:4px 11px;margin:0;background-color:#f9f9f9;border:1px solid #e1e1e1;border-radius:4px}.sun-editor .se-selector-table{display:none;position:absolute;top:34px;left:1px;z-index:5;padding:5px 0;float:left;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border-radius:4px;box-shadow:0 6px 12px rgba(0,0,0,.175)}.sun-editor .se-selector-table .se-table-size{font-size:18px;padding:0 5px}.sun-editor .se-selector-table .se-table-size-picker{position:absolute!important;z-index:3;font-size:18px;width:10em;height:10em;cursor:pointer}.sun-editor .se-selector-table .se-table-size-highlighted{position:absolute!important;z-index:2;font-size:18px;width:1em;height:1em;background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAADJmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4QTZCNzMzN0I3RUYxMUU4ODcwQ0QwMjM1NTgzRTJDNyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4QTZCNzMzNkI3RUYxMUU4ODcwQ0QwMjM1NTgzRTJDNyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MzYyNEUxRUI3RUUxMUU4ODZGQzgwRjNBODgyNTdFOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MzYyNEUxRkI3RUUxMUU4ODZGQzgwRjNBODgyNTdFOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pl0yAuwAAABBSURBVDhPY/wPBAxUAGCDGvdBeWSAeicIDTfIXREiQArYeR9hEBOEohyMGkQYjBpEGAxjg6ib+yFMygCVvMbAAABj0hwMTNeKJwAAAABJRU5ErkJggg==\") repeat}.sun-editor .se-selector-table .se-table-size-unhighlighted{position:relative!important;z-index:1;font-size:18px;width:10em;height:10em;background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIj4+Pjp6ekKlAqjAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKhmnaJzPAAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC\") repeat}.sun-editor .se-selector-table .se-table-size-display{padding-left:5px}.sun-editor .se-list-layer.se-table-split{top:36px}.sun-editor .se-list-layer .se-selector-color{display:flex;width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:270px;height:auto;padding:0;margin:auto}.sun-editor .se-list-layer .se-selector-color .se-color-pallet{width:100%;height:100%;padding:0}.sun-editor .se-list-layer .se-selector-color .se-color-pallet li{display:flex;float:left;position:relative;margin:0}.sun-editor .se-list-layer .se-selector-color .se-color-pallet button{display:block;cursor:default;width:30px;height:30px;text-indent:-9999px}.sun-editor .se-list-layer .se-selector-color .se-color-pallet button.active,.sun-editor .se-list-layer .se-selector-color .se-color-pallet button:focus,.sun-editor .se-list-layer .se-selector-color .se-color-pallet button:hover{border:3px solid #fff}.sun-editor .se-form-group{display:flex;width:100%;min-height:40px;height:auto;padding:4px}.sun-editor .se-form-group input{flex:auto;display:inline-block;width:auto;height:33px;font-size:12px;margin:1px 0;padding:0;border-radius:.25rem;border:1px solid #ccc}.sun-editor .se-form-group button,.sun-editor .se-submenu-form-group button{float:right;width:34px;height:34px;margin:0 2px!important}.sun-editor .se-form-group button.se-btn{border:1px solid #ccc}.sun-editor .se-form-group>div{position:relative}.sun-editor .se-form-group label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}.sun-editor .se-form-group-label{width:100%;height:auto;padding:0 4px}.sun-editor .se-form-group-label label{font-size:13px;font-weight:700}.sun-editor .se-submenu .se-form-group input{width:auto;height:33px;color:#555}.sun-editor .se-submenu .se-form-group .se-color-input{width:72px;text-transform:uppercase;border:none;border-bottom:2px solid #b1b1b1;outline:none}.sun-editor .se-submenu .se-form-group .se-color-input:focus{border-bottom:3px solid #b1b1b1}.sun-editor .se-wrapper{position:relative!important;width:100%;height:auto;overflow:hidden;z-index:1}.sun-editor .se-wrapper .se-wrapper-inner{width:100%;height:100%;min-height:65px;overflow-y:auto;overflow-x:auto;-webkit-overflow-scrolling:touch;user-select:auto;-o-user-select:auto;-moz-user-select:auto;-khtml-user-select:auto;-webkit-user-select:auto;-ms-user-select:auto}.sun-editor .se-wrapper .se-wrapper-inner:focus{outline:none}.sun-editor .se-wrapper .se-wrapper-code{background-color:#191919;color:#fff;font-size:13px;word-break:break-all;padding:4px;margin:0;resize:none!important}.sun-editor .se-wrapper .se-wrapper-wysiwyg{background-color:#fff;display:block}.sun-editor .se-wrapper .se-wrapper-code-mirror{font-size:13px}.sun-editor .se-wrapper .se-placeholder{position:absolute;display:none;white-space:nowrap;text-overflow:ellipsis;z-index:1;color:#b1b1b1;font-size:13px;line-height:1.5;top:0;left:0;right:0;overflow:hidden;margin-top:0;padding-top:16px;padding-left:16px;margin-left:0;padding-right:16px;margin-right:0;pointer-events:none;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden}.sun-editor .se-resizing-bar{display:flex;width:auto;height:auto;min-height:16px;border-top:1px solid #dadada;padding:0 4px;background-color:#fafafa;cursor:ns-resize}.sun-editor .se-resizing-bar.se-resizing-none{cursor:default}.sun-editor .se-resizing-back{position:absolute;display:none;cursor:default;top:0;left:0;width:100%;height:100%;z-index:2147483647}.sun-editor .se-resizing-bar .se-navigation{flex:auto;position:relative;width:auto;height:auto;color:#666;margin:0;padding:0;font-size:10px;font-weight:700;line-height:1.5;background:transparent}.sun-editor .se-resizing-bar .se-char-counter-wrapper{flex:none;position:relative;display:block;width:auto;height:auto;margin:0;padding:0;color:#999;font-size:13px;background:transparent}.sun-editor .se-resizing-bar .se-char-counter-wrapper.se-blink{color:#b94a48;-webkit-animation:blinker .2s linear infinite;animation:blinker .2s linear infinite}.sun-editor .se-resizing-bar .se-char-counter-wrapper .se-char-label{margin-right:4px}.sun-editor .se-dialog{position:absolute;display:none;top:0;left:0;width:100%;height:100%;z-index:2147483647}.sun-editor .se-dialog button,.sun-editor .se-dialog input,.sun-editor .se-dialog label{font-size:14px;line-height:1.5;color:#111;margin:0}.sun-editor .se-dialog .se-dialog-back{background-color:#222;opacity:.5}.sun-editor .se-dialog .se-dialog-back,.sun-editor .se-dialog .se-dialog-inner{position:absolute;width:100%;height:100%;top:0;left:0}.sun-editor .se-dialog .se-dialog-inner .se-dialog-content{position:relative;width:auto;max-width:500px;margin:1.75rem auto;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:4px;outline:0;box-shadow:0 3px 9px rgba(0,0,0,.5)}@media screen and (max-width:509px){.sun-editor .se-dialog .se-dialog-inner .se-dialog-content{width:100%}}.sun-editor .se-dialog .se-dialog-inner .se-dialog-content label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}.sun-editor .se-dialog .se-dialog-inner .se-dialog-content .se-btn-primary{display:inline-block;padding:6px 12px;margin:0 0 10px!important;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;touch-action:manipulation;border-radius:4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-header{height:50px;padding:6px 15px;border-bottom:1px solid #e5e5e5}.sun-editor .se-dialog .se-dialog-inner .se-dialog-header .se-dialog-close{float:right;font-weight:700;text-shadow:0 1px 0 #fff;-webkit-appearance:none;filter:alpha(opacity=100);opacity:1}.sun-editor .se-dialog .se-dialog-inner .se-dialog-header .se-modal-title{float:left;font-size:14px;font-weight:700;margin:0;padding:0;line-height:2.5}.sun-editor .se-dialog .se-dialog-inner .se-dialog-body{position:relative;padding:15px 15px 5px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form{margin-bottom:10px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form-footer{margin-top:10px;margin-bottom:0}.sun-editor .se-dialog .se-dialog-inner input:disabled{background-color:#f3f3f3}.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-text{width:100%}.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-text .size-h,.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-text .size-w{width:70px;text-align:center}.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-x{margin:0 8px;width:25px;text-align:center}.sun-editor .se-dialog .se-dialog-inner .se-dialog-footer{height:auto;min-height:55px;padding:10px 15px 0;text-align:right;border-top:1px solid #e5e5e5}.sun-editor .se-dialog .se-dialog-inner .se-dialog-footer>div{float:left}.sun-editor .se-dialog .se-dialog-inner .se-dialog-footer>div>label{margin:0 5px 0 0}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-radio{margin-left:12px;margin-right:6px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-check{margin-left:12px;margin-right:4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form-footer .se-dialog-btn-check{margin-left:0;margin-right:4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form-footer label:first-child{margin-right:16px;margin-left:0}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files{position:relative;display:flex;align-items:center}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files>input{flex:auto}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button{flex:auto;opacity:.8;border:1px solid #ccc}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button.se-file-remove>svg{width:8px;height:8px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button:hover{background-color:#f0f0f0;outline:0 none}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button:active{background-color:#e9e9e9;box-shadow:inset 0 3px 5px #d6d6d6}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-select{display:inline-block;width:auto;height:34px;font-size:14px;text-align:center;line-height:1.42857143}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-control{display:inline-block;width:70px;height:34px;font-size:14px;text-align:center;line-height:1.42857143}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form{display:block;width:100%;height:34px;font-size:14px;line-height:1.42857143;padding:0 4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form.se-input-url{direction:ltr}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form.se-input-url:disabled{text-decoration:line-through;color:#999}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-video-ratio{width:70px;margin-left:4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form a{color:#004cff}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-revert{border:1px solid #ccc}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-revert:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-revert:active{background-color:#d1d1d1;border-color:#c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-dialog-tabs{width:100%;height:25px;border-bottom:1px solid #e5e5e5}.sun-editor .se-dialog-tabs button{background-color:#e5e5e5;border-right:1px solid #e5e5e5;float:left;outline:none;padding:2px 13px;transition:.3s}.sun-editor .se-dialog-tabs button:hover{background-color:#fff}.sun-editor .se-dialog-tabs button.active{background-color:#fff;border-bottom:0}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form.se-math-exp{resize:vertical;height:4rem;border:1px solid #ccc;font-size:13px;padding:4px;direction:ltr}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-select.se-math-size{width:6em;height:28px;margin-left:1em}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview{font-size:13px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview>span{display:inline-block;box-shadow:0 0 0 .1rem #c7deff}.sun-editor .se-dialog .se-dialog-inner .se-link-preview{display:block;height:auto;max-height:18px;font-size:13px;font-weight:400;font-family:inherit;color:#666;background-color:transparent;overflow:hidden;text-overflow:ellipsis;word-break:break-all;white-space:pre}.sun-editor .se-dialog .se-dialog-inner .se-anchor-preview-form{width:100%;display:flex;margin-top:4px}.sun-editor .se-dialog .se-dialog-inner .se-anchor-preview-form .se-svg.se-anchor-preview-icon{flex:unset;display:none;line-height:1.5;color:#4592ff}.sun-editor .se-dialog .se-dialog-inner .se-anchor-preview-form .se-link-preview{flex:auto;margin:0}.sun-editor .se-dialog .se-dialog-inner .se-anchor-rel{height:34px}.sun-editor .se-dialog .se-dialog-inner .se-anchor-rel-btn{width:46px;color:#3f9dff}.sun-editor .se-dialog .se-dialog-inner .se-anchor-rel-wrapper{display:flex;line-height:1.5;padding-top:6px}.sun-editor .se-dialog .se-dialog-inner .se-anchor-rel-preview{text-align:left}.sun-editor .se-controller .se-arrow.se-arrow-up{border-bottom-color:rgba(0,0,0,.25)}.sun-editor .se-controller{position:absolute;display:none;overflow:visible;z-index:6;border:1px solid rgba(0,0,0,.25);border-radius:4px;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.sun-editor .se-controller .se-btn-group{position:relative;display:flex;vertical-align:middle;padding:2px;top:0;left:0}.sun-editor .se-controller .se-btn-group .se-btn-group-sub{left:50%;min-width:auto;width:-webkit-max-content;width:-moz-max-content;width:max-content;display:none}.sun-editor .se-controller .se-btn-group .se-btn-group-sub button{margin:0;min-width:72px}.sun-editor .se-controller .se-btn-group button{position:relative;min-height:34px;height:auto;border:none;border-radius:4px;margin:1px;padding:5px 10px;font-size:12px;line-height:1.5;display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;touch-action:manipulation}.sun-editor .se-controller .se-btn-group button:focus:enabled,.sun-editor .se-controller .se-btn-group button:hover:enabled{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-controller .se-btn-group button:active:enabled{background-color:#d1d1d1;border-color:#c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-controller .se-btn-group button span{display:block;padding:0;margin:0}.sun-editor .se-controller .se-btn-group button:enabled.active{color:#4592ff;outline:0 none}.sun-editor .se-controller .se-btn-group button:enabled.active:focus,.sun-editor .se-controller .se-btn-group button:enabled.active:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-controller .se-btn-group button:enabled.active:active{background-color:#d1d1d1;border-color:#c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-controller .se-btn-group button:enabled.on{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-controller .se-btn-group button:enabled.on:focus,.sun-editor .se-controller .se-btn-group button:enabled.on:hover{background-color:#d1d1d1;border-color:#c1c1c1;outline:0 none}.sun-editor .se-controller .se-btn-group button:enabled.on:active{background-color:#c1c1c1;border-color:#b1b1b1;box-shadow:inset 0 3px 5px #b1b1b1}.sun-editor .se-controller .se-form-group input{min-width:120px}.sun-editor .se-controller-resizing{margin-top:-50px!important;padding:0;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143}.sun-editor .se-controller-resizing .se-btn-group .se-btn-group-sub.se-resizing-align-list{width:74px}.sun-editor .se-resizing-container{position:absolute;display:none;outline:1px solid #3f9dff;background-color:transparent}.sun-editor .se-resizing-container .se-modal-resize{position:absolute;display:inline-block;background-color:#3f9dff;opacity:.3}.sun-editor .se-resizing-container .se-resize-dot{position:absolute;top:0;left:0;width:100%;height:100%}.sun-editor .se-resizing-container .se-resize-dot>span{position:absolute;width:7px;height:7px;background-color:#3f9dff;border:1px solid #4592ff}.sun-editor .se-resizing-container .se-resize-dot>span.tl{top:-5px;left:-5px;cursor:nw-resize}.sun-editor .se-resizing-container .se-resize-dot>span.tr{top:-5px;right:-5px;cursor:ne-resize}.sun-editor .se-resizing-container .se-resize-dot>span.bl{bottom:-5px;left:-5px;cursor:sw-resize}.sun-editor .se-resizing-container .se-resize-dot>span.br{right:-5px;bottom:-5px;cursor:se-resize}.sun-editor .se-resizing-container .se-resize-dot>span.lw{left:-7px;bottom:50%;cursor:w-resize}.sun-editor .se-resizing-container .se-resize-dot>span.th{left:50%;top:-7px;cursor:n-resize}.sun-editor .se-resizing-container .se-resize-dot>span.rw{right:-7px;bottom:50%;cursor:e-resize}.sun-editor .se-resizing-container .se-resize-dot>span.bh{right:50%;bottom:-7px;cursor:s-resize}.sun-editor .se-resizing-container .se-resize-display{position:absolute;right:0;bottom:0;padding:5px;margin:5px;font-size:12px;color:#fff;background-color:#333;border-radius:4px}.sun-editor .se-controller-table,.sun-editor .se-controller-table-cell{width:auto}.sun-editor .se-controller-link,.sun-editor .se-controller-table,.sun-editor .se-controller-table-cell{padding:0;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143}.sun-editor .se-controller-link:after,.sun-editor .se-controller-link:before{box-sizing:border-box}.sun-editor .se-controller-link .link-content{padding:0;margin:0}.sun-editor .se-controller-link .link-content a{display:inline-block;color:#4592ff;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;margin-left:5px}.sun-editor .se-file-browser{position:absolute;display:none;top:0;left:0;width:100%;height:100%;z-index:2147483647}.sun-editor .se-file-browser button,.sun-editor .se-file-browser input,.sun-editor .se-file-browser label{font-size:14px;line-height:1.5;color:#111;margin:0}.sun-editor .se-file-browser .se-file-browser-back{background-color:#222;opacity:.5}.sun-editor .se-file-browser .se-file-browser-back,.sun-editor .se-file-browser .se-file-browser-inner{position:absolute;display:block;width:100%;height:100%;top:0;left:0}.sun-editor .se-file-browser .se-file-browser-inner .se-file-browser-content{position:relative;width:960px;max-width:100%;margin:20px auto;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:4px;outline:0;box-shadow:0 3px 9px rgba(0,0,0,.5)}.sun-editor .se-file-browser .se-file-browser-header{height:auto;min-height:50px;padding:6px 15px;border-bottom:1px solid #e5e5e5}.sun-editor .se-file-browser .se-file-browser-header .se-file-browser-close{float:right;font-weight:700;text-shadow:0 1px 0 #fff;-webkit-appearance:none;filter:alpha(opacity=100);opacity:1}.sun-editor .se-file-browser .se-file-browser-header .se-file-browser-close>svg{width:12px;height:12px}.sun-editor .se-file-browser .se-file-browser-header .se-file-browser-title{font-size:16px;font-weight:700;margin:0;padding:0;line-height:2.2}.sun-editor .se-file-browser .se-file-browser-tags{display:block;width:100%;padding:0;text-align:left;margin:0 -15px}.sun-editor .se-file-browser .se-file-browser-tags a{display:inline-block;background-color:#f5f5f5;padding:6px 12px;margin:8px 0 8px 8px;color:#333;text-decoration:none;border-radius:32px;-moz-border-radius:32px;-webkit-border-radius:32px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;cursor:pointer}.sun-editor .se-file-browser .se-file-browser-tags a:hover{background-color:#e1e1e1}.sun-editor .se-file-browser .se-file-browser-tags a:active{background-color:#d1d1d1}.sun-editor .se-file-browser .se-file-browser-tags a.on{background-color:#ebf3fe;color:#4592ff}.sun-editor .se-file-browser .se-file-browser-tags a.on:hover{background-color:#d8e8fe}.sun-editor .se-file-browser .se-file-browser-tags a.on:active{background-color:#c7deff}.sun-editor .se-file-browser .se-file-browser-body{position:relative;height:auto;min-height:350px;padding:20px;overflow-y:auto}.sun-editor .se-file-browser .se-file-browser-body .se-file-browser-list{position:relative;width:100%}@media screen and (max-width:992px){.sun-editor .se-file-browser .se-file-browser-inner .se-file-browser-content{width:748px}}@media screen and (max-width:768px){.sun-editor .se-file-browser .se-file-browser-inner .se-file-browser-content{width:600px}}.sun-editor .se-file-browser .se-file-browser-list .se-file-item-column{position:relative;display:block;height:auto;float:left}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-column{width:calc(25% - 20px);margin:0 10px}@media screen and (max-width:992px){.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-column{width:calc(33% - 20px)}}@media screen and (max-width:768px){.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-column{width:calc(50% - 20px)}}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img{position:relative;display:block;cursor:pointer;width:100%;height:auto;border-radius:4px;outline:0;margin:10px 0}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img:hover{opacity:.8;box-shadow:0 0 0 .2rem #3288ff}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img>img{position:relative;display:block;width:100%;border-radius:4px;outline:0;height:auto}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img>.se-file-img-name{position:absolute;z-index:1;font-size:13px;color:#fff;left:0;bottom:0;padding:5px 10px;background-color:transparent;width:100%;height:30px;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img>.se-file-img-name.se-file-name-back{background-color:#333;opacity:.6}.sun-editor .se-notice{position:absolute;top:0;display:none;z-index:7;width:100%;height:auto;word-break:break-all;font-size:13px;color:#b94a48;background-color:#f2dede;padding:15px;margin:0;border:1px solid #eed3d7;user-select:auto;-o-user-select:auto;-moz-user-select:auto;-khtml-user-select:auto;-webkit-user-select:auto;-ms-user-select:auto}.sun-editor .se-notice button{float:right;padding:7px}.sun-editor .se-tooltip{position:relative;overflow:visible}.sun-editor .se-tooltip .se-tooltip-inner{visibility:hidden;position:absolute;display:block;width:auto;top:120%;left:50%;background:transparent;opacity:0;z-index:1;line-height:1.5;transition:opacity .5s;margin:0;padding:0;bottom:auto;float:none;pointer-events:none;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden}.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text{position:relative;display:inline-block;width:auto;left:-50%;font-size:.9em;margin:0;padding:4px 6px;border-radius:2px;background-color:#333;color:#fff;text-align:center;line-height:unset;white-space:nowrap;cursor:auto}.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text:after{content:\"\";position:absolute;bottom:100%;left:50%;margin-left:-5px;border:5px solid transparent;border-bottom-color:#333}.sun-editor .se-tooltip:hover .se-tooltip-inner{visibility:visible;opacity:1}.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut{display:block!important}.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut>.se-shortcut-key{display:inline;font-weight:700}.sun-editor.se-rtl .se-btn-tray{direction:rtl}.sun-editor.se-rtl .se-btn-select .txt{flex:auto;text-align:right;direction:rtl}.sun-editor.se-rtl .se-btn-list{text-align:right}.sun-editor.se-rtl .se-btn-list>.se-list-icon{margin:-1px 0 0 10px}.sun-editor.se-rtl .se-menu-list,.sun-editor.se-rtl .se-menu-list li{float:right}.sun-editor.se-rtl .se-list-layer *{direction:rtl}.sun-editor.se-rtl .se-list-layer.se-list-format ul blockquote{padding:0 7px 0 0;border-right-width:5px;border-left-width:0}.sun-editor.se-rtl .se-list-layer .se-selector-color .se-color-pallet li{float:right}.sun-editor.se-rtl .se-list-inner .se-list-checked li button>.se-svg{float:right;padding:6px 0 0 6px}.sun-editor.se-rtl .se-tooltip .se-tooltip-inner .se-tooltip-text,.sun-editor.se-rtl .se-wrapper .se-placeholder{direction:rtl}.sun-editor.se-rtl .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut{direction:ltr}.sun-editor.se-rtl .se-dialog *{direction:rtl}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-header .se-dialog-close{float:left}.sun-editor.se-rtl .se-dialog-tabs button,.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-header .se-modal-title{float:right}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-size-text{padding-right:34px}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-footer .se-btn-primary{float:left}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-footer>div{float:right}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-footer>div>label{margin:0 0 0 5px}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-form-footer label:first-child{margin-left:16px;margin-right:0}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-anchor-rel-preview{margin-left:4px;text-align:right}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-anchor-rel-btn{float:right}.sun-editor.se-rtl .se-file-browser *{direction:rtl}.sun-editor.se-rtl .se-file-browser .se-file-browser-tags{text-align:right}.sun-editor.se-rtl .se-file-browser .se-file-browser-tags a{margin:8px 8px 0}.sun-editor.se-rtl .se-file-browser .se-file-browser-header .se-file-browser-close{float:left}.sun-editor.se-rtl .se-controller .se-btn-group,.sun-editor.se-rtl .se-resizing-container .se-resize-display{direction:rtl}@-webkit-keyframes blinker{50%{opacity:0}}@keyframes blinker{50%{opacity:0}}@-webkit-keyframes spinner{to{transform:rotate(361deg)}}@keyframes spinner{to{transform:rotate(361deg)}}.sun-editor-editable{font-family:Helvetica Neue,sans-serif;font-size:13px;color:#333;line-height:1.5;background-color:#fff;word-break:normal;word-wrap:break-word;padding:16px;margin:0}.sun-editor-editable *{box-sizing:border-box;font-family:inherit;font-size:inherit;color:inherit}.sun-editor-editable.se-rtl *{direction:rtl}.sun-editor-editable audio,.sun-editor-editable figcaption,.sun-editor-editable figure,.sun-editor-editable iframe,.sun-editor-editable img,.sun-editor-editable td,.sun-editor-editable th,.sun-editor-editable video{position:relative}.sun-editor-editable .__se__float-left{float:left}.sun-editor-editable .__se__float-right{float:right}.sun-editor-editable .__se__float-center{float:center}.sun-editor-editable .__se__float-none{float:none}.sun-editor-editable span{display:inline;vertical-align:baseline;margin:0;padding:0}.sun-editor-editable span.katex{display:inline-block;direction:ltr}.sun-editor-editable a{color:#004cff;text-decoration:none}.sun-editor-editable span[style~=\"color:\"] a{color:inherit}.sun-editor-editable a:focus,.sun-editor-editable a:hover{cursor:pointer;color:#0093ff;text-decoration:underline}.sun-editor-editable a.on{color:#0093ff;background-color:#e8f7ff}.sun-editor-editable pre{display:block;padding:8px;margin:0 0 10px;font-family:monospace;color:#666;line-height:1.45;background-color:#f9f9f9;border:1px solid #e1e1e1;border-radius:2px;white-space:pre-wrap;word-wrap:break-word;overflow:visible}.sun-editor-editable ol{list-style-type:decimal}.sun-editor-editable ol,.sun-editor-editable ul{list-style-position:inside;display:block;-webkit-margin-before:1em;margin-block-start:1em;-webkit-margin-after:1em;margin-block-end:1em;-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:0;margin-inline-end:0;-webkit-padding-start:40px;padding-inline-start:40px}.sun-editor-editable ul{list-style-type:disc}.sun-editor-editable li{display:list-item;text-align:-webkit-match-parent;margin-bottom:5px}.sun-editor-editable ol ol,.sun-editor-editable ol ul,.sun-editor-editable ul ol,.sun-editor-editable ul ul{margin:0}.sun-editor-editable ol ol,.sun-editor-editable ul ol{list-style-type:lower-alpha}.sun-editor-editable ol ol ol,.sun-editor-editable ul ol ol,.sun-editor-editable ul ul ol{list-style-type:upper-roman}.sun-editor-editable ol ul,.sun-editor-editable ul ul{list-style-type:circle}.sun-editor-editable ol ol ul,.sun-editor-editable ol ul ul,.sun-editor-editable ul ul ul{list-style-type:square}.sun-editor-editable sub,.sun-editor-editable sup{font-size:75%;line-height:0}.sun-editor-editable sub{vertical-align:sub}.sun-editor-editable sup{vertical-align:super}.sun-editor-editable p{display:block;margin:0 0 10px}.sun-editor-editable div{display:block;margin:0;padding:0}.sun-editor-editable blockquote{display:block;font-family:inherit;font-size:inherit;color:#999;-webkit-margin-before:1em;margin-block-start:1em;-webkit-margin-after:1em;margin-block-end:1em;-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:0;margin-inline-end:0;padding:0 5px 0 20px;border:solid #b1b1b1;border-width:0 0 0 5px}.sun-editor-editable blockquote blockquote{border-color:#c1c1c1}.sun-editor-editable blockquote blockquote blockquote{border-color:#d1d1d1}.sun-editor-editable blockquote blockquote blockquote blockquote{border-color:#e1e1e1}.sun-editor-editable.se-rtl blockquote{padding-left:5px;padding-right:20px;border-left-width:0;border-right-width:5px}.sun-editor-editable h1{font-size:2em;-webkit-margin-before:.67em;margin-block-start:.67em;-webkit-margin-after:.67em;margin-block-end:.67em}.sun-editor-editable h1,.sun-editor-editable h2{display:block;-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:0;margin-inline-end:0;font-weight:700}.sun-editor-editable h2{font-size:1.5em;-webkit-margin-before:.83em;margin-block-start:.83em;-webkit-margin-after:.83em;margin-block-end:.83em}.sun-editor-editable h3{font-size:1.17em;-webkit-margin-before:1em;margin-block-start:1em;-webkit-margin-after:1em;margin-block-end:1em}.sun-editor-editable h3,.sun-editor-editable h4{display:block;-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:0;margin-inline-end:0;font-weight:700}.sun-editor-editable h4{font-size:1em;-webkit-margin-before:1.33em;margin-block-start:1.33em;-webkit-margin-after:1.33em;margin-block-end:1.33em}.sun-editor-editable h5{font-size:.83em;-webkit-margin-before:1.67em;margin-block-start:1.67em;-webkit-margin-after:1.67em;margin-block-end:1.67em}.sun-editor-editable h5,.sun-editor-editable h6{display:block;-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:0;margin-inline-end:0;font-weight:700}.sun-editor-editable h6{font-size:.67em;-webkit-margin-before:2.33em;margin-block-start:2.33em;-webkit-margin-after:2.33em;margin-block-end:2.33em}.sun-editor-editable hr{display:flex;border-width:1px 0 0;border-color:#000;-o-border-image:initial;border-image:initial;height:1px}.sun-editor-editable hr.__se__solid{border-style:solid none none}.sun-editor-editable hr.__se__dotted{border-style:dotted none none}.sun-editor-editable hr.__se__dashed{border-style:dashed none none}.sun-editor-editable table{display:table;table-layout:auto;border:1px solid #ccc;width:100%;max-width:100%;margin:0 0 10px;background-color:transparent;border-spacing:0;border-collapse:collapse}.sun-editor-editable.se-rtl table{margin:0 0 10px auto}.sun-editor-editable table thead{border-bottom:2px solid #333}.sun-editor-editable table tr{border:1px solid #efefef}.sun-editor-editable table th{background-color:#f3f3f3}.sun-editor-editable table td,.sun-editor-editable table th{border:1px solid #e1e1e1;padding:.4em;background-clip:padding-box}.sun-editor-editable table.se-table-size-auto{width:auto!important}.sun-editor-editable table.se-table-size-100{width:100%!important}.sun-editor-editable table.se-table-layout-auto{table-layout:auto!important}.sun-editor-editable table.se-table-layout-fixed{table-layout:fixed!important}.sun-editor-editable table td.se-table-selected-cell,.sun-editor-editable table th.se-table-selected-cell{border:1px double #4592ff;background-color:#f1f7ff}.sun-editor-editable.se-disabled *{user-select:none;-o-user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none}.sun-editor-editable .se-component{display:flex;padding:1px;margin:0 0 10px}.sun-editor-editable[contenteditable=true] .se-component{outline:1px dashed #e1e1e1;min-width:16px;min-height:16px}.sun-editor-editable[contenteditable=true] .se-component.se-component-copy{box-shadow:0 0 0 .2rem #3f9dff;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.sun-editor-editable audio,.sun-editor-editable iframe,.sun-editor-editable img,.sun-editor-editable video{display:block;margin:0;padding:0;width:auto;height:auto;max-width:100%}.sun-editor-editable[contenteditable=true] figure:after{position:absolute;content:\"\";z-index:1;top:0;left:0;right:0;bottom:0;cursor:default;display:block;background:transparent}.sun-editor-editable[contenteditable=true] figure a,.sun-editor-editable[contenteditable=true] figure iframe,.sun-editor-editable[contenteditable=true] figure img,.sun-editor-editable[contenteditable=true] figure video{z-index:0}.sun-editor-editable[contenteditable=true] figure figcaption{display:block;z-index:2}.sun-editor-editable[contenteditable=true] figure figcaption:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem #c7deff}.sun-editor-editable .se-image-container,.sun-editor-editable .se-video-container{width:auto;height:auto;max-width:100%}.sun-editor-editable figure{display:block;outline:none;margin:0;padding:0}.sun-editor-editable figure figcaption{padding:1em .5em;margin:0;background-color:#f9f9f9;outline:none}.sun-editor-editable figure figcaption p{line-height:2;margin:0}.sun-editor-editable .se-image-container a img{padding:1px;margin:1px;outline:1px solid #4592ff}.sun-editor-editable .se-video-container iframe,.sun-editor-editable .se-video-container video{outline:1px solid #9e9e9e;position:absolute;top:0;left:0;border:0;width:100%;height:100%}.sun-editor-editable .se-video-container figure{left:0;width:100%;max-width:100%}.sun-editor-editable audio{width:300px;height:54px}.sun-editor-editable audio.active{outline:2px solid #80bdff}.sun-editor-editable.se-show-block div,.sun-editor-editable.se-show-block h1,.sun-editor-editable.se-show-block h2,.sun-editor-editable.se-show-block h3,.sun-editor-editable.se-show-block h4,.sun-editor-editable.se-show-block h5,.sun-editor-editable.se-show-block h6,.sun-editor-editable.se-show-block li,.sun-editor-editable.se-show-block ol,.sun-editor-editable.se-show-block p,.sun-editor-editable.se-show-block pre,.sun-editor-editable.se-show-block ul{border:1px dashed #3f9dff!important;padding:14px 8px 8px!important}.sun-editor-editable.se-show-block ol,.sun-editor-editable.se-show-block ul{border:1px dashed #d539ff!important}.sun-editor-editable.se-show-block pre{border:1px dashed #27c022!important}.se-show-block p{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPAQMAAAAF7dc0AAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAaSURBVAjXY/j/gwGCPvxg+F4BQiAGDP1HQQByxxw0gqOzIwAAAABJRU5ErkJggg==\") no-repeat}.se-show-block div{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAPAQMAAAAxlBYoAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAmSURBVAjXY/j//wcDDH+8XsHwDYi/hwNx1A8w/nYLKH4XoQYJAwCXnSgcl2MOPgAAAABJRU5ErkJggg==\") no-repeat}.se-show-block h1{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAfSURBVAjXY/j/v4EBhr+9B+LzEPrDeygfhI8j1CBhAEhmJGY4Rf6uAAAAAElFTkSuQmCC\") no-repeat}.se-show-block h2{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAmSURBVAjXY/j/v4EBhr+dB+LtQPy9geEDEH97D8T3gbgdoQYJAwA51iPuD2haEAAAAABJRU5ErkJggg==\") no-repeat}.se-show-block h3{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAiSURBVAjXY/j/v4EBhr+dB+LtQPy9geHDeQgN5p9HqEHCADeWI+69VG2MAAAAAElFTkSuQmCC\") no-repeat}.se-show-block h4{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAPAQMAAADTSA1RAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAiSURBVAjXY/j//wADDH97DsTXIfjDdiDdDMTfIRhZHRQDAKJOJ6L+K3y7AAAAAElFTkSuQmCC\") no-repeat}.se-show-block h5{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAlSURBVAjXY/j/v4EBhr+1A/F+IO5vYPiwHUh/B2IQfR6hBgkDABlWIy5uM+9GAAAAAElFTkSuQmCC\") no-repeat}.se-show-block h6{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAiSURBVAjXY/j/v4EBhr+dB+LtQLy/geFDP5S9HSKOrA6KAR9GIza1ptJnAAAAAElFTkSuQmCC\") no-repeat}.se-show-block li{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA7SURBVDhPYxgFcNDQ0PAfykQBIHEYhgoRB/BpwCfHBKWpBkaggYxQGgOgBzyQD1aLLA4TGwWDGjAwAACR3RcEU9Ui+wAAAABJRU5ErkJggg==\") no-repeat}.se-show-block ol{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABHSURBVDhPYxgFcNDQ0PAfhKFcFIBLHCdA1oBNM0kGEmMAPgOZoDTVANUNxAqQvURMECADRiiNAWCagDSGGhyW4DRrMAEGBgAu0SX6WpGgjAAAAABJRU5ErkJggg==\") no-repeat}.se-show-block ul{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA1SURBVDhPYxgFDA0NDf+hTBSALI5LDQgwQWmqgVEDKQcsUBoF4ItFGEBXA+QzQpmDGjAwAAA8DQ4Lni6gdAAAAABJRU5ErkJggg==\") no-repeat}.sun-editor-editable .__se__p-bordered,.sun-editor .__se__p-bordered{border-top:1px solid #b1b1b1;border-bottom:1px solid #b1b1b1;padding:4px 0}.sun-editor-editable .__se__p-spaced,.sun-editor .__se__p-spaced{letter-spacing:1px}.sun-editor-editable .__se__p-neon,.sun-editor .__se__p-neon{font-weight:200;font-style:italic;background:#000;color:#fff;padding:6px 4px;border:2px solid #fff;border-radius:6px;text-transform:uppercase;-webkit-animation:neonFlicker 1.5s infinite alternate;animation:neonFlicker 1.5s infinite alternate}@-webkit-keyframes neonFlicker{0%,19%,21%,23%,25%,54%,56%,to{text-shadow:-.2rem -.2rem 1rem #fff,.2rem .2rem 1rem #fff,0 0 2px #f40,0 0 4px #f40,0 0 6px #f40,0 0 8px #f40,0 0 10px #f40;box-shadow:0 0 .5px #fff,inset 0 0 .5px #fff,0 0 2px #08f,inset 0 0 2px #08f,0 0 4px #08f,inset 0 0 4px #08f}20%,24%,55%{text-shadow:none;box-shadow:none}}@keyframes neonFlicker{0%,19%,21%,23%,25%,54%,56%,to{text-shadow:-.2rem -.2rem 1rem #fff,.2rem .2rem 1rem #fff,0 0 2px #f40,0 0 4px #f40,0 0 6px #f40,0 0 8px #f40,0 0 10px #f40;box-shadow:0 0 .5px #fff,inset 0 0 .5px #fff,0 0 2px #08f,inset 0 0 2px #08f,0 0 4px #08f,inset 0 0 4px #08f}20%,24%,55%{text-shadow:none;box-shadow:none}}.sun-editor-editable .__se__t-shadow,.sun-editor .__se__t-shadow{text-shadow:-.2rem -.2rem 1rem #fff,.2rem .2rem 1rem #fff,0 0 .2rem #999,0 0 .4rem #888,0 0 .6rem #777,0 0 .8rem #666,0 0 1rem #555}.sun-editor-editable .__se__t-code,.sun-editor .__se__t-code{font-family:monospace;color:#666;background-color:rgba(27,31,35,.05);border-radius:6px;padding:.2em .4em}", ""]); - -// exports - - -/***/ }), - -/***/ "./node_modules/css-loader/lib/css-base.js": -/*!*************************************************!*\ - !*** ./node_modules/css-loader/lib/css-base.js ***! - \*************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -// css base code, injected by the css-loader -module.exports = function(useSourceMap) { - var list = []; - - // return the list of modules as css string - list.toString = function toString() { - return this.map(function (item) { - var content = cssWithMappingToString(item, useSourceMap); - if(item[2]) { - return "@media " + item[2] + "{" + content + "}"; - } else { - return content; - } - }).join(""); - }; - - // import a list of modules into the list - list.i = function(modules, mediaQuery) { - if(typeof modules === "string") - modules = [[null, modules, ""]]; - var alreadyImportedModules = {}; - for(var i = 0; i < this.length; i++) { - var id = this[i][0]; - if(typeof id === "number") - alreadyImportedModules[id] = true; - } - for(i = 0; i < modules.length; i++) { - var item = modules[i]; - // skip already imported module - // this implementation is not 100% perfect for weird media query combinations - // when a module is imported multiple times with different media queries. - // I hope this will never occur (Hey this way we have smaller bundles) - if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { - if(mediaQuery && !item[2]) { - item[2] = mediaQuery; - } else if(mediaQuery) { - item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; - } - list.push(item); - } - } - }; - return list; -}; - -function cssWithMappingToString(item, useSourceMap) { - var content = item[1] || ''; - var cssMapping = item[3]; - if (!cssMapping) { - return content; - } - - if (useSourceMap && typeof btoa === 'function') { - var sourceMapping = toComment(cssMapping); - var sourceURLs = cssMapping.sources.map(function (source) { - return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */' - }); - - return [content].concat(sourceURLs).concat([sourceMapping]).join('\n'); - } - - return [content].join('\n'); -} - -// Adapted from convert-source-map (MIT) -function toComment(sourceMap) { - // eslint-disable-next-line no-undef - var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))); - var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64; - - return '/*# ' + data + ' */'; -} - - /***/ }), /***/ "./node_modules/jquery/dist/jquery.js": @@ -37974,21379 +37868,6 @@ process.chdir = function (dir) { process.umask = function() { return 0; }; -/***/ }), - -/***/ "./node_modules/style-loader/lib/addStyles.js": -/*!****************************************************!*\ - !*** ./node_modules/style-loader/lib/addStyles.js ***! - \****************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -var stylesInDom = {}; - -var memoize = function (fn) { - var memo; - - return function () { - if (typeof memo === "undefined") memo = fn.apply(this, arguments); - return memo; - }; -}; - -var isOldIE = memoize(function () { - // Test for IE <= 9 as proposed by Browserhacks - // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805 - // Tests for existence of standard globals is to allow style-loader - // to operate correctly into non-standard environments - // @see https://github.com/webpack-contrib/style-loader/issues/177 - return window && document && document.all && !window.atob; -}); - -var getTarget = function (target, parent) { - if (parent){ - return parent.querySelector(target); - } - return document.querySelector(target); -}; - -var getElement = (function (fn) { - var memo = {}; - - return function(target, parent) { - // If passing function in options, then use it for resolve "head" element. - // Useful for Shadow Root style i.e - // { - // insertInto: function () { return document.querySelector("#foo").shadowRoot } - // } - if (typeof target === 'function') { - return target(); - } - if (typeof memo[target] === "undefined") { - var styleTarget = getTarget.call(this, target, parent); - // Special case to return head of iframe instead of iframe itself - if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) { - try { - // This will throw an exception if access to iframe is blocked - // due to cross-origin restrictions - styleTarget = styleTarget.contentDocument.head; - } catch(e) { - styleTarget = null; - } - } - memo[target] = styleTarget; - } - return memo[target] - }; -})(); - -var singleton = null; -var singletonCounter = 0; -var stylesInsertedAtTop = []; - -var fixUrls = __webpack_require__(/*! ./urls */ "./node_modules/style-loader/lib/urls.js"); - -module.exports = function(list, options) { - if (typeof DEBUG !== "undefined" && DEBUG) { - if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment"); - } - - options = options || {}; - - options.attrs = typeof options.attrs === "object" ? options.attrs : {}; - - // Force single-tag solution on IE6-9, which has a hard limit on the # of ' + - '' + - '' + contentsHTML + '' + - '' - ); - } else { - const links = _d.head.getElementsByTagName('link'); - const styles = _d.head.getElementsByTagName('style'); - let linkHTML = ''; - for (let i = 0, len = links.length; i < len; i++) { - linkHTML += links[i].outerHTML; - } - for (let i = 0, len = styles.length; i < len; i++) { - linkHTML += styles[i].outerHTML; - } - - windowObject.document.write('' + - '' + - '' + - '' + - '' + - '' + lang.toolbar.preview + '' + - linkHTML + - '' + - '' + contentsHTML + '' + - '' - ); - } - }, - - /** - * @description Sets the HTML string - * @param {String|undefined} html HTML string - */ - setContents: function (html) { - this.removeRange(); - - const convertValue = (html === null || html === undefined) ? '' : this.convertContentsForEditor(html); - this._resetComponents(); - - if (!this._variable.isCodeView) { - context.element.wysiwyg.innerHTML = convertValue; - // history stack - this.history.push(false); - } else { - const value = this.convertHTMLForCodeView(convertValue); - this._setCodeView(value); - } - }, - - /** - * @description Sets the contents of the iframe's head tag and body tag when using the "iframe" or "fullPage" option. - * @param {Object} ctx { head: HTML string, body: HTML string} - */ - setIframeContents: function (ctx) { - if (!options.iframe) return false; - if (ctx.head) this._wd.head.innerHTML = ctx.head.replace(/[\s\S]*<\/script>/gi, ''); - if (ctx.body) this._wd.body.innerHTML = this.convertContentsForEditor(ctx.body); - }, - - /** - * @description Gets the current contents - * @param {Boolean} onlyContents Return only the contents of the body without headers when the "fullPage" option is true - * @returns {Object} - */ - getContents: function (onlyContents) { - const contents = context.element.wysiwyg.innerHTML; - const renderHTML = util.createElement('DIV'); - renderHTML.innerHTML = contents; - - const figcaptions = util.getListChildren(renderHTML, function (current) { - return /FIGCAPTION/i.test(current.nodeName); - }); - - for (let i = 0, len = figcaptions.length; i < len; i++) { - figcaptions[i].removeAttribute('contenteditable'); - } - - if (options.fullPage && !onlyContents) { - const attrs = util.getAttributesToString(this._wd.body, ['contenteditable']); - return '' + this._wd.head.outerHTML + '' + renderHTML.innerHTML + ''; - } else { - return renderHTML.innerHTML; - } - }, - - /** - * @description Returns HTML string according to tag type and configuration. - * Use only "cleanHTML" - * @param {Node} node Node - * @param {Boolean} requireFormat If true, text nodes that do not have a format node is wrapped with the format tag. - * @private - */ - _makeLine: function (node, requireFormat) { - const defaultTag = options.defaultTag; - // element - if (node.nodeType === 1) { - if (util._disallowedTags(node)) return ''; - if (!requireFormat || (util.isFormatElement(node) || util.isRangeFormatElement(node) || util.isComponent(node) || util.isMedia(node) || (util.isAnchor(node) && util.isMedia(node.firstElementChild)))) { - return node.outerHTML; - } else { - return '<' + defaultTag + '>' + node.outerHTML + ''; - } - } - // text - if (node.nodeType === 3) { - if (!requireFormat) return node.textContent; - const textArray = node.textContent.split(/\n/g); - let html = ''; - for (let i = 0, tLen = textArray.length, text; i < tLen; i++) { - text = textArray[i].trim(); - if (text.length > 0) html += '<' + defaultTag + '>' + text + ''; - } - return html; - } - // comments - if (node.nodeType === 8 && this._allowHTMLComments) { - return ''; - } - - return ''; - }, - - /** - * @description Removes attribute values such as style and converts tags that do not conform to the "html5" standard. - * @param {String} text - * @returns {String} HTML string - * @private - */ - _tagConvertor: function (text) { - if (!this._disallowedTextTagsRegExp) return text; - - const ec = options._textTagsMap; - return text.replace(this._disallowedTextTagsRegExp, function (m, t, n) { - return t + (typeof ec[n] === 'string' ? ec[n] : n); - }); - }, - - /** - * @description Delete disallowed tags - * @param {String} html HTML string - * @returns {String} - * @private - */ - _deleteDisallowedTags: function (html) { - return html - .replace(/\n/g, '') - .replace(/<(script|style)[\s\S]*>[\s\S]*<\/(script|style)>/gi, '') - .replace(/<[a-z0-9]+\:[a-z0-9]+[^>^\/]*>[^>]*<\/[a-z0-9]+\:[a-z0-9]+>/gi, '') - .replace(this.editorTagsWhitelistRegExp, ''); - }, - - /** - * @description Tag and tag attribute check RegExp function. (used by "cleanHTML" and "convertContentsForEditor") - * @param {Boolean} rowLevelCheck Row level check - * @param {String} m RegExp value - * @param {String} t RegExp value - * @returns {String} - * @private - */ - _cleanTags: function (rowLevelCheck, m, t) { - if (/^<[a-z0-9]+\:[a-z0-9]+/i.test(m)) return m; - - let v = null; - const tAttr = this._attributesTagsWhitelist[t.match(/(?!<)[a-zA-Z0-9]+/)[0].toLowerCase()]; - if (tAttr) v = m.match(tAttr); - else v = m.match(this._attributesWhitelistRegExp); - - if ((rowLevelCheck || /]*(?=>)/g, this._cleanTags.bind(this, false)); - - const dom = _d.createRange().createContextualFragment(html); - try { - util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, options.allowStyles); - } catch (error) { - console.warn('[SUNEDITOR.cleanHTML.consistencyCheck.fail] ' + error); - } - - if (this.managedTagsInfo && this.managedTagsInfo.query) { - const textCompList = dom.querySelectorAll(this.managedTagsInfo.query); - for (let i = 0, len = textCompList.length, initMethod, classList; i < len; i++) { - classList = [].slice.call(textCompList[i].classList); - for (let c = 0, cLen = classList.length; c < cLen; c++) { - initMethod = this.managedTagsInfo.map[classList[c]]; - if (initMethod) { - initMethod(textCompList[i]); - break; - } - } - } - } - - const domTree = dom.childNodes; - let cleanHTML = ''; - let requireFormat = false; - - for (let i = 0, len = domTree.length, t; i < len; i++) { - t = domTree[i]; - if (t.nodeType === 1 && !util.isTextStyleElement(t) && !util.isBreak(t) && !util._disallowedTags(t)) { - requireFormat = true; - break; - } - } - - for (let i = 0, len = domTree.length; i < len; i++) { - cleanHTML += this._makeLine(domTree[i], requireFormat); - } - - cleanHTML = util.htmlRemoveWhiteSpace(cleanHTML); - return this._tagConvertor(!cleanHTML ? html : !whitelist ? cleanHTML : cleanHTML.replace(typeof whitelist === 'string' ? util.createTagsWhitelist(whitelist) : whitelist, '')); - }, - - /** - * @description Converts contents into a format that can be placed in an editor - * @param {String} contents contents - * @returns {String} - */ - convertContentsForEditor: function (contents) { - contents = this._deleteDisallowedTags(contents).replace(/(<[a-zA-Z0-9]+)[^>]*(?=>)/g, this._cleanTags.bind(this, true)); - - const dom = _d.createRange().createContextualFragment(this._deleteDisallowedTags(contents)); - - try { - util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, options.allowStyles); - } catch (error) { - console.warn('[SUNEDITOR.convertContentsForEditor.consistencyCheck.fail] ' + error); - } - - if (this.managedTagsInfo && this.managedTagsInfo.query) { - const textCompList = dom.querySelectorAll(this.managedTagsInfo.query); - for (let i = 0, len = textCompList.length, initMethod, classList; i < len; i++) { - classList = [].slice.call(textCompList[i].classList); - for (let c = 0, cLen = classList.length; c < cLen; c++) { - initMethod = this.managedTagsInfo.map[classList[c]]; - if (initMethod) { - initMethod(textCompList[i]); - break; - } - } - } - } - - const domTree = dom.childNodes; - let cleanHTML = ''; - for (let i = 0, len = domTree.length; i < len; i++) { - cleanHTML += this._makeLine(domTree[i], true); - } - - if (cleanHTML.length === 0) return '<' + options.defaultTag + '>
'; - - cleanHTML = util.htmlRemoveWhiteSpace(cleanHTML); - return this._tagConvertor(cleanHTML); - }, - - /** - * @description Converts wysiwyg area element into a format that can be placed in an editor of code view mode - * @param {Element|String} html WYSIWYG element (context.element.wysiwyg) or HTML string. - * @returns {String} - */ - convertHTMLForCodeView: function (html) { - let returnHTML = ''; - const wRegExp = _w.RegExp; - const brReg = new wRegExp('^(BLOCKQUOTE|PRE|TABLE|THEAD|TBODY|TR|TH|TD|OL|UL|IMG|IFRAME|VIDEO|AUDIO|FIGURE|FIGCAPTION|HR|BR|CANVAS|SELECT)$', 'i'); - const isFormatElement = util.isFormatElement.bind(util); - const wDoc = typeof html === 'string' ? _d.createRange().createContextualFragment(html) : html; - - let indentSize = this._variable.codeIndent * 1; - indentSize = indentSize > 0 ? new _w.Array(indentSize + 1).join(' ') : ''; - - (function recursionFunc (element, indent, lineBR) { - const children = element.childNodes; - const elementRegTest = brReg.test(element.nodeName); - const elementIndent = (elementRegTest ? indent : ''); - - for (let i = 0, len = children.length, node, br, nodeRegTest; i < len; i++) { - node = children[i]; - nodeRegTest = brReg.test(node.nodeName); - br = nodeRegTest ? '\n' : ''; - lineBR = isFormatElement(node) && !elementRegTest && !/^(TH|TD)$/i.test(element.nodeName) ? '\n' : ''; - - if (node.nodeType === 8) { - returnHTML += '\n' + br; - continue; - } - if (node.nodeType === 3) { - returnHTML += util._HTMLConvertor((/^\n+$/.test(node.data) ? '' : node.data)); - continue; - } - if (node.childNodes.length === 0) { - returnHTML += (/^HR$/i.test(node.nodeName) ? '\n' : '') + elementIndent + node.outerHTML + br; - continue; - } - - node.innerHTML = node.innerHTML; - const tag = node.nodeName.toLowerCase(); - returnHTML += (lineBR || (elementRegTest ? '' : br)) + (elementIndent || nodeRegTest ? indent : '') + node.outerHTML.match(wRegExp('<' + tag + '[^>]*>', 'i'))[0] + br; - recursionFunc(node, indent + indentSize, ''); - returnHTML += (nodeRegTest ? indent : '') + '' + (lineBR || br || elementRegTest ? '\n' : false || /^(TH|TD)$/i.test(node.nodeName) ? '\n' : ''); - } - }(wDoc, '', '\n')); - - return returnHTML.trim() + '\n'; - }, - - /** - * @description Add an event to document. - * When created as an Iframe, the same event is added to the document in the Iframe. - * @param {String} type Event type - * @param {Function} listener Event listener - * @param {Boolean} useCapture Use event capture - */ - addDocEvent: function (type, listener, useCapture) { - _d.addEventListener(type, listener, useCapture); - if (options.iframe) { - this._wd.addEventListener(type, listener); - } - }, - - /** - * @description Remove events from document. -  * When created as an Iframe, the event of the document inside the Iframe is also removed. - * @param {String} type Event type - * @param {Function} listener Event listener - */ - removeDocEvent: function (type, listener) { - _d.removeEventListener(type, listener); - if (options.iframe) { - this._wd.removeEventListener(type, listener); - } - }, - - /** - * @description The current number of characters is counted and displayed. - * @param {String} inputText Text added. - * @returns {Boolean} - * @private - */ - _charCount: function (inputText) { - const maxCharCount = options.maxCharCount; - const countType = options.charCounterType; - let nextCharCount = 0; - if (!!inputText) nextCharCount = this.getCharLength(inputText, countType); - - this._setCharCount(); - - if (maxCharCount > 0) { - let over = false; - const count = functions.getCharCount(countType); - - if (count > maxCharCount) { - over = true; - if (nextCharCount > 0) { - this._editorRange(); - const range = this.getRange(); - const endOff = range.endOffset - 1; - const text = this.getSelectionNode().textContent; - const slicePosition = range.endOffset - (count - maxCharCount); - - this.getSelectionNode().textContent = text.slice(0, slicePosition < 0 ? 0 : slicePosition) + text.slice(range.endOffset, text.length); - this.setRange(range.endContainer, endOff, range.endContainer, endOff); - } - } else if ((count + nextCharCount) > maxCharCount) { - over = true; - } - - if (over) { - this._callCounterBlink(); - if (nextCharCount > 0) return false; - } - } - - return true; - }, - - /** - * @description When "element" is added, if it is greater than "options.maxCharCount", false is returned. - * @param {Node|String} element Element node or String. - * @param {String|null} charCounterType charCounterType. If it is null, the options.charCounterType - * @returns {Boolean} - */ - checkCharCount: function (element, charCounterType) { - if (options.maxCharCount) { - const countType = charCounterType || options.charCounterType; - const length = this.getCharLength((typeof element === 'string' ? element : this._charTypeHTML ? element.outerHTML : element.textContent), countType); - if (length > 0 && length + functions.getCharCount(countType) > options.maxCharCount) { - this._callCounterBlink(); - return false; - } - } - return true; - }, - - /** - * @description Get the length of the content. - * Depending on the option, the length of the character is taken. (charCounterType) - * @param {String} content Content to count - * @param {String} charCounterType options.charCounterType - * @returns {Number} - */ - getCharLength: function (content, charCounterType) { - return /byte/.test(charCounterType) ? util.getByteLength(content) : content.length; - }, - - /** - * @description Set the char count to charCounter element textContent. - * @private - */ - _setCharCount: function () { - if (context.element.charCounter) { - _w.setTimeout(function () { context.element.charCounter.textContent = functions.getCharCount(options.charCounterType); }); - } - }, - - /** - * @description The character counter blinks. - * @private - */ - _callCounterBlink: function () { - const charWrapper = context.element.charWrapper; - if (charWrapper && !util.hasClass(charWrapper, 'se-blink')) { - util.addClass(charWrapper, 'se-blink'); - _w.setTimeout(function () { - util.removeClass(charWrapper, 'se-blink'); - }, 600); - } - }, - - /** - * @description Check the components such as image and video and modify them according to the format. - * @private - */ - _checkComponents: function () { - for (let i = 0, len = this._fileInfoPluginsCheck.length; i < len; i++) { - this._fileInfoPluginsCheck[i](); - } - }, - - /** - * @description Initialize the information of the components. - * @private - */ - _resetComponents: function () { - for (let i = 0, len = this._fileInfoPluginsReset.length; i < len; i++) { - this._fileInfoPluginsReset[i](); - } - }, - - /** - * @description Set method in the code view area - * @param {String} value HTML string - * @private - */ - _setCodeView: function (value) { - if (options.codeMirrorEditor) { - options.codeMirrorEditor.getDoc().setValue(value); - } else { - context.element.code.value = value; - } - }, - - /** - * @description Get method in the code view area - * @private - */ - _getCodeView: function () { - return options.codeMirrorEditor ? options.codeMirrorEditor.getDoc().getValue() : context.element.code.value; - }, - - /** - * @description Initializ core variable - * @param {Boolean} reload Is relooad? - * @param {String} _initHTML initial html string - * @private - */ - _init: function (reload, _initHTML) { - const wRegExp = _w.RegExp; - this._ww = options.iframe ? context.element.wysiwygFrame.contentWindow : _w; - this._wd = _d; - this._charTypeHTML = options.charCounterType === 'byte-html'; - - if (!options.iframe && typeof _w.ShadowRoot === 'function') { - let child = context.element.wysiwygFrame; - while (child) { - if (child.shadowRoot) { - this._shadowRoot = child.shadowRoot; - break; - } else if (child instanceof _w.ShadowRoot) { - this._shadowRoot = child; - break; - } - child = child.parentNode; - } - if (this._shadowRoot) this._shadowRootControllerEventTarget = []; - } - - // set disallow text nodes - const disallowTextTags = _w.Object.keys(options._textTagsMap); - const allowTextTags = !options.addTagsWhitelist ? [] : options.addTagsWhitelist.split('|').filter(function (v) { return /b|i|ins|s|strike/i.test(v); }); - for (let i = 0; i < allowTextTags.length; i++) { - disallowTextTags.splice(disallowTextTags.indexOf(allowTextTags[i].toLowerCase()), 1); - } - this._disallowedTextTagsRegExp = disallowTextTags.length === 0 ? null : new wRegExp('(<\\/?)(' + disallowTextTags.join('|') + ')\\b\\s*(?:[^>^<]+)?\\s*(?=>)', 'gi'); - - // set whitelist - const defaultAttr = 'contenteditable|colspan|rowspan|target|href|download|rel|src|alt|class|type|controls|data-format|data-size|data-file-size|data-file-name|data-origin|data-align|data-image-link|data-rotate|data-proportion|data-percentage|origin-size|data-exp|data-font-size'; - this._allowHTMLComments = options._editorTagsWhitelist.indexOf('//') > -1; - this._htmlCheckWhitelistRegExp = new wRegExp('^(' + options._editorTagsWhitelist.replace('|//', '') + ')$', 'i'); - this.editorTagsWhitelistRegExp = util.createTagsWhitelist(options._editorTagsWhitelist.replace('|//', '|')); - this.pasteTagsWhitelistRegExp = util.createTagsWhitelist(options.pasteTagsWhitelist); - - const _attr = options.attributesWhitelist; - const tagsAttr = {}; - let allAttr = ''; - if (!!_attr) { - for (let k in _attr) { - if (!util.hasOwn(_attr, k)) continue; - if (k === 'all') { - allAttr = _attr[k] + '|'; - } else { - tagsAttr[k] = new wRegExp('((?:' + _attr[k] + '|' + defaultAttr + ')\s*=\s*"[^"]*")', 'ig'); - } - } - } - - this._attributesWhitelistRegExp = new wRegExp('((?:' + allAttr + defaultAttr + ')\s*=\s*"[^"]*")', 'ig'); - this._attributesTagsWhitelist = tagsAttr; - - // set modes - this._isInline = /inline/i.test(options.mode); - this._isBalloon = /balloon|balloon-always/i.test(options.mode); - this._isBalloonAlways = /balloon-always/i.test(options.mode); - - // caching buttons - this._cachingButtons(); - - // file components - this._fileInfoPluginsCheck = []; - this._fileInfoPluginsReset = []; - - // text components - this.managedTagsInfo = { query: '', map: {} }; - const managedClass = []; - - // Command and file plugins registration - this.activePlugins = []; - this._fileManager.tags = []; - this._fileManager.pluginMap = {}; - - let filePluginRegExp = []; - let plugin, button; - for (let key in plugins) { - if (!util.hasOwn(plugins, key)) continue; - plugin = plugins[key]; - button = pluginCallButtons[key]; - if (plugin.active && button) { - this.callPlugin(key, null, button); - } - if (typeof plugin.checkFileInfo === 'function' && typeof plugin.resetFileInfo === 'function') { - this.callPlugin(key, null, button); - this._fileInfoPluginsCheck.push(plugin.checkFileInfo.bind(this)); - this._fileInfoPluginsReset.push(plugin.resetFileInfo.bind(this)); - } - if (_w.Array.isArray(plugin.fileTags)) { - const fileTags = plugin.fileTags; - this.callPlugin(key, null, button); - this._fileManager.tags = this._fileManager.tags.concat(fileTags); - filePluginRegExp.push(key); - for (let tag = 0, tLen = fileTags.length; tag < tLen; tag++) { - this._fileManager.pluginMap[fileTags[tag].toLowerCase()] = key; - } - } - if (plugin.managedTags) { - const info = plugin.managedTags(); - managedClass.push('.' + info.className); - this.managedTagsInfo.map[info.className] = info.method.bind(this); - } - } - - this.managedTagsInfo.query = managedClass.toString(); - this._fileManager.queryString = this._fileManager.tags.join(','); - this._fileManager.regExp = new wRegExp('^(' + this._fileManager.tags.join('|') + ')$', 'i'); - this._fileManager.pluginRegExp = new wRegExp('^(' + (filePluginRegExp.length === 0 ? 'undefined' : filePluginRegExp.join('|')) + ')$', 'i'); - - // cache editor's element - this._variable._originCssText = context.element.topArea.style.cssText; - this._placeholder = context.element.placeholder; - this._lineBreaker = context.element.lineBreaker; - this._lineBreakerButton = this._lineBreaker.querySelector('button'); - - // Excute history function - this.history = Object(_history__WEBPACK_IMPORTED_MODULE_2__["default"])(this, this._onChange_historyStack.bind(this)); - - // register notice module - this.addModule([_plugins_modules_notice__WEBPACK_IMPORTED_MODULE_4__["default"]]); - - // Init, validate - if (options.iframe) { - this._wd = context.element.wysiwygFrame.contentDocument; - context.element.wysiwyg = this._wd.body; - if (options._editorStyles.editor) context.element.wysiwyg.style.cssText = options._editorStyles.editor; - if (options.height === 'auto') this._iframeAuto = this._wd.body; - } - - this._initWysiwygArea(reload, _initHTML); - }, - - /** - * @description Caching basic buttons to use - * @private - */ - _cachingButtons: function () { - this.codeViewDisabledButtons = context.element.toolbar.querySelectorAll('.se-toolbar button:not([class~="se-code-view-enabled"])'); - this.resizingDisabledButtons = context.element.toolbar.querySelectorAll('.se-toolbar button:not([class~="se-resizing-enabled"])'); - const tool = context.tool; - this.commandMap = { - SUB: tool.subscript, - SUP: tool.superscript, - OUTDENT: tool.outdent, - INDENT: tool.indent - }; - this.commandMap[options.textTags.bold.toUpperCase()] = tool.bold; - this.commandMap[options.textTags.underline.toUpperCase()] = tool.underline; - this.commandMap[options.textTags.italic.toUpperCase()] = tool.italic; - this.commandMap[options.textTags.strike.toUpperCase()] = tool.strike; - - this._styleCommandMap = { - fullScreen: tool.fullScreen, - showBlocks: tool.showBlocks, - codeView: tool.codeView - }; - }, - - /** - * @description Initializ wysiwyg area (Only called from core._init) - * @param {Boolean} reload Is relooad? - * @param {String} _initHTML initial html string - * @private - */ - _initWysiwygArea: function (reload, _initHTML) { - context.element.wysiwyg.innerHTML = reload ? _initHTML : this.convertContentsForEditor(typeof _initHTML === 'string' ? _initHTML : context.element.originElement.value); - }, - - /** - * @description Called when there are changes to tags in the wysiwyg region. - * @private - */ - _resourcesStateChange: function () { - this._iframeAutoHeight(); - this._checkPlaceholder(); - }, - - /** - * @description Called when after execute "history.push" - * @private - */ - _onChange_historyStack: function () { - event._applyTagEffects(); - core._variable.isChanged = true; - if (context.tool.save) context.tool.save.removeAttribute('disabled'); - if (functions.onChange) functions.onChange(this.getContents(true), this); - if (context.element.toolbar.style.display === 'block') event._showToolbarBalloon(); - }, - - /** - * @description Modify the height value of the iframe when the height of the iframe is automatic. - * @private - */ - _iframeAutoHeight: function () { - if (this._iframeAuto) { - _w.setTimeout(function () { context.element.wysiwygFrame.style.height = core._iframeAuto.offsetHeight + 'px'; }); - } - }, - - /** - * @description Set display property when there is placeholder. - * @private - */ - _checkPlaceholder: function () { - if (this._placeholder) { - if (this._variable.isCodeView) { - this._placeholder.style.display = 'none'; - return; - } - - const wysiwyg = context.element.wysiwyg; - if (!util.onlyZeroWidthSpace(wysiwyg.textContent) || wysiwyg.querySelector('.se-component, pre, blockquote, hr, li, table, img, iframe, video') || (wysiwyg.innerText.match(/\n/g) || '').length > 1) { - this._placeholder.style.display = 'none'; - } else { - this._placeholder.style.display = 'block'; - } - } - }, - - /** - * @description If there is no default format, add a format and move "selection". - * @param {String|null} formatName Format tag name (default: 'P') - * @private - */ - _setDefaultFormat: function (formatName) { - if (this._fileManager.pluginRegExp.test(this.currentControllerName)) return; - - const range = this.getRange(); - const commonCon = range.commonAncestorContainer; - const startCon = range.startContainer; - const rangeEl = util.getRangeFormatElement(commonCon, null); - let focusNode, offset, format; - - const fileComponent = util.getParentElement(commonCon, util.isComponent); - if (fileComponent && !util.isTable(fileComponent)) return; - if((util.isRangeFormatElement(startCon) || util.isWysiwygDiv(startCon)) && util.isComponent(startCon.childNodes[range.startOffset])) return; - - if (rangeEl) { - format = util.createElement(formatName || options.defaultTag); - format.innerHTML = rangeEl.innerHTML; - if (format.childNodes.length === 0) format.innerHTML = util.zeroWidthSpace; - - rangeEl.innerHTML = format.outerHTML; - format = rangeEl.firstChild; - focusNode = util.getEdgeChildNodes(format, null).sc; - - if (!focusNode) { - focusNode = util.createTextNode(util.zeroWidthSpace); - format.insertBefore(focusNode, format.firstChild); - } - - offset = focusNode.textContent.length; - this.setRange(focusNode, offset, focusNode, offset); - return; - } - - if(util.isRangeFormatElement(commonCon) && (commonCon.childNodes.length <= 1)) { - let br = null; - if (commonCon.childNodes.length === 1 && util.isBreak(commonCon.firstChild)) { - br = commonCon.firstChild; - } else { - br = util.createTextNode(util.zeroWidthSpace); - commonCon.appendChild(br); - } - - this.setRange(br, 1, br, 1); - return; - } - - this.execCommand('formatBlock', false, (formatName || options.defaultTag)); - focusNode = util.getEdgeChildNodes(commonCon, commonCon); - focusNode = focusNode ? focusNode.ec : commonCon; - - format = util.getFormatElement(focusNode, null); - if (!format) { - this.removeRange(); - this._editorRange(); - return; - } - - if (util.isBreak(format.nextSibling)) util.removeItem(format.nextSibling); - if (util.isBreak(format.previousSibling)) util.removeItem(format.previousSibling); - if (util.isBreak(focusNode)) { - const zeroWidth = util.createTextNode(util.zeroWidthSpace); - focusNode.parentNode.insertBefore(zeroWidth, focusNode); - focusNode = zeroWidth; - } - - this.effectNode = null; - this.nativeFocus(); - }, - - /** - * @description Initialization after "setOptions" - * @param {Object} el context.element - * @param {String} _initHTML Initial html string - * @private - */ - _setOptionsInit: function (el, _initHTML) { - this.context = context = Object(_context__WEBPACK_IMPORTED_MODULE_1__["default"])(el.originElement, this._getConstructed(el), options); - this._componentsInfoReset = true; - this._editorInit(true, _initHTML); - }, - - /** - * @description Initializ editor - * @param {Boolean} reload Is relooad? - * @param {String} _initHTML initial html string - * @private - */ - _editorInit: function (reload, _initHTML) { - // initialize core and add event listeners - this._init(reload, _initHTML); - event._addEvent(); - this._setCharCount(); - event._offStickyToolbar(); - event.onResize_window(); - - // toolbar visibility - context.element.toolbar.style.visibility = ''; - - this._checkComponents(); - this._componentsInfoInit = false; - this._componentsInfoReset = false; - - this.history.reset(true); - this._resourcesStateChange(); - - _w.setTimeout(function () { - if (typeof functions.onload === 'function') functions.onload(core, reload); - }); - }, - - /** - * @description Create and return an object to cache the new context. - * @param {Element} contextEl context.element - * @returns {Object} - * @private - */ - _getConstructed: function (contextEl) { - return { - _top: contextEl.topArea, - _relative: contextEl.relative, - _toolBar: contextEl.toolbar, - _menuTray: contextEl._menuTray, - _editorArea: contextEl.editorArea, - _wysiwygArea: contextEl.wysiwygFrame, - _codeArea: contextEl.code, - _placeholder: contextEl.placeholder, - _resizingBar: contextEl.resizingBar, - _navigation: contextEl.navigation, - _charCounter: contextEl.charCounter, - _charWrapper: contextEl.charWrapper, - _loading: contextEl.loading, - _lineBreaker: contextEl.lineBreaker, - _lineBreaker_t: contextEl.lineBreaker_t, - _lineBreaker_b: contextEl.lineBreaker_b, - _resizeBack: contextEl.resizeBackground, - _stickyDummy: contextEl._stickyDummy, - _arrow: contextEl._arrow - }; - } - }; - - /** - * @description event function - */ - const event = { - _IEisComposing: false, // In IE, there is no "e.isComposing" in the key-up event. - _lineBreakerBind: null, - _responsiveCurrentSize: 'default', - _responsiveButtonSize: null, - _responsiveButtons: null, - _directionKeyCode: new _w.RegExp('^(8|13|3[2-9]|40|46)$'), - _nonTextKeyCode: new _w.RegExp('^(8|13|1[6-9]|20|27|3[3-9]|40|45|46|11[2-9]|12[0-3]|144|145)$'), - _historyIgnoreKeyCode: new _w.RegExp('^(1[6-9]|20|27|3[3-9]|40|45|11[2-9]|12[0-3]|144|145)$'), - _onButtonsCheck: new _w.RegExp('^(' + _w.Object.keys(options._textTagsMap).join('|') + ')$', 'i'), - _frontZeroWidthReg: new _w.RegExp(util.zeroWidthSpace + '+', ''), - _keyCodeShortcut: { - 65: 'A', - 66: 'B', - 83: 'S', - 85: 'U', - 73: 'I', - 89: 'Y', - 90: 'Z', - 219: '[', - 221: ']' - }, - - _shortcutCommand: function (keyCode, shift) { - let command = null; - const keyStr = event._keyCodeShortcut[keyCode]; - - switch (keyStr) { - case 'A': - command = 'selectAll'; - break; - case 'B': - if (options.shortcutsDisable.indexOf('bold') === -1) { - command = 'bold'; - } - break; - case 'S': - if (shift && options.shortcutsDisable.indexOf('strike') === -1) { - command = 'strike'; - } else if (!shift && options.shortcutsDisable.indexOf('save') === -1) { - command = 'save'; - } - break; - case 'U': - if (options.shortcutsDisable.indexOf('underline') === -1) { - command = 'underline'; - } - break; - case 'I': - if (options.shortcutsDisable.indexOf('italic') === -1) { - command = 'italic'; - } - break; - case 'Z': - if (options.shortcutsDisable.indexOf('undo') === -1) { - if (shift) { - command = 'redo'; - } else { - command = 'undo'; - } - } - break; - case 'Y': - if (options.shortcutsDisable.indexOf('undo') === -1) { - command = 'redo'; - } - break; - case '[': - if (options.shortcutsDisable.indexOf('indent') === -1) { - command = options.rtl ? 'indent' : 'outdent'; - } - break; - case ']': - if (options.shortcutsDisable.indexOf('indent') === -1) { - command = options.rtl ? 'outdent' : 'indent'; - } - break; - } - - if (!command) return false; - - core.commandHandler(core.commandMap[command], command); - return true; - }, - - _applyTagEffects: function () { - let selectionNode = core.getSelectionNode(); - if (selectionNode === core.effectNode) return; - core.effectNode = selectionNode; - - const marginDir = options.rtl ? 'marginRight' : 'marginLeft'; - const commandMap = core.commandMap; - const classOnCheck = this._onButtonsCheck; - const commandMapNodes = []; - const currentNodes = []; - - const activePlugins = core.activePlugins; - const cLen = activePlugins.length; - let nodeName = ''; - - while (selectionNode.firstChild) { - selectionNode = selectionNode.firstChild; - } - - for (let element = selectionNode; !util.isWysiwygDiv(element); element = element.parentNode) { - if (!element) break; - if (element.nodeType !== 1 || util.isBreak(element)) continue; - nodeName = element.nodeName.toUpperCase(); - currentNodes.push(nodeName); - - /* Active plugins */ - for (let c = 0, name; c < cLen; c++) { - name = activePlugins[c]; - if (commandMapNodes.indexOf(name) === -1 && plugins[name].active.call(core, element)) { - commandMapNodes.push(name); - } - } - - if (util.isFormatElement(element)) { - /* Outdent */ - if (commandMapNodes.indexOf('OUTDENT') === -1 && commandMap.OUTDENT) { - if (util.isListCell(element) || (element.style[marginDir] && util.getNumber(element.style[marginDir], 0) > 0)) { - commandMapNodes.push('OUTDENT'); - commandMap.OUTDENT.removeAttribute('disabled'); - } - } - - /* Indent */ - if (commandMapNodes.indexOf('INDENT') === -1 && commandMap.INDENT && util.isListCell(element) && !element.previousElementSibling) { - commandMapNodes.push('INDENT'); - commandMap.INDENT.setAttribute('disabled', true); - } - - continue; - } - - /** default active buttons [strong, ins, em, del, sub, sup] */ - if (classOnCheck.test(nodeName)) { - commandMapNodes.push(nodeName); - util.addClass(commandMap[nodeName], 'active'); - } - } - - /** remove class, display text */ - for (let key in commandMap) { - if (commandMapNodes.indexOf(key) > -1 || !util.hasOwn(commandMap, key)) continue; - if (activePlugins.indexOf(key) > -1) { - plugins[key].active.call(core, null); - } else if (commandMap.OUTDENT && /^OUTDENT$/i.test(key)) { - commandMap.OUTDENT.setAttribute('disabled', true); - } else if (commandMap.INDENT && /^INDENT$/i.test(key)) { - commandMap.INDENT.removeAttribute('disabled'); - } else { - util.removeClass(commandMap[key], 'active'); - } - } - - /** save current nodes */ - core._variable.currentNodes = currentNodes.reverse(); - core._variable.currentNodesMap = commandMapNodes; - - /** Displays the current node structure to resizingBar */ - if (options.showPathLabel) context.element.navigation.textContent = core._variable.currentNodes.join(' > '); - }, - - _cancelCaptionEdit: function () { - this.setAttribute('contenteditable', false); - this.removeEventListener('blur', event._cancelCaptionEdit); - }, - - _buttonsEventHandler: function (e) { - let target = e.target; - if (core._bindControllersOff) e.stopPropagation(); - - if (/^(input|textarea|select|option)$/i.test(target.nodeName)) { - core._antiBlur = false; - } else { - e.preventDefault(); - } - - if (util.getParentElement(target, '.se-submenu')) { - e.stopPropagation(); - core._notHideToolbar = true; - } else { - let command = target.getAttribute('data-command'); - let className = target.className; - - while (!command && !/se-menu-list/.test(className) && !/sun-editor-common/.test(className)) { - target = target.parentNode; - command = target.getAttribute('data-command'); - className = target.className; - } - - if (command === core._submenuName || command === core._containerName) { - e.stopPropagation(); - } - } - }, - - onClick_toolbar: function (e) { - let target = e.target; - let display = target.getAttribute('data-display'); - let command = target.getAttribute('data-command'); - let className = target.className; - - while (target.parentNode && !command && !/se-menu-list/.test(className) && !/se-toolbar/.test(className)) { - target = target.parentNode; - command = target.getAttribute('data-command'); - display = target.getAttribute('data-display'); - className = target.className; - } - - if (!command && !display) return; - if (target.disabled) return; - if (!core.hasFocus) core.nativeFocus(); - if (!core._variable.isCodeView) core._editorRange(); - - core.actionCall(command, display, target); - }, - - onMouseDown_wysiwyg: function (e) { - if (util.isNonEditable(context.element.wysiwyg)) return; - - const tableCell = util.getParentElement(e.target, util.isCell); - if (tableCell) { - const tablePlugin = core.plugins.table; - if (tablePlugin && tableCell !== tablePlugin._fixedCell && !tablePlugin._shift) { - core.callPlugin('table', function () { - tablePlugin.onTableCellMultiSelect.call(core, tableCell, false); - }, null); - } - } - - if (core._isBalloon) { - event._hideToolbar(); - } - - if (/FIGURE/i.test(e.target.nodeName)) e.preventDefault(); - if (typeof functions.onMouseDown === 'function') functions.onMouseDown(e, core); - }, - - onClick_wysiwyg: function (e) { - const targetElement = e.target; - if (util.isNonEditable(context.element.wysiwyg)) return; - - const fileComponentInfo = core.getFileComponent(targetElement); - if (fileComponentInfo) { - e.preventDefault(); - core.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName); - return; - } - - const figcaption = util.getParentElement(targetElement, 'FIGCAPTION'); - if (util.isNonEditable(figcaption)) { - e.preventDefault(); - figcaption.setAttribute('contenteditable', true); - figcaption.focus(); - - if (core._isInline && !core._inlineToolbarAttr.isShow) { - event._showToolbarInline(); - - const hideToolbar = function () { - event._hideToolbar(); - figcaption.removeEventListener('blur', hideToolbar); - }; - - figcaption.addEventListener('blur', hideToolbar); - } - } - - _w.setTimeout(core._editorRange.bind(core)); - core._editorRange(); - - const selectionNode = core.getSelectionNode(); - const formatEl = util.getFormatElement(selectionNode, null); - const rangeEl = util.getRangeFormatElement(selectionNode, null); - if ((!formatEl || formatEl === rangeEl) && !util.isNonEditable(targetElement) && !util.isList(rangeEl)) { - const range = core.getRange(); - if (util.getFormatElement(range.startContainer) === util.getFormatElement(range.endContainer)) { - if (util.isList(rangeEl)) { - e.preventDefault(); - const oLi = util.createElement('LI'); - const prevLi = selectionNode.nextElementSibling; - oLi.appendChild(selectionNode); - rangeEl.insertBefore(oLi, prevLi); - core.focus(); - } else if (!util.isWysiwygDiv(selectionNode) && !util.isComponent(selectionNode) && (!util.isTable(selectionNode) || util.isCell(selectionNode))) { - e.preventDefault(); - core._setDefaultFormat(util.isRangeFormatElement(rangeEl) ? 'DIV' : options.defaultTag); - core.focus(); - } else { - event._applyTagEffects(); - } - } - } else { - event._applyTagEffects(); - } - - if (core._isBalloon) _w.setTimeout(event._toggleToolbarBalloon); - if (typeof functions.onClick === 'function') functions.onClick(e, core); - }, - - _balloonDelay: null, - _showToolbarBalloonDelay: function () { - if (event._balloonDelay) { - _w.clearTimeout(event._balloonDelay); - } - - event._balloonDelay = _w.setTimeout(function () { - _w.clearTimeout(this._balloonDelay); - this._balloonDelay = null; - this._showToolbarBalloon(); - }.bind(event), 350); - }, - - _toggleToolbarBalloon: function () { - core._editorRange(); - const range = core.getRange(); - if (core._bindControllersOff || (!core._isBalloonAlways && range.collapsed)) event._hideToolbar(); - else event._showToolbarBalloon(range); - }, - - _showToolbarBalloon: function (rangeObj) { - if (!core._isBalloon) return; - - const range = rangeObj || core.getRange(); - const toolbar = context.element.toolbar; - const topArea = context.element.topArea; - const selection = core.getSelection(); - - let isDirTop; - if (core._isBalloonAlways && range.collapsed) { - isDirTop = true; - } else if (selection.focusNode === selection.anchorNode) { - isDirTop = selection.focusOffset < selection.anchorOffset; - } else { - const childNodes = util.getListChildNodes(range.commonAncestorContainer, null); - isDirTop = util.getArrayIndex(childNodes, selection.focusNode) < util.getArrayIndex(childNodes, selection.anchorNode); - } - - let rects = range.getClientRects(); - rects = rects[isDirTop ? 0 : rects.length - 1]; - - const globalScroll = core.getGlobalScrollOffset(); - let scrollLeft = globalScroll.left; - let scrollTop = globalScroll.top; - - const editorWidth = topArea.offsetWidth; - const offsets = event._getEditorOffsets(null); - const stickyTop = offsets.top; - const editorLeft = offsets.left; - - toolbar.style.top = '-10000px'; - toolbar.style.visibility = 'hidden'; - toolbar.style.display = 'block'; - - if (!rects) { - const node = core.getSelectionNode(); - if (util.isFormatElement(node)) { - const zeroWidth = util.createTextNode(util.zeroWidthSpace); - core.insertNode(zeroWidth, null, false); - core.setRange(zeroWidth, 1, zeroWidth, 1); - core._editorRange(); - rects = core.getRange().getClientRects(); - rects = rects[isDirTop ? 0 : rects.length - 1]; - } - - if (!rects) { - const nodeOffset = util.getOffset(node, context.element.wysiwygFrame); - rects = { - left: nodeOffset.left, - top: nodeOffset.top, - right: nodeOffset.left, - bottom: nodeOffset.top + node.offsetHeight, - noText: true - }; - scrollLeft = 0; - scrollTop = 0; - } - - isDirTop = true; - } - - const arrowMargin = _w.Math.round(context.element._arrow.offsetWidth / 2); - const toolbarWidth = toolbar.offsetWidth; - const toolbarHeight = toolbar.offsetHeight; - const iframeRects = /iframe/i.test(context.element.wysiwygFrame.nodeName) ? context.element.wysiwygFrame.getClientRects()[0] : null; - if (iframeRects) { - rects = { - left: rects.left + iframeRects.left, - top: rects.top + iframeRects.top, - right: rects.right + iframeRects.right - iframeRects.width, - bottom: rects.bottom + iframeRects.bottom - iframeRects.height - }; - } - - event._setToolbarOffset(isDirTop, rects, toolbar, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop, arrowMargin); - if (toolbarWidth !== toolbar.offsetWidth || toolbarHeight !== toolbar.offsetHeight) { - event._setToolbarOffset(isDirTop, rects, toolbar, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop, arrowMargin); - } - - if (options.toolbarContainer) { - const editorParent = topArea.parentElement; - - let container = options.toolbarContainer; - let left = container.offsetLeft; - let top = container.offsetTop; - - while(!container.parentElement.contains(editorParent) || !/^(BODY|HTML)$/i.test(container.parentElement.nodeName)) { - container = container.offsetParent; - left += container.offsetLeft; - top += container.offsetTop; - } - - toolbar.style.left = (toolbar.offsetLeft - left + topArea.offsetLeft) + 'px'; - toolbar.style.top = (toolbar.offsetTop - top + topArea.offsetTop) + 'px'; - } - - toolbar.style.visibility = ''; - }, - - _setToolbarOffset: function (isDirTop, rects, toolbar, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop, arrowMargin) { - const padding = 1; - const toolbarWidth = toolbar.offsetWidth; - const toolbarHeight = rects.noText && !isDirTop ? 0 : toolbar.offsetHeight; - - const absoluteLeft = (isDirTop ? rects.left : rects.right) - editorLeft - (toolbarWidth / 2) + scrollLeft; - const overRight = absoluteLeft + toolbarWidth - editorWidth; - - let t = (isDirTop ? rects.top - toolbarHeight - arrowMargin : rects.bottom + arrowMargin) - (rects.noText ? 0 : stickyTop) + scrollTop; - let l = absoluteLeft < 0 ? padding : overRight < 0 ? absoluteLeft : absoluteLeft - overRight - padding - 1; - - let resetTop = false; - const space = t + (isDirTop ? (event._getEditorOffsets(null).top) : (toolbar.offsetHeight - context.element.wysiwyg.offsetHeight)); - if (!isDirTop && space > 0 && event._getPageBottomSpace() < space) { - isDirTop = true; - resetTop = true; - } else if (isDirTop && _d.documentElement.offsetTop > space) { - isDirTop = false; - resetTop = true; - } - - if (resetTop) t = (isDirTop ? rects.top - toolbarHeight - arrowMargin : rects.bottom + arrowMargin) - (rects.noText ? 0 : stickyTop) + scrollTop; - - toolbar.style.left = _w.Math.floor(l) + 'px'; - toolbar.style.top = _w.Math.floor(t) + 'px'; - - if (isDirTop) { - util.removeClass(context.element._arrow, 'se-arrow-up'); - util.addClass(context.element._arrow, 'se-arrow-down'); - context.element._arrow.style.top = toolbarHeight + 'px'; - } else { - util.removeClass(context.element._arrow, 'se-arrow-down'); - util.addClass(context.element._arrow, 'se-arrow-up'); - context.element._arrow.style.top = -arrowMargin + 'px'; - } - - const arrow_left = _w.Math.floor((toolbarWidth / 2) + (absoluteLeft - l)); - context.element._arrow.style.left = (arrow_left + arrowMargin > toolbar.offsetWidth ? toolbar.offsetWidth - arrowMargin : arrow_left < arrowMargin ? arrowMargin : arrow_left) + 'px'; - }, - - _showToolbarInline: function () { - if (!core._isInline) return; - - const toolbar = context.element.toolbar; - if (options.toolbarContainer) toolbar.style.position = 'relative'; - else toolbar.style.position = 'absolute'; - - toolbar.style.visibility = 'hidden'; - toolbar.style.display = 'block'; - core._inlineToolbarAttr.width = toolbar.style.width = options.toolbarWidth; - core._inlineToolbarAttr.top = toolbar.style.top = (options.toolbarContainer ? 0 : (-1 - toolbar.offsetHeight)) + 'px'; - - if (typeof functions.showInline === 'function') functions.showInline(toolbar, context, core); - - event.onScroll_window(); - core._inlineToolbarAttr.isShow = true; - toolbar.style.visibility = ''; - }, - - _hideToolbar: function () { - if (!core._notHideToolbar && !core._variable.isFullScreen) { - context.element.toolbar.style.display = 'none'; - core._inlineToolbarAttr.isShow = false; - } - }, - - onInput_wysiwyg: function (e) { - core._editorRange(); - - const data = (e.data === null ? '' : e.data === undefined ? ' ' : e.data) || ''; - if (!core._charCount(data)) { - e.preventDefault(); - e.stopPropagation(); - } - - // history stack - core.history.push(true); - - if (typeof functions.onInput === 'function') functions.onInput(e, core); - }, - - _isUneditableNode: function (range, isFront) { - const container = isFront ? range.startContainer : range.endContainer; - const offset = isFront ? range.startOffset : range.endOffset; - const siblingKey = isFront ? 'previousSibling' : 'nextSibling'; - const isElement = container.nodeType === 1; - let siblingNode; - - if (isElement) { - siblingNode = event._isUneditableNode_getSibling(container.childNodes[offset], siblingKey, container); - return siblingNode && siblingNode.nodeType === 1 && siblingNode.getAttribute('contenteditable') === 'false'; - } else { - siblingNode = event._isUneditableNode_getSibling(container, siblingKey, container); - return core.isEdgePoint(container, offset, isFront ? 'front' : 'end') && (siblingNode && siblingNode.nodeType === 1 && siblingNode.getAttribute('contenteditable') === 'false'); - } - }, - - _isUneditableNode_getSibling: function (selectNode, siblingKey, container) { - if (!selectNode) return null; - let siblingNode = selectNode[siblingKey]; - - if (!siblingNode) { - siblingNode = util.getFormatElement(container); - siblingNode = siblingNode ? siblingNode[siblingKey] : null; - if (siblingNode && !util.isComponent(siblingNode)) siblingNode = siblingKey === 'previousSibling' ? siblingNode.firstElementChild : siblingNode.lastElementChild; - else return null; - } - - return siblingNode; - }, - - _onShortcutKey: false, - onKeyDown_wysiwyg: function (e) { - const keyCode = e.keyCode; - const shift = e.shiftKey; - const ctrl = e.ctrlKey || e.metaKey || keyCode === 91 || keyCode === 92 || keyCode === 224; - const alt = e.altKey; - event._IEisComposing = keyCode === 229; - - core.submenuOff(); - - if (core._isBalloon) { - event._hideToolbar(); - } - - /** Shortcuts */ - if (ctrl && event._shortcutCommand(keyCode, shift)) { - event._onShortcutKey = true; - e.preventDefault(); - e.stopPropagation(); - return false; - } else if (event._onShortcutKey) { - event._onShortcutKey = false; - } - - /** default key action */ - let selectionNode = core.getSelectionNode(); - const range = core.getRange(); - const selectRange = !range.collapsed || range.startContainer !== range.endContainer; - const fileComponentName = core._fileManager.pluginRegExp.test(core.currentControllerName) ? core.currentControllerName : ''; - let formatEl = util.getFormatElement(selectionNode, null) || selectionNode; - let rangeEl = util.getRangeFormatElement(formatEl, null); - - switch (keyCode) { - case 8: /** backspace key */ - if (!selectRange) { - if (fileComponentName) { - e.preventDefault(); - e.stopPropagation(); - core.plugins[fileComponentName].destroy.call(core); - break; - } - } - - if (selectRange && event._hardDelete()) { - e.preventDefault(); - e.stopPropagation(); - break; - } - - if (!util.isFormatElement(formatEl) && !context.element.wysiwyg.firstElementChild && !util.isComponent(selectionNode)) { - e.preventDefault(); - e.stopPropagation(); - core._setDefaultFormat(options.defaultTag); - return false; - } - - if (!selectRange && !formatEl.previousElementSibling && (range.startOffset === 0 && !selectionNode.previousSibling && !util.isListCell(formatEl) && - (util.isFormatElement(formatEl) && (!util.isFreeFormatElement(formatEl) || util.isClosureFreeFormatElement(formatEl))))) { - // closure range - if (util.isClosureRangeFormatElement(formatEl.parentNode)) { - e.preventDefault(); - e.stopPropagation(); - return false; - } - // maintain default format - if (util.isWysiwygDiv(formatEl.parentNode) && formatEl.childNodes.length <= 1 && (!formatEl.firstChild || util.onlyZeroWidthSpace(formatEl.textContent))) { - e.preventDefault(); - e.stopPropagation(); - - if (formatEl.nodeName.toUpperCase() === options.defaultTag.toUpperCase()) { - formatEl.innerHTML = '
'; - const attrs = formatEl.attributes; - while (attrs[0]) { - formatEl.removeAttribute(attrs[0].name); - } - } else { - const defaultFormat = util.createElement(options.defaultTag); - defaultFormat.innerHTML = '
'; - formatEl.parentElement.replaceChild(defaultFormat, formatEl); - } - - core.nativeFocus(); - return false; - } - } - - // clean remove tag - if (formatEl && range.startContainer === range.endContainer && selectionNode.nodeType === 3 && !util.isFormatElement(selectionNode.parentNode)) { - if (range.collapsed ? selectionNode.textContent.length === 1 : (range.endOffset - range.startOffset) === selectionNode.textContent.length) { - e.preventDefault(); - - let offset = null; - let prev = selectionNode.parentNode.previousSibling; - const next = selectionNode.parentNode.nextSibling; - if (!prev) { - if (!next) { - prev = util.createElement('BR'); - formatEl.appendChild(prev); - } else { - prev = next; - offset = 0; - } - } - - selectionNode.textContent = ''; - util.removeItemAllParents(selectionNode, null, formatEl); - offset = typeof offset === 'number' ? offset : prev.nodeType === 3 ? prev.textContent.length : 1; - core.setRange(prev, offset, prev, offset); - break; - } - } - - // tag[contenteditable="false"] - if (event._isUneditableNode(range, true)) { - e.preventDefault(); - e.stopPropagation(); - break; - } - - // nested list - const commonCon = range.commonAncestorContainer; - formatEl = util.getFormatElement(range.startContainer, null); - rangeEl = util.getRangeFormatElement(formatEl, null); - if (rangeEl && formatEl && !util.isCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) { - if (util.isListCell(formatEl) && util.isList(rangeEl) && (util.isListCell(rangeEl.parentNode) || formatEl.previousElementSibling) && (selectionNode === formatEl || (selectionNode.nodeType === 3 && (!selectionNode.previousSibling || util.isList(selectionNode.previousSibling)))) && - (util.getFormatElement(range.startContainer, null) !== util.getFormatElement(range.endContainer, null) ? rangeEl.contains(range.startContainer) : (range.startOffset === 0 && range.collapsed))) { - if (range.startContainer !== range.endContainer) { - e.preventDefault(); - - core.removeNode(); - if (range.startContainer.nodeType === 3) { - core.setRange(range.startContainer, range.startContainer.textContent.length, range.startContainer, range.startContainer.textContent.length); - } - // history stack - core.history.push(true); - } else { - let prev = formatEl.previousElementSibling || rangeEl.parentNode; - if (util.isListCell(prev)) { - e.preventDefault(); - - let prevLast = prev; - if (!prev.contains(formatEl) && util.isListCell(prevLast) && util.isList(prevLast.lastElementChild)) { - prevLast = prevLast.lastElementChild.lastElementChild; - while (util.isListCell(prevLast) && util.isList(prevLast.lastElementChild)) { - prevLast = prevLast.lastElementChild && prevLast.lastElementChild.lastElementChild; - } - prev = prevLast; - } - - let con = prev === rangeEl.parentNode ? rangeEl.previousSibling : prev.lastChild; - if (!con) { - con = util.createTextNode(util.zeroWidthSpace); - rangeEl.parentNode.insertBefore(con, rangeEl.parentNode.firstChild); - } - const offset = con.nodeType === 3 ? con.textContent.length : 1; - const children = formatEl.childNodes; - let after = con; - let child = children[0]; - while ((child = children[0])) { - prev.insertBefore(child, after.nextSibling); - after = child; - } - - util.removeItem(formatEl); - if (rangeEl.children.length === 0) util.removeItem(rangeEl); - - core.setRange(con, offset, con, offset); - // history stack - core.history.push(true); - } - } - - break; - } - - // detach range - if (!selectRange && range.startOffset === 0) { - let detach = true; - let comm = commonCon; - while (comm && comm !== rangeEl && !util.isWysiwygDiv(comm)) { - if (comm.previousSibling) { - if (comm.previousSibling.nodeType === 1 || !util.onlyZeroWidthSpace(comm.previousSibling.textContent.trim())) { - detach = false; - break; - } - } - comm = comm.parentNode; - } - - if (detach && rangeEl.parentNode) { - e.preventDefault(); - core.detachRangeFormatElement(rangeEl, (util.isListCell(formatEl) ? [formatEl] : null), null, false, false); - // history stack - core.history.push(true); - break; - } - } - } - - // component - if (!selectRange && formatEl && (range.startOffset === 0 || (selectionNode === formatEl ? !!formatEl.childNodes[range.startOffset] : false))) { - const sel = selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : selectionNode; - const prev = formatEl.previousSibling; - // select file component - const ignoreZWS = (commonCon.nodeType === 3 || util.isBreak(commonCon)) && !commonCon.previousSibling && range.startOffset === 0; - if (!sel.previousSibling && (util.isComponent(commonCon.previousSibling) || (ignoreZWS && util.isComponent(prev)))) { - const fileComponentInfo = core.getFileComponent(prev); - if (fileComponentInfo) { - e.preventDefault(); - e.stopPropagation(); - if (formatEl.textContent.length === 0) util.removeItem(formatEl); - if (core.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName) === false) core.blur(); - } else if (util.isComponent(prev)) { - e.preventDefault(); - e.stopPropagation(); - util.removeItem(prev); - } - break; - } - // delete nonEditable - if (util.isNonEditable(sel.previousSibling)) { - e.preventDefault(); - e.stopPropagation(); - util.removeItem(sel.previousSibling); - break; - } - } - - break; - case 46: /** delete key */ - if (fileComponentName) { - e.preventDefault(); - e.stopPropagation(); - core.plugins[fileComponentName].destroy.call(core); - break; - } - - if (selectRange && event._hardDelete()) { - e.preventDefault(); - e.stopPropagation(); - break; - } - - // tag[contenteditable="false"] - if (event._isUneditableNode(range, false)) { - e.preventDefault(); - e.stopPropagation(); - break; - } - - // component - if ((util.isFormatElement(selectionNode) || selectionNode.nextSibling === null || (util.onlyZeroWidthSpace(selectionNode.nextSibling) && selectionNode.nextSibling.nextSibling === null)) && range.startOffset === selectionNode.textContent.length) { - let nextEl = formatEl.nextElementSibling; - if (!nextEl) { - e.preventDefault(); - break; - } - - if (util.isComponent(nextEl)) { - e.preventDefault(); - - if (util.onlyZeroWidthSpace(formatEl)) { - util.removeItem(formatEl); - // table component - if (util.isTable(nextEl)) { - let cell = util.getChildElement(nextEl, util.isCell, false); - cell = cell.firstElementChild || cell; - core.setRange(cell, 0, cell, 0); - break; - } - } - - // select file component - const fileComponentInfo = core.getFileComponent(nextEl); - if (fileComponentInfo) { - e.stopPropagation(); - if (core.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName) === false) core.blur(); - } else if (util.isComponent(nextEl)) { - e.stopPropagation(); - util.removeItem(nextEl); - } - - break; - } - } - - if (!selectRange && (core.isEdgePoint(range.endContainer, range.endOffset) || (selectionNode === formatEl ? !!formatEl.childNodes[range.startOffset] : false))) { - const sel = selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : selectionNode; - // delete nonEditable - if (util.isNonEditable(sel.nextSibling)) { - e.preventDefault(); - e.stopPropagation(); - util.removeItem(sel.nextSibling); - break; - } - } - - // nested list - formatEl = util.getFormatElement(range.startContainer, null); - rangeEl = util.getRangeFormatElement(formatEl, null); - if (util.isListCell(formatEl) && util.isList(rangeEl) && (selectionNode === formatEl || (selectionNode.nodeType === 3 && (!selectionNode.nextSibling || util.isList(selectionNode.nextSibling)) && - (util.getFormatElement(range.startContainer, null) !== util.getFormatElement(range.endContainer, null) ? rangeEl.contains(range.endContainer) : (range.endOffset === selectionNode.textContent.length && range.collapsed))))) { - if (range.startContainer !== range.endContainer) core.removeNode(); - - let next = util.getArrayItem(formatEl.children, util.isList, false); - next = next || formatEl.nextElementSibling || rangeEl.parentNode.nextElementSibling; - if (next && (util.isList(next) || util.getArrayItem(next.children, util.isList, false))) { - e.preventDefault(); - - let con, children; - if (util.isList(next)) { - const child = next.firstElementChild; - children = child.childNodes; - con = children[0]; - while (children[0]) { - formatEl.insertBefore(children[0], next); - } - util.removeItem(child); - } else { - con = next.firstChild; - children = next.childNodes; - while (children[0]) { - formatEl.appendChild(children[0]); - } - util.removeItem(next); - } - core.setRange(con, 0, con, 0); - // history stack - core.history.push(true); - } - break; - } - - break; - case 9: /** tab key */ - if (fileComponentName || options.tabDisable) break; - e.preventDefault(); - if (ctrl || alt || util.isWysiwygDiv(selectionNode)) break; - - const isEdge = (!range.collapsed || core.isEdgePoint(range.startContainer, range.startOffset)); - const selectedFormats = core.getSelectedElements(null); - selectionNode = core.getSelectionNode(); - const cells = []; - let lines = []; - let fc = util.isListCell(selectedFormats[0]), lc = util.isListCell(selectedFormats[selectedFormats.length - 1]); - let r = {sc: range.startContainer, so: range.startOffset, ec: range.endContainer, eo: range.endOffset}; - for (let i = 0, len = selectedFormats.length, f; i < len; i++) { - f = selectedFormats[i]; - if (util.isListCell(f)) { - if (!f.previousElementSibling && !shift) { - continue; - } else { - cells.push(f); - } - } else { - lines.push(f); - } - } - - // Nested list - if (cells.length > 0 && isEdge && core.plugins.list) { - r = core.plugins.list.editInsideList.call(core, shift, cells); - } else { - // table - const tableCell = util.getParentElement(selectionNode, util.isCell); - if (tableCell && isEdge) { - const table = util.getParentElement(tableCell, 'table'); - const cells = util.getListChildren(table, util.isCell); - let idx = shift ? util.prevIdx(cells, tableCell) : util.nextIdx(cells, tableCell); - - if (idx === cells.length && !shift) idx = 0; - if (idx === -1 && shift) idx = cells.length - 1; - - let moveCell = cells[idx]; - if (!moveCell) break; - moveCell = moveCell.firstElementChild || moveCell; - core.setRange(moveCell, 0, moveCell, 0); - break; - } - - lines = lines.concat(cells); - fc = lc = null; - } - - // Lines tab(4) - if (lines.length > 0) { - if (!shift) { - const tabText = util.createTextNode(new _w.Array(core._variable.tabSize + 1).join('\u00A0')); - if (lines.length === 1) { - const textRange = core.insertNode(tabText, null, true); - if (!textRange) return false; - if (!fc) { - r.sc = tabText; - r.so = textRange.endOffset; - } - if (!lc) { - r.ec = tabText; - r.eo = textRange.endOffset; - } - } else { - const len = lines.length - 1; - for (let i = 0, child; i <= len; i++) { - child = lines[i].firstChild; - if (!child) continue; - - if (util.isBreak(child)) { - lines[i].insertBefore(tabText.cloneNode(false), child); - } else { - child.textContent = tabText.textContent + child.textContent; - } - } - - const firstChild = util.getChildElement(lines[0], 'text', false); - const endChild = util.getChildElement(lines[len], 'text', true); - if (!fc && firstChild) { - r.sc = firstChild; - r.so = 0; - } - if (!lc && endChild) { - r.ec = endChild; - r.eo = endChild.textContent.length; - } - } - } else { - const len = lines.length - 1; - for (let i = 0, line; i <= len; i++) { - line = lines[i].childNodes; - for (let c = 0, cLen = line.length, child; c < cLen; c++) { - child = line[c]; - if (!child) break; - if (util.onlyZeroWidthSpace(child)) continue; - - if (/^\s{1,4}$/.test(child.textContent)) { - util.removeItem(child); - } else if (/^\s{1,4}/.test(child.textContent)) { - child.textContent = child.textContent.replace(/^\s{1,4}/, ''); - } - - break; - } - } - - const firstChild = util.getChildElement(lines[0], 'text', false); - const endChild = util.getChildElement(lines[len], 'text', true); - if (!fc && firstChild) { - r.sc = firstChild; - r.so = 0; - } - if (!lc && endChild) { - r.ec = endChild; - r.eo = endChild.textContent.length; - } - } - } - - core.setRange(r.sc, r.so, r.ec, r.eo); - // history stack - core.history.push(false); - - break; - case 13: /** enter key */ - const freeFormatEl = util.getFreeFormatElement(selectionNode, null); - - if (core._charTypeHTML) { - let enterHTML = ''; - if ((!shift && freeFormatEl) || shift) { - enterHTML = '
'; - } else { - enterHTML = '<' + formatEl.nodeName + '>
'; - } - - if (!core.checkCharCount(enterHTML, 'byte-html')) { - e.preventDefault(); - return false; - } - } - - if (!shift && /^H[1-6]$/i.test(formatEl.nodeName) && core.isEdgeFormat(range.endContainer, range.endOffset, 'end')) { - e.preventDefault(); - const newFormat = core.appendFormatTag(formatEl, options.defaultTag); - core.setRange(newFormat, 1, newFormat, 1); - break; - } - - if (!shift && freeFormatEl) { - e.preventDefault(); - const selectionFormat = selectionNode === freeFormatEl; - const wSelection = core.getSelection(); - const children = selectionNode.childNodes, offset = wSelection.focusOffset, prev = selectionNode.previousElementSibling, next = selectionNode.nextSibling; - - if (!util.isClosureFreeFormatElement(freeFormatEl) && !!children && ((selectionFormat && range.collapsed && children.length - 1 <= offset + 1 && util.isBreak(children[offset]) && (!children[offset + 1] || ((!children[offset + 2] || util.onlyZeroWidthSpace(children[offset + 2].textContent)) && children[offset + 1].nodeType === 3 && util.onlyZeroWidthSpace(children[offset + 1].textContent))) && offset > 0 && util.isBreak(children[offset - 1])) || - (!selectionFormat && util.onlyZeroWidthSpace(selectionNode.textContent) && util.isBreak(prev) && (util.isBreak(prev.previousSibling) || !util.onlyZeroWidthSpace(prev.previousSibling.textContent)) && (!next || (!util.isBreak(next) && util.onlyZeroWidthSpace(next.textContent)))))) { - if (selectionFormat) util.removeItem(children[offset - 1]); - else util.removeItem(selectionNode); - const newEl = core.appendFormatTag(freeFormatEl, util.isFormatElement(freeFormatEl.nextElementSibling) ? freeFormatEl.nextElementSibling : null); - util.copyFormatAttributes(newEl, freeFormatEl); - core.setRange(newEl, 1, newEl, 1); - break; - } - - if (selectionFormat) { - functions.insertHTML(((range.collapsed && util.isBreak(range.startContainer.childNodes[range.startOffset - 1])) ? '
' : '

'), true, false); - - let focusNode = wSelection.focusNode; - const wOffset = wSelection.focusOffset; - if (freeFormatEl === focusNode) { - focusNode = focusNode.childNodes[wOffset - offset > 1 ? wOffset - 1 : wOffset]; - } - - core.setRange(focusNode, 1, focusNode, 1); - } else { - const focusNext = wSelection.focusNode.nextSibling; - const br = util.createElement('BR'); - core.insertNode(br, null, false); - - const brPrev = br.previousSibling, brNext = br.nextSibling; - if (!util.isBreak(focusNext) && !util.isBreak(brPrev) && (!brNext || util.onlyZeroWidthSpace(brNext))) { - br.parentNode.insertBefore(br.cloneNode(false), br); - core.setRange(br, 1, br, 1); - } else { - core.setRange(brNext, 0, brNext, 0); - } - } - - event._onShortcutKey = true; - break; - } - - if (selectRange) break; - - if (rangeEl && formatEl && !util.isCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) { - const range = core.getRange(); - if(core.isEdgePoint(range.endContainer, range.endOffset) && util.isList(selectionNode.nextSibling)) { - e.preventDefault(); - const newEl = util.createElement('LI'); - const br = util.createElement('BR'); - newEl.appendChild(br); - - formatEl.parentNode.insertBefore(newEl, formatEl.nextElementSibling); - newEl.appendChild(selectionNode.nextSibling); - - core.setRange(br, 1, br, 1); - break; - } - - if ((range.commonAncestorContainer.nodeType === 3 ? !range.commonAncestorContainer.nextElementSibling : true) && util.onlyZeroWidthSpace(formatEl.innerText.trim())) { - e.preventDefault(); - let newEl = null; - - if (util.isListCell(rangeEl.parentNode)) { - rangeEl = formatEl.parentNode.parentNode.parentNode; - newEl = util.splitElement(formatEl, null, util.getElementDepth(formatEl) - 2); - if (!newEl) { - const newListCell = util.createElement('LI'); - newListCell.innerHTML = '
'; - rangeEl.insertBefore(newListCell, newEl); - newEl = newListCell; - } - } else { - const newFormat = util.isCell(rangeEl.parentNode) ? 'DIV' : util.isList(rangeEl.parentNode) ? 'LI' : util.isFormatElement(rangeEl.nextElementSibling) ? rangeEl.nextElementSibling.nodeName : util.isFormatElement(rangeEl.previousElementSibling) ? rangeEl.previousElementSibling.nodeName : options.defaultTag; - newEl = util.createElement(newFormat); - const edge = core.detachRangeFormatElement(rangeEl, [formatEl], null, true, true); - edge.cc.insertBefore(newEl, edge.ec); - } - - newEl.innerHTML = '
'; - util.copyFormatAttributes(newEl, formatEl); - util.removeItemAllParents(formatEl, null, null); - core.setRange(newEl, 1, newEl, 1); - break; - } - } - - if (rangeEl && util.getParentElement(rangeEl, 'FIGCAPTION') && util.getParentElement(rangeEl, util.isList)) { - e.preventDefault(); - formatEl = core.appendFormatTag(formatEl, null); - core.setRange(formatEl, 0, formatEl, 0); - } - - if (fileComponentName) { - e.preventDefault(); - e.stopPropagation(); - const compContext = context[fileComponentName]; - const container = compContext._container; - const sibling = container.previousElementSibling || container.nextElementSibling; - - let newEl = null; - if (util.isListCell(container.parentNode)) { - newEl = util.createElement('BR'); - } else { - newEl = util.createElement(util.isFormatElement(sibling) ? sibling.nodeName : options.defaultTag); - newEl.innerHTML = '
'; - } - - container.parentNode.insertBefore(newEl, container); - - core.callPlugin(fileComponentName, function () { - if (core.selectComponent(compContext._element, fileComponentName) === false) core.blur(); - }, null); - } - - break; - case 27: - if (fileComponentName) { - e.preventDefault(); - e.stopPropagation(); - core.controllersOff(); - return false; - } - break; - } - - if (shift && keyCode === 16) { - e.preventDefault(); - e.stopPropagation(); - const tablePlugin = core.plugins.table; - if (tablePlugin && !tablePlugin._shift && !tablePlugin._ref) { - const cell = util.getParentElement(formatEl, util.isCell); - if (cell) { - tablePlugin.onTableCellMultiSelect.call(core, cell, true); - return; - } - } - } else if (shift && (util.isOSX_IOS ? alt : ctrl) && keyCode === 32) { - e.preventDefault(); - e.stopPropagation(); - const nbsp = core.insertNode(util.createTextNode('\u00a0')); - if (nbsp && nbsp.container) { - core.setRange(nbsp.container, nbsp.endOffset, nbsp.container, nbsp.endOffset); - return; - } - } - - const textKey = !ctrl && !alt && !selectRange && !event._nonTextKeyCode.test(keyCode); - if (textKey && range.collapsed && range.startContainer === range.endContainer && util.isBreak(range.commonAncestorContainer)) { - const zeroWidth = util.createTextNode(util.zeroWidthSpace); - core.insertNode(zeroWidth, null, false); - core.setRange(zeroWidth, 1, zeroWidth, 1); - } - - if (typeof functions.onKeyDown === 'function') functions.onKeyDown(e, core); - }, - - onKeyUp_wysiwyg: function (e) { - if (event._onShortcutKey) return; - core._editorRange(); - - const range = core.getRange(); - const keyCode = e.keyCode; - const ctrl = e.ctrlKey || e.metaKey || keyCode === 91 || keyCode === 92 || keyCode === 224; - const alt = e.altKey; - let selectionNode = core.getSelectionNode(); - - if (core._isBalloon && ((core._isBalloonAlways && keyCode !== 27) || !range.collapsed)) { - if (core._isBalloonAlways) { - if (keyCode !== 27) event._showToolbarBalloonDelay(); - } else { - event._showToolbarBalloon(); - return; - } - } - - /** when format tag deleted */ - if (keyCode === 8 && util.isWysiwygDiv(selectionNode) && selectionNode.textContent === '' && selectionNode.children.length === 0) { - e.preventDefault(); - e.stopPropagation(); - - selectionNode.innerHTML = ''; - - const oFormatTag = util.createElement(util.isFormatElement(core._variable.currentNodes[0]) ? core._variable.currentNodes[0] : options.defaultTag); - oFormatTag.innerHTML = '
'; - - selectionNode.appendChild(oFormatTag); - core.setRange(oFormatTag, 0, oFormatTag, 0); - event._applyTagEffects(); - - core.history.push(false); - return; - } - - const formatEl = util.getFormatElement(selectionNode, null); - const rangeEl = util.getRangeFormatElement(selectionNode, null); - if (((!formatEl && range.collapsed) || formatEl === rangeEl) && !util.isComponent(selectionNode) && !util.isList(selectionNode)) { - core._setDefaultFormat(util.isRangeFormatElement(rangeEl) ? 'DIV' : options.defaultTag); - selectionNode = core.getSelectionNode(); - } - - if (event._directionKeyCode.test(keyCode)) { - event._applyTagEffects(); - } - - const textKey = !ctrl && !alt && !event._nonTextKeyCode.test(keyCode); - if (textKey && selectionNode.nodeType === 3 && util.zeroWidthRegExp.test(selectionNode.textContent) && !(e.isComposing !== undefined ? e.isComposing : event._IEisComposing)) { - let so = range.startOffset, eo = range.endOffset; - const frontZeroWidthCnt = (selectionNode.textContent.substring(0, eo).match(event._frontZeroWidthReg) || '').length; - so = range.startOffset - frontZeroWidthCnt; - eo = range.endOffset - frontZeroWidthCnt; - selectionNode.textContent = selectionNode.textContent.replace(util.zeroWidthRegExp, ''); - core.setRange(selectionNode, so < 0 ? 0 : so, selectionNode, eo < 0 ? 0 : eo); - } - - core._charCount(''); - - // history stack - core.history.push(true); - - if (typeof functions.onKeyUp === 'function') functions.onKeyUp(e, core); - }, - - onScroll_wysiwyg: function (e) { - core.controllersOff(); - if (core._isBalloon) event._hideToolbar(); - if (typeof functions.onScroll === 'function') functions.onScroll(e, core); - }, - - onFocus_wysiwyg: function (e) { - if (core._antiBlur) return; - core.hasFocus = true; - if (core._isInline) event._showToolbarInline(); - if (typeof functions.onFocus === 'function') functions.onFocus(e, core); - }, - - onBlur_wysiwyg: function (e) { - if (core._antiBlur || core._variable.isCodeView) return; - core.hasFocus = false; - core.controllersOff(); - if (core._isInline || core._isBalloon) event._hideToolbar(); - if (typeof functions.onBlur === 'function') functions.onBlur(e, core); - - // active class reset of buttons - const commandMap = core.commandMap; - const activePlugins = core.activePlugins; - for (let key in commandMap) { - if (!util.hasOwn(commandMap, key)) continue; - if (activePlugins.indexOf(key) > -1) { - plugins[key].active.call(core, null); - } else if (commandMap.OUTDENT && /^OUTDENT$/i.test(key)) { - commandMap.OUTDENT.setAttribute('disabled', true); - } else if (commandMap.INDENT && /^INDENT$/i.test(key)) { - commandMap.INDENT.removeAttribute('disabled'); - } else { - util.removeClass(commandMap[key], 'active'); - } - } - - core._variable.currentNodes = []; - core._variable.currentNodesMap = []; - if (options.showPathLabel) context.element.navigation.textContent = ''; - }, - - onMouseDown_resizingBar: function (e) { - e.stopPropagation(); - - core.submenuOff(); - core.controllersOff(); - - core._variable.resizeClientY = e.clientY; - context.element.resizeBackground.style.display = 'block'; - - function closureFunc() { - context.element.resizeBackground.style.display = 'none'; - _d.removeEventListener('mousemove', event._resize_editor); - _d.removeEventListener('mouseup', closureFunc); - } - - _d.addEventListener('mousemove', event._resize_editor); - _d.addEventListener('mouseup', closureFunc); - }, - - _resize_editor: function (e) { - const resizeInterval = context.element.editorArea.offsetHeight + (e.clientY - core._variable.resizeClientY); - context.element.wysiwygFrame.style.height = context.element.code.style.height = (resizeInterval < core._variable.minResizingSize ? core._variable.minResizingSize : resizeInterval) + 'px'; - core._variable.resizeClientY = e.clientY; - }, - - onResize_window: function () { - core.controllersOff(); - - const responsiveSize = event._responsiveButtonSize; - if (responsiveSize) { - let w = 0; - if ((core._isBalloon || core._isInline) && options.toolbarWidth === 'auto') { - w = context.element.topArea.offsetWidth; - } else { - w = context.element.toolbar.offsetWidth; - } - - let responsiveWidth = 'default'; - for (let i = 1, len = responsiveSize.length; i < len; i++) { - if (w < responsiveSize[i]) { - responsiveWidth = responsiveSize[i] + ''; - break; - } - } - - if (event._responsiveCurrentSize !== responsiveWidth) { - event._responsiveCurrentSize = responsiveWidth; - functions.setToolbarButtons(event._responsiveButtons[responsiveWidth]); - } - } - - if (context.element.toolbar.offsetWidth === 0) return; - - if (context.fileBrowser && context.fileBrowser.area.style.display === 'block') { - context.fileBrowser.body.style.maxHeight = (_w.innerHeight - context.fileBrowser.header.offsetHeight - 50) + 'px'; - } - - if (core.submenuActiveButton && core.submenu) { - core._setMenuPosition(core.submenuActiveButton, core.submenu); - } - - if (core._variable.isFullScreen) { - core._variable.innerHeight_fullScreen += (_w.innerHeight - context.element.toolbar.offsetHeight) - core._variable.innerHeight_fullScreen; - context.element.editorArea.style.height = core._variable.innerHeight_fullScreen + 'px'; - return; - } - - if (core._variable.isCodeView && core._isInline) { - event._showToolbarInline(); - return; - } - - core._iframeAutoHeight(); - - if (core._sticky) { - context.element.toolbar.style.width = (context.element.topArea.offsetWidth - 2) + 'px'; - event.onScroll_window(); - } - }, - - onScroll_window: function () { - if (core._variable.isFullScreen || context.element.toolbar.offsetWidth === 0 || options.stickyToolbar < 0) return; - - const element = context.element; - const editorHeight = element.editorArea.offsetHeight; - const y = (this.scrollY || _d.documentElement.scrollTop) + options.stickyToolbar; - const editorTop = event._getEditorOffsets(options.toolbarContainer).top - (core._isInline ? element.toolbar.offsetHeight : 0); - - if (y < editorTop) { - event._offStickyToolbar(); - } - else if (y + core._variable.minResizingSize >= editorHeight + editorTop) { - if (!core._sticky) event._onStickyToolbar(); - element.toolbar.style.top = (editorHeight + editorTop + options.stickyToolbar -y - core._variable.minResizingSize) + 'px'; - } - else if (y >= editorTop) { - event._onStickyToolbar(); - } - }, - - _getEditorOffsets: function (container) { - let offsetEl = container || context.element.topArea; - let t = 0, l = 0, s = 0; - - while (offsetEl) { - t += offsetEl.offsetTop; - l += offsetEl.offsetLeft; - s += offsetEl.scrollTop; - offsetEl = offsetEl.offsetParent; - } - - return { - top: t, - left: l, - scroll: s - }; - }, - - _getPageBottomSpace: function () { - return _d.documentElement.scrollHeight - (event._getEditorOffsets(null).top + context.element.topArea.offsetHeight); - }, - - _onStickyToolbar: function () { - const element = context.element; - - if (!core._isInline && !options.toolbarContainer) { - element._stickyDummy.style.height = element.toolbar.offsetHeight + 'px'; - element._stickyDummy.style.display = 'block'; - } - - element.toolbar.style.top = options.stickyToolbar + 'px'; - element.toolbar.style.width = core._isInline ? core._inlineToolbarAttr.width : element.toolbar.offsetWidth + 'px'; - util.addClass(element.toolbar, 'se-toolbar-sticky'); - core._sticky = true; - }, - - _offStickyToolbar: function () { - const element = context.element; - - element._stickyDummy.style.display = 'none'; - element.toolbar.style.top = core._isInline ? core._inlineToolbarAttr.top : ''; - element.toolbar.style.width = core._isInline ? core._inlineToolbarAttr.width : ''; - element.editorArea.style.marginTop = ''; - - util.removeClass(element.toolbar, 'se-toolbar-sticky'); - core._sticky = false; - }, - - _codeViewAutoHeight: function () { - context.element.code.style.height = context.element.code.scrollHeight + 'px'; - }, - - // FireFox - table delete, Chrome - image, video, audio - _hardDelete: function () { - const range = core.getRange(); - const sc = range.startContainer; - const ec = range.endContainer; - - // table - const sCell = util.getRangeFormatElement(sc); - const eCell = util.getRangeFormatElement(ec); - const sIsCell = util.isCell(sCell); - const eIsCell = util.isCell(eCell); - if (((sIsCell && !sCell.previousElementSibling && !sCell.parentElement.previousElementSibling) || (eIsCell && !eCell.nextElementSibling && !eCell.parentElement.nextElementSibling)) && sCell !== eCell) { - if (!sIsCell) { - util.removeItem(util.getParentElement(eCell, util.isComponent)); - } else if (!eIsCell) { - util.removeItem(util.getParentElement(sCell, util.isComponent)); - } else { - util.removeItem(util.getParentElement(sCell, util.isComponent)); - core.nativeFocus(); - return true; - } - } - - // component - const sComp = sc.nodeType === 1 ? util.getParentElement(sc, '.se-component') : null; - const eComp = ec.nodeType === 1 ? util.getParentElement(ec, '.se-component') : null; - if (sComp) util.removeItem(sComp); - if (eComp) util.removeItem(eComp); - - return false; - }, - - onPaste_wysiwyg: function (e) { - const clipboardData = util.isIE ? _w.clipboardData : e.clipboardData; - if (!clipboardData) return true; - return event._dataTransferAction('paste', e, clipboardData); - }, - - _setClipboardComponent: function (e, info, clipboardData) { - e.preventDefault(); - e.stopPropagation(); - clipboardData.setData('text/html', info.component.outerHTML); - }, - - onCopy_wysiwyg: function (e) { - const clipboardData = util.isIE ? _w.clipboardData : e.clipboardData; - if (typeof functions.onCopy === 'function' && !functions.onCopy(e, clipboardData, core)) { - e.preventDefault(); - e.stopPropagation(); - return false; - } - - const info = core.currentFileComponentInfo; - if (info && !util.isIE) { - event._setClipboardComponent(e, info, clipboardData); - util.addClass(info.component, 'se-component-copy'); - // copy effect - _w.setTimeout(function () { - util.removeClass(info.component, 'se-component-copy'); - }, 150); - } - }, - - onCut_wysiwyg: function (e) { - const clipboardData = util.isIE ? _w.clipboardData : e.clipboardData; - if (typeof functions.onCut === 'function' && !functions.onCut(e, clipboardData, core)) { - e.preventDefault(); - e.stopPropagation(); - return false; - } - - const info = core.currentFileComponentInfo; - if (info && !util.isIE) { - event._setClipboardComponent(e, info, clipboardData); - util.removeItem(info.component); - core.controllersOff(); - } - - _w.setTimeout(function () { - // history stack - core.history.push(false); - }); - }, - - onDrop_wysiwyg: function (e) { - const dataTransfer = e.dataTransfer; - if (!dataTransfer) return true; - if (util.isIE) { - e.preventDefault(); - e.stopPropagation(); - return false; - } - - core.removeNode(); - event._setDropLocationSelection(e); - return event._dataTransferAction('drop', e, dataTransfer); - }, - - _setDropLocationSelection: function (e) { - if (e.rangeParent) { - core.setRange(e.rangeParent, e.rangeOffset, e.rangeParent, e.rangeOffset); - } else if (core._wd.caretRangeFromPoint) { - const r = core._wd.caretRangeFromPoint(e.clientX, e.clientY); - core.setRange(r.startContainer, r.startOffset, r.endContainer, r.endOffset); - } else { - const r = core.getRange(); - core.setRange(r.startContainer, r.startOffset, r.endContainer, r.endOffset); - } - }, - - _dataTransferAction: function (type, e, data) { - let plainText, cleanData; - if (util.isIE) { - plainText = data.getData('Text'); - - const range = core.getRange(); - const tempDiv = util.createElement('DIV'); - const tempRange = { - sc: range.startContainer, - so: range.startOffset, - ec: range.endContainer, - eo: range.endOffset - }; - - tempDiv.setAttribute('contenteditable', true); - tempDiv.style.cssText = 'position:absolute; top:0; left:0; width:1px; height:1px; overflow:hidden;'; - - context.element.relative.appendChild(tempDiv); - tempDiv.focus(); - - _w.setTimeout(function () { - cleanData = tempDiv.innerHTML; - util.removeItem(tempDiv); - core.setRange(tempRange.sc, tempRange.so, tempRange.ec, tempRange.eo); - event._setClipboardData(type, e, plainText, cleanData, data); - }); - - return true; - } else { - plainText = data.getData('text/plain'); - cleanData = data.getData('text/html') || plainText; - if (event._setClipboardData(type, e, plainText, cleanData, data) === false) { - e.preventDefault(); - e.stopPropagation(); - return false; - } - } - }, - - _setClipboardData: function (type, e, plainText, cleanData, data) { - // MS word, OneNode, Excel - const MSData = /class=["']*Mso(Normal|List)/i.test(cleanData) || /content=["']*Word.Document/i.test(cleanData) || /content=["']*OneNote.File/i.test(cleanData) || /content=["']*Excel.Sheet/i.test(cleanData); - if (MSData) { - cleanData = cleanData.replace(/\n/g, ' '); - plainText = plainText.replace(/\n/g, ' '); - } else { - plainText = plainText.replace(/\n/g, ''); - } - - cleanData = core.cleanHTML(cleanData, core.pasteTagsWhitelistRegExp); - const maxCharCount = core._charCount(core._charTypeHTML ? cleanData : plainText); - - // paste event - if (type === 'paste' && typeof functions.onPaste === 'function') { - const value = functions.onPaste(e, cleanData, maxCharCount, core); - if (!value) return false; - if (typeof value === 'string') cleanData = value; - } - // drop event - if (type === 'drop' && typeof functions.onDrop === 'function') { - const value = functions.onDrop(e, cleanData, maxCharCount, core); - if (!value) return false; - if (typeof value === 'string') cleanData = value; - } - - // files - const files = data.files; - if (files.length > 0 && !MSData) { - if (/^image/.test(files[0].type) && core.plugins.image) { - functions.insertImage(files); - } - return false; - } - - if (!maxCharCount) { - return false; - } - - if (cleanData) { - functions.insertHTML(cleanData, true, false); - return false; - } - }, - - onMouseMove_wysiwyg: function (e) { - if (core.isDisabled) return; - const component = util.getParentElement(e.target, util.isComponent); - const lineBreakerStyle = core._lineBreaker.style; - - if (component && !core.currentControllerName) { - const ctxEl = context.element; - let scrollTop = 0; - let el = ctxEl.wysiwyg; - do { - scrollTop += el.scrollTop; - el = el.parentElement; - } while (el && !/^(BODY|HTML)$/i.test(el.nodeName)); - - const wScroll = ctxEl.wysiwyg.scrollTop; - const offsets = event._getEditorOffsets(null); - const componentTop = util.getOffset(component, ctxEl.wysiwygFrame).top + wScroll; - const y = e.pageY + scrollTop + (options.iframe && !options.toolbarContainer ? ctxEl.toolbar.offsetHeight : 0); - const c = componentTop + (options.iframe ? scrollTop : offsets.top); - - const isList = util.isListCell(component.parentNode); - let dir = '', top = ''; - if ((isList ? !component.previousSibling : !util.isFormatElement(component.previousElementSibling)) && y < (c + 20)) { - top = componentTop; - dir = 't'; - } else if ((isList ? !component.nextSibling : !util.isFormatElement(component.nextElementSibling)) && y > (c + component.offsetHeight - 20)) { - top = componentTop + component.offsetHeight; - dir = 'b'; - } else { - lineBreakerStyle.display = 'none'; - return; - } - - core._variable._lineBreakComp = component; - core._variable._lineBreakDir = dir; - lineBreakerStyle.top = (top - wScroll) + 'px'; - core._lineBreakerButton.style.left = (util.getOffset(component).left + (component.offsetWidth / 2) - 15) + 'px'; - lineBreakerStyle.display = 'block'; - } // off line breaker - else if (lineBreakerStyle.display !== 'none') { - lineBreakerStyle.display = 'none'; - } - }, - - _onMouseDown_lineBreak: function (e) { - e.preventDefault(); - }, - - _onLineBreak: function (e) { - e.preventDefault(); - - const component = core._variable._lineBreakComp; - const dir = !this ? core._variable._lineBreakDir : this; - const isList = util.isListCell(component.parentNode); - - const format = util.createElement(isList ? 'BR' : util.isCell(component.parentNode) ? 'DIV' : options.defaultTag); - if (!isList) format.innerHTML = '
'; - - if (core._charTypeHTML && !core.checkCharCount(format.outerHTML, 'byte-html')) return; - - component.parentNode.insertBefore(format, dir === 't' ? component : component.nextSibling); - core._lineBreaker.style.display = 'none'; - core._variable._lineBreakComp = null; - - const focusEl = isList ? format : format.firstChild; - core.setRange(focusEl, 1, focusEl, 1); - // history stack - core.history.push(false); - }, - - _addEvent: function () { - const eventWysiwyg = options.iframe ? core._ww : context.element.wysiwyg; - - /** toolbar event */ - context.element.toolbar.addEventListener('mousedown', event._buttonsEventHandler, false); - context.element._menuTray.addEventListener('mousedown', event._buttonsEventHandler, false); - context.element.toolbar.addEventListener('click', event.onClick_toolbar, false); - /** editor area */ - eventWysiwyg.addEventListener('mousedown', event.onMouseDown_wysiwyg, false); - eventWysiwyg.addEventListener('click', event.onClick_wysiwyg, false); - eventWysiwyg.addEventListener(util.isIE ? 'textinput' : 'input', event.onInput_wysiwyg, false); - eventWysiwyg.addEventListener('keydown', event.onKeyDown_wysiwyg, false); - eventWysiwyg.addEventListener('keyup', event.onKeyUp_wysiwyg, false); - eventWysiwyg.addEventListener('paste', event.onPaste_wysiwyg, false); - eventWysiwyg.addEventListener('copy', event.onCopy_wysiwyg, false); - eventWysiwyg.addEventListener('cut', event.onCut_wysiwyg, false); - eventWysiwyg.addEventListener('drop', event.onDrop_wysiwyg, false); - eventWysiwyg.addEventListener('scroll', event.onScroll_wysiwyg, false); - eventWysiwyg.addEventListener('focus', event.onFocus_wysiwyg, false); - eventWysiwyg.addEventListener('blur', event.onBlur_wysiwyg, false); - - /** line breaker */ - event._lineBreakerBind = { a: event._onLineBreak.bind(''), t: event._onLineBreak.bind('t'), b: event._onLineBreak.bind('b') }; - eventWysiwyg.addEventListener('mousemove', event.onMouseMove_wysiwyg, false); - core._lineBreakerButton.addEventListener('mousedown', event._onMouseDown_lineBreak, false); - core._lineBreakerButton.addEventListener('click', event._lineBreakerBind.a, false); - context.element.lineBreaker_t.addEventListener('mousedown', event._lineBreakerBind.t, false); - context.element.lineBreaker_b.addEventListener('mousedown', event._lineBreakerBind.b, false); - - /** Events are registered only when there is a table plugin. */ - if (core.plugins.table) { - eventWysiwyg.addEventListener('touchstart', event.onMouseDown_wysiwyg, {passive: true, useCapture: false}); - } - - /** code view area auto line */ - if (options.height === 'auto' && !options.codeMirrorEditor) { - context.element.code.addEventListener('keydown', event._codeViewAutoHeight, false); - context.element.code.addEventListener('keyup', event._codeViewAutoHeight, false); - context.element.code.addEventListener('paste', event._codeViewAutoHeight, false); - } - - /** resizingBar */ - if (context.element.resizingBar) { - if (/\d+/.test(options.height)) { - context.element.resizingBar.addEventListener('mousedown', event.onMouseDown_resizingBar, false); - } else { - util.addClass(context.element.resizingBar, 'se-resizing-none'); - } - } - - /** window event */ - event._setResponsiveToolbar(); - _w.removeEventListener('resize', event.onResize_window); - _w.removeEventListener('scroll', event.onScroll_window); - - _w.addEventListener('resize', event.onResize_window, false); - if (options.stickyToolbar > -1) { - _w.addEventListener('scroll', event.onScroll_window, false); - } - }, - - _removeEvent: function () { - const eventWysiwyg = options.iframe ? core._ww : context.element.wysiwyg; - - context.element.toolbar.removeEventListener('mousedown', event._buttonsEventHandler); - context.element._menuTray.removeEventListener('mousedown', event._buttonsEventHandler); - context.element.toolbar.removeEventListener('click', event.onClick_toolbar); - - eventWysiwyg.removeEventListener('mousedown', event.onMouseDown_wysiwyg); - eventWysiwyg.removeEventListener('click', event.onClick_wysiwyg); - eventWysiwyg.removeEventListener(util.isIE ? 'textinput' : 'input', event.onInput_wysiwyg); - eventWysiwyg.removeEventListener('keydown', event.onKeyDown_wysiwyg); - eventWysiwyg.removeEventListener('keyup', event.onKeyUp_wysiwyg); - eventWysiwyg.removeEventListener('paste', event.onPaste_wysiwyg); - eventWysiwyg.removeEventListener('copy', event.onCopy_wysiwyg); - eventWysiwyg.removeEventListener('cut', event.onCut_wysiwyg); - eventWysiwyg.removeEventListener('drop', event.onDrop_wysiwyg); - eventWysiwyg.removeEventListener('scroll', event.onScroll_wysiwyg); - - eventWysiwyg.removeEventListener('mousemove', event.onMouseMove_wysiwyg); - core._lineBreakerButton.removeEventListener('mousedown', event._onMouseDown_lineBreak); - core._lineBreakerButton.removeEventListener('click', event._lineBreakerBind.a); - context.element.lineBreaker_t.removeEventListener('mousedown', event._lineBreakerBind.t); - context.element.lineBreaker_b.removeEventListener('mousedown', event._lineBreakerBind.b); - event._lineBreakerBind = null; - - eventWysiwyg.removeEventListener('touchstart', event.onMouseDown_wysiwyg, {passive: true, useCapture: false}); - - eventWysiwyg.removeEventListener('focus', event.onFocus_wysiwyg); - eventWysiwyg.removeEventListener('blur', event.onBlur_wysiwyg); - - context.element.code.removeEventListener('keydown', event._codeViewAutoHeight); - context.element.code.removeEventListener('keyup', event._codeViewAutoHeight); - context.element.code.removeEventListener('paste', event._codeViewAutoHeight); - - if (context.element.resizingBar) { - context.element.resizingBar.removeEventListener('mousedown', event.onMouseDown_resizingBar); - } - - _w.removeEventListener('resize', event.onResize_window); - _w.removeEventListener('scroll', event.onScroll_window); - }, - - _setResponsiveToolbar: function () { - if (_responsiveButtons.length === 0) { - _responsiveButtons = null; - return; - } - - event._responsiveCurrentSize = 'default'; - const sizeArray = event._responsiveButtonSize = []; - const buttonsObj = event._responsiveButtons = {default: _responsiveButtons[0]}; - for (let i = 1, len = _responsiveButtons.length, size, buttonGroup; i < len; i++) { - buttonGroup = _responsiveButtons[i]; - size = buttonGroup[0] * 1; - sizeArray.push(size); - buttonsObj[size] = buttonGroup[1]; - } - - sizeArray.sort(function (a, b) { return a - b; }).unshift('default'); - } - }; - - /** functions */ - const functions = { - /** - * @description Core, Util object - */ - core: core, - util: util, - - /** - * @description Event functions - * @param {Object} e Event Object - * @param {Object} core Core object - */ - onload: null, - onScroll: null, - onMouseDown: null, - onClick: null, - onInput: null, - onKeyDown: null, - onKeyUp: null, - onCopy: null, - onCut: null, - onFocus: null, - onBlur: null, - - /** - * @description Event functions - * @param {String} contents Current contents - * @param {Object} core Core object - */ - onChange: null, - - /** - * @description Event functions (drop, paste) - * When false is returned, the default behavior is stopped. - * If the string is returned, the cleanData value is modified to the return value. - * @param {Object} e Event object. - * @param {String} cleanData HTML string modified for editor format. - * @param {Boolean} maxChartCount option (true if max character is exceeded) - * @param {Object} core Core object - * @returns {Boolean|String} - */ - onDrop: null, - onPaste: null, - - /** - * @description Called just before the inline toolbar is positioned and displayed on the screen. - * @param {Element} toolbar Toolbar Element - * @param {Object} context The editor's context object (editor.getContext()) - * @param {Object} core Core object - */ - showInline: null, - - /** - * @description Called just after the controller is positioned and displayed on the screen. - * controller - editing elements displayed on the screen [image resizing, table editor, link editor..]] - * @param {String} name The name of the plugin that called the controller - * @param {Array} controllers Array of Controller elements - * @param {Object} core Core object - */ - showController: null, - - /** - * @description An event when toggling between code view and wysiwyg view. - * @param {Boolean} isCodeView Whether the current code view mode - * @param {Object} core Core object - */ - toggleCodeView: null, - - /** - * @description An event when toggling full screen. - * @param {Boolean} isFullScreen Whether the current full screen mode - * @param {Object} core Core object - */ - toggleFullScreen: null, - - /** - * @description It replaces the default callback function of the image upload - * @param {Object} response Response object - * @param {Object} info Input information - * - linkValue: Link url value - * - linkNewWindow: Open in new window Check Value - * - inputWidth: Value of width input - * - inputHeight: Value of height input - * - align: Align Check Value - * - isUpdate: Update image if true, create image if false - * - element: If isUpdate is true, the currently selected image. - * @param {Object} core Core object - */ - imageUploadHandler: null, - - /** - * @description It replaces the default callback function of the video upload - * @param xmlHttp xmlHttpRequest object - * @param info Input information - * - inputWidth: Value of width input - * - inputHeight: Value of height input - * - align: Align Check Value - * - isUpdate: Update video if true, create video if false - * - element: If isUpdate is true, the currently selected video. - * @param core Core object - */ - videoUploadHandler: null, - - /** - * @description It replaces the default callback function of the audio upload - * @param xmlHttp xmlHttpRequest object - * @param info Input information - * - isUpdate: Update audio if true, create audio if false - * - element: If isUpdate is true, the currently selected audio. - * @param core Core object - */ - audioUploadHandler: null, - - /** - * @description Called before the image is uploaded - * If true is returned, the internal upload process runs normally. - * If false is returned, no image upload is performed. - * If new fileList are returned, replaced the previous fileList - * If undefined is returned, it waits until "uploadHandler" is executed. - * @param {Array} files Files array - * @param {Object} info info: { - * - linkValue: Link url value - * - linkNewWindow: Open in new window Check Value - * - inputWidth: Value of width input - * - inputHeight: Value of height input - * - align: Align Check Value - * - isUpdate: Update image if true, create image if false - * - element: If isUpdate is true, the currently selected image. - * } - * @param {Object} core Core object - * @param {Function} uploadHandler If undefined is returned, it waits until "uploadHandler" is executed. - * "uploadHandler" is an upload function with "core" and "info" bound. - * [upload files] : uploadHandler(files or [new File(...),]) - * [error] : uploadHandler("Error message") - * [Just finish] : uploadHandler() - * [directly register] : uploadHandler(response) // Same format as "imageUploadUrl" response - * ex) { - * // "errorMessage": "insert error message", - * "result": [ { "url": "...", "name": "...", "size": "999" }, ] - * } - * @returns {Boolean|Array|undefined} - */ - onImageUploadBefore: null, - /** - * @description Called before the video is uploaded - * If true is returned, the internal upload process runs normally. - * If false is returned, no video(iframe, video) upload is performed. - * If new fileList are returned, replaced the previous fileList - * If undefined is returned, it waits until "uploadHandler" is executed. - * @param {Array} files Files array - * @param {Object} info info: { - * - inputWidth: Value of width input - * - inputHeight: Value of height input - * - align: Align Check Value - * - isUpdate: Update video if true, create video if false - * - element: If isUpdate is true, the currently selected video. - * } - * @param {Object} core Core object - * @param {Function} uploadHandler If undefined is returned, it waits until "uploadHandler" is executed. - * "uploadHandler" is an upload function with "core" and "info" bound. - * [upload files] : uploadHandler(files or [new File(...),]) - * [error] : uploadHandler("Error message") - * [Just finish] : uploadHandler() - * [directly register] : uploadHandler(response) // Same format as "videoUploadUrl" response - * ex) { - * // "errorMessage": "insert error message", - * "result": [ { "url": "...", "name": "...", "size": "999" }, ] - * } - * @returns {Boolean|Array|undefined} - */ - onVideoUploadBefore: null, - /** - * @description Called before the audio is uploaded - * If true is returned, the internal upload process runs normally. - * If false is returned, no audio upload is performed. - * If new fileList are returned, replaced the previous fileList - * If undefined is returned, it waits until "uploadHandler" is executed. - * @param {Array} files Files array - * @param {Object} info info: { - * - isUpdate: Update audio if true, create audio if false - * - element: If isUpdate is true, the currently selected audio. - * } - * @param {Object} core Core object - * @param {Function} uploadHandler If undefined is returned, it waits until "uploadHandler" is executed. - * "uploadHandler" is an upload function with "core" and "info" bound. - * [upload files] : uploadHandler(files or [new File(...),]) - * [error] : uploadHandler("Error message") - * [Just finish] : uploadHandler() - * [directly register] : uploadHandler(response) // Same format as "audioUploadUrl" response - * ex) { - * // "errorMessage": "insert error message", - * "result": [ { "url": "...", "name": "...", "size": "999" }, ] - * } - * @returns {Boolean|Array|undefined} - */ - onAudioUploadBefore: null, - - /** - * @description Called when the image is uploaded, updated, deleted - * @param {Element} targetElement Target element - * @param {Number} index Uploaded index - * @param {String} state Upload status ('create', 'update', 'delete') - * @param {Object} info Image info object - * - index: data index - * - name: file name - * - size: file size - * - select: select function - * - delete: delete function - * - element: target element - * - src: src attribute of tag - * @param {Number} remainingFilesCount Count of remaining files to upload (0 when added as a url) - * @param {Object} core Core object - */ - onImageUpload: null, - /** - * @description Called when the video(iframe, video) is is uploaded, updated, deleted - * -- arguments is same "onImageUpload" -- - */ - onVideoUpload: null, - /** - * @description Called when the audio is is uploaded, updated, deleted - * -- arguments is same "onImageUpload" -- - */ - onAudioUpload: null, - - /** - * @description Called when the image is upload failed - * @param {String} errorMessage Error message - * @param {Object} result Response Object - * @param {Object} core Core object - * @returns {Boolean} - */ - onImageUploadError: null, - /** - * @description Called when the video(iframe, video) upload failed - * -- arguments is same "onImageUploadError" -- - */ - onVideoUploadError: null, - /** - * @description Called when the audio upload failed - * -- arguments is same "onImageUploadError" -- - */ - onAudioUploadError: null, - - /** - * @description Reset the buttons on the toolbar. (Editor is not reloaded) - * You cannot set a new plugin for the button. - * @param {Array} buttonList Button list - */ - setToolbarButtons: function (buttonList) { - core.submenuOff(); - core.containerOff(); - - const newToolbar = _constructor__WEBPACK_IMPORTED_MODULE_0__["default"]._createToolBar(_d, buttonList, core.plugins, options); - _responsiveButtons = newToolbar.responsiveButtons; - core._moreLayerActiveButton = null; - event._setResponsiveToolbar(); - - context.element.toolbar.replaceChild(newToolbar._buttonTray, context.element._buttonTray); - const newContext = Object(_context__WEBPACK_IMPORTED_MODULE_1__["default"])(context.element.originElement, core._getConstructed(context.element), options); - - context.element = newContext.element; - context.tool = newContext.tool; - if (options.iframe) context.element.wysiwyg = core._wd.body; - core._cachingButtons(); - core.history._resetCachingButton(); - - core.activePlugins = []; - const oldCallButtons = pluginCallButtons; - pluginCallButtons = newToolbar.pluginCallButtons; - let plugin, button, oldButton; - for (let key in pluginCallButtons) { - if (!util.hasOwn(pluginCallButtons, key)) continue; - plugin = plugins[key]; - button = pluginCallButtons[key]; - if (plugin.active && button) { - oldButton = oldCallButtons[key]; - core.callPlugin(key, null, oldButton || button); - if (oldButton) { - button.parentElement.replaceChild(oldButton, button); - pluginCallButtons[key] = oldButton; - } - } - } - - if (core.hasFocus) event._applyTagEffects(); - - if (core._variable.isCodeView) util.addClass(core._styleCommandMap.codeView, 'active'); - if (core._variable.isFullScreen) util.addClass(core._styleCommandMap.fullScreen, 'active'); - if (util.hasClass(context.element.wysiwyg, 'se-show-block')) util.addClass(core._styleCommandMap.showBlocks, 'active'); - }, - - /** - * @description Add or reset option property (Editor is reloaded) - * @param {Object} _options Options - */ - setOptions: function (_options) { - event._removeEvent(); - core._resetComponents(); - - util.removeClass(core._styleCommandMap.showBlocks, 'active'); - util.removeClass(core._styleCommandMap.codeView, 'active'); - core._variable.isCodeView = false; - core._iframeAuto = null; - - core.plugins = _options.plugins || core.plugins; - const mergeOptions = [options, _options].reduce(function (init, option) { - for (let key in option) { - if (!util.hasOwn(option, key)) continue; - if (key === 'plugins' && option[key] && init[key]) { - let i = init[key], o = option[key]; - i = i.length ? i : _w.Object.keys(i).map(function(name) { return i[name]; }); - o = o.length ? o : _w.Object.keys(o).map(function(name) { return o[name]; }); - init[key] = (o.filter(function(val) { return i.indexOf(val) === -1; })).concat(i); - } else { - init[key] = option[key]; - } - } - return init; - }, {}); - - const el = context.element; - const _initHTML = el.wysiwyg.innerHTML; - - // set option - const cons = _constructor__WEBPACK_IMPORTED_MODULE_0__["default"]._setOptions(mergeOptions, context, options); - - if (cons.callButtons) { - pluginCallButtons = cons.callButtons; - core.initPlugins = {}; - } - - if (cons.plugins) { - core.plugins = plugins = cons.plugins; - } - - // reset context - if (el._menuTray.children.length === 0) this._menuTray = {}; - _responsiveButtons = cons.toolbar.responsiveButtons; - core.options = options = mergeOptions; - core.lang = lang = options.lang; - - if (options.iframe) { - el.wysiwygFrame.addEventListener('load', function () { - util._setIframeDocument(this, options); - core._setOptionsInit(el, _initHTML); - }); - } - - el.editorArea.appendChild(el.wysiwygFrame); - - if (!options.iframe) { - core._setOptionsInit(el, _initHTML); - } - }, - - /** - * @description Set "options.defaultStyle" style. - * Define the style of the edit area - * It can also be defined with the "setOptions" method, but the "setDefaultStyle" method does not render the editor again. - * @param {String} style Style string - */ - setDefaultStyle: function (style) { - const newStyles = options._editorStyles = util._setDefaultOptionStyle(options, style); - const el = context.element; - - // top area - el.topArea.style.cssText = newStyles.top; - // code view - el.code.style.cssText = options._editorStyles.frame; - el.code.style.display = 'none'; - if (options.height === 'auto') { - el.code.style.overflow = 'hidden'; - } else { - el.code.style.overflow = ''; - } - // wysiwyg frame - if (!options.iframe) { - el.wysiwygFrame.style.cssText = newStyles.frame + newStyles.editor; - } else { - el.wysiwygFrame.style.cssText = newStyles.frame; - el.wysiwyg.style.cssText = newStyles.editor; - } - }, - - /** - * @description Open a notice area - * @param {String} message Notice message - */ - noticeOpen: function (message) { - core.notice.open.call(core, message); - }, - - /** - * @description Close a notice area - */ - noticeClose: function () { - core.notice.close.call(core); - }, - - /** - * @description Copying the contents of the editor to the original textarea - */ - save: function () { - context.element.originElement.value = core.getContents(false); - }, - - /** - * @description Gets the suneditor's context object. Contains settings, plugins, and cached element objects - * @returns {Object} - */ - getContext: function () { - return context; - }, - - /** - * @description Gets the contents of the suneditor - * @param {Boolean} onlyContents - Return only the contents of the body without headers when the "fullPage" option is true - * @returns {String} - */ - getContents: function (onlyContents) { - return core.getContents(onlyContents); - }, - - /** - * @description Gets only the text of the suneditor contents - * @returns {String} - */ - getText: function () { - return context.element.wysiwyg.textContent; - }, - - /** - * @description Get the editor's number of characters or binary data size. - * You can use the "charCounterType" option format. - * @param {String|null} charCounterType options - charCounterType ('char', 'byte', 'byte-html') - * If argument is no value, the currently set "charCounterType" option is used. - * @returns {Number} - */ - getCharCount: function (charCounterType) { - charCounterType = typeof charCounterType === 'string' ? charCounterType : options.charCounterType; - return core.getCharLength((core._charTypeHTML ? context.element.wysiwyg.innerHTML : context.element.wysiwyg.textContent), charCounterType); - }, - - /** - * @description Gets uploaded images informations - * - index: data index - * - name: file name - * - size: file size - * - select: select function - * - delete: delete function - * - element: target element - * - src: src attribute of tag - * @returns {Array} - */ - getImagesInfo: function () { - return context.image ? context.image._infoList : []; - }, - - /** - * @description Gets uploaded files(plugin using fileManager) information list. - * image: [img], video: [video, iframe], audio: [audio] - * When the argument value is 'image', it is the same function as "getImagesInfo". - * - index: data index - * - name: file name - * - size: file size - * - select: select function - * - delete: delete function - * - element: target element - * - src: src attribute of tag - * @param {String} pluginName Plugin name (image, video, audio) - * @returns {Array} - */ - getFilesInfo: function (pluginName) { - return context[pluginName] ? context[pluginName]._infoList : []; - }, - - /** - * @description Upload images using image plugin - * @param {FileList} files FileList - */ - insertImage: function (files) { - if (!core.plugins.image || !files) return; - - if (!core.initPlugins.image) core.callPlugin('image', core.plugins.image.submitAction.bind(core, files), null); - else core.plugins.image.submitAction.call(core, files); - core.focus(); - }, - - /** - * @description Inserts an HTML element or HTML string or plain string at the current cursor position - * @param {Element|String} html HTML Element or HTML string or plain string - * @param {Boolean} notCleaningData If true, inserts the HTML string without refining it with core.cleanHTML. - * @param {Boolean} checkCharCount If true, if "options.maxCharCount" is exceeded when "element" is added, null is returned without addition. - * @param {Boolean} rangeSelection If true, range select the inserted node. - */ - insertHTML: function (html, notCleaningData, checkCharCount, rangeSelection) { - if (typeof html === 'string') { - if (!notCleaningData) html = core.cleanHTML(html, null); - try { - const dom = _d.createRange().createContextualFragment(html); - const domTree = dom.childNodes; - - if (checkCharCount) { - const type = core._charTypeHTML ? 'outerHTML' : 'textContent'; - let checkHTML = ''; - for (let i = 0, len = domTree.length; i < len; i++) { - checkHTML += domTree[i][type]; - } - if (!core.checkCharCount(checkHTML, null)) return; - } - - let c, a, t, firstCon; - while ((c = domTree[0])) { - t = core.insertNode(c, a, false); - a = t.container || t; - if (!firstCon) firstCon = t; - } - - const offset = a.nodeType === 3 ? (t.endOffset || a.textContent.length): a.childNodes.length; - if (rangeSelection) core.setRange(firstCon.container || firstCon, firstCon.startOffset || 0, a, offset); - else core.setRange(a, offset, a, offset); - } catch (error) { - core.execCommand('insertHTML', false, html); - } - } else { - if (util.isComponent(html)) { - core.insertComponent(html, false, checkCharCount, false); - } else { - let afterNode = null; - if (util.isFormatElement(html) || util.isMedia(html)) { - afterNode = util.getFormatElement(core.getSelectionNode(), null); - } - core.insertNode(html, afterNode, checkCharCount); - } - } - - core.effectNode = null; - core.focus(); - - // history stack - core.history.push(false); - }, - - /** - * @description Change the contents of the suneditor - * @param {String|undefined} contents Contents to Input - */ - setContents: function (contents) { - core.setContents(contents); - }, - - /** - * @description Add contents to the suneditor - * @param {String} contents Contents to Input - */ - appendContents: function (contents) { - const convertValue = core.convertContentsForEditor(contents); - - if (!core._variable.isCodeView) { - const temp = util.createElement('DIV'); - temp.innerHTML = convertValue; - - const wysiwyg = context.element.wysiwyg; - const children = temp.children; - for (let i = 0, len = children.length; i < len; i++) { - wysiwyg.appendChild(children[i]); - } - } else { - core._setCodeView(core._getCodeView() + '\n' + core.convertHTMLForCodeView(convertValue)); - } - - // history stack - core.history.push(false); - }, - - /** - * @description Disable the suneditor - */ - disabled: function () { - context.tool.cover.style.display = 'block'; - context.element.wysiwyg.setAttribute('contenteditable', false); - core.isDisabled = true; - - if (options.codeMirrorEditor) { - options.codeMirrorEditor.setOption('readOnly', true); - } else { - context.element.code.setAttribute('disabled', 'disabled'); - } - }, - - /** - * @description Enable the suneditor - */ - enabled: function () { - context.tool.cover.style.display = 'none'; - context.element.wysiwyg.setAttribute('contenteditable', true); - core.isDisabled = false; - - if (options.codeMirrorEditor) { - options.codeMirrorEditor.setOption('readOnly', false); - } else { - context.element.code.removeAttribute('disabled'); - } - }, - - /** - * @description Show the suneditor - */ - show: function () { - const topAreaStyle = context.element.topArea.style; - if (topAreaStyle.display === 'none') topAreaStyle.display = options.display; - }, - - /** - * @description Hide the suneditor - */ - hide: function () { - context.element.topArea.style.display = 'none'; - }, - - /** - * @description Destroy the suneditor - */ - destroy: function () { - /** off menus */ - core.submenuOff(); - core.containerOff(); - core.controllersOff(); - if (core.notice) core.notice.close.call(core); - if (core.modalForm) core.plugins.dialog.close.call(core); - - /** remove history */ - core.history._destroy(); - - /** remove event listeners */ - event._removeEvent(); - - /** remove element */ - util.removeItem(context.element.toolbar); - util.removeItem(context.element.topArea); - - /** remove object reference */ - for (let k in core) { if (util.hasOwn(core, k)) delete core[k]; } - for (let k in event) { if (util.hasOwn(event, k)) delete event[k]; } - for (let k in context) { if (util.hasOwn(context, k)) delete context[k]; } - for (let k in pluginCallButtons) { if (util.hasOwn(pluginCallButtons, k)) delete pluginCallButtons[k]; } - - /** remove user object */ - for (let k in this) { if (util.hasOwn(this, k)) delete this[k]; } - }, - - /** - * @description Toolbar methods - */ - toolbar: { - /** - * @description Disable the toolbar - */ - disabled: function () { - context.tool.cover.style.display = 'block'; - }, - - /** - * @description Enable the toolbar - */ - enabled: function () { - context.tool.cover.style.display = 'none'; - }, - - /** - * @description Show the toolbar - */ - show: function () { - if (core._isInline) { - event._showToolbarInline(); - } else { - context.element.toolbar.style.display = ''; - context.element._stickyDummy.style.display = ''; - } - }, - - /** - * @description Hide the toolbar - */ - hide: function () { - if (core._isInline) { - event._hideToolbar(); - } else { - context.element.toolbar.style.display = 'none'; - context.element._stickyDummy.style.display = 'none'; - } - }, - } - }; - - /************ Core init ************/ - // functions - core.functions = functions; - core.options = options; - - // Create to sibling node - let contextEl = context.element; - let originEl = contextEl.originElement; - let topEl = contextEl.topArea; - originEl.style.display = 'none'; - topEl.style.display = 'block'; - - // init - if (options.iframe) { - contextEl.wysiwygFrame.addEventListener('load', function () { - util._setIframeDocument(this, options); - core._editorInit(false, options.value); - options.value = null; - }); - } - - // insert editor element - if (typeof originEl.nextElementSibling === 'object') { - originEl.parentNode.insertBefore(topEl, originEl.nextElementSibling); - } else { - originEl.parentNode.appendChild(topEl); - } - - contextEl.editorArea.appendChild(contextEl.wysiwygFrame); - contextEl = originEl = topEl = null; - - // init - if (!options.iframe) { - core._editorInit(false, options.value); - options.value = null; - } - - return functions; -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/lib/history.js": -/*!***************************************************!*\ - !*** ./node_modules/suneditor/src/lib/history.js ***! - \***************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2019 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = (function (core, change) { - const _w = core._w; - const util = core.util; - const delayTime = core.options.historyStackDelayTime; - let editor = core.context.element; - let undo = core.context.tool.undo; - let redo = core.context.tool.redo; - - let pushDelay = null; - let stackIndex = 0; - let stack = []; - - function setContentsFromStack () { - const item = stack[stackIndex]; - editor.wysiwyg.innerHTML = item.contents; - - core.setRange(util.getNodeFromPath(item.s.path, editor.wysiwyg), item.s.offset, util.getNodeFromPath(item.e.path, editor.wysiwyg), item.e.offset); - core.focus(); - - if (stackIndex === 0) { - if (undo) undo.setAttribute('disabled', true); - if (redo) redo.removeAttribute('disabled'); - } else if (stackIndex === stack.length - 1) { - if (undo) undo.removeAttribute('disabled'); - if (redo) redo.setAttribute('disabled', true); - } else { - if (undo) undo.removeAttribute('disabled'); - if (redo) redo.removeAttribute('disabled'); - } - - core.controllersOff(); - core._checkComponents(); - core._setCharCount(); - core._resourcesStateChange(); - - // onChange - change(); - } - - function pushStack () { - core._checkComponents(); - const current = core.getContents(true); - if (!current || (!!stack[stackIndex] && current === stack[stackIndex].contents)) return; - - stackIndex++; - const range = core._variable._range; - - if (stack.length > stackIndex) { - stack = stack.slice(0, stackIndex); - if (redo) redo.setAttribute('disabled', true); - } - - if (!range) { - stack[stackIndex] = { - contents: current, - s: { path: [0, 0], offset: [0, 0] }, - e: { path: 0, offset: 0 } - }; - } else { - stack[stackIndex] = { - contents: current, - s: { - path: util.getNodePath(range.startContainer, null, null), - offset: range.startOffset - }, - e: { - path: util.getNodePath(range.endContainer, null, null), - offset: range.endOffset - } - }; - } - - if (stackIndex === 1 && undo) undo.removeAttribute('disabled'); - - core._setCharCount(); - // onChange - change(); - } - - return { - /** - * @description History stack - */ - stack: stack, - - /** - * @description Saving the current status to the history object stack - * If "delay" is true, it will be saved after (options.historyStackDelayTime || 400) miliseconds - * If the function is called again with the "delay" argument true before it is saved, the delay time is renewal - * You can specify the delay time by sending a number. - * @param {Boolean|Number} delay If true, Add stack without delay time. - */ - push: function (delay) { - _w.setTimeout(core._resourcesStateChange.bind(core)); - const time = typeof delay === 'number' ? (delay > 0 ? delay : 0) : (!delay ? 0 : delayTime); - - if (!time || pushDelay) { - _w.clearTimeout(pushDelay); - if (!time) { - pushStack(); - return; - } - } - - pushDelay = _w.setTimeout(function () { - _w.clearTimeout(pushDelay); - pushDelay = null; - pushStack(); - }, time); - }, - - /** - * @description Undo function - */ - undo: function () { - if (stackIndex > 0) { - stackIndex--; - setContentsFromStack(); - } - }, - - /** - * @description Redo function - */ - redo: function () { - if (stack.length - 1 > stackIndex) { - stackIndex++; - setContentsFromStack(); - } - }, - - /** - * @description Go to the history stack for that index. - * If "index" is -1, go to the last stack - * @param {Number} index Stack index - */ - go: function (index) { - stackIndex = index < 0 ? (stack.length - 1) : index; - setContentsFromStack(); - }, - - /** - * @description Reset the history object - */ - reset: function (ignoreChangeEvent) { - if (undo) undo.setAttribute('disabled', true); - if (redo) redo.setAttribute('disabled', true); - core._variable.isChanged = false; - if (core.context.tool.save) core.context.tool.save.setAttribute('disabled', true); - - stack.splice(0); - stackIndex = 0; - - // pushStack - stack[stackIndex] = { - contents: core.getContents(true), - s: { - path: [0, 0], - offset: 0 - }, - e: { - path: [0, 0], - offset: 0 - } - }; - - if (!ignoreChangeEvent) change(); - }, - - /** - * @description Reset the disabled state of the buttons to fit the current stack. - * @private - */ - _resetCachingButton: function () { - editor = core.context.element; - undo = core.context.tool.undo; - redo = core.context.tool.redo; - - if (stackIndex === 0) { - if (undo) undo.setAttribute('disabled', true); - if (redo && stackIndex === stack.length - 1) redo.setAttribute('disabled', true); - core._variable.isChanged = false; - if (core.context.tool.save) core.context.tool.save.setAttribute('disabled', true); - } else if (stackIndex === stack.length - 1) { - if (redo) redo.setAttribute('disabled', true); - } - }, - - /** - * @description Remove all stacks and remove the timeout function. - * @private - */ - _destroy: function () { - if (pushDelay) _w.clearTimeout(pushDelay); - stack = null; - } - }; -}); - -/***/ }), - -/***/ "./node_modules/suneditor/src/lib/util.js": -/*!************************************************!*\ - !*** ./node_modules/suneditor/src/lib/util.js ***! - \************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/** - * @description utility function - */ -const util = { - _d: null, - _w: null, - isIE: null, - isIE_Edge: null, - isOSX_IOS: null, - _propertiesInit: function () { - if (this._d) return; - this._d = document; - this._w = window; - this.isIE = navigator.userAgent.indexOf('Trident') > -1; - this.isIE_Edge = (navigator.userAgent.indexOf('Trident') > -1) || (navigator.appVersion.indexOf('Edge') > -1); - this.isOSX_IOS = /(Mac|iPhone|iPod|iPad)/.test(navigator.platform); - }, - - /** - * @description HTML Reserved Word Converter. - * @param {String} contents - * @returns {String} HTML string - * @private - */ - _HTMLConvertor: function (contents) { - const ec = {'&': '&', '\u00A0': ' ', '\'': ''', '"': '"', '<': '<', '>': '>'}; - return contents.replace(/&|\u00A0|'|"|<|>/g, function (m) { - return (typeof ec[m] === 'string') ? ec[m] : m; - }); - }, - - /** - * @description Unicode Character 'ZERO WIDTH SPACE' (\u200B) - */ - zeroWidthSpace: String.fromCharCode(8203), - - /** - * @description Regular expression to find 'zero width space' (/\u200B/g) - */ - zeroWidthRegExp: new RegExp(String.fromCharCode(8203), 'g'), - - /** - * @description Regular expression to find only 'zero width space' (/^\u200B+$/) - */ - onlyZeroWidthRegExp: new RegExp('^' + String.fromCharCode(8203) + '+$'), - - /** - * @description A method that checks If the text is blank or to see if it contains 'ZERO WIDTH SPACE' or empty (util.zeroWidthSpace) - * @param {String|Node} text String value or Node - * @returns {Boolean} - */ - onlyZeroWidthSpace: function (text) { - if (typeof text !== 'string') text = text.textContent; - return text === '' || this.onlyZeroWidthRegExp.test(text); - }, - - /** - * @description Gets XMLHttpRequest object - * @returns {XMLHttpRequest|ActiveXObject} - */ - getXMLHttpRequest: function () { - /** IE */ - if (this._w.ActiveXObject) { - try { - return new ActiveXObject('Msxml2.XMLHTTP'); - } catch (e) { - try { - return new ActiveXObject('Microsoft.XMLHTTP'); - } catch (e1) { - return null; - } - } - } - /** netscape */ - else if (this._w.XMLHttpRequest) { - return new XMLHttpRequest(); - } - /** fail */ - else { - return null; - } - }, - - /** - * @description Create Element node - * @param {String} elementName Element name - * @returns {Element} - */ - createElement: function (elementName) { - return this._d.createElement(elementName); - }, - - /** - * @description Create text node - * @param {String} text text contents - * @returns {Node} - */ - createTextNode: function (text) { - return this._d.createTextNode(text || ''); - }, - - /** - * @description The editor checks tags by string. - * If there is "<" or ">" in the attribute of tag, HTML is broken when checking the tag. - * When using an attribute with "<" or ">", use "HTMLEncoder" to save. (ex: math(katex)) - * @param {String} contents HTML or Text string - * @returns {String} - */ - HTMLEncoder: function (contents) { - const ec = {'<': '$lt;', '>': '$gt;'}; - return contents.replace(/<|>/g, function (m) { - return (typeof ec[m] === 'string') ? ec[m] : m; - }); - }, - - /** - * @description The editor checks tags by string. - * If there is "<" or ">" in the attribute of tag, HTML is broken when checking the tag. - * Decoder of data stored as "HTMLEncoder" (ex: math(katex)) - * @param {String} contents HTML or Text string - * @returns {String} - */ - HTMLDecoder: function (contents) { - const ec = {'$lt;': '<', '$gt;': '>'}; - return contents.replace(/\$lt;|\$gt;/g, function (m) { - return (typeof ec[m] === 'string') ? ec[m] : m; - }); - }, - - /** - * @description This method run Object.prototype.hasOwnProperty.call(obj, key) - * @param {Object} obj Object - * @param {String} key obj.key - * @returns {Boolean} - */ - hasOwn: function (obj, key) { - return this._hasOwn.call(obj, key); - }, - _hasOwn: Object.prototype.hasOwnProperty, - - /** - * @deprecated - * @description Get the the tag path of the arguments value - * If not found, return the first found value - * @param {Array} nameArray File name array - * @param {String} extension js, css - * @returns {String} - */ - getIncludePath: function (nameArray, extension) { - let path = ''; - const pathList = []; - const tagName = extension === 'js' ? 'script' : 'link'; - const src = extension === 'js' ? 'src' : 'href'; - - let fileName = '(?:'; - for (let i = 0, len = nameArray.length; i < len; i++) { - fileName += nameArray[i] + (i < len - 1 ? '|' : ')'); - } - - const regExp = new this._w.RegExp('(^|.*[\\/])' + fileName + '(\\.[^\\/]+)?\.' + extension + '(?:\\?.*|;.*)?$', 'i'); - const extRegExp = new this._w.RegExp('.+\\.' + extension + '(?:\\?.*|;.*)?$', 'i'); - - for (let c = this._d.getElementsByTagName(tagName), i = 0; i < c.length; i++) { - if (extRegExp.test(c[i][src])) { - pathList.push(c[i]); - } - } - - for (let i = 0; i < pathList.length; i++) { - let editorTag = pathList[i][src].match(regExp); - if (editorTag) { - path = editorTag[0]; - break; - } - } - - if (path === '') path = pathList.length > 0 ? pathList[0][src] : ''; - - -1 === path.indexOf(':/') && '//' !== path.slice(0, 2) && (path = 0 === path.indexOf('/') ? location.href.match(/^.*?:\/\/[^\/]*/)[0] + path : location.href.match(/^[^\?]*\/(?:)/)[0] + path); - - if (!path) throw '[SUNEDITOR.util.getIncludePath.fail] The SUNEDITOR installation path could not be automatically detected. (name: +' + name + ', extension: ' + extension + ')'; - - return path; - }, - - /** - * @deprecated - * @description Returns the CSS text that has been applied to the current page. - * @param {Document|null} doc To get the CSS text of an document(core._wd). If null get the current document. - * @returns {String} Styles string - */ - getPageStyle: function (doc) { - let cssText = ''; - const sheets = (doc || this._d).styleSheets; - - for (let i = 0, len = sheets.length, rules; i < len; i++) { - try { - rules = sheets[i].cssRules; - } catch (e) { - continue; - } - - if (rules) { - for (let c = 0, cLen = rules.length; c < cLen; c++) { - cssText += rules[c].cssText; - } - } - } - - return cssText; - }, - - /** - * @description Get the argument iframe's document object - * @param {Element} iframe Iframe element (context.element.wysiwygFrame) - * @returns {Document} - */ - getIframeDocument: function (iframe) { - let wDocument = iframe.contentWindow || iframe.contentDocument; - if (wDocument.document) wDocument = wDocument.document; - return wDocument; - }, - - /** - * @description Get attributes of argument element to string ('class="---" name="---" ') - * @param {Element} element Element object - * @param {Array|null} exceptAttrs Array of attribute names to exclude from the result - * @returns {String} - */ - getAttributesToString: function (element, exceptAttrs) { - if (!element.attributes) return ''; - - const attrs = element.attributes; - let attrString = ''; - - for (let i = 0, len = attrs.length; i < len; i++) { - if (exceptAttrs && exceptAttrs.indexOf(attrs[i].name) > -1) continue; - attrString += attrs[i].name + '="' + attrs[i].value + '" '; - } - - return attrString; - }, - - /** - * @descriptionGets Get the length in bytes of a string. - * referencing code: "https://github.com/shaan1974/myrdin/blob/master/expressions/string.js#L11" - * @param {String} text String text - * @returns {Number} - */ - getByteLength: function(text) { - const encoder = this._w.encodeURIComponent; - let cr, cl; - if (this.isIE_Edge) { - cl = this._w.unescape(encoder(text.toString())).length; - cr = 0; - - if (encoder(text.toString()).match(/(%0A|%0D)/gi) !== null) { - cr = encoder(text.toString()).match(/(%0A|%0D)/gi).length; - } - - return cl + cr; - } else { - cl = (new this._w.TextEncoder('utf-8').encode(text.toString())).length; - cr = 0; - - if (encoder(text.toString()).match(/(%0A|%0D)/gi) !== null) { - cr = encoder(text.toString()).match(/(%0A|%0D)/gi).length; - } - - return cl + cr; - } - }, - - /** - * @description It is judged whether it is the edit region top div element or iframe's body tag. - * @param {Node} element The node to check - * @returns {Boolean} - */ - isWysiwygDiv: function (element) { - return element && element.nodeType === 1 && (this.hasClass(element, 'se-wrapper-wysiwyg') || /^BODY$/i.test(element.nodeName)); - }, - - /** - * @description It is judged whether it is the contenteditable property is false. - * @param {Node} element The node to check - * @returns {Boolean} - */ - isNonEditable: function (element) { - return element && element.nodeType === 1 && element.getAttribute('contenteditable') === 'false'; - }, - - /** - * @description It is judged whether it is a node related to the text style. - * (strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label|code) - * @param {Node} element The node to check - * @returns {Boolean} - */ - isTextStyleElement: function (element) { - return element && element.nodeType !== 3 && /^(strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label|code)$/i.test(element.nodeName); - }, - - /** - * @description It is judged whether it is the format element (P, DIV, H[1-6], PRE, LI | class="__se__format__replace_xxx") - * Format element also contain "free format Element" - * @param {Node} element The node to check - * @returns {Boolean} - */ - isFormatElement: function (element) { - return element && element.nodeType === 1 && (/^(P|DIV|H[1-6]|PRE|LI|TH|TD)$/i.test(element.nodeName) || this.hasClass(element, '(\\s|^)__se__format__replace_.+(\\s|$)|(\\s|^)__se__format__free_.+(\\s|$)')) && !this.isComponent(element) && !this.isWysiwygDiv(element); - }, - - /** - * @description It is judged whether it is the range format element. (BLOCKQUOTE, OL, UL, FIGCAPTION, TABLE, THEAD, TBODY, TR, TH, TD | class="__se__format__range_xxx") - * Range format element is wrap the "format element" and "component" - * @param {Node} element The node to check - * @returns {Boolean} - */ - isRangeFormatElement: function (element) { - return element && element.nodeType === 1 && (/^(BLOCKQUOTE|OL|UL|FIGCAPTION|TABLE|THEAD|TBODY|TR|TH|TD)$/i.test(element.nodeName) || this.hasClass(element, '(\\s|^)__se__format__range_.+(\\s|$)')); - }, - - /** - * @description It is judged whether it is the closure range format element. (TH, TD | class="__se__format__range__closure_xxx") - * Closure range format elements is included in the range format element. - * - Closure range format element is wrap the "format element" and "component" - * ※ You cannot exit this format with the Enter key or Backspace key. - * ※ Use it only in special cases. ([ex] format of table cells) - * @param {Node} element The node to check - * @returns {Boolean} - */ - isClosureRangeFormatElement: function (element) { - return element && element.nodeType === 1 && (/^(TH|TD)$/i.test(element.nodeName) || this.hasClass(element, '(\\s|^)__se__format__range__closure_.+(\\s|$)')); - }, - - /** - * @description It is judged whether it is the free format element. (PRE | class="__se__format__free_xxx") - * Free format elements is included in the format element. - * Free format elements's line break is "BR" tag. - * ※ Entering the Enter key in the space on the last line ends "Free Format" and appends "Format". - * @param {Node} element The node to check - * @returns {Boolean} - */ - isFreeFormatElement: function (element) { - return element && element.nodeType === 1 && (/^PRE$/i.test(element.nodeName) || this.hasClass(element, '(\\s|^)__se__format__free_.+(\\s|$)')) && !this.isComponent(element) && !this.isWysiwygDiv(element); - }, - - /** - * @description It is judged whether it is the closure free format element. (class="__se__format__free__closure_xxx") - * Closure free format elements is included in the free format element. - * - Closure free format elements's line break is "BR" tag. - * ※ You cannot exit this format with the Enter key or Backspace key. - * ※ Use it only in special cases. ([ex] format of table cells) - * @param {Node} element The node to check - * @returns {Boolean} - */ - isClosureFreeFormatElement: function (element) { - return element && element.nodeType === 1 && this.hasClass(element, '(\\s|^)__se__format__free__closure_.+(\\s|$)'); - }, - - /** - * @description It is judged whether it is the component[img, iframe, video, audio, table] cover(class="se-component") and table, hr - * @param {Node} element The node to check - * @returns {Boolean} - */ - isComponent: function (element) { - return element && (/se-component/.test(element.className) || /^(TABLE|HR)$/.test(element.nodeName)); - }, - - /** - * @description Checks for "__se__uneditable" in the class list. - * Components with class "__se__uneditable" cannot be modified. - * @param {Element} element The element to check - * @returns {Boolean} - */ - isUneditableComponent: function (element) { - return element && this.hasClass(element, '__se__uneditable'); - }, - - /** - * @description It is judged whether it is the component [img, iframe] cover(class="se-component") - * @param {Node} element The node to check - * @returns {Boolean} - */ - isMediaComponent: function (element) { - return element && /se-component/.test(element.className); - }, - - /** - * @description It is judged whether it is the not checking node. (class="katex", "__se__tag") - * @param {Node} element The node to check - * @returns {Boolean} - */ - isNotCheckingNode: function (element) { - return element && /katex|__se__tag/.test(element.className); - }, - - /** - * @description If a parent node that contains an argument node finds a format node (util.isFormatElement), it returns that node. - * @param {Node} element Reference node. - * @param {Function|null} validation Additional validation function. - * @returns {Element|null} - */ - getFormatElement: function (element, validation) { - if (!element) return null; - if (!validation) { - validation = function () { return true; }; - } - - while (element) { - if (this.isWysiwygDiv(element)) return null; - if (this.isRangeFormatElement(element)) element.firstElementChild; - if (this.isFormatElement(element) && validation(element)) return element; - - element = element.parentNode; - } - - return null; - }, - - /** - * @description If a parent node that contains an argument node finds a format node (util.isRangeFormatElement), it returns that node. - * @param {Node} element Reference node. - * @param {Function|null} validation Additional validation function. - * @returns {Element|null} - */ - getRangeFormatElement: function (element, validation) { - if (!element) return null; - if (!validation) { - validation = function () { return true; }; - } - - while (element) { - if (this.isWysiwygDiv(element)) return null; - if (this.isRangeFormatElement(element) && !/^(THEAD|TBODY|TR)$/i.test(element.nodeName) && validation(element)) return element; - element = element.parentNode; - } - - return null; - }, - - /** - * @description If a parent node that contains an argument node finds a free format node (util.isFreeFormatElement), it returns that node. - * @param {Node} element Reference node. - * @param {Function|null} validation Additional validation function. - * @returns {Element|null} - */ - getFreeFormatElement: function (element, validation) { - if (!element) return null; - if (!validation) { - validation = function () { return true; }; - } - - while (element) { - if (this.isWysiwygDiv(element)) return null; - if (this.isFreeFormatElement(element) && validation(element)) return element; - - element = element.parentNode; - } - - return null; - }, - - /** - * @description If a parent node that contains an argument node finds a closure free format node (util.isClosureFreeFormatElement), it returns that node. - * @param {Node} element Reference node. - * @param {Function|null} validation Additional validation function. - * @returns {Element|null} - */ - getClosureFreeFormatElement: function (element, validation) { - if (!element) return null; - if (!validation) { - validation = function () { return true; }; - } - - while (element) { - if (this.isWysiwygDiv(element)) return null; - if (this.isClosureFreeFormatElement(element) && validation(element)) return element; - - element = element.parentNode; - } - - return null; - }, - - /** - * @description Add style and className of copyEl to originEl - * @param {Element} originEl Origin element - * @param {Element} copyEl Element to copy - */ - copyTagAttributes: function (originEl, copyEl) { - if (copyEl.style.cssText) { - originEl.style.cssText += copyEl.style.cssText; - } - - const classes = copyEl.classList; - for (let i = 0, len = classes.length; i < len; i++) { - this.addClass(originEl, classes[i]); - } - - if (!originEl.style.cssText) originEl.removeAttribute('style'); - if (!originEl.className.trim()) originEl.removeAttribute('class'); - }, - - /** - * @description Copy and apply attributes of format tag that should be maintained. (style, class) Ignore "__se__format__" class - * @param {Element} originEl Origin element - * @param {Element} copyEl Element to copy - */ - copyFormatAttributes: function (originEl, copyEl) { - copyEl = copyEl.cloneNode(false); - copyEl.className = copyEl.className.replace(/(\s|^)__se__format__[^\s]+/g, ''); - this.copyTagAttributes(originEl, copyEl); - }, - - /** - * @description Get the item from the array that matches the condition. - * @param {Array|HTMLCollection|NodeList} array Array to get item - * @param {Function|null} validation Conditional function - * @param {Boolean} multi If true, returns all items that meet the criteria otherwise, returns an empty array. - * If false, returns only one item that meet the criteria otherwise return null. - * @returns {Array|Node|null} - */ - getArrayItem: function (array, validation, multi) { - if (!array || array.length === 0) return null; - - validation = validation || function () { return true; }; - const arr = []; - - for (let i = 0, len = array.length, a; i < len; i++) { - a = array[i]; - if (validation(a)) { - if (!multi) return a; - else arr.push(a); - } - } - - return !multi ? null : arr; - }, - - /** - * @description Get the index of the argument value in the element array - * @param {Array|HTMLCollection|NodeList} array element array - * @param {Node} element The element to find index - * @returns {Number} - */ - getArrayIndex: function (array, element) { - let idx = -1; - for (let i = 0, len = array.length; i < len; i++) { - if (array[i] === element) { - idx = i; - break; - } - } - - return idx; - }, - - /** - * @description Get the next index of the argument value in the element array - * @param {Array|HTMLCollection|NodeList} array element array - * @param {Node} item The element to find index - * @returns {Number} - */ - nextIdx: function (array, item) { - let idx = this.getArrayIndex(array, item); - if (idx === -1) return -1; - return idx + 1; - }, - - /** - * @description Get the previous index of the argument value in the element array - * @param {Array|HTMLCollection|NodeList} array Element array - * @param {Node} item The element to find index - * @returns {Number} - */ - prevIdx: function (array, item) { - let idx = this.getArrayIndex(array, item); - if (idx === -1) return -1; - return idx - 1; - }, - - /** - * @description Returns the index compared to other sibling nodes. - * @param {Node} node The Node to find index - * @returns {Number} - */ - getPositionIndex: function (node) { - let idx = 0; - while ((node = node.previousSibling)) { - idx += 1; - } - return idx; - }, - - /** - * @description Returns the position of the "node" in the "parentNode" in a numerical array. - * ex)

aabb

: getNodePath(node: "bb", parentNode: "

") -> [1, 0] - * @param {Node} node The Node to find position path - * @param {Node|null} parentNode Parent node. If null, wysiwyg div area - * @param {Object|null} _newOffsets If you send an object of the form "{s: 0, e: 0}", the text nodes that are attached together are merged into one, centered on the "node" argument. - * "_newOffsets.s" stores the length of the combined characters after "node" and "_newOffsets.e" stores the length of the combined characters before "node". - * Do not use unless absolutely necessary. - * @returns {Array} - */ - getNodePath: function (node, parentNode, _newOffsets) { - const path = []; - let finds = true; - - this.getParentElement(node, function (el) { - if (el === parentNode) finds = false; - if (finds && !this.isWysiwygDiv(el)) { - // merge text nodes - if (_newOffsets && el.nodeType === 3) { - let temp = null, tempText = null; - _newOffsets.s = _newOffsets.e = 0; - - let previous = el.previousSibling; - while (previous && previous.nodeType === 3) { - tempText = previous.textContent.replace(this.zeroWidthRegExp, ''); - _newOffsets.s += tempText.length; - el.textContent = tempText + el.textContent; - temp = previous; - previous = previous.previousSibling; - this.removeItem(temp); - } - - let next = el.nextSibling; - while (next && next.nodeType === 3) { - tempText = next.textContent.replace(this.zeroWidthRegExp, ''); - _newOffsets.e += tempText.length; - el.textContent += tempText; - temp = next; - next = next.nextSibling; - this.removeItem(temp); - } - } - - // index push - path.push(el); - } - return false; - }.bind(this)); - - return path.map(this.getPositionIndex).reverse(); - }, - - /** - * @description Returns the node in the location of the path array obtained from "util.getNodePath". - * @param {Array} offsets Position array, array obtained from "util.getNodePath" - * @param {Node} parentNode Base parent element - * @returns {Node} - */ - getNodeFromPath: function (offsets, parentNode) { - let current = parentNode; - let nodes; - - for (let i = 0, len = offsets.length; i < len; i++) { - nodes = current.childNodes; - if (nodes.length === 0) break; - if (nodes.length <= offsets[i]) { - current = nodes[nodes.length - 1]; - } else { - current = nodes[offsets[i]]; - } - } - - return current; - }, - - /** - * @description Compares the style and class for equal values. - * Returns true if both are text nodes. - * @param {Node} a Node to compare - * @param {Node} b Node to compare - * @returns {Boolean} - */ - isSameAttributes: function (a, b) { - if (a.nodeType === 3 && b.nodeType === 3) return true; - if (a.nodeType === 3 || b.nodeType === 3) return false; - - const style_a = a.style; - const style_b = b.style; - let compStyle = 0; - - for (let i = 0, len = style_a.length; i < len; i++) { - if (style_a[style_a[i]] === style_b[style_a[i]]) compStyle++; - } - - const class_a = a.classList; - const class_b = b.classList; - const reg = this._w.RegExp; - let compClass = 0; - - for (let i = 0, len = class_a.length; i < len; i++) { - if (reg('(\s|^)' + class_a[i] + '(\s|$)').test(class_b.value)) compClass++; - } - - return (compStyle === style_b.length && compStyle === style_a.length) && (compClass === class_b.length && compClass === class_a.length); - }, - - /** - * @description Check the node is a list (ol, ul) - * @param {Node|String} node The element or element name to check - * @returns {Boolean} - */ - isList: function (node) { - return node && /^(OL|UL)$/i.test(typeof node === 'string' ? node : node.nodeName); - }, - - /** - * @description Check the node is a list cell (li) - * @param {Node|String} node The element or element name to check - * @returns {Boolean} - */ - isListCell: function (node) { - return node && /^LI$/i.test(typeof node === 'string' ? node : node.nodeName); - }, - - /** - * @description Check the node is a table (table, thead, tbody, tr, th, td) - * @param {Node|String} node The element or element name to check - * @returns {Boolean} - */ - isTable: function (node) { - return node && /^(TABLE|THEAD|TBODY|TR|TH|TD)$/i.test(typeof node === 'string' ? node : node.nodeName); - }, - - /** - * @description Check the node is a table cell (td, th) - * @param {Node|String} node The element or element name to check - * @returns {Boolean} - */ - isCell: function (node) { - return node && /^(TD|TH)$/i.test(typeof node === 'string' ? node : node.nodeName); - }, - - /** - * @description Check the node is a break node (BR) - * @param {Node|String} node The element or element name to check - * @returns {Boolean} - */ - isBreak: function (node) { - return node && /^BR$/i.test(typeof node === 'string' ? node : node.nodeName); - }, - - - /** - * @description Check the node is a anchor node (A) - * @param {Node|String} node The element or element name to check - * @returns {Boolean} - */ - isAnchor: function (node) { - return node && /^A$/i.test(typeof node === 'string' ? node : node.nodeName); - }, - - /** - * @description Check the node is a media node (img, iframe, audio, video, canvas) - * @param {Node|String} node The element or element name to check - * @returns {Boolean} - */ - isMedia: function (node) { - return node && /^(IMG|IFRAME|AUDIO|VIDEO|CANVAS)$/i.test(typeof node === 'string' ? node : node.nodeName); - }, - - /** - * @description Checks for numeric (with decimal point). - * @param {String|Number} text Text string or number - * @returns {Boolean} - */ - isNumber: function (text) { - return !!text && /^-?\d+(\.\d+)?$/.test(text + ''); - }, - - /** - * @description Get a number. - * @param {String|Number} text Text string or number - * @param {Number} maxDec Maximum number of decimal places (-1 : Infinity) - * @returns {Number} - */ - getNumber: function (text, maxDec) { - if (!text) return 0; - - let number = (text + '').match(/-?\d+(\.\d+)?/); - if (!number || !number[0]) return 0; - - number = number[0]; - return maxDec < 0 ? number * 1 : maxDec === 0 ? this._w.Math.round(number * 1) : (number * 1).toFixed(maxDec) * 1; - }, - - /** - * @description Get all "children" of the argument value element (Without text nodes) - * @param {Element} element element to get child node - * @param {Function|null} validation Conditional function - * @returns {Array} - */ - getListChildren: function (element, validation) { - const children = []; - if (!element || !element.children || element.children.length === 0) return children; - - validation = validation || function () { return true; }; - - (function recursionFunc(current) { - if (element !== current && validation(current)) { - children.push(current); - } - - for (let i = 0, len = current.children.length; i < len; i++) { - recursionFunc(current.children[i]); - } - })(element); - - return children; - }, - - /** - * @description Get all "childNodes" of the argument value element (Include text nodes) - * @param {Node} element element to get child node - * @param {Function|null} validation Conditional function - * @returns {Array} - */ - getListChildNodes: function (element, validation) { - const children = []; - if (!element || element.childNodes.length === 0) return children; - - validation = validation || function () { return true; }; - - (function recursionFunc(current) { - if (element !== current && validation(current)) { - children.push(current); - } - - for (let i = 0, len = current.childNodes.length; i < len; i++) { - recursionFunc(current.childNodes[i]); - } - })(element); - - return children; - }, - - /** - * @description Returns the number of parents nodes. - * "0" when the parent node is the WYSIWYG area. - * "-1" when the element argument is the WYSIWYG area. - * @param {Node} element The element to check - * @returns {Number} - */ - getElementDepth: function (element) { - if (!element || this.isWysiwygDiv(element)) return -1; - - let depth = 0; - element = element.parentNode; - - while (element && !this.isWysiwygDiv(element)) { - depth += 1; - element = element.parentNode; - } - - return depth; - }, - - /** - * @description Compares two elements to find a common ancestor, and returns the order of the two elements. - * @param {Node} a Node to compare. - * @param {Node} b Node to compare. - * @returns {Object} { ancesstor, a, b, result: (a > b ? 1 : a < b ? -1 : 0) }; - */ - compareElements: function (a, b) { - let aNode = a, bNode = b; - while (aNode && bNode && aNode.parentNode !== bNode.parentNode) { - aNode = aNode.parentNode; - bNode = bNode.parentNode; - } - - if (!aNode || !bNode) return { ancestor: null, a: a, b: b, result: 0 }; - - const children = aNode.parentNode.childNodes; - const aIndex = this.getArrayIndex(children, aNode); - const bIndex = this.getArrayIndex(children, bNode); - - return { - ancestor: aNode.parentNode, - a: aNode, - b: bNode, - result: aIndex > bIndex ? 1 : aIndex < bIndex ? -1 : 0 - }; - }, - - /** - * @description Get the parent element of the argument value. - * A tag that satisfies the query condition is imported. - * Returns null if not found. - * @param {Node} element Reference element - * @param {String|Function} query Query String (nodeName, .className, #ID, :name) or validation function. - * Not use it like jquery. - * Only one condition can be entered at a time. - * @returns {Element|null} - */ - getParentElement: function (element, query) { - let check; - - if (typeof query === 'function') { - check = query; - } else { - let attr; - if (/^\./.test(query)) { - attr = 'className'; - query = query.split('.')[1]; - } else if (/^#/.test(query)) { - attr = 'id'; - query = '^' + query.split('#')[1] + '$'; - } else if (/^:/.test(query)) { - attr = 'name'; - query = '^' + query.split(':')[1] + '$'; - } else { - attr = 'nodeName'; - query = '^' + query + '$'; - } - - const regExp = new this._w.RegExp(query, 'i'); - check = function (el) { - return regExp.test(el[attr]); - }; - } - - while (element && !check(element)) { - if (this.isWysiwygDiv(element)) { - return null; - } - element = element.parentNode; - } - - return element; - }, - - /** - * @description Get the child element of the argument value. - * A tag that satisfies the query condition is imported. - * Returns null if not found. - * @param {Node} element Reference element - * @param {String|Function} query Query String (nodeName, .className, #ID, :name) or validation function. - * @param {Boolean} last If true returns the last node among the found child nodes. (default: first node) - * Not use it like jquery. - * Only one condition can be entered at a time. - * @returns {Element|null} - */ - getChildElement: function (element, query, last) { - let check; - - if (typeof query === 'function') { - check = query; - } else { - let attr; - if (/^\./.test(query)) { - attr = 'className'; - query = query.split('.')[1]; - } else if (/^#/.test(query)) { - attr = 'id'; - query = '^' + query.split('#')[1] + '$'; - } else if (/^:/.test(query)) { - attr = 'name'; - query = '^' + query.split(':')[1] + '$'; - } else { - attr = 'nodeName'; - query = '^' + (query === 'text' ? '#' + query : query) + '$'; - } - - const regExp = new this._w.RegExp(query, 'i'); - check = function (el) { - return regExp.test(el[attr]); - }; - } - - const childList = this.getListChildNodes(element, function (current) { - return check(current); - }); - - return childList[last ? childList.length - 1 : 0]; - }, - - /** - * @description 1. The first node of all the child nodes of the "first" element is returned. - * 2. The last node of all the child nodes of the "last" element is returned. - * 3. When there is no "last" element, the first and last nodes of all the children of the "first" element are returned. - * { sc: "first", ec: "last" } - * @param {Node} first First element - * @param {Node|null} last Last element - * @returns {Object} - */ - getEdgeChildNodes: function (first, last) { - if (!first) return; - if (!last) last = first; - - while (first && first.nodeType === 1 && first.childNodes.length > 0 && !this.isBreak(first)) first = first.firstChild; - while (last && last.nodeType === 1 && last.childNodes.length > 0 && !this.isBreak(last)) last = last.lastChild; - - return { - sc: first, - ec: last || first - }; - }, - - /** - * @description Returns the position of the left and top of argument. {left:0, top:0} - * @param {Node} element Target node - * @param {Element|null} wysiwygFrame When use iframe option, iframe object should be sent (context.element.wysiwygFrame) - * @returns {Object} - */ - getOffset: function (element, wysiwygFrame) { - let offsetLeft = 0; - let offsetTop = 0; - let offsetElement = element.nodeType === 3 ? element.parentElement : element; - const wysiwyg = this.getParentElement(element, this.isWysiwygDiv.bind(this)); - - while (offsetElement && !this.hasClass(offsetElement, 'se-container') && offsetElement !== wysiwyg) { - offsetLeft += offsetElement.offsetLeft; - offsetTop += offsetElement.offsetTop; - offsetElement = offsetElement.offsetParent; - } - - const iframe = wysiwygFrame && /iframe/i.test(wysiwygFrame.nodeName); - - return { - left: offsetLeft + (iframe ? wysiwygFrame.parentElement.offsetLeft : 0), - top: (offsetTop - (wysiwyg ? wysiwyg.scrollTop : 0)) + (iframe ? wysiwygFrame.parentElement.offsetTop : 0) - }; - }, - - /** - * @description It compares the start and end indexes of "a" and "b" and returns the number of overlapping indexes in the range. - * ex) 1, 5, 4, 6 => "2" (4 ~ 5) - * @param {Number} aStart Start index of "a" - * @param {Number} aEnd End index of "a" - * @param {Number} bStart Start index of "b" - * @param {Number} bEnd Start index of "b" - * @returns {Number} - */ - getOverlapRangeAtIndex: function (aStart, aEnd, bStart, bEnd) { - if (aStart <= bEnd ? aEnd < bStart : aEnd > bStart) return 0; - - const overlap = (aStart > bStart ? aStart : bStart) - (aEnd < bEnd ? aEnd : bEnd); - return (overlap < 0 ? overlap * -1 : overlap) + 1; - }, - - /** - * @description Set the text content value of the argument value element - * @param {Node} element Element to replace text content - * @param {String} txt Text to be applied - */ - changeTxt: function (element, txt) { - if (!element || !txt) return; - element.textContent = txt; - }, - - /** - * @description Replace element - * @param {Element} element Target element - * @param {String|Element} newElement String or element of the new element to apply - */ - changeElement: function (element, newElement) { - if (typeof newElement === 'string') { - if (element.outerHTML) { - element.outerHTML = newElement; - } else { - const doc = this.createElement('DIV'); - doc.innerHTML = newElement; - newElement = doc.firstChild; - element.parentNode.replaceChild(newElement, element); - } - } else if (newElement.nodeType === 1) { - element.parentNode.replaceChild(newElement, element); - } - }, - - /** - * @description Set style, if all styles are deleted, the style properties are deleted. - * @param {Element} element Element to set style - * @param {String} styleName Style attribute name (marginLeft, textAlign...) - * @param {String|Number} value Style value - */ - setStyle: function (element, styleName, value) { - element.style[styleName] = value; - - if (!value && !element.style.cssText) { - element.removeAttribute('style'); - } - }, - - /** - * @description Determine whether any of the matched elements are assigned the given class - * @param {Element} element Elements to search class name - * @param {String} className Class name to search for - * @returns {Boolean} - */ - hasClass: function (element, className) { - if (!element) return; - - return (new this._w.RegExp(className)).test(element.className); - }, - - /** - * @description Append the className value of the argument value element - * @param {Element} element Elements to add class name - * @param {String} className Class name to be add - */ - addClass: function (element, className) { - if (!element) return; - - const check = new this._w.RegExp('(\\s|^)' + className + '(\\s|$)'); - if (check.test(element.className)) return; - - element.className += (element.className.length > 0 ? ' ' : '') + className; - }, - - /** - * @description Delete the className value of the argument value element - * @param {Element} element Elements to remove class name - * @param {String} className Class name to be remove - */ - removeClass: function (element, className) { - if (!element) return; - - const check = new this._w.RegExp('(\\s|^)' + className + '(\\s|$)'); - element.className = element.className.replace(check, ' ').trim(); - - if (!element.className.trim()) element.removeAttribute('class'); - }, - - /** - * @description Argument value If there is no class name, insert it and delete the class name if it exists - * @param {Element} element Elements to replace class name - * @param {String} className Class name to be change - * @returns {Boolean|undefined} - */ - toggleClass: function (element, className) { - if (!element) return; - let result = false; - - const check = new this._w.RegExp('(\\s|^)' + className + '(\\s|$)'); - if (check.test(element.className)) { - element.className = element.className.replace(check, ' ').trim(); - } else { - element.className += ' ' + className; - result = true; - } - - if (!element.className.trim()) element.removeAttribute('class'); - - return result; - }, - - /** - * @description In the predefined code view mode, the buttons except the executable button are changed to the 'disabled' state. - * core.codeViewDisabledButtons (An array of buttons whose class name is not "se-code-view-enabled") - * core.resizingDisabledButtons (An array of buttons whose class name is not "se-resizing-enabled") - * @param {Boolean} disabled Disabled value - * @param {Array|HTMLCollection|NodeList} buttonList Button array - */ - setDisabledButtons: function (disabled, buttonList) { - for (let i = 0, len = buttonList.length; i < len; i++) { - buttonList[i].disabled = disabled; - } - }, - - /** - * @description Delete argumenu value element - * @param {Node} item Node to be remove - */ - removeItem: function (item) { - if (!item) return; - try { - item.remove(); - } catch (e) { - if (item.parentNode) item.parentNode.removeChild(item); - } - }, - - /** - * @description Delete all parent nodes that match the condition. - * Returns an {sc: previousSibling, ec: nextSibling}(the deleted node reference) or null. - * @param {Node} item Node to be remove - * @param {Function|null} validation Validation function. default(Deleted if it only have breakLine and blanks) - * @param {Element|null} stopParent Stop when the parent node reaches stopParent - * @returns {Object|null} {sc: previousSibling, ec: nextSibling} - */ - removeItemAllParents: function (item, validation, stopParent) { - if (!item) return null; - let cc = null; - if (!validation) { - validation = function (current) { - if (current === stopParent || this.isComponent(current)) return false; - const text = current.textContent.trim(); - return text.length === 0 || /^(\n|\u200B)+$/.test(text); - }.bind(this); - } - - (function recursionFunc (element) { - if (!util.isWysiwygDiv(element)) { - const parent = element.parentNode; - if (parent && validation(element)) { - cc = { - sc: element.previousElementSibling, - ec: element.nextElementSibling - }; - util.removeItem(element); - recursionFunc(parent); - } - } - }(item)); - - return cc; - }, - - /** - * @description Detach Nested all nested lists under the "baseNode". - * Returns a list with nested removed. - * @param {Node} baseNode Element on which to base. - * @param {Boolean} all If true, it also detach all nested lists of a returned list. - * @returns {Element} - */ - detachNestedList: function (baseNode, all) { - const rNode = this._deleteNestedList(baseNode); - let rangeElement, cNodes; - - if (rNode) { - rangeElement = rNode.cloneNode(false); - cNodes = rNode.childNodes; - const index = this.getPositionIndex(baseNode); - while (cNodes[index]) { - rangeElement.appendChild(cNodes[index]); - } - } else { - rangeElement = baseNode; - } - - let rChildren; - if (!all) { - const depth = this.getElementDepth(baseNode) + 2; - rChildren = this.getListChildren(baseNode, function (current) { return this.isListCell(current) && !current.previousElementSibling && this.getElementDepth(current) === depth; }.bind(this)); - } else { - rChildren = this.getListChildren(rangeElement, function (current) { return this.isListCell(current) && !current.previousElementSibling; }.bind(this)); - } - - for (let i = 0, len = rChildren.length; i < len; i++) { - this._deleteNestedList(rChildren[i]); - } - - if (rNode) { - rNode.parentNode.insertBefore(rangeElement, rNode.nextSibling); - if (cNodes && cNodes.length === 0) this.removeItem(rNode); - } - - return rangeElement === baseNode ? rangeElement.parentNode : rangeElement; - }, - - /** - * @description Sub function of util.detachNestedList method. - * @private - */ - _deleteNestedList: function (baseNode) { - const baseParent = baseNode.parentNode; - let sibling = baseParent; - let parent = sibling.parentNode; - let liSibling, liParent, child, index, c; - - while (this.isListCell(parent)) { - index = this.getPositionIndex(baseNode); - liSibling = parent.nextElementSibling; - liParent = parent.parentNode; - child = sibling; - while(child) { - sibling = sibling.nextSibling; - if (this.isList(child)) { - c = child.childNodes; - while (c[index]) { - liParent.insertBefore(c[index], liSibling); - } - if (c.length === 0) this.removeItem(child); - } else { - liParent.appendChild(child); - } - child = sibling; - } - sibling = liParent; - parent = liParent.parentNode; - } - - if (baseParent.children.length === 0) this.removeItem(baseParent); - - return liParent; - }, - - /** - * @description Split all tags based on "baseNode" - * Returns the last element of the splited tag. - * @param {Node} baseNode Element or text node on which to base - * @param {Number|null} offset Text offset of "baseNode" (Only valid when "baseNode" is a text node) - * @param {Number} depth The nesting depth of the element being split. (default: 0) - * @returns {Element} - */ - splitElement: function (baseNode, offset, depth) { - const bp = baseNode.parentNode; - let index = 0, newEl, children, temp; - let next = true; - if (!depth || depth < 0) depth = 0; - - if (baseNode.nodeType === 3) { - index = this.getPositionIndex(baseNode); - if (offset >= 0) { - baseNode.splitText(offset); - const after = this.getNodeFromPath([index + 1], bp); - if (this.onlyZeroWidthSpace(after)) after.data = this.zeroWidthSpace; - } - } else if (baseNode.nodeType === 1) { - if (!baseNode.previousSibling) { - if (this.getElementDepth(baseNode) === depth) next = false; - } else { - baseNode = baseNode.previousSibling; - } - } - - let depthEl = baseNode; - while (this.getElementDepth(depthEl) > depth) { - index = this.getPositionIndex(depthEl) + 1; - depthEl = depthEl.parentNode; - - temp = newEl; - newEl = depthEl.cloneNode(false); - children = depthEl.childNodes; - - if (temp) { - if (this.isListCell(newEl) && this.isList(temp) && temp.firstElementChild) { - newEl.innerHTML = temp.firstElementChild.innerHTML; - util.removeItem(temp.firstElementChild); - if (temp.children.length > 0) newEl.appendChild(temp); - } else { - newEl.appendChild(temp); - } - } - - while (children[index]) { - newEl.appendChild(children[index]); - } - } - - if (depthEl.childNodes.length <= 1 && (!depthEl.firstChild || depthEl.firstChild.textContent.length === 0)) depthEl.innerHTML = '
'; - - const pElement = depthEl.parentNode; - if (next) depthEl = depthEl.nextSibling; - if (!newEl) return depthEl; - - this.mergeSameTags(newEl, null, false); - this.mergeNestedTags(newEl, function (current) { return this.isList(current); }.bind(this)); - - if (newEl.childNodes.length > 0) pElement.insertBefore(newEl, depthEl); - else newEl = depthEl; - - if (bp.childNodes.length === 0) this.removeItem(bp); - - return newEl; - }, - - /** - * @description Use with "npdePath (util.getNodePath)" to merge the same attributes and tags if they are present and modify the nodepath. - * If "offset" has been changed, it will return as much "offset" as it has been modified. - * An array containing change offsets is returned in the order of the "nodePathArray" array. - * @param {Element} element Element - * @param {Array|null} nodePathArray Array of NodePath object ([util.getNodePath(), ..]) - * @param {Boolean} onlyText If true, non-text nodes(!util._isIgnoreNodeChange) like 'span', 'strong'.. are ignored. - * @returns {Array} [offset, ..] - */ - mergeSameTags: function (element, nodePathArray, onlyText) { - const inst = this; - const nodePathLen = nodePathArray ? nodePathArray.length : 0; - let offsets = null; - - if (nodePathLen) { - offsets = this._w.Array.apply(null, new this._w.Array(nodePathLen)).map(this._w.Number.prototype.valueOf, 0); - } - - (function recursionFunc(current, depth, depthIndex) { - const children = current.childNodes; - - for (let i = 0, len = children.length, child, next; i < len; i++) { - child = children[i]; - next = children[i + 1]; - if (!child) break; - if((onlyText && inst._isIgnoreNodeChange(child)) || (!onlyText && (inst.isTable(child) || inst.isListCell(child) || (inst.isFormatElement(child) && !inst.isFreeFormatElement(child))))) { - if (inst.isTable(child) || inst.isListCell(child)) { - recursionFunc(child, depth + 1, i); - } - continue; - } - if (len === 1 && current.nodeName === child.nodeName && current.parentNode) { - // update nodePath - if (nodePathLen) { - let path, c, p, cDepth, spliceDepth; - for (let n = 0; n < nodePathLen; n++) { - path = nodePathArray[n]; - if (path && path[depth] === i) { - c = child, p = current, cDepth = depth, spliceDepth = true; - while (cDepth >= 0) { - if (inst.getArrayIndex(p.childNodes, c) !== path[cDepth]) { - spliceDepth = false; - break; - } - c = child.parentNode; - p = c.parentNode; - cDepth--; - } - if (spliceDepth) { - path.splice(depth, 1); - path[depth] = i; - } - } - } - } - - // merge tag - inst.copyTagAttributes(child, current); - current.parentNode.insertBefore(child, current); - inst.removeItem(current); - } - if (!next) { - if (child.nodeType === 1) recursionFunc(child, depth + 1, i); - break; - } - - if (child.nodeName === next.nodeName && inst.isSameAttributes(child, next) && child.href === next.href) { - const childs = child.childNodes; - let childLength = 0; - for (let n = 0, nLen = childs.length; n < nLen; n++) { - if (childs[n].textContent.length > 0) childLength++; - } - - const l = child.lastChild; - const r = next.firstChild; - let addOffset = 0; - if (l && r) { - const textOffset = l.nodeType === 3 && r.nodeType === 3; - addOffset = l.textContent.length; - let tempL = l.previousSibling; - while(tempL && tempL.nodeType === 3) { - addOffset += tempL.textContent.length; - tempL = tempL.previousSibling; - } - - if (childLength > 0 && l.nodeType === 3 && r.nodeType === 3 && (l.textContent.length > 0 || r.textContent.length > 0)) childLength--; - - if (nodePathLen) { - let path = null; - for (let n = 0; n < nodePathLen; n++) { - path = nodePathArray[n]; - if (path && path[depth] > i) { - if (depth > 0 && path[depth - 1] !== depthIndex) continue; - - path[depth] -= 1; - if (path[depth + 1] >= 0 && path[depth] === i) { - path[depth + 1] += childLength; - if (textOffset) { - if (l && l.nodeType === 3 && r && r.nodeType === 3) { - offsets[n] += addOffset; - } - } - } - } - } - } - } - - if (child.nodeType === 3) { - addOffset = child.textContent.length; - child.textContent += next.textContent; - if (nodePathLen) { - let path = null; - for (let n = 0; n < nodePathLen; n++) { - path = nodePathArray[n]; - if (path && path[depth] > i) { - if (depth > 0 && path[depth - 1] !== depthIndex) continue; - - path[depth] -= 1; - if (path[depth + 1] >= 0 && path[depth] === i) { - path[depth + 1] += childLength; - offsets[n] += addOffset; - } - } - } - } - } else { - child.innerHTML += next.innerHTML; - } - - inst.removeItem(next); - i--; - } else if (child.nodeType === 1) { - recursionFunc(child, depth + 1, i); - } - } - })(element, 0, 0); - - return offsets; - }, - - /** - * @description Remove nested tags without other child nodes. - * @param {Element} element Element object - * @param {Function|String|null} validation Validation function / String("tag1|tag2..") / If null, all tags are applicable. - */ - mergeNestedTags: function (element, validation) { - if (typeof validation === 'string') { - validation = function (current) { return this.test(current.tagName); }.bind(new this._w.RegExp('^(' + (validation ? validation : '.+') + ')$', 'i')); - } else if (typeof validation !== 'function') { - validation = function () { return true; }; - } - - (function recursionFunc(current) { - let children = current.children; - if (children.length === 1 && children[0].nodeName === current.nodeName && validation(current)) { - const temp = children[0]; - children = temp.children; - while (children[0]) { - current.appendChild(children[0]); - } - current.removeChild(temp); - } - - for (let i = 0, len = current.children.length; i < len; i++) { - recursionFunc(current.children[i]); - } - })(element); - }, - - /** - * @description Delete a empty child node of argument element - * @param {Element} element Element node - * @param {Node|null} notRemoveNode Do not remove node - */ - removeEmptyNode: function (element, notRemoveNode) { - const inst = this; - - if (notRemoveNode) { - notRemoveNode = inst.getParentElement(notRemoveNode, function (current) { - return element === current.parentElement; - }); - } - - (function recursionFunc(current) { - if (inst._notTextNode(current) || current === notRemoveNode || inst.isNonEditable(current)) return 0; - if (current !== element && inst.onlyZeroWidthSpace(current.textContent) && (!current.firstChild || !inst.isBreak(current.firstChild))) { - if (current.parentNode) { - current.parentNode.removeChild(current); - return -1; - } - } else { - const children = current.children; - for (let i = 0, len = children.length, r = 0; i < len; i++) { - if (!children[i + r] || inst.isComponent(children[i + r])) continue; - r += recursionFunc(children[i + r]); - } - } - - return 0; - })(element); - - if (element.childNodes.length === 0) element.innerHTML = '
'; - }, - - /** - * @description Remove whitespace between tags in HTML string. - * @param {String} html HTML string - * @returns {String} - */ - htmlRemoveWhiteSpace: function (html) { - if (!html) return ''; - return html.trim().replace(/<\/?(?!strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label|code)[^>^<]+>\s+(?=<)/ig, function (m) { return m.trim(); }); - }, - - /** - * @description Sort a element array by depth of element. - * @param {Array} array Array object - * @param {Boolean} des true: descending order / false: ascending order - */ - sortByDepth: function (array, des) { - const t = !des ? -1 : 1; - const f = t * -1; - - array.sort(function (a, b) { - if (!this.isListCell(a) || !this.isListCell(b)) return 0; - a = this.getElementDepth(a); - b = this.getElementDepth(b); - return a > b ? t : a < b ? f : 0; - }.bind(this)); - }, - - /** - * @description Nodes that need to be added without modification when changing text nodes - * @param {Node} element Element to check - * @returns {Boolean} - * @private - */ - _isIgnoreNodeChange: function (element) { - return element && element.nodeType !== 3 && (this.isNonEditable(element) || !this.isTextStyleElement(element)); - }, - - /** - * @description Nodes that must remain undetached when changing text nodes (A, Label, Code) - * @param {Node|String} element Element to check - * @returns {Boolean} - * @private - */ - _isMaintainedNode: function (element) { - return element && element.nodeType !== 3 && /^(a|label|code)$/i.test(typeof element === 'string' ? element : element.nodeName); - }, - - /** - * @description Node with font-size style - * @param {Node} element Element to check - * @returns {Boolean} - * @private - */ - _isSizeNode: function (element) { - return element && element.nodeType !== 3 && this.isTextStyleElement(element) && !!element.style.fontSize; - }, - - /** - * @description Nodes without text - * @param {Node} element Element to check - * @returns {Boolean} - * @private - */ - _notTextNode: function (element) { - return element && element.nodeType !== 3 && (this.isComponent(element) || /^(br|input|select|canvas|img|iframe|audio|video)$/i.test(typeof element === 'string' ? element : element.nodeName)); - }, - - /** - * @description Check disallowed tags - * @param {Node} element Element to check - * @returns {Boolean} - * @private - */ - _disallowedTags: function (element) { - return /^(meta|script|link|style|[a-z]+\:[a-z]+)$/i.test(element.nodeName); - }, - - /** - * @description Create whitelist RegExp object. - * Return RegExp format: new RegExp("<\\/?\\b(?!" + list + ")\\b[^>^<]*+>", "gi") - * @param {String} list Tags list ("br|p|div|pre...") - * @returns {RegExp} - */ - createTagsWhitelist: function (list) { - return new RegExp('<\\/?\\b(?!\\b' + list.replace(/\|/g, '\\b|\\b') + '\\b)[^>]*>', 'gi'); - }, - - /** - * @description Get key of the options.allowStyles - * @param {Node} node Node - * @returns {String} - * @private - */ - _getCheckFormat: function (node) { - return node.nodeType === 3 ? 'null' : - this.isComponent(node) ? 'component' : - this.isClosureFreeFormatElement(node) ? 'closureFreeFormat' : - this.isFreeFormatElement(node) ? 'freeFormat' : - this.isClosureRangeFormatElement(node) ? 'closureRangeFormat' : - this.isRangeFormatElement(node) ? 'rangeFormat' : - this.isFormatElement(node) ? 'format' : node.nodeName.toLowerCase(); - }, - - /** - * @description Fix tags that do not fit the editor format. - * @param {Element} documentFragment Document fragment "DOCUMENT_FRAGMENT_NODE" (nodeType === 11) - * @param {RegExp} htmlCheckWhitelistRegExp Editor tags whitelist (core._htmlCheckWhitelistRegExp) - * @param {Object} allowStyles options.allowStyles - * @private - */ - _consistencyCheckOfHTML: function (documentFragment, htmlCheckWhitelistRegExp, allowStyles) { - /** - * It is can use ".children(util.getListChildren)" to exclude text nodes, but "documentFragment.children" is not supported in IE. - * So check the node type and exclude the text no (current.nodeType !== 1) - */ - const removeTags = [], emptyTags = [], wrongList = [], withoutFormatCells = []; - - // wrong position - const wrongTags = this.getListChildNodes(documentFragment, function (current) { - if (current.nodeType !== 1) return false; - - // white list - if (!htmlCheckWhitelistRegExp.test(current.nodeName) && current.childNodes.length === 0 && this.isNotCheckingNode(current)) { - removeTags.push(current); - return false; - } - - const nrtag = !this.getParentElement(current, this.isNotCheckingNode); - // empty tags - if ((!this.isTable(current) && !this.isListCell(current)) && (this.isFormatElement(current) || this.isRangeFormatElement(current) || this.isTextStyleElement(current)) && current.childNodes.length === 0 && nrtag) { - emptyTags.push(current); - return false; - } - - // wrong list - if (this.isList(current.parentNode) && !this.isList(current) && !this.isListCell(current)) { - wrongList.push(current); - return false; - } - - // table cells - if (this.isCell(current)) { - const fel = current.firstElementChild; - if (!this.isFormatElement(fel) && !this.isRangeFormatElement(fel) && !this.isComponent(fel)) { - withoutFormatCells.push(current); - return false; - } - } - - const result = current.parentNode !== documentFragment && - (this.isFormatElement(current) || this.isComponent(current) || this.isList(current)) && - !this.isRangeFormatElement(current.parentNode) && !this.isListCell(current.parentNode) && - !this.getParentElement(current, this.isComponent) && nrtag; - - // @v3 - // if (!result) { - // const styles = allowStyles[this._getCheckFormat(current)]; - // if (!!styles && styles.length > 0) { - // let s = ''; - // const currentStyle = current.style; - // for (let i = 0, len = styles.length; i < len; i++) { - // s += styles[i] + ':' + currentStyle[styles[i]] + '; '; - // } - - // if (!s) current.removeAttribute('style'); - // else current.style.cssText = s; - // } - // } - - return result; - }.bind(this)); - - for (let i = 0, len = removeTags.length; i < len; i++) { - this.removeItem(removeTags[i]); - } - - const checkTags = []; - for (let i = 0, len = wrongTags.length, t, p; i < len; i++) { - t = wrongTags[i]; - p = t.parentNode; - if (!p || !p.parentNode) continue; - p.parentNode.insertBefore(t, p); - checkTags.push(p); - } - - for (let i = 0, len = checkTags.length, t; i < len; i++) { - t = checkTags[i]; - if (this.onlyZeroWidthSpace(t.textContent.trim())) { - this.removeItem(t); - } - } - - for (let i = 0, len = emptyTags.length; i < len; i++) { - this.removeItem(emptyTags[i]); - } - - for (let i = 0, len = wrongList.length, t, tp, children, p; i < len; i++) { - t = wrongList[i]; - - tp = this.createElement('LI'); - children = t.childNodes; - while (children[0]) { - tp.appendChild(children[0]); - } - - p = t.parentNode; - if (!p) continue; - p.insertBefore(tp, t); - this.removeItem(t); - } - - for (let i = 0, len = withoutFormatCells.length, t, f; i < len; i++) { - t = withoutFormatCells[i]; - f = this.createElement('DIV'); - f.innerHTML = (t.textContent.trim().length === 0 && t.children.length === 0) ? '
' : t.innerHTML; - t.innerHTML = f.outerHTML; - } - }, - - _setDefaultOptionStyle: function (options, defaultStyle) { - let optionStyle = ''; - if (options.height) optionStyle += 'height:' + options.height + ';'; - if (options.minHeight) optionStyle += 'min-height:' + options.minHeight + ';'; - if (options.maxHeight) optionStyle += 'max-height:' + options.maxHeight + ';'; - if (options.position) optionStyle += 'position:' + options.position + ';'; - if (options.width) optionStyle += 'width:' + options.width + ';'; - if (options.minWidth) optionStyle += 'min-width:' + options.minWidth + ';'; - if (options.maxWidth) optionStyle += 'max-width:' + options.maxWidth + ';'; - - let top = '', frame = '', editor = ''; - defaultStyle = optionStyle + defaultStyle; - const styleArr = defaultStyle.split(';'); - for (let i = 0, len = styleArr.length, s; i < len; i++) { - s = styleArr[i].trim(); - if (!s) continue; - if (/^(min-|max-)?width\s*:/.test(s)) { - top += s + ';'; - continue; - } - if (/^(min-|max-)?height\s*:/.test(s)) { - if (/^height/.test(s) && s.split(':')[1].trim() === 'auto') { - options.height = 'auto'; - } - frame += s + ';'; - continue; - } - editor += s + ';'; - } - - return { - top: top, - frame: frame, - editor: editor - }; - }, - - _setIframeDocument: function (frame, options) { - frame.setAttribute('scrolling', 'auto'); - frame.contentDocument.head.innerHTML = '' + - '' + - '' + - this._setIframeCssTags(options); - frame.contentDocument.body.className = options._editableClass; - frame.contentDocument.body.setAttribute('contenteditable', true); - }, - - _setIframeCssTags: function (options) { - const linkNames = options.iframeCSSFileName; - const wRegExp = this._w.RegExp; - let tagString = ''; - - for (let f = 0, len = linkNames.length, path; f < len; f++) { - path = []; - - if (/(^https?:\/\/)|(^data:text\/css,)/.test(linkNames[f])) { - path.push(linkNames[f]); - } else { - const CSSFileName = new wRegExp('(^|.*[\\/])' + linkNames[f] + '(\\..+)?\\.css(?:\\?.*|;.*)?$', 'i'); - for (let c = document.getElementsByTagName('link'), i = 0, len = c.length, styleTag; i < len; i++) { - styleTag = c[i].href.match(CSSFileName); - if (styleTag) path.push(styleTag[0]); - } - } - - if (!path || path.length === 0) throw '[SUNEDITOR.constructor.iframe.fail] The suneditor CSS files installation path could not be automatically detected. Please set the option property "iframeCSSFileName" before creating editor instances.'; - - for (let i = 0, len = path.length; i < len; i++) { - tagString += ''; - } - } - - return tagString + (options.height === 'auto' ? '' : ''); - } -}; - -/* harmony default export */ __webpack_exports__["default"] = (util); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/command/blockquote.js": -/*!******************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/command/blockquote.js ***! - \******************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'blockquote', - display: 'command', - add: function (core, targetElement) { - const context = core.context; - context.blockquote = { - targetButton: targetElement, - tag: core.util.createElement('BLOCKQUOTE') - }; - }, - - /** - * @Override core - */ - active: function (element) { - if (!element) { - this.util.removeClass(this.context.blockquote.targetButton, 'active'); - } else if (/blockquote/i.test(element.nodeName)) { - this.util.addClass(this.context.blockquote.targetButton, 'active'); - return true; - } - - return false; - }, - - /** - * @Override core - */ - action: function () { - const currentBlockquote = this.util.getParentElement(this.getSelectionNode(), 'blockquote'); - - if (currentBlockquote) { - this.detachRangeFormatElement(currentBlockquote, null, null, false, false); - } else { - this.applyRangeFormatElement(this.context.blockquote.tag.cloneNode(false)); - } - } -}); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/dialog/audio.js": -/*!************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/dialog/audio.js ***! - \************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/dialog */ "./node_modules/suneditor/src/plugins/modules/dialog.js"); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_modules_dialog__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _modules_component__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../modules/component */ "./node_modules/suneditor/src/plugins/modules/component.js"); -/* harmony import */ var _modules_component__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_modules_component__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _modules_fileManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../modules/fileManager */ "./node_modules/suneditor/src/plugins/modules/fileManager.js"); -/* harmony import */ var _modules_fileManager__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_modules_fileManager__WEBPACK_IMPORTED_MODULE_2__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - - - - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'audio', - display: 'dialog', - add: function (core) { - core.addModule([_modules_dialog__WEBPACK_IMPORTED_MODULE_0___default.a, _modules_component__WEBPACK_IMPORTED_MODULE_1___default.a, _modules_fileManager__WEBPACK_IMPORTED_MODULE_2___default.a]); - - const context = core.context; - const contextAudio = context.audio = { - _infoList: [], // @Override fileManager - _infoIndex: 0, // @Override fileManager - _uploadFileLength: 0, // @Override fileManager - focusElement: null, // @Override dialog // This element has focus when the dialog is opened. - targetSelect: null, - _origin_w: core.options.audioWidth, - _origin_h: core.options.audioHeight, - _linkValue: '', - // @require @Override component - _element: null, - _cover: null, - _container: null, - }; - - /** dialog */ - let audio_dialog = this.setDialog(core); - contextAudio.modal = audio_dialog; - contextAudio.audioInputFile = audio_dialog.querySelector('._se_audio_files'); - contextAudio.audioUrlFile = audio_dialog.querySelector('.se-input-url'); - contextAudio.focusElement = contextAudio.audioInputFile || contextAudio.audioUrlFile; - contextAudio.preview = audio_dialog.querySelector('.se-link-preview'); - - /** controller */ - let audio_controller = this.setController(core); - contextAudio.controller = audio_controller; - - /** add event listeners */ - audio_dialog.querySelector('form').addEventListener('submit', this.submit.bind(core)); - if (contextAudio.audioInputFile) audio_dialog.querySelector('.se-dialog-files-edge-button').addEventListener('click', this._removeSelectedFiles.bind(contextAudio.audioInputFile, contextAudio.audioUrlFile, contextAudio.preview)); - if (contextAudio.audioInputFile && contextAudio.audioUrlFile) contextAudio.audioInputFile.addEventListener('change', this._fileInputChange.bind(contextAudio)); - audio_controller.addEventListener('click', this.onClick_controller.bind(core)); - if (contextAudio.audioUrlFile) contextAudio.audioUrlFile.addEventListener('input', this._onLinkPreview.bind(contextAudio.preview, contextAudio, core.options.linkProtocol)); - - /** append html */ - context.dialog.modal.appendChild(audio_dialog); - - /** append controller */ - context.element.relative.appendChild(audio_controller); - - /** empty memory */ - audio_dialog = null, audio_controller = null; - }, - - /** HTML - dialog */ - setDialog: function (core) { - const option = core.options; - const lang = core.lang; - const dialog = core.util.createElement('DIV'); - - dialog.className = 'se-dialog-content'; - dialog.style.display = 'none'; - let html = '' + - '

' + - '
' + - '' + - '' + lang.dialogBox.audioBox.title + '' + - '
' + - '
'; - - if (option.audioFileInput) { - html += '' + - '
' + - '' + - '
' + - '' + - '' + - '
' + - '
'; - } - - if (option.audioUrlInput) { - html += '' + - '
' + - '' + - '' + - '' + - '
'; - } - - html += '' + - '
' + - '' + - '
'; - - dialog.innerHTML = html; - - return dialog; - }, - - /** HTML - controller */ - setController: function (core) { - const lang = core.lang; - const icons = core.icons; - const link_btn = core.util.createElement('DIV'); - - link_btn.className = 'se-controller se-controller-link'; - link_btn.innerHTML = '' + - '
' + - ''; - - return link_btn; - }, - - // Disable url input when uploading files - _fileInputChange: function () { - if (!this.audioInputFile.value) { - this.audioUrlFile.removeAttribute('disabled'); - this.preview.style.textDecoration = ''; - } else { - this.audioUrlFile.setAttribute('disabled', true); - this.preview.style.textDecoration = 'line-through'; - } - }, - - // Disable url input when uploading files - _removeSelectedFiles: function (urlInput, preview) { - this.value = ''; - if (urlInput) { - urlInput.removeAttribute('disabled'); - preview.style.textDecoration = ''; - } - }, - - // create new audio tag - _createAudioTag: function () { - const oAudio = this.util.createElement('AUDIO'); - this.plugins.audio._setTagAttrs.call(this, oAudio); - - const w = this.context.audio._origin_w; - const h = this.context.audio._origin_h; - oAudio.setAttribute('origin-size', w + ',' + h); - oAudio.style.cssText = (w ? ('width:' + w + '; ') : '') + (h ? ('height:' + h + ';') : ''); - - return oAudio; - }, - - _setTagAttrs: function (element) { - element.setAttribute('controls', true); - - const attrs = this.options.audioTagAttrs; - if (!attrs) return; - - for (let key in attrs) { - if (!this.util.hasOwn(attrs, key)) continue; - element.setAttribute(key, attrs[key]); - } - }, - - _onLinkPreview: function (context, protocol, e) { - const value = e.target.value.trim(); - context._linkValue = this.textContent = !value ? '' : (protocol && value.indexOf('://') === -1 && value.indexOf('#') !== 0) ? protocol + value : value.indexOf('://') === -1 ? '/' + value : value; - }, - - /** - * @Required @Override fileManager - */ - fileTags: ['audio'], - - /** - * @Override core, fileManager, resizing - * @description It is called from core.selectComponent. - * @param {Element} element Target element - */ - select: function (element) { - this.plugins.audio.onModifyMode.call(this, element); - }, - - /** - * @Override fileManager, resizing - */ - destroy: function (element) { - element = element || this.context.audio._element; - const container = this.util.getParentElement(element, this.util.isComponent) || element; - const dataIndex = element.getAttribute('data-index') * 1; - const focusEl = (container.previousElementSibling || container.nextElementSibling); - - const emptyDiv = container.parentNode; - this.util.removeItem(container); - this.plugins.audio.init.call(this); - this.controllersOff(); - - if (emptyDiv !== this.context.element.wysiwyg) this.util.removeItemAllParents(emptyDiv, function (current) { return current.childNodes.length === 0; }, null); - - // focus - this.focusEdge(focusEl); - - // fileManager event - this.plugins.fileManager.deleteInfo.call(this, 'audio', dataIndex, this.functions.onAudioUpload); - - // history stack - this.history.push(false); - }, - - /** - * @Override fileManager - */ - checkFileInfo: function () { - this.plugins.fileManager.checkInfo.call(this, 'audio', ['audio'], this.functions.onAudioUpload, this.plugins.audio.updateCover.bind(this), false); - }, - - /** - * @Override fileManager - */ - resetFileInfo: function () { - this.plugins.fileManager.resetInfo.call(this, 'audio', this.functions.onAudioUpload); - }, - - /** - * @Required @Override dialog - */ - on: function (update) { - const contextAudio = this.context.audio; - - if (!update) { - this.plugins.audio.init.call(this); - if (contextAudio.audioInputFile && this.options.audioMultipleFile) contextAudio.audioInputFile.setAttribute('multiple', 'multiple'); - } else if (contextAudio._element) { - this.context.dialog.updateModal = true; - contextAudio._linkValue = contextAudio.preview.textContent = contextAudio.audioUrlFile.value = contextAudio._element.src; - if (contextAudio.audioInputFile && this.options.audioMultipleFile) contextAudio.audioInputFile.removeAttribute('multiple'); - } else { - if (contextAudio.audioInputFile && this.options.audioMultipleFile) contextAudio.audioInputFile.removeAttribute('multiple'); - } - }, - - /** - * @Required @Override dialog - */ - open: function () { - this.plugins.dialog.open.call(this, 'audio', 'audio' === this.currentControllerName); - }, - - submit: function (e) { - const contextAudio = this.context.audio; - - e.preventDefault(); - e.stopPropagation(); - - try { - if (contextAudio.audioInputFile && contextAudio.audioInputFile.files.length > 0) { - this.showLoading(); - this.plugins.audio.submitAction.call(this, contextAudio.audioInputFile.files); - } else if (contextAudio.audioUrlFile && contextAudio._linkValue.length > 0) { - this.showLoading(); - this.plugins.audio.setupUrl.call(this, contextAudio._linkValue); - } - } catch (error) { - this.closeLoading(); - throw Error('[SUNEDITOR.audio.submit.fail] cause : "' + error.message + '"'); - } finally { - this.plugins.dialog.close.call(this); - } - - return false; - }, - - submitAction: function (fileList) { - if (fileList.length === 0) return; - - let fileSize = 0; - let files = []; - for (let i = 0, len = fileList.length; i < len; i++) { - if (/audio/i.test(fileList[i].type)) { - files.push(fileList[i]); - fileSize += fileList[i].size; - } - } - - const limitSize = this.options.audioUploadSizeLimit; - if (limitSize > 0) { - let infoSize = 0; - const audiosInfo = this.context.audio._infoList; - for (let i = 0, len = audiosInfo.length; i < len; i++) { - infoSize += audiosInfo[i].size * 1; - } - - if ((fileSize + infoSize) > limitSize) { - this.closeLoading(); - const err = '[SUNEDITOR.audioUpload.fail] Size of uploadable total audios: ' + (limitSize/1000) + 'KB'; - if (typeof this.functions.onAudioUploadError !== 'function' || this.functions.onAudioUploadError(err, { 'limitSize': limitSize, 'currentSize': infoSize, 'uploadSize': fileSize }, this)) { - this.functions.noticeOpen(err); - } - return; - } - } - - const contextAudio = this.context.audio; - contextAudio._uploadFileLength = files.length; - - const info = { - isUpdate: this.context.dialog.updateModal, - element: contextAudio._element - }; - - if (typeof this.functions.onAudioUploadBefore === 'function') { - const result = this.functions.onAudioUploadBefore(files, info, this, function (data) { - if (data && this._w.Array.isArray(data.result)) { - this.plugins.audio.register.call(this, info, data); - } else { - this.plugins.audio.upload.call(this, info, data); - } - }.bind(this)); - - if (typeof result === 'undefined') return; - if (!result) { - this.closeLoading(); - return; - } - if (typeof result === 'object' && result.length > 0) files = result; - } - - this.plugins.audio.upload.call(this, info, files); - }, - - error: function (message, response) { - this.closeLoading(); - if (typeof this.functions.onAudioUploadError !== 'function' || this.functions.onAudioUploadError(message, response, this)) { - this.functions.noticeOpen(message); - throw Error('[SUNEDITOR.plugin.audio.exception] response: ' + message); - } - }, - - upload: function (info, files) { - if (!files) { - this.closeLoading(); - return; - } - if (typeof files === 'string') { - this.plugins.audio.error.call(this, files, null); - return; - } - - const audioUploadUrl = this.options.audioUploadUrl; - const filesLen = this.context.dialog.updateModal ? 1 : files.length; - - // create formData - const formData = new FormData(); - for (let i = 0; i < filesLen; i++) { - formData.append('file-' + i, files[i]); - } - - // server upload - this.plugins.fileManager.upload.call(this, audioUploadUrl, this.options.audioUploadHeader, formData, this.plugins.audio.callBack_upload.bind(this, info), this.functions.onAudioUploadError); - }, - - callBack_upload: function (info, xmlHttp) { - if (typeof this.functions.audioUploadHandler === 'function') { - this.functions.audioUploadHandler(xmlHttp, info, this); - } else { - const response = JSON.parse(xmlHttp.responseText); - if (response.errorMessage) { - this.plugins.audio.error.call(this, response.errorMessage, response); - } else { - this.plugins.audio.register.call(this, info, response); - } - } - }, - - register: function (info, response) { - const fileList = response.result; - - for (let i = 0, len = fileList.length, file, oAudio; i < len; i++) { - if (info.isUpdate) oAudio = info.element; - else oAudio = this.plugins.audio._createAudioTag.call(this); - - file = { name: fileList[i].name, size: fileList[i].size }; - this.plugins.audio.create_audio.call(this, oAudio, fileList[i].url, file, info.isUpdate); - } - - this.closeLoading(); - }, - - setupUrl: function (src) { - try { - if (src.length === 0) return false; - this.plugins.audio.create_audio.call(this, this.plugins.audio._createAudioTag.call(this), src, null, this.context.dialog.updateModal); - } catch (error) { - throw Error('[SUNEDITOR.audio.audio.fail] cause : "' + error.message + '"'); - } finally { - this.closeLoading(); - } - }, - - create_audio: function (element, src, file, isUpdate) { - const contextAudio = this.context.audio; - - // create new tag - if (!isUpdate) { - element.src = src; - const cover = this.plugins.component.set_cover.call(this, element); - const container = this.plugins.component.set_container.call(this, cover, ''); - if (!this.insertComponent(container, false, true, !this.options.mediaAutoSelect)) { - this.focus(); - return; - } - if (!this.options.mediaAutoSelect) { - const line = this.appendFormatTag(container, null); - this.setRange(line, 0, line, 0); - } - } // update - else { - if (contextAudio._element) element = contextAudio._element; - if (element && element.src !== src) { - element.src = src; - this.selectComponent(element, 'audio'); - } else { - this.selectComponent(element, 'audio'); - return; - } - } - - this.plugins.fileManager.setInfo.call(this, 'audio', element, this.functions.onAudioUpload, file, false); - if (isUpdate) this.history.push(false); - }, - - updateCover: function (element) { - const contextAudio = this.context.audio; - this.plugins.audio._setTagAttrs.call(this, element); - - // find component element - const existElement = this.util.getParentElement(element, this.util.isMediaComponent) || - this.util.getParentElement(element, function (current) { - return this.isWysiwygDiv(current.parentNode); - }.bind(this.util)); - - // clone element - contextAudio._element = element = element.cloneNode(false); - const cover = this.plugins.component.set_cover.call(this, element); - const container = this.plugins.component.set_container.call(this, cover, 'se-audio-container'); - - existElement.parentNode.replaceChild(container, existElement); - this.plugins.fileManager.setInfo.call(this, 'audio', element, this.functions.onAudioUpload, null, false); - }, - - /** - * @Required @Override fileManager, resizing - */ - onModifyMode: function (selectionTag) { - const contextAudio = this.context.audio; - - this.setControllerPosition(contextAudio.controller, selectionTag, 'bottom', {left: 0, top: 0}); - this.controllersOn(contextAudio.controller, selectionTag, this.plugins.audio.onControllerOff.bind(this, selectionTag), 'audio'); - - this.util.addClass(selectionTag, 'active'); - contextAudio._element = selectionTag; - contextAudio._cover = this.util.getParentElement(selectionTag, 'FIGURE'); - contextAudio._container = this.util.getParentElement(selectionTag, this.util.isComponent); - }, - - /** - * @Required @Override fileManager, resizing - */ - openModify: function (notOpen) { - if (this.context.audio.audioUrlFile) { - const contextAudio = this.context.audio; - contextAudio._linkValue = contextAudio.preview.textContent = contextAudio.audioUrlFile.value = contextAudio._element.src; - } - if (!notOpen) this.plugins.dialog.open.call(this, 'audio', true); - }, - - onClick_controller: function (e) { - e.stopPropagation(); - - const command = e.target.getAttribute('data-command'); - if (!command) return; - - e.preventDefault(); - - if (/update/.test(command)) { - this.plugins.audio.openModify.call(this, false); - } - else { /** delete */ - this.plugins.audio.destroy.call(this, this.context.audio._element); - } - - this.controllersOff(); - }, - - onControllerOff: function (selectionTag) { - this.util.removeClass(selectionTag, 'active'); - this.context.audio.controller.style.display = 'none'; - }, - - /** - * @Required @Override dialog - */ - init: function () { - if (this.context.dialog.updateModal) return; - const contextAudio = this.context.audio; - - if (contextAudio.audioInputFile) contextAudio.audioInputFile.value = ''; - if (contextAudio.audioUrlFile) contextAudio._linkValue = contextAudio.preview.textContent = contextAudio.audioUrlFile.value = ''; - if (contextAudio.audioInputFile && contextAudio.audioUrlFile) { - contextAudio.audioUrlFile.removeAttribute('disabled'); - contextAudio.preview.style.textDecoration = ''; - } - - contextAudio._element = null; - } -}); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/dialog/image.js": -/*!************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/dialog/image.js ***! - \************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/dialog */ "./node_modules/suneditor/src/plugins/modules/dialog.js"); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_modules_dialog__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _modules_anchor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../modules/_anchor */ "./node_modules/suneditor/src/plugins/modules/_anchor.js"); -/* harmony import */ var _modules_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../modules/component */ "./node_modules/suneditor/src/plugins/modules/component.js"); -/* harmony import */ var _modules_component__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_modules_component__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _modules_resizing__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../modules/resizing */ "./node_modules/suneditor/src/plugins/modules/resizing.js"); -/* harmony import */ var _modules_resizing__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_modules_resizing__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _modules_fileManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../modules/fileManager */ "./node_modules/suneditor/src/plugins/modules/fileManager.js"); -/* harmony import */ var _modules_fileManager__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_modules_fileManager__WEBPACK_IMPORTED_MODULE_4__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - - - - - - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'image', - display: 'dialog', - add: function (core) { - core.addModule([_modules_dialog__WEBPACK_IMPORTED_MODULE_0___default.a, _modules_anchor__WEBPACK_IMPORTED_MODULE_1__["default"], _modules_component__WEBPACK_IMPORTED_MODULE_2___default.a, _modules_resizing__WEBPACK_IMPORTED_MODULE_3___default.a, _modules_fileManager__WEBPACK_IMPORTED_MODULE_4___default.a]); - - const options = core.options; - const context = core.context; - const contextImage = context.image = { - _infoList: [], // @Override fileManager - _infoIndex: 0, // @Override fileManager - _uploadFileLength: 0, // @Override fileManager - focusElement: null, // @Override dialog // This element has focus when the dialog is opened. - sizeUnit: options._imageSizeUnit, - _linkElement: '', - _altText: '', - _align: 'none', - _floatClassRegExp: '__se__float\\-[a-z]+', - _v_src: {_linkValue: ''}, - svgDefaultSize: '30%', - base64RenderIndex: 0, - // @require @Override component - _element: null, - _cover: null, - _container: null, - // @Override resizing properties - inputX: null, - inputY: null, - _element_w: 1, - _element_h: 1, - _element_l: 0, - _element_t: 0, - _defaultSizeX: 'auto', - _defaultSizeY: 'auto', - _origin_w: options.imageWidth === 'auto' ? '' : options.imageWidth, - _origin_h: options.imageHeight === 'auto' ? '' : options.imageHeight, - _proportionChecked: true, - _resizing: options.imageResizing, - _resizeDotHide: !options.imageHeightShow, - _rotation: options.imageRotation, - _onlyPercentage: options.imageSizeOnlyPercentage, - _ratio: false, - _ratioX: 1, - _ratioY: 1, - _captionShow: true, - _captionChecked: false, - _caption: null, - captionCheckEl: null - }; - - /** image dialog */ - let image_dialog = this.setDialog(core); - contextImage.modal = image_dialog; - contextImage.imgInputFile = image_dialog.querySelector('._se_image_file'); - contextImage.imgUrlFile = image_dialog.querySelector('._se_image_url'); - contextImage.focusElement = contextImage.imgInputFile || contextImage.imgUrlFile; - contextImage.altText = image_dialog.querySelector('._se_image_alt'); - contextImage.captionCheckEl = image_dialog.querySelector('._se_image_check_caption'); - contextImage.previewSrc = image_dialog.querySelector('._se_tab_content_image .se-link-preview'); - - /** add event listeners */ - image_dialog.querySelector('.se-dialog-tabs').addEventListener('click', this.openTab.bind(core)); - image_dialog.querySelector('form').addEventListener('submit', this.submit.bind(core)); - if (contextImage.imgInputFile) image_dialog.querySelector('.se-file-remove').addEventListener('click', this._removeSelectedFiles.bind(contextImage.imgInputFile, contextImage.imgUrlFile, contextImage.previewSrc)); - if (contextImage.imgUrlFile) contextImage.imgUrlFile.addEventListener('input', this._onLinkPreview.bind(contextImage.previewSrc, contextImage._v_src, options.linkProtocol)); - if (contextImage.imgInputFile && contextImage.imgUrlFile) contextImage.imgInputFile.addEventListener('change', this._fileInputChange.bind(contextImage)); - - const imageGalleryButton = image_dialog.querySelector('.__se__gallery'); - if (imageGalleryButton) imageGalleryButton.addEventListener('click', this._openGallery.bind(core)); - - contextImage.proportion = {}; - contextImage.inputX = {}; - contextImage.inputY = {}; - if (options.imageResizing) { - contextImage.proportion = image_dialog.querySelector('._se_image_check_proportion'); - contextImage.inputX = image_dialog.querySelector('._se_image_size_x'); - contextImage.inputY = image_dialog.querySelector('._se_image_size_y'); - contextImage.inputX.value = options.imageWidth; - contextImage.inputY.value = options.imageHeight; - - contextImage.inputX.addEventListener('keyup', this.setInputSize.bind(core, 'x')); - contextImage.inputY.addEventListener('keyup', this.setInputSize.bind(core, 'y')); - - contextImage.inputX.addEventListener('change', this.setRatio.bind(core)); - contextImage.inputY.addEventListener('change', this.setRatio.bind(core)); - contextImage.proportion.addEventListener('change', this.setRatio.bind(core)); - - image_dialog.querySelector('.se-dialog-btn-revert').addEventListener('click', this.sizeRevert.bind(core)); - } - - /** append html */ - context.dialog.modal.appendChild(image_dialog); - - /** link event */ - core.plugins.anchor.initEvent.call(core, 'image', image_dialog.querySelector('._se_tab_content_url')); - contextImage.anchorCtx = core.context.anchor.caller.image; - - /** empty memory */ - image_dialog = null; - }, - - /** dialog */ - setDialog: function (core) { - const option = core.options; - const lang = core.lang; - const dialog = core.util.createElement('DIV'); - - dialog.className = 'se-dialog-content se-dialog-image'; - dialog.style.display = 'none'; - - let html = '' + - '
' + - '' + - '' + lang.dialogBox.imageBox.title + '' + - '
' + - '
' + - '' + - '' + - '
' + - '
' + - '
' + - '
'; - - if (option.imageFileInput) { - html += '' + - '
' + - '' + - '
' + - '' + - '' + - '
' + - '
' ; - } - - if (option.imageUrlInput) { - html += '' + - '
' + - '' + - '
' + - '' + - ((option.imageGalleryUrl && core.plugins.imageGallery) ? '' : '') + - '
' + - '' + - '
'; - } - - html += '
' + - '
' + - '' + - '
'; - - if (option.imageResizing) { - const onlyPercentage = option.imageSizeOnlyPercentage; - const onlyPercentDisplay = onlyPercentage ? ' style="display: none !important;"' : ''; - const heightDisplay = !option.imageHeightShow ? ' style="display: none !important;"' : ''; - html += '
'; - if (onlyPercentage || !option.imageHeightShow) { - html += '' + - '
' + - '' + - '
'; - } else { - html += '' + - '
' + - '' + - '' + - '' + - '
'; - } - html += '' + - '' + - '' + - '' + - ' ' + lang.dialogBox.proportion + '' + - '' + - '
' ; - } - - html += '' + - '' + - '
' + - '
' + - '' + - '' + - '
'; - - dialog.innerHTML = html; - - return dialog; - }, - - _fileInputChange: function () { - if (!this.imgInputFile.value) { - this.imgUrlFile.removeAttribute('disabled'); - this.previewSrc.style.textDecoration = ''; - } else { - this.imgUrlFile.setAttribute('disabled', true); - this.previewSrc.style.textDecoration = 'line-through'; - } - }, - - _removeSelectedFiles: function (urlInput, previewSrc) { - this.value = ''; - if (urlInput) { - urlInput.removeAttribute('disabled'); - previewSrc.style.textDecoration = ''; - } - }, - - _openGallery: function () { - this.callPlugin('imageGallery', this.plugins.imageGallery.open.bind(this, this.plugins.image._setUrlInput.bind(this.context.image)), null); - }, - - _setUrlInput: function (target) { - this.altText.value = target.alt; - this._v_src._linkValue = this.previewSrc.textContent = this.imgUrlFile.value = target.src; - this.imgUrlFile.focus(); - }, - - _onLinkPreview: function (context, protocol, e) { - const value = e.target.value.trim(); - context._linkValue = this.textContent = !value ? '' : (protocol && value.indexOf('://') === -1 && value.indexOf('#') !== 0) ? protocol + value : value.indexOf('://') === -1 ? '/' + value : value; - }, - - /** - * @Override @Required fileManager - */ - fileTags: ['img'], - - /** - * @Override core, fileManager, resizing - * @description It is called from core.selectComponent. - * @param {Element} element Target element - */ - select: function (element) { - this.plugins.image.onModifyMode.call(this, element, this.plugins.resizing.call_controller_resize.call(this, element, 'image')); - }, - - /** - * @Override fileManager, resizing - */ - destroy: function (element) { - const imageEl = element || this.context.image._element; - const imageContainer = this.util.getParentElement(imageEl, this.util.isMediaComponent) || imageEl; - const dataIndex = imageEl.getAttribute('data-index') * 1; - let focusEl = (imageContainer.previousElementSibling || imageContainer.nextElementSibling); - - const emptyDiv = imageContainer.parentNode; - this.util.removeItem(imageContainer); - this.plugins.image.init.call(this); - this.controllersOff(); - - if (emptyDiv !== this.context.element.wysiwyg) this.util.removeItemAllParents(emptyDiv, function (current) { return current.childNodes.length === 0; }, null); - - // focus - this.focusEdge(focusEl); - - // event - this.plugins.fileManager.deleteInfo.call(this, 'image', dataIndex, this.functions.onImageUpload); - - // history stack - this.history.push(false); - }, - - /** - * @Required @Override dialog - */ - on: function (update) { - const contextImage = this.context.image; - - if (!update) { - contextImage.inputX.value = contextImage._origin_w = this.options.imageWidth === contextImage._defaultSizeX ? '' : this.options.imageWidth; - contextImage.inputY.value = contextImage._origin_h = this.options.imageHeight === contextImage._defaultSizeY ? '' : this.options.imageHeight; - if (contextImage.imgInputFile && this.options.imageMultipleFile) contextImage.imgInputFile.setAttribute('multiple', 'multiple'); - } else { - if (contextImage.imgInputFile && this.options.imageMultipleFile) contextImage.imgInputFile.removeAttribute('multiple'); - } - this.plugins.anchor.on.call(this, contextImage.anchorCtx, update); - }, - - /** - * @Required @Override dialog - */ - open: function () { - this.plugins.dialog.open.call(this, 'image', 'image' === this.currentControllerName); - }, - - openTab: function (e) { - const modal = this.context.image.modal; - const targetElement = (e === 'init' ? modal.querySelector('._se_tab_link') : e.target); - - if (!/^BUTTON$/i.test(targetElement.tagName)) { - return false; - } - - // Declare all variables - const tabName = targetElement.getAttribute('data-tab-link'); - const contentClassName = '_se_tab_content'; - let i, tabContent, tabLinks; - - // Get all elements with class="tabcontent" and hide them - tabContent = modal.getElementsByClassName(contentClassName); - for (i = 0; i < tabContent.length; i++) { - tabContent[i].style.display = 'none'; - } - - // Get all elements with class="tablinks" and remove the class "active" - tabLinks = modal.getElementsByClassName('_se_tab_link'); - for (i = 0; i < tabLinks.length; i++) { - this.util.removeClass(tabLinks[i], 'active'); - } - - // Show the current tab, and add an "active" class to the button that opened the tab - modal.querySelector('.' + contentClassName + '_' + tabName).style.display = 'block'; - this.util.addClass(targetElement, 'active'); - - // focus - if (tabName === 'image' && this.context.image.focusElement) { - this.context.image.focusElement.focus(); - } else if (tabName === 'url') { - this.context.anchor.caller.image.urlInput.focus(); - } - - return false; - }, - - submit: function (e) { - const contextImage = this.context.image; - const imagePlugin = this.plugins.image; - - e.preventDefault(); - e.stopPropagation(); - - contextImage._altText = contextImage.altText.value; - contextImage._align = contextImage.modal.querySelector('input[name="suneditor_image_radio"]:checked').value; - contextImage._captionChecked = contextImage.captionCheckEl.checked; - if (contextImage._resizing) contextImage._proportionChecked = contextImage.proportion.checked; - - try { - if (this.context.dialog.updateModal) { - imagePlugin.update_image.call(this, false, true, false); - } - - if (contextImage.imgInputFile && contextImage.imgInputFile.files.length > 0) { - this.showLoading(); - imagePlugin.submitAction.call(this, this.context.image.imgInputFile.files); - } else if (contextImage.imgUrlFile && contextImage._v_src._linkValue.length > 0) { - this.showLoading(); - imagePlugin.onRender_imgUrl.call(this); - } - } catch (error) { - this.closeLoading(); - throw Error('[SUNEDITOR.image.submit.fail] cause : "' + error.message + '"'); - } finally { - this.plugins.dialog.close.call(this); - } - - return false; - }, - - submitAction: function (fileList) { - if (fileList.length === 0) return; - - let fileSize = 0; - let files = []; - for (let i = 0, len = fileList.length; i < len; i++) { - if (/image/i.test(fileList[i].type)) { - files.push(fileList[i]); - fileSize += fileList[i].size; - } - } - - const limitSize = this.options.imageUploadSizeLimit; - if (limitSize > 0) { - let infoSize = 0; - const imagesInfo = this.context.image._infoList; - for (let i = 0, len = imagesInfo.length; i < len; i++) { - infoSize += imagesInfo[i].size * 1; - } - - if ((fileSize + infoSize) > limitSize) { - this.closeLoading(); - const err = '[SUNEDITOR.imageUpload.fail] Size of uploadable total images: ' + (limitSize/1000) + 'KB'; - if (typeof this.functions.onImageUploadError !== 'function' || this.functions.onImageUploadError(err, { 'limitSize': limitSize, 'currentSize': infoSize, 'uploadSize': fileSize }, this)) { - this.functions.noticeOpen(err); - } - return; - } - } - - const contextImage = this.context.image; - contextImage._uploadFileLength = files.length; - - const anchor = this.plugins.anchor.createAnchor.call(this, contextImage.anchorCtx, true); - const info = { - anchor: anchor, - inputWidth: contextImage.inputX.value, - inputHeight: contextImage.inputY.value, - align: contextImage._align, - isUpdate: this.context.dialog.updateModal, - element: contextImage._element - }; - - if (typeof this.functions.onImageUploadBefore === 'function') { - const result = this.functions.onImageUploadBefore(files, info, this, function (data) { - if (data && this._w.Array.isArray(data.result)) { - this.plugins.image.register.call(this, info, data); - } else { - this.plugins.image.upload.call(this, info, data); - } - }.bind(this)); - - if (typeof result === 'undefined') return; - if (!result) { - this.closeLoading(); - return; - } - if (this._w.Array.isArray(result) && result.length > 0) files = result; - } - - this.plugins.image.upload.call(this, info, files); - }, - - error: function (message, response) { - this.closeLoading(); - if (typeof this.functions.onImageUploadError !== 'function' || this.functions.onImageUploadError(message, response, this)) { - this.functions.noticeOpen(message); - throw Error('[SUNEDITOR.plugin.image.error] response: ' + message); - } - }, - - upload: function (info, files) { - if (!files) { - this.closeLoading(); - return; - } - if (typeof files === 'string') { - this.plugins.image.error.call(this, files, null); - return; - } - - const imageUploadUrl = this.options.imageUploadUrl; - const filesLen = this.context.dialog.updateModal ? 1 : files.length; - - // server upload - if (typeof imageUploadUrl === 'string' && imageUploadUrl.length > 0) { - const formData = new FormData(); - for (let i = 0; i < filesLen; i++) { - formData.append('file-' + i, files[i]); - } - this.plugins.fileManager.upload.call(this, imageUploadUrl, this.options.imageUploadHeader, formData, this.plugins.image.callBack_imgUpload.bind(this, info), this.functions.onImageUploadError); - } else { // base64 - this.plugins.image.setup_reader.call(this, files, info.anchor, info.inputWidth, info.inputHeight, info.align, filesLen, info.isUpdate); - } - }, - - callBack_imgUpload: function (info, xmlHttp) { - if (typeof this.functions.imageUploadHandler === 'function') { - this.functions.imageUploadHandler(xmlHttp, info, this); - } else { - const response = JSON.parse(xmlHttp.responseText); - if (response.errorMessage) { - this.plugins.image.error.call(this, response.errorMessage, response); - } else { - this.plugins.image.register.call(this, info, response); - } - } - }, - - register: function (info, response) { - const fileList = response.result; - - for (let i = 0, len = fileList.length, file; i < len; i++) { - file = { name: fileList[i].name, size: fileList[i].size }; - if (info.isUpdate) { - this.plugins.image.update_src.call(this, fileList[i].url, info.element, file); - break; - } else { - this.plugins.image.create_image.call(this, fileList[i].url, info.anchor, info.inputWidth, info.inputHeight, info.align, file); - } - } - - this.closeLoading(); - }, - - setup_reader: function (files, anchor, width, height, align, filesLen, isUpdate) { - try { - this.context.image.base64RenderIndex = filesLen; - const wFileReader = this._w.FileReader; - const filesStack = [filesLen]; - this.context.image.inputX.value = width; - this.context.image.inputY.value = height; - - for (let i = 0, reader, file; i < filesLen; i++) { - reader = new wFileReader(); - file = files[i]; - - reader.onload = function (reader, update, updateElement, file, index) { - filesStack[index] = { result: reader.result, file: file }; - - if (--this.context.image.base64RenderIndex === 0) { - this.plugins.image.onRender_imgBase64.call(this, update, filesStack, updateElement, anchor, width, height, align); - this.closeLoading(); - } - }.bind(this, reader, isUpdate, this.context.image._element, file, i); - - reader.readAsDataURL(file); - } - } catch (e) { - this.closeLoading(); - throw Error('[SUNEDITOR.image.setup_reader.fail] cause : "' + e.message + '"'); - } - }, - - onRender_imgBase64: function (update, filesStack, updateElement, anchor, width, height, align) { - const updateMethod = this.plugins.image.update_src; - const createMethod = this.plugins.image.create_image; - - for (let i = 0, len = filesStack.length; i < len; i++) { - if (update) { - this.context.image._element.setAttribute('data-file-name', filesStack[i].file.name); - this.context.image._element.setAttribute('data-file-size', filesStack[i].file.size); - updateMethod.call(this, filesStack[i].result, updateElement, filesStack[i].file); - } else { - createMethod.call(this, filesStack[i].result, anchor, width, height, align, filesStack[i].file); - } - } - }, - - onRender_imgUrl: function () { - const contextImage = this.context.image; - if (contextImage._v_src._linkValue.length === 0) return false; - - try { - const file = {name: contextImage._v_src._linkValue.split('/').pop(), size: 0}; - if (this.context.dialog.updateModal) this.plugins.image.update_src.call(this, contextImage._v_src._linkValue, contextImage._element, file); - else this.plugins.image.create_image.call(this, contextImage._v_src._linkValue, this.plugins.anchor.createAnchor.call(this, contextImage.anchorCtx, true), contextImage.inputX.value, contextImage.inputY.value, contextImage._align, file); - } catch (e) { - throw Error('[SUNEDITOR.image.URLRendering.fail] cause : "' + e.message + '"'); - } finally { - this.closeLoading(); - } - }, - - onRender_link: function (imgTag, anchor) { - if (anchor) { - anchor.setAttribute('data-image-link', 'image'); - imgTag.setAttribute('data-image-link', anchor.href); - anchor.appendChild(imgTag); - return anchor; - } - - return imgTag; - }, - - /** - * @Override resizing - * @param {String} xy 'x': width, 'y': height - * @param {KeyboardEvent} e Event object - */ - setInputSize: function (xy, e) { - if (e && e.keyCode === 32) { - e.preventDefault(); - return; - } - - this.plugins.resizing._module_setInputSize.call(this, this.context.image, xy); - }, - - /** - * @Override resizing - */ - setRatio: function () { - this.plugins.resizing._module_setRatio.call(this, this.context.image); - }, - - /** - * @Override fileManager - */ - checkFileInfo: function () { - const imagePlugin = this.plugins.image; - - const modifyHandler = function (tag) { - imagePlugin.onModifyMode.call(this, tag, null); - imagePlugin.openModify.call(this, true); - imagePlugin.update_image.call(this, true, false, true); - }.bind(this); - - this.plugins.fileManager.checkInfo.call(this, 'image', ['img'], this.functions.onImageUpload, modifyHandler, true); - }, - - /** - * @Override fileManager - */ - resetFileInfo: function () { - this.plugins.fileManager.resetInfo.call(this, 'image', this.functions.onImageUpload); - }, - - create_image: function (src, anchor, width, height, align, file) { - const imagePlugin = this.plugins.image; - const contextImage = this.context.image; - this.context.resizing._resize_plugin = 'image'; - - let oImg = this.util.createElement('IMG'); - oImg.src = src; - oImg.alt = contextImage._altText; - oImg.setAttribute('data-rotate', '0'); - anchor = imagePlugin.onRender_link.call(this, oImg, anchor); - - if (contextImage._resizing) { - oImg.setAttribute('data-proportion', contextImage._proportionChecked); - } - - const cover = this.plugins.component.set_cover.call(this, anchor); - const container = this.plugins.component.set_container.call(this, cover, 'se-image-container'); - - // caption - if (contextImage._captionChecked) { - contextImage._caption = this.plugins.component.create_caption.call(this); - contextImage._caption.setAttribute('contenteditable', false); - cover.appendChild(contextImage._caption); - } - - contextImage._element = oImg; - contextImage._cover = cover; - contextImage._container = container; - - // set size - imagePlugin.applySize.call(this, width, height); - - // align - imagePlugin.setAlign.call(this, align, oImg, cover, container); - - oImg.onload = imagePlugin._image_create_onload.bind(this, oImg, contextImage.svgDefaultSize, container); - if (this.insertComponent(container, true, true, true)) this.plugins.fileManager.setInfo.call(this, 'image', oImg, this.functions.onImageUpload, file, true); - this.context.resizing._resize_plugin = ''; - }, - - _image_create_onload: function (oImg, svgDefaultSize, container) { - // svg exception handling - if (oImg.offsetWidth === 0) this.plugins.image.applySize.call(this, svgDefaultSize, ''); - if (this.options.mediaAutoSelect) { - this.selectComponent(oImg, 'image'); - } else { - const line = this.appendFormatTag(container, null); - this.setRange(line, 0, line, 0); - } - }, - - update_image: function (init, openController, notHistoryPush) { - const contextImage = this.context.image; - let imageEl = contextImage._element; - let cover = contextImage._cover; - let container = contextImage._container; - let isNewContainer = false; - - if (cover === null) { - isNewContainer = true; - imageEl = contextImage._element.cloneNode(true); - cover = this.plugins.component.set_cover.call(this, imageEl); - } - - if (container === null) { - cover = cover.cloneNode(true); - imageEl = cover.querySelector('img'); - isNewContainer = true; - container = this.plugins.component.set_container.call(this, cover, 'se-image-container'); - } else if (isNewContainer) { - container.innerHTML = ''; - container.appendChild(cover); - contextImage._cover = cover; - contextImage._element = imageEl; - isNewContainer = false; - } - - // check size - let changeSize; - const x = this.util.isNumber(contextImage.inputX.value) ? contextImage.inputX.value + contextImage.sizeUnit : contextImage.inputX.value; - const y = this.util.isNumber(contextImage.inputY.value) ? contextImage.inputY.value + contextImage.sizeUnit : contextImage.inputY.value; - if (/%$/.test(imageEl.style.width)) { - changeSize = x !== container.style.width || y !== container.style.height; - } else { - changeSize = x !== imageEl.style.width || y !== imageEl.style.height; - } - - // alt - imageEl.alt = contextImage._altText; - - // caption - let modifiedCaption = false; - if (contextImage._captionChecked) { - if (!contextImage._caption) { - contextImage._caption = this.plugins.component.create_caption.call(this); - cover.appendChild(contextImage._caption); - modifiedCaption = true; - } - } else { - if (contextImage._caption) { - this.util.removeItem(contextImage._caption); - contextImage._caption = null; - modifiedCaption = true; - } - } - - // link - const anchor = this.plugins.anchor.createAnchor.call(this, contextImage.anchorCtx, true); - if (anchor) { - contextImage._linkElement = anchor; - cover.insertBefore(this.plugins.image.onRender_link.call(this, imageEl, anchor), contextImage._caption); - } else if (contextImage._linkElement !== null) { - const imageElement = imageEl; - - imageElement.setAttribute('data-image-link', ''); - const newEl = imageElement.cloneNode(true); - cover.removeChild(contextImage._linkElement); - cover.insertBefore(newEl, contextImage._caption); - imageEl = newEl; - } - - if (isNewContainer) { - const existElement = (this.util.isRangeFormatElement(contextImage._element.parentNode) || this.util.isWysiwygDiv(contextImage._element.parentNode)) ? - contextImage._element : - /^A$/i.test(contextImage._element.parentNode.nodeName) ? contextImage._element.parentNode : this.util.getFormatElement(contextImage._element) || contextImage._element; - - if (this.util.isFormatElement(existElement) && existElement.textContent.length > 0) { - existElement.parentNode.insertBefore(container, existElement.nextElementSibling); - this.util.removeItem(contextImage._element); - } else { - existElement.parentNode.replaceChild(container, existElement); - } - - imageEl = container.querySelector('img'); - - contextImage._element = imageEl; - contextImage._cover = cover; - contextImage._container = container; - } - - // transform - if (modifiedCaption || (!contextImage._onlyPercentage && changeSize)) { - if (!init && (/\d+/.test(imageEl.style.height) || (this.context.resizing._rotateVertical && contextImage._captionChecked))) { - if (/%$/.test(contextImage.inputX.value) || /%$/.test(contextImage.inputY.value)) { - this.plugins.resizing.resetTransform.call(this, imageEl); - } else { - this.plugins.resizing.setTransformSize.call(this, imageEl, this.util.getNumber(contextImage.inputX.value, 0), this.util.getNumber(contextImage.inputY.value, 0)); - } - } - } - - // size - let isPercent = false; - if (contextImage._resizing) { - imageEl.setAttribute('data-proportion', contextImage._proportionChecked); - if (changeSize) { - this.plugins.image.applySize.call(this); - } - } - - // align - if (!(isPercent && contextImage._align === 'center')) { - this.plugins.image.setAlign.call(this, null, imageEl, null, null); - } - - // set imagesInfo - if (init) { - this.plugins.fileManager.setInfo.call(this, 'image', imageEl, this.functions.onImageUpload, null, true); - } - - if (openController) { - this.selectComponent(imageEl, 'image'); - } - - // history stack - if (!notHistoryPush) this.history.push(false); - }, - - update_src: function (src, element, file) { - element.src = src; - this._w.setTimeout(this.plugins.fileManager.setInfo.bind(this, 'image', element, this.functions.onImageUpload, file, true)); - this.selectComponent(element, 'image'); - }, - - /** - * @Required @Override fileManager, resizing - */ - onModifyMode: function (element, size) { - if (!element) return; - - const contextImage = this.context.image; - contextImage._linkElement = contextImage.anchorCtx.linkAnchor = /^A$/i.test(element.parentNode.nodeName) ? element.parentNode : null; - contextImage._element = element; - contextImage._cover = this.util.getParentElement(element, 'FIGURE'); - contextImage._container = this.util.getParentElement(element, this.util.isMediaComponent); - contextImage._caption = this.util.getChildElement(contextImage._cover, 'FIGCAPTION'); - contextImage._align = element.style.float || element.getAttribute('data-align') || 'none'; - element.style.float = ''; - - if (size) { - contextImage._element_w = size.w; - contextImage._element_h = size.h; - contextImage._element_t = size.t; - contextImage._element_l = size.l; - } - - let userSize = contextImage._element.getAttribute('data-size') || contextImage._element.getAttribute('data-origin'); - if (userSize) { - userSize = userSize.split(','); - contextImage._origin_w = userSize[0]; - contextImage._origin_h = userSize[1]; - } else if (size) { - contextImage._origin_w = size.w; - contextImage._origin_h = size.h; - } - }, - - /** - * @Required @Override fileManager, resizing - */ - openModify: function (notOpen) { - const contextImage = this.context.image; - if (contextImage.imgUrlFile) { - contextImage._v_src._linkValue = contextImage.previewSrc.textContent = contextImage.imgUrlFile.value = contextImage._element.src; - } - contextImage._altText = contextImage.altText.value = contextImage._element.alt; - contextImage.modal.querySelector('input[name="suneditor_image_radio"][value="' + contextImage._align + '"]').checked = true; - contextImage._align = contextImage.modal.querySelector('input[name="suneditor_image_radio"]:checked').value; - contextImage._captionChecked = contextImage.captionCheckEl.checked = !!contextImage._caption; - - if (contextImage._resizing) { - this.plugins.resizing._module_setModifyInputSize.call(this, contextImage, this.plugins.image); - } - - if (!notOpen) this.plugins.dialog.open.call(this, 'image', true); - }, - - /** - * @Override fileManager - */ - applySize: function (w, h) { - const contextImage = this.context.image; - - if (!w) w = contextImage.inputX.value || this.options.imageWidth; - if (!h) h = contextImage.inputY.value || this.options.imageHeight; - - if ((contextImage._onlyPercentage && !!w) || /%$/.test(w)) { - this.plugins.image.setPercentSize.call(this, w, h); - return true; - } else if ((!w || w === 'auto') && (!h || h === 'auto')) { - this.plugins.image.setAutoSize.call(this); - } else { - this.plugins.image.setSize.call(this, w, h, false); - } - - return false; - }, - - /** - * @Override resizing - */ - sizeRevert: function () { - this.plugins.resizing._module_sizeRevert.call(this, this.context.image); - }, - - /** - * @Override resizing - */ - setSize: function (w, h, notResetPercentage, direction) { - const contextImage = this.context.image; - const onlyW = /^(rw|lw)$/.test(direction); - const onlyH = /^(th|bh)$/.test(direction); - - if (!onlyH) { - contextImage._element.style.width = this.util.isNumber(w) ? w + contextImage.sizeUnit : w; - this.plugins.image.cancelPercentAttr.call(this); - } - if (!onlyW) { - contextImage._element.style.height = this.util.isNumber(h) ? h + contextImage.sizeUnit : /%$/.test(h) ? '' : h; - } - - if (contextImage._align === 'center') this.plugins.image.setAlign.call(this, null, null, null, null); - if (!notResetPercentage) contextImage._element.removeAttribute('data-percentage'); - - // save current size - this.plugins.resizing._module_saveCurrentSize.call(this, contextImage); - }, - - /** - * @Override resizing - */ - setAutoSize: function () { - const contextImage = this.context.image; - - this.plugins.resizing.resetTransform.call(this, contextImage._element); - this.plugins.image.cancelPercentAttr.call(this); - - contextImage._element.style.maxWidth = ''; - contextImage._element.style.width = ''; - contextImage._element.style.height = ''; - contextImage._cover.style.width = ''; - contextImage._cover.style.height = ''; - - this.plugins.image.setAlign.call(this, null, null, null, null); - contextImage._element.setAttribute('data-percentage', 'auto,auto'); - - // save current size - this.plugins.resizing._module_saveCurrentSize.call(this, contextImage); - }, - - /** - * @Override resizing - */ - setOriginSize: function () { - const contextImage = this.context.image; - contextImage._element.removeAttribute('data-percentage'); - - this.plugins.resizing.resetTransform.call(this, contextImage._element); - this.plugins.image.cancelPercentAttr.call(this); - - const originSize = (contextImage._element.getAttribute('data-origin') || '').split(','); - const w = originSize[0]; - const h = originSize[1]; - - if (originSize) { - if (contextImage._onlyPercentage || (/%$/.test(w) && (/%$/.test(h) || !/\d/.test(h)))) { - this.plugins.image.setPercentSize.call(this, w, h); - } else { - this.plugins.image.setSize.call(this, w, h); - } - - // save current size - this.plugins.resizing._module_saveCurrentSize.call(this, contextImage); - } - }, - - /** - * @Override resizing - */ - setPercentSize: function (w, h) { - const contextImage = this.context.image; - h = !!h && !/%$/.test(h) && !this.util.getNumber(h, 0) ? this.util.isNumber(h) ? h + '%' : h : this.util.isNumber(h) ? h + contextImage.sizeUnit : (h || ''); - const heightPercentage = /%$/.test(h); - - contextImage._container.style.width = this.util.isNumber(w) ? w + '%' : w; - contextImage._container.style.height = ''; - contextImage._cover.style.width = '100%'; - contextImage._cover.style.height = !heightPercentage ? '' : h; - contextImage._element.style.width = '100%'; - contextImage._element.style.height = heightPercentage ? '' : h; - contextImage._element.style.maxWidth = ''; - - if (contextImage._align === 'center') this.plugins.image.setAlign.call(this, null, null, null, null); - - contextImage._element.setAttribute('data-percentage', w + ',' + h); - this.plugins.resizing.setCaptionPosition.call(this, contextImage._element); - - // save current size - this.plugins.resizing._module_saveCurrentSize.call(this, contextImage); - }, - - /** - * @Override resizing - */ - cancelPercentAttr: function () { - const contextImage = this.context.image; - - contextImage._cover.style.width = ''; - contextImage._cover.style.height = ''; - contextImage._container.style.width = ''; - contextImage._container.style.height = ''; - - this.util.removeClass(contextImage._container, this.context.image._floatClassRegExp); - this.util.addClass(contextImage._container, '__se__float-' + contextImage._align); - - if (contextImage._align === 'center') this.plugins.image.setAlign.call(this, null, null, null, null); - }, - - /** - * @Override resizing - */ - setAlign: function (align, element, cover, container) { - const contextImage = this.context.image; - - if (!align) align = contextImage._align; - if (!element) element = contextImage._element; - if (!cover) cover = contextImage._cover; - if (!container) container = contextImage._container; - - if (align && align !== 'none') { - cover.style.margin = 'auto'; - } else { - cover.style.margin = '0'; - } - - if (/%$/.test(element.style.width) && align === 'center') { - container.style.minWidth = '100%'; - cover.style.width = container.style.width; - } else { - container.style.minWidth = ''; - cover.style.width = this.context.resizing._rotateVertical ? (element.style.height || element.offsetHeight) : ((!element.style.width || element.style.width === 'auto') ? '' : element.style.width || '100%'); - } - - if (!this.util.hasClass(container, '__se__float-' + align)) { - this.util.removeClass(container, contextImage._floatClassRegExp); - this.util.addClass(container, '__se__float-' + align); - } - - element.setAttribute('data-align', align); - }, - - /** - * @Override dialog - */ - init: function () { - const contextImage = this.context.image; - if (contextImage.imgInputFile) contextImage.imgInputFile.value = ''; - if (contextImage.imgUrlFile) contextImage._v_src._linkValue = contextImage.previewSrc.textContent = contextImage.imgUrlFile.value = ''; - if (contextImage.imgInputFile && contextImage.imgUrlFile) { - contextImage.imgUrlFile.removeAttribute('disabled'); - contextImage.previewSrc.style.textDecoration = ''; - } - - contextImage.altText.value = ''; - contextImage.modal.querySelector('input[name="suneditor_image_radio"][value="none"]').checked = true; - contextImage.captionCheckEl.checked = false; - contextImage._element = null; - this.plugins.image.openTab.call(this, 'init'); - - if (contextImage._resizing) { - contextImage.inputX.value = this.options.imageWidth === contextImage._defaultSizeX ? '' : this.options.imageWidth; - contextImage.inputY.value = this.options.imageHeight === contextImage._defaultSizeY ? '' : this.options.imageHeight; - contextImage.proportion.checked = true; - contextImage._ratio = false; - contextImage._ratioX = 1; - contextImage._ratioY = 1; - } - - this.plugins.anchor.init.call(this, contextImage.anchorCtx); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/dialog/link.js": -/*!***********************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/dialog/link.js ***! - \***********************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/dialog */ "./node_modules/suneditor/src/plugins/modules/dialog.js"); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_modules_dialog__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _modules_anchor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../modules/_anchor */ "./node_modules/suneditor/src/plugins/modules/_anchor.js"); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - - - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'link', - display: 'dialog', - add: function (core) { - core.addModule([_modules_dialog__WEBPACK_IMPORTED_MODULE_0___default.a, _modules_anchor__WEBPACK_IMPORTED_MODULE_1__["default"]]); - - const context = core.context; - const contextLink = context.link = { - focusElement: null, // @Override dialog // This element has focus when the dialog is opened. - _linkAnchor: null, - anchorCtx: null - }; - - /** link dialog */ - let link_dialog = this.setDialog(core); - contextLink.modal = link_dialog; - - /** link controller */ - let link_controller = this.setController_LinkButton(core); - contextLink.linkController = link_controller; - - link_dialog.querySelector('form').addEventListener('submit', this.submit.bind(core)); - link_controller.addEventListener('click', this.onClick_linkController.bind(core)); - - /** append html */ - context.dialog.modal.appendChild(link_dialog); - - /** append controller */ - context.element.relative.appendChild(link_controller); - - /** link event */ - core.plugins.anchor.initEvent.call(core, 'link', link_dialog); - contextLink.focusElement = context.anchor.caller.link.urlInput; - - /** empty memory */ - link_dialog = null, link_controller = null; - }, - - /** dialog */ - setDialog: function (core) { - const lang = core.lang; - const dialog = core.util.createElement('DIV'); - const icons = core.icons; - - dialog.className = 'se-dialog-content'; - dialog.style.display = 'none'; - let html = '' + - '
' + - '
' + - '' + - '' + lang.dialogBox.linkBox.title + '' + - '
' + - core.context.anchor.forms.innerHTML + - '' + - '
'; - - dialog.innerHTML = html; - return dialog; - }, - - /** modify controller button */ - setController_LinkButton: function (core) { - const lang = core.lang; - const icons = core.icons; - const link_btn = core.util.createElement('DIV'); - - link_btn.className = 'se-controller se-controller-link'; - link_btn.innerHTML = '' + - '
' + - ''; - - return link_btn; - }, - - /** - * @Override dialog - */ - open: function () { - this.plugins.dialog.open.call(this, 'link', 'link' === this.currentControllerName); - }, - - submit: function (e) { - this.showLoading(); - - e.preventDefault(); - e.stopPropagation(); - - try { - const oA = this.plugins.anchor.createAnchor.call(this, this.context.anchor.caller.link, false); - - if (!this.context.dialog.updateModal) { - const selectedFormats = this.getSelectedElements(); - if (selectedFormats.length > 1) { - const oFormat = this.util.createElement(selectedFormats[0].nodeName); - oFormat.appendChild(oA); - if (!this.insertNode(oFormat, null, true)) return; - } else { - if (!this.insertNode(oA, null, true)) return; - } - - this.setRange(oA.childNodes[0], 0, oA.childNodes[0], oA.textContent.length); - } else { - // set range - const textNode = this.context.link._linkAnchor.childNodes[0]; - this.setRange(textNode, 0, textNode, textNode.textContent.length); - } - } finally { - this.plugins.dialog.close.call(this); - this.closeLoading(); - // history stack - this.history.push(false); - } - - return false; - }, - - /** - * @Override core - */ - active: function (element) { - if (!element) { - if (this.controllerArray.indexOf(this.context.link.linkController) > -1) { - this.controllersOff(); - } - } else if (this.util.isAnchor(element) && element.getAttribute('data-image-link') === null) { - if (this.controllerArray.indexOf(this.context.link.linkController) < 0) { - this.plugins.link.call_controller.call(this, element); - } - return true; - } - - return false; - }, - - /** - * @Override dialog - */ - on: function (update) { - this.plugins.anchor.on.call(this, this.context.anchor.caller.link, update); - }, - - call_controller: function (selectionATag) { - this.editLink = this.context.link._linkAnchor = this.context.anchor.caller.link.linkAnchor = selectionATag; - const linkBtn = this.context.link.linkController; - const link = linkBtn.querySelector('a'); - - link.href = selectionATag.href; - link.title = selectionATag.textContent; - link.textContent = selectionATag.textContent; - - this.util.addClass(selectionATag, 'on'); - this.setControllerPosition(linkBtn, selectionATag, 'bottom', {left: 0, top: 0}); - this.controllersOn(linkBtn, selectionATag, 'link', this.util.removeClass.bind(this.util, this.context.link._linkAnchor, 'on')); - }, - - onClick_linkController: function (e) { - e.stopPropagation(); - - const command = e.target.getAttribute('data-command') || e.target.parentNode.getAttribute('data-command'); - if (!command) return; - - e.preventDefault(); - - if (/update/.test(command)) { - this.plugins.dialog.open.call(this, 'link', true); - } else if (/unlink/.test(command)) { - const sc = this.util.getChildElement(this.context.link._linkAnchor, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, false); - const ec = this.util.getChildElement(this.context.link._linkAnchor, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, true); - this.setRange(sc, 0, ec, ec.textContent.length); - this.nodeChange(null, null, ['A'], false); - } else { - /** delete */ - this.util.removeItem(this.context.link._linkAnchor); - this.context.anchor.caller.link.linkAnchor = null; - this.focus(); - - // history stack - this.history.push(false); - } - - this.controllersOff(); - }, - - /** - * @Override dialog - */ - init: function () { - this.context.link.linkController.style.display = 'none'; - this.plugins.anchor.init.call(this, this.context.anchor.caller.link); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/dialog/math.js": -/*!***********************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/dialog/math.js ***! - \***********************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/dialog */ "./node_modules/suneditor/src/plugins/modules/dialog.js"); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_modules_dialog__WEBPACK_IMPORTED_MODULE_0__); - - - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'math', - display: 'dialog', - add: function (core) { - core.addModule([_modules_dialog__WEBPACK_IMPORTED_MODULE_0___default.a]); - - const context = core.context; - context.math = { - focusElement: null, // @Override dialog // This element has focus when the dialog is opened. - previewElement: null, - fontSizeElement: null, - _mathExp: null - }; - - /** math dialog */ - let math_dialog = this.setDialog(core); - context.math.modal = math_dialog; - context.math.focusElement = math_dialog.querySelector('.se-math-exp'); - context.math.previewElement = math_dialog.querySelector('.se-math-preview'); - context.math.fontSizeElement = math_dialog.querySelector('.se-math-size'); - context.math.focusElement.addEventListener('keyup', this._renderMathExp.bind(core, context.math), false); - context.math.focusElement.addEventListener('change', this._renderMathExp.bind(core, context.math), false); - context.math.fontSizeElement.addEventListener('change', function (e) { this.fontSize = e.target.value; }.bind(context.math.previewElement.style), false); - - /** math controller */ - let math_controller = this.setController_MathButton(core); - context.math.mathController = math_controller; - context.math._mathExp = null; - - /** add event listeners */ - math_dialog.querySelector('form').addEventListener('submit', this.submit.bind(core), false); - math_controller.addEventListener('click', this.onClick_mathController.bind(core)); - - /** append html */ - context.dialog.modal.appendChild(math_dialog); - context.element.relative.appendChild(math_controller); - - /** empty memory */ - math_dialog = null, math_controller = null; - }, - - /** dialog */ - setDialog: function (core) { - const lang = core.lang; - const dialog = core.util.createElement('DIV'); - - dialog.className = 'se-dialog-content'; - dialog.style.display = 'none'; - dialog.innerHTML = '' + - '
' + - '
' + - '' + - '' + lang.dialogBox.mathBox.title + '' + - '
' + - '
' + - '
' + - '' + - '' + - '
' + - '
' + - '' + - '' + - '
' + - '
' + - '' + - '

' + - '
' + - '
' + - '' + - '
'; - - return dialog; - }, - - /** modify controller button */ - setController_MathButton: function (core) { - const lang = core.lang; - const math_btn = core.util.createElement('DIV'); - - math_btn.className = 'se-controller se-controller-link'; - math_btn.innerHTML = '' + - '
' + - '' + - ''; - - return math_btn; - }, - - /** - * @Required @Override dialog - */ - open: function () { - this.plugins.dialog.open.call(this, 'math', 'math' === this.currentControllerName); - }, - - /** - * @Override core - managedTagsInfo - */ - managedTags: function () { - return { - className: 'katex', - method: function (element) { - if (!element.getAttribute('data-exp')) return; - const dom = this._d.createRange().createContextualFragment(this.plugins.math._renderer.call(this, this.util.HTMLDecoder(element.getAttribute('data-exp')))); - element.innerHTML = dom.querySelector('.katex').innerHTML; - } - }; - }, - - _renderer: function (exp) { - const katex = this.options.katex; - return katex.src.renderToString(exp, katex.options); - }, - - _renderMathExp: function (contextMath, e) { - contextMath.previewElement.innerHTML = this.plugins.math._renderer.call(this, e.target.value); - }, - - submit: function (e) { - this.showLoading(); - - e.preventDefault(); - e.stopPropagation(); - - const submitAction = function () { - if (this.context.math.focusElement.value.trim().length === 0) return false; - - const contextMath = this.context.math; - const mathExp = contextMath.focusElement.value; - const katexEl = contextMath.previewElement.querySelector('.katex'); - - if (!katexEl) return false; - katexEl.className = '__se__katex ' + katexEl.className; - katexEl.setAttribute('contenteditable', false); - katexEl.setAttribute('data-exp', this.util.HTMLEncoder(mathExp)); - katexEl.setAttribute('data-font-size', contextMath.fontSizeElement.value); - katexEl.style.fontSize = contextMath.fontSizeElement.value; - - if (!this.context.dialog.updateModal) { - const selectedFormats = this.getSelectedElements(); - - if (selectedFormats.length > 1) { - const oFormat = this.util.createElement(selectedFormats[0].nodeName); - oFormat.appendChild(katexEl); - if (!this.insertNode(oFormat, null, true)) return false; - } else { - if (!this.insertNode(katexEl, null, true)) return false; - } - - const empty = this.util.createTextNode(this.util.zeroWidthSpace); - katexEl.parentNode.insertBefore(empty, katexEl.nextSibling); - this.setRange(katexEl, 0, katexEl, 1); - } else { - const containerEl = this.util.getParentElement(contextMath._mathExp, '.katex'); - containerEl.parentNode.replaceChild(katexEl, containerEl); - this.setRange(katexEl, 0, katexEl, 1); - } - - contextMath.focusElement.value = ''; - contextMath.fontSizeElement.value = '1em'; - contextMath.previewElement.style.fontSize = '1em'; - contextMath.previewElement.innerHTML = ''; - - return true; - }.bind(this); - - try { - if (submitAction()) { - this.plugins.dialog.close.call(this); - // history stack - this.history.push(false); - } - } catch (e) { - this.plugins.dialog.close.call(this); - } finally { - this.closeLoading(); - } - - return false; - }, - - active: function (element) { - if (!element) { - if (this.controllerArray.indexOf(this.context.math.mathController) > -1) { - this.controllersOff(); - } - } else if (element.getAttribute('data-exp')) { - if (this.controllerArray.indexOf(this.context.math.mathController) < 0) { - this.setRange(element, 0, element, 1); - this.plugins.math.call_controller.call(this, element); - } - return true; - } - - return false; - }, - - on: function (update) { - if (!update) { - this.plugins.math.init.call(this); - } else { - const contextMath = this.context.math; - if (contextMath._mathExp) { - const exp = this.util.HTMLDecoder(contextMath._mathExp.getAttribute('data-exp')); - const fontSize = contextMath._mathExp.getAttribute('data-font-size') || '1em'; - this.context.dialog.updateModal = true; - contextMath.focusElement.value = exp; - contextMath.fontSizeElement.value = fontSize; - contextMath.previewElement.innerHTML = this.plugins.math._renderer.call(this, exp); - contextMath.previewElement.style.fontSize = fontSize; - } - } - }, - - call_controller: function (mathTag) { - this.context.math._mathExp = mathTag; - const mathBtn = this.context.math.mathController; - - this.setControllerPosition(mathBtn, mathTag, 'bottom', {left: 0, top: 0}); - this.controllersOn(mathBtn, mathTag, 'math'); - }, - - onClick_mathController: function (e) { - e.stopPropagation(); - - const command = e.target.getAttribute('data-command') || e.target.parentNode.getAttribute('data-command'); - if (!command) return; - - e.preventDefault(); - - if (/update/.test(command)) { - this.context.math.focusElement.value = this.util.HTMLDecoder(this.context.math._mathExp.getAttribute('data-exp')); - this.plugins.dialog.open.call(this, 'math', true); - } else { - /** delete */ - this.util.removeItem(this.context.math._mathExp); - this.context.math._mathExp = null; - this.focus(); - - // history stack - this.history.push(false); - } - - this.controllersOff(); - }, - - init: function () { - const contextMath = this.context.math; - contextMath.mathController.style.display = 'none'; - contextMath._mathExp = null; - contextMath.focusElement.value = ''; - contextMath.previewElement.innerHTML = ''; - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/dialog/video.js": -/*!************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/dialog/video.js ***! - \************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/dialog */ "./node_modules/suneditor/src/plugins/modules/dialog.js"); -/* harmony import */ var _modules_dialog__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_modules_dialog__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _modules_component__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../modules/component */ "./node_modules/suneditor/src/plugins/modules/component.js"); -/* harmony import */ var _modules_component__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_modules_component__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _modules_resizing__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../modules/resizing */ "./node_modules/suneditor/src/plugins/modules/resizing.js"); -/* harmony import */ var _modules_resizing__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_modules_resizing__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _modules_fileManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../modules/fileManager */ "./node_modules/suneditor/src/plugins/modules/fileManager.js"); -/* harmony import */ var _modules_fileManager__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_modules_fileManager__WEBPACK_IMPORTED_MODULE_3__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - - - - - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'video', - display: 'dialog', - add: function (core) { - core.addModule([_modules_dialog__WEBPACK_IMPORTED_MODULE_0___default.a, _modules_component__WEBPACK_IMPORTED_MODULE_1___default.a, _modules_resizing__WEBPACK_IMPORTED_MODULE_2___default.a, _modules_fileManager__WEBPACK_IMPORTED_MODULE_3___default.a]); - - const options = core.options; - const context = core.context; - const contextVideo = context.video = { - _infoList: [], // @Override fileManager - _infoIndex: 0, // @Override fileManager - _uploadFileLength: 0, // @Override fileManager - focusElement: null, // @Override dialog // This element has focus when the dialog is opened. - sizeUnit: options._videoSizeUnit, - _align: 'none', - _floatClassRegExp: '__se__float\\-[a-z]+', - _youtubeQuery: options.youtubeQuery, - _videoRatio: (options.videoRatio * 100) + '%', - _defaultRatio: (options.videoRatio * 100) + '%', - _linkValue: '', - // @require @Override component - _element: null, - _cover: null, - _container: null, - // @Override resizing properties - inputX: null, - inputY: null, - _element_w: 1, - _element_h: 1, - _element_l: 0, - _element_t: 0, - _defaultSizeX: '100%', - _defaultSizeY: (options.videoRatio * 100) + '%', - _origin_w: options.videoWidth === '100%' ? '' : options.videoWidth, - _origin_h: options.videoHeight === '56.25%' ? '' : options.videoHeight, - _proportionChecked: true, - _resizing: options.videoResizing, - _resizeDotHide: !options.videoHeightShow, - _rotation: options.videoRotation, - _onlyPercentage: options.videoSizeOnlyPercentage, - _ratio: false, - _ratioX: 1, - _ratioY: 1, - _captionShow: false - }; - - /** video dialog */ - let video_dialog = this.setDialog(core); - contextVideo.modal = video_dialog; - contextVideo.videoInputFile = video_dialog.querySelector('._se_video_file'); - contextVideo.videoUrlFile = video_dialog.querySelector('.se-input-url'); - contextVideo.focusElement = contextVideo.videoUrlFile || contextVideo.videoInputFile; - contextVideo.preview = video_dialog.querySelector('.se-link-preview'); - - /** add event listeners */ - video_dialog.querySelector('form').addEventListener('submit', this.submit.bind(core)); - if (contextVideo.videoInputFile) video_dialog.querySelector('.se-dialog-files-edge-button').addEventListener('click', this._removeSelectedFiles.bind(contextVideo.videoInputFile, contextVideo.videoUrlFile, contextVideo.preview)); - if (contextVideo.videoInputFile && contextVideo.videoUrlFile) contextVideo.videoInputFile.addEventListener('change', this._fileInputChange.bind(contextVideo)); - if (contextVideo.videoUrlFile) contextVideo.videoUrlFile.addEventListener('input', this._onLinkPreview.bind(contextVideo.preview, contextVideo, options.linkProtocol)); - - contextVideo.proportion = {}; - contextVideo.videoRatioOption = {}; - contextVideo.inputX = {}; - contextVideo.inputY = {}; - if (options.videoResizing) { - contextVideo.proportion = video_dialog.querySelector('._se_video_check_proportion'); - contextVideo.videoRatioOption = video_dialog.querySelector('.se-video-ratio'); - contextVideo.inputX = video_dialog.querySelector('._se_video_size_x'); - contextVideo.inputY = video_dialog.querySelector('._se_video_size_y'); - contextVideo.inputX.value = options.videoWidth; - contextVideo.inputY.value = options.videoHeight; - - contextVideo.inputX.addEventListener('keyup', this.setInputSize.bind(core, 'x')); - contextVideo.inputY.addEventListener('keyup', this.setInputSize.bind(core, 'y')); - - contextVideo.inputX.addEventListener('change', this.setRatio.bind(core)); - contextVideo.inputY.addEventListener('change', this.setRatio.bind(core)); - contextVideo.proportion.addEventListener('change', this.setRatio.bind(core)); - contextVideo.videoRatioOption.addEventListener('change', this.setVideoRatio.bind(core)); - - video_dialog.querySelector('.se-dialog-btn-revert').addEventListener('click', this.sizeRevert.bind(core)); - } - - /** append html */ - context.dialog.modal.appendChild(video_dialog); - - /** empty memory */ - video_dialog = null; - }, - - /** dialog */ - setDialog: function (core) { - const option = core.options; - const lang = core.lang; - const dialog = core.util.createElement('DIV'); - - dialog.className = 'se-dialog-content'; - dialog.style.display = 'none'; - let html = '' + - '
' + - '
' + - '' + - '' + lang.dialogBox.videoBox.title + '' + - '
' + - '
'; - - if (option.videoFileInput) { - html += '' + - '
' + - '' + - '
' + - '' + - '' + - '
' + - '
' ; - } - - if (option.videoUrlInput) { - html += '' + - '
' + - '' + - '' + - '' + - '
'; - } - - if (option.videoResizing) { - const ratioList = option.videoRatioList || [{name: '16:9', value: 0.5625}, {name: '4:3', value: 0.75}, {name: '21:9', value: 0.4285}]; - const ratio = option.videoRatio; - const onlyPercentage = option.videoSizeOnlyPercentage; - const onlyPercentDisplay = onlyPercentage ? ' style="display: none !important;"' : ''; - const heightDisplay = !option.videoHeightShow ? ' style="display: none !important;"' : ''; - const ratioDisplay = !option.videoRatioShow ? ' style="display: none !important;"' : ''; - const onlyWidthDisplay = !onlyPercentage && !option.videoHeightShow && !option.videoRatioShow ? ' style="display: none !important;"' : ''; - html += '' + - '
' + - '
' + - '' + - '' + - '' + - '' + - '
' + - '' + - '' + - '' + - '' + - '' + - '
' + - ''; - } - - html += '' + - '
' + - '' + - '
'; - - dialog.innerHTML = html; - - return dialog; - }, - - _fileInputChange: function () { - if (!this.videoInputFile.value) { - this.videoUrlFile.removeAttribute('disabled'); - this.preview.style.textDecoration = ''; - } else { - this.videoUrlFile.setAttribute('disabled', true); - this.preview.style.textDecoration = 'line-through'; - } - }, - - _removeSelectedFiles: function (urlInput, preview) { - this.value = ''; - if (urlInput) { - urlInput.removeAttribute('disabled'); - preview.style.textDecoration = ''; - } - }, - - _onLinkPreview: function (context, protocol, e) { - const value = e.target.value.trim(); - if (/^$/.test(value)) { - context._linkValue = value; - this.textContent = ''; - } else { - context._linkValue = this.textContent = !value ? '' : (protocol && value.indexOf('://') === -1 && value.indexOf('#') !== 0) ? protocol + value : value.indexOf('://') === -1 ? '/' + value : value; - } - }, - - _setTagAttrs: function (element) { - element.setAttribute('controls', true); - - const attrs = this.options.videoTagAttrs; - if (!attrs) return; - - for (let key in attrs) { - if (!this.util.hasOwn(attrs, key)) continue; - element.setAttribute(key, attrs[key]); - } - }, - - createVideoTag: function () { - const videoTag = this.util.createElement('VIDEO'); - this.plugins.video._setTagAttrs.call(this, videoTag); - return videoTag; - }, - - _setIframeAttrs: function (element) { - element.frameBorder = '0'; - element.allowFullscreen = true; - - const attrs = this.options.videoIframeAttrs; - if (!attrs) return; - - for (let key in attrs) { - if (!this.util.hasOwn(attrs, key)) continue; - element.setAttribute(key, attrs[key]); - } - }, - - createIframeTag: function () { - const iframeTag = this.util.createElement('IFRAME'); - this.plugins.video._setIframeAttrs.call(this, iframeTag); - return iframeTag; - }, - - /** - * @Override @Required fileManager - */ - fileTags: ['iframe', 'video'], - - /** - * @Override core, resizing, fileManager - * @description It is called from core.selectComponent. - * @param {Element} element Target element - */ - select: function (element) { - this.plugins.video.onModifyMode.call(this, element, this.plugins.resizing.call_controller_resize.call(this, element, 'video')); - }, - - /** - * @Override fileManager, resizing - */ - destroy: function (element) { - const frame = element || this.context.video._element; - const container = this.context.video._container; - const dataIndex = frame.getAttribute('data-index') * 1; - let focusEl = (container.previousElementSibling || container.nextElementSibling); - - const emptyDiv = container.parentNode; - this.util.removeItem(container); - this.plugins.video.init.call(this); - this.controllersOff(); - - if (emptyDiv !== this.context.element.wysiwyg) this.util.removeItemAllParents(emptyDiv, function (current) { return current.childNodes.length === 0; }, null); - - // focus - this.focusEdge(focusEl); - - // event - this.plugins.fileManager.deleteInfo.call(this, 'video', dataIndex, this.functions.onVideoUpload); - - // history stack - this.history.push(false); - }, - - /** - * @Required @Override dialog - */ - on: function (update) { - const contextVideo = this.context.video; - - if (!update) { - contextVideo.inputX.value = contextVideo._origin_w = this.options.videoWidth === contextVideo._defaultSizeX ? '' : this.options.videoWidth; - contextVideo.inputY.value = contextVideo._origin_h = this.options.videoHeight === contextVideo._defaultSizeY ? '' : this.options.videoHeight; - contextVideo.proportion.disabled = true; - if (contextVideo.videoInputFile && this.options.videoMultipleFile) contextVideo.videoInputFile.setAttribute('multiple', 'multiple'); - } else { - if (contextVideo.videoInputFile && this.options.videoMultipleFile) contextVideo.videoInputFile.removeAttribute('multiple'); - } - - if (contextVideo._resizing) { - this.plugins.video.setVideoRatioSelect.call(this, contextVideo._origin_h || contextVideo._defaultRatio); - } - }, - - /** - * @Required @Override dialog - */ - open: function () { - this.plugins.dialog.open.call(this, 'video', 'video' === this.currentControllerName); - }, - - setVideoRatio: function (e) { - const contextVideo = this.context.video; - const value = e.target.options[e.target.selectedIndex].value; - - contextVideo._defaultSizeY = contextVideo._videoRatio = !value ? contextVideo._defaultSizeY : (value * 100) + '%'; - contextVideo.inputY.placeholder = !value ? '' : (value * 100) + '%'; - contextVideo.inputY.value = ''; - }, - - /** - * @Override resizing - * @param {String} xy 'x': width, 'y': height - * @param {KeyboardEvent} e Event object - */ - setInputSize: function (xy, e) { - if (e && e.keyCode === 32) { - e.preventDefault(); - return; - } - - const contextVideo = this.context.video; - this.plugins.resizing._module_setInputSize.call(this, contextVideo, xy); - - if (xy === 'y') { - this.plugins.video.setVideoRatioSelect.call(this, e.target.value || contextVideo._defaultRatio); - } - }, - - /** - * @Override resizing - */ - setRatio: function () { - this.plugins.resizing._module_setRatio.call(this, this.context.video); - }, - - submit: function (e) { - const contextVideo = this.context.video; - const videoPlugin = this.plugins.video; - - e.preventDefault(); - e.stopPropagation(); - - contextVideo._align = contextVideo.modal.querySelector('input[name="suneditor_video_radio"]:checked').value; - - try { - if (contextVideo.videoInputFile && contextVideo.videoInputFile.files.length > 0) { - this.showLoading(); - videoPlugin.submitAction.call(this, this.context.video.videoInputFile.files); - } else if (contextVideo.videoUrlFile && contextVideo._linkValue.length > 0) { - this.showLoading(); - videoPlugin.setup_url.call(this); - } - } catch (error) { - this.closeLoading(); - throw Error('[SUNEDITOR.video.submit.fail] cause : "' + error.message + '"'); - } finally { - this.plugins.dialog.close.call(this); - } - - return false; - }, - - submitAction: function (fileList) { - if (fileList.length === 0) return; - - let fileSize = 0; - let files = []; - for (let i = 0, len = fileList.length; i < len; i++) { - if (/video/i.test(fileList[i].type)) { - files.push(fileList[i]); - fileSize += fileList[i].size; - } - } - - const limitSize = this.options.videoUploadSizeLimit; - if (limitSize > 0) { - let infoSize = 0; - const videosInfo = this.context.video._infoList; - for (let i = 0, len = videosInfo.length; i < len; i++) { - infoSize += videosInfo[i].size * 1; - } - - if ((fileSize + infoSize) > limitSize) { - this.closeLoading(); - const err = '[SUNEDITOR.videoUpload.fail] Size of uploadable total videos: ' + (limitSize/1000) + 'KB'; - if (typeof this.functions.onVideoUploadError !== 'function' || this.functions.onVideoUploadError(err, { 'limitSize': limitSize, 'currentSize': infoSize, 'uploadSize': fileSize }, this)) { - this.functions.noticeOpen(err); - } - return; - } - } - - const contextVideo = this.context.video; - contextVideo._uploadFileLength = files.length; - - const info = { - inputWidth: contextVideo.inputX.value, - inputHeight: contextVideo.inputY.value, - align: contextVideo._align, - isUpdate: this.context.dialog.updateModal, - element: contextVideo._element - }; - - if (typeof this.functions.onVideoUploadBefore === 'function') { - const result = this.functions.onVideoUploadBefore(files, info, this, function (data) { - if (data && this._w.Array.isArray(data.result)) { - this.plugins.video.register.call(this, info, data); - } else { - this.plugins.video.upload.call(this, info, data); - } - }.bind(this)); - - if (typeof result === 'undefined') return; - if (!result) { - this.closeLoading(); - return; - } - if (typeof result === 'object' && result.length > 0) files = result; - } - - this.plugins.video.upload.call(this, info, files); - }, - - error: function (message, response) { - this.closeLoading(); - if (typeof this.functions.onVideoUploadError !== 'function' || this.functions.onVideoUploadError(message, response, this)) { - this.functions.noticeOpen(message); - throw Error('[SUNEDITOR.plugin.video.error] response: ' + message); - } - }, - - upload: function (info, files) { - if (!files) { - this.closeLoading(); - return; - } - if (typeof files === 'string') { - this.plugins.video.error.call(this, files, null); - return; - } - - const videoUploadUrl = this.options.videoUploadUrl; - const filesLen = this.context.dialog.updateModal ? 1 : files.length; - - // server upload - if (typeof videoUploadUrl === 'string' && videoUploadUrl.length > 0) { - const formData = new FormData(); - for (let i = 0; i < filesLen; i++) { - formData.append('file-' + i, files[i]); - } - this.plugins.fileManager.upload.call(this, videoUploadUrl, this.options.videoUploadHeader, formData, this.plugins.video.callBack_videoUpload.bind(this, info), this.functions.onVideoUploadError); - } else { - throw Error('[SUNEDITOR.videoUpload.fail] cause : There is no "videoUploadUrl" option.'); - } - }, - - callBack_videoUpload: function (info, xmlHttp) { - if (typeof this.functions.videoUploadHandler === 'function') { - this.functions.videoUploadHandler(xmlHttp, info, this); - } else { - const response = JSON.parse(xmlHttp.responseText); - if (response.errorMessage) { - this.plugins.video.error.call(this, response.errorMessage, response); - } else { - this.plugins.video.register.call(this, info, response); - } - } - }, - - register: function (info, response) { - const fileList = response.result; - const videoTag = this.plugins.video.createVideoTag.call(this); - - for (let i = 0, len = fileList.length, file; i < len; i++) { - file = { name: fileList[i].name, size: fileList[i].size }; - this.plugins.video.create_video.call(this, (info.isUpdate ? info.element : videoTag.cloneNode(false)), fileList[i].url, info.inputWidth, info.inputHeight, info.align, file, info.isUpdate); - } - - this.closeLoading(); - }, - - setup_url: function () { - try { - const contextVideo = this.context.video; - let url = contextVideo._linkValue; - - if (url.length === 0) return false; - - /** iframe source */ - if (/^$/.test(url)) { - const oIframe = (new this._w.DOMParser()).parseFromString(url, 'text/html').querySelector('iframe'); - url = oIframe.src; - if (url.length === 0) return false; - } - - /** youtube */ - if (/youtu\.?be/.test(url)) { - if (!/^http/.test(url)) url = 'https://' + url; - url = url.replace('watch?v=', ''); - if (!/^\/\/.+\/embed\//.test(url)) { - url = url.replace(url.match(/\/\/.+\//)[0], '//www.youtube.com/embed/').replace('&', '?&'); - } - - if (contextVideo._youtubeQuery.length > 0) { - if (/\?/.test(url)) { - const splitUrl = url.split('?'); - url = splitUrl[0] + '?' + contextVideo._youtubeQuery + '&' + splitUrl[1]; - } else { - url += '?' + contextVideo._youtubeQuery; - } - } - } else if (/vimeo\.com/.test(url)) { - if (url.endsWith('/')) { - url = url.slice(0, -1); - } - url = 'https://player.vimeo.com/video/' + url.slice(url.lastIndexOf('/') + 1); - } - - this.plugins.video.create_video.call(this, this.plugins.video.createIframeTag.call(this), url, contextVideo.inputX.value, contextVideo.inputY.value, contextVideo._align, null, this.context.dialog.updateModal); - } catch (error) { - throw Error('[SUNEDITOR.video.upload.fail] cause : "' + error.message + '"'); - } finally { - this.closeLoading(); - } - }, - - create_video: function (oFrame, src, width, height, align, file, isUpdate) { - this.context.resizing._resize_plugin = 'video'; - const contextVideo = this.context.video; - - let cover = null; - let container = null; - let init = false; - - /** update */ - if (isUpdate) { - oFrame = contextVideo._element; - if (oFrame.src !== src) { - init = true; - const isYoutube = /youtu\.?be/.test(src); - const isVimeo = /vimeo\.com/.test(src); - if ((isYoutube || isVimeo) && !/^iframe$/i.test(oFrame.nodeName)) { - const newTag = this.plugins.video.createIframeTag.call(this); - newTag.src = src; - oFrame.parentNode.replaceChild(newTag, oFrame); - contextVideo._element = oFrame = newTag; - } else if (!isYoutube && !isVimeo && !/^videoo$/i.test(oFrame.nodeName)) { - const newTag = this.plugins.video.createVideoTag.call(this); - newTag.src = src; - oFrame.parentNode.replaceChild(newTag, oFrame); - contextVideo._element = oFrame = newTag; - } else { - oFrame.src = src; - } - } - container = contextVideo._container; - cover = this.util.getParentElement(oFrame, 'FIGURE'); - } - /** create */ - else { - init = true; - oFrame.src = src; - contextVideo._element = oFrame; - cover = this.plugins.component.set_cover.call(this, oFrame); - container = this.plugins.component.set_container.call(this, cover, 'se-video-container'); - } - - /** rendering */ - contextVideo._cover = cover; - contextVideo._container = container; - - const inputUpdate = (this.plugins.resizing._module_getSizeX.call(this, contextVideo) !== (width || contextVideo._defaultSizeX)) || (this.plugins.resizing._module_getSizeY.call(this, contextVideo) !== (height || contextVideo._videoRatio)); - const changeSize = !isUpdate || inputUpdate; - - if (contextVideo._resizing) { - this.context.video._proportionChecked = contextVideo.proportion.checked; - oFrame.setAttribute('data-proportion', contextVideo._proportionChecked); - } - - // size - let isPercent = false; - if (changeSize) { - isPercent = this.plugins.video.applySize.call(this); - } - - // align - if (!(isPercent && align === 'center')) { - this.plugins.video.setAlign.call(this, null, oFrame, cover, container); - } - - let changed = true; - if (!isUpdate) { - changed = this.insertComponent(container, false, true, !this.options.mediaAutoSelect); - if (!this.options.mediaAutoSelect) { - const line = this.appendFormatTag(container, null); - this.setRange(line, 0, line, 0); - } - } else if (contextVideo._resizing && this.context.resizing._rotateVertical && changeSize) { - this.plugins.resizing.setTransformSize.call(this, oFrame, null, null); - } - - if (changed) { - if (init) { - this.plugins.fileManager.setInfo.call(this, 'video', oFrame, this.functions.onVideoUpload, file, true); - } - if (isUpdate) { - this.selectComponent(oFrame, 'video'); - // history stack - this.history.push(false); - } - } - - this.context.resizing._resize_plugin = ''; - }, - - _update_videoCover: function (oFrame) { - if (!oFrame) return; - - const contextVideo = this.context.video; - - if (/^video$/i.test(oFrame.nodeName)) this.plugins.video._setTagAttrs.call(this, oFrame); - else this.plugins.video._setIframeAttrs.call(this, oFrame); - - const existElement = this.util.getParentElement(oFrame, this.util.isMediaComponent) || - this.util.getParentElement(oFrame, function (current) { - return this.isWysiwygDiv(current.parentNode); - }.bind(this.util)); - - contextVideo._element = oFrame = oFrame.cloneNode(true); - const cover = contextVideo._cover = this.plugins.component.set_cover.call(this, oFrame); - const container = contextVideo._container = this.plugins.component.set_container.call(this, cover, 'se-video-container'); - - const figcaption = existElement.querySelector('figcaption'); - let caption = null; - if (!!figcaption) { - caption = this.util.createElement('DIV'); - caption.innerHTML = figcaption.innerHTML; - this.util.removeItem(figcaption); - } - - const size = (oFrame.getAttribute('data-size') || oFrame.getAttribute('data-origin') || '').split(','); - this.plugins.video.applySize.call(this, size[0], size[1]); - - if (this.util.isFormatElement(existElement) && existElement.textContent.length > 0) { - existElement.parentNode.insertBefore(container, existElement.nextElementSibling); - this.util.removeItem(contextVideo._element); - contextVideo._element = oFrame; - } else { - existElement.parentNode.replaceChild(container, existElement); - } - - if (!!caption) existElement.parentNode.insertBefore(caption, container.nextElementSibling); - this.plugins.fileManager.setInfo.call(this, 'video', oFrame, this.functions.onVideoUpload, null, true); - }, - - /** - * @Required @Override fileManager, resizing - */ - onModifyMode: function (element, size) { - const contextVideo = this.context.video; - contextVideo._element = element; - contextVideo._cover = this.util.getParentElement(element, 'FIGURE'); - contextVideo._container = this.util.getParentElement(element, this.util.isMediaComponent); - contextVideo._align = element.style.float || element.getAttribute('data-align') || 'none'; - element.style.float = ''; - - if (size) { - contextVideo._element_w = size.w; - contextVideo._element_h = size.h; - contextVideo._element_t = size.t; - contextVideo._element_l = size.l; - } - - let origin = contextVideo._element.getAttribute('data-size') || contextVideo._element.getAttribute('data-origin'); - if (origin) { - origin = origin.split(','); - contextVideo._origin_w = origin[0]; - contextVideo._origin_h = origin[1]; - } else if (size) { - contextVideo._origin_w = size.w; - contextVideo._origin_h = size.h; - } - }, - - /** - * @Required @Override fileManager, resizing - */ - openModify: function (notOpen) { - const contextVideo = this.context.video; - - if (contextVideo.videoUrlFile) contextVideo._linkValue = contextVideo.preview.textContent = contextVideo.videoUrlFile.value = (contextVideo._element.src || (contextVideo._element.querySelector('source') || '').src || ''); - contextVideo.modal.querySelector('input[name="suneditor_video_radio"][value="' + contextVideo._align + '"]').checked = true; - - if (contextVideo._resizing) { - this.plugins.resizing._module_setModifyInputSize.call(this, contextVideo, this.plugins.video); - - const y = contextVideo._videoRatio = this.plugins.resizing._module_getSizeY.call(this, contextVideo); - const ratioSelected = this.plugins.video.setVideoRatioSelect.call(this, y); - if (!ratioSelected) contextVideo.inputY.value = contextVideo._onlyPercentage ? this.util.getNumber(y, 2) : y; - } - - if (!notOpen) this.plugins.dialog.open.call(this, 'video', true); - }, - - setVideoRatioSelect: function (value) { - let ratioSelected = false; - const contextVideo = this.context.video; - const ratioOptions = contextVideo.videoRatioOption.options; - - if (/%$/.test(value) || contextVideo._onlyPercentage) value = (this.util.getNumber(value, 2) / 100) + ''; - else if (!this.util.isNumber(value) || (value * 1) >= 1) value = ''; - - contextVideo.inputY.placeholder = ''; - for (let i = 0, len = ratioOptions.length; i < len; i++) { - if (ratioOptions[i].value === value) { - ratioSelected = ratioOptions[i].selected = true; - contextVideo.inputY.placeholder = !value ? '' : (value * 100) + '%'; - } - else ratioOptions[i].selected = false; - } - - return ratioSelected; - }, - - /** - * @Override fileManager - */ - checkFileInfo: function () { - this.plugins.fileManager.checkInfo.call(this, 'video', ['iframe', 'video'], this.functions.onVideoUpload, this.plugins.video._update_videoCover.bind(this), true); - }, - - /** - * @Override fileManager - */ - resetFileInfo: function () { - this.plugins.fileManager.resetInfo.call(this, 'video', this.functions.onVideoUpload); - }, - - /** - * @Override fileManager - */ - applySize: function (w, h) { - const contextVideo = this.context.video; - - if (!w) w = contextVideo.inputX.value || this.options.videoWidth; - if (!h) h = contextVideo.inputY.value || this.options.videoHeight; - - if (contextVideo._onlyPercentage || /%$/.test(w) || !w) { - this.plugins.video.setPercentSize.call(this, (w || '100%'), (h || (/%$/.test(contextVideo._videoRatio) ? contextVideo._videoRatio : contextVideo._defaultRatio))); - return true; - } else if ((!w || w === 'auto') && (!h || h === 'auto')) { - this.plugins.video.setAutoSize.call(this); - } else { - this.plugins.video.setSize.call(this, w, (h || contextVideo._videoRatio || contextVideo._defaultRatio), false); - } - - return false; - }, - - /** - * @Override resizing - */ - sizeRevert: function () { - this.plugins.resizing._module_sizeRevert.call(this, this.context.video); - }, - - /** - * @Override resizing - */ - setSize: function (w, h, notResetPercentage, direction) { - const contextVideo = this.context.video; - const onlyW = /^(rw|lw)$/.test(direction); - const onlyH = /^(th|bh)$/.test(direction); - - if (!onlyH) w = this.util.getNumber(w, 0); - if (!onlyW) h = this.util.isNumber(h) ? h + contextVideo.sizeUnit : !h ? '' : h; - - if (!onlyH) contextVideo._element.style.width = w ? w + contextVideo.sizeUnit : ''; - if (!onlyW) contextVideo._cover.style.paddingBottom = contextVideo._cover.style.height = h; - - if (!onlyH && !/%$/.test(w)) { - contextVideo._cover.style.width = ''; - contextVideo._container.style.width = ''; - } - - if (!onlyW && !/%$/.test(h)) { - contextVideo._element.style.height = h; - } else { - contextVideo._element.style.height = ''; - } - - if (!notResetPercentage) contextVideo._element.removeAttribute('data-percentage'); - - // save current size - this.plugins.resizing._module_saveCurrentSize.call(this, contextVideo); - }, - - /** - * @Override resizing - */ - setAutoSize: function () { - this.plugins.video.setPercentSize.call(this, 100, this.context.video._defaultRatio); - }, - - /** - * @Override resizing - */ - setOriginSize: function (dataSize) { - const contextVideo = this.context.video; - contextVideo._element.removeAttribute('data-percentage'); - - this.plugins.resizing.resetTransform.call(this, contextVideo._element); - this.plugins.video.cancelPercentAttr.call(this); - - const originSize = ((dataSize ? contextVideo._element.getAttribute('data-size') : '') || contextVideo._element.getAttribute('data-origin') || '').split(','); - - if (originSize) { - const w = originSize[0]; - const h = originSize[1]; - - if (contextVideo._onlyPercentage || (/%$/.test(w) && (/%$/.test(h) || !/\d/.test(h)))) { - this.plugins.video.setPercentSize.call(this, w, h); - } else { - this.plugins.video.setSize.call(this, w, h); - } - - // save current size - this.plugins.resizing._module_saveCurrentSize.call(this, contextVideo); - } - }, - - /** - * @Override resizing - */ - setPercentSize: function (w, h) { - const contextVideo = this.context.video; - h = !!h && !/%$/.test(h) && !this.util.getNumber(h, 0) ? this.util.isNumber(h) ? h + '%' : h : this.util.isNumber(h) ? h + contextVideo.sizeUnit : (h || contextVideo._defaultRatio); - - contextVideo._container.style.width = this.util.isNumber(w) ? w + '%' : w; - contextVideo._container.style.height = ''; - contextVideo._cover.style.width = '100%'; - contextVideo._cover.style.height = h; - contextVideo._cover.style.paddingBottom = h; - contextVideo._element.style.width = '100%'; - contextVideo._element.style.height = '100%'; - contextVideo._element.style.maxWidth = ''; - - if (contextVideo._align === 'center') this.plugins.video.setAlign.call(this, null, null, null, null); - contextVideo._element.setAttribute('data-percentage', w + ',' + h); - - // save current size - this.plugins.resizing._module_saveCurrentSize.call(this, contextVideo); - }, - - /** - * @Override resizing - */ - cancelPercentAttr: function () { - const contextVideo = this.context.video; - - contextVideo._cover.style.width = ''; - contextVideo._cover.style.height = ''; - contextVideo._cover.style.paddingBottom = ''; - contextVideo._container.style.width = ''; - contextVideo._container.style.height = ''; - - this.util.removeClass(contextVideo._container, this.context.video._floatClassRegExp); - this.util.addClass(contextVideo._container, '__se__float-' + contextVideo._align); - - if (contextVideo._align === 'center') this.plugins.video.setAlign.call(this, null, null, null, null); - }, - - /** - * @Override resizing - */ - setAlign: function (align, element, cover, container) { - const contextVideo = this.context.video; - - if (!align) align = contextVideo._align; - if (!element) element = contextVideo._element; - if (!cover) cover = contextVideo._cover; - if (!container) container = contextVideo._container; - - if (align && align !== 'none') { - cover.style.margin = 'auto'; - } else { - cover.style.margin = '0'; - } - - if (/%$/.test(element.style.width) && align === 'center') { - container.style.minWidth = '100%'; - cover.style.width = container.style.width; - cover.style.height = cover.style.height; - cover.style.paddingBottom = !/%$/.test(cover.style.height) ? cover.style.height : this.util.getNumber((this.util.getNumber(cover.style.height, 2) / 100) * this.util.getNumber(cover.style.width, 2), 2) + '%'; - } else { - container.style.minWidth = ''; - cover.style.width = this.context.resizing._rotateVertical ? (element.style.height || element.offsetHeight) : (element.style.width || '100%'); - cover.style.paddingBottom = cover.style.height; - } - - if (!this.util.hasClass(container, '__se__float-' + align)) { - this.util.removeClass(container, contextVideo._floatClassRegExp); - this.util.addClass(container, '__se__float-' + align); - } - - element.setAttribute('data-align', align); - }, - - /** - * @Override dialog - */ - init: function () { - const contextVideo = this.context.video; - if (contextVideo.videoInputFile) contextVideo.videoInputFile.value = ''; - if (contextVideo.videoUrlFile) contextVideo._linkValue = contextVideo.preview.textContent = contextVideo.videoUrlFile.value = ''; - if (contextVideo.videoInputFile && contextVideo.videoUrlFile) { - contextVideo.videoUrlFile.removeAttribute('disabled'); - contextVideo.preview.style.textDecoration = ''; - } - - contextVideo._origin_w = this.options.videoWidth; - contextVideo._origin_h = this.options.videoHeight; - contextVideo.modal.querySelector('input[name="suneditor_video_radio"][value="none"]').checked = true; - - if (contextVideo._resizing) { - contextVideo.inputX.value = this.options.videoWidth === contextVideo._defaultSizeX ? '' : this.options.videoWidth; - contextVideo.inputY.value = this.options.videoHeight === contextVideo._defaultSizeY ? '' : this.options.videoHeight; - contextVideo.proportion.checked = true; - contextVideo.proportion.disabled = true; - this.plugins.video.setVideoRatioSelect.call(this, contextVideo._defaultRatio); - } - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/fileBrowser/imageGallery.js": -/*!************************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/fileBrowser/imageGallery.js ***! - \************************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _modules_fileBrowser__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/fileBrowser */ "./node_modules/suneditor/src/plugins/modules/fileBrowser.js"); -/* harmony import */ var _modules_fileBrowser__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_modules_fileBrowser__WEBPACK_IMPORTED_MODULE_0__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'imageGallery', - /** - * @description Constructor - * @param {Object} core Core object - */ - add: function (core) { - core.addModule([_modules_fileBrowser__WEBPACK_IMPORTED_MODULE_0___default.a]); - - const context = core.context; - context.imageGallery = { - title: core.lang.toolbar.imageGallery, // @Required @Override fileBrowser - File browser window title. - url: core.options.imageGalleryUrl, // @Required @Override fileBrowser - File server url. - listClass: 'se-image-list', // @Required @Override fileBrowser - Class name of list div. - itemTemplateHandler: this.drawItems, // @Required @Override fileBrowser - Function that defines the HTML of an file item. - selectorHandler: this.setImage.bind(core), // @Required @Override fileBrowser - Function that action when item click. - columnSize: 4 // @Option @Override fileBrowser - Number of "div.se-file-item-column" to be created (default: 4) - }; - }, - - /** - * @Required @Override fileBrowser - * @description Open a file browser. - * @param {Function|null} selectorHandler When the function comes as an argument value, it substitutes "context.selectorHandler". - */ - open: function (selectorHandler) { - this.plugins.fileBrowser.open.call(this, 'imageGallery', selectorHandler); - }, - - /** - * @Required @Override fileBrowser - * @description Define the HTML of the item to be put in "div.se-file-item-column". - * Format: [ - * { src: "image src", name: "name(@option)", alt: "image alt(@option)", tag: "tag name(@option)" } - * ] - * @param {Object} item Item of the response data's array - */ - drawItems: function (item) { - const srcName = item.src.split('/').pop(); - return '
' + (item.alt || srcName) + '' + - '
' + - '
' + (item.name || srcName) + '
' + - '
'; - }, - - setImage: function (target) { - this.callPlugin('image', function () { - const file = {name: target.parentNode.querySelector('.__se__img_name').textContent, size: 0}; - this.context.image._altText = target.alt; - this.plugins.image.create_image.call(this, target.src, null, this.context.image._origin_w, this.context.image._origin_h, 'none', file); - }.bind(this), null); - } -}); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/index.js": -/*!*****************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/index.js ***! - \*****************************************************/ -/*! exports provided: blockquote, align, font, fontSize, fontColor, hiliteColor, horizontalRule, list, table, formatBlock, lineHeight, template, paragraphStyle, textStyle, link, image, video, audio, math, imageGallery, default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _command_blockquote__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./command/blockquote */ "./node_modules/suneditor/src/plugins/command/blockquote.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "blockquote", function() { return _command_blockquote__WEBPACK_IMPORTED_MODULE_0__["default"]; }); - -/* harmony import */ var _submenu_align__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./submenu/align */ "./node_modules/suneditor/src/plugins/submenu/align.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "align", function() { return _submenu_align__WEBPACK_IMPORTED_MODULE_1__["default"]; }); - -/* harmony import */ var _submenu_font__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./submenu/font */ "./node_modules/suneditor/src/plugins/submenu/font.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "font", function() { return _submenu_font__WEBPACK_IMPORTED_MODULE_2__["default"]; }); - -/* harmony import */ var _submenu_fontSize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./submenu/fontSize */ "./node_modules/suneditor/src/plugins/submenu/fontSize.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fontSize", function() { return _submenu_fontSize__WEBPACK_IMPORTED_MODULE_3__["default"]; }); - -/* harmony import */ var _submenu_fontColor__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./submenu/fontColor */ "./node_modules/suneditor/src/plugins/submenu/fontColor.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fontColor", function() { return _submenu_fontColor__WEBPACK_IMPORTED_MODULE_4__["default"]; }); - -/* harmony import */ var _submenu_hiliteColor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./submenu/hiliteColor */ "./node_modules/suneditor/src/plugins/submenu/hiliteColor.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "hiliteColor", function() { return _submenu_hiliteColor__WEBPACK_IMPORTED_MODULE_5__["default"]; }); - -/* harmony import */ var _submenu_horizontalRule__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./submenu/horizontalRule */ "./node_modules/suneditor/src/plugins/submenu/horizontalRule.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "horizontalRule", function() { return _submenu_horizontalRule__WEBPACK_IMPORTED_MODULE_6__["default"]; }); - -/* harmony import */ var _submenu_list__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./submenu/list */ "./node_modules/suneditor/src/plugins/submenu/list.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "list", function() { return _submenu_list__WEBPACK_IMPORTED_MODULE_7__["default"]; }); - -/* harmony import */ var _submenu_table__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./submenu/table */ "./node_modules/suneditor/src/plugins/submenu/table.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "table", function() { return _submenu_table__WEBPACK_IMPORTED_MODULE_8__["default"]; }); - -/* harmony import */ var _submenu_formatBlock__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./submenu/formatBlock */ "./node_modules/suneditor/src/plugins/submenu/formatBlock.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "formatBlock", function() { return _submenu_formatBlock__WEBPACK_IMPORTED_MODULE_9__["default"]; }); - -/* harmony import */ var _submenu_lineHeight__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./submenu/lineHeight */ "./node_modules/suneditor/src/plugins/submenu/lineHeight.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "lineHeight", function() { return _submenu_lineHeight__WEBPACK_IMPORTED_MODULE_10__["default"]; }); - -/* harmony import */ var _submenu_template__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./submenu/template */ "./node_modules/suneditor/src/plugins/submenu/template.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "template", function() { return _submenu_template__WEBPACK_IMPORTED_MODULE_11__["default"]; }); - -/* harmony import */ var _submenu_paragraphStyle__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./submenu/paragraphStyle */ "./node_modules/suneditor/src/plugins/submenu/paragraphStyle.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "paragraphStyle", function() { return _submenu_paragraphStyle__WEBPACK_IMPORTED_MODULE_12__["default"]; }); - -/* harmony import */ var _submenu_textStyle__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./submenu/textStyle */ "./node_modules/suneditor/src/plugins/submenu/textStyle.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "textStyle", function() { return _submenu_textStyle__WEBPACK_IMPORTED_MODULE_13__["default"]; }); - -/* harmony import */ var _dialog_link__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./dialog/link */ "./node_modules/suneditor/src/plugins/dialog/link.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "link", function() { return _dialog_link__WEBPACK_IMPORTED_MODULE_14__["default"]; }); - -/* harmony import */ var _dialog_image__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./dialog/image */ "./node_modules/suneditor/src/plugins/dialog/image.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "image", function() { return _dialog_image__WEBPACK_IMPORTED_MODULE_15__["default"]; }); - -/* harmony import */ var _dialog_video__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./dialog/video */ "./node_modules/suneditor/src/plugins/dialog/video.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "video", function() { return _dialog_video__WEBPACK_IMPORTED_MODULE_16__["default"]; }); - -/* harmony import */ var _dialog_audio__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./dialog/audio */ "./node_modules/suneditor/src/plugins/dialog/audio.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "audio", function() { return _dialog_audio__WEBPACK_IMPORTED_MODULE_17__["default"]; }); - -/* harmony import */ var _dialog_math__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./dialog/math */ "./node_modules/suneditor/src/plugins/dialog/math.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "math", function() { return _dialog_math__WEBPACK_IMPORTED_MODULE_18__["default"]; }); - -/* harmony import */ var _fileBrowser_imageGallery__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./fileBrowser/imageGallery */ "./node_modules/suneditor/src/plugins/fileBrowser/imageGallery.js"); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "imageGallery", function() { return _fileBrowser_imageGallery__WEBPACK_IMPORTED_MODULE_19__["default"]; }); - - - -// command - - -// submenu - - - - - - - - - - - - - - -// dialog - - - - - - -// file browser - - - -/* harmony default export */ __webpack_exports__["default"] = ({ blockquote: _command_blockquote__WEBPACK_IMPORTED_MODULE_0__["default"], align: _submenu_align__WEBPACK_IMPORTED_MODULE_1__["default"], font: _submenu_font__WEBPACK_IMPORTED_MODULE_2__["default"], fontSize: _submenu_fontSize__WEBPACK_IMPORTED_MODULE_3__["default"], fontColor: _submenu_fontColor__WEBPACK_IMPORTED_MODULE_4__["default"], hiliteColor: _submenu_hiliteColor__WEBPACK_IMPORTED_MODULE_5__["default"], horizontalRule: _submenu_horizontalRule__WEBPACK_IMPORTED_MODULE_6__["default"], list: _submenu_list__WEBPACK_IMPORTED_MODULE_7__["default"], table: _submenu_table__WEBPACK_IMPORTED_MODULE_8__["default"], formatBlock: _submenu_formatBlock__WEBPACK_IMPORTED_MODULE_9__["default"], lineHeight: _submenu_lineHeight__WEBPACK_IMPORTED_MODULE_10__["default"], template: _submenu_template__WEBPACK_IMPORTED_MODULE_11__["default"], paragraphStyle: _submenu_paragraphStyle__WEBPACK_IMPORTED_MODULE_12__["default"], textStyle: _submenu_textStyle__WEBPACK_IMPORTED_MODULE_13__["default"], link: _dialog_link__WEBPACK_IMPORTED_MODULE_14__["default"], image: _dialog_image__WEBPACK_IMPORTED_MODULE_15__["default"], video: _dialog_video__WEBPACK_IMPORTED_MODULE_16__["default"], audio: _dialog_audio__WEBPACK_IMPORTED_MODULE_17__["default"], math: _dialog_math__WEBPACK_IMPORTED_MODULE_18__["default"], imageGallery: _fileBrowser_imageGallery__WEBPACK_IMPORTED_MODULE_19__["default"] }); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/modules/_anchor.js": -/*!***************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/modules/_anchor.js ***! - \***************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'anchor', - add: function (core) { - core.context.anchor = { - caller: {}, - forms: this.setDialogForm(core), - host: core._w.location.origin + core._w.location.pathname - }; - }, - - /** dialog */ - setDialogForm: function (core) { - const lang = core.lang; - const relList = core.options.linkRel; - const defaultRel = (core.options.linkRelDefault.default || '').split(' '); - const icons = core.icons; - const forms = core.util.createElement('DIV'); - - let html = '
' + - '
' + - '' + - '
' + - '' + - '' + - '
' + - '
' + - '' + icons.bookmark + '' + - '' + icons.download + '' + - '' + - '
' + - '
' + - '
' + - '' + - '
' + - '
'; - - forms.innerHTML = html; - return forms; - }, - - initEvent: function (pluginName, forms) { - const anchorPlugin = this.plugins.anchor; - const context = this.context.anchor.caller[pluginName] = { - modal: forms, - urlInput: null, - linkDefaultRel: this.options.linkRelDefault, - defaultRel: this.options.linkRelDefault.default || '', - currentRel: [], - linkAnchor: null, - linkValue: '' - }; - - if (typeof context.linkDefaultRel.default === 'string') context.linkDefaultRel.default = context.linkDefaultRel.default.trim(); - if (typeof context.linkDefaultRel.check_new_window === 'string') context.linkDefaultRel.check_new_window = context.linkDefaultRel.check_new_window.trim(); - if (typeof context.linkDefaultRel.check_bookmark === 'string') context.linkDefaultRel.check_bookmark = context.linkDefaultRel.check_bookmark.trim(); - - context.urlInput = forms.querySelector('.se-input-url'); - context.anchorText = forms.querySelector('._se_anchor_text'); - context.newWindowCheck = forms.querySelector('._se_anchor_check'); - context.downloadCheck = forms.querySelector('._se_anchor_download'); - context.download = forms.querySelector('._se_anchor_download_icon'); - context.preview = forms.querySelector('.se-link-preview'); - context.bookmark = forms.querySelector('._se_anchor_bookmark_icon'); - context.bookmarkButton = forms.querySelector('._se_bookmark_button'); - - /** rel */ - if (this.options.linkRel.length > 0) { - context.relButton = forms.querySelector('.se-anchor-rel-btn'); - context.relList = forms.querySelector('.se-list-layer'); - context.relPreview = forms.querySelector('.se-anchor-rel-preview'); - context.relButton.addEventListener('click', anchorPlugin.onClick_relButton.bind(this, context)); - context.relList.addEventListener('click', anchorPlugin.onClick_relList.bind(this, context)); - } - - context.newWindowCheck.addEventListener('change', anchorPlugin.onChange_newWindowCheck.bind(this, context)); - context.downloadCheck.addEventListener('change', anchorPlugin.onChange_downloadCheck.bind(this, context)); - context.urlInput.addEventListener('input', anchorPlugin.setLinkPreview.bind(this, context, this.options.linkProtocol)); - context.bookmarkButton.addEventListener('click', anchorPlugin.onClick_bookmarkButton.bind(this, context)); - }, - - on: function (contextAnchor, update) { - if (!update) { - this.plugins.anchor.init.call(this, contextAnchor); - contextAnchor.anchorText.value = this.getSelection().toString(); - } else if (contextAnchor.linkAnchor) { - this.context.dialog.updateModal = true; - contextAnchor.linkValue = contextAnchor.preview.textContent = contextAnchor.urlInput.value = (contextAnchor.linkAnchor.id ? '#' + contextAnchor.linkAnchor.id : contextAnchor.linkAnchor.href); - contextAnchor.anchorText.value = contextAnchor.linkAnchor.getAttribute('alt') || contextAnchor.linkAnchor.textContent; - contextAnchor.newWindowCheck.checked = (/_blank/i.test(contextAnchor.linkAnchor.target) ? true : false); - contextAnchor.downloadCheck.checked = contextAnchor.linkAnchor.download; - } - - this.plugins.anchor.setRel.call(this, contextAnchor, (update && contextAnchor.linkAnchor) ? contextAnchor.linkAnchor.rel : contextAnchor.defaultRel); - this.plugins.anchor.setLinkPreview.call(this, contextAnchor, this.options.linkProtocol, contextAnchor.linkValue); - }, - - _closeRelMenu: null, - toggleRelList: function (contextAnchor, show) { - if (!show) { - if (this.plugins.anchor._closeRelMenu) this.plugins.anchor._closeRelMenu(); - } else { - const target = contextAnchor.relButton; - const relList = contextAnchor.relList; - this.util.addClass(target, 'active'); - relList.style.visibility = 'hidden'; - relList.style.display = 'block'; - if (!this.options.rtl) relList.style.left = (target.offsetLeft + target.offsetWidth + 1) + 'px'; - else relList.style.left = (target.offsetLeft - relList.offsetWidth - 1) + 'px'; - relList.style.top = (target.offsetTop + (target.offsetHeight / 2) - (relList.offsetHeight / 2)) + 'px'; - relList.style.visibility = ''; - - this.plugins.anchor._closeRelMenu = function (context, target, e) { - if (e && (context.relButton.contains(e.target) || context.relList.contains(e.target))) return; - this.util.removeClass(target, 'active'); - context.relList.style.display = 'none'; - this.modalForm.removeEventListener('click', this.plugins.anchor._closeRelMenu); - this.plugins.anchor._closeRelMenu = null; - }.bind(this, contextAnchor, target); - - this.modalForm.addEventListener('click', this.plugins.anchor._closeRelMenu); - } - }, - - onClick_relButton: function (contextAnchor, e) { - this.plugins.anchor.toggleRelList.call(this, contextAnchor, !this.util.hasClass(e.target, 'active')); - }, - - onClick_relList: function (contextAnchor, e) { - const target = e.target; - const cmd = target.getAttribute('data-command'); - if (!cmd) return; - - const current = contextAnchor.currentRel; - const checked = this.util.toggleClass(target, 'se-checked'); - const index = current.indexOf(cmd); - if (checked) { - if (index === -1) current.push(cmd); - } else { - if (index > -1) current.splice(index, 1); - } - - contextAnchor.relPreview.title = contextAnchor.relPreview.textContent = current.join(' '); - }, - - setRel: function (contextAnchor, relAttr) { - const relListEl = contextAnchor.relList; - const rels = contextAnchor.currentRel = !relAttr ? [] : relAttr.split(' '); - if (!relListEl) return; - - const checkedRel = relListEl.querySelectorAll('button'); - for (let i = 0, len = checkedRel.length, cmd; i < len; i++) { - cmd = checkedRel[i].getAttribute('data-command'); - if (rels.indexOf(cmd) > -1) { - this.util.addClass(checkedRel[i], 'se-checked'); - } else { - this.util.removeClass(checkedRel[i], 'se-checked'); - } - } - - contextAnchor.relPreview.title = contextAnchor.relPreview.textContent = rels.join(' '); - }, - - setLinkPreview: function (context, protocol, e) { - const preview = context.preview; - const value = typeof e === 'string' ? e : e.target.value.trim(); - const reservedProtocol = /^(mailto\:|https*\:\/\/)/.test(value); - const sameProtocol = !protocol ? false : this._w.RegExp('^' + value.substr(0, protocol.length)).test(protocol); - context.linkValue = preview.textContent = !value ? '' : (protocol && !reservedProtocol && !sameProtocol) ? protocol + value : reservedProtocol ? value : /^www\./.test(value) ? 'http://' + value : this.context.anchor.host + (/^\//.test(value) ? '' : '/') + value; - - if (value.indexOf('#') === 0) { - context.bookmark.style.display = 'block'; - this.util.addClass(context.bookmarkButton, 'active'); - } else { - context.bookmark.style.display = 'none'; - this.util.removeClass(context.bookmarkButton, 'active'); - } - - if (value.indexOf('#') === -1 && context.downloadCheck.checked) { - context.download.style.display = 'block'; - } else { - context.download.style.display = 'none'; - } - }, - - updateAnchor: function (anchor, url, alt, contextAnchor, notText) { - // bookmark - if (/^\#/.test(url)) { - anchor.id = url.substr(1); - } else { - anchor.removeAttribute('id'); - } - - // download - if (!/^\#/.test(url) && contextAnchor.downloadCheck.checked) { - anchor.setAttribute('download', alt || url); - } else { - anchor.removeAttribute('download'); - } - - // new window - if (contextAnchor.newWindowCheck.checked) anchor.target = '_blank'; - else anchor.removeAttribute('target'); - - // rel - const rel = contextAnchor.currentRel.join(' '); - if (!rel) anchor.removeAttribute('rel'); - else anchor.rel = rel; - - // est url, alt - anchor.href = url; - anchor.setAttribute('alt', alt); - anchor.textContent = notText ? '' : alt; - }, - - createAnchor: function (contextAnchor, notText) { - if (contextAnchor.linkValue.length === 0) return null; - - const url = contextAnchor.linkValue; - const anchor = contextAnchor.anchorText; - const anchorText = anchor.value.length === 0 ? url : anchor.value; - - const oA = contextAnchor.linkAnchor || this.util.createElement('A'); - this.plugins.anchor.updateAnchor(oA, url, anchorText, contextAnchor, notText); - - contextAnchor.linkValue = contextAnchor.preview.textContent = contextAnchor.urlInput.value = contextAnchor.anchorText.value = ''; - - return oA; - }, - - onClick_bookmarkButton: function (contextAnchor) { - let url = contextAnchor.urlInput.value; - if (/^\#/.test(url)) { - url = url.substr(1); - contextAnchor.bookmark.style.display = 'none'; - this.util.removeClass(contextAnchor.bookmarkButton, 'active'); - } else { - url = '#' + url; - contextAnchor.bookmark.style.display = 'block'; - this.util.addClass(contextAnchor.bookmarkButton, 'active'); - contextAnchor.downloadCheck.checked = false; - contextAnchor.download.style.display = 'none'; - } - - contextAnchor.linkValue = contextAnchor.preview.textContent = contextAnchor.urlInput.value = url; - contextAnchor.urlInput.focus(); - }, - - onChange_newWindowCheck: function (contextAnchor, e) { - if (typeof contextAnchor.linkDefaultRel.check_new_window !== 'string') return; - if (e.target.checked) { - this.plugins.anchor.setRel.call(this, contextAnchor, this.plugins.anchor._relMerge.call(this, contextAnchor, contextAnchor.linkDefaultRel.check_new_window)); - } else { - this.plugins.anchor.setRel.call(this, contextAnchor, this.plugins.anchor._relDelete.call(this, contextAnchor, contextAnchor.linkDefaultRel.check_new_window)); - } - }, - - onChange_downloadCheck: function (contextAnchor, e) { - if (e.target.checked) { - contextAnchor.download.style.display = 'block'; - contextAnchor.bookmark.style.display = 'none'; - this.util.removeClass(contextAnchor.bookmarkButton, 'active'); - contextAnchor.linkValue = contextAnchor.preview.textContent = contextAnchor.urlInput.value = contextAnchor.urlInput.value.replace(/^\#+/, ''); - if (typeof contextAnchor.linkDefaultRel.check_bookmark === 'string') { - this.plugins.anchor.setRel.call(this, contextAnchor, this.plugins.anchor._relMerge.call(this, contextAnchor, contextAnchor.linkDefaultRel.check_bookmark)); - } - } else { - contextAnchor.download.style.display = 'none'; - if (typeof contextAnchor.linkDefaultRel.check_bookmark === 'string') { - this.plugins.anchor.setRel.call(this, contextAnchor, this.plugins.anchor._relDelete.call(this, contextAnchor, contextAnchor.linkDefaultRel.check_bookmark)); - } - } - }, - - _relMerge: function (contextAnchor, relAttr) { - const current = contextAnchor.currentRel; - if (!relAttr) return current.join(' '); - - if (/^only\:/.test(relAttr)) { - relAttr = relAttr.replace(/^only\:/, '').trim(); - contextAnchor.currentRel = relAttr.split(' '); - return relAttr; - } - - const rels = relAttr.split(' '); - for (let i = 0, len = rels.length, index; i < len; i++) { - index = current.indexOf(rels[i]); - if (index === -1) current.push(rels[i]); - } - - return current.join(' '); - }, - - _relDelete: function (contextAnchor, relAttr) { - if (!relAttr) return contextAnchor.currentRel.join(' '); - if (/^only\:/.test(relAttr)) relAttr = relAttr.replace(/^only\:/, '').trim(); - - const rels = contextAnchor.currentRel.join(' ').replace(this._w.RegExp(relAttr + '\\s*'), ''); - contextAnchor.currentRel = rels.split(' '); - return rels; - }, - - init: function (contextAnchor) { - contextAnchor.linkAnchor = null; - contextAnchor.linkValue = contextAnchor.preview.textContent = contextAnchor.urlInput.value = ''; - contextAnchor.anchorText.value = ''; - contextAnchor.newWindowCheck.checked = false; - contextAnchor.downloadCheck.checked = false; - this.plugins.anchor.setRel.call(this, contextAnchor, contextAnchor.defaultRel); - if (contextAnchor.relList) { - this.plugins.anchor.toggleRelList.call(this, contextAnchor, false); - } - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/modules/_colorPicker.js": -/*!********************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/modules/_colorPicker.js ***! - \********************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2018 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'colorPicker', - /** - * @description Constructor - * @param {Object} core Core object - */ - add: function (core) { - const context = core.context; - context.colorPicker = { - colorListHTML: '', - _colorInput: '', - _defaultColor: '#000', - _styleProperty: 'color', - _currentColor: '', - _colorList: [] - }; - - /** set submenu */ - context.colorPicker.colorListHTML = this.createColorList(core, this._makeColorList); - }, - - /** - * @description Create color list - * @param {Object} core Core object - * @param {Function} makeColor this._makeColorList - * @returns {String} HTML string - */ - createColorList: function (core, makeColor) { - const option = core.options; - const lang = core.lang; - const colorList = !option.colorList || option.colorList.length === 0 ? - [ - '#ff0000', '#ff5e00', '#ffe400', '#abf200', '#00d8ff', '#0055ff', '#6600ff', '#ff00dd', '#000000', - '#ffd8d8', '#fae0d4', '#faf4c0', '#e4f7ba', '#d4f4fa', '#d9e5ff', '#e8d9ff', '#ffd9fa', '#f1f1f1', - '#ffa7a7', '#ffc19e', '#faed7d', '#cef279', '#b2ebf4', '#b2ccff', '#d1b2ff', '#ffb2f5', '#bdbdbd', - '#f15f5f', '#f29661', '#e5d85c', '#bce55c', '#5cd1e5', '#6699ff', '#a366ff', '#f261df', '#8c8c8c', - '#980000', '#993800', '#998a00', '#6b9900', '#008299', '#003399', '#3d0099', '#990085', '#353535', - '#670000', '#662500', '#665c00', '#476600', '#005766', '#002266', '#290066', '#660058', '#222222' - ] : option.colorList; - - let colorArr = []; - let list = '
'; - for (let i = 0, len = colorList.length, color; i < len; i++) { - color = colorList[i]; - if (!color) continue; - - if (typeof color === 'string') { - colorArr.push(color); - if (i < len - 1) continue; - } - if (colorArr.length > 0) { - list += '
' + makeColor(colorArr) + '
'; - colorArr = []; - } - if (typeof color === 'object') { - list += '
' + makeColor(color) + '
'; - } - } - list += '' + - '
' + - '' + - '' + - '' + - '
' + - '
'; - - return list; - }, - - /** - * @description Internal function used by this.createColorList - * @param {Array} colorList Color list - * @private - */ - _makeColorList: function (colorList) { - let list = ''; - - list += '
    '; - for (let i = 0, len = colorList.length, color; i < len; i++) { - color = colorList[i]; - if (typeof color === 'string') { - list += '
  • ' + - '' + - '
  • '; - } - } - list += '
'; - - return list; - }, - - /** - * @description Displays or resets the currently selected color at color list. - * @param {Node} node Current Selected node - * @param {String|null} color Color value - */ - init: function (node, color) { - const colorPicker = this.plugins.colorPicker; - let fillColor = color ? color : colorPicker.getColorInNode.call(this, node) || this.context.colorPicker._defaultColor; - fillColor = colorPicker.isHexColor(fillColor) ? fillColor : colorPicker.rgb2hex(fillColor) || fillColor; - - const colorList = this.context.colorPicker._colorList; - if (colorList) { - for (let i = 0, len = colorList.length; i < len; i++) { - if (fillColor.toLowerCase() === colorList[i].getAttribute('data-value').toLowerCase()) { - this.util.addClass(colorList[i], 'active'); - } else { - this.util.removeClass(colorList[i], 'active'); - } - } - } - - colorPicker.setInputText.call(this, colorPicker.colorName2hex.call(this, fillColor)); - }, - - /** - * @description Store color values - * @param {String} hexColorStr Hax color value - */ - setCurrentColor: function (hexColorStr) { - this.context.colorPicker._currentColor = hexColorStr; - this.context.colorPicker._colorInput.style.borderColor = hexColorStr; - }, - - /** - * @description Set color at input element - * @param {String} hexColorStr Hax color value - */ - setInputText: function (hexColorStr) { - hexColorStr = /^#/.test(hexColorStr) ? hexColorStr : '#' + hexColorStr; - this.context.colorPicker._colorInput.value = hexColorStr; - this.plugins.colorPicker.setCurrentColor.call(this, hexColorStr); - }, - - /** - * @description Gets color value at color property of node - * @param {Node} node Selected node - * @returns {String} - */ - getColorInNode: function (node) { - let findColor = ''; - const styleProperty = this.context.colorPicker._styleProperty; - - while (node && !this.util.isWysiwygDiv(node) && findColor.length === 0) { - if (node.nodeType === 1 && node.style[styleProperty]) findColor = node.style[styleProperty]; - node = node.parentNode; - } - - return findColor; - }, - - /** - * @description Function to check hex format color - * @param {String} str Color value - */ - isHexColor: function (str) { - return /^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(str); - }, - - /** - * @description Function to convert hex format to a rgb color - * @param {String} rgb RGB color format - * @returns {String} - */ - rgb2hex: function (rgb) { - const rgbMatch = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); - - return (rgbMatch && rgbMatch.length === 4) ? "#" + - ("0" + parseInt(rgbMatch[1],10).toString(16)).slice(-2) + - ("0" + parseInt(rgbMatch[2],10).toString(16)).slice(-2) + - ("0" + parseInt(rgbMatch[3],10).toString(16)).slice(-2) : ''; - }, - - /** - * @description Converts color values of other formats to hex color values and returns. - * @param {String} colorName Color value - * @returns {String} - */ - colorName2hex: function (colorName) { - if (/^#/.test(colorName)) return colorName; - var temp = this.util.createElement('div'); - temp.style.display = 'none'; - temp.style.color = colorName; - var colors = this._w.getComputedStyle(this._d.body.appendChild(temp)).color.match(/\d+/g).map(function (a) { return parseInt(a,10); }); - this.util.removeItem(temp); - return (colors.length >= 3) ? '#' + (((1 << 24) + (colors[0] << 16) + (colors[1] << 8) + colors[2]).toString(16).substr(1)) : false; - } -}); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/modules/_notice.js": -/*!***************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/modules/_notice.js ***! - \***************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'notice', - /** - * @description Constructor - * @param {Object} core Core object - */ - add: function (core) { - const context = core.context; - context.notice = {}; - - /** dialog */ - let notice_div = core.util.createElement('DIV'); - let notice_span = core.util.createElement('SPAN'); - let notice_button = core.util.createElement('BUTTON'); - - notice_div.className = 'se-notice'; - notice_button.className = 'close'; - notice_button.setAttribute('aria-label', 'Close'); - notice_button.setAttribute('title', core.lang.dialogBox.close); - notice_button.innerHTML = core.icons.cancel; - - notice_div.appendChild(notice_span); - notice_div.appendChild(notice_button); - - context.notice.modal = notice_div; - context.notice.message = notice_span; - - /** add event listeners */ - notice_button.addEventListener('click', this.onClick_cancel.bind(core)); - - /** append html */ - context.element.editorArea.appendChild(notice_div); - - /** empty memory */ - notice_div = null; - }, - - /** - * @description Event when clicking the cancel button - * @param {MouseEvent} e Event object - */ - onClick_cancel: function (e) { - e.preventDefault(); - e.stopPropagation(); - this.plugins.notice.close.call(this); - }, - - /** - * @description Open the notice panel - * @param {String} text Notice message - */ - open: function (text) { - this.context.notice.message.textContent = text; - this.context.notice.modal.style.display = 'block'; - }, - - /** - * @description Open the notice panel - */ - close: function () { - this.context.notice.modal.style.display = 'none'; - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/modules/component.js": -/*!*****************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/modules/component.js ***! - \*****************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -(function (global, factory) { - if ( true && typeof module.exports === 'object') { - module.exports = global.document ? - factory(global, true) : - function (w) { - if (!w.document) { - throw new Error('SUNEDITOR_MODULES a window with a document'); - } - return factory(w); - }; - } else { - factory(global); - } -}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) { - const component = { - name: 'component', - /** - * @description Create a container for the resizing component and insert the element. - * @param {Element} cover Cover element (FIGURE) - * @param {String} className Class name of container (fixed: se-component) - * @returns {Element} Created container element - */ - set_container: function (cover, className) { - const container = this.util.createElement('DIV'); - container.className = 'se-component ' + className; - container.setAttribute('contenteditable', false); - container.appendChild(cover); - - return container; - }, - - /** - * @description Cover the target element with a FIGURE element. - * @param {Element} element Target element - */ - set_cover: function (element) { - const cover = this.util.createElement('FIGURE'); - cover.appendChild(element); - - return cover; - }, - - /** - * @description Return HTML string of caption(FIGCAPTION) element - * @returns {String} - */ - create_caption: function () { - const caption = this.util.createElement('FIGCAPTION'); - caption.setAttribute('contenteditable', true); - caption.innerHTML = '
' + this.lang.dialogBox.caption + '
'; - return caption; - } - }; - - if (typeof noGlobal === typeof undefined) { - if (!window.SUNEDITOR_MODULES) { - Object.defineProperty(window, 'SUNEDITOR_MODULES', { - enumerable: true, - writable: false, - configurable: false, - value: {} - }); - } - - Object.defineProperty(window.SUNEDITOR_MODULES, 'component', { - enumerable: true, - writable: false, - configurable: false, - value: component - }); - } - - return component; -})); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/modules/dialog.js": -/*!**************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/modules/dialog.js ***! - \**************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -(function (global, factory) { - if ( true && typeof module.exports === 'object') { - module.exports = global.document ? - factory(global, true) : - function (w) { - if (!w.document) { - throw new Error('SUNEDITOR_MODULES a window with a document'); - } - return factory(w); - }; - } else { - factory(global); - } -}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) { - const dialog = { - name: 'dialog', - /** - * @description Constructor - * @param {Object} core Core object - */ - add: function (core) { - const context = core.context; - context.dialog = { - kind: '', - updateModal: false, - _closeSignal: false - }; - - /** dialog */ - let dialog_div = core.util.createElement('DIV'); - dialog_div.className = 'se-dialog sun-editor-common'; - - let dialog_back = core.util.createElement('DIV'); - dialog_back.className = 'se-dialog-back'; - dialog_back.style.display = 'none'; - - let dialog_area = core.util.createElement('DIV'); - dialog_area.className = 'se-dialog-inner'; - dialog_area.style.display = 'none'; - - dialog_div.appendChild(dialog_back); - dialog_div.appendChild(dialog_area); - - context.dialog.modalArea = dialog_div; - context.dialog.back = dialog_back; - context.dialog.modal = dialog_area; - - /** add event listeners */ - context.dialog.modal.addEventListener('mousedown', this._onMouseDown_dialog.bind(core)); - context.dialog.modal.addEventListener('click', this._onClick_dialog.bind(core)); - - /** append html */ - context.element.relative.appendChild(dialog_div); - - /** empty memory */ - dialog_div = null, dialog_back = null, dialog_area = null; - }, - - /** - * @description Event to control the behavior of closing the dialog - * @param {MouseEvent} e Event object - * @private - */ - _onMouseDown_dialog: function (e) { - if (/se-dialog-inner/.test(e.target.className)) { - this.context.dialog._closeSignal = true; - } else { - this.context.dialog._closeSignal = false; - } - }, - - /** - * @description Event to close the window when the outside area of the dialog or close button is click - * @param {MouseEvent} e Event object - * @private - */ - _onClick_dialog: function (e) { - if (/close/.test(e.target.getAttribute('data-command')) || this.context.dialog._closeSignal) { - this.plugins.dialog.close.call(this); - } - }, - - /** - * @description Open a Dialog plugin - * @param {String} kind Dialog plugin name - * @param {Boolean} update Whether it will open for update ('image' === this.currentControllerName) - */ - open: function (kind, update) { - if (this.modalForm) return false; - if (this.plugins.dialog._bindClose) { - this._d.removeEventListener('keydown', this.plugins.dialog._bindClose); - this.plugins.dialog._bindClose = null; - } - - this.plugins.dialog._bindClose = function (e) { - if (!/27/.test(e.keyCode)) return; - this.plugins.dialog.close.call(this); - }.bind(this); - this._d.addEventListener('keydown', this.plugins.dialog._bindClose); - - this.context.dialog.updateModal = update; - - if (this.options.popupDisplay === 'full') { - this.context.dialog.modalArea.style.position = 'fixed'; - } else { - this.context.dialog.modalArea.style.position = 'absolute'; - } - - this.context.dialog.kind = kind; - this.modalForm = this.context[kind].modal; - const focusElement = this.context[kind].focusElement; - - if (typeof this.plugins[kind].on === 'function') this.plugins[kind].on.call(this, update); - - this.context.dialog.modalArea.style.display = 'block'; - this.context.dialog.back.style.display = 'block'; - // this.context.dialog.modal.style.display = 'flex'; @v3 - this.context.dialog.modal.style.display = 'block'; - this.modalForm.style.display = 'block'; - - if (focusElement) focusElement.focus(); - }, - - _bindClose: null, - - /** - * @description Close a Dialog plugin - * The plugin's "init" method is called. - */ - close: function () { - if (this.plugins.dialog._bindClose) { - this._d.removeEventListener('keydown', this.plugins.dialog._bindClose); - this.plugins.dialog._bindClose = null; - } - - const kind = this.context.dialog.kind; - this.modalForm.style.display = 'none'; - this.context.dialog.back.style.display = 'none'; - this.context.dialog.modalArea.style.display = 'none'; - this.context.dialog.updateModal = false; - if (typeof this.plugins[kind].init === 'function') this.plugins[kind].init.call(this); - this.context.dialog.kind = ''; - this.modalForm = null; - this.focus(); - } - }; - - if (typeof noGlobal === typeof undefined) { - if (!window.SUNEDITOR_MODULES) { - Object.defineProperty(window, 'SUNEDITOR_MODULES', { - enumerable: true, - writable: false, - configurable: false, - value: {} - }); - } - - Object.defineProperty(window.SUNEDITOR_MODULES, 'dialog', { - enumerable: true, - writable: false, - configurable: false, - value: dialog - }); - } - - return dialog; -})); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/modules/fileBrowser.js": -/*!*******************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/modules/fileBrowser.js ***! - \*******************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -(function (global, factory) { - if ( true && typeof module.exports === 'object') { - module.exports = global.document ? - factory(global, true) : - function (w) { - if (!w.document) { - throw new Error('SUNEDITOR_MODULES a window with a document'); - } - return factory(w); - }; - } else { - factory(global); - } -}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) { - const fileBrowser = { - name: 'fileBrowser', - _xmlHttp: null, - _loading: null, - - /** - * @description Constructor - * @param {Object} core Core object - */ - add: function (core) { - const context = core.context; - context.fileBrowser = { - _closeSignal: false, - area: null, - header: null, - tagArea: null, - body: null, - list: null, - tagElements: null, - items: [], - selectedTags: [], - selectorHandler: null, - contextPlugin: '', - columnSize: 4 - }; - - /** fileBrowser */ - let browser_div = core.util.createElement('DIV'); - browser_div.className = 'se-file-browser sun-editor-common'; - - let back = core.util.createElement('DIV'); - back.className = 'se-file-browser-back'; - - let content = core.util.createElement('DIV'); - content.className = 'se-file-browser-inner'; - content.innerHTML = this.set_browser(core); - - browser_div.appendChild(back); - browser_div.appendChild(content); - this._loading = browser_div.querySelector('.se-loading-box'); - - context.fileBrowser.area = browser_div; - context.fileBrowser.header = content.querySelector('.se-file-browser-header'); - context.fileBrowser.titleArea = content.querySelector('.se-file-browser-title'); - context.fileBrowser.tagArea = content.querySelector('.se-file-browser-tags'); - context.fileBrowser.body = content.querySelector('.se-file-browser-body'); - context.fileBrowser.list = content.querySelector('.se-file-browser-list'); - - /** add event listeners */ - context.fileBrowser.tagArea.addEventListener('click', this.onClickTag.bind(core)); - context.fileBrowser.list.addEventListener('click', this.onClickFile.bind(core)); - content.addEventListener('mousedown', this._onMouseDown_browser.bind(core)); - content.addEventListener('click', this._onClick_browser.bind(core)); - - /** append html */ - context.element.relative.appendChild(browser_div); - - /** empty memory */ - browser_div = null, back = null, content = null; - }, - - set_browser: function (core) { - const lang = core.lang; - - return '
' + - '
' + - '' + - '' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
'; - }, - - /** - * @description Event to control the behavior of closing the browser - * @param {MouseEvent} e Event object - * @private - */ - _onMouseDown_browser: function (e) { - if (/se-file-browser-inner/.test(e.target.className)) { - this.context.fileBrowser._closeSignal = true; - } else { - this.context.fileBrowser._closeSignal = false; - } - }, - - /** - * @description Event to close the window when the outside area of the browser or close button is click - * @param {MouseEvent} e Event object - * @private - */ - _onClick_browser: function (e) { - e.stopPropagation(); - - if (/close/.test(e.target.getAttribute('data-command')) || this.context.fileBrowser._closeSignal) { - this.plugins.fileBrowser.close.call(this); - } - }, - - /** - * @description Open a file browser plugin - * @param {String} pluginName Plugin name using the file browser - * @param {Function|null} selectorHandler When the function comes as an argument value, it substitutes "context.selectorHandler". - */ - open: function (pluginName, selectorHandler) { - if (this.plugins.fileBrowser._bindClose) { - this._d.removeEventListener('keydown', this.plugins.fileBrowser._bindClose); - this.plugins.fileBrowser._bindClose = null; - } - - this.plugins.fileBrowser._bindClose = function (e) { - if (!/27/.test(e.keyCode)) return; - this.plugins.fileBrowser.close.call(this); - }.bind(this); - this._d.addEventListener('keydown', this.plugins.fileBrowser._bindClose); - - const fileBrowserContext = this.context.fileBrowser; - fileBrowserContext.contextPlugin = pluginName; - fileBrowserContext.selectorHandler = selectorHandler; - - const pluginContext = this.context[pluginName]; - const listClassName = pluginContext.listClass; - if (!this.util.hasClass(fileBrowserContext.list, listClassName)) { - fileBrowserContext.list.className = 'se-file-browser-list ' + listClassName; - } - - if (this.options.popupDisplay === 'full') { - fileBrowserContext.area.style.position = 'fixed'; - } else { - fileBrowserContext.area.style.position = 'absolute'; - } - - fileBrowserContext.titleArea.textContent = pluginContext.title; - fileBrowserContext.area.style.display = 'block'; - - this.plugins.fileBrowser._drawFileList.call(this, this.context[pluginName].url); - }, - - _bindClose: null, - - /** - * @description Close a fileBrowser plugin - * The plugin's "init" method is called. - */ - close: function () { - const fileBrowserPlugin = this.plugins.fileBrowser; - - if (fileBrowserPlugin._xmlHttp) { - fileBrowserPlugin._xmlHttp.abort(); - } - - if (fileBrowserPlugin._bindClose) { - this._d.removeEventListener('keydown', fileBrowserPlugin._bindClose); - fileBrowserPlugin._bindClose = null; - } - - const fileBrowserContext = this.context.fileBrowser; - fileBrowserContext.area.style.display = 'none'; - fileBrowserContext.selectorHandler = null; - fileBrowserContext.selectedTags = []; - fileBrowserContext.items = []; - fileBrowserContext.list.innerHTML = fileBrowserContext.tagArea.innerHTML = fileBrowserContext.titleArea.textContent = ''; - - if (typeof this.plugins[fileBrowserContext.contextPlugin].init === 'function') this.plugins[fileBrowserContext.contextPlugin].init.call(this); - fileBrowserContext.contextPlugin = ''; - }, - - /** - * @description Show file browser loading box - */ - showBrowserLoading: function () { - this._loading.style.display = 'block'; - }, - - /** - * @description Close file browser loading box - */ - closeBrowserLoading: function () { - this._loading.style.display = 'none'; - }, - - _drawFileList: function (url) { - const fileBrowserPlugin = this.plugins.fileBrowser; - - const xmlHttp = fileBrowserPlugin._xmlHttp = this.util.getXMLHttpRequest(); - xmlHttp.onreadystatechange = fileBrowserPlugin._callBackGet.bind(this, xmlHttp); - xmlHttp.open('get', url, true); - xmlHttp.send(null); - - this.plugins.fileBrowser.showBrowserLoading(); - }, - - _callBackGet: function (xmlHttp) { - if (xmlHttp.readyState === 4) { - this.plugins.fileBrowser._xmlHttp = null; - if (xmlHttp.status === 200) { - try { - this.plugins.fileBrowser._drawListItem.call(this, JSON.parse(xmlHttp.responseText).result, true); - } catch (e) { - throw Error('[SUNEDITOR.fileBrowser.drawList.fail] cause : "' + e.message + '"'); - } finally { - this.plugins.fileBrowser.closeBrowserLoading(); - this.context.fileBrowser.body.style.maxHeight = (this._w.innerHeight - this.context.fileBrowser.header.offsetHeight - 50) + 'px'; - } - } else { // exception - this.plugins.fileBrowser.closeBrowserLoading(); - if (xmlHttp.status !== 0) { - const res = !xmlHttp.responseText ? xmlHttp : JSON.parse(xmlHttp.responseText); - const err = '[SUNEDITOR.fileBrowser.get.serverException] status: ' + xmlHttp.status + ', response: ' + (res.errorMessage || xmlHttp.responseText); - throw Error(err); - } - } - } - }, - - _drawListItem: function (items, update) { - const fileBrowserContext = this.context.fileBrowser; - const pluginContext = this.context[fileBrowserContext.contextPlugin]; - - const _tags = []; - const len = items.length; - const columnSize = pluginContext.columnSize || fileBrowserContext.columnSize; - const splitSize = columnSize <= 1 ? 1 : (Math.round(len/columnSize) || 1); - const drawItemHandler = pluginContext.itemTemplateHandler; - - let tagsHTML = ''; - let listHTML = '
'; - let columns = 1; - for (let i = 0, item, tags; i < len; i++) { - item = items[i]; - tags = !item.tag ? [] : typeof item.tag === 'string' ? item.tag.split(',') : item.tag; - tags = item.tag = tags.map(function (v) { return v.trim(); }); - listHTML += drawItemHandler(item); - - if ((i + 1) % splitSize === 0 && columns < columnSize && (i + 1) < len) { - columns++; - listHTML += '
'; - } - - if (update && tags.length > 0) { - for (let t = 0, tLen = tags.length, tag; t < tLen; t++) { - tag = tags[t]; - if (tag && _tags.indexOf(tag) === -1) { - _tags.push(tag); - tagsHTML += '' + tag + ''; - } - } - } - } - listHTML += '
'; - - fileBrowserContext.list.innerHTML = listHTML; - - if (update) { - fileBrowserContext.items = items; - fileBrowserContext.tagArea.innerHTML = tagsHTML; - fileBrowserContext.tagElements = fileBrowserContext.tagArea.querySelectorAll('A'); - } - }, - - onClickTag: function (e) { - const target = e.target; - if (!this.util.isAnchor(target)) return; - - const tagName = target.textContent; - const fileBrowserPlugin = this.plugins.fileBrowser; - const fileBrowserContext = this.context.fileBrowser; - - const selectTag = fileBrowserContext.tagArea.querySelector('a[title="' + tagName + '"]'); - const selectedTags = fileBrowserContext.selectedTags; - const sTagIndex = selectedTags.indexOf(tagName); - - if (sTagIndex > -1){ - selectedTags.splice(sTagIndex, 1); - this.util.removeClass(selectTag, 'on'); - } else { - selectedTags.push(tagName); - this.util.addClass(selectTag, 'on'); - } - - fileBrowserPlugin._drawListItem.call(this, - selectedTags.length === 0 ? - fileBrowserContext.items : - fileBrowserContext.items.filter(function (item) { - return item.tag.some(function (tag) { - return selectedTags.indexOf(tag) > -1; - }); - }), false); - }, - - onClickFile: function (e) { - e.preventDefault(); - e.stopPropagation(); - - const fileBrowserContext = this.context.fileBrowser; - const listEl = fileBrowserContext.list; - let target = e.target; - let command = null; - - if (target === listEl) return; - - while (listEl !== target.parentNode) { - command = target.getAttribute('data-command'); - if (command) break; - target = target.parentNode; - } - - if (!command) return; - - const handler = (fileBrowserContext.selectorHandler || this.context[fileBrowserContext.contextPlugin].selectorHandler); - this.plugins.fileBrowser.close.call(this); - handler(target); - } - }; - - if (typeof noGlobal === typeof undefined) { - if (!window.SUNEDITOR_MODULES) { - Object.defineProperty(window, 'SUNEDITOR_MODULES', { - enumerable: true, - writable: false, - configurable: false, - value: {} - }); - } - - Object.defineProperty(window.SUNEDITOR_MODULES, 'fileBrowser', { - enumerable: true, - writable: false, - configurable: false, - value: fileBrowser - }); - } - - return fileBrowser; -})); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/modules/fileManager.js": -/*!*******************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/modules/fileManager.js ***! - \*******************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -(function (global, factory) { - if ( true && typeof module.exports === 'object') { - module.exports = global.document ? - factory(global, true) : - function (w) { - if (!w.document) { - throw new Error('SUNEDITOR_MODULES a window with a document'); - } - return factory(w); - }; - } else { - factory(global); - } -}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) { - const fileManager = { - name: 'fileManager', - _xmlHttp: null, - - _checkMediaComponent: function (tag) { - if (/IMG/i.test(tag)) { - return !/FIGURE/i.test(tag.parentElement.nodeName) || !/FIGURE/i.test(tag.parentElement.parentElement.nodeName); - } else if (/VIDEO/i.test(tag)) { - return !/FIGURE/i.test(tag.parentElement.nodeName); - } - return true; - }, - - /** - * @description Upload the file to the server. - * @param {String} uploadUrl Upload server url - * @param {Object|null} uploadHeader Request header - * @param {FormData} formData FormData in body - * @param {Function|null} callBack Success call back function - * @param {Function|null} errorCallBack Error call back function - * @example this.plugins.fileManager.upload.call(this, imageUploadUrl, this.options.imageUploadHeader, formData, this.plugins.image.callBack_imgUpload.bind(this, info), this.functions.onImageUploadError); - */ - upload: function (uploadUrl, uploadHeader, formData, callBack, errorCallBack) { - this.showLoading(); - const filePlugin = this.plugins.fileManager; - const xmlHttp = filePlugin._xmlHttp = this.util.getXMLHttpRequest(); - - xmlHttp.onreadystatechange = filePlugin._callBackUpload.bind(this, xmlHttp, callBack, errorCallBack); - xmlHttp.open('post', uploadUrl, true); - if(uploadHeader !== null && typeof uploadHeader === 'object' && this._w.Object.keys(uploadHeader).length > 0){ - for(let key in uploadHeader){ - xmlHttp.setRequestHeader(key, uploadHeader[key]); - } - } - xmlHttp.send(formData); - }, - - _callBackUpload: function (xmlHttp, callBack, errorCallBack) { - if (xmlHttp.readyState === 4) { - if (xmlHttp.status === 200) { - try { - callBack(xmlHttp); - } catch (e) { - throw Error('[SUNEDITOR.fileManager.upload.callBack.fail] cause : "' + e.message + '"'); - } finally { - this.closeLoading(); - } - } else { // exception - this.closeLoading(); - const res = !xmlHttp.responseText ? xmlHttp : JSON.parse(xmlHttp.responseText); - if (typeof errorCallBack !== 'function' || errorCallBack('', res, this)) { - const err = '[SUNEDITOR.fileManager.upload.serverException] status: ' + xmlHttp.status + ', response: ' + (res.errorMessage || xmlHttp.responseText); - this.functions.noticeOpen(err); - throw Error(err); - } - } - } - }, - - /** - * @description Checke the file's information and modify the tag that does not fit the format. - * @param {String} pluginName Plugin name - * @param {Array} tagNames Tag array to check - * @param {Function|null} uploadEventHandler Event handler to process updated file info after checking (used in "setInfo") - * @param {Function} modifyHandler A function to modify a tag that does not fit the format (Argument value: Tag element) - * @param {Boolean} resizing True if the plugin is using a resizing module - * @example - * const modifyHandler = function (tag) { - * imagePlugin.onModifyMode.call(this, tag, null); - * imagePlugin.openModify.call(this, true); - * imagePlugin.update_image.call(this, true, false, true); - * }.bind(this); - * this.plugins.fileManager.checkInfo.call(this, 'image', ['img'], this.functions.onImageUpload, modifyHandler, true); - */ - checkInfo: function (pluginName, tagNames, uploadEventHandler, modifyHandler, resizing) { - let tags = []; - for (let i = 0, len = tagNames.length; i < len; i++) { - tags = tags.concat([].slice.call(this.context.element.wysiwyg.getElementsByTagName(tagNames[i]))); - } - - const fileManagerPlugin = this.plugins.fileManager; - const context = this.context[pluginName]; - const infoList = context._infoList; - const setFileInfo = fileManagerPlugin.setInfo.bind(this); - - if (tags.length === infoList.length) { - // reset - if (this._componentsInfoReset) { - for (let i = 0, len = tags.length; i < len; i++) { - setFileInfo(pluginName, tags[i], uploadEventHandler, null, resizing); - } - return ; - } else { - let infoUpdate = false; - for (let i = 0, len = infoList.length, info; i < len; i++) { - info = infoList[i]; - if (tags.filter(function (t) { return info.src === t.src && info.index.toString() === t.getAttribute('data-index'); }).length === 0) { - infoUpdate = true; - break; - } - } - // pass - if (!infoUpdate) return; - } - } - - // check - const _resize_plugin = resizing ? this.context.resizing._resize_plugin : ''; - if (resizing) this.context.resizing._resize_plugin = pluginName; - const currentTags = []; - const infoIndex = []; - for (let i = 0, len = infoList.length; i < len; i++) { - infoIndex[i] = infoList[i].index; - } - - for (let i = 0, len = tags.length, tag; i < len; i++) { - tag = tags[i]; - if (!this.util.getParentElement(tag, this.util.isMediaComponent) || !fileManagerPlugin._checkMediaComponent(tag)) { - currentTags.push(context._infoIndex); - modifyHandler(tag); - } else if (!tag.getAttribute('data-index') || infoIndex.indexOf(tag.getAttribute('data-index') * 1) < 0) { - currentTags.push(context._infoIndex); - tag.removeAttribute('data-index'); - setFileInfo(pluginName, tag, uploadEventHandler, null, resizing); - } else { - currentTags.push(tag.getAttribute('data-index') * 1); - } - } - - for (let i = 0, dataIndex; i < infoList.length; i++) { - dataIndex = infoList[i].index; - if (currentTags.indexOf(dataIndex) > -1) continue; - - infoList.splice(i, 1); - if (typeof uploadEventHandler === 'function') uploadEventHandler(null, dataIndex, 'delete', null, 0, this); - i--; - } - - if (resizing) this.context.resizing._resize_plugin = _resize_plugin; - }, - - /** - * @description Create info object of file and add it to "_infoList" (this.context[pluginName]._infoList[]) - * @param {String} pluginName Plugin name - * @param {Element} element - * @param {Function|null} uploadEventHandler Event handler to process updated file info (created in setInfo) - * @param {Object|null} file - * @param {Boolean} resizing True if the plugin is using a resizing module - * @example - * uploadCallBack {.. file = { name: fileList[i].name, size: fileList[i].size }; - * this.plugins.fileManager.setInfo.call(this, 'image', oImg, this.functions.onImageUpload, file, true); - */ - setInfo: function (pluginName, element, uploadEventHandler, file, resizing) { - const _resize_plugin = resizing ? this.context.resizing._resize_plugin : ''; - if (resizing) this.context.resizing._resize_plugin = pluginName; - - const plguin = this.plugins[pluginName]; - const context = this.context[pluginName]; - const infoList = context._infoList; - let dataIndex = element.getAttribute('data-index'); - let info = null; - let state = ''; - - if (!file) { - file = { - 'name': element.getAttribute('data-file-name') || (typeof element.src === 'string' ? element.src.split('/').pop() : ''), - 'size': element.getAttribute('data-file-size') || 0 - }; - } - - // create - if (!dataIndex || this._componentsInfoInit) { - state = 'create'; - dataIndex = context._infoIndex++; - - element.setAttribute('data-index', dataIndex); - element.setAttribute('data-file-name', file.name); - element.setAttribute('data-file-size', file.size); - - info = { - src: element.src, - index: dataIndex * 1, - name: file.name, - size: file.size - }; - - infoList.push(info); - } else { // update - state = 'update'; - dataIndex *= 1; - - for (let i = 0, len = infoList.length; i < len; i++) { - if (dataIndex === infoList[i].index) { - info = infoList[i]; - break; - } - } - - if (!info) { - dataIndex = context._infoIndex++; - info = { index: dataIndex }; - infoList.push(info); - } - - info.src = element.src; - info.name = element.getAttribute("data-file-name"); - info.size = element.getAttribute("data-file-size") * 1; - } - - // method bind - info.element = element; - info.delete = plguin.destroy.bind(this, element); - info.select = function (element) { - element.scrollIntoView(true); - this._w.setTimeout(plguin.select.bind(this, element)); - }.bind(this, element); - - if (resizing) { - if (!element.getAttribute('origin-size') && element.naturalWidth) { - element.setAttribute('origin-size', element.naturalWidth + ',' + element.naturalHeight); - } - - if (!element.getAttribute('data-origin')) { - const container = this.util.getParentElement(element, this.util.isMediaComponent); - const cover = this.util.getParentElement(element, 'FIGURE'); - - const w = this.plugins.resizing._module_getSizeX.call(this, context, element, cover, container); - const h = this.plugins.resizing._module_getSizeY.call(this, context, element, cover, container); - element.setAttribute('data-origin', w + ',' + h); - element.setAttribute('data-size', w + ',' + h); - } - - if (!element.style.width) { - const size = (element.getAttribute('data-size') || element.getAttribute('data-origin') || '').split(','); - plguin.onModifyMode.call(this, element, null); - plguin.applySize.call(this, size[0], size[1]); - } - - this.context.resizing._resize_plugin = _resize_plugin; - } - - if (typeof uploadEventHandler === 'function') uploadEventHandler(element, dataIndex, state, info, --context._uploadFileLength < 0 ? 0 : context._uploadFileLength, this); - }, - - /** - * @description Delete info object at "_infoList" - * @param {String} pluginName Plugin name - * @param {Number} index index of info object (this.context[pluginName]._infoList[].index) - * @param {Function|null} uploadEventHandler Event handler to process updated file info (created in setInfo) - */ - deleteInfo: function (pluginName, index, uploadEventHandler) { - if (index >= 0) { - const infoList = this.context[pluginName]._infoList; - - for (let i = 0, len = infoList.length; i < len; i++) { - if (index === infoList[i].index) { - infoList.splice(i, 1); - if (typeof uploadEventHandler === 'function') uploadEventHandler(null, index, 'delete', null, 0, this); - return; - } - } - } - }, - - /** - * @description Reset info object and "_infoList = []", "_infoIndex = 0" - * @param {String} pluginName Plugin name - * @param {Function|null} uploadEventHandler Event handler to process updated file info (created in setInfo) - */ - resetInfo: function (pluginName, uploadEventHandler) { - const context = this.context[pluginName]; - - if (typeof uploadEventHandler === 'function') { - const infoList = context._infoList; - for (let i = 0, len = infoList.length; i < len; i++) { - uploadEventHandler(null, infoList[i].index, 'delete', null, 0, this); - } - } - - context._infoList = []; - context._infoIndex = 0; - } - }; - - if (typeof noGlobal === typeof undefined) { - if (!window.SUNEDITOR_MODULES) { - Object.defineProperty(window, 'SUNEDITOR_MODULES', { - enumerable: true, - writable: false, - configurable: false, - value: {} - }); - } - - Object.defineProperty(window.SUNEDITOR_MODULES, 'fileManager', { - enumerable: true, - writable: false, - configurable: false, - value: fileManager - }); - } - - return fileManager; -})); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/modules/resizing.js": -/*!****************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/modules/resizing.js ***! - \****************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -(function (global, factory) { - if ( true && typeof module.exports === 'object') { - module.exports = global.document ? - factory(global, true) : - function (w) { - if (!w.document) { - throw new Error('SUNEDITOR_MODULES a window with a document'); - } - return factory(w); - }; - } else { - factory(global); - } -}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) { - const resizing = { - name: 'resizing', - /** - * @description Constructor - * Require context properties when resizing module - inputX: Element, - inputY: Element, - _container: null, - _cover: null, - _element: null, - _element_w: 1, - _element_h: 1, - _element_l: 0, - _element_t: 0, - _defaultSizeX: 'auto', - _defaultSizeY: 'auto', - _origin_w: core.options.imageWidth === 'auto' ? '' : core.options.imageWidth, - _origin_h: core.options.imageHeight === 'auto' ? '' : core.options.imageHeight, - _proportionChecked: true, - // -- select function -- - _resizing: core.options.imageResizing, - _resizeDotHide: !core.options.imageHeightShow, - _rotation: core.options.imageRotation, - _onlyPercentage: core.options.imageSizeOnlyPercentage, - _ratio: false, - _ratioX: 1, - _ratioY: 1 - _captionShow: true, - // -- when used caption (_captionShow: true) -- - _caption: null, - _captionChecked: false, - captionCheckEl: null, - * @param {Object} core Core object - */ - add: function (core) { - const icons = core.icons; - const context = core.context; - context.resizing = { - _resizeClientX: 0, - _resizeClientY: 0, - _resize_plugin: '', - _resize_w: 0, - _resize_h: 0, - _origin_w: 0, - _origin_h: 0, - _rotateVertical: false, - _resize_direction: '', - _move_path: null, - _isChange: false, - alignIcons: { - basic: icons.align_justify, - left: icons.align_left, - right: icons.align_right, - center: icons.align_center - } - }; - - /** resize controller, button */ - let resize_div_container = this.setController_resize(core); - context.resizing.resizeContainer = resize_div_container; - - context.resizing.resizeDiv = resize_div_container.querySelector('.se-modal-resize'); - context.resizing.resizeDot = resize_div_container.querySelector('.se-resize-dot'); - context.resizing.resizeDisplay = resize_div_container.querySelector('.se-resize-display'); - - let resize_button = this.setController_button(core); - context.resizing.resizeButton = resize_button; - - let resize_handles = context.resizing.resizeHandles = context.resizing.resizeDot.querySelectorAll('span'); - context.resizing.resizeButtonGroup = resize_button.querySelector('._se_resizing_btn_group'); - context.resizing.rotationButtons = resize_button.querySelectorAll('._se_resizing_btn_group ._se_rotation'); - context.resizing.percentageButtons = resize_button.querySelectorAll('._se_resizing_btn_group ._se_percentage'); - - context.resizing.alignMenu = resize_button.querySelector('.se-resizing-align-list'); - context.resizing.alignMenuList = context.resizing.alignMenu.querySelectorAll('button'); - - context.resizing.alignButton = resize_button.querySelector('._se_resizing_align_button'); - context.resizing.autoSizeButton = resize_button.querySelector('._se_resizing_btn_group ._se_auto_size'); - context.resizing.captionButton = resize_button.querySelector('._se_resizing_caption_button'); - - /** add event listeners */ - resize_div_container.addEventListener('mousedown', function (e) { e.preventDefault(); }); - resize_handles[0].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core)); - resize_handles[1].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core)); - resize_handles[2].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core)); - resize_handles[3].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core)); - resize_handles[4].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core)); - resize_handles[5].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core)); - resize_handles[6].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core)); - resize_handles[7].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core)); - resize_button.addEventListener('click', this.onClick_resizeButton.bind(core)); - - /** append html */ - context.element.relative.appendChild(resize_div_container); - context.element.relative.appendChild(resize_button); - - /** empty memory */ - resize_div_container = null, resize_button = null, resize_handles = null; - }, - - /** resize controller, button (image, iframe, video) */ - setController_resize: function (core) { - const resize_container = core.util.createElement('DIV'); - - resize_container.className = 'se-controller se-resizing-container'; - resize_container.style.display = 'none'; - resize_container.innerHTML = '' + - '
' + - '
' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '
' + - '
'; - - return resize_container; - }, - - setController_button: function (core) { - const lang = core.lang; - const icons = core.icons; - const resize_button = core.util.createElement("DIV"); - - resize_button.className = "se-controller se-controller-resizing"; - resize_button.innerHTML = '' + - '
' + - '
' + - '' + - '' + - '' + - '' + - '' + - '' + - '
' + - '
' + - '' + - '' + - '' + - '
' + - '
' + - '
    ' + - '
  • ' + - '
  • ' + - '
  • ' + - '
  • ' + - '
' + - '
' + - '
' + - '' + - '' + - '' + - '' + - '
'; - - return resize_button; - }, - - /** - * @description Gets the width size - * @param {Object} contextPlugin context object of plugin (core.context[plugin]) - * @param {Element} element Target element - * @param {Element} cover Cover element (FIGURE) - * @param {Element} container Container element (DIV.se-component) - * @returns {String} - */ - _module_getSizeX: function (contextPlugin, element, cover, container) { - if (!element) element = contextPlugin._element; - if (!cover) cover = contextPlugin._cover; - if (!container) container = contextPlugin._container; - - if (!element) return ''; - - return !/%$/.test(element.style.width) ? element.style.width : ((container && this.util.getNumber(container.style.width, 2)) || 100) + '%'; - }, - - /** - * @description Gets the height size - * @param {Object} contextPlugin context object of plugin (core.context[plugin]) - * @param {Element} element Target element - * @param {Element} cover Cover element (FIGURE) - * @param {Element} container Container element (DIV.se-component) - * @returns {String} - */ - _module_getSizeY: function (contextPlugin, element, cover, container) { - if (!element) element = contextPlugin._element; - if (!cover) cover = contextPlugin._cover; - if (!container) container = contextPlugin._container; - - if (!container || !cover) return (element && element.style.height) || ''; - - return this.util.getNumber(cover.style.paddingBottom, 0) > 0 && !this.context.resizing._rotateVertical ? cover.style.height : (!/%$/.test(element.style.height) || !/%$/.test(element.style.width) ? element.style.height : ((container && this.util.getNumber(container.style.height, 2)) || 100) + '%'); - }, - - /** - * @description Called at the "openModify" to put the size of the current target into the size input element. - * @param {Object} contextPlugin context object of plugin (core.context[plugin]) - * @param {Object} pluginObj Plugin object - */ - _module_setModifyInputSize: function (contextPlugin, pluginObj) { - const percentageRotation = contextPlugin._onlyPercentage && this.context.resizing._rotateVertical; - contextPlugin.proportion.checked = contextPlugin._proportionChecked = contextPlugin._element.getAttribute('data-proportion') !== 'false'; - - let x = percentageRotation ? '' : this.plugins.resizing._module_getSizeX.call(this, contextPlugin); - if (x === contextPlugin._defaultSizeX) x = ''; - if (contextPlugin._onlyPercentage) x = this.util.getNumber(x, 2); - contextPlugin.inputX.value = x; - pluginObj.setInputSize.call(this, 'x'); - - if (!contextPlugin._onlyPercentage) { - let y = percentageRotation ? '' : this.plugins.resizing._module_getSizeY.call(this, contextPlugin); - if (y === contextPlugin._defaultSizeY) y = ''; - if (contextPlugin._onlyPercentage) y = this.util.getNumber(y, 2); - contextPlugin.inputY.value = y; - } - - contextPlugin.inputX.disabled = percentageRotation ? true : false; - contextPlugin.inputY.disabled = percentageRotation ? true : false; - contextPlugin.proportion.disabled = percentageRotation ? true : false; - - pluginObj.setRatio.call(this); - }, - - /** - * @description It is called in "setInputSize" (input tag keyupEvent), - * checks the value entered in the input tag, - * calculates the ratio, and sets the calculated value in the input tag of the opposite size. - * @param {Object} contextPlugin context object of plugin (core.context[plugin]) - * @param {String} xy 'x': width, 'y': height - */ - _module_setInputSize: function (contextPlugin, xy) { - if (contextPlugin._onlyPercentage) { - if (xy === 'x' && contextPlugin.inputX.value > 100) contextPlugin.inputX.value = 100; - return; - } - - if (contextPlugin.proportion.checked && contextPlugin._ratio && /\d/.test(contextPlugin.inputX.value) && /\d/.test(contextPlugin.inputY.value)) { - const xUnit = contextPlugin.inputX.value.replace(/\d+|\./g, '') || contextPlugin.sizeUnit; - const yUnit = contextPlugin.inputY.value.replace(/\d+|\./g, '') || contextPlugin.sizeUnit; - - if (xUnit !== yUnit) return; - - const dec = xUnit === '%' ? 2 : 0; - - if (xy === 'x') { - contextPlugin.inputY.value = this.util.getNumber(contextPlugin._ratioY * this.util.getNumber(contextPlugin.inputX.value, dec), dec) + yUnit; - } else { - contextPlugin.inputX.value = this.util.getNumber(contextPlugin._ratioX * this.util.getNumber(contextPlugin.inputY.value, dec), dec) + xUnit; - } - } - }, - - /** - * @description It is called in "setRatio" (input and proportionCheck tags changeEvent), - * checks the value of the input tag, calculates the ratio, and resets it in the input tag. - * @param {Object} contextPlugin context object of plugin (core.context[plugin]) - */ - _module_setRatio: function (contextPlugin) { - const xValue = contextPlugin.inputX.value; - const yValue = contextPlugin.inputY.value; - - if (contextPlugin.proportion.checked && /\d+/.test(xValue) && /\d+/.test(yValue)) { - const xUnit = xValue.replace(/\d+|\./g, '') || contextPlugin.sizeUnit; - const yUnit = yValue.replace(/\d+|\./g, '') || contextPlugin.sizeUnit; - - if (xUnit !== yUnit) { - contextPlugin._ratio = false; - } else if (!contextPlugin._ratio) { - const x = this.util.getNumber(xValue, 0); - const y = this.util.getNumber(yValue, 0); - - contextPlugin._ratio = true; - contextPlugin._ratioX = x / y; - contextPlugin._ratioY = y / x; - } - } else { - contextPlugin._ratio = false; - } - }, - - /** - * @description Revert size of element to origin size (plugin._origin_w, plugin._origin_h) - * @param {Object} contextPlugin context object of plugin (core.context[plugin]) - */ - _module_sizeRevert: function (contextPlugin) { - if (contextPlugin._onlyPercentage) { - contextPlugin.inputX.value = contextPlugin._origin_w > 100 ? 100 : contextPlugin._origin_w; - } else { - contextPlugin.inputX.value = contextPlugin._origin_w; - contextPlugin.inputY.value = contextPlugin._origin_h; - } - }, - - /** - * @description Save the size data (element.setAttribute("data-size")) - * Used at the "setSize" method - * @param {Object} contextPlugin context object of plugin (core.context[plugin]) - */ - _module_saveCurrentSize: function (contextPlugin) { - const x = this.plugins.resizing._module_getSizeX.call(this, contextPlugin); - const y = this.plugins.resizing._module_getSizeY.call(this, contextPlugin); - contextPlugin._element.setAttribute('data-size', x + ',' + y); - if (!!contextPlugin._videoRatio) contextPlugin._videoRatio = y; - }, - - /** - * @description Call the resizing module - * @param {Element} targetElement Resizing target element - * @param {string} plugin Plugin name - * @returns {Object} Size of resizing div {w, h, t, l} - */ - call_controller_resize: function (targetElement, plugin) { - const contextResizing = this.context.resizing; - const contextPlugin = this.context[plugin]; - contextResizing._resize_plugin = plugin; - - const resizeContainer = contextResizing.resizeContainer; - const resizeDiv = contextResizing.resizeDiv; - const offset = this.util.getOffset(targetElement, this.context.element.wysiwygFrame); - - const isVertical = contextResizing._rotateVertical = /^(90|270)$/.test(Math.abs(targetElement.getAttribute('data-rotate')).toString()); - - const w = isVertical ? targetElement.offsetHeight : targetElement.offsetWidth; - const h = isVertical ? targetElement.offsetWidth : targetElement.offsetHeight; - const t = offset.top; - const l = offset.left - this.context.element.wysiwygFrame.scrollLeft; - - resizeContainer.style.top = t + 'px'; - resizeContainer.style.left = l + 'px'; - resizeContainer.style.width = w + 'px'; - resizeContainer.style.height = h + 'px'; - - resizeDiv.style.top = '0px'; - resizeDiv.style.left = '0px'; - resizeDiv.style.width = w + 'px'; - resizeDiv.style.height = h + 'px'; - - let align = targetElement.getAttribute('data-align') || 'basic'; - align = align === 'none' ? 'basic' : align; - - // text - const container = this.util.getParentElement(targetElement, this.util.isComponent); - const cover = this.util.getParentElement(targetElement, 'FIGURE'); - const displayX = this.plugins.resizing._module_getSizeX.call(this, contextPlugin, targetElement, cover, container) || 'auto'; - const displayY = contextPlugin._onlyPercentage && plugin === 'image' ? '' : ', ' + (this.plugins.resizing._module_getSizeY.call(this, contextPlugin, targetElement, cover, container) || 'auto'); - this.util.changeTxt(contextResizing.resizeDisplay, this.lang.dialogBox[align] + ' (' + displayX + displayY + ')'); - - // resizing display - contextResizing.resizeButtonGroup.style.display = contextPlugin._resizing ? '' : 'none'; - const resizeDotShow = contextPlugin._resizing && !contextPlugin._resizeDotHide && !contextPlugin._onlyPercentage ? 'flex' : 'none'; - const resizeHandles = contextResizing.resizeHandles; - for (let i = 0, len = resizeHandles.length; i < len; i++) { - resizeHandles[i].style.display = resizeDotShow; - } - - if (contextPlugin._resizing) { - const rotations = contextResizing.rotationButtons; - rotations[0].style.display = rotations[1].style.display = contextPlugin._rotation ? '' : 'none'; - } - - // align icon - const alignList = contextResizing.alignMenuList; - this.util.changeElement(contextResizing.alignButton.firstElementChild, contextResizing.alignIcons[align]); - for (let i = 0, len = alignList.length; i < len; i++) { - if (alignList[i].getAttribute('data-value') === align) this.util.addClass(alignList[i], 'on'); - else this.util.removeClass(alignList[i], 'on'); - } - - // percentage active - const pButtons = contextResizing.percentageButtons; - const value = /%$/.test(targetElement.style.width) && /%$/.test(container.style.width) ? (this.util.getNumber(container.style.width, 0) / 100) + '' : '' ; - for (let i = 0, len = pButtons.length; i < len; i++) { - if (pButtons[i].getAttribute('data-value') === value) { - this.util.addClass(pButtons[i], 'active'); - } else { - this.util.removeClass(pButtons[i], 'active'); - } - } - - // caption display, active - if (!contextPlugin._captionShow) { - contextResizing.captionButton.style.display = 'none'; - } else { - contextResizing.captionButton.style.display = ''; - if (this.util.getChildElement(targetElement.parentNode, 'figcaption')) { - this.util.addClass(contextResizing.captionButton, 'active'); - contextPlugin._captionChecked = true; - } else { - this.util.removeClass(contextResizing.captionButton, 'active'); - contextPlugin._captionChecked = false; - } - } - - resizeContainer.style.display = 'block'; - - const addOffset = {left: 0, top: 50}; - if (this.options.iframe) { - addOffset.left -= this.context.element.wysiwygFrame.parentElement.offsetLeft; - addOffset.top -= this.context.element.wysiwygFrame.parentElement.offsetTop; - } - - this.setControllerPosition(contextResizing.resizeButton, resizeContainer, 'bottom', addOffset); - this.controllersOn(resizeContainer, contextResizing.resizeButton, this.util.setDisabledButtons.bind(this, false, this.resizingDisabledButtons), targetElement, plugin); - this.util.setDisabledButtons(true, this.resizingDisabledButtons); - - contextResizing._resize_w = w; - contextResizing._resize_h = h; - - const originSize = (targetElement.getAttribute('origin-size') || '').split(','); - contextResizing._origin_w = originSize[0] || targetElement.naturalWidth; - contextResizing._origin_h = originSize[1] || targetElement.naturalHeight; - - return { - w: w, - h: h, - t: t, - l: l - }; - }, - - _closeAlignMenu: null, - - /** - * @description Open align submenu of module - */ - openAlignMenu: function () { - const alignButton = this.context.resizing.alignButton; - this.util.addClass(alignButton, 'on'); - this.context.resizing.alignMenu.style.top = (alignButton.offsetTop + alignButton.offsetHeight) + 'px'; - this.context.resizing.alignMenu.style.left = (alignButton.offsetLeft - alignButton.offsetWidth / 2) + 'px'; - this.context.resizing.alignMenu.style.display = 'block'; - - this.plugins.resizing._closeAlignMenu = function () { - this.util.removeClass(this.context.resizing.alignButton, 'on'); - this.context.resizing.alignMenu.style.display = 'none'; - this.removeDocEvent('click', this.plugins.resizing._closeAlignMenu); - this.plugins.resizing._closeAlignMenu = null; - }.bind(this); - - this.addDocEvent('click', this.plugins.resizing._closeAlignMenu); - }, - - /** - * @description Click event of resizing toolbar - * Performs the action of the clicked toolbar button. - * @param {MouseEvent} e Event object - */ - onClick_resizeButton: function (e) { - e.stopPropagation(); - - const target = e.target; - const command = target.getAttribute('data-command') || target.parentNode.getAttribute('data-command'); - - if (!command) return; - - const value = target.getAttribute('data-value') || target.parentNode.getAttribute('data-value'); - - const pluginName = this.context.resizing._resize_plugin; - const currentContext = this.context[pluginName]; - const contextEl = currentContext._element; - const currentModule = this.plugins[pluginName]; - - e.preventDefault(); - - if (typeof this.plugins.resizing._closeAlignMenu === 'function') { - this.plugins.resizing._closeAlignMenu(); - if (command === 'onalign') return; - } - - switch (command) { - case 'auto': - this.plugins.resizing.resetTransform.call(this, contextEl); - currentModule.setAutoSize.call(this); - this.selectComponent(contextEl, pluginName); - break; - case 'percent': - let percentY = this.plugins.resizing._module_getSizeY.call(this, currentContext); - if (this.context.resizing._rotateVertical) { - const percentage = contextEl.getAttribute('data-percentage'); - if (percentage) percentY = percentage.split(',')[1]; - } - - this.plugins.resizing.resetTransform.call(this, contextEl); - currentModule.setPercentSize.call(this, (value * 100), (this.util.getNumber(percentY, 0) === null || !/%$/.test(percentY)) ? '' : percentY); - this.selectComponent(contextEl, pluginName); - break; - case 'mirror': - const r = contextEl.getAttribute('data-rotate') || '0'; - let x = contextEl.getAttribute('data-rotateX') || ''; - let y = contextEl.getAttribute('data-rotateY') || ''; - - if ((value === 'h' && !this.context.resizing._rotateVertical) || (value === 'v' && this.context.resizing._rotateVertical)) { - y = y ? '' : '180'; - } else { - x = x ? '' : '180'; - } - - contextEl.setAttribute('data-rotateX', x); - contextEl.setAttribute('data-rotateY', y); - - this.plugins.resizing._setTransForm(contextEl, r, x, y); - break; - case 'rotate': - const contextResizing = this.context.resizing; - const slope = (contextEl.getAttribute('data-rotate') * 1) + (value * 1); - const deg = this._w.Math.abs(slope) >= 360 ? 0 : slope; - - contextEl.setAttribute('data-rotate', deg); - contextResizing._rotateVertical = /^(90|270)$/.test(this._w.Math.abs(deg).toString()); - this.plugins.resizing.setTransformSize.call(this, contextEl, null, null); - - this.selectComponent(contextEl, pluginName); - break; - case 'onalign': - this.plugins.resizing.openAlignMenu.call(this); - return; - case 'align': - const alignValue = value === 'basic' ? 'none' : value; - currentModule.setAlign.call(this, alignValue, null, null, null); - this.selectComponent(contextEl, pluginName); - break; - case 'caption': - const caption = !currentContext._captionChecked; - currentModule.openModify.call(this, true); - currentContext._captionChecked = currentContext.captionCheckEl.checked = caption; - - currentModule.update_image.call(this, false, false, false); - - if (caption) { - const captionText = this.util.getChildElement(currentContext._caption, function (current) { - return current.nodeType === 3; - }); - - if (!captionText) { - currentContext._caption.focus(); - } else { - this.setRange(captionText, 0, captionText, captionText.textContent.length); - } - - this.controllersOff(); - } else { - this.selectComponent(contextEl, pluginName); - currentModule.openModify.call(this, true); - } - - break; - case 'revert': - currentModule.setOriginSize.call(this); - this.selectComponent(contextEl, pluginName); - break; - case 'update': - currentModule.openModify.call(this); - this.controllersOff(); - break; - case 'delete': - currentModule.destroy.call(this); - break; - } - - // history stack - this.history.push(false); - }, - - /** - * @description Initialize the transform style (rotation) of the element. - * @param {Element} element Target element - */ - resetTransform: function (element) { - const size = (element.getAttribute('data-size') || element.getAttribute('data-origin') || '').split(','); - this.context.resizing._rotateVertical = false; - - element.style.maxWidth = ''; - element.style.transform = ''; - element.style.transformOrigin = ''; - element.setAttribute('data-rotate', ''); - element.setAttribute('data-rotateX', ''); - element.setAttribute('data-rotateY', ''); - - this.plugins[this.context.resizing._resize_plugin].setSize.call(this, size[0] ? size[0] : 'auto', size[1] ? size[1] : '', true); - }, - - /** - * @description Set the transform style (rotation) of the element. - * @param {Element} element Target element - * @param {Number|null} width Element's width size - * @param {Number|null} height Element's height size - */ - setTransformSize: function (element, width, height) { - let percentage = element.getAttribute('data-percentage'); - const isVertical = this.context.resizing._rotateVertical; - const deg = element.getAttribute('data-rotate') * 1; - let transOrigin = ''; - - if (percentage && !isVertical) { - percentage = percentage.split(','); - if (percentage[0] === 'auto' && percentage[1] === 'auto') { - this.plugins[this.context.resizing._resize_plugin].setAutoSize.call(this); - } else { - this.plugins[this.context.resizing._resize_plugin].setPercentSize.call(this, percentage[0], percentage[1]); - } - } else { - const cover = this.util.getParentElement(element, 'FIGURE'); - - const offsetW = width || element.offsetWidth; - const offsetH = height || element.offsetHeight; - const w = (isVertical ? offsetH : offsetW) + 'px'; - const h = (isVertical ? offsetW : offsetH) + 'px'; - - this.plugins[this.context.resizing._resize_plugin].cancelPercentAttr.call(this); - this.plugins[this.context.resizing._resize_plugin].setSize.call(this, offsetW + 'px', offsetH + 'px', true); - - cover.style.width = w; - cover.style.height = (!!this.context[this.context.resizing._resize_plugin]._caption ? '' : h); - - if (isVertical) { - let transW = (offsetW/2) + 'px ' + (offsetW/2) + 'px 0'; - let transH = (offsetH/2) + 'px ' + (offsetH/2) + 'px 0'; - transOrigin = deg === 90 || deg === -270 ? transH : transW; - } - } - - element.style.transformOrigin = transOrigin; - this.plugins.resizing._setTransForm(element, deg.toString(), element.getAttribute('data-rotateX') || '', element.getAttribute('data-rotateY') || ''); - - if (isVertical) element.style.maxWidth = 'none'; - else element.style.maxWidth = ''; - - this.plugins.resizing.setCaptionPosition.call(this, element); - }, - - _setTransForm: function (element, r, x, y) { - let width = (element.offsetWidth - element.offsetHeight) * (/-/.test(r) ? 1 : -1); - let translate = ''; - - if (/[1-9]/.test(r) && (x || y)) { - translate = x ? 'Y' : 'X'; - - switch (r) { - case '90': - translate = x && y ? 'X' : y ? translate : ''; - break; - case '270': - width *= -1; - translate = x && y ? 'Y' : x ? translate : ''; - break; - case '-90': - translate = x && y ? 'Y' : x ? translate : ''; - break; - case '-270': - width *= -1; - translate = x && y ? 'X' : y ? translate : ''; - break; - default: - translate = ''; - } - } - - if (r % 180 === 0) { - element.style.maxWidth = ''; - } - - element.style.transform = 'rotate(' + r + 'deg)' + (x ? ' rotateX(' + x + 'deg)' : '') + (y ? ' rotateY(' + y + 'deg)' : '') + (translate ? ' translate' + translate + '(' + width + 'px)' : ''); - }, - - /** - * @description The position of the caption is set automatically. - * @param {Element} element Target element (not caption element) - */ - setCaptionPosition: function (element) { - const figcaption = this.util.getChildElement(this.util.getParentElement(element, 'FIGURE'), 'FIGCAPTION'); - if (figcaption) { - figcaption.style.marginTop = (this.context.resizing._rotateVertical ? element.offsetWidth - element.offsetHeight : 0) + 'px'; - } - }, - - /** - * @description Mouse down event of resize handles - * @param {MouseEvent} e Event object - */ - onMouseDown_resize_handle: function (e) { - e.stopPropagation(); - e.preventDefault(); - - const contextResizing = this.context.resizing; - const direction = contextResizing._resize_direction = e.target.classList[0]; - - contextResizing._resizeClientX = e.clientX; - contextResizing._resizeClientY = e.clientY; - this.context.element.resizeBackground.style.display = 'block'; - contextResizing.resizeButton.style.display = 'none'; - contextResizing.resizeDiv.style.float = /l/.test(direction) ? 'right' : /r/.test(direction) ? 'left' : 'none'; - - const closureFunc_bind = function closureFunc(e) { - if (e.type === 'keydown' && e.keyCode !== 27) return; - - const change = contextResizing._isChange; - contextResizing._isChange = false; - - this.removeDocEvent('mousemove', resizing_element_bind); - this.removeDocEvent('mouseup', closureFunc_bind); - this.removeDocEvent('keydown', closureFunc_bind); - - if (e.type === 'keydown') { - this.controllersOff(); - this.context.element.resizeBackground.style.display = 'none'; - this.plugins[this.context.resizing._resize_plugin].init.call(this); - } else { - // element resize - this.plugins.resizing.cancel_controller_resize.call(this, direction); - // history stack - if (change) this.history.push(false); - } - }.bind(this); - - const resizing_element_bind = this.plugins.resizing.resizing_element.bind(this, contextResizing, direction, this.context[contextResizing._resize_plugin]); - this.addDocEvent('mousemove', resizing_element_bind); - this.addDocEvent('mouseup', closureFunc_bind); - this.addDocEvent('keydown', closureFunc_bind); - }, - - /** - * @description Mouse move event after call "onMouseDown_resize_handle" of resize handles - * The size of the module's "div" is adjusted according to the mouse move event. - * @param {Object} contextResizing "core.context.resizing" object (binding argument) - * @param {String} direction Direction ("tl", "tr", "bl", "br", "lw", "th", "rw", "bh") (binding argument) - * @param {Object} plugin "core.context[currentPlugin]" object (binding argument) - * @param {MouseEvent} e Event object - */ - resizing_element: function (contextResizing, direction, plugin, e) { - const clientX = e.clientX; - const clientY = e.clientY; - - let resultW = plugin._element_w; - let resultH = plugin._element_h; - - const w = plugin._element_w + (/r/.test(direction) ? clientX - contextResizing._resizeClientX : contextResizing._resizeClientX - clientX); - const h = plugin._element_h + (/b/.test(direction) ? clientY - contextResizing._resizeClientY : contextResizing._resizeClientY - clientY); - const wh = ((plugin._element_h / plugin._element_w) * w); - - if (/t/.test(direction)) contextResizing.resizeDiv.style.top = (plugin._element_h - (/h/.test(direction) ? h : wh)) + 'px'; - if (/l/.test(direction)) contextResizing.resizeDiv.style.left = (plugin._element_w - w) + 'px'; - - if (/r|l/.test(direction)) { - contextResizing.resizeDiv.style.width = w + 'px'; - resultW = w; - } - - if (/^(t|b)[^h]$/.test(direction)) { - contextResizing.resizeDiv.style.height = wh + 'px'; - resultH = wh; - } - else if (/^(t|b)h$/.test(direction)) { - contextResizing.resizeDiv.style.height = h + 'px'; - resultH = h; - } - - contextResizing._resize_w = resultW; - contextResizing._resize_h = resultH; - this.util.changeTxt(contextResizing.resizeDisplay, this._w.Math.round(resultW) + ' x ' + this._w.Math.round(resultH)); - contextResizing._isChange = true; - }, - - /** - * @description Resize the element to the size of the "div" adjusted in the "resizing_element" method. - * Called at the mouse-up event registered in "onMouseDown_resize_handle". - * @param {String} direction Direction ("tl", "tr", "bl", "br", "lw", "th", "rw", "bh") - */ - cancel_controller_resize: function (direction) { - const isVertical = this.context.resizing._rotateVertical; - this.controllersOff(); - this.context.element.resizeBackground.style.display = 'none'; - - let w = this._w.Math.round(isVertical ? this.context.resizing._resize_h : this.context.resizing._resize_w); - let h = this._w.Math.round(isVertical ? this.context.resizing._resize_w : this.context.resizing._resize_h); - - if (!isVertical && !/%$/.test(w)) { - const padding = 16; - const limit = this.context.element.wysiwygFrame.clientWidth - (padding * 2) - 2; - - if (this.util.getNumber(w, 0) > limit) { - h = this._w.Math.round((h / w) * limit); - w = limit; - } - } - - const pluginName = this.context.resizing._resize_plugin; - this.plugins[pluginName].setSize.call(this, w, h, false, direction); - if (isVertical) this.plugins.resizing.setTransformSize.call(this, this.context[this.context.resizing._resize_plugin]._element, w, h); - - this.selectComponent(this.context[pluginName]._element, pluginName); - } - }; - - if (typeof noGlobal === typeof undefined) { - if (!window.SUNEDITOR_MODULES) { - Object.defineProperty(window, 'SUNEDITOR_MODULES', { - enumerable: true, - writable: false, - configurable: false, - value: {} - }); - } - - Object.defineProperty(window.SUNEDITOR_MODULES, 'resizing', { - enumerable: true, - writable: false, - configurable: false, - value: resizing - }); - } - - return resizing; -})); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/align.js": -/*!*************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/align.js ***! - \*************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'align', - display: 'submenu', - add: function (core, targetElement) { - const icons = core.icons; - const context = core.context; - context.align = { - targetButton: targetElement, - _alignList: null, - currentAlign: '', - defaultDir: core.options.rtl ? 'right' : 'left', - icons: { - justify: icons.align_justify, - left: icons.align_left, - right: icons.align_right, - center: icons.align_center - } - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - let listUl = listDiv.querySelector('ul'); - - /** add event listeners */ - listUl.addEventListener('click', this.pickup.bind(core)); - context.align._alignList = listUl.querySelectorAll('li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null, listUl = null; - }, - - setSubmenu: function (core) { - const lang = core.lang; - const icons = core.icons; - const listDiv = core.util.createElement('DIV'); - const leftDir = core.context.align.defaultDir === 'left'; - - const leftMenu = '
  • ' + - '' + - '
  • '; - - const rightMenu = '
  • ' + - '' + - '
  • '; - - listDiv.className = 'se-submenu se-list-layer se-list-align'; - listDiv.innerHTML = '' + - '
    ' + - '
      ' + - (leftDir ? leftMenu : rightMenu) + - '
    • ' + - '' + - '
    • ' + - (leftDir? rightMenu : leftMenu) + - '
    • ' + - '' + - '
    • ' + - '
    ' + - '
    '; - - return listDiv; - }, - - /** - * @Override core - */ - active: function (element) { - const alignContext = this.context.align; - const targetButton = alignContext.targetButton; - const target = targetButton.firstElementChild; - - if (!element) { - this.util.changeElement(target, alignContext.icons[alignContext.defaultDir]); - targetButton.removeAttribute('data-focus'); - } else if (this.util.isFormatElement(element)) { - const textAlign = element.style.textAlign; - if (textAlign) { - this.util.changeElement(target, alignContext.icons[textAlign] || alignContext.icons[alignContext.defaultDir]); - targetButton.setAttribute('data-focus', textAlign); - return true; - } - } - - return false; - }, - - /** - * @Override submenu - */ - on: function () { - const alignContext = this.context.align; - const alignList = alignContext._alignList; - const currentAlign = alignContext.targetButton.getAttribute('data-focus') || alignContext.defaultDir; - - if (currentAlign !== alignContext.currentAlign) { - for (let i = 0, len = alignList.length; i < len; i++) { - if (currentAlign === alignList[i].getAttribute('data-value')) { - this.util.addClass(alignList[i], 'active'); - } else { - this.util.removeClass(alignList[i], 'active'); - } - } - - alignContext.currentAlign = currentAlign; - } - }, - - pickup: function (e) { - e.preventDefault(); - e.stopPropagation(); - - let target = e.target; - let value = null; - - while (!value && !/UL/i.test(target.tagName)) { - value = target.getAttribute('data-value'); - target = target.parentNode; - } - - if (!value) return; - - const defaultDir = this.context.align.defaultDir; - const selectedFormsts = this.getSelectedElements(); - for (let i = 0, len = selectedFormsts.length; i < len; i++) { - this.util.setStyle(selectedFormsts[i], 'textAlign', (value === defaultDir ? '' : value)); - } - - this.effectNode = null; - this.submenuOff(); - this.focus(); - - // history stack - this.history.push(false); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/font.js": -/*!************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/font.js ***! - \************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'font', - display: 'submenu', - add: function (core, targetElement) { - const context = core.context; - context.font = { - targetText: targetElement.querySelector('.txt'), - targetTooltip: targetElement.parentNode.querySelector('.se-tooltip-text'), - _fontList: null, - currentFont: '' - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - - /** add event listeners */ - listDiv.querySelector('.se-list-inner').addEventListener('click', this.pickup.bind(core)); - - context.font._fontList = listDiv.querySelectorAll('ul li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null; - }, - - setSubmenu: function (core) { - const option = core.options; - const lang = core.lang; - const listDiv = core.util.createElement('DIV'); - - listDiv.className = 'se-submenu se-list-layer se-list-font-family'; - - let font, text, i, len; - let fontList = !option.font ? - [ - 'Arial', - 'Comic Sans MS', - 'Courier New', - 'Impact', - 'Georgia', - 'tahoma', - 'Trebuchet MS', - 'Verdana' - ] : option.font; - - let list = '
    ' + - '
      ' + - '
    • '; - for (i = 0, len = fontList.length; i < len; i++) { - font = fontList[i]; - text = font.split(',')[0]; - list += '
    • '; - } - list += '
    '; - listDiv.innerHTML = list; - - return listDiv; - }, - - /** - * @Override core - */ - active: function (element) { - const target = this.context.font.targetText; - const tooltip = this.context.font.targetTooltip; - - if (!element) { - const font = this.lang.toolbar.font; - this.util.changeTxt(target, font); - this.util.changeTxt(tooltip, font); - } else if (element.style && element.style.fontFamily.length > 0) { - const selectFont = element.style.fontFamily.replace(/["']/g,''); - this.util.changeTxt(target, selectFont); - this.util.changeTxt(tooltip, selectFont); - return true; - } - - return false; - }, - - /** - * @Override submenu - */ - on: function () { - const fontContext = this.context.font; - const fontList = fontContext._fontList; - const currentFont = fontContext.targetText.textContent; - - if (currentFont !== fontContext.currentFont) { - for (let i = 0, len = fontList.length; i < len; i++) { - if (currentFont === fontList[i].getAttribute('data-value')) { - this.util.addClass(fontList[i], 'active'); - } else { - this.util.removeClass(fontList[i], 'active'); - } - } - - fontContext.currentFont = currentFont; - } - }, - - pickup: function (e) { - if (!/^BUTTON$/i.test(e.target.tagName)) return false; - - e.preventDefault(); - e.stopPropagation(); - - const value = e.target.getAttribute('data-value'); - - if (value) { - const newNode = this.util.createElement('SPAN'); - newNode.style.fontFamily = value; - this.nodeChange(newNode, ['font-family'], null, null); - } else { - this.nodeChange(null, ['font-family'], ['span'], true); - } - - this.submenuOff(); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/fontColor.js": -/*!*****************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/fontColor.js ***! - \*****************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _modules_colorPicker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/_colorPicker */ "./node_modules/suneditor/src/plugins/modules/_colorPicker.js"); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'fontColor', - display: 'submenu', - add: function (core, targetElement) { - core.addModule([_modules_colorPicker__WEBPACK_IMPORTED_MODULE_0__["default"]]); - - const context = core.context; - context.fontColor = { - previewEl: null, - colorInput: null, - colorList: null - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - context.fontColor.colorInput = listDiv.querySelector('._se_color_picker_input'); - - /** add event listeners */ - context.fontColor.colorInput.addEventListener('keyup', this.onChangeInput.bind(core)); - listDiv.querySelector('._se_color_picker_submit').addEventListener('click', this.submit.bind(core)); - listDiv.querySelector('._se_color_picker_remove').addEventListener('click', this.remove.bind(core)); - listDiv.addEventListener('click', this.pickup.bind(core)); - context.fontColor.colorList = listDiv.querySelectorAll('li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null; - }, - - setSubmenu: function (core) { - const colorArea = core.context.colorPicker.colorListHTML; - const listDiv = core.util.createElement('DIV'); - - listDiv.className = 'se-submenu se-list-layer'; - listDiv.innerHTML = colorArea; - - return listDiv; - }, - - /** - * @Override submenu - */ - on: function () { - const contextPicker = this.context.colorPicker; - const contextFontColor = this.context.fontColor; - - contextPicker._colorInput = contextFontColor.colorInput; - contextPicker._defaultColor = '#333333'; - contextPicker._styleProperty = 'color'; - contextPicker._colorList = contextFontColor.colorList; - - this.plugins.colorPicker.init.call(this, this.getSelectionNode(), null); - }, - - /** - * @Override _colorPicker - */ - onChangeInput: function (e) { - this.plugins.colorPicker.setCurrentColor.call(this, e.target.value); - }, - - submit: function () { - this.plugins.fontColor.applyColor.call(this, this.context.colorPicker._currentColor); - }, - - pickup: function (e) { - e.preventDefault(); - e.stopPropagation(); - - this.plugins.fontColor.applyColor.call(this, e.target.getAttribute('data-value')); - }, - - remove: function () { - this.nodeChange(null, ['color'], ['span'], true); - this.submenuOff(); - }, - - applyColor: function (color) { - if (!color) return; - - const newNode = this.util.createElement('SPAN'); - newNode.style.color = color; - this.nodeChange(newNode, ['color'], null, null); - - this.submenuOff(); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/fontSize.js": -/*!****************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/fontSize.js ***! - \****************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'fontSize', - display: 'submenu', - add: function (core, targetElement) { - const context = core.context; - context.fontSize = { - targetText: targetElement.querySelector('.txt'), - _sizeList: null, - currentSize: '' - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - let listUl = listDiv.querySelector('ul'); - - /** add event listeners */ - listUl.addEventListener('click', this.pickup.bind(core)); - context.fontSize._sizeList = listUl.querySelectorAll('li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null, listUl = null; - }, - - setSubmenu: function (core) { - const option = core.options; - const lang = core.lang; - const listDiv = core.util.createElement('DIV'); - - listDiv.className = 'se-submenu se-list-layer se-list-font-size'; - - const sizeList = !option.fontSize ? [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72] : option.fontSize; - - let list = '
    ' + - '
      ' + - '
    • '; - for (let i = 0, unit = option.fontSizeUnit, len = sizeList.length, size; i < len; i++) { - size = sizeList[i]; - list += '
    • '; - } - list += '
    '; - - listDiv.innerHTML = list; - - return listDiv; - }, - - /** - * @Override core - */ - active: function (element) { - if (!element) { - this.util.changeTxt(this.context.fontSize.targetText, this.lang.toolbar.fontSize); - } else if (element.style && element.style.fontSize.length > 0) { - this.util.changeTxt(this.context.fontSize.targetText, element.style.fontSize); - return true; - } - - return false; - }, - - /** - * @Override submenu - */ - on: function () { - const fontSizeContext = this.context.fontSize; - const sizeList = fontSizeContext._sizeList; - const currentSize = fontSizeContext.targetText.textContent; - - if (currentSize !== fontSizeContext.currentSize) { - for (let i = 0, len = sizeList.length; i < len; i++) { - if (currentSize === sizeList[i].getAttribute('data-value')) { - this.util.addClass(sizeList[i], 'active'); - } else { - this.util.removeClass(sizeList[i], 'active'); - } - } - - fontSizeContext.currentSize = currentSize; - } - }, - - pickup: function (e) { - if (!/^BUTTON$/i.test(e.target.tagName)) return false; - - e.preventDefault(); - e.stopPropagation(); - - const value = e.target.getAttribute('data-value'); - - if (value) { - const newNode = this.util.createElement('SPAN'); - newNode.style.fontSize = value; - this.nodeChange(newNode, ['font-size'], null, null); - } else { - this.nodeChange(null, ['font-size'], ['span'], true); - } - - this.submenuOff(); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/formatBlock.js": -/*!*******************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/formatBlock.js ***! - \*******************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'formatBlock', - display: 'submenu', - add: function (core, targetElement) { - const context = core.context; - context.formatBlock = { - targetText: targetElement.querySelector('.txt'), - targetTooltip: targetElement.parentNode.querySelector('.se-tooltip-text'), - _formatList: null, - currentFormat: '' - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - - /** add event listeners */ - listDiv.querySelector('ul').addEventListener('click', this.pickUp.bind(core)); - context.formatBlock._formatList = listDiv.querySelectorAll('li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null; - }, - - setSubmenu: function (core) { - const option = core.options; - const lang_toolbar = core.lang.toolbar; - const listDiv = core.util.createElement('DIV'); - listDiv.className = 'se-submenu se-list-layer se-list-format'; - - const defaultFormats = ['p', 'div', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']; - const formatList = !option.formats || option.formats.length === 0 ? defaultFormats : option.formats; - - let list = '
      '; - for (let i = 0, len = formatList.length, format, tagName, command, name, h, attrs, className; i < len; i++) { - format = formatList[i]; - - if (typeof format === 'string' && defaultFormats.indexOf(format) > -1) { - tagName = format.toLowerCase(); - command = tagName === 'blockquote' ? 'range' : tagName === 'pre' ? 'free' : 'replace'; - h = /^h/.test(tagName) ? tagName.match(/\d+/)[0] : ''; - name = lang_toolbar['tag_' + (h ? 'h' : tagName)] + h; - className = ''; - attrs = ''; - } else { - tagName = format.tag.toLowerCase(); - command = format.command; - name = format.name || tagName; - className = format.class; - attrs = className ? ' class="' + className + '"' : ''; - } - - list += '
    • ' + - '
    • '; - } - list += '
    '; - - listDiv.innerHTML = list; - - return listDiv; - }, - - /** - * @Override core - */ - active: function (element) { - let formatTitle = this.lang.toolbar.formats; - const target = this.context.formatBlock.targetText; - const tooltip = this.context.formatBlock.targetTooltip; - - if (!element) { - this.util.changeTxt(target, formatTitle); - this.util.changeTxt(tooltip, formatTitle); - } else if (this.util.isFormatElement(element)) { - const formatContext = this.context.formatBlock; - const formatList = formatContext._formatList; - const nodeName = element.nodeName.toLowerCase(); - const className = (element.className.match(/(\s|^)__se__format__[^\s]+/) || [''])[0].trim(); - - for (let i = 0, len = formatList.length, f; i < len; i++) { - f = formatList[i]; - if (nodeName === f.getAttribute('data-value') && className === f.getAttribute('data-class')) { - formatTitle = f.title; - break; - } - } - - this.util.changeTxt(target, formatTitle); - this.util.changeTxt(tooltip, formatTitle); - target.setAttribute('data-value', nodeName); - target.setAttribute('data-class', className); - - return true; - } - - return false; - }, - - /** - * @Override submenu - */ - on: function () { - const formatContext = this.context.formatBlock; - const formatList = formatContext._formatList; - const target = formatContext.targetText; - const currentFormat = (target.getAttribute('data-value') || '') + (target.getAttribute('data-class') || ''); - - if (currentFormat !== formatContext.currentFormat) { - for (let i = 0, len = formatList.length, f; i < len; i++) { - f = formatList[i]; - if (currentFormat === f.getAttribute('data-value') + f.getAttribute('data-class')) { - this.util.addClass(f, 'active'); - } else { - this.util.removeClass(f, 'active'); - } - } - - formatContext.currentFormat = currentFormat; - } - }, - - pickUp: function (e) { - e.preventDefault(); - e.stopPropagation(); - - let target = e.target; - let command = null, value = null, tag = null, className = ''; - - while (!command && !/UL/i.test(target.tagName)) { - command = target.getAttribute('data-command'); - value = target.getAttribute('data-value'); - className = target.getAttribute('data-class'); - if (command) { - tag = target.firstChild; - break; - } - target = target.parentNode; - } - - if (!command) return; - - // blockquote - if (command === 'range') { - const rangeElement = tag.cloneNode(false); - this.applyRangeFormatElement(rangeElement); - } - // free, replace - else { - let range = this.getRange(); - let selectedFormsts = this.getSelectedElementsAndComponents(false); - - if (selectedFormsts.length === 0) { - range = this.getRange_addLine(range, null); - selectedFormsts = this.getSelectedElementsAndComponents(false); - if (selectedFormsts.length === 0) return; - } - - const startOffset = range.startOffset; - const endOffset = range.endOffset; - - const util = this.util; - let first = selectedFormsts[0]; - let last = selectedFormsts[selectedFormsts.length - 1]; - const firstPath = util.getNodePath(range.startContainer, first, null, null); - const lastPath = util.getNodePath(range.endContainer, last, null, null); - - // remove selected list - const rlist = this.detachList(selectedFormsts, false); - if (rlist.sc) first = rlist.sc; - if (rlist.ec) last = rlist.ec; - - // change format tag - this.setRange(util.getNodeFromPath(firstPath, first), startOffset, util.getNodeFromPath(lastPath, last), endOffset); - const modifiedFormsts = this.getSelectedElementsAndComponents(false); - - // free format - if (command === 'free') { - const len = modifiedFormsts.length - 1; - let parentNode = modifiedFormsts[len].parentNode; - let freeElement = tag.cloneNode(false); - const focusElement = freeElement; - - for (let i = len, f, html, before, next, inner, isComp, first = true; i >= 0; i--) { - f = modifiedFormsts[i]; - if (f === (!modifiedFormsts[i + 1] ? null : modifiedFormsts[i + 1].parentNode)) continue; - - isComp = util.isComponent(f); - html = isComp ? '' : f.innerHTML.replace(/(?!>)\s+(?=<)|\n/g, ' '); - before = util.getParentElement(f, function (current) { - return current.parentNode === parentNode; - }); - - if (parentNode !== f.parentNode || isComp) { - if (util.isFormatElement(parentNode)) { - parentNode.parentNode.insertBefore(freeElement, parentNode.nextSibling); - parentNode = parentNode.parentNode; - } else { - parentNode.insertBefore(freeElement, before ? before.nextSibling : null); - parentNode = f.parentNode; - } - - next = freeElement.nextSibling; - if (next && freeElement.nodeName === next.nodeName && util.isSameAttributes(freeElement, next)) { - freeElement.innerHTML += '
    ' + next.innerHTML; - util.removeItem(next); - } - - freeElement = tag.cloneNode(false); - first = true; - } - - inner = freeElement.innerHTML; - freeElement.innerHTML = ((first || !html || !inner || /
    $/i.test(html)) ? html : html + '
    ') + inner; - - if (i === 0) { - parentNode.insertBefore(freeElement, f); - next = f.nextSibling; - if (next && freeElement.nodeName === next.nodeName && util.isSameAttributes(freeElement, next)) { - freeElement.innerHTML += '
    ' + next.innerHTML; - util.removeItem(next); - } - - const prev = freeElement.previousSibling; - if (prev && freeElement.nodeName === prev.nodeName && util.isSameAttributes(freeElement, prev)) { - prev.innerHTML += '
    ' + freeElement.innerHTML; - util.removeItem(freeElement); - } - } - - if (!isComp) util.removeItem(f); - if (!!html) first = false; - } - - this.setRange(focusElement, 0, focusElement, 0); - } - // replace format - else { - for (let i = 0, len = modifiedFormsts.length, node, newFormat; i < len; i++) { - node = modifiedFormsts[i]; - - if ((node.nodeName.toLowerCase() !== value.toLowerCase() || (node.className.match(/(\s|^)__se__format__[^\s]+/) || [''])[0].trim() !== className) && !util.isComponent(node)) { - newFormat = tag.cloneNode(false); - util.copyFormatAttributes(newFormat, node); - newFormat.innerHTML = node.innerHTML; - - node.parentNode.replaceChild(newFormat, node); - } - - if (i === 0) first = newFormat || node; - if (i === len - 1) last = newFormat || node; - newFormat = null; - } - - this.setRange(util.getNodeFromPath(firstPath, first), startOffset, util.getNodeFromPath(lastPath, last), endOffset); - } - - // history stack - this.history.push(false); - } - - this.submenuOff(); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/hiliteColor.js": -/*!*******************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/hiliteColor.js ***! - \*******************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _modules_colorPicker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/_colorPicker */ "./node_modules/suneditor/src/plugins/modules/_colorPicker.js"); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'hiliteColor', - display: 'submenu', - add: function (core, targetElement) { - core.addModule([_modules_colorPicker__WEBPACK_IMPORTED_MODULE_0__["default"]]); - - const context = core.context; - context.hiliteColor = { - previewEl: null, - colorInput: null, - colorList: null - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - context.hiliteColor.colorInput = listDiv.querySelector('._se_color_picker_input'); - - /** add event listeners */ - context.hiliteColor.colorInput.addEventListener('keyup', this.onChangeInput.bind(core)); - listDiv.querySelector('._se_color_picker_submit').addEventListener('click', this.submit.bind(core)); - listDiv.querySelector('._se_color_picker_remove').addEventListener('click', this.remove.bind(core)); - listDiv.addEventListener('click', this.pickup.bind(core)); - - context.hiliteColor.colorList = listDiv.querySelectorAll('li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null; - }, - - setSubmenu: function (core) { - const colorArea = core.context.colorPicker.colorListHTML; - const listDiv = core.util.createElement('DIV'); - - listDiv.className = 'se-submenu se-list-layer'; - listDiv.innerHTML = colorArea; - - return listDiv; - }, - - /** - * @Override submenu - */ - on: function () { - const contextPicker = this.context.colorPicker; - const contextHiliteColor = this.context.hiliteColor; - - contextPicker._colorInput = contextHiliteColor.colorInput; - contextPicker._defaultColor = '#FFFFFF'; - contextPicker._styleProperty = 'backgroundColor'; - contextPicker._colorList = contextHiliteColor.colorList; - - this.plugins.colorPicker.init.call(this, this.getSelectionNode(), null); - }, - - /** - * @Override _colorPicker - */ - onChangeInput: function (e) { - this.plugins.colorPicker.setCurrentColor.call(this, e.target.value); - }, - - submit: function () { - this.plugins.hiliteColor.applyColor.call(this, this.context.colorPicker._currentColor); - }, - - pickup: function (e) { - e.preventDefault(); - e.stopPropagation(); - - this.plugins.hiliteColor.applyColor.call(this, e.target.getAttribute('data-value')); - }, - - remove: function () { - this.nodeChange(null, ['background-color'], ['span'], true); - this.submenuOff(); - }, - - applyColor: function (color) { - if (!color) return; - - const newNode = this.util.createElement('SPAN'); - newNode.style.backgroundColor = color; - this.nodeChange(newNode, ['background-color'], null, null); - - this.submenuOff(); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/horizontalRule.js": -/*!**********************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/horizontalRule.js ***! - \**********************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'horizontalRule', - display: 'submenu', - add: function (core, targetElement) { - /** set submenu */ - let listDiv = this.setSubmenu(core); - - /** add event listeners */ - listDiv.querySelector('ul').addEventListener('click', this.horizontalRulePick.bind(core)); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null; - }, - - setSubmenu: function (core) { - const lang = core.lang; - const listDiv = core.util.createElement('DIV'); - - listDiv.className = 'se-submenu se-list-layer se-list-line'; - listDiv.innerHTML = '' + - '
    ' + - '
      ' + - '
    • ' + - '' + - '
    • ' + - '
    • ' + - '' + - '
    • ' + - '
    • ' + - '' + - '
    • ' + - '
    ' + - '
    '; - - return listDiv; - }, - - appendHr: function (className) { - const oHr = this.util.createElement('HR'); - oHr.className = className; - this.focus(); - return this.insertComponent(oHr, false, true, false); - }, - - horizontalRulePick: function (e) { - e.preventDefault(); - e.stopPropagation(); - - let target = e.target; - let value = null; - - while (!value && !/UL/i.test(target.tagName)) { - value = target.getAttribute('data-value'); - target = target.parentNode; - } - - if (!value) return; - - const oNode = this.plugins.horizontalRule.appendHr.call(this, '__se__' + value); - if (oNode) { - this.setRange(oNode, 0, oNode, 0); - this.submenuOff(); - } - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/lineHeight.js": -/*!******************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/lineHeight.js ***! - \******************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 20197 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'lineHeight', - display: 'submenu', - add: function (core, targetElement) { - const context = core.context; - context.lineHeight = { - _sizeList: null, - currentSize: -1 - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - let listUl = listDiv.querySelector('ul'); - - /** add event listeners */ - listUl.addEventListener('click', this.pickup.bind(core)); - - context.lineHeight._sizeList = listUl.querySelectorAll('li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null, listUl = null; - }, - - setSubmenu: function (core) { - const option = core.options; - const lang = core.lang; - const listDiv = core.util.createElement('DIV'); - - listDiv.className = 'se-submenu se-list-layer'; - - const sizeList = !option.lineHeights ? [ - {text: '1', value: 1}, - {text: '1.15', value: 1.15}, - {text: '1.5', value: 1.5}, - {text: '2', value: 2} - ] : option.lineHeights; - - let list = '
    ' + - '
      ' + - '
    • '; - for (let i = 0, len = sizeList.length, text, size; i < len; i++) { - size = sizeList[i]; - list += '
    • '; - } - list += '
    '; - - listDiv.innerHTML = list; - - return listDiv; - }, - - /** - * @Override submenu - */ - on: function () { - const lineHeightContext = this.context.lineHeight; - const sizeList = lineHeightContext._sizeList; - const format = this.util.getFormatElement(this.getSelectionNode()); - const currentSize = !format ? '' : format.style.lineHeight + ''; - - if (currentSize !== lineHeightContext.currentSize) { - for (let i = 0, len = sizeList.length; i < len; i++) { - if (currentSize === sizeList[i].getAttribute('data-value')) { - this.util.addClass(sizeList[i], 'active'); - } else { - this.util.removeClass(sizeList[i], 'active'); - } - } - - lineHeightContext.currentSize = currentSize; - } - }, - - pickup: function (e) { - if (!/^BUTTON$/i.test(e.target.tagName)) return false; - - e.preventDefault(); - e.stopPropagation(); - - const value = e.target.getAttribute('data-value') || ''; - const formats = this.getSelectedElements(); - - for (let i = 0, len = formats.length; i < len; i++) { - formats[i].style.lineHeight = value; - } - - this.submenuOff(); - - // history stack - this.history.push(false); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/list.js": -/*!************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/list.js ***! - \************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'list', - display: 'submenu', - add: function (core, targetElement) { - const context = core.context; - context.list = { - targetButton: targetElement, - _list: null, - currentList: '', - icons: { - bullets: core.icons.list_bullets, - number: core.icons.list_number - } - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - let listUl = listDiv.querySelector('ul'); - - /** add event listeners */ - listUl.addEventListener('click', this.pickup.bind(core)); - context.list._list = listUl.querySelectorAll('li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null, listUl = null; - }, - - setSubmenu: function (core) { - const lang = core.lang; - const listDiv = core.util.createElement('DIV'); - - listDiv.className = 'se-submenu se-list-layer'; - listDiv.innerHTML = '' + - '
    ' + - '
      ' + - '
    • ' + - '
    • ' + - '
    ' + - '
    '; - - return listDiv; - }, - - /** - * @Override core - */ - active: function (element) { - const button = this.context.list.targetButton; - const icon = button.firstElementChild; - const util = this.util; - - if (!element) { - button.removeAttribute('data-focus'); - util.changeElement(icon, this.context.list.icons.number); - util.removeClass(button, 'active'); - } else if (util.isList(element)) { - const nodeName = element.nodeName; - button.setAttribute('data-focus', nodeName); - util.addClass(button, 'active'); - if (/UL/i.test(nodeName)) { - util.changeElement(icon, this.context.list.icons.bullets); - } else { - util.changeElement(icon, this.context.list.icons.number); - } - - return true; - } - - return false; - }, - - /** - * @Override submenu - */ - on: function () { - const listContext = this.context.list; - const list = listContext._list; - const currentList = listContext.targetButton.getAttribute('data-focus') || ''; - - if (currentList !== listContext.currentList) { - for (let i = 0, len = list.length; i < len; i++) { - if (currentList === list[i].getAttribute('data-command')) { - this.util.addClass(list[i], 'active'); - } else { - this.util.removeClass(list[i], 'active'); - } - } - - listContext.currentList = currentList; - } - }, - - editList: function (command, selectedCells, detach) { - let range = this.getRange(); - let selectedFormats = !selectedCells ? this.getSelectedElementsAndComponents(false) : selectedCells; - - if (selectedFormats.length === 0) { - if (selectedCells) return; - range = this.getRange_addLine(range, null); - selectedFormats = this.getSelectedElementsAndComponents(false); - if (selectedFormats.length === 0) return; - } - - const util = this.util; - util.sortByDepth(selectedFormats, true); - - // merge - let firstSel = selectedFormats[0]; - let lastSel = selectedFormats[selectedFormats.length - 1]; - let topEl = (util.isListCell(firstSel) || util.isComponent(firstSel)) && !firstSel.previousElementSibling ? firstSel.parentNode.previousElementSibling : firstSel.previousElementSibling; - let bottomEl = (util.isListCell(lastSel) || util.isComponent(lastSel)) && !lastSel.nextElementSibling ? lastSel.parentNode.nextElementSibling : lastSel.nextElementSibling; - - const originRange = { - sc: range.startContainer, - so: range.startOffset, - ec: range.endContainer, - eo: range.endOffset - }; - - let isRemove = true; - - for (let i = 0, len = selectedFormats.length; i < len; i++) { - if (!util.isList(util.getRangeFormatElement(selectedFormats[i], function (current) { - return this.getRangeFormatElement(current) && current !== selectedFormats[i]; - }.bind(util)))) { - isRemove = false; - break; - } - } - - if (isRemove && (!topEl || (firstSel.tagName !== topEl.tagName || command !== topEl.tagName.toUpperCase())) && (!bottomEl || (lastSel.tagName !== bottomEl.tagName || command !== bottomEl.tagName.toUpperCase()))) { - if (detach) { - for (let i = 0, len = selectedFormats.length; i < len; i++) { - for (let j = i - 1; j >= 0; j--) { - if (selectedFormats[j].contains(selectedFormats[i])) { - selectedFormats.splice(i, 1); - i--; len--; - break; - } - } - } - } - - const currentFormat = util.getRangeFormatElement(firstSel); - const cancel = currentFormat && currentFormat.tagName === command; - let rangeArr, tempList; - const passComponent = function (current) { - return !this.isComponent(current); - }.bind(util); - - if (!cancel) tempList = util.createElement(command); - - for (let i = 0, len = selectedFormats.length, r, o; i < len; i++) { - o = util.getRangeFormatElement(selectedFormats[i], passComponent); - if (!o || !util.isList(o)) continue; - - if (!r) { - r = o; - rangeArr = {r: r, f: [util.getParentElement(selectedFormats[i], 'LI')]}; - } else { - if (r !== o) { - if (detach && util.isListCell(o.parentNode)) { - this.plugins.list._detachNested.call(this, rangeArr.f); - } else { - this.detachRangeFormatElement(rangeArr.f[0].parentNode, rangeArr.f, tempList, false, true); - } - - o = selectedFormats[i].parentNode; - if (!cancel) tempList = util.createElement(command); - - r = o; - rangeArr = {r: r, f: [util.getParentElement(selectedFormats[i], 'LI')]}; - } else { - rangeArr.f.push(util.getParentElement(selectedFormats[i], 'LI')); - } - } - - if (i === len - 1) { - if (detach && util.isListCell(o.parentNode)) { - this.plugins.list._detachNested.call(this, rangeArr.f); - } else { - this.detachRangeFormatElement(rangeArr.f[0].parentNode, rangeArr.f, tempList, false, true); - } - } - } - } else { - const topElParent = topEl ? topEl.parentNode : topEl; - const bottomElParent = bottomEl ? bottomEl.parentNode : bottomEl; - topEl = topElParent && !util.isWysiwygDiv(topElParent) && topElParent.nodeName === command ? topElParent : topEl; - bottomEl = bottomElParent && !util.isWysiwygDiv(bottomElParent) && bottomElParent.nodeName === command ? bottomElParent : bottomEl; - - const mergeTop = topEl && topEl.tagName === command; - const mergeBottom = bottomEl && bottomEl.tagName === command; - - let list = mergeTop ? topEl : util.createElement(command); - let firstList = null; - let lastList = null; - let topNumber = null; - let bottomNumber = null; - - const passComponent = function (current) { - return !this.isComponent(current) && !this.isList(current); - }.bind(util); - - for (let i = 0, len = selectedFormats.length, newCell, fTag, isCell, next, originParent, nextParent, parentTag, siblingTag, rangeTag; i < len; i++) { - fTag = selectedFormats[i]; - if (fTag.childNodes.length === 0 && !util._isIgnoreNodeChange(fTag)) { - util.removeItem(fTag); - continue; - } - next = selectedFormats[i + 1]; - originParent = fTag.parentNode; - nextParent = next ? next.parentNode : null; - isCell = util.isListCell(fTag); - rangeTag = util.isRangeFormatElement(originParent) ? originParent : null; - parentTag = isCell && !util.isWysiwygDiv(originParent) ? originParent.parentNode : originParent; - siblingTag = isCell && !util.isWysiwygDiv(originParent) ? (!next || util.isListCell(parentTag)) ? originParent : originParent.nextSibling : fTag.nextSibling; - - newCell = util.createElement('LI'); - util.copyFormatAttributes(newCell, fTag); - if (util.isComponent(fTag)) { - const isHR = /^HR$/i.test(fTag.nodeName); - if (!isHR) newCell.innerHTML = '
    '; - newCell.innerHTML += fTag.outerHTML; - if (isHR) newCell.innerHTML += '
    '; - } else { - const fChildren = fTag.childNodes; - while (fChildren[0]) { - newCell.appendChild(fChildren[0]); - } - } - list.appendChild(newCell); - - if (!next) lastList = list; - if (!next || parentTag !== nextParent || util.isRangeFormatElement(siblingTag)) { - if (!firstList) firstList = list; - if ((!mergeTop || !next || parentTag !== nextParent) && !(next && util.isList(nextParent) && nextParent === originParent)) { - if (list.parentNode !== parentTag) parentTag.insertBefore(list, siblingTag); - } - } - - util.removeItem(fTag); - if (mergeTop && topNumber === null) topNumber = list.children.length - 1; - if (next && (util.getRangeFormatElement(nextParent, passComponent) !== util.getRangeFormatElement(originParent, passComponent) || (util.isList(nextParent) && util.isList(originParent) && util.getElementDepth(nextParent) !== util.getElementDepth(originParent)))) { - list = util.createElement(command); - } - - if (rangeTag && rangeTag.children.length === 0) util.removeItem(rangeTag); - } - - if (topNumber) { - firstList = firstList.children[topNumber]; - } - - if (mergeBottom) { - bottomNumber = list.children.length - 1; - list.innerHTML += bottomEl.innerHTML; - lastList = list.children[bottomNumber]; - util.removeItem(bottomEl); - } - } - - this.effectNode = null; - return originRange; - }, - - _detachNested: function (cells) { - const first = cells[0]; - const last = cells[cells.length - 1]; - const next = last.nextElementSibling; - const originList = first.parentNode; - const sibling = originList.parentNode.nextElementSibling; - const parentNode = originList.parentNode.parentNode; - - for (let c = 0, cLen = cells.length; c < cLen; c++) { - parentNode.insertBefore(cells[c], sibling); - } - - if (next && originList.children.length > 0) { - const newList = originList.cloneNode(false); - const children = originList.childNodes; - const index = this.util.getPositionIndex(next); - while (children[index]) { - newList.appendChild(children[index]); - } - last.appendChild(newList); - } - - if (originList.children.length === 0) this.util.removeItem(originList); - this.util.mergeSameTags(parentNode); - - const edge = this.util.getEdgeChildNodes(first, last); - - return { - cc: first.parentNode, - sc: edge.sc, - ec: edge.ec - }; - }, - - editInsideList: function (remove, selectedCells) { - selectedCells = !selectedCells ? this.getSelectedElements().filter(function (el) { return this.isListCell(el); }.bind(this.util)) : selectedCells; - const cellsLen = selectedCells.length; - if (cellsLen === 0 || (!remove && (!this.util.isListCell(selectedCells[0].previousElementSibling) && !this.util.isListCell(selectedCells[cellsLen - 1].nextElementSibling)))) { - return { - sc: selectedCells[0], - so: 0, - ec: selectedCells[cellsLen - 1], - eo: 1 - }; - } - - let originList = selectedCells[0].parentNode; - let lastCell = selectedCells[cellsLen - 1]; - let range = null; - - if (remove) { - if (originList !== lastCell.parentNode && this.util.isList(lastCell.parentNode.parentNode) && lastCell.nextElementSibling) { - lastCell = lastCell.nextElementSibling; - while (lastCell) { - selectedCells.push(lastCell); - lastCell = lastCell.nextElementSibling; - } - } - range = this.plugins.list.editList.call(this, originList.nodeName.toUpperCase(), selectedCells, true); - } else { - let innerList = this.util.createElement(originList.nodeName); - let prev = selectedCells[0].previousElementSibling; - let next = lastCell.nextElementSibling; - const nodePath = { s: null, e: null, sl: originList, el: originList }; - - for (let i = 0, len = cellsLen, c; i < len; i++) { - c = selectedCells[i]; - if (c.parentNode !== originList) { - this.plugins.list._insiedList.call(this, originList, innerList, prev, next, nodePath); - originList = c.parentNode; - innerList = this.util.createElement(originList.nodeName); - } - - prev = c.previousElementSibling; - next = c.nextElementSibling; - innerList.appendChild(c); - } - - this.plugins.list._insiedList.call(this, originList, innerList, prev, next, nodePath); - - const sc = this.util.getNodeFromPath(nodePath.s, nodePath.sl); - const ec = this.util.getNodeFromPath(nodePath.e, nodePath.el); - range = { - sc: sc, - so: 0, - ec: ec, - eo: ec.textContent.length - }; - } - - return range; - }, - - _insiedList: function (originList, innerList, prev, next, nodePath) { - let insertPrev = false; - - if (prev && innerList.tagName === prev.tagName) { - const children = innerList.children; - while (children[0]) { - prev.appendChild(children[0]); - } - - innerList = prev; - insertPrev = true; - } - - if (next && innerList.tagName === next.tagName) { - const children = next.children; - while (children[0]) { - innerList.appendChild(children[0]); - } - - const temp = next.nextElementSibling; - next.parentNode.removeChild(next); - next = temp; - } - - if (!insertPrev) { - if (this.util.isListCell(prev)) { - originList = prev; - next = null; - } - - originList.insertBefore(innerList, next); - - if (!nodePath.s) { - nodePath.s = this.util.getNodePath(innerList.firstElementChild.firstChild, originList, null); - nodePath.sl = originList; - } - - const slPath = originList.contains(nodePath.sl) ? this.util.getNodePath(nodePath.sl, originList) : null; - nodePath.e = this.util.getNodePath(innerList.lastElementChild.firstChild, originList, null); - nodePath.el = originList; - - this.util.mergeSameTags(originList, [nodePath.s, nodePath.e, slPath], false); - this.util.mergeNestedTags(originList); - if (slPath) nodePath.sl = this.util.getNodeFromPath(slPath, originList); - } - - return innerList; - }, - - pickup: function (e) { - e.preventDefault(); - e.stopPropagation(); - - let target = e.target; - let command = ''; - - while (!command && !/^UL$/i.test(target.tagName)) { - command = target.getAttribute('data-command'); - target = target.parentNode; - } - - if (!command) return; - - const range = this.plugins.list.editList.call(this, command, null, false); - if (range) this.setRange(range.sc, range.so, range.ec, range.eo); - - this.submenuOff(); - - // history stack - this.history.push(false); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/paragraphStyle.js": -/*!**********************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/paragraphStyle.js ***! - \**********************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'paragraphStyle', - display: 'submenu', - add: function (core, targetElement) { - const context = core.context; - context.paragraphStyle = { - _classList: null - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - - /** add event listeners */ - listDiv.querySelector('ul').addEventListener('click', this.pickUp.bind(core)); - - context.paragraphStyle._classList = listDiv.querySelectorAll('li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null; - }, - - setSubmenu: function (core) { - const option = core.options; - const listDiv = core.util.createElement('DIV'); - listDiv.className = 'se-submenu se-list-layer se-list-format'; - - const menuLang = core.lang.menu; - const defaultList = { - spaced: { - name: menuLang.spaced, - class: '__se__p-spaced', - _class: '' - }, - bordered: { - name: menuLang.bordered, - class: '__se__p-bordered', - _class: '' - }, - neon: { - name: menuLang.neon, - class: '__se__p-neon', - _class: '' - } - }; - const paragraphStyles = !option.paragraphStyles || option.paragraphStyles.length === 0 ? ['spaced', 'bordered', 'neon'] : option.paragraphStyles; - - let list = '
      '; - for (let i = 0, len = paragraphStyles.length, p, name, attrs, _class; i < len; i++) { - p = paragraphStyles[i]; - - if (typeof p === 'string') { - const defaultStyle = defaultList[p.toLowerCase()]; - if (!defaultStyle) continue; - p = defaultStyle; - } - - name = p.name; - attrs = p.class ? ' class="' + p.class + '"' : ''; - _class = p._class; - - list += '
    • ' + - '
    ' + - ''; - } - list += ''; - - listDiv.innerHTML = list; - - return listDiv; - }, - - /** - * @Override submenu - */ - on: function () { - const paragraphContext = this.context.paragraphStyle; - const paragraphList = paragraphContext._classList; - const currentFormat = this.util.getFormatElement(this.getSelectionNode()); - - for (let i = 0, len = paragraphList.length; i < len; i++) { - if (this.util.hasClass(currentFormat, paragraphList[i].getAttribute('data-value'))) { - this.util.addClass(paragraphList[i], 'active'); - } else { - this.util.removeClass(paragraphList[i], 'active'); - } - } - }, - - pickUp: function (e) { - e.preventDefault(); - e.stopPropagation(); - - let target = e.target; - let value = null; - - while (!/^UL$/i.test(target.tagName)) { - value = target.getAttribute('data-value'); - if (value) break; - target = target.parentNode; - } - - if (!value) return; - - let selectedFormsts = this.getSelectedElements(); - if (selectedFormsts.length === 0) { - this.getRange_addLine(this.getRange(), null); - selectedFormsts = this.getSelectedElements(); - if (selectedFormsts.length === 0) return; - } - - // change format class - const toggleClass = this.util.hasClass(target, 'active') ? this.util.removeClass.bind(this.util) : this.util.addClass.bind(this.util); - for (let i = 0, len = selectedFormsts.length; i < len; i++) { - toggleClass(selectedFormsts[i], value); - } - - this.submenuOff(); - - // history stack - this.history.push(false); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/table.js": -/*!*************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/table.js ***! - \*************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'table', - display: 'submenu', - add: function (core, targetElement) { - const context = core.context; - let contextTable = context.table = { - _element: null, - _tdElement: null, - _trElement: null, - _trElements: null, - _tableXY: [], - _maxWidth: true, - _fixedColumn: false, - _rtl: core.options.rtl, - cellControllerTop: core.options.tableCellControllerPosition === 'top', - resizeText: null, - headerButton: null, - mergeButton: null, - splitButton: null, - splitMenu: null, - maxText: core.lang.controller.maxSize, - minText: core.lang.controller.minSize, - _physical_cellCnt: 0, - _logical_cellCnt: 0, - _rowCnt: 0, - _rowIndex: 0, - _physical_cellIndex: 0, - _logical_cellIndex: 0, - _current_colSpan: 0, - _current_rowSpan: 0, - icons: { - expansion: core.icons.expansion, - reduction: core.icons.reduction - } - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - let tablePicker = listDiv.querySelector('.se-controller-table-picker'); - - contextTable.tableHighlight = listDiv.querySelector('.se-table-size-highlighted'); - contextTable.tableUnHighlight = listDiv.querySelector('.se-table-size-unhighlighted'); - contextTable.tableDisplay = listDiv.querySelector('.se-table-size-display'); - if (core.options.rtl) contextTable.tableHighlight.style.left = (10 * 18 - 13) + 'px'; - - /** set table controller */ - let tableController = this.setController_table(core); - contextTable.tableController = tableController; - contextTable.resizeButton = tableController.querySelector('._se_table_resize'); - contextTable.resizeText = tableController.querySelector('._se_table_resize > span > span'); - contextTable.columnFixedButton = tableController.querySelector('._se_table_fixed_column'); - contextTable.headerButton = tableController.querySelector('._se_table_header'); - - /** set resizing */ - let resizeDiv = this.setController_tableEditor(core, contextTable.cellControllerTop); - contextTable.resizeDiv = resizeDiv; - contextTable.splitMenu = resizeDiv.querySelector('.se-btn-group-sub'); - contextTable.mergeButton = resizeDiv.querySelector('._se_table_merge_button'); - contextTable.splitButton = resizeDiv.querySelector('._se_table_split_button'); - contextTable.insertRowAboveButton = resizeDiv.querySelector('._se_table_insert_row_a'); - contextTable.insertRowBelowButton = resizeDiv.querySelector('._se_table_insert_row_b'); - - /** add event listeners */ - tablePicker.addEventListener('mousemove', this.onMouseMove_tablePicker.bind(core, contextTable)); - tablePicker.addEventListener('click', this.appendTable.bind(core)); - resizeDiv.addEventListener('click', this.onClick_tableController.bind(core)); - tableController.addEventListener('click', this.onClick_tableController.bind(core)); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** append controller */ - context.element.relative.appendChild(resizeDiv); - context.element.relative.appendChild(tableController); - - /** empty memory */ - listDiv = null, tablePicker = null, resizeDiv = null, tableController = null, contextTable = null; - }, - - setSubmenu: function (core) { - const listDiv = core.util.createElement('DIV'); - listDiv.className = 'se-submenu se-selector-table'; - listDiv.innerHTML = '' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    1 x 1
    '; - - return listDiv; - }, - - setController_table: function (core) { - const lang = core.lang; - const icons = core.icons; - const tableResize = core.util.createElement('DIV'); - - tableResize.className = 'se-controller se-controller-table'; - tableResize.innerHTML = '' + - '
    ' + - '
    ' + - '' + - '' + - '' + - '' + - '
    ' + - '
    '; - - return tableResize; - }, - - setController_tableEditor: function (core, cellControllerTop) { - const lang = core.lang; - const icons = core.icons; - const tableResize = core.util.createElement('DIV'); - - tableResize.className = 'se-controller se-controller-table-cell'; - tableResize.innerHTML = (cellControllerTop ? '' : '
    ') + - '
    ' + - '' + - '' + - '' + - '' + - '
    ' + - '
    ' + - '' + - '' + - '' + - '' + - '
    ' + - '
    ' + - '
      ' + - '
    • ' + - lang.controller.VerticalSplit + '
    • ' + - '
    • ' + - lang.controller.HorizontalSplit + '
    • ' + - '
    ' + - '
    ' + - '
    ' + - '
    '; - - return tableResize; - }, - - appendTable: function () { - const oTable = this.util.createElement('TABLE'); - const createCells = this.plugins.table.createCells; - - const x = this.context.table._tableXY[0]; - let y = this.context.table._tableXY[1]; - let tableHTML = ''; - while (y > 0) { - tableHTML += '' + createCells.call(this, 'td', x) + ''; - --y; - } - tableHTML += ''; - oTable.innerHTML = tableHTML; - - const changed = this.insertComponent(oTable, false, true, false); - - if (changed) { - const firstTd = oTable.querySelector('td div'); - this.setRange(firstTd, 0, firstTd, 0); - this.plugins.table.reset_table_picker.call(this); - } - }, - - createCells: function (nodeName, cnt, returnElement) { - nodeName = nodeName.toLowerCase(); - - if (!returnElement) { - let cellsHTML = ''; - while (cnt > 0) { - cellsHTML += '<' +nodeName + '>

    '; - cnt--; - } - return cellsHTML; - } else { - const cell = this.util.createElement(nodeName); - cell.innerHTML = '

    '; - return cell; - } - }, - - onMouseMove_tablePicker: function (contextTable, e) { - e.stopPropagation(); - - let x = this._w.Math.ceil(e.offsetX / 18); - let y = this._w.Math.ceil(e.offsetY / 18); - x = x < 1 ? 1 : x; - y = y < 1 ? 1 : y; - - if (contextTable._rtl) { - contextTable.tableHighlight.style.left = (x * 18 - 13) + 'px'; - x = 11 - x; - } - - contextTable.tableHighlight.style.width = x + 'em'; - contextTable.tableHighlight.style.height = y + 'em'; - - // let x_u = x < 5 ? 5 : (x > 9 ? 10 : x + 1); - // let y_u = y < 5 ? 5 : (y > 9 ? 10 : y + 1); - // contextTable.tableUnHighlight.style.width = x_u + 'em'; - // contextTable.tableUnHighlight.style.height = y_u + 'em'; - - this.util.changeTxt(contextTable.tableDisplay, x + ' x ' + y); - contextTable._tableXY = [x, y]; - }, - - reset_table_picker: function () { - if (!this.context.table.tableHighlight) return; - - const highlight = this.context.table.tableHighlight.style; - const unHighlight = this.context.table.tableUnHighlight.style; - - highlight.width = '1em'; - highlight.height = '1em'; - unHighlight.width = '10em'; - unHighlight.height = '10em'; - - this.util.changeTxt(this.context.table.tableDisplay, '1 x 1'); - this.submenuOff(); - }, - - init: function () { - const contextTable = this.context.table; - const tablePlugin = this.plugins.table; - - tablePlugin._removeEvents.call(this); - - if (tablePlugin._selectedTable) { - const selectedCells = tablePlugin._selectedTable.querySelectorAll('.se-table-selected-cell'); - for (let i = 0, len = selectedCells.length; i < len; i++) { - this.util.removeClass(selectedCells[i], 'se-table-selected-cell'); - } - } - - tablePlugin._toggleEditor.call(this, true); - - contextTable._element = null; - contextTable._tdElement = null; - contextTable._trElement = null; - contextTable._trElements = null; - contextTable._tableXY = []; - contextTable._maxWidth = true; - contextTable._fixedColumn = false; - contextTable._physical_cellCnt = 0; - contextTable._logical_cellCnt = 0; - contextTable._rowCnt = 0; - contextTable._rowIndex = 0; - contextTable._physical_cellIndex = 0; - contextTable._logical_cellIndex = 0; - contextTable._current_colSpan = 0; - contextTable._current_rowSpan = 0; - - tablePlugin._shift = false; - tablePlugin._selectedCells = null; - tablePlugin._selectedTable = null; - tablePlugin._ref = null; - - tablePlugin._fixedCell = null; - tablePlugin._selectedCell = null; - tablePlugin._fixedCellName = null; - }, - - /** table edit controller */ - call_controller_tableEdit: function (tdElement) { - const tablePlugin = this.plugins.table; - const contextTable = this.context.table; - - if (!this.getSelection().isCollapsed && !tablePlugin._selectedCell) { - this.controllersOff(); - this.util.removeClass(tdElement, 'se-table-selected-cell'); - return; - } - - const tableElement = contextTable._element || this.plugins.table._selectedTable || this.util.getParentElement(tdElement, 'TABLE'); - contextTable._maxWidth = this.util.hasClass(tableElement, 'se-table-size-100') || tableElement.style.width === '100%' || (!tableElement.style.width && !this.util.hasClass(tableElement, 'se-table-size-auto')); - contextTable._fixedColumn = this.util.hasClass(tableElement, 'se-table-layout-fixed') || tableElement.style.tableLayout === 'fixed'; - tablePlugin.setTableStyle.call(this, contextTable._maxWidth ? 'width|column' : 'width'); - - tablePlugin.setPositionControllerTop.call(this, tableElement); - tablePlugin.setPositionControllerDiv.call(this, tdElement, tablePlugin._shift); - - if (!tablePlugin._shift) this.controllersOn(contextTable.resizeDiv, contextTable.tableController, tablePlugin.init.bind(this), tdElement, 'table'); - }, - - setPositionControllerTop: function (tableElement) { - this.setControllerPosition(this.context.table.tableController, tableElement, 'top', {left: 0, top: 0}); - }, - - setPositionControllerDiv: function (tdElement, reset) { - const contextTable = this.context.table; - const resizeDiv = contextTable.resizeDiv; - - this.plugins.table.setCellInfo.call(this, tdElement, reset); - - if (contextTable.cellControllerTop) { - this.setControllerPosition(resizeDiv, contextTable._element, 'top', {left: contextTable.tableController.offsetWidth, top: 0}); - } else { - this.setControllerPosition(resizeDiv, tdElement, 'bottom', {left: 0, top: 0}); - } - }, - - setCellInfo: function (tdElement, reset) { - const contextTable = this.context.table; - const table = contextTable._element = this.plugins.table._selectedTable || this.util.getParentElement(tdElement, 'TABLE'); - - if (/THEAD/i.test(table.firstElementChild.nodeName)) { - this.util.addClass(contextTable.headerButton, 'active'); - } else { - this.util.removeClass(contextTable.headerButton, 'active'); - } - - if (reset || contextTable._physical_cellCnt === 0) { - if (contextTable._tdElement !== tdElement) { - contextTable._tdElement = tdElement; - contextTable._trElement = tdElement.parentNode; - } - - const rows = contextTable._trElements = table.rows; - const cellIndex = tdElement.cellIndex; - - let cellCnt = 0; - for (let i = 0, cells = rows[0].cells, len = rows[0].cells.length; i < len; i++) { - cellCnt += cells[i].colSpan; - } - - // row cnt, row index - const rowIndex = contextTable._rowIndex = contextTable._trElement.rowIndex; - contextTable._rowCnt = rows.length; - - // cell cnt, physical cell index - contextTable._physical_cellCnt = contextTable._trElement.cells.length; - contextTable._logical_cellCnt = cellCnt; - contextTable._physical_cellIndex = cellIndex; - - // span - contextTable._current_colSpan = contextTable._tdElement.colSpan - 1; - contextTable._current_rowSpan - contextTable._trElement.cells[cellIndex].rowSpan - 1; - - // find logcal cell index - let rowSpanArr = []; - let spanIndex = []; - for (let i = 0, cells, colSpan; i <= rowIndex; i++) { - cells = rows[i].cells; - colSpan = 0; - for (let c = 0, cLen = cells.length, cell, cs, rs, logcalIndex; c < cLen; c++) { - cell = cells[c]; - cs = cell.colSpan - 1; - rs = cell.rowSpan - 1; - logcalIndex = c + colSpan; - - if (spanIndex.length > 0) { - for (let r = 0, arr; r < spanIndex.length; r++) { - arr = spanIndex[r]; - if (arr.row > i) continue; - if (logcalIndex >= arr.index) { - colSpan += arr.cs; - logcalIndex += arr.cs; - arr.rs -= 1; - arr.row = i + 1; - if (arr.rs < 1) { - spanIndex.splice(r, 1); - r--; - } - } else if (c === cLen - 1) { - arr.rs -= 1; - arr.row = i + 1; - if (arr.rs < 1) { - spanIndex.splice(r, 1); - r--; - } - } - } - } - - // logcal cell index - if (i === rowIndex && c === cellIndex) { - contextTable._logical_cellIndex = logcalIndex; - break; - } - - if (rs > 0) { - rowSpanArr.push({ - index: logcalIndex, - cs: cs + 1, - rs: rs, - row: -1 - }); - } - - colSpan += cs; - } - - spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {return a.index - b.index;}); - rowSpanArr = []; - } - - rowSpanArr = null; - spanIndex = null; - } - }, - - editTable: function (type, option) { - const tablePlugin = this.plugins.table; - const contextTable = this.context.table; - const table = contextTable._element; - const isRow = type === 'row'; - - if (isRow) { - const tableAttr = contextTable._trElement.parentNode; - if (/^THEAD$/i.test(tableAttr.nodeName)) { - if (option === 'up') { - return; - } else if (!tableAttr.nextElementSibling || !/^TBODY$/i.test(tableAttr.nextElementSibling.nodeName)) { - table.innerHTML += '' + tablePlugin.createCells.call(this, 'td', contextTable._logical_cellCnt, false) + ''; - return; - } - } - } - - // multi - if (tablePlugin._ref) { - const positionCell = contextTable._tdElement; - const selectedCells = tablePlugin._selectedCells; - // multi - row - if (isRow) { - // remove row - if (!option) { - let row = selectedCells[0].parentNode; - const removeCells = [selectedCells[0]]; - - for (let i = 1, len = selectedCells.length, cell; i < len; i++) { - cell = selectedCells[i]; - if (row !== cell.parentNode) { - removeCells.push(cell); - row = cell.parentNode; - } - } - - for (let i = 0, len = removeCells.length; i < len; i++) { - tablePlugin.setCellInfo.call(this, removeCells[i], true); - tablePlugin.editRow.call(this, option); - } - } else { // edit row - tablePlugin.setCellInfo.call(this, option === 'up' ? selectedCells[0] : selectedCells[selectedCells.length - 1], true); - tablePlugin.editRow.call(this, option, positionCell); - } - } else { // multi - cell - const firstRow = selectedCells[0].parentNode; - // remove cell - if (!option) { - const removeCells = [selectedCells[0]]; - - for (let i = 1, len = selectedCells.length, cell; i < len; i++) { - cell = selectedCells[i]; - if (firstRow === cell.parentNode) { - removeCells.push(cell); - } else { - break; - } - } - - for (let i = 0, len = removeCells.length; i < len; i++) { - tablePlugin.setCellInfo.call(this, removeCells[i], true); - tablePlugin.editCell.call(this, option); - } - } else { // edit cell - let rightCell = null; - - for (let i = 0, len = selectedCells.length - 1; i < len; i++) { - if (firstRow !== selectedCells[i + 1].parentNode) { - rightCell = selectedCells[i]; - break; - } - } - - tablePlugin.setCellInfo.call(this, option === 'left' ? selectedCells[0] : rightCell || selectedCells[0], true); - tablePlugin.editCell.call(this, option, positionCell); - } - } - - if (!option) tablePlugin.init.call(this); - } // one - else { - tablePlugin[isRow ? 'editRow' : 'editCell'].call(this, option); - } - - // after remove - if (!option) { - const children = table.children; - for (let i = 0; i < children.length; i++) { - if (children[i].children.length === 0) { - this.util.removeItem(children[i]); - i--; - } - } - - if (table.children.length === 0) this.util.removeItem(table); - } - }, - - editRow: function (option, positionResetElement) { - const contextTable = this.context.table; - const remove = !option; - - const up = option === 'up'; - const originRowIndex = contextTable._rowIndex; - const rowIndex = remove || up ? originRowIndex : originRowIndex + contextTable._current_rowSpan + 1; - const sign = remove ? -1 : 1; - - const rows = contextTable._trElements; - let cellCnt = contextTable._logical_cellCnt; - - for (let i = 0, len = originRowIndex + (remove ? -1 : 0), cell; i <= len; i++) { - cell = rows[i].cells; - if (cell.length === 0) return; - - for (let c = 0, cLen = cell.length, rs, cs; c < cLen; c++) { - rs = cell[c].rowSpan; - cs = cell[c].colSpan; - if (rs < 2 && cs < 2) continue; - - if (rs + i > rowIndex && rowIndex > i) { - cell[c].rowSpan = rs + sign; - cellCnt -= cs; - } - } - } - - if (remove) { - const next = rows[originRowIndex + 1]; - if (next) { - const spanCells = []; - let cells = rows[originRowIndex].cells; - let colSpan = 0; - - for (let i = 0, len = cells.length, cell, logcalIndex; i < len; i++) { - cell = cells[i]; - logcalIndex = i + colSpan; - colSpan += cell.colSpan - 1; - - if (cell.rowSpan > 1) { - cell.rowSpan -= 1; - spanCells.push({cell: cell.cloneNode(false), index: logcalIndex}); - } - } - - if (spanCells.length > 0) { - let spanCell = spanCells.shift(); - cells = next.cells; - colSpan = 0; - - for (let i = 0, len = cells.length, cell, logcalIndex; i < len; i++) { - cell = cells[i]; - logcalIndex = i + colSpan; - colSpan += cell.colSpan - 1; - - if (logcalIndex >= spanCell.index) { - i--, colSpan--; - colSpan += spanCell.cell.colSpan - 1; - next.insertBefore(spanCell.cell, cell); - spanCell = spanCells.shift(); - if (!spanCell) break; - } - } - - if (spanCell) { - next.appendChild(spanCell.cell); - for (let i = 0, len = spanCells.length; i < len; i++) { - next.appendChild(spanCells[i].cell); - } - } - } - } - - contextTable._element.deleteRow(rowIndex); - } else { - const newRow = contextTable._element.insertRow(rowIndex); - newRow.innerHTML = this.plugins.table.createCells.call(this, 'td', cellCnt, false); - } - - if (!remove) { - this.plugins.table.setPositionControllerDiv.call(this, positionResetElement || contextTable._tdElement, true); - } else { - this.controllersOff(); - } - }, - - editCell: function (option, positionResetElement) { - const contextTable = this.context.table; - const util = this.util; - const remove = !option; - - const left = option === 'left'; - const colSpan = contextTable._current_colSpan; - const cellIndex = remove || left ? contextTable._logical_cellIndex : contextTable._logical_cellIndex + colSpan + 1; - - const rows = contextTable._trElements; - let rowSpanArr = []; - let spanIndex = []; - let passCell = 0; - const removeCell = []; - const removeSpanArr = []; - - for (let i = 0, len = contextTable._rowCnt, row, insertIndex, cells, newCell, applySpan, cellColSpan; i < len; i++) { - row = rows[i]; - insertIndex = cellIndex; - applySpan = false; - cells = row.cells; - cellColSpan = 0; - - for (let c = 0, cell, cLen = cells.length, rs, cs, removeIndex; c < cLen; c++) { - cell = cells[c]; - if (!cell) break; - - rs = cell.rowSpan - 1; - cs = cell.colSpan - 1; - - if (!remove) { - if (c >= insertIndex) break; - if (cs > 0) { - if (passCell < 1 && cs + c >= insertIndex) { - cell.colSpan += 1; - insertIndex = null; - passCell = rs + 1; - break; - } - - insertIndex -= cs; - } - - if (!applySpan) { - for (let r = 0, arr; r < spanIndex.length; r++) { - arr = spanIndex[r]; - insertIndex -= arr.cs; - arr.rs -= 1; - if (arr.rs < 1) { - spanIndex.splice(r, 1); - r--; - } - } - applySpan = true; - } - } else { - removeIndex = c + cellColSpan; - - if (spanIndex.length > 0) { - const lastCell = !cells[c + 1]; - for (let r = 0, arr; r < spanIndex.length; r++) { - arr = spanIndex[r]; - if (arr.row > i) continue; - - if (removeIndex >= arr.index) { - cellColSpan += arr.cs; - removeIndex = c + cellColSpan; - arr.rs -= 1; - arr.row = i + 1; - if (arr.rs < 1) { - spanIndex.splice(r, 1); - r--; - } - } else if (lastCell) { - arr.rs -= 1; - arr.row = i + 1; - if (arr.rs < 1) { - spanIndex.splice(r, 1); - r--; - } - } - } - } - - if (rs > 0) { - rowSpanArr.push({ - rs: rs, - cs: cs + 1, - index: removeIndex, - row: -1 - }); - } - - if (removeIndex >= insertIndex && removeIndex + cs <= insertIndex + colSpan) { - removeCell.push(cell); - } else if (removeIndex <= insertIndex + colSpan && removeIndex + cs >= insertIndex) { - cell.colSpan -= util.getOverlapRangeAtIndex(cellIndex, cellIndex + colSpan, removeIndex, removeIndex + cs); - } else if (rs > 0 && (removeIndex < insertIndex || removeIndex + cs > insertIndex + colSpan)) { - removeSpanArr.push({ - cell: cell, - i: i, - rs: i + rs - }); - } - - cellColSpan += cs; - } - } - - spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {return a.index - b.index;}); - rowSpanArr = []; - - if (!remove) { - if (passCell > 0) { - passCell -= 1; - continue; - } - - if (insertIndex !== null && cells.length > 0) { - newCell = this.plugins.table.createCells.call(this, cells[0].nodeName, 0, true); - newCell = row.insertBefore(newCell, cells[insertIndex]); - } - } - } - - if (remove) { - let removeFirst, removeEnd; - for (let r = 0, rLen = removeCell.length, row; r < rLen; r++) { - row = removeCell[r].parentNode; - util.removeItem(removeCell[r]); - if (row.cells.length === 0) { - if (!removeFirst) removeFirst = util.getArrayIndex(rows, row); - removeEnd = util.getArrayIndex(rows, row); - util.removeItem(row); - } - } - - for (let c = 0, cLen = removeSpanArr.length, rowSpanCell; c < cLen; c++) { - rowSpanCell = removeSpanArr[c]; - rowSpanCell.cell.rowSpan = util.getOverlapRangeAtIndex(removeFirst, removeEnd, rowSpanCell.i, rowSpanCell.rs); - } - - this.controllersOff(); - } else { - this.plugins.table.setPositionControllerDiv.call(this, positionResetElement || contextTable._tdElement, true); - } - }, - - _closeSplitMenu: null, - openSplitMenu: function () { - this.util.addClass(this.context.table.splitButton, 'on'); - this.context.table.splitMenu.style.display = 'inline-table'; - - this.plugins.table._closeSplitMenu = function () { - this.util.removeClass(this.context.table.splitButton, 'on'); - this.context.table.splitMenu.style.display = 'none'; - this.removeDocEvent('click', this.plugins.table._closeSplitMenu); - this.plugins.table._closeSplitMenu = null; - }.bind(this); - - this.addDocEvent('click', this.plugins.table._closeSplitMenu); - }, - - splitCells: function (direction) { - const util = this.util; - const vertical = direction === 'vertical'; - const contextTable = this.context.table; - const currentCell = contextTable._tdElement; - const rows = contextTable._trElements; - const currentRow = contextTable._trElement; - const index = contextTable._logical_cellIndex; - const rowIndex = contextTable._rowIndex; - const newCell = this.plugins.table.createCells.call(this, currentCell.nodeName, 0, true); - - // vertical - if (vertical) { - const currentColSpan = currentCell.colSpan; - newCell.rowSpan = currentCell.rowSpan; - - // colspan > 1 - if (currentColSpan > 1) { - newCell.colSpan = this._w.Math.floor(currentColSpan/2); - currentCell.colSpan = currentColSpan - newCell.colSpan; - currentRow.insertBefore(newCell, currentCell.nextElementSibling); - } else { // colspan - 1 - let rowSpanArr = []; - let spanIndex = []; - - for (let i = 0, len = contextTable._rowCnt, cells, colSpan; i < len; i++) { - cells = rows[i].cells; - colSpan = 0; - for (let c = 0, cLen = cells.length, cell, cs, rs, logcalIndex; c < cLen; c++) { - cell = cells[c]; - cs = cell.colSpan - 1; - rs = cell.rowSpan - 1; - logcalIndex = c + colSpan; - - if (spanIndex.length > 0) { - for (let r = 0, arr; r < spanIndex.length; r++) { - arr = spanIndex[r]; - if (arr.row > i) continue; - if (logcalIndex >= arr.index) { - colSpan += arr.cs; - logcalIndex += arr.cs; - arr.rs -= 1; - arr.row = i + 1; - if (arr.rs < 1) { - spanIndex.splice(r, 1); - r--; - } - } else if (c === cLen - 1) { - arr.rs -= 1; - arr.row = i + 1; - if (arr.rs < 1) { - spanIndex.splice(r, 1); - r--; - } - } - } - } - - if (logcalIndex <= index && rs > 0) { - rowSpanArr.push({ - index: logcalIndex, - cs: cs + 1, - rs: rs, - row: -1 - }); - } - - if (cell !== currentCell && logcalIndex <= index && logcalIndex + cs >= index + currentColSpan - 1) { - cell.colSpan += 1; - break; - } - - if (logcalIndex > index) break; - - colSpan += cs; - } - - spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {return a.index - b.index;}); - rowSpanArr = []; - } - - currentRow.insertBefore(newCell, currentCell.nextElementSibling); - } - } else { // horizontal - const currentRowSpan = currentCell.rowSpan; - newCell.colSpan = currentCell.colSpan; - - // rowspan > 1 - if (currentRowSpan > 1) { - newCell.rowSpan = this._w.Math.floor(currentRowSpan/2); - const newRowSpan = currentRowSpan - newCell.rowSpan; - - const rowSpanArr = []; - const nextRowIndex = util.getArrayIndex(rows, currentRow) + newRowSpan; - - for (let i = 0, cells, colSpan; i < nextRowIndex; i++) { - cells = rows[i].cells; - colSpan = 0; - for (let c = 0, cLen = cells.length, cell, cs, logcalIndex; c < cLen; c++) { - logcalIndex = c + colSpan; - if (logcalIndex >= index) break; - - cell = cells[c]; - cs = cell.rowSpan - 1; - if (cs > 0 && cs + i >= nextRowIndex && logcalIndex < index) { - rowSpanArr.push({ - index: logcalIndex, - cs: cell.colSpan - }); - } - colSpan += cell.colSpan - 1; - } - } - - const nextRow = rows[nextRowIndex]; - const nextCells = nextRow.cells; - let rs = rowSpanArr.shift(); - - for (let c = 0, cLen = nextCells.length, colSpan = 0, cell, cs, logcalIndex, insertIndex; c < cLen; c++) { - logcalIndex = c + colSpan; - cell = nextCells[c]; - cs = cell.colSpan - 1; - insertIndex = logcalIndex + cs + 1; - - if (rs && insertIndex >= rs.index) { - colSpan += rs.cs; - insertIndex += rs.cs; - rs = rowSpanArr.shift(); - } - - if (insertIndex >= index || c === cLen - 1) { - nextRow.insertBefore(newCell, cell.nextElementSibling); - break; - } - - colSpan += cs; - } - - currentCell.rowSpan = newRowSpan; - } else { // rowspan - 1 - newCell.rowSpan = currentCell.rowSpan; - const newRow = util.createElement('TR'); - newRow.appendChild(newCell); - - for (let i = 0, cells; i < rowIndex; i++) { - cells = rows[i].cells; - if (cells.length === 0) return; - - for (let c = 0, cLen = cells.length; c < cLen; c++) { - if (i + cells[c].rowSpan - 1 >= rowIndex) { - cells[c].rowSpan += 1; - } - } - } - - const physicalIndex = contextTable._physical_cellIndex; - const cells = currentRow.cells; - - for (let c = 0, cLen = cells.length; c < cLen; c++) { - if (c === physicalIndex) continue; - cells[c].rowSpan += 1; - } - - currentRow.parentNode.insertBefore(newRow, currentRow.nextElementSibling); - } - } - - this.focusEdge(currentCell); - this.plugins.table.setPositionControllerDiv.call(this, currentCell, true); - }, - - mergeCells: function () { - const tablePlugin = this.plugins.table; - const contextTable = this.context.table; - const util = this.util; - - const ref = tablePlugin._ref; - const selectedCells = tablePlugin._selectedCells; - const mergeCell = selectedCells[0]; - - let emptyRowFirst = null; - let emptyRowLast = null; - let cs = (ref.ce - ref.cs) + 1; - let rs = (ref.re - ref.rs) + 1; - let mergeHTML = ''; - let row = null; - - for (let i = 1, len = selectedCells.length, cell, ch; i < len; i++) { - cell = selectedCells[i]; - if (row !== cell.parentNode) row = cell.parentNode; - - ch = cell.children; - for (let c = 0, cLen = ch.length; c < cLen; c++) { - if (util.isFormatElement(ch[c]) && util.onlyZeroWidthSpace(ch[c].textContent)) { - util.removeItem(ch[c]); - } - } - - mergeHTML += cell.innerHTML; - util.removeItem(cell); - - if (row.cells.length === 0) { - if (!emptyRowFirst) emptyRowFirst = row; - else emptyRowLast = row; - rs -= 1; - } - } - - if (emptyRowFirst) { - const rows = contextTable._trElements; - const rowIndexFirst = util.getArrayIndex(rows, emptyRowFirst); - const rowIndexLast = util.getArrayIndex(rows, emptyRowLast || emptyRowFirst); - const removeRows = []; - - for (let i = 0, cells; i <= rowIndexLast; i++) { - cells = rows[i].cells; - if (cells.length === 0) { - removeRows.push(rows[i]); - continue; - } - - for (let c = 0, cLen = cells.length, cell, rs; c < cLen; c++) { - cell = cells[c]; - rs = cell.rowSpan - 1; - if (rs > 0 && i + rs >= rowIndexFirst) { - cell.rowSpan -= util.getOverlapRangeAtIndex(rowIndexFirst, rowIndexLast, i, i + rs); - } - } - } - - for (let i = 0, len = removeRows.length; i < len; i++) { - util.removeItem(removeRows[i]); - } - } - - mergeCell.innerHTML += mergeHTML; - mergeCell.colSpan = cs; - mergeCell.rowSpan = rs; - - this.controllersOff(); - tablePlugin.setActiveButton.call(this, true, false); - tablePlugin.call_controller_tableEdit.call(this, mergeCell); - - util.addClass(mergeCell, 'se-table-selected-cell'); - this.focusEdge(mergeCell); - }, - - toggleHeader: function () { - const util = this.util; - const headerButton = this.context.table.headerButton; - const active = util.hasClass(headerButton, 'active'); - const table = this.context.table._element; - - if (!active) { - const header = util.createElement('THEAD'); - header.innerHTML = '' + this.plugins.table.createCells.call(this, 'th', this.context.table._logical_cellCnt, false) + ''; - table.insertBefore(header, table.firstElementChild); - } else { - util.removeItem(table.querySelector('thead')); - } - - util.toggleClass(headerButton, 'active'); - - if (/TH/i.test(this.context.table._tdElement.nodeName)) { - this.controllersOff(); - } else { - this.plugins.table.setPositionControllerDiv.call(this, this.context.table._tdElement, false); - } - }, - - setTableStyle: function (styles) { - const contextTable = this.context.table; - const tableElement = contextTable._element; - let icon, span, sizeIcon, text; - - if (styles.indexOf('width') > -1) { - icon = contextTable.resizeButton.firstElementChild; - span = contextTable.resizeText; - - if (!contextTable._maxWidth) { - sizeIcon = contextTable.icons.expansion; - text = contextTable.maxText; - contextTable.columnFixedButton.style.display = 'none'; - this.util.removeClass(tableElement, 'se-table-size-100'); - this.util.addClass(tableElement, 'se-table-size-auto'); - } else { - sizeIcon = contextTable.icons.reduction; - text = contextTable.minText; - contextTable.columnFixedButton.style.display = 'block'; - this.util.removeClass(tableElement, 'se-table-size-auto'); - this.util.addClass(tableElement, 'se-table-size-100'); - } - - this.util.changeElement(icon, sizeIcon); - this.util.changeTxt(span, text); - } - - if (styles.indexOf('column') > -1) { - if (!contextTable._fixedColumn) { - this.util.removeClass(tableElement, 'se-table-layout-fixed'); - this.util.addClass(tableElement, 'se-table-layout-auto'); - this.util.removeClass(contextTable.columnFixedButton, 'active'); - } else { - this.util.removeClass(tableElement, 'se-table-layout-auto'); - this.util.addClass(tableElement, 'se-table-layout-fixed'); - this.util.addClass(contextTable.columnFixedButton, 'active'); - } - - } - }, - - setActiveButton: function (fixedCell, selectedCell) { - const contextTable = this.context.table; - - if (/^TH$/i.test(fixedCell.nodeName)) { - contextTable.insertRowAboveButton.setAttribute('disabled', true); - contextTable.insertRowBelowButton.setAttribute('disabled', true); - } else { - contextTable.insertRowAboveButton.removeAttribute('disabled'); - contextTable.insertRowBelowButton.removeAttribute('disabled'); - } - - if (!selectedCell || fixedCell === selectedCell) { - contextTable.splitButton.removeAttribute('disabled'); - contextTable.mergeButton.setAttribute('disabled', true); - } else { - contextTable.splitButton.setAttribute('disabled', true); - contextTable.mergeButton.removeAttribute('disabled'); - } - }, - - // multi selecte - _bindOnSelect: null, - _bindOffSelect: null, - _bindOffShift: null, - _selectedCells: null, - _shift: false, - _fixedCell: null, - _fixedCellName: null, - _selectedCell: null, - _selectedTable: null, - _ref: null, - _toggleEditor: function (enabled) { - this.context.element.wysiwyg.setAttribute('contenteditable', enabled); - if (enabled) this.util.removeClass(this.context.element.wysiwyg, 'se-disabled'); - else this.util.addClass(this.context.element.wysiwyg, 'se-disabled'); - }, - - _offCellMultiSelect: function (e) { - e.stopPropagation(); - const tablePlugin = this.plugins.table; - - if (!tablePlugin._shift) { - tablePlugin._removeEvents.call(this); - tablePlugin._toggleEditor.call(this, true); - } else if (tablePlugin._initBind) { - this._wd.removeEventListener('touchmove', tablePlugin._initBind); - tablePlugin._initBind = null; - } - - if (!tablePlugin._fixedCell || !tablePlugin._selectedTable) return; - - tablePlugin.setActiveButton.call(this, tablePlugin._fixedCell, tablePlugin._selectedCell); - tablePlugin.call_controller_tableEdit.call(this, tablePlugin._selectedCell || tablePlugin._fixedCell); - - tablePlugin._selectedCells = tablePlugin._selectedTable.querySelectorAll('.se-table-selected-cell'); - if (tablePlugin._selectedCell && tablePlugin._fixedCell) this.focusEdge(tablePlugin._selectedCell); - - if (!tablePlugin._shift) { - tablePlugin._fixedCell = null; - tablePlugin._selectedCell = null; - tablePlugin._fixedCellName = null; - } - }, - - _onCellMultiSelect: function (e) { - this._antiBlur = true; - const tablePlugin = this.plugins.table; - const target = this.util.getParentElement(e.target, this.util.isCell); - - if (tablePlugin._shift) { - if (target === tablePlugin._fixedCell) tablePlugin._toggleEditor.call(this, true); - else tablePlugin._toggleEditor.call(this, false); - } else if (!tablePlugin._ref) { - if (target === tablePlugin._fixedCell) return; - else tablePlugin._toggleEditor.call(this, false); - } - - if (!target || target === tablePlugin._selectedCell || tablePlugin._fixedCellName !== target.nodeName || - tablePlugin._selectedTable !== this.util.getParentElement(target, 'TABLE')) { - return; - } - - tablePlugin._selectedCell = target; - tablePlugin._setMultiCells.call(this, tablePlugin._fixedCell, target); - }, - - _setMultiCells: function (startCell, endCell) { - const tablePlugin = this.plugins.table; - const rows = tablePlugin._selectedTable.rows; - const util = this.util; - - const selectedCells = tablePlugin._selectedTable.querySelectorAll('.se-table-selected-cell'); - for (let i = 0, len = selectedCells.length; i < len; i++) { - util.removeClass(selectedCells[i], 'se-table-selected-cell'); - } - - if (startCell === endCell) { - util.addClass(startCell, 'se-table-selected-cell'); - if (!tablePlugin._shift) return; - } - - let findSelectedCell = true; - let spanIndex = []; - let rowSpanArr = []; - const ref = tablePlugin._ref = {_i: 0, cs: null, ce: null, rs: null, re: null}; - - for (let i = 0, len = rows.length, cells, colSpan; i < len; i++) { - cells = rows[i].cells; - colSpan = 0; - - for (let c = 0, cLen = cells.length, cell, logcalIndex, cs, rs; c < cLen; c++) { - cell = cells[c]; - cs = cell.colSpan - 1; - rs = cell.rowSpan - 1; - logcalIndex = c + colSpan; - - if (spanIndex.length > 0) { - for (let r = 0, arr; r < spanIndex.length; r++) { - arr = spanIndex[r]; - if (arr.row > i) continue; - if (logcalIndex >= arr.index) { - colSpan += arr.cs; - logcalIndex += arr.cs; - arr.rs -= 1; - arr.row = i + 1; - if (arr.rs < 1) { - spanIndex.splice(r, 1); - r--; - } - } else if (c === cLen - 1) { - arr.rs -= 1; - arr.row = i + 1; - if (arr.rs < 1) { - spanIndex.splice(r, 1); - r--; - } - } - } - } - - if (findSelectedCell) { - if (cell === startCell || cell === endCell) { - ref.cs = ref.cs !== null && ref.cs < logcalIndex ? ref.cs : logcalIndex; - ref.ce = ref.ce !== null && ref.ce > logcalIndex + cs ? ref.ce : logcalIndex + cs; - ref.rs = ref.rs !== null && ref.rs < i ? ref.rs : i; - ref.re = ref.re !== null && ref.re > i + rs ? ref.re : i + rs; - ref._i += 1; - } - - if (ref._i === 2) { - findSelectedCell = false; - spanIndex = []; - rowSpanArr = []; - i = -1; - break; - } - } else if (util.getOverlapRangeAtIndex(ref.cs, ref.ce, logcalIndex, logcalIndex + cs) && util.getOverlapRangeAtIndex(ref.rs, ref.re, i, i + rs)) { - const newCs = ref.cs < logcalIndex ? ref.cs : logcalIndex; - const newCe = ref.ce > logcalIndex + cs ? ref.ce : logcalIndex + cs; - const newRs = ref.rs < i ? ref.rs : i; - const newRe = ref.re > i + rs ? ref.re : i + rs; - - if (ref.cs !== newCs || ref.ce !== newCe || ref.rs !== newRs || ref.re !== newRe) { - ref.cs = newCs; - ref.ce = newCe; - ref.rs = newRs; - ref.re = newRe; - i = -1; - - spanIndex = []; - rowSpanArr = []; - break; - } - - util.addClass(cell, 'se-table-selected-cell'); - } - - if (rs > 0) { - rowSpanArr.push({ - index: logcalIndex, - cs: cs + 1, - rs: rs, - row: -1 - }); - } - - colSpan += cell.colSpan - 1; - } - - spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {return a.index - b.index;}); - rowSpanArr = []; - } - }, - - _removeEvents: function () { - const tablePlugin = this.plugins.table; - - if (tablePlugin._initBind) { - this._wd.removeEventListener('touchmove', tablePlugin._initBind); - tablePlugin._initBind = null; - } - - if (tablePlugin._bindOnSelect) { - this._wd.removeEventListener('mousedown', tablePlugin._bindOnSelect); - this._wd.removeEventListener('mousemove', tablePlugin._bindOnSelect); - tablePlugin._bindOnSelect = null; - } - - if (tablePlugin._bindOffSelect) { - this._wd.removeEventListener('mouseup', tablePlugin._bindOffSelect); - tablePlugin._bindOffSelect = null; - } - - if (tablePlugin._bindOffShift) { - this._wd.removeEventListener('keyup', tablePlugin._bindOffShift); - tablePlugin._bindOffShift = null; - } - }, - - _initBind: null, - onTableCellMultiSelect: function (tdElement, shift) { - const tablePlugin = this.plugins.table; - - tablePlugin._removeEvents.call(this); - this.controllersOff(); - - tablePlugin._shift = shift; - tablePlugin._fixedCell = tdElement; - tablePlugin._fixedCellName = tdElement.nodeName; - tablePlugin._selectedTable = this.util.getParentElement(tdElement, 'TABLE'); - - const selectedCells = tablePlugin._selectedTable.querySelectorAll('.se-table-selected-cell'); - for (let i = 0, len = selectedCells.length; i < len; i++) { - this.util.removeClass(selectedCells[i], 'se-table-selected-cell'); - } - - this.util.addClass(tdElement, 'se-table-selected-cell'); - - tablePlugin._bindOnSelect = tablePlugin._onCellMultiSelect.bind(this); - tablePlugin._bindOffSelect = tablePlugin._offCellMultiSelect.bind(this); - - if (!shift) { - this._wd.addEventListener('mousemove', tablePlugin._bindOnSelect, false); - } else { - tablePlugin._bindOffShift = function () { - this.controllersOn(this.context.table.resizeDiv, this.context.table.tableController, this.plugins.table.init.bind(this), tdElement, 'table'); - if (!tablePlugin._ref) this.controllersOff(); - }.bind(this); - - this._wd.addEventListener('keyup', tablePlugin._bindOffShift, false); - this._wd.addEventListener('mousedown', tablePlugin._bindOnSelect, false); - } - - this._wd.addEventListener('mouseup', tablePlugin._bindOffSelect, false); - tablePlugin._initBind = tablePlugin.init.bind(this); - this._wd.addEventListener('touchmove', tablePlugin._initBind, false); - }, - - onClick_tableController: function (e) { - e.stopPropagation(); - const target = e.target.getAttribute('data-command') ? e.target : e.target.parentNode; - - if (target.getAttribute('disabled')) return; - - const command = target.getAttribute('data-command'); - const value = target.getAttribute('data-value'); - const option = target.getAttribute('data-option'); - const tablePlugin = this.plugins.table; - - if (typeof tablePlugin._closeSplitMenu === 'function') { - tablePlugin._closeSplitMenu(); - if (command === 'onsplit') return; - } - - if (!command) return; - - e.preventDefault(); - const contextTable = this.context.table; - - switch (command) { - case 'insert': - case 'delete': - tablePlugin.editTable.call(this, value, option); - break; - case 'header': - tablePlugin.toggleHeader.call(this); - break; - case 'onsplit': - tablePlugin.openSplitMenu.call(this); - break; - case 'split': - tablePlugin.splitCells.call(this, value); - break; - case 'merge': - tablePlugin.mergeCells.call(this); - break; - case 'resize': - contextTable._maxWidth = !contextTable._maxWidth; - tablePlugin.setTableStyle.call(this, 'width'); - tablePlugin.setPositionControllerTop.call(this, contextTable._element); - tablePlugin.setPositionControllerDiv.call(this, contextTable._tdElement, tablePlugin._shift); - break; - case 'layout': - contextTable._fixedColumn = !contextTable._fixedColumn; - tablePlugin.setTableStyle.call(this, 'column'); - tablePlugin.setPositionControllerTop.call(this, contextTable._element); - tablePlugin.setPositionControllerDiv.call(this, contextTable._tdElement, tablePlugin._shift); - break; - case 'remove': - const emptyDiv = contextTable._element.parentNode; - this.util.removeItem(contextTable._element); - this.controllersOff(); - - if (emptyDiv !== this.context.element.wysiwyg) this.util.removeItemAllParents(emptyDiv, function (current) { return current.childNodes.length === 0; }, null); - this.focus(); - } - - // history stack - this.history.push(false); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/template.js": -/*!****************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/template.js ***! - \****************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'template', - display: 'submenu', - add: function (core, targetElement) { - const context = core.context; - context.template = {}; - - /** set submenu */ - let templateDiv = this.setSubmenu(core); - - /** add event listeners */ - templateDiv.querySelector('ul').addEventListener('click', this.pickup.bind(core)); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, templateDiv); - - /** empty memory */ - templateDiv = null; - }, - - setSubmenu: function (core) { - const templateList = core.options.templates; - if (!templateList || templateList.length === 0) { - throw Error('[SUNEDITOR.plugins.template.fail] To use the "template" plugin, please define the "templates" option.'); - } - - const listDiv = core.util.createElement('DIV'); - listDiv.className = 'se-list-layer'; - - let list = '
    ' + - '
      '; - for (let i = 0, len = templateList.length, t; i < len; i++) { - t = templateList[i]; - list += '
    • '; - } - list += '
    '; - - listDiv.innerHTML = list; - - return listDiv; - }, - - pickup: function (e) { - if (!/^BUTTON$/i.test(e.target.tagName)) return false; - - e.preventDefault(); - e.stopPropagation(); - - const temp = this.options.templates[e.target.getAttribute('data-value')]; - - if (temp.html) { - this.setContents(temp.html); - } else { - this.submenuOff(); - throw Error('[SUNEDITOR.template.fail] cause : "templates[i].html not found"'); - } - - this.submenuOff(); - } -}); - -/***/ }), - -/***/ "./node_modules/suneditor/src/plugins/submenu/textStyle.js": -/*!*****************************************************************!*\ - !*** ./node_modules/suneditor/src/plugins/submenu/textStyle.js ***! - \*****************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - -/* harmony default export */ __webpack_exports__["default"] = ({ - name: 'textStyle', - display: 'submenu', - add: function (core, targetElement) { - const context = core.context; - context.textStyle = { - _styleList: null - }; - - /** set submenu */ - let listDiv = this.setSubmenu(core); - let listUl = listDiv.querySelector('ul'); - - /** add event listeners */ - listUl.addEventListener('click', this.pickup.bind(core)); - - context.textStyle._styleList = listDiv.querySelectorAll('li button'); - - /** append target button menu */ - core.initMenuTarget(this.name, targetElement, listDiv); - - /** empty memory */ - listDiv = null, listUl = null; - }, - - setSubmenu: function (core) { - const option = core.options; - const listDiv = core.util.createElement('DIV'); - listDiv.className = 'se-submenu se-list-layer se-list-format'; - - const defaultList = { - code: { - name: core.lang.menu.code, - class: '__se__t-code', - tag: 'code', - }, - translucent: { - name: core.lang.menu.translucent, - style: 'opacity: 0.5;', - tag: 'span', - }, - shadow: { - name: core.lang.menu.shadow, - class: '__se__t-shadow', - tag: 'span', - } - }; - const styleList = !option.textStyles ? core._w.Object.keys(defaultList) : option.textStyles; - - let list = '
      '; - for (let i = 0, len = styleList.length, t, tag, name, attrs, command, value, _class; i < len; i++) { - t = styleList[i]; - attrs = '', value = '', command = []; - - if (typeof t === 'string') { - const defaultStyle = defaultList[t.toLowerCase()]; - if (!defaultStyle) continue; - t = defaultStyle; - } - - name = t.name; - tag = t.tag || 'span'; - _class = t._class; - - if (t.style) { - attrs += ' style="' + t.style + '"'; - value += t.style.replace(/:[^;]+(;|$)\s*/g, ','); - command.push('style'); - } - if (t.class) { - attrs += ' class="' + t.class + '"'; - value += '.' + t.class.trim().replace(/\s+/g, ',.'); - command.push('class'); - } - - value = value.replace(/,$/, ''); - - list += '
    • ' + - '
    • '; - } - list += '
    '; - - listDiv.innerHTML = list; - - return listDiv; - }, - - /** - * @Override submenu - */ - on: function () { - const util = this.util; - const textStyleContext = this.context.textStyle; - const styleButtonList = textStyleContext._styleList; - const selectionNode = this.getSelectionNode(); - - for (let i = 0, len = styleButtonList.length, btn, data, active; i < len; i++) { - btn = styleButtonList[i]; - data = btn.getAttribute('data-value').split(','); - - for (let v = 0, node, value; v < data.length; v++) { - node = selectionNode; - active = false; - - while (node && !util.isFormatElement(node) && !util.isComponent(node)) { - if (node.nodeName.toLowerCase() === btn.getAttribute('data-command').toLowerCase()) { - value = data[v]; - if (/^\./.test(value) ? util.hasClass(node, value.replace(/^\./, '')) : !!node.style[value]) { - active = true; - break; - } - } - node = node.parentNode; - } - - if (!active) break; - } - - active ? util.addClass(btn, 'active') : util.removeClass(btn, 'active'); - } - - }, - - pickup: function (e) { - e.preventDefault(); - e.stopPropagation(); - - let target = e.target; - let command = null, tag = null; - - while (!command && !/UL/i.test(target.tagName)) { - command = target.getAttribute('data-command'); - if (command) { - tag = target.firstChild; - break; - } - target = target.parentNode; - } - - if (!command) return; - - const checkStyles = tag.style.cssText.replace(/:.+(;|$)/g, ',').split(','); - checkStyles.pop(); - - const classes = tag.classList; - for (let i = 0, len = classes.length; i < len; i++) { - checkStyles.push('.' + classes[i]); - } - - const newNode = this.util.hasClass(target, 'active') ? null : tag.cloneNode(false); - const removeNodes = newNode ? null : [tag.nodeName]; - this.nodeChange(newNode, checkStyles, removeNodes, true); - - this.submenuOff(); - } -}); - - -/***/ }), - -/***/ "./node_modules/suneditor/src/suneditor.js": -/*!*************************************************!*\ - !*** ./node_modules/suneditor/src/suneditor.js ***! - \*************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _lib_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib/core */ "./node_modules/suneditor/src/lib/core.js"); -/* harmony import */ var _lib_util__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lib/util */ "./node_modules/suneditor/src/lib/util.js"); -/* harmony import */ var _lib_constructor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lib/constructor */ "./node_modules/suneditor/src/lib/constructor.js"); -/* harmony import */ var _lib_context__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lib/context */ "./node_modules/suneditor/src/lib/context.js"); -/* - * wysiwyg web editor - * - * suneditor.js - * Copyright 2017 JiHong Lee. - * MIT license. - */ - - - - - - - -/* harmony default export */ __webpack_exports__["default"] = ({ - /** - * @description Returns the create function with preset options. - * If the options overlap, the options of the 'create' function take precedence. - * @param {Json} options Initialization options - * @returns {Object} - */ - init: function (init_options) { - return { - create: function (idOrElement, options) { - return this.create(idOrElement, options, init_options); - }.bind(this) - }; - }, - - /** - * @description Create the suneditor - * @param {String|Element} idOrElement textarea Id or textarea element - * @param {JSON|Object} options user options - * @returns {Object} - */ - create: function (idOrElement, options, _init_options) { - _lib_util__WEBPACK_IMPORTED_MODULE_1__["default"]._propertiesInit(); - - if (typeof options !== 'object') options = {}; - if (_init_options) { - options = [_init_options, options].reduce(function (init, option) { - for (let key in option) { - if (!_lib_util__WEBPACK_IMPORTED_MODULE_1__["default"].hasOwn(option, key)) continue; - if (key === 'plugins' && option[key] && init[key]) { - let i = init[key], o = option[key]; - i = i.length ? i : Object.keys(i).map(function(name) { return i[name]; }); - o = o.length ? o : Object.keys(o).map(function(name) { return o[name]; }); - init[key] = (o.filter(function(val) { return i.indexOf(val) === -1; })).concat(i); - } else { - init[key] = option[key]; - } - } - return init; - }, {}); - } - - const element = typeof idOrElement === 'string' ? document.getElementById(idOrElement) : idOrElement; - - if (!element) { - if (typeof idOrElement === 'string') { - throw Error('[SUNEDITOR.create.fail] The element for that id was not found (ID:"' + idOrElement + '")'); - } - - throw Error('[SUNEDITOR.create.fail] suneditor requires textarea\'s element or id value'); - } - - const cons = _lib_constructor__WEBPACK_IMPORTED_MODULE_2__["default"].init(element, options); - - if (cons.constructed._top.id && document.getElementById(cons.constructed._top.id)) { - throw Error('[SUNEDITOR.create.fail] The ID of the suneditor you are trying to create already exists (ID:"' + cons.constructed._top.id + '")'); - } - - return Object(_lib_core__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_lib_context__WEBPACK_IMPORTED_MODULE_3__["default"])(element, cons.constructed, cons.options), cons.pluginCallButtons, cons.plugins, cons.options.lang, options, cons._responsiveButtons); - } -}); - - /***/ }), /***/ "./node_modules/webpack/buildin/global.js": @@ -59427,8 +37948,6 @@ module.exports = function(module) { */ __webpack_require__(/*! ./bootstrap */ "./resources/js/bootstrap.js"); -__webpack_require__(/*! ./suneditor */ "./resources/js/suneditor.js"); - /***/ }), /***/ "./resources/js/bootstrap.js": @@ -59478,36 +37997,6 @@ window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; /***/ }), -/***/ "./resources/js/suneditor.js": -/*!***********************************!*\ - !*** ./resources/js/suneditor.js ***! - \***********************************/ -/*! no exports provided */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var suneditor_dist_css_suneditor_min_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! suneditor/dist/css/suneditor.min.css */ "./node_modules/suneditor/dist/css/suneditor.min.css"); -/* harmony import */ var suneditor_dist_css_suneditor_min_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(suneditor_dist_css_suneditor_min_css__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var suneditor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! suneditor */ "./node_modules/suneditor/src/suneditor.js"); -/* harmony import */ var suneditor_src_plugins__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! suneditor/src/plugins */ "./node_modules/suneditor/src/plugins/index.js"); - - - -suneditor__WEBPACK_IMPORTED_MODULE_1__["default"].create('sample', { - plugins: suneditor_src_plugins__WEBPACK_IMPORTED_MODULE_2__["default"], - buttonList: [['undo', 'redo'], ['font', 'fontSize', 'formatBlock'], ['paragraphStyle', 'blockquote'], ['bold', 'underline', 'italic', 'strike', 'subscript', 'superscript'], ['fontColor', 'hiliteColor', 'textStyle'], ['removeFormat'], '/', // Line break - ['outdent', 'indent'], ['align', 'horizontalRule', 'list', 'lineHeight'], ['table', 'link', 'image', 'video', 'audio' - /** ,'math' */ - ], // You must add the 'katex' library at options to use the 'math' plugin. - - /** ['imageGallery'] */ - // You must add the "imageGalleryUrl". - ['fullScreen', 'showBlocks', 'codeView'], ['preview', 'print'], ['save', 'template']] -}); - -/***/ }), - /***/ "./resources/sass/app.scss": /*!*********************************!*\ !*** ./resources/sass/app.scss ***! diff --git a/motorradig/resources/js/app.js b/motorradig/resources/js/app.js index 7380882..9c481b4 100644 --- a/motorradig/resources/js/app.js +++ b/motorradig/resources/js/app.js @@ -5,4 +5,3 @@ */ require('./bootstrap'); -require('./suneditor'); diff --git a/motorradig/resources/js/bootstrap.js b/motorradig/resources/js/bootstrap.js index d4738d9..4688344 100644 --- a/motorradig/resources/js/bootstrap.js +++ b/motorradig/resources/js/bootstrap.js @@ -40,3 +40,4 @@ window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; // cluster: process.env.MIX_PUSHER_APP_CLUSTER, // forceTLS: true // }); + diff --git a/motorradig/resources/js/suneditor.js b/motorradig/resources/js/suneditor.js deleted file mode 100644 index ed9fbc9..0000000 --- a/motorradig/resources/js/suneditor.js +++ /dev/null @@ -1,25 +0,0 @@ -import 'suneditor/dist/css/suneditor.min.css' -import suneditor from 'suneditor' -import plugins from 'suneditor/src/plugins' - -suneditor.create('sample', { - plugins: plugins, - buttonList: [ - ['undo', 'redo'], - ['font', 'fontSize', 'formatBlock'], - ['paragraphStyle', 'blockquote'], - ['bold', 'underline', 'italic', 'strike', 'subscript', 'superscript'], - ['fontColor', 'hiliteColor', 'textStyle'], - ['removeFormat'], - '/', // Line break - ['outdent', 'indent'], - ['align', 'horizontalRule', 'list', 'lineHeight'], - ['table', 'link', 'image', 'video', 'audio' /** ,'math' */], // You must add the 'katex' library at options to use the 'math' plugin. - /** ['imageGallery'] */ // You must add the "imageGalleryUrl". - ['fullScreen', 'showBlocks', 'codeView'], - ['preview', 'print'], - ['save', 'template'] - ] -}) - - diff --git a/motorradig/resources/views/admin/edit_home.blade.php b/motorradig/resources/views/admin/edit_home.blade.php index 170fa9c..4925851 100644 --- a/motorradig/resources/views/admin/edit_home.blade.php +++ b/motorradig/resources/views/admin/edit_home.blade.php @@ -11,7 +11,7 @@
    @csrf @@ -20,8 +20,8 @@ {{-- --}} - @@ -39,12 +39,19 @@ + + + + + +