define([ 'jquery' , 'nbextensions/visualpython/src/common/vpCommon' , 'nbextensions/visualpython/src/common/constant' , 'nbextensions/visualpython/src/container/vpContainer' , './api.js' , './constData.js' , './blockContainer.js' , './createBlockBtn.js' , './createApiBtn.js' , './createGroup.js' , './api_list.js' , './component/boardMenuBar.js' // TEST: File Navigation , 'nbextensions/visualpython/src/common/vpFileNavigation' ], function ( $, vpCommon, vpConst, vpContainer, api, constData, blockContainer, createBlockBtn, createApiBtn, createGroup, api_list, apiBlockMenuInit // TEST: File Navigation , FileNavigation ) { const { IsCodeBlockType, ControlToggleInput, LoadVariableList, MapGroupTypeToName } = api; const { BLOCK_GROUP_TYPE , BLOCK_CODELINE_BTN_TYPE , BLOCK_CODELINE_TYPE , FOCUSED_PAGE_TYPE , BLOCK_DIRECTION , VP_ID_PREFIX , VP_ID_WRAPPER , VP_ID_APIBLOCK_LEFT_TAB_API , VP_ID_APIBLOCK_LEFT_TAP_APILIST_PAGE , VP_ID_APIBLOCK_NODE_BLOCK_PLUS_BUTTON , VP_ID_APIBLOCK_TEXT_BLOCK_PLUS_BUTTON , VP_ID_APIBLOCK_BOARD_MAKE_NODE_BLOCK_INPUT , VP_ID_APIBLOCK_BOARD_MAKE_NODE_PATH , VP_ID_APIBLOCK_DELETE_BLOCK_ALL , VP_ID_APIBLOCK_MENU_BOX , VP_APIBLOCK_BOARD_OPTION_PREVIEW_BUTTON , VP_APIBLOCK_BOARD_OPTION_CANCEL_BUTTON , VP_APIBLOCK_BOARD_OPTION_APPLY_BUTTON , VP_CLASS_PREFIX , VP_CLASS_BLOCK_GROUPBOX_PREFIX , VP_CLASS_APIBLOCK_BOARD_CONTAINER , VP_CLASS_APIBLOCK_BUTTONS , VP_CLASS_APIBLOCK_BOARD , VP_CLASS_APIBLOCK_OPTION_TAB , NUM_DELETE_KEY_EVENT_NUMBER , NUM_ENTER_KEY_EVENT_NUMBER , NUM_APIBLOCK_LEFT_PAGE_WIDTH , NUM_API_BOARD_CENTER_PAGE_WIDTH , STR_CLICK , STR_EMPTY , STR_WIDTH , STR_MAX_WIDTH , STR_PARENT , STR_NONE , STR_NOTEBOOK , STR_HEADER , STR_CELL , STR_CODEMIRROR_LINES , STR_UNTITLED } = constData; const BlockContainer = blockContainer; const CreateBlockBtn = createBlockBtn; const CreateApiBtn = createApiBtn; const CreateGroup = createGroup; const { toggleApiListSubGroupShow , loadLibraries , loadLibrariesToJson , getNavigationInfo } = api_list; const { saveAsNotePage , openNotePage , closeNoteExtraMenu , saveNotePageAction_newVersion , openNotePageAction_newVersion } = vpContainer; var init = function(apiBlockPackage){ /** 제이쿼리 커스텀 메소드 생성 * 싱글 클릭 혹은 더블 클릭 바인딩 * * 이 메소드 하나로 싱글 클릭과 더블 클릭을 동시에 처리할 수 있음 */ $.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) { return this.each(function(){ var clicks = 0, self = this; $(this).click(function(event){ clicks++; if (clicks == 1) { setTimeout(function(){ if(clicks == 1) { single_click_callback.call(self, event); } else { double_click_callback.call(self, event); } clicks = 0; }, timeout || 300); } }); }); } /** block container 생성 * 싱글톤 무조건 1개 */ var blockContainer = new BlockContainer(); blockContainer.setImportPackageThis(apiBlockPackage); /** Logic에 블럭 그룹 생성 */ var createLogicGroupArray = Object.values(BLOCK_GROUP_TYPE); var logicBlockContainer = VP_CLASS_PREFIX + VP_CLASS_BLOCK_GROUPBOX_PREFIX + 'logic'; createLogicGroupArray.forEach(enumData => { var groupName = MapGroupTypeToName(enumData); var open = false; var defaultOpenGroupList = ['Define', 'Control']; // open defined group div if (defaultOpenGroupList.includes(groupName)) { open = true; } new CreateGroup(blockContainer, enumData, MapGroupTypeToName(enumData), logicBlockContainer, 0, open); }); /** Logic(Define, Control, Execute)에 블럭 생성 버튼 생성 */ var createBlockBtnArray = Object.values(BLOCK_CODELINE_BTN_TYPE); createBlockBtnArray.forEach(enumData => { new CreateBlockBtn(blockContainer, enumData); }); /** 추가: API 버튼 추가 */ var xmlLibraries = {}; loadLibrariesToJson(function(param) { xmlLibraries = param.getJson(); // make group & list apiLibariesToBtn(blockContainer, xmlLibraries.library); }, xmlLibraries); /** 추가: FIXME: Data Analysis 메뉴 임시 추가 */ var TEMP_DA_MENUS = [ 'Database', 'Crawling', 'Data Preprocessing', 'EDA', 'Visualization', 'Text Analysis' ]; TEMP_DA_MENUS.forEach((menu, idx) => { new CreateGroup(blockContainer, 'da_' + idx, menu, VP_CLASS_PREFIX + 'vp-block-group-box-da'); }); /** 추가: FIXME: AI 메뉴 임시 추가 */ var TEMP_AI_MENUS = [ 'Machine Learning', 'Deep Learning' ] TEMP_AI_MENUS.forEach((menu, idx) => { new CreateGroup(blockContainer, 'ai_' + idx, menu, VP_CLASS_PREFIX + 'vp-block-group-box-ai'); }); /** API Block 햄버거 메뉴바 생성 */ apiBlockMenuInit(blockContainer); /** ------------------처음 파일을 오픈할 때 화면의 width 값 계산 ----------------------------------- */ /** 전체 visual python width 계산 */ var mainPageRectWidth = $(VP_ID_PREFIX + VP_ID_WRAPPER).css(STR_WIDTH); var index = mainPageRectWidth.indexOf('px'); var mainPageRectWidthNum = parseInt(mainPageRectWidth.slice(0,index)); /** 왼쪽 Logic, API 블럭 생성 영역의 width*/ var buttonsPageRectWidth = NUM_APIBLOCK_LEFT_PAGE_WIDTH; /** 가운데 board 영역의 width */ var boardPageRectWidth = NUM_API_BOARD_CENTER_PAGE_WIDTH; /** 오른쪽 option 영역의 width 계산 */ var optionPageRectWidth = mainPageRectWidthNum - buttonsPageRectWidth - boardPageRectWidth - 68; /** visual python 전체의 width 렌더링 */ $(vpCommon.wrapSelector(VP_ID_PREFIX + VP_ID_WRAPPER)).css(STR_WIDTH, mainPageRectWidth); /** 가운데 board 영역의 width 렌더링 */ $(vpCommon.wrapSelector(VP_CLASS_PREFIX + VP_CLASS_APIBLOCK_BOARD_CONTAINER)).css(STR_WIDTH, boardPageRectWidth); /** 오른쪽 option 영역의 width 렌더링*/ $(vpCommon.wrapSelector(VP_CLASS_PREFIX + VP_CLASS_APIBLOCK_OPTION_TAB)).css(STR_WIDTH, optionPageRectWidth); /** 오른쪽 option 영역의 max-width 렌더링*/ // var optionPageRectWidth_maxWidth = mainPageRectWidthNum - buttonsPageRectWidth - 290 - 103; var optionPageRectWidth_maxWidth = mainPageRectWidthNum - buttonsPageRectWidth - boardPageRectWidth - 8 - 68; $(vpCommon.wrapSelector(VP_CLASS_PREFIX + VP_CLASS_APIBLOCK_OPTION_TAB)).css(STR_MAX_WIDTH, optionPageRectWidth_maxWidth); /** 가운데 board 위 영역의 렌더링 */ $(VP_ID_PREFIX + VP_ID_APIBLOCK_BOARD_MAKE_NODE_BLOCK_INPUT).val(STR_UNTITLED); $(VP_ID_PREFIX + VP_ID_APIBLOCK_BOARD_MAKE_NODE_BLOCK_INPUT).focus(); /** API List 함수들을 Logic아래에 렌더링한 후에 * API List xml 데이터를 xmlLibraries변수에 대입 */ var xmlLibraries = loadLibraries(VP_ID_PREFIX + VP_ID_APIBLOCK_LEFT_TAB_API); /** 블럭이 생성되어 보여지는 container dom을 생성하고 * board에 container dom을 렌더링 */ blockContainer.reNewContainerDom(); /** Block Max Width 설정 */ blockContainer.setBlockMaxWidth(boardPageRectWidth - 60); /** delete 키 or 엔터 키를 누를 때 keyup 이벤트 발동 */ // $(document).keyup(function(e) { // var keycode = e.keyCode // ? e.keyCode // : e.which; // var selectedBlock = blockContainer.getSelectBlock(); // /** Delete 이벤트 */ // /** block을 클릭하고 delete 키 눌렀을 때 */ // if (keycode == NUM_DELETE_KEY_EVENT_NUMBER // && selectedBlock){ // selectedBlock.deleteBlock_childBlockList(); // blockContainer.resetOptionPage(); // blockContainer.reRenderAllBlock_asc(); // } // /** 엔터 이벤트 */ // /** node 블럭을 클릭하고 엔터키를 눌렀을 때 */ // if (keycode == NUM_ENTER_KEY_EVENT_NUMBER // && selectedBlock // && selectedBlock.getBlockType() == BLOCK_CODELINE_TYPE.NODE){ // // console.log('엔터'); // selectedBlock.renderNodeBlockInput(STR_NONE); // } // }); /** Logic, API, Data Analysis 의 > 버튼 클릭 */ $(document).on(STR_CLICK,`.vp-apiblock-panel-area-vertical-btn`, function(){ if ($(this).hasClass(`vp-apiblock-arrow-down`)) { // 펼치기 $(this).removeClass(`vp-apiblock-arrow-down`); $(this).addClass(`vp-apiblock-arrow-up`); $(this).parent().parent().removeClass(`vp-apiblock-minimize`); } else { // 닫기 $(this).removeClass(`vp-apiblock-arrow-up`); $(this).addClass(`vp-apiblock-arrow-down`); $(this).parent().parent().addClass(`vp-apiblock-minimize`); } }); /** Logic, API, Data Analysis 의 이름 클릭*/ $(document).on(STR_CLICK,`.vp-block-blocktab-name`, function(){ var $arrowBtn = $(this).prev(); if ($($arrowBtn).hasClass(`vp-apiblock-arrow-down`)) { // 펼치기 $($arrowBtn).removeClass(`vp-apiblock-arrow-down`); $($arrowBtn).addClass(`vp-apiblock-arrow-up`); $($arrowBtn).parent().parent().removeClass(`vp-apiblock-minimize`); } else { // 닫기 $($arrowBtn).removeClass(`vp-apiblock-arrow-up`); $($arrowBtn).addClass(`vp-apiblock-arrow-down`); $($arrowBtn).parent().parent().addClass(`vp-apiblock-minimize`); } }); // 추가 : 대메뉴 접기/펼치기 $('.vp-apiblock-category').on(STR_CLICK, function() { var category = $(this).attr('data-category'); // 해당 대메뉴 접기/펼치기 토글 $('.vp-block-group-box-' + category).toggle(); }); /** 2021-01-28 수정: 주피터쪽을 선택한다고 VisualPython의 포커스를 변경하지 않도록 수정 * 2021-02-10 수정: 주피터쪽 선택 여부는 체크, 대신 VisualPython의 작업환경을 초기화하지 않도록 수정 */ /** visual python 화면 이외에 화면(jupyter header 영역 , jupyter cell 영역)을 클릭했을 때, * page 포커스 해제 * option (N/A) 처리 * selected 된 블럭 해제 */ $(vpCommon.wrapSelector(`${VP_ID_PREFIX}${STR_NOTEBOOK}, ${VP_ID_PREFIX}${STR_HEADER}, ${VP_CLASS_PREFIX}${STR_CELL}, ${VP_CLASS_PREFIX}${STR_CODEMIRROR_LINES}, div#notebook`)).click(function(event) { // blockContainer.resetBlockList(); // blockContainer.resetOptionPage(); blockContainer.setFocusedPageType(FOCUSED_PAGE_TYPE.NULL); }); /** Create block buttons page를 클릭했을 때 */ $(vpCommon.wrapSelector(VP_CLASS_PREFIX + VP_CLASS_APIBLOCK_BUTTONS)).click(function(event) { blockContainer.setFocusedPageType(FOCUSED_PAGE_TYPE.BUTTONS); }); /** Block Board page를 클릭했을 때 */ $(vpCommon.wrapSelector(VP_CLASS_PREFIX + VP_CLASS_APIBLOCK_BOARD)).click(function(event) { /** Board에서 Board page를 클릭하고, block을 클릭하지 않았을 때 */ if ($(event.target).hasClass('vp-apiblock-board-body') || $(event.target).hasClass('vp-block-container')) { blockContainer.checkModified(); blockContainer.checkSaveOptionPage(function(result) { blockContainer.resetBlockList(); blockContainer.resetOptionPage(); }); } }); /** Block Board 위 Input 영역을 클릭했을 때 */ $(vpCommon.wrapSelector(VP_ID_PREFIX + "vp_apiblock_board_main_title")).click(function(event) { blockContainer.setFocusedPageType(FOCUSED_PAGE_TYPE.BOARD_TITLE); }); /** Board Main Title에서 엔터키 눌렀을 때 */ $(vpCommon.wrapSelector(VP_ID_PREFIX + "vp_apiblock_board_main_title")).keyup(function(event) { var keyCode = event.keyCode ? event.keyCode : event.which; if (keyCode == NUM_ENTER_KEY_EVENT_NUMBER) { blockContainer.setFocusedPageType(FOCUSED_PAGE_TYPE.NULL); $(this).find('input').blur(); } }); /** Board File Name changed */ $(vpCommon.wrapSelector(VP_ID_PREFIX + VP_ID_APIBLOCK_BOARD_MAKE_NODE_BLOCK_INPUT)).change(function(event) { // reset path $(vpCommon.wrapSelector(VP_ID_PREFIX + VP_ID_APIBLOCK_BOARD_MAKE_NODE_PATH)).val(''); }); /** API List를 클릭했을 때*/ $(vpCommon.wrapSelector(VP_ID_PREFIX + VP_ID_APIBLOCK_LEFT_TAP_APILIST_PAGE)).click(function(event) { blockContainer.setFocusedPageType(FOCUSED_PAGE_TYPE.API_LIST_TAB); }); /** Option page를 클릭했을 때 */ $(vpCommon.wrapSelector(VP_CLASS_PREFIX + VP_CLASS_APIBLOCK_OPTION_TAB)).click(function(event) { blockContainer.setFocusedPageType(FOCUSED_PAGE_TYPE.OPTION); }); /** 블럭 복사하고 붙여넣는 기능 이벤트 바인딩 */ $(document).ready(function() { var ctrlDown = false, ctrlKey = 17, cmdKey = 91, vKey = 86, cKey = 67; $(document).keydown(function(e) { if (e.keyCode == ctrlKey || e.keyCode == cmdKey) { ctrlDown = true; } }).keyup(function(e) { if (e.keyCode == ctrlKey || e.keyCode == cmdKey) { ctrlDown = false; } }).click(function(e) { // check modified blockContainer.checkModified(); }); $(document).change($(vpCommon.wrapSelector('.vp-apiblock-option input')), function() { // check modified blockContainer.checkModified(); }); // DEPRECATED: ctrl+c / ctrl+v 삭제 // $(document).keydown(function(e) { // /** board에 선택한 블럭 없거나 // * TEXT 블럭인 경우에 ctrl + c , ctrl + v 금지 // */ // var selectedBlock = blockContainer.getSelectBlock(); // if (!selectedBlock // || selectedBlock.getBlockType() == BLOCK_CODELINE_TYPE.TEXT // || IsCodeBlockType(selectedBlock.getBlockType()) == true ) { // return; // } // // console.log('selectedBlock',selectedBlock); // /** ctrl + c */ // if (ctrlDown // && e.ctrlKey && (e.keyCode == cKey) // && !e.shiftKey && !e.altKey ) { // blockContainer.setCtrlSaveData(); // } // /** ctrl + v */ // if (ctrlDown // && e.ctrlKey && (e.keyCode == vKey) // && !e.shiftKey && !e.altKey ) { // blockContainer.copyCtrlSaveData(); // } // }); }); /** +node 블럭 생성 버튼 클릭 함수 바인딩 */ $(document).on(STR_CLICK, VP_ID_PREFIX + VP_ID_APIBLOCK_NODE_BLOCK_PLUS_BUTTON, function() { // blockContainer.createNodeBlock(true); // +code 블럭 생성 blockContainer.createCodeBlock(); }); /** +text 블럭 생성 버튼 클릭 함수 바인딩 */ $(document).on(STR_CLICK, VP_ID_PREFIX + VP_ID_APIBLOCK_TEXT_BLOCK_PLUS_BUTTON, function() { blockContainer.createTextBlock(); }); /** option page - preview 버튼 클릭 함수 바인딩 */ $(document).on(STR_CLICK, VP_ID_PREFIX + VP_APIBLOCK_BOARD_OPTION_PREVIEW_BUTTON, function() { var selectedBlock = blockContainer.getSelectBlock(); if (selectedBlock == null) { blockContainer.hideOptionPreviewBox(); if ($(this).hasClass('enabled')) { blockContainer.resetOptionPage(); $(this).removeClass('enabled'); } else { blockContainer.showOptionPageWithPreview(); $(this).addClass('enabled'); } } else { if ($(this).hasClass('enabled')) { blockContainer.hideOptionPreviewBox(); $(this).removeClass('enabled'); } else { blockContainer.showOptionPreviewBox(); $(this).addClass('enabled'); } } }); /** option page - cancel 버튼 클릭 함수 바인딩 */ $(document).on(STR_CLICK, VP_ID_PREFIX + VP_APIBLOCK_BOARD_OPTION_CANCEL_BUTTON, function() { blockContainer.cancelBlock(); }); /** option page - apply 버튼 클릭 함수 바인딩 */ $(document).on(STR_CLICK, VP_ID_PREFIX + VP_APIBLOCK_BOARD_OPTION_APPLY_BUTTON, function() { // if disabled, do nothing if ($(this).hasClass('disabled')) { return; } blockContainer.applyBlock(); }); /** * API List item 클릭 이벤트 함수 바인딩 * API List 목록의 함수에 대응되는 API List 블럭을 생성하기 위해서 */ $(document).off(STR_CLICK,VP_CLASS_PREFIX + vpConst.LIST_ITEM_LIBRARY + 'li'); $(document).on(STR_CLICK, VP_CLASS_PREFIX + vpConst.LIST_ITEM_LIBRARY + 'li', function(event) { event.stopPropagation(); if ($(this).hasClass(vpConst.LIST_ITEM_LIBRARY_GROUP)) { toggleApiListSubGroupShow($(this)); } else if ($(this).hasClass(vpConst.LIST_ITEM_LIBRARY_FUNCTION)) { const funcID = $(this).data(vpConst.LIBRARY_ITEM_DATA_ID.replace(vpConst.TAG_DATA_PREFIX, "")); var naviInfo = getNavigationInfo(funcID); /** board에 선택한 API List 블럭 생성 */ blockContainer.createAPIListBlock(funcID, naviInfo); } }); /** API Block의 option을 화면 좌우로 resize하는 이벤트 함수 */ $(vpCommon.wrapSelector(VP_CLASS_PREFIX + VP_CLASS_APIBLOCK_OPTION_TAB)).resizable({ containment: STR_PARENT, // 부모 dom을 기준으로 resize -> 확실하진 않지만 'parent'라고 되어있어서 추정 handles: 'w', // 'w'는 width 좌우 'h'는 상하 height resizeHeight: false // height resize 금지 // resize 할 경우 계속 실행 ,resize:(function() { blockContainer.setIsOptionPageResize(true); blockContainer.resizeOptionPopup(); }) // resize 끝나면 멈춤 ,stop: function(event, ui) { blockContainer.setIsOptionPageResize(false); } }); /** 햄버거 메뉴 open 클릭 */ $(document).on(STR_CLICK, vpCommon.wrapSelector(vpCommon.formatString("#{0}", vpConst.VP_NOTE_EXTRA_MENU_OPEN_NOTE)), function() { var saveFileName = $(VP_ID_PREFIX + VP_ID_APIBLOCK_BOARD_MAKE_NODE_BLOCK_INPUT).val(); /** 빈 string이거나 * Untitled이면 File navigation을 open */ if ( saveFileName == STR_EMPTY || saveFileName == STR_UNTITLED) { openNotePage(); /** File navigation을 open하지 않고 alert창 띄움*/ } else { var saveFilePath = vpCommon.formatString("./{0}.{1}", saveFileName, vpConst.VP_NOTE_EXTENSION); apiBlockPackage.openMultiBtnModal_new('Save As', `Save changes to '${saveFileName}.vp'`,['Yes','No', 'Cancel'], [() => { saveNotePageAction_newVersion(saveFileName, saveFilePath); openNotePage(); },() => { openNotePage(); },() => { }]); } }); /** 햄버거 메뉴 save 저장 클릭 */ $(document).on(STR_CLICK, vpCommon.wrapSelector(vpCommon.formatString("#{0}", vpConst.VP_NOTE_EXTRA_MENU_SAVE_NOTE)), function() { var saveFileName = $(VP_ID_PREFIX + VP_ID_APIBLOCK_BOARD_MAKE_NODE_BLOCK_INPUT).val(); var saveFilePath = $(VP_ID_PREFIX + VP_ID_APIBLOCK_BOARD_MAKE_NODE_PATH).val(); // path // TEST: File Navigation // var state = { // }; // var fileNavigation = new FileNavigation(FileNavigation.FILE_TYPE.SAVE_VP_NOTE, state); // return; /** 빈 string이거나 * Untitled이면 File navigation을 open */ if ( saveFileName == STR_EMPTY || saveFileName == STR_UNTITLED) { saveAsNotePage(); closeNoteExtraMenu(); /** File navigation을 open하지 않고 alert창 띄움*/ } else { if (!saveFilePath.includes(saveFileName)) { // 다른 파일이면 save as saveAsNotePage(); closeNoteExtraMenu(); } else { var saveFilePath = vpCommon.formatString("{0}", saveFilePath, vpConst.VP_NOTE_EXTENSION); saveNotePageAction_newVersion(vpCommon.formatString("{0}.{1}", saveFileName, vpConst.VP_NOTE_EXTENSION), saveFilePath); // apiBlockPackage.openMultiBtnModal_new('Save As', `Save changes to '${saveFileName}.vp'`,['Yes', 'No', 'Cancel'], [() => { // },() => { // },() => { // }]); } } }); /** 햄버거 메뉴 save as 다른 이름으로 저장 클릭 이벤트 함수 */ $(document).on(STR_CLICK, vpCommon.wrapSelector(vpCommon.formatString("#{0}", vpConst.VP_NOTE_EXTRA_MENU_SAVE_AS_NOTE)), function() { saveAsNotePage(); closeNoteExtraMenu(); }); /** * 파일 브라우저 로드 파일 선택 */ $(document).on("fileReadSelected.fileNavigation", function(e) { // 선택 파일 확장자가 노트 세이브 파일인 경우만 동작 if (e.path.substring(e.path.lastIndexOf(".") + 1) === vpConst.VP_NOTE_EXTENSION) { openNotePageAction_newVersion(); } }); /** * 파일 브라우저 저장 파일 선택 */ $(document).on("fileSaveSelected.fileNavigation", function(e) { // 선택 파일 확장자가 노트 세이브 파일인 경우만 동작 if (e.path.substring(e.path.lastIndexOf(".") + 1) === vpConst.VP_NOTE_EXTENSION) { var selectedPath = $(vpCommon.wrapSelector(vpCommon.formatString("#{0}", vpConst.VP_NOTE_REAL_FILE_PATH))).val(); var saveFileName = selectedPath.substring(selectedPath.lastIndexOf("/") + 1); // FIXME: 여기부분 수정해야 함 saveNotePageAction_newVersion(saveFileName, selectedPath); // apiBlockPackage.openMultiBtnModal_new('Save As', `Save changes to '${saveFileName}'`,['Yes','No', 'Cancel'], [() => { // },() => { // },() => { // }]); } }); $(document).on('click', function(evt) { if (evt.target.id != 'vp_apiblock_menu_box') { // close block menu $(vpCommon.wrapSelector(vpCommon.formatString('#{0}', VP_ID_APIBLOCK_MENU_BOX))).hide(); } }); ControlToggleInput(); return blockContainer; } var apiLibariesToBtn = function(blockContainer, libObj, parentId = '') { if (libObj._type == undefined // root || libObj._type == 'package') { // 패키지인 경우 그룹 생성 if (libObj._name != undefined) { if (libObj._level == 0) { var open = false; if (libObj._name == 'Common') { // Common은 처음에 열어놓고 시작 open = true; } new CreateGroup(blockContainer, libObj._id, libObj._name, VP_CLASS_PREFIX + 'vp-block-group-box-api', libObj._level, open); } else { new CreateGroup(blockContainer, libObj._id, libObj._name, VP_CLASS_PREFIX + 'vp-apiblock-left-tab-' + parentId, libObj._level); } } // 하위 아이템 있으면 다시 호출 if (libObj.item) { if (typeof libObj.item == "object") { if (Array.isArray(libObj.item)) { // item이 array일 경우 libObj.item.forEach(obj => { apiLibariesToBtn(blockContainer, obj, libObj._id); }); } else { // 단일 항목일 경우 apiLibariesToBtn(blockContainer, libObj.item, libObj._id); } } } } else if (libObj._type == 'function' && libObj.level != "0") { // 함수인 경우 버튼 생성 (단, level은 0 이상) // parentId 없는 경우 생성안함 if (parentId != undefined && parentId !== STR_EMPTY) { new CreateApiBtn(blockContainer, libObj._id, libObj._name, parentId); } } } return init; });