PageSourceSearch

https://c-on.co.kr/weven_service/asset/js/bm2/manager/ToolManager.js

js c-on.co.kr collected 2026-10-05 22:22:50 UTC 38,637 bytes, 1,026 lines download raw bytes

1/**
2 * created by WEVEN on 2020-03-02
3 * 아래의 소스는 WEVEN에 저작권이 있으므로 무단 사용 및 재 배포를 금합니다.
4 */
5// event type
6var ToolButtonEvent = {
7    CLICK : "ToolBtnClick",
8    KEY_UP : "ToolBtnKeyUp",
9    OP_CLICK : "ToolBtnOpClick",
10    OP_KEYUP : "ToolBtnOpKeyUp",
11    OP_MOUSEUP : "ToolBtnOpMouseup",
12    OP_MOUSEDOWN : "ToolBtnOpMousedown",
13    OP_MOUSEMOVE : "ToolBtnOpMousemove"
14}
15
16bm.toolManager = {
17
18    name : 'ToolManager'
19    ,configList : ['WVBoardConfig', 'WVCalendarConfig', 'WVQnaConfig', 'WVShopConfig']
20    ,toolList : []
21    ,showToolList : []
22    ,extraToolList : []
23    ,targetElement : null
24    ,targetElementList : []
25    ,focusToolBtnType : ""
26    ,isEventRegistered : false
27    ,isMultiSelectMode : false
28    ,isTabActiveStyle : false
29    ,isMenuTarget : false
30    ,isShopListTarget : false
31
32    ,menuEditableToolList : ["ToolBtnTextFont","ToolBtnTextSize","ToolBtnTextBold","ToolBtnTextColor","ToolBtnTextDecoration","ToolBtnTextLetterSpacing","ToolBtnTextLineHeight","ToolBtnDomSpace","ToolBtnDomAlignHorizontalDefault","ToolBtnDomBackgroundColor", "ToolBtnHeaderFooterSetting"]
33    ,shopListEditableToolList : ["ToolBtnTextHistory", "ToolBtnDomSpace", "autoWidth", "fullWidth", "ToolBtnDomWidth", "ToolBtnDomHeight", "ToolBtnDomAlignHorizontalDefault", "left", "none", "right", "ToolBtnDomBackgroundBorder", "ToolBtnDomBackgroundColor",
34                                "ToolBtnDomBoxShadow", "ToolBtnSwiperAuto"]
35    ,spaceBlockEditableToolList : ["ToolBtnHistory", "ToolBtnTextHistory", "ToolBtnHeaderFooterSetting"]
36
37    ,selectedClass : "edit_target_block"
38    ,selectedAreaClass : "edit_target_block_area"
39
40    ,activeStatus : 0
41
42    ,onToolEditBefore : null
43    ,onToolEditAfter : null
44
45    ,iframeWindow : null
46
47    ,frameOutToolList : {
48        normal: ['ToolInsta'], 
49        expert: ['ToolInsta', 'ToolThumb', 'ToolSwiper', 'ToolSvg','ToolTable','ToolLine', 'ToolVideo', 'ToolMap', 'ToolImage']
50    }
51    ,noPrependToolList : {
52        normal: [], 
53        expert: ['ToolThumb', 'ToolSwiper']
54    }
55
56    , getIframeWindow: function () {
57        if (this.iframeWindow) return this.iframeWindow;
58        else {
59            if ($("#WEVEN_IFRAME").length > 0) {
60                this.iframeWindow = $("#WEVEN_IFRAME")[0].contentWindow;
61                return this.iframeWindow;
62            }
63            return null;
64        }
65    }
66
67    ,init : function(){
68
69        var _this = this;
70        var toolType, resetMsg;
71
72        //ToolList 등록
73        let registTool = (toolset) => {
74            $(toolset).each( function(){
75                toolType = $(this).attr( "data-wv-toolset" );
76                resetMsg = $(this).attr( "data-wv-reset-msg" );
77                if( window[ toolType ] ){
78                    toolset = new window[ toolType ]();
79                    if( !toolset ){
80                    }
81                    toolset.init( toolType, this, null, null, resetMsg );
82
83                    _this.addToolSet( toolType, toolset );
84
85                }
86            });
87        }
88
89        //툴바
90        if(window.toolMode === 'side') {
91            registTool("#contentTool [data-wv-toolset]");
92        }else {
93            registTool("#defaultToolSetCon [data-wv-toolset]");
94            registTool("#effectToolSetCon [data-wv-toolset]");
95            registTool("#contentTool [data-wv-toolset]");
96        }
97        
98        //탑메뉴
99        registTool('#admin_top_toolbar.board' + " [data-wv-toolset]");
100
101        if(window.toolMode === 'side') {
102            this.toolSide = $('#contentTool');
103            this.targetToolProp = this.toolSide.find('#targetToolProp');
104            this.targetElementType = {text: '텍스트', image: '이미지', line: '선'};
105            this.makeToolSet( "ToolSvg" );
106            this.makeToolSet( "ToolVideo" );
107            // this.makeToolSet( "ToolLine" );
108            // this.makeToolSet( "ToolImage" );
109        }else {
110            this.makeToolSet( "ToolImage" );
111            this.makeToolSet( "ToolThumb" );
112            this.makeToolSet( "ToolSwiper" );
113            this.makeToolSet( "ToolTab" );
114            this.makeToolSet( "ToolInsta" );
115            this.makeToolSet( "ToolSvg" );
116            this.makeToolSet( "ToolTable" );
117            this.makeToolSet( "ToolLine" );
118            this.makeToolSet( "ToolVideo" );
119            this.makeToolSet( "ToolMap" );
120            if(window.toolMode === 'design') {
121                this.makeToolSet( "ToolText" );
122            }
123            if(isStudio) {
124                this.makeToolSet( "ToolLabel" );
125            }
126            editorProgress.check(this.name);
127        }
128    }
129
130    /**
131     * 툴셋을 관리 리스트에 추가할 경우 호출되는 함수
132     * @param toolType
133     */
134    ,addToolSet : function (toolType, toolset) {
135        this.toolList[ toolType ] = toolset;
136        this.toolList.push( toolset );
137    }
138
139    /**
140     * 기본 툴이 아닌 액션 블럭등 외부에서 등록하는 툴셋
141     * @param toolType
142     */
143    ,makeToolSet : function ( toolType ) {
144        var toolset = this.getTool( toolType );
145
146        if( !toolset ){
147            if( !window[ toolType ] ){
148                console.warn( "등록된 Tool Type 객체가 없습니다 : " + toolType );
149                return;
150            }
151
152            toolset = new window[ toolType ]();
153            var element = $("[data-wv-toolset="+toolType+"]")[0];
154            toolset.init( toolType, element );
155            this.addToolSet( toolType, toolset );
156
157
158
159            var $document;
160
161            //툴셋위치 분기
162            const isFrameOutTool = (toolType) => {
163                let key;
164
165                try{
166                    isExpertMode === true ? key = 'expert' : key = 'normal';
167                }catch(error) {
168                    key = 'expert';
169                    console.warn(error);
170                }
171
172                if(this['frameOutToolList'][key].indexOf(toolType) > -1) {
173                    return true;
174                }else {
175                    return false;
176                }
177            }
178
179            if (this.getIframeWindow() && isFrameOutTool(toolType)) {
180                $document = $(document);
181                toolset.elementFrameOut = true;
182            } else {
183                $document = $("#WEVEN_IFRAME").contents();
184                toolset.elementFrameOut = false;
185            }
186
187            //뗏다붙이기 제어
188            const noPrependToolListSet = (toolType) => {
189                let key;
190
191                try{
192                    isExpertMode === true ? key = 'expert' : key = 'normal';
193                }catch(error) {
194                    key = 'expert';
195                }
196
197                if(this['noPrependToolList'][key].indexOf(toolType) > -1) {
198                    return true;
199                }else {
200                    return false;
201                }
202            }
203
204            if(!noPrependToolListSet(toolType)) {
205                $document.find("body").prepend(element);
206            }
207
208            this.extraToolList.push( toolset );
209        }
210
211        return toolset;
212    }
213
214    ,getTool : function ( type ) {
215        return this.toolList[ type ];
216    }
217
218    ,reset : function(){
219        this.deactive();
220        this.active();
221    }
222
223    ,active : function(){
224        //이미 전체적액티브체크상태면 패스
225        if (this.activeStatus == 1) return;
226        this.activeStatus = 1;
227
228        //모조리 미리 액티브시켜서 이벤트를 활성화시킨다 => 블록이 선택되지 않은 경우 등 => 추이를 본 후 아래 모드분기처리를 리팩토링한다
229        var len = this.toolList.length;
230        for (var i = 0; i < len; i++) {
231            var tool = this.toolList[i];
232
233            if (tool.status == 0) {
234                tool.active(null, null, window.toolMode);
235            } else {
236                console.warn('이미 액티브 되어있음');
237            }
238        }
239
240        if (window.toolMode !== 'side' && window.toolMode !== 'design') {
241            // 에디터 전문가모드만
242            // this.toolList["ToolText"].toolBtnList["ToolBtnTextHistory"].active(); // 히스토리 버튼만 미리 액티브
243        } else {
244            // this.toolList["ToolHistory"].toolBtnList["ToolBtnHistory"].active(); // 히스토리 버튼만 미리 액티브
245
246            if (window.toolMode === 'design') this.toolList["ToolHeaderFooterSetting"].toolBtnList["ToolBtnHeaderFooterSetting"].active();
247        }
248
249        var $document, win;
250        if ( this.getIframeWindow() ){
251            $document = $("#WEVEN_IFRAME").contents();
252            win = this.getIframeWindow();
253        }else{
254            $document = $(document);
255            win = window;
256        }
257
258        var textBlock = $document.find(".wveditor_text");
259        textBlock = textBlock.filter(function (idx, selector) {
260            return $(selector).parent("[data-wv-menu-depth]").length === 0;
261        });
262        // if( textBlock.length > 0 ){
263        //     textBlock.attr( 'contentEditable', "true" ).attr('spellcheck', "true" );
264        // }
265
266        bm.selectionManager.active( win );
267
268        this.registEvent();
269    }
270
271    /**
272     *
273     * @param isTempDeactive : 히스토리 컨트롤 등 임시로 deactive -> active 할 경우 true 로 전달함.
274     */
275    ,deactive : function( isTempDeactive ){
276        if( this.activeStatus == 0 ) return;
277        this.activeStatus = 0;
278
279
280        var $document;
281        if( $("#WEVEN_IFRAME").length > 0 ){
282            $document = $("#WEVEN_IFRAME").contents();
283        }else{
284            $document = $(document);
285        }
286
287        var textBlock = $document.find(".wveditor_text");
288        if( textBlock.length > 0 ){
289            textBlock.attr( 'contentEditable', "false" ).attr('spellcheck', "false" );
290            textBlock.find('[contentEditable]').attr( 'contentEditable', "false" ).attr( 'spellcheck', "false" ); // 블럭 안에 테이블
291        }
292
293        this.hideExtraTool();
294        bm.selectionManager.deactive();
295
296        var len = this.toolList.length;
297        var tool;
298        for( var i=0; i<len; i++ ){
299            tool = this.toolList[i];
300            tool.deactive( isTempDeactive );
301        }
302
303        this.showToolList.length = 0;
304        this.removeImageChangeHandler( this.targetElement );
305
306        if( this.isMultiSelectMode ){
307            this.removeTargetElementMulti();
308        }else{
309            this.removeTargetElementSingle( this.targetElement );
310        }
311
312        this.removeEvent();
313    }
314
315    /**
316     *
317     * @param isTempDeactive : 히스토리 컨트롤 등 임시로 deactive -> active 할 경우 true 로 전달함.
318     */
319    ,extraToolHide : function(){
320        this.hideExtraTool();
321    }
322
323    , onBodyClick: function (e) {
324        const _this = bm.toolManager;
325        const target = $(e.target);
326        _this.setFocusToolBtn("");
327
328        if (window.toolMode === 'side') {
329            if (target.closest('[data-wv-design-area]').length === 0
330                && target.closest('#contentTool').length === 0
331                && target.closest('#wvSizeControlCon').length === 0 && target.closest('.layoutControlBtn ').length === 0) {
332                _this.toolSide.hide();
333            } else {
334                _this.toolSide.show();
335            }
336        }
337        events(_this).dispatch("onBodyClick", { e: e });
338    }
339
340    ,onKeyDown : function (e) {
341        if( e.keyCode == 27 ){
342            bm.toolManager.hideAllToolBtnOption();
343        }
344    }
345
346    , registEvent: function () {
347        if (this.isEventRegistered) return;
348        this.isEventRegistered = true;
349
350        const ifw = this.getIframeWindow();
351
352        window.addEventListener("click", this.onBodyClick);
353        window.addEventListener("keydown", this.onKeyDown);
354        if (ifw) {
355            ifw.addEventListener("click", this.onBodyClick);
356            ifw.addEventListener("keydown", this.onKeyDown);
357        }
358    }
359
360    , removeEvent: function (isTemp) {
361        if (this.isEventRegistered == false) return;
362        this.isEventRegistered = false;
363
364        const ifw = this.getIframeWindow();
365
366        window.removeEventListener("click", this.onBodyClick);
367        window.removeEventListener("keydown", this.onKeyDown);
368        if (ifw) {
369            ifw.removeEventListener("click", this.onBodyClick);
370            ifw.removeEventListener("keydown", this.onKeyDown);
371        }
372    }
373
374    ,quickEdit : function (data) {
375        var toolType = data.type;
376        var value = data.value;
377        var tool = this.getTool( toolType );
378        tool.quickEdit( value );
379    }
380
381    
382    ,toolBtnEditBefore : function (toolBtn, targetElement, historyType, data) {
383        if( this.onToolEditBefore ) this.onToolEditBefore( toolBtn, targetElement, historyType, data );
384    }
385
386    ,toolBtnEditAfter : function (toolBtn, targetElement, historyType, data ) {
387        if( this.onToolEditAfter ) this.onToolEditAfter( toolBtn, targetElement, historyType, data );
388    }
389
390    ,onToolPrevHistory : function() {
391        events( this ).dispatch( "historyUndo" );
392    }
393
394    ,onToolNextHistory : function() {
395        events( this ).dispatch( "historyRedo" );
396    }
397
398    ,onChangeGridMaxWidth : function( width ) {
399        events( this ).dispatch( "changeGridMaxWidth", {width: width} );
400    }
401
402    ,repositionToolSet : function () {
403
404        var len = this.toolList.length;
405        var tool;
406        for( var i=0; i<len; i++ ){
407            tool = this.toolList[i];
408            tool.reposition();
409        }
410    }
411
412    ,repositionExtraToolSet : function () {
413
414        var len = this.extraToolList.length;
415        var tool;
416        for( var i=0; i<len; i++ ){
417            tool = this.extraToolList[i];
418            if( !$(tool.element).hasClass('setting_wrap') ) tool.reposition();
419        }
420    }
421
422
423    // 툴 안의 버튼 활성화 여부
424    ,setFocusToolBtn : function( type ){
425        this.focusToolBtnType = type;
426        this.hideAllToolBtnOption( type );
427    }
428
429    ,hideAllTool : function () {
430
431        bm.each( this.toolList, function( key, tool ){
432            tool.hide();
433        } );
434
435        this.toolList.length = 0;
436    }
437
438    , hideExtraTool: function () {
439        this.extraToolList.forEach(tool => {
440            //아이프레임 바깥쪽에 붙는 사이드형 메뉴는 숨김처리 하지 않음
441            if (tool.elementFrameOut == true) {
442                tool.closeConfig ? tool.closeConfig() : null;
443            } else {
444                tool.hide();
445            }
446        })
447    }
448
449    ,hideAllToolBtnOption : function( excludeType ){
450
451        bm.each( this.toolList, function( key, tool ){
452            tool.hideOptionAll( excludeType );
453        } );
454    }
455
456    ,showExtraToolByTarget : function(targetElement){
457        var tool;
458        var targetElementBlockInner = $(targetElement).find(" > [data-wv-layout-element=block_inner]" );
459        var editTypeList = ["wveditor_table", "wveditor_svg", "wveditor_line", "wveditor_image", "wveditor_thumb", "wveditor_recentboard", "wveditor_video" ];
460        var i, type, currentType;
461        var toollen = editTypeList.length;
462
463        for (i = 0; i < toollen; i++) {
464            type = editTypeList[i];
465            if( $(targetElement).hasClass(type) || $(targetElementBlockInner).hasClass(type) ){
466                currentType = type;
467                break;
468            }
469        }
470
471        switch(currentType){
472            case 'wveditor_table':
473                tool = this.toolList['ToolTable'];
474                tool.show();
475                tool.reposition();
476                break;
477            case 'wveditor_svg':
478                tool = this.toolList['ToolSvg'];
479                tool.show();
480                tool.reposition();
481                break;
482            case 'wveditor_line':
483                tool = this.toolList['ToolLine'];
484                tool.show();
485                tool.reposition();
486                break;
487            case 'wveditor_image':
488                tool = this.toolList['ToolImage'];
489                if(tool) {
490                    tool.show();
491                    tool.reposition();
492                }
493                break;
494            case 'wveditor_thumb':
495                tool = this.toolList['ToolThumb', 'ToolSwiper'];
496                tool.show();
497                tool.reposition();
498                break;
499            case 'wveditor_video':
500                tool = this.toolList['ToolVideo'];
501                tool.show();
502                tool.reposition();
503                break;
504            case 'wveditor_map':
505                tool = this.toolList['ToolMap'];
506                tool.show();
507                tool.reposition();
508                break;
509        }
510    }
511
512    /**
513     * 외부에서 컨텐츠 선택 모드를 멀티인지 아닌지 입력해주는 함수.
514     * @param mode
515     * @param add 기존단일블록 유지
516     */
517    ,setModeChange : function( mode , add=true ){
518
519        if( mode == "multi" ){
520            this.isMultiSelectMode = true;
521
522            if( this.targetElement && this.targetElementList.length == 0 ){
523                if(add) {
524                    this.targetElementList.push( this.targetElement );
525                }
526                this.targetElement = null;
527            }
528        }else{
529            this.isMultiSelectMode = false;
530            if( this.targetElementList && this.targetElementList.length > 0 ){
531                this.removeTargetElementMulti();
532            }
533        }
534    }
535
536    ,setIsMenuTarget : function ( target ) {
537        var _this = this;
538        if(!target || target.length === 0) return;
539
540        var menuResId;
541        if(target.length > 1) {
542            _this.isMenuTarget = true;
543            target.forEach(function (el) {
544                if($(el).closest('[data-wv-layout-element="menu"]').length === 0) {
545                    _this.isMenuTarget = false;
546                    return false;
547                } else {
548                    if(!menuResId) menuResId = $(el).closest('[data-wv-gnb]').attr('data-wv-res-id');
549                    if(menuResId !== $(el).closest('[data-wv-gnb]').attr('data-wv-res-id')) {   // 서로 다른 data-wv-gnb의 메뉴 요소를 선택했을 때
550                        _this.isMenuTarget = false;
551                        return false;
552                    }
553                }
554            });
555        } else {
556            _this.isMenuTarget = $(target).closest('[data-wv-layout-element="menu"]').length > 0;
557        }
558
559        if(_this.isMenuTarget) {
560            _this.menuTargetSelector = '[data-wv-res-id="' + $(target).closest('[data-wv-gnb]').attr('data-wv-res-id') + '"] ' + $(target)[0].nodeName.toLowerCase() + '[data-wv-menu-depth="' + $(target).attr('data-wv-menu-depth') + '"]';
561        } else {
562            _this.menuTargetSelector = "";
563        }
564    }
565
566    ,setIsShopListTarget : function ( target ) {
567        var _this = this;
568        if(!target || target.length === 0) return;
569
570        if($(target).attr('data-wv-layout-element-type') === 'shop_list') {
571            _this.isShopListTarget = true;
572        }else{
573            _this.isShopListTarget = false;
574        }
575    }
576
577    ,kitReposition : function () {
578        events(this).dispatch( "kitReposition" );
579    }
580
581    ,resetHitTestBlock: function() { // 소스코드 수정후 블럭내 블럭요소가 다시 붙는 경우 reset
582        events(this).dispatch("resetHitTestBlock");
583    }
584
585    ,registTextChangeHandler : function( targetElement ){
586        var _this = this;
587        if(!targetElement || targetElement.length == 0) return;
588        $(targetElement).find('.wveditor_text').off("keyup").on("keyup", function(e){
589            if(e.target != targetElement && e.target.parentElement != targetElement) {
590                $(e.target).off("keyup");
591                return;
592            }
593
594            //e.stopPropagation();
595            events(_this).dispatch("kitReposition");
596        })
597    }
598
599    ,removeTextChangeHandler : function ( targetElement ) {
600        if(!targetElement || targetElement.length == 0) return;
601
602        $(targetElement).find('.wveditor_text').off("keyup");
603    }
604
605    ,removeIncEditHandler : function( targetElement ){
606        $(targetElement).off("dblclick")
607    }
608
609
610    ,targetImage : null
611    ,prevTargetElement : null
612    ,registImageChangeHandler : function ( targetElement ) {
613        var _this = this;
614        if(!targetElement || targetElement.length == 0) return;
615
616        var bgImg = $(targetElement).css("backgroundImage");
617        if ((bgImg != "none" && bgImg != "" && bgImg.indexOf("url(") > -1)) {
618            $(targetElement).off("dblclick").on("dblclick", function (e) {
619
620                if (e.target != targetElement && e.target.parentElement != targetElement && $(e.target).closest('[data-wv-layout-element="block"]')[0] != targetElement) {
621                    $(e.target).off("dblclick");
622                    return;
623                }
624
625                e.stopPropagation();
626
627                openFileManager();
628            });
629        } else {
630            //$(targetElement).off("dblclick").on( "dblclick", function(e){ // 파일매니저 팝업이 겹쳐서 뜨는 경우로 인해 수정 2020.06.01 xilie
631            $(targetElement).find('> .wveditor_image').off("dblclick").on( "dblclick", function(e){
632                if( e.target.tagName.toLowerCase() != "img" && ($(e.target).hasClass("wveditor_image") == false || $(e.target).find("img").length == 0 )) {
633                    $(e.target).off("dblclick");
634                    return;
635                }
636                e.stopPropagation();
637                var target = e.target;
638                if (target.tagName.toLowerCase() == "img") {
639                    _this.targetImage = target;
640
641                    var isHeaderLogoImg = false;
642                    if ($(target).closest('[data-wv-inc^=header]').length > 0 && $(target).closest('[data-wv-layout-element="block"]').attr('data-wv-logo') !== undefined) isHeaderLogoImg = true;
643
644                    openFileManager(function (item) {
645                        if (isHeaderLogoImg) {
646                            wvAdminIFrameBridge._WVHeaderFooter.onFileManagerFileSelected(item, _this.targetImage)
647                        } else {
648                            _this.toolList["ToolText"].toolBtnList["ToolBtnTextImage"].onFileManagerFileSelected(item, _this.targetImage);
649                        }
650                    });
651
652                }else if(target.tagName.toLowerCase() == "div" && $(target).children().length == 1 && $(target).find('img').length == 1){
653
654                    // 이미지 위에 after로 그린 아이콘 클릭 시 부모가 target이 되기 때문에 그 자식이 img인지 체크해서 파일매니저를 띄워줌 ...hsj
655                    // 현재 이미지 위에 after로 그린 아이콘 없어짐 ...230213 ymg
656
657                    _this.targetImage = $(target).find('img');
658
659                    openFileManager(function (item) {
660                        _this.toolList["ToolText"].toolBtnList["ToolBtnTextImage"].onFileManagerFileSelected(item, _this.targetImage);
661                    });
662                }
663            });
664
665            $(targetElement).find('> .wveditor_text').off("dblclick").on("dblclick", "img", function (e) {
666                e.stopPropagation();
667                var target = e.target;
668                _this.targetImage = target;
669
670                openFileManager(function (item) {
671                    _this.toolList["ToolText"].toolBtnList["ToolBtnTextImage"].onFileManagerFileSelected(item, _this.targetImage);
672                });
673            });
674        }
675    }
676
677    ,removeImageChangeHandler : function ( targetElement ) {
678        if(!targetElement || targetElement.length == 0) return;
679
680        var bgImg = $(targetElement).css("backgroundImage");
681        if( bgImg != "none" && bgImg != "" && bgImg.indexOf( "url(" ) > -1 ) {
682            $(targetElement).off("dblclick")
683        } else {
684            $(targetElement).find('> .wveditor_image').off("dblclick");
685        }
686
687        $(targetElement).find('> .wveditor_text').off("dblclick", "img");
688    }
689
690    /**
691     * 타겟 선택시 설정
692     * @param targetElement
693     */
694    ,changeTargetElement : function( targetElement , e){
695        var targetChanged = false;
696        var _this = this;
697
698
699        if( this.targetElementList && this.targetElementList.length > 0 ){
700            this.removeTargetElementMulti();
701        }
702
703        this.registImageChangeHandler( targetElement );
704        this.registTextChangeHandler( targetElement );
705
706        if (window.toolMode === 'side') {
707            var _WVLayoutKit = wvAdminIFrameBridge._WVLayoutKit;
708
709            if (targetElement) {
710                //블록자체에 이동이벤트를 줌
711                if (this.editorMode === 'product') {
712                    // mouseAdapter(targetElement).offDrag();
713                    // if ($(targetElement).attr('data-wv-layout-element-restr
713icted') === undefined && $(targetElement).attr('data-wv-layout-element-lock') === undefined) {
714                    //     let dragEvent = bm.dragMove;
715                    //     dragEvent.settingReset();
716                    //     dragEvent.target = _WVLayoutKit.targetElementList.length > 0 ? _WVLayoutKit.targetElementList : _WVLayoutKit.targetElement;
717                    //     mouseAdapter(targetElement).onDrag(dragEvent.onFreeMove, dragEvent.onFreeMoveEnd, dragEvent.onFreeMoveStart);
718                    // }
719                } else {
720                    mouseAdapter(targetElement).offDrag();
721                    if ($(targetElement).attr('data-wv-layout-element-restricted') === undefined && $(targetElement).attr('data-wv-layout-element-lock') === undefined) {
722                        let dragEvent = bm.dragMove;
723                        dragEvent.settingReset();
724                        dragEvent.target = _WVLayoutKit.targetElementList.length > 0 ? _WVLayoutKit.targetElementList : _WVLayoutKit.targetElement;
725                        mouseAdapter(targetElement).onDrag(dragEvent.onFreeMove, dragEvent.onFreeMoveEnd, dragEvent.onFreeMoveStart);
726                        $(this.targetElement).css({ cursor: 'move' });
727                        $(targetElement).css({ cursor: 'move' });
728                    }
729                }
730                //텍스트선택영역 해제
731                var selection = wvAdminIFrameBridge.iframeWindow.getSelection();
732                //편집가능 제한 (원래블록, 대상블록)
733                $(this.targetElement).find('.wveditor_text').attr('contenteditable', false);
734                $(targetElement).find('.wveditor_text').attr('contenteditable', false);
735                selection.removeAllRanges();
736                //툴사이드 타이틀
737                let type = this.targetElementType[$(targetElement).attr('data-wv-layout-element-type')];
738                if(!type) {
739                    type = this.targetElementType[$(targetElement).find('[data-wv-layout-element-type]').attr('data-wv-layout-element-type')];
740                    if(!type) {
741                        type = '일반블록';
742                    }
743                }
744                //툴사이드 타이틀 변경
745                _this.targetToolProp.text(type);
746                //툴사이드 노출
747                _this.toolSide.show();
748                //레이어메뉴 갱신
749                wvAdminIFrameBridge._WVToolbarLayerWindow.setLayerDefault();
750            }
751
752        }
753
754        this.hideExtraTool();
755
756        if( $(targetElement).attr( "data-wv-layout-element") != "block" ){
757            targetElement = $(targetElement).closest("[data-wv-layout-element=block]");
758        }
759
760        if( targetElement.hasOwnProperty("length") ) targetElement = targetElement[0];
761
762
763        // is single
764        if( this.targetElement != targetElement ){
765
766            var elementType = $(this.targetElement).attr("data-wv-layout-element-type");
767
768            // 이전 타겟이 테이블 이었을 때만 선택 상태를 초기화 함.
769            if( bm.string.contains(elementType, "table") ){
770                bm.tableSelectionManager.removeRange();
771            }
772
773            if( this.targetElement ){
774                // $(this.targetElement).off('mouseup');
775
776                if( !isPrdDetailInfo ){
777                    this.removeIncEditHandler(this.targetElement);
778                }
779                this.removeImageChangeHandler(this.targetElement);
780                this.removeTextChangeHandler(this.targetElement);
781            }
782            this.removeTargetElementSingle( this.targetElement );
783            this.targetElement = targetElement;
784            $(this.targetElement).addClass( this.selectedClass );
785            // if($(this.targetElement).closest('[data-wv-list-template]').length > 0) $(this.targetElement).closest('[data-wv-list-template]').addClass( this.selectedAreaClass );
786            // else $(this.targetElement).closest('[data-wv-design-area]').addClass( this.selectedAreaClass );
787
788            $(this.targetElement).closest('[data-wv-design-area]').addClass( this.selectedAreaClass );
789
790            targetChanged = true;
791        }
792
793        // 메뉴 요소가 타겟인지 체크
794        this.setIsMenuTarget( targetElement );
795        this.setIsShopListTarget (targetElement);
796
797        function isLayoutKitElement(target){
798            //mouseup 이벤트가 layoutKit 내의 element 위치에서 발생했는지 파악하는 함수
799            var isKitElement = false;
800
801            if($(target).closest('#wvPosDisplayCon').length != 0){
802                isKitElement = true;
803            }else if($(target).closest('#wvSizeDisplayCon').length != 0){
804                isKitElement = true;
805            }else if($(target).closest('#wvSizeControlCon').length != 0){
806                isKitElement = true;
807            }else if($(target).closest('#layoutMoveBtn').length != 0){
808                isKitElement = true;
809            }else if($(target).closest('.layoutElementFreeMove').length != 0){
810                isKitElement = true;
811            }
812
813            return isKitElement;
814        }
815
816        var i, tool;
817        var len = this.toolList.length;
818        for (i = 0; i < len; i++) {
819            tool = this.toolList[i];
820
821            if( tool.status == 0 ){
822                tool.active( targetElement, e, window.toolMode);
823            }else{
824                tool.changeTarget( targetElement , e, window.toolMode);
825            }
826        }
827
828        if ($(e.data.targetElement).closest('[data-wv-layout-element="block"]').length == 0 || isLayoutKitElement(e.target)) return false;
829
830        //configList 컨트롤
831        this.configList.forEach(config => {
832            const frameConfig = wvAdminIFrameBridge['_' + config];
833
834            if(!frameConfig) return;
835
836            frameConfig.configControl(targetElement);
837        })
838
839        const isMulti = wvAdminIFrameBridge._WVLayoutKit.isMultiSelectMode;
840        const hasTargetList = _this.targetElementList?.length > 0;
841        const hasSingleTarget = _this.targetElement;
842        
843        if ((isMulti && hasTargetList) || (!isMulti && hasSingleTarget)) {
844          const el = this.targetElement;
845          const effectAttr = el?.getAttribute('data-wv-effect');
846        
847          if (el && effectAttr) {
848            const effect = JSON.parse(effectAttr);
849            if (effect.setIdArr) {
850                //effect전용 로직
851                return;
852            }
853          }
854        
855          if (targetChanged) {
856            this.toolStyleSetting();
857          }
858        }
859    }
860
861
862    /**
863     * 멀티 타겟 선택시 설정
864     * target 이 list 일 경우 replace 를 한다.
865     * @param targetElement
866     */
867    ,changeTargetElementList : function( target, isReplace ){
868
869        // for(let i=0; i< target.length; i++) {
870        //     mouseAdapter(target[i]).offDrag();
871        // }
872
873        // 1. 기존 싱글 선택모드에 대한 타겟이 있으면 이를 제거하고
874        if( this.targetElement ){
875            // $(this.targetElement).off('mouseup');
876            this.targetElement = null;
877        }
878
879        // 2. 기타 툴을 모두 끄고
880        bm.each(this.extraToolList, function(key, toolset ){
881            toolset.hide();
882        })
883
884        // 대체를 원하면 기존 값을 모두 초기화 하고
885        var i, element, len;
886        if( isReplace ){
887            this.removeTargetElementMulti();
888        }
889
890        // 3. 추가 선택인지, 기존 선택된 엘리먼트 삭제인지에 따라 핸들링
891        if( !this.targetElementList ) this.targetElementList = [];
892        len = target.length;
893        if( len ){
894            for (i = 0; i < len; i++) {
895                element = target[i];
896                this.targetElementList.push( element );
897                $(element).addClass( this.selectedClass );
898
899                // if($(element).closest('[data-wv-list-template]').length > 0) $(element).closest('[data-wv-list-template]').addClass( this.selectedAreaClass );
900                // else $(element).closest('[data-wv-design-area]').addClass( this.selectedAreaClass );
901
902                $(element).closest('[data-wv-design-area]').addClass( this.selectedAreaClass );
903
904                //블록자체에 이동이벤트를 줌
905                var _WVAdminBlockMove = wvAdminIFrameBridge._WVAdminBlockMove;
906                // if ($(element).attr('data-wv-layout-element-restricted') === undefined) {
907                //     mouseAdapter(element).onDrag(_WVAdminBlockMove.onFreeMove, _WVAdminBlockMove.onFreeMoveEnd, _WVAdminBlockMove.onFreeMoveStart);
908                // }
909            }
910        }else{
911            this.targetElementList.push( target );
912            $(target).addClass( this.selectedClass );
913
914            // if($(target).closest('[data-wv-list-template]').length > 0) $(target).closest('[data-wv-list-template]').addClass( this.selectedAreaClass );
915            // else $(target).closest('[data-wv-design-area]').addClass( this.selectedAreaClass );
916
917            $(target).closest('[data-wv-design-area]').addClass( this.selectedAreaClass );
918
919            //블록자체에 이동이벤트를 줌
920            var _WVAdminBlockMove = wvAdminIFrameBridge._WVAdminBlockMove;
921            // if ($(target).attr('data-wv-layout-element-restricted') === undefined) {
922            //     mouseAdapter(target).onDrag(_WVAdminBlockMove.onFreeMove, _WVAdminBlockMove.onFreeMoveEnd, _WVAdminBlockMove.onFreeMoveStart);
923            // }
924        }
925
926        // 메뉴 요소가 타겟인지 체크
927        this.setIsMenuTarget( this.targetElementList );
928        this.setIsShopListTarget(this.targetElementList);
929
930        var i, tool;
931        var len = this.toolList.length;
932        for (i = 0; i < len; i++) {
933            tool = this.toolList[i];
934
935            if( tool.status == 0 ){
936                tool.active( this.targetElementList );
937            }else{
938                tool.changeTarget( this.targetElementList );
939            }
940
941        }
942    }
943
944
945    /**
946     * 현재 보여지는 툴버튼 관련한 스타일의 활성화
947     */
948    ,toolStyleSetting: function( type ) {
949        var i, tool;
950        
951        if( type ){ 
952            // 특정 타입을 호출하면
953            this.toolList[type].setStyleTool();
954
955        }else{
956            // 특정 타입이 없으므로 전체 스타일 현행화
957
958            var len = this.toolList.length;
959
960            for (i = 0; i < len; i++) {
961                tool = this.toolList[i];
962                tool.setStyleTool();
963            }
964        }
965
966    }
967
968    /**
969     * 타겟 제거
970     */
971    ,removeTargetElementSingle : function( element ){
972        $(element).removeClass( this.selectedClass );
973        $(element).closest('[data-wv-design-area]').removeClass( this.selectedAreaClass );
974        // $(element).closest('[data-wv-list-template]').removeClass( this.selectedAreaClass );
975        this.targetElement = null;
976    }
977
978    /**
979     * 타겟 전체 제거
980     */
981    ,removeTargetElementMulti : function ( element ) {
982
983        // element 를 던지면 1개만 삭제
984        if( element ){
985
986            var i, el;
987            var len = element.length;
988            if( len ){
989                for (i = 0; i < len; i++) {
990                    el = element[i];
991
992                    $(el).removeClass( this.selectedClass );
993                    $(el).closest('[data-wv-design-area]').removeClass( this.selectedAreaClass );
994                    // $(el).closest('[data-wv-list-template]').removeClass( this.selectedAreaClass );
995                    this.targetElementList.splice( this.targetElementList.indexOf( el ), 1 );
996                }
997            }else{
998
999                $(element).removeClass( this.selectedClass );
1000                $(element).closest('[data-wv-design-area]').removeClass( this.selectedAreaClass );
1001                // $(element).closest('[data-wv-list-template]').removeClass( this.selectedAreaClass );
1002                this.targetElementList.splice( this.targetElementList.indexOf( element ), 1 );
1003            }
1004
1005        }else{
1006            var len = this.targetElementList.length;
1007            var el;
1008            for( var i=0; i<len; i++ ){
1009                el = this.targetElementList[i];
1010                $(el).removeClass( this.selectedClass );
1011                $(el).closest('[data-wv-design-area]').removeClass( this.selectedAreaClass );
1012                // $(el).closest('[data-wv-list-template]').removeClass( this.selectedAreaClass );
1013            }
1014            this.targetElementList.length = 0;
1015        }
1016    }
1017
1018    /**
1019     * 타겟 변경 이후
1020     */
1021    , targetStatusChangeComplete: function (targetElement, e) {
1022        this.toolList.forEach(tool => {
1023            if (tool.targetStatusChangeComplete) tool.targetStatusChangeComplete();
1024        })
1025    }
1026}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.